Share via


篩選狀態

[與此頁面相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議使用舊版 API 的現有程式碼盡可能重寫為使用新的 API。

篩選準則有三種可能的狀態:已停止、暫停和執行。 暫停狀態的目的是要提示圖形中的資料,讓執行命令立即回應。 篩選圖形管理員會控制所有狀態轉換。 當應用程式呼叫 IMediaControl::RunIMediaControl::P auseIMediaControl::Stop時,篩選圖形管理員會在所有篩選準則上呼叫對應的 IMediaFilter 方法。 在已停止和執行之間轉換一律會經歷暫停狀態,因此,如果應用程式在已停止的圖形上呼叫 [ 執行 ] ,篩選圖形管理員會在執行圖形之前暫停圖形。

對於大部分篩選準則,執行中和暫停的狀態都相同。 請考慮下列篩選圖表:

來源 > 轉換 > 轉譯器

假設現在來源篩選不是即時擷取來源。 當來源篩選暫停時,它會建立一個執行緒來產生新的資料,並儘快寫入媒體範例。 執行緒會在轉換篩選器的輸入針腳上呼叫 IMemInputPin::Receive ,以「推送」下游的範例。 轉換篩選準則會接收來源篩選執行緒上的範例。 它可能會使用背景工作執行緒將樣本傳遞至轉譯器,但通常會在相同的執行緒上傳遞它們。 當轉譯器暫停時,它會等候接收樣本。 收到一個之後,它會無限期封鎖並保留該樣本。 如果是視訊轉譯器,它會將範例顯示為海報影像,視需要重新繪製影像。

此時,資料流程已完全提示並準備好進行轉譯。 如果圖表保持暫停狀態,則樣本會在第一個範例後面的圖形中「堆積」,直到 接收IMemAllocator::GetBuffer中封鎖每個篩選。 不過,不會遺失任何資料。 一旦解除封鎖來源執行緒,它只會從封鎖的點繼續。

來源篩選和轉換篩選會忽略從暫停到執行中的轉換—它們只會盡可能繼續處理資料。 但是當轉譯器執行時,它會開始轉譯範例。 首先,它會呈現暫停時所保留的樣本。 然後,每次收到新的樣本時,都會計算樣本的呈現時間。 (如需詳細資訊,請參閱 DirectShow.) 轉譯器會保留每個樣本,直到呈現範例為止。 當它等候簡報時間時,它會在 Receive 方法中封鎖,或使用佇列在背景工作執行緒上接收新的範例。 轉譯器上游的篩選不會涉及排程。

擷取裝置等即時來源是這個一般架構的例外狀況。 使用即時來源時,不適合事先提示任何資料。 應用程式可能會暫停圖形,然後在執行圖形之前等候很長的時間。 圖形不應該轉譯「過時」樣本。 因此,即時來源在暫停時不會產生任何樣本,只在執行時才會產生。 若要向 Filter Graph 管理員發出這項訊號,來源篩選的 IMediaFilter::GetState 方法會傳回VFW_S_CANT_CUE。 此傳回碼表示篩選已切換為暫停狀態,即使轉譯器未收到任何資料也一樣。

當篩選停止時,它會拒絕傳遞給它的任何更多樣本。 來源篩選會關閉其串流執行緒,而其他篩選會關閉他們可能已建立的任何背景工作執行緒。 針腳會取消認可其配置器。

狀態轉換

篩選圖形管理員會依上游循序執行所有狀態轉換,從轉譯器開始,並回溯至來源篩選。 此順序是必要的,以防止樣本遭到卸載,以及防止圖形死結。 最重要的狀態轉換是在暫停和停止之間:

  • 已停止以暫停:當每個篩選暫停時,它就已準備好接收下一個篩選準則中的範例。 來源篩選準則是最後一個暫停。 它會建立串流執行緒並開始傳遞範例。 因為所有下游篩選都會暫停,所以沒有任何篩選會拒絕任何樣本。 篩選圖形管理員在圖表中的每個轉譯器都收到範例 (,但即時來源除外,如先前) 所述,否則不會完成轉換。
  • 暫停停止:當篩選停止時,它會釋放它保留的任何範例,以解除封鎖 在 GetBuffer中等候的任何上游篩選。 如果篩選準則正在等候 Receive 方法內的資源,它會停止等候並從 Receive傳回,這會解除封鎖呼叫篩選準則。 因此,當 Filter Graph 管理員停止下一個上游篩選時,該篩選不會在 GetBufferReceive中遭到封鎖,而且可以回應 stop 命令。 上游篩選器可能會在取得 stop 命令之前提供一些額外的範例,但下游篩選只會拒絕它們,因為它已經停止。

篩選圖形中的資料流程