天天看点

Mp4文件解析

MP4可以说是当前最流行的视频格式,要播放一个MP4文件需要首先将其结构给解析出来。MP4的结构往简单了说就是类似于俄罗斯套娃一样的很多box套box,往复杂了说就是很多种类的box,而且还需要做一些解析和计算的操作,下面就按照其结构来分析一下MP4文件里的主要的box.左侧的目录可以清晰地展示出各种box之间的关系。需要注意的是在ISO标准中box的种类非常多,这里只是列举分析了一些比较重要的box.

Mp4Box

首先我们需要先了解一下box的结构。在Mp4中所有的box都包含了一个BoxHeader和BoxData.其中BoxHeader包含了box的类型和整个box的长度,BoxData里面包含了子box或者各种数据。基于这种结构的考虑,我就可以设计出所有box的父类,还需要注意的是Media Data Box的长度有可能超出32位int的范围,在这种情况下,size的大小就被设置为1,然后使用接下来的64位来存储其长度。如果box的type为”uuid”的话,那接下来的16byte就用来存储uuid.

在上面我们定义了父类Mp4box,一般情况下box头部的长度都是8byte, 但是还有一种box在头部还有1byte的version和3byte的flags。所以我们需要创建一个Fullbox父类,让所有这种类型的box来继承它。

ftyp

代表了File type box. 一般在文件的开头处(只有固定大小的文件签名可以在其前面),主要包含了该文件brand等,其定义方式如下:

moov

代表了Movie box,这个box包含了一个mvhd box 和多个trak box(如video,audio等),一般在文件的开头处仅次于ftyp,但是也有放在文件末尾的。

代表了Movie Header box。 包含了整个媒体问题的信息。

creationTime: 一个int型的数据代表了文件的创建时间(从1904年1月1日凌晨开始的秒数)

modificationTime:修改时间,定义同上

timescale:1秒内包含的时间单位,和下面的duration结合可以得到媒体的时长。

duration:媒体的时长,以时长最长的track为准

rate:播放的速度,1.0为正常速度

volume:播放的音量

matrix:视频的转换矩阵

nextTrackId:下一个track的id

代表了 Track box。包含了一条track。通常情况下一个视频会包含video和audio两条track,还有一条hint track是为streaming准备的。

一个trak box内包含了tkdh和mdia两种box。

代表了Track Header Box。每个trck box会包含一个tkhd box来存储这条track的信息。

creationTime: 这条track的创建时间(同mvhd)

modificationTime: 这条track的更改时间(同nvhd)

trackId: 当前track的id,不能为0

duration: 当前track的时长

layer: 播放时video track的前后顺序,数字越小的越在上层。

alternateGroup: 对track进行分组,同一个组内同时只能播放一个track

volume: 音量大小,对于video track 会是0

matrix:video的转换矩阵

width/height 视频的宽度和长度,以像素为单位

代表了Media Box, 用来包含当前track的信息。mdia baox主要有三个子box,分别是hdlr、mdhd和minf,我们会在接下来分析这几个子box。

其中componentName并不是mdia box需要解析的内容,在这里我们用来存储当前track的类型,如是vedio还是audio。

mdhd

代表了Media Header Box。包含了一些当前track的信息,如creationTime等,在上文已经提过了,这里将不再赘述。

language 当前媒体的语言代码

hdlr

代表了Handler Refrence Box。包含了当前track类型的信息,如这条track是video、sound还是hint。

minf

代表了Media Information Box。 内部主要包含了一个stbl box。

stbl

代表了Sample Table Box。 这个box包含了当前track中所有Samples的时间和数据索引,所以根据这些信息就可以定位某个时间点的Sample及其大小等信息。

这个box包含了很多子box,将各个子box的信息结合起来就得得到Samples的详细信息了。具体怎么计算将在最后做一下分析。

stts

代表了Decoding Time to Sample Box。这个box包含了一个表,从这个表里可以根据解码时间来定位sample的序号。

sampleCount: 一个时间段内连续的Sample个数

sampleDelta:一个时间段内sample的delta。

ctts

代表了Sample Table Box。包含了decoding time 和composition time之间的偏移量。

sampleCount: 特定偏移量内连续的Sample个数

sampleDelta: CT和DT之间的偏移量,如CT(n)=DT(n)+CTTS(n)

stsd

代表了Sample Description Box,里面包含了一些子box,用来存储编码的信息。根据当前track的类型来决定子box的类型。

####### VisualSampleEntry

//todo

MP4

继续阅读