Share via


デコーダーによる IAMVideoAccelerator の使用方法

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayerIMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]

IAMVideoAccelerator インターフェイスを使用すると、DirectX ビデオ アクセラレーション (VA) を含む一般的なビデオ アクセラレーション操作が可能になります。 DirectX VA 以外のアクセラレーションの場合、デコーダーとビデオ ドライバーの両方が共通のプロトコルに準拠している必要があります。

このセクションでは、このインターフェイスを使用するときにデコーダーが従う必要がある操作の一般的な順序について説明します。 DirectX VA ベースのデコーダーに固有の詳細については、「 DirectX ビデオ アクセラレーションを IAMVideoAccelerator にマッピングする」を参照してください

注意

このインターフェイスは、Windows 2000 以降で使用できます。

 

IAMVideoAccelerator インターフェイスは、オーバーレイ ミキサーまたはビデオ 混合レンダラー (VMR) の入力ピンで公開されます。 IAMVideoAcceleratorNotify インターフェイスは、デコーダーの出力ピンで公開されます。 フィルター ピンを接続するためのイベントのシーケンスは次のとおりです。

  1. Filter Graph Manager は、デコーダー フィルターの出力ピンで IPin::Connect を呼び出します。 AM_MEDIA_TYPEは省略可能なパラメーターです。

    • AM_MEDIA_TYPE は、メディアの種類を記述するデータ構造です。 これには、majortype GUID (ここではMEDIATYPE_Videoする必要があります)、サブタイプ GUID (この場合はビデオ アクセラレータ GUID である必要があります)、その他のさまざまなものが含まれています。 そのうちの 1 つは、メディアに関する情報を含む形式の GUID です。たとえば、 MPEG1VIDEOINFOVIDEOINFOHEADERMPEG2VIDEOINFO、または VIDEOINFOHEADER2 構造体では、圧縮されていないビデオ画像の幅と高さを含みます。
    • AM_MEDIA_TYPE構造は、存在する場合は、指定されたメディアの種類を使用して動作するようにデコーダーに指示します。これは、"完全に指定された" または "部分的に指定された" 可能性があります。 "完全に指定" されている場合、デコーダーは通常、そのメディアの種類で操作を試みます。 "部分的に指定された" 場合は、"部分的に指定された" メディアの種類と一致する方法で接続するために使用できる "完全に指定された" 互換性のある操作モードの検索が試みられます。
    • 接続に使用する "完全に指定された" メディアの種類を見つけようとする通常の方法は、出力ピンがサポートするすべての "完全に指定された" メディアタイプのリストを実行し、"部分的に指定された" メディアタイプと互換性があり、成功するまでそれぞれのメディアタイプとの接続を試みる方法です。 IPin::Connect 呼び出しにAM_MEDIA_TYPEが含まれないが、出力ピンですべてのメディアの種類をチェックする必要がある場合、通常はプロセスは似ています。
  2. デコーダーは、特定のAM_MEDIA_TYPE (ビデオ アクセラレータ GUID を含む) がダウンストリーム入力ピンでサポートされているかどうかをチェックする場合は、そのピンの IPin::QueryAccept (ビデオ アクセラレータ GUID をAM_MEDIA_TYPEのサブタイプとして使用) を呼び出すか、下の項目 5 で説明するようにそのピンへの接続を試みることができます。

  3. デコーダーがダウンストリーム入力ピンがサポートするビデオ アクセラレータ GUID を認識せず、ダウンストリーム入力ピンの IPin::QueryAccept を呼び出して特定の候補のビデオ アクセラレータ GUID のみを提案したくない場合、デコーダーは IAMVideoAccelerator::GetVideoAcceleratorGUIDs を呼び出して、ピンがサポートするビデオ アクセラレータ GUID の一覧を取得できます。

  4. 一部の特定のビデオ アクセラレータ GUID の場合、デコーダーはダウンストリーム入力ピンの IAMVideoAccelerator::GetUncompFormatsSupported を呼び出して、特定のビデオ アクセラレータ GUID のレンダリングに使用できる DDPIXELFORMAT ピクセル形式の一覧を取得できます。 返されるリストは、優先順位が下がっている (つまり、最も優先される形式が最初に一覧表示されている) と見なす必要があります。

  5. デコーダーはダウンストリーム入力ピンの IPin::ReceiveConnection を呼び出し、メディアの種類のサブタイプとして適切なビデオ アクセラレータ GUID を持つ AM_MEDIA_TYPE を渡します。 これにより、非圧縮出力サーフェスの作成 ( AM_MEDIA_TYPEで見つかった幅と高さ、以下で説明する呼び出しによって割り当てられるサーフェスの数、およびビデオ アクセラレータがその目的で使用できるその他の情報 (ビデオ アクセラレータ GUID 自体など) を使用して割り当てられるなど、操作の接続が設定されます。 ダウンストリーム入力ピンがビデオ アクセラレータ GUID またはその他の接続の側面を拒否した場合、 IPin::ReceiveConnection が失敗する可能性があります。 IPin::ReceiveConnection が失敗した場合、これは返された HRESULT で示され、デコーダーは、たとえば、AM_MEDIA_TYPE構造体に新しいビデオ アクセラレータ GUID を使用して、もう一度呼び出しを試みることができます。

    • [!注意]

      これは、デコーダーがダウンストリーム入力ピンでサポートされている内容を特定するもう 1 つの方法 (および最も明確な方法) です。 IPin::ReceiveConnection を呼び出して接続を試み、接続試行が成功したかどうかを確認するだけです。

       

    • IPin::ReceiveConnection 中に、レンダラーはデコーダーの IAMVideoAcceleratorNotify::GetUncompSurfacesInfo を呼び出し、割り当てる非圧縮サーフェスの数を把握するために、ビデオ アクセラレータ GUID と AMVAUncompBufferInfo 構造体を渡します。 デコーダーは、特定の種類に割り当てられるサーフェスの最小数と最大数、および割り当てられるサーフェスのピクセル形式を記述する DDPIXELFORMAT 構造体を含む 構造体を入力して返します。

    • [!注意]

      ビデオ アクセラレータ GUID 以外の IAMVideoAcceleratorNotify::GetUncompSurfacesInfo の呼び出しでは、実際にはデコーダーには何も渡されません。

       

  6. レンダラーはデコーダーの IAMVideoAcceleratorNotify::SetUncompSurfacesInfo を呼び出し、割り当てられた非圧縮サーフェスの実際の数をデコーダーに渡します。

  7. レンダラーはデコーダーの IAMVideoAcceleratorNotify::GetCreateVideoAcceleratorData を呼び出して、ビデオ アクセラレータの初期化に必要なデータを取得します。

  8. デコーダーは IAMVideoAccelerator::GetCompBufferInfo を呼び出し、ビデオ アクセラレータ GUID、 AMVAUncompDataInfo 構造体、圧縮バッファーの種類の数を渡して、ビデオ アクセラレータ GUID で使用される圧縮データ バッファーの各種類に対応する AMVACompBufferInfo データ構造のセットを取得します。

    • AMVAUncompDataInfo 構造体には、デコードされた非圧縮データの幅と高さ (ピクセル単位) と、圧縮されていない画像の DDPIXELFORMAT が含まれます。
    • 返される AMVACompBufferInfo データ構造体には、次のものが含まれます。
      • 特定の型に必要な圧縮バッファーの数。

      • 作成するサーフェスの幅と高さ (実際の意味を持つフィールドとそうでないフィールド)。

        注意

        圧縮バッファーの DirectDraw サーフェス割り当て操作では、これらのサーフェスの幅または高さが 2^15 以上になることは現在提供されていませんが、この制限に違反した場合、サーフェス割り当ての呼び出しが過度に失敗することはありません。 そのため、ドライバーは、このような極端なサイズを回避するために圧縮バッファー メモリの要求を構造化できます。 たとえば、width="1" と height="65536" のバッファーを要求するのではなく、ドライバーは width="1024" と height="64" のバッファーを要求する必要があります。

         

      • サーフェスで使用される合計バイト数。

      • DirectDrawSurface オブジェクトを定義する DDSCAPS2 型の構造体。圧縮データを格納するサーフェスを作成する機能を記述します。

      • DDPIXELFORMAT。圧縮データを格納するためにサーフェスを作成するために使用されるピクセル形式を記述します (実際の意味を持つ場合とそうでない場合があるフィールド)。

注意

デコーダーの IAMVideoAcceleratorNotify インターフェイス メソッドの一部に対するレンダラーの呼び出しは、レンダラーの IPin::ReceiveConnection に対するデコーダーの呼び出しの内部で発生する可能性があります (通常は発生します)。 具体的には、これは次の場合に適用されます。

 

注意

動的な形式の変更をサポートするために、デコーダーは、フィルターが接続され実行されている間に、上記ごとに IPin::ReceiveConnection やその他のメソッドを呼び出すこともできます。 この機能は、動的な形式の変更をサポートするために提供されます (ただし、H.263、Annex P、sense ではありません。すべてのデータ セットがゼロから再び起動され、参照画像情報が失われるため)。

 

初期化後の操作中に 使用される IAMVideoAccelerator の説明を次に示します。

  1. 非圧縮サーフェスごとに、デコーダーは IAMVideoAccelerator::BeginFrame を呼び出して、出力画像を作成する処理を開始します。 これを行うと、デコーダーは AMVABeginFrameInfo 構造体を 送信します。

    • AMVABeginFrameInfo 構造体には、宛先バッファーのインデックス、ダウンストリームに送信するデータへのポインター、およびデコーダーが読み取るためのデータをアクセラレータが配置できる場所へのポインターが含まれています。

    • 注 1: アクセラレータは、ダウンストリームに移動する前にレンダラーによって変換されるため、実際には宛先バッファー インデックスを受け取りません。

    • 注 2: IAMVideoAccelerator::BeginFrame は、 IAMVideoAccelerator::EndFrame の呼び出しの間に複数回呼び出すことができます。

    • 注 3: インターフェイス操作では、ビットストリーム内のすべての画像を処理するために IAMVideoAccelerator::BeginFrameIAMVideoAccelerator::EndFrame を呼び出す必要があるという前提はありません。

      IAMVideoAccelerator::BeginFrame は、インターフェイスに関する限り、インデックスと非圧縮サーフェスの間にレンダラー内に関連付けを作成することです。 また、デバイス ドライバーで特定の関数を呼び出す手段も提供します (デコーダーとデバイス ドライバーの間で任意のデータをやり取りする手段がサポートされています)。

      (ただし、DirectX VA 操作では、以下に説明する要件があります。 IAMVideoAccelerator::BeginFrameIAMVideoAccelerator::EndFrame は、ビットストリーム内のすべての個々の画像を処理するために呼び出す必要があります)。

  2. アクセラレータに圧縮されていないデータを送信する場合、デコーダーは次を呼び出します。

    • IAMVideoAccelerator::QueryRenderStatus を使用して、バッファーの読み取りまたは書き込みが安全かどうかを判断します。
    • IAMVideoAccelerator::GetBuffer を使用して、指定されたバッファーへのアクセスをロックして取得します (このアクセスを取得するために以前にこれを呼び出していない場合)。 GetBuffer を使用して、 IAMVideoAccelerator::BeginFrame が呼び出された最後の非圧縮出力画像の内容のコピーを取得することもできます。このコピー先バッファー インデックスに 対して IAMVideoAccelerator::EndFrame が呼び出されていません。 DDI が要求されたバッファーのDDERR_WASSTILLDRAWINGのレンダリング状態を返す場合、この条件がクリアされるまで 、GetBuffer 内でスリープ ループが操作されます。 GetBuffer を呼び出すには、デコーダーには、IAMVideoAccelerator::GetCompBufferInfo を呼び出すことによって取得される AMVACompBufferInfo データ構造からの情報が必要です。
    • AMVABUFFERINFO データ構造の配列で示されているように、一連の圧縮バッファー内のデータを処理する必要があることを示す IAMVideoAccelerator::Execute。 関数コード dwFunction は、この呼び出しでドライバーに渡されます。 lpPrivateInputData ポインターは、ダウンストリームに送信するために一部のデータにも渡され、lpPrivateOutputData ポインターは、ダウンストリーム プロセスがデコーダーが読み取るためのデータを配置できる場所に渡されます。
    • IAMVideoAccelerator::ReleaseBuffer : デコーダーが指定したバッファーの使用を一瞬完了し、バッファーへのロックされたアクセスが不要になっていることを示します。 (デコーダーがバッファーを引き続き使用する場合は、IAMVideoAccelerator::ReleaseBuffer を一瞬呼び出さないため、実際にバッファーを使用しない予定になるまで IAMVideoAccelerator::GetBuffer を呼び出す必要がなくなります)。QueryRenderStatus がバッファーの書き込みが安全であることを示すまで、Execute が呼び出された後、デコーダーはバッファーに書き込むべきではありません。
  3. 宛先バッファーの出力処理を完了するために、デコーダーは IAMVideoAccelerator::EndFrame を呼び出します。 この呼び出しでは、任意のデータをダウンストリームに渡すことができます。これは、この呼び出しの結果として発生する基本的なすべてです。 この呼び出しでは宛先バッファー インデックスは送信されないため、渡される任意のデータにこの指示が含まれていない限り、完了した宛先バッファーを正確にアクセラレータに示すことはできません。

  4. フレームを表示するために、デコーダーは、表示するフレームのインデックスを使用して IAMVideoAccelerator::D isplayFrame を呼び出し、開始/停止タイム スタンプと関連するフラグ (AM_SAMPLE2_PROPERTIES構造体の dwTypeSpecificFlagsVIDEOINFOHEADER2 構造体の dwInterlaceFlags など) を含む IMediaSample 構造体を呼び出します。 デコーダーは、 DisplayFrame を呼び出す前に、フレームの内容に影響を与えるすべての圧縮解除操作が完了したことを確認する必要があります。

  5. 最後に、デコーダーは、すべての処理が完了したら、 IAMVideoAccelerator::EndFrame を呼び出して残りのすべての開始出力フレームの完了を示し、未リリースの各バッファーに対して IAMVideoAccelerator::ReleaseBuffer を呼び出して、ロックされているすべてのバッファーを解放する必要があります。

デコーダーのインターフェイスと仕様