Skip to content
Snippets Groups Projects
mpegaudiodec.c 89.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • Michael Niedermayer's avatar
    Michael Niedermayer committed
    
            INT_AA(0)
            INT_AA(1)
            INT_AA(2)
            INT_AA(3)
            INT_AA(4)
            INT_AA(5)
            INT_AA(6)
            INT_AA(7)
    
        }
    }
    
    static void compute_antialias_float(MPADecodeContext *s,
                                  GranuleDef *g)
    {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int32_t *ptr;
        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;
        }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            float tmp0, tmp1;
    
            float *csa = &csa_table_float[0][0];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #define FLOAT_AA(j)\
            tmp0= ptr[-1-j];\
            tmp1= ptr[   j];\
            ptr[-1-j] = lrintf(tmp0 * csa[0+4*j] - tmp1 * csa[1+4*j]);\
            ptr[   j] = lrintf(tmp0 * csa[1+4*j] + tmp1 * csa[0+4*j]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            FLOAT_AA(0)
            FLOAT_AA(1)
            FLOAT_AA(2)
            FLOAT_AA(3)
            FLOAT_AA(4)
            FLOAT_AA(5)
            FLOAT_AA(6)
            FLOAT_AA(7)
    
    
                              int32_t *sb_samples,
                              int32_t *mdct_buf)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int32_t *ptr, *win, *win1, *buf, *out_ptr, *ptr1;
    
        int32_t out2[12];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int i, j, mdct_long_end, v, sblimit;
    
    
        /* find last non zero block */
        ptr = g->sb_hybrid + 576;
        ptr1 = g->sb_hybrid + 2 * 18;
        while (ptr >= ptr1) {
            ptr -= 6;
            v = ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5];
            if (v != 0)
                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;
        }
    
        buf = mdct_buf;
        ptr = g->sb_hybrid;
        for(j=0;j<mdct_long_end;j++) {
            /* apply window & overlap with previous buffer */
            out_ptr = sb_samples + j;
            /* select window */
            if (g->switch_point && j < 2)
                win1 = mdct_win[0];
            else
                win1 = mdct_win[g->block_type];
            /* select frequency inversion */
            win = win1 + ((4 * 36) & -(j & 1));
    
            imdct36(out_ptr, buf, ptr, win);
            out_ptr += 18*SBLIMIT;
    
            ptr += 18;
            buf += 18;
        }
        for(j=mdct_long_end;j<sblimit;j++) {
            /* select frequency inversion */
            win = mdct_win[2] + ((4 * 36) & -(j & 1));
            out_ptr = sb_samples + j;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            for(i=0; i<6; i++){
                *out_ptr = buf[i];
                out_ptr += SBLIMIT;
            }
            imdct12(out2, ptr + 0);
            for(i=0;i<6;i++) {
                *out_ptr = MULH(out2[i], win[i]) + buf[i + 6*1];
                buf[i + 6*2] = MULH(out2[i + 6], win[i + 6]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            imdct12(out2, ptr + 1);
            for(i=0;i<6;i++) {
                *out_ptr = MULH(out2[i], win[i]) + buf[i + 6*2];
                buf[i + 6*0] = MULH(out2[i + 6], win[i + 6]);
                out_ptr += SBLIMIT;
            }
            imdct12(out2, ptr + 2);
            for(i=0;i<6;i++) {
                buf[i + 6*0] = MULH(out2[i], win[i]) + buf[i + 6*0];
                buf[i + 6*1] = MULH(out2[i + 6], win[i + 6]);
                buf[i + 6*2] = 0;
            }
    
            ptr += 18;
            buf += 18;
        }
        /* zero bands */
        for(j=sblimit;j<SBLIMIT;j++) {
            /* overlap */
            out_ptr = sb_samples + j;
            for(i=0;i<18;i++) {
                *out_ptr = buf[i];
                buf[i] = 0;
                out_ptr += SBLIMIT;
            }
            buf += 18;
        }
    }
    
    
    #if defined(DEBUG)
    
    void sample_dump(int fnum, int32_t *tab, int n)
    
        int32_t v;
    
            snprintf(buf, sizeof(buf), "/tmp/out%d.%s.pcm",
                    fnum,
    
            av_log(NULL, AV_LOG_DEBUG, "pos=%d\n", pos);
    
                av_log(NULL, AV_LOG_DEBUG, " %0.4f", (double)tab[i] / FRAC_ONE);
    
                    av_log(NULL, AV_LOG_DEBUG, "\n");
    
        for(i=0;i<n;i++) {
            /* 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, bits_left;
        GranuleDef granules[2][2], *g;
    
        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++) {
                dprintf("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);
                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_bits(&s->gb, 1);
                if (blocksplit_flag) {
                    g->block_type = get_bits(&s->gb, 2);
                    if (g->block_type == 0)
                        return -1;
                    g->switch_point = get_bits(&s->gb, 1);
                    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);
                    /* compute huffman coded region sizes */
                    if (g->block_type == 2)
                        g->region_size[0] = (36 / 2);
                    else {
    
                        if (s->sample_rate_index <= 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);
                } else {
                    int region_address1, region_address2, l;
                    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);
    
                    dprintf("region1=%d region2=%d\n",
    
                    g->region_size[0] =
    
                        band_index_long[s->sample_rate_index][region_address1 + 1] >> 1;
                    l = region_address1 + region_address2 + 2;
                    /* should not overflow */
                    if (l > 22)
                        l = 22;
    
                    g->region_size[1] =
    
                        band_index_long[s->sample_rate_index][l] >> 1;
                }
                /* convert region offsets to region sizes and truncate
                   size to big_values */
                g->region_size[2] = (576 / 2);
                j = 0;
                for(i=0;i<3;i++) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    k = FFMIN(g->region_size[i], g->big_values);
    
                    g->region_size[i] = k - j;
                    j = k;
                }
    
                /* compute band indexes */
                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 48 first
                           exponents as long blocks (XXX: check this!) */
                        if (s->sample_rate_index <= 2)
                            g->long_end = 8;
                        else if (s->sample_rate_index != 8)
                            g->long_end = 6;
                        else
                            g->long_end = 4; /* 8000 Hz */
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                        g->short_start = 2 + (s->sample_rate_index != 8);
    
                    } else {
                        g->long_end = 0;
                        g->short_start = 0;
                    }
                } else {
                    g->short_start = 13;
                    g->long_end = 22;
                }
    
                g->preflag = 0;
                if (!s->lsf)
                    g->preflag = get_bits(&s->gb, 1);
                g->scalefac_scale = get_bits(&s->gb, 1);
                g->count1table_select = get_bits(&s->gb, 1);
                dprintf("block_type=%d switch_point=%d\n",
                        g->block_type, g->switch_point);
            }
        }
    
    
    Roberto Togni's avatar
    Roberto Togni committed
      if (!s->adu_mode) {
    
        /* now we get bits from the main_data_begin offset */
        dprintf("seekback: %d\n", main_data_begin);
        seek_to_maindata(s, main_data_begin);
    
    
        for(gr=0;gr<nb_granules;gr++) {
            for(ch=0;ch<s->nb_channels;ch++) {
                g = &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];
                    dprintf("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)
    
                        dprintf("scfsi=%x gr=%d ch=%d scale_factors:\n",
    
                            dprintf(" %d", g->scale_factors[i]);
                        dprintf("\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)
    
                        dprintf("gr=%d ch=%d scale_factors:\n",
    
                            dprintf(" %d", g->scale_factors[i]);
                        dprintf("\n");
    
                    }
    #endif
                }
    
                exponents_from_scale_factors(s, g, exponents);
    
                /* read Huffman coded residue */
                if (huffman_decode(s, g, exponents,
                                   bits_pos + g->part2_3_length) < 0)
                    return -1;
    
    #if defined(DEBUG)
                sample_dump(0, g->sb_hybrid, 576);
    
    #endif
    
                /* skip extension bits */
                bits_left = g->part2_3_length - (get_bits_count(&s->gb) - bits_pos);
                if (bits_left < 0) {
                    dprintf("bits_left=%d\n", bits_left);
                    return -1;
                }
                while (bits_left >= 16) {
                    skip_bits(&s->gb, 16);
                    bits_left -= 16;
                }
                if (bits_left > 0)
                    skip_bits(&s->gb, bits_left);
            } /* 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 */
        return nb_granules * 18;
    }
    
    
    static int mp_decode_frame(MPADecodeContext *s,
    
        init_get_bits(&s->gb, s->inbuf + HEADER_SIZE,
    
                      (s->inbuf_ptr - s->inbuf - HEADER_SIZE)*8);
    
        /* skip error protection field */
        if (s->error_protection)
            get_bits(&s->gb, 16);
    
        dprintf("frame %d:\n", s->frame_count);
        switch(s->layer) {
        case 1:
            nb_frames = mp_decode_layer1(s);
            break;
        case 2:
            nb_frames = mp_decode_layer2(s);
            break;
        case 3:
        default:
            nb_frames = mp_decode_layer3(s);
            break;
        }
    #if defined(DEBUG)
        for(i=0;i<nb_frames;i++) {
            for(ch=0;ch<s->nb_channels;ch++) {
                int j;
    
                dprintf("%d-%d:", i, ch);
    
                    dprintf(" %0.6f", (double)s->sb_samples[ch][i][j] / FRAC_ONE);
                dprintf("\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,
                            uint8_t * buf, int buf_size)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        MPADecodeContext *s = avctx->priv_data;
    
        uint32_t header;
        uint8_t *buf_ptr;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int len, out_size;
    
        OUT_INT *out_samples = data;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        buf_ptr = buf;
        while (buf_size > 0) {
    
            len = s->inbuf_ptr - s->inbuf;
            if (s->frame_size == 0) {
    
                /* special case for next header for first frame in free
                   format case (XXX: find a simpler method) */
                if (s->free_format_next_header != 0) {
                    s->inbuf[0] = s->free_format_next_header >> 24;
                    s->inbuf[1] = s->free_format_next_header >> 16;
                    s->inbuf[2] = s->free_format_next_header >> 8;
                    s->inbuf[3] = s->free_format_next_header;
                    s->inbuf_ptr = s->inbuf + 4;
                    s->free_format_next_header = 0;
                    goto got_header;
                }
    
                /* no header seen : find one. We need at least HEADER_SIZE
    
                len = HEADER_SIZE - len;
                if (len > buf_size)
                    len = buf_size;
                if (len > 0) {
                    memcpy(s->inbuf_ptr, buf_ptr, len);
                    buf_ptr += len;
                    buf_size -= len;
                    s->inbuf_ptr += len;
                }
                if ((s->inbuf_ptr - s->inbuf) >= HEADER_SIZE) {
    
                    header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
                        (s->inbuf[2] << 8) | s->inbuf[3];
    
                    if (ff_mpa_check_header(header) < 0) {
                        /* no sync found : move by one byte (inefficient, but simple!) */
                        memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
                        s->inbuf_ptr--;
    
                        dprintf("skip %x\n", header);
                        /* reset free format frame size to give a chance
                           to get a new bitrate */
                        s->free_format_frame_size = 0;
    
                    } else {
                        if (decode_header(s, header) == 1) {
    
                            /* free format: prepare to compute frame size */
    
                            s->frame_size = -1;
    
                        /* update codec info */
                        avctx->sample_rate = s->sample_rate;
                        avctx->channels = s->nb_channels;
                        avctx->bit_rate = s->bit_rate;
    
                        switch(s->layer) {
                        case 1:
                            avctx->frame_size = 384;
                            break;
                        case 2:
                            avctx->frame_size = 1152;
                            break;
                        case 3:
                            if (s->lsf)
                                avctx->frame_size = 576;
                            else
                                avctx->frame_size = 1152;
                            break;
                        }
    
            } else if (s->frame_size == -1) {
                /* free format : find next sync to compute frame size */
    
                len = MPA_MAX_CODED_FRAME_SIZE - len;
                if (len > buf_size)
                    len = buf_size;
    
                    /* frame too long: resync */
    
                    memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
                    s->inbuf_ptr--;
    
                    uint8_t *p, *pend;
                    uint32_t header1;
    
                    int padding;
    
                    memcpy(s->inbuf_ptr, buf_ptr, len);
                    /* check for header */
                    p = s->inbuf_ptr - 3;
                    pend = s->inbuf_ptr + len - 4;
                    while (p <= pend) {
                        header = (p[0] << 24) | (p[1] << 16) |
                            (p[2] << 8) | p[3];
                        header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
                            (s->inbuf[2] << 8) | s->inbuf[3];
                        /* check with high probability that we have a
                           valid header */
                        if ((header & SAME_HEADER_MASK) ==
                            (header1 & SAME_HEADER_MASK)) {
                            /* header found: update pointers */
                            len = (p + 4) - s->inbuf_ptr;
                            buf_ptr += len;
                            buf_size -= len;
                            s->inbuf_ptr = p;
                            /* compute frame size */
                            s->free_format_next_header = header;
                            s->free_format_frame_size = s->inbuf_ptr - s->inbuf;
                            padding = (header1 >> 9) & 1;
                            if (s->layer == 1)
                                s->free_format_frame_size -= padding * 4;
                            else
                                s->free_format_frame_size -= padding;
    
                            dprintf("free frame size=%d padding=%d\n",
    
                                    s->free_format_frame_size, padding);
                            decode_header(s, header1);
                            goto next_data;
                        }
                        p++;
                    }
                    /* not found: simply increase pointers */
                    buf_ptr += len;
                    s->inbuf_ptr += len;
                    buf_size -= len;
                }
    
            } else if (len < s->frame_size) {
    
                if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
                    s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
    
                len = s->frame_size - len;
                if (len > buf_size)
                    len = buf_size;
                memcpy(s->inbuf_ptr, buf_ptr, len);
                buf_ptr += len;
                s->inbuf_ptr += len;
                buf_size -= len;
            }
    
            if (s->frame_size > 0 &&
    
                (s->inbuf_ptr - s->inbuf) >= s->frame_size) {
                if (avctx->parse_only) {
                    /* simply return the frame data */
                    *(uint8_t **)data = s->inbuf;
                    out_size = s->inbuf_ptr - s->inbuf;
                } else {
                    out_size = mp_decode_frame(s, out_samples);
                }
    
                s->inbuf_ptr = s->inbuf;
                s->frame_size = 0;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                if(out_size>=0)
    
                    *data_size = out_size;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                else
                    av_log(avctx, AV_LOG_DEBUG, "Error while decoding mpeg audio frame\n"); //FIXME return -1 / but also return the number of bytes consumed
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
        return buf_ptr - buf;
    }
    
    
    Roberto Togni's avatar
    Roberto Togni committed
    
    static int decode_frame_adu(AVCodecContext * avctx,
    
                            void *data, int *data_size,
                            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;
    
        memcpy(s->inbuf, buf, len);
        s->inbuf_ptr = s->inbuf + len;
    
        // Get header and restore sync word
        header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
                  (s->inbuf[2] << 8) | s->inbuf[3] | 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;
        }
    
        decode_header(s, header);
        /* 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;
    
        avctx->frame_size=s->frame_size = len;
    
        if (avctx->parse_only) {
            /* simply return the frame data */
            *(uint8_t **)data = s->inbuf;
            out_size = s->inbuf_ptr - s->inbuf;
        } else {
            out_size = mp_decode_frame(s, out_samples);
        }
    
        *data_size = out_size;
        return buf_size;
    }
    
    
    
    /* Next 3 arrays are indexed by channel config number (passed via codecdata) */
    static int mp3Frames[16] = {0,1,1,2,3,3,4,5,2};   /* number of mp3 decoder instances */
    static int mp3Channels[16] = {0,1,2,3,4,5,6,8,4}; /* total output channels */
    /* offsets into output buffer, assume output order is FL FR BL BR C LFE */
    static int chan_offset[9][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
        {0,2}           // FLR BLRS
    };
    
    
    static int decode_init_mp3on4(AVCodecContext * avctx)
    {
        MP3On4DecodeContext *s = avctx->priv_data;
        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;
        }
    
        s->chan_cfg = (((unsigned char *)avctx->extradata)[1] >> 3) & 0x0f;
        s->frames = mp3Frames[s->chan_cfg];
        if(!s->frames) {
            av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
            return -1;
        }
        avctx->channels = mp3Channels[s->chan_cfg];
    
        /* 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 inited 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]->inbuf = &s->mp3decctx[i]->inbuf1[0][BACKSTEP_SIZE];
            s->mp3decctx[i]->inbuf_ptr = s->mp3decctx[i]->inbuf;
            s->mp3decctx[i]->adu_mode = 1;
        }
    
        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,
                            uint8_t * buf, int buf_size)
    
    {
        MP3On4DecodeContext *s = avctx->priv_data;
        MPADecodeContext *m;
        int len, 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 fsize;
        unsigned char *start2 = buf, *start;
        int fr, i, j, n;
        int off = avctx->channels;
        int *coff = chan_offset[s->chan_cfg];
    
        len = buf_size;
    
        // Discard too short frames
        if (buf_size < HEADER_SIZE) {
            *data_size = 0;
            return buf_size;
        }
    
        // If only one decoder interleave is not needed
        outptr = s->frames == 1 ? out_samples : decoded_buf;
    
        for (fr = 0; fr < s->frames; fr++) {
            start = start2;
            fsize = (start[0] << 4) | (start[1] >> 4);
            start2 += fsize;
            if (fsize > len)
                fsize = len;
            len -= fsize;
            if (fsize > MPA_MAX_CODED_FRAME_SIZE)
                fsize = MPA_MAX_CODED_FRAME_SIZE;
            m = s->mp3decctx[fr];
            assert (m != NULL);
            /* copy original to new */
            m->inbuf_ptr = m->inbuf + fsize;
            memcpy(m->inbuf, start, fsize);
    
            // Get header
            header = (m->inbuf[0] << 24) | (m->inbuf[1] << 16) |
                      (m->inbuf[2] << 8) | m->inbuf[3] | 0xfff00000;
    
            if (ff_mpa_check_header(header) < 0) { // Bad header, discard block
                *data_size = 0;
                return buf_size;
            }
    
            decode_header(m, header);
            mp_decode_frame(m, decoded_buf);
    
            n = MPA_FRAME_SIZE * m->nb_channels;
            out_size += n * sizeof(OUT_INT);
            if(s->frames > 1) {
                /* interleave output data */
                bp = out_samples + coff[fr];
                if(m->nb_channels == 1) {
                    for(j = 0; j < n; j++) {
                        *bp = decoded_buf[j];
                        bp += off;
                    }
                } else {
                    for(j = 0; j < n; j++) {
                        bp[0] = decoded_buf[j++];
                        bp[1] = decoded_buf[j];
                        bp += off;
                    }
                }
            }
        }
    
        /* update codec info */
        avctx->sample_rate = s->mp3decctx[0]->sample_rate;
        avctx->frame_size= buf_size;
        avctx->bit_rate = 0;
        for (i = 0; i < s->frames; i++)
            avctx->bit_rate += s->mp3decctx[i]->bit_rate;
    
        *data_size = out_size;
        return buf_size;
    }
    
    
    
    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,
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    };
    
    
    AVCodec mp3_decoder =
    {
        "mp3",
        CODEC_TYPE_AUDIO,
    
        CODEC_ID_MP3,
    
        sizeof(MPADecodeContext),
        decode_init,
        NULL,
        NULL,
        decode_frame,
    
    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,
    };
    
    
    AVCodec mp3on4_decoder =
    {
        "mp3on4",
        CODEC_TYPE_AUDIO,
        CODEC_ID_MP3ON4,
        sizeof(MP3On4DecodeContext),
        decode_init_mp3on4,
        NULL,
        decode_close_mp3on4,
        decode_frame_mp3on4,
        0
    };