MPEG-2音频解码

来源:互联网 发布:动漫 惊艳 音乐 知乎 编辑:程序博客网 时间:2024/04/30 10:37

MPEG-2音频的解码过程:

 

1、检查4个字节的音频头,过程为:

static inline int ff_mpa_check_header(uint32_t header){
    /* header */
    if ((header & 0xffe00000) != 0xffe00000) //即前11位为固定头信息,全为1
        return -1;
    /* layer check */
    if ((header & (3<<17)) == 0)//即第14、15两位表示layer
        return -1;
    /* bit rate */
    if ((header & (0xf<<12)) == 0xf<<12)//即第17、18、19、20四位不能全为1
        return -1;
    /* frequency */
    if ((header & (3<<10)) == 3<<10)//即第21、22位不能全为1
        return -1;
    return 0;
}

 

2、根据header信息得到相应参数信息:

s->layer = 4 - ((header >> 17) & 3);)//即第14、15两位与0x0011相与,再被4减

sample_rate_index = (header >> 10) & 3;//获取的是采样率的索引,ff_mpa_freq_tab[3] = { 44100, 48000, 32000 };

sample_rate = ff_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25);//其中,if (header & (1<<20))

                                                                                                                       //{s->lsf =(header & (1<<19)) ? 0 : 1;
                                                                                                                       // mpeg25 = 0;
                                                                                                                       // } else {
                                                                                                                       //s->lsf = 1;
                                                                                                                       //mpeg25 = 1;
                                                                                                                       // } 

sample_rate_index += 3 * (s->lsf + mpeg25);
s->sample_rate_index = sample_rate_index;

s->sample_rate = sample_rate;

bitrate_index = (header >> 12) & 0xf;

s->mode = (header >> 6) & 3;

padding = (header >> 9) & 1;

if (s->mode == MPA_MONO)
        s->nb_channels = 1;
    else
        s->nb_channels = 2;

if (bitrate_index != 0) {
        frame_size = ff_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index];
        s->bit_rate = frame_size * 1000;
        switch(s->layer) {
        case 1:
            frame_size = (frame_size * 12000) / sample_rate;
            frame_size = (frame_size + padding) * 4;
            break;
        case 2:
            frame_size = (frame_size * 144000) / sample_rate;
            frame_size += padding;
            break;
        default:
        case 3:
            frame_size = (frame_size * 144000) / (sample_rate << s->lsf);
            frame_size += padding;
            break;
        }
        s->frame_size = frame_size;
    } else {
        /* if no frame size computed, signal it */
        return 1;
    }

其中,

const uint16_t ff_mpa_bitrate_tab[2][3][15] = {
    { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
      {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
      {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
    { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
      {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
      {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
    }
};

 

根据layer数,即可知道该音频的编码类型:

layer = 1, 对应MPEG1

layer = 2, 对应MPEG2,framesize = 1152 //1152与外面开辟的保存输出数据的缓冲大小有关,如果开辟空间大小<1152*avctx-                                                                //>channels*2时,则空间太小;

layer = 3, 对应MPEG3(MP3)

通过比较送入的数据buf_size和解析header获取的数据大小 s->frame_size相比,即可得知当前送入的数据是否有问题:

如果s->frame_size > buf_size,则送入的帧不够;

如果s->frame_size < buf_size,则该帧可能有问题;

 

3、解码

3.1  /*先根据参数(bitrate、channel、samplerate)等信息,选取码表*/

    table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels, s->sample_rate, s->lsf);

 

3.2  /* parse bit allocation */

    j = 0;
    for(i=0;i<bound;i++) {
        bit_alloc_bits = alloc_table[j];
        for(ch=0;ch<s->nb_channels;ch++) {
            bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
        }
        j += 1 << bit_alloc_bits;
    }
    for(i=bound;i<sblimit;i++) {
        bit_alloc_bits = alloc_table[j];
        v = get_bits(&s->gb, bit_alloc_bits);
        bit_alloc[0][i] = v;
        bit_alloc[1][i] = v;
        j += 1 << bit_alloc_bits;
    }

 

3.3 /* scale codes */

   for(i=0;i<sblimit;i++) {
        for(ch=0;ch<s->nb_channels;ch++) {
            if (bit_alloc[ch][i])
                scale_code[ch][i] = get_bits(&s->gb, 2);
        }
    }

 

3.4 /* scale factors */

for(i=0;i<sblimit;i++) {
        for(ch=0;ch<s->nb_channels;ch++) {
            if (bit_alloc[ch][i]) {
                sf = scale_factors[ch][i];
                switch(scale_code[ch][i]) {
                default:
                case 0:
                    sf[0] = get_bits(&s->gb, 6);
                    sf[1] = get_bits(&s->gb, 6);
                    sf[2] = get_bits(&s->gb, 6);
                    break;
                case 2:
                    sf[0] = get_bits(&s->gb, 6);
                    sf[1] = sf[0];
                    sf[2] = sf[0];
                    break;
                case 1:
                    sf[0] = get_bits(&s->gb, 6);
                    sf[2] = get_bits(&s->gb, 6);
                    sf[1] = sf[0];
                    break;
                case 3:
                    sf[0] = get_bits(&s->gb, 6);
                    sf[2] = get_bits(&s->gb, 6);
                    sf[1] = sf[2];
                    break;
                }
            }
        }
    }

3.5 /* samples */

    for(k=0;k<3;k++) {
        for(l=0;l<12;l+=3) {
            j = 0;
            for(i=0;i<bound;i++) {
                bit_alloc_bits = alloc_table[j];
                for(ch=0;ch<s->nb_channels;ch++) {
                    b = bit_alloc[ch][i];
                    if (b) {
                        scale = scale_factors[ch][i][k];
                        qindex = alloc_table[j+b];
                        bits = ff_mpa_quant_bits[qindex];
                        if (bits < 0) {
                            int v2;
                            /* 3 values at the same time */
                            v = get_bits(&s->gb, -bits);
                            v2 = division_tabs[qindex][v];
                            steps  = ff_mpa_quant_steps[qindex];

                            s->sb_samples[ch][k * 12 + l + 0][i] =
                                l2_unscale_group(steps, v2        & 15, scale);
                            s->sb_samples[ch][k * 12 + l + 1][i] =
                                l2_unscale_group(steps, (v2 >> 4) & 15, scale);
                            s->sb_samples[ch][k * 12 + l + 2][i] =
                                l2_unscale_group(steps,  v2 >> 8      , scale);
                        } else {
                            for(m=0;m<3;m++) {
                                v = get_bits(&s->gb, bits);
                                v = l1_unscale(bits - 1, v, scale);
                                s->sb_samples[ch][k * 12 + l + m][i] = v;
                            }
                        }
                    } else {
                        s->sb_samples[ch][k * 12 + l + 0][i] = 0;
                        s->sb_samples[ch][k * 12 + l + 1][i] = 0;
                        s->sb_samples[ch][k * 12 + l + 2][i] = 0;
                    }
                }
                /* next subband in alloc table */
                j += 1 << bit_alloc_bits;
            }
            /* XXX: find a way to avoid this duplication of code */
            for(i=bound;i<sblimit;i++) {
                bit_alloc_bits = alloc_table[j];
                b = bit_alloc[0][i];
                if (b) {
                    int mant, scale0, scale1;
                    scale0 = scale_factors[0][i][k];
                    scale1 = scale_factors[1][i][k];
                    qindex = alloc_table[j+b];
                    bits = ff_mpa_quant_bits[qindex];
                    if (bits < 0) {
                        /* 3 values at the same time */
                        v = get_bits(&s->gb, -bits);
                        steps = ff_mpa_quant_steps[qindex];
                        mant = v % steps;
                        v = v / steps;
                        s->sb_samples[0][k * 12 + l + 0][i] =
                            l2_unscale_group(steps, mant, scale0);
                        s->sb_samples[1][k * 12 + l + 0][i] =
                            l2_unscale_group(steps, mant, scale1);
                        mant = v % steps;
                        v = v / steps;
                        s->sb_samples[0][k * 12 + l + 1][i] =
                            l2_unscale_group(steps, mant, scale0);
                        s->sb_samples[1][k * 12 + l + 1][i] =
                            l2_unscale_group(steps, mant, scale1);
                        s->sb_samples[0][k * 12 + l + 2][i] =
                            l2_unscale_group(steps, v, scale0);
                        s->sb_samples[1][k * 12 + l + 2][i] =
                            l2_unscale_group(steps, v, scale1);
                    } else {
                        for(m=0;m<3;m++) {
                            mant = get_bits(&s->gb, bits);
                            s->sb_samples[0][k * 12 + l + m][i] =
                                l1_unscale(bits - 1, mant, scale0);
                            s->sb_samples[1][k * 12 + l + m][i] =
                                l1_unscale(bits - 1, mant, scale1);
                        }
                    }
                } else {
                    s->sb_samples[0][k * 12 + l + 0][i] = 0;
                    s->sb_samples[0][k * 12 + l + 1][i] = 0;
                    s->sb_samples[0][k * 12 + l + 2][i] = 0;
                    s->sb_samples[1][k * 12 + l + 0][i] = 0;
                    s->sb_samples[1][k * 12 + l + 1][i] = 0;
                    s->sb_samples[1][k * 12 + l + 2][i] = 0;
                }
                /* next subband in alloc table */
                j += 1 << bit_alloc_bits;
            }
            /* fill remaining samples to zero */
            for(i=sblimit;i<SBLIMIT;i++) {
                for(ch=0;ch<s->nb_channels;ch++) {
                    s->sb_samples[ch][k * 12 + l + 0][i] = 0;
                    s->sb_samples[ch][k * 12 + l + 1][i] = 0;
                    s->sb_samples[ch][k * 12 + l + 2][i] = 0;
                }
            }
        }
    }

nb->frames = 36;

 

3.6 ff_mpa_synth_filter过程

先进行逆dct变换,dct32(synth_buf, sb_samples);

之后进行apply_window_mp3_c变换;

 

4.0 最后输出的PCM数据的实际大小为:

nb_frames * 32 * 2* s->nb_channels;

 

原创粉丝点击