共用方式為


傳遞樣品

[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngine,以及 Media 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傳回值並不表示 接收 一律封鎖,只是可能。

雖然 接收 可以封鎖以等候資源變得可用,但不應封鎖以等候來自上游過濾器的更多數據。 這樣做可能會導致死鎖,上游篩選會等候下游篩選釋放樣本,而這永遠不會發生,因為下游篩選在等候上游篩選。 不過,如果篩選有多個輸入針腳,一個接腳可以等候另一個針腳接收數據。 例如,AVI Mux 篩選器會執行此動作,使其可以交錯音訊和視訊數據。

針腳可能會因為許多原因而拒絕樣本:

  • 針腳正在清洗(請參閱 清洗)。
  • 引腳未連接。
  • 過濾器已停止。
  • 發生其他錯誤。

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

您可以將前三個案例視為「預期」失敗,因為濾波器處於錯誤狀態,無法正確接收樣本。 意外的失敗會導致針腳拒絕樣本,即使針腳處於接收狀態也是如此。 如果發生此類型的錯誤,管腳應該向下游傳送數據流結束通知,並將 EC_ERRORABORT 事件傳送至 Filter Graph 管理員。

在 DirectShow 基類中,CBaseInputPin::CheckStreaming 方法會檢查一般失敗案例,例如排清、停止等等。 衍生類別需要檢查過濾器特定的失敗情況。 發生錯誤時,CBaseInputPin::Receive 方法會傳送數據流結束通知和EC_ERRORABORT事件。

拉動模型:請求範例

IAsyncReader 介面中,輸入端子會呼叫下列其中一種方法,從輸出端子請求取樣:

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

何時傳遞數據

過濾器在執行狀態時會持續提供範例。 在大部分情況下,過濾器在暫停時也會提供樣本。 這可讓圖形提示數據,以便在呼叫 執行 時立即開始播放(請參閱 篩選狀態)。 如果您的篩檢器在暫停時未傳遞數據,篩檢器的 IMediaFilter::GetState 方法應該會在暫停狀態下返回 VFW_S_CANT_CUE。 此傳回碼指示過濾圖在完成暫停轉換之前,不要等候來自您的篩選器的數據。 否則,Pause 方法將會無限期封鎖。 如需範例程式代碼,請參閱 CBaseFilter::GetState

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

  • 實時來源,例如擷取篩選,不應該在暫停時傳送數據。 請參閱 在擷取篩選中產生的數據。
  • 分離器篩選器在暫停時可能會傳送數據,也可能不會,具體取決於實作。 如果過濾器使用個別的執行緒將數據放入每個輸出端的列隊中,則它可以在暫停時傳送數據。 但是,如果篩選器為每個輸出接腳使用單個執行緒,那麼第一個接腳在呼叫 Receive時可能會封鎖執行緒,這將阻止其他接腳發送數據。 在此情況下,您應該傳回VFW_S_CANT_CUE。
  • 篩選可能會偶爾傳遞數據。 例如,它可能會剖析自定義數據流,並在傳遞其他封包時篩選掉某些封包。 在此情況下,過濾器可能無法保證在暫停時傳遞資料。

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

接收和傳遞樣品