我正在创建一个同时从前后摄像头获取视频的应用程序。两个相机都将图像发送到各自的ImageReader
进行某些处理。我也有一个TextureView
,可以显示来自任何一个用户所需摄像机的预览。
因此,显示预览的摄像机的捕获会话具有两个表面ImageReader
和TextureView
,而另一个摄像机只有ImageReader
。
现在,当用户切换摄像机时,我想从一个TextureView
中删除Surface
的CameraCaptureSession
并添加到其他会话中
有什么方法可以在不关闭会话的情况下从Surface
中删除CameraCaptureSession
?
到目前为止,我的代码(类似于后置摄像头):
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mTextureView.getWidth(), mTextureView.getHeight());
mCaptureRequestBuilderFront = mCameraDeviceFront.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
List<Surface> surfaces = new ArrayList<Surface>();
/* Make Surface out of texture as preview is shown on a Surface */
Surface surface = new Surface(surfaceTexture);
surfaces.add(surface);
mCaptureRequestBuilderFront.addTarget(surface);
/* Make Surface out of ImageReader to get images for processing */
Surface readerSurface = mImageReaderFront.getSurface();
surfaces.add(readerSurface);
mCaptureRequestBuilderFront.addTarget(readerSurface);
/* Create the Capture Session to start getting images from the camera */
mCameraDeviceFront.createCaptureSession(
surfaces
, mSessionCallbackFront
, mBackgroundHandler);
不,这是不可能的。您当然可以停止在请求中定位TextureView,但另一个会话不能在其输出集中包含TextureView,除非没有它重新创建第一个会话。
[如果要使它更平滑,则基本上需要实现自己的缓冲路由-例如,有一个GL舞台,该舞台具有两个输入SurfaceTextures,并渲染到TextureView SurfaceTexture中,然后将每个摄影机连接到SurfaceTexture。然后,编写一个像素着色器,该着色器仅将Surface Texture A或B复制到输出中,具体取决于哪个摄像机处于活动状态。
这是很多样板,但效率很高。
[在最新的Android版本上,您可以尝试使用一对用于相机的ImageReader和用于ImageView的ImageWriter,使用接受使用标记和ImageReader constructor的GPU_SAMPLED_IMAGE。然后将您当前处于活动状态的ImageReader中的Image排队到ImageWriter中的TextureView中。