ストリームの変更の処理

このトピックでは、ストリーミング中に Media Foundation 変換 (MFT) で書式の変更を処理する方法について説明します。

重要

このトピックはエンコーダーには適用されません。 エンコーダーでは、このトピックの説明に従って、形式の変更を反映しないでください。 エンコーダーは、現在構成されている出力の種類に一致する入力の種類のみを受け入れる必要があります。

 

書式の変更の概要

一般に、ストリーミング中に形式が変更される理由は 2 つあります。

  • クライアントは、新しい形式でストリームに切り替える場合があります。 たとえば、デジタル テレビでは、チャネルの変更が原因で発生する可能性があります。
  • H.264 などの一部のビデオ形式では、ビットストリームによってフォーマットの変更が通知される場合があります。 このような変更には、フィールドの支配、ビデオ解像度、ピクセル縦横比の変更が含まれる場合があります。

エンコードの種類が変更された場合、クライアントはパイプラインから MFT を削除し、別の MFT に置き換える必要がある場合があります。 (たとえば、クライアントは新しいデコーダーでスワップする必要がある場合があります)。このトピックでは、その状況については説明しません。 このトピックでは、現在の MFT が新しい形式を処理できる場合のみを取り上げます。

形式が変更された場合、MFT には新しい入力タイプ、新しい出力タイプ、またはその両方が必要になる場合があります。

  • 入力の種類の変更は、クライアントによって開始されます。 MFT によって独自の入力型が変更されることはありません。
  • 出力の種類の変更は、MFT によって開始されます。 MFT は新しい出力の種類が必要であることを通知し、クライアントは新しい出力の種類を MFT とネゴシエートします。

したがって、次の 3 つの異なるケースが考えられます。

  • クライアントは、新しい入力の種類を設定します。 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. クライアントは、ProcessOutputMF_E_TRANSFORM_NEED_MORE_INPUTを返すまで IMFTransform::P rocessOutput を呼び出して MFT をドレインします。
  3. クライアントは IMFTransform::SetInputType を呼び出して、新しい入力の種類を設定します。
  4. MFT は入力の種類を検証します。 型が無効な場合、 SetInputTypeMF_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 は入力の種類を検証します。 型が無効な場合、 SetInputTypeMF_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_CHANGEが TRUE の場合、主な違いは、新しい入力の種類を設定する前にクライアントが MFT をドレインする必要がないということです。 その結果、MFT が入力サンプルを保持している間に、入力の種類が変更される可能性があります。 MFT が単にこれらのサンプルをドロップしないことが重要です。 また、MFT がキャッシュされたすべてのデータを処理するまで、出力の種類を変更することはできません。

前の段落は特にビデオ デコーダーに適用されます。これは、時間的な順序でコード化されたフレームを受信できるため、それらをキャッシュする必要があります。 MFT が入力サンプルをキャッシュしない場合、ドレインは基本的に非操作です。 その場合、MFT はMFT_SUPPORT_DYNAMIC_FORMAT_CHANGEを FALSE に設定できます (または、属性の設定を解除したままにします)。

また、すべての MFT は、ドレイン後にフォーマットの変更を正しく処理することが期待されることに注意してください。 MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE属性は、MFT がドレインなしでフォーマット変更をサポートするかどうかを示します。

インターレース モードの変更

ビデオインターレース モードの変更は、現在のメディアの種類を無効にしないため、特別なケースです。 代わりに、メディア サンプルに属性を設定して、各ビデオ フレームにインターレース モードを指定します。 ビデオ MFT では、各入力サンプルにこれらのフラグが存在するかどうかを確認する必要があります。

インターレース モードは、フィールドの支配がトップ フィールドからボトム フィールドに切り替わるとき、またはビデオがプログレッシブとインターレースの画像を切り替えるときに変更できます。

詳細については、「 サンプルでのインターレース フラグ」を参照してください。

カスタム MFT の記述