Skip to content
Snippets Groups Projects
mpegaudiodec_template.c 63 KiB
Newer Older
  • Learn to ignore specific revisions
  • Fabrice Bellard's avatar
    Fabrice Bellard committed
    /*
     * MPEG Audio decoder
    
     * Copyright (c) 2001, 2002 Fabrice Bellard
    
    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
    
    /**
    
     * MPEG Audio decoder
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
    
    #include "libavutil/attributes.h"
    
    #include "libavutil/avassert.h"
    
    #include "libavutil/channel_layout.h"
    
    #include "libavutil/float_dsp.h"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #include "avcodec.h"
    
    #include "get_bits.h"
    
    #include "internal.h"
    
    #include "mathops.h"
    
    #include "mpegaudiodsp.h"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    /*
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     */
    
    
    Roberto Togni's avatar
    Roberto Togni committed
    #include "mpegaudio.h"
    
    #include "mpegaudiodecheader.h"
    
    #define BACKSTEP_SIZE 512
    #define EXTRABYTES 24
    
    #define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES
    
    
    /* layer 3 "granule" */
    typedef struct GranuleDef {
        uint8_t scfsi;
        int part2_3_length;
        int big_values;
        int global_gain;
        int scalefac_compress;
        uint8_t block_type;
        uint8_t switch_point;
        int table_select[3];
        int subblock_gain[3];
        uint8_t scalefac_scale;
        uint8_t count1table_select;
        int region_size[3]; /* number of huffman codes in each region */
        int preflag;
        int short_start, long_end; /* long/short band indexes */
        uint8_t scale_factors[40];
    
        DECLARE_ALIGNED(16, INTFLOAT, sb_hybrid)[SBLIMIT * 18]; /* 576 samples */
    
    } GranuleDef;
    
    typedef struct MPADecodeContext {
        MPA_DECODE_HEADER
    
        uint8_t last_buf[LAST_BUF_SIZE];
    
        int last_buf_size;
        /* next header (used in free format parsing) */
        uint32_t free_format_next_header;
        GetBitContext gb;
        GetBitContext in_gb;
    
        DECLARE_ALIGNED(32, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512 * 2];
    
        int synth_buf_offset[MPA_MAX_CHANNELS];
    
        DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT];
    
        INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
        GranuleDef granules[2][2]; /* Used in Layer 3 */
        int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
        int dither_state;
    
        AVCodecContext* avctx;
        MPADSPContext mpadsp;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #define HEADER_SIZE 4
    
    
    #include "mpegaudiodectab.h"
    
    /* vlc structure for decoding layer 3 huffman tables */
    
    static VLC huff_vlc[16];
    
    static VLC_TYPE huff_vlc_tables[
    
        0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 +
      142 + 204 + 190 + 170 + 542 + 460 + 662 + 414
    
      ][2];
    static const int huff_vlc_tables_sizes[16] = {
    
        0,  128,  128,  128,  130,  128,  154,  166,
      142,  204,  190,  170,  542,  460,  662,  414
    
    static VLC_TYPE  huff_quad_vlc_tables[128+16][2];
    static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 };
    
    static uint16_t band_index_long[9][23];
    
    #include "mpegaudio_tablegen.h"
    
    static INTFLOAT is_table[2][16];
    static INTFLOAT is_table_lsf[2][2][16];
    
    static INTFLOAT csa_table[8][4];
    
    static int16_t division_tab3[1<<6 ];
    static int16_t division_tab5[1<<8 ];
    static int16_t division_tab9[1<<11];
    
    static int16_t * const division_tabs[4] = {
        division_tab3, division_tab5, NULL, division_tab9
    };
    
    
    /* lower 2 bits: modulo 3, higher bits: shift */
    
    static uint16_t scale_factor_modshift[64];
    
    /* [i][j]:  2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
    
    static int32_t scale_factor_mult[15][3];
    
    /* mult table for layer 2 group quantization */
    
    #define SCALE_GEN(v) \
    
    { FIXR_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(0.6299605249 * (v)) }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    static const int32_t scale_factor_mult2[3][3] = {
    
        SCALE_GEN(4.0 / 3.0), /* 3 steps */
        SCALE_GEN(4.0 / 5.0), /* 5 steps */
        SCALE_GEN(4.0 / 9.0), /* 9 steps */
    
    /**
     * Convert region offsets to region sizes and truncate
     * size to big_values.
     */
    
    static void region_offset2size(GranuleDef *g)
    
    {
        int i, k, j = 0;
        g->region_size[2] = 576 / 2;
        for (i = 0; i < 3; i++) {
    
            k = FFMIN(g->region_size[i], g->big_values);
            g->region_size[i] = k - j;
            j = k;
        }
    }
    
    
    static void init_short_region(MPADecodeContext *s, GranuleDef *g)
    
        if (g->block_type == 2) {
            if (s->sample_rate_index != 8)
                g->region_size[0] = (36 / 2);
            else
                g->region_size[0] = (72 / 2);
        } else {
    
            if (s->sample_rate_index <= 2)
                g->region_size[0] = (36 / 2);
            else if (s->sample_rate_index != 8)
                g->region_size[0] = (54 / 2);
            else
                g->region_size[0] = (108 / 2);
        }
        g->region_size[1] = (576 / 2);
    }
    
    
    static void init_long_region(MPADecodeContext *s, GranuleDef *g,
                                 int ra1, int ra2)
    
        g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
    
        /* should not overflow */
        l = FFMIN(ra1 + ra2 + 2, 22);
    
        g->region_size[1] = band_index_long[s->sample_rate_index][      l] >> 1;
    
    static void compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
    
        if (g->block_type == 2) {
            if (g->switch_point) {
                /* if switched mode, we handle the 36 first samples as
    
                    long blocks.  For 8000Hz, we handle the 72 first
                    exponents as long blocks */
    
                if (s->sample_rate_index <= 2)
                    g->long_end = 8;
                else
    
                g->short_start = 3;
    
                g->short_start = 0;
            }
        } else {
            g->short_start = 13;
    
    /* layer 1 unscaling */
    /* n = number of bits of the mantissa minus 1 */
    static inline int l1_unscale(int n, int mant, int scale_factor)
    {
        int shift, mod;
    
        int64_t val;
    
        shift   = scale_factor_modshift[scale_factor];
        mod     = shift & 3;
    
        val     = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]);
        shift  += n;
    
        /* NOTE: at this point, 1 <= shift >= 21 + 15 */
        return (int)((val + (1LL << (shift - 1))) >> shift);
    
    }
    
    static inline int l2_unscale_group(int steps, int mant, int scale_factor)
    {
        int shift, mod, val;
    
    
        shift   = scale_factor_modshift[scale_factor];
        mod     = shift & 3;
    
    
        val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
        /* NOTE: at this point, 0 <= shift <= 21 */
        if (shift > 0)
            val = (val + (1 << (shift - 1))) >> shift;
        return val;
    
    }
    
    /* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
    static inline int l3_unscale(int value, int exponent)
    {
        unsigned int m;
        int e;
    
    
        e  = table_4_3_exp  [4 * value + (exponent & 3)];
        m  = table_4_3_value[4 * value + (exponent & 3)];
        e -= exponent >> 2;
        assert(e >= 1);
    
        m = (m + (1 << (e - 1))) >> e;
    
    static av_cold void decode_init_static(void)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        int offset;
    
        /* scale factors table for layer 1/2 */
        for (i = 0; i < 64; i++) {
            int shift, mod;
            /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
            shift = i / 3;
            mod   = i % 3;
            scale_factor_modshift[i] = mod | (shift << 2);
        }
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        /* scale factor multiply for layer 1 */
        for (i = 0; i < 15; i++) {
            int n, norm;
            n = i + 2;
            norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
            scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0          * 2.0), FRAC_BITS);
            scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
            scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
    
            ff_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm,
    
    Justin Ruggles's avatar
    Justin Ruggles committed
                    scale_factor_mult[i][0],
                    scale_factor_mult[i][1],
                    scale_factor_mult[i][2]);
        }
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        /* huffman decode tables */
        offset = 0;
        for (i = 1; i < 16; i++) {
            const HuffTable *h = &mpa_huff_tables[i];
            int xsize, x, y;
    
            uint8_t  tmp_bits [512] = { 0 };
            uint16_t tmp_codes[512] = { 0 };
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            xsize = h->xsize;
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            j = 0;
            for (x = 0; x < xsize; x++) {
                for (y = 0; y < xsize; y++) {
                    tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j  ];
                    tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            /* XXX: fail test */
            huff_vlc[i].table = huff_vlc_tables+offset;
            huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
            init_vlc(&huff_vlc[i], 7, 512,
                     tmp_bits, 1, 1, tmp_codes, 2, 2,
                     INIT_VLC_USE_NEW_STATIC);
            offset += huff_vlc_tables_sizes[i];
        }
        assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
    
        offset = 0;
        for (i = 0; i < 2; i++) {
            huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
            huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
            init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
                     mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
                     INIT_VLC_USE_NEW_STATIC);
            offset += huff_quad_vlc_tables_sizes[i];
        }
        assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
    
        for (i = 0; i < 9; i++) {
            k = 0;
            for (j = 0; j < 22; j++) {
                band_index_long[i][j] = k;
                k += band_size_long[i][j];
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            band_index_long[i][22] = k;
        }
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        /* compute n ^ (4/3) and store it in mantissa/exp format */
    
        mpegaudio_tableinit();
    
        for (i = 0; i < 4; i++) {
            if (ff_mpa_quant_bits[i] < 0) {
                for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) {
                    int val1, val2, val3, steps;
                    int val = j;
                    steps   = ff_mpa_quant_steps[i];
                    val1    = val % steps;
                    val    /= steps;
                    val2    = val % steps;
                    val3    = val / steps;
                    division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        for (i = 0; i < 7; i++) {
            float f;
            INTFLOAT v;
            if (i != 6) {
                f = tan((double)i * M_PI / 12.0);
                v = FIXR(f / (1.0 + f));
            } else {
                v = FIXR(1.0);
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            is_table[0][    i] = v;
            is_table[1][6 - i] = v;
        }
        /* invalid values */
        for (i = 7; i < 16; i++)
            is_table[0][i] = is_table[1][i] = 0.0;
    
        for (i = 0; i < 16; i++) {
            double f;
            int e, k;
    
            for (j = 0; j < 2; j++) {
                e = -(j + 1) * ((i + 1) >> 1);
                f = pow(2.0, e / 4.0);
                k = i & 1;
                is_table_lsf[j][k ^ 1][i] = FIXR(f);
                is_table_lsf[j][k    ][i] = FIXR(1.0);
    
                ff_dlog(NULL, "is_table_lsf %d %d: %f %f\n",
    
    Justin Ruggles's avatar
    Justin Ruggles committed
                        i, j, (float) is_table_lsf[j][0][i],
                        (float) is_table_lsf[j][1][i]);
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        for (i = 0; i < 8; i++) {
            float ci, cs, ca;
            ci = ci_table[i];
            cs = 1.0 / sqrt(1.0 + ci * ci);
            ca = cs * ci;
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            csa_table[i][0] = FIXHR(cs/4);
            csa_table[i][1] = FIXHR(ca/4);
            csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
            csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4);
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            csa_table[i][0] = cs;
            csa_table[i][1] = ca;
            csa_table[i][2] = ca + cs;
            csa_table[i][3] = ca - cs;
    
    static av_cold int decode_init(AVCodecContext * avctx)
    {
    
        static int initialized_tables = 0;
    
        MPADecodeContext *s = avctx->priv_data;
    
    
        if (!initialized_tables) {
            decode_init_static();
            initialized_tables = 1;
        }
    
    
        avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
    
        if (avctx->request_sample_fmt == OUT_FMT &&
            avctx->codec_id != AV_CODEC_ID_MP3ON4)
            avctx->sample_fmt = OUT_FMT;
        else
            avctx->sample_fmt = OUT_FMT_P;
    
        s->err_recognition = avctx->err_recognition;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (avctx->codec_id == AV_CODEC_ID_MP3ADU)
    
    Roberto Togni's avatar
    Roberto Togni committed
            s->adu_mode = 1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #define C3 FIXHR(0.86602540378443864676/2)
    
    #define C4 FIXHR(0.70710678118654752439/2) //0.5 / cos(pi*(9)/36)
    #define C5 FIXHR(0.51763809020504152469/2) //0.5 / cos(pi*(5)/36)
    #define C6 FIXHR(1.93185165257813657349/4) //0.5 / cos(pi*(15)/36)
    
    /* 12 points IMDCT. We compute it "by hand" by factorizing obvious
       cases. */
    
    static void imdct12(INTFLOAT *out, INTFLOAT *in)
    
        INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2;
    
        in0  = in[0*3];
        in1  = in[1*3] + in[0*3];
        in2  = in[2*3] + in[1*3];
        in3  = in[3*3] + in[2*3];
        in4  = in[4*3] + in[3*3];
        in5  = in[5*3] + in[4*3];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        in5 += in3;
        in3 += in1;
    
    
        in2  = MULH3(in2, C3, 2);
        in3  = MULH3(in3, C3, 4);
    
        t1   = in0 - in4;
    
        t2   = MULH3(in1 - in5, C4, 2);
    
    
        out[ 7] =
        out[10] = t1 + t2;
        out[ 1] =
        out[ 4] = t1 - t2;
    
        in0    += SHR(in4, 1);
        in4     = in0 + in2;
        in5    += 2*in1;
    
        in1     = MULH3(in5 + in3, C5, 1);
    
        out[ 8] =
        out[ 9] = in4 + in1;
        out[ 2] =
        out[ 3] = in4 - in1;
    
        in0    -= in2;
    
        in5     = MULH3(in5 - in3, C6, 2);
    
        out[ 0] =
        out[ 5] = in0 - in5;
        out[ 6] =
        out[11] = in0 + in5;
    
    }
    
    /* return the number of decoded frames */
    static int mp_decode_layer1(MPADecodeContext *s)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT];
        uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT];
    
        if (s->mode == MPA_JSTEREO)
    
            bound = (s->mode_ext + 1) * 4;
        else
            bound = SBLIMIT;
    
        /* allocation bits */
    
        for (i = 0; i < bound; i++) {
            for (ch = 0; ch < s->nb_channels; ch++) {
    
        for (i = bound; i < SBLIMIT; i++)
    
            allocation[0][i] = get_bits(&s->gb, 4);
    
        /* scale factors */
    
        for (i = 0; i < bound; i++) {
            for (ch = 0; ch < s->nb_channels; ch++) {
    
                if (allocation[ch][i])
                    scale_factors[ch][i] = get_bits(&s->gb, 6);
            }
        }
    
        for (i = bound; i < SBLIMIT; i++) {
    
            if (allocation[0][i]) {
                scale_factors[0][i] = get_bits(&s->gb, 6);
                scale_factors[1][i] = get_bits(&s->gb, 6);
            }
        }
    
        for (j = 0; j < 12; j++) {
            for (i = 0; i < bound; i++) {
                for (ch = 0; ch < s->nb_channels; ch++) {
    
                    n = allocation[ch][i];
                    if (n) {
                        mant = get_bits(&s->gb, n + 1);
                        v = l1_unscale(n, mant, scale_factors[ch][i]);
                    } else {
                        v = 0;
                    }
                    s->sb_samples[ch][j][i] = v;
                }
            }
    
            for (i = bound; i < SBLIMIT; i++) {
    
                n = allocation[0][i];
                if (n) {
                    mant = get_bits(&s->gb, n + 1);
                    v = l1_unscale(n, mant, scale_factors[0][i]);
                    s->sb_samples[0][j][i] = v;
                    v = l1_unscale(n, mant, scale_factors[1][i]);
                    s->sb_samples[1][j][i] = v;
                } else {
                    s->sb_samples[0][j][i] = 0;
                    s->sb_samples[1][j][i] = 0;
                }
            }
        }
        return 12;
    }
    
    static int mp_decode_layer2(MPADecodeContext *s)
    {
        int sblimit; /* number of used subbands */
        const unsigned char *alloc_table;
        int table, bit_alloc_bits, i, j, ch, bound, v;
        unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
        unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
        unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf;
        int scale, qindex, bits, steps, k, l, m, b;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels,
    
                                       s->sample_rate, s->lsf);
        sblimit     = ff_mpa_sblimit_table[table];
    
        alloc_table = ff_mpa_alloc_tables[table];
    
        if (s->mode == MPA_JSTEREO)
    
        ff_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit);
    
        if (bound > sblimit)
            bound = sblimit;
    
        for (i = 0; i < bound; i++) {
    
            for (ch = 0; ch < s->nb_channels; ch++)
    
                bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
            j += 1 << bit_alloc_bits;
        }
    
        for (i = bound; i < sblimit; i++) {
    
            bit_alloc_bits = alloc_table[j];
            v = get_bits(&s->gb, bit_alloc_bits);
            bit_alloc[0][i] = v;
            bit_alloc[1][i] = v;
            j += 1 << bit_alloc_bits;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
        for (i = 0; i < sblimit; i++) {
            for (ch = 0; ch < s->nb_channels; ch++) {
    
                if (bit_alloc[ch][i])
    
        for (i = 0; i < sblimit; i++) {
            for (ch = 0; ch < s->nb_channels; ch++) {
    
                if (bit_alloc[ch][i]) {
                    sf = scale_factors[ch][i];
    
                    switch (scale_code[ch][i]) {
    
                    default:
                    case 0:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[1] = get_bits(&s->gb, 6);
                        sf[2] = get_bits(&s->gb, 6);
                        break;
                    case 2:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[1] = sf[0];
                        sf[2] = sf[0];
                        break;
                    case 1:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[2] = get_bits(&s->gb, 6);
                        sf[1] = sf[0];
                        break;
                    case 3:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[2] = get_bits(&s->gb, 6);
                        sf[1] = sf[2];
                        break;
                    }
                }
            }
        }
    
        /* samples */
    
        for (k = 0; k < 3; k++) {
            for (l = 0; l < 12; l += 3) {
    
                for (i = 0; i < bound; i++) {
    
                    for (ch = 0; ch < s->nb_channels; ch++) {
    
                        b = bit_alloc[ch][i];
                        if (b) {
                            scale = scale_factors[ch][i][k];
                            qindex = alloc_table[j+b];
    
                            bits = ff_mpa_quant_bits[qindex];
    
                                /* 3 values at the same time */
                                v = get_bits(&s->gb, -bits);
    
                                v2 = division_tabs[qindex][v];
                                steps  = ff_mpa_quant_steps[qindex];
    
    
                                s->sb_samples[ch][k * 12 + l + 0][i] =
    
                                    l2_unscale_group(steps,  v2       & 15, scale);
    
                                s->sb_samples[ch][k * 12 + l + 1][i] =
    
                                    l2_unscale_group(steps, (v2 >> 4) & 15, scale);
    
                                s->sb_samples[ch][k * 12 + l + 2][i] =
    
                                    l2_unscale_group(steps,  v2 >> 8      , scale);
    
                                for (m = 0; m < 3; m++) {
    
                                    v = get_bits(&s->gb, bits);
                                    v = l1_unscale(bits - 1, v, scale);
                                    s->sb_samples[ch][k * 12 + l + m][i] = v;
                                }
                            }
                        } else {
                            s->sb_samples[ch][k * 12 + l + 0][i] = 0;
                            s->sb_samples[ch][k * 12 + l + 1][i] = 0;
                            s->sb_samples[ch][k * 12 + l + 2][i] = 0;
                        }
                    }
                    /* next subband in alloc table */
    
                    j += 1 << bit_alloc_bits;
    
                }
                /* XXX: find a way to avoid this duplication of code */
    
                for (i = bound; i < sblimit; i++) {
    
                    bit_alloc_bits = alloc_table[j];
                    b = bit_alloc[0][i];
                    if (b) {
                        int mant, scale0, scale1;
                        scale0 = scale_factors[0][i][k];
                        scale1 = scale_factors[1][i][k];
                        qindex = alloc_table[j+b];
    
                        bits = ff_mpa_quant_bits[qindex];
    
                        if (bits < 0) {
                            /* 3 values at the same time */
                            v = get_bits(&s->gb, -bits);
    
                            steps = ff_mpa_quant_steps[qindex];
    
                            s->sb_samples[0][k * 12 + l + 0][i] =
    
                            s->sb_samples[1][k * 12 + l + 0][i] =
    
                                l2_unscale_group(steps, mant, scale1);
                            mant = v % steps;
                            v = v / steps;
    
                            s->sb_samples[0][k * 12 + l + 1][i] =
    
                            s->sb_samples[1][k * 12 + l + 1][i] =
    
                            s->sb_samples[0][k * 12 + l + 2][i] =
    
                            s->sb_samples[1][k * 12 + l + 2][i] =
    
                                l2_unscale_group(steps, v, scale1);
                        } else {
    
                            for (m = 0; m < 3; m++) {
    
                                s->sb_samples[0][k * 12 + l + m][i] =
    
                                s->sb_samples[1][k * 12 + l + m][i] =
    
                                    l1_unscale(bits - 1, mant, scale1);
                            }
                        }
                    } else {
                        s->sb_samples[0][k * 12 + l + 0][i] = 0;
                        s->sb_samples[0][k * 12 + l + 1][i] = 0;
                        s->sb_samples[0][k * 12 + l + 2][i] = 0;
                        s->sb_samples[1][k * 12 + l + 0][i] = 0;
                        s->sb_samples[1][k * 12 + l + 1][i] = 0;
                        s->sb_samples[1][k * 12 + l + 2][i] = 0;
                    }
                    /* next subband in alloc table */
    
                    j += 1 << bit_alloc_bits;
    
                for (i = sblimit; i < SBLIMIT; i++) {
                    for (ch = 0; ch < s->nb_channels; ch++) {
    
                        s->sb_samples[ch][k * 12 + l + 0][i] = 0;
                        s->sb_samples[ch][k * 12 + l + 1][i] = 0;
                        s->sb_samples[ch][k * 12 + l + 2][i] = 0;
                    }
                }
            }
        }
        return 3 * 12;
    
    #define SPLIT(dst,sf,n)             \
        if (n == 3) {                   \
            int m = (sf * 171) >> 9;    \
            dst   = sf - 3 * m;         \
            sf    = m;                  \
        } else if (n == 4) {            \
            dst  = sf & 3;              \
            sf >>= 2;                   \
        } else if (n == 5) {            \
            int m = (sf * 205) >> 10;   \
            dst   = sf - 5 * m;         \
            sf    = m;                  \
        } else if (n == 6) {            \
            int m = (sf * 171) >> 10;   \
            dst   = sf - 6 * m;         \
            sf    = m;                  \
        } else {                        \
            dst = 0;                    \
    
    static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2,
                                               int n3)
    
        SPLIT(slen[3], sf, n3)
        SPLIT(slen[2], sf, n2)
        SPLIT(slen[1], sf, n1)
    
    static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g,
    
                                             int16_t *exponents)
    
        const uint8_t *bstab, *pretab;
    
        int len, i, j, k, l, v0, shift, gain, gains[3];
    
        int16_t *exp_ptr;
    
        gain    = g->global_gain - 210;
        shift   = g->scalefac_scale + 1;
    
        bstab  = band_size_long[s->sample_rate_index];
    
        for (i = 0; i < g->long_end; i++) {
    
            v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400;
    
            for (j = len; j > 0; j--)
    
            bstab    = band_size_short[s->sample_rate_index];
    
            gains[0] = gain - (g->subblock_gain[0] << 3);
            gains[1] = gain - (g->subblock_gain[1] << 3);
            gains[2] = gain - (g->subblock_gain[2] << 3);
    
            k        = g->long_end;
            for (i = g->short_start; i < 13; i++) {
    
                for (l = 0; l < 3; l++) {
    
                    v0 = gains[l] - (g->scale_factors[k++] << shift) + 400;
    
                    for (j = len; j > 0; j--)
                        *exp_ptr++ = v0;
    
                }
            }
        }
    }
    
    /* handle n = 0 too */
    static inline int get_bitsz(GetBitContext *s, int n)
    {
    
        return n ? get_bits(s, n) : 0;
    
    static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos,
                              int *end_pos2)
    {
        if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) {
            s->gb           = s->in_gb;
            s->in_gb.buffer = NULL;
    
            assert((get_bits_count(&s->gb) & 7) == 0);
            skip_bits_long(&s->gb, *pos - *end_pos);
    
            *end_pos2 =
            *end_pos  = *end_pos2 + get_bits_count(&s->gb) - *pos;
            *pos      = get_bits_count(&s->gb);
    
    /* Following is a optimized code for
                INTFLOAT v = *src
                if(get_bits1(&s->gb))
                    v = -v;
                *dst = v;
    */
    #if CONFIG_FLOAT
    
    #define READ_FLIP_SIGN(dst,src)                     \
        v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31);  \
        AV_WN32A(dst, v);
    
    #define READ_FLIP_SIGN(dst,src)     \
        v      = -get_bits1(&s->gb);    \
        *(dst) = (*(src) ^ v) - v;
    
    static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
    
        int end_pos = FFMIN(end_pos2, s->gb.size_in_bits);
    
    
        /* low frequencies (called big values) */
        s_index = 0;
    
        for (i = 0; i < 3; i++) {
    
            j = g->region_size[i];
            if (j == 0)
                continue;
            /* select vlc table */
    
            k       = g->table_select[i];
            l       = mpa_huff_data[k][0];
    
            vlc     = &huff_vlc[l];
    
            if (!l) {
                memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j);
                s_index += 2 * j;
    
            /* read huffcode and compute each couple */
    
            for (; j > 0; j--) {
    
                int exponent, x, y;
    
                int pos = get_bits_count(&s->gb);
    
                    switch_buffer(s, &pos, &end_pos, &end_pos2);
    
                    if (pos >= end_pos)
    
                y = get_vlc2(&s->gb, vlc->table, 7, 3);
    
                    g->sb_hybrid[s_index  ] =
                    g->sb_hybrid[s_index+1] = 0;
                    s_index += 2;
                    continue;
                }
    
    
                exponent= exponents[s_index];
    
                ff_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n",
    
                        i, g->region_size[i] - j, x, y, exponent);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    x = y >> 5;
                    y = y & 0x0f;
    
                    if (x < 15) {
                        READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x)
                    } else {
    
                        x += get_bitsz(&s->gb, linbits);
    
                        v  = l3_unscale(x, exponent);
    
                        if (get_bits1(&s->gb))
                            v = -v;
                        g->sb_hybrid[s_index] = v;
    
                    if (y < 15) {
                        READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y)
                    } else {
    
                        y += get_bitsz(&s->gb, linbits);
    
                        v  = l3_unscale(y, exponent);
    
                        if (get_bits1(&s->gb))
                            v = -v;
                        g->sb_hybrid[s_index+1] = v;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    x = y >> 5;
                    y = y & 0x0f;
                    x += y;
    
                    if (x < 15) {
                        READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x)
                    } else {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                        x += get_bitsz(&s->gb, linbits);
    
                        v  = l3_unscale(x, exponent);
    
                        if (get_bits1(&s->gb))
                            v = -v;
                        g->sb_hybrid[s_index+!!y] = v;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    }
    
                    g->sb_hybrid[s_index + !y] = 0;
    
        /* high frequencies */
        vlc = &huff_quad_vlc[g->count1table_select];
    
            pos = get_bits_count(&s->gb);
            if (pos >= end_pos) {
    
                if (pos > end_pos2 && last_pos) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    /* some encoders generate an incorrect size for this
                       part. We must go back into the data */
                    s_index -= 4;
                    skip_bits_long(&s->gb, last_pos - pos);
    
                    av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos);
    
                    if(s->err_recognition & AV_EF_BITSTREAM)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    break;
                }
    
                switch_buffer(s, &pos, &end_pos, &end_pos2);
    
                if (pos >= end_pos)
    
            code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1);
    
            ff_dlog(s->avctx, "t=%d code=%d\n", g->count1table_select, code);
    
            g->sb_hybrid[s_index+0] =
            g->sb_hybrid[s_index+1] =
            g->sb_hybrid[s_index+2] =
            g->sb_hybrid[s_index+3] = 0;
            while (code) {
                static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 };
    
                int pos = s_index + idxtab[code];
                code   ^= 8 >> idxtab[code];
                READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos])
    
        bits_left = end_pos2 - get_bits_count(&s->gb);
    
        if (bits_left < 0 && (s->err_recognition & AV_EF_BUFFER)) {
    
            av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
    
        } else if (bits_left > 0 && (s->err_recognition & AV_EF_BUFFER)) {
    
            av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
    
        memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index));
    
        i = get_bits_count(&s->gb);
    
        switch_buffer(s, &i, &end_pos, &end_pos2);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }
    
    
    /* Reorder short blocks from bitstream order to interleaved order. It
       would be faster to do it in parsing, but the code would be far more
       complicated */
    static void reorder_block(MPADecodeContext *s, GranuleDef *g)
    {
    
        INTFLOAT *ptr, *dst, *ptr1;
        INTFLOAT tmp[576];
    
            if (s->sample_rate_index != 8)