Commit b02dd712 authored by Fiona Glaser's avatar Fiona Glaser

Fix weightb with delta_poc_bottom

Has no effect yet, but will be required once we add TFF/BFF signalling support in interlaced mode.
Gives 0.5-0.7% better compression with proper TFF/BFF signalling.
parent 12353fb9
...@@ -651,7 +651,8 @@ struct x264_t ...@@ -651,7 +651,8 @@ struct x264_t
/* B_direct and weighted prediction */ /* B_direct and weighted prediction */
int16_t dist_scale_factor[16][2]; int16_t dist_scale_factor[16][2];
int16_t bipred_weight[32][4]; int8_t bipred_weight_buf[2][32][4];
int8_t (*bipred_weight)[4];
/* maps fref1[0]'s ref indices into the current list0 */ /* maps fref1[0]'s ref indices into the current list0 */
#define map_col_to_list0(col) h->mb.map_col_to_list0[col+2] #define map_col_to_list0(col) h->mb.map_col_to_list0[col+2]
int8_t map_col_to_list0[18]; int8_t map_col_to_list0[18];
......
...@@ -1235,16 +1235,20 @@ void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y ) ...@@ -1235,16 +1235,20 @@ void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y )
} }
/* load skip */ /* load skip */
if( h->sh.i_type == SLICE_TYPE_B && h->param.b_cabac ) if( h->sh.i_type == SLICE_TYPE_B )
{ {
uint8_t skipbp; h->mb.bipred_weight = h->mb.bipred_weight_buf[h->mb.b_interlaced&(i_mb_y&1)];
x264_macroblock_cache_skip( h, 0, 0, 4, 4, 0 ); if( h->param.b_cabac )
skipbp = i_left_type >= 0 ? h->mb.skipbp[i_left_xy] : 0; {
h->mb.cache.skip[x264_scan8[0] - 1] = skipbp & 0x2; uint8_t skipbp;
h->mb.cache.skip[x264_scan8[8] - 1] = skipbp & 0x8; x264_macroblock_cache_skip( h, 0, 0, 4, 4, 0 );
skipbp = i_top_type >= 0 ? h->mb.skipbp[i_top_xy] : 0; skipbp = i_left_type >= 0 ? h->mb.skipbp[i_left_xy] : 0;
h->mb.cache.skip[x264_scan8[0] - 8] = skipbp & 0x4; h->mb.cache.skip[x264_scan8[0] - 1] = skipbp & 0x2;
h->mb.cache.skip[x264_scan8[4] - 8] = skipbp & 0x8; h->mb.cache.skip[x264_scan8[8] - 1] = skipbp & 0x8;
skipbp = i_top_type >= 0 ? h->mb.skipbp[i_top_xy] : 0;
h->mb.cache.skip[x264_scan8[0] - 8] = skipbp & 0x4;
h->mb.cache.skip[x264_scan8[4] - 8] = skipbp & 0x8;
}
} }
if( h->sh.i_type == SLICE_TYPE_P ) if( h->sh.i_type == SLICE_TYPE_P )
...@@ -1446,45 +1450,50 @@ void x264_macroblock_cache_save( x264_t *h ) ...@@ -1446,45 +1450,50 @@ void x264_macroblock_cache_save( x264_t *h )
} }
} }
void x264_macroblock_bipred_init( x264_t *h ) void x264_macroblock_bipred_init( x264_t *h )
{ {
int i_ref0, i_ref1; int i_ref0, i_ref1, field;
for( i_ref0 = 0; i_ref0 < h->i_ref0; i_ref0++ ) for( field = 0; field <= h->sh.b_mbaff; field++ )
{ for( i_ref0 = 0; i_ref0 < (h->i_ref0<<h->sh.b_mbaff); i_ref0++ )
int poc0 = h->fref0[i_ref0]->i_poc;
for( i_ref1 = 0; i_ref1 < h->i_ref1; i_ref1++ )
{ {
int dist_scale_factor; int poc0 = h->fref0[i_ref0>>h->sh.b_mbaff]->i_poc;
int poc1 = h->fref1[i_ref1]->i_poc; if( h->sh.b_mbaff && field^(i_ref0&1) )
int td = x264_clip3( poc1 - poc0, -128, 127 ); poc0 += h->sh.i_delta_poc_bottom;
if( td == 0 /* || pic0 is a long-term ref */ ) for( i_ref1 = 0; i_ref1 < (h->i_ref1<<h->sh.b_mbaff); i_ref1++ )
dist_scale_factor = 256;
else
{ {
int tb = x264_clip3( h->fdec->i_poc - poc0, -128, 127 ); int dist_scale_factor;
int tx = (16384 + (abs(td) >> 1)) / td; int poc1 = h->fref1[i_ref1>>h->sh.b_mbaff]->i_poc;
dist_scale_factor = x264_clip3( (tb * tx + 32) >> 6, -1024, 1023 ); if( h->sh.b_mbaff && field^(i_ref1&1) )
} poc1 += h->sh.i_delta_poc_bottom;
h->mb.dist_scale_factor[i_ref0][i_ref1] = dist_scale_factor; int cur_poc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom;
int td = x264_clip3( poc1 - poc0, -128, 127 );
if( td == 0 /* || pic0 is a long-term ref */ )
dist_scale_factor = 256;
else
{
int tb = x264_clip3( cur_poc - poc0, -128, 127 );
int tx = (16384 + (abs(td) >> 1)) / td;
dist_scale_factor = x264_clip3( (tb * tx + 32) >> 6, -1024, 1023 );
}
dist_scale_factor >>= 2; // FIXME: will need this if we ever do temporal MV pred with interlaced
if( h->param.analyse.b_weighted_bipred if( !h->sh.b_mbaff )
&& dist_scale_factor >= -64 h->mb.dist_scale_factor[i_ref0][i_ref1] = dist_scale_factor;
&& dist_scale_factor <= 128 )
{ dist_scale_factor >>= 2;
h->mb.bipred_weight[i_ref0][i_ref1] = 64 - dist_scale_factor; if( h->param.analyse.b_weighted_bipred
// ssse3 implementation of biweight doesn't support the extrema. && dist_scale_factor >= -64
// if we ever generate them, we'll have to drop that optimization. && dist_scale_factor <= 128 )
assert( dist_scale_factor >= -63 && dist_scale_factor <= 127 ); {
h->mb.bipred_weight_buf[field][i_ref0][i_ref1] = 64 - dist_scale_factor;
// ssse3 implementation of biweight doesn't support the extrema.
// if we ever generate them, we'll have to drop that optimization.
assert( dist_scale_factor >= -63 && dist_scale_factor <= 127 );
}
else
h->mb.bipred_weight_buf[field][i_ref0][i_ref1] = 32;
} }
else
h->mb.bipred_weight[i_ref0][i_ref1] = 32;
} }
}
if( h->sh.b_mbaff )
{
for( i_ref0 = 2*h->i_ref0-1; i_ref0 >= 0; i_ref0-- )
for( i_ref1 = 2*h->i_ref1-1; i_ref1 >= 0; i_ref1-- )
h->mb.bipred_weight[i_ref0][i_ref1] = h->mb.bipred_weight[i_ref0>>1][i_ref1>>1];
}
} }
...@@ -1545,7 +1545,7 @@ static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp ) ...@@ -1545,7 +1545,7 @@ static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp )
if( h->sps->i_poc_type == 0 ) if( h->sps->i_poc_type == 0 )
{ {
h->sh.i_poc_lsb = h->fdec->i_poc & ( (1 << h->sps->i_log2_max_poc_lsb) - 1 ); h->sh.i_poc_lsb = h->fdec->i_poc & ( (1 << h->sps->i_log2_max_poc_lsb) - 1 );
h->sh.i_delta_poc_bottom = 0; /* XXX won't work for field */ h->sh.i_delta_poc_bottom = 0;
} }
else if( h->sps->i_poc_type == 1 ) else if( h->sps->i_poc_type == 1 )
{ {
......
...@@ -369,7 +369,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t * ...@@ -369,7 +369,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
pps->i_sps_id = sps->i_id; pps->i_sps_id = sps->i_id;
pps->b_cabac = param->b_cabac; pps->b_cabac = param->b_cabac;
pps->b_pic_order = 0; pps->b_pic_order = param->b_interlaced;
pps->i_num_slice_groups = 1; pps->i_num_slice_groups = 1;
pps->i_num_ref_idx_l0_active = 1; pps->i_num_ref_idx_l0_active = 1;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment