MP4格式学习

简介

MP4视频文件封装格式是基于QuickTime容器格式定义的,因此参考QuickTime的格式定义对理解MP4文件格式很有帮助。MP4文件格式是一个十分开放的容器,几乎可以用来描述所有的媒体结构,MP4文件中的媒体描述与媒体数据是分开的,并且媒体数据的组织也很自由,不一定要按照时间顺序排列,甚至媒体数据可以直接引用其他文件。同时,MP4也支持流媒体。MP4目前被广泛用于封装h.264视频和AAC音频,是高清视频的代表。

格式概述

MP4文件中的所有数据都装在box(QuickTime中为atom)中,也就是说MP4文件由若干个box组成,每个box有类型和长度,可以将box理解为一个数据对象块。box中可以包含另一个box,这种box称为container box。一个MP4文件首先会有且只有一个“ftyp”类型的box,作为MP4格式的标志并包含关于文件的一些信息;之后会有且只有一个“moov”类型的box(Movie Box),它是一种container box,子box包含了媒体的metadata信息;MP4文件的媒体数据包含在“mdat”类型的box(Midia Data Box)中,该类型的box也是container box,可以有多个,也可以没有(当媒体数据全部引用其他文件时),媒体数据的结构由metadata进行描述。

MP4格式学习_第1张图片

Box

首先需要说明的是,box中的字节序为网络字节序,也就是大端字节序(Big-Endian),简单的说,就是一个32位的4字节整数存储方式为高位字节在内存的低端。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中。)
size后面紧跟的32位为box type,一般是4个字符,如“ftyp”、“moov”等,这些box type都是已经预定义好的,分别表示固定的意义。如果是“uuid”,表示该box为用户扩展类型。如果box type是未定义的,应该将其忽略。

Base Box{
    BoxHead{
        box_size 4byte;
        box_type 4byte;
    };
    BoxBody
};

接下来我们看看真正的Box

ftyp box(file type box)

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

"ftyp" body依次包括1个32位的major brand(4个字符),1个32位的minor version(整数)和1个以32位(4个字符)为单位元素的数组compatible brands。这些都是用来指示文件应用级别的信息。该box的字节实例如下:
MP4格式学习_第2张图片

struct mov_ftyp_t                                                                                                      
{
    uint32_t major_brand;
    uint32_t minor_version;

    uint32_t compatible_brands[N_BRAND];
    size_t brands_count;
};

moov box(movie box)

该box包含了文件媒体的metadata信息,moov是一个container box,具体内容信息由子box诠释。同File Type Box一样,该box有且只有一个,且只被包含在文件层。一般情况下,moov会紧随ftyp出现。
一般情况下(限于篇幅,本文只讲解常见的MP4文件结构),moov中会包含1个mvhd和若干个trak。其中mvhd为header box,一般作为moov的第一个子box出现(对于其他container box来说,header box都应作为首个子box出现)。trak包含了一个track的相关信息,是一个container box。下图为部分moov的字节实例,其中红色部分为box header,绿色为mvhd,黄色为一部分trak。

mvhd(movie header box)

字段 字节数 说明
box size 4 box 的大小
box type 4 box 的类型
version 1 box 的版本,0或则1,一般为0。一下的字节数均按照version=0设置
flag 3
creation time 4 创建时间,相对于UTC时间(1904-01-01零点的秒数)
modification time 4 修改时间
time scale 4 文件媒体在1秒内的时间刻度,即把1秒划分成多少个小的时间片)
duration 4 该track的时间长度,用duration和time sacle值可以计算出track的时长;
比如audio track的time scale = 8000,duration=560128,则时长为70.016;
video track的time scale=600,duration=42000,时长为70。
rate 4 推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16]。
如1.0会表示成0x00010000,表示正常向前播放。
volume 2 与rate类似,[8.8] 格式,1.0(0x0100)表示最大音量
reserved 10 保留位
matrix 36 视频变换矩阵
pre-defined 24
next track id 4 下一个track的id号

mvhd的字节实例如下图,各字段已经用颜色区分开:
1177848-20171124103340343-505155072
数据结构的定义

struct mov_mvhd_t
{
    // FullBox
    uint32_t version : 8;
    uint32_t flags : 24; 

    uint32_t timescale; // time-scale for the entire presentation, the number of time units that pass in one second
    uint64_t duration; // default UINT64_MAX(by timescale)
    uint64_t creation_time; // seconds sine midnight, Jan. 1, 1904, UTC
    uint64_t modification_time; // seconds sine midnight, Jan. 1, 1904, UTC

    uint32_t rate;
    uint16_t volume; // fixed point 8.8 number, 1.0 (0x0100) is full volume
    //uint16_t reserved;
    //uint32_t reserved2[2];
    int32_t matrix[9]; // u,v,w
    //int32_t pre_defined[6];
    uint32_t next_track_ID;
};

trak(track box)

trak也是一个container box,其子box包含了该track的媒体数据引用和描述(hint track除外)。一个MP4文件中的媒体可以包含多个track,且至少有一个track,这些track之间彼此独立,有自己的时间和空间信息。trak必须包含一个tkhd和一个mdia,此外还有很多可选的box(略)。其中tkhd为track header box,mdia为media box,该box是一个包含一些track媒体数据信息box的container box。
MP4格式学习_第3张图片

tkhd(track header box)

tkhd结构如下表。

字段 字节数 意义
box size 4 box大小
box type 4 box类型
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
flags 3 按位或操作结果值,预定义如下:
0x000001 track_enabled,否则该track不被播放;
0x000002 track_in_movie,表示该track在播放中被引用;
0x000004 track_in_preview,表示该track在预览时被引用。
一般该值为7,如果一个媒体所有track均未设置track_in_movie和track_in_preview,
将被理解为所有track均设置了这两项;对于hint track,该值为0
creation time 4 创建时间(相对于UTC时间1904-01-01零点的秒数)
modification time 4 修改时间
track id 4 id号,不能重复且不能为0
reserved 4 保留位
duration 4 track的时间长度
reserved 8 保留位
layer 2 视频层,默认为0,值小的在上层
alternate group 2 track分组信息,默认为0表示该track未与其他track有群组关系
volume 2 [8.8] 格式,如果为音频track,1.0(0x0100)表示最大音量;否则为0
reserved 2 保留位
matrix 36 视频变换矩阵
width 4
height 4

mdia(Media Box)

mdia也是个container box,其子box的结构和种类还是比较复杂的。先来看一个mdia的实例结构树图。

MP4格式学习_第4张图片

mdhd(media header box)

结构如下表:
字段 字节数 意义
box size 4 box大小
box type 4 box类型
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
flags 3
creation time 4 创建时间(相对于UTC时间1904-01-01零点的秒数)
modification time 4 修改时间
time scale 4 文件媒体在1秒内的时间刻度,即把1秒划分成多少个小的时间片)
duration 4 该track的时间长度,用duration和time sacle值可以计算出track的时长;
比如audio track的time scale = 8000,duration=560128,则时长为70.016;
video track的time scale=600,duration=42000,时长为70。
language 2 媒体语言码。最高位为0,后面15位为3个字符(见ISO 639-2/T标准中定义)
pre-defined 2
字段 字节数 意义
box size 4 box大小
box type 4 box类型
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
flags 3
pre-defined 4
handler type 4 在media box中,该值为4个字符:
vide— video track
soun— audio track
hint— hint track
reserved 12
name 不定 track type name,以‘0’结尾的字符串

你可能感兴趣的:(ffmpeg,mp4)