vulkan从小白到专家——YUV处理
1 YUV使用场景
通过生产者消费者模式,底层照相机,录制视频生成buffer,图形渲染模块作为消费者,
拿到的通常是多层平面表示的像素格式,即YCbCr格式。图像信息通常由多层图片构成,
如果gles开发,开发者需要维护两套纹理,分别保存YUV的多层平面信息,然后再fragment shader中分别采样,结果再进行混合。。非常繁琐
基于vulkan YUV扩展,驱动自动生成shader,从多个图像的平面上采样,然后将结果转化成rgba的格式,
yuv有多种不同格式:nv12、nv21、420p。
youtube上的vulkanised24上的视频:https://www.youtube.com/watch?v=RABV11Nr-gE&t=1348s
2 VK_KHR_sampler_ycbcr_conversion
The use of Y′CBCR sampler conversion is an area in 3D graphics not used by most Vulkan developers. It is mainly used for processing inputs from video decoders and cameras. The use of the extension assumes basic knowledge of Y′CBCR concepts.This extension provides the ability to perform specified color space conversions during texture sampling operations for the Y′CBCR color space natively. It also adds a selection of multi-planar formats, image aspect plane, and the ability to bind memory to the planes of an image collectively or separately.
Y′CBCR采样器转换的使用是大多数Vulkan开发者未曾涉足的3D图形领域,其主要应用于视频解码器和摄像头输入的处理。使用该扩展功能需具备Y′CBCR色彩空间的基本概念。
该扩展原生支持在纹理采样操作期间执行指定的Y′CBCR色彩空间转换,同时新增了多平面格式选项、图像切面(aspect plane)概念,并允许将内存整体或分别绑定至图像的各个平面。
https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_sampler_ycbcr_conversion.html
2.1 查询能力
VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR ycbcrFeatures = {};ycbcrFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR;VkPhysicalDeviceFeatures2 features2 = {};features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;features2.pNext = &ycbcrFeatures;vkGetPhysicalDeviceFeatures2(physicalDevice, &features2);if (!ycbcrFeatures.samplerYcbcrConversion) {throw std::runtime_error("Y′CBCR conversion not supported!");}
2.2 创建转换器
重点指定颜色空间即色域相关的转化,
VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR 指定了yuv专程rgb以后到色域信息,
问deepseek到结果:标清601,高清的709,HDR的BT2020,
VkSamplerYcbcrConversionCreateInfoKHR ycbcrCreateInfo = {};
ycbcrCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR;
ycbcrCreateInfo.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
ycbcrCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR;
ycbcrCreateInfo.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR;
ycbcrCreateInfo.components = {VK_COMPONENT_SWIZZLE_IDENTITY, // RVK_COMPONENT_SWIZZLE_IDENTITY, // GVK_COMPONENT_SWIZZLE_IDENTITY, // BVK_COMPONENT_SWIZZLE_IDENTITY // A
};
ycbcrCreateInfo.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN_KHR;
ycbcrCreateInfo.chromaFilter = VK_FILTER_LINEAR;VkSamplerYcbcrConversionKHR ycbcrConversion;
vkCreateSamplerYcbcrConversionKHR(device, &ycbcrCreateInfo, nullptr, &ycbcrConversion);
//或者vkCreateSamplerYcbcrConversion ,不同版本vulkan api 有差异!
2.3 pipeline中集成
createTexture的时候,根据解析的纹理格式desc中的平面个数智能开启YUV的配置,最终得在ImageView中设置ycbcrInfo
https://github.com/corporateshark/lightweightvk/blob/master/samples/004_YUV.cpp