Android 在两个进程之间共享 SurfaceTexture

Android sharing SurfaceTexture between two processes

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

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

到目前为止,我正在创建一个带有生成的 OpenGL 纹理的 SurfaceTexture(通过 glGenTextures),然后我将这个表面纹理设置到我的 TextureView:

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

在 activity 上显示此 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 访问的。

谢谢

系统支持为所欲为,但不知道现在的public是否可以API。

确保我们达成共识的一些背景...

Surface 是生产者-消费者对的生产者端。使用 SurfaceTexture,应用程序可以访问两端。渲染到 SurfaceTexture 的 Surface 的任何内容都将转换为 OpenGL ES "external" 纹理。

媒体和显示 API 的工作方式是让消费者创建配对,然后将 Surface 交给应用程序。这就是为什么,如果你创建一个 SurfaceView,你不能使用 Surface,直到 surfaceCreated() 回调触发——BufferQueue 对象由系统图形合成器(SurfaceFlinger)创建,生产者端通过 Binder 传递IPC 到您的应用程序。由 mediaserver 进程创建的 MediaCodec 编码器的 Surface 输入也是如此。

您可以将从 SurfaceView 或 SurfaceTexture 获得的 Surface 传递给产生输出的东西,例如相机预览或 MediaCodec 解码器。在引擎盖下,这些通过 IPC 将 Surface 传递到 mediaserver 进程。随着帧的产生,图形缓冲区通过引用传递给消费者。 SurfaceFlinger 显示它从 SurfaceView 获取的帧,SurfaceTexture 只是将它们转换为纹理。

所以你想要做的是在应用程序中创建一个 SurfaceTexture,为它构造一个 Surface,然后将该 Surface 传递给你的服务。您的服务会生成帧并将它们写入 Surface,Surface 会通过 IPC 将它们发送给您应用中的 SurfaceTexture 使用者,后者会将它们转换为 GLES 纹理。

我还没有尝试通过 AIDL 传递 Surface,所以我不知道它是否真的有效。

在进程之间传递纹理 ID 将不起作用。如果在创建第二个上下文时将第一个上下文作为参数传递,则可以从两个不同的 EGLContext 访问纹理,但我认为这不会跨进程工作。

有关系统工作方式的更多详细信息,请参阅 architecture doc