Streaming de cámara concurrente

Android permite que los dispositivos admitan la transmisión simultánea de dispositivos con cámara. Por ejemplo, esto permite que un dispositivo tenga las cámaras frontal y trasera funcionando al mismo tiempo. Desde Android 11, la API de Camera2 incluye los siguientes métodos a los que las aplicaciones pueden llamar para determinar si las cámaras admiten la transmisión simultánea 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 : comprueba si el conjunto de dispositivos de cámara proporcionado y sus configuraciones de sesión correspondientes se pueden configurar simultáneamente.

Un conjunto de combinaciones de transmisiones obligatorias que deben admitirse durante la transmisión simultánea se incluyen a través de las características de la cámara de un dispositivo de cámara en la propiedad SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS .

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 Casos de uso de muestra
YUV s1440p Procesamiento de imágenes o vídeos en la aplicación
PRIV s1440p Análisis del visor en la aplicación
JPEG s1440p Sin captura de imágenes fijas en el visor
YUV / PRIV s720p JPEG s1440p Imágenes fijas estándar
YUV / PRIV s720p YUV / PRIV s1440p Vídeo en la aplicación o procesamiento con vista previa

Los dispositivos con capacidad MONOCHROME ( CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES incluye CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME ) que admiten Y8 deben admitir la sustitución de transmisiones YUV con Y8 en todas las combinaciones de transmisiones garantizadas.

s720p se refiere a 720p (1280 x 720) o la resolución máxima admitida para el formato particular devuelto por StreamConfigurationMap.getOutputSizes() . s1440p se refiere a 1440p (1920 x 1440) o la resolución máxima admitida para el formato particular devuelto por StreamConfigurationMap.getOutputSizes() . Los dispositivos cuyas capacidades no incluyen ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE deben admitir al menos una única secuencia Y16, Dataspace::DEPTH con resolución sVGA, durante la operación simultánea, donde sVGA es la menor de las dos resoluciones siguientes:

  • resolución de salida máxima para el formato dado
  • 640 x 480

Implementación

Para permitir que las aplicaciones consulten un dispositivo para determinar si sus cámaras admiten transmisión simultánea, implemente la interfaz HAL ICameraProvider@2.6 , que incluye los siguientes métodos:

Para obtener una implementación de referencia de la interfaz HAL ICameraProvider@2.6 , consulte la biblioteca 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, utilice la prueba CTS ConcurrentCameraTest.java . Además, pruebe el uso de una aplicación que abra varias cámaras y las opere simultáneamente.

Problemas de asignación de recursos

Si los HAL de cámara anuncian soporte para el funcionamiento simultáneo de dispositivos de cámara, podrían tener problemas de asignación de recursos, especialmente en el caso de que haya suficientes recursos de procesador de señal de imagen (ISP) en el teléfono para transmitir simultáneamente las cámaras frontal y trasera (u otras). , pero no a su máxima capacidad. En este caso, la cámara HAL debe asignar recursos de hardware limitados a cada dispositivo de cámara.

Escenario de ejemplo

El siguiente escenario demuestra este problema.

Problema

El dispositivo tiene la siguiente configuración:

  • Camera ID 0 es una cámara lógica respaldada por una cámara gran angular y una cámara ultra gran angular, cada una de las cuales requiere un recurso ISP.
  • La ID de cámara 1 es una cámara que requiere 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 la cámara HAL reserve dos ISP que anticipen el uso de la cámara ultraancha y gran angular.

Si ese es el 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 marco puede abrir los ID de cámara 0 y 1 antes de configurar las sesiones para proporcionar una pista a la cámara HAL sobre cómo asignar recursos (porque ahora espera el funcionamiento simultáneo de las cámaras). Sin embargo, esto puede llevar a capacidades limitadas, por ejemplo, es posible que el zoom no pueda manejar la relación de rango de zoom completo (porque cambiar las ID de las cámaras físicas puede ser problemático).

Para implementar esta solución, realice las siguientes actualizaciones en provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds .

  • Exija que para el funcionamiento simultáneo de cámaras, el marco de la cámara debe abrir los dispositivos de la cámara ( @3.2::ICameraDevice::open ) antes de configurar cualquier sesión en los dispositivos de la cámara. Esto permite a los proveedores de cámaras asignar recursos en consecuencia.

  • Para solucionar el problema de no poder manejar la relación de rango de zoom completo, asegúrese de que las aplicaciones de la cámara, cuando utilicen cámaras simultáneamente, utilicen la configuración de control ZOOM_RATIO entre solo 1x y MAX_DIGITAL_ZOOM en lugar del ZOOM_RATIO_RANGE completo (esto evita el cambio de cámaras físicas internas, lo que potencialmente requiere más ISP).

Problema con testDualCameraPreview

Cuando realiza las actualizaciones anteriores, puede crear un problema con un comportamiento permitido por la prueba MultiViewTest.java#testDualCameraPreview .

La prueba testDualCameraPreview 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 fallas de apertura de la cámara con ERROR_MAX_CAMERAS_IN_USE [1] . Las aplicaciones de terceros pueden depender de este comportamiento.

Debido a que la cámara HAL no conocerá el conjunto completo de ID de cámara que se abren para operación simultánea antes de configurar las sesiones, podría resultarle difícil asignar recursos de hardware (suponiendo que exista competencia para ellos).

Para solucionar este problema, manteniendo la compatibilidad con versiones anteriores además de admitir la transmisión simultánea, las HAL de las cámaras deberían fallar en las llamadas openCamera con ERROR_MAX_CAMERAS_IN_USE si no pueden admitir la configuración de transmisión completa para todas las cámaras que se ejecutan simultáneamente.