gpt4 book ai didi

ffmpeg - iPhone 上 Shader 将 YUV 转为 RGB

转载 作者:行者123 更新时间:2023-12-04 23:05:36 26 4
gpt4 key购买 nike

目前我正在使用 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。如果我将实际图像大小设置为纹理大小,则图像完全适合纹理,但图像颜色有点奇怪。它有太多的绿色。

有人给我一些线索吗?
提前致谢。

最佳答案

首先,您需要为非幂的两个纹理设置正确的包裹模式。

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
  • 为 2d 图像( Sprite )加载适当的 viewProj 矩阵,最好使用正射投影。
    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 .

    关于ffmpeg - iPhone 上 Shader 将 YUV 转为 RGB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10567155/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com