排清數據
[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、IMFMediaEngine和媒體基礎架構中的 音訊/視頻擷取所取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 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 方法會採用篩選鎖定,以串行化狀態變更。 由於清空操作在應用程式線程上執行,而串流線程可能正處於執行 接收 呼叫的過程中,因此進行串流鎖定尚不安全。 針腳必須保證 接收 不會被封鎖,並確保任何後續對 接收 的呼叫都將失敗。 CBaseInputPin::BeginFlush 方法會設定內部旗標,CBaseInputPin::m_bFlushing。 當旗標 TRUE時,Receive 方法會失敗。
透過將 BeginFlush 調用傳送到下游,該接口可確保所有下游濾鏡釋放它們的樣本,並從 Receive 調用中返回。 這進一步保證輸入腳位不會遭到封鎖,等待 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的最後一個步驟,因為在排清完成且所有下游濾鏡收到通知之後,針腳才能接收任何樣本。
相關主題