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进行描述。网络

--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是未定义的,应该将其忽略。ide

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

接下来咱们看看真正的Boxui

ftyp box(file type box)

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

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

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。
moovcode

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。
track
trak的部分字节实例以下图,其中黄色为trak box的头,绿色为tkhd,蓝色为edts(一个可选box),红色为一部分mdia。
trak对象

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的实例结构树图。

clipboard.png

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’结尾的字符串
相关文章
相关标签/搜索