天天看点

[DirectShow] 023 - Live Sources

A live source, also called a push source , receives data in real time. Examples include video capture and network broadcasts. In general, a live source cannot control the rate at which data arrives

live source 也叫做 push source ,实时接收数据。例子包含视频采集和网络传输。一般, live source 不能控制数据到达的速率。

A filter is considered to be a live source if either of the following are true:

如果下列之一为真,那 filter 就被看做是一个 live source :

·         The filter returns the AM_FILTER_MISC_FLAGS_IS_SOURCE flag from the IAMFilterMiscFlags::GetMiscFlags method, and at least one of its output pins exposes the IAMPushSource interface.

·         The filter exposes the IKsPropertySet interface and has a capture pin (PIN_CATEGORY_CAPTURE). See Pin Property Set for more information.

·         filter 从 IAMFilterMiscFlags::GetMiscFlages 方法返回 AM_FILTER_MISC_FLAGS_IS_SOURCE 标记,且至少有一个 output pin 暴露 IAMPushSource 接口。

·         filter 暴露 IKsPropertySet 接口且有一个 capture pin ( PIN_CATEGORY_CAPTURE )。

If a live source filter provides a clock, the Filter Graph Manager will prefer that clock when it chooses the graph reference clock. See Reference Clocks for more information.

如果 live source filter 提供一个时钟,当 Filter Graph Manager 选择 graph 参考时钟的时候会优先选择 live source filter 提供的。

A filter's latency is the amount of time it takes the filter to process a sample. For live sources, the latency is determined by the size of the buffer used to hold samples. For example, suppose the filter graph has a video source with a latency of 33 milliseconds (ms) and an audio source with a latency of 500 ms. Each video frame arrives at the video renderer about 470 ms before the matching audio sample reaches the audio renderer. Unless the graph compensates for the difference, the audio and video will not be synchronized.

filter 的 latency 是 filter 用来处理一个 sample 的时间量。对于 live source , latency 由用于处理 sample 的缓冲的大小决定。例如,假设 filter graph 有一个视频源的 latency 是 33 毫秒,一个音频源的 latency 是 500 毫秒,在匹配的音频 sample 到达音频 renderer 之前,每一个视频帧用了大概 470 毫毛到达视频 renderer 。除非 graph 补偿差异,否则音频和视频将不同步。

Live sources can be synchronized through the IAMPushSource interface. The Filter Graph Manager does not synchronize live sources unless the application enables synchronization by calling the IAMGraphStreams::SyncUsingStreamOffset method. If synchronization is enabled, the Filter Graph Manager queries each source filter for IAMPushSource . If the filter supports IAMPushSource , the Filter Graph Manager calls IAMLatency::GetLatency to retrieve the filter's expected latency. (The IAMPushSource interface inherits IAMLatency .) From the combined latency values, the Filter Graph Manager determines the maximum expected latency in the graph. It then calls IAMPushSource::SetStreamOffset to give each source filter a stream offset, which that filter adds to the time stamps that it generates.

live source 可以通过 IAMPushSource 接口同步。 Filter Graph Manager 不会去同步 live source ,除非应用程序调用 IAMGraphStreams::SyncUsingStreamOffset 方法使其能同步。如果同步使能, Filter Graph Manager 为 IAMPushSource 询问每一个 source filter 。如果 filter 支持 IAMPushSource , Filter Graph Manager 调用 IAMLatency::GetLatency 获得 filter 的预期 latency 。通过联合 latency values , Filter Graph Manager 可以决定 graph 中预期 laency 的最大值。调用 IAMPushSource::SetStreamOffset 给每一个 source filter 设置一个流偏移。

This method is intended primarily for live preview. However, note that a preview pin on a live capture device (such as a camera) does not set time stamps on the samples it delivers. Therefore, to use this method with a live capture device, you must preview from the capture pin. For more information, see DirectShow Video Capture Filters .

这个方法主要是为实时预览准备。不过记住,实时采集设备不会在它传递的 sample 上设置时间戳。因此,在实时采集设备上使用这种方法,就必须在采集 pin 上预览。

Currently the IAMPushSource interface is supported by the VFW Capture filter and the Audio Capture filter.

当前, IAMPushSource 接口被 VFW Capture filter 和 Audio Capture filter 支持。

If a renderer filter schedules samples using one reference clock, but the source filter produces them using a different clock, glitches can occur in playback. The renderer might run faster than the source, causing gaps in the data. Or it might run slower than the source, causing samples to "bunch up," until at some point the graph will drop samples. Typically, a live source cannot control its production rate, so instead the renderer should match rates with the source.

如果 renderer filter 使用一个参考时钟安排 sample , source filter 使用不同的时钟生产 sample ,那么回放就有可能发生差错。 renderer 有可能运行的比 source filter 快,原因是数据有间隔。也可能比 source filter 慢,原因是 sample 都挤到了一起, graph 将丢掉之前的一些 sample 。 live source 不能控制生产速率,所以 renderer 需要与 source 匹配速率。

Currently, only the audio renderer performs rate matching, because glitches in audio playback are more noticeable than glitches in video. To perform rate-matching, the audio renderer must select something against which it will match rates. It uses the following algorithm:

目前,只有音频 renderer 执行速率匹配,因为音频回放中的差错比视频中的明显。要执行速率匹配,音频 renderer 必须选择一些反对它匹配速率的事情:

·         If the graph is not using a reference clock, the audio renderer does not try to match rates. (Whenever the graph has no reference clock, samples are always rendered immediately as they arrive.)

·         Otherwise, if there is a reference clock for the graph, the audio renderer checks whether there is a live source upstream, using the criteria described previously. If not, the audio renderer does not match rates.

·         If there is a live source upstream, and that source exposes the IAMPushSource interface on its output pin, the audio renderer calls IAMPushSource::GetPushSourceFlags . It looks for one of the following flags:

·         AM_PUSHSOURCECAPS_INTERNAL_RM. This flag means the source filter has its own rate-matching mechanism, so the audio renderer does not match rates.

·         AM_PUSHSOURCECAPS_NOT_LIVE. This flag means the source filter is not really a live source, even though it exposes the IAMPushSource interface. Therefore, the audio renderer does not match rates.

·         AM_PUSHSOURCECAPS_PRIVATE_CLOCK. This flag means the source filter is using a private clock to generate time stamps. In this case, the audio renderer matches rates against the time stamps. (If the samples have no time stamps, however, the renderer ignores this flag.)

·         If GetPushSourceFlags returns no flags (zero), the audio renderer's behavior depends on the graph clock and whether the samples have time stamps:

·         If the audio renderer is not the graph clock, and the samples have time stamps, the audio renderer matches rates against the time stamps.

·         If the samples do not have time stamps, the audio renderer tries to match the rate of incoming audio data.

·         If the audio renderer is the graph clock, it tries to match the incoming data rate.

·         如果 graph 没有使用参考时钟,音频 renderer 不尝试速率匹配。(当 graph 没有参考时钟的时候, sample 总是在到达的时候立即播放。)

·         否则,如果 graph 有参考时钟,音频 renderer 使用先前描述的标准检测是否有 live source 。如果没有,音频 renderer 不进行速率匹配。

·         如果存在 live source ,并且 source 在 output pin 导出 IAMPushSource 接口,那么音频 renderer 调用 IAMPushSource::GetPushSourceFlages 获得标记,标记内容如下:

·         AM_PUSHSOURCECAPS_INTERNAL_RM 。这个标记意味 source filter 有自己的速率匹配机制,因此音频 renderer 不进行速率匹配。

·         AM_PUSHSOURCECAPS_NOT_LIVE 。这个标记意味 source filter 不是真实的 live source ,只是暴露了 IAMPushSource 接口。因此,音频 renderer 不匹配速率。

·         AM_PUSHSOURCECAPS_PRIVATE_CLOCK 。这个标记意味 source filter 使用私有时钟生成时间戳。在这种情况下,音频 renderer 匹配速率替换时间戳。(如果 sample 没有时间戳, renderer 忽略这个标记。)

·         如果 GetPushSourceFlags 返回 0 ,那么音频 renderer 的行为就依赖于 graph 的时钟和 sample 释放有时间戳:

·         如果音频 renderer 不是 graph 时钟,且 sample 有时间戳,那么音频 renderer 匹配速率不使用时间戳。

·         如果 sample 没有时间戳,音频 renderer 尝试匹配刚刚到来数据的速率。

·         如果音频 renderer 是 graph 时钟,它将尝试匹配刚刚到来的数据的速率。

The reason for the last case is the following: If the audio renderer is the reference clock, and the source filter is using the same clock to generate time stamps, then the audio renderer cannot match rates against the time stamps. If it did, in effect it would be trying to match rates with itself, which could cause the clock to drift. Therefore, in this case the renderer matches the rate of incoming audio data.

最后一种情况是:如果音频 renderer 是参考时钟,且 source filter 使用同样的时钟产生时间戳,那么音频 renderer 不能匹配速率。如果它匹配速率,实际上它是在与自己匹配速率。因此,这种情况下 renderer 匹配刚刚到来的音频数据的速率。

继续阅读