Transmisión simultánea de la cámara

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 a los que las apps pueden llamar para determinar si las cámaras admiten transmisiones simultáneas y las configuraciones de transmisión 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.

Un conjunto de combinaciones de transmisiones obligatorias que se deben admitir durante la transmisión simultánea se incluye 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 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 integrado en la app o procesamiento con vista previa

Los dispositivos con la función 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 × 720) o a la resolución máxima compatible para el formato particular que muestra StreamConfigurationMap.getOutputSizes(). s1440p hace referencia a 1440p (1920 x 1440) o a la resolución máxima compatible para el formato específico que muestra StreamConfigurationMap.getOutputSizes(). Los dispositivos cuyas capacidades no incluyen ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE deben admitir al menos una sola transmisión Y16, Dataspace::DEPTH con resolución sVGA, durante el funcionamiento simultáneo, donde sVGA es la más pequeña de las siguientes resoluciones:

  • la 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 la transmisión simultánea, implementa la interfaz de HAL de ICameraProvider@2.6, que incluye los siguientes métodos:

Para obtener una implementación de referencia de la interfaz de HAL de ICameraProvider@2.6, consulta la biblioteca de HAL de la cámara emulada en EmulatedCameraProviderHWLImpl.cpp.

Validación

Para probar que la implementación de esta función funcione según lo previsto, usa la prueba de CTS de ConcurrentCameraTest.java. Además, prueba con una app que abra varias cámaras y las opere de forma simultánea.

Problemas con las asignaciones de recursos

Si los HAL de la cámara anuncian compatibilidad con el funcionamiento simultáneo de los dispositivos de cámara, es posible que se produzcan problemas de asignación de recursos, en especial, si hay suficientes recursos de procesador de señal de imagen (ISP) en el teléfono para transmitir cámaras frontal y posterior (o alguna otra) de forma simultánea, pero no a su máxima capacidad. En este caso, el HAL de la cámara debe asignar recursos de hardware limitados a cada dispositivo de cámara.

Situación de ejemplo

En el siguiente escenario, se muestra 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 ultra gran angular, que toman un recurso de ISP cada una.
  • El ID de la 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 la 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 ultraancha y ancha.

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 abordar este problema, el framework puede abrir los IDs de cámara 0 y 1 antes de configurar sesiones para proporcionar una sugerencia al HAL de la cámara sobre cómo asignar recursos (ya que ahora espera el funcionamiento simultáneo de las cámaras). Sin embargo, esto puede generar capacidades limitadas, por ejemplo, es posible que el zoom no pueda controlar la relación completa del rango de zoom (porque cambiar los IDs de la cámara física puede ser problemático).

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

  • Establece 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 completa, asegúrate de que las apps de cámara, cuando usen cámaras de forma simultánea, usen el parámetro de configuración de control ZOOM_RATIO entre solo 1x y MAX_DIGITAL_ZOOM en lugar de ZOOM_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 realizas las actualizaciones anteriores, se 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]. Es posible que las apps de terceros dependan de este comportamiento.

Como el HAL de la cámara no conocerá el conjunto completo de IDs de cámara que se abrirán 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 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 de forma simultánea.