刷新数据
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
以下伪代码演示如何实现 IPin::BeginFlush 方法:
HRESULT CMyInputPin::BeginFlush()
{
CAutoLock lock_it(m_pLock);
// First, make sure the Receive method will fail from now on.
HRESULT hr = CBaseInputPin::BeginFlush();
// Force downstream filters to release samples. If our Receive method
// is blocked in GetBuffer or Deliver, this will unblock it.
for (each output pin)
{
hr = pOutputPin->DeliverBeginFlush();
}
// Unblock our Receive method if it is waiting on an event.
SetEvent(m_hSomeEventThatReceiveNeedsToWaitOn);
// At this point, the Receive method can't be blocked. Make sure
// it finishes, by taking the streaming lock. (Not necessary if this
// is the last step.)
{
CAutoLock lock_2(&m_csReceive);
/* Now it's safe to do anything that would crash or hang
if Receive were executing. */
}
return hr;
}
刷新开始时, BeginFlush 方法采用筛选器锁,该锁将序列化状态更改。 使用流式处理锁尚不安全,因为刷新发生在应用程序线程上,并且流式处理线程可能正在 接收 调用中。 引脚需要保证 Receive 不会被阻止,并且对 Receive 的任何后续调用都将失败。 CBaseInputPin::BeginFlush 方法设置内部标志 CBaseInputPin::m_bFlushing。 当标志为 TRUE 时, Receive 方法将失败。
通过向下游传递 BeginFlush 调用,引脚可以保证所有下游筛选器释放其示例并从 接收 调用返回。 这反过来又保证不会阻止输入引脚等待 GetBuffer 或 Receive。 例如,如果固定的 Receive 方法曾经等待事件 (获取资源) , 则 BeginFlush 方法应通过设置事件来强制等待终止。 此时, Receive 方法保证返回, 并且 m_bFlushing 标志会阻止新的 Receive 调用执行任何工作。
对于某些筛选器,这只需 BeginFlush 即可完成。 EndFlush 方法将向筛选器发出信号,表明它可以再次开始接收样本。 其他筛选器可能需要在 BeginFlush 中使用也在 Receive 中使用的变量或资源。 在这种情况下,筛选器应首先保留流式处理锁。 请确保不要在上述任何步骤之前执行此操作,因为可能会导致死锁。
EndFlush 方法保留筛选器锁,并将调用传播到下游:
HRESULT CMyInputPin::EndFlush()
{
CAutoLock lock_it(m_pLock);
for (each output pin)
hr = pOutputPin->DeliverEndFlush();
return CBaseInputPin::EndFlush();
}
CBaseInputPin::EndFlush 方法将m_bFlushing标志重置为 FALSE,这允许 Receive 方法再次开始接收样本。 这应该是 EndFlush 中的最后一步,因为引脚在刷新完成并通知所有下游筛选器之前不得接收任何样本。
相关主题