【问题标题】:opengl es yuv to rgb conversion display only green and pink colorsopengl es yuv 到 rgb 的转换只显示绿色和粉红色
【发布时间】:2014-02-26 03:14:57
【问题描述】:

我正在使用 opengl 着色器进行 yuv 到 rgb 的转换。但它只显示绿色和粉红色。我正在使用 ffmpeg 解码电影。我是这方面的初学者,所以不知道如何解决它。 ffmpeg 给我三个 yuv 缓冲区。我直接将这些缓冲区分配给三个纹理。

这是我正在使用的着色器。

static const char* VERTEX_SHADER =
"attribute vec4 vPosition;                      \n"
"attribute vec2 a_texCoord;                     \n"
"varying vec2 tc;                               \n"
"uniform mat4 u_mvpMat;                         \n"
"void main()                                    \n"
"{                                              \n"
"   gl_Position = u_mvpMat * vPosition;         \n"
"   tc = a_texCoord;                            \n"
"}                                              \n";

static const char* YUV_FRAG_SHADER =
"#ifdef GL_ES                                   \n"
"precision highp float;                         \n"
"#endif                                         \n"
"varying vec2 tc;                               \n"
"uniform sampler2D TextureY;                    \n"
"uniform sampler2D TextureU;                    \n"
"uniform sampler2D TextureV;                    \n"
"uniform float imageWidth;                      \n"
"uniform float imageHeight;                     \n"

"void main(void)                                \n"
"{                                              \n"
    "float nx, ny;                              \n"
    "vec3 yuv;                                  \n"
    "vec3 rgb;                                  \n"
    "nx = tc.x;                                 \n"
    "ny = tc.y;                                 \n"

    "yuv.x = texture2D(TextureY, tc).r;         \n"
    "yuv.y = texture2D(TextureU, vec2(nx/2.0, ny/2.0)).r - 0.5;   \n"
    "yuv.z = texture2D(TextureV, vec2(nx/2.0, ny/2.0)).r - 0.5;   \n"

    // Using BT.709 which is the standard for HDTV
    "rgb = mat3( 1,              1,      1,     \n"
                "0,       -0.18732, 1.8556,     \n"
                "1.57481, -0.46813,      0)*yuv;\n"

    // BT.601, which is the standard for SDTV is provided as a reference
    //"rgb = mat3( 1,            1,     1,        \n"
    //            "0,     -0.34413, 1.772,        \n"
    //            "1.402, -0.71414,     0) * yuv; \n"
    "gl_FragColor = vec4(rgb, 1.0);             \n"
"}                                              \n";

输出:

我做错了什么?这个你能帮我吗。

谢谢。

更新:

在调试ffmpeg解码时,发现ffmpeg解码器给出PIX_FMT_YUV420P输出格式。我是否必须进行一些调整才能获得正确的图像颜色?

【问题讨论】:

  • 屏幕截图表明颜色纹理的大小被放大了 2 倍。着色器本身并没有解释这是如何发生的。您将解码后的 yuv 发送到 opengl 的代码可能会有所帮助。也许,只需将vec2(nx/2.0, ny/2.0) 替换为tc 就足够了。
  • 用 tc 替换 vec2(nx/2.0, ny/2.0) 没有帮助。它仍然显示绿色和粉红色。
  • mvpMat 是一个身份矩阵,所以我不知道它是如何过度缩放的。我是 YUV 和 Opengl 的初学者。
  • ffmpeg 库为我提供解码的 yuv 数据。我只是传递这些数据,因为它是打开 gl。它将如何遮蔽一些光线?
  • 纹理颜色是否过度缩放是图像中未​​显示正确颜色的问题?我无法找出过度缩放的确切原因。

标签: android ios opengl-es ffmpeg yuv


【解决方案1】:

我不确定这种转变:

"rgb = mat3( 1,              1,      1,     \n"
            "0,       -0.18732, 1.8556,     \n"
            "1.57481, -0.46813,      0)*yuv;\n"

在刷新我对 GLSL using this page as reference 中矩阵 * 向量运算的记忆时,我认为您要么需要转置系数矩阵,要么将 yuv 移动到运算的前面,即 yuv * mat3(...)。以mat3(...) * yuv 执行操作意味着:

r = y * 1 + u * 1 + v * 1
g = y * 0 + u * -0.18732 + v * 1.8556
b = y * 1.57481 + u * -0.46813 + v * 0

而且这些转换是非常不正确的。

作为另一个参考,这里有一个小的、完整的示例 GLSL 着色器程序,它可以转换 YUV -> RGB,可能有一些指导意义:http://www.fourcc.org/source/YUV420P-OpenGL-GLSLang.c

【讨论】:

    猜你喜欢
    • 2014-02-25
    • 2014-08-26
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多