2 * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifndef AVCODEC_SNOW_H
23 #define AVCODEC_SNOW_H
30 #include "rangecoder.h"
33 #define FF_MPV_OFFSET(x) (offsetof(MpegEncContext, x) + offsetof(SnowContext, m))
34 #include "mpegvideo.h"
41 #define QROOT (1<<QSHIFT)
42 #define LOSSLESS_QLOG -128
44 #define MAX_REF_FRAMES 8
46 #define LOG2_OBMC_MAX 8
47 #define OBMC_MAX (1<<(LOG2_OBMC_MAX))
48 typedef struct BlockNode
{
54 //#define TYPE_SPLIT 1
57 //#define TYPE_NOCOLOR 4
58 uint8_t level
; //FIXME merge into type?
61 static const BlockNode null_block
= { //FIXME add border maybe
62 .color
= {128,128,128},
70 #define LOG2_MB_SIZE 4
71 #define MB_SIZE (1<<LOG2_MB_SIZE)
72 #define ENCODER_EXTRA_BITS 4
75 typedef struct x_and_coeff
{
80 typedef struct SubBand
{
85 int qlog
; ///< log(qscale)/log[2^(1/6)]
90 int stride_line
; ///< Stride measured in lines, not pixels.
91 x_and_coeff
* x_coeff
;
92 struct SubBand
*parent
;
93 uint8_t state
[/*7*2*/ 7 + 512][32];
99 SubBand band
[MAX_DECOMPOSITIONS
][4];
102 int8_t hcoeff
[HTAPS_MAX
/2];
107 int8_t last_hcoeff
[HTAPS_MAX
/2];
111 typedef struct SnowContext
{
113 AVCodecContext
*avctx
;
118 VideoDSPContext vdsp
;
119 H264QpelContext h264qpel
;
120 MpegvideoEncDSPContext mpvencdsp
;
122 const AVFrame
*new_picture
;
123 AVFrame
*input_picture
; ///< new_picture with the internal linesizes
124 AVFrame
*current_picture
;
125 AVFrame
*last_picture
[MAX_REF_FRAMES
];
126 uint8_t *halfpel_plane
[MAX_REF_FRAMES
][4][4];
127 AVFrame
*mconly_picture
;
128 // uint8_t q_context[16];
129 uint8_t header_state
[32];
130 uint8_t block_state
[128 + 32*128];
134 int spatial_decomposition_type
;
135 int last_spatial_decomposition_type
;
136 int temporal_decomposition_type
;
137 int spatial_decomposition_count
;
138 int last_spatial_decomposition_count
;
139 int temporal_decomposition_count
;
142 int16_t (*ref_mvs
[MAX_REF_FRAMES
])[2];
143 uint32_t *ref_scores
[MAX_REF_FRAMES
];
144 DWTELEM
*spatial_dwt_buffer
;
145 DWTELEM
*temp_dwt_buffer
;
146 IDWTELEM
*spatial_idwt_buffer
;
147 IDWTELEM
*temp_idwt_buffer
;
152 int spatial_scalability
;
162 #define QBIAS_SHIFT 3
166 int last_block_max_depth
;
168 Plane plane
[MAX_PLANES
];
170 #define ME_CACHE_SIZE 1024
171 unsigned me_cache
[ME_CACHE_SIZE
];
172 unsigned me_cache_generation
;
177 MpegEncContext m
; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
180 uint8_t *emu_edge_buffer
;
184 extern const uint8_t * const ff_obmc_tab
[4];
185 extern uint8_t ff_qexp
[QROOT
];
186 extern int ff_scale_mv_ref
[MAX_REF_FRAMES
][MAX_REF_FRAMES
];
188 /* C bits used by mmx/sse2/altivec */
190 static av_always_inline
void snow_interleave_line_header(int * i
, int width
, IDWTELEM
* low
, IDWTELEM
* high
){
194 low
[(*i
)+1] = low
[((*i
)+1)>>1];
199 static av_always_inline
void snow_interleave_line_footer(int * i
, IDWTELEM
* low
, IDWTELEM
* high
){
200 for (; (*i
)>=0; (*i
)-=2){
201 low
[(*i
)+1] = high
[(*i
)>>1];
202 low
[*i
] = low
[(*i
)>>1];
206 static av_always_inline
void snow_horizontal_compose_lift_lead_out(int i
, IDWTELEM
* dst
, IDWTELEM
* src
, IDWTELEM
* ref
, int width
, int w
, int lift_high
, int mul
, int add
, int shift
){
208 dst
[i
] = src
[i
] - ((mul
* (ref
[i
] + ref
[i
+ 1]) + add
) >> shift
);
211 if((width
^lift_high
)&1){
212 dst
[w
] = src
[w
] - ((mul
* 2 * ref
[w
] + add
) >> shift
);
216 static av_always_inline
void snow_horizontal_compose_liftS_lead_out(int i
, IDWTELEM
* dst
, IDWTELEM
* src
, IDWTELEM
* ref
, int width
, int w
){
218 dst
[i
] = src
[i
] + ((ref
[i
] + ref
[(i
+1)]+W_BO
+ 4 * src
[i
]) >> W_BS
);
222 dst
[w
] = src
[w
] + ((2 * ref
[w
] + W_BO
+ 4 * src
[w
]) >> W_BS
);
228 int ff_snow_common_init(AVCodecContext
*avctx
);
229 int ff_snow_common_init_after_header(AVCodecContext
*avctx
);
230 void ff_snow_common_end(SnowContext
*s
);
231 void ff_snow_release_buffer(AVCodecContext
*avctx
);
232 void ff_snow_reset_contexts(SnowContext
*s
);
233 int ff_snow_alloc_blocks(SnowContext
*s
);
234 int ff_snow_frame_start(SnowContext
*s
);
235 void ff_snow_pred_block(SnowContext
*s
, uint8_t *dst
, uint8_t *tmp
, ptrdiff_t stride
,
236 int sx
, int sy
, int b_w
, int b_h
, const BlockNode
*block
,
237 int plane_index
, int w
, int h
);
238 int ff_snow_get_buffer(SnowContext
*s
, AVFrame
*frame
);
239 /* common inline functions */
240 //XXX doublecheck all of them should stay inlined
242 static inline void snow_set_blocks(SnowContext
*s
, int level
, int x
, int y
, int l
, int cb
, int cr
, int mx
, int my
, int ref
, int type
){
243 const int w
= s
->b_width
<< s
->block_max_depth
;
244 const int rem_depth
= s
->block_max_depth
- level
;
245 const int index
= (x
+ y
*w
) << rem_depth
;
246 const int block_w
= 1<<rem_depth
;
259 for(j
=0; j
<block_w
; j
++){
260 for(i
=0; i
<block_w
; i
++){
261 s
->block
[index
+ i
+ j
*w
]= block
;
266 static inline void pred_mv(SnowContext
*s
, int *mx
, int *my
, int ref
,
267 const BlockNode
*left
, const BlockNode
*top
, const BlockNode
*tr
){
268 if(s
->ref_frames
== 1){
269 *mx
= mid_pred(left
->mx
, top
->mx
, tr
->mx
);
270 *my
= mid_pred(left
->my
, top
->my
, tr
->my
);
272 const int *scale
= ff_scale_mv_ref
[ref
];
273 *mx
= mid_pred((left
->mx
* scale
[left
->ref
] + 128) >>8,
274 (top
->mx
* scale
[top
->ref
] + 128) >>8,
275 (tr
->mx
* scale
[tr
->ref
] + 128) >>8);
276 *my
= mid_pred((left
->my
* scale
[left
->ref
] + 128) >>8,
277 (top
->my
* scale
[top
->ref
] + 128) >>8,
278 (tr
->my
* scale
[tr
->ref
] + 128) >>8);
282 static av_always_inline
int same_block(BlockNode
*a
, BlockNode
*b
){
283 if((a
->type
&BLOCK_INTRA
) && (b
->type
&BLOCK_INTRA
)){
284 return !((a
->color
[0] - b
->color
[0]) | (a
->color
[1] - b
->color
[1]) | (a
->color
[2] - b
->color
[2]));
286 return !((a
->mx
- b
->mx
) | (a
->my
- b
->my
) | (a
->ref
- b
->ref
) | ((a
->type
^ b
->type
)&BLOCK_INTRA
));
290 //FIXME name cleanup (b_w, block_w, b_width stuff)
291 //XXX should we really inline it?
292 static av_always_inline
void add_yblock(SnowContext
*s
, int sliced
, slice_buffer
*sb
, IDWTELEM
*dst
, uint8_t *dst8
, const uint8_t *obmc
, int src_x
, int src_y
, int b_w
, int b_h
, int w
, int h
, int dst_stride
, int src_stride
, int obmc_stride
, int b_x
, int b_y
, int add
, int offset_dst
, int plane_index
){
293 const int b_width
= s
->b_width
<< s
->block_max_depth
;
294 const int b_height
= s
->b_height
<< s
->block_max_depth
;
295 const int b_stride
= b_width
;
296 BlockNode
*lt
= &s
->block
[b_x
+ b_y
*b_stride
];
298 BlockNode
*lb
= lt
+b_stride
;
301 int tmp_step
= src_stride
>= 7*MB_SIZE
? MB_SIZE
: MB_SIZE
*src_stride
;
302 uint8_t *tmp
= s
->scratchbuf
;
309 }else if(b_x
+ 1 >= b_width
){
316 }else if(b_y
+ 1 >= b_height
){
321 if(src_x
<0){ //FIXME merge with prev & always round internal width up to *16
324 if(!sliced
&& !offset_dst
)
332 obmc
-= src_y
*obmc_stride
;
334 if(!sliced
&& !offset_dst
)
335 dst
-= src_y
*dst_stride
;
342 if(b_w
<=0 || b_h
<=0) return;
344 av_assert2(src_stride
> 2*MB_SIZE
+ 5);
346 if(!sliced
&& offset_dst
)
347 dst
+= src_x
+ src_y
*dst_stride
;
348 dst8
+= src_x
+ src_y
*src_stride
;
349 // src += src_x + src_y*src_stride;
351 ptmp
= tmp
+ 3*tmp_step
;
354 ff_snow_pred_block(s
, block
[0], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, lt
, plane_index
, w
, h
);
356 if(same_block(lt
, rt
)){
361 ff_snow_pred_block(s
, block
[1], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, rt
, plane_index
, w
, h
);
364 if(same_block(lt
, lb
)){
366 }else if(same_block(rt
, lb
)){
371 ff_snow_pred_block(s
, block
[2], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, lb
, plane_index
, w
, h
);
374 if(same_block(lt
, rb
) ){
376 }else if(same_block(rt
, rb
)){
378 }else if(same_block(lb
, rb
)){
382 ff_snow_pred_block(s
, block
[3], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, rb
, plane_index
, w
, h
);
385 s
->dwt
.inner_add_yblock(obmc
, obmc_stride
, block
, b_w
, b_h
, src_x
,src_y
, src_stride
, sb
, add
, dst8
);
387 for(y
=0; y
<b_h
; y
++){
388 //FIXME ugly misuse of obmc_stride
389 const uint8_t *obmc1
= obmc
+ y
*obmc_stride
;
390 const uint8_t *obmc2
= obmc1
+ (obmc_stride
>>1);
391 const uint8_t *obmc3
= obmc1
+ obmc_stride
*(obmc_stride
>>1);
392 const uint8_t *obmc4
= obmc3
+ (obmc_stride
>>1);
393 for(x
=0; x
<b_w
; x
++){
394 int v
= obmc1
[x
] * block
[3][x
+ y
*src_stride
]
395 +obmc2
[x
] * block
[2][x
+ y
*src_stride
]
396 +obmc3
[x
] * block
[1][x
+ y
*src_stride
]
397 +obmc4
[x
] * block
[0][x
+ y
*src_stride
];
399 v
<<= 8 - LOG2_OBMC_MAX
;
404 v
+= dst
[x
+ y
*dst_stride
];
405 v
= (v
+ (1<<(FRAC_BITS
-1))) >> FRAC_BITS
;
406 if(v
&(~255)) v
= ~(v
>>31);
407 dst8
[x
+ y
*src_stride
] = v
;
409 dst
[x
+ y
*dst_stride
] -= v
;
416 static av_always_inline
void predict_slice(SnowContext
*s
, IDWTELEM
*buf
, int plane_index
, int add
, int mb_y
){
417 Plane
*p
= &s
->plane
[plane_index
];
418 const int mb_w
= s
->b_width
<< s
->block_max_depth
;
419 const int mb_h
= s
->b_height
<< s
->block_max_depth
;
421 int block_size
= MB_SIZE
>> s
->block_max_depth
;
422 int block_w
= plane_index
? block_size
>>s
->chroma_h_shift
: block_size
;
423 int block_h
= plane_index
? block_size
>>s
->chroma_v_shift
: block_size
;
424 const uint8_t *obmc
= plane_index
? ff_obmc_tab
[s
->block_max_depth
+s
->chroma_h_shift
] : ff_obmc_tab
[s
->block_max_depth
];
425 const int obmc_stride
= plane_index
? (2*block_size
)>>s
->chroma_h_shift
: 2*block_size
;
426 int ref_stride
= s
->current_picture
->linesize
[plane_index
];
427 uint8_t *dst8
= s
->current_picture
->data
[plane_index
];
430 av_assert2(s
->chroma_h_shift
== s
->chroma_v_shift
); // obmc params assume squares
431 if(s
->keyframe
|| (s
->avctx
->debug
&512)){
436 for(y
=block_h
*mb_y
; y
<FFMIN(h
,block_h
*(mb_y
+1)); y
++){
438 int v
= buf
[x
+ y
*w
] + (128<<FRAC_BITS
) + (1<<(FRAC_BITS
-1));
440 if(v
&(~255)) v
= ~(v
>>31);
441 dst8
[x
+ y
*ref_stride
]= v
;
445 for(y
=block_h
*mb_y
; y
<FFMIN(h
,block_h
*(mb_y
+1)); y
++){
447 buf
[x
+ y
*w
]-= 128<<FRAC_BITS
;
455 for(mb_x
=0; mb_x
<=mb_w
; mb_x
++){
456 add_yblock(s
, 0, NULL
, buf
, dst8
, obmc
,
457 block_w
*mb_x
- block_w
/2,
458 block_h
*mb_y
- block_h
/2,
461 w
, ref_stride
, obmc_stride
,
463 add
, 1, plane_index
);
467 static av_always_inline
void predict_plane(SnowContext
*s
, IDWTELEM
*buf
, int plane_index
, int add
){
468 const int mb_h
= s
->b_height
<< s
->block_max_depth
;
470 for(mb_y
=0; mb_y
<=mb_h
; mb_y
++)
471 predict_slice(s
, buf
, plane_index
, add
, mb_y
);
474 static inline void set_blocks(SnowContext
*s
, int level
, int x
, int y
, int l
, int cb
, int cr
, int mx
, int my
, int ref
, int type
){
475 const int w
= s
->b_width
<< s
->block_max_depth
;
476 const int rem_depth
= s
->block_max_depth
- level
;
477 const int index
= (x
+ y
*w
) << rem_depth
;
478 const int block_w
= 1<<rem_depth
;
479 const int block_h
= 1<<rem_depth
; //FIXME "w!=h"
492 for(j
=0; j
<block_h
; j
++){
493 for(i
=0; i
<block_w
; i
++){
494 s
->block
[index
+ i
+ j
*w
]= block
;
499 static inline void init_ref(MotionEstContext
*c
, uint8_t *src
[3], uint8_t *ref
[3], uint8_t *ref2
[3], int x
, int y
, int ref_index
){
500 SnowContext
*s
= c
->avctx
->priv_data
;
501 const int offset
[3]= {
503 ((y
*c
->uvstride
+ x
)>>s
->chroma_h_shift
),
504 ((y
*c
->uvstride
+ x
)>>s
->chroma_h_shift
),
508 c
->src
[0][i
]= src
[i
];
509 c
->ref
[0][i
]= ref
[i
] + offset
[i
];
511 av_assert2(!ref_index
);
515 /* bitstream functions */
517 extern const int8_t ff_quant3bA
[256];
519 #define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
521 static inline void put_symbol(RangeCoder
*c
, uint8_t *state
, int v
, int is_signed
){
525 const int a
= FFABS(v
);
526 const int e
= av_log2(a
);
527 const int el
= FFMIN(e
, 10);
528 put_rac(c
, state
+0, 0);
531 put_rac(c
, state
+1+i
, 1); //1..10
534 put_rac(c
, state
+1+9, 1); //1..10
536 put_rac(c
, state
+1+FFMIN(i
,9), 0);
538 for(i
=e
-1; i
>=el
; i
--){
539 put_rac(c
, state
+22+9, (a
>>i
)&1); //22..31
542 put_rac(c
, state
+22+i
, (a
>>i
)&1); //22..31
546 put_rac(c
, state
+11 + el
, v
< 0); //11..21
548 put_rac(c
, state
+0, 1);
552 static inline int get_symbol(RangeCoder
*c
, uint8_t *state
, int is_signed
){
553 if(get_rac(c
, state
+0))
558 while(get_rac(c
, state
+1 + FFMIN(e
,9))){ //1..10
563 for(i
=e
-1; i
>=0; i
--){
564 a
+= a
+ get_rac(c
, state
+22 + FFMIN(i
,9)); //22..31
567 e
= -(is_signed
&& get_rac(c
, state
+11 + FFMIN(e
,10))); //11..21
572 static inline void put_symbol2(RangeCoder
*c
, uint8_t *state
, int v
, int log2
){
574 int r
= log2
>=0 ? 1<<log2
: 1;
577 av_assert2(log2
>=-4);
580 put_rac(c
, state
+4+log2
, 1);
585 put_rac(c
, state
+4+log2
, 0);
587 for(i
=log2
-1; i
>=0; i
--){
588 put_rac(c
, state
+31-i
, (v
>>i
)&1);
592 static inline int get_symbol2(RangeCoder
*c
, uint8_t *state
, int log2
){
594 int r
= log2
>=0 ? 1<<log2
: 1;
597 av_assert2(log2
>=-4);
599 while(log2
<28 && get_rac(c
, state
+4+log2
)){
605 for(i
=log2
-1; i
>=0; i
--){
606 v
+= get_rac(c
, state
+31-i
)<<i
;
612 static inline void unpack_coeffs(SnowContext
*s
, SubBand
*b
, SubBand
* parent
, int orientation
){
613 const int w
= b
->width
;
614 const int h
= b
->height
;
618 x_and_coeff
*xc
= b
->x_coeff
;
619 x_and_coeff
*prev_xc
= NULL
;
620 x_and_coeff
*prev2_xc
= xc
;
621 x_and_coeff
*parent_xc
= parent
? parent
->x_coeff
: NULL
;
622 x_and_coeff
*prev_parent_xc
= parent_xc
;
624 runs
= get_symbol2(&s
->c
, b
->state
[30], 0);
625 if(runs
-- > 0) run
= get_symbol2(&s
->c
, b
->state
[1], 3);
632 if(y
&& prev_xc
->x
== 0){
644 if(prev_xc
->x
== x
+ 1)
650 if(x
>>1 > parent_xc
->x
){
653 if(x
>>1 == parent_xc
->x
){
657 if(/*ll|*/l
|lt
|t
|rt
|p
){
658 int context
= av_log2(/*FFABS(ll) + */3*(l
>>1) + (lt
>>1) + (t
&~1) + (rt
>>1) + (p
>>1));
660 v
=get_rac(&s
->c
, &b
->state
[0][context
]);
662 v
= 2*(get_symbol2(&s
->c
, b
->state
[context
+ 2], context
-4) + 1);
663 v
+=get_rac(&s
->c
, &b
->state
[0][16 + 1 + 3 + ff_quant3bA
[l
&0xFF] + 3*ff_quant3bA
[t
&0xFF]]);
664 if ((uint16_t)v
!= v
) {
665 av_log(s
->avctx
, AV_LOG_ERROR
, "Coefficient damaged\n");
673 if(runs
-- > 0) run
= get_symbol2(&s
->c
, b
->state
[1], 3);
675 v
= 2*(get_symbol2(&s
->c
, b
->state
[0 + 2], 0-4) + 1);
676 v
+=get_rac(&s
->c
, &b
->state
[0][16 + 1 + 3]);
677 if ((uint16_t)v
!= v
) {
678 av_log(s
->avctx
, AV_LOG_ERROR
, "Coefficient damaged\n");
688 av_assert2(run
>= 0);
689 if(y
) max_run
= FFMIN(run
, prev_xc
->x
- x
- 2);
690 else max_run
= FFMIN(run
, w
-x
-1);
692 max_run
= FFMIN(max_run
, 2*parent_xc
->x
- x
- 1);
693 av_assert2(max_run
>= 0 && max_run
<= run
);
700 (xc
++)->x
= w
+1; //end marker
706 while(parent_xc
->x
!= parent
->width
+1)
709 prev_parent_xc
= parent_xc
;
711 parent_xc
= prev_parent_xc
;
716 (xc
++)->x
= w
+1; //end marker
719 #endif /* AVCODEC_SNOW_H */