You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

YUV4:2:0转RGB后图像偏绿的D3D11渲染问题排查

YUV420转RGB渲染偏绿问题排查

问题背景

解码得到YUV420平面帧(UV分量未打包),使用D3D11渲染时需转换为RGB格式(假设渲染目标视图不支持YUV)。创建3个DXGI_FORMAT_R8_UNORM类型的纹理和ShaderResourceView,将帧的每个平面数据复制到对应视图,依靠采样器处理Y与UV平面的尺寸差异。黑白画面显示正常,但彩色画面严重偏绿。已尝试交换UV平面、调整转换系数,遵循官方图像转换指南,问题仍未解决。

相关代码

像素着色器代码

min16float4 main(PixelShaderInput input) : SV_TARGET
{
    float y = YChannel.Sample(defaultSampler, input.texCoord).r;
    float u = UChannel.Sample(defaultSampler, input.texCoord).r - 0.5;
    float v = VChannel.Sample(defaultSampler, input.texCoord).r - 0.5;

    float r = y + 1.13983 * v;
    float g = y - 0.39465 * u - 0.58060 * v;
    float b = y + 2.03211 * u;

    return min16float4(r, g, b , 1.f);
}

创建ShaderResourceView代码

D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = 1670;
texDesc.Height = 626;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8_UNORM;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DYNAMIC;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;


dev->CreateTexture2D(&texDesc, NULL, &pYPictureTexture);
dev->CreateTexture2D(&texDesc, NULL, &pUPictureTexture);
dev->CreateTexture2D(&texDesc, NULL, &pVPictureTexture);

D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
shaderResourceViewDesc.Format = DXGI_FORMAT_R8_UNORM;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;

dev->CreateShaderResourceView(pYPictureTexture, &shaderResourceViewDesc, &pYPictureTextureResourceView);

dev->CreateShaderResourceView(pUPictureTexture, &shaderResourceViewDesc, &pUPictureTextureResourceView);

dev->CreateShaderResourceView(pVPictureTexture, &shaderResourceViewDesc, &pVPictureTextureResourceView);

复制FFmpeg解码后AVFrames代码

int height = 626;
int width = 1670;    

D3D11_MAPPED_SUBRESOURCE msY;
D3D11_MAPPED_SUBRESOURCE msU;
D3D11_MAPPED_SUBRESOURCE msV;
devcon->Map(pYPictureTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &msY);

memcpy(msY.pData, frame->data[0], height * width);
devcon->Unmap(pYPictureTexture, 0);

devcon->Map(pUPictureTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &msU);
memcpy(msU.pData, frame->data[1], (height*width) / 4);
devcon->Unmap(pUPictureTexture, 0);


devcon->Map(pVPictureTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &msV);
memcpy(msV.pData, frame->data[2], (height*width) / 4);
devcon->Unmap(pVPictureTexture, 0);

问题排查方向

  • UV纹理尺寸错误:YUV420的UV平面宽高应为Y平面的1/2(即Width=835,Height=313),当前UV纹理和Y平面尺寸一致,采样时会重复读取数据导致色彩偏移。
  • 行间距(Pitch)未正确处理:FFmpeg的AVFrame->linesize可能大于实际宽度,直接用height*width拷贝会导致数据错位,应使用linesize[0]、linesize[1]、linesize[2]计算拷贝字节数,逐行拷贝而非直接memcpy整个区域。
  • 色彩空间系数不匹配:当前转换系数对应BT.601标准,若视频为BT.709格式,需调整系数:
    float r = y + 1.5748 * v;
    float g = y - 0.1873 * u - 0.4681 * v;
    float b = y + 1.8556 * u;
    
  • 采样器设置问题:确保采样器使用D3D11_FILTER_MIN_MAG_MIP_LINEAR,地址模式设置合理,避免UV采样时拉伸错误。

内容的提问来源于stack exchange,提问作者luckybroma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:37:51