[x264-devel] commit: Optimize neighbor CBP calculation and fix related regression ( Jason Garrett-Glaser )

git version control git at videolan.org
Mon Feb 16 14:59:59 CET 2009


x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Mon Feb 16 05:56:12 2009 -0800| [a933a3e6a6be918a2ae56e3d94ecea29143b9ea5] | committer: Jason Garrett-Glaser 

Optimize neighbor CBP calculation and fix related regression
r1105 introduced array overflow in cbp handling

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=a933a3e6a6be918a2ae56e3d94ecea29143b9ea5
---

 common/common.h     |    4 ++++
 common/macroblock.c |    4 ++++
 encoder/cabac.c     |   37 ++++++++++++++-----------------------
 3 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/common/common.h b/common/common.h
index 394f9da..c8fb1d9 100644
--- a/common/common.h
+++ b/common/common.h
@@ -529,6 +529,10 @@ struct x264_t
             /* number of neighbors (top and left) that used 8x8 dct */
             int     i_neighbour_transform_size;
             int     i_neighbour_interlaced;
+
+            /* neighbor CBPs */
+            int     i_cbp_top;
+            int     i_cbp_left;
         } cache;
 
         /* */
diff --git a/common/macroblock.c b/common/macroblock.c
index 5f73c9b..71b0906 100644
--- a/common/macroblock.c
+++ b/common/macroblock.c
@@ -897,6 +897,7 @@ void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y )
     {
         h->mb.i_mb_type_top =
         i_top_type= h->mb.type[i_top_xy];
+        h->mb.cache.i_cbp_top = h->mb.cbp[i_top_xy];
 
         h->mb.i_neighbour |= MB_TOP;
 
@@ -912,6 +913,7 @@ void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y )
     else
     {
         h->mb.i_mb_type_top = -1;
+        h->mb.cache.i_cbp_top = -1;
 
         /* load intra4x4 */
         h->mb.cache.intra4x4_pred_mode[x264_scan8[0] - 8] =
@@ -935,6 +937,7 @@ void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y )
         i_left_xy = i_mb_xy - 1;
         h->mb.i_mb_type_left =
         i_left_type = h->mb.type[i_left_xy];
+        h->mb.cache.i_cbp_left = h->mb.cbp[h->mb.i_mb_xy - 1];
 
         h->mb.i_neighbour |= MB_LEFT;
 
@@ -959,6 +962,7 @@ void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y )
     else
     {
         h->mb.i_mb_type_left = -1;
+        h->mb.cache.i_cbp_left = -1;
 
         h->mb.cache.intra4x4_pred_mode[x264_scan8[0 ] - 1] =
         h->mb.cache.intra4x4_pred_mode[x264_scan8[2 ] - 1] =
diff --git a/encoder/cabac.c b/encoder/cabac.c
index f84c1b4..8e3fba0 100644
--- a/encoder/cabac.c
+++ b/encoder/cabac.c
@@ -233,8 +233,8 @@ static void x264_cabac_mb_intra_chroma_pred_mode( x264_t *h, x264_cabac_t *cb )
 static void x264_cabac_mb_cbp_luma( x264_t *h, x264_cabac_t *cb )
 {
     int cbp = h->mb.i_cbp_luma;
-    int cbp_l = h->mb.i_neighbour & MB_LEFT ? h->mb.cbp[h->mb.i_mb_xy - 1] : -1;
-    int cbp_t = h->mb.i_neighbour & MB_TOP ? h->mb.cbp[h->mb.i_mb_top_xy] : -1;
+    int cbp_l = h->mb.cache.i_cbp_left;
+    int cbp_t = h->mb.cache.i_cbp_top;
     x264_cabac_encode_decision( cb, 76 - ((cbp_l >> 1) & 1) - ((cbp_t >> 1) & 2), (h->mb.i_cbp_luma >> 0) & 1 );
     x264_cabac_encode_decision( cb, 76 - ((cbp   >> 0) & 1) - ((cbp_t >> 2) & 2), (h->mb.i_cbp_luma >> 1) & 1 );
     x264_cabac_encode_decision( cb, 76 - ((cbp_l >> 3) & 1) - ((cbp   << 1) & 2), (h->mb.i_cbp_luma >> 2) & 1 );
@@ -243,20 +243,12 @@ static void x264_cabac_mb_cbp_luma( x264_t *h, x264_cabac_t *cb )
 
 static void x264_cabac_mb_cbp_chroma( x264_t *h, x264_cabac_t *cb )
 {
-    int cbp_a = -1;
-    int cbp_b = -1;
-    int ctx;
-
-    /* No need to test for SKIP/PCM */
-    if( h->mb.i_neighbour & MB_LEFT )
-        cbp_a = (h->mb.cbp[h->mb.i_mb_xy - 1] >> 4)&0x3;
+    int cbp_a = h->mb.cache.i_cbp_left & 0x30;
+    int cbp_b = h->mb.cache.i_cbp_top  & 0x30;
+    int ctx = 0;
 
-    if( h->mb.i_neighbour & MB_TOP )
-        cbp_b = (h->mb.cbp[h->mb.i_mb_top_xy] >> 4)&0x3;
-
-    ctx = 0;
-    if( cbp_a > 0 ) ctx++;
-    if( cbp_b > 0 ) ctx += 2;
+    if( cbp_a && h->mb.cache.i_cbp_left != -1 ) ctx++;
+    if( cbp_b && h->mb.cache.i_cbp_top  != -1 ) ctx+=2;
     if( h->mb.i_cbp_chroma == 0 )
         x264_cabac_encode_decision_noup( cb, 77 + ctx, 0 );
     else
@@ -264,8 +256,8 @@ static void x264_cabac_mb_cbp_chroma( x264_t *h, x264_cabac_t *cb )
         x264_cabac_encode_decision_noup( cb, 77 + ctx, 1 );
 
         ctx = 4;
-        if( cbp_a == 2 ) ctx++;
-        if( cbp_b == 2 ) ctx += 2;
+        if( cbp_a == 0x20 ) ctx++;
+        if( cbp_b == 0x20 ) ctx += 2;
         x264_cabac_encode_decision_noup( cb, 77 + ctx, h->mb.i_cbp_chroma > 1 );
     }
 }
@@ -531,15 +523,14 @@ static int ALWAYS_INLINE x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int
             i_nzb &= 0x7f + (b_intra << 7);
             return 4*i_cat + 2*!!i_nzb + !!i_nza;
         case DCT_LUMA_DC:
-            /* Note: this depends on the exact values of MB_LEFT and MB_TOP enums */
-            i_nza = ((h->mb.cbp[h->mb.i_mb_xy - 1] >> 8) | ~h->mb.i_neighbour) & 1;
-            i_nzb = ((h->mb.cbp[h->mb.i_mb_top_xy] >> 7) | ~h->mb.i_neighbour) & 2;
-            return 4*i_cat + i_nzb + i_nza;
+            i_nza = (h->mb.cache.i_cbp_left >> 8) & 1;
+            i_nzb = (h->mb.cache.i_cbp_top  >> 8) & 1;
+            return 4*i_cat + 2*i_nzb + i_nza;
         case DCT_CHROMA_DC:
             /* no need to test skip/pcm */
             i_idx -= 25;
-            i_nza = h->mb.i_neighbour & MB_LEFT ? (h->mb.cbp[h->mb.i_mb_xy - 1] >> (9 + i_idx)) & 1 : b_intra;
-            i_nzb = h->mb.i_neighbour & MB_TOP  ? (h->mb.cbp[h->mb.i_mb_top_xy] >> (9 + i_idx)) & 1 : b_intra;
+            i_nza = h->mb.cache.i_cbp_left != -1 ? (h->mb.cache.i_cbp_left >> (9 + i_idx)) & 1 : b_intra;
+            i_nzb = h->mb.cache.i_cbp_top  != -1 ? (h->mb.cache.i_cbp_top  >> (9 + i_idx)) & 1 : b_intra;
             return 4*i_cat + 2*i_nzb + i_nza;
         default:
             return 0;



More information about the x264-devel mailing list