DXVA 视频处理

DXVA 视频处理封装了用于处理未压缩视频图像的图形硬件的功能。 视频处理服务包括反交错和视频混合。

本主题包含以下部分:

概述

图形硬件可以使用图形处理单元(GPU)来处理未压缩的视频图像。 视频处理设备是封装这些功能的软件组件。 应用程序可以使用视频处理设备来执行以下功能:

  • 反交错和反转电视
  • 将视频子流混合到主视频图像上
  • 颜色调整(ProcAmp)和图像筛选
  • 图像缩放
  • 颜色空间转换
  • Alpha 混合

下图显示了视频处理管道中的阶段。 此图不打算显示实际实现。 例如,图形驱动程序可以将多个阶段合并到单个作中。 所有这些作都可以在对视频处理设备的单个调用中执行。 驱动程序可能不支持此处显示的一些阶段,例如噪音和详细信息筛选。

显示 dxva 视频处理阶段的关系图。

视频处理管道的输入始终包含 视频流,其中包含主图像数据。 主视频流确定输出视频的帧速率。 输出视频的每个帧都相对于主要视频流的输入数据进行计算。 主流中的像素始终不透明,没有每像素 alpha 数据。 主要视频流可以是渐进式或交错的。

(可选)视频处理管道最多可以接收 15 个视频子流。 子流包含辅助图像数据,例如隐藏式字幕或 DVD 子图片。 这些图像通过主要视频流显示,通常不会自行显示。 子流图片可以包含每像素 alpha 数据,并且始终是渐进式帧。 视频处理设备 alpha 将子流图像与主视频流中的当前反交错帧混合。

在本主题的其余部分,术语 图片 用于视频处理设备的输入数据。 图片可能包含渐进式框架、单个字段或两个交错字段。 输出始终是无交错的帧。

视频驱动程序可以实现多个视频处理设备,以提供不同的视频处理功能集。 设备由 GUID 标识。 以下 GUID 是预定义的:

  • DXVA2_VideoProcBobDevice。 此设备执行 bob 取消交错。
  • DXVA2_VideoProcProgressiveDevice。 如果视频仅包含渐进式帧,且没有交错帧,则使用此设备。 (一些视频内容包含渐进式和交错帧的组合。渐进式设备不能用于此类“混合”视频内容,因为交错帧需要反交错步骤。

支持 DXVA 视频处理的每个图形驱动程序必须至少实现这两台设备。 图形驱动程序还可以提供其他设备,这些设备由特定于驱动程序的 GUID 标识。 例如,驱动程序可能实现专有的反交错算法,该算法可生成比 bob 反交错更好的质量输出。 某些反交错算法可能需要从主流中向前或向后引用图片。 如果是这样,调用方必须按照正确的顺序将这些图片提供给驱动程序,如本节稍后所述。

还提供了参考软件设备。 软件设备针对质量而不是速度进行优化,可能不足以进行实时视频处理。 引用软件设备使用 GUID 值DXVA2_VideoProcSoftwareDevice。

创建视频处理设备

在使用 DXVA 视频处理之前,应用程序必须创建视频处理设备。 下面是本部分其余部分更详细地介绍的步骤的简要概述:

  1. 获取指向 IDirectXVideoProcessorService 接口的指针。
  2. 为主要视频流创建视频格式的说明。 使用此说明获取支持视频格式的视频处理设备的列表。 设备由 GUID 标识。
  3. 对于特定设备,获取设备支持的呈现目标格式列表。 格式以 D3DFORMAT 值列表的形式返回。 如果计划混合子流,也获取支持的子流格式的列表。
  4. 查询每个设备的功能。
  5. 创建视频处理设备。

有时可以省略其中一些步骤。 例如,你可以尝试使用首选格式创建视频处理设备,而不是获取呈现目标格式的列表,并查看它是否成功。 常见的格式(如D3DFMT_X8R8G8B8)可能会成功。

本部分的其余部分详细介绍了这些步骤。

获取 IDirectXVideoProcessorService 指针

从 Direct3D 设备获取 IDirectXVideoProcessorService 接口。 可通过两种方法获取指向此接口的指针:

如果有指向 Direct3D 设备的指针,可以通过调用 DXVA2CreateVideoService 函数来获取 IDirectXVideoProcessorService 指针。 传入指向设备的 IDirect3DDevice9 接口的指针,并为 riid 参数指定IID_IDirectXVideoProcessorService,如以下代码所示:

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

n 在某些情况下,一个对象创建 Direct3D 设备,然后通过 Direct3D 设备管理器与其他对象共享它。 在这种情况下,可以在设备管理器上调用 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 方法。 该方法返回 GUID 数组,每个视频处理设备均可用于此视频格式。

请考虑一个应用程序,该应用程序使用 BT.709 的 YUV 颜色定义以 YUY2 格式呈现视频流,帧速率为每秒 29.97 帧。 假设视频内容完全由渐进式帧组成。 以下代码片段演示如何填写格式说明并获取设备 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 执行其余步骤。

枚举 Render-Target 格式

若要获取设备支持的呈现目标格式列表,请将设备 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
        );

视频进程 Blit

主要视频处理作是 视频处理 blit。 ( blit 是将两个或多个位图合并为单个位图的任何作。视频处理 blit 结合了输入图片以创建输出帧。若要执行视频处理 blit,请调用 IDirectXVideoProcessor::VideoProcessBlt。 此方法将一组视频示例传递给视频处理设备。 作为响应,视频处理设备处理输入图片并生成一个输出帧。 处理可以包括反交错、颜色空间转换和子流混合。 输出将写入调用方提供的目标图面。

VideoProcessBlt 方法采用以下参数:

  • pRT 指向将接收已处理的视频帧的 IDirect3DSurface9 呈现目标图面。
  • pBltParams 指向指定 blit 参数 的DXVA2_VideoProcessBltParams 结构。
  • pSamplesDXVA2_VideoSample 结构的数组的地址。 这些结构包含 blit 的输入示例。
  • NumSamples 提供 pSamples 数组的大小。
  • 保留参数是保留的,应设置为 NULL

pSamples 数组中,调用方必须提供以下输入示例:

  • 主视频流的当前图片。
  • 向前和向后引用图片,如果需要,则为反交错算法。
  • 零个或多个子流图片,最多 15 个子流。

驱动程序预期此数组按特定顺序排列,如 输入示例顺序中所述。

Blit 参数

DXVA2_VideoProcessBltParams结构包含 blit 的常规参数。 最重要的参数存储在结构的以下成员中:

  • TargetFrame 是输出帧的呈现时间。 对于渐进式内容,此时间必须等于主要视频流中当前帧的开始时间。 这一次是在该输入示例DXVA2_VideoSample结构的 Start 成员中指定的。

    对于交错内容,具有两个交错字段的帧生成两个无交错输出帧。 在第一个输出帧中,演示时间必须与主视频流中当前图片的开始时间相等,就像渐进式内容一样。 在第二个输出帧中,开始时间必须等于当前图片在主视频流的开始时间与流中下一张图片的开始时间之间的中点。 例如,如果输入视频是每秒 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结构的数组。 其中每个结构都包含有关一个输入样本的信息,以及指向包含样本的 Direct3D 图面的指针。 每个示例都是下列示例之一:

  • 主流的当前图片。
  • 用于取消交错的主流的向前或向后引用图片。
  • 子流图片。

稍后将在 “输入示例顺序”部分介绍样本必须出现在数组中的确切顺序。

最多可以提供 15 个子流图片,尽管大多数视频应用程序最多只需要一个子流。 每个对 VideoProcessBlt 的调用都可以更改子流的数量。 子流图片通过设置DXVA2_VideoSample结构的 SampleFormat.SampleFormat 成员等于DXVA2_SampleSubStream来指示。 对于主视频流,此成员描述输入视频的交错。 有关详细信息,请参阅 DXVA2_SampleFormat 枚举。

对于主要视频流,DXVA2_VideoSample结构的“开始”和“结束”成员提供输入样本的开始和结束时间。 对于子流图片,请将这些值设置为零,因为呈现时间始终从主流计算。 应用程序负责跟踪何时应显示每个子流图片并在适当时间将其提交到 VideoProcessBlt

两个矩形定义源视频如何为每个流定位:

  • DXVA2_VideoSample结构的 SrcRect 成员指定源矩形,源图片的矩形区域将显示在复合输出帧中。 若要裁剪图片,请将此值设置为小于帧大小的值。 否则,将其设置为等于帧大小。
  • 同一结构的 DstRect 成员指定 目标矩形,即目标图面的矩形区域,其中将显示视频帧。

驱动程序将源矩形中的像素点入目标矩形。 这两个矩形可以具有不同的大小或纵横比;驱动程序会根据需要缩放映像。 此外,每个输入流都可以使用不同的缩放因子。 事实上,缩放可能需要在输出帧中生成正确的纵横比。 驱动程序不考虑源的像素纵横比,因此,如果源图像使用非平方像素,则由应用程序来计算正确的目标矩形。

首选子流格式为 AYUV 和 AI44。 后者是具有 16 种颜色的托盘格式。 调色板条目在DXVA2_VideoSample结构的 Pal 成员中指定。 (如果源视频格式最初表示为媒体基础媒体类型,则调色板条目存储在 MF_MT_PALETTE 属性中。对于非托盘化格式,将此数组清除为零。

图像合成

每个 blit作由以下三个矩形定义:

  • 目标矩形 (TargetRect) 定义目标图面中将显示输出的区域。 输出图像被剪裁到此矩形。
  • 每个流(DstRect的目标矩形定义输入流出现在复合图像中的位置。
  • 每个流的 矩形(SrcRect)定义源图像的哪个部分出现。

目标矩形和目标矩形相对于目标图面指定。 源矩形相对于源图像指定。 所有矩形都以像素为单位指定。

显示源、目标和目标矩形的关系图

视频处理设备 alpha 使用以下任何 alpha 数据源混合输入图片:

  • 子流中的每像素 alpha 数据。
  • DXVA2_VideoSample结构的PlanarAlpha 成员中指定的每个视频流的平面 alpha 值。
  • 复合图像的平面 alpha 值,在DXVA2_VideoProcessBltParams结构的 Alpha 成员中指定的。 此值用于将整个复合图像与背景色混合。

本部分提供了一系列示例,演示视频处理设备如何创建输出图像。

示例 1:装箱

此示例演示如何将目标矩形设置为小于目标矩形来装箱源图像。 本示例中的主要视频流是 720 × 480 图像,旨在以 16:9 纵横比显示。 目标图面为 640 × 480 像素(4:3 纵横比)。 若要实现正确的纵横比,目标矩形必须为 640 × 360。 为简单起见,此示例不包含子流。 下图显示了源矩形和目标矩形。

显示装箱的示意图。

上图显示了以下矩形:

  • 目标矩形: { 0, 0, 640, 480 }

  • 主要视频:

    • 源矩形: { 0, 0, 720, 480 }
    • 目标矩形: { 0, 60, 640, 420 }

驱动程序将取消对视频的隔行,将无交帧缩小到 640 × 360,并将帧点入目标矩形。 目标矩形大于目标矩形,因此驱动程序将使用背景色填充框架上方和下方的水平条。 背景色在 DXVA2_VideoProcessBltParams 结构中指定。

示例 2:拉伸子流图像

子流图片可以扩展到主要视频图片之外。 例如,在 DVD 视频中,主视频流可以具有 4:3 纵横比,而子流为 16:9。 在此示例中,两个视频流具有相同的源尺寸(720 × 480),但子流旨在以 16:9 纵横比显示。 为了实现此纵横比,子流图像水平拉伸。 下图显示了源矩形和目标矩形。

显示子流图像拉伸的示意图。

上图显示了以下矩形:

  • 目标矩形:{ 0、0、854、480 }

  • 主要视频:

    • 源矩形: { 0, 0, 720, 480 }
    • 目标矩形:{ 0, 107, 474, 480 }
  • 子流:

    • 源矩形: { 0, 0, 720, 480 }
    • 目标矩形: { 0, 0, 854, 480 }

这些值保留图像高度,并水平缩放两个图像。 在两个图像出现的区域中,它们都是 alpha 混合的。 子流图片扩展到主要视频之外的位置,子流将 alpha 与背景色混合。 此 alpha 混合表示关系图右侧已更改的颜色。

示例 3:不匹配的流高度

在上一示例中,子流和主流的高度相同。 流也可以具有不匹配的高度,如此示例所示。 目标矩形中的区域,其中没有使用背景色绘制视频,在本示例中为黑色。 下图显示了源矩形和目标矩形。

显示不匹配的流高度的关系图,

上图显示了以下矩形:

  • 目标矩形:{ 0、0、150、85 }
  • 主要视频:
    • 源矩形: { 0, 0, 150, 50 }
    • 目标矩形: { 0, 17, 150, 67 }
  • 子流:
    • 源矩形: { 0, 0, 100, 85 }
    • 目标矩形: { 25, 0, 125, 85 }

示例 4:目标矩形小于目标图面

此示例显示了目标矩形小于目标图面的情况。

显示目标矩形的 blit 图。

上图显示了以下矩形:

  • 目标图面: { 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 的关系图。

上图显示了以下矩形:

  • 目标矩形: { 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:与目标矩形相交

此示例类似于上一个示例,但目标矩形相交。 图面尺寸与上一示例中相同,但源矩形和目标矩形不同。 同样,视频被裁剪,但未拉伸。 下图显示了源矩形和目标矩形。

显示与目标矩形相交的关系图。

上图显示了以下矩形:

  • 目标矩形: { 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 区域。

显示拉伸和裁剪的示意图。

上图显示了以下矩形:

  • 目标矩形: { 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 顺序的子流图片。 示例必须按以下顺序放入数组中:

  • 主要视频流的示例首先以时态顺序显示在数组中。 根据反交错模式,驱动程序可能需要主要视频流中的一个或多个参考示例。 DXVA2_VideoProcessorCaps结构的 NumForwardRefSamples 和 NumBackwardRefSamples 成员指定需要多少个向前和向后引用样本。 调用方必须提供这些参考示例,即使视频内容是渐进式的,并且不需要反交错。 (当向反交错设备提供渐进式帧时,例如,当源包含交错帧和渐进帧的混合时,可能会出现这种情况。
  • 在主视频流的样本之后,数组最多可以包含 15 个子流样本,按 Z 顺序排列,从下到上。 子流始终是渐进式的,不需要参考图片。

随时,主视频流可以在交错和渐进式内容之间切换,子流的数量可能会更改。

DXVA2_VideoSample结构的 SampleFormat.SampleFormat 成员指示图片的类型。 对于子流图片,请将此值设置为DXVA2_SampleSubStream。 对于渐进式图片,该值DXVA2_SampleProgressiveFrame。 对于交错图片,该值取决于字段布局。

如果驱动程序需要前向和向后引用示例,则视频序列开始时可能无法使用完整数量的样本。 在这种情况下,请在 pSamples 数组中包含它们的条目,但会将缺失的样本标记为具有类型DXVA2_SampleUnknown。

DXVA2_VideoSample结构的“开始”和“结束”成员为每个样本提供临时位置。 这些值仅用于主要视频流中的示例。 对于子流图片,请将这两个成员设置为零。

以下示例可能有助于阐明这些要求。

示例 1

如果没有子流,并且取消交错算法不需要引用样本(NumForwardRefSamplesNumBackwardRefSamples 均为零),则会出现最简单的情况。 Bob 取消交错是此类算法的一个示例。 在这种情况下, pSamples 数组应包含单个输入图面,如下表所示。

索引 图面类型 时态位置
pSamples[0] 交错图片。 T

 

假定时间值 T 是当前视频帧的开始时间。

示例 2

在此示例中,应用程序将两个子流与主流混合。 反交错算法不需要引用示例。 下表显示了如何在 pSamples 数组中排列这些示例。

索引 图面类型 时态位置 Z 顺序
pSamples[0] 交错图片 T 0
pSamples[1] 子流 0 1
pSamples[2] 子流 0 2

 

示例 3

现在假设反交错算法需要一个向后引用样本和一个向前引用样本。 此外,还提供了两张子流图片,总共有五个图面。 下表显示了正确的排序。

索引 图面类型 时态位置 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 是以下帧的开始时间。

如果视频流切换到渐进式内容(使用相同的反交错模式),则应用程序必须提供相同数量的示例,如下表所示。

索引 图面类型 时态位置 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。

假设反交错模式需要一个向前引用和一个向后引用示例,则对 VideoProcessBlt 的前三个调用将具有以下三个表中所示的输入序列。

索引 图面类型 时态位置
pSamples[0] 未知 0
pSamples[1] 未知 0
pSamples[2] 交错图片(参考) T +1

 

索引 图面类型 时态位置
pSamples[0] 未知 0
pSamples[1] 交错图片 T
pSamples[2] 交错图片(参考) T +1

 

索引 图面类型 时态位置
pSamples[0] 交错图片 T ~1
pSamples[1] 交错图片 T
pSamples[2] 交错图片(参考) T +1

 

DirectX 视频加速 2.0

DXVA2_VideoProc示例