Estensioni della fotocamera

I produttori di dispositivi possono esporre estensioni come bokeh, modalità notturna e HDR a sviluppatori di terze parti tramite l'interfaccia Camera Extensions fornita dalla libreria del fornitore OEM. Gli sviluppatori possono utilizzare l' API Camera2 Extensions e l' API CameraX Extensions per accedere alle estensioni implementate nella libreria del fornitore OEM.

Per un elenco delle estensioni supportate, che è lo stesso per Camera2 e CameraX, consulta API delle estensioni CameraX . Se desideri aggiungere un'estensione, segnala un bug con Issue Tracker .

Questa pagina descrive come implementare e abilitare la libreria del fornitore OEM sui dispositivi.

Architettura

Il diagramma seguente descrive l'architettura dell'interfaccia Camera Extensions o extensions-interface : Architettura

Figura 1. Diagramma dell'architettura delle estensioni della fotocamera

Come mostrato nel diagramma, per supportare le estensioni della fotocamera, è necessario implementare l' extensions-interface fornita dalla libreria del fornitore OEM. La libreria del fornitore OEM abilita due API: CameraX Extensions API e Camera2 Extensions API , utilizzate rispettivamente dalle app CameraX e Camera2 per accedere alle estensioni del fornitore.

Implementare la libreria del fornitore OEM

Per implementare la libreria del fornitore OEM, copiare i file camera-extensions-stub in un progetto di libreria di sistema. Questi file definiscono l'interfaccia delle estensioni della fotocamera.

I file camera-extensions-stub sono suddivisi nelle seguenti categorie:

File di interfaccia essenziali (non modificare)

  • 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

Implementazioni obbligatorie (aggiungi la tua implementazione)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Classi di estensione Bokeh (implementala se l'estensione Bokeh è supportata)

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

Classi di estensione notturna (implementala se l'estensione notturna è supportata)

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

Classi di estensione automatica (implementala se l'estensione automatica è supportata)

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

Classi di estensione HDR (implementalo se l'estensione HDR è supportata)

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

Classi di estensione Face Retouch (implementalo se l'estensione Face Retouch è supportata)

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

Utilità (opzionali, cancellabili)

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

Non è necessario fornire un'implementazione per ogni estensione. Se non implementi un'estensione, imposta isExtensionAvailable() per restituire false o rimuovere le classi Extender corrispondenti. Le API delle estensioni Camera2 e CameraX segnalano all'app che l'estensione non è disponibile.

Esaminiamo il modo in cui le API Camera2 e CameraX Extensions interagiscono con la libreria del fornitore per abilitare un'estensione. Il diagramma seguente illustra il flusso end-to-end utilizzando l'estensione Notte come esempio:

Flusso principale

Figura 2. Implementazione dell'estensione notturna

  1. Verifica della versione:

    Camera2/X chiama ExtensionVersionImpl.checkApiVersion() per garantire che la versione extensions-interface implementata dall'OEM sia compatibile con le versioni supportate da Camera2/X.

  2. Inizializzazione della libreria del fornitore:

    InitializerImpl ha un metodo init() che inizializza la libreria del fornitore. Camera2/X completa l'inizializzazione prima di accedere alle classi Extender.

  3. Istanziare le classi Extender:

    Crea un'istanza delle classi Extender per l'estensione. Esistono due tipi di extender: Extender di base e Extender avanzato. È necessario implementare un tipo di Extender per tutte le estensioni. Per ulteriori informazioni, consulta Basic Extender e Advanced Extender .

    Camera2/X istanzia e interagisce con le classi Extender per recuperare informazioni e abilitare l'estensione. Per una determinata estensione, Camera2/X può istanziare più volte le classi Extender. Di conseguenza, non eseguire un'inizializzazione pesante nel costruttore o nella chiamata init() . Eseguire il lavoro pesante solo quando la sessione della fotocamera sta per iniziare, ad esempio quando viene chiamato onInit() in Basic Extender o initSession() in Advanced Extender.

    Per l'estensione Night, vengono istanziate le seguenti classi Extender per il tipo Basic Extender:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    E per il tipo Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. Verifica la disponibilità delle estensioni:

    Prima di abilitare l'estensione, isExtensionAvailable() controlla se l'estensione è disponibile sull'ID della fotocamera specificato tramite l'istanza di Extender.

  5. Inizializzare l'Extender con le informazioni sulla fotocamera:

    Camera2/X chiama init() sull'istanza Extender e le passa l'ID della fotocamera e CameraCharacteristics .

  6. Richiedi informazioni:

    Richiama la classe Extender per recuperare informazioni come le risoluzioni supportate, acquisire comunque la latenza stimata e acquisire le chiavi di richiesta dall'Extender in preparazione all'abilitazione dell'estensione.

  7. Abilita l'estensione sull'Extender:

    La classe Extender fornisce tutte le interfacce necessarie per abilitare la classe. Offre un meccanismo per collegare l'implementazione OEM alla pipeline Camera2, ad esempio inserendo parametri di richiesta di acquisizione o abilitando un post processore.

    Per il tipo Advanced Extender, Camera2/X interagisce con SessionProcessorImpl per abilitare l'estensione. Camera2/X recupera l'istanza SessionProcessorImpl chiamando createSessionProcessor() sull'Extender.

Le sezioni seguenti descrivono il flusso di estensione in maggiore dettaglio.

Verifica della versione

Quando si carica la libreria del fornitore OEM dal dispositivo in fase di runtime, Camera2/X verifica se la libreria è compatibile con la versione extensions-interface . L' extensions-interface utilizza il controllo delle versioni semantico o MAJOR.MINOR.PATCH, ad esempio 1.1.0 o 1.2.0. Tuttavia, durante la verifica della versione vengono utilizzate solo le versioni principale e secondaria.

Per verificare la versione, Camera2/X chiama ExtensionVersionImpl.checkApiVersion() con la versione extensions-interface supportata. Camera2/X utilizza quindi la versione riportata dalla libreria OEM per determinare se l'estensione può essere abilitata e quali funzionalità deve richiamare.

Compatibilità delle versioni principali

Se le versioni principali dell'interfaccia dell'estensione sono diverse tra Camera2/X e la libreria del fornitore, allora viene considerata incompatibile e l'estensione viene disabilitata.

Retrocompatibilità

Finché la versione principale è identica, Camera2/X garantisce la compatibilità con le librerie dei fornitori OEM realizzate con versioni precedenti extensions-interface . Ad esempio, se Camera2/X supporta extensions-interface 1.3.0, le librerie del fornitore OEM che hanno implementato 1.0.0, 1.1.0 e 1.2.0 sono ancora compatibili. Ciò significa anche che dopo aver implementato una versione specifica della libreria del fornitore, Camera2/X si assicura che la libreria sia retrocompatibile con le prossime versioni extension-interface .

Compatibilità futura

La compatibilità futura con le librerie dei fornitori extensions-interface più recenti dipende da te, l'OEM. Se hai bisogno di alcune funzionalità per implementare le estensioni, potresti voler abilitare le estensioni a partire da una determinata versione. In questo caso, è possibile restituire la versione extensions-interface supportata quando la versione della libreria Camera2/X soddisfa i requisiti. Se le versioni Camera2/X non sono supportate, puoi restituire una versione incompatibile come 99.0.0 per disabilitare le estensioni.

Inizializzazione della libreria del fornitore

Dopo aver verificato la versione extensions-interface implementata dalla libreria OEM, Camera2/X avvia il processo di inizializzazione. Il metodo InitializerImpl.init() segnala alla libreria OEM che un'app sta tentando di utilizzare le estensioni.

Camera2/X non effettua altre chiamate alla libreria OEM (a parte il controllo della versione) finché la libreria del fornitore OEM non chiama OnExtensionsInitializedCallback.onSuccess() per notificare il completamento dell'inizializzazione.

È necessario implementare InitializerImpl a partire extensions-interface 1.1.0. Camera2/X salta il passaggio di inizializzazione della libreria se la libreria del fornitore OEM implementa extensions-interface 1.0.0.

Extender di base rispetto a Extender avanzato

Esistono due tipi di implementazione extensions-interface : Basic Extender e Advanced Extender. Advanced Extender è supportato a partire extensions-interface 1.2.0.

Implementa Basic Extender per le estensioni che elaborano le immagini nell'HAL della fotocamera o utilizzano un post processore in grado di elaborare flussi YUV.

Implementa Advanced Extender per le estensioni che necessitano di personalizzare la configurazione del flusso Camera2 e inviare richieste di acquisizione secondo necessità.

Per il confronto vedere la tabella seguente:

Estensore di base Estensore avanzato
Configurazioni di flusso Fisso
Anteprima: PRIVATE o YUV_420_888 (se esiste il processore)
Cattura ancora: JPEG o YUV_420_888 (se esiste il processore)
Personalizzabile dall'OEM.
Invio richiesta di acquisizione Solo Camera2/X può inviare richieste di acquisizione. È possibile impostare i parametri per queste richieste. Quando il processore viene fornito per l'acquisizione delle immagini, Camera2/X può inviare più richieste di acquisizione e inviare tutte le immagini e i risultati dell'acquisizione al processore. Viene fornita un'istanza RequestProcessorImpl per eseguire la richiesta di acquisizione camera2 e ottenere risultati e immagine.

Camera2/X richiama startRepeating e startCapture su SessionProcessorImpl per segnalare all'OEM di avviare rispettivamente la richiesta ripetuta di anteprima e avviare la sequenza di acquisizione fissa.

Ganci nella pipeline della fotocamera
  • onPresetSession fornisce i parametri di sessione.
  • onEnableSession invia una singola richiesta subito dopo la configurazione CameraCaptureSession .
  • onDisableSession invia una singola richiesta prima che CameraCaptureSession venga chiusa.
  • initSession inizializza e restituisce una configurazione personalizzata della sessione camera2 per creare la sessione di acquisizione.
  • onCaptureSessionStart viene richiamato subito dopo la configurazione di CameraCaptureSession .
  • onCaptureSessionEnd viene richiamato prima che CameraCaptureSession venga chiuso.
Adatto a Estensioni implementate nell'HAL della fotocamera o in un processore che elabora le immagini YUV.
  • Dispone di implementazioni basate su Camera2 per le estensioni.
  • Richiede una configurazione del flusso personalizzata come il flusso RAW.
  • Richiede una sequenza di acquisizione interattiva.
Versione API supportata Estensioni Camera2: Android 13 o versioni successive
Estensioni CameraX: camera-extensions 1.1.0 o successiva
Estensioni Camera2: Android 12L o versione successiva
Estensioni CameraX: camera-extensions 1.2.0-alpha03 o successiva

Flussi dell'app

La tabella seguente mostra tre tipi di flussi di app e le corrispondenti chiamate API Camera Extensions. Sebbene Camera2/X fornisca queste API, è necessario implementare correttamente la libreria del fornitore per supportare questi flussi, che descriveremo più dettagliatamente in una sezione successiva.

Estensioni Camera2 Estensioni CameraX
Richiedi la disponibilità delle estensioni CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Richiedi informazioni CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX gestisce il resto delle informazioni all'interno della libreria.

Anteprima e acquisizione di immagini fisse con l'estensione abilitata CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle(lifecycleOwner, cameraSelector, anteprima, ...)

Estensore di base

L'interfaccia Basic Extender fornisce hook in diversi punti nella pipeline della fotocamera. Ogni tipo di estensione ha classi Extender corrispondenti che gli OEM devono implementare.

La seguente tabella elenca le classi Extender che gli OEM devono implementare per ciascuna estensione:

Classi extender da implementare
Notte NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java HdrImageCaptureExtenderImpl.java
Auto AutoPreviewExtenderImpl.java AutoImageCaptureExtenderImpl.java
Bokeh BokehPreviewExtenderImpl.java BokehImageCaptureExtenderImpl.java
Ritocco del viso BeautyPreviewExtenderImpl.java BeautyImageCaptureExtenderImpl.java

Utilizziamo PreviewExtenderImpl e ImageCaptureExtenderImpl come segnaposto nell'esempio seguente. Sostituiscili con i nomi dei file effettivi che stai implementando.

Basic Extender ha le seguenti funzionalità:

  • Iniettare i parametri della sessione durante la configurazione CameraCaptureSession ( onPresetSession ).
  • Notifica gli eventi di inizio e chiusura della sessione di acquisizione e invia una singola richiesta per notificare l'HAL con i parametri restituiti ( onEnableSession , onDisableSession ).
  • Iniettare i parametri di acquisizione per la richiesta ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Aggiungi processori per l'anteprima e cattura comunque in grado di elaborare il flusso YUV_420_888 .

Vediamo come Camera2/X richiama l' extensions-interface per ottenere i tre flussi dell'app menzionati sopra.

Flusso dell'app 1: verifica la disponibilità dell'estensione

BasicExtenderAppFlow1

Figura 3. Flusso dell'app 1 su Basic Extender

In questo flusso, Camera2/X chiama direttamente il metodo isExtensionAvailable() sia di PreviewExtenderImpl che di ImageCaptureExtenderImpl senza chiamare init() . Entrambe le classi Extender devono restituire true per abilitare le estensioni.

Questo è spesso il primo passaggio da parte delle app per verificare se il tipo di estensione specificato è supportato per un determinato ID fotocamera prima di abilitare l'estensione. Questo perché alcune estensioni sono supportate solo su determinati ID fotocamera.

Flusso dell'app 2: query di informazioni

BasicExtenderAppFlow2

Figura 4. Flusso dell'app 2 su Basic Extender

Dopo aver determinato se l'estensione è disponibile, le app devono richiedere le seguenti informazioni prima di abilitare l'estensione.

  • Intervallo di latenza di acquisizione continua: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange restituisce l'intervallo di latenza di acquisizione affinché l'app possa valutare se è appropriato abilitare l'estensione per lo scenario corrente.

  • Dimensioni supportate per la superficie di anteprima e acquisizione: ImageCaptureExtenderImpl.getSupportedResolutions e PreviewExtenderImpl.getSupportedResolutions restituiscono un elenco di formati immagine e le dimensioni supportate per il formato e le dimensioni della superficie.

  • Chiavi di richiesta e risultato supportate: Camera2/X richiama i seguenti metodi per recuperare le chiavi di richiesta di acquisizione e le chiavi di risultato supportate dall'implementazione:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X chiama sempre init() su queste classi Extender prima di richiedere ulteriori informazioni.

Flusso dell'app 3: anteprima/acquisizione di immagini fisse con estensione abilitata (implementazione HAL)

BasicExtenderAppFlow3

Figura 5. Flusso dell'app 3 su Basic Extender

Il diagramma sopra illustra il flusso principale per abilitare l'anteprima e l'acquisizione continua con un'estensione senza processore. Ciò significa che l'HAL della fotocamera elabora l'estensione.

In questo flusso, Camera2/X chiama prima init() e poi onInit , che ti avvisa che una sessione della fotocamera sta per iniziare con le estensioni specificate. Puoi eseguire un'inizializzazione pesante in onInit() .

Durante la configurazione di CameraCaptureSession , Camera2/X richiama onPresetSession per ottenere i parametri della sessione. Dopo che la sessione di acquisizione è stata configurata correttamente, Camera2/X richiama onEnableSession restituendo un'istanza CaptureStageImpl che contiene i parametri di acquisizione. Camera2/X invia immediatamente una singola richiesta con questi parametri di acquisizione per notificare l'HAL. Allo stesso modo, prima che la sessione di acquisizione venga chiusa, Camera2/X richiama onDisableSession e quindi invia una singola richiesta con i parametri di acquisizione restituiti.

La richiesta ripetuta attivata da Camera2/X contiene i parametri di richiesta restituiti da PreviewExtenderImpl.getCaptureStage() . Inoltre, la richiesta di acquisizione di immagini fisse contiene i parametri restituiti da ImageCaptureExtenderImpl.getCaptureStages() .

Infine, Camera2/X invoca onDeInit() al termine della sessione della fotocamera. Puoi rilasciare risorse in onDeinit() .

Anteprima del processore

Oltre all'HAL della fotocamera, è possibile implementare anche estensioni in un processore.

Implementa PreviewExtenderImpl.getProcessorType per specificare il tipo di processore come spiegato di seguito:

  • PROCESSOR_TYPE_NONE : nessun processore. Le immagini vengono elaborate nell'HAL della fotocamera.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY : il tipo di processore consente di aggiornare la richiesta ripetuta con nuovi parametri di richiesta di acquisizione basati sull'ultimo TotalCaptureResult .

    PreviewExtenderImpl.getProcessor deve restituire un'istanza RequestUpdateProcessorImpl che elabora l'istanza TotalCaptureResult e restituisce un'istanza CaptureStageImpl per aggiornare la richiesta ripetuta. PreviewExtenderImpl.getCaptureStage() dovrebbe anche riflettere il risultato dell'elaborazione e restituire l'ultimo CaptureStageImpl .

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : questo tipo consente di implementare un processore per elaborare le immagini YUV_420_888 e scrivere l'output su una superficie PRIVATE .

    È necessario implementare e restituire un'istanza PreviewImageProcessorImpl in PreviewExtenderImpl.getProcessor . Il processore è responsabile dell'elaborazione delle immagini di input YUV_420_888 . Dovrebbe scrivere l'output nel formato PRIVATE di anteprima. Camera2/X utilizza una superficie YUV_420_888 anziché PRIVATE per configurare CameraCaptureSession per l'anteprima.

    Vedere la seguente illustrazione per il flusso:

AnteprimaProcessore

Figura 6. Flusso di anteprima con PreviewImageProcessorImpl

L'interfaccia PreviewImageProcessorImpl estende ProcessImpl e dispone di tre metodi importanti:

  • onOutputSurface(Surface surface, int imageFormat) imposta la superficie di output per il processore. Per PreviewImageProcessorImpl , imageFormat è un formato pixel come PixelFormat.RGBA_8888 .

  • onResolutionUpdate(Size size) imposta la dimensione dell'immagine di input.

  • onImageFormatUpdate(int imageFormat) imposta il formato immagine dell'immagine di input. Attualmente può essere solo YUV_420_888 .

Processore di acquisizione delle immagini

Per l'acquisizione di immagini fisse, puoi implementare un processore restituendo un'istanza CaptureProcessorImpl utilizzando ImageCaptureExtenderImpl.getCaptureProcessor . Il processore è responsabile dell'elaborazione di un elenco di immagini YUV_420_888 acquisite e di istanze TotalCaptureResult e di scrivere l'output su una superficie YUV_420_888 .

Puoi tranquillamente presumere che l'anteprima sia abilitata e in esecuzione prima di inviare la richiesta di acquisizione statica.

Vedere il flusso nel diagramma seguente:

CaptureProcessor

Figura 7. Flusso di acquisizione continua con CaptureProcessorImpl

  1. Camera2/X utilizza una superficie in formato YUV_420_888 per l'acquisizione di immagini fisse per configurare la sessione di acquisizione. Camera2/X prepara CaptureProcessorImpl chiamando:

    • CaptureProcessorImpl.onImageFormatUpdate() con YUV_420_888 .
    • CaptureProcessorImpl.onResolutionUpdate() con la dimensione dell'immagine di input.
    • CaptureProcessorImpl.onOutputSurface() con una superficie di output YUV_420_888 .
  2. ImageCaptureExtenderImpl.getCaptureStages restituisce un elenco di CaptureStageImpl , in cui ogni elemento è mappato a un'istanza CaptureRequest con parametri di acquisizione inviati da Camera2/X. Ad esempio, se restituisce un elenco di tre istanze CaptureStageImpl , Camera2/X invia tre richieste di acquisizione con i parametri di acquisizione corrispondenti utilizzando l'API captureBurst .

  3. Le immagini ricevute e le istanze TotalCaptureResult vengono raggruppate e inviate a CaptureProcessorImpl per l'elaborazione.

  4. CaptureProcessorImpl scrive l'immagine del risultato (formato YUV_420_888 ) sulla superficie di output specificata dalla chiamata onOutputSurface() . Camera2/X lo converte in immagini JPEG, se necessario.

Supporta chiavi e risultati delle richieste di acquisizione

Oltre all'anteprima e all'acquisizione della fotocamera, le app possono impostare lo zoom, i parametri del flash o attivare un tocco per mettere a fuoco. Questi parametri potrebbero non essere compatibili con l'implementazione dell'estensione.

I seguenti metodi sono stati aggiunti extensions-interface 1.3.0 per consentirti di esporre i parametri supportati dalla tua implementazione:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() restituisce le chiavi della richiesta di acquisizione supportate dalla tua implementazione.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() restituisce le chiavi del risultato di acquisizione contenute nel risultato di acquisizione.

Se l'HAL della fotocamera elabora l'estensione, Camera2/X recupera i risultati dell'acquisizione in CameraCaptureSession.CaptureCallback . Tuttavia, se il processore è implementato, Camera2/X recupera i risultati dell'acquisizione in ProcessResultImpl , che viene passato al metodo process() in PreviewImageProcessorImpl e CaptureProcessorImpl . Sei responsabile di segnalare il risultato dell'acquisizione tramite ProcessResultImpl a Camera2/X.

Vedere la definizione dell'interfaccia CaptureProcessorImpl di seguito come esempio. extensions-interface 1.3.0 o successiva, viene invocata la seconda chiamata process() :

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);
}

Per le operazioni comuni della fotocamera come zoom, tocco per mettere a fuoco, flash e compensazione dell'esposizione, consigliamo di supportare i seguenti tasti sia per la richiesta di acquisizione che per il risultato dell'acquisizione:

  • Ingrandisci:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Tocca per mettere a fuoco:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Veloce:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Compensazione dell'esposizione:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Per gli extender Basic che implementano la versione 1.2.0 o versioni precedenti, l'API CameraX Extensions supporta esplicitamente tutte le chiavi di cui sopra. Per extensions-interface 1.3.0, sia CameraX che Camera2 rispettano l'elenco restituito e supportano solo le chiavi in ​​esso contenute. Ad esempio, se decidi di restituire solo CaptureRequest#CONTROL_ZOOM_RATIO e CaptureRequest#SCALER_CROP_REGION nell'implementazione 1.3.0, significa che solo lo zoom è supportato per l'app mentre il tocco per mettere a fuoco, il flash e la compensazione dell'esposizione non sono consentiti.

Estensore avanzato

Advanced Extender è un tipo di implementazione del fornitore basata sull'API Camera2. Questo tipo di extender è stato aggiunto extensions-interface 1.2.0. A seconda del produttore del dispositivo, le estensioni potrebbero essere implementate nel livello dell'app, il che dipende dai seguenti fattori:

  • Configurazione del flusso personalizzato: configura flussi personalizzati come il flusso RAW o disponi di più flussi per diversi ID fisici della telecamera.

  • Capacità di inviare richieste Camera2: supporta una logica di interazione complicata in grado di inviare richieste di acquisizione con parametri basati sui risultati delle richieste precedenti.

Advanced Extender fornisce un wrapper o un livello intermedio, così puoi personalizzare la configurazione del flusso e inviare richieste di acquisizione su richiesta.

File da implementare

Per passare all'implementazione Advanced Extender, il metodo isAdvancedExtenderImplemented() in ExtensionVersionImpl deve restituire true . Per ogni tipo di estensione, gli OEM devono implementare le classi Extender corrispondenti. I file di implementazione di Advanced Extender si trovano nel pacchetto advanced .

Classi extender da implementare
Notte advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Auto advanced/AutoAdvancedExtenderImpl.java
Bokeh advanced/BokehAdvancedExtenderImpl.java
Ritocco viso advanced/BeautyAdvancedExtenderImpl.java

Utilizziamo AdvancedExtenderImpl come segnaposto nell'esempio seguente. Sostituiscilo con il nome del file Extender per l'estensione che stai implementando.

Vediamo come Camera2/X richiama l' extensions-interface per ottenere i tre flussi dell'app.

Flusso dell'app 1: verifica la disponibilità delle estensioni

AdvancedAppFlow1

Figura 8. Flusso dell'app 1 su Advanced Extender

Innanzitutto, l'app controlla se l'estensione specificata è supportata.

Flusso dell'app 2: query di informazioni

AdvancedAppFlow2

Figura 9. Flusso dell'app 2 su Advanced Extender

Dopo aver chiamato AdvancedExtenderImpl.init() , l'app può eseguire query sulle seguenti informazioni su AdvancedExtenderImpl :

  • Latenza di acquisizione ancora stimata: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() restituisce l'intervallo di latenza di acquisizione affinché l'app valuti se è appropriato abilitare l'estensione per lo scenario corrente.

  • Risoluzioni supportate per l'anteprima e l'acquisizione fissa:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() restituisce una mappa del formato immagine all'elenco delle dimensioni supportate per il formato e le dimensioni della superficie di anteprima. Gli OEM devono supportare almeno il formato PRIVATE .

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() restituisce il formato e le dimensioni supportati per la superficie di acquisizione fissa. Gli OEM devono supportare sia l'output in formato JPEG che YUV_420_888 .

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() restituisce le dimensioni supportate per un flusso YUV_420_888 aggiuntivo per l'analisi delle immagini. Se la superficie YUV dell'analisi delle immagini non è supportata, getSupportedYuvAnalysisResolutions() dovrebbe restituire null o un elenco vuoto.

  • Chiavi/risultati di richiesta di acquisizione disponibili (aggiunti extensions-interface 1.3.0): Camera2/X richiama i seguenti metodi per recuperare le chiavi di richiesta di acquisizione supportate e le chiavi di risultato dall'implementazione:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Per ulteriori informazioni, consulta Supporto delle chiavi e dei risultati delle richieste di acquisizione .

Flusso dell'app 3: anteprima/acquisizione di immagini fisse con l'estensione abilitata

AdvancedAppFlow3

Figura 10. Flusso dell'app 3 su Advanced Extender

Il diagramma precedente mostra il flusso principale per l'avvio dell'anteprima e l'acquisizione di immagini fisse per il tipo Advanced Extender. Esaminiamo ogni passaggio.

  1. Istanza SessionProcessorImpl

    L'implementazione principale di Advanced Extender è in SessionProcessorImpl , che è responsabile di fornire una configurazione di sessione personalizzata e inviare richieste di acquisizione per avviare l'anteprima e continuare a richiedere l'acquisizione. AdvancedExtenderImpl.createSessionProcessor() viene richiamato per restituire l'istanza SessionProcessorImpl .

  2. initSession

    SessionProcessorImpl.initSession() inizializza la sessione per l'estensione. Qui è dove allochi le risorse e restituisci una configurazione di sessione per preparare una CameraCaptureSession .

    Per i parametri di input, Camera2/X specifica le configurazioni della superficie di output per l'anteprima, l'acquisizione di immagini fisse e un'analisi dell'immagine YUV opzionale. Questa configurazione della superficie di output ( OutputSurfaceImpl ) contiene la superficie, le dimensioni e il formato dell'immagine che vengono recuperati con i seguenti metodi in AdvancedExtenderImpl :

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

    È necessario restituire un'istanza Camera2SessionConfigImpl , che consiste in un elenco di istanze Camera2OutputConfigImpl e i parametri di sessione utilizzati per configurare CameraCaptureSession . L'utente è responsabile dell'output delle immagini corrette della telecamera sulle superfici di output trasmesse da Camera2/X. Ecco alcune opzioni per abilitare l'output:

    • Elaborazione nell'HAL della fotocamera: puoi aggiungere direttamente le superfici di output a CameraCaptureSession con un'implementazione SurfaceOutputConfigImpl . Ciò configura la superficie di output fornita alla pipeline della fotocamera e consente all'HAL della fotocamera di elaborare l'immagine.
    • Elaborazione della superficie ImageReader intermedia (RAW, YUV, ecc.): aggiungi le superfici ImageReader intermedie a CameraCaptureSession con un'istanza ImageReaderOutputConfigImpl .

      È necessario elaborare le immagini intermedie e scrivere l'immagine risultante sulla superficie di output.

    • Utilizza la condivisione della superficie Camera2: utilizza la condivisione della superficie con un'altra superficie aggiungendo qualsiasi istanza Camera2OutputConfigImpl al metodo getSurfaceSharingOutputConfigs() di un'altra istanza Camera2OutputConfigImpl . Il formato e le dimensioni della superficie devono essere identici.

    Tutti Camera2OutputConfigImpl inclusi SurfaceOutputConfigImpl e ImageReaderOutputConfigImpl devono avere un ID univoco ( getId() ), che viene utilizzato per specificare la superficie di destinazione e recuperare l'immagine da ImageReaderOutputConfigImpl .

  3. onCaptureSessionStart e RequestProcessorImpl

    Quando CameraCaptureSession viene avviato e il framework Camera richiama onConfigured() , Camera2/X richiama SessionProcessorImpl.onCaptureSessionStart() con il wrapper della richiesta Camera2 RequestProcessImpl . Camera2/X implementa RequestProcessImpl , che consente di eseguire le richieste di acquisizione e recuperare le immagini se viene utilizzato ImageReaderOutputConfigImpl .

    Le API RequestProcessImpl sono simili alle API Camera2 CameraCaptureSession in termini di esecuzione delle richieste. Le differenze sono:

    • La superficie di destinazione è specificata dall'ID dell'istanza Camera2OutputConfigImpl .
    • La capacità di recuperare l'immagine di ImageReader .

    Puoi chiamare RequestProcessorImpl.setImageProcessor() con un ID Camera2OutputConfigImpl specificato per registrare un'istanza ImageProcessorImpl per ricevere immagini.

    L'istanza RequestProcessImpl diventa non valida dopo che Camera2/X chiama SessionProcessorImpl.onCaptureSessionEnd() .

  4. Avvia l'anteprima e scatta una foto

    Nell'implementazione Advanced Extender, è possibile inviare richieste di acquisizione tramite l'interfaccia RequestProcessorImpl . Camera2/X ti avvisa di avviare la richiesta ripetuta di anteprima o la sequenza di acquisizione fissa chiamando rispettivamente SessionProcessorImpl#startRepeating e SessionProcessorImpl#startCapture . Dovresti inviare richieste di acquisizione per soddisfare queste richieste di anteprima e di acquisizione continua.

    Camera2/X imposta anche i parametri della richiesta di acquisizione tramite SessionProcessorImpl#setParameters . È necessario impostare questi parametri di richiesta (se i parametri sono supportati) sia sulle richieste ripetute che su quelle singole.

    È necessario supportare almeno CaptureRequest.JPEG_ORIENTATION e CaptureRequest.JPEG_QUALITY . extensions-interface 1.3.0 supporta le chiavi di richiesta e di risultato, che vengono esposte con i seguenti metodi:

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

    Quando gli sviluppatori impostano le chiavi nell'elenco getAvailableCaptureRequestKeys , è necessario abilitare i parametri e assicurarsi che il risultato dell'acquisizione contenga le chiavi nell'elenco getAvailableCaptureResultKeys .

  5. startTrigger

    SessionProcessorImpl.startTrigger() viene richiamato per avviare il trigger come CaptureRequest.CONTROL_AF_TRIGGER e CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Puoi ignorare eventuali chiavi di richiesta di acquisizione che non sono state pubblicizzate in AdvancedExtenderImpl.getAvailableCaptureRequestKeys() .

    startTrigger() è supportato extensions-interface 1.3.0. Consente alle app di implementare tap-to-focus e flash con estensioni.

  6. Ripulire

    Al termine di una sessione di acquisizione, SessionProcessorImpl.onCaptureSessionEnd() viene richiamato prima della chiusura CameraCaptureSession . Una volta chiusa la sessione di acquisizione, deInitSession() esegue la pulizia.

Supporta l'anteprima, l'acquisizione di immagini fisse e l'analisi delle immagini

Dovresti applicare l'estensione sia per i casi d'uso di anteprima che per quelli di acquisizione continua. Tuttavia, se la latenza è troppo elevata per mostrare senza problemi l'anteprima, puoi applicare l'estensione solo per l'acquisizione di immagini fisse.

Per il tipo Basic Extender, indipendentemente dall'abilitazione dell'estensione per l'anteprima, è necessario implementare sia ImageCaptureExtenderImpl che PreviewExtenderImpl per una determinata estensione. Spesso un'app utilizza anche un flusso YUV per analizzare il contenuto dell'immagine come la ricerca di codici QR o testo. Per supportare meglio questo caso d'uso, è necessario supportare la combinazione di streaming di anteprima, ancora cattura e un flusso YUV_420_888 per la configurazione CameraCaptureSession . Ciò significa che se si implementa un processore, è necessario supportare la combinazione di flusso di tre flussi YUV_420_888 .

Per Extender Advanced, la fotocamera2/x passa tre superfici di uscita alla chiamata SessionProcessorImpl.initSession() . Queste superfici di output sono rispettivamente per l'anteprima, la cattura e l'analisi delle immagini. È necessario assicurarsi che l'anteprima e le superfici di output ancora di acquisizione mostrino l'output valido. Tuttavia, per la superficie di uscita dell'analisi delle immagini, assicurarsi che funzioni solo quando non è nullo. Se l'implementazione non è in grado di supportare il flusso di analisi delle immagini, è possibile restituire un elenco vuoto in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . Ciò garantisce che la superficie di uscita dell'analisi delle immagini sia sempre nulla in SessionProcessorImpl.initSession() .

Supportare l'acquisizione di video

L'attuale architettura di estensione della fotocamera supporta solo l'anteprima e l'acquisizione di casi d'uso. Non supportiamo abilitare l'estensione sulle superfici MediaCodec o MediaRecorder per la registrazione del video. Tuttavia, è possibile per le app registrare l'output di anteprima.

Supportare le superfici MediaCodec e MediaRecorder è sotto inchiesta.

Metadati specifici per estensione

Per Android 14 e oltre, i metadati specifici per estensione consentono ai client di estensione della fotocamera di impostare e ricevere impostazioni e risultati specifici per le richieste di acquisizione di estensione. In particolare, i client di estensione della fotocamera possono utilizzare il parametro di richiesta di acquisizione EXTENSION_STRENGTH per controllare la potenza di estensione e il risultato di acquisizione EXTENSION_CURRENT_TYPE per indicare il tipo di estensione abilitato.

Richieste di acquisizione

Il parametro di richiesta di acquisizione EXTENSION_STRENGTH controlla la resistenza dell'effetto di post-elaborazione dell'estensione. Il risultato di acquisizione corrispondente include il valore di resistenza predefinito se questo parametro non è impostato esplicitamente dal client. Questo parametro può essere applicato come segue per questi tipi di estensione:

  • BOKEH : controlla la quantità di sfocatura.
  • HDR e NIGHT : controlla la quantità di immagini fuse e la luminosità dell'immagine finale.
  • FACE_RETOUCH : controlla la quantità di miglioramento cosmetico e levigatura della pelle.

L'intervallo supportato per il parametro EXTENSION_STRENGTH è compreso tra 0 e 100 , con 0 che indica alcuna elaborazione di estensione o semplice passthrough e 100 che indicano la massima intensità di estensione dell'effetto di elaborazione.

Per aggiungere supporto per EXTENSION_STRENGTH , utilizzare le API parametri specifiche del fornitore introdotte nella versione 1.3.0 dell'interfaccia della libreria di estensione. Per ulteriori informazioni, consultare getAvailableCaptureRequestKeys() .

Risultati di acquisizione

Il risultato di acquisizione EXTENSION_CURRENT_TYPE consente alle implementazioni di estensione di notificare ai clienti il ​​tipo di estensione attivo.

Poiché le estensioni che utilizzano il tipo AUTO passano dinamicamente tra i tipi di estensione come HDR e NIGHT a seconda delle condizioni della scena, le app di estensioni della fotocamera possono utilizzare EXTENSION_CURRENT_TYPE per visualizzare informazioni sull'estensione corrente selezionata dall'estensione AUTO .

In tempo reale ancora catturare la stima della latenza

Per Android 14 e oltre, i clienti di estensione della fotocamera possono interrogare le stime di latenza ancora in tempo reale in base alle condizioni della scena e dell'ambiente utilizzando getRealtimeStillCaptureLatency() . Questo metodo fornisce stime più accurate rispetto al metodo statico getEstimatedCaptureLatencyRangeMillis() . Sulla base della stima della latenza, le app possono decidere di saltare l'elaborazione dell'estensione o di visualizzare un'indicazione per notificare agli utenti un'operazione di lunga durata.

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();

Per supportare le stime di latenza ancora in tempo reale, implementa quanto segue:

Calcelli di elaborazione di elaborazione di elaborazione

Per Android 14 e oltre, i client di estensione della fotocamera possono ricevere callback per l'avanzamento delle operazioni di elaborazione di acquisizione a lungo termine. Le app possono visualizzare gli attuali progressi per gli utenti per migliorare l'esperienza utente complessiva.

Le app possono utilizzare il seguente codice per integrare questa funzione:

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
    }
  }
…
}

Per supportare i callback di elaborazione dell'acquisizione, l'implementazione del fornitore di estensione deve chiamare i seguenti callback con il valore di avanzamento corrente:

Postview ancora cattura

Per Android 14 e superiore, le estensioni della fotocamera possono fornire una postview (immagine di anteprima) utilizzando setPostviewOutputConfiguration . Per migliorare l'esperienza dell'utente, le app possono visualizzare un'immagine postview come segnaposto quando un'estensione sta vivendo una maggiore latenza di elaborazione e sostituire l'immagine quando è disponibile l'immagine finale. Le app possono configurare e emettere richieste di acquisizione postview utilizzando il seguente codice di riferimento:

{
…
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();
…
}

Per supportare PostView ancora cattura, l'implementazione del fornitore deve implementare quanto segue:

Supportare l'output di SurfaceView

Per Android 14 e oltre, i client di estensione della fotocamera possono utilizzare i percorsi di rendering di anteprima ottimizzati di potenza e prestazioni registrando un'istanza SurfaceView per l'uscita di anteprima per le richieste di ripetizione.

Per supportare l'output SurfaceView , l'implementazione dell'estensione del fornitore deve essere in grado di streaming e output di anteprima alle istanze SurfaceView . Per verificare che ciò sia supportato, eseguire il modulo CTS SurfaceViewExtensionPreviewTest.java .

Tipi di sessione specifici del fornitore

La funzione consente alle implementazioni di estensione del fornitore di selezionare un tipo di sessione specifico del fornitore che verrà impostato nella sessione di acquisizione della fotocamera interna anziché nel valore predefinito.

La funzionalità funziona interamente all'interno del framework e dello stack del fornitore e non ha un impatto API visibile cliente/pubblico.

Per selezionare un tipo di sessione specifico del fornitore, implementa quanto segue per le librerie di estensione: * ExtenderStateListener.onSessionType() per estensioni di base * Camera2SessionConfigImpl.getSessionType() per estensioni avanzate

Cronologia della versione dell'interfaccia estensioni

La tabella seguente mostra la cronologia della versione dell'interfaccia di estensione della fotocamera. Dovresti sempre implementare la libreria dei fornitori con l'ultima versione.

Versione Funzionalità aggiunte
1.0.0
  • Verifica della versione
    • ExtensionVersionImpl
  • Extender di base
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Inizializzazione della libreria
    • InitializerImpl
  • Esporre risoluzioni supportate
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Ottieni la latenza di cattura stimata
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Esporre chiavi/tasti dei risultati della richiesta di acquisizione supportati
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys e getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys e getAvailableCaptureResultKeys
    • Nuovo process() Chiamata che prende ProcessResultImpl in PreviewImageProcessorImpl e CaptureProcessorImpl
    • Supporto Richiesta Tipo di trigger
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Metadati specifici per estensione
  • Le stime della latenza di acquisizione ancora dinamica
  • Calcelli di elaborazione di elaborazione di elaborazione
  • Postview ancora cattura
  • Supporto per l'uscita SurfaceView
  • Tipi di sessione specifici del fornitore

Implementazione di riferimento

Le seguenti implementazioni della libreria del fornitore OEM di riferimento sono disponibili in frameworks/ex .

  • advancedSample : un'implementazione di base di Extender Advanced.

  • sample : un'implementazione di base di Extender di base.

  • service_based_sample : un'implementazione che dimostra come ospitare le estensioni della fotocamera in un Service . Questa implementazione contiene i seguenti componenti:

    • oem_library : una libreria OEM per estensioni della fotocamera per API della fotocamera2 e della camera da telecamere che implementa Extensions-Interface . Questo funge da passthrough che inoltra le chiamate Extensions-Interface al servizio. Questa libreria fornisce anche file AIDL e classi wrapper per comunicare con il servizio.

      Advanced Extender è abilitato per impostazione predefinita. Per abilitare l'estensione di base, modifica ExtensionsVersionImpl#isAdvancedExtenderImplemented per restituire false .

    • extensions_service : un'implementazione di esempio del servizio di estensioni. Aggiungi la tua implementazione qui. L'interfaccia da implementare nel servizio è simile all'interfaccia Extensions-Interface . Ad esempio, l'implementazione di IAdvancedExtenderImpl.Stub esegue le stesse operazioni di AdvancedExtenderImpl . ImageWrapper e TotalCaptureResultWrapper sono tenuti a rendere per rendere Image e TotalCaptureResult .

Imposta la libreria dei fornitori su un dispositivo

La libreria del fornitore OEM non è integrata in un'app; Viene caricato dal dispositivo in fase di esecuzione dalla fotocamera2/x. In Camerax, il tag <uses-library> dichiara che la libreria androidx.camera.extensions.impl , che è definita nel file AndroidManifest.xml della libreria della camera-extensions , è una dipendenza del camrarax e deve essere caricata in fase di esecuzione. In Camera2, il framework carica un servizio di estensione che dichiara anche che <uses-library> carica la stessa libreria androidx.camera.extensions.impl in fase di esecuzione.

Ciò consente alle app di terze parti che utilizzano estensioni per caricare automaticamente la libreria del fornitore OEM. La libreria OEM è contrassegnata come opzionale in modo che le app possano eseguire su dispositivi che non hanno la libreria sul dispositivo. La fotocamera2/x gestisce automaticamente questo comportamento quando un'app cerca di utilizzare un'estensione della fotocamera purché il produttore del dispositivo posiziona la libreria OEM sul dispositivo in modo che possa essere scoperto dall'app.

Per impostare la libreria OEM su un dispositivo, eseguire quanto segue:

  1. Aggiungi un file di autorizzazione, richiesto dal tag <uses-library> , utilizzando il seguente formato: /etc/permissions/ ANY_FILENAME .xml . Ad esempio, /etc/permissions/camera_extensions.xml . I file in questa directory forniscono una mappatura della libreria denominata in <uses-library> al percorso del file effettivo sul dispositivo.
  2. Utilizzare l'esempio seguente per aggiungere le informazioni richieste al file.

    • name deve essere androidx.camera.extensions.impl in quanto è la libreria per cui il camrace cerca.
    • file è il percorso assoluto del file che contiene l'implementazione delle estensioni (ad esempio, /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>
    

In Android 12 o superiore, i dispositivi true supporto delle estensioni della ro.camerax.extensions.enabled Per fare ciò, aggiungi la seguente riga nel dispositivo Crea file:

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

Validazione

Per testare l'implementazione della libreria dei fornitori OEM durante la fase di sviluppo, utilizzare l'app Esempio su androidx-main/camera/integration-tests/extensionstestapp/ , che funziona attraverso varie estensioni dei fornitori.

Dopo aver completato l'implementazione, utilizzare lo strumento di convalida delle estensioni della fotocamera per eseguire test automatizzati e manuali per verificare che la libreria dei fornitori sia implementata correttamente.

Modalità scena estesa rispetto alle estensioni della fotocamera

Per l'estensione di Bokeh, oltre a esporlo utilizzando le estensioni della fotocamera, è possibile esporre l'estensione utilizzando la modalità di scena estesa, che è abilitata tramite il tasto CONTROL_EXTENDED_SCENE_MODE . Per ulteriori dettagli sull'implementazione, consultare il bokeh della fotocamera .

La modalità di scena estesa ha meno restrizioni rispetto alle estensioni della fotocamera per le app fotocamera2. Ad esempio, è possibile abilitare la modalità di scena estesa in una normale istanza CameraCaptureSession che supporta le combinazioni di flusso flessibili e i parametri di richiesta di acquisizione. Al contrario, le estensioni della fotocamera supportano solo un set fisso di tipi di flusso e hanno un supporto limitato per i parametri di richiesta di acquisizione.

Un aspetto negativo della modalità di scena estesa è che è possibile implementarlo solo nella fotocamera HAL, il che significa che deve essere verificato funzionare attraverso tutti i controlli ortogonali disponibili per gli sviluppatori di app.

Si consiglia di esporre il bokeh utilizzando sia la modalità di scena estesa che le estensioni della fotocamera perché le app potrebbero preferire utilizzare una particolare API per abilitare il bokeh. Raccomandiamo prima di utilizzare la modalità di scena estesa perché questo è il modo più flessibile per le app per consentire l'estensione del bokeh. Quindi è possibile implementare l'interfaccia di estensioni della fotocamera in base alla modalità scena estesa. Se l'implementazione di bokeh nella fotocamera HAL è difficile, ad esempio, poiché richiede un post -processore in esecuzione nel livello dell'app per elaborare le immagini, ti consigliamo di implementare l'estensione del bokeh utilizzando l'interfaccia delle estensioni della fotocamera.

Domande frequenti (FAQ)

Ci sono restrizioni sui livelli API?

SÌ. Ciò dipende dal set di funzionalità API Android richiesto dall'implementazione della libreria del fornitore OEM. Ad esempio, ExtenderStateListener.onPresetSession() utilizza la chiamata SessionConfiguration.setSessionParameters() per impostare un set di tag di base. Questa chiamata è disponibile solo al livello API 28 e superiore. Per i dettagli sui metodi di interfaccia specifici, consultare la documentazione di riferimento API .