示例都是以NVIDIA Deepstream中的sample_720p.mp4为例。

1 概念与术语

  1. Box:MP4文件是由一个个Box组成的,可以将其理解为一个数据块,它由Header+Data组成,Data 可以存储媒体元数据和实际的音视频码流数据。Box可直接存储数据块,也可包含其它Box,我们把包含其它Box的Box称为container box。

  2. Sample:可理解为采样,对于视频可理解为一帧数据,音频一帧数据就是一段固定时间的音频数据,可以由多个Sample数据组成,存储媒体数据的单位是sample。

  3. Chunk:连续几个sample组成的单元被称为chunk,每个chunk在文件中有一个偏移量,整个偏移量从文件头算起,在这个chunk内,sample是连续存储的。

  4. Track:表示一些chunk的集合,对于媒体数据而言就是一个视频序列或者音频序列,常说的音频/视频轨可对照该概念上。除了Video Track和Audio Track外,还可以有非媒体数据,比如Hint Track,这种类型的Track就不包含媒体数据,可以包含一些将其他数据打包成媒体数据的指示信息或者字幕信息。简单来说,Track是音视频中可以独立操作的媒体单位。

alt text

2 box

2.1 ftyp(File Type Box)

  1. ftyp(File Type Box)是一个非常重要的box,它定义了文件类型以及该文件所支持的兼容规范。

  2. 该box有且只有1个,并且只能被包含在文件层,而不能被其他box包含。该box应该被放在文件的最开始,指示该MP4文件应用的相关信息。

alt text

alt text

2.2 mdat

实际的音视频数据存储,就是在该容器里面。

2.3 moov(Movie Box)

  1. moov是一个container box,一个文件只有一个,其包含的所有box用于描述媒体信息(metadata)。描述mdat里面的视频帧或者音频数据是如何播放的。

  2. 由于是一个 container box,所以除了 box header,其 box body 就是其它的 box

2.3.1 mvhd(Movie Header Box)

  1. mvhd 作为媒体信息的 header 出现(注意此header不是box header,而是moov媒体信息的header),用于描述一些所有媒体共享的基本信息。

  2. mvhd 语法继承自fullbox,注意下述示例出现的version和flags字段属于fullbox header

alt text

2.3.2 trak

  1. trak box 是一个 container box,其子 box 包含了该 track 的媒体信息。

  2. 一个 mp4 文件可以包含多个 track,track之间是独立的,trak box 用于描述每一路媒体流。

  3. 一般情况下有两个trak,分别对应音频流和视频流。

trak里面含有三个box,分别是:

  • tkhd(track header box):用于简单描述该路媒体流的信息,如创建时间,修改时间,时长,视频长宽等。

  • edts(edit Box):子Box为elst(Edit List Box),主要用于描述时间轴上的编辑操作(指定视频或音频轨道的偏移、剪辑,或者跳过某些部分,来调整媒体的时间轴)。

  • mdia(media box):用于详细描述该路媒体流的信息(里面会有每帧的解码时间、显示时间相关计算数据、每帧的size)

Trak里面有stream type(使用的是AVC/H.264或者)

alt text

2.3.2.1 tkhd(track header box)

  1. tkhd 作为媒体信息的header出现(注意此 header 不是 box header,而是 track 媒体信息的 header),用于描述一些该track的基本信息。

  2. tkhd语法继承自fullbox,注意下述示例出现的version和flags 字段属于fullbox header。

alt text

2.3.2.2 edts(edit Box)—>elst

edts Box 包含有关编辑列表的信息,主要用于描述时间轴上的编辑操作。它通常包含一个或多个Edit List Box(elst),用于定义如何对轨道的播放进行编辑。

例如,通过 edts,可以指定视频或音频轨道的偏移、剪辑,或者跳过某些部分,来调整媒体的时间轴。

它下边有一个elst(Edit List Box),它的作用是使track的时间戳产生偏移。看一下一些字段:

alt text

这里的media_time偏移,为的是pts从0开始,一会在计算pts的时候会用到

3 定位样本box

下面的box是 dinf (Data Information Box)里面的box。

在介绍stbl box之前,需要先介绍一下mp4中定义的sample与chunk:

  • sample:ISO/IEC 14496-12 中定义 samples 之间不能共享同一个时间戳,因此,在音视频 track 中,一个 sample 代表一个视频或音频帧。

  • chunk:多个 sample 的集合,实际上音视频 track 中,chunk 与 sample 一一对应。

alt text

3.1 stbl(Sample Table Box)

 stbl box是一个container box,是整个track中最重要的一个box,其子box描述了该路媒体流的解码相关信息、音视频位置信息、时间戳信息等。

3.2 avc1

  • avc1,是 avc/h264/mpeg-4 part 10视频编解码格式的代称,是一个 container box,但是 box body 也携带自身的信息。

  • avcC(AVC Video Stream Definition Box),存储 sps && pps,即在 ISO/IEC 14496-15 中定义的 AVCDecoderConfigurationRecord 结构。(其实就是extradata部分)

alt text

3.3 stts(time to sample box)

  1. 存储了该 track 每个 sample 到 dts 的时间映射关系。(可以计算出解码时间戳)

  2. 包含了一个压缩版本的表,通过这个表可以从解码时间映射到sample序号。表中的每一项是连续相同的编码时间增量(Decode Delta)的个数和编码时间增量。通过把时间增量累加就可以建立一个完整的time to sample表。

alt text

可以计算得到dts:

sample样本计数是从1开始计数,不是从0开始

alt text

3.4 stss(sync sample box)

它包含media中的关键帧的sample表。关键帧是为了支持随机访问。如果此表不存在,说明每一个sample都是一个关键帧。

alt text

alt text

3.5 ctts

  1. 存储了该 track 中,每个 sample 的 pts 与 dts 时间差(cts = pts - dts):

  2. 如果一个视频只有I帧和P帧,则ctts这个表就不需要了,因为解码顺序和显示顺序是一致的,但是如果视频中存在B帧,则需要ctts。

alt text

3.6 stsz

包含sample的数量和每个sample的字节大小,这个box相对来说体积比较大的。表明视频帧或者音频帧大小,FFmpeg 里面的AVPacket 的size 数据大小,就是从这个box中来的。

alt text

alt text

参考

参考1:分析工具

参考2:视频封装格式:MP4格式详解

参考3:音视频封装:MP4结构概述和分析工具