【发布时间】:2018-08-24 20:51:42
【问题描述】:
我在 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 转换,它工作正常。
【问题讨论】:
-
你试过this吗?
-
@Programmer YUYV(在你建议的答案中)是 YUV 4:2:2,与 OP YUV420p 不同,即平面 YUV 4:2:0
-
在这里在黑暗中拍摄(不了解 iOS 平台)但是......你确定它没有将 RGBA 解释为......比如说,RBGA 吗?如果你把赋值给 dst 的 u[0] 和 v[0] 倒置怎么办?
-
没有回答您的问题,但您应该知道构建
dst的这一步非常耗时且没有必要。您可以拥有一个将 YUV420 纹理作为输入并生成 RGB 的着色器。 -
所以在你的第二张照片中,U 通道看起来不对,不是吗?你能发布正确的预期图片吗?