Fix weightb with delta_poc_bottom
authorJason Garrett-Glaser <darkshikari@gmail.com>
Wed, 25 Nov 2009 00:21:07 +0000 (16:21 -0800)
committerJason Garrett-Glaser <darkshikari@gmail.com>
Wed, 25 Nov 2009 00:38:11 +0000 (16:38 -0800)
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.

common/common.h
common/macroblock.c
encoder/encoder.c
encoder/set.c

index 1da3c02..eab28e1 100644 (file)
@@ -651,7 +651,8 @@ struct x264_t
 
         /* B_direct and weighted prediction */
         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 */
 #define map_col_to_list0(col) h->mb.map_col_to_list0[col+2]
         int8_t  map_col_to_list0[18];
index 34de9c8..4e93093 100644 (file)
@@ -1235,16 +1235,20 @@ void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y )
         }
 
         /* 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;
-            x264_macroblock_cache_skip( h, 0, 0, 4, 4, 0 );
-            skipbp = i_left_type >= 0 ? h->mb.skipbp[i_left_xy] : 0;
-            h->mb.cache.skip[x264_scan8[0] - 1] = skipbp & 0x2;
-            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;
+            h->mb.bipred_weight = h->mb.bipred_weight_buf[h->mb.b_interlaced&(i_mb_y&1)];
+            if( h->param.b_cabac )
+            {
+                uint8_t skipbp;
+                x264_macroblock_cache_skip( h, 0, 0, 4, 4, 0 );
+                skipbp = i_left_type >= 0 ? h->mb.skipbp[i_left_xy] : 0;
+                h->mb.cache.skip[x264_scan8[0] - 1] = skipbp & 0x2;
+                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 )
@@ -1446,45 +1450,50 @@ void x264_macroblock_cache_save( x264_t *h )
     }
 }
 
+
 void x264_macroblock_bipred_init( x264_t *h )
 {
-    int i_ref0, i_ref1;
-    for( i_ref0 = 0; i_ref0 < h->i_ref0; i_ref0++ )
-    {
-        int poc0 = h->fref0[i_ref0]->i_poc;
-        for( i_ref1 = 0; i_ref1 < h->i_ref1; i_ref1++ )
+    int i_ref0, i_ref1, field;
+    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 dist_scale_factor;
-            int poc1 = h->fref1[i_ref1]->i_poc;
-            int td = x264_clip3( poc1 - poc0, -128, 127 );
-            if( td == 0 /* || pic0 is a long-term ref */ )
-                dist_scale_factor = 256;
-            else
+            int poc0 = h->fref0[i_ref0>>h->sh.b_mbaff]->i_poc;
+            if( h->sh.b_mbaff && field^(i_ref0&1) )
+                poc0 += h->sh.i_delta_poc_bottom;
+            for( i_ref1 = 0; i_ref1 < (h->i_ref1<<h->sh.b_mbaff); i_ref1++ )
             {
-                int tb = x264_clip3( h->fdec->i_poc - poc0, -128, 127 );
-                int tx = (16384 + (abs(td) >> 1)) / td;
-                dist_scale_factor = x264_clip3( (tb * tx + 32) >> 6, -1024, 1023 );
-            }
-            h->mb.dist_scale_factor[i_ref0][i_ref1] = dist_scale_factor;
+                int dist_scale_factor;
+                int poc1 = h->fref1[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;
+                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;
-            if( h->param.analyse.b_weighted_bipred
-                  && dist_scale_factor >= -64
-                  && dist_scale_factor <= 128 )
-            {
-                h->mb.bipred_weight[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 );
+                // FIXME: will need this if we ever do temporal MV pred with interlaced
+                if( !h->sh.b_mbaff )
+                    h->mb.dist_scale_factor[i_ref0][i_ref1] = dist_scale_factor;
+
+                dist_scale_factor >>= 2;
+                if( h->param.analyse.b_weighted_bipred
+                      && dist_scale_factor >= -64
+                      && dist_scale_factor <= 128 )
+                {
+                    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];
-    }
 }
+
index 8905fa0..06e08fa 100644 (file)
@@ -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 )
     {
         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 )
     {
index f108055..5ceb6b6 100644 (file)
@@ -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->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_ref_idx_l0_active = 1;