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

paw*_*ski 10 rgb yuv ios opengl-es-2.0 apple-tv

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

我几乎对OpenGL一无所知,第二个选项仍然无效:)

你能指点一下如何继续吗?先感谢您.

jpa*_*pap 20

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

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

我正在使用这些技术在我的超快iPhone相机应用程序SnappyCam中发挥很大作用.

您处于正确的实施轨道:使用GL_LUMINANCE纹理Y,GL_LUMINANCE_ALPHA如果您CbCr是交错的.否则,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
    );
Run Code Online (Sandbox Code Playgroud)

然后你将使用glTexSubImage2D()或iOS5纹理缓存来更新这些纹理.

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