YUV420p 上的大量绿色 --> iOS 上 OpenGL 2.0 着色器中的 RGB

2024-04-29

我想使用 ffmpeg 和 OpenGL ES 2.0 为 iOS 制作一个电影播放器 但我有一些问题。输出 RGB 图像有很多绿色。 这是代码和图像

  • 480x320 宽度和高度:
  • 512x512 纹理宽度和高度

我从 ffmpeg AVFrame 获得了 YUV420p 行数据。

    for (int i = 0, nDataLen = 0; i < 3; i++) {
        int nShift = (i == 0) ? 0 : 1;
        uint8_t *pYUVData = (uint8_t *)_frame->data[i];
        for (int j = 0; j < (mHeight >> nShift); j++) {
            memcpy(&pData->pOutBuffer[nDataLen], pYUVData, (mWidth >> nShift));
            pYUVData += _frame->linesize[i];
            nDataLen += (mWidth >> nShift);
        }
    }

并为Y、U和V通道准备纹理。

//: U Texture
    if (sampler1Texture) glDeleteTextures(1, &sampler1Texture);

    glActiveTexture(GL_TEXTURE1);
    glGenTextures(1, &sampler1Texture);
    glBindTexture(GL_TEXTURE_2D, sampler1Texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // This is necessary for non-power-of-two textures
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glEnable(GL_TEXTURE_2D);

    glTexImage2D(GL_TEXTURE_2D, 
                 0, 
                 GL_LUMINANCE, 
                 texW / 2, 
                 texH / 2, 
                 0, 
                 GL_LUMINANCE, 
                 GL_UNSIGNED_BYTE,
                 NULL);

    //: V Texture
    if (sampler2Texture) glDeleteTextures(1, &sampler2Texture);

    glActiveTexture(GL_TEXTURE2);
    glGenTextures(1, &sampler2Texture);
    glBindTexture(GL_TEXTURE_2D, sampler2Texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // This is necessary for non-power-of-two textures
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glEnable(GL_TEXTURE_2D);

    glTexImage2D(GL_TEXTURE_2D, 
                 0, 
                 GL_LUMINANCE, 
                 texW / 2, 
                 texH / 2, 
                 0, 
                 GL_LUMINANCE,
                 GL_UNSIGNED_BYTE,
                 NULL);

    //: Y Texture
    if (sampler0Texture) glDeleteTextures(1, &sampler0Texture);

    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &sampler0Texture);
    glBindTexture(GL_TEXTURE_2D, sampler0Texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // This is necessary for non-power-of-two textures
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glEnable(GL_TEXTURE_2D);

    glTexImage2D(GL_TEXTURE_2D, 
                 0, 
                 GL_LUMINANCE, 
                 texW, 
                 texH, 
                 0, 
                 GL_LUMINANCE,
                 GL_UNSIGNED_BYTE, 
                 NULL);

渲染部分如下。

int _idxU = mFrameW * mFrameH;
int _idxV = _idxU + (_idxU / 4);

// U data
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, sampler1Texture);
glUniform1i(sampler1Uniform, 1);

glTexSubImage2D(
                GL_TEXTURE_2D, 
                0, 
                0, 
                0, 
                mFrameW / 2,            // source width
                mFrameH / 2,            // source height
                GL_LUMINANCE,
                GL_UNSIGNED_BYTE, 
                &_frameData[_idxU]);

// V data
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, sampler2Texture);
glUniform1i(sampler2Texture, 2);

glTexSubImage2D(
                GL_TEXTURE_2D, 
                0, 
                0, 
                0, 
                mFrameW / 2,            // source width
                mFrameH / 2,            // source height
                GL_LUMINANCE,
                GL_UNSIGNED_BYTE,
                &_frameData[_idxV]);

// Y data
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sampler0Texture);
glUniform1i(sampler0Uniform, 0);

glTexSubImage2D(
                GL_TEXTURE_2D, 
                0, 
                0, 
                0, 
                mFrameW,            // source width
                mFrameH,            // source height
                GL_LUMINANCE,
                GL_UNSIGNED_BYTE,
                _frameData);

顶点着色器和片段着色器如下。

attribute vec4 Position;
attribute vec2 TexCoordIn;

varying vec2 TexCoordOut;
varying vec2 TexCoordOut_UV;

uniform mat4 Projection;
uniform mat4 Modelview;

void main()
{
    gl_Position = Projection * Modelview * Position;
    TexCoordOut = TexCoordIn;
}



uniform sampler2D sampler0; // Y Texture Sampler
uniform sampler2D sampler1; // U Texture Sampler
uniform sampler2D sampler2; // V Texture Sampler

varying highp vec2 TexCoordOut;

void main()
{
    highp float y = texture2D(sampler0, TexCoordOut).r;
    highp float u = texture2D(sampler2, TexCoordOut).r - 0.5;
    highp float v = texture2D(sampler1, TexCoordOut).r - 0.5;

    //y = 0.0;
    //u = 0.0;
    //v = 0.0;

    highp float r = y + 1.13983 * v;
    highp float g = y - 0.39465 * u - 0.58060 * v;
    highp float b = y + 2.03211 * u;

    gl_FragColor = vec4(r, g, b, 1.0);
}

Y 纹理(灰度)是正确的,但 U 和 V 有很多绿色。 所以最终的 RGB 图像 (Y+U+V) 有很多绿色。 有什么问题?

请帮忙。 谢谢。


Change u and v制服(反之亦然),你就会得到正确的结果。

所以像素着色器(保持不变):

uniform sampler2D sampler0; // Y Texture Sampler
uniform sampler2D sampler1; // U Texture Sampler
uniform sampler2D sampler2; // V Texture Sampler

varying highp vec2 TexCoordOut;

void main()
{
    highp float y = texture2D(sampler0, TexCoordOut).r;
    highp float u = texture2D(sampler2, TexCoordOut).r - 0.5;
    highp float v = texture2D(sampler1, TexCoordOut).r - 0.5;

    highp float r = y + 1.13983 * v;
    highp float g = y - 0.39465 * u - 0.58060 * v;
    highp float b = y + 2.03211 * u;

    gl_FragColor = vec4(r, g, b, 1.0);
}

和渲染代码:

// RENDERING

    int _idxU = mFrameW * mFrameH;
    int _idxV = _idxU + (_idxU / 4);

    // U data
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, sampler1Texture);

    GLint sampler1Uniform = glGetUniformLocation(programStandard, "sampler2");

    glUniform1i(sampler1Uniform, 1);

    glTexSubImage2D(
                    GL_TEXTURE_2D,
                    0,
                    0,
                    0,
                    mFrameW / 2,            // source width
                    mFrameH / 2,            // source height
                    GL_LUMINANCE,
                    GL_UNSIGNED_BYTE,
                    &_frameData[_idxU]);

    // V data
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, sampler2Texture);

    GLint sampler2Uniform = glGetUniformLocation(programStandard, "sampler1");
    glUniform1i(sampler2Uniform, 2);

    glTexSubImage2D(
                    GL_TEXTURE_2D,
                    0,
                    0,
                    0,
                    mFrameW / 2,            // source width
                    mFrameH / 2,            // source height
                    GL_LUMINANCE,
                    GL_UNSIGNED_BYTE,
                    &_frameData[_idxV]);

    // Y data
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, sampler0Texture);

    GLint sampler0Uniform = glGetUniformLocation(programStandard, "sampler0");
    glUniform1i(sampler0Uniform, 0);

    glTexSubImage2D(
                    GL_TEXTURE_2D,
                    0,
                    0,
                    0,
                    mFrameW,            // source width
                    mFrameH,            // source height
                    GL_LUMINANCE,
                    GL_UNSIGNED_BYTE,
                    _frameData);


    //draw RECT
    glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, squareVertices);
    glEnableVertexAttribArray(ATTRIB_VERTEX);

    //ATTRIB_TEXTUREPOSITON
    glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureCoords);
    glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    free(_frameData);

    [(EAGLView *)self.view presentFramebuffer];

结论:u <-> v制服。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

YUV420p 上的大量绿色 --> iOS 上 OpenGL 2.0 着色器中的 RGB 的相关文章

  • WebGL iOS 渲染为浮点纹理

    我正在尝试在 iOS Safari 上的 WebGL 中渲染浮点纹理 而不是在本机应用程序中 我已经设法让 iOS 读取手动 例如从 JavaScript 创建的浮点纹理 但是当我创建浮点类型的帧缓冲区并使用 GPU 渲染到其中时 它不起作
  • 如何从 NSString 中删除十六进制字符

    我面临一个与字符串中的某些十六进制值相关的问题 我需要从字符串中删除十六进制字符 The problem is when i print object it prints as BLANK line And in debug mode it
  • 更改 UITextField 辅助功能描述

    有没有办法将 UITextField 的辅助功能标签设置为 文本字段 之外的其他内容 因此 我不想将其称为 文本字段 而是将其命名为 代码验证字段 我的建议是不要试图在内置语音输出上智取系统 对于盲人用户来说 文本字段正在编辑 相当于 该项
  • 如何将十六进制数组转换为 UIImage?

    有几个与使用 P25mi 动态打印图像相关的未解答问题 没有一个得到公认的答案 下面有几个链接 如何将图像转换为位图代码以便在 iPhone 中进行蓝牙打印 https stackoverflow com questions 1383828
  • 在 Swift 中检查一个数组是否包含另一个数组的所有元素

    我想为数组编写一个扩展来检查一个数组是否包含另一个数组的所有元素 在我的用例中它是字符串对象 但我一直得到 Cannot convert value of type T Generator Element to expected argum
  • 在模拟器中运行应用程序时删除本地通知的 iOS 权限警报

    我正在尝试编写验收测试KIF https github com kif framework KIF在一个很早就要求本地通知权限的应用程序上 不幸的是 由于 iOS 模拟器安全原因无法使用 KIF 自动接受 iOS 权限警报 https gi
  • 如果 NSExtensionActivationRule 设置为仅音频,则共享扩展不会出现在有功能的应用程序中

    我正在尝试创建一个共享扩展 用户可以从任何有能力的应用程序上传她的录音 该文档甚至有一个简单的示例 请参阅声明共享或操作扩展支持的数据类型 https developer apple com library content document
  • 如何在 Xcode 4 中通过一个操作归档多个目标

    我有一个包含多个目标的项目 这些目标都适用于不同的 iOS 应用程序 例如 一个用于精简版的目标 另一个用于专业版的目标 我想立即构建并归档我的所有应用程序 目前 我对每个目标都有一个方案 我用它来独立归档每个应用程序 但现在我必须开始归档
  • UIImage:如何获取网站选项卡图标

    我正在开发一个 RSS 阅读器 我需要获取每个提要的图标 例如 如果我的提要是 google com 我想获取 G 图标并将其放入 UIImage 或其他内容中 关于如何实现这一目标有什么想法吗 最简单的方法是使用 Google NSStr
  • 如何在 EKRecurrenceRule 中设置一周中某一天的数组?

    我想在用户选择的特定日期每周添加事件 可以是一个或多个 也可以是一整天 我将用户选择的日期值存储在模型类变量中 但是 当我添加事件并选择日期时 假设今天是星期一 我选择星期二和星期三并保存 然后我查看周一和周三添加的 iPhone 日历 我
  • 为什么 GDB 调试器不断冻结 Xcode 4?

    这真是一个奇怪的错误 我正在开发一个使用相机源的 iPhone 项目 并通过 OpenGL 着色器运行它以对其应用效果 然而 每次我在代码中简单地创建一个新的 GLfloat 时 调试器都会在启动时冻结 我无法复制和粘贴文本 因为整个 XC
  • PowerShell 脚本 ffmpeg

    作为一名优秀的 Windows 系统管理员 我终于开始学习 PowerShell 话虽这么说 我不知道我在做什么 惊讶 惊讶 我认为远离生产环境 在家里使用 PowerShell 对我来说将是一次很好的学习经历 最近 我开始使用 FFMPE
  • Xcode 9.0.1 应用程序分发程序已更改

    最近我将 Xcode 升级到了 Xcode 9 1 之后 当我尝试发布我的应用程序时 Xcode 不允许选择我为临时创建的分发配置文件 这么说 配置文件不是 IOS 应用商店配置文件 如果 Xcode 9 1 的应用程序分发过程有变化 请告
  • 以编程方式更改 UISlider 的范围

    如何以编程方式设置 UISlider 的最小最大范围 例如 虚拟代码 UISlider slider UISlider alloc init slider min 3 slider max 3 EDIT 所以我有以下内容 sl minimu
  • 是否可以使用 iOS SDK 更改 Amazon Cognito 中的用户名?

    正如标题中所写 是否可以更改 Amazon Cognito 用户的用户名 我在文档中找不到任何内容 可以更新preferred username使用 iOS SDK 的 Cognito 用户 使用updateAttributesAPI 调用
  • UIWebView 未正确加载 JavaScript - 嵌入式 Facebook 帖子

    Facebook 有一项新功能 允许用户将公共帖子嵌入网页中 我想尝试在 UIWebView 内的 iPhone 应用程序中使用它 转义必要的代码非常简单 但即使我手动转义代码 Web 视图也不会正确加载帖子 JavaScript 根本不起
  • 后台模式下的 AVSpeechSynthesizer

    我无法获取 iOS 7AVSpeechSynthesizer当我的 iOS 应用程序处于后台模式时工作 我添加了 应用程序播放音频 应用程序支持的后台模式的关键 但我仍然无法让它工作 我还研究了创建一个AVMutableCompositio
  • iOS SDK:MapKit MKPolyLine 未显示

    我试图在地图上显示多段线 但该线没有显示 我尝试了很多事情 但注意到似乎有用 我检查了核心数据函数 它正在返回数据 所以这不是问题 它必须是我在地图点创建或地图上绘制的某个地方 我猜 我确信一定是某个地方出了点小错误 但我找不到它 My c
  • iOS SWIFT - WebRTC 从前置摄像头更改为后置摄像头

    WebRTC 视频默认使用前置摄像头 效果很好 但是 我需要将其切换到后置摄像头 但我无法找到任何代码来执行此操作 我需要编辑哪一部分 是 localView 或 localVideoTrack 还是捕获器 斯威夫特3 0 对等连接只能有一
  • 将我的免费应用程序从 Universal 升级到仅限 iPhone

    我释放我的free app到 appStore 它的版本是 1 0 它是一个Universal app 现在我想发布 1 1 版本到 appStore 我将其升级到iPhone only appStore会拒绝我吗 我已阅读类似的问题 ht

随机推荐