如果 SurfaceView 大小不是受支持的大小之一,camera2 将崩溃
camera2 will crash if SurfaceView size is not one of the supported sizes
当使用 SurfaceHolder/SurfaceView 配置 CaptureSession 时,我希望 SurfaceView 可以具有任何布局大小,而我通过 surfaceView.getHolder( ).setFixedSize(preview_width, preview_height).结果应该是传入的预览缓冲区可能会缩小到布局大小。
但是在 camera2 - 硬件级别 LEGACY - 中,配置 CaptureSession 只有在我使用与 streamConfigurationMap.getOutputSizes(SurfaceHolder.class).否则,图片不会缩小,但配置会报错。
/**
* Prerequisites:
* - The device must be opened.
* - The surface view must be ready.
*/
protected void init() {
// ...
try {
CameraCaptureSession.StateCallback cb = new CameraCaptureSession.StateCallback() {
// ...
};
// The following line will result in an error*, if the viewfinder has not the right size:
cameraDevice.createCaptureSession(Arrays.asList(viewfinder.getHolder().getSurface(), imageReaderSmall.getSurface()), cb, null);
}
catch (CameraAccessException e) {
// ...
}
}
来自日志(Samsung Galaxy A3 '14,SDV v21):
05-12 ...: Output sizes for SurfaceHolder.class: [1440x1080, 1280x720, 960x720, 880x720, 960x540, 720x540, 800x480, 720x480, 640x480, 528x432, 352x288, 320x240, 176x144]
...
05-12 ... I/CameraManager: Using legacy camera HAL.
...
05-12 ... I/OpenGLRenderer: Initialized EGL, version 1.4
05-12 ... D/OpenGLRenderer: Get maximum texture size. GL_MAX_TEXTURE_SIZE is 4096
05-12 ... D/OpenGLRenderer: Enabling debug mode 0
05-12 ....CameraActivity: Surface created
05-12 ....CameraActivity: Surface changed 4 540x405
*) 05-12 ... E/CameraDevice-0-LE: Surface with size (w=540, h=405) and format 0x4 is not valid, size not in valid set: [1440x1080, 1280x720, 960x720, 880x720, 960x540, 720x540, 800x480, 720x480, 640x480, 528x432, 352x288, 320x240, 176x144]
05-12 ... W/CameraDevice-JV-0: Stream configuration failed
05-12 ... E/CameraCaptureSession: Session 0: Failed to create capture session; configuration failed
...
05-12 ....CameraActivity: Configure failed!
使用 Nexus 5X,SDK v23,并在 surfaceHolder.setFixedSize()
之后等待 surfaceChanged()
调用,不在支持的输出尺寸列表中的预览尺寸没有错误,但是预览没有开始。来自日志:
05-12 08:47:10.052 ....CameraActivity: Surface created
05-12 08:47:10.053 ....CameraActivity: Surface changed 4 1455x1080
05-12 08:47:10.054 ....CameraActivity: Find preview size for 1455x1080 (1.347424:1) px
05-12 08:47:10.054 ....CameraActivity: Preview size 1600x1200 px
05-12 08:47:10.070 ....CameraActivity: Surface changed 4 1600x1200
05-12 08:47:10.110 ....CameraActivity: Session started
05-12 08:47:10.163 ....CameraActivity: Surface: Surface(name=null)/@0xec338e5
结果:预览没有开始,我可以给surface view一个背景色来演示一下。
如何解决这个问题并仍然使用比使用 SurfaceTexture 性能更高且向后兼容的 SurfaceView。
调用 setFixedSize 后,您需要等待 surfaceChanged() 回调再次触发,然后才能创建相机捕获会话。
setFixedSize 对必要的 SurfaceView 更改进行排队,但不会立即生效。
当使用 SurfaceHolder/SurfaceView 配置 CaptureSession 时,我希望 SurfaceView 可以具有任何布局大小,而我通过 surfaceView.getHolder( ).setFixedSize(preview_width, preview_height).结果应该是传入的预览缓冲区可能会缩小到布局大小。
但是在 camera2 - 硬件级别 LEGACY - 中,配置 CaptureSession 只有在我使用与 streamConfigurationMap.getOutputSizes(SurfaceHolder.class).否则,图片不会缩小,但配置会报错。
/**
* Prerequisites:
* - The device must be opened.
* - The surface view must be ready.
*/
protected void init() {
// ...
try {
CameraCaptureSession.StateCallback cb = new CameraCaptureSession.StateCallback() {
// ...
};
// The following line will result in an error*, if the viewfinder has not the right size:
cameraDevice.createCaptureSession(Arrays.asList(viewfinder.getHolder().getSurface(), imageReaderSmall.getSurface()), cb, null);
}
catch (CameraAccessException e) {
// ...
}
}
来自日志(Samsung Galaxy A3 '14,SDV v21):
05-12 ...: Output sizes for SurfaceHolder.class: [1440x1080, 1280x720, 960x720, 880x720, 960x540, 720x540, 800x480, 720x480, 640x480, 528x432, 352x288, 320x240, 176x144]
...
05-12 ... I/CameraManager: Using legacy camera HAL.
...
05-12 ... I/OpenGLRenderer: Initialized EGL, version 1.4
05-12 ... D/OpenGLRenderer: Get maximum texture size. GL_MAX_TEXTURE_SIZE is 4096
05-12 ... D/OpenGLRenderer: Enabling debug mode 0
05-12 ....CameraActivity: Surface created
05-12 ....CameraActivity: Surface changed 4 540x405
*) 05-12 ... E/CameraDevice-0-LE: Surface with size (w=540, h=405) and format 0x4 is not valid, size not in valid set: [1440x1080, 1280x720, 960x720, 880x720, 960x540, 720x540, 800x480, 720x480, 640x480, 528x432, 352x288, 320x240, 176x144]
05-12 ... W/CameraDevice-JV-0: Stream configuration failed
05-12 ... E/CameraCaptureSession: Session 0: Failed to create capture session; configuration failed
...
05-12 ....CameraActivity: Configure failed!
使用 Nexus 5X,SDK v23,并在 surfaceHolder.setFixedSize()
之后等待 surfaceChanged()
调用,不在支持的输出尺寸列表中的预览尺寸没有错误,但是预览没有开始。来自日志:
05-12 08:47:10.052 ....CameraActivity: Surface created
05-12 08:47:10.053 ....CameraActivity: Surface changed 4 1455x1080
05-12 08:47:10.054 ....CameraActivity: Find preview size for 1455x1080 (1.347424:1) px
05-12 08:47:10.054 ....CameraActivity: Preview size 1600x1200 px
05-12 08:47:10.070 ....CameraActivity: Surface changed 4 1600x1200
05-12 08:47:10.110 ....CameraActivity: Session started
05-12 08:47:10.163 ....CameraActivity: Surface: Surface(name=null)/@0xec338e5
结果:预览没有开始,我可以给surface view一个背景色来演示一下。
如何解决这个问题并仍然使用比使用 SurfaceTexture 性能更高且向后兼容的 SurfaceView。
调用 setFixedSize 后,您需要等待 surfaceChanged() 回调再次触发,然后才能创建相机捕获会话。
setFixedSize 对必要的 SurfaceView 更改进行排队,但不会立即生效。