【发布时间】: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