多个视频渲染过程中出现颜色错误的图片
Posted
技术标签:
【中文标题】多个视频渲染过程中出现颜色错误的图片【英文标题】:Miscolored picture during multiple video rendering 【发布时间】:2014-06-24 12:22:49 【问题描述】:我目前正在将两个不同的视频流同时渲染到两个不同的 OpenGL 纹理。我使用QAbstractVideoSurface
的实现来准备视频的每一帧,然后将其传递给我的OpenGL 绘制方法。每一帧都以 YUV 编码到达,所以为了获得 RGB 值,我使用 GLSL。
问题如下:每次我尝试绘制多个这些视频时,第一个视频都可以正常播放,但另一个视频的频道会出现一些问题。
我的顶点着色器:
#version 420
attribute vec2 position;
attribute vec2 texcoord;
uniform mat4 modelViewProjectionMatrix;
varying vec2 v_texcoord;
void main()
gl_Position = modelViewProjectionMatrix * vec4(position, 0, 1);
v_texcoord = texcoord.xy;
我的片段着色器:
#version 420
varying vec2 v_texcoord;
uniform sampler2D s_texture_y;
uniform sampler2D s_texture_u;
uniform sampler2D s_texture_v;
uniform float s_texture_alpha;
void main(void)
highp float y = texture2D(s_texture_y, v_texcoord).r;
highp float u = texture2D(s_texture_u, v_texcoord).r - 0.5;
highp float v = texture2D(s_texture_v, v_texcoord).r - 0.5;
highp float r = y + 1.402 * v;
highp float g = y - 0.344 * u - 0.714 * v;
highp float b = y + 1.772 * u;
gl_FragColor = vec4(r, g, b, s_texture_alpha);
结果如下图:
有时它会正确,有时甚至更糟,但第一个视频始终正确播放。
在玩弄了一些通道之后,我发现有时 u 变量在片段着色器中获得与 v 相同的值。我的纹理绑定如下:
uniformSamplers[0] = functions.glGetUniformLocation(program, "s_texture_y");
uniformSamplers[1] = functions.glGetUniformLocation(program, "s_texture_u");
uniformSamplers[2] = functions.glGetUniformLocation(program, "s_texture_v");
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, textRef);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, image_width, image_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (GLvoid*)(image));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
functions.glUniform1i(uniformSamplers[0], 0);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, textRefU);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, image_width / 2, image_height / 2, 0, GL_LUMINANCE,
GL_UNSIGNED_BYTE, (GLvoid*)(image + image_width * image_height));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
functions.glUniform1i(uniformSamplers[1], 1);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, textRefV);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, image_width / 2, image_height / 2, 0, GL_LUMINANCE,
GL_UNSIGNED_BYTE, (GLvoid*)(image + image_height * image_width + (image_width / 2) * (image_height / 2)));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
functions.glUniform1i(uniformSamplers[2], 2);
【问题讨论】:
#version 420
..."我使用 OpenGL ES"...嗯,是哪一个?
我的意思是 GLSL,抱歉,已更正。
我认为您确实应该将其转换为独立的单文件示例。您可以生成一个虚拟的 YUV 源图像,无需处理视频。这也将帮助您隔离问题。
【参考方案1】:
这个问题很糟糕,我专注于着色器并花了几天时间试图找出那里的问题。然而,问题在于纹理参考初始化。所有三个引用都具有相同的值,因此我每次都覆盖了相同的纹理。将这三个都设置为不同的值,它可以完美地工作。
【讨论】:
以上是关于多个视频渲染过程中出现颜色错误的图片的主要内容,如果未能解决你的问题,请参考以下文章
Android UIPaint Gradient 渐变渲染 ① ( LinearGradient 线性渐变渲染 | 设置渲染方向 | 设置渲染颜色 | 设置渲染模式 | MIRROR )