MFT と DMO の比較

Media Foundation 変換 (MFT) は、DirectX Media Objects (DMO) で最初に導入された変換モデルの進化です。 このトピックでは、MFT が DNO と異なる主な方法をまとめます。 DMO インターフェイスに既に慣れている場合、または既存のDMOを MFT に変換する場合は、このトピックを参照してください。

このトピックは、次のセクションで構成されています。

ストリームの数

DMOには固定数のストリームがあり、MFT は動的な数のストリームをサポートできます。 クライアントは入力ストリームを追加でき、MFT は処理中に新しい出力ストリームを追加できます。 ただし、動的ストリームをサポートするために MFT は必要ありません。 MFT には、DMOと同様に、固定数のストリームを含めることができます。

MFT で動的ストリームをサポートするには、次のメソッドを使用します。

さらに、 IMFTransform::P rocessOutput メソッドは、出力ストリームを追加または削除するための動作を定義します。

DNO には固定ストリームがあるため、DMO上のストリームは、0 から始まるインデックス値を使用して識別されます。 一方、MFT では、必ずしもインデックス値に対応していないストリーム識別子を使用します。 これは、MFT 上のストリームの数が変わる可能性があるためです。 たとえば、ストリーム 0 を削除し、ストリーム 1 を最初のストリームのままにします。 ただし、固定数のストリームを持つ MFT では、DMO と同じ規則を遵守し、ストリーム識別子にインデックス値を使用する必要があります。

形式に関するネゴシエーション

MFT では、 IMFMediaType インターフェイスを使用してメディアの種類を記述します。 それ以外の場合、MFT とのフォーマット ネゴシエーションは、DMO と同じ基本原則に基づいて動作します。 次の表に、DNO のフォーマット ネゴシエーション メソッドと、MFT の対応するメソッドを示します。

DMO メソッド MFT メソッド
IMediaObject::GetInputCurrentType IMFTransform::GetInputCurrentType
IMediaObject::GetInputMaxLatency IMFTransform::GetInputStreamInfo
IMediaObject::GetInputSizeInfo IMFTransform::GetInputStreamInfo
IMediaObject::GetInputType IMFTransform::GetInputAvailableType
IMediaObject::GetOutputCurrentType IMFTransform::GetOutputCurrentType
IMediaObject::GetOutputSizeInfo IMFTransform::GetOutputStreamInfo
IMediaObject::GetOutputType IMFTransform::GetOutputAvailableType

 

ストリーミング

DMO と同様に、MFT は ProcessInput メソッドと ProcessOutput メソッドの呼び出しを通じてデータを処理します。 データをストリーミングするときのDMOプロセスと MFT プロセスの主な違いを次に示します。

リソースの割り当て

MFT には、DDO で使用される IMediaObject::AllocateStreamingResources メソッドと IMediaObject::FreeStreamingResources メソッドがありません。 リソースの割り当てと割り当て解除を効率的に処理するために、MFT は IMFTransform::P rocessMessage メソッドで次のメッセージに応答できます。

さらに、クライアントは、次のメッセージを含む ProcessMessage を呼び出すことによって、ストリームの開始と終了を通知できます。

これら 2 つのメッセージには、まったく同等のDMOはありません。

データの処理

MFT は、メディア サンプルを使用して入力データと出力データを保持します。 メディア サンプルは IMFSample インターフェイスを公開し、次のデータを含みます。

  • タイム スタンプと期間。
  • サンプルごとの情報を含む属性。 属性の一覧については、「 サンプル属性」を参照してください。
  • 0 個以上のメディア バッファー。 各メディア バッファーは、 IMFMediaBuffer インターフェイスを 公開します。

IMFMediaBuffer インターフェイスは、DMO IMediaBuffer インターフェイスに似ています。 基になるメモリ バッファーにアクセスするには、 IMFMediaBuffer::Lock を呼び出します。 このメソッドは、DNO の IMediaBuffer::GetBufferAndLength とほぼ同じです。

非圧縮ビデオ データの場合、メディア バッファーは IMF2DBuffer インターフェイスもサポートする場合があります。 非圧縮ビデオを処理する MFT (入力または出力) は、バッファーが公開する場合に IMF2DBuffer インターフェイスを使用するように準備する必要があります。 詳細については、「 圧縮されていないビデオ バッファー」を参照してください。

Media Foundation には IMFMediaBuffer の標準的な実装がいくつか用意されているため、通常は独自の実装を記述する必要はありません。 Media Foundation バッファーからDMO バッファーを作成するには、MFCreateLegacyMediaBufferOnMFMediaBuffer を呼び出します。

フラッシュ

MFT には Flush メソッドがありません。 MFT をフラッシュするには、MFT_MESSAGE_COMMAND_FLUSH メッセージを使用して IMFTransform::P rocessMessage を呼び出します。

ストリームの不連続性

MFT には 不連続性 メソッドはありません。 ストリームの不連続性を通知するには、入力サンプルに MFSampleExtension_Discontinuity 属性を設定します。

その他の相違点

MFT と DMI の間のその他の小さな違いを次に示します。

Flags

次の表に、さまざまなDMO フラグとその MFT に相当するフラグを示します。 DMO フラグが MFT フラグに直接マップされるたびに、両方のフラグの数値が同じになります。 ただし、一部のDMOフラグには、正確な MFT と同等の値がありません。その逆も同様です。

ProcessInput フラグ

DNO: _DMO_INPUT_DATA_BUFFER_FLAGS 列挙。

MFT: 同等の列挙型はありません。

DMO フラグ MFT フラグ
DMO_INPUT_DATA_BUFFERF_SYNCPOINT 同等のフラグはありません。 代わりに、サンプルに MFSampleExtension_CleanPoint 属性を設定します。
DMO_INPUT_DATA_BUFFERF_TIME 同等のフラグはありません。 代わりに、サンプル で IMFSample::SetSampleTime を呼び出します。
DMO_INPUT_DATA_BUFFERF_TIMELENGTH 同等のフラグはありません。 代わりに、サンプル で IMFSample::SetSampleDuration を呼び出します。

 

ProcessOutput フラグ

DNO: _DMO_PROCESS_OUTPUT_FLAGS 列挙。

MFT: _MFT_PROCESS_OUTPUT_FLAGS 列挙。

DMO フラグ MFT フラグ
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DNO: _DMO_OUTPUT_DATA_BUFFER_FLAGS 列挙。

MFT: _MFT_OUTPUT_DATA_BUFFER_FLAGS 列挙。

DMO フラグ MFT フラグ
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT 同等のフラグはありません。 代わりに、サンプルの MFSampleExtension_CleanPoint 属性を確認してください。
DMO_OUTPUT_DATA_BUFFERF_TIME 同等のフラグはありません。 代わりに、サンプル で IMFSample::GetSampleTime を呼び出します。
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH 同等のフラグはありません。 代わりに、サンプル で IMFSample::GetSampleDuration を呼び出します。
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
同等のフラグはありません。 MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
同等のフラグはありません。 MFT_OUTPUT_DATA_BUFFER_STREAM_END
同等のフラグはありません。 MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

GetInputStatus フラグ

DNO: _DMO_INPUT_STATUS_FLAGS 列挙。

MFT: _MFT_INPUT_STATUS_FLAGS 列挙。

DMO フラグ MFT フラグ
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

GetOutputStatus フラグ

DNO: 同等の列挙はありません。

MFT: _MFT_OUTPUT_STATUS_FLAGS 列挙。

DMO フラグ MFT フラグ
同等のフラグはありません。 MFT_OUTPUT_STATUS_SAMPLE_READY

 

GetInputStreamInfo フラグ

DNO: _DMO_INPUT_STREAM_INFO_FLAGS 列挙。

MFT: _MFT_INPUT_STREAM_INFO_FLAGS 列挙。

DMO フラグ MFT フラグ
DMO_INPUT_STREAMF_WHOLE_SAMPLES MFT_INPUT_STREAM_WHOLE_SAMPLES
DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_INPUT_STREAMF_HOLDS_BUFFERS MFT_INPUT_STREAM_HOLDS_BUFFERS
同等のフラグはありません。 MFT_INPUT_STREAM_DOES_NOT_ADDREF
同等のフラグはありません。 MFT_INPUT_STREAM_REMOVABLE
同等のフラグはありません。 MFT_INPUT_STREAM_OPTIONAL

 

GetOutputStreamInfo フラグ

DNO: _DMO_OUTPUT_STREAM_INFO_FLAGS 列挙。

MFT: _MFT_OUTPUT_STREAM_INFO_FLAGS 列挙。

DMO フラグ MFT フラグ
DMO_OUTPUT_STREAMF_WHOLE_SAMPLES MFT_OUTPUT_STREAM_WHOLE_SAMPLES
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_OUTPUT_STREAMF_DISCARDABLE MFT_OUTPUT_STREAM_DISCARDABLE
DMO_OUTPUT_STREAMF_OPTIONAL MFT_OUTPUT_STREAM_OPTIONAL
同等のフラグはありません。 MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
同等のフラグはありません。 MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
同等のフラグはありません。 MFT_OUTPUT_STREAM_LAZY_READ
同等のフラグはありません。 MFT_OUTPUT_STREAM_REMOVABLE

 

SetInputType/SetOutputType フラグ

DLO: 列挙_DMO_SET_TYPE_FLAGS

MFT: 列挙_MFT_SET_TYPE_FLAGS

DMO フラグ MFT フラグ
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR 同等のフラグはありません。 代わりに、メディアの種類を NULL に設定して、メディアの種類をクリアします。

 

エラー コード

次の表は、DMOエラー コードを MFT エラー コードにマップする方法を示しています。 ハイブリッド MFT/DMO オブジェクトは、IMediaObject メソッドのDMO エラー コードと IMFTransform メソッドの MFT エラー コードを返す必要があります。 DMOエラー コードは、ヘッダー ファイル MediaErr.h で定義されています。 MFT エラー コードは、ヘッダー ファイル mferror.h で定義されています。

エラー コードのDMO MFT エラー コード
DMO_E_INVALIDTYPE MF_E_INVALIDTYPE
DMO_E_INVALIDSTREAMINDEX MF_E_INVALIDSTREAMNUMBER
DMO_E_NOTACCEPTING MF_E_NOTACCEPTING
DMO_E_NO_MORE_ITEMS MF_E_NO_MORE_TYPES
DMO_E_TYPE_NOT_ACCEPTED MF_E_INVALIDMEDIATYPE
DMO_E_TYPE_NOT_SET MF_E_TRANSFORM_TYPE_NOT_SET

 

ハイブリッド DMO/MFT オブジェクトの作成

IMFTransform インターフェイスは、DirectX Media Objects (DMO) の主要なインターフェイスである IMediaObject に大まかに基づいています。 両方のインターフェイスを公開するオブジェクトを作成できます。 ただし、インターフェイスには同じ名前を共有するいくつかのメソッドがあるため、名前付けの競合が発生する可能性があります。 この問題は、次の 2 つの方法のいずれかで解決できます。

解決策 1: MFT 関数を含む .cpp ファイルの先頭に次の行を含めます。

#define MFT_UNIQUE_METHOD_NAMES

これにより、 IMFTransform インターフェイスの宣言が変更され、ほとんどのメソッド名の先頭に "MFT" が付きます。 したがって、 IMFTransform::P rocessInputIMFTransform::MFTProcessInput になり、 IMediaObject::P rocessInput は元の名前を保持します。 この手法は、既存のDMOをハイブリッド DMO/MFT に変換する場合に最も便利です。 DMO メソッドを変更せずに、新しい MFT メソッドを追加できます。

解決策 2: C++ 構文を使用して、複数のインターフェイスから継承された名前を明確にします。 たとえば、 MFT バージョンの ProcessInput を次のように宣言します。

CMyHybridObject::IMFTransform::ProcessInput(...)

次のように ProcessInput のDMO バージョンを宣言します。

CMyHybridObject::IMediaObject::ProcessInput(...)

オブジェクト内のメソッドを内部呼び出す場合は、この構文を使用できますが、これを行うと、メソッドの仮想状態がオーバーライドされます。 オブジェクト内から呼び出しを行うより良い方法は次のとおりです。

hr = ((IMediaObject*)this)->ProcessInput(...)

このようにして、 CMyHybridObject から別のクラスを派生させ、CMyHybridObject::IMediaObject::P rocessInput メソッドをオーバーライドすると、正しい仮想メソッドが呼び出されます。 DMO インターフェイスについては、DirectShow SDK のドキュメントに記載されています。

Media Foundation の変換