前言
内容为个人总结的一些理解,如果有错误感谢提出交流~
MP4格式详解
MP4文件由多个box与FullBox组成。每个box由header和data两部分组成。FullBox是box的扩展,以box结构为基础,在header中增加8位的version标志和24位的flags标志(由特定的FullBox定义)。
box中size最小是8字节,当size=0时表示这个box是文件的最后一个box,当size=1时说明该box需要更长的字节来表示长度(额外8字节)。
box中data为box的实际数据,可以是纯媒体数据,也可以是更多子box。当一个box中data是一系列的子box时,这个box又可以称为Container(容器)box。
如果box的type是uuid,那会在header的最后添加一个128位的UUID值。
moov解析
是容器box,定义了MP4文件的元数据信息,在文件中有且仅有一个,moov里面包含的子box作为描述媒体数据的信息的容器。多媒体实际数据,如音频或视频数据,则在moov box中被引用,但不包含在其中。
moov至少包含以下3种box中的一种,也可以包含其他(这里不做介绍)
- mvhd:Movie Header Box,存放多媒体信息头的容器。
- cmov:CompressMovie box,压缩过的电影信息容器。
- rmra:Reference Movie box,参考电影信息容器。
下面介绍moov下的几个box,
mvhd解析(直接包含数据)
mvhd是二级容器,包含了与整个播放展示相关的元数据。如文件创建修改时间,timescale,视频时长,播放音量,播放速度
trak解析
trak是容器box,定义了媒体文件中一个track的信息。一个trak中要求必须有一个tkhd和mdia。
track轨道表示一些sample的集合,表示为视频或音频序列。chunk块表示在一个track中几个连续sample组成的单元,属于逻辑概念。sample采样表示与一个时间戳相关的数据,一般对应视频中的一个帧,或对应Audio中一段压缩的音频。
tkhd解析(直接包含数据)
每个trak只能有一个tkhd。它是强制性的,包含描述单个轨道的特性的元数据。
mdia解析(容器box)
其必须包含如下容器,
- 媒体头容器:Media Header box(mdhd),直接包含数据,
- 句柄参考容器:Handle Reference box(hdlr),直接包含数据,
-
媒体信息容器:Media Information box(minf),包含了很多重要的子容器,例如与音视频采样等信息相关的容器。如vmhd、smhd、dinf、stbl(后续会详细说明),这里不详细介绍,可以参考深入理解ffmpeg P224
-
用户数据容器:User Data box(udta)
stbl解析(minf的子容器)
stbl为采样列表容器(Sample Table box),是一个容器box,该容器是在trak-mdia-minf下,包含转化媒体时间到实际的sample的信息,也表征了如何进一步解析sample的信息,例如,视频数据是否需要解压缩、解压缩采用的是什么编解码算法等。
利用stbl就可以定位sample到媒体时间、文件位置的映射关系,决定其类型、大小,以及如何在其他容器中找到紧邻的sample。如果它所在的track引用了数据,那么必须包含以下子box,
-
采样描述容器(stsd):它主要包含解码器所需要的基本信息,里面的细节规定一般与特定的编码器相关。
-
采样大小容器(stsz)
-
Chunk采样容器(stsc)
-
Chunk偏移容器(stco)
stbl是一个重要的box,而且必须包含至少一个条目,因为它包含了检索media sample的索引信息。没有的话无法计算出media sample储存的位置。采样同步容器(stss)是可选的,如果没有,表示所有的sample都是采样同步的。
下面介绍stbl的重要子容器
Chunk偏移容器(stco)
它通过一个offset定义了每个chunk到文件开头的位置,当有多个track时候chunk可能交错记录在mdat也可能分开记录。示例如下,
Chunk采样容器(stsc)
该box里包含的表用于计算一个给定chunk里包含多少个sample。header省略后例子如下,(省略的chunk表示和上一个一样, 比如first_chunk = 2的后面)
采样大小容器(stsz)
stsz box里的表说明给定了track内的每个sample的大小,单位是字节。这里只展示entry_list中表项的例子如下,
采样时间容器(stts)
stts box用于将每个sample映射到时间上,实例如下(省略header)。当表中正好只有一个条目,意味每个轨道所有sample都有相同的持续时间。因此一个条目就可以计算得到每个sample到时间的映射(持续时间使用sample_delta计算)。
edts解析
是一个容器box,通过子容器elst将track做一个逻辑上的偏移。
MP4主要结构
分片的MP4(fMP4)
fMP4主要结构示意图如下所示,一个fMP4流由一个初始化段和一连串的媒体段组成。初始化段还是ftyp box和moov box组成,
但是在moov中会包含额外的信息来表示这是一个切片的fMP4。另外与传统的moov相比,这里的moov只存储文件级别的媒体信息,因此会比较的小。这里会有一个传统MP4没有的mvex box,这是一个可选的容器box,由mehd和trex组成。其中mehd是可选的,它指定整个文件的持续时间,即对应最长的轨道持续时间(包含所有分片);trex是必选的,每个轨道都有一个单独的trex,这个box为其轨道指定默认的标识和值。
音视频的切片文件由一个moof box和一个mdatbox组成,前者包含该片段的元数据,后者是有效载荷。以下示意图不展开说明。