D3D12 ビデオ エンコード
この記事では、Direct3D12 ビデオ エンコード機能に関するドライバー開発者向けの一般情報を提供します。 アプリケーション レベルの仕様を含む詳細については、D3D ビデオ エンコード仕様に関する資料を参照してください。
Direct3D 12 ビデオ エンコードについて
Windows 11 (WDDM 3.0) より前は、DirectX 12 によって、ビデオ デコード、ビデオ処理、モーション推定など、いくつかのビデオ アプリケーションで GPU アクセラレーションをサポートするために、アプリケーション レベルおよびドライバー レベルのインターフェイス (API と DDI) が提供されていました。
Windows 11 以降、D3D12 では既存のビデオ API/DDI ファミリにビデオ エンコード機能が追加されています。 この機能は既存の D3D12 フレームワークと一貫性のある一連のエンコード API/DDI を提供するもので、開発者は GPU アクセラレーション対応ビデオ エンジンを使用してビデオ エンコードを実行できます。
ビデオ エンコード フレームワークは、モノのインターネット (IoT)、クラウド、メディア API、機械学習、ゲーム ストリーミングといった多様なシナリオでビデオ エンコード ハードウェア アクセラレーション機能を利用できるようにするものです。
AV1 エンコードのサポートは、Windows 11 バージョン 24H2 (WDDM 3.2) で追加されています。 詳しくは、「D3D12 AV1 ビデオ エンコード」をご覧ください。
サポートされているコーデック
Windows 11 以降のサポート対象コーデックは H.264 と HEVC ですが、D3D12 ビデオ エンコード フレームワークを使用すれば、AV1 などの新しいコーデックにオープンに拡張できます。
このフレームワークのインターフェイスのコーデック固有の側面は、コーデック固有の構造体と共用体型へのアクセスに委任されています。 たとえば、D3D12DDI_VIDEO_ENCODER_CODEC_CONFIGURATION_0082_0 構造体には、コーデック固有の構成情報を含むコーデック固有の D3D12DDI_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_0082_0 構造体と D3D12DDI_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_0082_0 構造体へのポインターを持つ共用体が含まれています。
拡張性に関するバイナリ インターフェイスの互換性を維持するために、共用体型には常にコーデック固有の構造体へのポインターが含まれます。 共用体型のサイズは、ホスト アーキテクチャのポインター サイズに基づいて一定です。 この決定により、インターフェイスを拡張する場合に、共用体型のメンバーを保持する (または匿名共用体型を含む) 構造体が、その型サイズを変更することも防止できます。 一部の共用体には列挙型へのポインターのみが含まれています。整合性を保つために、新しいコーデックがそれらの概念を表すために列挙型よりも複雑な型を必要とする場合にも、これらの列挙型がポインターとして参照されます。
レポート ビデオ エンコードのサポートおよび機能の報告
ビデオ エンコードのサポートと機能をドライバーが報告できるようにするために、既存のビデオ関連フレームワークが拡張されました。
D3D12DDI_FEATURE_VERSION_VIDEO_0083_0 は、Windows 11 に導入された D3D12 ビデオ エンコードのすべてのマイルストーンの最初の完全な実装を定義したバージョン番号です。
D3D12DDICAPS_TYPE_VIDEO_0020 列挙は、次のビデオ エンコード サポート値を含むように拡張されました。
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_CODEC = 31,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_PROFILE_LEVEL = 32,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_OUTPUT_RESOLUTION_RATIOS_COUNT = 33,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_OUTPUT_RESOLUTION = 34,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_INPUT_FORMAT = 35,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_RATE_CONTROL_MODE = 36,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_INTRA_REFRESH_MODE = 37,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_FRAME_SUBREGION_LAYOUT_MODE = 38,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_HEAP_SIZE = 39,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_CODEC_CONFIGURATION_SUPPORT = 40,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_SUPPORT = 41,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT = 42,
- D3D12DDICAPS_TYPE_VIDEO_0080_ENCODER_RESOURCE_REQUIREMENTS = 43
D3D ランタイムは、ドライバーの PFND3D12DDI_VIDEO_GETCAPS コールバックを呼び出して、ビデオ エンコード サポートを照会します。
ビデオ エンコードをサポートするドライバーは、ビデオ エンコード コールバック関数へのポインターを D3D12DDI_DEVICE_FUNCS_VIDEO_0082_0 構造体に入れて D3D ランタイムに提供します。
D3D12 ビデオ エンコード コールバック関数
D3D12 ビデオ エンコードをサポートするには、ドライバーで次のコールバック関数を実装します。
ビデオ エンコーダーを表すドライバー オブジェクトの作成
PFND3D12DDI_CALCPRIVATEVIDEOENCODERSIZE_0082_0: D3D ランタイムがドライバー オブジェクトに割り当てる必要があるメモリ量を計算します。
PFND3D12DDI_CREATEVIDEOENCODER_0082_0: ビデオ エンコード セッションの状態を保持する実際のビデオ エンコーダー オブジェクトを作成します。
ビデオ エンコーダー ヒープを表すドライバー オブジェクトの作成
PFND3D12DDI_CALCPRIVATEVIDEOENCODERHEAPSIZE_0080_2: D3D ランタイムがドライバー オブジェクトに割り当てる必要があるメモリ量を計算します。
PFND3D12DDI_CREATEVIDEOENCODERHEAP_0080_2: 解像度に依存するドライバーのリソースと状態を含むビデオ エンコーダー ヒープ オブジェクトを作成します。
フレームのエンコード
PFND3D12DDI_VIDEO_ENCODE_FRAME_0082_0: エンコード フレーム操作をコマンド一覧に記録します。
PFND3D12DDI_VIDEO_ENCODE_RESOLVE_OUTPUT_METADATA_0082_0: エンコード操作後にこの関数も呼び出して、エンコード操作の出力メタデータを読み取り可能な形式に解決する必要があります。 解決後のドライバーのメタデータのレイアウトは、こちらの仕様の図に示されている例のようになります。
ビデオ エンコーダーおよび関連ヒープの破棄
テスト
次のテストは、Windows Hardware Lab Kit (WHLK) の一部として含まれています。 詳細については、WHLK を参照してください。
テスト名 | 説明 |
---|---|
CreateVideoEncoder | 報告された CheckFeatureSupport 関連のケースに基づいて、VideoEncoder/VideoEncoderHeap の作成を検証します。 |
SingleEncodeH264/HEVC | 構造画像の基本検査のための QR コード ベースのテスト。 入力画像シーケンスに定義済みの QR コンテンツをスタンプしてから、エンコードとデコードを行い、最終的に出力値 (および、ある程度の品質) が期待どおりであることを確認します。 |
EncodeProfileLevelSuggestionsH264/HEVC | H.264/HEVC 仕様と、D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT に入力として渡された構成に基づき、D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT.SuggestedProfile/Level の値が想定どおりであることを検証します。 |
EncodeHeapSizeCap | 増加していくさまざまな入力引数を使用してメモリ占有領域の増加を検証します。 |
SimpleGOPEncodeH264/HEVC (10 ビット) | さまざまな解像度、GOP パターン、スライス モード、その他のコーデック構成を使用して入力ビデオをトランスコードし、入力ビデオ ストリームの違いに対して、エンコードされた出力ビデオが許容可能かどうかを検証します。 この比較は、ピーク信号対雑音比 (PSNR) を使用して行われます。 |
EncodeSubregions/ResolutionReconfiguration | オンザフライ再構成を検証します。 |
EncodeH264LongTermReferences | 長期画像参照の使用を検証します。 |
EncodeIntraRefresh | オープン IPP...P...P... GOP を使用して、イントラ リフレッシュの簡単なシナリオを検証します。 |
VideoEncodeCommandListFeatures | ビデオ エンコード コマンド一覧のプレディケーションとマーカーを検証します。 |
VideoEncodeTimestamps | ビデオ エンコード コマンド一覧のタイムスタンプを検証します。 |
ビデオ エンコードのシナリオ
OneCore
D3D12 ビデオ エンコードのサポートにより、D3D12 しか使用できないプラットフォームで、移植可能なハードウェア アクセラレーション対応ビデオ エンコードが可能になります。 これには、クラウド コンピューティングおよび IoT プラットフォームで使用されるさまざまな OneCore SKU が含まれます。 これらのシナリオでは、プラットフォーム固有のソリューションを使用することなく、ビデオ エンコード アクセラレーションを利用できます。
メディア API
移植性のある下位レベル ビデオ エンコード機能をすべてのハードウェア ベンダーで利用できます。 これにより、より上位のレベルのメディア API (メディア ファンデーションなど) が、さまざまなハードウェア プラットフォームの抽象化を処理するこの API の上にメディア レイヤーを構築できます。 API の下位レベルの設計によって、これらの上位レベルのメディア レイヤーは、参照画像管理やビットストリーム ヘッダーの書き込みの完全な制御など、ビデオ エンコード セッションの同期とメモリ割り当て/レジデンシーをきめ細かく制御することで、それぞれのシナリオに合わせて最適化できます。 この API の上にあるレイヤーへ管理責任をシフトすることにより、ハードウェア ベンダーはメディア レイヤーで一貫したエンコード ポリシー セット (アダプティブ GOP などの DPG ヒューリスティックなど) を持つことができ、異なるハードウェア プラットフォーム間で再利用できます。
D3D グラフィックス、コンピューティング、機械学習との相互運用性
D3D12 ビデオ エンコード API を使用すると、D3D12 ビデオ エンコードを D3D12 グラフィックス、コンピューティング、機械学習というシナリオと効率的に相互運用できます。カメラ ストリームで機械学習推論を実行するようなシナリオにとって、これは興味深いものになります。
ゲーム ストリーミング シナリオ
D3D12 ビデオ エンコード API を使用すると、高性能な下位レベル API を必要とするゲーム ストリーミング シナリオが可能になります。