【问题标题】:Android camera surfaceTexture - How to preserve previous frames?Android相机表面纹理 - 如何保留以前的帧?
【发布时间】:2014-01-12 21:36:34
【问题描述】:

我正在使用 SurfaceTexture 进行实时相机预览。这会将数据流作为纹理直接发送到 GPU。

每个新的相机帧都会覆盖此纹理。

现在 - 我想避免这种覆盖并在内存中保留最后几个 (n) 帧(这是我的最终目标)

来自相机的数据总是会覆盖 n 个可用纹理中最旧的纹理。我只需要在它们之间交替。

当数据进入时,这些纹理需要立即渲染。

我不需要:将捕获的数据保存为字节缓冲区并将其转换回新纹理 = 慢,所有这些都必须是实时的。性能是这里的关键。

我已经使用这个程序示例在surfaceTexture模式下运行相机:http://maninara.blogspot.co.uk/2012/09/render-camera-preview-using-opengl-es.html

我尝试使用 SurfaceTexture 类的 attachToGLContext(int texName) 方法附加一个新纹理,但它似乎不允许我在不破坏前一个的情况下这样做,似乎我必须在附加之前使用“detachFromGLContext()”一个新的..

http://developer.android.com/reference/android/graphics/SurfaceTexture.html

任何帮助表示赞赏。

【问题讨论】:

    标签: android opengl-es camera textures


    【解决方案1】:

    如何将数据流发送到纹理?

    就我而言,我在onSurfaceCreated 中创建了多个纹理。然后在onDraw 中覆盖它们。整个过程是实时的,不需要framebuffer来存储数据。

    onDraw 中,我使用glActiveTextureglBindTexture 选择要覆盖的纹理。 这是代码,希望对您有所帮助。

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + texture_index); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, m_texture[texture_index]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, m_frame.width, m_frame.height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, camera_data);

    【讨论】:

    • 实时纹理由 .updateTexImage() 提供。所以总结一下?: 1. onDraw:使用 glGenTextures 为要保存的纹理保留空闲插槽。 2. 来自相机预览的流以纹理的形式出现,而不是作为图像数据(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,hTex[0 ])。因此,我将使用 glGetTexImage 来获取对图像数据的引用(你称之为“camera_data”),使用:glGetTexImage(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0, format, type, camera_data)) 3. 按照你的步骤。它看起来对吗?下一帧不会覆盖我们刚刚保存的纹理吗?
    • 现在对我来说重要的是区分这里发生了什么?:假设一张图像的数据是 3MB。当相机提供预览纹理时,它每帧仅将 3MB 移动到 GPU 并渲染:(相机捕获 -> 移动 3MB -> GPU 渲染)。当我们进行所有这些帧保留时,我们是否: 移动对 3MB 数据的引用? (这正是我想要的) 像这样:(相机队长 -> 移动 3MB -> GPU 撕裂。-> 获取 3MB 的参考并保留)或者我们是否不止一次移动实际的 3MB?像这样:(相机捕捉 -> 移动 3MB -> GPU 撕裂。 -> 再次移动 3MB 到 tex)谢谢
    • 1.是的,使用 glGenTextures 为要保存的纹理预留空闲插槽。 2. 我以前没有使用过 glGetTexImage,我认为你的方式是对的。 3. 使用 glActiveTexture 和 glBindTexture 选择您要覆盖的插槽。因此,您可以保留不想覆盖的插槽。 4.我认为(移动3MB -> 获取纹理)的过程发生在您调用glGetTexImage时,因此如果在同一帧上不再调用glGetTexImage,则每帧移动3MB。
    • 从四处搜索,看起来 glGetTexImage 和 glTexImage2D 复制了所有图像数据(移动了 3MB)。请给我一些时间来试验这些,因为我还不是很精通opengl。我将测试这些,如果该方法不会过多地降低性能,那将是适合我的选项,因此我会接受您的回答,否则我可能会寻找其他选项如何指向 3MB 数据而不是移动它.感谢您的帮助。
    • 您建议的方法的问题是我必须以某种方式从凸轮中提取字节缓冲区数据。在我创建另一个纹理之前,glTexImage2d 需要它作为输入。我发现 glGetTexImage 不是由 GLES20 指定的,所以从 tex 中提取缓冲区的唯一选项。正在使用 glReadPixels,然后使用 glteximage2d 创建新纹理,但这是双倍的工作。
    猜你喜欢
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    相关资源
    最近更新 更多