Skip to content
Snippets Groups Projects
mpegaudiodec.c 66.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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)
    
        for (i = g->short_start; i < 13; i++) {
            len  = band_size_short[s->sample_rate_index][i];
    
            dst  = tmp;
            for (j = len; j > 0; j--) {
    
                *dst++ = ptr[0*len];
                *dst++ = ptr[1*len];
                *dst++ = ptr[2*len];
                ptr++;
    
    static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)
    
        int sf_max, sf, len, non_zero_found;
        INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2;
    
        int non_zero_found_short[3];
    
        /* intensity stereo */
        if (s->mode_ext & MODE_EXT_I_STEREO) {
            if (!s->lsf) {
                is_tab = is_table;
                sf_max = 7;
            } else {
                is_tab = is_table_lsf[g1->scalefac_compress & 1];
                sf_max = 16;
            }
    
            tab0 = g0->sb_hybrid + 576;
            tab1 = g1->sb_hybrid + 576;
    
            non_zero_found_short[0] = 0;
            non_zero_found_short[1] = 0;
            non_zero_found_short[2] = 0;
            k = (13 - g1->short_start) * 3 + g1->long_end - 3;
    
            for (i = 12; i >= g1->short_start; i--) {
    
                /* for last band, use previous scale factor */
                if (i != 11)
                    k -= 3;
                len = band_size_short[s->sample_rate_index][i];
    
                for (l = 2; l >= 0; l--) {
    
                    tab0 -= len;
                    tab1 -= len;
                    if (!non_zero_found_short[l]) {
                        /* test if non zero band. if so, stop doing i-stereo */
    
                        for (j = 0; j < len; j++) {
    
                            if (tab1[j] != 0) {
                                non_zero_found_short[l] = 1;
                                goto found1;
                            }
                        }
                        sf = g1->scale_factors[k + l];
                        if (sf >= sf_max)
                            goto found1;
    
                        v1 = is_tab[0][sf];
                        v2 = is_tab[1][sf];
    
                        for (j = 0; j < len; j++) {
                            tmp0    = tab0[j];
    
                            tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
                            tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
    
                        if (s->mode_ext & MODE_EXT_MS_STEREO) {
                            /* lower part of the spectrum : do ms stereo
                               if enabled */
    
                            for (j = 0; j < len; j++) {
                                tmp0    = tab0[j];
                                tmp1    = tab1[j];
    
                                tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
                                tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
    
            non_zero_found = non_zero_found_short[0] |
    
                             non_zero_found_short[1] |
                             non_zero_found_short[2];
    
            for (i = g1->long_end - 1;i >= 0;i--) {
                len   = band_size_long[s->sample_rate_index][i];
    
                tab0 -= len;
                tab1 -= len;
                /* test if non zero band. if so, stop doing i-stereo */
                if (!non_zero_found) {
    
                    for (j = 0; j < len; j++) {
    
                        if (tab1[j] != 0) {
                            non_zero_found = 1;
                            goto found2;
                        }
                    }
                    /* for last band, use previous scale factor */
    
                    k  = (i == 21) ? 20 : i;
    
                    sf = g1->scale_factors[k];
                    if (sf >= sf_max)
                        goto found2;
                    v1 = is_tab[0][sf];
                    v2 = is_tab[1][sf];
    
                    for (j = 0; j < len; j++) {
                        tmp0    = tab0[j];
    
                        tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
                        tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
    
                    if (s->mode_ext & MODE_EXT_MS_STEREO) {
                        /* lower part of the spectrum : do ms stereo
                           if enabled */
    
                        for (j = 0; j < len; j++) {
                            tmp0    = tab0[j];
                            tmp1    = tab1[j];
    
                            tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
                            tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
    
                        }
                    }
                }
            }
        } else if (s->mode_ext & MODE_EXT_MS_STEREO) {
            /* ms stereo ONLY */
            /* NOTE: the 1/sqrt(2) normalization factor is included in the
               global gain */
            tab0 = g0->sb_hybrid;
            tab1 = g1->sb_hybrid;
    
            for (i = 0; i < 576; i++) {
                tmp0    = tab0[i];
                tmp1    = tab1[i];
    
    #if CONFIG_FLOAT
    #define AA(j) do {                                                      \
            float tmp0 = ptr[-1-j];                                         \
            float tmp1 = ptr[   j];                                         \
            ptr[-1-j] = tmp0 * csa_table[j][0] - tmp1 * csa_table[j][1];    \
            ptr[   j] = tmp0 * csa_table[j][1] + tmp1 * csa_table[j][0];    \
        } while (0)
    #else
    #define AA(j) do {                                              \
            int tmp0 = ptr[-1-j];                                   \
            int tmp1 = ptr[   j];                                   \
            int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]);          \
    
            ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2]));   \
            ptr[   j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3]));   \
    
        } while (0)
    #endif
    
    static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int n, i;
    
    
        /* we antialias only "long" bands */
        if (g->block_type == 2) {
            if (!g->switch_point)
                return;
            /* XXX: check this for 8000Hz case */
            n = 1;
        } else {
            n = SBLIMIT - 1;
        }
    
        for (i = n; i > 0; i--) {
    
    static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
                              INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
    
        INTFLOAT *win, *out_ptr, *ptr, *buf, *ptr1;
    
        INTFLOAT out2[12];
        int i, j, mdct_long_end, sblimit;
    
        ptr  = g->sb_hybrid + 576;
    
        ptr1 = g->sb_hybrid + 2 * 18;
        while (ptr >= ptr1) {
    
            p    = (int32_t*)ptr;
            if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5])
    
                break;
        }
        sblimit = ((ptr - g->sb_hybrid) / 18) + 1;
    
        if (g->block_type == 2) {
            /* XXX: check for 8000 Hz */
            if (g->switch_point)
                mdct_long_end = 2;
            else
                mdct_long_end = 0;
        } else {
            mdct_long_end = sblimit;
        }
    
    
        s->mpadsp.RENAME(imdct36_blocks)(sb_samples, mdct_buf, g->sb_hybrid,
                                         mdct_long_end, g->switch_point,
                                         g->block_type);
    
        buf = mdct_buf + 4*18*(mdct_long_end >> 2) + (mdct_long_end & 3);
        ptr = g->sb_hybrid + 18 * mdct_long_end;
    
    
        for (j = mdct_long_end; j < sblimit; j++) {
    
            win     = RENAME(ff_mdct_win)[2 + (4  & -(j & 1))];
    
            for (i = 0; i < 6; i++) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                out_ptr += SBLIMIT;
            }
            imdct12(out2, ptr + 0);
    
            for (i = 0; i < 6; i++) {
    
                *out_ptr     = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*1)];
                buf[4*(i + 6*2)] = MULH3(out2[i + 6], win[i + 6], 1);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            imdct12(out2, ptr + 1);
    
            for (i = 0; i < 6; i++) {
    
                *out_ptr     = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*2)];
                buf[4*(i + 6*0)] = MULH3(out2[i + 6], win[i + 6], 1);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                out_ptr += SBLIMIT;
            }
            imdct12(out2, ptr + 2);
    
            for (i = 0; i < 6; i++) {
    
                buf[4*(i + 6*0)] = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*0)];
                buf[4*(i + 6*1)] = MULH3(out2[i + 6], win[i + 6], 1);
                buf[4*(i + 6*2)] = 0;
    
        for (j = sblimit; j < SBLIMIT; j++) {
    
            for (i = 0; i < 18; i++) {
    
        }
    }
    
    /* main layer3 decoding function */
    static int mp_decode_layer3(MPADecodeContext *s)
    {
    
        int nb_granules, main_data_begin;
    
        int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;
    
        int16_t exponents[576]; //FIXME try INTFLOAT
    
    
        /* read side info */
        if (s->lsf) {
            main_data_begin = get_bits(&s->gb, 8);
    
            skip_bits(&s->gb, s->nb_channels);
    
            nb_granules = 1;
        } else {
            main_data_begin = get_bits(&s->gb, 9);
            if (s->nb_channels == 2)
    
                skip_bits(&s->gb, 3);
    
                skip_bits(&s->gb, 5);
    
            for (ch = 0; ch < s->nb_channels; ch++) {
    
                s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */
                s->granules[ch][1].scfsi = get_bits(&s->gb, 4);
    
        for (gr = 0; gr < nb_granules; gr++) {
            for (ch = 0; ch < s->nb_channels; ch++) {
    
                av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);
    
                g = &s->granules[ch][gr];
    
                g->part2_3_length = get_bits(&s->gb, 12);
    
                g->big_values     = get_bits(&s->gb,  9);
                if (g->big_values > 288) {
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                    av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");
    
                    return AVERROR_INVALIDDATA;
    
                g->global_gain = get_bits(&s->gb, 8);
                /* if MS stereo only is selected, we precompute the
                   1/sqrt(2) renormalization factor */
    
                if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) ==
    
                    MODE_EXT_MS_STEREO)
                    g->global_gain -= 2;
                if (s->lsf)
                    g->scalefac_compress = get_bits(&s->gb, 9);
                else
                    g->scalefac_compress = get_bits(&s->gb, 4);
    
                blocksplit_flag = get_bits1(&s->gb);
    
                if (blocksplit_flag) {
                    g->block_type = get_bits(&s->gb, 2);
    
                    if (g->block_type == 0) {
    
                        av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");
    
                        return AVERROR_INVALIDDATA;
    
                    g->switch_point = get_bits1(&s->gb);
    
                    for (i = 0; i < 2; i++)
    
                        g->table_select[i] = get_bits(&s->gb, 5);
    
                    for (i = 0; i < 3; i++)
    
                        g->subblock_gain[i] = get_bits(&s->gb, 3);
    
                    int region_address1, region_address2;
    
                    for (i = 0; i < 3; i++)
    
                        g->table_select[i] = get_bits(&s->gb, 5);
                    /* compute huffman coded region sizes */
                    region_address1 = get_bits(&s->gb, 4);
                    region_address2 = get_bits(&s->gb, 3);
    
                    av_dlog(s->avctx, "region1=%d region2=%d\n",
    
                    ff_init_long_region(s, g, region_address1, region_address2);
    
                ff_region_offset2size(g);
                ff_compute_band_indexes(s, g);
    
                    g->preflag = get_bits1(&s->gb);
    
                g->scalefac_scale     = get_bits1(&s->gb);
    
                g->count1table_select = get_bits1(&s->gb);
    
                av_dlog(s->avctx, "block_type=%d switch_point=%d\n",
    
        if (!s->adu_mode) {
    
            const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
    
            int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES);
    
            assert((get_bits_count(&s->gb) & 7) == 0);
            /* now we get bits from the main_data_begin offset */
            av_dlog(s->avctx, "seekback: %d\n", main_data_begin);
        //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size);
    
            memcpy(s->last_buf + s->last_buf_size, ptr, extrasize);
    
            init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
    
            s->gb.size_in_bits_plus8 += extrasize * 8;
    
            s->last_buf_size <<= 3;
    
            for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) {
                for (ch = 0; ch < s->nb_channels; ch++) {
    
                    g = &s->granules[ch][gr];
                    s->last_buf_size += g->part2_3_length;
    
                    memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
                }
    
            skip = s->last_buf_size - 8 * main_data_begin;
            if (skip >= s->gb.size_in_bits && s->in_gb.buffer) {
                skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits);
    
                s->gb           = s->in_gb;
                s->in_gb.buffer = NULL;
    
            } else {
                skip_bits_long(&s->gb, skip);
    
        for (; gr < nb_granules; gr++) {
            for (ch = 0; ch < s->nb_channels; ch++) {
    
                g = &s->granules[ch][gr];
    
                    uint8_t *sc;
    
                    int slen, slen1, slen2;
    
                    /* MPEG1 scale factors */
                    slen1 = slen_table[0][g->scalefac_compress];
                    slen2 = slen_table[1][g->scalefac_compress];
    
                    av_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2);
    
                    if (g->block_type == 2) {
                        n = g->switch_point ? 17 : 18;
                        j = 0;
    
                        if (slen1) {
                            for (i = 0; i < n; i++)
    
                                g->scale_factors[j++] = get_bits(&s->gb, slen1);
    
                        } else {
                            for (i = 0; i < n; i++)
    
                                g->scale_factors[j++] = 0;
                        }
    
                        if (slen2) {
                            for (i = 0; i < 18; i++)
    
                                g->scale_factors[j++] = get_bits(&s->gb, slen2);
    
                            for (i = 0; i < 3; i++)
    
                                g->scale_factors[j++] = 0;
    
                        } else {
                            for (i = 0; i < 21; i++)
    
                                g->scale_factors[j++] = 0;
                        }
    
                        sc = s->granules[ch][0].scale_factors;
    
                        for (k = 0; k < 4; k++) {
                            n = k == 0 ? 6 : 5;
    
                            if ((g->scfsi & (0x8 >> k)) == 0) {
                                slen = (k < 2) ? slen1 : slen2;
    
                                if (slen) {
                                    for (i = 0; i < n; i++)
    
                                        g->scale_factors[j++] = get_bits(&s->gb, slen);
    
                                } else {
                                    for (i = 0; i < n; i++)
    
                                        g->scale_factors[j++] = 0;
                                }
    
                                for (i = 0; i < n; i++) {
    
                                    g->scale_factors[j] = sc[j];
                                    j++;
                                }
                            }
                        }
                        g->scale_factors[j++] = 0;
                    }
                } else {
                    int tindex, tindex2, slen[4], sl, sf;
    
                    /* LSF scale factors */
    
                    if (g->block_type == 2)
    
                    sf = g->scalefac_compress;
                    if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {
                        /* intensity stereo case */
                        sf >>= 1;
                        if (sf < 180) {
                            lsf_sf_expand(slen, sf, 6, 6, 0);
                            tindex2 = 3;
                        } else if (sf < 244) {
                            lsf_sf_expand(slen, sf - 180, 4, 4, 0);
                            tindex2 = 4;
                        } else {
                            lsf_sf_expand(slen, sf - 244, 3, 0, 0);
                            tindex2 = 5;
                        }
                    } else {
                        /* normal case */
                        if (sf < 400) {
                            lsf_sf_expand(slen, sf, 5, 4, 4);
                            tindex2 = 0;
                        } else if (sf < 500) {
                            lsf_sf_expand(slen, sf - 400, 5, 4, 0);
                            tindex2 = 1;
                        } else {
                            lsf_sf_expand(slen, sf - 500, 3, 0, 0);
                            tindex2 = 2;
                            g->preflag = 1;
                        }
                    }
    
                    j = 0;
    
                    for (k = 0; k < 4; k++) {
                        n  = lsf_nsf_table[tindex2][tindex][k];
    
                        if (sl) {
                            for (i = 0; i < n; i++)
    
                                g->scale_factors[j++] = get_bits(&s->gb, sl);
    
                        } else {
                            for (i = 0; i < n; i++)
    
                                g->scale_factors[j++] = 0;
                        }
    
                    for (; j < 40; j++)
    
                        g->scale_factors[j] = 0;
                }
    
                exponents_from_scale_factors(s, g, exponents);
    
                /* read Huffman coded residue */
    
                huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);
    
                compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);
    
            for (ch = 0; ch < s->nb_channels; ch++) {
    
                g = &s->granules[ch][gr];
    
                compute_antialias(s, g);
    
                compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
    
        if (get_bits_count(&s->gb) < 0)
    
            skip_bits_long(&s->gb, -get_bits_count(&s->gb));
    
    static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples,
                               const uint8_t *buf, int buf_size)
    
        int i, nb_frames, ch, ret;
    
        init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
    
        /* skip error protection field */
        if (s->error_protection)
    
            skip_bits(&s->gb, 16);
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
            s->avctx->frame_size = 384;
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
            s->avctx->frame_size = 1152;
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
            s->avctx->frame_size = s->lsf ? 576 : 1152;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            s->last_buf_size=0;
    
            if (s->in_gb.buffer) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                align_get_bits(&s->gb);
    
                i = get_bits_left(&s->gb)>>3;
                if (i >= 0 && i <= BACKSTEP_SIZE) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i);
                    s->last_buf_size=i;
    
                    av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i);
    
                s->gb           = s->in_gb;
                s->in_gb.buffer = NULL;
    
            align_get_bits(&s->gb);
            assert((get_bits_count(&s->gb) & 7) == 0);
    
            i = get_bits_left(&s->gb) >> 3;
    
            if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) {
                if (i < 0)
    
                    av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i);
    
                i = FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE);
    
            assert(i <= buf_size - HEADER_SIZE && i >= 0);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            s->last_buf_size += i;
    
        /* get output buffer */
        if (!samples) {
            s->frame.nb_samples = s->avctx->frame_size;
            if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) {
                av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                return ret;
            }
            samples = (OUT_INT *)s->frame.data[0];
    
        for (ch = 0; ch < s->nb_channels; ch++) {
    
            for (i = 0; i < nb_frames; i++) {
    
                             s->synth_buf[ch], &(s->synth_buf_offset[ch]),
    
                             RENAME(ff_mpa_synth_window), &s->dither_state,
    
                             samples_ptr, s->nb_channels,
    
                             s->sb_samples[ch][i]);
                samples_ptr += 32 * s->nb_channels;
            }
        }
    
        return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
    
    static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr,
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        const uint8_t *buf  = avpkt->data;
        int buf_size        = avpkt->size;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        MPADecodeContext *s = avctx->priv_data;
    
        uint32_t header;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (buf_size < HEADER_SIZE)
    
            return AVERROR_INVALIDDATA;
    
        header = AV_RB32(buf);
    
        if (ff_mpa_check_header(header) < 0) {
    
            av_log(avctx, AV_LOG_ERROR, "Header missing\n");
    
            return AVERROR_INVALIDDATA;
    
        if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
    
            /* free format: prepare to compute frame size */
            s->frame_size = -1;
    
            return AVERROR_INVALIDDATA;
    
        avctx->channels       = s->nb_channels;
    
        avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
    
        if (!avctx->bit_rate)
            avctx->bit_rate = s->bit_rate;
    
        if (s->frame_size <= 0 || s->frame_size > buf_size) {
    
            av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
    
            return AVERROR_INVALIDDATA;
    
        } else if (s->frame_size < buf_size) {
    
            av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
        out_size = mp_decode_frame(s, NULL, buf, buf_size);
    
        if (out_size >= 0) {
    
            *got_frame_ptr   = 1;
            *(AVFrame *)data = s->frame;
    
            avctx->sample_rate = s->sample_rate;
            //FIXME maybe move the other codec info stuff from above here too
    
        } else {
            av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
            /* Only return an error if the bad frame makes up the whole packet.
               If there is more data in the packet, just consume the bad frame
               instead of returning an error, which would discard the whole
               packet. */
    
            *got_frame_ptr = 0;
    
            if (buf_size == avpkt->size)
                return out_size;
        }
    
    static void flush(AVCodecContext *avctx)
    {
    
        MPADecodeContext *s = avctx->priv_data;
    
        memset(s->synth_buf, 0, sizeof(s->synth_buf));
    
        s->last_buf_size = 0;
    
    #if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
    
    static int decode_frame_adu(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
    
        const uint8_t *buf  = avpkt->data;
        int buf_size        = avpkt->size;
    
    Roberto Togni's avatar
    Roberto Togni committed
        MPADecodeContext *s = avctx->priv_data;
        uint32_t header;
        int len, out_size;
    
        len = buf_size;
    
        // Discard too short frames
        if (buf_size < HEADER_SIZE) {
    
            av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
            return AVERROR_INVALIDDATA;
    
    Roberto Togni's avatar
    Roberto Togni committed
        }
    
    
        if (len > MPA_MAX_CODED_FRAME_SIZE)
            len = MPA_MAX_CODED_FRAME_SIZE;
    
        // Get header and restore sync word
    
        header = AV_RB32(buf) | 0xffe00000;
    
        if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame
    
            av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
            return AVERROR_INVALIDDATA;
    
        avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
    
    Roberto Togni's avatar
    Roberto Togni committed
        /* update codec info */
        avctx->sample_rate = s->sample_rate;
    
        avctx->channels    = s->nb_channels;
    
        if (!avctx->bit_rate)
            avctx->bit_rate = s->bit_rate;
    
    Roberto Togni's avatar
    Roberto Togni committed
        avctx->sub_id = s->layer;
    
    
        out_size = mp_decode_frame(s, NULL, buf, buf_size);
    
        *got_frame_ptr   = 1;
        *(AVFrame *)data = s->frame;
    
    Roberto Togni's avatar
    Roberto Togni committed
    
        return buf_size;
    }
    
    #endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */
    
    #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
    
    /**
     * Context for MP3On4 decoder
     */
    typedef struct MP3On4DecodeContext {
    
        AVFrame *frame;
    
        int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
        int syncword;                   ///< syncword patch
        const uint8_t *coff;            ///< channel offsets in output buffer
    
        MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
    
        OUT_INT *decoded_buf;           ///< output buffer for decoded samples
    
    #include "mpeg4audio.h"
    
    
    /* Next 3 arrays are indexed by channel config number (passed via codecdata) */
    
    
    /* number of mp3 decoder instances */
    static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 };
    
    
    /* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */
    
    static const uint8_t chan_offset[8][5] = {
    
        { 0             },
        { 0             },  // C
        { 0             },  // FLR
        { 2, 0          },  // C FLR
        { 2, 0, 3       },  // C FLR BS
        { 2, 0, 3       },  // C FLR BLRS
        { 2, 0, 4, 3    },  // C FLR BLRS LFE
        { 2, 0, 6, 4, 3 },  // C FLR BLRS BLR LFE
    
    /* mp3on4 channel layouts */
    static const int16_t chan_layout[8] = {
        0,
        AV_CH_LAYOUT_MONO,
        AV_CH_LAYOUT_STEREO,
        AV_CH_LAYOUT_SURROUND,
        AV_CH_LAYOUT_4POINT0,
        AV_CH_LAYOUT_5POINT0,
        AV_CH_LAYOUT_5POINT1,
        AV_CH_LAYOUT_7POINT1
    };
    
    static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
    {
        MP3On4DecodeContext *s = avctx->priv_data;
        int i;
    
        for (i = 0; i < s->frames; i++)
            av_free(s->mp3decctx[i]);
    
        av_freep(&s->decoded_buf);
    
        return 0;
    }
    
    
    
    static int decode_init_mp3on4(AVCodecContext * avctx)
    {
        MP3On4DecodeContext *s = avctx->priv_data;
    
        MPEG4AudioConfig cfg;
    
        int i;
    
        if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) {
            av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");
    
            return AVERROR_INVALIDDATA;
    
        avpriv_mpeg4audio_get_config(&cfg, avctx->extradata,
                                     avctx->extradata_size * 8, 1);
    
        if (!cfg.chan_config || cfg.chan_config > 7) {
    
            av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
    
            return AVERROR_INVALIDDATA;
    
        s->frames             = mp3Frames[cfg.chan_config];
        s->coff               = chan_offset[cfg.chan_config];
        avctx->channels       = ff_mpeg4audio_channels[cfg.chan_config];
    
        avctx->channel_layout = chan_layout[cfg.chan_config];
    
        if (cfg.sample_rate < 16000)
            s->syncword = 0xffe00000;
        else
            s->syncword = 0xfff00000;
    
    
        /* Init the first mp3 decoder in standard way, so that all tables get builded
         * We replace avctx->priv_data with the context of the first decoder so that
         * decode_init() does not have to be changed.
    
         * Other decoders will be initialized here copying data from the first context
    
         */
        // Allocate zeroed memory for the first decoder context
        s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));
    
        if (!s->mp3decctx[0])
            goto alloc_fail;
    
        // Put decoder context in place to make init_decode() happy
        avctx->priv_data = s->mp3decctx[0];
        decode_init(avctx);
    
        s->frame = avctx->coded_frame;
    
        // Restore mp3on4 context pointer
        avctx->priv_data = s;
        s->mp3decctx[0]->adu_mode = 1; // Set adu mode
    
        /* Create a separate codec/context for each frame (first is already ok).
         * Each frame is 1 or 2 channels - up to 5 frames allowed
         */
        for (i = 1; i < s->frames; i++) {
            s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));
    
            if (!s->mp3decctx[i])
                goto alloc_fail;
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
            s->mp3decctx[i]->avctx = avctx;
    
            s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
    
        /* Allocate buffer for multi-channel output if needed */
        if (s->frames > 1) {
            s->decoded_buf = av_malloc(MPA_FRAME_SIZE * MPA_MAX_CHANNELS *
                                       sizeof(*s->decoded_buf));
            if (!s->decoded_buf)
                goto alloc_fail;
        }
    
    alloc_fail:
        decode_close_mp3on4(avctx);
        return AVERROR(ENOMEM);
    
    static void flush_mp3on4(AVCodecContext *avctx)
    {
        int i;
        MP3On4DecodeContext *s = avctx->priv_data;
    
        for (i = 0; i < s->frames; i++) {
            MPADecodeContext *m = s->mp3decctx[i];
            memset(m->synth_buf, 0, sizeof(m->synth_buf));
            m->last_buf_size = 0;
        }
    }
    
    
    
    static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
                                   int *got_frame_ptr, AVPacket *avpkt)
    
        const uint8_t *buf     = avpkt->data;
        int buf_size           = avpkt->size;
    
        MP3On4DecodeContext *s = avctx->priv_data;
        MPADecodeContext *m;
    
        int fsize, len = buf_size, out_size = 0;
    
        OUT_INT *out_samples;
    
        int fr, j, n, ch, ret;
    
        /* get output buffer */
        s->frame->nb_samples = MPA_FRAME_SIZE;
        if ((ret = avctx->get_buffer(avctx, s->frame)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
            return ret;
    
        out_samples = (OUT_INT *)s->frame->data[0];
    
        if (buf_size < HEADER_SIZE)
    
            return AVERROR_INVALIDDATA;
    
    
        // If only one decoder interleave is not needed
    
        outptr = s->frames == 1 ? out_samples : s->decoded_buf;
    
        avctx->bit_rate = 0;
    
    
        for (fr = 0; fr < s->frames; fr++) {
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
            fsize = AV_RB16(buf) >> 4;
    
            fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
    
            m     = s->mp3decctx[fr];
            assert(m != NULL);
    
            if (fsize < HEADER_SIZE) {
                av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
                return AVERROR_INVALIDDATA;
            }
    
            header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
    
            if (ff_mpa_check_header(header) < 0) // Bad header, discard block
                break;
    
            avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
    
    
            if (ch + m->nb_channels > avctx->channels) {
                av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
                                            "channel count\n");
                return AVERROR_INVALIDDATA;
            }
            ch += m->nb_channels;
    
    
            out_size += mp_decode_frame(m, outptr, buf, fsize);
    
            buf      += fsize;
            len      -= fsize;
    
            if (s->frames > 1) {
    
                n = m->avctx->frame_size*m->nb_channels;
    
                bp = out_samples + s->coff[fr];
    
                if (m->nb_channels == 1) {
                    for (j = 0; j < n; j++) {
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
                        bp += avctx->channels;
    
                    for (j = 0; j < n; j++) {
    
                        bp[0] = s->decoded_buf[j++];
                        bp[1] = s->decoded_buf[j];
    
                        bp   += avctx->channels;
    
            avctx->bit_rate += m->bit_rate;
    
        }
    
        /* update codec info */
        avctx->sample_rate = s->mp3decctx[0]->sample_rate;
    
    
        s->frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
        *got_frame_ptr   = 1;
        *(AVFrame *)data = *s->frame;
    
    
    #endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
    
    #if !CONFIG_FLOAT
    
    #if CONFIG_MP1_DECODER
    
    AVCodec ff_mp1_decoder = {
        .name           = "mp1",
        .type           = AVMEDIA_TYPE_AUDIO,
        .id             = CODEC_ID_MP1,
        .priv_data_size = sizeof(MPADecodeContext),
        .init           = decode_init,
        .decode         = decode_frame,
    
        .capabilities   = CODEC_CAP_DR1,
    
        .flush          = flush,
        .long_name      = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
    
    #if CONFIG_MP2_DECODER
    
    AVCodec ff_mp2_decoder = {
        .name           = "mp2",
        .type           = AVMEDIA_TYPE_AUDIO,
        .id             = CODEC_ID_MP2,
        .priv_data_size = sizeof(MPADecodeContext),
        .init           = decode_init,
        .decode         = decode_frame,
    
        .capabilities   = CODEC_CAP_DR1,
    
        .flush          = flush,
        .long_name      = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    };
    
    #if CONFIG_MP3_DECODER