[x264-devel] Precalculate CABAC initialization contexts

Jason Garrett-Glaser git at videolan.org
Tue Apr 26 07:49:12 CEST 2011


x264 | branch: master | Jason Garrett-Glaser <jason at x264.com> | Sun Apr 24 18:36:26 2011 -0700| [b5a8ad7e0047ec65cb01d64b1151e358a7b84314] | committer: Jason Garrett-Glaser

Precalculate CABAC initialization contexts
Slightly faster encoding with lots of slices.

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

 common/cabac.c    |   29 +++++++++++++++++------------
 common/common.h   |    3 ++-
 common/vlc.c      |    2 +-
 encoder/encoder.c |    6 ++++--
 tools/checkasm.c  |    1 +
 5 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/common/cabac.c b/common/cabac.c
index 5623f75..01c262a 100644
--- a/common/cabac.c
+++ b/common/cabac.c
@@ -753,24 +753,29 @@ const uint16_t x264_cabac_entropy[128] =
     FIX8(0.9285), FIX8(1.0752), FIX8(1.0000), FIX8(1.0000)
 };
 
+uint8_t x264_cabac_contexts[4][QP_MAX_SPEC+1][460];
+
+void x264_cabac_init( void )
+{
+    for( int i = 0; i < 4; i++ )
+    {
+        const int8_t (*cabac_context_init)[460][2] = i == 0 ? &x264_cabac_context_init_I
+                                                            : &x264_cabac_context_init_PB[i-1];
+        for( int qp = 0; qp <= QP_MAX_SPEC; qp++ )
+            for( int j = 0; j < 460; j++ )
+            {
+                int state = x264_clip3( (((*cabac_context_init)[j][0] * qp) >> 4) + (*cabac_context_init)[j][1], 1, 126 );
+                x264_cabac_contexts[i][qp][j] = (X264_MIN( state, 127-state ) << 1) | (state >> 6);
+            }
+    }
+}
 
 /*****************************************************************************
  *
  *****************************************************************************/
 void x264_cabac_context_init( x264_cabac_t *cb, int i_slice_type, int i_qp, int i_model )
 {
-    const int8_t (*cabac_context_init)[460][2];
-
-    if( i_slice_type == SLICE_TYPE_I )
-        cabac_context_init = &x264_cabac_context_init_I;
-    else
-        cabac_context_init = &x264_cabac_context_init_PB[i_model];
-
-    for( int i = 0; i < 460; i++ )
-    {
-        int state = x264_clip3( (((*cabac_context_init)[i][0] * i_qp) >> 4) + (*cabac_context_init)[i][1], 1, 126 );
-        cb->state[i] = (X264_MIN( state, 127-state ) << 1) | (state >> 6);
-    }
+    memcpy( cb->state, x264_cabac_contexts[i_slice_type == SLICE_TYPE_I ? 0 : i_model + 1][i_qp], 460 );
 }
 
 void x264_cabac_encode_init_core( x264_cabac_t *cb )
diff --git a/common/common.h b/common/common.h
index 03211eb..1fe8662 100644
--- a/common/common.h
+++ b/common/common.h
@@ -205,7 +205,8 @@ void x264_log( x264_t *h, int i_level, const char *psz_fmt, ... );
 
 void x264_reduce_fraction( uint32_t *n, uint32_t *d );
 void x264_reduce_fraction64( uint64_t *n, uint64_t *d );
-void x264_init_vlc_tables( void );
+void x264_cavlc_init( void );
+void x264_cabac_init( void );
 
 static ALWAYS_INLINE pixel x264_clip_pixel( int x )
 {
diff --git a/common/vlc.c b/common/vlc.c
index fc2fc50..0968705 100644
--- a/common/vlc.c
+++ b/common/vlc.c
@@ -695,7 +695,7 @@ const vlc_t x264_run_before[7][16] =
 
 vlc_large_t x264_level_token[7][LEVEL_TABLE_SIZE];
 
-void x264_init_vlc_tables( void )
+void x264_cavlc_init( void )
 {
     for( int i_suffix = 0; i_suffix < 7; i_suffix++ )
         for( int16_t level = -LEVEL_TABLE_SIZE/2; level < LEVEL_TABLE_SIZE/2; level++ )
diff --git a/encoder/encoder.c b/encoder/encoder.c
index 872800c..e81172d 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -1090,8 +1090,10 @@ x264_t *x264_encoder_open( x264_param_t *param )
     x264_predict_8x8c_init( h->param.cpu, h->predict_8x8c );
     x264_predict_8x8_init( h->param.cpu, h->predict_8x8, &h->predict_8x8_filter );
     x264_predict_4x4_init( h->param.cpu, h->predict_4x4 );
-    if( !h->param.b_cabac )
-        x264_init_vlc_tables();
+    if( h->param.b_cabac )
+        x264_cabac_init();
+    else
+        x264_cavlc_init();
     x264_pixel_init( h->param.cpu, &h->pixf );
     x264_dct_init( h->param.cpu, &h->dctf );
     x264_zigzag_init( h->param.cpu, &h->zigzagf, h->param.b_interlaced );
diff --git a/tools/checkasm.c b/tools/checkasm.c
index eda0d4f..bf7ce7b 100644
--- a/tools/checkasm.c
+++ b/tools/checkasm.c
@@ -1894,6 +1894,7 @@ static int check_cabac( int cpu_ref, int cpu_new )
     int ret = 0, ok, used_asm = 1;
     if( cpu_ref || run_cabac_decision_c == run_cabac_decision_asm )
         return 0;
+    x264_cabac_init();
 
     set_func_name( "cabac_encode_decision" );
     memcpy( buf4, buf3, 0x1000 );



More information about the x264-devel mailing list