刷新数据

以下伪代码演示如何实现 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 的任何后续调用都将失败。 CBaseInputPin::BeginFlush 方法设置内部标志 CBaseInputPin::m_bFlushing。 当标志为 TRUE 时, Receive 方法将失败。

通过下游传递 BeginFlush 调用,引脚保证所有下游筛选器释放其样本并从 接收 呼叫返回。 这又保证输入引脚不会阻止等待 GetBufferReceive。 例如,如果 pin 的 Receive 方法在事件 (等待,若要获取资源) , BeginFlush 方法应通过设置事件强制等待终止。 此时,可以保证 接收 方法返回, m_bFlushing 标志会阻止新的 接收 调用执行任何工作。

对于某些筛选器,这是 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 中的最后一步,因为引脚在刷新完成后不得收到任何样本,并且所有下游筛选器都会收到通知。

线程和关键部分