Skip to content
Snippets Groups Projects
mpegaudiodec.c 80.1 KiB
Newer Older
  • Learn to ignore specific revisions
  •         /* normalize to 23 frac bits */
            v = tab[i] << (23 - FRAC_BITS);
    
            fwrite(&v, 1, sizeof(int32_t), f);
    
    }
    #endif
    
    
    /* main layer3 decoding function */
    static int mp_decode_layer3(MPADecodeContext *s)
    {
        int nb_granules, main_data_begin, private_bits;
    
        int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;
    
        int16_t exponents[576];
    
    
        /* read side info */
        if (s->lsf) {
            main_data_begin = get_bits(&s->gb, 8);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            private_bits = get_bits(&s->gb, s->nb_channels);
    
            nb_granules = 1;
        } else {
            main_data_begin = get_bits(&s->gb, 9);
            if (s->nb_channels == 2)
                private_bits = get_bits(&s->gb, 3);
            else
                private_bits = get_bits(&s->gb, 5);
            nb_granules = 2;
            for(ch=0;ch<s->nb_channels;ch++) {
                granules[ch][0].scfsi = 0; /* all scale factors are transmitted */
                granules[ch][1].scfsi = get_bits(&s->gb, 4);
            }
        }
    
        for(gr=0;gr<nb_granules;gr++) {
            for(ch=0;ch<s->nb_channels;ch++) {
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                dprintf(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);
    
                g = &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");
    
                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(NULL, AV_LOG_ERROR, "invalid block type\n");
    
                    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;
    
                    g->block_type = 0;
                    g->switch_point = 0;
                    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);
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                    dprintf(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);
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                dprintf(s->avctx, "block_type=%d switch_point=%d\n",
    
    Roberto Togni's avatar
    Roberto Togni committed
      if (!s->adu_mode) {
    
        const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        assert((get_bits_count(&s->gb) & 7) == 0);
    
        /* now we get bits from the main_data_begin offset */
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
        dprintf(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, EXTRABYTES);
        s->in_gb= s->gb;
    
            init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
            skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin));
    
    
        for(gr=0;gr<nb_granules;gr++) {
            for(ch=0;ch<s->nb_channels;ch++) {
                g = &granules[ch][gr];
    
                if(get_bits_count(&s->gb)<0){
    
    Diego Biurrun's avatar
    Diego Biurrun committed
                    av_log(NULL, AV_LOG_ERROR, "mdb:%d, lastbuf:%d skipping granule %d\n",
    
                                                main_data_begin, s->last_buf_size, gr);
                    skip_bits_long(&s->gb, g->part2_3_length);
                    memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
                    if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer){
                        skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
                        s->gb= s->in_gb;
                        s->in_gb.buffer=NULL;
                    }
                    continue;
                }
    
                    uint8_t *sc;
    
                    int slen, slen1, slen2;
    
                    /* MPEG1 scale factors */
                    slen1 = slen_table[0][g->scalefac_compress];
                    slen2 = slen_table[1][g->scalefac_compress];
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                    dprintf(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;
                        }
    
                    } else {
                        sc = granules[ch][0].scale_factors;
                        j = 0;
                        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;
                                }
    
                            } else {
                                /* simply copy from last granule */
                                for(i=0;i<n;i++) {
                                    g->scale_factors[j] = sc[j];
                                    j++;
                                }
                            }
                        }
                        g->scale_factors[j++] = 0;
                    }
    
    #if defined(DEBUG)
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                        dprintf(s->avctx, "scfsi=%x gr=%d ch=%d scale_factors:\n",
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                            dprintf(s->avctx, " %d", g->scale_factors[i]);
                        dprintf(s->avctx, "\n");
    
                    }
    #endif
                } else {
                    int tindex, tindex2, slen[4], sl, sf;
    
                    /* LSF scale factors */
                    if (g->block_type == 2) {
                        tindex = g->switch_point ? 2 : 1;
                    } else {
                        tindex = 0;
                    }
                    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];
                        sl = slen[k];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                        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;
                        }
    
                    }
                    /* XXX: should compute exact size */
                    for(;j<40;j++)
                        g->scale_factors[j] = 0;
    
    #if defined(DEBUG)
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                        dprintf(s->avctx, "gr=%d ch=%d scale_factors:\n",
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                            dprintf(s->avctx, " %d", g->scale_factors[i]);
                        dprintf(s->avctx, "\n");
    
                    }
    #endif
                }
    
                exponents_from_scale_factors(s, g, exponents);
    
                /* read Huffman coded residue */
    
                huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);
    
    #if defined(DEBUG)
                sample_dump(0, g->sb_hybrid, 576);
    
    #endif
            } /* ch */
    
            if (s->nb_channels == 2)
                compute_stereo(s, &granules[0][gr], &granules[1][gr]);
    
            for(ch=0;ch<s->nb_channels;ch++) {
                g = &granules[ch][gr];
    
                reorder_block(s, g);
    
    #if defined(DEBUG)
    
                compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
    
                sample_dump(2, &s->sb_samples[ch][18 * gr][0], 576);
    #endif
            }
        } /* gr */
    
        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)
    
        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);
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
        dprintf(s->avctx, "frame %d:\n", s->frame_count);
    
    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){
                align_get_bits(&s->gb);
                i= (s->gb.size_in_bits - get_bits_count(&s->gb))>>3;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                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;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                }else
                    av_log(NULL, AV_LOG_ERROR, "invalid old backstep %d\n", i);
    
                s->in_gb.buffer= NULL;
    
            align_get_bits(&s->gb);
            assert((get_bits_count(&s->gb) & 7) == 0);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            i= (s->gb.size_in_bits - get_bits_count(&s->gb))>>3;
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            if(i<0 || i > BACKSTEP_SIZE || nb_frames<0){
                av_log(NULL, AV_LOG_ERROR, "invalid new backstep %d\n", i);
                i= FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE);
            }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            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;
    
            break;
        }
    #if defined(DEBUG)
        for(i=0;i<nb_frames;i++) {
            for(ch=0;ch<s->nb_channels;ch++) {
                int j;
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                dprintf(s->avctx, "%d-%d:", i, ch);
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                    dprintf(s->avctx, " %0.6f", (double)s->sb_samples[ch][i][j] / FRAC_ONE);
                dprintf(s->avctx, "\n");
    
            }
        }
    #endif
        /* apply the synthesis filter */
        for(ch=0;ch<s->nb_channels;ch++) {
            samples_ptr = samples + ch;
            for(i=0;i<nb_frames;i++) {
    
                ff_mpa_synth_filter(s->synth_buf[ch], &(s->synth_buf_offset[ch]),
    
                             window, &s->dither_state,
                             samples_ptr, s->nb_channels,
    
                             s->sb_samples[ch][i]);
                samples_ptr += 32 * s->nb_channels;
            }
        }
    #ifdef DEBUG
    
        s->frame_count++;
    
        return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    static int decode_frame(AVCodecContext * avctx,
    
                            void *data, int *data_size,
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                            const uint8_t * buf, int buf_size)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        MPADecodeContext *s = avctx->priv_data;
    
        uint32_t header;
    
        OUT_INT *out_samples = data;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        header = AV_RB32(buf);
    
        if(ff_mpa_check_header(header) < 0){
            buf++;
    //        buf_size--;
    
    Diego Biurrun's avatar
    Diego Biurrun committed
            av_log(avctx, AV_LOG_ERROR, "Header missing skipping one byte.\n");
    
        if (ff_mpegaudio_decode_header(s, header) == 1) {
    
            /* free format: prepare to compute frame size */
            s->frame_size = -1;
            return -1;
        }
        /* update codec info */
        avctx->channels = s->nb_channels;
        avctx->bit_rate = s->bit_rate;
        avctx->sub_id = s->layer;
    
    
        if(s->frame_size<=0 || s->frame_size > buf_size){
    
            av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
            return -1;
    
        }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, out_samples, buf, buf_size);
    
            avctx->sample_rate = s->sample_rate;
            //FIXME maybe move the other codec info stuff from above here too
        }else
    
    Diego Biurrun's avatar
    Diego Biurrun committed
            av_log(avctx, AV_LOG_DEBUG, "Error while decoding MPEG audio frame.\n"); //FIXME return -1 / but also return the number of bytes consumed
    
    static void flush(AVCodecContext *avctx){
        MPADecodeContext *s = avctx->priv_data;
    
        memset(s->synth_buf, 0, sizeof(s->synth_buf));
    
    #ifdef CONFIG_MP3ADU_DECODER
    
    Roberto Togni's avatar
    Roberto Togni committed
    static int decode_frame_adu(AVCodecContext * avctx,
    
                            void *data, int *data_size,
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                            const uint8_t * buf, int buf_size)
    
    Roberto Togni's avatar
    Roberto Togni committed
    {
        MPADecodeContext *s = avctx->priv_data;
        uint32_t header;
        int len, out_size;
    
        OUT_INT *out_samples = data;
    
    Roberto Togni's avatar
    Roberto Togni committed
    
        len = buf_size;
    
        // Discard too short frames
        if (buf_size < HEADER_SIZE) {
            *data_size = 0;
            return buf_size;
        }
    
    
        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
    
    Roberto Togni's avatar
    Roberto Togni committed
            *data_size = 0;
            return buf_size;
        }
    
    
        ff_mpegaudio_decode_header(s, header);
    
    Roberto Togni's avatar
    Roberto Togni committed
        /* update codec info */
        avctx->sample_rate = s->sample_rate;
        avctx->channels = s->nb_channels;
        avctx->bit_rate = s->bit_rate;
        avctx->sub_id = s->layer;
    
    
    Roberto Togni's avatar
    Roberto Togni committed
    
        if (avctx->parse_only) {
    
    Roberto Togni's avatar
    Roberto Togni committed
        } else {
    
            out_size = mp_decode_frame(s, out_samples, buf, buf_size);
    
    Roberto Togni's avatar
    Roberto Togni committed
        }
    
        *data_size = out_size;
        return buf_size;
    }
    
    #endif /* CONFIG_MP3ADU_DECODER */
    
    #ifdef CONFIG_MP3ON4_DECODER
    
    /**
     * Context for MP3On4 decoder
     */
    typedef struct MP3On4DecodeContext {
        int frames;   ///< number of mp3 frames per block (number of mp3 decoder instances)
        int syncword; ///< syncword patch
    
        const uint8_t *coff; ///< channels offsets in output buffer
    
        MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
    } MP3On4DecodeContext;
    
    
    #include "mpeg4audio.h"
    
    
    /* Next 3 arrays are indexed by channel config number (passed via codecdata) */
    
    static const uint8_t mp3Frames[8] = {0,1,1,2,3,3,4,5};   /* number of mp3 decoder instances */
    
    /* offsets into output buffer, assume output order is FL FR BL BR C LFE */
    
    static const uint8_t chan_offset[8][5] = {
    
        {0},
        {0},            // C
        {0},            // FLR
        {2,0},          // C FLR
        {2,0,3},        // C FLR BS
        {4,0,2},        // C FLR BLRS
        {4,0,2,5},      // C FLR BLRS LFE
        {4,0,2,6,5},    // C FLR BLRS BLR LFE
    };
    
    
    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 -1;
        }
    
    
        ff_mpeg4audio_get_config(&cfg, avctx->extradata, avctx->extradata_size);
        if (!cfg.chan_config || cfg.chan_config > 7) {
    
            av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
            return -1;
        }
    
        s->frames = mp3Frames[cfg.chan_config];
        s->coff = chan_offset[cfg.chan_config];
        avctx->channels = ff_mpeg4audio_channels[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));
        // Put decoder context in place to make init_decode() happy
        avctx->priv_data = s->mp3decctx[0];
        decode_init(avctx);
        // 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));
            s->mp3decctx[i]->compute_antialias = s->mp3decctx[0]->compute_antialias;
            s->mp3decctx[i]->adu_mode = 1;
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
            s->mp3decctx[i]->avctx = avctx;
    
        }
    
        return 0;
    }
    
    
    static int decode_close_mp3on4(AVCodecContext * avctx)
    {
        MP3On4DecodeContext *s = avctx->priv_data;
        int i;
    
        for (i = 0; i < s->frames; i++)
            if (s->mp3decctx[i])
                av_free(s->mp3decctx[i]);
    
        return 0;
    }
    
    
    static int decode_frame_mp3on4(AVCodecContext * avctx,
    
                            void *data, int *data_size,
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                            const uint8_t * buf, int buf_size)
    
    {
        MP3On4DecodeContext *s = avctx->priv_data;
        MPADecodeContext *m;
    
        int fsize, len = buf_size, out_size = 0;
    
        uint32_t header;
        OUT_INT *out_samples = data;
        OUT_INT decoded_buf[MPA_FRAME_SIZE * MPA_MAX_CHANNELS];
        OUT_INT *outptr, *bp;
    
        int fr, j, n;
    
        *data_size = 0;
    
        if (buf_size < HEADER_SIZE)
            return -1;
    
    
        // If only one decoder interleave is not needed
        outptr = s->frames == 1 ? out_samples : 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);
    
            header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
    
            if (ff_mpa_check_header(header) < 0) // Bad header, discard block
                break;
    
            ff_mpegaudio_decode_header(m, header);
    
            out_size += mp_decode_frame(m, outptr, buf, fsize);
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
            buf += fsize;
            len -= fsize;
    
                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++) {
                        *bp = decoded_buf[j];
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
                        bp += avctx->channels;
    
                    }
                } else {
                    for(j = 0; j < n; j++) {
                        bp[0] = decoded_buf[j++];
                        bp[1] = decoded_buf[j];
    
    Baptiste Coudurier's avatar
    Baptiste Coudurier committed
                        bp += avctx->channels;
    
            avctx->bit_rate += m->bit_rate;
    
        }
    
        /* update codec info */
        avctx->sample_rate = s->mp3decctx[0]->sample_rate;
    
        *data_size = out_size;
        return buf_size;
    }
    
    #endif /* CONFIG_MP3ON4_DECODER */
    
    #ifdef CONFIG_MP2_DECODER
    
    AVCodec mp2_decoder =
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        CODEC_TYPE_AUDIO,
        CODEC_ID_MP2,
        sizeof(MPADecodeContext),
        decode_init,
        NULL,
        NULL,
        decode_frame,
    
        .long_name= NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    };
    
    #endif
    #ifdef CONFIG_MP3_DECODER
    
    AVCodec mp3_decoder =
    {
        "mp3",
        CODEC_TYPE_AUDIO,
    
        CODEC_ID_MP3,
    
        sizeof(MPADecodeContext),
        decode_init,
        NULL,
        NULL,
        decode_frame,
    
        .long_name= NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
    
    #endif
    #ifdef CONFIG_MP3ADU_DECODER
    
    Roberto Togni's avatar
    Roberto Togni committed
    AVCodec mp3adu_decoder =
    {
        "mp3adu",
        CODEC_TYPE_AUDIO,
        CODEC_ID_MP3ADU,
        sizeof(MPADecodeContext),
        decode_init,
        NULL,
        NULL,
        decode_frame_adu,
        CODEC_CAP_PARSE_ONLY,
    
        .long_name= NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
    
    #endif
    #ifdef CONFIG_MP3ON4_DECODER
    
    AVCodec mp3on4_decoder =
    {
        "mp3on4",
        CODEC_TYPE_AUDIO,
        CODEC_ID_MP3ON4,
        sizeof(MP3On4DecodeContext),
        decode_init_mp3on4,
        NULL,
        decode_close_mp3on4,
        decode_frame_mp3on4,
    
        .long_name= NULL_IF_CONFIG_SMALL("MP3onMP4"),