@ -255,12 +255,15 @@ typedef struct H264Context{
int max_pic_num ;
//Weighted pred stuff
int use_weight ;
int use_weight_chroma ;
int luma_log2_weight_denom ;
int chroma_log2_weight_denom ;
int luma_weight [ 2 ] [ 16 ] ;
int luma_offset [ 2 ] [ 16 ] ;
int chroma_weight [ 2 ] [ 16 ] [ 2 ] ;
int chroma_offset [ 2 ] [ 16 ] [ 2 ] ;
int implicit_weight [ 16 ] [ 16 ] ;
//deblock
int deblocking_filter ; ///< disable_deblocking_filter_idc with 1<->0
@ -2203,7 +2206,7 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
chroma_op ( dest_cr , src_cr , s - > uvlinesize , chroma_height , mx & 7 , my & 7 ) ;
}
static inline void mc_part ( H264Context * h , int n , int square , int chroma_height , int delta ,
static inline void mc_part_std ( H264Context * h , int n , int square , int chroma_height , int delta ,
uint8_t * dest_y , uint8_t * dest_cb , uint8_t * dest_cr ,
int x_offset , int y_offset ,
qpel_mc_func * qpix_put , h264_chroma_mc_func chroma_put ,
@ -2237,9 +2240,95 @@ static inline void mc_part(H264Context *h, int n, int square, int chroma_height,
}
}
static inline void mc_part_weighted ( H264Context * h , int n , int square , int chroma_height , int delta ,
uint8_t * dest_y , uint8_t * dest_cb , uint8_t * dest_cr ,
int x_offset , int y_offset ,
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 ) {
MpegEncContext * const s = & h - > s ;
dest_y + = 2 * x_offset + 2 * y_offset * s - > linesize ;
dest_cb + = x_offset + y_offset * s - > uvlinesize ;
dest_cr + = x_offset + y_offset * s - > uvlinesize ;
x_offset + = 8 * s - > mb_x ;
y_offset + = 8 * s - > mb_y ;
if ( list0 & & list1 ) {
/* 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 = tmp_cb + 8 * s - > uvlinesize ;
uint8_t * tmp_y = tmp_cr + 8 * s - > 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 ) ;
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 ) ;
if ( h - > use_weight = = 2 ) {
int weight0 = h - > implicit_weight [ refn0 ] [ refn1 ] ;
int weight1 = 64 - weight0 ;
luma_weight_avg ( dest_y , tmp_y , s - > linesize , 5 , weight0 , weight1 , 0 , 0 ) ;
chroma_weight_avg ( dest_cb , tmp_cb , s - > uvlinesize , 5 , weight0 , weight1 , 0 , 0 ) ;
chroma_weight_avg ( dest_cr , tmp_cr , s - > uvlinesize , 5 , weight0 , weight1 , 0 , 0 ) ;
} else {
luma_weight_avg ( dest_y , tmp_y , s - > linesize , h - > luma_log2_weight_denom ,
h - > luma_weight [ 0 ] [ refn0 ] , h - > luma_weight [ 1 ] [ refn1 ] ,
h - > luma_offset [ 0 ] [ refn0 ] , h - > luma_offset [ 1 ] [ refn1 ] ) ;
chroma_weight_avg ( dest_cb , tmp_cb , s - > uvlinesize , h - > chroma_log2_weight_denom ,
h - > chroma_weight [ 0 ] [ refn0 ] [ 0 ] , h - > chroma_weight [ 1 ] [ refn1 ] [ 0 ] ,
h - > chroma_offset [ 0 ] [ refn0 ] [ 0 ] , h - > chroma_offset [ 1 ] [ refn1 ] [ 0 ] ) ;
chroma_weight_avg ( dest_cr , tmp_cr , s - > uvlinesize , h - > chroma_log2_weight_denom ,
h - > chroma_weight [ 0 ] [ refn0 ] [ 1 ] , h - > chroma_weight [ 1 ] [ refn1 ] [ 1 ] ,
h - > chroma_offset [ 0 ] [ refn0 ] [ 1 ] , h - > chroma_offset [ 1 ] [ refn1 ] [ 1 ] ) ;
}
} else {
int list = list1 ? 1 : 0 ;
int refn = h - > ref_cache [ list ] [ scan8 [ n ] ] ;
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 ) ;
luma_weight_op ( dest_y , s - > linesize , h - > luma_log2_weight_denom ,
h - > luma_weight [ list ] [ refn ] , h - > luma_offset [ list ] [ refn ] ) ;
if ( h - > use_weight_chroma ) {
chroma_weight_op ( dest_cb , s - > uvlinesize , h - > chroma_log2_weight_denom ,
h - > chroma_weight [ list ] [ refn ] [ 0 ] , h - > chroma_offset [ list ] [ refn ] [ 0 ] ) ;
chroma_weight_op ( dest_cr , s - > uvlinesize , h - > chroma_log2_weight_denom ,
h - > chroma_weight [ list ] [ refn ] [ 1 ] , h - > chroma_offset [ list ] [ refn ] [ 1 ] ) ;
}
}
}
static inline void mc_part ( H264Context * h , int n , int square , int chroma_height , int delta ,
uint8_t * dest_y , uint8_t * dest_cb , uint8_t * dest_cr ,
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 ,
h264_weight_func * weight_op , h264_biweight_func * weight_avg ,
int list0 , int list1 ) {
if ( ( h - > use_weight = = 2 & & list0 & & list1
& & ( h - > implicit_weight [ h - > ref_cache [ 0 ] [ scan8 [ n ] ] ] [ h - > ref_cache [ 1 ] [ scan8 [ n ] ] ] ! = 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 ) ;
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 ) ;
}
static 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 ) ) {
qpel_mc_func ( * qpix_avg ) [ 16 ] , h264_chroma_mc_func ( * chroma_avg ) ,
h264_weight_func * weight_op , h264_biweight_func * weight_avg ) {
MpegEncContext * const s = & h - > s ;
const int mb_xy = s - > mb_x + s - > mb_y * s - > mb_stride ;
const int mb_type = s - > current_picture . mb_type [ mb_xy ] ;
@ -2249,20 +2338,25 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t
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 [ 0 ] , & weight_avg [ 0 ] ,
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ) ;
} else if ( IS_16X8 ( mb_type ) ) {
mc_part ( h , 0 , 0 , 4 , 8 , 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 ,
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 ) ) ;
} else if ( IS_8X16 ( mb_type ) ) {
mc_part ( h , 0 , 0 , 8 , 8 * s - > 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 ) ) ;
mc_part ( h , 4 , 0 , 8 , 8 * s - > 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 ) ) ;
} else {
int i ;
@ -2278,20 +2372,25 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t
if ( IS_SUB_8X8 ( sub_mb_type ) ) {
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 ) ) ;
} 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 ,
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 ,
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 ) ) ;
} else if ( IS_SUB_4X8 ( sub_mb_type ) ) {
mc_part ( h , n , 0 , 4 , 4 * s - > 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 ) ) ;
mc_part ( h , n + 1 , 0 , 4 , 4 * s - > 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 ) ) ;
} else {
int j ;
@ -2301,6 +2400,7 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t
int sub_y_offset = y_offset + ( j & 2 ) ;
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 ) ) ;
}
}
@ -2397,6 +2497,8 @@ static void free_tables(H264Context *h){
av_freep ( & h - > mb2b_xy ) ;
av_freep ( & h - > mb2b8_xy ) ;
av_freep ( & h - > s . obmc_scratchpad ) ;
}
/**
@ -2437,6 +2539,8 @@ static int alloc_tables(H264Context *h){
h - > mb2b8_xy [ mb_xy ] = b8_xy ;
}
}
CHECKED_ALLOCZ ( s - > obmc_scratchpad , 16 * s - > linesize + 2 * 8 * s - > uvlinesize ) ;
return 0 ;
fail :
@ -2668,7 +2772,8 @@ static void hl_decode_mb(H264Context *h){
} else if ( s - > codec_id = = CODEC_ID_H264 ) {
hl_motion ( h , dest_y , dest_cb , dest_cr ,
s - > dsp . put_h264_qpel_pixels_tab , s - > dsp . put_h264_chroma_pixels_tab ,
s - > dsp . avg_h264_qpel_pixels_tab , s - > dsp . avg_h264_chroma_pixels_tab ) ;
s - > dsp . avg_h264_qpel_pixels_tab , s - > dsp . avg_h264_chroma_pixels_tab ,
s - > dsp . weight_h264_pixels_tab , s - > dsp . biweight_h264_pixels_tab ) ;
}
@ -2898,9 +3003,14 @@ static int decode_ref_pic_list_reordering(H264Context *h){
static int pred_weight_table ( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
int list , i ;
int luma_def , chroma_def ;
h - > use_weight = 0 ;
h - > use_weight_chroma = 0 ;
h - > luma_log2_weight_denom = get_ue_golomb ( & s - > gb ) ;
h - > chroma_log2_weight_denom = get_ue_golomb ( & s - > gb ) ;
luma_def = 1 < < h - > luma_log2_weight_denom ;
chroma_def = 1 < < h - > chroma_log2_weight_denom ;
for ( list = 0 ; list < 2 ; list + + ) {
for ( i = 0 ; i < h - > ref_count [ list ] ; i + + ) {
@ -2910,6 +3020,12 @@ static int pred_weight_table(H264Context *h){
if ( luma_weight_flag ) {
h - > luma_weight [ list ] [ i ] = get_se_golomb ( & s - > gb ) ;
h - > luma_offset [ list ] [ i ] = get_se_golomb ( & s - > gb ) ;
if ( h - > luma_weight [ list ] [ i ] ! = luma_def
| | h - > luma_offset [ list ] [ i ] ! = 0 )
h - > use_weight = 1 ;
} else {
h - > luma_weight [ list ] [ i ] = luma_def ;
h - > luma_offset [ list ] [ i ] = 0 ;
}
chroma_weight_flag = get_bits1 ( & s - > gb ) ;
@ -2918,14 +3034,62 @@ static int pred_weight_table(H264Context *h){
for ( j = 0 ; j < 2 ; j + + ) {
h - > chroma_weight [ list ] [ i ] [ j ] = get_se_golomb ( & s - > gb ) ;
h - > chroma_offset [ list ] [ i ] [ j ] = get_se_golomb ( & s - > gb ) ;
if ( h - > chroma_weight [ list ] [ i ] [ j ] ! = chroma_def
| | h - > chroma_offset [ list ] [ i ] [ j ] ! = 0 )
h - > use_weight_chroma = 1 ;
}
} else {
int j ;
for ( j = 0 ; j < 2 ; j + + ) {
h - > chroma_weight [ list ] [ i ] [ j ] = chroma_def ;
h - > chroma_offset [ list ] [ i ] [ j ] = 0 ;
}
}
}
if ( h - > slice_type ! = B_TYPE ) break ;
}
h - > use_weight = h - > use_weight | | h - > use_weight_chroma ;
return 0 ;
}
static void implicit_weight_table ( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
int list , i ;
int ref0 , ref1 ;
int cur_poc = s - > current_picture_ptr - > poc ;
if ( h - > ref_count [ 0 ] = = 1 & & h - > ref_count [ 1 ] = = 1
& & h - > ref_list [ 0 ] [ 0 ] . poc + h - > ref_list [ 1 ] [ 0 ] . poc = = 2 * cur_poc ) {
h - > use_weight = 0 ;
h - > use_weight_chroma = 0 ;
return ;
}
h - > use_weight = 2 ;
h - > use_weight_chroma = 2 ;
h - > luma_log2_weight_denom = 5 ;
h - > chroma_log2_weight_denom = 5 ;
/* FIXME: MBAFF */
for ( ref0 = 0 ; ref0 < h - > ref_count [ 0 ] ; ref0 + + ) {
int poc0 = h - > ref_list [ 0 ] [ ref0 ] . poc ;
for ( ref1 = 0 ; ref1 < h - > ref_count [ 1 ] ; ref1 + + ) {
int poc1 = h - > ref_list [ 0 ] [ ref1 ] . poc ;
int td = clip ( poc1 - poc0 , - 128 , 127 ) ;
if ( td ) {
int tb = clip ( cur_poc - poc0 , - 128 , 127 ) ;
int tx = ( 16384 + ( ABS ( td ) > > 1 ) ) / td ;
int dist_scale_factor = clip ( ( tb * tx + 32 ) > > 6 , - 1024 , 1023 ) > > 2 ;
if ( dist_scale_factor < - 64 | | dist_scale_factor > 128 )
h - > implicit_weight [ ref0 ] [ ref1 ] = 32 ;
else
h - > implicit_weight [ ref0 ] [ ref1 ] = 64 - dist_scale_factor ;
} else
h - > implicit_weight [ ref0 ] [ ref1 ] = 32 ;
}
}
}
/**
* instantaneous decoder refresh .
*/
@ -3387,6 +3551,10 @@ static int decode_slice_header(H264Context *h){
if ( ( h - > pps . weighted_pred & & ( h - > slice_type = = P_TYPE | | h - > slice_type = = SP_TYPE ) )
| | ( h - > pps . weighted_bipred_idc = = 1 & & h - > slice_type = = B_TYPE ) )
pred_weight_table ( h ) ;
else if ( h - > pps . weighted_bipred_idc = = 2 & & h - > slice_type = = B_TYPE )
implicit_weight_table ( h ) ;
else
h - > use_weight = 0 ;
if ( s - > current_picture . reference )
decode_ref_pic_marking ( h ) ;
@ -3431,14 +3599,16 @@ static int decode_slice_header(H264Context *h){
h - > slice_num + + ;
if ( s - > avctx - > debug & FF_DEBUG_PICT_INFO ) {
av_log ( h - > s . avctx , AV_LOG_DEBUG , " slice:%d mb:%d %c pps:%d frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d \n " ,
av_log ( h - > s . avctx , AV_LOG_DEBUG , " slice:%d mb:%d %c pps:%d frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d weight:%d%s \n " ,
h - > slice_num , first_mb_in_slice ,
av_get_pict_type_char ( h - > slice_type ) ,
pps_id , h - > frame_num ,
s - > current_picture_ptr - > field_poc [ 0 ] , s - > current_picture_ptr - > field_poc [ 1 ] ,
h - > ref_count [ 0 ] , h - > ref_count [ 1 ] ,
s - > qscale ,
h - > deblocking_filter
h - > deblocking_filter ,
h - > use_weight ,
h - > use_weight = = 1 & & h - > use_weight_chroma ? " c " : " "
) ;
}