时间戳

[与此页面关联的功能(DirectShow)是一项旧功能。 它已被 MediaPlayerIMFMediaEngine取代,并在媒体基金会 音频/视频捕获。 这些功能已针对 Windows 10 和 Windows 11 进行了优化。 Microsoft强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获,而不是 DirectShow。 Microsoft建议重写使用旧 API 的现有代码,以尽可能使用新 API。]

时间戳 定义媒体样本的开始和完成时间(以流时间为单位)。 时间戳有时称为 表示时间。 阅读本文的其余部分时,请务必记住并非所有格式都以相同的方式使用时间戳。 例如,并非所有 MPEG 示例都带有时间戳。 在 MPEG 筛选器图中,在解码器输出时间戳之前,不会将时间戳应用于每个帧。

当呈现器筛选器收到示例时,它会根据时间戳计划呈现。 如果样本迟到或没有时间戳,筛选器会立即呈现样本。 否则,筛选器将等到示例开始时间之后才会呈现示例。 (它通过调用 IReferenceClock::AdviseTime 方法等待开始时间。

源筛选器和分析程序筛选器负责在处理的示例上设置正确的时间戳。 使用以下准则。

  • 文件播放:第一个示例为时间戳,开始时间为零。 后续时间戳由样本长度和播放速率确定,后者本身由文件格式确定。 分析文件的筛选器负责计算正确的时间戳(例如,AVI 拆分器)。
  • 视频和音频捕获:每个示例的时间戳与捕获的流时间相等,并注意以下事项:
    • 预览图钉(而不是捕获引脚)中的视频帧不会加时间戳。 由于图形延迟,带有捕获时间标记的视频帧将始终晚到达视频呈现器。 这可能会导致呈现器在进行质量控制时删除帧。 有关质量控制的信息,请参阅 Quality-Control 管理
    • 音频捕获:音频捕获筛选器使用自己的缓冲区集,这些缓冲区与音频驱动程序使用的缓冲区分开。 音频驱动程序按固定间隔填充捕获筛选器的缓冲区。 间隔取决于驱动程序,但通常不超过 10 毫秒。 音频样本上的时间戳反映了驱动程序填充音频捕获筛选器缓冲区的时间。 这些时间可能稍微不准确,尤其是在应用程序使用非常小的缓冲区大小时。 但是,媒体时间将准确反映缓冲区中的音频样本数。
  • 复用筛选器:根据输出格式,复用筛选器可能需要生成时间戳,也可能不需要。 例如,AVI 文件格式使用没有时间戳的固定帧速率,因此 AVI Mux 筛选器假定样本大约在正确的时间到达。 但是,如果传入时间戳显示大于一个帧的间隙,AVI Mux 将写入一个索引条目,其大小为零,以指示删除的帧。 在文件播放时,会在运行时生成新的时间戳,如前所述。

若要在示例上设置时间戳,请调用 IMediaSample::SetTime 方法。

媒体时报

(可选)筛选器还可以为示例指定 媒体时间。 在视频流中,媒体时间表示帧数。 在音频流中,媒体时间表示数据包中的样本编号。 例如,如果每个数据包包含 44.1 千赫(kHz)音频中的一秒,则第一个数据包的媒体开始时间为零,媒体停止时间为 44100。 在可查找流中,媒体时间始终相对于流的开始时间。 例如,假设你从 15 fps 视频流的开头寻求 2 秒。 查找后的第一个媒体示例的时间戳为零,但媒体时间为 30。

呈现器和复用器筛选器可以使用媒体时间通过检查间隙来确定帧或样本是否已删除。 但是,不需要筛选器来设置媒体时间。 若要在示例上设置媒体时间,请调用 IMediaSample::SetMediaTime 方法。

DirectShow 中的 时间和时钟