Flux vidéo simultané de la caméra

Android permet aux appareils de prendre en charge le streaming simultané des appareils photo. Par exemple, cela permet à un appareil d'utiliser simultanément la caméra avant et la caméra arrière. À partir d'Android 11, l'API Camera2 inclut les méthodes suivantes que les applications peuvent appeler pour déterminer si les caméras sont compatibles avec la diffusion simultanée et les configurations de flux compatibles.

  • getConcurrentCameraIds : obtient l'ensemble des combinaisons d'identifiants d'appareils photo actuellement connectés qui permettent de configurer simultanément des sessions d'appareils photo.
  • isConcurrentSessionConfigurationSupported : vérifie si l'ensemble d'appareils photo fourni et les configurations de session correspondantes peuvent être configurés simultanément.

Un ensemble de combinaisons de flux obligatoires qui doivent être prises en charge lors du streaming simultané est inclus dans les caractéristiques de la caméra de l'appareil photo dans la propriété SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS.

Chaque appareil photo annoncé via getConcurrentStreamingCameraIds() doit prendre en charge les configurations garanties suivantes pour les flux simultanés.

Cible 1 Cible 2
Type Taille maximale Type Taille maximale Exemples de cas d'utilisation
YUV s1440p Traitement des vidéos ou des images dans l'application
PRIV s1440p Analyse du viseur dans l'application
JPEG s1440p Impossible de prendre une photo avec l'appareil photo
YUV / PRIV s720p JPEG s1440p Imagerie fixe standard
YUV / PRIV s720p YUV / PRIV s1440p Vidéo dans l'application ou traitement avec aperçu

Les appareils compatibles avec la fonctionnalité MONOCHROME (CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES inclut CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) et Y8 doivent permettre de remplacer les flux YUV par Y8 dans toutes les combinaisons de flux garanties.

s720p fait référence à 720p (1 280 x 720) ou à la résolution maximale prise en charge pour le format particulier renvoyé par StreamConfigurationMap.getOutputSizes(). s1440p fait référence à 1440p (1 920 x 1 440) ou à la résolution maximale prise en charge pour le format particulier renvoyé par StreamConfigurationMap.getOutputSizes(). Les appareils dont les fonctionnalités n'incluent pas ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE doivent prendre en charge au moins un flux Y16, Dataspace::DEPTH avec une résolution sVGA, lors d'un fonctionnement simultané, où sVGA est la plus petite des deux résolutions suivantes:

  • résolution de sortie maximale pour le format donné
  • 640 x 480

Implémentation

Pour permettre aux applications d'interroger un appareil afin de déterminer si ses caméras sont compatibles avec le streaming simultané, implémentez l'interface HAL ICameraProvider@2.6, qui comprend les méthodes suivantes:

Pour obtenir une implémentation de référence de l'interface HAL ICameraProvider@2.6, consultez la bibliothèque HAL de l'appareil photo émulé à l'adresse EmulatedCameraProviderHWLImpl.cpp.

Validation

Pour vérifier que votre implémentation de cette fonctionnalité fonctionne comme prévu, utilisez le test CTS ConcurrentCameraTest.java. Testez également à l'aide d'une application qui ouvre plusieurs caméras et les fait fonctionner simultanément.

Problèmes d'allocation de ressources

Si les HAL de l'appareil photo annoncent la prise en charge du fonctionnement simultané des appareils photo, ils peuvent rencontrer des problèmes d'allocation de ressources, en particulier s'il existe suffisamment de ressources de processeur de signal d'image (ISP) sur le téléphone pour diffuser simultanément les caméras avant et arrière (ou d'autres), mais pas à leur pleine capacité. Dans ce cas, le HAL de la caméra doit allouer des ressources matérielles limitées à chaque appareil photo.

Exemple de scénario

Le scénario suivant illustre ce problème.

Problème

L'appareil présente la configuration suivante:

  • L'ID de l'appareil photo 0 est un appareil photo logique soutenu par un appareil photo grand angle et un appareil photo ultra grand angle, qui utilisent chacun une ressource ISP.
  • L'ID de caméra 1 est une caméra qui utilise une ressource ISP.

L'appareil (téléphone) dispose de deux FAI. Si l'ID de caméra 0 est ouvert et qu'une session est configurée, il est possible que le HAL de la caméra réserve deux ISP en anticipant l'utilisation des caméras ultra grand angle et grand angle.

Dans ce cas, la caméra avant (ID 1) ne peut configurer aucun flux, car les deux FAI sont utilisés.

Solution

Pour résoudre ce problème, le framework peut ouvrir les ID de caméra 0 et 1 avant de configurer les sessions afin d'indiquer au HAL de la caméra comment allouer des ressources (car il s'attend désormais à un fonctionnement simultané des caméras). Toutefois, cela peut entraîner des fonctionnalités limitées. Par exemple, le zoom risque de ne pas pouvoir gérer la plage de zoom complète (car le changement d'ID de caméra physique peut s'avérer problématique).

Pour mettre en œuvre cette solution, apportez les modifications suivantes à provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds.

  • Exiger que, pour le fonctionnement simultané des caméras, le framework de caméra doit ouvrir les appareils photo (@3.2::ICameraDevice::open) avant de configurer des sessions sur les appareils photo. Cela permet aux fournisseurs d'appareils photo d'allouer les ressources en conséquence.

  • Pour résoudre le problème d'impossibilité de gérer le rapport de la plage de zoom complète, assurez-vous que les applications d'appareil photo, lorsqu'elles utilisent des appareils photo simultanément, utilisent le paramètre de commande ZOOM_RATIO entre 1x et MAX_DIGITAL_ZOOM uniquement au lieu de ZOOM_RATIO_RANGE complet (cela empêche le basculement des caméras physiques en interne, ce qui nécessite potentiellement plus d'ISP).

Problème avec testDualCameraPreview

Lorsque vous effectuez les modifications ci-dessus, un problème peut se produire avec un comportement autorisé par le test MultiViewTest.java#testDualCameraPreview.

Le test testDualCameraPreview ne configure pas les sessions qu'après l'ouverture de toutes les caméras. Il suit la séquence suivante:

for each camera  in cameraDevices :
  device = openCamera(camera)
     createCaptureSession(device);

Il tolère toutefois les échecs d'ouverture de l'appareil photo avec ERROR_MAX_CAMERAS_IN_USE [1]. Les applications tierces peuvent dépendre de ce comportement.

Étant donné que le HAL de l'appareil photo ne connaît pas l'ensemble complet des ID de caméra ouverts pour une opération simultanée avant de configurer les sessions, il peut être difficile pour lui d'allouer des ressources matérielles (en supposant qu'il y ait une certaine concurrence).

Pour résoudre ce problème, tout en conservant la rétrocompatibilité et en prenant en charge le streaming simultané, les HAL de l'appareil photo doivent échouer les appels openCamera avec ERROR_MAX_CAMERAS_IN_USE s'ils ne sont pas compatibles avec la configuration complète du flux pour toutes les caméras exécutées simultanément.