Precalculate CABAC initialization contexts
authorJason Garrett-Glaser <jason@x264.com>
Mon, 25 Apr 2011 01:36:26 +0000 (18:36 -0700)
committerJason Garrett-Glaser <jason@x264.com>
Tue, 26 Apr 2011 05:45:27 +0000 (22:45 -0700)
Slightly faster encoding with lots of slices.

common/cabac.c
common/common.h
common/vlc.c
encoder/encoder.c
tools/checkasm.c

index 5623f75..01c262a 100644 (file)
@@ -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 )
index 03211eb..1fe8662 100644 (file)
@@ -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 )
 {
index fc2fc50..0968705 100644 (file)
@@ -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++ )
index 872800c..e81172d 100644 (file)
@@ -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 );
index eda0d4f..bf7ce7b 100644 (file)
@@ -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 );