Android permite que los dispositivos admitan la transmisión simultánea de dispositivos de cámara. Por ejemplo, esto permite que un dispositivo tenga las cámaras frontal y posterior en funcionamiento al mismo tiempo. A partir de Android 11, la API de Camera2 incluye los siguientes métodos que las apps pueden llamar para determinar si las cámaras admiten transmisiones simultáneas y las configuraciones de transmisión que son compatibles.
getConcurrentCameraIds
: Obtiene el conjunto de combinaciones de identificadores de dispositivos de cámara conectados actualmente que admiten la configuración de sesiones de dispositivos de cámara de forma simultánea.isConcurrentSessionConfigurationSupported
: Verifica si el conjunto proporcionado de dispositivos de cámara y sus configuraciones de sesión correspondientes se pueden configurar de forma simultánea.
En la propiedad SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS
, se incluye un conjunto de combinaciones de transmisión obligatorias que deben admitirse durante la transmisión simultánea a través de las características de la cámara de un dispositivo de cámara.
Cada dispositivo de cámara anunciado a través de getConcurrentStreamingCameraIds()
debe admitir las siguientes configuraciones garantizadas para transmisiones simultáneas.
Objetivo 1 | Objetivo 2 | |||
---|---|---|---|---|
Tipo | Tamaño máximo | Tipo | Tamaño máximo | Ejemplos de casos de uso |
YUV | s1440p | Procesamiento de imágenes o videos en la app | ||
PRIV | s1440p | Análisis del visor integrado en la app | ||
JPEG | s1440p | No se puede capturar imágenes fijas con el visor | ||
YUV / PRIV | s720p | JPEG | s1440p | Imágenes fijas estándar |
YUV / PRIV | s720p | YUV / PRIV | s1440p | Video en la app o procesamiento con vista previa |
Los dispositivos con la capacidad MONOCHROME
(CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
incluye CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
) que admiten Y8 deben admitir la sustitución de transmisiones YUV por Y8 en todas las combinaciones de transmisiones garantizadas.
s720p
hace referencia a 720p (1280 x 720) o a la resolución máxima admitida para el formato específico que devuelve StreamConfigurationMap.getOutputSizes()
.
s1440p
hace referencia a 1440p (1920 x 1440) o a la resolución máxima admitida para el formato específico que devuelve StreamConfigurationMap.getOutputSizes()
.
Los dispositivos cuyas capacidades no incluyen ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
deben admitir al menos una transmisión Y16, Dataspace::DEPTH
con resolución sVGA, durante el funcionamiento simultáneo, donde sVGA es la más pequeña de las dos siguientes resoluciones:
- Resolución máxima de salida para el formato determinado
- 640 × 480
Implementación
Para permitir que las apps consulten un dispositivo y determinen si sus cámaras admiten transmisiones simultáneas, implementa la interfaz de HAL ICameraProvider@2.6
, que incluye los siguientes métodos:
Para obtener una implementación de referencia de la interfaz de ICameraProvider@2.6
HAL, consulta la biblioteca de HAL de cámara emulada en EmulatedCameraProviderHWLImpl.cpp
.
Validación
Para probar que la implementación de esta función funciona según lo previsto, usa la prueba de CTS ConcurrentCameraTest.java
. Además, realiza pruebas con una app que abra varias cámaras y las opere de forma simultánea.
Problemas con la asignación de recursos
Si los HAL de la cámara anuncian la compatibilidad con el funcionamiento simultáneo de los dispositivos de cámara, es posible que tengan problemas de asignación de recursos, especialmente en el caso de que haya suficientes recursos del procesador de señales de imagen (ISP) en el teléfono para transmitir simultáneamente las cámaras frontal y posterior (o de otro tipo), pero no a su capacidad máxima. En este caso, la HAL de la cámara debe asignar recursos de hardware limitados a cada dispositivo de cámara.
Situación de ejemplo
En la siguiente situación, se demuestra este problema.
Problema
El dispositivo tiene la siguiente configuración:
- El ID de cámara
0
es una cámara lógica respaldada por una cámara gran angular y una ultra gran angular, cada una de las cuales toma un recurso del ISP. - El ID de cámara
1
es una cámara que toma un recurso de ISP.
El dispositivo (teléfono) tiene dos ISP. Si se abre el ID de cámara 0
y se configura una sesión, es posible que el HAL de la cámara reserve dos ISP anticipando el uso de la cámara tanto gran angular como ultra gran angular.
En ese caso, la cámara frontal (ID 1
) no puede configurar ninguna transmisión porque ambos ISP están en uso.
Solución
Para solucionar este problema, el framework puede abrir los dos IDs de cámara 0
y 1
antes de configurar las sesiones para proporcionar una sugerencia a la HAL de la cámara sobre cómo asignar recursos (porque ahora espera el funcionamiento simultáneo de las cámaras).
Sin embargo, esto puede limitar las capacidades. Por ejemplo, es posible que el zoom no pueda controlar el rango completo de la relación de zoom (porque cambiar los IDs de las cámaras físicas puede ser problemático).
Para implementar esta solución, realiza las siguientes actualizaciones en provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds
.
Se exige que, para el funcionamiento simultáneo de las cámaras, el framework de la cámara debe abrir los dispositivos de cámara (
@3.2::ICameraDevice::open
) antes de configurar cualquier sesión en los dispositivos de cámara. Esto permite que los proveedores de cámaras asignen recursos según corresponda.Para abordar el problema de no poder controlar la relación de rango de zoom completo, asegúrate de que las apps de cámara, cuando usan cámaras de forma simultánea, tengan garantizado el uso del parámetro de configuración de control
ZOOM_RATIO
solo entre 1x yMAX_DIGITAL_ZOOM
en lugar delZOOM_RATIO_RANGE
completo (esto evita el cambio de cámaras físicas de forma interna, lo que podría requerir más ISP).
Problema con testDualCameraPreview
Cuando realices las actualizaciones anteriores, es posible que se cree un problema con un comportamiento permitido por la prueba MultiViewTest.java#testDualCameraPreview
.
El testDualCameraPreview
de prueba no configura sesiones solo después de abrir todas las cámaras. Sigue esta secuencia:
for each camera in cameraDevices :
device = openCamera(camera)
createCaptureSession(device);
Sin embargo, tolera las fallas de apertura de la cámara con ERROR_MAX_CAMERAS_IN_USE [1]
. Es posible que las apps de terceros dependan de este comportamiento.
Dado que el HAL de la cámara no conocerá el conjunto completo de IDs de cámara que se abren para la operación simultánea antes de configurar las sesiones, podría ser difícil asignar recursos de hardware (suponiendo que haya cierta competencia por ellos).
Para abordar este problema, además de mantener la retrocompatibilidad y admitir la transmisión simultánea, las HAL de la cámara deben fallar las llamadas de openCamera
con ERROR_MAX_CAMERAS_IN_USE
si no pueden admitir la configuración completa de la transmisión para todas las cámaras que se ejecutan de forma simultánea.