【问题标题】:How to improve opengl es display performance in android如何在android中提高opengl es显示性能
【发布时间】:2014-04-17 11:06:39
【问题描述】:

我正在努力提高我们视频会议项目在 android 中的视频显示效率。视频显示是在原生 opengl 代码中实现的。 opengl代码是在opengl版本1的本地实现的。下面给出的代码用于显示视频的每一帧。

int ofi_vc_video_display::render_video_frame(unsigned char *frame_buffer)
{

    // Check the frame is available or not. If available display the frame.
    if (frame_buffer != NULL){

        // Clear the screen buffers.
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Bind the frame data to the texture.
        glTexSubImage2D(GL_TEXTURE_2D,
                        0,
                        0,
                        0,
                        frame_width,
                        frame_height,
                        GL_RGB,
                        GL_UNSIGNED_BYTE,
                        frame_buffer);

        // Check for the error status.
        while ((gl_error_status=glGetError()) != GL_NO_ERROR) {

            error_status = gl_error_status;
          }

        // Transform and rotate the texture.
        glMatrixMode(GL_TEXTURE);
        glLoadIdentity();
        glTranslatef(0.5, 0.5, 0.0);
        glRotatef(180.0, 180.0, 0.0,1.0);
        glTranslatef(-0.5, -0.5, 0.0);
        glMatrixMode(GL_MODELVIEW);

        glLoadIdentity();
        glTranslatef(0, 0, -4);

        // Enable drawing texture.
        glBindTexture(GL_TEXTURE_2D, mTextureId);

        // Draw the frames in texture.
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

        // Check for the error status.
        while ((gl_error_status=glGetError()) != GL_NO_ERROR) {

            error_status = gl_error_status;
          }
    }
    return error_status;
}

所有初始化都在之前完成。 该代码适用于较低的分辨率。但是当显示 640 X 480 等更高分辨率时,glTexSubImage2D 本身需要大约 35 - 40 毫秒,整个显示时间超过每帧 50 毫秒。但我需要 30 fps。

有人可以帮助您提出建议吗?

【问题讨论】:

  • 哪个设备和 Android 版本?你的视频帧有多大? Grafika 中有纹理上传速度测试(github.com/google/grafika);你从中获得了什么价值?
  • @fadden 以上数据来自amazone kindle fire hdx with android 4.2.2。而且我无法运行您的graphika,因为它需要4.3。我在摩托罗拉 moto G 中使用 4.4.2 进行了测试,glTexSubImage2D 每帧耗时超过 50 - 65 毫秒,纹理上传速度测试为 3807 us 每次迭代......
  • sdk 版本 9 支持我的应用
  • @fadden 有没有其他方法可以加快帧显示速度......
  • 上传速度测试使用 512x512 RGBA 纹理。你从中得到的数字是合理的(我在 N5/N10 上得到 1600us)。您是否正在创建二次幂纹理并将帧数据加载到其中? (我想知道 glTexImage2D 是否比 glTexSubImage2D 提供速度优势......但你必须先将帧复制到 POT 缓冲区。)

标签: android opengl-es


【解决方案1】:

glTexSubImage2D() 对于视频帧速率来说太慢了。使用 OpenGL ES 1.1 和本机代码,您可以通过避免这种情况并改用 EGL 图像扩展来更快地将视频帧加载到纹理中。在this article 中使用示例代码进行讨论。

使用 OpenGL ES 2.0,您还可以在着色器代码中执行 YUV 到 RGB 颜色空间的转换,这也是视频性能的主要改进。我之前在 StackOverflow 上发布过这样的示例。

【讨论】:

  • @ClayMontgomery.. 感谢您的重播和详细的文章.. 我正在尝试实现它。但是文章说 GraphicsBuffer 仅适用于 ndk 中没有的框架 api。但我是用本机代码编写的。我该怎么做才能用 ndk 构建它。对不起,如果怀疑是愚蠢的,但我不清楚这一点..
  • 那句话是错误的,我认为来自不同的博客。我的文章中的清单 5 展示了如何将 GraphicBuffer 与本机代码一起使用。
  • @ClayMontgomery。感谢您的回复.. 但是我无法使用 ndk-r9d 构建我的代码。这是说 GraphicBuffer 没有在这个范围内声明。是否需要添加另一个头文件? eglCreateImageKHR 和 glEGLImageTargetTexture2DOES 的相同 cmets....
  • @ClayMontgomery // 将 2D 图像写入 pBitmap 对于您的示例的这一行,我使用了从源帧数组到位图数组的 memcpy。希望那会很好......但我仍然无法构建它......我应该在制作文件中做些什么......
  • 链接的文章是正确的——GraphicBuffer 类不是 NDK 的一部分,也不是公共 API。当新版本的 Android 发布时,任何使用它的代码都可能会中断。头文件可以通过下载AOSP源码获得;访问 developer.android.com。但是,您不能只获取 android.googlesource.com/platform/frameworks/native/+/…,您还需要它的所有依赖项。
猜你喜欢
  • 2013-09-13
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 2015-09-28
  • 1970-01-01
  • 2011-07-07
  • 2011-11-05
相关资源
最近更新 更多