共用方式為


排清資料

[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 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 呼叫下游,針腳可確保所有下游篩選都會釋放其範例,並從 接收 呼叫傳回。 接著,這可確保不會封鎖輸入針腳等候 GetBufferReceive。 例如,如果您釘選的 Receive 方法曾等候事件 (,若要取得資源) , BeginFlush 方法應該藉由設定事件來強制等候終止。 此時, Receive 方法保證會傳回, 而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的最後一個步驟,因為針腳必須等到排清完成且所有下游篩選都收到通知之後,才收到任何樣本。

執行緒和關鍵區段