我有一个 Android 应用程序,可以将视频解码为 yuv420p 格式,然后使用 OpenGLES 渲染视频帧。我使用 glTexSubImage2D() 将 y/u/v 缓冲区上传到 GPU,然后使用着色器进行 YUV2RGB 转换。所有 EGL/OpenGL 设置/渲染代码都是本机代码。
现在我并不是说我的代码没有问题,但考虑到相同的代码在 iOS (iPad/iPhone)、Nexus 7、Kindle HD 8.9、三星 Note 1 和其他一些便宜的中国平板电脑 (A31/ RockChip 3188) 运行 Android 4.0/4.1/4.2。我会说我的代码不太可能是错误的。在这些设备上,glTexSubImage2D() 使用不到 16 毫秒来上传 SD 或 720P 高清纹理。
但是,在 Nexus 10 上,glTexSubImage2D() 处理 SD 或 720P HD 纹理大约需要 50~90ms,这对于 30fps 或 60fps 视频来说太慢了。
我想知道
1)如果我应该选择不同的纹理格式(RGBA 或 BGRA)。有没有办法检测 GPU 使用的最佳纹理格式是什么?
2) 如果在所有其他 SOC 上存在“关闭”但在 Exynos 5 上设置为“开启”的功能。例如,自动 MIPMAP 生成选项。(我把它关了,顺便说一句)
3) 如果这是三星 Exynos SOC 的已知问题 - 我找不到 Exynos CPU 的支持论坛
4) 配置 EGL 表面时我需要设置任何选项吗?比如,透明度,表面格式等?(我不知道我在说什么)
5) 这可能意味着 GPU 正在进行隐式格式转换,但我检查了始终使用 GL_LUMINANCE。它再次适用于所有其他平台。
6)还有什么?
我的 EGL 配置:
const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_NONE
};
初始设置:
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, ctx->frameW, ctx->frameH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); /* also for U/V */
随后的部分替换:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ctx->frameW, ctx->frameH, GL_LUMINANCE, GL_UNSIGNED_BYTE, yBuffer); /*also for U/V */
我正在尝试以 SD 或 720P HD 分辨率以 ~30FPS 或 ~60FPS 渲染视频。