Extensions de caméra

Les fabricants d'appareils peuvent exposer des extensions telles que le bokeh, le mode nuit et le HDR à des développeurs tiers via l'interface Camera Extensions fournie par la bibliothèque du fournisseur OEM. Les développeurs peuvent utiliser l' API Camera2 Extensions et l' API CameraX Extensions pour accéder aux extensions implémentées dans la bibliothèque du fournisseur OEM.

Pour obtenir la liste des extensions prises en charge, qui est la même pour Camera2 et CameraX, consultez CameraX Extensions API . Si vous souhaitez ajouter une extension, signalez un bug avec Issue Tracker .

Cette page décrit comment implémenter et activer la bibliothèque du fournisseur OEM sur les appareils.

Architecture

Le schéma suivant décrit l'architecture de l'interface Camera Extensions ou extensions-interface : Architecture

Figure 1. Schéma d'architecture des extensions de caméra

Comme le montre le diagramme, pour prendre en charge les extensions de caméra, vous devez implémenter l' extensions-interface fournie par la bibliothèque du fournisseur OEM. Votre bibliothèque de fournisseur OEM active deux API : CameraX Extensions API et Camera2 Extensions API , qui sont utilisées respectivement par les applications CameraX et Camera2 pour accéder aux extensions du fournisseur.

Implémenter la bibliothèque du fournisseur OEM

Pour implémenter la bibliothèque du fournisseur OEM, copiez les fichiers camera-extensions-stub dans un projet de bibliothèque système. Ces fichiers définissent l'interface des extensions de caméra.

Les fichiers camera-extensions-stub sont répartis dans les catégories suivantes :

Fichiers d'interface essentiels (ne pas modifier)

  • PreviewExtenderImpl.java
  • ImageCaptureExtenderImpl.java
  • ExtenderStateListener.java
  • ProcessorImpl.java
  • PreviewImageProcessorImpl.java
  • CaptureProcessorImpl.java
  • CaptureStageImpl.java
  • RequestUpdateProcessorImpl.java
  • ProcessResultImpl.java
  • advanced/AdvancedExtenderImpl.java
  • advanced/Camera2OutputConfigImpl.java
  • advanced/Camera2SessionConfigImpl.java
  • advanced/ImageProcessorImpl.java
  • advanced/ImageReaderOutputConfigImpl.java
  • advanced/ImageReferenceImpl.java
  • advanced/MultiResolutionImageReaderOutputConfigImpl.java
  • advanced/OutputSurfaceImpl.java
  • advanced/RequestProcessorImpl.java
  • advanced/SessionProcessorImpl.java
  • advanced/SurfaceOutputConfigImpl.java

Implémentations obligatoires (ajoutez votre implémentation)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Classes d'extension Bokeh (implémentez-les si l'extension Bokeh est prise en charge)

  • BokehImageCaptureExtenderImpl.java
  • BokehPreviewExtenderImpl.java
  • advanced/BokehAdvancedExtenderImpl.java

Classes d'extension de nuit (implémentez-les si l'extension de nuit est prise en charge)

  • NightImageCaptureExtenderImpl.java
  • NightPreviewExtenderImpl.java
  • advanced/NightAdvancedExtenderImpl.java

Classes d'extension automatique (implémentez-la si l'extension automatique est prise en charge)

  • AutoImageCaptureExtenderImpl.java
  • AutoPreviewExtenderImpl.java
  • advanced/AutoAdvancedExtenderImpl.java

Classes d'extension HDR (implémentez-les si l'extension HDR est prise en charge)

  • HdrImageCaptureExtenderImpl.java
  • HdrPreviewExtenderImpl.java
  • advanced/HdrAdvancedExtenderImpl.java

Classes d'extension Face Retouch (implémentez-les si l'extension Face Retouch est prise en charge)

  • BeautyImageCaptureExtenderImpl.java
  • BeautyPreviewExtenderImpl.java
  • advanced/BeautyAdvancedExtenderImpl.java

Utilitaires (facultatif, peuvent être supprimés)

  • advanced/Camera2OutputConfigImplBuilder.java
  • advanced/Camera2SessionConfigImplBuilder.java

Vous n'êtes pas obligé de fournir une implémentation pour chaque extension. Si vous n'implémentez pas d'extension, définissez isExtensionAvailable() pour renvoyer false ou supprimez les classes Extender correspondantes. Les API des extensions Camera2 et CameraX signalent à l'application que l'extension n'est pas disponible.

Voyons comment les API des extensions Camera2 et CameraX interagissent avec la bibliothèque du fournisseur pour activer une extension. Le diagramme suivant illustre le flux de bout en bout en utilisant l'extension Night comme exemple :

Flux principal

Figure 2. Mise en œuvre de l'extension de nuit

  1. Vérification des versions :

    Camera2/X appelle ExtensionVersionImpl.checkApiVersion() pour garantir que la version extensions-interface implémentée par OEM est compatible avec les versions prises en charge par Camera2/X.

  2. Initialisation de la bibliothèque du fournisseur :

    InitializerImpl possède une méthode init() qui initialise la bibliothèque du fournisseur. Camera2/X termine l'initialisation avant d'accéder aux classes Extender.

  3. Instancier les classes Extender :

    Instancie les classes Extender pour l'extension. Il existe deux types d'extension : l'extension de base et l'extension avancée. Vous devez implémenter un type d'extension pour toutes les extensions. Pour plus d’informations, consultez Basic Extender et Advanced Extender .

    Camera2/X instancie et interagit avec les classes Extender pour récupérer des informations et activer l'extension. Pour une extension donnée, Camera2/X peut instancier les classes Extender plusieurs fois. Par conséquent, n’effectuez pas d’initialisation lourde dans le constructeur ou dans l’appel init() . Faites le gros du travail uniquement lorsque la session de caméra est sur le point de démarrer, par exemple lorsque onInit() est appelé dans Basic Extender ou initSession() est appelé dans Advanced Extender.

    Pour l'extension Night, les classes Extender suivantes sont instanciées pour le type Basic Extender :

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Et pour le type Advanced Extender :

    • NightAdvancedExtenderImpl.java
  4. Vérifiez la disponibilité des extensions :

    Avant d'activer l'extension, isExtensionAvailable() vérifie si l'extension est disponible sur l'ID de caméra spécifié via l'instance Extender.

  5. Initialisez le répéteur avec les informations de la caméra :

    Camera2/X appelle init() sur l'instance Extender et lui transmet l'ID de la caméra et CameraCharacteristics .

  6. Informations sur la requête :

    Appelle la classe Extender pour récupérer des informations telles que les résolutions prises en charge, toujours capturer la latence estimée et capturer les clés de requête de l'Extender en vue de l'activation de l'extension.

  7. Activer l'extension sur le répéteur :

    La classe Extender fournit toutes les interfaces nécessaires pour activer la classe. Il offre un mécanisme pour intégrer l'implémentation OEM dans le pipeline Camera2, comme l'injection de paramètres de demande de capture ou l'activation d'un post-processeur.

    Pour le type Advanced Extender, Camera2/X interagit avec SessionProcessorImpl pour activer l'extension. Camera2/X récupère l'instance SessionProcessorImpl en appelant createSessionProcessor() sur l'Extender.

Les sections suivantes décrivent le flux d’extension plus en détail.

Vérification des versions

Lors du chargement de la bibliothèque du fournisseur OEM à partir de l'appareil au moment de l'exécution, Camera2/X vérifie si la bibliothèque est compatible avec la version extensions-interface . L' extensions-interface utilise le versioning sémantique, ou MAJOR.MINOR.PATCH, par exemple 1.1.0 ou 1.2.0. Cependant, seules les versions majeures et mineures sont utilisées lors de la vérification de version.

Pour vérifier la version, Camera2/X appelle ExtensionVersionImpl.checkApiVersion() avec la version extensions-interface prise en charge. Camera2/X utilise ensuite la version signalée par la bibliothèque OEM pour déterminer si l'extension peut être activée et quelles fonctionnalités elle doit invoquer.

Compatibilité des versions majeures

Si les versions majeures de l' interface d'extension sont différentes entre Camera2/X et la bibliothèque du fournisseur, alors elle est considérée comme incompatible et l'extension est désactivée.

Rétrocompatibilité

Tant que la version majeure est identique, Camera2/X garantit une compatibilité descendante avec les bibliothèques des fournisseurs OEM créées avec les versions extensions-interface précédentes. Par exemple, si Camera2/X prend en charge extensions-interface 1.3.0, les bibliothèques des fournisseurs OEM qui ont implémenté 1.0.0, 1.1.0 et 1.2.0 sont toujours compatibles. Cela signifie également qu'après avoir implémenté une version spécifique de la bibliothèque du fournisseur, Camera2/X s'assure que la bibliothèque est rétrocompatible avec les prochaines versions extension-interface .

Compatibilité ascendante

La compatibilité ascendante avec les bibliothèques des fournisseurs extensions-interface plus récentes dépend de vous, l'OEM. Si vous avez besoin de certaines fonctionnalités pour implémenter les extensions, vous souhaiterez peut-être activer les extensions à partir d'une certaine version. Dans ce cas, vous pouvez renvoyer la version extensions-interface prise en charge lorsque la version de la bibliothèque Camera2/X répond aux exigences. Si les versions Camera2/X ne sont pas prises en charge, vous pouvez renvoyer une version incompatible telle que 99.0.0 pour désactiver les extensions.

Initialisation de la bibliothèque du fournisseur

Après avoir vérifié la version extensions-interface implémentée par la bibliothèque OEM, Camera2/X démarre le processus d'initialisation. La méthode InitializerImpl.init() signale à la bibliothèque OEM qu'une application tente d'utiliser des extensions.

Camera2/X n'effectue aucun autre appel à la bibliothèque OEM (en dehors de la vérification de version) jusqu'à ce que la bibliothèque du fournisseur OEM appelle OnExtensionsInitializedCallback.onSuccess() pour notifier la fin de l'initialisation.

Vous devez implémenter InitializerImpl à partir de extensions-interface 1.1.0. Camera2/X ignore l'étape d'initialisation de la bibliothèque si la bibliothèque du fournisseur OEM implémente extensions-interface 1.0.0.

Extendeur de base versus Extender avancé

Il existe deux types d’implémentation extensions-interface : Basic Extender et Advanced Extender. Advanced Extender est pris en charge depuis extensions-interface 1.2.0.

Implémentez Basic Extender pour les extensions qui traitent les images dans la caméra HAL ou utilisez un post-processeur capable de traiter les flux YUV.

Implémentez Advanced Extender pour les extensions qui doivent personnaliser la configuration du flux Camera2 et envoyer des demandes de capture si nécessaire.

Voir le tableau suivant pour la comparaison :

Extension de base Extension avancée
Configurations de flux Fixé
Aperçu : PRIVATE ou YUV_420_888 (si le processeur existe)
Capture fixe : JPEG ou YUV_420_888 (si le processeur existe)
Personnalisable par OEM.
Envoi d'une demande de capture Seul Camera2/X peut envoyer des demandes de capture. Vous pouvez définir les paramètres de ces requêtes. Lorsque le processeur est fourni pour la capture d'images, Camera2/X peut envoyer plusieurs demandes de capture et envoyer toutes les images et les résultats de capture au processeur. Une instance RequestProcessorImpl vous est fournie pour exécuter la demande de capture camera2 et obtenir les résultats et l'image.

Camera2/X appelle startRepeating et startCapture sur SessionProcessorImpl pour signaler à l'OEM de lancer la demande répétitive de prévisualisation et de démarrer la séquence de capture fixe respectivement.

Crochets dans le pipeline de la caméra
  • onPresetSession fournit des paramètres de session.
  • onEnableSession envoie une seule requête juste après la configuration CameraCaptureSession .
  • onDisableSession envoie une seule requête avant la fermeture CameraCaptureSession .
  • initSession initialise et renvoie une configuration de session camera2 personnalisée pour créer la session de capture.
  • onCaptureSessionStart est invoqué juste après la configuration CameraCaptureSession .
  • onCaptureSessionEnd est invoqué avant la fermeture CameraCaptureSession .
Convient à Extensions implémentées dans la caméra HAL ou dans un processeur qui traite les images YUV.
  • Possède des implémentations basées sur Camera2 pour les extensions.
  • Nécessite une configuration de flux personnalisée telle que le flux RAW.
  • Nécessite une séquence de capture interactive.
Version d'API prise en charge Extensions Camera2 : Android 13 ou supérieur
Extensions CameraX : camera-extensions 1.1.0 ou supérieure
Extensions Camera2 : Android 12L ou supérieur
Extensions CameraX : camera-extensions 1.2.0-alpha03 ou supérieure

Flux d'applications

Le tableau suivant présente trois types de flux d'applications et leurs appels d'API Camera Extensions correspondants. Bien que Camera2/X fournisse ces API, vous devez correctement implémenter la bibliothèque du fournisseur pour prendre en charge ces flux, que nous décrivons plus en détail dans une section ultérieure.

Extensions Caméra2 Extensions CaméraX
Disponibilité des extensions de requête CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Informations sur la requête CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX gère le reste des informations dans la bibliothèque.

Prévisualiser et capturer avec l'extension activée CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle (lifecycleOwner, cameraSelector, aperçu, ...)

Extension de base

L'interface Basic Extender fournit des connexions à plusieurs endroits dans le pipeline de la caméra. Chaque type d'extension possède des classes Extender correspondantes que les OEM doivent implémenter.

Le tableau suivant répertorie les classes d'extension que les OEM doivent implémenter pour chaque extension :

Classes d'extension à implémenter
Nuit NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java HdrImageCaptureExtenderImpl.java
Auto AutoPreviewExtenderImpl.java AutoImageCaptureExtenderImpl.java
Bokeh BokehPreviewExtenderImpl.java BokehImageCaptureExtenderImpl.java
Retouche du visage BeautyPreviewExtenderImpl.java BeautyImageCaptureExtenderImpl.java

Nous utilisons PreviewExtenderImpl et ImageCaptureExtenderImpl comme espaces réservés dans l'exemple suivant. Remplacez-les par les noms des fichiers réels que vous implémentez.

Basic Extender a les capacités suivantes :

  • Injectez les paramètres de session lors de la configuration CameraCaptureSession ( onPresetSession ).
  • Vous avertir des événements de début et de fermeture de la session de capture et envoyer une seule demande pour informer le HAL avec les paramètres renvoyés ( onEnableSession , onDisableSession ).
  • Injectez des paramètres de capture pour la requête ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Ajoutez des processeurs pour l'aperçu et continuez à capturer, capables de traiter le flux YUV_420_888 .

Voyons comment Camera2/X invoque l' extensions-interface pour réaliser les trois flux d'application mentionnés ci-dessus.

Flux d'application 1 : Vérifier la disponibilité des extensions

BasicExtenderAppFlow1

Figure 3. Flux d'application 1 sur Basic Extender

Dans ce flux, Camera2/X appelle directement la méthode isExtensionAvailable() de PreviewExtenderImpl et ImageCaptureExtenderImpl sans appeler init() . Les deux classes Extender doivent renvoyer true pour activer les extensions.

Il s'agit souvent de la première étape permettant aux applications de vérifier si le type d'extension donné est pris en charge pour un ID de caméra donné avant d'activer l'extension. En effet, certaines extensions ne sont prises en charge que sur certains identifiants de caméra.

Flux d'application 2 : interroger des informations

BasicExtenderAppFlow2

Figure 4. Flux d'application 2 sur Basic Extender

Après avoir déterminé si l'extension est disponible, les applications doivent demander les informations suivantes avant d'activer l'extension.

  • Plage de latence de capture toujours : ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange renvoie la plage de latence de capture pour que l'application évalue s'il est approprié d'activer l'extension pour le scénario actuel.

  • Tailles prises en charge pour la surface d'aperçu et de capture : ImageCaptureExtenderImpl.getSupportedResolutions et PreviewExtenderImpl.getSupportedResolutions renvoient une liste de formats d'image et les tailles prises en charge pour le format et la taille de la surface.

  • Clés de demande et de résultat prises en charge : Camera2/X appelle les méthodes suivantes pour récupérer les clés de demande de capture et les clés de résultat prises en charge à partir de votre implémentation :

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X appelle toujours init() en premier sur ces classes Extender avant de demander plus d'informations.

Flux d'application 3 : prévisualiser/capturer avec l'extension activée (implémentation HAL)

BasicExtenderAppFlow3

Figure 5. Flux d'application 3 sur Basic Extender

Le diagramme ci-dessus illustre le flux principal d'activation de la prévisualisation et de la capture avec une extension sans aucun processeur. Cela signifie que la caméra HAL traite l'extension.

Dans ce flux, Camera2/X appelle d'abord init() puis onInit , qui vous informe qu'une session de caméra est sur le point de démarrer avec les extensions spécifiées. Vous pouvez effectuer une initialisation lourde dans onInit() .

Lors de la configuration CameraCaptureSession , Camera2/X appelle onPresetSession pour obtenir les paramètres de session. Une fois la session de capture configurée avec succès, Camera2/X appelle onEnableSession et renvoie une instance CaptureStageImpl contenant les paramètres de capture. Camera2/X envoie immédiatement une seule requête avec ces paramètres de capture pour informer le HAL. De même, avant la fermeture de la session de capture, Camera2/X appelle onDisableSession puis envoie une seule requête avec les paramètres de capture renvoyés.

La requête répétitive déclenchée par Camera2/X contient les paramètres de requête renvoyés par PreviewExtenderImpl.getCaptureStage() . De plus, la demande de capture fixe contient les paramètres renvoyés par ImageCaptureExtenderImpl.getCaptureStages() .

Enfin, Camera2/X appelle onDeInit() une fois la session de caméra terminée. Vous pouvez libérer des ressources dans onDeinit() .

Processeur de prévisualisation

En plus de la caméra HAL, vous pouvez également implémenter des extensions dans un processeur.

Implémentez PreviewExtenderImpl.getProcessorType pour spécifier le type de processeur comme expliqué ci-dessous :

  • PROCESSOR_TYPE_NONE : Aucun processeur. Les images sont traitées dans la caméra HAL.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY : Le type de processeur vous permet de mettre à jour la requête répétitive avec de nouveaux paramètres de requête de capture basés sur le dernier TotalCaptureResult .

    PreviewExtenderImpl.getProcessor doit renvoyer une instance RequestUpdateProcessorImpl qui traite l'instance TotalCaptureResult et renvoie une instance CaptureStageImpl pour mettre à jour la demande répétitive. PreviewExtenderImpl.getCaptureStage() doit également refléter le résultat du traitement et renvoyer le dernier CaptureStageImpl .

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : Ce type vous permet d'implémenter un processeur pour traiter les images YUV_420_888 et écrire la sortie sur une surface PRIVATE .

    Vous devez implémenter et renvoyer une instance PreviewImageProcessorImpl dans PreviewExtenderImpl.getProcessor . Le processeur est responsable du traitement des images d'entrée YUV_420_888 . Il doit écrire la sortie au format PRIVATE d'aperçu. Camera2/X utilise une surface YUV_420_888 au lieu de PRIVATE pour configurer CameraCaptureSession pour l'aperçu.

    Voir l'illustration suivante pour le flux :

AperçuProcesseur

Figure 6. Aperçu du flux avec PreviewImageProcessorImpl

L'interface PreviewImageProcessorImpl étend ProcessImpl et dispose de trois méthodes importantes :

  • onOutputSurface(Surface surface, int imageFormat) définit la surface de sortie du processeur. Pour PreviewImageProcessorImpl , imageFormat est un format de pixel tel que PixelFormat.RGBA_8888 .

  • onResolutionUpdate(Size size) définit la taille de l'image d'entrée.

  • onImageFormatUpdate(int imageFormat) définit le format d'image de l'image d'entrée. Actuellement, il ne peut s'agir que YUV_420_888 .

Processeur de capture d'images

Pour une capture fixe, vous pouvez implémenter un processeur en renvoyant une instance CaptureProcessorImpl à l'aide de ImageCaptureExtenderImpl.getCaptureProcessor . Le processeur est chargé de traiter une liste d'images YUV_420_888 capturées et d'instances TotalCaptureResult et d'écrire la sortie sur une surface YUV_420_888 .

Vous pouvez supposer en toute sécurité que l'aperçu est activé et en cours d'exécution avant d'envoyer la demande de capture fixe.

Voir le flux dans le diagramme ci-dessous :

Processeur de capture

Figure 7. Capturez toujours le flux avec CaptureProcessorImpl

  1. Camera2/X utilise une surface au format YUV_420_888 pour la capture fixe afin de configurer la session de capture. Camera2/X prépare CaptureProcessorImpl en appelant :

    • CaptureProcessorImpl.onImageFormatUpdate() avec YUV_420_888 .
    • CaptureProcessorImpl.onResolutionUpdate() avec la taille de l'image d'entrée.
    • CaptureProcessorImpl.onOutputSurface() avec une surface de sortie YUV_420_888 .
  2. ImageCaptureExtenderImpl.getCaptureStages renvoie une liste de CaptureStageImpl , où chaque élément est mappé à une instance CaptureRequest avec les paramètres de capture envoyés par Camera2/X. Par exemple, s'il renvoie une liste de trois instances CaptureStageImpl , Camera2/X envoie trois demandes de capture avec les paramètres de capture correspondants à l'aide de l'API captureBurst .

  3. Les images reçues et les instances TotalCaptureResult sont regroupées et envoyées à CaptureProcessorImpl pour traitement.

  4. CaptureProcessorImpl écrit l'image résultante (format YUV_420_888 ) sur la surface de sortie spécifiée par l'appel onOutputSurface() . Camera2/X le convertit en images JPEG si nécessaire.

Prise en charge des clés et des résultats des demandes de capture

En plus de l'aperçu et de la capture de l'appareil photo, les applications peuvent définir le zoom, les paramètres du flash ou déclencher une mise au point par pression. Ces paramètres peuvent ne pas être compatibles avec l'implémentation de votre extension.

Les méthodes suivantes ont été ajoutées à extensions-interface 1.3.0 pour vous permettre d'exposer les paramètres pris en charge par votre implémentation :

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() renvoie les clés de demande de capture prises en charge par votre implémentation.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() renvoie les clés de résultat de capture contenues dans le résultat de capture.

Si la caméra HAL traite l'extension, Camera2/X récupère les résultats de capture dans CameraCaptureSession.CaptureCallback . Cependant, si le processeur est implémenté, Camera2/X récupère les résultats de capture dans ProcessResultImpl , qui sont transmis à la méthode process() dans PreviewImageProcessorImpl et CaptureProcessorImpl . Vous êtes responsable de signaler le résultat de la capture via ProcessResultImpl à Camera2/X.

Voir la définition de l'interface CaptureProcessorImpl ci-dessous à titre d'exemple. Dans extensions-interface 1.3.0 ou supérieur, le deuxième appel process() est invoqué :

Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}

Pour les opérations courantes de l'appareil photo telles que le zoom, la mise au point, le flash et la compensation d'exposition, nous vous recommandons de prendre en charge les touches suivantes pour la demande de capture et le résultat de la capture :

  • Zoom:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Appuyez pour faire la mise au point :
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Éclair:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • La compensation d'exposition:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Pour les extensions de base qui implémentent la version 1.2.0 ou des versions antérieures, l'API CameraX Extensions prend explicitement en charge toutes les clés ci-dessus. Pour extensions-interface 1.3.0, CameraX et Camera2 honorent la liste renvoyée et prennent en charge uniquement les clés qu'elle contient. Par exemple, si vous décidez de renvoyer uniquement CaptureRequest#CONTROL_ZOOM_RATIO et CaptureRequest#SCALER_CROP_REGION dans l'implémentation 1.3.0, cela signifie que seul le zoom est pris en charge pour l'application, tandis que la mise au point, le flash et la compensation d'exposition ne sont pas autorisés.

Extension avancée

Advanced Extender est un type d'implémentation de fournisseur basé sur l'API Camera2. Ce type d'extension a été ajouté dans extensions-interface 1.2.0. Selon le fabricant de l'appareil, des extensions peuvent être implémentées dans la couche d'application, ce qui dépend des facteurs suivants :

  • Configuration de flux personnalisé : configurez des flux personnalisés comme le flux RAW ou disposez de plusieurs flux pour différents ID de caméra physique.

  • Possibilité d'envoyer des requêtes Camera2 : prend en charge une logique d'interaction compliquée qui peut envoyer des requêtes de capture avec des paramètres basés sur les résultats des requêtes précédentes.

Advanced Extender fournit un wrapper, ou une couche intermédiaire, afin que vous puissiez personnaliser la configuration du flux et envoyer des demandes de capture à la demande.

Fichiers à implémenter

Pour passer à l’implémentation Advanced Extender, la méthode isAdvancedExtenderImplemented() dans ExtensionVersionImpl doit renvoyer true . Pour chaque type d’extension, les OEM doivent implémenter les classes Extender correspondantes. Les fichiers d'implémentation d'Advanced Extender se trouvent dans le package avancé .

Classes d'extension à implémenter
Nuit advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Auto advanced/AutoAdvancedExtenderImpl.java
Bokeh advanced/BokehAdvancedExtenderImpl.java
Retouche du visage advanced/BeautyAdvancedExtenderImpl.java

Nous utilisons AdvancedExtenderImpl comme espace réservé dans l'exemple suivant. Remplacez-le par le nom du fichier Extender pour l'extension que vous implémentez.

Voyons comment Camera2/X invoque l' extensions-interface pour réaliser les trois flux d'application.

Flux d'application 1 : Vérifier la disponibilité des extensions

AvancéAppFlow1

Figure 8. Flux d'application 1 sur Advanced Extender

Tout d'abord, l'application vérifie si l'extension donnée est prise en charge.

Flux d'application 2 : interroger des informations

AvancéAppFlow2

Figure 9. Flux d'application 2 sur Advanced Extender

Après avoir appelé AdvancedExtenderImpl.init() , l'application peut interroger les informations suivantes sur AdvancedExtenderImpl :

  • Latence de capture estimée : AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() renvoie la plage de latence de capture pour que l'application évalue s'il est approprié d'activer l'extension pour le scénario actuel.

  • Résolutions prises en charge pour l'aperçu et la capture :

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() renvoie une carte du format d'image vers la liste des tailles prises en charge pour le format et la taille de la surface d'aperçu. Les OEM doivent prendre en charge au moins le format PRIVATE .

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() renvoie le format et les tailles pris en charge pour la surface de capture fixe. Les OEM doivent prendre en charge la sortie aux formats JPEG et YUV_420_888 .

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() renvoie les tailles prises en charge pour un flux YUV_420_888 supplémentaire pour l'analyse d'image. Si la surface YUV d'analyse d'image n'est pas prise en charge, getSupportedYuvAnalysisResolutions() doit renvoyer null ou une liste vide.

  • Clés/résultats de demande de capture disponibles (ajoutés dans extensions-interface 1.3.0) : Camera2/X invoque les méthodes suivantes pour récupérer les clés de demande de capture et les clés de résultat prises en charge à partir de votre implémentation :

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Pour plus d’informations, consultez Prise en charge des clés et des résultats des demandes de capture .

Flux d'application 3 : aperçu/capture fixe avec l'extension activée

AvancéAppFlow3

Figure 10. Flux d'application 3 sur Advanced Extender

Le diagramme ci-dessus montre le flux principal pour démarrer l'aperçu et continuer la capture pour le type Advanced Extender. Passons en revue chaque étape.

  1. Instance SessionProcessorImpl

    L'implémentation principale d'Advanced Extender se trouve dans SessionProcessorImpl , qui est chargé de fournir une configuration de session personnalisée et d'envoyer des demandes de capture pour lancer l'aperçu et toujours la demande de capture. AdvancedExtenderImpl.createSessionProcessor() est invoqué pour renvoyer l'instance SessionProcessorImpl .

  2. initSession

    SessionProcessorImpl.initSession() initialise la session pour l'extension. C'est ici que vous allouez des ressources et renvoyez une configuration de session pour préparer une CameraCaptureSession .

    Pour les paramètres d'entrée, Camera2/X spécifie les configurations de surface de sortie pour l'aperçu, la capture d'images fixes et une analyse d'image YUV facultative. Cette configuration de surface de sortie ( OutputSurfaceImpl ) contient la surface, la taille et le format d'image qui sont récupérés par les méthodes suivantes dans AdvancedExtenderImpl :

    • getSupportedPreviewOutputResolutions()
    • getSupportedCaptureOutputResolutions()
    • getSupportedYuvAnalysisResolutions()

    Vous devez renvoyer une instance Camera2SessionConfigImpl , composée d'une liste d'instances Camera2OutputConfigImpl et des paramètres de session utilisés pour configurer CameraCaptureSession . Vous êtes responsable de la sortie des images de caméra correctes sur les surfaces de sortie transmises par Camera2/X. Voici quelques options pour activer la sortie :

    • Traitement dans la caméra HAL : vous pouvez ajouter directement les surfaces de sortie à CameraCaptureSession avec une implémentation SurfaceOutputConfigImpl . Cela configure la surface de sortie fournie au pipeline de la caméra et permet à la caméra HAL de traiter l'image.
    • Traitement de la surface ImageReader intermédiaire (RAW, YUV, etc.) : ajoutez les surfaces ImageReader intermédiaires à CameraCaptureSession avec une instance ImageReaderOutputConfigImpl .

      Vous devez traiter les images intermédiaires et écrire l'image résultante sur la surface de sortie.

    • Utiliser le partage de surface Camera2 : utilisez le partage de surface avec une autre surface en ajoutant n'importe quelle instance Camera2OutputConfigImpl à la méthode getSurfaceSharingOutputConfigs() d'une autre instance Camera2OutputConfigImpl . Le format et la taille de la surface doivent être identiques.

    Tous Camera2OutputConfigImpl , y compris SurfaceOutputConfigImpl et ImageReaderOutputConfigImpl , doivent avoir un ID unique ( getId() ), qui est utilisé pour spécifier la surface cible et récupérer l'image de ImageReaderOutputConfigImpl .

  3. onCaptureSessionStart et RequestProcessorImpl

    Lorsque CameraCaptureSession démarre et que le framework Camera appelle onConfigured() , Camera2/X appelle SessionProcessorImpl.onCaptureSessionStart() avec le wrapper de requête Camera2 RequestProcessImpl . Camera2/X implémente RequestProcessImpl , qui vous permet d' exécuter les demandes de capture et de récupérer des images si ImageReaderOutputConfigImpl est utilisé.

    Les API RequestProcessImpl sont similaires aux API Camera2 CameraCaptureSession en termes d'exécution de requêtes. Les différences sont :

    • La surface cible est spécifiée par l'ID de l'instance Camera2OutputConfigImpl .
    • La capacité de récupérer l’image du ImageReader .

    Vous pouvez appeler RequestProcessorImpl.setImageProcessor() avec un ID Camera2OutputConfigImpl spécifié pour enregistrer une instance ImageProcessorImpl afin de recevoir des images.

    L'instance RequestProcessImpl devient invalide après que Camera2/X appelle SessionProcessorImpl.onCaptureSessionEnd() .

  4. Lancez l'aperçu et prenez une photo

    Dans l'implémentation Advanced Extender, vous pouvez envoyer des demandes de capture via l'interface RequestProcessorImpl . Camera2/X vous informe de démarrer la demande répétitive de prévisualisation ou de séquence de capture fixe en appelant respectivement SessionProcessorImpl#startRepeating et SessionProcessorImpl#startCapture . Vous devez envoyer des demandes de capture pour satisfaire ces demandes de prévisualisation et de capture fixe.

    Camera2/X définit également les paramètres de demande de capture via SessionProcessorImpl#setParameters . Vous devez définir ces paramètres de requête (si les paramètres sont pris en charge) sur les requêtes répétitives et uniques.

    Vous devez prendre en charge au moins CaptureRequest.JPEG_ORIENTATION et CaptureRequest.JPEG_QUALITY . extensions-interface 1.3.0 prend en charge les clés de requête et de résultat, qui sont exposées par les méthodes suivantes :

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys()

    Lorsque les développeurs définissent les clés dans la liste getAvailableCaptureRequestKeys , vous devez activer les paramètres et vous assurer que le résultat de la capture contient les clés dans la liste getAvailableCaptureResultKeys .

  5. startTrigger

    SessionProcessorImpl.startTrigger() est invoqué pour démarrer le déclencheur tel que CaptureRequest.CONTROL_AF_TRIGGER et CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Vous pouvez ignorer toutes les clés de demande de capture qui n'ont pas été annoncées dans AdvancedExtenderImpl.getAvailableCaptureRequestKeys() .

    startTrigger() est pris en charge depuis extensions-interface 1.3.0. Il permet aux applications d'implémenter le tap-to-focus et le flash avec des extensions.

  6. Nettoyer

    À la fin d'une session de capture, SessionProcessorImpl.onCaptureSessionEnd() est invoqué avant la fermeture CameraCaptureSession . Une fois la session de capture fermée, deInitSession() effectue le nettoyage.

Prise en charge de l'aperçu, de la capture d'images fixes et de l'analyse d'images

Vous devez appliquer l'extension à la fois pour les cas d'utilisation d'aperçu et de capture. Toutefois, si la latence est trop élevée pour afficher l'aperçu en douceur, vous pouvez appliquer l'extension uniquement pour la capture d'images fixes.

Pour le type Basic Extender, indépendamment de l’activation de l’extension pour l’aperçu, vous devez implémenter à la fois ImageCaptureExtenderImpl et PreviewExtenderImpl pour une extension donnée. Souvent, une application utilise également un flux YUV pour analyser le contenu de l'image, par exemple pour rechercher des codes QR ou du texte. Pour mieux prendre en charge ce cas d'utilisation, vous devez prendre en charge la combinaison de flux d'aperçu, de capture d'images fixes et un flux YUV_420_888 pour configurer CameraCaptureSession . Cela signifie que si vous implémentez un processeur, vous devez alors prendre en charge la combinaison de trois flux YUV_420_888 .

Pour Advanced Extender, Camera2/X transmet trois surfaces de sortie à l'appel SessionProcessorImpl.initSession() . Ces surfaces de sortie sont respectivement destinées à la prévisualisation, à la capture d'images fixes et à l'analyse d'images. Vous devez vous assurer que les surfaces de sortie d'aperçu et de capture affichent la sortie valide. Cependant, pour la surface de sortie de l’analyse d’image, assurez-vous qu’elle fonctionne uniquement lorsqu’elle n’est pas nulle. Si votre implémentation ne peut pas prendre en charge le flux d'analyse d'image, vous pouvez renvoyer une liste vide dans AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . Cela garantit que la surface de sortie de l'analyse d'image est toujours nulle dans SessionProcessorImpl.initSession() .

Prise en charge de la capture vidéo

L’architecture actuelle de Camera Extension prend en charge uniquement les cas d’utilisation de prévisualisation et de capture. Nous ne prenons pas en charge l'activation de l'extension sur les surfaces MediaCodec ou MediaRecorder pour l'enregistrement de la vidéo. Cependant, il est possible pour les applications d'enregistrer la sortie d'aperçu.

La prise en charge des surfaces MediaCodec et MediaRecorder est à l’étude.

Métadonnées spécifiques à l'extension

Pour Android 14 et versions ultérieures, les métadonnées spécifiques à l'extension permettent aux clients d'extension de caméra de définir et de recevoir les paramètres et les résultats des demandes de capture spécifiques à l'extension. Plus précisément, les clients d'extension de caméra peuvent utiliser le paramètre de demande de capture EXTENSION_STRENGTH pour contrôler la force de l'extension et le résultat de la capture EXTENSION_CURRENT_TYPE pour indiquer le type d'extension activé.

Capturer les demandes

Le paramètre de demande de capture EXTENSION_STRENGTH contrôle la force de l’effet de post-traitement de l’extension. Le résultat de la capture correspondant inclut la valeur de force par défaut si ce paramètre n'est pas défini explicitement par le client. Ce paramètre peut être appliqué comme suit pour ces types d'extension :

  • BOKEH : Contrôle la quantité de flou.
  • HDR et NIGHT : Contrôle la quantité d'images fusionnées et la luminosité de l'image finale.
  • FACE_RETOUCH : Contrôle la quantité d'amélioration cosmétique et de lissage de la peau.

La plage prise en charge pour le paramètre EXTENSION_STRENGTH est comprise entre 0 et 100 , 0 indiquant l'absence de traitement d'extension ou un simple relais et 100 indiquant la force d'extension maximale de l'effet de traitement.

Pour ajouter la prise en charge de EXTENSION_STRENGTH , utilisez les API de paramètres spécifiques au fournisseur introduites dans la version 1.3.0 de l'interface de la bibliothèque d'extensions. Pour plus d'informations, consultez getAvailableCaptureRequestKeys() .

Capturer les résultats

Le résultat de la capture EXTENSION_CURRENT_TYPE permet aux implémentations d'extension d'informer les clients du type d'extension actif.

Étant donné que les extensions utilisant le type AUTO basculent dynamiquement entre les types d'extension tels que HDR et NIGHT en fonction des conditions de la scène, les applications d'extensions de caméra peuvent utiliser EXTENSION_CURRENT_TYPE pour afficher des informations sur l'extension actuelle sélectionnée par l'extension AUTO .

Estimation de la latence de capture en temps réel

Pour Android 14 et versions ultérieures, les clients d'extension de caméra peuvent interroger des estimations de latence de capture en temps réel en fonction des conditions de la scène et de l'environnement à l'aide de getRealtimeStillCaptureLatency() . Cette méthode fournit des estimations plus précises que la méthode statique getEstimatedCaptureLatencyRangeMillis() . Sur la base de l'estimation de la latence, les applications peuvent décider d'ignorer le traitement des extensions ou d'afficher une indication pour informer les utilisateurs d'une opération de longue durée.

CameraExtensionSession.StillCaptureLatency latency;

latency = extensionSession.getRealtimeStillCaptureLatency();

// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().

latency.getCaptureLatency();

// The processing latency from  ExtensionCaptureCallback#onCaptureProcessStarted() until  the processed frame returns to the client.

latency.getProcessingLatency();

Pour prendre en charge les estimations de latence de capture en temps réel, implémentez les éléments suivants :

Capturer les rappels de progression du traitement

Pour Android 14 et versions ultérieures, les clients d’extension de caméra peuvent recevoir des rappels pour la progression des opérations de traitement de capture d’images fixes de longue durée. Les applications peuvent afficher la progression actuelle aux utilisateurs pour améliorer l'expérience utilisateur globale.

Les applications peuvent utiliser le code suivant pour intégrer cette fonctionnalité :

import android.hardware.camera2.CameraExtensionSession.
ExtensionCaptureCallback;

{
…
  class AppCallbackImpl extends ExtensionCaptureCallback {
…
    @Override
    public void onCaptureProcessProgressed(
      @NonNull CameraExtensionSession session,
      @NonNull CaptureRequest request,
      @IntRange(from = 0, to = 100) int progress) {
      // Update app UI with current progress
    }
  }
…
}

Pour prendre en charge les rappels de progression du traitement de capture, l'implémentation de votre fournisseur d'extension doit appeler les rappels suivants avec la valeur de progression actuelle :

Postview toujours capturé

Pour Android 14 et versions ultérieures, les extensions de caméra peuvent fournir une post-vue (image d'aperçu) à l'aide de setPostviewOutputConfiguration . Pour améliorer l'expérience utilisateur, les applications peuvent afficher une image post-vue comme espace réservé lorsqu'une extension connaît une latence de traitement accrue, et remplacer l'image lorsque l'image finale est disponible. Les applications peuvent configurer et émettre des demandes de capture post-vue à l'aide du code de référence suivant :

{
…
if (!CameraExtensionCharacteristics.isPostviewAvailable()) {
    continue;
}
…
ExtensionSessionConfiguration extensionConfiguration = new
        ExtensionSessionConfiguration(
                CameraExtensionCharacteristics.EXTENSION_NIGHT,
                outputConfig,
                backgroundExecutor,
                extensionSessionStateCallback
    );

extensionConfiguration.setPostviewOutputConfiguration(
    postviewImageOutput);
…
CaptureRequest.Builder captureRequestBuilder =
    cameraDevice.createCaptureRequest(
        CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(stillImageReader.getSurface());
captureRequestBuilder.addTarget(postviewImageSurface);

CaptureRequest captureRequest = captureRequestBuilder.build();
…
}

Pour prendre en charge la capture post-vue, l'implémentation de votre fournisseur doit implémenter les éléments suivants :

Prise en charge de la sortie SurfaceView

Pour Android 14 et versions ultérieures, les clients d’extension de caméra peuvent utiliser des chemins de rendu d’aperçu optimisés en termes de puissance et de performances en enregistrant une instance SurfaceView pour la sortie d’aperçu pour les demandes répétées.

Pour prendre en charge la sortie SurfaceView , l’implémentation de votre extension de fournisseur doit être capable de diffuser et de générer un aperçu sur les instances SurfaceView . Pour vérifier que cela est pris en charge, exécutez le module CTS SurfaceViewExtensionPreviewTest.java .

Types de sessions spécifiques au fournisseur

La fonctionnalité permet aux implémentations d'extensions de fournisseur de sélectionner un type de session spécifique au fournisseur qui sera défini dans la session de capture de caméra interne au lieu de la valeur par défaut.

La fonctionnalité fonctionne entièrement dans le cadre et la pile du fournisseur et n'a aucun impact visible sur l'API client/public.

Pour sélectionner un type de session spécifique au fournisseur, implémentez ce qui suit pour vos bibliothèques d'extensions : * ExtenderStateListener.onSessionType() pour les extensions de base * Camera2SessionConfigImpl.getSessionType() pour les extensions avancées

Historique des versions de l'interface des extensions

Le tableau suivant présente l’historique des versions de l’interface Camera Extension. Vous devez toujours implémenter la bibliothèque du fournisseur avec la dernière version.

Version Fonctionnalités ajoutées
1.0.0
  • Vérification des versions
    • ExtensionVersionImpl
  • Extension de base
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Initialisation de la bibliothèque
    • InitializerImpl
  • Exposer les résolutions prises en charge
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • Extension avancée
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Obtenez une latence de capture estimée
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Exposer les clés de demande de capture/clés de résultats prises en charge
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys et getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys et getAvailableCaptureResultKeys
    • Nouvel appel process() qui prend ProcessResultImpl dans PreviewImageProcessorImpl et CaptureProcessorImpl
    • Demande de type de déclencheur de prise en charge
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Métadonnées spécifiques à l'extension
  • Dynamique toujours capturer les estimations de latence
  • Capturer les rappels de progression du traitement
  • Postview toujours capturé
  • Prise en charge de la sortie SurfaceView
  • Types de sessions spécifiques au fournisseur

Implémentation de référence

Les implémentations de bibliothèques de fournisseurs OEM de référence suivantes sont disponibles dans frameworks/ex .

  • advancedSample : Une implémentation de base d’Advanced Extender.

  • sample : une implémentation de base de Basic Extender.

  • service_based_sample : une implémentation qui montre comment héberger des extensions de caméra dans un Service . Cette implémentation contient les composants suivants :

    • oem_library : une bibliothèque OEM d'extensions de caméra pour les API d'extensions Camera2 et CameraX qui implémente Extensions-Interface . Cela agit comme un relais qui transfère les appels d’ Extensions-Interface vers le service. Cette bibliothèque fournit également des fichiers AIDL et des classes wrapper pour communiquer avec le service.

      Advanced Extender est activé par défaut. Pour activer Basic Extender, modifiez ExtensionsVersionImpl#isAdvancedExtenderImplemented pour renvoyer false .

    • extensions_service : un exemple d'implémentation du service d'extensions. Ajoutez votre implémentation ici. L'interface à implémenter dans le service est similaire à Extensions-Interface . Par exemple, l’implémentation de IAdvancedExtenderImpl.Stub effectue les mêmes opérations que AdvancedExtenderImpl . ImageWrapper et TotalCaptureResultWrapper sont requis pour rendre Image et TotalCaptureResult parcellaires.

Configurer la bibliothèque du fournisseur sur un appareil

La bibliothèque du fournisseur OEM n’est pas intégrée à une application ; il est chargé depuis l'appareil au moment de l'exécution par Camera2/X. Dans CameraX, la balise <uses-library> déclare que la bibliothèque androidx.camera.extensions.impl , qui est définie dans le fichier AndroidManifest.xml de la bibliothèque camera-extensions , est une dépendance de CameraX et doit être chargée au moment de l'exécution. Dans Camera2, le framework charge un service d'extensions qui déclare également que <uses-library> charge la même bibliothèque androidx.camera.extensions.impl au moment de l'exécution.

Cela permet aux applications tierces utilisant des extensions de charger automatiquement la bibliothèque du fournisseur OEM. La bibliothèque OEM est marquée comme facultative afin que les applications puissent s'exécuter sur des appareils qui ne disposent pas de la bibliothèque sur l'appareil. Camera2/X gère automatiquement ce comportement lorsqu'une application tente d'utiliser une extension de caméra, à condition que le fabricant de l'appareil place la bibliothèque OEM sur l'appareil afin qu'elle puisse être découverte par l'application.

Pour configurer la bibliothèque OEM sur un appareil, procédez comme suit :

  1. Ajoutez un fichier d'autorisations, requis par la balise <uses-library> , en utilisant le format suivant : /etc/permissions/ ANY_FILENAME .xml . Par exemple, /etc/permissions/camera_extensions.xml . Les fichiers de ce répertoire fournissent un mappage de la bibliothèque nommée dans <uses-library> au chemin de fichier réel sur le périphérique.
  2. Utilisez l'exemple ci-dessous pour ajouter les informations requises au fichier.

    • name doit être androidx.camera.extensions.impl car c'est la bibliothèque recherchée par CameraX.
    • file est le chemin absolu du fichier qui contient l'implémentation des extensions (par exemple, /system/framework/androidx.camera.extensions.impl.jar ).
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="androidx.camera.extensions.impl"
                 file="OEM_IMPLEMENTED_JAR" />
    </permissions>
    

Sous Android 12 ou version ultérieure, la propriété ro.camerax.extensions.enabled doit être définie sur les appareils prenant en charge les extensions CameraX sur true , ce qui permet de demander si un appareil prend en charge les extensions. Pour ce faire, ajoutez la ligne suivante dans le fichier make du périphérique :

PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \

Validation

Pour tester votre implémentation de la bibliothèque du fournisseur OEM pendant la phase de développement, utilisez l'exemple d'application sur androidx-main/camera/integration-tests/extensionstestapp/ , qui s'exécute via diverses extensions du fournisseur.

Une fois votre implémentation terminée, utilisez l' outil de validation des extensions de caméra pour exécuter des tests automatisés et manuels afin de vérifier que la bibliothèque du fournisseur est correctement implémentée.

Mode scène étendu par rapport aux extensions de caméra

Pour l'extension bokeh, en plus de l'exposer à l'aide des extensions de caméra, vous pouvez exposer l'extension à l'aide du mode scène étendu, qui est activé via la touche CONTROL_EXTENDED_SCENE_MODE . Pour plus de détails sur la mise en œuvre, consultez Camera Bokeh .

Le mode scène étendu a moins de restrictions par rapport aux extensions de caméra pour les applications camera2. Par exemple, vous pouvez activer le mode scène étendu dans une instance CameraCaptureSession standard qui prend en charge des combinaisons de flux flexibles et des paramètres de demande de capture. En revanche, les extensions de caméra ne prennent en charge qu'un ensemble fixe de types de flux et ont une prise en charge limitée des paramètres de demande de capture.

L'inconvénient du mode scène étendu est que vous ne pouvez l'implémenter que dans le HAL de la caméra, ce qui signifie qu'il doit être vérifié pour fonctionner sur toutes les commandes orthogonales disponibles pour les développeurs d'applications.

Nous vous recommandons d'exposer le bokeh en utilisant à la fois le mode scène étendu et les extensions de caméra, car les applications peuvent préférer utiliser une API particulière pour activer le bokeh. Nous vous recommandons d'utiliser d'abord le mode scène étendu, car il s'agit du moyen le plus flexible pour les applications d'activer l'extension bokeh. Ensuite, vous pouvez implémenter l'interface des extensions de caméra basée sur le mode scène étendu. Si l'implémentation du bokeh dans la caméra HAL est difficile, par exemple parce qu'elle nécessite un post-processeur exécuté dans la couche application pour traiter les images, nous vous recommandons d'implémenter l'extension bokeh à l'aide de l'interface Camera Extensions.

Foire aux questions (FAQ)

Y a-t-il des restrictions sur les niveaux d'API ?

Oui. Cela dépend de l'ensemble des fonctionnalités de l'API Android requises par l'implémentation de la bibliothèque du fournisseur OEM. Par exemple, ExtenderStateListener.onPresetSession() utilise l'appel SessionConfiguration.setSessionParameters() pour définir un ensemble de balises de base. Cet appel est disponible uniquement au niveau API 28 et supérieur. Pour plus de détails sur les méthodes d'interface spécifiques, consultez la documentation de référence de l'API .