From d869a460dbdc6efbafbf74d1a2ef14eae367179e Mon Sep 17 00:00:00 2001 From: Jason Garrett-Glaser Date: Tue, 19 May 2009 21:29:21 +0000 Subject: [PATCH] LGPL version of ac3_decode_transform_coeffs_ch, ~12.4% faster. Originally committed as revision 18875 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/ac3dec.c | 109 ++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index c176cb3d76..05dfd0db93 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -439,12 +439,12 @@ static void calc_transform_coeffs_cpl(AC3DecodeContext *s) * Grouped mantissas for 3-level 5-level and 11-level quantization */ typedef struct { - int b1_mant[3]; - int b2_mant[3]; - int b4_mant[2]; - int b1ptr; - int b2ptr; - int b4ptr; + int b1_mant[2]; + int b2_mant[2]; + int b4_mant; + int b1; + int b2; + int b4; } mant_groups; /** @@ -453,73 +453,72 @@ typedef struct { */ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m) { + int start_freq = s->start_freq[ch_index]; + int end_freq = s->end_freq[ch_index]; + uint8_t *baps = s->bap[ch_index]; + int8_t *exps = s->dexps[ch_index]; + int *coeffs = s->fixed_coeffs[ch_index]; GetBitContext *gbc = &s->gbc; - int i, gcode, tbap, start, end; - uint8_t *exps; - uint8_t *bap; - int *coeffs; + int freq; - exps = s->dexps[ch_index]; - bap = s->bap[ch_index]; - coeffs = s->fixed_coeffs[ch_index]; - start = s->start_freq[ch_index]; - end = s->end_freq[ch_index]; - - for (i = start; i < end; i++) { - tbap = bap[i]; - switch (tbap) { + for(freq = start_freq; freq < end_freq; freq++){ + int bap = baps[freq]; + int mantissa; + switch(bap){ case 0: - coeffs[i] = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000; + mantissa = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000; break; - case 1: - if(m->b1ptr > 2) { - gcode = get_bits(gbc, 5); - m->b1_mant[0] = b1_mantissas[gcode][0]; - m->b1_mant[1] = b1_mantissas[gcode][1]; - m->b1_mant[2] = b1_mantissas[gcode][2]; - m->b1ptr = 0; + if(m->b1){ + m->b1--; + mantissa = m->b1_mant[m->b1]; + } + else{ + int bits = get_bits(gbc, 5); + mantissa = b1_mantissas[bits][0]; + m->b1_mant[1] = b1_mantissas[bits][1]; + m->b1_mant[0] = b1_mantissas[bits][2]; + m->b1 = 2; } - coeffs[i] = m->b1_mant[m->b1ptr++]; break; - case 2: - if(m->b2ptr > 2) { - gcode = get_bits(gbc, 7); - m->b2_mant[0] = b2_mantissas[gcode][0]; - m->b2_mant[1] = b2_mantissas[gcode][1]; - m->b2_mant[2] = b2_mantissas[gcode][2]; - m->b2ptr = 0; + if(m->b2){ + m->b2--; + mantissa = m->b2_mant[m->b2]; + } + else{ + int bits = get_bits(gbc, 7); + mantissa = b2_mantissas[bits][0]; + m->b2_mant[1] = b2_mantissas[bits][1]; + m->b2_mant[0] = b2_mantissas[bits][2]; + m->b2 = 2; } - coeffs[i] = m->b2_mant[m->b2ptr++]; break; - case 3: - coeffs[i] = b3_mantissas[get_bits(gbc, 3)]; + mantissa = b3_mantissas[get_bits(gbc, 3)]; break; - case 4: - if(m->b4ptr > 1) { - gcode = get_bits(gbc, 7); - m->b4_mant[0] = b4_mantissas[gcode][0]; - m->b4_mant[1] = b4_mantissas[gcode][1]; - m->b4ptr = 0; + if(m->b4){ + m->b4 = 0; + mantissa = m->b4_mant; + } + else{ + int bits = get_bits(gbc, 7); + mantissa = b4_mantissas[bits][0]; + m->b4_mant = b4_mantissas[bits][1]; + m->b4 = 1; } - coeffs[i] = m->b4_mant[m->b4ptr++]; break; - case 5: - coeffs[i] = b5_mantissas[get_bits(gbc, 4)]; + mantissa = b5_mantissas[get_bits(gbc, 4)]; break; - - default: { - /* asymmetric dequantization */ - int qlevel = quantization_tab[tbap]; - coeffs[i] = get_sbits(gbc, qlevel) << (24 - qlevel); + default: /* 6 to 15 */ + mantissa = get_bits(gbc, quantization_tab[bap]); + /* Shift mantissa and sign-extend it. */ + mantissa = (mantissa << (32-quantization_tab[bap]))>>8; break; - } } - coeffs[i] >>= exps[i]; + coeffs[freq] = mantissa >> exps[freq]; } } @@ -582,7 +581,7 @@ static void decode_transform_coeffs(AC3DecodeContext *s, int blk) int got_cplchan = 0; mant_groups m; - m.b1ptr = m.b2ptr = m.b4ptr = 3; + m.b1 = m.b2 = m.b4 = 0; for (ch = 1; ch <= s->channels; ch++) { /* transform coefficients for full-bandwidth channel */