[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、IMFMediaEngine以及媒體基金會中的音訊/視訊擷取 取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayer、IMFMediaEngine 和 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]
本節說明如何使用 DMO 處理數據流。 本節所列的步驟是默認行為;所有 DMO 都必須支援這裡所述的方法。 這些方法會針對輸入和輸出使用不同的緩衝區。 某些 DMO 也支援使用單一緩衝區就地處理。 如需就地處理的詳細資訊,請參閱 In-Place 處理。
配置緩衝區
用戶端負責所有緩衝區配置。 在 DMO 上設定媒體類型之後,請查詢 DMO 以取得每個數據流的緩衝區需求。 視媒體類型而定,這些可能會變更。 針對每個數據流,呼叫 IMediaObject::GetInputSizeInfo 或 IMediaObject::GetOutputSizeInfo 方法。 這些方法會傳回下列資訊:
- 最小緩衝區大小,以位元組為單位。
- 對齊需求,如有需要。 如果起始位址是某些指定整數的倍數,則會對齊緩衝區。
- DMO 會保留前視的資料量上限。 此數位僅適用於輸入數據流。 對於某些種類的數據(例如 MPEG 編碼),DMO 可能需要在數據流中向前看。 lookahead 值會指出 DMO 在產生輸出之前需要多少輸入數據。
客戶端必須配置符合這些需求的緩衝區。 此外,DMO 可能有用戶端如何封裝輸入數據的需求。 例如,DMO 可能需要每個緩衝區只包含一個範例(或視訊畫面)。 若要判斷這些需求,請呼叫 IMediaObject::GetInputStreamInfo 方法。 IMediaObject::GetOutputStreamInfo 方法會傳回輸出數據流的類似資訊。
在預設串流模型中,用戶端不會將原始緩衝區指標傳遞至 DMO。 相反地,它會使用輕量型 COM 物件來公開 IMediaBuffer 介面。 IMediaBuffer 介面可作為記憶體區塊的 COM 包裝函式。 因為它是 COM 物件,因此支持參考計數,這有助於確保緩衝區在仍在使用時不會釋放。
注意
IMediaBuffer 介面提供類似 DirectShow 中 IMediaSample 介面的函式。
用戶端必須實作 IMediaBuffer 物件。 如需詳細資訊,請參閱 實作 IMediaBuffer。
處理數據
若要處理資料,請執行下列動作:
- 針對每個輸入資料流,將輸入數據填入緩衝區。
- 呼叫 IMediaObject::P rocessInput 來傳遞每個緩衝區。
- 呼叫 IMediaObject::P rocessOutput 來處理數據。 這個方法會採用緩衝區陣列,每個輸出數據流各一個。
- 重複直到沒有其他輸入數據為止。
ProcessInput 方法一次接受一個數據流的輸入。 一般而言,方法會立即傳回,而 DMO 會保留 IMediaBuffer 對象的參考計數。 它會在處理完緩衝區中的所有資料後,或者在應用程式排清 DMO 時釋放物件。 在 DMO 釋放它之前,請勿重複使用緩衝區。 若要判斷輸入數據流是否可以接受更多數據,請呼叫 IMediaObject::GetInputStatus 方法。 如果數據流可以接受更多輸入,這個方法會傳回DMO_INPUT_STATUSF_ACCEPT_DATA旗標。
ProcessOutput 方法會一次性為所有的輸出流生成輸出。 應用程式會傳入一組 DMO_OUTPUT_DATA_BUFFER 結構,每個輸出流各一個。 陣列中的每個結構都有 IMediaBuffer 物件的指標。 DMO 會將盡可能多的輸出數據寫入緩衝區。 它也會設定各種旗標來報告作業的狀態。 DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE旗標表示 DMO 可以從現有的輸入產生更多輸出。 在此情況下,用戶端可以再次呼叫 ProcessOutput。 否則,它應該用更多的輸入數據來呼叫 ProcessInput。 DMO 絕不會修改輸入緩衝區中的數據;它只會寫入輸出緩衝區。
在將所有數據傳遞至輸入流之後,請呼叫 IMediaObject::Discontinuity 功能。 在您處理剩餘的輸出或排清 DMO 之前,DMO 不會接受該數據流的進一步輸入。
串流開始的任何時間點,DMO 就能夠接收輸入或產生輸出,或兩者皆可。 因此,GetInputStatus 會傳回DMO_INPUT_STATUSF_ACCEPT_DATA,或 ProcessOutput 傳回DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE。 應用程式會藉由檢查這些旗標,然後呼叫 ProcessInput 或 ProcessOutput 來維持資料流。 若要中斷數據流,請呼叫 IMediaObject::Flush 方法。 這個方法會導致 DMO 捨棄其內部持有的任何緩衝區。
相關主題