From 9588ec340c3f33c7474b4cd2893046cfdaee42bf Mon Sep 17 00:00:00 2001 From: Alexander Strange Date: Wed, 2 Jul 2008 22:08:12 +0000 Subject: [PATCH] Clone decode_cabac_residual() for DC residuals, to get rid of a bunch of branches in the main loop. Originally committed as revision 14050 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/h264.c | 59 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index b667547a14..4e5e7e7e0a 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -5337,24 +5337,28 @@ static int decode_cabac_mb_mvd( H264Context *h, int list, int n, int l ) { return get_cabac_bypass_sign( &h->cabac, -mvd ); } -static inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx ) { +static av_always_inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx, int is_dc ) { int nza, nzb; int ctx = 0; + if( is_dc ) { if( cat == 0 ) { nza = h->left_cbp&0x100; nzb = h-> top_cbp&0x100; - } else if( cat == 1 || cat == 2 ) { - nza = h->non_zero_count_cache[scan8[idx] - 1]; - nzb = h->non_zero_count_cache[scan8[idx] - 8]; - } else if( cat == 3 ) { + } else { nza = (h->left_cbp>>(6+idx))&0x01; nzb = (h-> top_cbp>>(6+idx))&0x01; + } + } else { + if( cat == 1 || cat == 2 ) { + nza = h->non_zero_count_cache[scan8[idx] - 1]; + nzb = h->non_zero_count_cache[scan8[idx] - 8]; } else { assert(cat == 4); nza = h->non_zero_count_cache[scan8[16+idx] - 1]; nzb = h->non_zero_count_cache[scan8[16+idx] - 8]; } + } if( nza > 0 ) ctx++; @@ -5372,7 +5376,7 @@ DECLARE_ASM_CONST(1, uint8_t, last_coeff_flag_offset_8x8[63]) = { 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8 }; -static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff) { +static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff, int is_dc ) { static const int significant_coeff_flag_offset[2][6] = { { 105+0, 105+15, 105+29, 105+44, 105+47, 402 }, { 277+0, 277+15, 277+29, 277+44, 277+47, 436 } @@ -5440,12 +5444,15 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int */ /* read coded block flag */ - if( cat != 5 ) { - if( get_cabac( CC, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n ) ] ) == 0 ) { + if( is_dc || cat != 5 ) { + if( get_cabac( CC, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n, is_dc ) ] ) == 0 ) { + if( !is_dc ) { if( cat == 1 || cat == 2 ) h->non_zero_count_cache[scan8[n]] = 0; - else if( cat == 4 ) + else h->non_zero_count_cache[scan8[16+n]] = 0; + } + #ifdef CABAC_ON_STACK h->cabac.range = cc.range ; h->cabac.low = cc.low ; @@ -5462,7 +5469,7 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int abs_level_m1_ctx_base = h->cabac_state + coeff_abs_level_m1_offset[cat]; - if( cat == 5 ) { + if( !is_dc && cat == 5 ) { #define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \ for(last= 0; last < coefs; last++) { \ uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \ @@ -5491,18 +5498,21 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int } assert(coeff_count > 0); + if( is_dc ) { if( cat == 0 ) h->cbp_table[h->mb_xy] |= 0x100; - else if( cat == 1 || cat == 2 ) - h->non_zero_count_cache[scan8[n]] = coeff_count; - else if( cat == 3 ) + else h->cbp_table[h->mb_xy] |= 0x40 << n; + } else { + if( cat == 1 || cat == 2 ) + h->non_zero_count_cache[scan8[n]] = coeff_count; else if( cat == 4 ) h->non_zero_count_cache[scan8[16+n]] = coeff_count; else { assert( cat == 5 ); fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1); } + } for( coeff_count--; coeff_count >= 0; coeff_count-- ) { uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; @@ -5511,7 +5521,7 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int if( get_cabac( CC, ctx ) == 0 ) { node_ctx = coeff_abs_level_transition[0][node_ctx]; - if( !qmul ) { + if( is_dc ) { block[j] = get_cabac_bypass_sign( CC, -1); }else{ block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; @@ -5538,7 +5548,7 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int coeff_abs+= 14; } - if( !qmul ) { + if( is_dc ) { if( get_cabac_bypass( CC ) ) block[j] = -coeff_abs; else block[j] = coeff_abs; }else{ @@ -5555,6 +5565,25 @@ static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int } +#ifndef CONFIG_SMALL +static void decode_cabac_residual_dc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) { + decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 1); +} + +static void decode_cabac_residual_nondc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) { + decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0); +} +#endif + +static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) { +#ifdef CONFIG_SMALL + decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, cat == 0 || cat == 3); +#else + if( cat == 0 || cat == 3 ) decode_cabac_residual_dc(h, block, cat, n, scantable, qmul, max_coeff); + else decode_cabac_residual_nondc(h, block, cat, n, scantable, qmul, max_coeff); +#endif +} + static inline void compute_mb_neighbors(H264Context *h) { MpegEncContext * const s = &h->s;