Flux vidéo simultané de la caméra

Android permet aux appareils de prendre en charge le streaming simultané des caméras. 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'appareil photo actuellement connectés qui permettent de configurer simultanément des sessions d'appareil 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 accepter au moins un flux Y16, Dataspace::DEPTH avec une résolution sVGA, lors d'opérations simultanées, où sVGA correspond à 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 inclut les méthodes suivantes:

Pour 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 avec 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

La configuration de l'appareil est la 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) est associé à 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 des sessions afin de fournir des indications au HAL de la caméra sur l'allocation des ressources (car il attend désormais le 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 des 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 testDualCameraPreview de test ne configure pas les sessions uniquement après l'ouverture de tous les appareils photo. 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 d'appareil photo 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, en maintenant la rétrocompatibilité en plus de la prise en charge des flux simultanés, les HAL de caméra doivent échouer aux appels openCamera avec ERROR_MAX_CAMERAS_IN_USE si elles ne peuvent pas être compatibles avec la configuration de flux complet pour toutes les caméras exécutées simultanément.