DirectShow实时源
实时源(也称为推送push源)实时接收数据。示例包括视频捕获和网络广播。通常,活动源无法控制数据到达的速率。
如果满足以下任一条件,则筛选器被视为实时源:
- 过滤器从IAMFilterMiscFlags::GetMiscFlags方法返回AM_FILTER_MISC_FLAGS_IS_SOURCE标志,并且至少有一个输出管脚公开IAMPushSource接口。
- 过滤器公开IKsPropertySet接口并具有一个捕获pin(PIN_CATEGORY_CAPTURE)。有关详细信息,请参见接点特性集。
如果实时源筛选器提供时钟,则筛选器图形管理器在选择图形参考时钟时将首选该时钟。
延迟
过滤器的延迟是过滤器处理Sample所需的时间量。对于实时源,延迟由用于保存样本的缓冲区大小决定。例如,假设滤波器图具有延迟为33毫秒(ms)的视频源和延迟为500毫秒的音频源。在匹配音频Sample到达音频渲染器之前,每个视频帧到达视频呈现器约470毫秒。除非图形补偿了差异,否则音频和视频将不会同步。
可以通过IAMPushSource接口同步实时源。除非应用程序通过调用IAMGraphStreams::SyncUsingStreamOffset方法启用同步,否则筛选器图形管理器不会同步实时源。如果启用了同步,则过滤器图形管理器将查询每个源过滤器中的IAMPushSource。如果筛选器支持IAMPushSource,则筛选器图形管理器将调用IAMPlastency::GetLatency来检索筛选器的预期延迟。(IAMPushSource接口继承IAMPlastency。)根据组合的延迟值,筛选器图形管理器确定图形中的最大预期延迟。然后,它调用IAMPushSource::SetStreamOffset为每个源过滤器提供一个流偏移量,该过滤器将该偏移量添加到它生成的时间戳中。
此方法主要用于实时渲染。但是,请注意,实时捕获设备(如相机)上的预览pin不会在其提供的sample上设置时间戳。因此,要对实时捕获设备使用此方法,必须从捕获pin进行预览。
速率匹配
如果渲染器过滤器使用一个参考时钟调度采样,但源过滤器使用不同的时钟生成采样,则回放时可能会出现故障。渲染器可能比源运行得更快,从而导致数据中出现间隙。或者它可能比源运行得慢,导致Sample“聚集”,直到在某个点图形将丢弃样本。通常,实时源无法控制其生产速率,因此渲染器应该将速率与源匹配。
目前,只有音频渲染器执行速率匹配,因为音频播放中的故障比视频中的故障更明显。要执行速率匹配,音频渲染器必须选择与速率匹配的内容。它使用以下算法:
- 如果图形未使用参考时钟,则音频渲染器不会尝试匹配速率。(每当图形没有参考时钟时,采样总是在到达时立即渲染。)
- 否则,如果图形有一个参考时钟,音频渲染器将使用前面描述的条件检查上游是否有一个活动源。如果不匹配,则音频渲染器与速率不匹配。
- 如果上游有一个活动源,并且该源在其输出pin上公开了IAMPushSource接口,则音频呈现器将调用IAMPushSource::GetPushSourceFlags。它查找以下标志之一:
- AM_PUSHSOURCECAPS_INTERNAL_RM:此标志表示源过滤器有自己的速率匹配机制,因此音频渲染器不匹配速率。
- AM_PUSHSOURCECAPS_NOT_LIVE:这个标志意味着源过滤器不是真正的活动源,即使它公开了IAMPushSource接口。因此,音频渲染器与速率不匹配。
- AM_PUSHSOURCECAPS_PRIVATE_CLOCK:此标志表示源筛选器正在使用专用时钟生成时间戳。在这种情况下,音频渲染器根据时间戳匹配速率。(但是,如果采样没有时间戳,渲染器将忽略此标志。)
- 如果GetPushSourceFlags不返回任何标志(零),则音频呈现器的行为取决于图形时钟以及示例是否具有时间戳:
- 如果音频渲染器不是图形时钟,并且采样具有时间戳,则音频渲染器将速率与时间戳匹配。
- 如果采样没有时间戳,音频渲染器将尝试匹配传入音频数据的速率。
- 如果音频渲染器是图形时钟,它将尝试匹配传入的数据速率。
最后一种情况的原因如下:如果音频渲染器是参考时钟,并且源过滤器使用相同的时钟来生成时间戳,那么音频渲染器无法根据时间戳匹配速率。如果真的这样做了,实际上它将试图使利率与自身相匹配,这可能导致时钟漂移。因此,在这种情况下,渲染器匹配传入音频数据的速率。