Diffusion simultanée de caméras

Android permet aux appareils de prendre en charge le streaming simultané d'appareils photo. Par exemple, cela permet à un appareil de faire fonctionner simultanément les caméras avant et 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 prennent en charge le streaming simultané et les configurations de flux prises en charge.

  • getConcurrentCameraIds : obtient l'ensemble des combinaisons d'identifiants de périphérique de caméra actuellement connectés qui prennent en charge la configuration simultanée des sessions de périphérique de caméra.
  • isConcurrentSessionConfigurationSupported : vérifie si l'ensemble de caméras fourni et leurs 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é sont incluses via les caractéristiques de caméra d'un périphérique de caméra dans la propriété SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS .

Chaque périphérique de caméra annoncé via getConcurrentStreamingCameraIds() doit prendre en charge les configurations garanties suivantes pour les flux simultanés.

Cible 1 Cible 2
Taper taille max Taper taille max Exemples de cas d'utilisation
YUV s1440p Traitement de vidéo ou d'image dans l'application
PRIVÉ s1440p Analyse du viseur dans l'application
JPEG s1440p Pas de capture d'image fixe dans le viseur
YUV/PRIV s720p JPEG s1440p Imagerie standard
YUV/PRIV s720p YUV/PRIV s1440p Vidéo intégrée à l'application ou traitement avec aperçu

Les appareils dotés de la fonctionnalité MONOCHROME ( CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES inclut CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME ) prenant en charge Y8 doivent prendre en charge le remplacement des flux YUV par Y8 dans toutes les combinaisons de flux garanties.

s720p fait référence à 720p (1280 x 720) ou à la résolution maximale prise en charge pour le format particulier renvoyé par StreamConfigurationMap.getOutputSizes() . s1440p fait référence à 1440p (1920 x 1440) 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 seul flux Y16, Dataspace::DEPTH avec une résolution sVGA, pendant 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

Mise en œuvre

Pour permettre aux applications d'interroger un appareil afin de déterminer si ses caméras prennent en charge le streaming simultané, implémentez l'interface ICameraProvider@2.6 HAL, 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 caméra émulée sur EmulatedCameraProviderHWLImpl.cpp .

Validation

Pour tester que votre implémentation de cette fonctionnalité fonctionne comme prévu, utilisez le test ConcurrentCameraTest.java CTS. Testez également en utilisant une application qui ouvre plusieurs caméras et les fait fonctionner simultanément.

Problèmes d'allocation des ressources

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

Exemple de scénario

Le scénario suivant illustre ce problème.

Problème

L'appareil a la configuration suivante :

  • La caméra ID 0 est une caméra logique soutenue par une caméra large et ultra-large, qui utilisent chacune une ressource FAI.
  • L'ID de caméra 1 est une caméra qui utilise une ressource FAI.

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 la caméra HAL réserve deux FAI anticipant l'utilisation de la caméra ultra-large et large.

Si tel est le cas, la caméra frontale (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 pour fournir une indication au HAL de la caméra sur la façon d'allouer les ressources (car il s'attend désormais à un fonctionnement simultané des caméras). Cependant, cela peut conduire à des capacités limitées, par exemple, le zoom peut ne pas être en mesure de gérer la totalité du rapport de plage de zoom (car le changement d'ID de caméra physique peut être problématique).

Pour implémenter cette solution, effectuez les mises à jour suivantes sur provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds .

  • Exigez que pour le fonctionnement simultané des caméras, la structure de la caméra doit ouvrir les périphériques de caméra ( @3.2::ICameraDevice::open ) avant de configurer des sessions sur les périphériques de caméra. Cela permet aux fournisseurs de caméras d'allouer des ressources en conséquence.

  • Pour résoudre le problème de l'impossibilité de gérer le rapport de plage de zoom complet, assurez-vous que les applications d'appareil photo, lorsqu'elles utilisent des appareils photo simultanément, sont garanties d'utiliser le paramètre de contrôle ZOOM_RATIO entre seulement 1x et MAX_DIGITAL_ZOOM au lieu du ZOOM_RATIO_RANGE complet (cela empêche le changement de caméras physiques en interne, ce qui nécessite potentiellement davantage de FAI).

Problème avec testDualCameraPreview

Lorsque vous effectuez les mises à jour ci-dessus, cela peut créer un problème avec un comportement autorisé par le test MultiViewTest.java#testDualCameraPreview .

Le test testDualCameraPreview ne configure pas les sessions uniquement après avoir ouvert toutes les caméras. Il suit cette séquence :

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

Il tolère cependant les échecs d'ouverture de caméra avec ERROR_MAX_CAMERAS_IN_USE [1] . Les applications tierces peuvent dépendre de ce comportement.

Étant donné que le HAL de la caméra ne connaît pas l'ensemble complet des identifiants de caméra ouverts pour un fonctionnement simultané avant de configurer les sessions, il pourrait être difficile pour lui d'allouer des ressources matérielles (en supposant qu'il y ait une certaine concurrence pour eux).

Pour résoudre ce problème, en maintenant la compatibilité descendante et en prenant en charge le streaming simultané, les HAL de caméra doivent échouer aux appels openCamera avec ERROR_MAX_CAMERAS_IN_USE s'ils ne peuvent pas prendre en charge la configuration de flux complet pour toutes les caméras exécutées simultanément.