是否可以在两个进程之间共享SurfaceTexture,例如Activity和Service?
我想用TextureView创建一个Activity,并从一个单独的Service更新它的SurfaceTexture。
到目前为止,我使用生成的OpenGL纹理(通过glGenTextures)创建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访问此进程。
由于
答案 0 :(得分:6)
系统支持您所需的功能,但我不知道当前的公共API是否可行。
确保我们处于同一页面的一些背景......
Surface是生产者 - 消费者对的生产者。使用SurfaceTexture,应用程序可以访问两端。渲染到SurfaceTexture曲面的任何内容都将转换为OpenGL ES"外部"质地。
媒体和显示API的工作方式是让消费者创建该对,然后将Surface交给应用。这就是为什么,如果你创建一个SurfaceView,你不能使用Surface直到surfaceCreated()
回调触发 - BufferQueue对象是由系统图形合成器(SurfaceFlinger)创建的,并且生产者端被传递通过Binder IPC到您的应用程序。对于MediaCodec编码器的Surface输入也是如此,它由mediaserver
进程创建。
您可以将SurfaceView或SurfaceTexture获得的Surface传递给产生输出的东西,例如Camera preview或MediaCodec解码器。在引擎盖下,这些通过IPC传递到mediaserver
进程。生成帧时,图形缓冲区通过引用传递给使用者。 SurfaceFlinger显示从SurfaceView获取的帧,SurfaceTexture只是将它们转换为纹理。
因此,您要做的是在应用中创建SurfaceTexture,为其构建Surface,并将Surface传递给您的服务。您的服务会生成帧并将它们写入Surface,这会将它们通过IPC发送到您应用中的SurfaceTexture消费者,这会将它们转换为GLES纹理。
我还没有尝试过Surface通过AIDL,所以我不知道它是否真的有效。
在进程之间传递纹理ID不会起作用。如果在创建第二个上下文时将第一个上下文作为参数传递,则可以从两个不同的EGLContex中访问纹理,但我不认为预期会跨进程工作。
有关系统工作方式的更多详细信息,请参阅architecture doc。