Android 允许设备支持相机设备的并发流。例如,这允许设备同时运行前置和后置摄像头。从 Android 11 开始,Camera2 API 包括以下方法,应用可以调用这些方法来确定相机是否支持并发流以及支持的流配置。
-
getConcurrentStreamingCameraIds
:获取当前连接的支持同时配置相机设备会话的相机设备标识符的组合集。 -
isConcurrentSessionConfigurationSupported
:检查提供的一组相机设备及其相应的会话配置是否可以同时配置。
通过相机设备的相机特性在SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS
属性中包含一组必须在并发流式传输期间支持的强制流组合。
每个通过getConcurrentStreamingCameraIds()
通告的相机设备必须支持以下保证的并发流配置。
目标 1 | 目标 2 | |||
---|---|---|---|---|
类型 | 最大尺寸 | 类型 | 最大尺寸 | 示例用例 |
YUV | s1440p | 应用内视频或图像处理 | ||
私人信息 | s1440p | 应用内取景器分析 | ||
JPEG | s1440p | 无取景器静止图像捕捉 | ||
YUV / PRIV | s720p | JPEG | s1440p | 标准静止成像 |
YUV / PRIV | s720p | YUV / PRIV | s1440p | 应用内视频或预览处理 |
具有支持 Y8 的MONOCHROME
功能( CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
包括CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
)的设备必须支持在所有保证的流组合中用 Y8 替换 YUV 流。
s720p
是指 720p (1280 x 720) 或StreamConfigurationMap.getOutputSizes()
返回的特定格式的最大支持分辨率。 s1440p
指的是 1440p (1920 x 1440) 或StreamConfigurationMap.getOutputSizes()
返回的特定格式的最大支持分辨率。功能不包括ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
的设备在并发操作期间必须支持至少一个 Y16 流、Dataspace Dataspace::DEPTH
和 sVGA 分辨率,其中 sVGA 是以下两个分辨率中的较小者:
- 给定格式的最大输出分辨率
- 640 x 480
执行
要让应用程序查询设备以确定其摄像头是否支持并发流,请实现ICameraProvider@2.6
HAL 接口,该接口包括以下方法:
有关ICameraProvider@2.6
HAL 接口的参考实现,请参阅 EmulatedCameraProviderHWLImpl.cpp 中的模拟相机EmulatedCameraProviderHWLImpl.cpp
库。
验证
要测试此功能的实现是否按预期工作,请使用ConcurrentCameraTest.java
CTS 测试。此外,使用可打开多个摄像头并同时操作它们的应用程序进行测试。
资源分配问题
如果摄像头 HAL 宣传支持摄像头设备的并发操作,它们可能会遇到资源分配问题,尤其是在手机上有足够的图像信号处理器 (ISP) 资源可以同时流式传输前后(或其他)摄像头的情况下,但不是全力以赴。在这种情况下,相机 HAL 必须为每个相机设备分配有限的硬件资源。
示例场景
下面的场景演示了这个问题。
问题
该设备具有以下配置:
- 摄像头 ID
0
是一个逻辑摄像头,由一个广角和超广角摄像头支持,每个摄像头占用一个 ISP 资源。 - 摄像机 ID
1
是一台占用一个 ISP 资源的摄像机。
该设备(电话)有两个 ISP。如果摄像头 ID 0
已打开并配置了会话,则摄像头 HAL 可能会保留两个 ISP,以预测超宽和宽摄像头的使用。
如果是这种情况,前置摄像头 (ID 1
) 无法配置任何流,因为两个 ISP 都在使用中。
解决方案
为了解决这个问题,框架可以在配置会话之前打开相机 ID 0
和1
,以向相机 HAL 提供有关如何分配资源的提示(因为它现在需要相机的并发操作)。但是,这可能会导致功能受限,例如,缩放可能无法处理完整的缩放范围比(因为切换物理相机 ID 可能会出现问题)。
要实施此解决方案,请对provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds
进行以下更新。
强制要求相机的并发操作,相机框架必须在相机设备上配置任何会话之前打开相机设备(
@3.2::ICameraDevice::open
)。这允许相机提供商相应地分配资源。为了解决无法处理全变焦范围比例的问题,请确保相机应用程序在同时使用相机时,保证使用仅 1x 和
MAX_DIGITAL_ZOOM
之间的ZOOM_RATIO
控制设置,而不是完整的ZOOM_RATIO_RANGE
(这可以防止切换内部的物理相机,这可能需要更多的 ISP)。
testDualCameraPreview 的问题
当您进行上述更新时,可能会导致MultiViewTest.java#testDualCameraPreview
测试允许的行为出现问题。
测试testDualCameraPreview
仅在打开所有相机后才配置会话。它遵循以下顺序:
for each camera in cameraDevices :
device = openCamera(camera)
createCaptureSession(device);
但是,它确实可以容忍带有ERROR_MAX_CAMERAS_IN_USE [1]
的相机打开失败。第三方应用程序可能取决于此行为。
由于相机 HAL 在配置会话之前不知道为并发操作打开的完整相机 ID 集,因此它可能很难分配硬件资源(假设它们存在一些竞争)。
为了解决这个问题,除了支持并发流式传输之外,还要保持向后兼容性,如果相机 HAL 不能支持同时运行的所有相机的完整流式配置,相机 HAL 应该使用ERROR_MAX_CAMERAS_IN_USE
openCamera
调用失败。