Mp4 ESDS BOX结构

1,055 阅读4分钟

基础知识

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函数中。