1.MP4解析工具
mediainfo
mp4box:http://download.tsi.telecom-paristech.fr/gpac/mp4box.js/filereader.html
对于Mp4来说,都是一个个box来去组织元素。比如竖着的box,就是一个个box,这里就是重点关注moov。mp4?件由box组成,每个box分为Header和Data。其中Header部分包含了box的类型和??,Data包含了?box或者数据,box可以嵌套?box。MP4?件的基本组成单元是box,也就是说MP4?件是由各种各样的box组成的,有parent box,还有children box。因此,这些boxes之间存在?定的层次关系,总结如下表所示,表中标记出了各个box必选或可选特性,√代表Box必选。
下图是?个典型mp4?件的基本结构:
Hexinator:
Mp4box和mediainfo对比。
这个trak,就是表示是多少路音频和视频。每一个AVstream都对应一个track。每个track,可能都有宽高信息,编译器信息,采样率,声道,time_base(time_scale)。
表示track width和heigth使用了4个字节。
视频和音频的时间刻度不一样。
音视频的handler也不一样。
比较重要的sample table。
一个MP4文件分为多个track,一个track分为多个chunk,一个chunk有多个sample。mp4数据索引和真正的数据分开区域存储。
先用数据索引找到moov,然后才能找到mdat。
下面的解释就是chunk1-84,都是一一对应1个sample,chunk85,一一对应2个sample,chunk86-88,一一对应一个sample,chunk89,一一对应2个sample,chunk90,一一对应一个sample。
可以根据sample size去读取每一帧数据的大小。
ftyp
File Type Box,?般在?件的开始位置,描述的?件的版本、兼容协议等。
moov
Movie Box,包含本?件中所有媒体数据的宏观描述信息以及每路媒体轨道的具体信息。?般位于放在?件末尾,但如果为了?持http边下载边播放则需要将moov提前。注意,当改变moov位置时,内部?些值需要重新计算。
mdat
Media Data Box,存放具体的媒体数据。
Moov Insider
mp4的媒体数据信息主要存放在Moov Box中,是我们需要分析的重点。moov的主要组成部分如下:
mvhd
Movie Header Box,记录整个媒体?件的描述信息,如创建时间、修改时间、时间度量标尺、可播放时?等。
下图示例中,可以获取?件信息如时?为 Duration: 5016 ms秒。
udta
User Data Box,?定义数据。
track
Track Box,记录媒体流信息,?件中可以存在?个或多个track,它们之间是相互独?的。
每个track包含以下?个组成部分:
tkhd
Track Header Box,包含关于媒体流的头信息。下图示例中,可以看到流信息如视频流宽度800,?度1920。
?频的tkhd,则?如duration、volume等。
mdia
Media Box,这是?个包含track媒体数据信息的container box。?box包括:
mdhd:Media Header Box,存放视频流创建时间,?度等信息。
hdlr:Handler Reference Box,媒体的播放过程信息。
minf:Media Information Box,解释track媒体数据的handler-specific信息。minf同样是个containerbox,其内部需要关注的内容是stbl,这也是moov中最复杂的部分。stbl包含了媒体流每?个sample在?件中的offset,pts,duration等信息。想要播放?个mp4?件,必须根据stbl正确找到每个sample并送给解码器。
mdia展开如下图所示:
mdhd
Media Header Box,存放视频流创建时间,?度等信息。视频的mdhd,Time scale,Duration等信息。
?频的mdhd,也类似视频,但要注意Time scale,我们在计算时间戳的时候都要使?该Time scale,对应我们流??的AVStream->time_base。
hdlr
Handler Reference Box,媒体的播放过程信息。视频的hdlr,重点Component subtype: vide。
?频的hdlr,Component subtype: soun,如果我们多个?轨的时候,Component name:粤语。
我们分析的?件另?路?轨,根据不同的名字来进行区别。
minf
minf:Media Information Box,解释track媒体数据的handler-specific信息。minf同样是个containerbox,其内部需要关注的内容是stbl,这也是moov中最复杂的部分。stbl包含了媒体流每?个sample在?件中的offset,pts,duration等信息。想要播放?个mp4?件,必须根据stbl正确找到每个sample并送给解码器。
?且需要注意的是,minf??的?容器,?频和视频轨是有区别的,?如视频轨:vmhd, ?频轨则为:smhd
vmhd
smhd
Stbl Insider
Sample Table Box,上?提到mdia中最主要的部分是存放?件中每个sample信息的stbl。在解析stbl前,我们需要区分chunk和sample这两个概念。
在mp4?件中,sample是?个媒体流的基本单元,例如视频流的?个sample代表实际的nal数据。chunk是数据存储的基本单位,它是?系列sample数据的集合,?个chunk中可以包含?个或多的sample。
stbl?来描述每个sample的信息,包含以下?个主要的?box:
stsd
Sample Description Box,存放解码必须的描述信息。下图示例中,对于h264的视频流,其具体类型为 avc1 ,extensions中其中存放有sps,pps等解码必要信息。
视频的stsd
??包含了avc1,avc1???包含了avcC和pasp。
avc1:包含了视频Width、Height。
avcC:包含了视频编码器相关的信息,包括sps、pps等信息。
?频的stsd
用Hexinator分析,包含了音频相关的信息,比如采样率,通道数。
stts
Time-to-Sample Box,定义每个sample时?。Time-To-Sample的table entry布局如下:
stts table entry布局
sample count:sample个数。
sample duration:sample持续时间。
持续时间相同的连续sample可以放到?个entry?达到节省空间的?的。这?先给出来的是视频的stts,Number of entries,这个参数需要注意并不是sample的个数,sample的实际数量需要将每个entry的sample count进?累加才是真正的sample个数。
下图示例中,第1个sample时间为3720,单位?mdhd的time scale进?换算,?如视频的是90000,此时换算成秒为3720/90000 = 0.0413333333333333秒。
再给出个?频的stts,只是mdhd的time scale的差别,之前我们看到?频为44100,则计算第?个sample的时间。1024/44100=0.0232199546485261秒。
stss
Sync Sample Box,同步sample表,存放关键帧列表,关键帧是为了?持随机访问。
stss的table entry布局如下:
stss table entry布局
下图示例中,该视频track有3个关键帧:
stsc
Sample-To-Chunk Box,sample-chunk映射表。
上?提到mp4通常把sample封装到chunk中,?个chunk可能会包含?个或者?个sample。Sample-To-Chunk Atom的table entry布局如下图所示:
First chunk:使?该表项的第?个chunk序号
Samples per chunk:使?该表项的chunk中包含有?个sample
Sample description ID:使?该表项的chunk参考的stsd表项序号
下图示例中,可以看到该视频track?共有1个stsc表项,chunk序列1-x,每个chunk包含?个sample。这?则说明每个chunk??只有?个sample(?个chunk是可以有多个sample)。
stsz
Sample Size Box,指定了每个sample的size。Sample Size Atom包含两sample总数和?张包含了每个sample size的表。
sample size 表的entry布局如下图:
下图示例中,该视频流?共有110个sample,第1个sample??为42072字节,第2个sample??为7354个字节。
stco
Chunk Offset Box,指定了每个chunk在?件中的位置,这个表是确定每个sample在?件中位置的关键。该表包含了chunk个数和?个包含每个chunk在?件中偏移位置的表。每个表项的内存布局如下:
需要注意,这?stco只是指定的每个chunk在?件中的偏移位置,并没有给出每个sample在?件中的偏移。想要获得每个sample的偏移位置,需要结合 Sample Size box(stsz)和Sample-To-Chunk(stsc) 计算后取得。
下图示例中,该视频流第1个chunk在?件中的偏移为4750,?这?是每个chunk只有?个sample,此时第?个sample的起始位置就为4750->0x1D78,数据??则参照stsz,第?个sample size为172818。
?如偏移位置,7544->0x1D78。
如何计算sample偏移位置
上?提到通过stco并不能直接获取某个sample的偏移位置,下?举例说明如何获取某?个pts对应的sample在?件中的位置。
?体需要以下步骤:
(1)将pts转换到媒体对应的时间坐标系。
(2)根据stts((decoding) time-to-sample)计算某个pts对应的sample序号。
(3)根据stsc(sample-to-chunk)计算sample序号存放在哪个chunk中。
(4)根据stco(chunk offset)获取对应chunk在?件中的偏移位置。
(5)根据stsz获取sample在chunk内的偏移位置并加上第4步获取的偏移,计算出sample在?件中的偏移。
例如,想要获取3.64秒视频sample数据在?件中的位置。
(1)根据time scale参数,将3.64秒转换为视频时间轴对应的3640000 (假如时间刻度不为毫秒)。
视频轨:time scale为90000,转成对应的时间戳为3.64秒*90000。
(2)遍历累加下表所示stts所有项?,计算得到3640000位于第110个sample = 327600。
(3)计算出多个sample_deltas叠加才到了327600, 我们这?姑且按3780作为平均值计算,实际是3720*1+3780*1+3690*1+3780*2 …… 这样?直叠加进?。327600/3780 =86.66666666666667,取整为86。
(4)查询下表所示stsc所有项?,计算得到第86个sample位于第86个chunk,并且在该chunk中位于第1个sample(因为我们的码流是每个chunk对应了?个sample)。
(5)查询下表所示stco所有项?,得到第86个chunk在?件中偏移位置为1004678。使?hexinator。
(6)查询下表所示stsz所有项?,得到第86个sample的size为20934。计算得到3.64秒视频sample数据在?件中。
offset:1004678+0 = 1004678
size:20934。
验证:?编辑器打开mp4?件,定位到?件偏移1004678位置。09分隔符,这?占?了6个字节, 再看真正的数据区域,前4字节也为 NALU的?度0x000051bc=20924。
总共占?的字节计算 4+2+4+20924 = 20934。
《整理mp4协议重点,将协议读薄》:
?个chunk含有多个sample的情景参考下?链接进?分析:
mp4?件格式重点解析:https://www.jianshu.com/p/44c9567d8fcb
本篇文章就分析到这里,非常详细的MP4分析,如果对你有用,可以关注,点赞,收藏,转发。
本文来自一场戏投稿,不代表胡巴网立场,如若转载,请注明出处:https://www.hu85.com/321643.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 xxxxx@qq.com 举报,一经查实,本站将立刻删除。