在2018年初,Khronos的vulkan工作组开始探索如何将硬件加速的视频压缩和解压缩整合到Vulkan API中。今天,Khronos正在发布一套临时vulkan视频加速扩展:'vulkan视频'。此博客将概述vulkan的新视频处理功能,并在延长最终确定之前欢迎反馈,以便他们为您的视频应用提供有效的加速!
Vulkan视频遵循Vulkan哲学,提供灵活,细粒度控制对应用程序的视频处理调度,同步和内存利用。利用现有的vulkan框架实现了高效,低延迟,低端设备的处理资源,包括在多个CPU内核和视频编解码器硬件上分发流处理任务 - 所有这些都具有跨多个平台和从小嵌入式设备的设备的应用程序的可移植性性能服务器。
为了补充vulkan视频的低级设计,khronos计划在vulkan sdk中添加支持,其中包含验证和更高级别的抽象,这将加快视频应用程序的视频应用程序,其中帧内框架和黑盒子解码和编码就足够了。这将由Windows和Linux上的一系列应用程序使用案例进行互补的vulkan视频样本。
临时vulkan视频扩展与Vulkan现有的图形,计算和显示功能密切集成了硬件加速视频处理。我们邀请所有开发人员提供反馈,以便最终确定的vulkan视频1.0扩展可以精细调整,以便在任何地方提供令人兴奋的vutkan应用程序的新功能!
GPU通常包含专用的视频解码和编码与其他图形和计算引擎无关的加速引擎。实际上,一些物理设备可以仅支持视频解码和/或视频编码操作。因此,Vulkan视频添加了视频解码和编码队列,可以使用VKQueueFlagbits查询。
此外,视频编解码器领域正在持续发展,通过越来越高级和特定于域的视频编码工具,实现更高效的视频压缩和减压 - 导致新的编解码器和编解码器扩展。因此,除了与所有编解码器相关的通用“核心”扩展,vulkan视频已经设计了对各种现有和未来编解码器的灵活支持,该视频划分为通用的“核心”扩展和编解码器特定扩展。核心扩展包括视频编解码的视频队列功能:
该临时vulkan视频发布还包括三个扩展,其扩展由核心视频KHR扩展定义的基础结构,以支持H.264-Decode,H.264编码和H.265-Decode:
这些EXT扩展不会定义API调用,它们只是扩展数据结构。目前正在开发中有一个H.265-edode扩展,并且在稍后的发布后,预计VP9解码和AV1解码/编码扩展将很快跟随。
作为示例,只支持H.264解码的vulkan视频实现将仅公开对vk_khr_video_queue,vk_khr_video_decode_queue和vk_ext_video_decode_h264扩展的支持,并且应用程序将所有三个扩展一起使用,以在该目标设备上执行H.264解码操作。
标准vKgetPhysicalDeviceQueueFamilyProperties2 API可用于确定对Codec扩展的支持,例如H.265解码,H.264编码,通过链接VkvideoQueueFamilyPropertize2kHR来检索VKVIDEoDecodeCoperationFlagskhr。
视频编码专家经常分析视频比特流,以调查编码伪像,并使用比特流中的编解码器的语法元素使用编解码器规范来改善视频质量,该编解码器规范定义了语法和工具的行为描述。 vulkan视频可以轻松识别与编解码器语法元素或编解码器定义的术语相对应的API字段,而无需在编解码器标准规范中介绍已充分记录的说明具有漂亮的vUlkan规范。
特定于编解码标准(" std")C头定义了相应编解码器标准规范的命名和样式约定中的具有显式和派生编解码器语法字段的结构。这些STD结构用作vUlkan视频编解码器EXT扩展结构中的字段。临时vutkan视频发布提供以下编解码器STD标题:
视频代码转换通常用于从较旧的复码到更新的编解码器转换视频内容,从而受益于改进的压缩效率。它还可用于将内容转换为编解码器,更适合于目标环境的有效消耗。图3描绘了用于视频转码的基本框图。
视频转码的第一阶段是解码输入视频比特流(字节序列)以生成构成视频序列的图像。在比特流中解码单个图像通常需要引用一个或多个先前解码的图像,这必须在解码的图像缓冲器(DPB)中以此目的被保留。注意,一些实施方式可以支持使用输出图像和DPB图像的相同图像资源,而其他实现可能需要或更喜欢从DPB图像中的解码操作解耦输出图像,例如用于在保持输出的同时使用专有布局并将元数据与DPB图像一起使用和存储元数据用于外部消耗的标准布局中的图像。最后,要到达原始视频序列,可能需要按照比特流指示重新订购输出图像。
代码转换的第二阶段涉及使用新编解码器(或者具有不同组件组的相同编解码器)对解码的图像进行编码。编码过程基本上是解码过程的反向:输入是一系列图像,可以在编码之前重新排序,并且可能需要保留"重建"或在编码以下图像的同时引用的图像的解码版本。注意,通常,输入图像不用于编码过程中的参考,以避免在解码消费者端的比特流时避免漂移,因为编码通常是有损操作。代码转换应用程序管道解码和编码操作以减少转码时所需的解码输出/编码输入图像的数量。
代码转换应用程序的第一步是分配必要的资源。视频解码和编码操作的基本资源使用标准vulkan对象:
Vulkan视频扩展了VKBufferUsage,VkimageUsage和VkimageLayout,与视频解码/编码使用和布局相关的位,应用程序以最佳地管理视频解码和编码资源。
视频编解码器通常定义"配置文件"用于宣传编码比特流使用的特征集的广告。编解码符合的HW解码器通常支持全套配置文件功能,以便它们可以处理所有兼容的内容。相比之下,硬件供应商可以支持硬件编码器中的所选配置文件功能,并且仍然生成符合的比特流,由区域驱动和成本考虑,同时优先考虑密钥编码API和用例。 VKVIDEOPOOFILEKHR结构定义目标视频配置文件:
YCBCR色度分子采样和亮度/色度分量比特深度(例如,4:2:0,8位Luma / Chroma),因为视频编解码器在YUV图像上运行以进行编码效率
特定于编解码器的视频配置文件(例如H.264主配置文件),通过Chited EXT结构,特定于使用中的编解码器操作
用于视频操作的资源可能具有基于目标视频配置文件的特定于实现的属性和需求,因此应用程序应在查询属性时指定目标视频配置文件,或创建各种资源(图像,缓冲区等)。
VKFormat API调用枚举给定视频编解码器操作和视频配置文件的支持的视频图像:
一旦资源分配,转码应用程序会创建一个视频会话。 VKVIDEOSESSIONKHR视频会话对象提供了一个上下文,可以在特定视频流上运行时存储持久状态。可以创建vkvideosessionkhr的单独实例以在多个视频流上同时运行。以下API创建,销毁,查询内存要求和绑定存储器到视频会话对象:
如果应用程序是支持解码动态地改变分辨率的视频比特流,以处理变化的网络条件,则应使用最大视频流参数来创建视频会话,从而分配足够的资源。
为应用程序提供了一个API来查询实现的功能,包括某些设置的最小值和最大限制:
vulkan视频使用vkvideoSessionParameterskhr对象,针对给定的vkvideosessionkhr实例创建,以将视频参数集存储为控制流处理,例如:描述在流内应用于流中的一个或多个图片的设置 - 例如H.264序列和图片参数集。
应用程序可以为给定视频会话创建多个会话参数对象,指定预期该对象的各种参数集的最大数量。这允许用户稍后将更多参数集添加到同一对象,但在某些条件下。或者,用户可以使用更多存储容量创建另一个会话参数对象,并继承从先前创建的会话参数对象保留的现有参数集。这避免了通过Vulkan API重新翻译参数集,并启用跨对象重新使用其内部表示。
目前,会话参数对象用于存储H.264 SPS和PPS参数集,以及H.265 VPS,SP和PPS参数集。对于解码操作,预计应用程序将解析包含这些编解码器头部的比特流段,以根据需要创建/更新会话参数对象。
现在,创建视频会话,通过将视频比特流解析为由视频编解码器所定义的单独解码比特流段的序列来开始解码。如前所述,其中一些段携带适用于多个图片的编解码器参数集。其他比特流段携带编码图像本身或编码的子图像区域(例如H.264切片)。
视频解码硬件加速通常仅适用于与图像/图片或其子区域相关的比特流段,而与参数集相关的段被设计用于基于CPU的简单解码或解析。参数集还旨在有效地传达用于提前解码视频比特流的资源要求,并确定硬件解码器是否支持解码实际比特流。
除了加速图像或子区域解码中,实现还可以利用各种技术来解决比特流误差(例如,由不可靠的网络传输期间腐败引起)。还可能需要存储与先前解码相关的统计数据或状态,以帮助解码视频序列中的当前/未来的图像/子图像。通常,应用程序将使用vulkan视频进行沉重的升降级解码,同时处理解析,资源管理和内部同步。
现在,最终是时候将视频解码操作记录到vulkan命令缓冲区中:
这是vk_khr_video_decode_queue扩展中提供的唯一API调用。在提交给GPU之前,在内存中为视频设备构建命令缓冲区和比特流数据。
目前仅支持图片级解码命令(由用于解码操作的相应编解码器特定的EXT扩展结构指定,例如vkvideodeCodeh264pictureInfoext)。我们有兴趣听取使用需要要求更精细的颗粒操作的情况!
现在我们有解码的图像,编码涉及类似的详细任务来解码,但是具有更大的决策点(图5)。在序列级别,应用程序可以为生成的比特流配置目标比特率。实现雇用专有算法,以评估图片复杂性和预算跨图像的比特分配以及在每个图片的子区域内。通常称为"速率控制",此特征也需要存储统计数据和状态,同时编码序列的未来图片。
作为编码过程的一部分,还必须在编码每个图像或子图像区域时使用的编解码器工具以及应该在编码时引用哪些其他图片。甚至可以在最低级编码单元(例如16x16像素块)上应用决定,用于指定比特流语法(如编解码器所定义)。除了用于生成最终基本视频比特流的图像或子图像区域的比特流之外,还必须对相应的参数集进行编码。
编码器实现可以在所提供的编解码器工具集中变化,以及暴露给用户的详细控制级别。同样,用户期望对编码有很大差异;有些用户更喜欢黑盒式编码器,这些编码器简单地馈送图像和一些高级设置,具有在引擎盖下生成的所有详细语法。一些高级用户可能需要更多地控制低级编码过程,以在应用程序中启用特定于域的优化。
vulkan视频是平衡这些要求的结果,导致低级API来鼓励广泛的Silicon供应商采用,同时依赖于工具和层来隐藏优选更高级别API的应用程序的复杂性。 vulkan视频使供应商扩展揭示了特定于供应商的控件,如果存在交叉供应商支持,则可以标准化。
图5.还示出了介绍的一些附加的vUlkan视频命令和查询,其接下来描述。
现在我们准备通过将视频编码操作记录为vulkan命令缓冲区来启动编码过程:
目前仅支持图片级编码命令(由特定于编码的特定于编码的EXT扩展结构指定,用于编码操作,例如,VKVIDEOENCODEH264VCLFRAMEINFoext)。将来,编码命令可以自身支持子图像区域的编码(例如,在H.264中的多切片帧中的单个切片)。
所有图片和参考管理决策都留给了应用程序,该应用程序还直接控制与参考管理相关的比特流语法。此外,应用程序可以选择通过实现来请求生成H.264 SPS / PPS比特流段(参见VKVIDEOENCODEH264EMITPICTUREPARAMENTEREXT)。这提供了一种用于实现如果需要生成完整的基本比特流的路径。
使用以下API记录编码器速率控制设置,以vulkan命令缓冲区:
请注意,这些设置在执行时间轴中生效(即队列提交)。该API还允许将视频会话重置为初始状态,例如,如果视频会话将用于处理新视频流。此通用API挂钩可实现其他流级控制操作的未来扩展。
作为许多解码或编码操作可以在相同的命令缓冲区中记录,所有依赖于相同的资源和设置,vulkan视频定义了一对API调用以在会话期间标记视频命令控制参数的范围:
vkcmdbeginvideocodingkhr为单个视频流设置用于视频操作的命令缓冲区上下文。此时提供了VKVIDEOSESSIONKHR对象,以及VKVIDEOSESSIONPERAMETERSKHR对象包含参数集,用于所有后续视频解码或编码操作,直到范围结束。在此之后,预期一个或多个VKCMD *视频* KHR,指定实际解码/编码操作和/或视频控制操作。用于同步的标准vUlkan命令,布局转换等也可以与视频命令一起存在。 VKCMDENDVIDEOCODINGKHR结束了视频操作的范围。
可以使用每个集合的相同或不同的视频会话和视频会话参数对象将vkcmdbeginvideocodkhr和vkcmdendvideocodingkhrcommands界定的多组视频命令录制到相同的命令缓冲区中。还可以在多个命令缓冲区中使用具有相应的视频会话对象的视频会话参数对象并行地记录到多个命令缓冲器中。
vulkan视频添加了一个新的强制vkquerytype,以报告输出缓冲区中的编码比特流的位置和大小(请参阅vk_query_type_video_encode_bitstream_buffer_range_khr)。
此外,添加可选的结果状态查询类型以确定括在vkcmdbeginquery和vkcmdendquery命令之间括起一组操作的完成状态。此结果状态本身可以使用vk_query_type_result_status_only_khr查询类型,或与使用vk_query_result_with_status_bit_khr的另一个查询类型一起报告。结果状态不是特定于视频操作,并且可以用于在执行需要额外调查的任何vulkan命令期间报告错误。对于视频操作,实现可以在遇到解码语法错误时报告错误状态,或者当编码比特流缓冲区溢出时。
随着视频查询通常由主机消耗,视频队列仅支持查询结果(vkgetQueryPoolResults)的主机转换,并且不支持设备转换(vkcmdcopyquerypoolresults)。请告诉我们设备翻译是否对您的用例很重要!
这总结了代码转换示例演练!我们希望这使您可以享受vulkan视频如何通过在复杂的vulkan管道中集成视频,图形,计算和显示操作中的高级视频加速来实现您自己的产品中的新功能。
临时vutkan视频扩展的发布标志着这一重要的新vutkan功能的第一次公开曝光,是能够实现行业审查和反馈的重要里程碑。请通过Khronos Vulkan视频Github问题分享您的想法。
与任何临时版本一样,可以响应于开发人员反馈而更新vulkan视频扩展。因此,我们要求司机供应商不发货支持这些临时扩展的生产驱动程序,并且ISV不会在其生产应用中使用这些临时扩展。要使用这些临时扩展,应用程序必须明确使能Beta扩展如下:
NVIDIA已发布实现vulkan视频的Beta Vulkan驱动程序,以及一个样本vulkan视频解码应用程序vk_video_decoder,使开发人员能够对当前临时扩展进行原型和实验。
将为最终vUlkan视频1.0扩展添加vulkan SDK验证层支持。对于此临时版本,验证层只会验证禁用vulkan视频扩展。
Khronos现在将努力完成vulkan视频1.0规格,SDK和一致性测试,因此焦点可以转向支持额外的编解码器和更高级的视频功能!
我们期待您对Vulkan视频的反馈。 感谢您的兴趣和支持对您的用例和应用程序有效的vulkan视频!