Android 11 添加了 API 来查询对同时使用多个摄像头(包括前置摄像头和后置摄像头)的支持。
要在运行应用的设备上检查支持情况,请使用以下方法:
getConcurrentStreamingCameraIds() 可返回摄像头 ID 组合 Set,这些组合可与有保证的数据流组合并发进行流式传输(如果它们是由同一应用进程配置的)。
isConcurrentSessionConfigurationSupported() 可查询摄像头设备是否可以并发支持相应的会话配置。
原文如下:
Android allows devices to support concurrent streaming of camera devices. For example,
this allows a device to have both the front and back cameras operating at the same time.
From Android R, the Camera2 API includes the following methods that apps can call to
determine if the cameras support concurrent streaming and the stream configurations that
are supported.
-
getConcurrentStreamingCameraIds
(https://developer.android.com/reference/android/hardware/camera2/CameraManager?
hl=id#getConcurrentCameraIds())
: Gets the set of combinations of currently connected camera device identifiers that
support configuring camera device sessions concurrently. -
isConcurrentSessionConfigurationSupported
(https://developer.android.com/reference/android/hardware/camera2/CameraManager?
hl=id#isConcurrentSessionConfigurationSupported(java.util.Map%3Cjava.lang.String,%20android.
hardware.camera2.params.SessionConfiguration%3E))
: Checks whether the provided set of camera devices and their corresponding session
configurations can be configured concurrently.
A set of mandatory stream combinations that must be supported during concurrent
streaming are included through a camera device’s camera characteristics in the
SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS
(https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#SCALER
_MANDATORY_CONCURRENT_STREAM_COMBINATIONS)
property.
Each camera device advertised through getConcurrentStreamingCameraIds() must support
the following guaranteed configurations for concurrent streams.
Target 1 | Target 2 | ||
---|---|---|---|
Type | Max size | Type Max size | Sample use cases |
YUV | s1440p | In-app video or image processing | |
PRIV | s1440p | In-app viewfinder analysis | |
JPEG | s1440p | No viewfinder still image capture |
Target 1 | Target 2 | |||
---|---|---|---|---|
Type | Max size | Type | Max size | Sample use cases |
YUV / PRIV | s720p | JPEG | s1440p | Standard still imaging |
YUV / PRIV | s720p | YUV / PRIV | s1440p | In-app video or processing with preview |
Devices with the MONOCHROME capability
(CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
(https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#REQUES
T_AVAILABLE_CAPABILITIES)
includes CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
(https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#REQUEST_AV
AILABLE_CAPABILITIES_MONOCHROME)
) supporting Y8 must support substituting YUV streams with Y8 in all guaranteed stream
combinations.
s720p refers to 720p (1280 x 720) or the maximum supported resolution for the particular
format returned by StreamConfigurationMap.getOutputSizes()
(https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMa
p#getOutputSizes(int))
. s1440p refers to 1440p (1920 x 1440) or the maximum supported resolution for the
particular format returned by StreamConfigurationMap.getOutputSizes()
(https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMa
p#getOutputSizes(int))
. Devices whose capabilities don’t include
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
(https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#REQUEST_AV
AILABLE_CAPABILITIES_BACKWARD_COMPATIBLE)
must support at least a single Y16 stream, Dataspace::DEPTH with sVGA resolution, during
concurrent operation, where sVGA is the smaller of the two following resolutions:
- maximum output resolution for the given format
- 640 x 480
Implementation
To allow apps to query a device to determine if its cameras support concurrent streaming,
implement the ICameraProvider@2.6
(https://partner-android.googlesource.com/platform/hardware/interfaces/+/refs/heads/r-fsrelease/
camera/provider/2.6/ICameraProvider.hal)
HAL interface, which includes the following methods:
- getConcurrentStreamingCameraIds
(https://partner-android.googlesource.com/platform/hardware/interfaces/+/refs/heads/r-fsrelease/
camera/provider/2.6/ICameraProvider.hal#101) - isConcurrentStreamCombinationSupported
(https://partner-android.googlesource.com/platform/hardware/interfaces/+/refs/heads/r-fsrelease/
camera/provider/2.6/ICameraProvider.hal#149)
For a reference implementation of the ICameraProvider@2.6HAL interface, see the
emulated camera HAL library at EmulatedCameraProviderHWLImpl.cpp
(https://partner-android.googlesource.com/platform/hardware/google/camera/+/refs/heads/r-fsrelease/
devices/EmulatedCamera/hwl/EmulatedCameraProviderHWLImpl.cpp#256)
.
Validation
To test that your implementation of this feature works as intended, use the
ConcurrentCameraTest.java
(https://partner-android.googlesource.com/platform/cts/+/refs/heads/r-fsrelease/
tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java)
CTS test. Also, test using an app that opens up multiple cameras and operates them
concurrently.
Resource allocations problems
If camera HALs advertise support for concurrent operation of camera devices, they might
run into resource allocation problems, especially in the case where there are enough image
signal processor (ISP) resources on the phone to stream both front and back (or other)
cameras concurrently, but not to their full capacity. In this case, the camera HAL must
allocate limited hardware resources to each camera device.
Example scenario
The following scenario demonstrates this problem.
Problem
The device has the following configuration:
- Camera ID 0 is a logical camera backed by a wide and ultra-wide camera, which each
take one ISP resource. - Camera ID 1 is a camera which takes one ISP resource.
The device (phone) has two ISPs. If camera ID 0 is opened and a session is configured, it’s
possible that the camera HAL reserves two ISPs anticipating both ultrawide and wide
camera use.
If that’s the case, the front camera (ID 1) can’t configure any streams because both ISPs are
in use.
Solution
To address this problem, the framework can open both camera IDs 0 and 1 before
configuring sessions to provide a hint to the camera HAL about how to allocate resources
(because it now expects concurrent operation of cameras). However, this can lead to
limited capabilities, for example, zoom might not be able to handle the full zoom range ratio
(because switching physical camera IDs might be problematic).
To implement this solution, make the following updates to
provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds.
- Mandate that for concurrent operation of cameras, the camera framework must open
camera devices (@3.2::ICameraDevice::open) before configuring any sessions on the
camera devices. This allows camera providers to allocate resources accordingly. - To address the issue of not being able to handle the full zoom range ratio, ensure that
camera apps, when using cameras concurrently, are guaranteed to use the
ZOOM_RATIO control setting between only 1x and MAX_DIGITAL_ZOOM instead of the
complete ZOOM_RATIO_RANGE (this prevents the switching of physical cameras
internally, which potentially requires more ISPs).
Note: Camera IDs advertised in a combination through getConcurrenStreamingCameraIds must not
conflict. For example if getConcurrentStreamingCameraIds advertises {0,1}, {2,1}, camera IDs 0 and
2 are allowed to conflict, however camera IDs 0 and 1, and 1 and 2 must not conflict.
Problem with testDualCameraPreview
When you make the updates above, it can create a problem with a behavior allowed by the
MultiViewTest.java#testDualCameraPreview test.
The test testDualCameraPreview doesn’t configure sessions only after opening all cameras.
It follows this sequence:
for each camera in cameraDevices:
device = openCamera(camera)
createCaptureSession(device);
It does, however, tolerate camera open failures with ERROR_MAX_CAMERAS_IN_USE [1]. Thirdparty
apps might depend on this behavior.
Because the camera HAL won’t know the complete set of camera IDs being opened for
concurrent operation before configuring sessions, it could be hard for it to allocate
hardware resources (assuming there is some competition for them).
To address this problem, maintaining backward compatibility in addition to supporting
concurrent streaming, camera HALs should fail openCamera calls with
ERROR_MAX_CAMERAS_IN_USE if they can’t support full stream configuration for all cameras
running concurrently.