Camera2在Android API中用两个物理流替换了一个逻辑流29

时间:2019-04-30 14:48:34

标签: android android-camera2

当发布Android 9(API 28)时,我很高兴发现带有多个摄像头的手机的物理摄像头会暴露出来,我为无法访问它们而感到非常沮丧。今天我偶然发现了Android Q documentation,上面写着:

  

从API级别29开始,某些或所有物理相机可能不会独立地暴露给应用程序,在这种情况下,CameraManager.getCameraIdList()中将不提供物理相机ID。但是应用程序仍然可以通过调用CameraManager.getCameraCharacteristics(String)来查询物理相机的特征。

此声明使我感到困惑,是否意味着Android正在回溯?变更的目的是什么?

我有兴趣在非常精细的水平上管理相机,这种变化是否会阻止我使用Android 9进行今天的工作?

它说可能不再列出ID,但是仍然可以查询其特征,我们应该如何在没有ID的情况下获取摄像机的特征?我猜我们应该通过逻辑相机上的getPhysicalCameraIds()获取物理相机的ID,但这是否意味着如果我们想使用“隐藏”相机,就必须测试一堆随机ID字符串?

enter image description here

我们还能在未曝光的物理相机上使用SessionConfiguration创建捕获会话吗?

有人可以阐明这一点吗?

2 个答案:

答案 0 :(得分:2)

我尝试使用 Pixel 5 (Android 11) 的第一个逻辑后置摄像头的物理 ID 打开摄像头,但失败并显示错误:未知摄像头 ID....

因此 Pixel 5 仅返回 2 个逻辑相机 ID,并且只能使用 cameraManager.openCamera(...) 方法打开这 2 个相机...

Samsung S10(也是 Android 11)返回 4 个逻辑摄像头 id,并且所有这些逻辑摄像头都没有任何物理摄像头 id,所有 4 个摄像头都可以毫无问题地使用。

Pixel 5 相机信息:

enter image description here

Samsung S10 相机信息:

enter image description here

虽然我没有尝试 Pixel 5 setPhysicalCameraId(cameraId) https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration.html#setPhysicalCameraId(java.lang.String)

我觉得这个方法可以用来切换不同的物理相机(比如我们可以打开广角相机)

更新

是的,我们可以在 Pixel 4、5(我猜还有更多设备和制造商)上使用 setPhysicalCameraId 方法来设置特定的物理相机

接下来是逻辑:

  1. 您使用相机管理器使用逻辑相机 ID 打开相机

  2. 那么如果该逻辑相机支持多相机功能,那么它应该具有非空的物理相机 ID 列表

  3. 您可以从物理相机 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)

但仍然没有任何改变

答案 1 :(得分:1)

这不是回溯。实际上,这种概括是向您更好地控制复杂相机设置的重要步骤。

在API 29之前,如果制造商无法为构成复合相机的每个镜头提供单独的 cameraDevice ,则他们无法将镜头参数公开给开发者。他们唯一的选择是将复合相机整体曝光。

问题不是

  

我们还能在未曝光的物理相机上使用SessionConfiguration创建捕获会话吗?

但是,

  

现在我们可以读取之前无法曝光的物理相机的特征!

有了新的更改,制造商可以为您提供“后置摄像头1”,“后置摄像头2”等所有可用信息,即使没有办法在它们上开始单独的捕获会话。

getPhysicalCameraIds()参考说明:

  

在API级别29之前,保证所有返回的ID均由CameraManager.getCameraIdList()返回,并且可以由CameraManager.openCamera()直接打开。从API级别29开始,对于返回的每个ID,如果CameraManager.getCameraIdList()也返回了ID,则CameraManager.openCamera()可以将其用作独立的摄像头。否则,摄像机ID只能用作当前逻辑摄像机的一部分。

这意味着您可以使用getPhysicalCameraIds()CameraManager.getCameraCharacteristics(id)中返回的任何ID:

  

从API级别29开始,此功能还可用于查询只能用作逻辑多机的一部分的物理机的功能。无法通过openCamera(String, CameraDevice.StateCallback, Handler)直接打开这些相机。

相关问题