共用方式為


處理 DMO 中的資料

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

本節說明如何使用 DMO 處理資料流程。 本節所列的步驟是預設行為;所有 DMO 都必須支援這裡所述的方法。 這些方法會針對輸入和輸出使用不同的緩衝區。 某些 DMO 也支援使用單一緩衝區就地處理。 如需就地處理的詳細資訊,請參閱 就地處理

配置緩衝區

用戶端負責所有緩衝區配置。 在 DMO 上設定媒體類型之後,請查詢 DMO 以取得每個資料流程的緩衝區需求。 這些可能會根據媒體類型而變更。 針對每個資料流程,呼叫 IMediaObject::GetInputSizeInfoIMediaObject::GetOutputSizeInfo 方法。 這些方法會傳回下列資訊:

  • 緩衝區大小下限,以位元組為單位。
  • 如果有的話,對齊需求。 如果起始位址是某些指定整數的倍數,則會對齊緩衝區。
  • DMO 將保留的查閱資料量上限。 此數位僅適用于輸入資料流程。 例如,針對某些類型的資料 (,MPEG 編碼) ,DMO 可能需要在資料流程中向前查看。 Lookahead 值表示 DMO 在產生輸出之前需要多少輸入資料。

用戶端必須配置符合這些需求的緩衝區。 此外,DMO 可能會有用戶端如何封裝輸入資料的需求。 例如,DMO 可能需要每個緩衝區只包含一個範例 (或視訊畫面) 。 若要判斷這些需求,請呼叫 IMediaObject::GetInputStreamInfo 方法。 IMediaObject::GetOutputStreamInfo方法會傳回輸出資料流程的類似資訊。

在預設串流模型中,用戶端不會將原始緩衝區指標傳遞至 DMO。 而是使用輕量型 COM 物件來公開 IMediaBuffer 介面。 IMediaBuffer介面可作為記憶體區塊的 COM 包裝函式。 因為它是 COM 物件,所以它支援參考計數,這有助於確保緩衝區未釋放,同時仍在使用中。

注意

IMediaBuffer介面提供類似DirectShow 中 IMediaSample介面的函式。

 

用戶端必須實作 IMediaBuffer 物件。 如需詳細資訊,請參閱 實作 IMediaBuffer

處理資料

若要處理資料,請執行下列動作:

  1. 針對每個輸入資料流程,使用輸入資料填入緩衝區。
  2. 呼叫 IMediaObject::P rocessInput 來傳遞每個緩衝區。
  3. 呼叫 IMediaObject::P rocessOutput 來處理資料。 此方法會採用緩衝區陣列,每個輸出資料流程各一個。
  4. 重複直到沒有其他輸入資料為止。

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::D iscontinuity 方法。 在您處理其餘輸出 (或排清 DMO) 之前,DMO 不接受該資料流程的進一步輸入。

串流開始之後的任何時間點,DMO 就能夠接收輸入或產生輸出,或是兩者。 因此, GetInputStatus 會傳回DMO_INPUT_STATUSF_ACCEPT_DATA,或 ProcessOutput 會傳回DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE。 應用程式會測試這些旗標,並據以呼叫 ProcessInputProcessOutput 來保持資料流程。 若要中斷資料流程,請呼叫 IMediaObject::Flush 方法。 此方法會導致 DMO 捨棄其內部保存的任何緩衝區。

直接裝載 DMO

就地處理