]> granicus.if.org Git - libx264/commitdiff
Fix reconfiguration of b_tff
authorFiona Glaser <fiona@x264.com>
Mon, 24 Jan 2011 05:03:14 +0000 (21:03 -0800)
committerFiona Glaser <fiona@x264.com>
Tue, 25 Jan 2011 10:42:21 +0000 (02:42 -0800)
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
common/macroblock.c
common/mvpred.c
encoder/encoder.c
encoder/set.c

index 2097ad9a68353ec5cfe1ce04e24ba3146e7c2f22..f5eba7d70a5ff343b7e513a7776a8778315130ee 100644 (file)
@@ -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;
index 5a06d241185b3f3fd444079770dc9e51a426a94e..42216caede79f55fb202908202aea0e156d4bbaa 100644 (file)
@@ -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]<<h->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]<<h->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;
index 3534a0c18a081808c3e79eded9594b8c28ad2232..e93def3d2d1ec0bafddb254089c46fed208170ce 100644 (file)
@@ -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 ) \
         { \
index dbe4b0e799d7e6aa88ebc4072cc2e9f09614a5f3..0b19a216955887933afa7e069fbd952095b2c05c 100644 (file)
@@ -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++;
 
index 622d16fc6242434eb972b9c4411631c84671c0ae..eb1aa71ab43d76950f4111ef0cf1fffa3c751067 100644 (file)
@@ -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;