Media Foundation 変換 (MFT) は、メディア データを処理するための汎用モデルを提供します。 MFT は、デコーダー、エンコーダー、およびデジタル信号プロセッサ (DSP) に使用されます。 要するに、メディア ソースとメディア シンクの間のメディア パイプラインに存在するものは MFT です。
ほとんどのアプリケーションでは、MFT データ処理の詳細は、Media Foundation アーキテクチャの上位レイヤーによって隠されています。 多くの Media Foundation アプリケーションでは、MFT を直接呼び出すことはありません。 ただし、MFT をアプリケーションで直接ホストすることは確実に可能です。
MFT は、DirectX Media Objects (DMO) で最初に導入された変換モデルの進化です。 実際、両方のモデルをサポートする変換を作成するのは比較的簡単です。 DNO と比較して、必要な MFT の動作がより明確に指定されているため、正しい実装を簡単に記述できます。 さらに、MFT では、ハードウェアで高速化されたビデオ処理をサポートできます。
このトピックでは、特定のメソッド呼び出しではなく、全体的な設計に焦点を当てて、MFT 処理モデルの概要について説明します。 詳細な手順については、「 基本的な MFT 処理モデル」を参照してください。
ストリーム
MFT には、入力ストリームと出力ストリームがあります。 入力ストリームはデータを受信し、出力ストリームはデータを生成します。 たとえば、デコーダーには、エンコードされたデータを受信する 1 つの入力ストリームと、デコードされたデータを生成する 1 つの出力ストリームがあります。
MFT 上のストリームは、個別の COM オブジェクトとして表されません。 代わりに、各ストリームには指定されたストリーム識別子があり、 IMFTransform インターフェイスのメソッドはストリーム識別子を入力パラメーターとして受け取ります。
一部の MFT には、固定数のストリームがあります。 たとえば、デコーダーとエンコーダーには通常、入力と出力が 1 つだけ存在します。 他の MFT には、動的な数のストリームがあります。 MFT で動的ストリームがサポートされている場合、クライアントは新しい入力ストリームを追加できます。 クライアントは出力ストリームを追加できませんが、処理中に MFT によって出力ストリームが追加または削除される場合があります。 たとえば、マルチプレクサーを使用すると、通常、クライアントは入力ストリームを追加し、多重化ストリームに対して 1 つの出力を持つことができます。 デマルチプレクサーは、1つの入力に対して逆に複数の出力ストリームを持ち、入力ストリームの内容に応じてその数が動的に変化します。 次の図は、マルチプレクサーとデマルチプレクサーの違いを示しています。
メディアの種類
MFT が最初に作成されるとき、どのストリームにも確立された形式はありません。 MFT がデータを処理するには、クライアントがストリームの形式を設定する必要があります。 たとえば、デコーダーでは、入力形式は元のソース ファイルで使用される圧縮形式であり、出力形式は PCM オーディオや RGB ビデオなどの非圧縮形式です。 ストリーム形式については、 メディアの種類を使用して説明します。
MFT の内部状態によっては、ストリームごとに使用可能なメディアの種類の一覧が提供される場合があります。 このリストは、メディアの種類を設定するときにヒントとして使用できます。 メディアの種類をあるストリームに設定すると、別のストリームで使用可能な種類の一覧が変更される可能性があります。 たとえば、デコーダーは通常、クライアントが入力の種類を設定するまで、出力の種類を提供できません。 入力の種類には、デコーダーが使用可能な出力の種類の一覧を返すために必要な情報が含まれています。
ストリームにメディアの種類を設定するには、 IMFTransform::SetInputType または IMFTransform::SetOutputType を呼び出します。 ストリームに使用できるメディアの種類の一覧を取得するには、 IMFTransform::GetInputAvailableType または IMFTransform::GetOutputAvailableType を呼び出します。
データの処理
クライアントがストリームにメディアの種類を設定すると、MFT はデータを処理する準備が整います。 これを実現するために、クライアントは MFT に入力データを提供することと、MFT から出力データを取得する方法を代わりに使用します。
- 入力データを MFT に渡すには、 IMFTransform::P rocessInput を呼び出します。
- MFT から出力データをプルするには、 IMFTransform::P rocessOutput を呼び出します。
ProcessInput メソッドは、クライアントによって割り当てられたメディア サンプルへのポインターを受け取ります。 メディア サンプルには 1 つ以上のバッファーが含まれており、各バッファーには処理する MFT の入力データが含まれています。
ProcessOutput メソッドは、2 つの異なる割り当てモデルをサポートしています。MFT によって出力バッファーが割り当てられるか、クライアントが出力バッファーを割り当てます。 一部の MFT では両方の割り当てモデルがサポートされていますが、MFT で両方をサポートする必要はありません。 たとえば、MFT では、クライアントが出力バッファーを割り当てる必要がある場合があります。 IMFTransform::GetOutputStreamInfo メソッドは、MFT でサポートされている割り当てモデルを含む、出力ストリームに関する情報を返します。
MFT は、パイプラインの待機時間を最小限に抑えるために、できるだけ少ないデータをバッファーするように設計されています。 したがって、MFT は、任意の時点で、次のいずれかの条件を通知できます。
- MFT には、より多くの入力データが必要です。 この状態では、クライアントが ProcessInput を少なくとも 1 回呼び出すまで、MFT は出力を生成できません。
- クライアントが ProcessOutput を少なくとも 1 回呼び出すまで、MFT はそれ以上の入力を受け入れなくなります。
たとえば、ビデオ デコーダーを使用して、キー フレームとデルタ フレームの組み合わせを含むビデオ ストリームをデコードしているとします。 最初に、MFT ではフレームをデコードする前に、何らかの入力が必要です。 クライアントは ProcessInput を 呼び出して、最初のフレームを配信します。 最初のフレームが差分フレームであるとします (次の図では、予測フレームの 'P' として示されています)。 デコーダーはこのフレームを保持しますが、次のキー フレームを取得するまで出力を生成することはできません。
クライアントは引き続き ProcessInput を呼び出し、最終的に次のキー フレームに到達します (次の図では、コード化されたフレーム内の "I" として示されています)。 これで、デコーダーはデコードを開始するのに十分なフレームを持っています。 この時点で入力の受け入れは停止し、クライアントはデコードされたフレームを取得するために ProcessOutput を呼び出す必要があります。
クライアントの最も簡単な方法は、 ProcessInput と ProcessOutput の呼び出しを代替することです。 より高度なアルゴリズムについては、「 基本的な MFT 処理モデル」を参照してください。
関連トピック