DirectX 视频加速 IAMVideoAccelerator 操作规范

[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayerIMFMediaEngine音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

精确的操作机制如下:

  1. 此处定义的每个受限模式配置文件都有一个关联的 DirectX VA GUID,该 GUID 可由下游输入引脚的 IPin::QueryAcceptIPin::ReceiveConnection 提供支持,并列在 IAMVideoAccelerator::GetVideoAcceleratorGUIDs 中。

  2. 同样,与 DirectX VA 配合使用的每个加密协议类型应具有关联的加密协议类型 GUID,该协议类型可由下游输入引脚的 IPin::QueryAcceptIPin::ReceiveConnection 提供支持,并列在 IAMVideoAccelerator::GetVideoAcceleratorGUIDs 中。 不应在此列表中发送“无加密”GUID DXVA_NoEncrypt,因为需要支持它,因此是隐式的。

  3. 调用 IPin::ReceiveConnection 以尝试连接到下游输入引脚后,解码器的 IAMVideoAcceleratorNotify::GetCreateVideoAcceleratorData 应返回指向包含连接连接模式信息的DXVA_ConnectMode数据结构的指针。 IAMVideoAccelerator::GetCompBufferInfo 应使用 *pdwNumTypesCompBuffers = 16 调用,并应根据约定返回压缩缓冲区信息,即 DirectX VA 规范 () 第 3.4 节中定义的每个缓冲区的类型数可以直接用作返回的 AMVACompBufferInfo 数据结构数组中的从零开始的索引。 这要求对于将不使用的任何缓冲区类型 (包括缓冲区类型 0, 由于没有定义使用该缓冲区类型) ,因此加速器驱动程序将为 AMVACompBufferInfo 数据结构提供某种形式的“dummy”参数值, (例如 dwNumCompBuffers=0、dwWidthToCreate=0、dwHeightToCreate=0 和 dwBytesToAllocate=0) 。

  4. DXVA 函数指示和关联的数据缓冲区使用 IAMVideoAccelerator::Execute 发送。 DXVA 函数在调用的 dwFunction 参数中指示。 与初始化相关的唯一 DXVA 函数是DXVA_ConfigQueryOrReplyFunc和DXVA_EncryptProtocolFunc。

    • 如果 dwFunction 包含DXVA_ConfigQueryOrReplyFunc,则用于在此调用中将数据传递到加速器的 lpPrivateInputData 指针应指向配置数据结构,用于从加速器接收信息的 lpPrivateOutputData 指针应指向可放置备用或重复配置数据结构的区域,AMVABUFFERINFO 数组的 pamvaBufferInfo 指针应为 NULL, 和 dwNumBuffers 应为零。 如果协议执行 (出现严重问题(例如配置参数) 无效),返回的 HRESULT 包含S_OK或S_FALSE指示,或者E_FAIL或E_INVALIDARG或其他一些错误指示 HRESULT。 对 IAMVideoAccelerator::Execute 的所有使用DXVA_ConfigQueryOrReplyFunc的所有调用应先于对 IAMVideoAccelerator::Execute 的所有其他调用。

    • 如果 dwFunction 包含DXVA_EncryptProtocolFunc, 用于在此调用中将数据传递到加速器的 lpPrivateInputData 指针应指向以 DXVA_EncryptProtocolHeader 开头的加密协议数据结构,用于从加速器接收信息的 lpPrivateOutputData 指针应指向要返回的数据 (区域,例如加密协议) 的证书 (,该证书以 DXVA_EncryptProtocolHeader) 开头, AMVABUFFERINFO 数组的 pamvaBufferInfo 指针应为 NULL,dwNumBuffers 为零。 只要加密协议正常运行,返回的 HRESULT 将包含S_OK,并在协议执行中出现严重问题时包含E_FAIL或E_INVALIDARG或其他一些错误指示 HRESULT。

      以上述方式初始化操作后,解码器的实际操作将按如下所示进行:

  5. 在发送任何具有压缩缓冲区参数的bDXVA_Func之前,应调用 IAMVideoAccelerator::BeginFrame,从而导致写入未压缩的目标图面。 DirectX VA 中的 IAMVideoAccelerator::BeginFrame 的目的是将目标图面与索引值相关联,并通知视频加速器驱动程序启动写入图面的意图,以便驱动程序可以响应指示该图面是否已准备好被覆盖。 在 IAMVideoAccelerator::BeginFrame 中传递的 AMVABeginFrameInfo 结构应包含指向单个 WORD wBeginPictureIndex 参数的 pInputData 指针,该参数与传递到 IAMVideoAccelerator::BeginFrame (的帧索引匹配,dwSizeInputData 应为 2) 。 这是在压缩缓冲区中用于命令对图面的写入 (例如,用作 wDecodedPictureIndex、wDeblockedPictureIndex、wBlendedDestinationIndex 或 wPicResampleDestPicIndex) 的索引。 每次对 IAMVideoAccelerator::BeginFrame 的调用应与对 IAMVideoAccelerator::EndFrame 的相应调用配对,如下所述。 例如,如果要对压缩图片进行解码,然后使用前端 buffer-to-buffer 混合与图形图像进行 alpha 混合,则在将压缩图片解码为 wDecodedPictureIndex 中指定的图面之前,将调用 IAMVideoAccelerator ::EndFrame,然后在传递用于解码图片的所有压缩缓冲区后调用 IAMVideoAccelerator::EndFrame , 然后,在命令将图形源与解码图片的 alpha 混合组合到 wBlendedDestinationIndex 中指定的图面之前,对 IAMVideoAccelerator::BeginFrame 进行第二次调用,然后在 alpha 混合组合操作后再次调用 IAMVideoAccelerator::EndFrame 。AMVABeginFrameInfo 中的指针 pOutputData 应为 NULL (,dwSizeOutputData 应为“0”) 。 IAMVideoAccelerator::BeginFrame 返回的 HRESULT 应为:

    • S_OK未压缩的表面是否可用且可供使用。
    • E_PENDING未压缩表面尚未可供使用,但如果正在读取未压缩的图面进行显示,并且尚未) 完成表面的读取/显示,则 (即将可用。
    • 仅当 (检测到数据格式或协议错误(例如 dwSizeInputData 错误值或非 NULL pOutputData) )时,E_FAIL或E_INVALIDARG其他错误指示。
  6. DXVA 函数指示和关联的数据缓冲区使用 IAMVideoAccelerator::Execute 发送。 在对 IAMVideoAccelerator::Execute 的同一调用中可以指示多个bDXVA_Func值。 bDXVA_Func值应打包到调用的 dwFunction 参数中,第一个函数命令位于 8 个 MSB 中,下一个命令位于接下来的 8 位中,依此以类比,其余任何位填充为零。 bDXVA_Func 的值0xFF指示bDXVA_Func已扩展到两个或四个字节。 如果第二个字节也0xFF,则表示bDXVA_Func已扩展到四个字节。 如果第三个字节的上四位0xF或0x0,则表示bDXVA_Func包含DXVA_ConfigQueryOrReplyFunc或DXVA_EncryptProtocolFunc。 多字节命令不应指示延续到 dwFunction 结束。 解码器必须小心,以确保在对 IAMVideoAccelerator::Execute 的同一调用中指定的不同bDXVA_Func值之间不存在顺序依赖关系,并且所有潜在的争用条件 (,例如图片解码和子图片混合之间、子图片加载与子图片混合之间,等等,) 通过对 IAMVideoAccelerator 的适当调用来阻止:在 后续调用 IAMVideoAccelerator:: Execute 之前,BeginFrame 和 IAMVideoAccelerator::QueryRenderStatus。

    • 如果 dwFunction 包含DXVA_ConfigQueryOrReplyFunc,则用于在此调用中将数据传递到加速器的 lpPrivateInputData 指针应指向配置数据结构,用于从加速器接收信息的 lpPrivateOutputData 指针应指向可放置备用或重复配置数据结构的区域,AMVABUFFERINFO 数组的 pamvaBufferInfo 指针应为 NULL, 和 dwNumBuffers 应为零。 返回的 HRESULT 包含S_OK或S_FALSE指示以响应查询,或者在协议执行 (出现严重问题(如 invalid.configuration 参数) )时E_FAIL或E_INVALIDARG其他一些错误指示 HRESULT。 对 IAMVideoAccelerator::Execute 的所有使用DXVA_ConfigQueryOrReplyFunc的所有调用应先于对 IAMVideoAccelerator::Execute 的所有其他调用。

    • 如果 dwFunction 包含DXVA_EncryptProtocolFunc, 用于在此调用中将数据传递到加速器的 lpPrivateInputData 指针应指向以 DXVA_EncryptProtocolHeader 开头的加密协议数据结构,用于从加速器接收信息的 lpPrivateOutputData 指针应指向要返回的数据 (区域,例如加密协议) 的证书 (,该证书以 DXVA_EncryptProtocolHeader) 开头, AMVABUFFERINFO 数组的 pamvaBufferInfo 指针应为 NULL,dwNumBuffers 为零。 只要加密协议正常运行,返回的 HRESULT 将包含S_OK,并在协议执行中出现严重问题时包含E_FAIL或E_INVALIDARG或其他一些错误指示 HRESULT。

    • 如果 dwFunction 不包含DXVA_ConfigQueryOrReplyFunc或DXVA_EncryptProtocolFunc,则用于将数据传递到加速器的 lpPrivateInputData 指针应指向缓冲区说明列表。 每个缓冲区的缓冲区说明列表结构中的前四个条目 (dwTypeIndex、dwBufferIndex、dwDataOffset 和 dwDataSize) 应等于同一缓冲区的 AMVABUFFERINFO 数据结构中的条目。 如果在 dwFunction 中指定了bDXVA_Func等于“1”,而 bPicReadbackRequests 为“1”,则用于从加速器接收信息的 lpPrivateOutputData 指针应指向永久性内存 (例如,堆) 将填充来自加速器的读回宏块数据 (此类数据不保证存在,直到 IAMVideoAccelerator:: 用于写入同一图片参数缓冲区的 QueryRenderStatus 指示S_OK,如以下) 项 10 中所述。 否则,用于从加速器接收信息的 lpPrivateOutputData 指针应指向要设置为以下指示值之一的单个 DWORD, (对于报告主机外 VLD 操作中的位流错误) 特别有用。

      说明
      0 执行正常。
      1 遇到数据格式的小问题。
      2 遇到数据格式的重大问题。
      3 遇到严重数据格式问题。
      4 遇到其他严重问题。

       

      如果指示任一类型的“严重”问题,软件解码器应停止运行函数 () ,除非可以采取纠正措施。 在图片的缓冲区渲染完成后,主机才能读取从加速器返回的此数据, IAMVideoAccelerator::QueryRenderStatus 可以对其进行测试。 只要接口操作正常运行,返回的 HRESULT 将包含S_OK,如果出现严重问题,可能会返回E_FAIL或E_INVALIDARG或其他一些错误指示 HRESULT。

  7. 使用 IAMVideoAccelerator::Execute (bDXVA_Func等于“1”)时,图片解码参数缓冲区应是发送用于对每张图片进行解码的第一个缓冲区之一,并且所有用于解码位流图片的缓冲区应先发送用于解码后续图片的任何缓冲区。 如果发送宏块控制命令缓冲区,应发送相应的残差数据缓冲区 (包含同一个宏块) 使用相同的 IAMVideoAccelerator::Execute 调用的数据。

  8. 应在发送所有压缩缓冲区后调用 IAMVideoAccelerator::EndFrame,该缓冲区将导致在指定的未压缩图面中创建输出内容, (为 wDecodedPictureIndex、wDeblockedPictureIndex、wBlendedDestinationIndex 或 wPicResampleDestPicIndex) 指定的操作的结果。 调用 IAMVideoAccelerator::EndFrame 的目的是通知视频加速器硬件指定操作所需的所有数据已发送。 指向通过 IAMVideoAccelerator::EndFrame 向下游发送的数据的指针应指向包含结束帧索引的单个 WORD wEndPictureIndex。 此参数应与在发送相关压缩缓冲区之前调用 IAMVideoAccelerator::BeginFrame 中指定的 wBeginPictureIndex 值匹配。 调用 IAMVideoAccelerator::EndFrame 之后, 在任何图片的 wDecodedPictureIndex、wDeblockedPictureIndex、wBlendedDestindex 或 wPicResampleDestPicIndex 中找不到具有索引 wEndPictureIndex 的未压缩图面,直到发出对 IAMVideoAccelerator::BeginFrame 的另一次调用来宣布将发生这种情况,并且结果已返回S_OK。 但是,该目标图面索引可能发生在后续读取访问命令中,例如 wForwardRefPictureIndex、wBackwardRefPictureIndex、wPicResampleSourcePicIndex 或 bRefPicSelect[i]。 除非存在某种数据格式或协议错误,否则 IAMVideoAccelerator::EndFrame 返回的 HRESULT 应S_OK,在这种情况下,它可以E_FAIL或E_INVALIDARG或其他一些错误指示。

  9. 例如,在基于字段的解码 (,在 MPEG-2 位流) 不会在加速器接口中将位流中的功能图片与未压缩表面进行一对一映射。 在 MPEG-2 位流中解码字段图片时,将解码两张“图片”以生成一个完整的未压缩表面输出。 在 DirectX VA 接口定义中,每个帧对应于 wDecodedPictureIndex、wDeblockedPictureIndex、wBlendedDestinationIndex 或 wPicResampleDestPicIndex 的每次使用。 因此,需要对 IAMVideoAccelerator::BeginFrameIAMVideoAccelerator::EndFrame 进行两对调用,才能将字段图片解码为输出未压缩的图面。

  10. 调用 IAMVideoAccelerator::QueryRenderStatus ,其中 dwFlags 等于零,在调用具有特定 wEndPictureIndex 的 IAMVideoAccelerator::EndFrame 之后的某个时候发生,并检查 wDecodedPictureIndex 中包含 wEndPictureIndex 的已发送缓冲区的状态, wDeblockedPictureIndex、wBlendedDestinationIndex 或 wPicResampleDestPicIndex 将返回S_OK指示(如果将数据写入未压缩图面的所有操作都已完成)如果操作尚未完成,则 和 将返回E_PENDING。 发生协议错误时,可能会返回E_FAIL、E_INVALIDARG或其他一些错误指示。

将 DirectX 视频加速映射到 IAMVideoAccelerator