YUV420p 到 RGB 的转换改变了 U 和 V 值 - iOS Unity3D
YUV420p to RGB conversion has shifted U and V values - iOS Unity3D
我在 Unity 中有一个原生插件,可以使用 FFMPEG 将 H264 帧解码为 YUV420p。
为了显示输出图像,我将 YUV 值重新排列为 RGBA 纹理并使用 Unity 着色器将 YUV 转换为 RGB(只是为了使其更快)。
以下是我原生插件中的重排代码:
unsigned char* yStartLocation = (unsigned char*)m_pFrame->data[0];
unsigned char* uStartLocation = (unsigned char*)m_pFrame->data[1];
unsigned char* vStartLocation = (unsigned char*)m_pFrame->data[2];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
unsigned char* y = yStartLocation + ((y * width) + x);
unsigned char* u = uStartLocation + ((y * (width / 4)) + (x / 2));
unsigned char* v = vStartLocation + ((y * (width / 4)) + (x / 2));
//REF: https://en.wikipedia.org/wiki/YUV
// Write the texture pixel
dst[0] = y[0]; //R
dst[1] = u[0]; //G
dst[2] = v[0]; //B
dst[3] = 255; //A
// To next pixel
dst += 4;
// dst is the pointer to target texture RGBA data
}
}
将 YUV 转换为 RGB 的着色器工作完美,我已经在多个项目中使用它。
现在,我在 iOS 平台上使用相同的代码进行解码。但出于某种原因,U 和 V 值现在发生了变化:
Y 纹理
U 纹理
iOS 或 OpenGL 有什么我遗漏的吗?
非常感谢任何帮助。
谢谢!
请注意,我在第一个屏幕截图中填写了 R=G=B = Y,在第二个屏幕截图中填写了 U。(如果有意义的话)
编辑:
这是我得到的输出:
编辑2:
根据一些研究,我认为这可能与隔行扫描有关。
参考:Link
现在我已经转向使用 sws_scale 基于 CPU 的 YUV-RGB 转换并且它工作正常。
问题出在这一行:
uStartLocation + ((y * (width / 4)) + (x / 2));
应该是
uStartLocation + (((y / 2) * (width / 2)) + (x / 2));
因为 int 舍入导致整个帧移动。尝试优化计算时出现非常愚蠢的错误。
希望对大家有所帮助。
我在 Unity 中有一个原生插件,可以使用 FFMPEG 将 H264 帧解码为 YUV420p。
为了显示输出图像,我将 YUV 值重新排列为 RGBA 纹理并使用 Unity 着色器将 YUV 转换为 RGB(只是为了使其更快)。
以下是我原生插件中的重排代码:
unsigned char* yStartLocation = (unsigned char*)m_pFrame->data[0];
unsigned char* uStartLocation = (unsigned char*)m_pFrame->data[1];
unsigned char* vStartLocation = (unsigned char*)m_pFrame->data[2];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
unsigned char* y = yStartLocation + ((y * width) + x);
unsigned char* u = uStartLocation + ((y * (width / 4)) + (x / 2));
unsigned char* v = vStartLocation + ((y * (width / 4)) + (x / 2));
//REF: https://en.wikipedia.org/wiki/YUV
// Write the texture pixel
dst[0] = y[0]; //R
dst[1] = u[0]; //G
dst[2] = v[0]; //B
dst[3] = 255; //A
// To next pixel
dst += 4;
// dst is the pointer to target texture RGBA data
}
}
将 YUV 转换为 RGB 的着色器工作完美,我已经在多个项目中使用它。
现在,我在 iOS 平台上使用相同的代码进行解码。但出于某种原因,U 和 V 值现在发生了变化:
Y 纹理
U 纹理
iOS 或 OpenGL 有什么我遗漏的吗?
非常感谢任何帮助。 谢谢!
请注意,我在第一个屏幕截图中填写了 R=G=B = Y,在第二个屏幕截图中填写了 U。(如果有意义的话)
编辑:
这是我得到的输出:
编辑2: 根据一些研究,我认为这可能与隔行扫描有关。
参考:Link
现在我已经转向使用 sws_scale 基于 CPU 的 YUV-RGB 转换并且它工作正常。
问题出在这一行:
uStartLocation + ((y * (width / 4)) + (x / 2));
应该是
uStartLocation + (((y / 2) * (width / 2)) + (x / 2));
因为 int 舍入导致整个帧移动。尝试优化计算时出现非常愚蠢的错误。
希望对大家有所帮助。