處理資料流程變更

本主題描述媒體基礎轉換 (MFT) 如何在串流期間處理格式變更。

重要

本主題不適用於編碼器。 編碼器不應傳播格式變更,如本主題所述。 編碼器應該只接受符合目前設定輸出類型的輸入類型。

 

格式變更概觀

一般而言,格式在串流期間可能會變更兩個原因。

  • 用戶端可能會切換至具有新格式的資料流程。 例如,在數位電視中,這可能是因為通道變更而發生。
  • 在某些視訊格式中,例如 H.264,bitstream 可能會發出格式變更的訊號。 這類變更可能包括欄位支配、視訊解析度或圖元外觀比例的變更。

如果編碼類型變更,用戶端可能需要從管線移除 MFT,並將它取代為另一個 MFT。 (例如,用戶端可能需要在新解碼器中交換。) 本主題未涵蓋該情況。 本主題僅涵蓋目前 MFT 可以處理新格式的情況。

如果格式變更,MFT 可能需要新的輸入類型、新的輸出類型或兩者。

  • 用戶端會起始輸入類型的變更。 MFT 永遠不會變更自己的輸入類型。
  • MFT 會起始輸出類型的變更。 MFT 表示它需要新的輸出類型,而用戶端會與 MFT 交涉新的輸出類型。

因此,可能會有三個不同的案例:

  • 用戶端會設定新的輸入類型。 MFT 會取用新的格式,但不會變更其輸出類型。
  • 用戶端會設定新的輸入類型,而這會觸發輸出類型的變更。
  • 輸入類型不會變更,但 MFT 會偵測位資料流程中的格式變更,這需要新的輸出類型。

實作格式變更

本主題的其餘部分說明用戶端如何處理格式變更,以及如何在 MFT 中實作格式變更。

輸出類型

任何 MFT 都可以起始其輸出類型的變更,如下所示:

  1. 用戶端會呼叫 IMFTransform::P rocessOutput。 MFT 會回應如下:
    1. MFT 不會在 ProcessOutput中產生輸出範例。
    2. MFT 會在 MFT_OUTPUT_DATA_BUFFER 結構的 dwStatus 成員中設定 MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE 旗標。
    3. ProcessOutput方法會傳回錯誤碼MF_E_TRANSFORM_STREAM_CHANGE
  2. 用戶端會呼叫 IMFTransform::GetOutputAvailableType。 這個方法會傳回一組更新的輸出類型。
  3. 用戶端會呼叫 SetOutputType 來設定新的輸出類型。
  4. 用戶端會繼續呼叫ProcessInputProcessOutput/ 。

輸入類型

對輸入類型的變更是由用戶端起始,永遠不會由 MFT 起始。 如果輸入類型變更,它可能會觸發輸出類型的變更。

確切的事件順序取決於 MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE 屬性的值。

描述
FALSE 在用戶端設定新的輸入類型之前,它必須清空 MFT。
TRUE 用戶端可以設定新的輸入類型,而不需要清空 MFT。

 

MFT 會透過 其 IMFTransform::GetAttributes 方法公開此屬性。 此屬性的預設值為 FALSE;如果 MFT 未設定 屬性,請將值視為 FALSE

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE為 FALSE

  1. 用戶端會傳送 MFT_MESSAGE_COMMAND_DRAIN 訊息。
  2. 用戶端會呼叫 IMFTransform::P rocessOutput 來清空 MFT,直到 ProcessOutput 傳回 MF_E_TRANSFORM_NEED_MORE_INPUT為止。
  3. 用戶端會呼叫 IMFTransform::SetInputType 來設定新的輸入類型。
  4. MFT 會驗證輸入類型。 如果類型無效, SetInputType傳回MF_E_INVALIDMEDIATYPE 或其他錯誤碼。 否則, SetInputType 會傳回S_OK。
  5. 假設輸入類型有效,MFT 會評估輸出類型是否也會變更。 如果沒有,串流會繼續執行,而且不需要採取進一步的動作。
  6. 如果輸出類型變更:
    1. MFT 會使目前的輸出媒體類型失效,並更新可用的輸出媒體類型清單。
    2. 下一次 呼叫 ProcessOutput傳回MF_E_TRANSFORM_STREAM_CHANGE,如上一節所述。
    3. 用戶端會呼叫 IMFTransform::GetOutputAvailableType 以取得更新的輸出類型清單。
    4. 用戶端會呼叫 SetOutputType

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE為 TRUE

  1. 用戶端會呼叫 IMFTransform::SetInputType 來設定新的輸入類型。
  2. MFT 會驗證輸入類型。 如果類型無效, SetInputType傳回MF_E_INVALIDMEDIATYPE 或其他錯誤碼。 否則, SetInputType 會傳回S_OK。
  3. 假設輸入類型有效,MFT 會評估輸出類型是否也會變更。 如果沒有,串流會繼續執行,而且不需要採取進一步的動作。
  4. 在輸出類型變更之前,MFT 必須處理任何快取的輸入範例,如下所示:
    1. MFT 不會使目前的輸出類型失效。
    2. MFT 會從快取的輸入範例產生盡可能多的輸出。
    3. MFT 在處理快取樣本時是否接受新的輸入樣本是選擇性的。 如果是,新的輸入範例會使用新的輸入格式,因此 MFT 必須追蹤格式變更時的點。
  5. 在 MFT 處理輸入類型變更之前收到的所有樣本之後, IMFTransform::P rocessOutput傳回MF_E_TRANSFORM_STREAM_CHANGE
  6. MFT 會使目前的輸出類型失效,並更新可用的輸出媒體類型清單。
  7. 用戶端會交涉新的輸出類型,如先前所述。

非同步 MFT必須傳回MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE屬性值TRUE。 使用非同步 MFT 時,用戶端可以假設 MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE 屬性設定為 TRUE

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGETRUE時,主要差異在於用戶端不需要清空 MFT,再設定新的輸入類型。 因此,當 MFT 保留輸入樣本時,輸入類型可能會變更。 MFT 不只卸載這些範例就很重要。 此外,除非 MFT 處理其所有快取的資料,否則輸出類型無法變更。

上一個段落特別適用于視訊解碼器,這些解碼器可以從時態順序接收編碼的框架,因此需要快取它們。 如果 MFT 不會快取輸入樣本,清空基本上就是無作業。 在此情況下,MFT 可以將 MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE 設定為 FALSE (,或將屬性保留為未設定) 。

此外,請注意,每個 MFT 預期會在清空之後正確處理格式變更。 MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE屬性會指出 MFT 是否支援格式變更,而不需要清空。

交錯模式中的變更

視訊交錯模式中的變更是特殊案例,因為它們不會使目前的媒體類型失效。 而是藉由在媒體範例上設定屬性,為每個視訊畫面指定交錯模式。 影片 MFT 應該檢查每個輸入範例是否有這些旗標。

當欄位支配從頂端欄位切換至底端欄位,或視訊在漸進式和交錯圖片之間切換時,交錯模式可能會變更。

如需詳細資訊,請參閱 範例上的交錯旗標

撰寫自訂 MFT