]> git.sesse.net Git - x264/commitdiff
MBAFF: CABAC encoding of skips
authorSimon Horlick <simonhorlick@gmail.com>
Tue, 29 Mar 2011 14:46:34 +0000 (15:46 +0100)
committerFiona Glaser <fiona@x264.com>
Thu, 12 May 2011 06:06:19 +0000 (23:06 -0700)
common/common.h
common/macroblock.c
encoder/cabac.c

index 263f99414a4f0bed5324d48fb72777fa89a623fb..f19f2f646cbab9b0c8b1a5290e23970953dae727 100644 (file)
@@ -750,6 +750,7 @@ struct x264_t
 
             /* number of neighbors (top and left) that used 8x8 dct */
             int     i_neighbour_transform_size;
+            int     i_neighbour_skip;
 
             /* neighbor CBPs */
             int     i_cbp_top;
index e597d199b763ff3e4fee3f359dc6458fc51c04a0..0ae560b7be93d3471f99343dfbb6fe01cf0187fd 100644 (file)
@@ -1138,6 +1138,35 @@ void x264_macroblock_cache_load( x264_t *h, int mb_x, int mb_y )
         }
     }
 
+    if( h->param.b_cabac )
+    {
+        int left_xy, top_xy;
+        if( h->sh.b_mbaff )
+        {
+            /* Neighbours here are calculated based on field_decoding_flag */
+            int mb_xy = mb_x + (mb_y&~1)*h->mb.i_mb_stride;
+            left_xy = mb_xy - 1;
+            if( (mb_y&1) && mb_x > 0 && h->mb.field_decoding_flag == h->mb.field[left_xy] )
+                left_xy += h->mb.i_mb_stride;
+            if( h->mb.field_decoding_flag )
+            {
+                top_xy = mb_xy - h->mb.i_mb_stride;
+                if( !(mb_y&1) && top_xy >= 0 && h->mb.slice_table[top_xy] == h->sh.i_first_mb && h->mb.field[top_xy] )
+                    top_xy -= h->mb.i_mb_stride;
+            }
+            else
+                top_xy = mb_x + (mb_y-1)*h->mb.i_mb_stride;
+        }
+        else
+        {
+            left_xy = h->mb.i_mb_left_xy[0];
+            top_xy = h->mb.i_mb_top_xy;
+        }
+
+        h->mb.cache.i_neighbour_skip =   (mb_x >  0 && h->mb.slice_table[left_xy] == h->sh.i_first_mb && !IS_SKIP( h->mb.type[left_xy] ))
+                                     + (top_xy >= 0 && h->mb.slice_table[top_xy]  == h->sh.i_first_mb && !IS_SKIP( h->mb.type[top_xy] ));
+    }
+
     /* load skip */
     if( h->sh.i_type == SLICE_TYPE_B )
     {
index 7f9750dfe676e48380bbf741456d65cc9c6d905c..139a3efd48e866118c6a9f95716d52e63147110e 100644 (file)
@@ -296,9 +296,9 @@ static void x264_cabac_mb_qp_delta( x264_t *h, x264_cabac_t *cb )
 #if !RDO_SKIP_BS
 void x264_cabac_mb_skip( x264_t *h, int b_skip )
 {
-    int ctx = ((h->mb.i_neighbour & MB_LEFT) && !IS_SKIP( h->mb.i_mb_type_left[0] ))
-            + ((h->mb.i_neighbour & MB_TOP) && !IS_SKIP( h->mb.i_mb_type_top ))
-            + (h->sh.i_type == SLICE_TYPE_P ? 11 : 24);
+    int ctx = h->mb.cache.i_neighbour_skip + 11;
+    if( h->sh.i_type != SLICE_TYPE_P )
+       ctx += 13;
     x264_cabac_encode_decision( &h->cabac, ctx, b_skip );
 }
 #endif
@@ -351,7 +351,7 @@ static void x264_cabac_mb_ref( x264_t *h, x264_cabac_t *cb, int i_list, int idx
     const int i8 = x264_scan8[idx];
     const int i_refa = h->mb.cache.ref[i_list][i8 - 1];
     const int i_refb = h->mb.cache.ref[i_list][i8 - 8];
-    int ctx  = 0;
+    int ctx = 0;
 
     if( i_refa > 0 && !h->mb.cache.skip[i8 - 1] )
         ctx++;