次の方法で共有


非同期 MFT

このトピックでは、Media Foundation 変換 (MFT) の非同期データ処理について説明します。

Note

このトピックは、Windows 7 以降に適用されます。

 

非同期 MFT について

Windows Vista で MFT が導入されたとき、API は 同期 データ処理用に設計されていました。 そのモデルでは、MFT は常に入力の取得を待機しているか、出力の生成を待機しています。

一般的なビデオ デコーダーについて考えてみましょう。 デコードされたフレームを取得するために、クライアントは IMFTransform::P rocessOutput を呼び出します。 デコーダーにフレームをデコードするのに十分なデータがある場合、MFT がフレームをデコードする間、 ProcessOutput はブロックします。 それ以外の場合、 ProcessOutputMF_E_TRANSFORM_NEED_MORE_INPUTを返し、クライアントが IMFTransform::P rocessInput を呼び出す必要があることを示します。

デコーダーが 1 つのスレッドですべてのデコード操作を実行する場合、このモデルは適切に機能します。 ただし、デコーダーが複数のスレッドを使用してフレームを並列にデコードするとします。 最適なパフォーマンスを得るには、デコード スレッドがアイドル状態になったときに、デコーダーが新しい入力を受け取る必要があります。 ただし、スレッドがデコード操作を完了する速度は、 ProcessInputProcessOutput に対するクライアントの呼び出しと正確には一致せず、スレッドは作業を待機します。

Windows 7 では、MFT に対してイベント ドリブン の非同期 処理が導入されています。 このモデルでは、MFT で入力が必要な場合や出力がある場合は常に、クライアントにイベントを送信します。

一般的な要件

このトピックでは、非同期 MFT と同期 MFT の違いについて説明します。 このトピックで説明する場合を除き、2 つの処理モデルは同じです。 (特に、フォーマット ネゴシエーションは同じです)。

非同期 MFT では、次のインターフェイスを実装する必要があります。

イベント

非同期 MFT は、次のイベントを使用して、データ処理の状態を通知します。

Event 説明
METransformNeedInput MFT がより多くの入力を受け入れられるときに送信されます。
METransformHaveOutput MFT に出力があるときに送信されます。
METransformDrainComplete ドレイン操作が完了したときに送信されます。 「ドレイン」を参照してください。
METransformMarker マーカーが処理されるときに送信されます。 「マーカー」を参照してください。

 

これらのイベントは帯域外で送信されます。 MFT のコンテキストでの帯域内イベントと帯域外イベントの違いを理解することが重要です。

元の MFT 設計では、 インバンド イベントが サポートされています。 インバンド イベントには、形式の変更に関する情報など、データ ストリームに関する情報が含まれます。 クライアントは、 IMFTransform::P rocessEvent を呼び出して、MFT にインバンド イベントを送信します。 MFT は、 ProcessOutput メソッドでインバンド イベントをクライアントに送り返すことができます。 (具体的には、イベントは MFT_OUTPUT_DATA_BUFFER 構造体の pEvents メンバーで伝達されます)。

MFT は、 次のように IMFMediaEventGenerator インターフェイスを介して帯域外イベントを送信します。

  1. MFT は、「Media Event Generators」で説明されているように、IMFMediaEventGenerator インターフェイスを実装します。
  2. クライアントは、IMFMediaEventGenerator インターフェイスの MFT で IUnknown::QueryInterface を呼び出します。 非同期 MFT では、このインターフェイスを公開する必要があります。 同期 MFT では、このインターフェイスを公開しないでください。
  3. クライアントは 、IMFMediaEventGenerator::BeginGetEventIMFMediaEventGenerator::EndGetEvent を呼び出して、MFT から帯域外イベントを受信します。

ProcessInput

IMFTransform::P rocessInput メソッドは次のように変更されます。

  1. ストリーミングが開始されると、クライアントは MFT_MESSAGE_NOTIFY_START_OF_STREAM メッセージを送信します。
  2. ストリーミング中、MFT は METransformNeedInput イベントを送信してデータを要求します。 イベント データはストリーム識別子です。
  3. METransformNeedInput イベントごとに、クライアントは指定されたストリームに対して ProcessInput を呼び出します。
  4. ストリーミングの最後に、クライアントは MFT_MESSAGE_NOTIFY_END_OF_STREAM メッセージを使用して ProcessMessage を呼び出すことができます。

実装に関する注意事項:

ProcessOutput

IMFTransform::P rocessOutput メソッドは次のように変更されます。

  1. MFT は、出力があるたびに METransformHaveOutput イベントを送信します。
  2. METransformHaveOutput イベントごとに、クライアントは ProcessOutput を呼び出します。

実装に関する注意事項:

ドレイン中

MFT をドレインすると、既に送信されている入力データからできる限り多くの出力が MFT によって生成されます。 非同期 MFT のドレインは、次のように機能します。

  1. クライアントは 、MFT_MESSAGE_COMMAND_DRAIN メッセージを送信します。
  2. MFT は、処理するデータがなくなったまで METransformHaveOutput イベントを送信し続けます。 この間 、METransformNeedInput イベントは送信されません。
  3. MFT は、最後の METransformHaveOutput イベントを送信した後、 METransformDrainComplete イベントを送信します。

ドレインが完了すると、MFT は、クライアントからMFT_MESSAGE_NOTIFY_START_OF_STREAM メッセージを受信するまで、別の METransformNeedInput イベントを送信しません。

フラッシュ

クライアントは、 MFT_MESSAGE_COMMAND_FLUSH メッセージを送信することで MFT をフラッシュできます。 MFT は、保持しているすべての入出力サンプルをドロップします。

MFT は、クライアントからMFT_MESSAGE_NOTIFY_START_OF_STREAMメッセージを受信するまで、別の METransformNeedInput イベントを送信しません。

マーカー

クライアントは、 MFT_MESSAGE_COMMAND_MARKER メッセージを送信することで、ストリーム内のポイントをマークできます。 MFT は次のように応答します。

  1. MFT は、既存の入力データからできるだけ多くの出力サンプルを生成し、出力サンプルごとに METransformHaveOutput イベントを送信します。
  2. すべての出力が生成されると、MFT は METransformMarker イベントを送信します。 このイベントは、 すべての METransformHaveOutput イベントの後に送信する必要があります。

たとえば、デコーダーに 4 つの出力サンプルを生成するのに十分な入力データがあるとします。 クライアントが MFT_MESSAGE_COMMAND_MARKER メッセージを送信すると、MFT は 4 つの METransformHaveOutput イベント (出力サンプルごとに 1 つ) をキューに入れ、その後に METransformMarker イベントをキューに入れます。

マーカー メッセージはドレイン メッセージに似ています。 ただし、ドレインはストリームの中断と見なされますが、マーカーは見なされません。 ドレインとマーカーには、次の違いがあります。

排水:

  • ドレイン中、MFT は METransformNeedInput イベントを 送信しません。
  • MFT は、出力サンプルの作成に使用できない入力データを破棄します。
  • 一部の MFT では、データの末尾に "尾" が生成されます。 たとえば、リバーブやエコーなどのオーディオエフェクトは、入力データが停止した後に余分なデータを生成します。 尾部を生成する MFT は、ドレイン操作の終了時に行う必要があります。
  • MFT のドレインが完了すると、次の出力サンプルに MFSampleExtension_Discontinuity 属性がマークされ、ストリームの不連続性が示されます。

マーカー:

  • MFT は、マーカー イベントを送信する前 に METransformNeedInput イベントを送信し続けます。
  • MFT は入力データを破棄しません。 部分的なデータがある場合は、マーカー ポイントの後に処理する必要があります。
  • MFT はマーカー ポイントで尾を生成しません。
  • MFT は、マーカー ポイントの後に不連続性フラグを設定しません。

変更の書式設定

非同期 MFT では、 ストリーム変更の処理に関するページで説明されているように、動的な形式の変更をサポートする必要があります。

属性

有効な属性ストアを返すには、非同期 MFT で IMFTransform::GetAttributes メソッドを実装する必要があります。 非同期 MFT には、次の属性が適用されます。

属性 説明
MF_TRANSFORM_ASYNC MFT では、この属性を TRUE (1) に設定する必要があります。 クライアントは、この属性に対してクエリを実行して、MFT が非同期であるかどうかを検出できます。
MF_TRANSFORM_ASYNC_UNLOCK
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE MFT では、この属性を TRUE (1) に設定する必要があります。 クライアントでは、この属性が設定されていると想定できます。

 

非同期 MFT のロック解除

非同期 MFT は、元の MFT データ処理モデルと互換性がありません。 非同期 MFT が既存のアプリケーションを壊さないようにするために、次のメカニズムが定義されています。

クライアントは、MFT で IMFTransform::GetAttributes を呼び出します。 クライアントは、この MF_TRANSFORM_ASYNC 属性の を照会します。 非同期 MFT の場合、この属性の値は **TRUE** です。 MFT のロックを解除するには、クライアントで MF_TRANSFORM_ASYNC_UNLOCK 属性を **TRUE** に設定する必要があります。

クライアントが MFT のロックを解除するまで、すべての IMFTransform メソッドは、次の例外を除き、 MF_E_TRANSFORM_ASYNC_LOCKEDを返す必要があります。

次のコードは、非同期 MFT のロックを解除する方法を示しています。

HRESULT UnlockAsyncMFT(IMFTransform *pMFT)
{
    IMFAttributes *pAttributes = NULL;

    HRESULT hr = hr = pMFT->GetAttributes(&pAttributes);

    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
        pAttributes->Release();
    }
    
    return hr;
}

MFT のシャットダウン

非同期 MFT は 、IMFShutdown インターフェイスを実装する必要があります。

  • シャットダウン: MFT はイベント キューをシャットダウンする必要があります。 標準イベント キューを使用する場合は、 IMFMediaEventQueue::Shutdown を呼び出します。 必要に応じて、MFT は他のリソースを解放できます。 クライアントは、Shutdown を呼び出した後に MFT を使用しないでください。
  • GetShutdownStatus: Shutdown が呼び出された後、MFT は pStatus パラメーターでMFSHUTDOWN_COMPLETED値を返す必要があります。 MFSHUTDOWN_INITIATED値を返さないでください。

登録と列挙

非同期 MFT を登録するには、MFTRegister 関数を呼び出し、Flags パラメーターに MFT_ENUM_FLAG_ASYNCMFT フラグを設定します。 (以前は、このフラグは予約されていました。

非同期 MFT を列挙するには、MFTEnumEx 関数を呼び出し、Flags パラメーターに MFT_ENUM_FLAG_ASYNCMFT フラグを設定します。 下位互換性のために、 MFTEnum 関数は非同期 MFT を列挙しません。 そうしないと、ユーザーのコンピューターに非同期 MFT をインストールすると、既存のアプリケーションが壊れる可能性があります。

Media Foundation Transforms