目前我正在使用FFMPEG开发视频播放器。 我试图通过Shader将YUV420P转换为RGB来降低性能,我可以看到它工作正常。当我尝试更改图像大小时,会导致此问题。
案例1. YUV到RGB非常完美。但是图像并不完全适合纹理边界。 例如,如果我播放640x360视频,则右(640-512)部分被裁剪而底部(512-360)被填充绿色矩形。
FRAME_X=512; //This is texture size
FRAME_Y=512;
avpicture_fill((AVPicture *) f, [currentVideoBuffer.data mutableBytes],
enc->pix_fmt,
FRAME_X, FRAME_Y);
av_picture_copy((AVPicture *) f, (AVPicture *) avFrame,
enc->pix_fmt,
enc->width, enc->height);
...
int yuvWidth= FRAME_X ;
int yuvHeight= FRAME_Y;
glBindTexture ( GL_TEXTURE_2D, textureIdY );
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
yuvWidth, yuvHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, y_channel);
glBindTexture ( GL_TEXTURE_2D, textureIdU );
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
yuvWidth/2, yuvHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, u_channel);
glBindTexture ( GL_TEXTURE_2D, textureIdV );
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
yuvWidth/2, yuvHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, v_channel);
案例2.如果我将实际图像大小设置为纹理大小,那么图像完全适合纹理,但图像的颜色有点奇怪。它有太多的绿色。
有人给我一些线索吗? 提前谢谢。
答案 0 :(得分:3)
首先,您需要为两个纹理的非幂次设置正确的包裹模式。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
然后,尝试将过滤模式设置为GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
着色器。
顶点着色器
attribute vec4 position;
attribute vec2 texcoord;
uniform mat4 modelViewProjectionMatrix;
varying vec2 v_texcoord;
void main()
{
gl_Position = modelViewProjectionMatrix * position;
v_texcoord = texcoord.xy;
}
设置顶点
vertices[0] = -1.0f; // x0
vertices[1] = -1.0f; // y0
vertices[2] = 1.0f; // ..
vertices[3] = -1.0f;
vertices[4] = -1.0f;
vertices[5] = 1.0f;
vertices[6] = 1.0f; // x3
vertices[7] = 1.0f; // y3
加载适当的viewProj矩阵,对于2d图像(精灵),最好使用正投影。
GLfloat modelviewProj[16];
mat4f_LoadOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, modelviewProj);
glUniformMatrix4fv(_uniformMatrix, 1, GL_FALSE, modelviewProj);
接下来,请确保使用正确的文字坐标,例如
GLfloat texCoords[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
最后,像这样的片段着色器:
varying highp vec2 v_texcoord;
uniform sampler2D s_texture_y;
uniform sampler2D s_texture_u;
uniform sampler2D s_texture_v;
void main()
{
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,1.0);
}
您可以将我的代码视为在iOS上使用FFmpeg和OpenGLES的示例:https://github.com/kolyvan/kxmovie。