MP4文件格式详解
2012-10-11 12:00
330 查看
************************************
**结构概述**
************************************
一、基本概念
1.mp4概述
MP4文件中的所有数据都装在box(QuickTime中为atom)中,也就是说MP4文件由若干个box组成,每个box有类型和长度,可以将box理解为一个数据对象块。box中可以包含另一个box,这种box称为containerbox。一个MP4文件首先会有且只有一个“ftyp”类型的box,作为MP4格式的标志并包含关于文件的一些信息;之后会有且只有一个“moov”类型的box(MovieBox),它是一种containerbox,子box包含了媒体的metadata信息;MP4文件的媒体数据包含在“mdat”类型的box(Midia
DataBox)中,该类型的box也是containerbox,可以有多个,也可以没有(当媒体数据全部引用其他文件时),媒体数据的结构由metadata进行描述。
下面是一些概念:
track表示一些sample的集合,对于媒体数据来说,track表示一个视频或音频序列。
hinttrack这个特殊的track并不包含媒体数据,而是包含了一些将其他数据track打包成流媒体的指示信息。
sample对于非hinttrack来说,videosample即为一帧视频,或一组连续视频帧,audiosample即为一段连续的压缩音频,它们统称sample。对于hinttrack,sample定义一个或多个流媒体包的格式。
sampletable指明sampe时序和物理布局的表。
chunk一个track的几个sample组成的单元。
在本文中,我们不讨论涉及hint的内容,只关注包含媒体数据的本地MP4文件。下图为一个典型的MP4文件的结构树。
2、Box
首先需要说明的是,box中的字节序为网络字节序,也就是大端字节序(Big-Endian),简单的说,就是一个32位的4字节整数存储方式为高位字节在内存的低端。Box由header和body组成,其中header统一指明box的大小和类型,body根据类型有不同的意义和格式。
标准的box开头的4个字节(32位)为boxsize,该大小包括boxheader和boxbody整个box的大小,这样我们就可以在文件中定位各个box。如果size为1,则表示这个box的大小为largesize,真正的size值要在largesize域上得到。(实际上只有“mdat”类型的box才有可能用到largesize。)如果size为0,表示该box为文件的最后一个box,文件结尾即为该box结尾。(同样只存在于“mdat”类型的box中。)
size后面紧跟的32位为boxtype,一般是4个字符,如“ftyp”、“moov”等,这些boxtype都是已经预定义好的,分别表示固定的意义。如果是“uuid”,表示该box为用户扩展类型。如果boxtype是未定义的,应该将其忽略
(1、mp4文件由许多Box和FullBox组成。
(2、Box,每个Box由Header和Data组成。
(3、FullBox,是Box的扩展,Box结构的基础上在Header中增加8bitsversion和24bitsflags。
(4、Header,包含了整个Box的长度size和类型type。当size==0时,代表这是文件中最后一个Box;当size==1时,意味着Box长度需要更多bits来描述,在后面会定义一个64bits的largesize描述Box的长度;当type是uuid时,代表Box中的数据是用户自定义扩展类型。
(5、Data,是Box的实际数据,可以是纯数据也可以是更多的子Boxes。
(6、当一个Box的Data中是一系列子Box时,这个Box又可成为ContainerBox。当一个Box里面不包含子Box时,这个Box称为leafBox,而FullBox是mp4格式协议规定的某些特殊的Box。
Boxheader的结构用伪代码表示如下:
结构如下图:
BOX结构描述图
二、MP4文件格式(ISO-14496-12/14)
MP4文件就是由各式各样的Box组成的,下表中列出了所有必选或可选的Box类型,√代表Box必选。
先简单介绍几个重要的box,以便诸位在后续学习时心中有数:
1、ftypbox,在文件的开始位置,描述的文件的版本、兼容协议等;
2、moovbox,这个box中不包含具体媒体数据,但包含本文件中所有媒体数据的宏观描述信息,moovbox下有mvhd和trakbox。
>>mvhd中记录了创建时间、修改时间、时间度量标尺、可播放时长等信息。
>>trak中的一系列子box描述了每个媒体轨道的具体信息。
3、moofbox,这个box是视频分片的描述信息。并不是MP4文件必须的部分,但在我们常见的可在线播放的MP4格式文件中(例如SilverlightSmoothStreaming中的ismv文件)确是重中之重。
4、mdatbox,实际媒体数据。我们最终解码播放的数据都在这里面。
5、mfrabox,一般在文件末尾,媒体的索引文件,可通过查询直接定位所需时间点的媒体数据。
附:SmoothStreaming中ismv文件结构,文件分为了多个Fragments,每个Fragment中包含moof和mdat。这样的结构符合渐进式播放需求。(mdat及其描述信息逐步传输,收齐一个Fragment便可播放其中的mdat)。
************************************
**文件类型ftyp**
************************************
ftypbox的数据结构的伪代码表示:
什么是brands?官方是这样描述的:
Eachbrandisaprintablefour-charactercode,registeredwithISO,thatidentifiesaprecisespecification.//在ISO注册的4个字符。
下表来源于网络,列出了几种常见的基于基础文件格式的,媒体封装格式标识。
更多的内容可以查看http://www.ftyps.com/
结合实际文件,下图是MP4文件起始位置存放的数据
length(4字节):0x0000001c:box的长度是28字节;
boxtype(4字节):0x66747970:“ftyp”的ASCII码,box的标识;
major_brand(4字节):0x69736f6d:“isom“的ASCII码;
minor_version(4字节):0x00000200:ismo的版本号;
compatible_brands(12字节):说明本文件遵从(或称兼容)ismo,iso2,mp41三种协议。
ftypbox通常放在文件的开始,通过对该box解析可以让我们的软件(播放器、demux、解析器)知道应该使用哪种协议对这该文件解析。
************************************
**元数据moov**
************************************
moviebox——containerboxwhosesub-boxesdefinethemetadataforapresentation(‘moov’)
moov包含的一系列次级box中存储着媒体播放所需的元数据(metadata)。
两点疑问:什么是元数据?moov有哪些次级box?
1)元数据:描述数据的数据。针对媒体文件而言元数据都有哪些呢?为了让大家直观了解:
上图是使用“格式工厂”获取某MP4文件的媒体信息,这些媒体信息基本都包含在moov中。
视频包括编码等级、分辨率、色域、码率、帧率、位深、时长等等……
音频又包括声道、采样率等音频特有属性。
这些元数据对于我们的价值在于:我们的系统(比如PC播放器,高清播放机)可以通过对moovbox的解析,自动适配运行在某种模式下去播放影片。在嵌入式领域,由于DSP或ARM的Ram空间有限,经常需要动态加载本次播放所需的解码器(算法程序),通过自适配可以用最廉价的CPU,完成一款支持多码率多格式的全能播放器。
2)moov用哪些次级box来保存这些信息?
mvhd——Thisboxdefinesoverallinformationwhichismedia-independent,andrelevanttotheentirepresentation.
全文件唯一的(一个文件中只能包含一个mvhdbox),对整个文件所包含的媒体数据作全面的全局的描述。包含了媒体的创建与修改时间时间刻度、默认音量、色域、时长等信息。
首先mvhd是个FullBox,引用我第一篇文中解释:“FullBox,是Box的扩展,Box结构的基础上在Header中增加8bitsversion和24bitsflags。”,见下图:
图中标红的是moovbox的长度与标识,
标蓝的是mvhd的长度0x6c,
标黄的是mvhd的标识与内容:
0x6D766864是mvhd的ASCII标识;
0x00000000是FullBox扩展出来的标识位,这里是全0,Version和flags都是0,参见前面的结构定义可知后面的时间与时长采用了32bit表示方式。
第一个0x7C25B080是创建时间,第二个0x7C25B080是最后修改时间。可见媒体未被修改过。这两个数值是怎么描述具体时间的呢?
timeisanintegerthatdeclaresthecreationtimeofthepresentation(insecondssincemidnight,Jan.1,1904,inUTCtime)
即,从UTC时间的1904年1月1日0点至今的秒数。我们手动算一下:
0x7C25B080=2082844800秒,大概是66.0465年(每年按365天算,不考虑闰年),1904+66=1970年中。看来这个媒体文件生成的并不规范,没有按照ISO的规范填写创建与修改时间(bytheway,该文件是一年前使用iKu转码生成)。不过这里的时间并不影响播放器识别并播放影片。
我们假设4字节的时间描述取其最大值0xFFFFFFFF,通过计算最多支持到2040年。如果,假设该参数是播放视频所必备的参数,那么到2040年后,也许所有的MP4文件一夜间就无法播放了~(0==Version这种)。
0x000003E8是timescale,该数值表示本文件的所有时间描述所采用的单位。0x3E8=1000,即将1s平均分为1000份,每份1ms。
0x000A06A2是duration,媒体可播放时长,0xA06A2=657058,这个数值的单位与实际时间的对应关系就要通过上面的timescale参数。
duration/timescale=可播放时长(s)。这里算出该视频能播放657.058s。使用MPC打开,时长与我们计算的一致。
timescale时间刻度贯穿在整个文件中,所有对于时间的描述都要以其为参照,例如解码时间DTS,展示时间PTS等最重要的时间描述。
0x00010000媒体速率,这个值代表原始倍速。
0x0100媒体音量,这个值代表满音量。
接下来的一系列值都是结构中的预定义值,参见结构定义即可。
trakbox——Thisisacontainerboxforasingletrackofapresentation.Apresentationconsistsofoneormoretracks.Eachtrackisindependentoftheothertracksinthepresentationandcarriesitsowntemporalandspatialinformation.
EachtrackwillcontainitsassociatedMediaBox.
其次级box中包含了单个媒体轨道(Track)所特有的描述信息。
我们知道一部视频一般都有多个轨道组成。
例如,《让子弹飞》的正版DVD,1)有一条视频轨用于电影画面。2)至少有两条音频轨分别提供了普通话与四川话版,实际上为了营造更加逼真的现场效果,为了配合多声道家庭影院该影片还独有一条音效轨。3)多条字幕轨,简体中文,繁体中文,英文……。从中我们可以理解为什么trakbox可以有多个:每个track都是独立的,具有自我特征与属性的,因此需要各自描述互不干涉。
我们一般所看的MP4文件中moov下都至少是mvhd-trak-trak-trak...这种构成。
tkhdbox的数据结构的伪代码表示:
类似我们moov中的mvhdbox,但tkhd仅仅描述的单一Track的特性。
上图是实际媒体中的tkhd的数据:
0x5c是tkhdbox长度,0x746b6864是“tkhd”的ASCII码。
0x0000000f是使用了Fullbox中的flag位(Fullbox8bitsversion+24bitsflag,详见我第一篇日志),这里flag=0xf,即1111b。
这4位从低到高分别代表:
Track_enabled:Indicatesthatthetrackisenabled.若此位为0,则该track内容无需播放(比如我们用一些非线编软件<如SonyVegas>做视频剪辑时,有些Track仅为我们参考与模仿用,在输出时将该Track关掉)。
Track_in_movie:Indicatesthatthetrackisusedinthepresentation.
Track_in_preview:Indicatesthatthetrackisusedwhenpreviewingthepresentation.
Track_in_poster:Indicatesthatthetrackisusedinmovie'sposter.
/*-------------------------------------------------------------------------------------------------------*/
important:我们知道,MP4文件格式是ISO-14496-12基础文件格式的衍生品,14496-14中对-12协议进行了扩充与进一步定义。
重要的是该“14496-12基础文件格式”协议如果认祖归宗,我们发现这种文件格式最初是由Apple公司的QuickTime媒体格式发展而来的。
即,mov格式发展出了“ISO14496-12协议”,再由该协议衍生出了mp4,f4v,ismv,3gp等我们常见的媒体封装格式。
因此上述标志位的poster位,在14496-12中并没有见到描述,而在Apple的协议中却看到了准确定义。
详见https://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap2/qtff2.html
/*-------------------------------------------------------------------------------------------------------*/
两个0xc5268eb6是track的创建时间与最后修改时间;
紧随其后的0x00000002,代表trackID=2,TrackID是非0的,唯一的,不可重复使用的标识track的方式;
后面32bit全0是保留位;
0x0009d97c是本track的时长,需要配合mvhdbox中的timescale计算实际的持续时间。
后续一些写死的字段不再分析,有些与mvhd重复,可以参见之前的文章。我们看两个关键字段:
layer,类似photoshop中图层的概念,数值小的在播放时更贴近用户(上层图层)。
alternate_group,track的备用分组ID,当该值为0时,意味着本track内容无备份;否则本track会可能会有零到多个备份track。当播放时相同groupID的track只选择一个进行播放。
**结构概述**
************************************
一、基本概念
1.mp4概述
MP4文件中的所有数据都装在box(QuickTime中为atom)中,也就是说MP4文件由若干个box组成,每个box有类型和长度,可以将box理解为一个数据对象块。box中可以包含另一个box,这种box称为containerbox。一个MP4文件首先会有且只有一个“ftyp”类型的box,作为MP4格式的标志并包含关于文件的一些信息;之后会有且只有一个“moov”类型的box(MovieBox),它是一种containerbox,子box包含了媒体的metadata信息;MP4文件的媒体数据包含在“mdat”类型的box(Midia
DataBox)中,该类型的box也是containerbox,可以有多个,也可以没有(当媒体数据全部引用其他文件时),媒体数据的结构由metadata进行描述。
下面是一些概念:
track表示一些sample的集合,对于媒体数据来说,track表示一个视频或音频序列。
hinttrack这个特殊的track并不包含媒体数据,而是包含了一些将其他数据track打包成流媒体的指示信息。
sample对于非hinttrack来说,videosample即为一帧视频,或一组连续视频帧,audiosample即为一段连续的压缩音频,它们统称sample。对于hinttrack,sample定义一个或多个流媒体包的格式。
sampletable指明sampe时序和物理布局的表。
chunk一个track的几个sample组成的单元。
在本文中,我们不讨论涉及hint的内容,只关注包含媒体数据的本地MP4文件。下图为一个典型的MP4文件的结构树。
2、Box
首先需要说明的是,box中的字节序为网络字节序,也就是大端字节序(Big-Endian),简单的说,就是一个32位的4字节整数存储方式为高位字节在内存的低端。Box由header和body组成,其中header统一指明box的大小和类型,body根据类型有不同的意义和格式。
标准的box开头的4个字节(32位)为boxsize,该大小包括boxheader和boxbody整个box的大小,这样我们就可以在文件中定位各个box。如果size为1,则表示这个box的大小为largesize,真正的size值要在largesize域上得到。(实际上只有“mdat”类型的box才有可能用到largesize。)如果size为0,表示该box为文件的最后一个box,文件结尾即为该box结尾。(同样只存在于“mdat”类型的box中。)
size后面紧跟的32位为boxtype,一般是4个字符,如“ftyp”、“moov”等,这些boxtype都是已经预定义好的,分别表示固定的意义。如果是“uuid”,表示该box为用户扩展类型。如果boxtype是未定义的,应该将其忽略
(1、mp4文件由许多Box和FullBox组成。
(2、Box,每个Box由Header和Data组成。
(3、FullBox,是Box的扩展,Box结构的基础上在Header中增加8bitsversion和24bitsflags。
(4、Header,包含了整个Box的长度size和类型type。当size==0时,代表这是文件中最后一个Box;当size==1时,意味着Box长度需要更多bits来描述,在后面会定义一个64bits的largesize描述Box的长度;当type是uuid时,代表Box中的数据是用户自定义扩展类型。
(5、Data,是Box的实际数据,可以是纯数据也可以是更多的子Boxes。
(6、当一个Box的Data中是一系列子Box时,这个Box又可成为ContainerBox。当一个Box里面不包含子Box时,这个Box称为leafBox,而FullBox是mp4格式协议规定的某些特殊的Box。
Boxheader的结构用伪代码表示如下:
aligned(8)classBox(unsignedint(32)boxtype,optionalunsignedint(8)[16]extended_type) { unsignedint(32)size; unsignedint(32)type=boxtype; if(size==1) { unsignedint(64)largesize; } elseif(size==0) { //boxextendstoendoffile } if(boxtype==‘uuid’) { unsignedint(8)[16]usertype=extended_type; }
结构如下图:
BOX结构描述图
二、MP4文件格式(ISO-14496-12/14)
MP4文件就是由各式各样的Box组成的,下表中列出了所有必选或可选的Box类型,√代表Box必选。
ftyp | √ | filetypeandcompatibility | |||||
pdin | progressivedownloadinformation | ||||||
moov | √ | containerforallthemetadata | |||||
mvhd | √ | movieheader,overalldeclarations | |||||
trak | √ | containerforanindividualtrackorstream | |||||
tkhd | √ | trackheader,overallinformationaboutthetrack | |||||
tref | trackreferencecontainer | ||||||
edts | editlistcontainer | ||||||
elst | aneditlist | ||||||
mdia | √ | containerforthemediainformationinatrack | |||||
mdhd | √ | mediaheader,overallinformationaboutthemedia | |||||
hdlr | √ | handler,declaresthemedia(handler)type | |||||
minf | √ | mediainformationcontainer | |||||
vmhd | videomediaheader,overallinformation(videotrackonly) | ||||||
smhd | soundmediaheader,overallinformation(soundtrackonly) | ||||||
hmhd | hintmediaheader,overallinformation(hinttrackonly) | ||||||
nmhd | Nullmediaheader,overallinformation(sometracksonly) | ||||||
dinf | √ | datainformationbox,container | |||||
dref | √ | datareferencebox,declaressource(s)ofmediadataintrack | |||||
stbl | √ | sampletablebox,containerforthetime/spacemap | |||||
stsd | √ | sampledescriptions(codectypes,initializationetc.) | |||||
stts | √ | (decoding)time-to-sample | |||||
ctts | (composition)timetosample | ||||||
stsc | √ | sample-to-chunk,partialdata-offset information | |||||
stsz | samplesizes(framing) | ||||||
stz2 | compactsamplesizes(framing) | ||||||
stco | √ | chunkoffset,partialdata-offsetinformation | |||||
co64 | 64-bitchunkoffset | ||||||
stss | syncsampletable(randomaccesspoints) | ||||||
stsh | shadowsyncsampletable | ||||||
padb | samplepaddingbits | ||||||
stdp | sampledegradationpriority | ||||||
sdtp | independentanddisposablesamples | ||||||
sbgp | sample-to-group | ||||||
sgpd | samplegroupdescription | ||||||
subs | sub-sampleinformation | ||||||
mvex | movieextendsbox | ||||||
mehd | movieextendsheaderbox | ||||||
trex | √ | trackextendsdefaults | |||||
ipmc | IPMPControlBox | ||||||
moof | moviefragment | ||||||
mfhd | √ | moviefragmentheader | |||||
traf | trackfragment | ||||||
tfhd | √ | trackfragmentheader | |||||
trun | trackfragmentrun | ||||||
sdtp | independentanddisposablesamples | ||||||
sbgp | sample-to-group | ||||||
subs | sub-sampleinformation | ||||||
mfra | moviefragmentrandomaccess | ||||||
tfra | trackfragmentrandomaccess | ||||||
mfro | √ | moviefragmentrandomaccessoffset | |||||
mdat | mediadatacontainer | ||||||
free | freespace | ||||||
skip | freespace | ||||||
udta | user-data | ||||||
cprt | copyrightetc. | ||||||
meta | metadata | ||||||
hdlr | √ | handler,declaresthemetadata(handler)type | |||||
dinf | datainformationbox,container | ||||||
dref | datareferencebox,declaressource(s)ofmetadataitems | ||||||
ipmc | IPMPControlBox | ||||||
iloc | itemlocation | ||||||
ipro | itemprotection | ||||||
sinf | protectionschemeinformationbox | ||||||
frma | originalformatbox | ||||||
imif | IPMPInformationbox | ||||||
schm | schemetypebox | ||||||
schi | schemeinformationbox | ||||||
iinf | iteminformation | ||||||
xml | XMLcontainer | ||||||
bxml | binaryXMLcontainer | ||||||
pitm | primaryitemreference | ||||||
fiin | filedeliveryiteminformation | ||||||
paen | partitionentry | ||||||
fpar | filepartition | ||||||
fecr | FECreservoir | ||||||
segr | filedeliverysessiongroup | ||||||
gitn | groupidtoname | ||||||
tsel | trackselection | ||||||
meco | additionalmetadatacontainer | ||||||
mere | metaboxrelation |
1、ftypbox,在文件的开始位置,描述的文件的版本、兼容协议等;
2、moovbox,这个box中不包含具体媒体数据,但包含本文件中所有媒体数据的宏观描述信息,moovbox下有mvhd和trakbox。
>>mvhd中记录了创建时间、修改时间、时间度量标尺、可播放时长等信息。
>>trak中的一系列子box描述了每个媒体轨道的具体信息。
3、moofbox,这个box是视频分片的描述信息。并不是MP4文件必须的部分,但在我们常见的可在线播放的MP4格式文件中(例如SilverlightSmoothStreaming中的ismv文件)确是重中之重。
4、mdatbox,实际媒体数据。我们最终解码播放的数据都在这里面。
5、mfrabox,一般在文件末尾,媒体的索引文件,可通过查询直接定位所需时间点的媒体数据。
附:SmoothStreaming中ismv文件结构,文件分为了多个Fragments,每个Fragment中包含moof和mdat。这样的结构符合渐进式播放需求。(mdat及其描述信息逐步传输,收齐一个Fragment便可播放其中的mdat)。
************************************
**文件类型ftyp**
************************************
ftypbox的数据结构的伪代码表示:
aligned(8)classFileTypeBoxextendsBox(‘ftyp’) { unsignedint(32)major_brand; unsignedint(32)minor_version; unsignedint(32)compatible_brands[];//toendofthebox }
什么是brands?官方是这样描述的:
Eachbrandisaprintablefour-charactercode,registeredwithISO,thatidentifiesaprecisespecification.//在ISO注册的4个字符。
下表来源于网络,列出了几种常见的基于基础文件格式的,媒体封装格式标识。
更多的内容可以查看
Brand | Extension | MimeType | |
MP4 | mp41,mp42 | .mp4 | video/mp4,audio/mp4,application/mp4 |
3GPP | various,e.g.3gp4,3gp5 | .3gp | video/3gpp,audio/3gpp |
3GPP2 | 3g2a | .3g2 | video/3gpp2,audio/3gpp2 |
MotionJPEG2000 | mjp2 | .mj2 | video/mj2 |
QuickTime | "qt" | .mov | video/quicktime |
length(4字节):0x0000001c:box的长度是28字节;
boxtype(4字节):0x66747970:“ftyp”的ASCII码,box的标识;
major_brand(4字节):0x69736f6d:“isom“的ASCII码;
minor_version(4字节):0x00000200:ismo的版本号;
compatible_brands(12字节):说明本文件遵从(或称兼容)ismo,iso2,mp41三种协议。
ftypbox通常放在文件的开始,通过对该box解析可以让我们的软件(播放器、demux、解析器)知道应该使用哪种协议对这该文件解析。
************************************
**元数据moov**
************************************
moviebox——containerboxwhosesub-boxesdefinethemetadataforapresentation(‘moov’)
moov包含的一系列次级box中存储着媒体播放所需的元数据(metadata)。
两点疑问:什么是元数据?moov有哪些次级box?
1)元数据:描述数据的数据。针对媒体文件而言元数据都有哪些呢?为了让大家直观了解:
上图是使用“格式工厂”获取某MP4文件的媒体信息,这些媒体信息基本都包含在moov中。
视频包括编码等级、分辨率、色域、码率、帧率、位深、时长等等……
音频又包括声道、采样率等音频特有属性。
这些元数据对于我们的价值在于:我们的系统(比如PC播放器,高清播放机)可以通过对moovbox的解析,自动适配运行在某种模式下去播放影片。在嵌入式领域,由于DSP或ARM的Ram空间有限,经常需要动态加载本次播放所需的解码器(算法程序),通过自适配可以用最廉价的CPU,完成一款支持多码率多格式的全能播放器。
2)moov用哪些次级box来保存这些信息?
mvhd——Thisboxdefinesoverallinformationwhichismedia-independent,andrelevanttotheentirepresentation.
全文件唯一的(一个文件中只能包含一个mvhdbox),对整个文件所包含的媒体数据作全面的全局的描述。包含了媒体的创建与修改时间时间刻度、默认音量、色域、时长等信息。
aligned(8)classMovieHeaderBoxextendsFullBox(‘mvhd’,version,0) { if(version==1) { unsignedint(64)creation_time; unsignedint(64)modification_time; unsignedint(32)timescale; unsignedint(64)duration; } else {//version==0 unsignedint(32)creation_time; unsignedint(32)modification_time; unsignedint(32)timescale; unsignedint(32)duration; } templateint(32)rate=0x00010000;//typically1.0 templateint(16)volume=0x0100;//typically,fullvolume constbit(16)reserved=0; constunsignedint(32)[2]reserved=0; templateint(32)[9]matrix={0x00010000,0,0,0,0x00010000,0,0,0,0x40000000}; //Unitymatrix bit(32)[6]pre_defined=0; unsignedint(32)next_track_ID; }
首先mvhd是个FullBox,引用我第一篇文中解释:“FullBox,是Box的扩展,Box结构的基础上在Header中增加8bitsversion和24bitsflags。”,见下图:
图中标红的是moovbox的长度与标识,
标蓝的是mvhd的长度0x6c,
标黄的是mvhd的标识与内容:
0x6D766864是mvhd的ASCII标识;
0x00000000是FullBox扩展出来的标识位,这里是全0,Version和flags都是0,参见前面的结构定义可知后面的时间与时长采用了32bit表示方式。
第一个0x7C25B080是创建时间,第二个0x7C25B080是最后修改时间。可见媒体未被修改过。这两个数值是怎么描述具体时间的呢?
timeisanintegerthatdeclaresthecreationtimeofthepresentation(insecondssincemidnight,Jan.1,1904,inUTCtime)
即,从UTC时间的1904年1月1日0点至今的秒数。我们手动算一下:
0x7C25B080=2082844800秒,大概是66.0465年(每年按365天算,不考虑闰年),1904+66=1970年中。看来这个媒体文件生成的并不规范,没有按照ISO的规范填写创建与修改时间(bytheway,该文件是一年前使用iKu转码生成)。不过这里的时间并不影响播放器识别并播放影片。
我们假设4字节的时间描述取其最大值0xFFFFFFFF,通过计算最多支持到2040年。如果,假设该参数是播放视频所必备的参数,那么到2040年后,也许所有的MP4文件一夜间就无法播放了~(0==Version这种)。
0x000003E8是timescale,该数值表示本文件的所有时间描述所采用的单位。0x3E8=1000,即将1s平均分为1000份,每份1ms。
0x000A06A2是duration,媒体可播放时长,0xA06A2=657058,这个数值的单位与实际时间的对应关系就要通过上面的timescale参数。
duration/timescale=可播放时长(s)。这里算出该视频能播放657.058s。使用MPC打开,时长与我们计算的一致。
timescale时间刻度贯穿在整个文件中,所有对于时间的描述都要以其为参照,例如解码时间DTS,展示时间PTS等最重要的时间描述。
0x00010000媒体速率,这个值代表原始倍速。
0x0100媒体音量,这个值代表满音量。
接下来的一系列值都是结构中的预定义值,参见结构定义即可。
trakbox——Thisisacontainerboxforasingletrackofapresentation.Apresentationconsistsofoneormoretracks.Eachtrackisindependentoftheothertracksinthepresentationandcarriesitsowntemporalandspatialinformation.
EachtrackwillcontainitsassociatedMediaBox.
其次级box中包含了单个媒体轨道(Track)所特有的描述信息。
我们知道一部视频一般都有多个轨道组成。
例如,《让子弹飞》的正版DVD,1)有一条视频轨用于电影画面。2)至少有两条音频轨分别提供了普通话与四川话版,实际上为了营造更加逼真的现场效果,为了配合多声道家庭影院该影片还独有一条音效轨。3)多条字幕轨,简体中文,繁体中文,英文……。从中我们可以理解为什么trakbox可以有多个:每个track都是独立的,具有自我特征与属性的,因此需要各自描述互不干涉。
我们一般所看的MP4文件中moov下都至少是mvhd-trak-trak-trak...这种构成。
tkhdbox的数据结构的伪代码表示:
aligned(8)classTrackHeaderBoxextendsFullBox(‘tkhd’,version,flags)
{
if(version==1)
{
unsignedint(64)creation_time;
unsignedint(64)modification_time;
unsignedint(32)track_ID;
constunsignedint(32)reserved=0;
unsignedint(64)duration;
}
else
{//version==0
unsignedint(32)creation_time;
unsignedint(32)modification_time;
unsignedint(32)track_ID;
constunsignedint(32)reserved=0;
unsignedint(32)duration;
}
constunsignedint(32)[2]reserved=0;
templateint(16)layer=0;
templateint(16)alternate_group=0;
templateint(16)volume={iftrack_is_audio0x0100else0};
constunsignedint(16)reserved=0;
templateint(32)[9]matrix={0x00010000,0,0,0,0x00010000,0,0,0,0x40000000};
//unitymatrix
unsignedint(32)width;
unsignedint(32)height;
}
类似我们moov中的mvhdbox,但tkhd仅仅描述的单一Track的特性。
上图是实际媒体中的tkhd的数据:
0x5c是tkhdbox长度,0x746b6864是“tkhd”的ASCII码。
0x0000000f是使用了Fullbox中的flag位(Fullbox8bitsversion+24bitsflag,详见我第一篇日志),这里flag=0xf,即1111b。
这4位从低到高分别代表:
Track_enabled:Indicatesthatthetrackisenabled.若此位为0,则该track内容无需播放(比如我们用一些非线编软件<如SonyVegas>做视频剪辑时,有些Track仅为我们参考与模仿用,在输出时将该Track关掉)。
Track_in_movie:Indicatesthatthetrackisusedinthepresentation.
Track_in_preview:Indicatesthatthetrackisusedwhenpreviewingthepresentation.
Track_in_poster:Indicatesthatthetrackisusedinmovie'sposter.
/*-------------------------------------------------------------------------------------------------------*/
important:我们知道,MP4文件格式是ISO-14496-12基础文件格式的衍生品,14496-14中对-12协议进行了扩充与进一步定义。
重要的是该“14496-12基础文件格式”协议如果认祖归宗,我们发现这种文件格式最初是由Apple公司的QuickTime媒体格式发展而来的。
即,mov格式发展出了“ISO14496-12协议”,再由该协议衍生出了mp4,f4v,ismv,3gp等我们常见的媒体封装格式。
因此上述标志位的poster位,在14496-12中并没有见到描述,而在Apple的协议中却看到了准确定义。
详见
/*-------------------------------------------------------------------------------------------------------*/
两个0xc5268eb6是track的创建时间与最后修改时间;
紧随其后的0x00000002,代表trackID=2,TrackID是非0的,唯一的,不可重复使用的标识track的方式;
后面32bit全0是保留位;
0x0009d97c是本track的时长,需要配合mvhdbox中的timescale计算实际的持续时间。
后续一些写死的字段不再分析,有些与mvhd重复,可以参见之前的文章。我们看两个关键字段:
layer,类似photoshop中图层的概念,数值小的在播放时更贴近用户(上层图层)。
alternate_group,track的备用分组ID,当该值为0时,意味着本track内容无备份;否则本track会可能会有零到多个备份track。当播放时相同groupID的track只选择一个进行播放。
相关文章推荐
- MP4文件格式详解——结构概述
- MP4文件格式详解
- MP4文件格式详解——元数据moov(一)mvhd box
- MP4文件格式详解——元数据moov(二)tkhd box(转)
- MP4文件格式详解——元数据moov(二)tkhd box
- MP4文件格式详解——结构概述 (转)
- 嵌入式 MP4文件格式详解结构概述
- MP4文件格式详解——元数据moov(二)tkhd box
- MP4文件格式详解
- MP4文件格式详解——元数据moov(一)mvhd box
- MP4文件格式详解——元数据moov(三)tref box
- MP4文件格式详解
- 多媒体 MP4文件格式详解——文件类型ftyp
- MP4文件格式详解——元数据moov(三)tref box(转)
- MP4文件格式详解——元数据moov(二)tkhd box
- MP4文件格式详解——文件类型ftyp
- MP4文件格式详解
- 多媒体 MP4文件格式详解——元数据moov(一)mvhd box
- MP4文件格式详解——文件类型ftyp(转)
- MP4文件格式详解——结构概述