From dfdf73eb1abc039d0067d178909ab77eb9cb6608 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 14 Dec 2010 14:53:02 +0000 Subject: [PATCH] Split exponent processing into separate functions. Originally committed as revision 25991 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/ac3enc.c | 166 ++++++++++++++++++++++++++++++-------------- 1 file changed, 114 insertions(+), 52 deletions(-) diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index f05ff4a65b..c26d868bbb 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -411,6 +411,41 @@ static void apply_mdct(AC3EncodeContext *s, } +/** + * Extract exponents from the MDCT coefficients. + * This takes into account the normalization that was done to the input samples + * by adjusting the exponents by the exponent shift values. + */ +static void extract_exponents(AC3EncodeContext *s, + int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS], + int8_t exp_shift[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS], + uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]) +{ + int blk, ch, i; + + /* extract exponents */ + for (ch = 0; ch < s->channels; ch++) { + for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + /* compute "exponents". We take into account the normalization there */ + for (i = 0; i < AC3_MAX_COEFS; i++) { + int e; + int v = abs(mdct_coef[blk][ch][i]); + if (v == 0) + e = 24; + else { + e = 23 - av_log2(v) + exp_shift[blk][ch]; + if (e >= 24) { + e = 24; + mdct_coef[blk][ch][i] = 0; + } + } + exp[blk][ch][i] = e; + } + } + } +} + + /** * Calculate the sum of absolute differences (SAD) between 2 sets of exponents. */ @@ -472,6 +507,21 @@ static void compute_exp_strategy_ch(uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX } +/** + * Calculate exponent strategies for all channels. + */ +static void compute_exp_strategy(AC3EncodeContext *s, + uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS], + uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]) +{ + int ch; + + for (ch = 0; ch < s->channels; ch++) { + compute_exp_strategy_ch(exp_strategy, exp, ch, ch == s->lfe_channel); + } +} + + /** * Set each encoded exponent in a block to the minimum of itself and the * exponent in the same frequency bin of a following block. @@ -539,6 +589,68 @@ static int encode_exponents_blk_ch(uint8_t encoded_exp[AC3_MAX_COEFS], } +/** + * Encode exponents from original extracted form to what the decoder will see. + * This copies and groups exponents based on exponent strategy and reduces + * deltas between adjacent exponent groups so that they can be differentially + * encoded. + * @return bits needed to encode the exponents + */ +static int encode_exponents(AC3EncodeContext *s, + uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS], + uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS], + uint8_t encoded_exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]) +{ + int blk, blk1, blk2, ch; + int frame_bits; + + frame_bits = 0; + for (ch = 0; ch < s->channels; ch++) { + /* for the EXP_REUSE case we select the min of the exponents */ + blk = 0; + while (blk < AC3_MAX_BLOCKS) { + blk1 = blk + 1; + while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1][ch] == EXP_REUSE) { + exponent_min(exp[blk][ch], exp[blk1][ch], s->nb_coefs[ch]); + blk1++; + } + frame_bits += encode_exponents_blk_ch(encoded_exp[blk][ch], + exp[blk][ch], s->nb_coefs[ch], + exp_strategy[blk][ch]); + /* copy encoded exponents for reuse case */ + for (blk2 = blk+1; blk2 < blk1; blk2++) { + memcpy(encoded_exp[blk2][ch], encoded_exp[blk][ch], + s->nb_coefs[ch] * sizeof(uint8_t)); + } + blk = blk1; + } + } + + return frame_bits; +} + + +/** + * Calculate final exponents from the supplied MDCT coefficients and exponent shift. + * Extract exponents from MDCT coefficients, calculate exponent strategies, + * and encode final exponents. + * @return bits needed to encode the exponents + */ +static int process_exponents(AC3EncodeContext *s, + int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS], + int8_t exp_shift[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS], + uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS], + uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS], + uint8_t encoded_exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]) +{ + extract_exponents(s, mdct_coef, exp_shift, exp); + + compute_exp_strategy(s, exp_strategy, exp); + + return encode_exponents(s, exp, exp_strategy, encoded_exp); +} + + /** * Calculate the number of bits needed to encode a set of mantissas. */ @@ -1174,8 +1286,7 @@ static int ac3_encode_frame(AVCodecContext *avctx, { AC3EncodeContext *s = avctx->priv_data; const int16_t *samples = data; - int v; - int blk, blk1, blk2, ch, i; + int blk; int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE]; int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]; uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]; @@ -1189,56 +1300,7 @@ static int ac3_encode_frame(AVCodecContext *avctx, apply_mdct(s, planar_samples, exp_shift, mdct_coef); - /* extract exponents */ - for (ch = 0; ch < s->channels; ch++) { - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { - /* compute "exponents". We take into account the normalization there */ - for (i = 0; i < AC3_MAX_COEFS; i++) { - int e; - v = abs(mdct_coef[blk][ch][i]); - if (v == 0) - e = 24; - else { - e = 23 - av_log2(v) + exp_shift[blk][ch]; - if (e >= 24) { - e = 24; - mdct_coef[blk][ch][i] = 0; - } - } - exp[blk][ch][i] = e; - } - } - } - - /* compute exponent strategies */ - for (ch = 0; ch < s->channels; ch++) { - compute_exp_strategy_ch(exp_strategy, exp, ch, ch == s->lfe_channel); - } - - /* encode exponents */ - frame_bits = 0; - for (ch = 0; ch < s->channels; ch++) { - /* compute the exponents as the decoder will see them. The - EXP_REUSE case must be handled carefully : we select the - min of the exponents */ - blk = 0; - while (blk < AC3_MAX_BLOCKS) { - blk1 = blk + 1; - while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1][ch] == EXP_REUSE) { - exponent_min(exp[blk][ch], exp[blk1][ch], s->nb_coefs[ch]); - blk1++; - } - frame_bits += encode_exponents_blk_ch(encoded_exp[blk][ch], - exp[blk][ch], s->nb_coefs[ch], - exp_strategy[blk][ch]); - /* copy encoded exponents for reuse case */ - for (blk2 = blk+1; blk2 < blk1; blk2++) { - memcpy(encoded_exp[blk2][ch], encoded_exp[blk][ch], - s->nb_coefs[ch] * sizeof(uint8_t)); - } - blk = blk1; - } - } + frame_bits = process_exponents(s, mdct_coef, exp_shift, exp, exp_strategy, encoded_exp); /* adjust for fractional frame sizes */ while (s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) {