时间戳和持续时间
本主题介绍媒体基础转换 如何处理时间戳。
MFT 必须在所有输出样本中尽可能准确地设置时间戳和持续时间。 对于采用一个输入缓冲区并完全将其处理到输出缓冲区的简单 MFT,MFT 应仅将时间戳和持续时间直接从输入示例复制到输出示例。 但是,许多转换比这更复杂,可能需要对输出时间进行更复杂的计算。 所有 MFT 都应遵守以下基本规则:
- 如果输入样本上提供了准确的时间戳或持续时间,MFT 应尝试在所有未压缩的视频或音频输出样本上放置时间戳和持续时间,也可以计算。 某些输出时间戳可能需要内插,尤其是对于解码器。
- 应尽可能多地保留输入样本的时间戳和持续时间。
- 输出时间戳或持续时间可能与输入不匹配,因为 MFT 会阻碍数据,或者将输出分解为与输入不同的大小片段。 在这种情况下,MFT 应从最早的输入示例计算输出时间戳,其中包含用于创建输出示例的数据。 若要计算输出时间戳,请将相应输入样本的输入时间戳添加到已从该样本转换的数据的持续时间。 本部分末尾的第二个示例说明了这一想法。
- 如果输入样本具有持续时间,则应保留该持续时间。 如果输入样本没有持续时间,则 MFT 应根据输出缓冲区的大小或媒体类型提供的数据速率计算持续时间。
- 计算持续时间应截断(向下舍入),而不是舍入到最接近的增量。 管道有足够的可宽延时间来处理稍不准确的持续时间,但管道处理持续时间比 1% 过长的持续时间要短 1% 更容易。 也就是说,除了舍入之外,没有理由故意缩短持续时间。
解码器
解码器将压缩的数据包转换为未压缩的数据。 由于输出未压缩,解码器需要特殊义务才能正确获取时间戳和持续时间。 某些压缩格式(尤其是 MPEG-2)在所有输入数据包上没有时间戳,并且通常在任何数据包上都没有持续时间。 对于这些格式,解码器负责在每个输出样本上放置有效的时间戳和持续时间,方法是对自上次时间戳输入样本以来所有输出的隐含持续时间求和。
对于视频,如果持续时间以压缩格式不可用,解码器应将持续时间计算为帧速率的反函数,转换为 100 纳秒单位并向下舍入。
对于音频,如果持续时间以压缩格式不可用,解码器应计算持续时间,因为音频采样率的反数乘以输出缓冲区中的样本数,转换为 100 纳秒单位并向下舍入。
转换应输出没有时间戳的示例的唯一时间是 MFT 从未收到输入样本上的时间戳,或者无法计算上一个输入时间戳的准确输出时间戳。
音频解码器
对于音频解码器,每个输出样本的持续时间是从音频采样率计算的,以及输出缓冲区中每个通道的 PCM 样本数。
计算输出时间戳的正确方法取决于输入样本是否包含时间戳。
如果输入示例包含时间戳,解码器将从输入时间戳计算输出时间戳,如下所示:
- 如果每个输入缓冲区包含一个或多个完整的压缩帧(没有部分帧),则输出时间戳等于输入时间戳,减去解码器的已知延迟。 例如,Dolby Digital (AC-3) 解码器延迟为 256 个 PCM 样本。 例如,在 48-kHz 采样率下,延迟为 5.33 毫秒(毫秒)。 因此,如果输入时间戳为 1000 毫秒,则输出时间戳为 1000 – 5.33 = 994.66 毫秒。 如果输入缓冲区包含多个整个压缩帧,解码器将为输入样本中的每个帧生成一个输出样本。 所有输出示例都将正确标记时间戳,这样就没有差距。
- 根据传输格式,输入缓冲区可能包含部分帧。 例如,缓冲区可能包含上一个输入缓冲区中帧的一部分,后跟一个或多个完整帧,后跟下一帧的开头。 在这种情况下,通常可以假定输入时间戳对应于缓冲区内启动的第一个帧。 (也就是说,在上一个缓冲区中启动的部分帧不包括在当前缓冲区的时间戳中。相应地计算输出时间戳。
如果输入示例不包含任何时间戳:
- 解码器应生成自己的时间戳,将第一个输出时间戳设置为零。
- 样本持续时间根据缓冲区中的输出样本数和采样率计算。
- 后续时间戳是从以前的时间戳和持续时间计算的:当前时间戳 + 当前持续时间 = 下一个时间戳。 输出时间戳中不应有差距。
如果输入流最初包含时间戳,但出于某种原因切换到无时间戳,解码器应继续生成自己的输出时间戳,这样它们就连续且没有差距。
如果输入流包含时间戳,但时间存在差距,则解码器只会传播这些间隔。 换句话说,解码器不应尝试修复输入流中不一致的时间戳。
搅拌机
注意
在 Windows Vista 中,媒体基础管道不支持具有多个输入的 MFT。 Windows 7 支持多输入 MFT。
混音器采用多个输入,并将其混合到一个输出中。 如果输入流未完全锁定速率,或者彼此的时间略有偏移,则输出上可以设置的时间不明确。 下面是一些准则,具体取决于媒体类型:
音频。 在启动时或立即清空或刷新后,音频混音器应等待生成输出样本,直到它已收到所有必需的输入流上的输入样本。 此时,它应选择初始示例的最早时间戳,以用作输出时间戳的基线。 其他流应以沉默填充,以弥补任何时间差异。 如果在可选输入流上收到示例,则还应将其纳入计算中。 从这一点开始,MFT 应努力生成连续且未中断的输出时间戳链。 通常,MFT 不应尝试考虑相对于另一个流的偏移。 相反,它应从基线时间戳、输出速率和缓冲区大小计算输出时间戳。 当发生另一个排水或刷新时,MFT 应重置其基线时间戳。
视频。 在启动时或立即清空或刷新后,视频混音器应等待生成输出样本,直到它已收到所有所需输入流的输入样本。 此时,它应选择初始示例的最早时间戳,以用作输出时间戳的基线。 通常,它应努力保持连续和常规输出时间戳和固定持续时间,即使输入不是常规的,如有必要,重复输入帧。
编码
编码器将未压缩的音频或视频转换为压缩的数据包。 编码器应遵循以下准则:
编码器应遵循输出格式的约定。 如果格式通常不是每个示例的时间戳,就像在 MPEG-2 中一样,并不是每个输出样本都需要时间戳和持续时间。
如果输入时间戳具有时间戳的字段,则输入时间戳应保留为输出格式,除非其他源(如应用程序本身)提供了更好的时间信息。
多路复用器
注意
在 Windows Vista 中,媒体基础管道不支持具有多个输入的 MFT。 Windows 7 支持多输入 MFT。
多路复用器将两个不同的音频或视频流组合成一种交错格式,例如 AVI 或 MPEG-2 传输流。 多路复用器应遵循以下准则:
多路复用器应遵循输出格式的约定。 如果格式通常不是每个示例的时间戳,就像在 MPEG-2 中一样,并不是每个输出样本都需要时间戳和持续时间。
时间戳应反映将放置在该数据包中开始的任何帧上的最早时间,或从该数据包解码的第一个音频样本的时间。 如果此准则与输出格式的约定冲突,请忽略此准则。
Demultiplexers
解体器将交错格式(如 AVI 或 MPEG-2 传输流)拆分为基础音频和视频流。
如果格式包含特定的时间戳信息,可用于根据输入时间戳计算准确的输出时间戳,则应使用该信息。 但是,如果格式包含与输入时间戳无关的完全不同的基数中的时间,并且无法计算输入时间戳的准确偏移量,则应忽略该格式的自身时间。
如果格式没有可用时间戳信息,则解体程序应遵循以下规则:
如果可能,未压缩的输出流应具有有效的时间戳和持续时间,从最近的上一个输入时间戳计算。
压缩的输出流应仅对从具有时间戳的输入样本派生的第一个输出样本具有时间戳。 如果输入示例没有时间戳,则派生自该输入样本的输出示例应具有时间戳。 如果输入样本分解为多个输出样本,则只有第一个输出示例应具有时间戳,其余示例不应有时间戳。
例子
示例 1. 假设视频效果始终采用未压缩的输入帧,应用效果并将其复制到输出。 它永远不会保留任何帧或缓冲区任何输入。 此 MFT 仅将时间戳和持续时间从输入示例复制到输出示例(如果可用),并且根本不执行时间计算。
示例 2. 假设音频效果将转换每个输入缓冲区的 10 毫秒(ms),从而节省额外的 10 毫秒以与下一个缓冲区组合。 它获取所有持续时间为 50 毫秒的样本流。 下表显示了输入时间。
样本 | 输入时间 | 输入持续时间 | 输出时间 | 输出持续时间 |
---|---|---|---|---|
1 | 20 | 50 | 20 | 40 |
2 | 70 | 50 | 60 | 50 |
3 | 121 | 50 | 110 | 50 |
4 | 171 | 50 | 161 | 50 |
请注意样本 2 的实际持续时间与基于下一个时间戳(121 ? 70 = 51)的隐含持续时间之间的 1 毫秒差异。
由于 MFT 保留 10 毫秒,因此将输入样本 1 的前 40 毫秒输出为输出样本 1,时间戳为 20 毫秒,持续时间为 40 毫秒。
输出示例 2 将以前保留的 10 毫秒与 40 毫秒的输入样本 2 组合在一起。 此示例的时间戳为 60 毫秒(上一个输入样本的时间戳 20 毫秒,加上已从该样本处理的数据持续时间 40 毫秒)。 它得到的持续时间为 50 毫秒。
同样,下一个示例的时间戳为 110 毫秒(70 毫秒 + 40 毫秒),持续时间为 50 毫秒。
下一个计算更有趣。 上一个输出时间和持续时间的隐含时间戳为 160 毫秒(时间戳 110 毫秒 + 持续时间 50 毫秒)。 但是,输出时间戳应从最早输入样本的输入时间戳计算,该时间戳与输出样本的时间重叠,以及已从该样本处理的任何数据的长度。 最接近的重叠输入样本是示例 4(时间戳 = 171),但这不是最早的一个。 最早的重叠样本是示例 3(时间戳 = 121)。 添加已从该示例处理的 40 毫秒,结果是 161。
相关主题