MFT と DMO の比較
Media Foundation 変換 (MFT) は、DirectX Media Objects (DMO) で最初に導入された変換モデルの進化です。 このトピックでは、MF が DMO と異なるメイン方法についてまとめます。 DMO インターフェイスに既に慣れている場合、または既存の DMO を MFT に変換する場合は、このトピックをお読みください。
このトピックは、次のセクションで構成されています。
ストリームの数
DMO には固定数のストリームがあり、MFT では動的な数のストリームをサポートできます。 クライアントは入力ストリームを追加でき、MFT は処理中に新しい出力ストリームを追加できます。 ただし、動的ストリームをサポートするために MFT は必要ありません。 MFT には、DMO と同様に、固定数のストリームを含めることができます。
MFT で動的ストリームをサポートするには、次のメソッドを使用します。
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
さらに、 IMFTransform::P rocessOutput メソッドは、出力ストリームを追加または削除するための動作を定義します。
DMO には固定ストリームがあるため、DMO 上のストリームは 0 から始まるインデックス値を使用して識別されます。 一方、MFT では、必ずしもインデックス値に対応していないストリーム識別子を使用します。 これは、MFT 上のストリームの数が変更される可能性があるためです。 たとえば、ストリーム 0 を削除し、ストリーム 1 を最初のストリームとして残します。 ただし、固定数のストリームを持つ MFT では、DMO と同じ規則を遵守し、ストリーム識別子にインデックス値を使用する必要があります。
形式に関するネゴシエーション
MFT は 、IMFMediaType インターフェイスを使用してメディアの種類を記述します。 それ以外の場合、MFT とのフォーマット ネゴシエーションは、DMO と同じ基本原則に基づいて動作します。 次の表に、DMU のフォーマット ネゴシエーション メソッドと、MFT の対応するメソッドを示します。
ストリーム
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 の小さな違いをいくつか示します。
次の DMO メソッドに相当する MFT はありません。
集計をサポートするために MFT は必要ありません。
MFT では、ドレインと呼ばれる操作 がサポートされます。 ドレインの目的は、MFT にこれ以上入力データを提供せずに (ストリームの末尾など) MF に残っているデータを処理することです。 MFT をドレインするには、MFT_MESSAGE_COMMAND_DRAIN メッセージと共に IMFTransform::P rocessMessage を呼び出します。 詳細については、「 基本的な MFT 処理モデル」を参照してください。
MFT には、ストリームごとの属性を含む属性を含めることができます。 MFT から属性を取得するには、次のメソッドを使用します。
MFT はイベントを処理できます。 MFT にイベントを送信するには、 IMFTransform::P rocessEvent を呼び出します。 MFT は ProcessOutput メソッドを使用してクライアントにイベントを送信できます。 詳細については、「 基本的な MFT 処理モデル」を参照してください。
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 rocessInput は IMFTransform::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 ドキュメントに記載されています。
関連トピック