Android两个进程之间共享SurfaceTexture

7

是否可以在两个进程之间共享SurfaceTexture,例如一个Activity和一个Service?

我想创建一个带有TextureView的Activity,并从单独的Service中更新其SurfaceTexture。

到目前为止,我正在使用生成的OpenGL纹理(通过glGenTextures)创建SurfaceTexture,然后将此SurfaceTexture设置为我的TextureView:

mSurfaceTexture = new SurfaceTexture(texture_id);
mTextureView.setSurfaceTexture(mSurfaceTexture);

将相机预览显示在活动中的此SurfaceTexture上正常工作:

mCamera = Camera.open();
mCamera.setPreviewTexture(mTextureView.getSurfaceTexture());
mCamera.startPreview();

我想要做类似的事情,但是从另一个服务传递texture_id,大致如下:

mCamera = Camera.open();
mCamera.setPreviewTexture(new SurfaceTexture(texture_id));
mCamera.startPreview();

原因是我有一个单独的进程调用私有API,需要SurfaceTexture来流传一些内容,而这个进程通过aidl从应用程序访问。

谢谢

1个回答

8

该系统支持您想要的操作,但我不确定是否可以使用当前的公共API实现。

为了确保我们在同一个页面上......

Surface是生产者-消费者对中的生产者端。通过SurfaceTexture,应用程序可以访问两端。渲染到SurfaceTexture的Surface的任何内容都会转换为OpenGL ES“外部”纹理。

媒体和显示API的工作方式是由使用者创建一对并将Surface交给应用程序。这就是为什么如果您创建了SurfaceView,则无法在surfaceCreated()回调触发之前使用Surface -- BufferQueue对象由系统图形合成器(SurfaceFlinger)创建,并且生产者端通过Binder IPC传递到您的应用程序。对于输入到MediaCodec编码器的Surface也是如此,它们由mediaserver进程创建。

您可以将从SurfaceView或SurfaceTexture获得的Surface传递给生成输出的某些内容,例如相机预览或MediaCodec解码器。在幕后,这些通过IPC将Surface传递到mediaserver进程。当生成帧时,图形缓冲区会被引用传递给消费者。SurfaceFlinger显示从SurfaceView获取的帧,而SurfaceTexture仅将其转换为纹理。
因此,您需要在应用程序中创建一个SurfaceTexture,为其构建一个Surface,并将该Surface传递给您的服务。您的服务将生成帧并将其写入Surface,该Surface将通过IPC发送到您的应用程序中的SurfaceTexture消费者,该消费者将其转换为GLES纹理。
我没有尝试通过AIDL传递Surface,所以我不知道它是否实际可行。
在进程之间传递纹理ID是行不通的。如果在创建第二个EGLContext时将第一个上下文作为参数传递,则可以从两个不同的EGLContext访问纹理,但我认为这不应跨进程工作。
有关系统工作方式的更多详细信息可以在架构文档中找到。

很酷,谢谢解释。我确实在想着使用 Surface View 是唯一的选择,你证实了这一点。 - Philippe Goncalves

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接