@ -314,12 +314,13 @@ static void chroma_dc_dct_c(DCTELEM *block){
static inline void mc_dir_part ( H264Context * h , Picture * pic , int n , int square , int chroma_height , int delta , int list ,
uint8_t * dest_y , uint8_t * dest_cb , uint8_t * dest_cr ,
int src_x_offset , int src_y_offset ,
qpel_mc_func * qpix_op , h264_chroma_mc_func chroma_op ) {
qpel_mc_func * qpix_op , h264_chroma_mc_func chroma_op ,
int pixel_shift ) {
MpegEncContext * const s = & h - > s ;
const int mx = h - > mv_cache [ list ] [ scan8 [ n ] ] [ 0 ] + src_x_offset * 8 ;
int my = h - > mv_cache [ list ] [ scan8 [ n ] ] [ 1 ] + src_y_offset * 8 ;
const int luma_xy = ( mx & 3 ) + ( ( my & 3 ) < < 2 ) ;
uint8_t * src_y = pic - > data [ 0 ] + ( mx > > 2 ) + ( my > > 2 ) * h - > mb_linesize ;
uint8_t * src_y = pic - > data [ 0 ] + ( ( mx > > 2 ) < < pixel_shift ) + ( my > > 2 ) * h - > mb_linesize ;
uint8_t * src_cb , * src_cr ;
int extra_width = h - > emu_edge_width ;
int extra_height = h - > emu_edge_height ;
@ -336,8 +337,8 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
| | full_my < 0 - extra_height
| | full_mx + 16 /*FIXME*/ > pic_width + extra_width
| | full_my + 16 /*FIXME*/ > pic_height + extra_height ) {
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer , src_y - 2 - 2 * h - > mb_linesize , h - > mb_linesize , 16 + 5 , 16 + 5 /*FIXME*/ , full_mx - 2 , full_my - 2 , pic_width , pic_height ) ;
src_y = s - > edge_emu_buffer + 2 + 2 * h - > mb_linesize ;
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer , src_y - ( 2 < < pixel_shift ) - 2 * h - > mb_linesize , h - > mb_linesize , 16 + 5 , 16 + 5 /*FIXME*/ , full_mx - 2 , full_my - 2 , pic_width , pic_height ) ;
src_y = s - > edge_emu_buffer + ( 2 < < pixel_shift ) + 2 * h - > mb_linesize ;
emu = 1 ;
}
@ -353,8 +354,8 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
my + = 2 * ( ( s - > mb_y & 1 ) - ( pic - > reference - 1 ) ) ;
emu | = ( my > > 3 ) < 0 | | ( my > > 3 ) + 8 > = ( pic_height > > 1 ) ;
}
src_cb = pic - > data [ 1 ] + ( mx > > 3 ) + ( my > > 3 ) * h - > mb_uvlinesize ;
src_cr = pic - > data [ 2 ] + ( mx > > 3 ) + ( my > > 3 ) * h - > mb_uvlinesize ;
src_cb = pic - > data [ 1 ] + ( ( mx > > 3 ) < < pixel_shift ) + ( my > > 3 ) * h - > mb_uvlinesize ;
src_cr = pic - > data [ 2 ] + ( ( mx > > 3 ) < < pixel_shift ) + ( my > > 3 ) * h - > mb_uvlinesize ;
if ( emu ) {
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer , src_cb , h - > mb_uvlinesize , 9 , 9 /*FIXME*/ , ( mx > > 3 ) , ( my > > 3 ) , pic_width > > 1 , pic_height > > 1 ) ;
@ -374,14 +375,14 @@ static inline void mc_part_std(H264Context *h, int n, int square, int chroma_hei
int x_offset , int y_offset ,
qpel_mc_func * qpix_put , h264_chroma_mc_func chroma_put ,
qpel_mc_func * qpix_avg , h264_chroma_mc_func chroma_avg ,
int list0 , int list1 ) {
int list0 , int list1 , int pixel_shift ) {
MpegEncContext * const s = & h - > s ;
qpel_mc_func * qpix_op = qpix_put ;
h264_chroma_mc_func chroma_op = chroma_put ;
dest_y + = 2 * x_offset + 2 * y_offset * h - > mb_linesize ;
dest_cb + = x_offset + y_offset * h - > mb_uvlinesize ;
dest_cr + = x_offset + y_offset * h - > mb_uvlinesize ;
dest_y + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
dest_cb + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
dest_cr + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
x_offset + = 8 * s - > mb_x ;
y_offset + = 8 * ( s - > mb_y > > MB_FIELD ) ;
@ -389,7 +390,7 @@ static inline void mc_part_std(H264Context *h, int n, int square, int chroma_hei
Picture * ref = & h - > ref_list [ 0 ] [ h - > ref_cache [ 0 ] [ scan8 [ n ] ] ] ;
mc_dir_part ( h , ref , n , square , chroma_height , delta , 0 ,
dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_op , chroma_op ) ;
qpix_op , chroma_op , pixel_shift ) ;
qpix_op = qpix_avg ;
chroma_op = chroma_avg ;
@ -399,7 +400,7 @@ static inline void mc_part_std(H264Context *h, int n, int square, int chroma_hei
Picture * ref = & h - > ref_list [ 1 ] [ h - > ref_cache [ 1 ] [ scan8 [ n ] ] ] ;
mc_dir_part ( h , ref , n , square , chroma_height , delta , 1 ,
dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_op , chroma_op ) ;
qpix_op , chroma_op , pixel_shift ) ;
}
}
@ -409,12 +410,12 @@ static inline void mc_part_weighted(H264Context *h, int n, int square, int chrom
qpel_mc_func * qpix_put , h264_chroma_mc_func chroma_put ,
h264_weight_func luma_weight_op , h264_weight_func chroma_weight_op ,
h264_biweight_func luma_weight_avg , h264_biweight_func chroma_weight_avg ,
int list0 , int list1 ) {
int list0 , int list1 , int pixel_shift ) {
MpegEncContext * const s = & h - > s ;
dest_y + = 2 * x_offset + 2 * y_offset * h - > mb_linesize ;
dest_cb + = x_offset + y_offset * h - > mb_uvlinesize ;
dest_cr + = x_offset + y_offset * h - > mb_uvlinesize ;
dest_y + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
dest_cb + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
dest_cr + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
x_offset + = 8 * s - > mb_x ;
y_offset + = 8 * ( s - > mb_y > > MB_FIELD ) ;
@ -422,17 +423,17 @@ static inline void mc_part_weighted(H264Context *h, int n, int square, int chrom
/* don't optimize for luma-only case, since B-frames usually
* use implicit weights = > chroma too . */
uint8_t * tmp_cb = s - > obmc_scratchpad ;
uint8_t * tmp_cr = s - > obmc_scratchpad + 8 ;
uint8_t * tmp_cr = s - > obmc_scratchpad + ( 8 < < pixel_shift ) ;
uint8_t * tmp_y = s - > obmc_scratchpad + 8 * h - > mb_uvlinesize ;
int refn0 = h - > ref_cache [ 0 ] [ scan8 [ n ] ] ;
int refn1 = h - > ref_cache [ 1 ] [ scan8 [ n ] ] ;
mc_dir_part ( h , & h - > ref_list [ 0 ] [ refn0 ] , n , square , chroma_height , delta , 0 ,
dest_y , dest_cb , dest_cr ,
x_offset , y_offset , qpix_put , chroma_put ) ;
x_offset , y_offset , qpix_put , chroma_put , pixel_shift ) ;
mc_dir_part ( h , & h - > ref_list [ 1 ] [ refn1 ] , n , square , chroma_height , delta , 1 ,
tmp_y , tmp_cb , tmp_cr ,
x_offset , y_offset , qpix_put , chroma_put ) ;
x_offset , y_offset , qpix_put , chroma_put , pixel_shift ) ;
if ( h - > use_weight = = 2 ) {
int weight0 = h - > implicit_weight [ refn0 ] [ refn1 ] [ s - > mb_y & 1 ] ;
@ -457,7 +458,7 @@ static inline void mc_part_weighted(H264Context *h, int n, int square, int chrom
Picture * ref = & h - > ref_list [ list ] [ refn ] ;
mc_dir_part ( h , ref , n , square , chroma_height , delta , list ,
dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_put , chroma_put ) ;
qpix_put , chroma_put , pixel_shift ) ;
luma_weight_op ( dest_y , h - > mb_linesize , h - > luma_log2_weight_denom ,
h - > luma_weight [ refn ] [ list ] [ 0 ] , h - > luma_weight [ refn ] [ list ] [ 1 ] ) ;
@ -476,19 +477,21 @@ static inline void mc_part(H264Context *h, int n, int square, int chroma_height,
qpel_mc_func * qpix_put , h264_chroma_mc_func chroma_put ,
qpel_mc_func * qpix_avg , h264_chroma_mc_func chroma_avg ,
h264_weight_func * weight_op , h264_biweight_func * weight_avg ,
int list0 , int list1 ) {
int list0 , int list1 , int pixel_shift ) {
if ( ( h - > use_weight = = 2 & & list0 & & list1
& & ( h - > implicit_weight [ h - > ref_cache [ 0 ] [ scan8 [ n ] ] ] [ h - > ref_cache [ 1 ] [ scan8 [ n ] ] ] [ h - > s . mb_y & 1 ] ! = 32 ) )
| | h - > use_weight = = 1 )
mc_part_weighted ( h , n , square , chroma_height , delta , dest_y , dest_cb , dest_cr ,
x_offset , y_offset , qpix_put , chroma_put ,
weight_op [ 0 ] , weight_op [ 3 ] , weight_avg [ 0 ] , weight_avg [ 3 ] , list0 , list1 ) ;
weight_op [ 0 ] , weight_op [ 3 ] , weight_avg [ 0 ] ,
weight_avg [ 3 ] , list0 , list1 , pixel_shift ) ;
else
mc_part_std ( h , n , square , chroma_height , delta , dest_y , dest_cb , dest_cr ,
x_offset , y_offset , qpix_put , chroma_put , qpix_avg , chroma_avg , list0 , list1 ) ;
x_offset , y_offset , qpix_put , chroma_put , qpix_avg ,
chroma_avg , list0 , list1 , pixel_shift ) ;
}
static inline void prefetch_motion ( H264Context * h , int list ) {
static inline void prefetch_motion ( H264Context * h , int list , int pixel_shift ) {
/* fetch pixels for estimated mv 4 macroblocks ahead
* optimized for 64 byte cache lines */
MpegEncContext * const s = & h - > s ;
@ -497,48 +500,54 @@ static inline void prefetch_motion(H264Context *h, int list){
const int mx = ( h - > mv_cache [ list ] [ scan8 [ 0 ] ] [ 0 ] > > 2 ) + 16 * s - > mb_x + 8 ;
const int my = ( h - > mv_cache [ list ] [ scan8 [ 0 ] ] [ 1 ] > > 2 ) + 16 * s - > mb_y ;
uint8_t * * src = h - > ref_list [ list ] [ refn ] . data ;
int off = mx + ( my + ( s - > mb_x & 3 ) * 4 ) * h - > mb_linesize + 64 ;
int off = ( mx < < pixel_shift ) + ( my + ( s - > mb_x & 3 ) * 4 ) * h - > mb_linesize + ( 64 < < pixel_shift ) ;
s - > dsp . prefetch ( src [ 0 ] + off , s - > linesize , 4 ) ;
off = ( mx > > 1 ) + ( ( my > > 1 ) + ( s - > mb_x & 7 ) ) * s - > uvlinesize + 64 ;
off = ( ( mx > > 1 ) < < pixel_shift ) + ( ( my > > 1 ) + ( s - > mb_x & 7 ) ) * s - > uvlinesize + ( 64 < < pixel_shift ) ;
s - > dsp . prefetch ( src [ 1 ] + off , src [ 2 ] - src [ 1 ] , 2 ) ;
}
}
static void hl_motion ( H264Context * h , uint8_t * dest_y , uint8_t * dest_cb , uint8_t * dest_cr ,
static av_always_inline void hl_motion ( H264Context * h , uint8_t * dest_y , uint8_t * dest_cb , uint8_t * dest_cr ,
qpel_mc_func ( * qpix_put ) [ 16 ] , h264_chroma_mc_func ( * chroma_put ) ,
qpel_mc_func ( * qpix_avg ) [ 16 ] , h264_chroma_mc_func ( * chroma_avg ) ,
h264_weight_func * weight_op , h264_biweight_func * weight_avg ) {
h264_weight_func * weight_op , h264_biweight_func * weight_avg ,
int pixel_shift ) {
MpegEncContext * const s = & h - > s ;
const int mb_xy = h - > mb_xy ;
const int mb_type = s - > current_picture . mb_type [ mb_xy ] ;
assert ( IS_INTER ( mb_type ) ) ;
prefetch_motion ( h , 0 ) ;
prefetch_motion ( h , 0 , pixel_shift ) ;
if ( IS_16X16 ( mb_type ) ) {
mc_part ( h , 0 , 1 , 8 , 0 , dest_y , dest_cb , dest_cr , 0 , 0 ,
qpix_put [ 0 ] , chroma_put [ 0 ] , qpix_avg [ 0 ] , chroma_avg [ 0 ] ,
weight_op , weight_avg ,
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ) ;
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ,
pixel_shift ) ;
} else if ( IS_16X8 ( mb_type ) ) {
mc_part ( h , 0 , 0 , 4 , 8 , dest_y , dest_cb , dest_cr , 0 , 0 ,
mc_part ( h , 0 , 0 , 4 , 8 < < pixel_shift , dest_y , dest_cb , dest_cr , 0 , 0 ,
qpix_put [ 1 ] , chroma_put [ 0 ] , qpix_avg [ 1 ] , chroma_avg [ 0 ] ,
& weight_op [ 1 ] , & weight_avg [ 1 ] ,
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ) ;
mc_part ( h , 8 , 0 , 4 , 8 , dest_y , dest_cb , dest_cr , 0 , 4 ,
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ,
pixel_shift ) ;
mc_part ( h , 8 , 0 , 4 , 8 < < pixel_shift , dest_y , dest_cb , dest_cr , 0 , 4 ,
qpix_put [ 1 ] , chroma_put [ 0 ] , qpix_avg [ 1 ] , chroma_avg [ 0 ] ,
& weight_op [ 1 ] , & weight_avg [ 1 ] ,
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) ) ;
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) ,
pixel_shift ) ;
} else if ( IS_8X16 ( mb_type ) ) {
mc_part ( h , 0 , 0 , 8 , 8 * h - > mb_linesize , dest_y , dest_cb , dest_cr , 0 , 0 ,
qpix_put [ 1 ] , chroma_put [ 1 ] , qpix_avg [ 1 ] , chroma_avg [ 1 ] ,
& weight_op [ 2 ] , & weight_avg [ 2 ] ,
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ) ;
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ,
pixel_shift ) ;
mc_part ( h , 4 , 0 , 8 , 8 * h - > mb_linesize , dest_y , dest_cb , dest_cr , 4 , 0 ,
qpix_put [ 1 ] , chroma_put [ 1 ] , qpix_avg [ 1 ] , chroma_avg [ 1 ] ,
& weight_op [ 2 ] , & weight_avg [ 2 ] ,
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) ) ;
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) ,
pixel_shift ) ;
} else {
int i ;
@ -554,25 +563,30 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t
mc_part ( h , n , 1 , 4 , 0 , dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_put [ 1 ] , chroma_put [ 1 ] , qpix_avg [ 1 ] , chroma_avg [ 1 ] ,
& weight_op [ 3 ] , & weight_avg [ 3 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ) ;
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift ) ;
} else if ( IS_SUB_8X4 ( sub_mb_type ) ) {
mc_part ( h , n , 0 , 2 , 4 , dest_y , dest_cb , dest_cr , x_offset , y_offset ,
mc_part ( h , n , 0 , 2 , 4 < < pixel_shift , dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_put [ 2 ] , chroma_put [ 1 ] , qpix_avg [ 2 ] , chroma_avg [ 1 ] ,
& weight_op [ 4 ] , & weight_avg [ 4 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ) ;
mc_part ( h , n + 2 , 0 , 2 , 4 , dest_y , dest_cb , dest_cr , x_offset , y_offset + 2 ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift ) ;
mc_part ( h , n + 2 , 0 , 2 , 4 < < pixel_shift , dest_y , dest_cb , dest_cr , x_offset , y_offset + 2 ,
qpix_put [ 2 ] , chroma_put [ 1 ] , qpix_avg [ 2 ] , chroma_avg [ 1 ] ,
& weight_op [ 4 ] , & weight_avg [ 4 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ) ;
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift ) ;
} else if ( IS_SUB_4X8 ( sub_mb_type ) ) {
mc_part ( h , n , 0 , 4 , 4 * h - > mb_linesize , dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_put [ 2 ] , chroma_put [ 2 ] , qpix_avg [ 2 ] , chroma_avg [ 2 ] ,
& weight_op [ 5 ] , & weight_avg [ 5 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ) ;
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift ) ;
mc_part ( h , n + 1 , 0 , 4 , 4 * h - > mb_linesize , dest_y , dest_cb , dest_cr , x_offset + 2 , y_offset ,
qpix_put [ 2 ] , chroma_put [ 2 ] , qpix_avg [ 2 ] , chroma_avg [ 2 ] ,
& weight_op [ 5 ] , & weight_avg [ 5 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ) ;
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift ) ;
} else {
int j ;
assert ( IS_SUB_4X4 ( sub_mb_type ) ) ;
@ -582,15 +596,32 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t
mc_part ( h , n + j , 1 , 2 , 0 , dest_y , dest_cb , dest_cr , sub_x_offset , sub_y_offset ,
qpix_put [ 2 ] , chroma_put [ 2 ] , qpix_avg [ 2 ] , chroma_avg [ 2 ] ,
& weight_op [ 6 ] , & weight_avg [ 6 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ) ;
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift ) ;
}
}
}
}
prefetch_motion ( h , 1 ) ;
prefetch_motion ( h , 1 , pixel_shift ) ;
}
# define hl_motion_fn(sh, bits) \
static av_always_inline void hl_motion_ # # bits ( H264Context * h , \
uint8_t * dest_y , \
uint8_t * dest_cb , uint8_t * dest_cr , \
qpel_mc_func ( * qpix_put ) [ 16 ] , \
h264_chroma_mc_func ( * chroma_put ) , \
qpel_mc_func ( * qpix_avg ) [ 16 ] , \
h264_chroma_mc_func ( * chroma_avg ) , \
h264_weight_func * weight_op , \
h264_biweight_func * weight_avg ) \
{ \
hl_motion ( h , dest_y , dest_cb , dest_cr , qpix_put , chroma_put , \
qpix_avg , chroma_avg , weight_op , weight_avg , sh ) ; \
}
hl_motion_fn ( 0 , 8 ) ;
hl_motion_fn ( 1 , 16 ) ;
static void free_tables ( H264Context * h , int free_rbsp ) {
int i ;
@ -758,8 +789,8 @@ static void clone_tables(H264Context *dst, H264Context *src, int i){
* Allocate buffers which are not shared amongst multiple threads .
*/
static int context_init ( H264Context * h ) {
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > top_borders [ 0 ] , h - > s . mb_width * ( 16 + 8 + 8 ) * sizeof ( uint8_t ) , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > top_borders [ 1 ] , h - > s . mb_width * ( 16 + 8 + 8 ) * sizeof ( uint8_t ) , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > top_borders [ 0 ] , h - > s . mb_width * ( 16 + 8 + 8 ) * sizeof ( uint8_t ) * 2 , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > top_borders [ 1 ] , h - > s . mb_width * ( 16 + 8 + 8 ) * sizeof ( uint8_t ) * 2 , fail )
h - > ref_cache [ 0 ] [ scan8 [ 5 ] + 1 ] = h - > ref_cache [ 0 ] [ scan8 [ 7 ] + 1 ] = h - > ref_cache [ 0 ] [ scan8 [ 13 ] + 1 ] =
h - > ref_cache [ 1 ] [ scan8 [ 5 ] + 1 ] = h - > ref_cache [ 1 ] [ scan8 [ 7 ] + 1 ] = h - > ref_cache [ 1 ] [ scan8 [ 13 ] + 1 ] = PART_NOT_AVAILABLE ;
@ -861,6 +892,8 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){
ff_h264_decode_init_vlc ( ) ;
h - > pixel_shift = 0 ;
h - > thread_context [ 0 ] = h ;
h - > outputed_poc = INT_MIN ;
h - > prev_poc_msb = 1 < < 16 ;
@ -888,6 +921,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){
int ff_h264_frame_start ( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
int i ;
const int pixel_shift = h - > pixel_shift ;
if ( MPV_frame_start ( s , s - > avctx ) < 0 )
return - 1 ;
@ -904,14 +938,14 @@ int ff_h264_frame_start(H264Context *h){
assert ( s - > linesize & & s - > uvlinesize ) ;
for ( i = 0 ; i < 16 ; i + + ) {
h - > block_offset [ i ] = 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) + 4 * s - > linesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ 24 + i ] = 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) + 8 * s - > linesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 4 * s - > linesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ 24 + i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 8 * s - > linesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
}
for ( i = 0 ; i < 4 ; i + + ) {
h - > block_offset [ 16 + i ] =
h - > block_offset [ 20 + i ] = 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) + 4 * s - > uvlinesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ 20 + i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 4 * s - > uvlinesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ 24 + 16 + i ] =
h - > block_offset [ 24 + 20 + i ] = 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) + 8 * s - > uvlinesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ 24 + 20 + i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 8 * s - > uvlinesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
}
/* can't be in alloc_tables because linesize isn't known there.
@ -945,6 +979,7 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src
MpegEncContext * const s = & h - > s ;
uint8_t * top_border ;
int top_idx = 1 ;
const int pixel_shift = h - > pixel_shift ;
src_y - = linesize ;
src_cb - = uvlinesize ;
@ -955,9 +990,16 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src
if ( ! MB_MBAFF ) {
top_border = h - > top_borders [ 0 ] [ s - > mb_x ] ;
AV_COPY128 ( top_border , src_y + 15 * linesize ) ;
if ( pixel_shift )
AV_COPY128 ( top_border + 16 , src_y + 15 * linesize + 16 ) ;
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
if ( pixel_shift ) {
AV_COPY128 ( top_border + 32 , src_cb + 7 * uvlinesize ) ;
AV_COPY128 ( top_border + 48 , src_cr + 7 * uvlinesize ) ;
} else {
AV_COPY64 ( top_border + 16 , src_cb + 7 * uvlinesize ) ;
AV_COPY64 ( top_border + 24 , src_cr + 7 * uvlinesize ) ;
}
}
}
} else if ( MB_MBAFF ) {
@ -970,14 +1012,24 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src
// There are two lines saved, the line above the the top macroblock of a pair,
// and the line above the bottom macroblock
AV_COPY128 ( top_border , src_y + 16 * linesize ) ;
if ( pixel_shift )
AV_COPY128 ( top_border + 16 , src_y + 16 * linesize + 16 ) ;
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
if ( pixel_shift ) {
AV_COPY128 ( top_border + 32 , src_cb + 8 * uvlinesize ) ;
AV_COPY128 ( top_border + 48 , src_cr + 8 * uvlinesize ) ;
} else {
AV_COPY64 ( top_border + 16 , src_cb + 8 * uvlinesize ) ;
AV_COPY64 ( top_border + 24 , src_cr + 8 * uvlinesize ) ;
}
}
}
static inline void xchg_mb_border ( H264Context * h , uint8_t * src_y , uint8_t * src_cb , uint8_t * src_cr , int linesize , int uvlinesize , int xchg , int simple ) {
static inline void xchg_mb_border ( H264Context * h , uint8_t * src_y ,
uint8_t * src_cb , uint8_t * src_cr ,
int linesize , int uvlinesize ,
int xchg , int simple , int pixel_shift ) {
MpegEncContext * const s = & h - > s ;
int deblock_left ;
int deblock_top ;
@ -1002,41 +1054,62 @@ static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_c
deblock_top = ( s - > mb_y > ! ! MB_FIELD ) ;
}
src_y - = linesize + 1 ;
src_cb - = uvlinesize + 1 ;
src_cr - = uvlinesize + 1 ;
src_y - = linesize + 1 + pixel_shift ;
src_cb - = uvlinesize + 1 + pixel_shift ;
src_cr - = uvlinesize + 1 + pixel_shift ;
top_border_m1 = h - > top_borders [ top_idx ] [ s - > mb_x - 1 ] ;
top_border = h - > top_borders [ top_idx ] [ s - > mb_x ] ;
# define XCHG(a,b,xchg)\
if ( pixel_shift ) { \
if ( xchg ) { \
AV_SWAP64 ( b + 0 , a + 0 ) ; \
AV_SWAP64 ( b + 8 , a + 8 ) ; \
} else { \
AV_COPY128 ( b , a ) ; \
} \
} else \
if ( xchg ) AV_SWAP64 ( b , a ) ; \
else AV_COPY64 ( b , a ) ;
if ( deblock_top ) {
if ( deblock_left ) {
XCHG ( top_border_m1 + 8 , src_y - 7 , 1 ) ;
XCHG ( top_border_m1 + ( 8 < < pixel_shift ) , src_y - ( 7 < < pixel_shift ) , 1 ) ;
}
XCHG ( top_border + 0 , src_y + 1 , xchg ) ;
XCHG ( top_border + 8 , src_y + 9 , 1 ) ;
XCHG ( top_border + ( 0 < < pixel_shift ) , src_y + ( 1 < < pixel_shift ) , xchg ) ;
XCHG ( top_border + ( 8 < < pixel_shift ) , src_y + ( 9 < < pixel_shift ) , 1 ) ;
if ( s - > mb_x + 1 < s - > mb_width ) {
XCHG ( h - > top_borders [ top_idx ] [ s - > mb_x + 1 ] , src_y + 17 , 1 ) ;
XCHG ( h - > top_borders [ top_idx ] [ s - > mb_x + 1 ] , src_y + ( 17 < < pixel_shift ) , 1 ) ;
}
}
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
if ( deblock_top ) {
if ( deblock_left ) {
XCHG ( top_border_m1 + 16 , src_cb - 7 , 1 ) ;
XCHG ( top_border_m1 + 24 , src_cr - 7 , 1 ) ;
XCHG ( top_border_m1 + ( 16 < < pixel_shift ) , src_cb - ( 7 < < pixel_shift ) , 1 ) ;
XCHG ( top_border_m1 + ( 24 < < pixel_shift ) , src_cr - ( 7 < < pixel_shift ) , 1 ) ;
}
XCHG ( top_border + 16 , src_cb + 1 , 1 ) ;
XCHG ( top_border + 24 , src_cr + 1 , 1 ) ;
XCHG ( top_border + ( 16 < < pixel_shift ) , src_cb + 1 + pixel_shift , 1 ) ;
XCHG ( top_border + ( 24 < < pixel_shift ) , src_cr + 1 + pixel_shift , 1 ) ;
}
}
}
static av_always_inline void hl_decode_mb_internal ( H264Context * h , int simple ) {
static av_always_inline int dctcoef_get ( DCTELEM * mb , int high_bit_depth , int index ) {
if ( high_bit_depth ) {
return AV_RN32A ( ( ( int32_t * ) mb ) + index ) ;
} else
return AV_RN16A ( mb + index ) ;
}
static av_always_inline void dctcoef_set ( DCTELEM * mb , int high_bit_depth , int index , int value ) {
if ( high_bit_depth ) {
AV_WN32A ( ( ( int32_t * ) mb ) + index , value ) ;
} else
AV_WN16A ( mb + index , value ) ;
}
static av_always_inline void hl_decode_mb_internal ( H264Context * h , int simple , int pixel_shift ) {
MpegEncContext * const s = & h - > s ;
const int mb_x = s - > mb_x ;
const int mb_y = s - > mb_y ;
@ -1052,12 +1125,12 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
void ( * idct_add ) ( uint8_t * dst , DCTELEM * block , int stride ) ;
void ( * idct_dc_add ) ( uint8_t * dst , DCTELEM * block , int stride ) ;
dest_y = s - > current_picture . data [ 0 ] + ( mb_x + mb_y * s - > linesize ) * 16 ;
dest_cb = s - > current_picture . data [ 1 ] + ( mb_x + mb_y * s - > uvlinesize ) * 8 ;
dest_cr = s - > current_picture . data [ 2 ] + ( mb_x + mb_y * s - > uvlinesize ) * 8 ;
dest_y = s - > current_picture . data [ 0 ] + ( ( mb_x < < pixel_shift ) + mb_y * s - > linesize ) * 16 ;
dest_cb = s - > current_picture . data [ 1 ] + ( ( mb_x < < pixel_shift ) + mb_y * s - > uvlinesize ) * 8 ;
dest_cr = s - > current_picture . data [ 2 ] + ( ( mb_x < < pixel_shift ) + mb_y * s - > uvlinesize ) * 8 ;
s - > dsp . prefetch ( dest_y + ( s - > mb_x & 3 ) * 4 * s - > linesize + 64 , s - > linesize , 4 ) ;
s - > dsp . prefetch ( dest_cb + ( s - > mb_x & 7 ) * s - > uvlinesize + 64 , dest_cr - dest_cb , 2 ) ;
s - > dsp . prefetch ( dest_y + ( s - > mb_x & 3 ) * 4 * s - > linesize + ( 64 < < pixel_shift ) , s - > linesize , 4 ) ;
s - > dsp . prefetch ( dest_cb + ( s - > mb_x & 7 ) * s - > uvlinesize + ( 64 < < pixel_shift ) , dest_cr - dest_cb , 2 ) ;
h - > list_counts [ mb_xy ] = h - > list_count ;
@ -1094,6 +1167,28 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
}
if ( ! simple & & IS_INTRA_PCM ( mb_type ) ) {
if ( pixel_shift ) {
const int bit_depth = h - > sps . bit_depth_luma ;
int j ;
GetBitContext gb ;
init_get_bits ( & gb , ( uint8_t * ) h - > mb , 384 * bit_depth ) ;
for ( i = 0 ; i < 16 ; i + + ) {
uint16_t * tmp_y = ( uint16_t * ) ( dest_y + i * linesize ) ;
for ( j = 0 ; j < 16 ; j + + )
tmp_y [ j ] = get_bits ( & gb , bit_depth ) ;
}
for ( i = 0 ; i < 8 ; i + + ) {
uint16_t * tmp_cb = ( uint16_t * ) ( dest_cb + i * uvlinesize ) ;
for ( j = 0 ; j < 8 ; j + + )
tmp_cb [ j ] = get_bits ( & gb , bit_depth ) ;
}
for ( i = 0 ; i < 8 ; i + + ) {
uint16_t * tmp_cr = ( uint16_t * ) ( dest_cr + i * uvlinesize ) ;
for ( j = 0 ; j < 8 ; j + + )
tmp_cr [ j ] = get_bits ( & gb , bit_depth ) ;
}
} else {
for ( i = 0 ; i < 16 ; i + + ) {
memcpy ( dest_y + i * linesize , h - > mb + i * 8 , 16 ) ;
}
@ -1101,10 +1196,11 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
memcpy ( dest_cb + i * uvlinesize , h - > mb + 128 + i * 4 , 8 ) ;
memcpy ( dest_cr + i * uvlinesize , h - > mb + 160 + i * 4 , 8 ) ;
}
}
} else {
if ( IS_INTRA ( mb_type ) ) {
if ( h - > deblocking_filter )
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize , uvlinesize , 1 , simple ) ;
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize , uvlinesize , 1 , simple , pixel_shift ) ;
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
h - > hpc . pred8x8 [ h - > chroma_pred_mode ] ( dest_cb , uvlinesize ) ;
@ -1125,16 +1221,16 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
uint8_t * const ptr = dest_y + block_offset [ i ] ;
const int dir = h - > intra4x4_pred_mode_cache [ scan8 [ i ] ] ;
if ( transform_bypass & & h - > sps . profile_idc = = 244 & & dir < = 1 ) {
h - > hpc . pred8x8l_add [ dir ] ( ptr , h - > mb + i * 16 , linesize ) ;
h - > hpc . pred8x8l_add [ dir ] ( ptr , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
} else {
const int nnz = h - > non_zero_count_cache [ scan8 [ i ] ] ;
h - > hpc . pred8x8l [ dir ] ( ptr , ( h - > topleft_samples_available < < i ) & 0x8000 ,
( h - > topright_samples_available < < i ) & 0x4000 , linesize ) ;
if ( nnz ) {
if ( nnz = = 1 & & h - > mb [ i * 16 ] )
idct_dc_add ( ptr , h - > mb + i * 16 , linesize ) ;
if ( nnz = = 1 & & dctcoef_get ( h - > mb , pixel_shift , i * 16 ) )
idct_dc_add ( ptr , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
else
idct_add ( ptr , h - > mb + i * 16 , linesize ) ;
idct_add ( ptr , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
}
}
}
@ -1151,18 +1247,24 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
const int dir = h - > intra4x4_pred_mode_cache [ scan8 [ i ] ] ;
if ( transform_bypass & & h - > sps . profile_idc = = 244 & & dir < = 1 ) {
h - > hpc . pred4x4_add [ dir ] ( ptr , h - > mb + i * 16 , linesize ) ;
h - > hpc . pred4x4_add [ dir ] ( ptr , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
} else {
uint8_t * topright ;
int nnz , tr ;
uint64_t tr_high ;
if ( dir = = DIAG_DOWN_LEFT_PRED | | dir = = VERT_LEFT_PRED ) {
const int topright_avail = ( h - > topright_samples_available < < i ) & 0x8000 ;
assert ( mb_y | | linesize < = block_offset [ i ] ) ;
if ( ! topright_avail ) {
if ( pixel_shift ) {
tr_high = ( ( uint16_t * ) ptr ) [ 3 - linesize / 2 ] * 0x0001000100010001ULL ;
topright = ( uint8_t * ) & tr_high ;
} else {
tr = ptr [ 3 - linesize ] * 0x01010101 ;
topright = ( uint8_t * ) & tr ;
}
} else
topright = ptr + 4 - linesize ;
topright = ptr + ( 4 < < pixel_shift ) - linesize ;
} else
topright = NULL ;
@ -1170,10 +1272,10 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
nnz = h - > non_zero_count_cache [ scan8 [ i ] ] ;
if ( nnz ) {
if ( is_h264 ) {
if ( nnz = = 1 & & h - > mb [ i * 16 ] )
idct_dc_add ( ptr , h - > mb + i * 16 , linesize ) ;
if ( nnz = = 1 & & dctcoef_get ( h - > mb , pixel_shift , i * 16 ) )
idct_dc_add ( ptr , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
else
idct_add ( ptr , h - > mb + i * 16 , linesize ) ;
idct_add ( ptr , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
} else
ff_svq3_add_idct_c ( ptr , h - > mb + i * 16 , linesize , s - > qscale , 0 ) ;
}
@ -1191,19 +1293,27 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
static const uint8_t dc_mapping [ 16 ] = { 0 * 16 , 1 * 16 , 4 * 16 , 5 * 16 , 2 * 16 , 3 * 16 , 6 * 16 , 7 * 16 ,
8 * 16 , 9 * 16 , 12 * 16 , 13 * 16 , 10 * 16 , 11 * 16 , 14 * 16 , 15 * 16 } ;
for ( i = 0 ; i < 16 ; i + + )
h - > mb [ dc_mapping [ i ] ] = h - > mb_luma_dc [ i ] ;
dctcoef_set ( h - > mb , pixel_shift , dc_mapping [ i ] , dctcoef_get ( h - > mb_luma_dc , pixel_shift , i ) ) ;
}
}
} else
ff_svq3_luma_dc_dequant_idct_c ( h - > mb , h - > mb_luma_dc , s - > qscale ) ;
}
if ( h - > deblocking_filter )
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize , uvlinesize , 0 , simple ) ;
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize , uvlinesize , 0 , simple , pixel_shift ) ;
} else if ( is_h264 ) {
hl_motion ( h , dest_y , dest_cb , dest_cr ,
s - > me . qpel_put , s - > dsp . put_h264_chroma_pixels_tab ,
s - > me . qpel_avg , s - > dsp . avg_h264_chroma_pixels_tab ,
h - > h264dsp . weight_h264_pixels_tab , h - > h264dsp . biweight_h264_pixels_tab ) ;
if ( pixel_shift ) {
hl_motion_16 ( h , dest_y , dest_cb , dest_cr ,
s - > me . qpel_put , s - > dsp . put_h264_chroma_pixels_tab ,
s - > me . qpel_avg , s - > dsp . avg_h264_chroma_pixels_tab ,
h - > h264dsp . weight_h264_pixels_tab ,
h - > h264dsp . biweight_h264_pixels_tab ) ;
} else
hl_motion_8 ( h , dest_y , dest_cb , dest_cr ,
s - > me . qpel_put , s - > dsp . put_h264_chroma_pixels_tab ,
s - > me . qpel_avg , s - > dsp . avg_h264_chroma_pixels_tab ,
h - > h264dsp . weight_h264_pixels_tab ,
h - > h264dsp . biweight_h264_pixels_tab ) ;
}
@ -1215,8 +1325,8 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
h - > hpc . pred16x16_add [ h - > intra16x16_pred_mode ] ( dest_y , block_offset , h - > mb , linesize ) ;
} else {
for ( i = 0 ; i < 16 ; i + + ) {
if ( h - > non_zero_count_cache [ scan8 [ i ] ] | | h - > mb [ i * 16 ] )
s - > dsp . add_pixels4 ( dest_y + block_offset [ i ] , h - > mb + i * 16 , linesize ) ;
if ( h - > non_zero_count_cache [ scan8 [ i ] ] | | dctcoef_get ( h - > mb , pixel_shift , i * 16 ) )
s - > dsp . add_pixels4 ( dest_y + block_offset [ i ] , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
}
}
} else {
@ -1228,7 +1338,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
idct_add = IS_8x8DCT ( mb_type ) ? s - > dsp . add_pixels8 : s - > dsp . add_pixels4 ;
for ( i = 0 ; i < 16 ; i + = di ) {
if ( h - > non_zero_count_cache [ scan8 [ i ] ] ) {
idct_add ( dest_y + block_offset [ i ] , h - > mb + i * 16 , linesize ) ;
idct_add ( dest_y + block_offset [ i ] , h - > mb + ( i * 16 < < pixel_shift ) , linesize ) ;
}
}
} else {
@ -1253,21 +1363,21 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
uint8_t * dest [ 2 ] = { dest_cb , dest_cr } ;
if ( transform_bypass ) {
if ( IS_INTRA ( mb_type ) & & h - > sps . profile_idc = = 244 & & ( h - > chroma_pred_mode = = VERT_PRED8x8 | | h - > chroma_pred_mode = = HOR_PRED8x8 ) ) {
h - > hpc . pred8x8_add [ h - > chroma_pred_mode ] ( dest [ 0 ] , block_offset + 16 , h - > mb + 16 * 16 , uvlinesize ) ;
h - > hpc . pred8x8_add [ h - > chroma_pred_mode ] ( dest [ 1 ] , block_offset + 20 , h - > mb + 20 * 16 , uvlinesize ) ;
h - > hpc . pred8x8_add [ h - > chroma_pred_mode ] ( dest [ 0 ] , block_offset + 16 , h - > mb + ( 16 * 16 < < pixel_shift ) , uvlinesize ) ;
h - > hpc . pred8x8_add [ h - > chroma_pred_mode ] ( dest [ 1 ] , block_offset + 20 , h - > mb + ( 20 * 16 < < pixel_shift ) , uvlinesize ) ;
} else {
idct_add = s - > dsp . add_pixels4 ;
for ( i = 16 ; i < 16 + 8 ; i + + ) {
if ( h - > non_zero_count_cache [ scan8 [ i ] ] | | h - > mb [ i * 16 ] )
idct_add ( dest [ ( i & 4 ) > > 2 ] + block_offset [ i ] , h - > mb + i * 16 , uvlinesize ) ;
if ( h - > non_zero_count_cache [ scan8 [ i ] ] | | dctcoef_get ( h - > mb , pixel_shift , i * 16 ) )
idct_add ( dest [ ( i & 4 ) > > 2 ] + block_offset [ i ] , h - > mb + ( i * 16 < < pixel_shift ) , uvlinesize ) ;
}
}
} else {
if ( is_h264 ) {
if ( h - > non_zero_count_cache [ scan8 [ CHROMA_DC_BLOCK_INDEX + 0 ] ] )
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + 16 * 16 , h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 1 : 4 ] [ h - > chroma_qp [ 0 ] ] [ 0 ] ) ;
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + ( 16 * 16 < < pixel_shift ) , h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 1 : 4 ] [ h - > chroma_qp [ 0 ] ] [ 0 ] ) ;
if ( h - > non_zero_count_cache [ scan8 [ CHROMA_DC_BLOCK_INDEX + 1 ] ] )
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + 16 * 16 + 4 * 16 , h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 2 : 5 ] [ h - > chroma_qp [ 1 ] ] [ 0 ] ) ;
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + ( ( 16 * 16 + 4 * 16 ) < < pixel_shift ) , h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 2 : 5 ] [ h - > chroma_qp [ 1 ] ] [ 0 ] ) ;
h - > h264dsp . h264_idct_add8 ( dest , block_offset ,
h - > mb , uvlinesize ,
h - > non_zero_count_cache ) ;
@ -1291,15 +1401,18 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
/**
* Process a macroblock ; this case avoids checks for expensive uncommon cases .
*/
static void hl_decode_mb_simple ( H264Context * h ) {
hl_decode_mb_internal ( h , 1 ) ;
# define hl_decode_mb_simple(sh, bits) \
static void hl_decode_mb_simple_ # # bits ( H264Context * h ) { \
hl_decode_mb_internal ( h , 1 , sh ) ; \
}
hl_decode_mb_simple ( 0 , 8 ) ;
hl_decode_mb_simple ( 1 , 16 ) ;
/**
* Process a macroblock ; this handles edge cases , such as interlacing .
*/
static void av_noinline hl_decode_mb_complex ( H264Context * h ) {
hl_decode_mb_internal ( h , 0 ) ;
hl_decode_mb_internal ( h , 0 , h - > pixel_shift ) ;
}
void ff_h264_hl_decode_mb ( H264Context * h ) {
@ -1308,9 +1421,12 @@ void ff_h264_hl_decode_mb(H264Context *h){
const int mb_type = s - > current_picture . mb_type [ mb_xy ] ;
int is_complex = CONFIG_SMALL | | h - > is_complex | | IS_INTRA_PCM ( mb_type ) | | s - > qscale = = 0 ;
if ( is_complex )
if ( is_complex ) {
hl_decode_mb_complex ( h ) ;
else hl_decode_mb_simple ( h ) ;
} else if ( h - > pixel_shift ) {
hl_decode_mb_simple_16 ( h ) ;
} else
hl_decode_mb_simple_8 ( h ) ;
}
static int pred_weight_table ( H264Context * h ) {
@ -2432,6 +2548,7 @@ static void loop_filter(H264Context *h){
int linesize , uvlinesize , mb_x , mb_y ;
const int end_mb_y = s - > mb_y + FRAME_MBAFF ;
const int old_slice_type = h - > slice_type ;
const int pixel_shift = h - > pixel_shift ;
if ( h - > deblocking_filter ) {
for ( mb_x = 0 ; mb_x < s - > mb_width ; mb_x + + ) {
@ -2447,9 +2564,9 @@ static void loop_filter(H264Context *h){
s - > mb_x = mb_x ;
s - > mb_y = mb_y ;
dest_y = s - > current_picture . data [ 0 ] + ( mb_x + mb_y * s - > linesize ) * 16 ;
dest_cb = s - > current_picture . data [ 1 ] + ( mb_x + mb_y * s - > uvlinesize ) * 8 ;
dest_cr = s - > current_picture . data [ 2 ] + ( mb_x + mb_y * s - > uvlinesize ) * 8 ;
dest_y = s - > current_picture . data [ 0 ] + ( ( mb_x < < pixel_shift ) + mb_y * s - > linesize ) * 16 ;
dest_cb = s - > current_picture . data [ 1 ] + ( ( mb_x < < pixel_shift ) + mb_y * s - > uvlinesize ) * 8 ;
dest_cr = s - > current_picture . data [ 2 ] + ( ( mb_x < < pixel_shift ) + mb_y * s - > uvlinesize ) * 8 ;
//FIXME simplify above
if ( MB_FIELD ) {