时间戳
[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayer、 IMFMediaEngine 和 媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
时间戳定义媒体样本的开始和完成时间,以流时间度量。 时间戳有时称为 呈现时间。 阅读本文的其余部分时,请务必记住,并非所有格式都以相同的方式使用时间戳。 例如,并非所有 MPEG 样本都带有时间戳。 在 MPEG 筛选器图中,时间戳不会应用于每个帧,直到它们从解码器输出。
当呈现器筛选器收到示例时,它会根据时间戳计划呈现。 如果样本迟到或没有时间戳,筛选器将立即呈现样本。 否则,筛选器将等到示例的开始时间,然后才呈现示例。 (它通过调用 IReferenceClock::AdviseTime 方法等待开始时间。)
源筛选器和分析程序筛选器负责为其处理的样本设置正确的时间戳。 请遵循以下准则。
- 文件播放:第一个示例带有时间戳,开始时间为零。 后续时间戳由样本长度和播放速率决定,后者本身由文件格式决定。 分析文件的筛选器负责计算正确的时间戳, (例如 AVI 拆分器) 。
- 视频和音频捕获:每个样本都标有时间戳,其开始时间等于捕获时的流时间,但需要注意以下事项:
- 预览引脚中的视频帧 (而不是捕获引脚) 没有时间戳。 由于图形延迟,带有捕获时间标记的视频帧将始终晚于视频呈现器到达。 这可能会导致呈现器在试图进行质量控制时删除帧。 有关质量控制的信息,请参阅 质量控制管理。
- 音频捕获:音频捕获筛选器使用自己的一组缓冲区,这些缓冲区与音频驱动程序使用的缓冲区是分开的。 音频驱动程序按固定间隔填充捕获筛选器的缓冲区。 间隔取决于驱动程序,但通常不超过 10 毫秒。 音频样本上的时间戳反映了驱动程序填充音频捕获筛选器缓冲区的时间。 这些时间可能略有不准确,尤其是在应用程序使用非常小的缓冲区时。 但是,媒体时间将准确反映缓冲区中的音频样本数。
- 复用筛选器:根据输出格式,多路复用筛选器可能需要生成时间戳,也可能不需要生成时间戳。 例如,AVI 文件格式使用没有时间戳的固定帧速率,因此 AVI Mux 筛选器假定样本在大约正确的时间到达。 但是,如果传入时间戳显示大于一帧的间隙,AVI 复用器会写入一个索引条目,其大小为零,以指示丢弃的帧。 在文件播放时,会在运行时生成新的时间戳,如前所述。
若要在示例上设置时间戳,请调用 IMediaSample::SetTime 方法。
媒体时报
(可选)筛选器还可以指定样本的 媒体时间 。 在视频流中,媒体时间表示帧数。 在音频流中,媒体时间表示数据包中的样本数。 例如,如果每个数据包包含 44.1 千赫 (kHz) 音频的 1 秒,则第一个数据包的媒体开始时间为 0,媒体停止时间为 44100。 在可查找流中,媒体时间始终相对于流的开始时间。 例如,假设你从 15-fps 视频流的开始时间开始 2 秒。 搜寻后的第一个媒体样本的时间戳为零,但媒体时间为 30。
呈现器和复用器筛选器可以使用媒体时间,通过检查间隙来确定帧或样本是否已丢弃。 但是,不需要筛选器来设置媒体时间。 若要在示例上设置媒体时间,请调用 IMediaSample::SetMediaTime 方法。