0
点赞
收藏
分享

微信扫一扫

MP2 音频帧格式说明及解码流程

前言

MP2 文件格式基于 1152 个采样间隔的连续数字帧,具有四种可能的格式:

• 单声道格式

• 立体声格式

• 强度编码联合立体声格式(立体声无关)

• 双通道(不相关)

MPEG Audio Layer II (MP2) 是 MP3 标准的核心算法。 MPEG-1 Audio Layer 2 编码是从 MUSICAM 音频编解码器获得的。

格式说明

数据

f f5 c8 c4 ff ff ff ff ff ff ff ff ff ed 51 d5 72 f7 51 5d 4c 93 4e 3b 03 cf c6 fc 11 41 04 11 41 24 92 3d 3c 75 49 1c 72 d3 35 55 5b 4d 75 d5 6d 95 d9 5e

帧是MPEG-1处理的最小单元,一帧处理1152个PCM的样值,对于16KHz的采样率,一帧对应声音样本时间1152/48000=0.072s=72ms。


帧头(32 bit)

同步字(12bit)

1111 1111 1111 (转为16进制:FF F)

ID(1 bit)

这1位标志用来识别音频编码算法,如下(例子中是0):

 0: ISO/IEC 13818-3 [11] or MPEG-2 Audio extension to lower sampling frequencies;

 1: ISO/IEC 11172-3 [3].

Layer(2 bit)

这2位指示用了哪一层,对应如下(例子中是10):

Code

Layer

11

not used in DAB

10

Layer II

01

not used in DAB

00

reserved

 保护位(1bit)

这一位比较重要,表明该音频是否有CRC校验,如果是0,说明有,1则说明没有CRC校验。例子中是0.


比特率指示(4bit)

指示该音频的比特率,如下(只对应48KHz采样率,24KHz的表这里没有给出),示例音频可以看到这里是16进制的c对应二进制1100,比特率为256kbit/s


FFmpeg解码

MP2解码器

#if CONFIG_MP2_DECODER
AVCodec ff_mp2_decoder = {
    .name           = "mp2",
    .long_name      = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_MP2,
    .priv_data_size = sizeof(MPADecodeContext),
    .init           = decode_init,
    .decode         = decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
    .flush          = flush,
    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                      AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
};
#endif

输出采样格式

mpegaudiodec_fixed.c

#define OUT_FMT   AV_SAMPLE_FMT_S16
#define OUT_FMT_P AV_SAMPLE_FMT_S16P


static av_cold int decode_init(AVCodecContext * avctx)
{
    static int initialized_tables = 0;
    MPADecodeContext *s = avctx->priv_data;

    if (!initialized_tables) {
        decode_init_static();
        initialized_tables = 1;
    }

    s->avctx = avctx;

#if USE_FLOATS
    s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
    if (!s->fdsp)
        return AVERROR(ENOMEM);
#endif

    ff_mpadsp_init(&s->mpadsp);

    if (avctx->request_sample_fmt == OUT_FMT &&
        avctx->codec_id != AV_CODEC_ID_MP3ON4)
        avctx->sample_fmt = OUT_FMT;
    else
        //在这里指定了采样格式
        avctx->sample_fmt = OUT_FMT_P;
    s->err_recognition = avctx->err_recognition;

    if (avctx->codec_id == AV_CODEC_ID_MP3ADU)
        s->adu_mode = 1;

    return 0;
}

指定音频帧的采样个数

static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
                           const uint8_t *buf, int buf_size)
{
    int i, nb_frames, ch, ret;
    OUT_INT *samples_ptr;

    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);

    switch(s->layer) {
    case 1:
        s->avctx->frame_size = 384;
        nb_frames = mp_decode_layer1(s);
        break;
    case 2:
        s->avctx->frame_size = 1152;
        nb_frames = mp_decode_layer2(s);
        break;

问题记录

ffplay 探测MP2音频数据,显示音频数据属性

Stream #0:0: Audio: mp2, 16000 Hz, mono, fltp, 128 kb/s f=0/0

实际上fltp是不正确的,不过ffplay最后会强制默认为s16采样格式



基础信息





举报

相关推荐

0 条评论