【发布时间】:2017-08-03 01:08:22
【问题描述】:
我正在尝试了解 Android 中的图形内存使用/流程,特别是关于使用 MediaCodec 从相机编码帧的情况。为了做到这一点,我必须了解一堆我不清楚的图形、OpenGL 和 Android 术语/概念。我已经阅读了 Android 图形架构材料、一堆 SO 问题和一堆来源,但我仍然感到困惑,主要是因为这些术语似乎在不同的上下文中具有不同的含义。
我从fadden 的网站here 上查看了CameraToMpegTest。我的具体问题是MediaCodec::createInputSurface() 如何与Camera::setPreviewTexture() 一起工作。似乎创建了 OpenGL 纹理,然后将其用于创建 Android SurfaceTexture,然后可以将其传递给 setPreviewTexture()。我的具体问题:
- 调用
setPreviewTexture()对帧从相机进入的内存缓冲区有何实际作用? - 据我了解,OpenGL 纹理是一块可由 GPU 访问的内存。在 Android 上,这必须使用带有正确使用标志的 gralloc 进行分配。
SurfaceTexture的 Android 描述提到它允许您“将图像流式传输到给定的 OpenGL 纹理”:https://developer.android.com/reference/android/graphics/SurfaceTexture.html#SurfaceTexture(int)。SurfaceTexture在 OpenGL 纹理之上做了什么? -
MediaCodec::createInputSurface()返回一个 AndroidSurface。据我了解,AndroidSurface代表缓冲区队列的生产者端,因此它可能是多个缓冲区。 API reference 提到“必须使用硬件加速 API 渲染 Surface,例如 OpenGL ES”。相机捕获的帧如何从SurfaceTexture到输入到编码器的Surface?我看到 CameraToMpegTest 以某种方式使用此Surface创建了一个EGLSurface,但对 EGL 了解不多,我不明白这部分。 - 有人可以澄清“渲染”的用法吗?我看到诸如“渲染到表面”、“渲染到屏幕”之类的其他用法似乎可能意味着不同的东西。
编辑:对 mstorsjo 回复的跟进:
- 我深入研究了
CameraService中SurfaceTexture和CameraClient::setPreviewTarget()的代码,以尝试更好地理解Camera::setPreviewTexture()的内部工作原理,并提出更多问题。对于我最初理解内存分配的问题,SurfaceTexture似乎创建了一个BufferQueue和CameraService将关联的IGraphicBufferProducer传递给平台相机HAL 实现。然后,相机 HAL 可以适当地设置 gralloc 使用标志(例如GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_NEVER | GRALLOC_USAGE_HW_TEXTURE),还可以从该BufferQueue中取出缓冲区。所以相机捕捉帧的缓冲区是gralloc分配的缓冲区,带有一些特殊的使用标志,如GRALLOC_USAGE_HW_TEXTURE。我在具有统一内存架构的 ARM 平台上工作,因此 GPU 和 CPU 可以访问相同的内存,那么GRALLOC_USAGE_HW_TEXTURE标志会对缓冲区的分配方式产生什么样的影响? -
SurfaceTexture的 OpenGL (ES) 部分似乎主要作为GLConsumer的一部分实现,而魔法似乎在updateTexImage()中。是否为 OpenGL (ES) 纹理分配了额外的缓冲区,或者是否可以使用由相机填充的同一个 gralloc 缓冲区?此处是否需要进行一些内存复制才能将相机像素数据从 gralloc 缓冲区获取到 OpenGL (ES) 纹理中?我想我不明白调用updateTexImage()的作用。
【问题讨论】:
标签: android opengl-es android-camera android-mediacodec egl