共用方式為


排清數據

[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngine和媒體基礎架構中的 音訊/視頻擷取所取代。 這些功能已針對 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 方法會採用篩選鎖定,以串行化狀態變更。 由於清空操作在應用程式線程上執行,而串流線程可能正處於執行 接收 呼叫的過程中,因此進行串流鎖定尚不安全。 針腳必須保證 接收 不會被封鎖,並確保任何後續對 接收 的呼叫都將失敗。 CBaseInputPin::BeginFlush 方法會設定內部旗標,CBaseInputPin::m_bFlushing。 當旗標 TRUE時,Receive 方法會失敗。

透過將 BeginFlush 調用傳送到下游,該接口可確保所有下游濾鏡釋放它們的樣本,並從 Receive 調用中返回。 這進一步保證輸入腳位不會遭到封鎖,等待 GetBufferReceive。 如果您的釘選 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的最後一個步驟,因為在排清完成且所有下游濾鏡收到通知之後,針腳才能接收任何樣本。

線程和重要區段