篩選狀態
[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、imfMediaEngine 取代,並在媒體基金會 音訊/視訊擷取。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayer、IMFMediaEngine 和 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]
篩選條件有三種可能的狀態:已停止、暫停及執行。 暫停狀態的目的是在圖形中提示數據,讓執行命令立即回應。 Filter Graph Manager 會控制所有狀態轉換。 當應用程式呼叫 IMediaControl::Run、IMediaControl::P ause或 IMediaControl::Stop時,Filter Graph Manager 會在所有篩選上呼叫對應的 IMediaFilter 方法。 停止與執行之間的轉換一律會經歷暫停的狀態,因此,如果應用程式在已停止的圖形上呼叫 Run,Filter Graph Manager 會在執行圖形之前暫停圖形。
對於大多數篩選條件,執行中和暫停的狀態都相同。 請考慮下列篩選圖表:
來源 > 轉換 > 轉譯器
假設目前來源篩選不是即時擷取來源。 當來源篩選暫停時,它會建立一個線程來產生新的數據,並儘快寫入媒體範例。 線程會在轉換篩選器的輸入釘選上呼叫 IMemInputPin::Receive,以「推送」下游範例。 轉換篩選會接收來源篩選線程上的範例。 它可能會使用背景工作線程將範例傳遞至轉譯器,但通常會在相同的線程上傳遞它們。 當轉譯器暫停時,它會等候接收範例。 收到一個之後,它會無限期地封鎖並保留該範例。 如果是視訊轉譯器,則會將範例顯示為海報影像,並視需要重新繪製影像。
此時,數據流已完全提示並準備好轉譯。 如果圖表維持暫停狀態,範例會在第一個範例後面的圖表中「堆積」,直到 Receive 或 IMemAllocator::GetBuffer中封鎖每個篩選。 不過,不會遺失任何數據。 解除封鎖來源線程之後,它只會從封鎖的點繼續執行。
來源篩選和轉換篩選會忽略從暫停到執行中的轉換,它們只會盡可能快速地處理數據。 但是當轉譯器執行時,它會開始轉譯範例。 首先,它會呈現暫停時所保留的樣本。 然後,每次收到新的範例時,都會計算範例的呈現時間。 (如需詳細資訊,請參閱 DirectShow 中的時間和時鐘。轉譯器會保留每個範例,直到呈現時間為止,此時會轉譯範例。 當它等候簡報時間時,它會在 Receive 方法中封鎖,或接收具有佇列的背景工作線程的新範例。 來自轉譯器的上游篩選不涉及排程。
實時來源,例如擷取裝置,是這個一般架構的例外狀況。 使用即時來源時,並不適合事先提示任何數據。 應用程式可能會暫停圖形,然後在執行圖形之前等候很長的時間。 圖形不應該轉譯「過時」範例。 因此,即時來源只會在執行時,在暫停時不會產生任何範例。 若要向 Filter Graph 管理員發出這個訊號,來源篩選 IMediaFilter::GetState 方法會傳回VFW_S_CANT_CUE。 此傳回碼表示即使轉譯器未收到任何數據,篩選條件還是已切換至暫停狀態。
當篩選停止時,它會拒絕傳遞給它的任何樣本。 來源篩選會關閉其串流線程,而其他篩選會關閉他們可能建立的任何背景工作線程。 針腳會將其配置器取消認可。
狀態轉換
Filter Graph 管理員會依上游順序執行所有狀態轉換,從轉譯器開始,並回溯至來源篩選。 這個順序是必要的,以防止樣本被卸除,以及防止圖形死結。 最重要的狀態轉換是在暫停和停止之間:
- 已停止以暫停:當每個篩選暫停時,它便準備好接收下一個篩選條件中的樣本。 來源篩選條件是最後一個要暫停的篩選條件。 它會建立串流線程並開始傳遞範例。 由於所有下游篩選都已暫停,因此沒有任何篩選條件會拒絕任何樣本。 篩選圖形管理員不會完成轉換,直到圖形中的每個轉譯器都收到範例(但實時來源除外,如先前所述)。
- 暫停至已停止:當篩選停止時,它會釋放它保留的任何範例,這會解除封鎖任何在 getBuffer 中等候的上游篩選,。 如果篩選條件正在等候 Receive 方法內的資源,它會停止等候,並從 Receive傳回 ,這會解除封鎖呼叫的篩選條件。 因此,當 Filter Graph Manager 停止下一個上游篩選時,該篩選不會 在 getBuffer 或 Receive中封鎖,而且可以回應 stop 命令。 上游篩選條件可能會在取得 stop 命令之前提供一些額外的範例,但下游篩選條件只會拒絕它們,因為它已經停止。
相關主題
-
篩選圖表中的 數據流