次の方法で共有


ストリーム変更の処理

このトピックでは、ストリーミング中に 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. クライアントは ProcessInput/ProcessOutput の呼び出しを再開します。

入力タイプ

入力の種類に対する変更はクライアントによって開始され、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_CHANGETRUE の場合、メインの違いは、新しい入力の種類を設定する前にクライアントが MFT をドレインする必要がないということです。 その結果、MFT が入力サンプルを保持している間に入力の種類が変更される可能性があります。 MFT が単にこれらのサンプルをドロップしないことが重要です。 また、MFT がキャッシュされたすべてのデータを処理するまで、出力の種類を変更することはできません。

前の段落は、特にビデオ デコーダーに適用されます。これは、テンポラル順でコード化されたフレームを受信できるため、キャッシュする必要があります。 MFT が入力サンプルをキャッシュしない場合、ドレインは基本的に no-op です。 その場合、MFT は MFT_SUPPORT_DYNAMIC_FORMAT_CHANGEFALSE に設定できます (または属性を未設定のままにします)。

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

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

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

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

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

カスタム MFT の作成