MFT と DMO の比較

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

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

ストリームの数

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

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

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

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

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

MFT は 、IMFMediaType インターフェイスを使用してメディアの種類を記述します。 それ以外の場合、MFT とのフォーマット ネゴシエーションは、DMO と同じ基本原則に基づいて動作します。 次の表に、DMU のフォーマット ネゴシエーション メソッドと、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 には、DMU で使用される IMediaObject::AllocateStreamingResources メソッドと IMediaObject::FreeStreamingResources メソッドがありません。 リソースの割り当てと割り当て解除を効率的に処理するために、MFT は IMFTransform::P rocessMessage メソッドで次のメッセージに応答できます。

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

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

データの処理

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

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

IMFMediaBuffer インターフェイスは、DMO IMediaBuffer インターフェイスに似ています。 基になるメモリ バッファーにアクセスするには、 IMFMediaBuffer::Lock を呼び出します。 このメソッドは、DMU の 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 と DMO の小さな違いをいくつか示します。

Flags

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

ProcessInput フラグ

DLO: 列挙_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 フラグ

DMU: 列挙_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

 

DMU: 列挙_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 フラグ

DMO: 列挙_DMO_INPUT_STATUS_FLAGS

MFT: 列挙_MFT_INPUT_STATUS_FLAGS

DMO フラグ MFT フラグ
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

GetOutputStatus フラグ

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

MFT: 列挙_MFT_OUTPUT_STATUS_FLAGS

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

 

GetInputStreamInfo フラグ

DMU: 列挙_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 フラグ

DLO: 列挙_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++ 構文を使用して、複数のインターフェイスから継承された名前を明確にします。 たとえば、 次のように ProcessInput の MFT バージョンを宣言します。

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

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

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

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

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

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

Media Foundation Transforms