[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