多个视频渲染过程中出现颜色错误的图片

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】:

这个问题很糟糕,我专注于着色器并花了几天时间试图找出那里的问题。然而,问题在于纹理参考初始化。所有三个引用都具有相同的值,因此我每次都覆盖了相同的纹理。将这三个都设置为不同的值,它可以完美地工作。

【讨论】:

以上是关于多个视频渲染过程中出现颜色错误的图片的主要内容,如果未能解决你的问题,请参考以下文章

第十三章 视频播放器开发之渲染背景

渲染 SKTexture 时颜色错误

WebGL 纹理颜色原理

WebGL纹理颜色原理

Android UIPaint Gradient 渐变渲染 ① ( LinearGradient 线性渐变渲染 | 设置渲染方向 | 设置渲染颜色 | 设置渲染模式 | MIRROR )

OC - 使用 系统自己的UITabBarController 出现selectedImage的颜色为默认蓝色