mp4封装格式各box类型讲解及IBP帧计算
mp4封装格式各box类型讲解及IBP帧计算
- mp4封装格式各box类型讲解及IBP帧计算
- box
- ftyp box
- moov box
- mvhd box (Movie Header Box)
- trak box (Track Box)
- tkhd(track header box)
- mdia (Track Media Structure)
- mdhd (Media Header Box)
- PTS和DTS的计算
- I P B 帧的概念
- stts(Decoding Time to Sample Box)
- ctts(Composition Time to Sample Box)
- timescale
- stss (Sync Sample Box)
- stsz (Sample Size Boxes):
- stsc (Sample To Chunk Box):
- stco (Chunk Offset Box)
- mdat box
MP4文件封装格式,对应的标准为ISO/IEC 14496-12,即信息技术 视听对象编码的第12部分 ISO 基本媒体文件格式(Information technology Coding of audio-visual objects Part 12: ISO base media file format)
box
如果从整体上看,mp4所有的数据全部存放在 一个叫box
的结构中。
box,顾名思义,可以简单的理解为一个箱子
里面可以放任何符合大小的东西,也可以继续放箱子,箱子里面再放东西,这种箱子里面仍然放箱子的箱子称为容器箱子(container box) 你可以想象你要搬家,把你的家具全部放在一个个的箱子里面,然后一个大箱子把小箱子一个个再装箱。MP4中的 moov box 就是一种容器箱子。
box的字节序为网络字节序,也就是大端字节序(Big-Endian)Box由header和body组成,其中header统一指明box的大小和类型,body根据类型有不同的意义和作用。
box size 有三种可能:
1、通常的box开头的4个字节(32位)为box size,该大小包括box header和box body整个box的大小,这样我们就可以在文件中定位各个box。
2、如果 box size为1,则表示这个box的大小为large size(“mdat”类型)。
3、如果box size为0,表示该box为文件的最后一个box,文件结尾即为该box结尾。(同样只存在于“mdat”类型的box中。)
size后面紧跟的32位为box type,一般是4个字符,如“ftyp”、“moov”等,这些box type都是已经预定义好的,分别表示固定的意义。如果是“uuid”,表示该box为用户扩展类型,如果box type是未定义的,应该将其忽略。
14496-12标准中box的都有这些类型,这张表,也能从整体上了解完各类型box的说明:
MP4文件分析工具。
两个在线的MP4 分析工具,下面内容全部以此工具来分析一份demo
online-mp4-parser
online-mp4-parser-2
可以看到这份标准的mp4视频根路径上有四个box -- ftyp
、moov
、uuid
、mdat
ftyp 指定了文件类型
moov 保存了音视频数据的时空间信息
mdat 存放音视频数据
下面依赖工具简单依次分析一份普通mp4文件
ftyp box
该box有且只有1个,并且只能被包含在文件层,而不能被其他box包含。该box应该被放在文件的最开始,指示该MP4文件应用的相关信息。
“ftyp” body依次包括1个32位的major brand(4个字符),1个32位的minor version(整数)和1个以32位(4个字符)为单位元素的数组compatible brands。这些都是用来指示文件应用级别的信息。
moov box
moov box 是一个 container box 该box包含了文件媒体的元数据信息,具体内容信息由子box诠释。同File Type Box一样,该box有且只有一个,且只被包含在文件层。一般情况下,“moov”会紧随“ftyp”出现。
可以看到这个demo 中有 mvhd、trak、udta 三种 box 一般情况下 “moov”中会包含1个“mvhd”和若干个“trak”。其中“mvhd”为header box,一般作为“moov”的第一个子box出现。“trak”包含了一条音、视频轨/流/track的相关信息,也是一个container box。
该box是解析MP4文件里面最重要的一个box,它包含了音视频数据的编码格式、音视频数据样本,chunks的大小、存储位置也即偏移offset、时间戳单位、DTS,CTS(PTS),解码时间、显示时间等等...
moov box中记录的每帧音视频数据位置信息,实际上都在mdat box中,通过解析moov box来获取到每帧音视频数据具体位置后,使得播放器能方便的拖拉进度条。
mvhd box (Movie Header Box)
mvhd 描述了与具体音频或视频流无关的文件整体信息,其中的duration/timescale的值即为单位为秒的媒体时长。
trak box (Track Box)
trak也是一个container box,其子box包含了该track的媒体数据引用和描述。一个MP4文件中的媒体可以包含多个track,且至少有一个track,这些track之间彼此独立,有自己的时间和空间信息。“trak”必须包含一个“tkhd”和一个“mdia”,此外还有很多可选的box(略)。
tkhd(track header box)
tkhd 描述的该track的,如果是视频会有宽、高信息、 还有文件创建时间、修改时间等。
mdia (Track Media Structure)
mdia box 描述了这条音视频轨/流(trak)的媒体数据样本的主要信息,对播放器来说是一个很重要的box..
mdhd (Media Header Box)
当前音/视频轨/流(trak)的总体信息, 该box中有duration字段和timescale字段,duration/timescale的值即为当前流的时长。
hdlr box用来指定该流的类型
stsd box的子box用于保存该流的编码类型
avcC box指定了该流的编码类型为H264,储了解码所需的SPS、PPS信息。
stsc stsz stco三个box用于保存每帧视频或音频数据在文件中的保存位置。
stts stss ctts三个box用于保存媒体数据和时间戳的对应关系。
在同级的stbl的样本表box里面可以查到对应的样本 描述信息(stsd),时序信息(stts),样本的大小信息(stsz),样本到chunk的映射信息(stsc),chunk的位置信息(stco)等等
下面计算下PTS,来了解stbl box..
PTS和DTS的计算
I P B 帧的概念
在音视频中,为了提高压缩效率,会将每帧画面压缩为不同类型的视频帧数据。
I帧表示关键帧,包含有一帧画面的完整信息,解码时只需要本帧数据就可以解码出完整的一帧画面。
P帧表示前向参考帧,它保存了本帧与上一帧的差异信息,它不能单独解码,需要根据上一帧的画面加上本帧保存的差值来获取本帧的完整画面。
B帧为双向参考帧,它解码时需要依赖它之前和之后的帧来获取最终的画面
因为B帧需要依赖它后面的帧来进行解码,所以它的解码顺序就必然和显示顺序不能保持一致,这时就需要解码时间戳(DTS)和显示时间戳(PTS)来共同决定一帧视频数据何时解码,然后何时显示了。
举个例子
一小段视频帧序列如下 :
type : I --- B --- B --- P --- B --- B --- P
PTS : 0.33 0.67 1.00 1.33 1.67 2.00 2.33
DTS : 0.00 0.67 1.00 0.33 1.67 2.00 1.33
PTS >= DTS
根据mp4 stts和ctts 可以得到DTS和PTS
stts(Decoding Time to Sample Box)
stts 可以计算出每个sample的dts,其中sample_delta为该sample的dts相对于上一个smaple的差值,
那么此样本数据的dts为 :
0 1000 2000 3000 4000 ···
ctts(Composition Time to Sample Box)
Composition Time 构成时间目前我直接理解的PTS。。
ctts 有每个sample的构成时间(Composition Time)和解码时间(DTS)之间的差值(CTTS)即图中的composition_offset。
如果不存在ctts,则代表该流不存在B帧,那么PTS就直接等于DTS。
timescale
最后就是关于单位,你可以看到图中样本的单位都是以1000为单位浮动,实际上真实DTS和PTS时间是需要除以mdia/mdhd中的timescale。这里是30000。
有了这些,我们就可以在ctts里面计算出pts了 :
else if (box_type_equa(uint32_to_str(bh.type, sbuffer), "ctts")) {
uint32_t version = 0;
read_net_bytes_to_host_uint32(&box[8], &version);
if(version != 0) {
LOG_E("ctts unsupport version :%d ", version)
return;
}
uint32_t entry_cnt = 0;
read_net_bytes_to_host_uint32(&box[12], &entry_cnt);
char buf[128] = {0};
tree_childs_insert_with_val(tree, "version", uint32_to_ascii(version, buf));
tree_childs_insert_with_val(tree, "entry_cnt", uint32_to_ascii(entry_cnt, buf));
uint32_t i = 0, j = 0, num = 0, pos = 16;
for (i = 0; i < entry_cnt; i++) {
uint32_t sample_cnt;
read_net_bytes_to_host_uint32(&box[pos], &sample_cnt);
pos += 4;
uint32_t sample_offset;
read_net_bytes_to_host_uint32(&box[pos], &sample_offset);
pos += 4;
for (j = 0; j < sample_cnt; j++) {
PushBack_Array(pts_array, At_Array(dts_array, num++) + sample_offset);
float dt, pt = 0.0;
printf("dts : %9.3f ms | pts : %9.3f ms | \n", At_Array(dts_array, num - 1) / (mdhd_time_scale * 1.0), At_Array(pts_array, num - 1) / (mdhd_time_scale * 1.0));
}
stss (Sync Sample Box)
stss 里面存放了关键帧的序号(I帧),跳转时,需要从关键帧开始解码,否则会花屏。
stsz (Sample Size Boxes):
顾名思义,样本大小.
stsc (Sample To Chunk Box):
媒体数据的样本是被打包进chunks(块)的,chunks和样本(samples)的大小不固定,该box用于说明chunks关联样本的信息。
first_chunk 该入口第一个chunks的索引(index).
samples_per_chunk 样本数量/chunks.
stco (Chunk Offset Box)
描述每个chunks相对文件的偏移量。
如图 第一个chunks即前10个样本(此例), samples.1起始地址为 423257, samples.1的地址则为 423257 + 140798 = 564055, 依此类推...
有了这些即可计算出音视频的时间和空间信息了
mdat box
Meida Data Box 媒体数据box 位于顶层,定义是一个字节数组,用来存储媒体数据。该box数量可以为0个,也可以有多个(当媒体数据全部为外部文件引用时),数据直接跟在box type字段后面,具体数据结构的意义需要参考metadata(主要在sample table中描述)。
参考 : ISO/IEC 14496-12:2015规范
mp4封装格式各box类型讲解及IBP帧计算的更多相关文章
- ISO/IEC 15444-12 MP4 封装格式标准摘录 5
目录 Segments Segment Type Box Segment Index Box Subsegment Index Box Producer Reference Time Box Supp ...
- ISO/IEC 15444-12 MP4 封装格式标准摘录 4
目录 Movie Fragments Movie Extends Box Movie Extends Header Box Track Extends Box Movie Fragment Box M ...
- ISO/IEC 15444-12 MP4 封装格式标准摘录 3
目录 Track Data Layout Structures Data Information Box Data Reference Box Sample Size Boxes Compact Sa ...
- ISO/IEC 15444-12 MP4 封装格式标准摘录 2
目录 Track Media Structure Media Box Media Header Box Handler Reference Box Media Information Box Medi ...
- H.264标准(一)mp4封装格式详解
在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...
- 最简单的基于FFmpeg的封装格式处理:视音频复用器(muxer)
===================================================== 最简单的基于FFmpeg的封装格式处理系列文章列表: 最简单的基于FFmpeg的封装格式处理 ...
- 多媒体封装格式详解---MP4
MP4文件格式详解——结构概述 http://blog.csdn.net/pirateleo/article/details/7061452 一.基本概念 1. 文件,由许多Box和FullBox组成 ...
- Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型
转自原文 Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型 播放mp4格式的时候提示 Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型 原因是在IIS中 ...
- FLV视频封装格式详解
FLV视频封装格式详解 分类: FFMpeg编解码 2012-04-04 21:13 1378人阅读 评论(2) 收藏 举报 flvheaderaudiovideocodecfile 目录(?)[-] ...
随机推荐
- react: typescript integrate withRouter
define interface: export interface INav { nav: string } export interface IModuleItem { state?: strin ...
- [wp]xctf newscenter
手工注入 查询所有数据库名称和表名 ' union select 1,table_schema,table_name from information_schema.tables# 发现就两个数据库i ...
- 如何使用Markdown 编写文档
Markdown 是一种轻量级标记语言,用来编写文本文档,一般后缀名为.md.该语言在 2004 由约翰·格鲁伯(John Gruber)创建. 由于Markdown 语法简单,易读易写,变得越来越通 ...
- java1-3总结 19201421-吴志越
关于最近几次作业,从C语言到Java的过渡,也就是从面向过程到面向对象的过渡.其中,一共有三次作业,前俩次可能更加偏向于过程的设计,利用C语言的想法就可以完成,但是,从需要使用类的开始,就逐渐向对象偏 ...
- 好程序员分享Web前端面试题汇总JS篇之跨域问题
为什么80%的码农都做不了架构师?>>> 好程序员分享Web前端面试题汇总JS篇之跨域问题,接着上一篇文章我们继续来探讨web前端面试必备面试题. 跨域解决方案 1. 通过jso ...
- 《树莓派学习指南(基于Linux)》——本章小结
本节书摘来自异步社区<树莓派学习指南(基于Linux)>一书中的第二章的本章小结,作者[英]Peter Membrey ,[澳]David Hows ,译者 张志博,孙峻文,更多章节内容可 ...
- 线程状态及各状态下与锁和CPU的关系
线程的状态 Thread.State枚举类型中定义了线程的六种状态:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING和TERMINATED. 线程在某一时刻只能拥有 ...
- 补题Codeforces 1102E. Monotonic Renumeration
这个题还是不太懂,下面附上的是大佬的题解(https://zhanghuimeng.github.io/post/codeforces-1102e-monotonic-renumeration/) E ...
- USACO Training Section 1.1 坏掉的项链Broken Necklace
题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 n=29 的二个例子: 第一和第二个珠子在图片中已经被作记号. 图片 A ...
- B - Housewife Wind POJ - 2763 树剖+边权转化成点权
B - Housewife Wind POJ - 2763 因为树剖+线段树只能解决点权问题,所以这种题目给了边权的一般要转化成点权. 知道这个以后这个题目就很简单了. 怎么转化呢,就把这个边权转化为 ...