创建打包的YUV金属着色器

问题描述

我正在尝试创建一个金属着色器,以接收YUV UYVY图像缓冲区。我已经进行了一些研究,发现的唯一示例是针对Planar格式的,但是UYUV是Packed格式。

我认为将打包的缓冲区传递给Metal并具有着色器处理将是最快的?我也尝试过使用Accelerate框架转换为RGB,但是运气不高。我想将其保留在YUV中以提高性能。也许可以从打包格式转换为刨床?

这是我生成MTLTexture的代码。我指定.bgrg422格式以使其与缓冲区对齐。实际的金属视图是bgra8Unorm。

if let MetalDevice = MTLCreateSystemDefaultDevice() {
  let mtd = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgrg422,width: width,height: height,mipmapped: false)
  let texture = MetalDevice.makeTexture(descriptor: mtd)
  texture?.replace(region: MTLRegionMake2D(0,width,height),mipmapLevel: 0,withBytes: outPtr,bytesPerRow: bytesPerRow)
}

这是我发现的着色器,但是它具有两个纹理(Y和CbCr)。我将如何只处理一个包含所有内容的纹理?

// Captured image fragment function
fragment float4 capturedImageFragmentShader(TextureMappingVertex in [[stage_in]],texture2d<float,access::sample> capturedImageTextureY [[ texture(1) ]],access::sample> capturedImageTextureCbCr [[ texture(2) ]]) {
    
    constexpr sampler colorSampler(mip_filter::linear,mag_filter::linear,min_filter::linear);
    
    const float4x4 ycbcrToRGBTransform = float4x4(
        float4(+1.0000f,+1.0000f,+0.0000f),float4(+0.0000f,-0.3441f,+1.7720f,float4(+1.4020f,-0.7141f,+0.0000f,float4(-0.7010f,+0.5291f,-0.8860f,+1.0000f)
    );
    
    // Sample Y and CbCr textures to get the ycbcr color at the given texture coordinate
    float4 ycbcr = float4(capturedImageTextureY.sample(colorSampler,in.textureCoordinate).r,capturedImageTextureCbCr.sample(colorSampler,in.textureCoordinate).rg,1.0);
    
    // Return converted RGB color
    return ycbcrToRGBTransform * ycbcr;
}

谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)