[时间:2016-06] [状态:Open]

学习多媒体容器格式的目的

主要是为了回答以下问题:

  1. 该容器中数据是如何组织的?
  2. 该容器包含哪些编码格式的数据?这些数据是如何存储的?
  3. 该容器包含哪些元数据信息?包含哪些节目信息?
  4. 对于支持多节目的容器格式,如何找到对应的音频流、视频流、字幕流?
  5. 如何确定该容器的节目播放时长?
  6. 如何从该容器中提取音频、视频、字幕数据,并交给解码器解码,有时间戳否?
  7. 该容器是否支持seek?有哪些辅助信息?
  8. 是否支持直接流化?
  9. 哪里可以找到该容器格式最标准的文档资料?
  10. 有哪些可用的工具,方便分析容器格式异常或者错误?

1. MP4文件内部结构

MP4文件是有多个box嵌套构成的,所有数据都必须保存在box中,而且必须包含一个File Type box。

box的定义

其基本存储结构box(或者atom),其定义如下:

==========
BoxHeader
----------
BoxData
==========

其中BoxHeader定义如下:

Field name Type Size(bits)
box size uint32 32
box type uint32 32
largesize uint64 0/64
usertype uint8[16] 0/128

其中box size为1时,表示largesize域存在,size为0时,表示该box持续到文件结尾;box长度是64位无符号整数。当box type是"uuid"时,usertype域存在,表示自定义的box。

在解析时,可以忽略所有无法识别的box。

还有一种FullBox,作为Box的扩展,仅在header中添加了以下两个字段:

Field name Type Size(bits)
boxHeader - -
version uint8 8
flag uint24 24

在解析时可以忽略所有无法识别的version。

MP4顶部视图

MP4文件的整体结构如下:

表1 MP4 file structure
ftyp
pdin
moov
-
-
-
-
moof
-
-
-
mfra
-
-
mdat
free
skip
-
meta
-
-
-
-
-
-
-
-
-
-
-
meco
-
styp
sidx
ssix
prft

Box是可以相互嵌套的。上面表格中加黑的box类型是比较常见的,需要重点关注下。这个表中也仅给出了box的第二层嵌套关系。更详细的建议参考标准文档的6.2节。

从表1中可以看出movie数据是存储在mdat box中,但是如何解析这个box需要参考moov box。

接下来的部分也主要是与moov box解析有关。

2. Movie Structure('moov' box)

Movie Box在mp4文件中有且仅有一个。

Movie Header Box

Movie Header Box包含在Movie Structure Box中,通常包含媒体无关的信息,比如说播放时长、创建时间等。它是FullBox("mvhd")

其结构定义如下:

Field name Type Size(bits)
FullBoxHeader - -
creation time uint32/uint64 32/64
modify time uint32/uint64 32/64
timescale uint32 32
duration uint32/uint64 32/64
rate uint32 32
volume uint16 16
reserved uint8 80
matrix uint32[9] 9*32
pre_defined uint32[6] 6*32
next_track_ID uint32 32

对于version为1时,上面表格中选择数据类型为uint64,对于version为0时,选择类型为uint32。

这里解释下,timescale表示单位时间内的精度,即1秒内经过的时间单位计数;举个例子,正常的时间系统里以毫秒为单位,timescale就是1000。

duration中记录的是最长的track的播放长度。rate是16.16的格式,表示优先选择的播放速度,比如ox00010000表示1.0的播放速度。volume是浮点数的8.8的格式,表示优先选择的播放音量,0x0100表示1.0的音量大小。next_track_ID主要用于添加新的track,通常会大约当前文件最大track-ID。

Track Structure('trak' box)

一个mp4文件至少包含一个media trak box,不同的Track box是相互独立的。每个track box都携带独立的时域空域信息,同时包含相关的media box。track box有两种:media track和hint track,前者用于保存media相关信息,后者包含用于流媒体的打包信息。

track box包含的sub-box如下:

'trak' box
tkhd
tref
trgr
edts
---
meta
mdia
---
---
---
---
---

.1 track header box('tkhd')

这里边有一个字段,track_ID,用于唯一的表示当前track。

另一个字段,duration,用于记录当前track的播放长度。

.2 track media box('mdia')

track media box包含用于声明当前track信息的所有对象。以下sub-box需要关注:

  • handler box('hdlr')

    可获取track类型信息,主要是有字段handler_type(uint32_t)区分,具体含义如下:

    • 'vide' Video track
    • 'soun' Audio track
    • 'hint' Hint track

.3 media infomation box ('minf')

先看看media infomation box的构成,如下表:

minf
vmhd
smhd
hmhd
sthd
nmhd
dinf
---
stbl
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---

'minf' box中的header box是根据'hdlr' box中媒体类型一致的,只能出现一个。

.4 Sample Tables('stbl')

可以说stbl box是mp4中最复杂,包含媒体信息最多的box。主要包含时间和media samples的数据映射表,使用这部分数据可以按照时间检索sample的位置、类型、大小、实际偏移位置。

  • sample description box ('stsd')

    主要描述当前track有关的编码信息,以及用于初始化解码的附加信息。
  • Time to Sample box('stts' 'ctts')

    比较常见的'stts' box,decoding time to sample,通过这个box可以实现时间到sample number的映射。
  • sync sample box('stss')

    这个box提供了可以用于同步的sample索引号,并严格按照sample number递增顺序排列。如果不存在这个box,表示所有sample都是可以用于同步。对视频而言,sync sample通常指的关键帧。
  • sample size box('stsz' 'stz2')

    这个box记录每个sample的大小。'stsz' box存储格式如下:
Filed name type Size(bits)
FullBox Header --- ---
sample_size uint32 32
sample_count uint32 32
entry_size uint32[] varies

sample_size中表示sample长度,如果是0表示每个sample长度不定,会记录在entry_size中;否则每个sample长度一样,并且entry_size域不存在。

'stz2' box中的entry_size是compact的,长度由特定字段指定。

  • sample to chunk box('stsc')

    'stsc' box中记录了每个chunk中包含多少sample,其结构定义如下:
Filed name type Size(bits)
FullBox Header --- ---
entry_cout uint32 32
chunk_entry uint32[3] varies

chunk_entry包含三个字段:

first_chunk: uint32

samples_per_chunk: uint32

sample_description_index: uint32

每个entry表示从first_chunk开始的每个chunk都包含samples_per_chunk个samples,这些sample都可以用使用sample_description_index信息解码。

通过这个box,可以构建出当前track的chunk结构,及其包含的sample。

  • chunk offset box('stco' 'co64')

    这个box记录了chunk对应的offset,只是包含字段一个是32为('stco'),一个是64位('co64')。

    chunk offset box中记录都是相对文件的偏移量,可以直接通过这些信息读取。

Track Structure小结

由于'mdat' box中的多媒体数据是没有结构的,只能参考moov的trak box解析。反过头来。我们看一下针对单个track中的media信息存储应该是下面的结构:

|chunk #0| chunk#1| ... | chunk #n|

每个chunk的构成是下面的结构:

|sample #0|sample #1| ... | sample #n|

从trak box中的minf中可以看出,每个chunk的长度不定,其所包含的sample数目不同,每个sample的长度也不完全相同。

3. mp4中的节目信息有哪些? 如何获取?

每个'trak' box表示一个media,其类型记录在stsd中,对于视频,其中包括我们最关心的宽高信息、编码器,保存在VisualSampleEntry;对于音频,其中也包括采样率、声道数、编码方式等,这些信息保存在AudioSampleEntry或AudioSampleEntryV1中。

对于单节目的mp4文件,不需要选择流。从标准上来看'tkhd'中有一个字段alternate_group,估计这个是表示选择节目的一个标志。

4. 如何实现seek?

第2部分介绍moov的结构时,里面有很多信息是跟seek相关的,比如time-sample映射。那么为了实现seek到指定时间,在mp4中需要做如下工作:

  1. 使用timescale将目标时间标准化。
  2. 通过time-to-sample box找到指定track的给定时间之前的第一个sample number。
  3. 通过sync sample table查询sample number之前的第一个sync sample。
  4. 通过sample-to-chunk table查找到对应的chunk number。
  5. 通过chunk offset box查找到对应chunk在文件中的起始偏移量。
  6. 最后使用sample-to-chunk box和sample size box的信息计算出该chunk中需要读取的sample数据,即完成seek。

当然标准中还有关于edit list box的使用,这里多数情况下不涉及,所以不做额外介绍。

5. 其他问题

这里解释下上面没有涉及的问题。

该容器包含哪些元数据信息?包含哪些节目信息?

MP4中包含'meta' box,从中可以解析出需要的metadata,具体建议参考标准。

是否支持直接流化?

mp4支持流化,直接通过特定协议及hint track完成。后续会有介绍。

哪里可以找到该容器格式最标准的文档资料?

标准文档的全称是"ISO/IEC 14496-12:ISO base media file format"(c068960_ISO_IEC_14496-12_2015)。

我是从ISO.org的以下地址下载:http://www.iso.org/iso/home/store/catalogue_ics/catalogue_detail_ics.htm?csnumber=61988。

有哪些可用的工具,方便分析容器格式异常或者错误?

比较经典的工具是mp4info或者elecard streameye,但是如果对mp4熟悉了的话,直接二进制查看还是不错的。

总结

本文主要是关于mp4文件解析的介绍,是我第一次深入的了解mp4文件格式,虽然可用的测试文件不是很多,但是足够理解文件结构了。

本文内容主要作为我个人后续分析mp4文件的参考。

参考资料

  1. "ISO/IEC 14496-12:ISO base media file format"(c068960_ISO_IEC_14496-12_2015)。
  2. MP4文件格式解析
  3. http://blog.chinaunix.net/uid-20758197-id-5056943.html

多媒体文件格式之MP4的更多相关文章

  1. 多媒体文件格式(一):MP4 格式

    在互联网常见的格式中,跨平台最好的应该就属MP4文件了.因为MP4文件既可以在PC平台的Flashplayer中播放,又可以在移动平台的Android.iOS等平台中进行播放,而且使用系统默认的播放器 ...

  2. 多媒体文件格式分析 MP3文件结构及编解码流程

    多媒体文件格式分析 http://blog.csdn.net/taniya001/article/details/7962864 多媒体文件格式分析 MP3文件结构及编解码流程 http://www. ...

  3. 多媒体文件格式之FLV

    [时间:2016-07] [状态:Open] FLV是一个相对简单的多媒体格式,仅支持单节目,也就是说每个FLV只能至多一个音频.至多一个视频.FLV(Flash Video)是Adobe的一个免费开 ...

  4. 多媒体文件格式之MKV

    [时间:2016-07] [状态:Open] MKV是一种开源的多媒体封装格式,是Matroska中应用比较多的格式之一.常见的后缀格式是.mkv(视频,包括音频和字幕)..mka(纯音频)..mks ...

  5. 多媒体文件格式(二):FLV 格式

    在网络的直播与点播场景中,FLV也是一种常见的格式,FLV是Adobe发布的一种可以作为直播也可以作为点播的封装格式,其封装格式非常简单,均以FLVTAG的形式存在,并且每一个TAG都是独立存在的,接 ...

  6. 多媒体文件格式之AVI

    [时间:2016-07] [状态:Open] AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchange File Format的缩写)文件 ...

  7. 多媒体文件格式之RMVB

    [时间:2016-07] [状态:Open] RM/RMVB是Real公司私有的封装格式,常见的后缀形式是rm.ra.rmvb. 通常封装的都是real转悠的编码格式,比如音频中的sipro.cook ...

  8. 多媒体文件格式之ASF

    [时间:2016-06] [状态:Open] ASF,全称Advanced Systems Format,是由微软提出的开放封装格式标准.ASF是微软公司Windows Media的核心.这是一种包含 ...

  9. 多媒体文件格式(三):M3U8 格式

    一.M3U8 格式标准介绍 M3U8文件是指UTF-8编码格式的M3U文件.M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播 ...

随机推荐

  1. HDUOJ-------单词数

    单词数 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  2. C语言中的随意跳转

    C语言中有一个很不常用的头文件:setjmp.h. 这个头文件是C语言底层实现的,不像math.h里面的函数都是纯C语言实现的. setjmp.h包含两个函数: longjmp 跳转到某个位置 set ...

  3. 搭建简单的网络部分(OC)框架

    准备工作 1.文件目录结构示图(按照MVC分层) 文件目录结构图/自定义Cell Controller: CYXOneViewController Model: CYXMenu View: CYXCe ...

  4. 获取android手机基本信息

    /** * 获取android当前可用内存大小 */ private String getAvailMemory() {// 获取android当前可用内存大小 ActivityManager am  ...

  5. ASP.NET MVC3 Model验证总结 @Html.ValidationSummary(true)

    http://www.wyjexplorer.cn/Post/2012/8/3/model-validation-in-aspnet-mvc3 ASP.NET MVC3中的Model是自验证的,这是通 ...

  6. docker学习笔记 --- centos install

    Docker简介: Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发 ...

  7. 验证时出错。HRESULT = '8000000A'

    这本来是在VS2005下创建的一下项目,后来改用VS2010的开发环境,.NET Framework的版本号还是使用2.0, 但每次生成之后都会在解决方式的同级文件夹下产生一个名称乱码的文件夹, 攻克 ...

  8. SharePoint 关于拓扑错误的解决方案

    Issue Topology报错信息:SharePoint Web Services Round Robin Service Load Balancer Event: EndpointFailure. ...

  9. HttpWebRequest、HttpWebResponse、HttpClient、WebClient等http网络访问类的使用示例汇总

    工作中长期需要用到通过HTTP调用API以及文件上传下载,积累了不少经验,现在将各种不同方式进行一个汇总. 首先是HttpWebRequest: /// <summary> /// 向服务 ...

  10. Android_Bitmap_图片的二次采样并生成缩略图

    1.Bitmap概述 Android系统支持几种图片(.png (preferred), .jpg (acceptable), .gif (discouraged)), 其中Bitmap位图#ffff ...