[x264-devel] commit: faster residual_write_cabac (Jason Garrett-Glaser )
git version control
git at videolan.org
Tue May 20 12:08:26 CEST 2008
x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Sun May 18 07:14:28 2008 -0600| [bd6ce404c3c4c51b0133b8c1a3ebeeb4b60265c6]
faster residual_write_cabac
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=bd6ce404c3c4c51b0133b8c1a3ebeeb4b60265c6
---
encoder/cabac.c | 96 ++++++++++++++++++++++++++++++++++--------------------
1 files changed, 60 insertions(+), 36 deletions(-)
diff --git a/encoder/cabac.c b/encoder/cabac.c
index 7e70a25..27c9478 100644
--- a/encoder/cabac.c
+++ b/encoder/cabac.c
@@ -635,17 +635,17 @@ static int x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx )
}
-static const int significant_coeff_flag_offset[2][6] = {
+static const uint16_t significant_coeff_flag_offset[2][6] = {
{ 105, 120, 134, 149, 152, 402 },
{ 277, 292, 306, 321, 324, 436 }
};
-static const int last_coeff_flag_offset[2][6] = {
+static const uint16_t last_coeff_flag_offset[2][6] = {
{ 166, 181, 195, 210, 213, 417 },
{ 338, 353, 367, 382, 385, 451 }
};
-static const int coeff_abs_level_m1_offset[6] =
+static const uint16_t coeff_abs_level_m1_offset[6] =
{ 227, 237, 247, 257, 266, 426 };
-static const int significant_coeff_flag_offset_8x8[2][63] =
+static const uint8_t significant_coeff_flag_offset_8x8[2][63] =
{{
0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5,
4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7,
@@ -657,13 +657,13 @@ static const int significant_coeff_flag_offset_8x8[2][63] =
9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9,
9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14
}};
-static const int last_coeff_flag_offset_8x8[63] = {
+static const uint8_t last_coeff_flag_offset_8x8[63] = {
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8
};
-static const int identity[16] =
+static const uint8_t identity[16] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
// node ctx: 0..3: abslevel1 (with abslevelgt1 == 0).
@@ -672,7 +672,7 @@ static const int identity[16] =
static const int coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 };
/* map node ctx => cabac ctx for level>1 */
static const int coeff_abs_levelgt1_ctx[8] = { 5, 5, 5, 5, 6, 7, 8, 9 };
-static const int coeff_abs_level_transition[2][8] = {
+static const uint8_t coeff_abs_level_transition[2][8] = {
/* update node ctx after coding a level=1 */
{ 1, 2, 3, 3, 4, 5, 6, 7 },
/* update node ctx after coding a level>1 */
@@ -686,15 +686,15 @@ static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBl
const int i_ctx_level = coeff_abs_level_m1_offset[i_ctxBlockCat];
int i_coeff_abs_m1[64];
- int i_coeff_sign[64];
+ int UNUSED i_coeff_sign[64];
int i_coeff = 0;
int i_last = 0;
int i_sigmap_size;
int node_ctx = 0;
int i, j;
- const int *significant_coeff_flag_offset;
- const int *last_coeff_flag_offset;
+ const uint8_t *significant_coeff_flag_offset;
+ const uint8_t *last_coeff_flag_offset;
/* i_ctxBlockCat: 0-> DC 16x16 i_idx = 0
* 1-> AC 16x16 i_idx = luma4x4idx
@@ -704,24 +704,22 @@ static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBl
* 5-> Luma8x8 i_idx = luma8x8idx
*/
- for( j = i_count - 4; j >= 0; j -= 4 )
+ /* yes this is always aligned, and l[-1] exists in the cases where it's used (ac) */
+ for( j = i_count - 4; j >= -1; j -= 4 )
if( *(uint64_t*)(l+j) )
break;
- for( i = 0; i < j+4; i++ )
- if( l[i] != 0 )
- {
- i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;
- i_coeff_sign[i_coeff] = l[i] < 0;
- i_coeff++;
- i_last = i;
- }
if( i_count != 64 )
{
/* coded block flag */
- x264_cabac_encode_decision( cb, 85 + x264_cabac_mb_cbf_ctxidxinc( h, i_ctxBlockCat, i_idx ), i_coeff != 0 );
- if( i_coeff == 0 )
+ int ctx = 85 + x264_cabac_mb_cbf_ctxidxinc( h, i_ctxBlockCat, i_idx );
+ if( j >= -1 )
+ x264_cabac_encode_decision( cb, ctx, 1 );
+ else
+ {
+ x264_cabac_encode_decision( cb, ctx, 0 );
return;
+ }
}
significant_coeff_flag_offset = (i_ctxBlockCat == DCT_LUMA_8x8)
@@ -730,33 +728,55 @@ static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBl
last_coeff_flag_offset = (i_ctxBlockCat == DCT_LUMA_8x8)
? last_coeff_flag_offset_8x8 : identity;
+ for( i = j; i < j+4; i++)
+ if( l[i] )
+ i_last = i;
+
i_sigmap_size = X264_MIN( i_last+1, i_count-1 );
+
for( i = 0; i < i_sigmap_size; i++ )
{
- x264_cabac_encode_decision( cb, i_ctx_sig + significant_coeff_flag_offset[i], l[i] != 0 );
- if( l[i] != 0 )
+ if( l[i] )
+ {
+ i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;
+#ifndef RDO_SKIP_BS
+ i_coeff_sign[i_coeff] = l[i] < 0;
+#endif
+ i_coeff++;
+ x264_cabac_encode_decision( cb, i_ctx_sig + significant_coeff_flag_offset[i], 1 );
x264_cabac_encode_decision( cb, i_ctx_last + last_coeff_flag_offset[i], i == i_last );
+ }
+ else
+ x264_cabac_encode_decision( cb, i_ctx_sig + significant_coeff_flag_offset[i], 0 );
+ }
+
+ if( i == i_last )
+ {
+ i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;
+#ifndef RDO_SKIP_BS
+ i_coeff_sign[i_coeff] = l[i] < 0;
+#endif
+ i_coeff++;
}
for( i = i_coeff - 1; i >= 0; i-- )
{
/* write coeff_abs - 1 */
- const int i_prefix = X264_MIN( i_coeff_abs_m1[i], 14 );
- const int i_ctxIdxInc = coeff_abs_level1_ctx[node_ctx] + i_ctx_level;
- x264_cabac_encode_decision( cb, i_ctxIdxInc, i_prefix != 0 );
+ int i_prefix = X264_MIN( i_coeff_abs_m1[i], 14 );
+ int ctx = coeff_abs_level1_ctx[node_ctx] + i_ctx_level;
- if( i_prefix != 0 )
+ if( i_prefix )
{
- const int i_ctxIdxInc = coeff_abs_levelgt1_ctx[node_ctx] + i_ctx_level;
+ x264_cabac_encode_decision( cb, ctx, 1 );
+ ctx = coeff_abs_levelgt1_ctx[node_ctx] + i_ctx_level;
#ifdef RDO_SKIP_BS
- cb->f8_bits_encoded += cabac_prefix_size[i_prefix][cb->state[i_ctxIdxInc]];
- cb->state[i_ctxIdxInc] = cabac_prefix_transition[i_prefix][cb->state[i_ctxIdxInc]];
+ cb->f8_bits_encoded += cabac_prefix_size[i_prefix][cb->state[ctx]];
+ cb->state[ctx] = cabac_prefix_transition[i_prefix][cb->state[ctx]];
#else
- int j;
for( j = 0; j < i_prefix - 1; j++ )
- x264_cabac_encode_decision( cb, i_ctxIdxInc, 1 );
+ x264_cabac_encode_decision( cb, ctx, 1 );
if( i_prefix < 14 )
- x264_cabac_encode_decision( cb, i_ctxIdxInc, 0 );
+ x264_cabac_encode_decision( cb, ctx, 0 );
#endif
if( i_prefix >= 14 )
x264_cabac_encode_ue_bypass( cb, 0, i_coeff_abs_m1[i] - 14 );
@@ -764,13 +784,17 @@ static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBl
node_ctx = coeff_abs_level_transition[1][node_ctx];
}
else
+ {
+ x264_cabac_encode_decision( cb, ctx, 0 );
node_ctx = coeff_abs_level_transition[0][node_ctx];
-
- /* write sign */
#ifdef RDO_SKIP_BS
- if( i_prefix == 0 )
+ x264_cabac_encode_bypass( cb, 0 ); // sign
#endif
+ }
+
+#ifndef RDO_SKIP_BS
x264_cabac_encode_bypass( cb, i_coeff_sign[i] );
+#endif
}
}
More information about the x264-devel
mailing list