From 5696ec3b8c69b57bd7bf0692c31578439fce3b5d Mon Sep 17 00:00:00 2001 From: Fiona Glaser Date: Sun, 23 Jan 2011 21:03:14 -0800 Subject: [PATCH] Fix reconfiguration of b_tff Attempting to change field order during encoding could cause slight corruption. Also fix delta_poc_bottom to be correctly set if interlaced mode is used without B-frames. --- common/frame.h | 1 + common/macroblock.c | 18 +++++++----------- common/mvpred.c | 5 ++--- encoder/encoder.c | 13 +++++++------ encoder/set.c | 2 +- 5 files changed, 18 insertions(+), 21 deletions(-) diff --git a/common/frame.h b/common/frame.h index 2097ad9a..f5eba7d7 100644 --- a/common/frame.h +++ b/common/frame.h @@ -36,6 +36,7 @@ typedef struct x264_frame { /* */ int i_poc; + int i_delta_poc[2]; int i_type; int i_qpplus1; int64_t i_pts; diff --git a/common/macroblock.c b/common/macroblock.c index 5a06d241..42216cae 100644 --- a/common/macroblock.c +++ b/common/macroblock.c @@ -419,10 +419,8 @@ void x264_macroblock_slice_init( x264_t *h ) if( h->i_ref[0] > 0 ) for( int field = 0; field <= h->sh.b_mbaff; field++ ) { - int curpoc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom; - int refpoc = h->fref[0][0]->i_poc; - if( h->sh.b_mbaff && field ) - refpoc += h->sh.i_delta_poc_bottom; + int curpoc = h->fdec->i_poc + h->fdec->i_delta_poc[field]; + int refpoc = h->fref[0][0]->i_poc + h->fref[0][0]->i_delta_poc[field]; int delta = curpoc - refpoc; h->fdec->inv_ref_poc[field] = (256 + delta/2) / delta; @@ -1287,16 +1285,14 @@ void x264_macroblock_bipred_init( x264_t *h ) for( int field = 0; field <= h->sh.b_mbaff; field++ ) for( int i_ref0 = 0; i_ref0 < (h->i_ref[0]<sh.b_mbaff); i_ref0++ ) { - int poc0 = h->fref[0][i_ref0>>h->sh.b_mbaff]->i_poc; - if( h->sh.b_mbaff && field^(i_ref0&1) ) - poc0 += h->sh.i_delta_poc_bottom; + x264_frame_t *l0 = h->fref[0][i_ref0>>h->sh.b_mbaff]; + int poc0 = l0->i_poc + l0->i_delta_poc[field^(i_ref0&1)]; for( int i_ref1 = 0; i_ref1 < (h->i_ref[1]<sh.b_mbaff); i_ref1++ ) { int dist_scale_factor; - int poc1 = h->fref[1][i_ref1>>h->sh.b_mbaff]->i_poc; - if( h->sh.b_mbaff && field^(i_ref1&1) ) - poc1 += h->sh.i_delta_poc_bottom; - int cur_poc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom; + x264_frame_t *l1 = h->fref[1][i_ref1>>h->sh.b_mbaff]; + int poc1 = l1->i_poc + l1->i_delta_poc[field^(i_ref1&1)]; + int cur_poc = h->fdec->i_poc + h->fdec->i_delta_poc[field]; int td = x264_clip3( poc1 - poc0, -128, 127 ); if( td == 0 /* || pic0 is a long-term ref */ ) dist_scale_factor = 256; diff --git a/common/mvpred.c b/common/mvpred.c index 3534a0c1..e93def3d 100644 --- a/common/mvpred.c +++ b/common/mvpred.c @@ -437,10 +437,9 @@ void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int16_t mvc[ { x264_frame_t *l0 = h->fref[0][0]; int field = h->mb.i_mb_y&1; - int curpoc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom; + int curpoc = h->fdec->i_poc + h->fdec->i_delta_poc[field]; int refpoc = h->fref[i_list][i_ref>>h->sh.b_mbaff]->i_poc; - if( h->sh.b_mbaff && field^(i_ref&1) ) - refpoc += h->sh.i_delta_poc_bottom; + refpoc += l0->i_delta_poc[field^(i_ref&1)]; #define SET_TMVP( dx, dy ) \ { \ diff --git a/encoder/encoder.c b/encoder/encoder.c index dbe4b0e7..0b19a216 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -1845,11 +1845,12 @@ static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp ) if( h->param.b_interlaced ) { h->sh.i_delta_poc_bottom = h->param.b_tff ? 1 : -1; - if( h->sh.i_delta_poc_bottom == -1 ) - h->sh.i_poc = h->fdec->i_poc + 1; + h->sh.i_poc += h->sh.i_delta_poc_bottom == -1; } else h->sh.i_delta_poc_bottom = 0; + h->fdec->i_delta_poc[0] = h->sh.i_delta_poc_bottom == -1; + h->fdec->i_delta_poc[1] = h->sh.i_delta_poc_bottom == 1; } else if( h->sps->i_poc_type == 1 ) { @@ -2734,15 +2735,15 @@ int x264_encoder_encode( x264_t *h, if( h->i_ref[0] ) h->fdec->i_poc_l0ref0 = h->fref[0][0]->i_poc; + /* ------------------------ Create slice header ----------------------- */ + x264_slice_init( h, i_nal_type, i_global_qp ); + + /*------------------------- Weights -------------------------------------*/ if( h->sh.i_type == SLICE_TYPE_B ) x264_macroblock_bipred_init( h ); - /*------------------------- Weights -------------------------------------*/ x264_weighted_pred_init( h ); - /* ------------------------ Create slice header ----------------------- */ - x264_slice_init( h, i_nal_type, i_global_qp ); - if( i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE ) h->i_frame_num++; diff --git a/encoder/set.c b/encoder/set.c index 622d16fc..eb1aa71a 100644 --- a/encoder/set.c +++ b/encoder/set.c @@ -159,7 +159,7 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param ) while( (1 << sps->i_log2_max_frame_num) <= max_frame_num ) sps->i_log2_max_frame_num++; - sps->i_poc_type = param->i_bframe ? 0 : 2; + sps->i_poc_type = param->i_bframe || param->b_interlaced ? 0 : 2; if( sps->i_poc_type == 0 ) { int max_delta_poc = (param->i_bframe + 2) * (!!param->i_bframe_pyramid + 1) * 2; -- 2.40.0