Camera2:从已创建的 CameraCaptureSession 中删除 Surface
Camera2: Remove Surface from already created CameraCaptureSession
我正在创建一个同时从前置和后置摄像头获取视频的应用程序。两个摄像头都将图像发送到各自的 ImageReader
以进行某些处理。我还有一个 TextureView
来显示来自 任何一个 用户所需相机的预览。
所以显示预览的相机的捕获会话有两个表面 ImageReader
和 TextureView
而另一个相机只有 ImageReader
.
现在,当用户切换相机时 我想从一个 CameraCaptureSession
中删除 TextureView
的 Surface
并添加到另一个会话
有什么方法可以在不关闭会话的情况下从 CameraCaptureSession
中删除 Surface
?
我现在的代码(类似的是后置摄像头):
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,然后将每个相机连接到表面纹理。然后你编写一个像素着色器,它只将表面纹理 A 或 B 复制到输出中,具体取决于哪个相机处于活动状态。
样板文件很多,但效率很高。
在最近的 Android 版本中,您可以使用 ImageReader constructor that accepts a usage flag, with usage flag GPU_SAMPLED_IMAGE 尝试将一对用于相机的 ImageReader 和一个用于 TextureView 的 ImageWriter。然后将图像从您当前激活的 ImageReader 排队到 ImageWriter 到 TextureView。
我正在创建一个同时从前置和后置摄像头获取视频的应用程序。两个摄像头都将图像发送到各自的 ImageReader
以进行某些处理。我还有一个 TextureView
来显示来自 任何一个 用户所需相机的预览。
所以显示预览的相机的捕获会话有两个表面 ImageReader
和 TextureView
而另一个相机只有 ImageReader
.
现在,当用户切换相机时 我想从一个 CameraCaptureSession
中删除 TextureView
的 Surface
并添加到另一个会话
有什么方法可以在不关闭会话的情况下从 CameraCaptureSession
中删除 Surface
?
我现在的代码(类似的是后置摄像头):
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,然后将每个相机连接到表面纹理。然后你编写一个像素着色器,它只将表面纹理 A 或 B 复制到输出中,具体取决于哪个相机处于活动状态。
样板文件很多,但效率很高。
在最近的 Android 版本中,您可以使用 ImageReader constructor that accepts a usage flag, with usage flag GPU_SAMPLED_IMAGE 尝试将一对用于相机的 ImageReader 和一个用于 TextureView 的 ImageWriter。然后将图像从您当前激活的 ImageReader 排队到 ImageWriter 到 TextureView。