共用方式為


傳遞範例

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

本文說明篩選如何傳遞範例。 它描述推送模型、使用 IMemInputPin 方法,以及使用 IAsyncReader的提取模型。

推送模型:傳遞範例

輸出釘選會藉由呼叫 IMemInputPin::Receive 方法或 IMemInputPin::ReceiveMultiple 方法來傳遞範例,此方法是相等的,但會傳遞樣本陣列。 輸入針腳可以在 Receive (或 ReceiveMultiple) 內封鎖。 如果 pin 可能會封鎖,其 IMemInputPin::ReceiveCanBlock 方法應該會傳回S_OK。 如果針腳保證永遠不會封鎖, ReceiveCanBlock 應該會傳回S_FALSE。 S_OK傳回值並不表示 Receive 一律會封鎖,只是可能。

雖然 Receive 可以封鎖以等候資源變成可用狀態,但不應該封鎖以等候上游篩選準則中的更多資料。 這樣做可能會導致上游篩選等候下游篩選準則釋放範例的死結,因為下游篩選正在等候上游篩選,所以永遠不會發生。 不過,如果篩選有多個輸入針腳,一個針腳可以等候另一個針腳接收資料。 例如, AVI Mux 篩選器會執行這項作業,使其可以交錯音訊和視訊資料。

針腳可能會因為許多原因而拒絕範例:

  • 針腳正在排清 (請參閱 清) 。
  • 針腳未連線。
  • 篩選已停止。
  • 發生其他錯誤。

Receive方法應該在第一個案例中傳回S_FALSE,在其他案例中則傳回失敗碼。 當傳回碼不是S_OK時,上游篩選應該停止傳送樣本。

您可以將前三個案例視為「預期」失敗,也就是說,篩選準則處於錯誤的狀態以接收樣本。 即使針腳處於接收狀態,也會導致針腳拒絕樣本的意外失敗。 如果發生此類型的錯誤,針腳應該傳送資料流程結束通知下游,並將 EC_ERRORABORT 事件傳送至篩選圖形管理員。

在 DirectShow 基類中, CBaseInputPin::CheckStreaming 方法會檢查一般失敗案例—排清、停止等等。 衍生類別必須檢查篩選的特定失敗。 如果發生錯誤, CBaseInputPin::Receive 方法會傳送串流結束通知和EC_ERRORABORT事件。

提取模型:要求範例

IAsyncReader 介面中,輸入針腳會藉由呼叫下列其中一種方法,從輸出針腳要求範例:

Request方法是非同步;輸入針腳會呼叫IAsyncReader::WaitForNext以等候要求完成。 其他兩種方法是同步的。

傳遞資料的時機

篩選準則一律會在處於執行中狀態時提供樣本。 在大部分情況下,篩選準則也會在暫停時提供樣本。 這可讓圖表提示資料,以便在呼叫 Run 時立即啟動播放, (請參閱 篩選狀態) 。 如果您的篩選在暫停時未傳遞資料,篩選準則的 IMediaFilter::GetState 方法應該會傳回處於暫停狀態VFW_S_CANT_CUE。 此傳回碼會向篩選圖形發出訊號,使其在完成暫停轉換之前,不會等待篩選準則中的資料。 否則, Pause 方法將會無限期地封鎖。 如需範例程式碼,請參閱 CBaseFilter::GetState

以下是篩選準則可能需要傳回VFW_S_CANT_CUE的一些範例:

  • 即時來源,例如擷取篩選,不應該在暫停時傳送資料。 請參閱 在擷取篩選中產生資料
  • 視實作而定,分割器篩選準則可能會在暫停時或可能不會傳送資料。 如果篩選準則使用個別的執行緒來排入每個輸出釘選上的資料佇列,則可以在暫停時傳送資料。 但是,如果篩選準則針對每個輸出針腳使用單一線程,則第一個針腳可能會在呼叫 Receive時封鎖執行緒,這可防止其他針腳傳送資料。 在此情況下,您應該傳回VFW_S_CANT_CUE。
  • 篩選可能會偶爾傳遞資料。 例如,它可能會剖析自訂資料流程,並在傳遞其他封包時篩選掉某些封包。 在此情況下,可能無法保證在暫停時傳遞資料。

使用推送模型) 或剖析器篩選 (使用推送/提取模型 (來源篩選) 建立一或多個串流執行緒,以儘快傳遞範例。 下游篩選準則,例如解碼器和轉換,通常只有在在其輸入針腳上呼叫 Receive 時才會傳送資料。

接收和傳遞範例