Skip to content
Snippets Groups Projects
ac3enc.c 81.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • Fabrice Bellard's avatar
    Fabrice Bellard committed
    /*
    
     * Copyright (c) 2000 Fabrice Bellard
    
     * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
     * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     *
    
     * This file is part of Libav.
    
     * Libav is free software; you can redistribute it and/or
    
     * modify it under the terms of the GNU Lesser General Public
     * License as published by the Free Software Foundation; either
    
     * version 2.1 of the License, or (at your option) any later version.
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     *
    
     * Libav is distributed in the hope that it will be useful,
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
    
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * Lesser General Public License for more details.
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     *
    
     * You should have received a copy of the GNU Lesser General Public
    
     * License along with Libav; if not, write to the Free Software
    
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     */
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
    /**
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
     */
    
    #include <stdint.h>
    
    
    #include "libavutil/audioconvert.h"
    
    #include "libavutil/avstring.h"
    
    #include "libavutil/crc.h"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #include "avcodec.h"
    
    #include "ac3dsp.h"
    
    #include "ac3.h"
    
    #include "audioconvert.h"
    
    #include "fft.h"
    
    #include "ac3enc.h"
    #include "eac3enc.h"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        int16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; ///< mantissa pointers for bap=1,2,4
    
        int mant1_cnt, mant2_cnt, mant4_cnt;    ///< mantissa counts for bap=1,2,4
    } AC3Mant;
    
    #define CMIXLEV_NUM_OPTIONS 3
    static const float cmixlev_options[CMIXLEV_NUM_OPTIONS] = {
        LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, LEVEL_MINUS_6DB
    };
    
    #define SURMIXLEV_NUM_OPTIONS 3
    static const float surmixlev_options[SURMIXLEV_NUM_OPTIONS] = {
        LEVEL_MINUS_3DB, LEVEL_MINUS_6DB, LEVEL_ZERO
    };
    
    #define EXTMIXLEV_NUM_OPTIONS 8
    static const float extmixlev_options[EXTMIXLEV_NUM_OPTIONS] = {
        LEVEL_PLUS_3DB,  LEVEL_PLUS_1POINT5DB,  LEVEL_ONE,       LEVEL_MINUS_4POINT5DB,
        LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, LEVEL_MINUS_6DB, LEVEL_ZERO
    };
    
    
    
    /**
     * LUT for number of exponent groups.
    
     * exponent_group_tab[coupling][exponent strategy-1][number of coefficients]
    
    static uint8_t exponent_group_tab[2][3][256];
    
    /**
     * List of supported channel layouts.
     */
    
    const int64_t ff_ac3_channel_layouts[19] = {
    
         AV_CH_LAYOUT_MONO,
         AV_CH_LAYOUT_STEREO,
         AV_CH_LAYOUT_2_1,
         AV_CH_LAYOUT_SURROUND,
         AV_CH_LAYOUT_2_2,
         AV_CH_LAYOUT_QUAD,
         AV_CH_LAYOUT_4POINT0,
         AV_CH_LAYOUT_5POINT0,
         AV_CH_LAYOUT_5POINT0_BACK,
        (AV_CH_LAYOUT_MONO     | AV_CH_LOW_FREQUENCY),
        (AV_CH_LAYOUT_STEREO   | AV_CH_LOW_FREQUENCY),
        (AV_CH_LAYOUT_2_1      | AV_CH_LOW_FREQUENCY),
        (AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY),
        (AV_CH_LAYOUT_2_2      | AV_CH_LOW_FREQUENCY),
        (AV_CH_LAYOUT_QUAD     | AV_CH_LOW_FREQUENCY),
        (AV_CH_LAYOUT_4POINT0  | AV_CH_LOW_FREQUENCY),
         AV_CH_LAYOUT_5POINT1,
         AV_CH_LAYOUT_5POINT1_BACK,
         0
    };
    
    
    
    /**
     * LUT to select the bandwidth code based on the bit rate, sample rate, and
     * number of full-bandwidth channels.
     * bandwidth_tab[fbw_channels-1][sample rate code][bit rate code]
     */
    static const uint8_t ac3_bandwidth_tab[5][3][19] = {
    //      32  40  48  56  64  80  96 112 128 160 192 224 256 320 384 448 512 576 640
    
        { {  0,  0,  0, 12, 16, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 },
          {  0,  0,  0, 16, 20, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
          {  0,  0,  0, 32, 40, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } },
    
        { {  0,  0,  0,  0,  0,  0,  0, 20, 24, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48 },
          {  0,  0,  0,  0,  0,  0,  4, 24, 28, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
          {  0,  0,  0,  0,  0,  0, 20, 44, 52, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } },
    
        { {  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 24, 32, 40, 48, 48, 48, 48, 48, 48 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  4, 20, 28, 36, 44, 56, 56, 56, 56, 56, 56 },
          {  0,  0,  0,  0,  0,  0,  0,  0, 20, 40, 48, 60, 60, 60, 60, 60, 60, 60, 60 } },
    
        { {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 12, 24, 32, 48, 48, 48, 48, 48, 48 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 28, 36, 56, 56, 56, 56, 56, 56 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 32, 48, 60, 60, 60, 60, 60, 60, 60 } },
    
        { {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8, 20, 32, 40, 48, 48, 48, 48 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 12, 24, 36, 44, 56, 56, 56, 56 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 28, 44, 60, 60, 60, 60, 60, 60 } }
    };
    
    
    
    /**
     * LUT to select the coupling start band based on the bit rate, sample rate, and
     * number of full-bandwidth channels. -1 = coupling off
     * ac3_coupling_start_tab[channel_mode-2][sample rate code][bit rate code]
     *
     * TODO: more testing for optimal parameters.
     *       multi-channel tests at 44.1kHz and 32kHz.
     */
    static const int8_t ac3_coupling_start_tab[6][3][19] = {
    //      32  40  48  56  64  80  96 112 128 160 192 224 256 320 384 448 512 576 640
    
        // 2/0
        { {  0,  0,  0,  0,  0,  0,  0,  1,  1,  7,  8, 11, 12, -1, -1, -1, -1, -1, -1 },
          {  0,  0,  0,  0,  0,  0,  1,  3,  5,  7, 10, 12, 13, -1, -1, -1, -1, -1, -1 },
          {  0,  0,  0,  0,  1,  2,  2,  9, 13, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
    
        // 3/0
        { {  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  6,  9, 11, 12, 13, -1, -1, -1, -1 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  6,  9, 11, 12, 13, -1, -1, -1, -1 },
          { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
    
        // 2/1 - untested
        { {  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  6,  9, 11, 12, 13, -1, -1, -1, -1 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  6,  9, 11, 12, 13, -1, -1, -1, -1 },
          { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
    
        // 3/1
        { {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  2, 10, 11, 11, 12, 12, 14, -1 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  2, 10, 11, 11, 12, 12, 14, -1 },
          { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
    
        // 2/2 - untested
        { {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  2, 10, 11, 11, 12, 12, 14, -1 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  2, 10, 11, 11, 12, 12, 14, -1 },
          { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
    
        // 3/2
        { {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  6,  8, 11, 12, 12, -1, -1 },
          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  6,  8, 11, 12, 12, -1, -1 },
          { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
    };
    
    
    
    /**
     * Adjust the frame size to make the average bit rate match the target bit rate.
    
     * This is only needed for 11025, 22050, and 44100 sample rates or any E-AC-3.
    
    void ff_ac3_adjust_frame_size(AC3EncodeContext *s)
    
    {
        while (s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) {
            s->bits_written    -= s->bit_rate;
            s->samples_written -= s->sample_rate;
        }
    
        s->frame_size = s->frame_size_min +
                        2 * (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate);
    
        s->bits_written    += s->frame_size * 8;
    
        s->samples_written += AC3_BLOCK_SIZE * s->num_blocks;
    
    void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
    
    {
        int blk, ch;
        int got_cpl_snr;
    
    
        /* set coupling use flags for each block/channel */
        /* TODO: turn coupling on/off and adjust start band based on bit usage */
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            AC3Block *block = &s->blocks[blk];
            for (ch = 1; ch <= s->fbw_channels; ch++)
                block->channel_in_cpl[ch] = s->cpl_on;
        }
    
        /* enable coupling for each block if at least 2 channels have coupling
           enabled for that block */
        got_cpl_snr = 0;
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            AC3Block *block = &s->blocks[blk];
            block->num_cpl_channels = 0;
            for (ch = 1; ch <= s->fbw_channels; ch++)
                block->num_cpl_channels += block->channel_in_cpl[ch];
            block->cpl_in_use = block->num_cpl_channels > 1;
    
            num_cpl_blocks += block->cpl_in_use;
    
            if (!block->cpl_in_use) {
                block->num_cpl_channels = 0;
                for (ch = 1; ch <= s->fbw_channels; ch++)
                    block->channel_in_cpl[ch] = 0;
            }
    
            block->new_cpl_strategy = !blk;
            if (blk) {
                for (ch = 1; ch <= s->fbw_channels; ch++) {
                    if (block->channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) {
                        block->new_cpl_strategy = 1;
                        break;
                    }
                }
            }
            block->new_cpl_leak = block->new_cpl_strategy;
    
            if (!blk || (block->cpl_in_use && !got_cpl_snr)) {
                block->new_snr_offsets = 1;
                if (block->cpl_in_use)
                    got_cpl_snr = 1;
            } else {
                block->new_snr_offsets = 0;
            }
        }
    
        if (!num_cpl_blocks)
            s->cpl_on = 0;
    
    
        /* set bandwidth for each channel */
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            AC3Block *block = &s->blocks[blk];
            for (ch = 1; ch <= s->fbw_channels; ch++) {
                if (block->channel_in_cpl[ch])
                    block->end_freq[ch] = s->start_freq[CPL_CH];
                else
                    block->end_freq[ch] = s->bandwidth_code * 3 + 73;
            }
        }
    }
    
    
    
    /**
     * Apply stereo rematrixing to coefficients based on rematrixing flags.
     */
    
    void ff_ac3_apply_rematrixing(AC3EncodeContext *s)
    
    {
        int nb_coefs;
        int blk, bnd, i;
        int start, end;
        uint8_t *flags;
    
    
        if (!s->rematrixing_enabled)
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            AC3Block *block = &s->blocks[blk];
            if (block->new_rematrixing_strategy)
                flags = block->rematrixing_flags;
    
            nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]);
            for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) {
    
                if (flags[bnd]) {
                    start = ff_ac3_rematrix_band_tab[bnd];
                    end   = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
                    for (i = start; i < end; i++) {
    
                        int32_t lt = block->fixed_coef[1][i];
                        int32_t rt = block->fixed_coef[2][i];
                        block->fixed_coef[1][i] = (lt + rt) >> 1;
                        block->fixed_coef[2][i] = (lt - rt) >> 1;
    
    /**
     * Initialize exponent tables.
     */
    static av_cold void exponent_init(AC3EncodeContext *s)
    {
    
        int expstr, i, grpsize;
    
        for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) {
            grpsize = 3 << expstr;
    
            for (i = 12; i < 256; i++) {
                exponent_group_tab[0][expstr][i] = (i + grpsize - 4) / grpsize;
                exponent_group_tab[1][expstr][i] = (i              ) / grpsize;
    
        /* LFE */
    
        exponent_group_tab[0][0][7] = 2;
    
    
        if (CONFIG_EAC3_ENCODER && s->eac3)
            ff_eac3_exponent_init();
    
    /**
     * Extract exponents from the MDCT coefficients.
     */
    
    static void extract_exponents(AC3EncodeContext *s)
    
        int chan_size = AC3_MAX_COEFS * s->num_blocks * (s->channels - ch + 1);
    
        AC3Block *block = &s->blocks[0];
    
        s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], chan_size);
    
    /**
     * Exponent Difference Threshold.
     * New exponents are sent if their SAD exceed this number.
     */
    
    #define EXP_DIFF_THRESHOLD 500
    
    /**
     * Table used to select exponent strategy based on exponent reuse block interval.
     */
    static const uint8_t exp_strategy_reuse_tab[4][6] = {
        { EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
        { EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
        { EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
        { EXP_D45, EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15 }
    };
    
    /**
     * Calculate exponent strategies for all channels.
    
     * Array arrangement is reversed to simplify the per-channel calculation.
    
    static void compute_exp_strategy(AC3EncodeContext *s)
    
        for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) {
    
            uint8_t *exp_strategy = s->exp_strategy[ch];
            uint8_t *exp          = s->blocks[0].exp[ch];
            int exp_diff;
    
            /* estimate if the exponent variation & decide if they should be
               reused in the next frame */
            exp_strategy[0] = EXP_NEW;
            exp += AC3_MAX_COEFS;
    
            for (blk = 1; blk < s->num_blocks; blk++, exp += AC3_MAX_COEFS) {
    
                if (ch == CPL_CH) {
                    if (!s->blocks[blk-1].cpl_in_use) {
                        exp_strategy[blk] = EXP_NEW;
                        continue;
                    } else if (!s->blocks[blk].cpl_in_use) {
                        exp_strategy[blk] = EXP_REUSE;
                        continue;
                    }
                } else if (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) {
    
                    exp_strategy[blk] = EXP_NEW;
                    continue;
                }
    
                exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16);
    
                exp_strategy[blk] = EXP_REUSE;
                if (ch == CPL_CH && exp_diff > (EXP_DIFF_THRESHOLD * (s->blocks[blk].end_freq[ch] - s->start_freq[ch]) / AC3_MAX_COEFS))
                    exp_strategy[blk] = EXP_NEW;
                else if (ch > CPL_CH && exp_diff > EXP_DIFF_THRESHOLD)
    
                    exp_strategy[blk] = EXP_NEW;
            }
    
            /* now select the encoding strategy type : if exponents are often
               recoded, we use a coarse encoding */
            blk = 0;
    
                while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE)
    
                exp_strategy[blk] = exp_strategy_reuse_tab[s->num_blks_code][blk1-blk-1];
    
            for (blk = 1; blk < s->num_blocks; blk++)
    
                s->exp_strategy[ch][blk] = EXP_REUSE;
    
    
        /* for E-AC-3, determine frame exponent strategy */
        if (CONFIG_EAC3_ENCODER && s->eac3)
            ff_eac3_get_frame_exp_strategy(s);
    
    /**
     * Update the exponents so that they are the ones the decoder will decode.
     */
    
    static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy,
                                        int cpl)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_exps] * 3;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        /* for each group, compute the minimum exponent */
    
            for (i = 1, k = 1-cpl; i <= nb_groups; i++) {
    
                uint8_t exp_min = exp[k];
                if (exp[k+1] < exp_min)
                    exp_min = exp[k+1];
    
                exp[i-cpl] = exp_min;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            }
    
            for (i = 1, k = 1-cpl; i <= nb_groups; i++) {
    
                uint8_t exp_min = exp[k];
                if (exp[k+1] < exp_min)
                    exp_min = exp[k+1];
                if (exp[k+2] < exp_min)
                    exp_min = exp[k+2];
                if (exp[k+3] < exp_min)
                    exp_min = exp[k+3];
    
                exp[i-cpl] = exp_min;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        /* constraint for DC exponent */
    
        if (!cpl && exp[0] > 15)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        /* decrease the delta between each groups to within 2 so that they can be
           differentially encoded */
        for (i = 1; i <= nb_groups; i++)
    
            exp[i] = FFMIN(exp[i], exp[i-1] + 2);
    
            exp[i] = FFMIN(exp[i], exp[i+1] + 2);
    
        if (cpl)
            exp[-1] = exp[0] & ~1;
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* now we have the exponent values the decoder will see */
    
            for (i = nb_groups, k = (nb_groups * 2)-cpl; i > 0; i--) {
                uint8_t exp1 = exp[i-cpl];
    
                exp[k--] = exp1;
                exp[k--] = exp1;
            }
            break;
        case EXP_D45:
    
            for (i = nb_groups, k = (nb_groups * 4)-cpl; i > 0; i--) {
                exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i-cpl];
    
    /**
     * 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.
     */
    
    static void encode_exponents(AC3EncodeContext *s)
    
        int blk, blk1, ch, cpl;
    
        int nb_coefs, num_reuse_blocks;
    
        for (ch = !s->cpl_on; ch <= s->channels; ch++) {
            exp          = s->blocks[0].exp[ch] + s->start_freq[ch];
    
            cpl = (ch == CPL_CH);
    
                AC3Block *block = &s->blocks[blk];
                if (cpl && !block->cpl_in_use) {
                    exp += AC3_MAX_COEFS;
                    blk++;
                    continue;
                }
                nb_coefs = block->end_freq[ch] - s->start_freq[ch];
    
                /* count the number of EXP_REUSE blocks after the current block
    
                   and set exponent reference block numbers */
                s->exp_ref_block[ch][blk] = blk;
    
                while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE) {
    
                num_reuse_blocks = blk1 - blk - 1;
    
                /* for the EXP_REUSE case we select the min of the exponents */
    
                s->ac3dsp.ac3_exponent_min(exp-s->start_freq[ch], num_reuse_blocks,
                                           AC3_MAX_COEFS);
    
                encode_exponents_blk_ch(exp, nb_coefs, exp_strategy[blk], cpl);
    
                exp += AC3_MAX_COEFS * (num_reuse_blocks + 1);
    
    
        /* reference block numbers have been changed, so reset ref_bap_set */
        s->ref_bap_set = 0;
    
    /**
     * Count exponent bits based on bandwidth, coupling, and exponent strategies.
     */
    static int count_exponent_bits(AC3EncodeContext *s)
    {
        int blk, ch;
        int nb_groups, bit_count;
    
        bit_count = 0;
        for (blk = 0; blk < s->num_blocks; blk++) {
            AC3Block *block = &s->blocks[blk];
            for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
                int exp_strategy = s->exp_strategy[ch][blk];
                int cpl          = (ch == CPL_CH);
                int nb_coefs     = block->end_freq[ch] - s->start_freq[ch];
    
                if (exp_strategy == EXP_REUSE)
                    continue;
    
                nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_coefs];
                bit_count += 4 + (nb_groups * 7);
            }
        }
    
        return bit_count;
    }
    
    
    
    /**
     * Group exponents.
     * 3 delta-encoded exponents are in each 7-bit group. The number of groups
     * varies depending on exponent strategy and bandwidth.
     */
    
    void ff_ac3_group_exponents(AC3EncodeContext *s)
    
        int blk, ch, i, cpl;
    
        uint8_t *p;
        int delta0, delta1, delta2;
        int exp0, exp1;
    
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
    
                int exp_strategy = s->exp_strategy[ch][blk];
                if (exp_strategy == EXP_REUSE)
    
                cpl = (ch == CPL_CH);
    
                group_size = exp_strategy + (exp_strategy == EXP_D45);
    
                nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]];
                p = block->exp[ch] + s->start_freq[ch] - cpl;
    
    
                /* remaining exponents are delta encoded */
    
                    /* merge three delta in one code */
                    exp0   = exp1;
                    exp1   = p[0];
                    p     += group_size;
                    delta0 = exp1 - exp0 + 2;
    
                    av_assert2(delta0 >= 0 && delta0 <= 4);
    
    
                    exp0   = exp1;
                    exp1   = p[0];
                    p     += group_size;
                    delta1 = exp1 - exp0 + 2;
    
                    av_assert2(delta1 >= 0 && delta1 <= 4);
    
    
                    exp0   = exp1;
                    exp1   = p[0];
                    p     += group_size;
                    delta2 = exp1 - exp0 + 2;
    
                    av_assert2(delta2 >= 0 && delta2 <= 4);
    
                    block->grouped_exp[ch][i] = ((delta0 * 5 + delta1) * 5) + delta2;
    
    }
    
    
    /**
     * Calculate final exponents from the supplied MDCT coefficients and exponent shift.
     * Extract exponents from MDCT coefficients, calculate exponent strategies,
     * and encode final exponents.
     */
    
    void ff_ac3_process_exponents(AC3EncodeContext *s)
    
    /**
     * Count frame bits that are based solely on fixed parameters.
     * This only has to be run once when the encoder is initialized.
     */
    static void count_frame_bits_fixed(AC3EncodeContext *s)
    {
        static const int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 };
        int blk;
        int frame_bits;
    
        /* assumptions:
         *   no dynamic range codes
         *   bit allocation parameters do not change between blocks
         *   no delta bit allocation
         *   no skipped data
         *   no auxilliary data
    
         *   no E-AC-3 metadata
    
        frame_bits = 16; /* sync info */
        if (s->eac3) {
            /* bitstream info header */
            frame_bits += 35;
    
            frame_bits += 1 + 1;
            if (s->num_blocks != 0x6)
                frame_bits++;
            frame_bits++;
    
            /* audio frame header */
    
            frame_bits += 10;
            /* exponent strategy */
    
            if (s->use_frame_exp_strategy)
                frame_bits += 5 * s->fbw_channels;
            else
    
                frame_bits += s->num_blocks * 2 * s->fbw_channels;
    
            /* converter exponent strategy */
    
            if (s->num_blks_code != 0x3)
                frame_bits++;
            else
                frame_bits += s->fbw_channels * 5;
    
            /* snr offsets */
            frame_bits += 10;
            /* block start info */
    
        } else {
            frame_bits += 49;
            frame_bits += frame_bits_inc[s->channel_mode];
        }
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            if (!s->eac3) {
    
                /* block switch flags */
                frame_bits += s->fbw_channels;
    
                /* dither flags */
                frame_bits += s->fbw_channels;
    
            /* spectral extension */
            if (s->eac3)
                frame_bits++;
    
            if (!s->eac3) {
    
                /* exponent strategy */
                frame_bits += 2 * s->fbw_channels;
                if (s->lfe_on)
                    frame_bits++;
    
                /* bit allocation params */
                frame_bits++;
                if (!blk)
                    frame_bits += 2 + 2 + 2 + 2 + 3;
    
            /* converter snr offset */
            if (s->eac3)
                frame_bits++;
    
            if (!s->eac3) {
    
                /* delta bit allocation */
                frame_bits++;
    
                /* skipped data */
                frame_bits++;
    
        /* auxiliary data */
        frame_bits++;
    
    /**
     * Initialize bit allocation.
     * Set default parameter codes and calculate parameter values.
     */
    static void bit_alloc_init(AC3EncodeContext *s)
    {
        int ch;
    
        /* init default parameters */
        s->slow_decay_code = 2;
        s->fast_decay_code = 1;
        s->slow_gain_code  = 1;
    
        s->db_per_bit_code = s->eac3 ? 2 : 3;
    
        s->floor_code      = 7;
    
        for (ch = 0; ch <= s->channels; ch++)
    
            s->fast_gain_code[ch] = 4;
    
        /* initial snr offset */
        s->coarse_snr_offset = 40;
    
        /* compute real values */
        /* currently none of these values change during encoding, so we can just
           set them once at initialization */
        s->bit_alloc.slow_decay = ff_ac3_slow_decay_tab[s->slow_decay_code] >> s->bit_alloc.sr_shift;
        s->bit_alloc.fast_decay = ff_ac3_fast_decay_tab[s->fast_decay_code] >> s->bit_alloc.sr_shift;
        s->bit_alloc.slow_gain  = ff_ac3_slow_gain_tab[s->slow_gain_code];
        s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code];
        s->bit_alloc.floor      = ff_ac3_floor_tab[s->floor_code];
    
        s->bit_alloc.cpl_fast_leak = 0;
        s->bit_alloc.cpl_slow_leak = 0;
    
    /**
     * Count the bits used to encode the frame, minus exponents and mantissas.
    
     * Bits based on fixed parameters have already been counted, so now we just
     * have to add the bits based on parameters that change during encoding.
    
    static void count_frame_bits(AC3EncodeContext *s)
    
        AC3EncOptions *opt = &s->options;
    
        if (s->eac3) {
    
            if (opt->eac3_mixing_metadata) {
                if (s->channel_mode > AC3_CHMODE_STEREO)
                    frame_bits += 2;
                if (s->has_center)
                    frame_bits += 6;
                if (s->has_surround)
                    frame_bits += 6;
                frame_bits += s->lfe_on;
                frame_bits += 1 + 1 + 2;
                if (s->channel_mode < AC3_CHMODE_STEREO)
                    frame_bits++;
                frame_bits++;
            }
            if (opt->eac3_info_metadata) {
                frame_bits += 3 + 1 + 1;
                if (s->channel_mode == AC3_CHMODE_STEREO)
                    frame_bits += 2 + 2;
                if (s->channel_mode >= AC3_CHMODE_2F2R)
                    frame_bits += 2;
                frame_bits++;
                if (opt->audio_production_info)
                    frame_bits += 5 + 2 + 1;
                frame_bits++;
            }
    
            /* coupling */
            if (s->channel_mode > AC3_CHMODE_MONO) {
                frame_bits++;
    
                for (blk = 1; blk < s->num_blocks; blk++) {
    
                    AC3Block *block = &s->blocks[blk];
                    frame_bits++;
                    if (block->new_cpl_strategy)
                        frame_bits++;
                }
            }
            /* coupling exponent strategy */
    
            if (s->cpl_on) {
                if (s->use_frame_exp_strategy) {
                    frame_bits += 5 * s->cpl_on;
                } else {
    
                    for (blk = 0; blk < s->num_blocks; blk++)
    
                        frame_bits += 2 * s->blocks[blk].cpl_in_use;
                }
            }
    
            if (opt->audio_production_info)
                frame_bits += 7;
            if (s->bitstream_id == 6) {
                if (opt->extended_bsi_1)
                    frame_bits += 14;
                if (opt->extended_bsi_2)
                    frame_bits += 14;
            }
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            AC3Block *block = &s->blocks[blk];
    
            /* coupling strategy */
    
            if (block->new_cpl_strategy) {
    
                if (block->cpl_in_use) {
    
                    if (s->eac3)
                        frame_bits++;
                    if (!s->eac3 || s->channel_mode != AC3_CHMODE_STEREO)
    
                        frame_bits += s->fbw_channels;
    
                    if (s->channel_mode == AC3_CHMODE_STEREO)
                        frame_bits++;
                    frame_bits += 4 + 4;
    
                    if (s->eac3)
                        frame_bits++;
                    else
    
                        frame_bits += s->num_cpl_subbands - 1;
    
                }
            }
    
            /* coupling coordinates */
            if (block->cpl_in_use) {
                for (ch = 1; ch <= s->fbw_channels; ch++) {
                    if (block->channel_in_cpl[ch]) {
    
                        if (!s->eac3 || block->new_cpl_coords[ch] != 2)
    
                            frame_bits += 2;
                            frame_bits += (4 + 4) * s->num_cpl_bands;
                        }
                    }
                }
            }
    
    
            /* stereo rematrixing */
    
            if (s->channel_mode == AC3_CHMODE_STEREO) {
    
                if (!s->eac3 || blk > 0)
    
                if (s->blocks[blk].new_rematrixing_strategy)
    
                    frame_bits += block->num_rematrixing_bands;
    
            /* bandwidth codes & gain range */
    
            for (ch = 1; ch <= s->fbw_channels; ch++) {
                if (s->exp_strategy[ch][blk] != EXP_REUSE) {
                    if (!block->channel_in_cpl[ch])
                        frame_bits += 6;
                    frame_bits += 2;
                }
            }
    
            /* coupling exponent strategy */
    
            if (!s->eac3 && block->cpl_in_use)
    
                frame_bits += 2;
    
            /* snr offsets and fast gain codes */
    
            if (!s->eac3) {
    
                frame_bits++;
                if (block->new_snr_offsets)
                    frame_bits += 6 + (s->channels + block->cpl_in_use) * (4 + 3);
    
    
            /* coupling leak info */
            if (block->cpl_in_use) {
    
                if (!s->eac3 || block->new_cpl_leak != 2)
    
                if (block->new_cpl_leak)
                    frame_bits += 3 + 3;
    
        s->frame_bits = s->frame_bits_fixed + frame_bits;
    
    /**
     * Calculate masking curve based on the final exponents.
     * Also calculate the power spectral densities to use in future calculations.
     */
    
    static void bit_alloc_masking(AC3EncodeContext *s)
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
    
                /* We only need psd and mask for calculating bap.
                   Since we currently do not calculate bap when exponent
                   strategy is EXP_REUSE we do not need to calculate psd or mask. */
    
                if (s->exp_strategy[ch][blk] != EXP_REUSE) {
    
                    ff_ac3_bit_alloc_calc_psd(block->exp[ch], s->start_freq[ch],
                                              block->end_freq[ch], block->psd[ch],
                                              block->band_psd[ch]);
    
                    ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, block->band_psd[ch],
    
                                               s->start_freq[ch], block->end_freq[ch],
    
                                               ff_ac3_fast_gain_tab[s->fast_gain_code[ch]],
    
                                               DBA_NONE, 0, NULL, NULL, NULL,
    
    /**
     * Ensure that bap for each block and channel point to the current bap_buffer.
     * They may have been switched during the bit allocation search.
     */
    static void reset_block_bap(AC3EncodeContext *s)
    {
        int blk, ch;
    
        uint8_t *ref_bap;
    
        if (s->ref_bap[0][0] == s->bap_buffer && s->ref_bap_set)
    
    
        ref_bap = s->bap_buffer;
        for (ch = 0; ch <= s->channels; ch++) {
    
            for (blk = 0; blk < s->num_blocks; blk++)
    
                s->ref_bap[ch][blk] = ref_bap + AC3_MAX_COEFS * s->exp_ref_block[ch][blk];
    
            ref_bap += AC3_MAX_COEFS * s->num_blocks;
    
    /**
     * Initialize mantissa counts.
     * These are set so that they are padded to the next whole group size when bits
     * are counted in compute_mantissa_size.
     */
    static void count_mantissa_bits_init(uint16_t mant_cnt[AC3_MAX_BLOCKS][16])
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        int blk;
    
        for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
            memset(mant_cnt[blk], 0, sizeof(mant_cnt[blk]));
            mant_cnt[blk][1] = mant_cnt[blk][2] = 2;
            mant_cnt[blk][4] = 1;
        }
    }
    
    
    /**
     * Update mantissa bit counts for all blocks in 1 channel in a given bandwidth
     * range.
     */
    static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch,
                                              uint16_t mant_cnt[AC3_MAX_BLOCKS][16],
                                              int start, int end)
    {
        int blk;
    
    Justin Ruggles's avatar
    Justin Ruggles committed
    
    
        for (blk = 0; blk < s->num_blocks; blk++) {
    
            if (ch == CPL_CH && !block->cpl_in_use)
                continue;