6

我有一个 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 渲染视频。

4

3 回答 3

6

这是我们已向 ARM 报告的已知驱动程序问题。未来的更新应该会修复它。

于 2013-03-23T00:13:28.337 回答
1

编辑状态更新

我们现在已经设法重现了公共固件上一个路径的缓慢上传条件,您可能会遇到这种情况,这将在下一个驱动程序版本中得到修复。

如果您为正在上传的纹理双缓冲纹理 ID(例如,帧 N = ID X、N+1 = ID Y、N+2 = ID X、N+3 = ID Y 等)应该有助于避免这种情况在当前固件上。

谢谢, 异

于 2013-03-23T00:31:17.133 回答
1

我可以确认这已在 Android 4.3 中得到修复 - 我看到 RGBA 格式的性能提高了 2-3 倍,而其他纹理格式的性能提高了 10-50 倍,超过了 Android 4.2.2。这些结果适用于 glTexImage2D 和 glTexSubImage2D。(还不能添加评论,所以我不得不把它放在这里)

编辑:如果您坚持使用 4.2.2,则可以尝试使用 RGBA 纹理,它应该具有更好的性能(3-10 倍左右,具有更大的二次幂纹理大小)。

于 2013-08-05T07:46:33.667 回答