基础知识
ESDS BOX主要存储Element Stream Descriptors(ESDs),该Box Body的前4个字节为version&flag,一般全为0,从第4个字节开始为ESDs。
ESDs主要为3层,每层为包含关系,从外到里分别为:MP4ESDescr、MP4DecConfigDescr、MP4DecSpecificDescr,每个ESD的结构如下所示:
typedef esdStruct{
uint8_t tag; // 1字节的Tag Type
<不定长,最长4字节> size;
uint8_t[size] data;
} esdStruct;
可用的Tag Type有以下几种,Mp4主要处理MP4ESDescrTag、MP4DecConfigDescrTag和MP4DecSpecificDescrTag。
#define MP4ODescrTag 0x01
#define MP4IODescrTag 0x02
#define MP4ESDescrTag 0x03
#define MP4DecConfigDescrTag 0x04
#define MP4DecSpecificDescrTag 0x05
#define MP4SLDescrTag 0x06
实战解析
某个MP4的ESDS BOX:
00 00 00 33 65 73 64 73 00 00 00 00 03 80 80 80
22 00 02 00 04 80 80 80 14 40 15 00 00 00 00 01
f4 00 00 01 f4 00 05 80 80 80 02 12 10 06 80 80
80 01 02
00 00 00 33 65 73 64 73
8字节的Box Header,前4字节为Box Size(Box Header+ Box Body),后4字节的Box Type(ESDS),所以ESDS BOX的长度为51字节。
00 00 00 00
1字节的version,3字节的flags,一般都为0。
03 80 80 80 22 00 02 00
03表示MP4ESDescrTag,80 80 80 22表示长度为34字节,00 02表示ES_ID,00表示Flag,每个Bit都有不同的含义,具体可参考相关标准。
ESD中Tag和长度的解析可以参考FFmpegff_mp4_read_descr函数,MP4ESDescr的解析可以参考ff_mp4_parse_es_descr函数。
04 80 80 80 14 40 15 00 00 00 00 01 f4 00 00 01 f4 00
04表示MP4DecConfigDescrTag,80 80 80 14表示长度为20字节,40 15 00 00 00 00 01 f4 00 00 01 f4 00为MP4DecConfigDescr的有效内容,共13字节,它的第一个字节40表示Codec Tag,对应了一种编码。40对应的是AV_CODEC_ID_AAC编码。
FFmpeg isom.c中定义了MP4容器支持的所有编码格式:
/* http://www.mp4ra.org */
/* ordered by muxing preference */
const AVCodecTag ff_mp4_obj_type[] = {
{ AV_CODEC_ID_MOV_TEXT , 0x08 },
{ AV_CODEC_ID_MPEG4 , 0x20 },
{ AV_CODEC_ID_H264 , 0x21 },
{ AV_CODEC_ID_HEVC , 0x23 },
{ AV_CODEC_ID_AAC , 0x40 },
{ AV_CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */
{ AV_CODEC_ID_MPEG2VIDEO , 0x61 }, /* MPEG-2 Main */
{ AV_CODEC_ID_MPEG2VIDEO , 0x60 }, /* MPEG-2 Simple */
{ AV_CODEC_ID_MPEG2VIDEO , 0x62 }, /* MPEG-2 SNR */
{ AV_CODEC_ID_MPEG2VIDEO , 0x63 }, /* MPEG-2 Spatial */
{ AV_CODEC_ID_MPEG2VIDEO , 0x64 }, /* MPEG-2 High */
{ AV_CODEC_ID_MPEG2VIDEO , 0x65 }, /* MPEG-2 422 */
{ AV_CODEC_ID_AAC , 0x66 }, /* MPEG-2 AAC Main */
{ AV_CODEC_ID_AAC , 0x67 }, /* MPEG-2 AAC Low */
{ AV_CODEC_ID_AAC , 0x68 }, /* MPEG-2 AAC SSR */
{ AV_CODEC_ID_MP3 , 0x69 }, /* 13818-3 */
{ AV_CODEC_ID_MP2 , 0x69 }, /* 11172-3 */
{ AV_CODEC_ID_MPEG1VIDEO , 0x6A }, /* 11172-2 */
{ AV_CODEC_ID_MP3 , 0x6B }, /* 11172-3 */
{ AV_CODEC_ID_MJPEG , 0x6C }, /* 10918-1 */
{ AV_CODEC_ID_PNG , 0x6D },
{ AV_CODEC_ID_JPEG2000 , 0x6E }, /* 15444-1 */
{ AV_CODEC_ID_VC1 , 0xA3 },
{ AV_CODEC_ID_DIRAC , 0xA4 },
{ AV_CODEC_ID_AC3 , 0xA5 },
{ AV_CODEC_ID_EAC3 , 0xA6 },
{ AV_CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */
{ AV_CODEC_ID_VP9 , 0xC0 }, /* nonstandard, update when there is a standard value */
{ AV_CODEC_ID_FLAC , 0xC1 }, /* nonstandard, update when there is a standard value */
{ AV_CODEC_ID_TSCC2 , 0xD0 }, /* nonstandard, camtasia uses it */
{ AV_CODEC_ID_EVRC , 0xD1 }, /* nonstandard, pvAuthor uses it */
{ AV_CODEC_ID_VORBIS , 0xDD }, /* nonstandard, gpac uses it */
{ AV_CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* nonstandard, see unsupported-embedded-subs-2.mp4 */
{ AV_CODEC_ID_QCELP , 0xE1 },
{ AV_CODEC_ID_MPEG4SYSTEMS, 0x01 },
{ AV_CODEC_ID_MPEG4SYSTEMS, 0x02 },
{ AV_CODEC_ID_NONE , 0 },
};
MP4DecConfigDescr结构体的解析可以参考FFmpegff_mp4_read_dec_config_descr函数。
05 80 80 80 02 12 10
05表示MP4DecSpecificDescrTag,80 80 80 02表示长度为2字节,12 10为AudioSpecificConfig结构体,表示AAC元数据,就是FFmpegAVStream->codecpar->extradata中的数据。
MP4DecSpecificDescr结构体的解析也在ff_mp4_read_dec_config_descr函数中。