DirectX ビデオ アクセラレーションの有効化
[このページに関連付けられている機能である Windows Media Format 11 SDK は、レガシ機能です。 これは、ソース リーダーとシンク ライターによって置き換えられます。 ソース リーダーとシンク ライターは、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、Windows Media Format 11 SDK ではなくソース リーダーとシンク ライターを使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
このセクションでは、カスタム プレーヤーでストリーミング コンテンツを再生するときに Microsoft® DirectX® ビデオ アクセラレーションを有効にする方法について説明します。
バックグラウンド
DirectX ビデオ アクセラレーション (DirectX VA) は、2-D デコード操作のハードウェア アクセラレーション用の API 仕様です。 これにより、ソフトウェア デコーダーは、特定の CPU 負荷の高い操作を処理用のグラフィックス カードにオフロードできます。 これにより、エンド ユーザーは、DirectX VA 互換グラフィックス カードを搭載した古いコンピューターで全画面表示 DVD 再生などの高ビット レートビデオが可能になります。
Windows Media Format 9 Series SDK 以降では、DMO ラッパー フィルターで DirectX VA がサポートされています。 つまり、ローカル再生の場合、アプリケーションは WM ASF リーダー フィルターを使用して Windows メディア ベースのコンテンツを再生でき、グラフィックスカードがサポートしている場合は DirectX VA ハードウェア アクセラレータが自動的に呼び出されます。 ただし、WM ASF リーダー フィルターでは、ストリーミングされたコンテンツの再生はサポートされていません。 そのため、カスタム プレーヤーでストリーミング コンテンツを再生するときに DirectX VA をサポートする場合は、別のメカニズムを使用する必要があります。これは、Windows Media 9 シリーズ以降Windows メディア プレーヤーで使用されるメカニズムです。
Windows メディア プレーヤーは QASF フィルターが開発される前に設計されているため、Windows メディア プレーヤーには、Windows Media ベースのコンテンツを再生するための Windows Media Format SDK に基づく独自のソース フィルターがあります。 WMP Windows Media Source Filter は、圧縮解除されたデータをオーディオおよびビデオ レンダラーに直接配信します。 これに対し、WM ASF リーダーは、DMO ラッパー内でホストされている Windows Media Decoder DirectX Media Objects (DMO) に圧縮されたコンテンツをダウンストリームで配信します。 次の図は、WM ASF リーダーと WMP Windows メディア ソース フィルターの違いを示しています。
ストリーミング コンテンツに対して DirectX VA を有効にするには、上部の図のようなカスタム ソース フィルターを作成する必要があります。 基本的に、このフィルターでは、Windows Media Format SDK を使用して WM Reader オブジェクトをインスタンス化し、サンプルを展開し、出力ピンでダウンストリームに送信します。 この説明では、ソース フィルターを既に作成しており、DirectX VA サポートを実装する準備ができていることを前提としています。
DirectX VA を有効にするには、ソース フィルターの基本的なタスクは、DirectX VA 接続をネゴシエートするために必要なインターフェイスをビデオ レンダラーと WMV デコーダー DMO に提供することです。 ソース フィルターは、これらのネゴシエーションに参加しません。 ストリーミングの開始後、ソース フィルターで実行できる DirectX VA 関連のタスクは、WMV デコーダーがビデオ レンダラーに配信する前に、ビデオ サンプルのタイム スタンプを変更することだけです。 これを行う主な理由は、標準の DirectShow® インターフェイスが有効にするもの以外のカスタム タイムラインコントロールを提供することです。
Windows Media Format SDK、プレーヤーのソース フィルター、Windows Media Video デコーダー DMO、オーバーレイ ミキサーまたはビデオ 混合レンダラーの間で必要な通信を可能にするために、3 つのインターフェイスが定義されています。 これらのインターフェイスについては、次の表で説明します。
インターフェイス | 説明 |
---|---|
IWMCodecAMVideoAccelerator | Windows Media デコーダー DMO によって公開され、メディア プレーヤーのソース フィルターによって呼び出され、Windows Media Video コンテンツのデコードに DirectX VA を有効にするために必要なさまざまな接続を設定します。 |
IWMPlayerTimestampHook | プレーヤーのソース フィルターに実装されます。 これにより、フィルターはビデオ サンプルのタイム スタンプをダウンストリームに配信する前に変更できます。 |
IWMReaderAccelerator | WM Reader オブジェクトに実装されます。 これは、デコーダー DMO からインターフェイスを取得するために、プレーヤー ソース フィルターによって呼び出されます。 |
DirectX VA 対応再生での操作の順序
このセクションでは、DirectX VA 対応プレーヤーとそのソース フィルターの実行時の操作の一般的な順序について説明します。 このセクションで参照されるコンポーネントは次のとおりです。
- プレーヤーと呼ばれるサード パーティのメディア プレーヤー。
- Windows Media Format SDK を使用して Windows メディア ベースのコンテンツを展開する、プレーヤーによってインスタンス化されたカスタム ソース フィルター。
- プレーヤーのソース フィルターのビデオ出力ピン。出力ピンと呼ばれます。
- DirectShow ビデオ再生フィルター グラフ(グラフと呼ばれます)。
- VMR と呼ばれるビデオ 混合レンダラー。
- リーダーと呼ばれる Windows Media Format SDK 非同期リーダー オブジェクト。
- デコーダー DMO と呼ばれる Windows Media Video デコーダー DirectX メディア オブジェクト。
操作の順序は次のとおりです。
- プレーヤーは、ソース フィルターとリーダー オブジェクトをインスタンス化します。 リーダーは、ビデオ デコーダー DMO を作成し、その上に (圧縮された) 入力の種類を設定します。 これは、SDK とデコーダー DMO がグラフとのネゴシエーション プロセスに関与する必要があり、DMO が手順 9 の間に入力形式を認識する必要があるため、プレーヤーがビデオ再生グラフの構成を試みる前に行う必要があります。
- プレーヤーは IGraphBuilder::Render を呼び出し、ビデオ ソース フィルターの出力ピンを指定します。 この時点で、DirectShow フィルター グラフ マネージャーは VMR をプレーヤーのビデオ ソース フィルターに接続しようとします。
- フィルター グラフ マネージャーは、プレーヤーのビデオ ソース フィルターの出力ピンで IPin::Connect を呼び出します。
手順 4 から 10 は 、IPin::Connect 内で行われます。
ソース フィルターは、リーダーの IWMReaderAccelerator::GetCodecInterface メソッドから IWMCodecAMVideoAccelerator インターフェイスを取得します。 コーデックが DirectX VA をサポートしていない場合、 GetCodecInterface の呼び出しが失敗する可能性があります。 この場合、ネゴシエーションは DirectX VA サポートなしで通常どおり続行されます。
ソース フィルターは、IWMCodecAMVideoAccelerator::SetAcceleratorInterface を介してデコーダー DMO に接続するために渡されたピンから IAMVideoAccelerator ポインターを渡します。
次に、ソース フィルターは 、IPin::Connect 操作の残りの部分を CBaseOutputPin::Connect メソッドに委任します。 SDK を使用した形式の列挙は、現在と同様に続行されます。 コーデックが接続されているコンテンツに対して DirectX VA をサポートしている場合、コーデック DMO は、YUV と RGB の種類がサポートされる前に、これらの DirectX VA サブタイプを最初に提示します。 DirectX VA のサポートが利用可能な場合は、DirectX VA サブタイプのコンテキストで手順 7 から 11 が試行されます。 次のコード スニペットは、DirectX VA メディア サブタイプを識別する方法を示しています。
bool IsDXVASubtype( AM_MEDIA_TYPE * pmt ) { // All DXVA types have the same last 3 DWORDs. // guidDXVA is the base GUID for all DXVA subtypes. GUID guidDXVA = { 0x00000000, 0xa0c7, 0x11d3, { 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5 } }; unsigned long const * plguid; unsigned long const * plguidDXVA; plguid = (unsigned long const *)&pmt->subtype; plguidDXVA = (unsigned long *)&guidDXVA; if( ( plguid[1] == plguidDXVA[1] ) && ( plguid[2] == plguidDXVA[2] ) && ( plguid[3] == plguidDXVA[3] ) ) { return true; } return false; }
CBaseOutputPin::Connect 実装は、手順 3 で IPin::CompleteConnect を呼び出します。 DirectX VA サブタイプが考慮されている場合は、DirectX VA ネゴシエーションが試行されます。 出力ピンは IWMCodecAMVideoAccelerator::NegotiateConnection を呼び出し、現在の出力メディアの種類を渡します。
デコーダー DMO は 、IAMVideoAccelerator インターフェイスを介して VMR と必要なネゴシエーションを実行し、2 人が同意したビデオ サブタイプ GUID を返します。 出力ピンは、このプロセス中に受信したすべての IAMVideoAcceleratorNotify 呼び出しをデコーダー DMO の IAMVideoAcceleratorNotify インターフェイスに委任します。これは、 IWMReaderAccelerator::GetCodecInterface メソッドを使用して取得することもできます。
NegotiateConnection が成功した場合、出力ピンは IWMCodecAMVideoAccelerator::SetPlayerNotify を IWMPlayerTimestampHook インターフェイスで呼び出します。 このフックを使用すると、ソース フィルターは、レンダラーに渡される前に、サンプルのタイム スタンプを更新できます。
ソース フィルターは、ネゴシエートされたメディアの種類で IWMReaderAccelerator::Notify を呼び出します。 これにより、リーダーは内部変数を更新し、DirectX VA にコミットできます。 これは、コーデックまたはリーダーが失敗する最後の場所です。 上記の手順のいずれかが失敗した場合、ソース フィルターは手順 3 に戻り、リーダーによって列挙された次の型を試す必要があります。
再生が開始されます。 接続出力の種類が DirectX VA の場合、リーダーはデコーダー DMO からの出力バッファーを無視します。
IPin::D isconnect が発生すると、ソース フィルターは IWMCodecAMVideoAccelerator::SetAcceleratorInterface を NULL で呼び出します。 これにより、コーデックとレンダラーの間の DirectX VA 接続が切断されます。
関連トピック