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 delantera y trasera funcionando al mismo tiempo. A partir de Android 11, la API 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 compatibles.

  • getConcurrentStreamingCameraIds : obtiene el conjunto de combinaciones de identificadores de dispositivos de cámara actualmente conectados que admiten la configuración de sesiones de dispositivos de cámara simultáneamente.
  • isConcurrentSessionConfigurationSupported : comprueba si el conjunto proporcionado de dispositivos de cámara y sus configuraciones de sesión correspondientes se pueden configurar simultáneamente.

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 en la propiedad SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS .

Cada dispositivo de cámara anunciado a través getConcurrentStreamingCameraIds() debe admitir las siguientes configuraciones garantizadas para transmisiones simultáneas.

objetivo 1 Objetivo 2
Escribe tamaño máximo Escribe tamaño máximo Ejemplos de casos de uso
YUV s1440p Procesamiento de imágenes o videos en la aplicación
PRIV s1440p Análisis del visor en la aplicación
jpeg s1440p Captura de imágenes fijas sin visor
YUV / PRIV s720p jpeg s1440p Imágenes fijas estándar
YUV / PRIV s720p YUV / PRIV s1440p Procesamiento o video en la aplicación con vista previa

Los dispositivos con capacidad MONOCHROME ( CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES incluye CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME ) compatibles con Y8 deben admitir la sustitución de transmisiones YUV por Y8 en todas las combinaciones de transmisión 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 transmisión Y16, Dataspace::DEPTH con resolución sVGA, durante el funcionamiento simultáneo, donde sVGA es la menor de las dos resoluciones siguientes:

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

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 ver una implementación de referencia de la interfaz HAL de ICameraProvider@2.6 , consulte la biblioteca HAL de la cámara emulada en EmulatedCameraProviderHWLImpl.cpp .

Validación

Para probar que su implementación de esta función funciona según lo previsto, utilice la prueba CTS ConcurrentCameraTest.java . Además, pruebe con una aplicación que abra varias cámaras y las opere al mismo tiempo.

Problemas de asignación de recursos

Si las HAL de cámara anuncian soporte para el funcionamiento simultáneo de dispositivos de cámara, es posible que se encuentren con 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 delantera 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 escenario siguiente muestra este problema.

Problema

El dispositivo tiene la siguiente configuración:

  • Camera ID 0 es una cámara lógica respaldada por una cámara ancha y ultra ancha, cada una de las cuales toma un recurso ISP.
  • Camera ID 1 es una cámara que toma un recurso ISP.

El dispositivo (teléfono) tiene dos ISP. Si se abre la ID de cámara 0 y se configura una sesión, es posible que la HAL de la cámara reserve dos ISP anticipando el uso de cámaras ultra anchas y anchas.

Si ese es el caso, la cámara frontal (ID 1 ) no puede configurar ningún flujo porque ambos ISP están en uso.

Solución

Para abordar este problema, el marco puede abrir las ID de cámara 0 y 1 antes de configurar las sesiones para proporcionar una pista 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 conducir a capacidades limitadas, por ejemplo, es posible que el zoom no pueda manejar la relación de rango de zoom completa (porque cambiar las ID de cámara física puede ser problemático).

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

  • Ordene que para el funcionamiento simultáneo de las 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 abordar el problema de no poder manejar la relación de rango de zoom completo, asegúrese de que las aplicaciones de la cámara, al usar cámaras simultáneamente, estén garantizadas para usar 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 internamente, 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 cámara con ERROR_MAX_CAMERAS_IN_USE [1] . Las aplicaciones de terceros pueden depender de este comportamiento.

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

Para abordar este problema, mantener la compatibilidad con versiones anteriores además de admitir la transmisión simultánea, las HAL de cámara deberían fallar en las llamadas de 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.