MP4 ISO基础媒体文件格式 摘要 1

Object-structured File Organization

文件由一系列box组成。所有数据包含在box中。box以一个给出了size和type的header组成。header允许紧凑或扩展size (32位或 64位) 和紧凑或扩展type (32位或完整的通用唯一 id 器, 即 uuid)。标准的box都使用紧凑型 (32‐bit), 大多数盒子将使用紧凑 (32‐bit) 尺寸。通常, 只有媒体数据框需要64‐bit 大小。size在box的最开始位置。size为整个box大小。

标准box的分布:

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
  }
  if (boxtype==‘uuid’) { //不能识别的type应该忽略
    unsigned int(8)[16] usertype = extended_type;  
    }
  }

FullBox 分布:

aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v, bit(24) f) extends Box(boxtype) {
  unsigned int(8) version = v;  //specifies the version of this format of the box.
  bit(24) flags = f;  //a map of flags
}

1 File Type Box (ftyp)

类型 容器 强制性 数量
'ftyp' File Yes One
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
}

对于不同的使用方式,有不用的文件布局。
stream形式.png
上图是含有两个stream的文件,其具有时间顺序,但是是交错的。这对于采用stream播放的文件很有用。但对于本地文件,采用streams分别单独存放,效率和效果更好。
local形式.png
文件是由一系列box组成,一个box里可能含有其他box。这一系列文件只有一个medadata wrapper(Movie box),其通常在文件开始或者结尾(便于定位)。其他的在同一层次的box 有File‐Type box, Free Space Boxes, Movie Fragments,Meta‐data,和 Media Data Boxes。
Track Identifiers在文件中是唯一的。在mvhd box中的 next_track_ID是当前已存在的track id的最大值加一。但若此值所有位全为1(32‐bit unsigned maxint),就必须找一个未被使用的track id。
私有扩展的box通过'uuid' type实现。在box中,通常有两种格式, version = 0使用32-bit,version = 1使用64-bit;一般而言,能够使用version 0 的时候,就要使用,只有必须使用 version 1的时候,才使用64-bit。
为了提高文件的互操作性和实用性, box的顺序应遵循以下规则和准则:

  1. ftyp box应该在所有可变box之前(movie, free space,media data)。只有固定size box(比如:一个 file signature box),如果需要,才可能提前处理。
  2. 强烈建议header box放在该box的最前方,Movie Header, Track Header, Media Header,Video Media Header。
  3. 任意Fragment box 应该有序排列。
  4. 建议Sample Table Box 采用以下顺序:Sample Description, Time to Sample, Sample to Chunk, Sample Size, Chunk Offset。
  5. 强烈建议:Track Reference Box 和 Edit List(如果有的话)在Media Box之前处理;Handler Reference Box在Media Information Box之前处理;Data Information Box在Sample Table Box.之前处理。
  6. 建议用户数据boxes放在容器最后,无论是Movie Box还是Track Box。
  7. 建议Movie Fragment Random Access Box放在文件最后(如果出现)。
  8. 为了最大的便利性,progressive download information box应该尽早出现在文件中。

streaming

流式播放和本地播放一样重要。支持流式传输的文件或 "影片" 包括有关要流式传输的数据单位的信息。这个信息被包含在附加的tracks中, “hint” tracks。Hint tracks可能被用来记录stream,它们被称为Reception Hint Tracks,以区别plain(or server, or transmission) hint tracks。
Transmission or server hint tracks包含帮助流服务器形成用于传输的数据包的指令。这些说明可能包含服务器要发送的即时数据 (例如header信息) 或媒体数据的参考段。这些指令与本地回访文件的编码方式一致。
在记录一个或者多个数据包流的时候Reception hint tracks可能被使用。其表明了顺序,接收时间和接收数据包的内容等。
支持流式传输基于以下三点:

  1. 媒体数据表示为一组独立于网络的标准tracks, 可以正常播放、编辑等;
  2. hint tracks有一个通用的声明和基本结构;这种常见的格式是独立于协议的, 但包含在hint tracks中描述的协议的声明;
  3. 对于可能传输的每个协议, 都有一个特定的hint tracks设计;所有这些设计都使用相同的基本结构。例如, 可能有用于 rtp (适用于 internet) 和 MPEG‐2传输 (用于广播) 的设计, 也可能有用于新标准或供应商特定协议的设计。
    Hint tracks 用来描述文件中的基本流数据。每一个协议或者协议族有其自己的hint track format。

Hint tracks通过引用将数据从其他轨道中拉出(pulling)来构造流。这些其他轨道可能是hint tracks或基本流轨道。这些指针的确切形式由协议的示例格式定义, 但通常由四个信息组成: track参考索引、示例编号、偏移量和长度。在特定协议中可能内含其中一些。这些 "指针" 始终指向数据的实际来源。如果在另一个hint tracks的 "on top" 生成hint track, 则第二个hint track必须具有对第一个将来自这些media track的数据放置在流中的media track所使用的media track的直接引用。
所有提示跟踪都使用一组通用的声明和结构:

  • hint track通过 hint类型的track引用链接到它们所携带的基本stream tracks。
  • 在Handler Reference Box使用hint处理程序类型。
  • 使用Hint Media Header Box
  • 在示例描述中使用hint sample 条目, 其名称和格式是它们所代表的协议所独有的。

Server hint tracks 通常被标记为禁用本地播放,它们的track header 的 track_in_movietrack_in_preview标志都被设置为0。
hint track可以由创作工具创建, 也可以由hint工具添加到现有演示文稿中。这样的工具是媒体和协议之间的 "桥梁", 因为它密切理解这两者。这允许创作工具了解媒体格式, 但不包括协议, 服务器可以理解协议 (及其hint track), 但不能理解媒体数据的详细信息。hint track不使用单独合成时间;"ctts" 表不存在于hint track中。

Box Structures

File Structure and general boxes

Media Data Box

类型 容器 强制性 数量
'mdat' File Yes 0 or more
aligned(8) class MediaDataBox extends Box(‘mdat’) {
    bit(8) data[];
}

Free Space Box

类型 容器 强制性 数量
'free','skip' File Yes 0 or more

free‐space box的内容是不相关的, 可能会被忽略, 或者对象被删除, 而不会影响演示文稿。(删除对象时应谨慎, 因为这可能会使sample table中使用的偏移量无效, 除非此对象是在所有媒体数据之后)。

aligned(8) class FreeSpaceBox extends Box(free_type) {
  unsigned int(8) data[];
}

Progressive Download Information Box

类型 容器 强制性 数量
'pdin' File Yes 0 or more

"Progressive download information box" 框可帮助渐进式下载 iso 文件。该框包含成对数字 (到框的末尾), 指定有效文件下载比特率 (以字节为单位) 和建议的初始播放延迟 (以毫秒为单位) 的组合。
接收方可以估计它所过去的下载速率, 并从中通过对之间的线性插值或从第一个或最后一个条目的外推法获得适当初始延迟的上限估计。

aligned(8) class ProgressiveDownloadInfoBox extends FullBox(‘pdin’, version = 0, 0) {
  for (i=0; ; i++) { // to end of box
    unsigned int(32) rate;  // bytes/second
    unsigned int(32) initial_delay;  //suggested delay to use
  }
}

Movie Structure

Movie Box

类型 容器 强制性 数量
'moov' File Yes 1
aligned(8) class MovieBox extends Box(‘moov’){
}

Movie Header Box

类型 容器 强制性 数量
'mvhd' 'moov' Yes 1

此box定义了与媒体无关的总体信息, 并与整个presentation相关。

aligned(8) class MovieHeaderBox extends FullBox(‘mvhd’, version, 0) {
  if (version==1) {
    unsigned int(64) creation_time;  //in seconds since midnight, Jan. 1, 1904, in UTC time
    unsigned int(64) modification_time; //in seconds since midnight, Jan. 1, 1904, in UTC time
    unsigned int(32) timescale;  //指定整个演示文稿的time-scale; 这是一秒钟内传递的time units。 例如,以六十分之一秒为单位测量时间的时间坐标系的timescale = 60
    unsigned int(64) duration;  //presentation的长度(以timescale为参照)与所有tracks中最大的duration一致,不能确定时,设置为1s
  } else { // version==0
    unsigned int(32) creation_time;
    unsigned int(32) modification_time;
    unsigned int(32) timescale;
    unsigned int(32) duration;
  }
  template int(32) rate = 0x00010000; // typically 1.0  表示播放presentation的首选速率;1.0 (0x00010000) 是正常的正向播放
  template int(16) volume = 0x0100; // typically, full volume 示播放presentation的首选速率;1.0 (0x0100) is full volume
  const bit(16) reserved = 0;  
  const unsigned int(32)[2] reserved = 0;
  template int(32)[9] matrix = { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 }; // Unity matrix  Video的转换矩阵
  bit(32)[6] pre_defined = 0;
  unsigned int(32) next_track_ID; //下一个可用的track id值,非零值;如果所有32位全为1,新加入的track必须在文件中寻找一个未被使用的值作为track id
}

Track Structure

Track Box

类型 容器 强制性 数量
'trak' ‘moov’ Yes 1

一个presentation的单个track的box。一个presentation含有1个或者多个track box。各个track box互相独立,每个track含有其相关的media box。
使用track 有两个目的:1. 包含media data(media tracks) 2 包含流协议的数据化信息(hint tracks)
iso 文件中必须至少有一个media track, 并且与hint track有关的的所有media track都应保留在文件中, 即使其中的媒体数据未被hint track引用;删除所有hint track后, 整个un-hint的presentation应保持不变。

aligned(8) class TrackBox extends Box(‘trak’) {
}

Track Header Box

类型 容器 强制性 数量
'tkhd' ‘trak’ Yes 1

定义track特点。单一tkhd对应单一track。
在没有edit list的情况下, track的呈现从整个presentation的开头开始。empty edit用于抵消track的开始时间。
用于media tracks 的track header flags的默认值为7(track_enabledtrack_in_movie, track_in_preview)。如果一个presentation的所有tracks既没有track_in_movie也没有track_in_preview,那么认为这两个flags在所有tracks都设置了。Server hint tracks应该设置track_in_movietrack_in_preview为0,为了本地播放和预览时忽略它们。
这里的duration字段不包括接下来的Movie fragment的duration(如果有的话),只包括当前电影框中的媒体的持续时间。如果需要和可能,可以使用Movie Extends Header box记录包括movie fragments在内的持续时间。(意译,可能不准确)

aligned(8) class TrackHeaderBox extends FullBox(‘tkhd’, version, flags){
  if (version==1) {
    unsigned int(64) creation_time;  //creation time of this track (in seconds since midnight, Jan. 1, 1904, in UTC time)
    unsigned int(64) modification_time; //in seconds since midnight, Jan. 1, 1904, in UTC time
    unsigned int(32) track_ID;  //非零,不可复用
    const unsigned int(32) reserved = 0;
    unsigned int(64) duration;  //in the timescale indicated in the Movie Header Box) 。
                //如果有 track edit,等于当前track的所有edits之和。如果没有edit,等于所有sample duration(转换为mvhd的timescale)之和。
              //不能确定的话,置为1s
  } else { // version==0
    unsigned int(32) creation_time;
    unsigned int(32) modification_time;
    unsigned int(32) track_ID;
    const unsigned int(32) reserved = 0;
    unsigned int(32) duration;
  }
  const unsigned int(32)[2] reserved = 0;
  template int(16) layer = 0; //layer指定video track 的前后排序; 数字较小的曲目更接近观众。
                // 0是正常值,-1将位于轨道0的前面,依此类推。
  template int(16) alternate_group = 0;
  template int(16) volume = {if track_is_audio 0x0100 else 0};
  const unsigned int(16) reserved = 0;
  template int(32)[9] matrix={ 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };// unity matrix
  unsigned int(32) width;
  unsigned int(32) height;
}

flags是带标志的24位整数; 定义了以下值:
 Track_enabled: 启动track标志。0x000001为启用,低位为0不启用。
 Track_in_movie:表示track在presentation中使用。Flag为0x000002。
 Track_in_preview:track 在预览presentation时使用。Flag为0x000004。
 Track_size_is_aspect_ratio:widthhight不以像素为单位表示。值具有相同的单位,但未指定这些单位。 这些值仅表示所需的宽高比。 如果该轨道和其他相关轨道的纵横比不相同,则轨道的相应定位是不确定的,可能由外部上下文定义。 Flag为0x000008。
alternate_group是一个整数,指定一组或一组track。 如果该字段为0,则没有关于与其他track的可能关系的信息。 如果此字段不为0,则对于包含彼此的备用数据的track应该相同,而对于属于不同此类组的track则不同。 在任何时候,应该只播放或流式传输备用组中的一个track,并且必须通过比特率,编解码器,语言,数据包大小等属性与组中的其他track区分开。一个组可能只有一个成员。
widthheight 与track相关,具有如下特点:
 对于文本和subtitle tracks, 它们可以根据编码格式描述呈现区域建议的大小。对于此类track, 值0x0 还可用于指示数据可以以任何大小呈现, 未指示首选大小, 实际大小可能由外部上下文或通过重用另一个track的宽度和高度来确定。对于这些track, 也可以使用track_size_is_aspect_ratio 标志。
 对于不可视track (如音频), 应将其设置为零。
 对于所有其他track, 它们指定track的可视演示文稿大小。这些不需要与示例描述中记录的图像的像素尺寸相同;序列中的所有图像都将缩放到此大小, 然后再对矩阵表示的track进行任何整体转换。图像的像素尺寸是默认值。

Track Reference Box

类型 容器 强制性 数量
'tref' ‘trak’ No 0或1

该box提供一个容器track到另一个track的链接。

aligned(8) class TrackReferenceBox extends Box(‘tref’) {
}
aligned(8) class TrackReferenceTypeBox (unsigned int(32) reference_type) extends Box(reference_type) {
    unsigned int(32) track_IDs[];  //一个track到另一个track的id
}

Track Reference Box包含track reference type boxes:
reference_type应设置为以下值之一,或者已注册的值或从规范或注册派生的:
‘hint’ referenced track(s)包含当前hint track 的原始media。
‘cdsc' 当前track描述了referenced track
‘font‘ 当前track使用了 referenced track(s) 承载/定义的fonts
‘hind‘ 当前track依赖了referenced hint track, 它只应在使用referenced hint track时使用.
'vdep' 该track 包含所reference video track的辅助深度视频信息。
‘vplx’ 该轨道包含所reference video track的辅助视差视频信息。
‘subt’ 此track包含reference track的字幕,定时文本或叠加图形信息,或track所属的备用组中的任何track(如果有)。

Track Group Box

类型 容器 强制性 数量
'trgr' ‘trak’ No 0或1

此box允许指示track组,其中每个组共享特定特征或组内的track具有特定关系。该box包含零个或多个box,特定特征或关系由所包含box的box类型指示。包含的box包括标识符,该标识符可用于结束属于同一track组的track。在“track组box”中包含相同类型的包含box并且在这些包含box中具有相同标识符值的track属于同一track组。
track组不得用于表示track之间的依赖关系。 相反,track reference box用于此类目的。

aligned(8) class TrackGroupBox('trgr') {
}
aligned(8) class TrackGroupTypeBox(unsigned int(32) track_group_type) extends  FullBox(track_group_type, version = 0, flags = 0)
{
    unsigned int(32) track_group_id;
    // the remaining data may be specified for a particular track_group_type
}

track_group_type表示分组类型,应设置为以下值之一,或已注册的值,或派生规范或注册中的值:
'msrc' 表示此track属于多源presentation。在track_group_type'msrc'的组类型box中具有相同track_group_id值的track被映射为源自相同的源。 例如,视频电话呼叫的记录可以同时具有两个参与者的音频和视频,并且与一个参与者的音频track和视频track相关联的track_group_id的值不同于与另一个参与者的track相关联的track_group_id的值。

原文地址:https://www.cnblogs.com/gardenofhu/p/10031922.html