ハードウェア MFT
注意
このトピックは、Windows 7 以降に適用されます。
このトピックでは、ハードウェア エンコーダー、デコーダー、またはデジタルシグナル プロセッサ (DSP) へのプロキシとして機能する Media Foundation 変換 (MFT) を記述する方法について説明します。
重要
ハードウェア コーデックで AVStream マルチメディア クラス ドライバーを使用する場合、カスタム MFT は必要ありません。 Media Foundation は、この目的のために AVStream プロキシを提供します。 このトピックの情報は、ハードウェア コーデックが AVStream を使用しない特殊な場合にのみ適用されます。 詳細については、「 AVStream でのハードウェア コーデックのサポート」を参照してください。
このトピックは、次のセクションで構成されています。
はじめに
AVStream に基づいていないハードウェア コーデックは、ドライバーのプロキシとして機能する独自の MFT を提供する必要があります。 ハードウェア コーデックには、いくつかの異なる機能ブロックが組み込まれている場合があります。
- エンコーダー
- デコーダー
- フレームのスケーリング/フォーマット変換
これらの各関数は、個別の MFT によって管理する必要があります。 ハードウェア MFT は、汎用の "トランスコーダー" として機能してはいけません。代わりに、エンコード関数をエンコーダー MFT に、デコード関数をデコーダー MFT に配置します。 ハードウェアでフレームスケーリングとフォーマット変換が提供されている場合は、これらの関数を別のビデオプロセッサに配置し、 MFT_CATEGORY_VIDEO_PROCESSOR カテゴリに登録します。 ハードウェアがフレームのスケーリングやフォーマット変換をサポートしていない場合、Media Foundation はソフトウェア ビデオ プロセッサを提供します。
ハードウェア MFT には、次の一般的な要件があります。
- ハードウェア MFT では、「非同期 MFT」で説明されているように、新しい非同期処理モデルを使用する必要があります。
- ハードウェア MFT では、「動的形式の変更」の説明に従って、 動的形式の変更をサポートする必要があります。
ハードウェア MFT 属性
ハードウェア MFT では、属性に関連する次のメソッドを実装する必要があります。
- IMFTransform::GetAttributes: グローバル MFT 属性の属性ストアを返します。
- IMFTransform::GetInputStreamAttributes: 入力ストリームの属性ストアを返します。
- IMFTransform::GetOutputStreamAttributes: 出力ストリームの属性ストアを返します。
MFT を最初に作成するときは、独自のグローバル属性ストア (つまり 、GetAttributes によって返される属性ストア) に次の属性を設定する必要があります。
属性 | 説明 |
---|---|
MF_TRANSFORM_ASYNC | TRUE に設定する必要があります。 MFT が非同期処理を実行することを示します。 |
MFT_ENUM_HARDWARE_URL_Attribute | ハードウェア デバイスのシンボリック リンクが含まれています。 トポロジ ローダーは、この属性の存在を使用して、MFT がハードウェア デバイスを表しているかどうかをテストします。 |
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE | TRUE に設定する必要があります。 MFT で動的な形式の変更がサポートされていることを示します。 |
ハードウェア ハンドシェイク シーケンス
2 つの MFT が同じ物理デバイスを表している場合、ハードウェア バス経由など、ハードウェア内でデータを交換できます。 データをシステム メモリにコピーしてからデバイスに戻す必要はありません。
次の図では、"A" と "B" というラベルが付いた MFT は、同じハードウェア内の機能ブロックを表しています。 たとえば、コード変換のシナリオでは、"A" はハードウェア デコーダーを表し、"B" はハードウェア エンコーダーを表す場合があります。 "A" と "B" の間のデータ フローは、ハードウェア内で発生します。 "C" というラベルが付いた MFT はソフトウェア MFT です。 "B" から "C" へのデータ フローでは、システム メモリが使用されます。
ハードウェア接続を確立するには、2 つのハードウェア MFT でプライベート通信チャネルを使用する必要があります。 この接続は、フォーマット ネゴシエーション中、メディアの種類が設定される前、 および ProcessInput の最初の呼び出しの前に確立されます。 接続プロセスは次のように動作します。
トポロジ ローダーは、両方の MFT に MFT_ENUM_HARDWARE_URL_Attribute 属性が存在する場合にチェックします。 この属性の値は検査されないことに注意してください。
MFT_ENUM_HARDWARE_URL_Attributeが両方の MFT に存在する場合、トポロジ ローダーは次の処理を行います。
- トポロジ ローダーは、アップストリーム MFT (A) で IMFTransform::GetOutputStreamAttributes を呼び出します。 このメソッドは、 IMFAttributes ポインターを 返します。 このポインターを pUpstream と示します。
- トポロジ ローダーは、ダウンストリーム MFT (B) で IMFTransform::GetInputStreamAttributes を呼び出します。 この呼び出しでは、 IMFAttributes ポインターも返されます。 このポインターを pDownstream と示します。
- トポロジ ローダーは、IMFAttributes::SetUnknown を呼び出して pDownstream にMFT_CONNECTED_STREAM_ATTRIBUTE属性を設定します。 属性の値は pUpstream ポインターです。
- トポロジ ローダーは、pDownstream と pUpstream の両方でMFT_CONNECTED_TO_HW_STREAM属性を TRUE に設定します。
この時点で、ダウンストリーム MFT には、次の図に示すように、アップストリーム MFT の属性ストアへのポインターがあります。
注意
わかりやすくするために、この図はストリームと属性ストアを個別のオブジェクトとして示していますが、実装には必須ではありません。
ダウンストリーム MFT は IMFAttributes ポインターを使用して、アップストリーム MFT とのプライベート通信チャネルを確立します。 チャネルはプライベートであるため、正確なメカニズムは 実装によって定義されます。 たとえば、MFT はプライベート COM インターフェイスに対してクエリを実行する場合があります。
手順 4 の間に、ダウンストリーム MFT は、2 つの MFT が同じ物理デバイスを共有しているかどうかを確認する必要があります。 そうでない場合は、データ転送にシステム メモリを使用するようにフォールバックする必要があります。 これにより、MFT はソフトウェア MFT やその他のハードウェア デバイスで正しく動作します。
ハンドシェイクが成功し、2 つの MFT がプライベート データ チャネルを共有する場合、接続ポイントで標準データ処理モデル (次のセクションで説明) は使用されません。 具体的には、ダウンストリーム MFT は METransformNeedInput イベントを送信しません。詳細については、このトピックの次のセクションを参照してください。
データ処理
ハードウェア MFT がデータ転送にシステム メモリを使用する場合、このプロセスは次のように機能します。
- より多くの入力を要求するために、MFT は METransformNeedInput イベントを送信します。
- METransformNeedInput イベントにより、パイプラインは IMFTransform::P rocessInput を呼び出します。
- MFT に出力データがある場合、MFT は METransformHaveOutput イベントを 送信します。
- METransformHaveOutput イベントにより、パイプラインは IMFTransform::P rocessOutput を呼び出します。
詳細については、「 非同期 MFT」を参照してください。
ただし、MFT がハードウェア チャネルを使用している場合、ハードウェア接続ポイントではこれらのイベントは送信されません。これは、すべてのデータ転送がハードウェア内で内部的に行われるためです。 そのため、パイプラインは接続ポイントで ProcessInput または ProcessOutput を呼び出しません。
たとえば、このトピックの最初の図を考えてみましょう。 この構成を考えると、データ処理は次のように行われます。
- "A" は METransformNeedInput を 送信してデータを要求します。
- パイプラインは、"A" で ProcessInput を呼び出します。
- "A" と "B" は、ハードウェア内のデータを処理します。
- 処理が完了すると、"B" は METransformHaveOutput イベントを 送信します。
- パイプラインは、"B" で ProcessOutput を呼び出します。
ペア デコーダー/エンコーダー
デコーダーとエンコーダーが同じハードウェア チップ上に配置されている場合は、コード変換時にそれらを一緒に使用することをお勧めします。 つまり、一方を選択すると、もう一方がコード変換パイプラインで選択されます。 一致するハードウェア コーデックを確実に選択するには、両方のコーデック MFT がカスタム メディア タイプを提供する必要があります。 カスタム メディアの種類を作成するには:
- 必要に応じて、 MF_MT_MAJOR_TYPE 属性を MFMediaType_Audio または MFMediaType_Videoに設定します。
- MF_MT_SUBTYPE属性をカスタム GUID 値に設定します。
その他の型属性は省略可能です。 デコーダーは 、IMFTransform::GetOutputAvailableType からカスタム型を返し、エンコーダーは IMFTransform::GetInputAvailableType メソッドからカスタム型を返します。 どちらの場合も、カスタム型はリストの最初のエントリである必要があります (dwTypeIndex = 0)。
ソフトウェア コーデックを操作するには、ビデオ用の NV12 など、少なくとも 1 つの標準形式も返す必要があります。 標準形式は、カスタム型 (dwTypeIndex> 0) の後に表示されます。 2 つのコーデックを常にペアリングする必要があり、ソフトウェア コーデックと相互運用できない場合、MFT はカスタム形式のみを返し、標準形式は返しません。
注意
デコーダーが標準形式を返さない場合、 拡張ビデオ レンダラーでの再生には使用できません。 その場合は、トランスコード専用デコーダーとして登録する必要があります。 「 トランスコード専用デコーダー」を参照してください。
関連トピック