我正在尝试理解Android中与使用MediaCodec从相机编码帧有关的图形内存使用/流,并需要了解一些我不清楚的图形、OpenGL和Android术语/概念。为此,我已阅读了Android图形架构材料、大量SO问题和大量源代码,但仍感到困惑,主要是因为似乎在不同的上下文中术语具有不同的含义。
我查看了fadden网站上的CameraToMpegTest(链接)。我的具体问题是
我查看了fadden网站上的CameraToMpegTest(链接)。我的具体问题是
MediaCodec :: createInputSurface()
如何与Camera :: setPreviewTexture()
配合使用。似乎会创建一个OpenGL纹理,然后使用它来创建一个Android SurfaceTexture
,然后可以将其传递给 setPreviewTexture()
。我的具体问题:
- 调用
setPreviewTexture()
实际上是针对相机帧所在的哪个内存缓冲区进行的? - 据我所知,OpenGL纹理是GPU可访问的一块内存。在Android上,这必须使用正确的使用标志使用gralloc进行分配。 Android对
SurfaceTexture
的描述提到它允许您“将图像流式传输到给定的OpenGL纹理”:(链接)。SurfaceTexture
在OpenGL纹理之上有什么作用? MediaCodec :: createInputSurface()
返回一个AndroidSurface
。据我所知,AndroidSurface
表示缓冲区队列的生产者端,因此可能是多个缓冲区。 API参考 提到“表面必须使用硬件加速的API(例如OpenGL ES)进行渲染”。相机捕获的帧如何从SurfaceTexture
到输入到编码器的Surface
?我看到CameraToMpegTest以某种方式使用这个Surface
创建了一个EGLSurface
,但由于不了解EGL,我不明白这一部分。- 有人可以澄清“render”的用法吗?我看到诸如“渲染到表面”,“渲染到屏幕”等用法,似乎可能意味着不同的事情。
编辑:对mstorsjo的回复进行后续处理:
- 我深入研究了
Camera::setPreviewTexture()
中SurfaceTexture
和CameraService
中的CameraClient::setPreviewTarget()
代码,试图更好地理解其内部工作,并产生了一些问题。对于我的最初问题,即理解内存分配,似乎是SurfaceTexture
创建了一个BufferQueue
,而CameraService
将相关的IGraphicBufferProducer
传递给平台相机HAL实现。相机HAL随后可以适当地设置gralloc使用标志(例如,GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_NEVER | GRALLOC_USAGE_HW_TEXTURE
),并从此BufferQueue
出队缓冲区。因此,相机捕获帧的缓冲区是带有某些特殊使用标志(如GRALLOC_USAGE_HW_TEXTURE
)的gralloc分配缓冲区。我在ARM平台上工作,其具有统一的内存体系结构,因此GPU和CPU可以访问相同的内存,那么GRALLOC_USAGE_HW_TEXTURE
标志会对缓冲区分配产生什么影响? SurfaceTexture
的OpenGL(ES)部分似乎主要是作为GLConsumer
的一部分实现的,其中的魔法似乎在updateTexImage()
中。是否会为OpenGL(ES)纹理分配额外的缓冲区,还是可以使用由相机填充的相同gralloc缓冲区?这里是否需要进行一些内存复制以将相机像素数据从gralloc缓冲区复制到OpenGL(ES)纹理中?我猜想我不理解调用updateTexImage()
的作用。
updateTexImage()
中,我期望它交换这些缓冲区。但这只是我从用户角度的印象和假设,我不知道实际实现情况。 - mstorsjo