1. 概览
常用的一些Box
mdhd 存放视频流创建时间,长度等信息
avc1 视频宽高、extionsion中有sps、pps信息(关于avcC和esds)
esds:aac音频头信息、视频vos、vo头信息(参考)
stts:定义每个sample时长(+参考)
stsc:sample-chunk映射表
stsz:指定了每个sample的size
stco、co64:Chunk位置偏移表,指定了每个chunk在文件中的位置(参考)
elst:使某个track的时间戳产生偏移。较少见,参考
mp4a:另有mp4v,不同的mp4分支。
主流编码器的比较
以下是一个典型的mp4格式的文件。后面将逐行分析格式规范。
2. 详解
下面的内容翻译自 ISO_IEC_14496-12。
2.1 Box的概念
Box以一个header开头,它提供了 size 和 type。ftpy Box Header 支持压缩或扩展大小(32或64位,可变)以及压缩、扩展类型(32位或完整的通用唯一标识符,即UUID)。标准的Box都使用紧凑型(32位),大多数Box都使用紧凑型(32位)大小。通常只有媒体数据框需要64位大小。
大小是整个Box的大小(包括size、type、header)、字段和所有包含的框。这有助于文件的一般解析。
语法:
aligned(8) class Box (unsigned int(32) boxtype, optional unsigned int(8)[16] extended_type) { unsigned int(32) size; unsigned int(32) type = boxtype; if (size==1) { unsigned int(64) largesize; } else if (size==0) { // box extends to end of file } if (boxtype==‘uuid’) { unsigned int(8)[16] usertype = extended_type; } }
size:整型,为整个Box的大小(包含子Box),如果size是1,则使用largesize表示更大的范围(8字节),如果size是0则此Box作为文件中最后一个Box,范围直至文件末尾(only used for a Media Data Box)。
type:用来标识Box的类型,标准Box使用四个可打印字节表示,以便于识别。用户扩展使用扩展类型,在本例中,类型字段设置为“UUID”:
aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v, bit(24) f)
extends Box(boxtype) { unsigned int(8) version = v; bit(24) flags = f; }
应忽略和跳过未识别类型的Box。许多对象还包含 version number 和 flag 字段。
这两个字段的语义是:version是一个整数,指定此格式的框的版本。flag 是 flags 的映射。应忽略和跳过未识别版本的Box。
2.2 ftyp
全称File Type Box,该Box必须位于文件开头(如果有的话)。为了兼容早期的规范,没有写入ftyp Box的文件应该被视为包含 Major_brand='mp41', minor_version=0 和单向兼容版本 mp41。
按照本规范的这一部分构建的媒体文件可能与多个详细 spec 兼容,因此不可能总是针对文件使用单一的 type 或 brand。这意味着文件扩展名和多用途Internet邮件扩展名(MIME)type 的实用性有所降低。
此 Box 必须尽早放置在文件中(例如,在任何强制性签名之后,但在任何重要的可变大小的Box(如Movie Box、Media Box 或 Free Space)之前。它标识哪种 spec 是解析该文件的“最佳方式”,以及该 spec 的次要版本;以及该文件所遵循的一组其他 spec。实现此格式的读取器应尝试读取标记为与读取器实现的任何规范兼容的文件。因此,规范中的任何不兼容更改都应注册新的 “brand” 标识符,以标识符合新的 spec 的文件。(每种视频文件的Box都有自己的规范、版本号,要在ftyp里面标识才能被解复用器正确解读)。
次版本仅供参考。它不适用于兼容品牌,也不能用于确定文件是否符合标准。它可以更精确地识别主要规范,以便检查、调试或改进解码。文件通常在外部标识(例如,使用文件扩展名或MIME类型),以标识“最佳方式”(主要brand),或作者认为能够提供最大兼容性的brand。(每个厂商有自己的brand-品牌,对于用户来说只有Major_brand才是有意义的,minor_version的意义不大)。
本规范本节未定义任何 brand。但是下文第6.3节中有关于符合整个文件的 brand 的 spec 规范,而不仅仅是本节。本规范中定义的所有文件格式 brand 均包含在附录E中,并概述了其所需的功能。
语法:
aligned(8) class FileTypeBox extends Box(‘ftyp’) { unsigned int(32) major_brand; unsigned int(32) minor_version; unsigned int(32) compatible_brands[]; // to end of the box }
此 Box 标识此文件符合的规范。每个 brand 都是一个可打印的四字符代码,在ISO注册,用于识别精确的spec。
major_brand:主要品牌–是品牌标识;
minor_brand:是主要品牌的次要版本的信息,整数;
compatible_brands:是一个列表,在Box的最后,是一个brand。
下面,可见前32字节(0X20)是该Box的全部信息:
注意:文件通常是自包含的,不引用其它文件中的媒体。
2.3 流媒体
当准备流式传输时,文件必须包含信息,以便在发送信息的过程中指导流式服务器。此外,如果将这些指令和媒体数据交错,以便在提供演示文稿时避免过度查找,这是很有帮助的。同样重要的是,原始媒体数据应完好无损地保留,以便文件可以被验证、重新编辑或以其他方式重新使用。最后,如果可以为多个协议准备一个单独的文件,那么这很有帮助,因此不同的服务器可以在不同的协议上使用它。
2.4 本地展示
“本地”查看演示文稿(即直接从文件中查看,而不是通过流式互连)是一个重要的应用场景;在分发演示文稿时(例如在CD或DVD ROM上)、在开发过程中以及在流式服务器上验证内容时使用。必须支持这种本地查看,并提供完全随机访问。如果演示文稿是在CD或DVD ROM上,交错(interleave)是很重要的,因为查找可能很慢。
2.5 流式传输
当服务器从文件操作以生成流时,生成的流必须符合所用协议的规范,并且不应在文件本身中包含文件格式信息的踪迹。服务器需要能够随机访问演示文稿。通过引用来自多个演示文稿中的相同媒体数据来重新使用服务器内容(例如,摘录-excerpts)是有用的;如果媒体数据可以在只读媒体(例如CD)上,并且在准备流式处理时不进行复制,而只是进行扩充,则它还可以帮助流式处理。
下图显示了为通过多路复用协议进行流式传输而准备的演示文稿,只需要一个提示轨迹( hint track):
注意:hint trak 也是一种 trak,记录前一个audio、video。
3. 设计原则
文件结构是面向对象的;文件可以很简单地分解为组成对象,对象的结构直接从它们的类型中推断出来。
媒体数据不受文件格式的“框架”约束;提供媒体数据单元大小、类型和位置的文件格式声明在物理上与媒体数据不相邻。这使得可以将媒体数据子集化,并在其自然状态下使用它,而不需要复制它来为帧留出空间。元数据用于通过引用而不是通过包含来描述媒体数据。
类似地,特定流协议的协议信息不受媒体数据的“框架”(framed)约束;协议头在物理上与媒体数据不相邻。相反,可以通过引用包含媒体数据。这使得在自然状态下表示媒体数据成为可能,而不倾向于任何一种协议。它还使得同一组媒体数据可以用于本地表示和多个协议。
协议信息的构建方式使得流媒体服务器只需要知道协议及其发送方式;协议信息抽象了媒体的知识,因此服务器在很大程度上是媒体类型不可知的。类似地,媒体数据以不知道协议的方式存储,使媒体工具不受协议影响。(总的来讲,也就是协议和数据分离)。
文件格式不要求单个演示文稿位于单个文件中。这将启用内容的 sub-setting 和 re-use。与 no-framing 方法相结合时,还可以将媒体数据包含在未按本规范格式化的文件中(例如,仅包含媒体数据而不包含声明性信息的“原始”文件,或已在媒体或计算机行业使用的文件格式)。(no framed -> non-framing)。
文件格式基于一组常见的设计和一组丰富的可能的结构和用法。相同的格式适用于所有用途;不需要翻译。但是,当以特定方式使用时(例如,用于本地呈现),文件可能需要以特定方式进行结构化以获得最佳使用方式(例如,数据的时间顺序)。本规范未定义规范性结构规则,除非使用限制性外形。(这里就讲的大概就是复用,解复用的概念)。
4.0 文件结构
演示文稿可能包含在多个文件中。一个文件包含整个演示文稿的元数据,并按照此规范进行格式化。此文件还可能包含所有媒体数据,因此演示文稿是自包含的。其他文件(如果使用)不需要格式化为本规范;它们用于包含媒体数据,也可能包含未使用的媒体数据或其他信息。本规范仅涉及表示文件的结构。媒体数据文件的格式仅受本规范的约束,因为媒体文件中的媒体数据必须能够通过此处定义的元数据进行描述。
这些其他文件可以是ISO文件、图像文件或其他格式。只有媒体数据本身,如JPEG 2000图像,存储在这些其他文件中;所有定时和帧(位置和大小)信息都在ISO基本媒体文件中,因此辅助文件基本上是自由格式的。
如果一个ISO文件包含提示磁道,则引用生成提示的媒体数据的媒体磁道应保留在该文件中,即使其中的数据不是由提示磁道直接引用的;删除所有提示磁道后,整个未提示的表示应保留在文件中。请注意,媒体磁道可能会引用外部文件以获取其媒体数据。
附件A提供了一个信息丰富的介绍,可能对初次阅读者有所帮助。
总之:大概只有在CD/DVD种才会用到外部数据。
4.1 对象结构
文件是按对象序列结构的;其中一些对象可能包含其他对象。文件中的对象序列应正好包含一个表示元数据包装器(电影盒)。它通常靠近文件的开头或结尾,以便于查找。在这个级别上找到的其他对象可能是文件类型框、可用空间框、电影片段、元数据或媒体数据框。
4.2 元数据和媒体数据
元数据包含在元数据包装器(电影盒)中;媒体数据包含在同一文件中、媒体数据框中或其他文件中。媒体数据由图像或音频数据组成;媒体数据对象或媒体数据文件可能包含其他未引用的信息。
4.3 track 标识符
ISO文件中使用的磁道标识符在该文件中是唯一的;任何两个磁道不得使用相同的标识符。
存储在电影标题框的next_track_ID中的next track identifier值通常包含一个大于文件中找到的最大track identifier值的值。这使得在大多数情况下都可以轻松生成轨迹标识符。但是,如果这个值等于1(32位无符号maxint),则需要进一步搜索未使用的磁道标识符。
4.4 元数据结构(对象)
a. Box
此处未定义的类型字段被保留。私有扩展应通过“uuid”类型实现。此外,在本规范的未来版本中,为了避免与使用此格式的早期预标准版本的现有内容发生冲突,以下类型不会也不会使用,或仅在其现有意义上使用:
clip, crgn, matt, kmat, pnot, ctab, load, imap;
这些轨迹参考类型(在轨迹参考框的参考类型中找到):tmcd, chap, sync, scpt, ssrc.
b. 数据类型和字段
在本规范的许多框中,有两种变体形式:版本0使用32位字段,版本1使用64位大小的相同字段。一般来说,如果可以使用版本0 的Box(32位字段大小),则应该使用;版本1 Box应仅在需要其允许的64位字段大小时使用。如果计数器的值都是大的,那么就不能将它们的值以最大值的形式存储。
为了方便创建内容,文件中存储了创建和修改时间。这些数字可以是32位或64位数字,从1904年1月1日午夜开始计算秒数,这是闰年计算的一个方便日期。在2040年之前,32位就足够了。这些时间应以协调世界时(UTC)表示,因此如果显示,可能需要调整到本地时间。
定点数是一个整数除以2的适当幂得到的有符号或无符号值。例如,一个30.2的定点数是由一个32位整数除以4形成的。
在使用此规范的规范中,Box 说明中显示为“模板”的字段是可选的。如果该字段在另一个规范中使用,则该使用必须与此处的定义一致,并且该规范必须定义该使用是可选的还是强制的。类似地,在本规范的早期版本中使用了标记为“预定义”的字段。对于这两种类型的字段,如果规范中没有使用此类字段,则应将其设置为指定的默认值。如果不使用该字段,则在复制框时必须不检查该字段,并且在读取时忽略该字段。
出现在标题中的矩阵值指定视频图像的显示转换。并非所有派生规范都使用矩阵;如果不使用,则应将其设置为单位矩阵。如果使用矩阵,则使用矩阵将点(p,q)转换为(p',q'),如下所示:
坐标{p,q}位于解压缩帧上,{p',q'}位于渲染输出。因此,例如,矩阵{2,0,0,0,2,0,0,0,1}正好使图像的像素维数加倍。矩阵变换后的坐标不是以任何方式规范化的,而是代表实际的样本位置。因此{x,y}可以被视为图像的平移向量。
坐标原点位于左上角,X值向右增加,Y值向下增加。{p,q}和{p',q'}分别作为相对于原始图像左上角的绝对像素位置(在缩放到由轨迹标头的宽度和高度确定的大小之后)和变换(渲染)表面。
每个音轨使用其指定的矩阵组成一个整体图像;然后根据MovieHeaderBox中电影级别的矩阵对其进行变换和组合。例如,是否将生成的图像“剪裁”以将没有显示的像素消除到窗口内的垂直矩形区域,这取决于应用程序。因此,例如,如果只显示一个视频轨迹,并且它具有{20,30}的平移,并且在MovieHeaderBox中有一个单位矩阵,则应用程序可以选择不显示图像和原点之间的空“L”形区域。
矩阵中的所有值存储为16.16个定点值,u、v和w除外,它们存储为2.30个定点值。
矩阵中的值按{a,b,u,c,d,v,x,y,w}顺序存储。
4.5 Box Order(P26)
下表提供了正常封装结构的总体视图。
该表显示了可能出现在最左边列的顶层的那些框;缩进用于显示可能的限制。因此,例如,在音轨盒(trak)中找到了音轨标题框(tkhd),而trak在电影盒(moov)中找到。并非所有的框都需要在所有文件中使用;强制框用星号(*)标记。请参阅各个方框的说明,了解如果不存在可选框,则必须假设的内容。
用户数据对象只能放在电影或音轨盒中,使用扩展类型的对象可以放在各种各样的容器中,而不仅仅是顶层。
为了提高文件的互操作性和实用性,对于文件盒的顺序,应遵循以下规则和指南:
1) 文件类型框“ftyp”应出现在任何可变长度框(如电影、可用空间、媒体数据)之前。如果需要,只有固定大小的框(如文件签名)可以放在它前面。
2) 强烈建议首先将所有标题框放在其容器中:这些框是电影标题、曲目标题、媒体标题以及媒体信息框中的特定媒体标题(例如视频媒体标题)。
3) 任何电影片段盒应按顺序排列(见第8.8.5款)。
4) 建议示例表框中的框按以下顺序排列:示例说明、采样时间、采样到块、采样大小、块偏移量。
5) 强烈建议轨迹参考框和编辑列表(如果有的话)应该在媒体框之前,处理程序引用框应该在媒体信息框之前,数据信息框应该在示例表框之前。6) 建议将用户数据框放在其容器的最后一个位置,即“电影盒”或“轨迹盒”。
7) 建议将电影片段随机访问框(如果存在)放在文件的最后一个。
8) 建议尽可能早地将渐进式下载信息框放在文件中,以获得最大的效用。
4.3 URI作为类型指示符
当URI用作类型指示符时(例如在示例条目中或用于非定时元数据),URI必须是绝对的,而不是相对的,并且数据的格式和含义必须由相关的URI定义。这种标识可以是分层的,因为URI的初始子字符串可以标识数据的整体性质或族(例如。骨灰盒:旧的:标识元数据由ISO标准对象标识符标记)。
URI应该是,但不是必须是可引用的。它可能是由读取器与它所知道和识别的一组URI类型进行比较的字符串。uri为类型标识符提供了一个大的非冲突的非注册空间。
如果URI包含域名(例如,它是一个URL),那么它还应该包含mmyyyy格式的月份日期。该日期必须接近定义扩展的时间,并且URI是在该日期以域名所有者授权的方式定义的,这必须是真的。(这避免了域名更改所有权时出现的问题)。
5. Brand ID
适用于文件格式的brand定义见附录E。