Apple A4上的YUV到RGBA,我应该使用着色器还是NEON?

时间:2011-12-09 20:11:47

标签: ios opengl-es-2.0 rgb yuv apple-tv

我正在使用OpenGL ES和ffmpeg为Apple TV编写媒体播放器框架。 在OpenGL ES上渲染需要转换为RGBA,使用swscale进行软转换是无法忍受的慢速,因此使用互联网上的信息我提出了两个想法:使用neon(如here)或使用片段着色器以及GL_LUMINANCE和GL_LUMINANCE_ALPHA

正如我对OpenGL几乎一无所知,第二种选择仍然不起作用:)

你能指点一下如何继续吗? 提前谢谢。

2 个答案:

答案 0 :(得分:20)

学习OpenGL ES2.0着色器绝对值得:

  1. 您可以在GPU和CPU之间进行负载平衡(例如,当GPU渲染当前帧时,后续帧的视频解码)。
  2. 视频帧在任何情况下都需要转到GPU:如果你的视频采用4:2:0采样色度,使用YCbCr可以节省25%的总线带宽。
  3. 使用GPU硬件插补器,您可以免费获得4:2:0色度上采样。 (您的着色器应配置为对YC{b,r}纹理使用相同的顶点坐标,实际上将色度纹理拉伸到同一区域。)
  4. 在iOS5上,使用纹理缓存快速(无数据复制或调配)将YCbCr纹理推送到GPU(请参阅CVOpenGLESTextureCache* API函数)。与NEON相比,您将节省1-2个数据副本。
  5. 我使用这些技术效果很好in my super-fast iPhone camera app, SnappyCam

    您正处于实施的正确轨道:如果您的GL_LUMINANCE是交错的,请使用Y纹理GL_LUMINANCE_ALPHACbCr。否则,如果所有GL_LUMINANCE组件都未交错,请使用三个YCbCr纹理。

    为4:2创建两个纹理:0双平面YCbCr(其中CbCr是交错的)很简单:

        glBindTexture(GL_TEXTURE_2D, texture_y);
        glTexImage2D(
            GL_TEXTURE_2D, 
            0, 
            GL_LUMINANCE,        // Texture format (8bit)
            width,
            height,
            0,                   // No border
            GL_LUMINANCE,        // Source format (8bit)
            GL_UNSIGNED_BYTE,    // Source data format
            NULL
        );
        glBindTexture(GL_TEXTURE_2D, texture_cbcr);
        glTexImage2D(
            GL_TEXTURE_2D, 
            0, 
            GL_LUMINANCE_ALPHA, // Texture format (16-bit)
            width / 2,
            height / 2,
            0,                  // No border
            GL_LUMINANCE_ALPHA, // Source format (16-bits)
            GL_UNSIGNED_BYTE,   // Source data format
            NULL
        );
    

    然后您可以使用glTexSubImage2D()或iOS5纹理缓存来更新这些纹理。

    我还建议使用跨越纹理坐标空间varying的2D (x: [0,1], y: [0,1]),以便在片段着色器中避免任何相关的纹理读取。根据我的经验,最终结果是超快,根本不加载GPU。

答案 1 :(得分:0)

使用NEON将YUV转换为RGB非常慢。使用着色器卸载到GPU上。