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"
32 #include "mpegvideo.h"
39 #define QROOT (1<<QSHIFT)
40 #define LOSSLESS_QLOG -128
42 #define MAX_REF_FRAMES 8
44 #define LOG2_OBMC_MAX 8
45 #define OBMC_MAX (1<<(LOG2_OBMC_MAX))
46 typedef struct BlockNode
{
52 //#define TYPE_SPLIT 1
55 //#define TYPE_NOCOLOR 4
56 uint8_t level
; //FIXME merge into type?
59 static const BlockNode null_block
= { //FIXME add border maybe
60 .color
= {128,128,128},
68 #define LOG2_MB_SIZE 4
69 #define MB_SIZE (1<<LOG2_MB_SIZE)
70 #define ENCODER_EXTRA_BITS 4
73 typedef struct x_and_coeff
{
78 typedef struct SubBand
{
83 int qlog
; ///< log(qscale)/log[2^(1/6)]
88 int stride_line
; ///< Stride measured in lines, not pixels.
89 x_and_coeff
* x_coeff
;
90 struct SubBand
*parent
;
91 uint8_t state
[/*7*2*/ 7 + 512][32];
97 SubBand band
[MAX_DECOMPOSITIONS
][4];
100 int8_t hcoeff
[HTAPS_MAX
/2];
105 int8_t last_hcoeff
[HTAPS_MAX
/2];
109 typedef struct SnowContext
{
111 AVCodecContext
*avctx
;
116 VideoDSPContext vdsp
;
117 H264QpelContext h264qpel
;
118 MpegvideoEncDSPContext mpvencdsp
;
120 const AVFrame
*new_picture
;
121 AVFrame
*input_picture
; ///< new_picture with the internal linesizes
122 AVFrame
*current_picture
;
123 AVFrame
*last_picture
[MAX_REF_FRAMES
];
124 uint8_t *halfpel_plane
[MAX_REF_FRAMES
][4][4];
125 AVFrame
*mconly_picture
;
126 // uint8_t q_context[16];
127 uint8_t header_state
[32];
128 uint8_t block_state
[128 + 32*128];
132 int spatial_decomposition_type
;
133 int last_spatial_decomposition_type
;
134 int temporal_decomposition_type
;
135 int spatial_decomposition_count
;
136 int last_spatial_decomposition_count
;
137 int temporal_decomposition_count
;
140 int16_t (*ref_mvs
[MAX_REF_FRAMES
])[2];
141 uint32_t *ref_scores
[MAX_REF_FRAMES
];
142 DWTELEM
*spatial_dwt_buffer
;
143 DWTELEM
*temp_dwt_buffer
;
144 IDWTELEM
*spatial_idwt_buffer
;
145 IDWTELEM
*temp_idwt_buffer
;
150 int spatial_scalability
;
160 #define QBIAS_SHIFT 3
164 int last_block_max_depth
;
166 Plane plane
[MAX_PLANES
];
168 #define ME_CACHE_SIZE 1024
169 unsigned me_cache
[ME_CACHE_SIZE
];
170 unsigned me_cache_generation
;
175 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)
178 uint8_t *emu_edge_buffer
;
182 extern const uint8_t * const ff_obmc_tab
[4];
183 extern uint8_t ff_qexp
[QROOT
];
184 extern int ff_scale_mv_ref
[MAX_REF_FRAMES
][MAX_REF_FRAMES
];
186 /* C bits used by mmx/sse2/altivec */
188 static av_always_inline
void snow_interleave_line_header(int * i
, int width
, IDWTELEM
* low
, IDWTELEM
* high
){
192 low
[(*i
)+1] = low
[((*i
)+1)>>1];
197 static av_always_inline
void snow_interleave_line_footer(int * i
, IDWTELEM
* low
, IDWTELEM
* high
){
198 for (; (*i
)>=0; (*i
)-=2){
199 low
[(*i
)+1] = high
[(*i
)>>1];
200 low
[*i
] = low
[(*i
)>>1];
204 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
){
206 dst
[i
] = src
[i
] - ((mul
* (ref
[i
] + ref
[i
+ 1]) + add
) >> shift
);
209 if((width
^lift_high
)&1){
210 dst
[w
] = src
[w
] - ((mul
* 2 * ref
[w
] + add
) >> shift
);
214 static av_always_inline
void snow_horizontal_compose_liftS_lead_out(int i
, IDWTELEM
* dst
, IDWTELEM
* src
, IDWTELEM
* ref
, int width
, int w
){
216 dst
[i
] = src
[i
] + ((ref
[i
] + ref
[(i
+1)]+W_BO
+ 4 * src
[i
]) >> W_BS
);
220 dst
[w
] = src
[w
] + ((2 * ref
[w
] + W_BO
+ 4 * src
[w
]) >> W_BS
);
226 int ff_snow_common_init(AVCodecContext
*avctx
);
227 int ff_snow_common_init_after_header(AVCodecContext
*avctx
);
228 void ff_snow_common_end(SnowContext
*s
);
229 void ff_snow_release_buffer(AVCodecContext
*avctx
);
230 void ff_snow_reset_contexts(SnowContext
*s
);
231 int ff_snow_alloc_blocks(SnowContext
*s
);
232 int ff_snow_frame_start(SnowContext
*s
);
233 void ff_snow_pred_block(SnowContext
*s
, uint8_t *dst
, uint8_t *tmp
, ptrdiff_t stride
,
234 int sx
, int sy
, int b_w
, int b_h
, BlockNode
*block
,
235 int plane_index
, int w
, int h
);
236 int ff_snow_get_buffer(SnowContext
*s
, AVFrame
*frame
);
237 /* common inline functions */
238 //XXX doublecheck all of them should stay inlined
240 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
){
241 const int w
= s
->b_width
<< s
->block_max_depth
;
242 const int rem_depth
= s
->block_max_depth
- level
;
243 const int index
= (x
+ y
*w
) << rem_depth
;
244 const int block_w
= 1<<rem_depth
;
257 for(j
=0; j
<block_w
; j
++){
258 for(i
=0; i
<block_w
; i
++){
259 s
->block
[index
+ i
+ j
*w
]= block
;
264 static inline void pred_mv(SnowContext
*s
, int *mx
, int *my
, int ref
,
265 const BlockNode
*left
, const BlockNode
*top
, const BlockNode
*tr
){
266 if(s
->ref_frames
== 1){
267 *mx
= mid_pred(left
->mx
, top
->mx
, tr
->mx
);
268 *my
= mid_pred(left
->my
, top
->my
, tr
->my
);
270 const int *scale
= ff_scale_mv_ref
[ref
];
271 *mx
= mid_pred((left
->mx
* scale
[left
->ref
] + 128) >>8,
272 (top
->mx
* scale
[top
->ref
] + 128) >>8,
273 (tr
->mx
* scale
[tr
->ref
] + 128) >>8);
274 *my
= mid_pred((left
->my
* scale
[left
->ref
] + 128) >>8,
275 (top
->my
* scale
[top
->ref
] + 128) >>8,
276 (tr
->my
* scale
[tr
->ref
] + 128) >>8);
280 static av_always_inline
int same_block(BlockNode
*a
, BlockNode
*b
){
281 if((a
->type
&BLOCK_INTRA
) && (b
->type
&BLOCK_INTRA
)){
282 return !((a
->color
[0] - b
->color
[0]) | (a
->color
[1] - b
->color
[1]) | (a
->color
[2] - b
->color
[2]));
284 return !((a
->mx
- b
->mx
) | (a
->my
- b
->my
) | (a
->ref
- b
->ref
) | ((a
->type
^ b
->type
)&BLOCK_INTRA
));
288 //FIXME name cleanup (b_w, block_w, b_width stuff)
289 //XXX should we really inline it?
290 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
){
291 const int b_width
= s
->b_width
<< s
->block_max_depth
;
292 const int b_height
= s
->b_height
<< s
->block_max_depth
;
293 const int b_stride
= b_width
;
294 BlockNode
*lt
= &s
->block
[b_x
+ b_y
*b_stride
];
296 BlockNode
*lb
= lt
+b_stride
;
299 int tmp_step
= src_stride
>= 7*MB_SIZE
? MB_SIZE
: MB_SIZE
*src_stride
;
300 uint8_t *tmp
= s
->scratchbuf
;
307 }else if(b_x
+ 1 >= b_width
){
314 }else if(b_y
+ 1 >= b_height
){
319 if(src_x
<0){ //FIXME merge with prev & always round internal width up to *16
322 if(!sliced
&& !offset_dst
)
330 obmc
-= src_y
*obmc_stride
;
332 if(!sliced
&& !offset_dst
)
333 dst
-= src_y
*dst_stride
;
340 if(b_w
<=0 || b_h
<=0) return;
342 av_assert2(src_stride
> 2*MB_SIZE
+ 5);
344 if(!sliced
&& offset_dst
)
345 dst
+= src_x
+ src_y
*dst_stride
;
346 dst8
+= src_x
+ src_y
*src_stride
;
347 // src += src_x + src_y*src_stride;
349 ptmp
= tmp
+ 3*tmp_step
;
352 ff_snow_pred_block(s
, block
[0], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, lt
, plane_index
, w
, h
);
354 if(same_block(lt
, rt
)){
359 ff_snow_pred_block(s
, block
[1], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, rt
, plane_index
, w
, h
);
362 if(same_block(lt
, lb
)){
364 }else if(same_block(rt
, lb
)){
369 ff_snow_pred_block(s
, block
[2], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, lb
, plane_index
, w
, h
);
372 if(same_block(lt
, rb
) ){
374 }else if(same_block(rt
, rb
)){
376 }else if(same_block(lb
, rb
)){
380 ff_snow_pred_block(s
, block
[3], tmp
, src_stride
, src_x
, src_y
, b_w
, b_h
, rb
, plane_index
, w
, h
);
383 s
->dwt
.inner_add_yblock(obmc
, obmc_stride
, block
, b_w
, b_h
, src_x
,src_y
, src_stride
, sb
, add
, dst8
);
385 for(y
=0; y
<b_h
; y
++){
386 //FIXME ugly misuse of obmc_stride
387 const uint8_t *obmc1
= obmc
+ y
*obmc_stride
;
388 const uint8_t *obmc2
= obmc1
+ (obmc_stride
>>1);
389 const uint8_t *obmc3
= obmc1
+ obmc_stride
*(obmc_stride
>>1);
390 const uint8_t *obmc4
= obmc3
+ (obmc_stride
>>1);
391 for(x
=0; x
<b_w
; x
++){
392 int v
= obmc1
[x
] * block
[3][x
+ y
*src_stride
]
393 +obmc2
[x
] * block
[2][x
+ y
*src_stride
]
394 +obmc3
[x
] * block
[1][x
+ y
*src_stride
]
395 +obmc4
[x
] * block
[0][x
+ y
*src_stride
];
397 v
<<= 8 - LOG2_OBMC_MAX
;
402 v
+= dst
[x
+ y
*dst_stride
];
403 v
= (v
+ (1<<(FRAC_BITS
-1))) >> FRAC_BITS
;
404 if(v
&(~255)) v
= ~(v
>>31);
405 dst8
[x
+ y
*src_stride
] = v
;
407 dst
[x
+ y
*dst_stride
] -= v
;
414 static av_always_inline
void predict_slice(SnowContext
*s
, IDWTELEM
*buf
, int plane_index
, int add
, int mb_y
){
415 Plane
*p
= &s
->plane
[plane_index
];
416 const int mb_w
= s
->b_width
<< s
->block_max_depth
;
417 const int mb_h
= s
->b_height
<< s
->block_max_depth
;
419 int block_size
= MB_SIZE
>> s
->block_max_depth
;
420 int block_w
= plane_index
? block_size
>>s
->chroma_h_shift
: block_size
;
421 int block_h
= plane_index
? block_size
>>s
->chroma_v_shift
: block_size
;
422 const uint8_t *obmc
= plane_index
? ff_obmc_tab
[s
->block_max_depth
+s
->chroma_h_shift
] : ff_obmc_tab
[s
->block_max_depth
];
423 const int obmc_stride
= plane_index
? (2*block_size
)>>s
->chroma_h_shift
: 2*block_size
;
424 int ref_stride
= s
->current_picture
->linesize
[plane_index
];
425 uint8_t *dst8
= s
->current_picture
->data
[plane_index
];
428 av_assert2(s
->chroma_h_shift
== s
->chroma_v_shift
); // obmc params assume squares
429 if(s
->keyframe
|| (s
->avctx
->debug
&512)){
434 for(y
=block_h
*mb_y
; y
<FFMIN(h
,block_h
*(mb_y
+1)); y
++){
436 int v
= buf
[x
+ y
*w
] + (128<<FRAC_BITS
) + (1<<(FRAC_BITS
-1));
438 if(v
&(~255)) v
= ~(v
>>31);
439 dst8
[x
+ y
*ref_stride
]= v
;
443 for(y
=block_h
*mb_y
; y
<FFMIN(h
,block_h
*(mb_y
+1)); y
++){
445 buf
[x
+ y
*w
]-= 128<<FRAC_BITS
;
453 for(mb_x
=0; mb_x
<=mb_w
; mb_x
++){
454 add_yblock(s
, 0, NULL
, buf
, dst8
, obmc
,
455 block_w
*mb_x
- block_w
/2,
456 block_h
*mb_y
- block_h
/2,
459 w
, ref_stride
, obmc_stride
,
461 add
, 1, plane_index
);
465 static av_always_inline
void predict_plane(SnowContext
*s
, IDWTELEM
*buf
, int plane_index
, int add
){
466 const int mb_h
= s
->b_height
<< s
->block_max_depth
;
468 for(mb_y
=0; mb_y
<=mb_h
; mb_y
++)
469 predict_slice(s
, buf
, plane_index
, add
, mb_y
);
472 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
){
473 const int w
= s
->b_width
<< s
->block_max_depth
;
474 const int rem_depth
= s
->block_max_depth
- level
;
475 const int index
= (x
+ y
*w
) << rem_depth
;
476 const int block_w
= 1<<rem_depth
;
477 const int block_h
= 1<<rem_depth
; //FIXME "w!=h"
490 for(j
=0; j
<block_h
; j
++){
491 for(i
=0; i
<block_w
; i
++){
492 s
->block
[index
+ i
+ j
*w
]= block
;
497 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
){
498 SnowContext
*s
= c
->avctx
->priv_data
;
499 const int offset
[3]= {
501 ((y
*c
->uvstride
+ x
)>>s
->chroma_h_shift
),
502 ((y
*c
->uvstride
+ x
)>>s
->chroma_h_shift
),
506 c
->src
[0][i
]= src
[i
];
507 c
->ref
[0][i
]= ref
[i
] + offset
[i
];
509 av_assert2(!ref_index
);
513 /* bitstream functions */
515 extern const int8_t ff_quant3bA
[256];
517 #define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
519 static inline void put_symbol(RangeCoder
*c
, uint8_t *state
, int v
, int is_signed
){
523 const int a
= FFABS(v
);
524 const int e
= av_log2(a
);
525 const int el
= FFMIN(e
, 10);
526 put_rac(c
, state
+0, 0);
529 put_rac(c
, state
+1+i
, 1); //1..10
532 put_rac(c
, state
+1+9, 1); //1..10
534 put_rac(c
, state
+1+FFMIN(i
,9), 0);
536 for(i
=e
-1; i
>=el
; i
--){
537 put_rac(c
, state
+22+9, (a
>>i
)&1); //22..31
540 put_rac(c
, state
+22+i
, (a
>>i
)&1); //22..31
544 put_rac(c
, state
+11 + el
, v
< 0); //11..21
546 put_rac(c
, state
+0, 1);
550 static inline int get_symbol(RangeCoder
*c
, uint8_t *state
, int is_signed
){
551 if(get_rac(c
, state
+0))
556 while(get_rac(c
, state
+1 + FFMIN(e
,9))){ //1..10
561 for(i
=e
-1; i
>=0; i
--){
562 a
+= a
+ get_rac(c
, state
+22 + FFMIN(i
,9)); //22..31
565 e
= -(is_signed
&& get_rac(c
, state
+11 + FFMIN(e
,10))); //11..21
570 static inline void put_symbol2(RangeCoder
*c
, uint8_t *state
, int v
, int log2
){
572 int r
= log2
>=0 ? 1<<log2
: 1;
575 av_assert2(log2
>=-4);
578 put_rac(c
, state
+4+log2
, 1);
583 put_rac(c
, state
+4+log2
, 0);
585 for(i
=log2
-1; i
>=0; i
--){
586 put_rac(c
, state
+31-i
, (v
>>i
)&1);
590 static inline int get_symbol2(RangeCoder
*c
, uint8_t *state
, int log2
){
592 int r
= log2
>=0 ? 1<<log2
: 1;
595 av_assert2(log2
>=-4);
597 while(log2
<28 && get_rac(c
, state
+4+log2
)){
603 for(i
=log2
-1; i
>=0; i
--){
604 v
+= get_rac(c
, state
+31-i
)<<i
;
610 static inline void unpack_coeffs(SnowContext
*s
, SubBand
*b
, SubBand
* parent
, int orientation
){
611 const int w
= b
->width
;
612 const int h
= b
->height
;
616 x_and_coeff
*xc
= b
->x_coeff
;
617 x_and_coeff
*prev_xc
= NULL
;
618 x_and_coeff
*prev2_xc
= xc
;
619 x_and_coeff
*parent_xc
= parent
? parent
->x_coeff
: NULL
;
620 x_and_coeff
*prev_parent_xc
= parent_xc
;
622 runs
= get_symbol2(&s
->c
, b
->state
[30], 0);
623 if(runs
-- > 0) run
= get_symbol2(&s
->c
, b
->state
[1], 3);
630 if(y
&& prev_xc
->x
== 0){
642 if(prev_xc
->x
== x
+ 1)
648 if(x
>>1 > parent_xc
->x
){
651 if(x
>>1 == parent_xc
->x
){
655 if(/*ll|*/l
|lt
|t
|rt
|p
){
656 int context
= av_log2(/*FFABS(ll) + */3*(l
>>1) + (lt
>>1) + (t
&~1) + (rt
>>1) + (p
>>1));
658 v
=get_rac(&s
->c
, &b
->state
[0][context
]);
660 v
= 2*(get_symbol2(&s
->c
, b
->state
[context
+ 2], context
-4) + 1);
661 v
+=get_rac(&s
->c
, &b
->state
[0][16 + 1 + 3 + ff_quant3bA
[l
&0xFF] + 3*ff_quant3bA
[t
&0xFF]]);
662 if ((uint16_t)v
!= v
) {
663 av_log(s
->avctx
, AV_LOG_ERROR
, "Coefficient damaged\n");
671 if(runs
-- > 0) run
= get_symbol2(&s
->c
, b
->state
[1], 3);
673 v
= 2*(get_symbol2(&s
->c
, b
->state
[0 + 2], 0-4) + 1);
674 v
+=get_rac(&s
->c
, &b
->state
[0][16 + 1 + 3]);
675 if ((uint16_t)v
!= v
) {
676 av_log(s
->avctx
, AV_LOG_ERROR
, "Coefficient damaged\n");
686 av_assert2(run
>= 0);
687 if(y
) max_run
= FFMIN(run
, prev_xc
->x
- x
- 2);
688 else max_run
= FFMIN(run
, w
-x
-1);
690 max_run
= FFMIN(max_run
, 2*parent_xc
->x
- x
- 1);
691 av_assert2(max_run
>= 0 && max_run
<= run
);
698 (xc
++)->x
= w
+1; //end marker
704 while(parent_xc
->x
!= parent
->width
+1)
707 prev_parent_xc
= parent_xc
;
709 parent_xc
= prev_parent_xc
;
714 (xc
++)->x
= w
+1; //end marker
717 #endif /* AVCODEC_SNOW_H */