次の方法で共有


DXVA ビデオ処理

DXVA ビデオ処理では、圧縮されていないビデオ画像の処理に特化したグラフィックス ハードウェアの機能がカプセル化されます。 ビデオ処理サービスには、インターレース解除とビデオ ミキシングが含まれます。

このトピックは、次のセクションで構成されています。

概要

グラフィックス ハードウェアでは、グラフィックス処理装置 (GPU) を使用して、圧縮されていないビデオ画像を処理できます。 ''ビデオ処理'' デバイスは、これらの機能をカプセル化するソフトウェア コンポーネントです。 アプリケーションでは、ビデオ処理デバイスを使用して、次のような機能を実行できます。

  • インターレース解除と逆テレシネ
  • メインのビデオ画像へのビデオ サブストリームの混合
  • 色調整 (ProcAmp) と画像フィルター処理
  • イメージのスケーリング
  • 色空間変換
  • アルファ ブレンド

次の図は、ビデオ処理パイプラインのステージを示しています。 この図は、実際の実装を示すものではありません。 たとえば、グラフィックス ドライバーによって、複数のステージが 1 つの操作にまとめられる場合があります。 これらの操作はすべて、ビデオ処理デバイスへの 1 回の呼び出しで実行できます。 ノイズや詳細フィルター処理など、ここに示す一部のステージは、ドライバーでサポートされていない可能性があります。

diagram showing the stages of dxva video processing.

ビデオ処理パイプラインへの入力には常に、''プライマリ'' ビデオ ストリームが含まれ、これにはメインの画像データが含まれます。 プライマリ ビデオ ストリームによって、出力ビデオのフレーム レートが決まります。 出力ビデオの各フレームは、プライマリ ビデオ ストリームからの入力データを基準にして計算されます。 プライマリ ストリームのピクセルは常に不透明であり、ピクセル単位のアルファ データはありません。 プライマリ ビデオ ストリームは、プログレッシブまたはインターレースにすることができます。

必要に応じて、ビデオ処理パイプラインでは最大 15 個のビデオ サブストリームを受信できます。 サブストリームには、クローズド キャプションや DVD サブピクチャなどの補助画像データが含まれています。 これらの画像はプライマリ ビデオ ストリーム上に表示され、通常は単独で示されるものではありません。 サブストリーム ピクチャにはピクセル単位のアルファ データを含めることができ、常にプログレッシブ フレームです。 ビデオ処理デバイスによって、プライマリ ビデオ ストリームからの現在のインターレース解除フレームとサブストリーム画像がアルファブレンドされます。

このトピックの残りの部分では、ビデオ処理デバイスへの入力データに ''ピクチャ'' という用語が使用されます。 ピクチャは、プログレッシブ フレーム、1 つのフィールド、または 2 つのインタリーブ フィールドで構成される場合があります。 出力は常にインターレース解除されたフレームです。

ビデオ ドライバーでは、複数のビデオ処理デバイスを実装し、さまざまなビデオ処理機能のセットを提供できます。 デバイスは GUID で識別されます。 次の GUID が事前に定義されています。

  • DXVA2_VideoProcBobDevice。 このデバイスによって bob インターレース解除が実行されます。
  • DXVA2_VideoProcProgressiveDevice。 このデバイスは、ビデオにプログレッシブ フレームのみが含まれており、インターレース フレームがない場合に使用されます (一部のビデオ コンテンツには、プログレッシブとインターレース フレームが混在しています。この種の "混合" ビデオ コンテンツにはプログレッシブ デバイスを使用できません。インターレース解除手順はインターレース フレームに必要であるためです)。

DXVA ビデオ処理をサポートするすべてのグラフィックス ドライバーでは、少なくともこれら 2 つのデバイスを実装する必要があります。 グラフィックス ドライバーでは、ドライバー固有の GUID によって識別される他のデバイスが提供される場合もあります。 たとえば、ドライバーで、bob インターレース解除よりも品質の高い出力を生成する独自のインターレース解除アルゴリズムが実装される場合があります。 一部のインターレース解除アルゴリズムでは、プライマリ ストリームからの前方または後方参照ピクチャが必要になる場合があります。 その場合、呼び出し元は、このセクションの後半で説明されているように、正しい順序でドライバーにこれらのピクチャを提供する必要があります。

参照ソフトウェア デバイスも提供されます。 ソフトウェア デバイスは速度ではなく品質に最適化されており、リアルタイムのビデオ処理には適していない可能性があります。 参照ソフトウェア デバイスでは、GUID 値 DXVA2_VIDEOPROCSOFTWAREDEVICE が使用されます。

ビデオ処理デバイスの作成

DXVA ビデオ処理を使用する前に、アプリケーションでビデオ処理デバイスを作成する必要があります。 このセクションの残りの部分で詳しく説明する手順の概要を以下に示します。

  1. IDirectXVideoProcessorService インターフェイスへのポインターを取得します。
  2. プライマリ ビデオ ストリームのビデオ形式の説明を作成します。 この説明を使用して、ビデオ形式をサポートするビデオ処理デバイスの一覧を取得します。 デバイスは GUID で識別されます。
  3. 特定のデバイスについて、そのデバイスでサポートされているレンダー ターゲット形式の一覧を取得します。 形式は、D3DFORMAT 値の一覧として返されます。 サブストリームを混在させる予定の場合は、サポートされているサブストリーム形式の一覧も取得します。
  4. 各デバイスの機能のクエリを実行します。
  5. ビデオ処理デバイスを作成します。

これらの手順の一部を省略できる場合があります。 たとえば、レンダー ターゲット形式の一覧を取得する代わりに、単に好みの形式でビデオ処理デバイスを作成してみて、成功したかどうかを確認できます。 D3DFMT_X8R8G8B8 などの一般的な形式で成功する可能性があります。

このセクションの残りの部分では、これらの手順について詳しく説明します。

IDirectXVideoProcessorService ポインターを取得する

IDirectXVideoProcessorService インターフェイスは、Direct3D デバイスから取得されます。 このインターフェイスへのポインターを取得するには、次の 2 つの方法があります。

Direct3D デバイスへのポインターがある場合は、DXVA2CreateVideoService 関数を呼び出すことによって、IDirectXVideoProcessorService ポインターを取得できます。 次のコードに示すように、デバイスの IDirect3DDevice9 インターフェイスへのポインターを渡し、riid パラメーターの IID_IDirectXVideoProcessorService を指定します。

    // Create the DXVA-2 Video Processor service.
    hr = DXVA2CreateVideoService(g_pD3DD9, IID_PPV_ARGS(&g_pDXVAVPS));

場合によっては、1 つのオブジェクトで Direct3D デバイスが作成され、Direct3D Device Manager を介して他のオブジェクトと共有されます。 このような場合は、次のコードに示すように、デバイス マネージャーで IDirect3DDeviceManager9::GetVideoService を呼び出して、IDirectXVideoProcessorService ポインターを取得できます。

HRESULT GetVideoProcessorService(
    IDirect3DDeviceManager9 *pDeviceManager,
    IDirectXVideoProcessorService **ppVPService
    )
{
    *ppVPService = NULL;

    HANDLE hDevice;

    HRESULT hr = pDeviceManager->OpenDeviceHandle(&hDevice);
    if (SUCCEEDED(hr))
    {
        // Get the video processor service 
        HRESULT hr2 = pDeviceManager->GetVideoService(
            hDevice, 
            IID_PPV_ARGS(ppVPService)
            );

        // Close the device handle.
        hr = pDeviceManager->CloseDeviceHandle(hDevice);

        if (FAILED(hr2))
        {
            hr = hr2;
        }
    }

    if (FAILED(hr))
    {
        SafeRelease(ppVPService);
    }

    return hr;
}

ビデオ処理デバイスを列挙する

ビデオ処理デバイスの一覧を取得するには、プライマリ ビデオ ストリームの形式で DXVA2_VideoDesc 構造体を入力し、この構造体を IDirectXVideoProcessorService::GetVideoProcessorDeviceGuids メソッドに渡します。 このメソッドからは、このビデオ形式で使用できるビデオ処理デバイスごとに 1 つずつ、GUID の配列が返されます。

YUV 色の BT.709 定義を使用して、1 秒あたり 29.97 フレームのフレーム レートで、YUY2 形式でビデオ ストリームをレンダリングするアプリケーションを考えてみましょう。 ビデオ コンテンツがプログレッシブ フレームのみで構成されているとします。 次のコード フラグメントは、書式の説明を入力し、デバイス GUID を取得する方法を示しています。

    // Initialize the video descriptor.

    g_VideoDesc.SampleWidth                         = VIDEO_MAIN_WIDTH;
    g_VideoDesc.SampleHeight                        = VIDEO_MAIN_HEIGHT;
    g_VideoDesc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_MPEG2;
    g_VideoDesc.SampleFormat.NominalRange           = DXVA2_NominalRange_16_235;
    g_VideoDesc.SampleFormat.VideoTransferMatrix    = EX_COLOR_INFO[g_ExColorInfo][0];
    g_VideoDesc.SampleFormat.VideoLighting          = DXVA2_VideoLighting_dim;
    g_VideoDesc.SampleFormat.VideoPrimaries         = DXVA2_VideoPrimaries_BT709;
    g_VideoDesc.SampleFormat.VideoTransferFunction  = DXVA2_VideoTransFunc_709;
    g_VideoDesc.SampleFormat.SampleFormat           = DXVA2_SampleProgressiveFrame;
    g_VideoDesc.Format                              = VIDEO_MAIN_FORMAT;
    g_VideoDesc.InputSampleFreq.Numerator           = VIDEO_FPS;
    g_VideoDesc.InputSampleFreq.Denominator         = 1;
    g_VideoDesc.OutputFrameFreq.Numerator           = VIDEO_FPS;
    g_VideoDesc.OutputFrameFreq.Denominator         = 1;

    // Query the video processor GUID.

    UINT count;
    GUID* guids = NULL;

    hr = g_pDXVAVPS->GetVideoProcessorDeviceGuids(&g_VideoDesc, &count, &guids);

この例のコードは、DXVA2_VideoProc SDK サンプルから取得されたものです。

この例の pGuids 配列は、GetVideoProcessorDeviceGuids メソッドによって割り当てられるため、アプリケーションでは CoTaskMemFree を呼び出して配列を解放する必要があります。 残りの手順は、このメソッドによって返されるデバイス GUID のいずれかを使用して実行できます。

レンダー ターゲット形式を列挙する

デバイスでサポートされているレンダー ターゲット形式の一覧を取得するには、次のコードに示すように、デバイス GUID と DXVA2_VideoDesc 構造体を IDirectXVideoProcessorService::GetVideoProcessorRenderTargets メソッドに渡します。

    // Query the supported render-target formats.

    UINT i, count;
    D3DFORMAT* formats = NULL;

    HRESULT hr = g_pDXVAVPS->GetVideoProcessorRenderTargets(
        guid, &g_VideoDesc, &count, &formats);

    if (FAILED(hr))
    {
        DBGMSG((L"GetVideoProcessorRenderTargets failed: 0x%x.\n", hr));
        return FALSE;
    }

    for (i = 0; i < count; i++)
    {
        if (formats[i] == VIDEO_RENDER_TARGET_FORMAT)
        {
            break;
        }
    }

    CoTaskMemFree(formats);

    if (i >= count)
    {
        DBGMSG((L"The device does not support the render-target format.\n"));
        return FALSE;
    }

このメソッドからは、D3DFORMAT 値の配列が返されます。 この例では、入力の種類が YUY2 の場合、一般的な形式の一覧は D3DFMT_X8R8G8B8 (32 ビット RGB) と D3DMFT_YUY2 (入力形式) となります。 しかし、正確な一覧はドライバーによって異なります。

サブストリームで使用できる形式の一覧は、レンダー ターゲットの形式と入力形式によって異なる場合があります。 サブストリーム形式の一覧を取得するには、次のコードに示すように、デバイス GUID、形式構造体、およびレンダー ターゲット形式を IDirectXVideoProcessorService::GetVideoProcessorSubStreamFormats メソッドに渡します。

    // Query the supported substream formats.

    formats = NULL;

    hr = g_pDXVAVPS->GetVideoProcessorSubStreamFormats(
        guid, &g_VideoDesc, VIDEO_RENDER_TARGET_FORMAT, &count, &formats);

    if (FAILED(hr))
    {
        DBGMSG((L"GetVideoProcessorSubStreamFormats failed: 0x%x.\n", hr));
        return FALSE;
    }

    for (i = 0; i < count; i++)
    {
        if (formats[i] == VIDEO_SUB_FORMAT)
        {
            break;
        }
    }

    CoTaskMemFree(formats);

    if (i >= count)
    {
        DBGMSG((L"The device does not support the substream format.\n"));
        return FALSE;
    }

このメソッドからは、D3DFORMAT 値の別の配列が返されます。 一般的なサブストリーム形式は AYUV と AI44 です。

デバイス機能のクエリを実行する

特定のデバイスの機能を取得するには、デバイス GUID、形式構造体、およびレンダー ターゲット形式を IDirectXVideoProcessorService::GetVideoProcessorCaps メソッドに渡します。 このメソッドでは、DXVA2_VideoProcessorCaps 構造体にデバイス機能が入力されます。

    // Query video processor capabilities.

    hr = g_pDXVAVPS->GetVideoProcessorCaps(
        guid, &g_VideoDesc, VIDEO_RENDER_TARGET_FORMAT, &g_VPCaps);

    if (FAILED(hr))
    {
        DBGMSG((L"GetVideoProcessorCaps failed: 0x%x.\n", hr));
        return FALSE;
    }

デバイスを作成する

ビデオ処理デバイスを作成するには、IDirectXVideoProcessorService::CreateVideoProcessor を呼び出します。 このメソッドへの入力は、デバイス GUID、形式の説明、レンダー ターゲット形式、および混在させる予定のサブストリームの最大数です。 このメソッドからは、ビデオ処理デバイスを表す IDirectXVideoProcessor インターフェイスへのポインターが返されます。

    // Finally create a video processor device.

    hr = g_pDXVAVPS->CreateVideoProcessor(
        guid,
        &g_VideoDesc,
        VIDEO_RENDER_TARGET_FORMAT,
        SUB_STREAM_COUNT,
        &g_pDXVAVPD
        );

Video Process Blit

メインのビデオ処理操作は、''ビデオ処理 blit'' です (blit は、2 つ以上のビットマップを 1 つのビットマップにまとめる任意の操作です。ビデオ処理 blit では、入力ピクチャをまとめて出力フレームを作成します)。ビデオ処理 blit を実行するには、IDirectXVideoProcessor::VideoProcessBlt を呼び出します。 このメソッドでは、一連のビデオ サンプルがビデオ処理デバイスに渡されます。 それに応じて、ビデオ処理デバイスによって入力ピクチャが処理され、1 つの出力フレームが生成されます。 処理には、インターレース解除、色空間変換、サブストリームの混合が含まれる場合があります。 出力は、呼び出し元によって提供される変換先サーフェスに書き込まれます。

VideoProcessBlt メソッドは次のパラメーターを受け取ります。

  • pRT は、処理されたビデオ フレームを受け取る IDirect3DSurface9 レンダー ターゲット サーフェスを指します。
  • pBltParams は、blit のパラメーターを指定する DXVA2_VideoProcessBltParams 構造体を指します。
  • pSamples は、DXVA2_VideoSample 構造体の配列のアドレスです。 これらの構造体には、blit の入力サンプルが含まれています。
  • NumSamplespSamples 配列のサイズを示します。
  • Reserved パラメーターは予約済みであり、NULL に設定する必要があります。

pSamples 配列では、呼び出し元は次の入力サンプルを提供する必要があります。

  • プライマリ ビデオ ストリームの現在のピクチャ。
  • インターレース解除アルゴリズムで必要な場合は、前方と後方の参照ピクチャ。
  • 0 個以上のサブストリーム ピクチャ (最大 15 サブストリーム)。

ドライバーは、「入力サンプルの順序」で説明されているように、この配列が特定の順序であると想定しています。

blit パラメーター

DXVA2_VideoProcessBltParams 構造体には、blit の一般的なパラメーターが含まれています。 最も重要なパラメーターは、構造体の次のメンバーに格納されます。

  • TargetFrame は、出力フレームのプレゼンテーション時間です。 プログレッシブ コンテンツの場合、この時間はプライマリ ビデオ ストリームからの現在のフレームの開始時刻と等しい必要があります。 この時間は、その入力サンプルの DXVA2_VideoSample 構造体の Start メンバーで指定されます。

    インターレース コンテンツの場合、2 つのインタリーブ フィールドを持つフレームでは、2 つのインターレース解除された出力フレームが生成されます。 最初の出力フレームでは、プレゼンテーション時間は、プログレッシブ コンテンツと同様に、プライマリ ビデオ ストリーム内の現在のピクチャの開始時刻と等しい必要があります。 2 番目の出力フレームでは、開始時刻は、プライマリ ビデオ ストリーム内の現在のピクチャの開始時刻とストリーム内の次のピクチャの開始時刻の中間点と等しい必要があります。 たとえば、入力ビデオが 25 フレーム/秒 (50 フィールド/秒) の場合、出力フレームには次の表に示すタイム スタンプが表示されます。 タイム スタンプは 100 ナノ秒単位で表示されます。

    入力ピクチャ TargetFrame (1) TargetFrame (2)
    0 0 200000
    400000 0 600000
    800000 800000 1000000
    1200000 1200000 1400000

     

    インターレース コンテンツが、インタリーブ フィールドではなく単一フィールドで構成されている場合、出力時間は常に、プログレッシブ コンテンツと同様に、入力時間と一致します。

  • TargetRect では、変換先サーフェス内の四角形領域が定義されます。 blit ではこの領域に出力が書き込まれます。 具体的には、TargetRect 内のすべてのピクセルが変更され、TargetRect 外のピクセルは変更されません。 ターゲットの四角形では、すべての入力ビデオ ストリームの四角形領域が定義されます。 その四角形内での個々のストリームの配置は、IDirectXVideoProcessor::VideoProcessBltpSamples パラメーターを介して制御されます。

  • BackgroundColor は、ビデオ画像が表示されない場所の背景の色を示します。 たとえば、16 x 9 のビデオ画像が 4 x 3 領域内に表示される場合 (レターボックス化)、レターボックス化された領域は背景色で表示されます。 背景色は、ターゲットの四角形 (TargetRect) 内でのみ適用されます。 TargetRect 外のピクセルは変更されません。

  • DestFormat では、出力ビデオの色空間について説明されます。たとえば、ITU-R BT.709 と BT.601 のどちらの色を使用するかなどです。 この情報は、画像の表示方法に影響を与える可能性があります。 詳細については、「拡張色情報」を参照してください。

その他のパラメーターについては、DXVA2_VideoProcessBltParams 構造体の参照ページで説明されています。

入力サンプル

IDirectXVideoProcessor::VideoProcessBltpSamples パラメーターは、DXVA2_VideoSample 構造体の配列を指します。 これらの各構造体には、1 つの入力サンプルに関する情報と、そのサンプルを含む Direct3D サーフェスへのポインターが含まれています。 各サンプルは次のいずれかです。

  • プライマリ ストリームからの現在のピクチャ。
  • インターレース解除に使用される、プライマリ ストリームからの前方または後方参照ピクチャ。
  • サブストリーム ピクチャ。

配列にサンプルを表示する必要がある正確な順序については、「入力サンプルの順序」セクションで後ほど説明します。

最大 15 個のサブストリーム ピクチャを提供できますが、ほとんどのビデオ アプリケーションで必要なサブストリームは多くても 1 つのみです。 VideoProcessBlt を呼び出すたびに、サブストリームの数が変わる可能性があります。 サブストリーム ピクチャは、DXVA2_SampleSubStream と等しい DXVA2_VideoSample 構造体の SampleFormat.SampleFormat メンバーを設定することによって示されます。 プライマリ ビデオ ストリームの場合は、このメンバーで入力ビデオのインターレースについて説明されます。 詳細については、「DXVA2_SampleFormat 列挙」を参照してください。

プライマリ ビデオ ストリームの場合、DXVA2_VideoSample 構造体の StartEnd メンバーは、入力サンプルの開始時刻と終了時刻を示します。 サブストリーム ピクチャの場合、プレゼンテーション時間は常にプライマリ ストリームから計算されるため、これらの値を 0 に設定します。 アプリケーションでは、各サブストリーム ピクチャを表示する必要があるタイミングを追跡し、適切なタイミングで VideoProcessBlt を送信する必要があります。

2 つの四角形で、ストリームごとにソース ビデオがどのように配置されるかが定義されます。

  • DXVA2_VideoSample 構造体の SrcRect メンバーでは、合成された出力フレームに表示されるソース ピクチャの四角形領域である ''ソース四角形'' が指定されます。 ピクチャをトリミングするには、これをフレーム サイズより小さい値に設定します。 それ以外の場合は、フレーム サイズと同じ値に設定します。
  • 同じ構造体の DstRect メンバーでは、ビデオ フレームが表示される変換先サーフェスの四角形領域である ''変換先四角形'' が指定されます。

ドライバーによって、ソース四角形から変換先四角形にピクセルが blit されます。 2 つの四角形で異なるサイズまたは縦横比を使用できます。ドライバーによって、必要に応じて画像がスケーリングされます。 さらに、各入力ストリームで異なるスケール ファクターを使用できます。 実際、出力フレームで正しい縦横比を生成するには、スケーリングが必要になる場合があります。 ドライバーではソースのピクセル縦横比が考慮されないので、ソース画像で非正方形ピクセルが使用される場合、正しい変換先四角形を計算するかどうかはアプリケーション次第です。

推奨されるサブストリーム形式は、AYUV と AI44 です。 後者は、16 色のパレット化された形式です。 パレット エントリは、DXVA2_VideoSample 構造体の Pal メンバーで指定されます (ソース ビデオ形式が最初にメディア ファンデーション メディア タイプとして表現されている場合、パレット エントリは MF_MT_PALETTE 属性に格納されます)。パレット化されていない形式の場合、この配列を 0 にクリアします。

画像合成

すべての blit 操作は、次の 3 つの四角形によって定義されます。

  • ''ターゲット'' 四角形 (TargetRect) では、出力が表示される変換先サーフェス内の領域が定義されます。 出力画像は、この四角形にクリップされます。
  • 各ストリームの ''変換先'' 四角形 (DstRect) では、入力ストリームが合成画像で表示される場所が定義されます。
  • 各ストリームの ''ソース'' 四角形 (SrcRect) では、ソース画像のどの部分が表示されるかが定義されます。

ターゲットと変換先の四角形は、変換先サーフェスを基準にして指定されます。 ソース四角形は、ソース画像を基準に指定されます。 すべての四角形はピクセル単位で指定されます。

diagram showing source, destination, and target rectangles

ビデオ処理デバイスによって、次のいずれかのアルファ データ ソースを使用して、入力ピクチャがアルファ ブレンドされます。

  • サブストリームからのピクセル単位のアルファ データ。
  • DXVA2_VideoSample 構造体の PlanarAlpha メンバーで指定された、各ビデオ ストリームの平面アルファ値。
  • DXVA2_VideoProcessBltParams 構造体の Alpha メンバーで指定された、合成画像の平面アルファ値。 この値は、合成画像全体を背景色とブレンドするために使用されます。

このセクションでは、ビデオ処理デバイスによる出力画像の作成方法を示す一連の例を示します。

例 1: レターボックス化

この例は、変換先四角形をターゲット四角形よりも小さく設定して、ソース画像をレターボックス化する方法を示しています。 この例のプライマリ ビデオ ストリームは 720 × 480 の画像であり、16:9 の縦横比で表示されます。 変換先サーフェスは 640 × 480 ピクセル (4:3 縦横比) です。 正しい縦横比を実現するには、変換先四角形を 640 × 360 にする必要があります。 わかりやすくするために、この例にはサブストリームは含まれません。 次の図はソースと変換先の四角形を示しています。

diagram showing letterboxing.

上の図は次の四角形を示しています。

  • ターゲット四角形: { 0、0、640、480 }

  • プライマリ ビデオ:

    • ソース四角形: { 0、0、720、480 }
    • 変換先四角形: { 0、60、640、420 }

ドライバーによってビデオのインターレースが解除され、インターレース解除されたフレームが 640 × 360 に縮小され、フレームが変換先四角形に blit されます。 ターゲット四角形は変換先四角形よりも大きいので、ドライバーでは背景色を使用して、フレームの上下の水平バーを塗りつぶします。 背景色は、DXVA2_VideoProcessBltParams 構造体で指定されます。

例 2: サブストリーム画像の引き伸ばし

サブストリーム ピクチャは、プライマリ ビデオ ピクチャを超えて拡張できます。 たとえば、DVD ビデオでは、プライマリ ビデオ ストリームの縦横比は 4:3 にできますが、サブストリームは 16:9 です。 この例では、両方のビデオ ストリームのソース ディメンションは同じ (720 × 480) ですが、サブストリームは 16:9 の縦横比で表示することを意図しています。 この縦横比を実現するために、サブストリーム画像は水平方向に引き伸ばされます。 次の図にはソースと変換先の四角形が示されています。

diagram showing substream image stretching.

上の図は次の四角形を示しています。

  • ターゲット四角形: { 0、0、854、480 }

  • プライマリ ビデオ:

    • ソース四角形: { 0、0、720、480 }
    • 変換先四角形: { 0、107、474、480 }
  • サブストリーム:

    • ソース四角形: { 0、0、720、480 }
    • 変換先四角形: { 0、0、854、480 }

これらの値で、画像の高さが維持され、両方の画像が水平方向にスケーリングされます。 両方の画像が表示される領域では、アルファ ブレンドされます。 サブストリーム ピクチャがプライマリ ビデオを超えて拡張される場合、サブストリームは背景色でアルファ ブレンドされます。 このアルファ ブレンドでは、図の右側にある変更された色が考慮されます。

例 3: 一致しないストリームの高さ

前の例では、サブストリームとプライマリ ストリームの高さは同じです。 この例に示すように、ストリームの高さが一致しない場合もあります。 ビデオが表示されないターゲット四角形内の領域は、背景色 (この例では黒) を使用して描画されます。 次の図にはソースと変換先の四角形が示されています。

diagram showing mismatched stream heights,

上の図は次の四角形を示しています。

  • ターゲット四角形: { 0、0、150、85 }
  • プライマリ ビデオ:
    • ソース四角形: { 0、0、150、50 }
    • 変換先四角形: { 0、17、150、67 }
  • サブストリーム:
    • ソース四角形: { 0、0、100、85 }
    • 変換先四角形: { 25、0、125、85 }

例 4: ターゲットの四角形が変換先サーフェスより小さい

この例は、ターゲットの四角形が変換先サーフェスよりも小さい場合を示しています。

diagram showing a blit to a destination rectangle.

上の図は次の四角形を示しています。

  • 変換先サーフェス: { 0、0、300、200 }
  • ターゲット四角形: { 0、0、150、85 }
  • プライマリ ビデオ:
    • ソース四角形: { 0、0、150、50 }
    • 変換先四角形: { 0、17、150、67 }
  • サブストリーム:
    • ソース四角形: { 0、0、100、85 }
    • 変換先四角形: { 25、0、125、85 }

ターゲット四角形の外側のピクセルは変更されないため、背景色はターゲット四角形内にのみ表示されます。 点で描かれた領域は、blit の影響を受けない変換先サーフェスの部分を示します。

例 5: ソース四角形

ソース ピクチャよりも小さいソース四角形を指定すると、ドライバーによってピクチャのその部分だけが blit されます。 この例では、ソース四角形で、プライマリ ビデオ ストリームの右下のクアドラントとサブストリームの左下のクアドラント (図にハッシュ マークで示されている) が指定されます。 変換先四角形はソース四角形と同じサイズであるため、ビデオは引き伸ばされません。 次の図にはソースと変換先の四角形が示されています。

diagram showing a blit from two source rectangles.

上の図は次の四角形を示しています。

  • ターゲット四角形: { 0、0、720、576 }
  • プライマリ ビデオ:
    • ソース サーフェス サイズ: { 0、0、720、480 }
    • ソース四角形: { 360、240、720、480 }
    • 変換先四角形: { 0、0、360、240 }
  • サブストリーム:
    • ソース サーフェス サイズ: { 0、0、640、576 }
    • ソース四角形: { 0、288、320、576 }
    • 変換先四角形: { 400、0、720、288 }

例 6: 交差する変換先四角形

この例は前の四角形に似ていますが、変換先四角形が交差しています。 サーフェス ディメンションは前の例と同じですが、ソースと変換先の四角形は同じではありません。 ここでも、ビデオはトリミングされますが、引き伸ばされません。 次の図にはソースと変換先の四角形が示されています。

diagram showing intersecting destination rectangles.

上の図は次の四角形を示しています。

  • ターゲット四角形: { 0、0、720、576 }
  • プライマリ ビデオ:
    • ソース サーフェス サイズ: { 0、0、720、480 }
    • ソース四角形: { 260、92、720、480 }
    • 変換先四角形: { 0、0、460、388 }
  • サブストリーム:
    • ソース サーフェス サイズ: { 0、0、640、576 }
    • ソース四角形: { 0、0、460、388 }
    • 変換先四角形: { 260、188、720、576 }

例 7: ビデオの引き伸ばしとトリミング

この例では、ビデオは引き伸ばされ、トリミングされます。 各ストリームからの 180 × 120 領域は、変換先四角形の 360 × 240 領域をカバーするように引き伸ばされます。

diagram showing stretching and cropping.

上の図は次の四角形を示しています。

  • ターゲット四角形: { 0、0、720、480 }
  • プライマリ ビデオ:
    • ソースサーフェスサイズ: { 0、0、360、240 }
    • ソース四角形: { 180、120、360、240 }
    • 変換先四角形: { 0、0、360、240 }
  • サブストリーム:
    • ソースサーフェスサイズ: { 0、0、360、240 }
    • ソース四角形: { 0、0、180、120 }
    • 変換先四角形: { 360、240、720、480 }

入力サンプルの順序

VideoProcessBlt メソッドの pSamples パラメーターは、入力サンプルの配列へのポインターです。 プライマリ ビデオ ストリームからのサンプルが最初に表示され、次にサブストリーム ピクチャが Z オーダーで表示されます。 サンプルは、次の順序で配列に配置する必要があります。

  • プライマリ ビデオ ストリームのサンプルは、時間順で、配列に最初に表示されます。 インターレース解除モードによっては、ドライバーでプライマリ ビデオ ストリームからの 1 つまたは複数の参照サンプルが必要になる場合があります。 DXVA2_VideoProcessorCaps 構造体の NumForwardRefSamples および NumBackwardRefSamples メンバーでは、必要な前方および後方参照サンプルの数が指定されます。 ビデオ コンテンツがプログレッシブであり、インターレース解除を必要としない場合でも、呼び出し元はこれらの参照サンプルを提供する必要があります (これは、たとえば、ソースにインターレースとプログレッシブ フレームの両方が混在している場合など、インターレース解除デバイスにプログレッシブ フレームが与えられる場合に発生する可能性があります)。
  • プライマリ ビデオ ストリームのサンプルの後に、配列には、Z オーダーで下から上に配置された最大 15 個のサブストリーム サンプルを含めることができます。 サブストリームは常にプログレッシブであり、参照ピクチャは必要ありません。

プライマリ ビデオ ストリームでは、いつでもインターレースとプログレッシブ コンテンツを切り替えることができ、サブストリームの数が変わる場合があります。

DXVA2_VideoSample 構造体の SampleFormat.SampleFormat メンバーは、ピクチャの種類を示します。 サブストリーム ピクチャの場合は、この値を DXVA2_SampleSubStream に設定します。 プログレッシブ ピクチャの場合、値は DXVA2_SampleProgressiveFrame です。 インターレース ピクチャの場合、値はフィールド レイアウトによって異なります。

ドライバーで前方と後方参照サンプルが必要な場合は、ビデオ シーケンスの開始時にすべてのサンプルを使用できない可能性があります。 その場合は、pSamples 配列にそれらのエントリを含めますが、欠落しているサンプルは種類が DXVA2_SampleUnknown であるものとしてマークします。

DXVA2_VideoSample 構造体の StartEnd メンバーは、各サンプルの一時的な場所を示します。 これらの値は、プライマリ ビデオ ストリームからのサンプルにのみ使用されます。 サブストリーム ピクチャの場合は、両方のメンバーを 0 に設定します。

次の例は、これらの要件を明確にするのに役立つ場合があります。

例 1

最も簡単なケースは、サブストリームがなく、インターレース解除アルゴリズムで参照サンプルが必要ではない場合に発生します (NumForwardRefSamplesNumBackwardRefSamples の両方がゼロである)。 bob インターレース解除は、このようなアルゴリズムの一例です。 この場合、次の表に示すように、pSamples 配列には 1 つの入力サーフェスが含まれている必要があります。

Index サーフェスの種類 一時的な場所
pSamples[0] インターレース ピクチャ。 T

 

時刻値 T は、現在のビデオ フレームの開始時刻と見なされます。

例 2

この例では、アプリケーションによって、2 つのサブストリームとプライマリ ストリームが混合されています。 インターレース解除アルゴリズムでは参照サンプルは必要ありません。 次の表に、これらのサンプルを pSamples 配列に配置する方法を示します。

Index サーフェスの種類 一時的な場所 Z オーダー
pSamples[0] インターレース ピクチャ T 0
pSamples[1] サブストリーム 0 1
pSamples[2] サブストリーム 0 2

 

例 3

ここで、インターレース解除アルゴリズムに、1 つの後方参照サンプルと 1 つの前方参照サンプルが必要であるとします。 さらに、合計 5 つのサーフェスに対して 2 つのサブストリーム ピクチャが提供されます。 正しい順序を次の表に示します。

Index サーフェスの種類 一時的な場所 Z オーダー
pSamples[0] インターレース ピクチャ (参照) T −1 適用なし
pSamples[1] インターレース ピクチャ T 0
pSamples[2] インターレース ピクチャ (参照) T +1 適用なし
pSamples[3] サブストリーム 0 1
pSamples[4] サブストリーム 0 2

 

時刻 T -1 は現在のフレームより前のフレームの開始時刻で、T +1 は次のフレームの開始時刻です。

同じインターレース解除モードを使用して、ビデオ ストリームがプログレッシブ コンテンツに切り替わる場合、アプリケーションでは、次の表に示すように、同じ数のサンプルを提供する必要があります。

Index サーフェスの種類 一時的な場所 Z オーダー
pSamples[0] プログレッシブ ピクチャ (参照) T −1 適用なし
pSamples[1] プログレッシブ ピクチャ T 0
pSamples[2] プログレッシブ ピクチャ (参照) T +1 適用なし
pSamples[3] サブストリーム 0 1
pSamples[4] サブストリーム 0 2

 

例 4

ビデオ シーケンスの開始時に、前方と後方参照のサンプルが使用できない場合があります。 この場合、欠落しているサンプルのエントリは pSamples 配列に含まれており、サンプルの種類は DXVA2_SampleUnknown です。

インターレース解除モードに前方と後方参照サンプルが 1 つずつ必要であると仮定すると、VideoProcessBlt への最初の 3 回の呼び出しでは、次の 3 つの表に示されている入力シーケンスが含まれます。

Index サーフェスの種類 一時的な場所
pSamples[0] Unknown 0
pSamples[1] Unknown 0
pSamples[2] インターレース ピクチャ (参照) T +1

 

Index サーフェスの種類 一時的な場所
pSamples[0] Unknown 0
pSamples[1] インターレース ピクチャ T
pSamples[2] インターレース ピクチャ (参照) T +1

 

Index サーフェスの種類 一時的な場所
pSamples[0] インターレース ピクチャ T −1
pSamples[1] インターレース ピクチャ T
pSamples[2] インターレース ピクチャ (参照) T +1

 

DirectX ビデオ アクセラレータ 2.0

DXVA2_VideoProc サンプル