DirectX 视频加速 IAMVideoAccelerator作规范

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

作的精确机制如下所示:

  1. 此处定义的每个受限模式配置文件都有一个关联的 DirectX VA 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 数据结构提供某种形式的“虚拟”参数值(例如 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,从而导致写入未压缩的目标图面。 IAMVideoAccelerator::BeginFrame DirectX VA 中的目的是将目标图面与索引值相关联,并通知视频加速器驱动程序启动写入图面,以便驱动程序能够响应指示图面是否已准备好覆盖。 在 IAMVideoAccelerator::BeginFrame 中传递的AMVABeginFrameInfo 结构应包含 pInputData 指针,该指针指向与传递到 IAMVideoAccelerator::BeginFrame(dwSizeInputData 应为 2) 的帧索引匹配。 这是在压缩缓冲区中使用的索引,用于命令写入图面(例如,用作 wDecodedPictureIndex、wDeblockedPictureIndex、wBlendedDestinationIndex 或 wPicResampleDestPicIndex)。 对 IAMVideoAccelerator::BeginFrame 的每个调用应与对 IAMVideoAccelerator::EndFrame 的相应调用配对,如下所述。 例如,如果要解码压缩图片,然后使用前端缓冲区到缓冲区混合与图形图像进行 alpha 混合, 在将压缩图片解码为 wDecodedPictureIndex 中指定的图面之前,将调用 IAMVideoAccelerator::BeginFrame,然后在传递用于解码图片的所有压缩缓冲区后调用 IAMVideoAccelerator::EndFrame, 然后,在第二次调用 IAMVideoAccelerator::BeginFrame 之前,先命令将图形源与解码后的图片混合到 wBlendedDestinationIndex 中指定的图面,然后在 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 中,下一个命令位于下一个八位,以零填充所有剩余位。 bDXVA_Func的值0xFF指示bDXVA_Func扩展到两到四个字节。 如果第二个字节也0xFF,则表示bDXVA_Func扩展到四个字节。 如果第三个字节的前四位是0xF或0x0,则表示bDXVA_Func包含DXVA_ConfigQueryOrReplyFunc或DXVA_EncryptProtocolFunc。 多字节命令不应指示 dwFunction 结尾的延续。 解码器必须小心,以确保在对 IAMVideoAccelerator::Execute 调用中指定的不同bDXVA_Func值之间不存在任何顺序依赖关系,以及所有潜在的争用条件(例如,图片解码和子图片混合之间、子图片加载和子图片混合等)都无法通过适当的调用 IAMVideoAccelerator:BeginFrameIAMVideoAccelerator::QueryRenderStatus,然后再调用 IAMVideoAccelerator::Execute

    • 如果 dwFunction 包含DXVA_ConfigQueryOrReplyFunc,用于将数据传递到此调用中的加速器的 lpPrivateInputData 指针应指向配置数据结构,用于从加速器接收信息的 lpPrivateOutputData 指针应指向可放置替代或重复配置数据结构的区域,AMVABUFFERINFO 数组的 pamvaBufferInfo 指针应 NULL; 和 dwNumBuffers 应为零。 返回的 HRESULT 包含响应查询的S_OK或S_FALSE指示,或者在协议执行中出现严重问题时E_FAIL或E_INVALIDARG一些其他错误指示 HRESULT(例如 invalid.configuration 参数)。 对 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 遇到其他严重问题。

       

      如果指示任一类型的“严重”问题,则软件解码器应停止运行函数(s),除非可以采取纠正措施。 在图片的缓冲区呈现完成后,主机才会读取从加速器返回的此数据,如 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 中都找不到索引 wEndPictureIndex 的未压缩图面, wDeblockedPictureIndex、wBlendedDestinationIndex 或 wPicResampleDestPicIndex,直到再次调用 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 等于零,在调用 IAMVideoAccelerator::EndFrame 与特定的 wEndPictureIndex 并检查发送的缓冲区的状态,该缓冲区包含 wDecodedPictureIndex 中的 wEndPictureIndex, wDeblockedPictureIndex、wBlendedDestinationIndex 或 wPicResampleDestPicIndex 将返回一个S_OK指示(如果将数据写入未压缩图面的所有作都有)已完成,如果作尚未完成,则返回E_PENDING。 如果发生协议错误,可能会返回E_FAIL或E_INVALIDARG或其他一些错误指示。

将 DirectX 视频加速映射到 IAMVideoAccelerator