BOX结构分析
MP4 文件中所有数据都封装在 box 中,每个 box 有类型和长度,box 之间可以嵌套,这就形成了如图所示的树状结构。
Box中的字节序为网络字节序,也就是大端字节序(Big-Endian)。Box由header和body组成,其中header统一指明box的大小和类型,body根据类型有不同的意义和格式。
标准的box开头的4个字节(32位)为box size,该大小包括box header和box body整个box的大小,这样我们就可以在文件中定位各个box。如果size为1,则表示这个box的大小为large size,真正的size值要在largesize域上得到。(实际上只有“mdat”类型的box才有可能用到large size。)如果size为0,表示该box为文件的最后一个box,文件结尾即为该box结尾。(同样只存在于“mdat”类型的box中)。
box size后面的4个字节表示box type,一般是4个字符,表示固定含义。如果box type是“uuid”,表示该box为用户扩展类型,解析时将其忽略。Box的组成如图所示。
1.ftyp
ftyp box的全称为File Type Box,是MP4格式的标志,包含关于文件的一些信息,描述文件遵从的MP4规范和版本。该box通常放在文件的开始,便于解码器基于相应的协议对文件进行解析。目标文件的ftyp box如图所示。
ftyp box中描述了最推荐的解析格式(major brand),版本(minor version)和可兼容的版本(compatible brands)。根据解析出的信息,该box的类型为ftyp,box长度为32字节,box body长度为28字节,最推荐的解析格式为isom,版本为512,可兼容的文件格式有isom,mp41,avc1。
2.free
free box的全称为Free Space Box,这类box不是必须的,该box内容也不会影响媒体文件的播放。Box中的内容不相关,可以忽略,也可以删除对象,但不会影响表示。
3.mdat
mdat box的全称为Media Data Box,用于存放具体的媒体数据信息。
4.moov
moov box的全称为Movie Box,该box包含了文件媒体的metadata信息,是一个container box(嵌套其他box的box),具体详细信息由子box给出。经过流化的文件moov在mdat之前,便于对文件头信息进行解析后再对媒体数据进行解析。本文件没有经过流化所以moov在mdat后。
moov中最重要的两个box是mvhd和trak,其中mvhd是针对整个影片的信息,trak是针对单个轨道的信息。
4.1 mvhd
mvhd box的全称为Movie Header Box,它存放了MP4文件的整体信息,跟具体的音视频流无关,比如创建时间、文件时长等。
mvhd box中描述了创建时间(create time)、修改时间(modification time)、时间刻度(time scale)、媒体时长(duration)、下一个trak box的id(next track id)、音量(volume)和播放速度(rate)等信息。
根据解析出的信息,该影片的时间刻度为1000,即把1s分成了1000个单元,通过duration和timescale的信息可以得知媒体时长为duration/timescale=4022/1000=4.022s。媒体的音量和推荐播放速度都是1.0。
4.2 trak
trak box的全称为Track Box,它也是一个Container Box,包含了单个轨道的metadata信息。通常一个Mp4文件媒体数据中,包含一个或多个track,每个track都包含自己的时间和空间信息,且彼此独立。每个track中,也包含了与之相关的媒体信息。Trak box中包含了两个关键box: 包含流协议分组化信息的Track Header Box和包含媒体数据的Media Box。
4.2.1 tkhd
tkhd box的全称为Track Header Box,用于描述track的基本属性。
根据解析出的信息,该轨道的时长为4000/1000=4s,分辨率为1920*1080。从宽高比可以判断这是一个视频轨道(与hdlr中的video相对应),并且轨道的叠加顺序在最上层。
4.2.2 edts
edts box的全称是Edit Box,是一个Container Box。
4.2.2.1 elst
elst box的全称为Edit List Box,负责跟踪媒体的时间和持续时间。
4.2.3 mdia
mdia box的全称是Media Box,是一个Container Box,其子Box描述了轨道的媒体数据样本的主要信息,对播放器来说是一个重要的box。
4.2.3.1 mdhd
mdhd box的全称是Media Header Box,该box声明了媒体的整体信息。根据解析出的信息,该轨道的实际时长为51200/12800=4s。
4.2.3.2 hdlr
hdlr box的全称是Handler Reference Box,该box声明当前track的类型,以及对应的处理器(handler),决定了track中媒体数据播放的处理过程。
其中handler_type有三种取值:表示video track的vide,表示audio track的soun,表示hint track的hint。根据解析出的信息,第一个轨道的处理器类型为video,说明这是一个视频流轨道;第二个轨道的处理器类型为sound,说明这是一个音频流轨道。
4.2.3.3 minf
minf box的全称为Media Information Box,该box声明了媒体特征信息的所有对象。
vmhd box的全称为Video Media Header Box,是视频轨道的头信息,存放视频轨道的整体信息。其中graphicsmode 指定此视频轨道的合成模式,opcolor是一组3原色值(红色,绿色,蓝色),供graphicsmode 使用。
dinf box的全称为Data Information Box,包含媒体信息在track中的位置信息,包含一个dref类型的子box。Dref box的全称为Data Reference Box,该box包含一个数据引用表(通常是URL)用于声明播放需要使用到的媒体数据的位置。
stbl box的全称为Sample Table Box,它表示样本表容器,是MP4规范中非常重要的容器。它包含了一个track中所有媒体样本的所有时间和数据的引用,该box对解码和渲染mp4文件很关键。使用容器中的sample信息,可以定位sample的媒体时间、定位其类型,决定其大小,以及在其它容器中,确定相邻sample的offset。
stsd box的全称为Sample Description Box,它表示样本描述容器,提供了编码类型和用于编码初始化的详细信息。该box给出视频、音频的编码、宽高、音量等信息,以及每个sample中包含多少个frame。Stsd box的子box为avc1,说明了视频的编码类型avc1和宽高比等编码信息。Avc1 box下的avcc box更具体地描述了编码的格式、版本、时间戳等信息。
stts box的全称为Decoding Time to Sample Box,它存储了sample的duration,描述了sample时序的映射方法,我们通过它可以找到任何时间的sample,为调整媒体播放进度提供了可能。
stss box的全称为Sync Sample Box,该Box提供流中同步样本的紧凑标记,标记了关键帧,提供随机访问点标记。 它包含了一个table, table的每个entry标记了一个sample,该sample是媒体关键帧。table按sample编号的严格递增顺序排列。如果不存在该Box,则每个sample都是关键帧。
ctts box的全称为Composition Time to Sample Box,用于同步pts和dts。H264编码中B帧采用双向预测导致帧重排,解码顺序和显示顺序不同,从而使pts和dts有偏差。通过CTS记录偏差,计算ctts=CTS-DTS,用于回复解码的时间戳。
stsc box的全称为Sample To Chunk Box,该box用一个表描述了sample与chunk的映射关系(每个chunk中包含几个sample),查看这张表就可以找到包含指定sample的chunk,从而找到这个sample。
stsz box的全称为Sample Size Boxes,该box定义了每个sample的大小,包含了媒体中全部sample的数目和一张给出每个sample大小的表。这个box相对来说体积是比较大的。
stco box的全称为Chunk Offset Box,定义了每个thunk在媒体流中的位置。位置有两种可能,32位的和64位的,后者对非常大的电影很有用。在一个表中只会有一种可能,这个位置是在整个文件中的,而不是在任何box中的,这样做就可以直接在文件中找到媒体数据,而不用解释box。