感谢Google Translate, Microsoft Translate。通篇机翻,不保证绝对正确。
类型 |
容器 |
强制性 |
数量 |
'mdia' |
'trak' |
Yes |
1 |
媒体声明容器包含在track中声明有关媒体数据的信息的所有对象。 |
|
|
|
aligned(8) class MediaBox extends Box(‘mdia’) {
}
类型 |
容器 |
强制性 |
数量 |
'mdhd' |
'mdia' |
Yes |
1 |
说明在一个track中的media-independent 且 meida相关特点的全局信息。 |
|
|
|
aligned(8) class MediaHeaderBox extends FullBox(‘mdhd’, version, 0) {
if (version==1) {
unsigned int(64) creation_time;
unsigned int(64) modification_time;
unsigned int(32) timescale; //number of time units that pass in one second
unsigned int(64) duration; //declares the duration of this media (in the scale of the timescale). 不能确定的话设置为1s
} else { // version==0
unsigned int(32) creation_time;
unsigned int(32) modification_time;
unsigned int(32) timescale;
unsigned int(32) duration;
}
bit(1) pad = 0;
unsigned int(5)[3] language; // ISO-639-2/T language code
unsigned int(16) pre_defined = 0;
}
Handler Reference Box
类型 |
容器 |
强制性 |
数量 |
'hdlr' |
'mdia' 或'meta' |
Yes |
1 |
声明track的媒体类型, 从而显示track中的媒体数据的过程。例如, 解码器提供视频的格式将存储在视频track中, 由视频处理程序进行标识。媒体格式存储的文档标识该格式使用的媒体类型。任何类型的元数据流都有一个通用处理程序; 例如,对于视频或音频,特定格式由sample entry。 |
|
|
|
aligned(8) class HandlerBox extends FullBox(‘hdlr’, version = 0, 0) {
unsigned int(32) pre_defined = 0;
unsigned int(32) handler_type;
const unsigned int(32)[3] reserved = 0;
string name; //human‐readable name for the track type
}
类型 |
容器 |
强制性 |
数量 |
'minf' |
'mdia' 或'meta' |
Yes |
1 |
包含track中media的声明特点信息的对象。 |
|
|
|
aligned(8) class MediaInformationBox extends Box(‘minf’) {
}
每种track类型都有不同的媒体信息标题(对应于媒体处理类型); 应该存在匹配的标题。使用的media header的类型由媒体类型的定义确定,并且必须与媒体处理程序匹配。
类型 |
容器 |
强制性 |
数量 |
'nmhd' |
'minf' |
Yes(特定media header) |
1 |
aligned(8) class NullMediaHeaderBox
extends FullBox(’nmhd’, version = 0, flags) {
}
Sample Tables
Sample Table Box
类型 |
容器 |
强制性 |
数量 |
'stbl' |
'minf' |
Yes |
1 |
sample table包含track中媒体样本的所有时间和数据索引。 使用此处的表格,可以及时定位样本,确定其类型(例如,是否I帧),并确定它们的大小,容器和到该容器的偏移量。如果包含“Sample Tablesbox”的track不引用任何数据,则其不需要包含任何子box(这不是一个非常有用的媒体track)。 |
|
|
|
如果包含引用数据,接下来的sub-boxes是需要的:Sample Description, Sample Size, Sample To Chunk, Chunk Offset。并且,Sample Description Box至少含有一个entry。Sample Description Box是必需的,因为它包含数据引用索引字段,该字段指示用于检索媒体样本的数据引用box。 如果没有样本描述,则无法确定媒体样本的存储位置。 Sync Sample Box是可选的。 如果不存在Sync Sample Box,则所有样本都是Sync Samples。
aligned(8) class SampleTableBox extends Box(‘stbl’) {
}aligned(8) class SampleTableBox extends Box(‘stbl’) {
}
Sample Description Box
类型 |
容器 |
强制性 |
数量 |
'stsd' |
'stbl' |
Yes |
1 |
提供了有关所用编码类型的详细信息,以及该编码所需的任何初始化信息。 |
|
|
|
一个track中可能有多种Descriptions. |
|
|
|
aligned(8) abstract class SampleEntry (unsigned int(32) format) extends Box(format){
const unsigned int(8)[6] reserved = 0;
unsigned int(16) data_reference_index;
}
class BitRateBox extends Box(‘btrt’){
unsigned int(32) bufferSizeDB;
unsigned int(32) maxBitrate;
unsigned int(32) avgBitrate;
}
aligned(8) class SampleDescriptionBox (unsigned int(32) handler_type) extends FullBox('stsd', version, 0){
int i ;
unsigned int(32) entry_count;
for (i = 1 ; i <= entry_count ; i++){
SampleEntry(); // an instance of a class derived from SampleEntry
}
}
version
版本设置为零,除非该框包含AudioSampleEntryV1,其版本必须为1
entry_count
后续表的entry数目
data_reference_index
包含用于检索与使用sample description的sample关联数据的数据引用的索引。 数据引用存储在Data Reference Boxes中。 索引的范围从1到数据引用的数量。
bufferSizeDB
bytes为单位,给出基本流的解码buffer的大小
maxBitrate
1s内任意窗口的速率 bits/s
avgBitrate
整个presentation的速率 bits/s
Degradation Priority Box
类型 |
容器 |
强制性 |
数量 |
'stdp' |
'stbl' |
No |
0/1 |
包含每个box的degradation priority。值存在一个table中。 |
|
|
|
aligned(8) class DegradationPriorityBox extends FullBox(‘stdp’, version = 0, 0) {
int i;
for (i=0; i < sample_count; i++) {
unsigned int(16) priority;
}
}
Track Time Structures
Time to Sample Boxes
sample的组成时间(CT)和解码时间(DT)从sample time box导出,其中有两种类型。解码时间在Decoding Time to Sample Box中定义,给出连续解码时间之间的时间增量。在Composition Time to Sample box中导出合成时间,作为与解码时间的合成时间偏移。如果track中每个sample的合成时间和解码时间相同,则只需要Decoding Time to Sample box;composition time to sample box 必须不能出现。
time to sample boxes必须为所有sample提供非零duration,但可能除了最后一个sample不用这样。 “stts” box中的duration严格为正(非零),最后一个entry除外,该条目可能为零。该规则源于以下规则:流中没有两个时间戳可以是相同的。将sample添加到流中时必须非常小心,以前最后一个sample可能需要建立非零持续时间,以便遵守此规则。如果最后一个sample的持续时间不确定,请使用任意小值和“dwell”编辑。
一些编码系统可以允许仅用于参考而不是输出的sample(例如,视频中的非显示参考帧)。 当track中存在任何此类非输出sample时,以下内容适用:
- 非输出sample应给出和合成时间(composition time),此时间应该在输出sample的时间范围之外。
- 一个edit list 应该用于排除non-output samples的合成时间
- 当track包含CompositionOffsetBox (‘ctts’)时:
a. CompositionOffsetBox的version=1 版本应该使用
b. 对于每个non-output sample,sample_offset
的值应设置为等于可能的最大负数(对于32-bit 值,-231)
c. CompositionToDecodeBox('cslg'
)应该包含在track 的SampleTableBox('stbl'
)中,并且
d. 当track存在CompositionToDecodeBox时,box中的最小DecodeToDisplayDelta
字段的值应等于CompositionOffsetBox中的最小合成偏移量,不包non-output sample的sample_offset
值。
Decoding Time to Sample Box
类型 |
容器 |
强制性 |
数量 |
'stts' |
'stbl' |
Yes |
1 |
此box包含table的紧凑版本,允许从解码时间到sample编号进行索引。 其他table从sample编号中提供sample大小和指针。 table中的每个条目都给出了具有相同时间增量的连续sample的数量,以及这些sample的增量。 通过添加增量,可以构建完整的sample时间映射。 |
|
|
|
Decoding Time to Sample Box包含解码时间增量:\(DT(n+1) = DT(n) + STTS(n)\),其中,\(STTS(n)\)是sample n的table entry。 |
|
|
|
sample entries 按照解码时间戳排序。因此时间增量非负。 |
|
|
|
DT轴的原点为零;\(DT(i) = sum(for j = 0 to i -1 of delta(j))\),且所有的增量和给出了track中meida的长度(未映射到总时间刻度,并且不考虑任何edit list)。 |
|
|
|
如果Edit List Box非空(非零),则编辑列表框提供初始CT值。 |
|
|
|
aligned(8) class TimeToSampleBox extends FullBox(’stts’, version = 0, 0) {
unsigned int(32) entry_count;
int i;
for (i=0; i < entry_count; i++) {
unsigned int(32) sample_count;
unsigned int(32) sample_delta; //in the time-scale of the media
}
}
Composition Time to Sample Box
类型 |
容器 |
强制性 |
数量 |
'ctts' |
'stbl' |
No |
0/1 |
此box提供解码时间和合成时间之间的偏移。 在该box的version 0中,解码时间必须小于合成时间,并且偏移table示为无符号数,使得\(CT(n) = DT(n) + CTTS(n)\)其中 \(CTTS(n)\)是(未压缩的)sample的table entry。 在此box的version 1中,合成时间轴和解码时间线仍然相互派生,但偏移是有符号的。 建议对于计算的合成时间戳,只有一个值为0(零)。 |
|
|
|
对于任一版本的box,每个sample必须具有唯一的合成时间戳值,即两个sample的时间戳永远不会相同。 |
|
|
|
可能确实没有帧在0时刻构成; 对此的处理是未指定的(系统可能显示第一帧更长或合适的填充颜色)。 |
|
|
|
当使用此box的版本1时,CompositionToDecodeBox也可以存在于sample表中以关联合成和解码时间轴。 如果需要向后兼容或与未知读取器集兼容,则应尽可能使用此box的版本0。 在此box的任一版本中,特别是在版本0下,如果期望media在track时间0开始,并且第一媒体sample的合成时间不为0,则可以使用edit list来“移位” 媒体到时间0。 |
|
|
|
composition time to sample table 是可选的,且必须在任何sample的 DT 和 CT 不同时存在的时候才能出现。 |
|
|
|
hint tracks不使用此box。 |
|
|
|
aligned(8) class CompositionOffsetBox extends FullBox(‘ctts’, version, 0) {
unsigned int(32) entry_count;
int i;
if (version==0) {
for (i=0; i < entry_count; i++) {
unsigned int(32) sample_count;
unsigned int(32) sample_offset; //offset between CT and DT such that CT(n) = DT(n) +CTTS(n).
}
}
else if (version == 1) {
for (i=0; i < entry_count; i++) {
unsigned int(32) sample_count;
signed int(32) sample_offset;
}
}
}
Composition to Decode Box
类型 |
容器 |
强制性 |
数量 |
'cslg' |
'stbl'或'trep' |
No |
0/1 |
当使用有符号的组合偏移量时, 此box可用于关联组合和解码时间线, 并处理有符号组合偏移量引入的一些歧义。 |
|
|
|
请注意, 所有这些字段都适用于整个media (而不仅仅是由任何编辑选择的字段)。建议不要选择任何不映射到示例的合成时间线的任何部分, 无论是明示的还是暗示的。例如, 如果最小的合成时间为 1000, 则默认编辑从0到meida duration会遗漏与不与media sample相关联时间段0~1000。在这些情况下, 播放器的行为以及在此间隔中组成的内容是未定义的。建议最小计算的 CTS 为零, 或与第一次编辑的开头匹配。 |
|
|
|
track中最后一个sample的composition duration可能 (通常) 不明确或不清楚;合成结束时间的字段可以用来澄清这种模糊性, 并随着构图开始时间的延长, 为track建立明确的合成持续时间。 |
|
|
|
当 Composition to Decode Box包含在 Sample Table Box中时, 它仅记录Movie Box中示例的合成和解码时间关系, 不包括任何后续的movie fragments。当 Composition to Decode Box包含在Track Extension |
|
|
|
Properties Box中时, 它将记录Movie Box后面的所有movie fragments中sample的合成和解码时间关系。 |
|
|
|
此box的版本1支持64‐bit 时间戳, 并且仅在需要时才应使用 (至少有一个值不适合 32位)。 |
|
|
|
class CompositionToDecodeBox extends FullBox(‘cslg’, version, 0) {
if (version==0) {
signed int(32) compositionToDTSShift;
signed int(32) leastDecodeToDisplayDelta; //最小合成偏移量
signed int(32) greatestDecodeToDisplayDelta; //最大合成偏移量
signed int(32) compositionStartTime; //此track的任意sample 的最小computed composition time (CTS)
signed int(32) compositionEndTime; //在当前track中具有最大的 computed composition time (CTS) 的 composition time + composition duration,
//如果此字段采用值 0, 则合成结束时间未知。
} else {
signed int(64) compositionToDTSShift;
signed int(64) leastDecodeToDisplayDelta;
signed int(64) greatestDecodeToDisplayDelta;
signed int(64) compositionStartTime;
signed int(64) compositionEndTime;
}
}
compositionToDTSShift
: 如果此值加到 合成时间(由DTS的CTS偏移计算),那么对于所有sample,其CTS保证大于等于其DTS,且指定的配置文件级别所隐含的缓冲模型将被遵守。如果 leastDecodeToDisplayDelta
为正数,此值可为0; 否则其至少(-leastDecodeToDisplayDelta
)
Sync Sample Box
类型 |
容器 |
强制性 |
数量 |
'stss' |
'stbl' |
No |
0/1 |
此box提供流中sync samples的紧凑标记。 该table按sample编号的严格递增顺序排列。 |
|
|
|
如果此box未出现,所有sample都是sync samples。 |
|
|
|
aligned(8) class SyncSampleBox extends FullBox(‘stss’, version = 0, 0) {
unsigned int(32) entry_count; //为0时,流中没有sync sample,接下来的table为空
int i;
for (i=0; i < entry_count; i++) {
unsigned int(32) sample_number;
}
}
Shadow Sync Sample Box
类型 |
容器 |
强制性 |
数量 |
'stsh' |
'stbl' |
No |
0/1 |
提供了一组可选的sync sample,可在搜索或出于类似目的时使用。 在正常的正向播放中,他们会被忽略。 |
|
|
|
ShadowSyncTable中的每个entry都包含一对sample编号。第一个entry(shadowedsample- |
|
|
|
number)表示将为其定义shdowSync的sample编号。这应该 |
|
|
|
始终是非同步sample(例如帧差异)。第二个sample号(sync-samplenumber) |
|
|
|
表示当存在时可以使用的同步sample(即关键帧)的sample号 |
|
|
|
在shadowed-sample-number处或之前需要同步sample。 |
|
|
|
ShadowSyncBox中的entry应根据shadowed-sample-number字段进行排序。 |
|
|
|
shdowSyncsample通常放置在track的未在期间呈现的区域中 |
|
|
|
正常播放(通过编辑列表编辑出来),但这不是必需的。shdowSync |
|
|
|
如果被忽略,则可以忽略该表并且track将正确播放(并寻找)(尽管可能没有 |
|
|
|
最佳)。 |
|
|
|
ShadowSyncSample替换而不是增加它shdow的sample(即发送的下一个sample是 |
|
|
|
阴影sample数+ 1)。shdowSyncsample被视为在时间发生时 |
|
|
|
对其进行采样shdow,使其具有阴影的sample持续时间。 |
|
|
|
如果shdow sample也被用作一部分,则提示和传输可能会变得更加复杂 |
|
|
|
正常播放,或作为阴影多次使用。在这种情况下,提示track可能需要单独 |
|
|
|
shdowSync,所有这些都可以将媒体数据从媒体track中的一个shdowSync中获取 |
|
|
|
允许标题中需要不同的时间戳等。 |
|
|
|
aligned(8) class ShadowSyncSampleBox extends FullBox(‘stsh’, version = 0, 0) {
unsigned int(32) entry_count;
int i;
for (i=0; i < entry_count; i++) {
unsigned int(32) shadowed_sample_number;
unsigned int(32) sync_sample_number;
}
}
Independent and Disposable Samples Box
类型 |
容器 |
强制性 |
数量 |
'sdtp' |
'stbl' |
No |
0/1 |
这个可选table回答了关于sample 依赖的3个问题: |
|
|
|
- 是否当前sample依赖其他sample(举例:是否I-帧)?
- 其他sample是否依赖当前sample?
- 此sample是否包含此时的多个(冗余)数据编码(可能具有不同的依赖关系)?
这个table没有的时候:
- 同sync sample table(部分)回答第一个问题; 在大多数视频编解码器中,I-picture也是同步点
- 其他sample对此sample的依赖关系是未知的
- 冗余编码的存在是未知的
More Detail Ref:ISO/IEC 15444-12
aligned(8) class SampleDependencyTypeBox extends FullBox(‘sdtp’, version = 0, 0) {
for (i=0; i < sample_count; i++){
unsigned int(2) is_leading;
unsigned int(2) sample_depends_on;
unsigned int(2) sample_is_depended_on;
unsigned int(2) sample_has_redundancy;
}
}
Edit Box
类型 |
容器 |
强制性 |
数量 |
'edts' |
'trak' |
No |
0/1 |
edit box将演示时间线映射到存储在文件中的媒体时间线。 edit box是edit list的容器。 |
|
|
|
edit box是可选的。 如果没有此box,则会对这些时间线进行隐式的一对一映射,并且在演示开始时开始演示track。 空编辑用于偏移track的开始时间。 |
|
|
|
aligned(8) class EditBox extends Box(‘edts’) {
}
Edit List Box
类型 |
容器 |
强制性 |
数量 |
'elst' |
'edts' |
No |
0/1 |
此box包含显式时间轴map。 每个entry定义track时间线的一部分:通过映射 media time‐line的一部分,或通过指示“空”时间,或通过定义“停留”,其中媒体中的单个时间点保持一段时间。 |
|
|
|
track(流)的起始偏移由初始空编辑表示。 |
|
|
|
非空编辑可以插入初始movie中不存在的媒体时间线的一部分,并且仅存在于后续movie片段中。 特别是在片段化movie文件的空初始movie中(当还没有媒体sample存在时),该编辑的segment_duration可以为零,因此编辑提供从movie和movie呈现时间到movie呈现时间的偏移。 随后的movie片段。 当使用合成偏移时,建议使用这样的编辑来为第一个呈现的sample建立0的呈现时间。 |
|
|
|
aligned(8) class EditListBox extends FullBox(‘elst’, version, 0) {
unsigned int(32) entry_count;
for (i=1; i <= entry_count; i++) {
if (version==1) {
unsigned int(64) segment_duration; //specifies the duration of this edit segment in units of the
timescale in the Movie Header Box
int(64) media_time;
} else { // version==0
unsigned int(32) segment_duration;
int(32) media_time;
}
int(16) media_rate_integer;
int(16) media_rate_fraction = 0;
}
}
media_time
是一个整数,包含此编辑段的meida内的开始时间(以媒体时间刻度单位,在合成时间内)。 如果此字段设置为-1,则为空编辑。 track中的最后一次编辑永远不会是空编辑。 Movie Header Box中的持续时间与曲目持续时间之间的任何差异都表示为结尾处的隐式空编辑。
media_rate
指定播放与此编辑片段对应的媒体的相对速率。 如果此值为0,则编辑指定“停留”:媒体时间的媒体将显示段持续时间。 否则,该字段应包含值1。