前言
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采样格式
基础信息