android - 同步相机预览和处理

标签 android opengl-es

我正在设计一个具有 OpenGL 处理管道(着色器集合)并同时要求最终用户查看未处理相机预览的应用程序。

举个例子,假设您想向用户显示相机预览,同时计算从相机接收到的场景中红色对象的数量,但是您使用任何着色器来计算对象数量,例如色调过滤等不应该被用户看到。

我该如何正确设置它?

我知道我可以设置相机预览,然后在回调中接收 YUV 格式的相机帧数据,然后将其转储到 OpenGL 纹理中并以这种方式处理帧,但是,这会带来性能问题。我必须将数据从相机硬件往返到 VM,然后将其传回 GPU 内存。我正在使用 SurfaceTexture 以 OpenGL 可理解的格式直接从相机获取数据,并将其传递给我的着色器以解决此问题。

我以为我可以向最终用户显示相同的未处理的 SurfaceTexture,但是 TextureView 没有我可以传递它的构造函数或 setter SurfaceTexture 我想让它渲染。它总是创建自己的。

这是我当前设置的概述:

  • GLRenderThread:此类从 Thread 扩展,设置 OpenGL 上下文、显示等,并使用 SurfaceTexture 作为表面(eglCreateWindowSurface 的第三个参数)。
  • GLFilterChain:对输入纹理执行检测的着色器集合。
  • Camera:使用单独的 SurfaceTexture 作为 GLFilterChain 的输入并获取相机的预览
  • 最后是显示 GLRenderThread 的 SurfaceTexture 的 TextureView

显然,通过此设置,我向用户展示了处理后的帧,这不是我想要的。此外,帧的处理不是实时的。基本上,我通过链运行来自 Camera 的输入一次,一旦完成所有过滤器,我调用 updateTexImage从相机中抓取下一帧。我在 Nexus 4 上的处理速度约为每秒 10 帧。

我觉得我可能需要使用 2 个 GL 上下文,一个用于实时预览,一个用于处理,但我不确定。我希望有人能将我推向正确的方向。

最佳答案

你能上传一些你正在使用的代码吗?

您也许可以在为最初用于显示预览的表面 View 创建并绑定(bind)到表面 View 的纹理上调用 glDrawArrays,然后刷新它并将单独的纹理与其他纹理绑定(bind)以进行分析?像

GLES20.glUseProgram(simpleProgram);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

GLES20.glUseProgram(crazyProgram);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[1]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

将相机的预览表面纹理绑定(bind)到纹理[0],然后为纹理[1]创建一个单独的表面纹理

也许吧?

关于android - 同步相机预览和处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18449162/

相关文章:

android - 如何实现 Android Lollipop Curved Motion API?

android - 'Android 预编译器' 错误 'Path must include project and resource name'

java - 切换图例可见性时 TChart 崩溃?

iphone - 加快 iPhone 3G 上的全屏图像绘制

opengl - 是否可以围绕它自己的轴而不是围绕基坐标轴旋转对象?

android - 改变 fragment

android - 在 godot 中按住屏幕触摸

java - OpenGL ES 2.0 翻译(移动对象)

ios - OpenGL ES 3.0 上下文未在 iPad 上创建(在模拟器中工作)

Android OpenGL 视频捕获