时间戳和持续时间
本主题介绍 媒体基础转换 应如何处理时间戳。
MFT 必须对所有输出样本设置尽可能准确的时间戳和持续时间。 对于采用一个输入缓冲区并将其完全处理到输出缓冲区的简单 MFT,MFT 应仅将时间戳和持续时间直接从输入样本复制到输出样本。 但是,许多转换都比这更复杂,可能需要更复杂的输出时间计算。 所有 MCT 都应遵守以下基本规则:
- 如果输入样本上给出了准确的时间戳或持续时间,或者可以计算,MFT 应尝试在所有未压缩的视频或音频输出样本上放置时间戳和持续时间。 某些输出时间戳可能需要内插,尤其是对于解码器。
- 应尽可能在输出样本上保留输入样本的时间戳和持续时间。
- 输出时间戳或持续时间可能与输入不匹配,因为 MFT 会保留数据或将输出分解为与输入大小不同的部分。 在这种情况下,MFT 应从最早的输入样本中计算输出时间戳,该样本包含用于创建输出示例的数据。 若要计算输出时间戳,请将相应输入样本的输入时间戳添加到已从该样本转换的数据的持续时间。 本部分末尾的第二个示例说明了这一想法。
- 如果输入样本具有持续时间,则应保留该持续时间。 如果输入样本没有持续时间,MFT 应根据输出缓冲区的大小或媒体类型提供的数据速率(如果可能)计算持续时间。
- 计算的持续时间应截断 () 向下舍入,而不是舍入到最接近的增量。 管道有足够的松散时间来处理稍有不准确的持续时间,但管道处理持续时间比 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 中,Media Foundation 管道不支持具有多个输入的 MCT。 Windows 7 支持多输入 MCT。
混音器接受多个输入,并将其混合到一个输出中。 如果输入流不是完全速率锁定的,或者彼此之间的时间略有偏移,那么在输出上设置的时间可能会不明确。 下面是一些指南,具体取决于媒体类型:
音频。 在启动时或排出或刷新后,音频混音器应等待生成输出样本,直到它收到所有所需输入流的输入样本。 此时,它应选择初始样本的最早时间戳,以用作输出时间戳的基线。 其他流应填充静音,以弥补任何时间差异。 如果在可选输入流上收到示例,则还应将其纳入计算中。 从此,MFT 应努力生成连续且不间断的输出时间戳链。 通常,MFT 不应尝试考虑一个流相对于另一个流偏移。 相反,它应根据基线时间戳、输出速率和缓冲区大小计算输出时间戳。 当发生另一个排出或刷新时,MFT 应重置其基线时间戳。
视频。 在启动时或排出或刷新后,视频混音器应等待生成输出样本,直到它收到所有所需输入流的输入样本。 此时,它应选择初始样本的最早时间戳,以用作输出时间戳的基线。 一般情况下,它应努力保留连续和常规的输出时间戳和固定持续时间,即使输入不是常规的,如有必要,通过重复输入帧。
编码器
编码器将未压缩的音频或视频转换为压缩数据包。 编码器应遵循以下准则:
编码器应遵循输出格式的约定。 如果格式通常不是每个样本的时间戳(如 MPEG-2 中所示),则并非每个输出样本都需要有时间戳和持续时间。
如果格式具有时间戳字段,则输入时间戳应保留为输出格式,除非从其他源(例如应用程序本身)提供了更好的时间信息。
多路复用器
注意
在 Windows Vista 中,Media Foundation 管道不支持具有多个输入的 MCT。 Windows 7 支持多输入 MCT。
多路复用器将两个不同的音频或视频流合并为一种交错格式,例如 AVI 或 MPEG-2 传输流。 多路复用器应遵循以下准则:
多路复用器应遵循输出格式的约定。 如果格式通常不是每个样本的时间戳(如 MPEG-2 中所示),则并非每个输出样本都需要有时间戳和持续时间。
时间戳应反映将放置在从该数据包开始的任何帧上的最早时间,或将从该数据包解码的第一个音频样本的时间。 如果此准则与输出格式的约定冲突,请忽略此准则。
多路复用器
多路复用器将交错格式(如 AVI 或 MPEG-2 传输流)拆分为基础音频和视频流。
如果格式包含可用于根据输入时间戳计算准确输出时间戳的特定时间戳信息,则应使用该信息。 但是,如果格式包含与输入时间戳无关的完全不同的基数,并且无法计算输入时间戳的准确偏移量,则应忽略格式自己的时间。
如果格式没有可用时间戳信息,则多路复用器应遵循以下规则:
如果可能,未压缩的输出流应具有有效的时间戳和持续时间,这些时间戳是从最接近的上一个输入时间戳计算得出的。
压缩的输出流应仅在派生自具有时间戳的输入样本的第一个输出样本上具有时间戳。 如果输入样本没有时间戳,则派生自该输入样本的输出样本不应具有时间戳。 如果输入样本被分解为多个输出样本,则只有第一个输出样本应具有时间戳,而其他输出样本应没有时间戳。
示例
示例 1。 假设视频效果始终采用未压缩的输入帧,应用该效果并将其复制到输出。 它永远不会保留任何帧或缓冲任何输入。 此 MFT 只是将时间戳和持续时间从输入示例复制到输出示例(如果可用),并且根本不执行任何时间计算。
示例 2。 假设音频效果转换每个输入缓冲区的 10 毫秒 (毫秒) ,从而节省额外的 10 毫秒以与下一个缓冲区合并。 它获取所有持续时间为 50 毫秒的样本流。 下表显示了输入时间。
示例 | 输入时间 | 输入持续时间 | 输出时间 | 输出持续时间 |
---|---|---|---|---|
1 | 20 | 50 | 20 | 40 |
2 | 70 | 50 | 60 | 50 |
3 | 121 | 50 | 110 | 50 |
4 | 171 | 50 | 161 | 50 |
请注意样本 2 的实际持续时间与基于下一个时间戳的隐含持续时间之间的 1 毫秒差异 (121?70 = 51) 。
由于 MFT 会推迟 10 毫秒,因此它将输入样本 1 的前 40 毫秒输出为输出样本 1,时间戳为 20 毫秒,持续时间为 40 毫秒。
输出样本 2 将之前保留的 10 毫秒与输入样本 2 的 40 毫秒相结合。 此示例的时间戳为 60 毫秒, (上一个输入样本的时间戳(20 毫秒),加上已从该样本处理的数据的持续时间,) 40 毫秒。 它的持续时间为 50 毫秒。
同样,下一个示例的时间戳为 110 毫秒 (70 毫秒 + 40 毫秒) ,持续时间为 50 毫秒。
下一个计算更有趣。 上一个输出时间和持续时间的隐含时间戳为 160 毫秒 (时间戳 110 毫秒 + 持续时间 50 毫秒) 。 但是,输出时间戳应根据最早输入样本的输入时间戳计算,该时间戳与输出样本的时间重叠,以及已从该样本处理的任何数据的长度。 最接近的重叠输入样本是样本 4 (时间戳 = 171) ,但这不是最早的。 最早的重叠示例是示例 3 (时间戳 = 121) 。 加上已从该样本处理的 40 毫秒,结果为 161。
相关主题