我正在使用OpenGL ES和ffmpeg为Apple TV编写媒体播放器框架。 在OpenGL ES上渲染需要转换为RGBA,使用swscale进行软转换是无法忍受的慢速,因此使用互联网上的信息我提出了两个想法:使用neon(如here)或使用片段着色器以及GL_LUMINANCE和GL_LUMINANCE_ALPHA
正如我对OpenGL几乎一无所知,第二种选择仍然不起作用:)
你能指点一下如何继续吗? 提前谢谢。
答案 0 :(得分:20)
学习OpenGL ES2.0着色器绝对值得:
YCbCr
可以节省25%的总线带宽。Y
和C{b,r}
纹理使用相同的顶点坐标,实际上将色度纹理拉伸到同一区域。)YCbCr
纹理推送到GPU(请参阅CVOpenGLESTextureCache*
API函数)。与NEON相比,您将节省1-2个数据副本。我使用这些技术效果很好in my super-fast iPhone camera app, 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
);
然后您可以使用glTexSubImage2D()
或iOS5纹理缓存来更新这些纹理。
我还建议使用跨越纹理坐标空间varying
的2D (x: [0,1], y: [0,1])
,以便在片段着色器中避免任何相关的纹理读取。根据我的经验,最终结果是超快,根本不加载GPU。
答案 1 :(得分:0)
使用NEON将YUV转换为RGB非常慢。使用着色器卸载到GPU上。