Camera2 在 Android API 29 中用两个物理流替换一个逻辑流
Camera2 replacing one logical stream with two physical streams in Android API 29
当Android9(API28)发布的时候,我很高兴的发现多摄手机的物理摄像头会被曝光,我一直很郁闷没有能够访问它们。今天我偶然发现 android Q documentation 上面写着:
Starting from API level 29, some or all physical cameras may not be independently exposed to the application, in which case the physical camera IDs will not be available in CameraManager.getCameraIdList(). But the application can still query the physical cameras' characteristics by calling CameraManager.getCameraCharacteristics(String).
这个说法让我很疑惑,难道说Android是在回溯?改变的目的是什么?
我有兴趣在非常精细的水平上管理相机,此更改是否会阻止我使用 Android 9 做我今天能做的事情?
上面说ID可以不列出来了,但是特征还是可以查询的,没有ID的相机怎么获取特征呢?我想我们应该通过 getPhysicalCameraIds()
在逻辑相机上获取物理相机的 ID,但这是否意味着如果我们想使用 "hidden" 相机,我们必须测试一堆随机的身份证字符串?
我们是否仍然能够在未曝光的物理相机上使用 SessionConfiguration 创建捕获会话?
有人可以解释一下吗?
这不是回溯。实际上,这种概括是让您更好地控制复杂相机设置的重要一步。
在API29之前,如果制造商不能为构成复合相机的每个镜头提供单独的cameraDevice,他们就无法曝光镜头参数给开发者。他们唯一的选择就是将复合相机整体曝光。
问题不是
And will we still be able to create capture sessions with SessionConfiguration on physical cameras that are not exposed?
而是,
And now we can read the characteristics of physical cameras that could not be exposed before‼
通过新的更改,制造商可以为您提供有关 "Back camera1"、"Back camera2" 等的所有可用信息,即使无法在它们上启动单独的捕获会话。
Prior to API level 29, all returned IDs are guaranteed to be returned by CameraManager.getCameraIdList(), and can be opened directly by CameraManager.openCamera(). Starting from API level 29, for each of the returned ID, if it's also returned by CameraManager.getCameraIdList(), it can be used as a standalone camera by CameraManager.openCamera(). Otherwise, the camera ID can only be used as part of the current logical camera.
这意味着您可以在 CameraManager.getCameraCharacteristics(id):
中使用 getPhysicalCameraIds() 返回的任何 id
From API level 29, this function can also be used to query the capabilities of physical cameras that can only be used as part of logical multi-camera. These cameras cannot not be opened directly via openCamera(String, CameraDevice.StateCallback, Handler).
我尝试使用 Pixel 5 (Android 11) 的第一个逻辑后置摄像头的物理 ID 打开摄像头,但失败并显示错误:未知摄像头 ID.. ..
所以 Pixel 5 returns 只有 2 个逻辑相机 ID,并且只有这 2 个相机可以使用 cameraManager.openCamera(...)
方法打开...
Samsung S10(还有 Android 11)returns 4 个逻辑相机 ID,并且没有所有这些逻辑相机的任何物理相机 ID, 4个摄像头都可以正常使用
Pixel 5 相机信息:
三星S10相机信息:
虽然我没有尝试 Pixel 5 setPhysicalCameraId(cameraId)
https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration.html#setPhysicalCameraId(java.lang.String)
我觉得这个方法可以用来切换不同的物理相机(比如我们可以开广角相机)
更新
是的,我们可以对 Pixel 4、5(我想还有更多设备和制造商)使用 setPhysicalCameraId
方法来设置特定的物理相机
接下来就是逻辑了:
您使用相机管理器使用逻辑相机 ID 打开相机
那么如果逻辑摄像头支持多摄像头功能,那么它应该有非空的物理摄像头 ID 列表
您可以从物理相机ID列表中选择任何ID并将其设置为OutputConfiguration
:
val outputs = surfaces.map {
OutputConfiguration(it).apply {
setPhysicalCameraId(cameraIdx)
}
}
cameraDevice.createCaptureSessionByOutputConfigurations(
outputs,
stateCallback,
backgroundCameraHandler
)
更新! WARNING! 但它预览的是同一个视图,所以这个方法似乎不起作用(虽然没有例外),没有任何改变,无论你是否设置物理相机
似乎从 Android 10 - Android 10 (api 29) camera2 api regression with wide-angle camera
开始就坏了
更新
我还尝试使用 SessionConfiguration
对象而不是弃用的方法 createCaptureSessionByOutputConfigurations
创建捕获会话
val config = SessionConfiguration(
SessionConfiguration.SESSION_REGULAR,
outputs,
backgroundCameraExecutor!!,
stateCallback
)
cameraDevice.createCaptureSession(config)
但还是没有任何改变
当Android9(API28)发布的时候,我很高兴的发现多摄手机的物理摄像头会被曝光,我一直很郁闷没有能够访问它们。今天我偶然发现 android Q documentation 上面写着:
Starting from API level 29, some or all physical cameras may not be independently exposed to the application, in which case the physical camera IDs will not be available in CameraManager.getCameraIdList(). But the application can still query the physical cameras' characteristics by calling CameraManager.getCameraCharacteristics(String).
这个说法让我很疑惑,难道说Android是在回溯?改变的目的是什么?
我有兴趣在非常精细的水平上管理相机,此更改是否会阻止我使用 Android 9 做我今天能做的事情?
上面说ID可以不列出来了,但是特征还是可以查询的,没有ID的相机怎么获取特征呢?我想我们应该通过 getPhysicalCameraIds()
在逻辑相机上获取物理相机的 ID,但这是否意味着如果我们想使用 "hidden" 相机,我们必须测试一堆随机的身份证字符串?
我们是否仍然能够在未曝光的物理相机上使用 SessionConfiguration 创建捕获会话?
有人可以解释一下吗?
这不是回溯。实际上,这种概括是让您更好地控制复杂相机设置的重要一步。
在API29之前,如果制造商不能为构成复合相机的每个镜头提供单独的cameraDevice,他们就无法曝光镜头参数给开发者。他们唯一的选择就是将复合相机整体曝光。
问题不是
And will we still be able to create capture sessions with SessionConfiguration on physical cameras that are not exposed?
而是,
And now we can read the characteristics of physical cameras that could not be exposed before‼
通过新的更改,制造商可以为您提供有关 "Back camera1"、"Back camera2" 等的所有可用信息,即使无法在它们上启动单独的捕获会话。
Prior to API level 29, all returned IDs are guaranteed to be returned by CameraManager.getCameraIdList(), and can be opened directly by CameraManager.openCamera(). Starting from API level 29, for each of the returned ID, if it's also returned by CameraManager.getCameraIdList(), it can be used as a standalone camera by CameraManager.openCamera(). Otherwise, the camera ID can only be used as part of the current logical camera.
这意味着您可以在 CameraManager.getCameraCharacteristics(id):
中使用 getPhysicalCameraIds() 返回的任何 idFrom API level 29, this function can also be used to query the capabilities of physical cameras that can only be used as part of logical multi-camera. These cameras cannot
notbe opened directly via openCamera(String, CameraDevice.StateCallback, Handler).
我尝试使用 Pixel 5 (Android 11) 的第一个逻辑后置摄像头的物理 ID 打开摄像头,但失败并显示错误:未知摄像头 ID.. ..
所以 Pixel 5 returns 只有 2 个逻辑相机 ID,并且只有这 2 个相机可以使用 cameraManager.openCamera(...)
方法打开...
Samsung S10(还有 Android 11)returns 4 个逻辑相机 ID,并且没有所有这些逻辑相机的任何物理相机 ID, 4个摄像头都可以正常使用
Pixel 5 相机信息:
三星S10相机信息:
虽然我没有尝试 Pixel 5 setPhysicalCameraId(cameraId)
https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration.html#setPhysicalCameraId(java.lang.String)
我觉得这个方法可以用来切换不同的物理相机(比如我们可以开广角相机)
更新
是的,我们可以对 Pixel 4、5(我想还有更多设备和制造商)使用 setPhysicalCameraId
方法来设置特定的物理相机
接下来就是逻辑了:
您使用相机管理器使用逻辑相机 ID 打开相机
那么如果逻辑摄像头支持多摄像头功能,那么它应该有非空的物理摄像头 ID 列表
您可以从物理相机ID列表中选择任何ID并将其设置为
OutputConfiguration
:
val outputs = surfaces.map {
OutputConfiguration(it).apply {
setPhysicalCameraId(cameraIdx)
}
}
cameraDevice.createCaptureSessionByOutputConfigurations(
outputs,
stateCallback,
backgroundCameraHandler
)
更新! WARNING! 但它预览的是同一个视图,所以这个方法似乎不起作用(虽然没有例外),没有任何改变,无论你是否设置物理相机
似乎从 Android 10 - Android 10 (api 29) camera2 api regression with wide-angle camera
开始就坏了更新
我还尝试使用 SessionConfiguration
对象而不是弃用的方法 createCaptureSessionByOutputConfigurations
val config = SessionConfiguration(
SessionConfiguration.SESSION_REGULAR,
outputs,
backgroundCameraExecutor!!,
stateCallback
)
cameraDevice.createCaptureSession(config)
但还是没有任何改变