Kameraerweiterungen

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Gerätehersteller können Spezialeffekte wie Bokeh, Nachtmodus und HDR über die von der OEM-Anbieterbibliothek bereitgestellte Schnittstelle „Kameraerweiterungen“ Drittentwicklern zur Verfügung stellen. Entwickler können die Camera2 Extensions API und die CameraX Extensions API verwenden, um Effekte zu aktivieren, die als Erweiterungen in der OEM-Anbieterbibliothek auf dem Gerät implementiert sind.

Eine Liste der unterstützten Erweiterungen, die für Camera2 und CameraX gleich sind, finden Sie unter CameraX Extensions API . Wenn Sie eine Erweiterung hinzufügen möchten, melden Sie hier einen Fehler .

Auf dieser Seite wird beschrieben, wie Sie die OEM-Anbieterbibliothek auf Geräten implementieren und aktivieren.

Die Architektur

Das folgende Diagramm beschreibt die Architektur der Camera Extensions-Schnittstelle oder extensions-interface : Die Architektur

Abbildung 1. Architekturdiagramm der Kameraerweiterungen

Wie im Diagramm gezeigt, müssen Sie zur Unterstützung von Kameraerweiterungen die extensions-interface die von der OEM-Anbieterbibliothek bereitgestellt wird. Ihre OEM-Anbieterbibliothek aktiviert zwei APIs: CameraX Extensions API und Camera2 Extensions API , die von CameraX- bzw. Camera2-Apps verwendet werden, um auf Anbietererweiterungen zuzugreifen.

Implementieren Sie die OEM-Anbieterbibliothek

Um die OEM-Lieferantenbibliothek zu implementieren, kopieren Sie die camera-extensions-stub in ein Systembibliotheksprojekt. Diese Dateien definieren die Schnittstelle der Kameraerweiterungen.

Die camera-extensions-stub Dateien sind in die folgenden Kategorien unterteilt:

Wesentliche Schnittstellendateien (nicht ändern)

  • 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

Obligatorische Implementierungen (fügen Sie Ihre Implementierung hinzu)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Bokeh-Extender-Klassen (implementieren, wenn die Bokeh-Erweiterung unterstützt wird)

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

Night-Extender-Klassen (implementieren, wenn Night-Extension unterstützt wird)

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

Auto-Extender-Klassen (implementieren, wenn Auto-Extension unterstützt wird)

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

HDR-Extender-Klassen (implementieren, wenn die HDR-Erweiterung unterstützt wird)

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

Face Retouch Extender-Klassen (implementieren, wenn die Face Retouch-Erweiterung unterstützt wird)

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

Dienstprogramme (optional, können gelöscht werden)

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

Sie müssen nicht für jede Erweiterung eine Implementierung bereitstellen. Wenn Sie keine Erweiterung implementieren, legen isExtensionAvailable() , um false zurückzugeben, oder entfernen Sie die entsprechenden Extender-Klassen. Die Camera2- und CameraX-Erweiterungs-APIs melden der App, dass die Erweiterung nicht verfügbar ist.

Sehen wir uns an, wie die Camera2- und CameraX-Erweiterungs-APIs mit der Anbieterbibliothek interagieren, um eine Erweiterung zu aktivieren. Das folgende Diagramm veranschaulicht den End-to-End-Fluss am Beispiel der Night-Erweiterung:

Hauptstrom

Abbildung 2. Implementierung der Nachterweiterung

  1. Versionsprüfung:

    Camera2/X ruft ExtensionVersionImpl.checkApiVersion() auf, um sicherzustellen, dass die OEM-implementierte Version der extensions-interface mit den von Camera2/X unterstützten Versionen kompatibel ist.

  2. Initialisierung der Herstellerbibliothek:

    InitializerImpl hat eine Methode init() , die die Herstellerbibliothek initialisiert. Camera2/X schließt die Initialisierung ab, bevor auf die Extender-Klassen zugegriffen wird.

  3. Extender-Klassen instanziieren:

    Instanziiert die Extender-Klassen für die Erweiterung. Es gibt zwei Extender-Typen: Basic Extender und Advanced Extender. Sie müssen einen Extender-Typ für alle Erweiterungen implementieren. Weitere Informationen finden Sie unter Basic Extender im Vergleich zu Advanced Extender .

    Camera2/X instanziiert und interagiert mit den Extender-Klassen, um Informationen abzurufen und die Erweiterung zu aktivieren. Für eine bestimmte Erweiterung kann Camera2/X die Extender-Klassen mehrmals instanziieren. Führen Sie daher keine schwerfällige Initialisierung im Konstruktor oder beim init() Aufruf durch. Führen Sie das schwere Heben nur dann durch, wenn die Kamerasitzung kurz vor dem Start steht, z. B. wenn onInit() in Basic Extender oder initSession() in Advanced Extender aufgerufen wird.

    Für die Night-Erweiterung werden die folgenden Extender-Klassen für den Basis-Extender-Typ instanziiert:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Und für den Advanced Extender-Typ:

    • NightAdvancedExtenderImpl.java
  4. Verfügbarkeit der Erweiterung prüfen:

    Vor dem Aktivieren der Erweiterung prüft isExtensionAvailable() , ob die Erweiterung für die angegebene Kamera-ID über die Extender-Instanz verfügbar ist.

  5. Initialisieren Sie den Extender mit Kamerainformationen:

    Camera2/X ruft init() auf der Extender-Instanz auf und übergibt ihr die Kamera-ID und CameraCharacteristics .

  6. Informationen abfragen:

    Ruft die Extender-Klasse auf, um Informationen wie unterstützte Auflösungen abzurufen, weiterhin geschätzte Latenz zu erfassen und Anforderungsschlüssel vom Extender in Vorbereitung auf die Aktivierung der Erweiterung zu erfassen.

  7. Erweiterung auf dem Extender aktivieren:

    Die Extender-Klasse stellt alle Schnittstellen bereit, die zum Aktivieren der Klasse erforderlich sind. Es bietet einen Mechanismus zum Einbinden der OEM-Implementierung in die Camera2-Pipeline, z. B. das Einfügen von Erfassungsanforderungsparametern oder das Aktivieren eines Postprozessors.

    Beim Advanced Extender-Typ interagiert Camera2/X mit SessionProcessorImpl , um die Erweiterung zu aktivieren. Camera2/X ruft die SessionProcessorImpl Instanz durch Aufrufen von createSessionProcessor() auf dem Extender ab.

In den folgenden Abschnitten wird der Erweiterungsablauf ausführlicher beschrieben.

Versionsüberprüfung

Beim Laden der OEM-Herstellerbibliothek vom Gerät zur Laufzeit überprüft Camera2/X, ob die Bibliothek mit der Version der extensions-interface kompatibel ist. Die extensions-interface verwendet semantische Versionierung oder MAJOR.MINOR.PATCH, zum Beispiel 1.1.0 oder 1.2.0. Bei der Versionsprüfung werden jedoch nur die Haupt- und Nebenversionen verwendet.

Um die Version zu überprüfen, ruft Camera2/X ExtensionVersionImpl.checkApiVersion() mit der unterstützten Version der extensions-interface . Camera2/X verwendet dann die von der OEM-Bibliothek gemeldete Version, um festzustellen, ob die Erweiterung aktiviert werden kann und welche Funktionen sie aufrufen soll.

Kompatibilität der Hauptversion

Wenn sich die Hauptversionen der Erweiterungsschnittstelle zwischen Camera2/X und der Herstellerbibliothek unterscheiden, wird dies als inkompatibel betrachtet und die Erweiterung deaktiviert.

Rückwärtskompatibilität

Solange die Hauptversion identisch ist, stellt Camera2/X die Abwärtskompatibilität mit Bibliotheken von OEM extensions-interface erstellt wurden. Wenn beispielsweise Camera2/X extensions-interface 1.3.0 unterstützt, sind die OEM-Lieferantenbibliotheken, die 1.0.0, 1.1.0 und 1.2.0 implementiert haben, immer noch kompatibel. Das bedeutet auch, dass Camera2/X nach der Implementierung einer bestimmten Version der Herstellerbibliothek sicherstellt, dass die Bibliothek abwärtskompatibel mit kommenden extension-interface ist.

Aufwärtskompatibilität

Die Aufwärtskompatibilität mit Anbieterbibliotheken neuerer extensions-interface hängt von Ihnen, dem OEM, ab. Wenn Sie einige Funktionen benötigen, um die Erweiterungen zu implementieren, möchten Sie die Erweiterungen möglicherweise ab einer bestimmten Version aktivieren. In diesem Fall können Sie die unterstützte Version der extensions-interface Bibliotheksversion die Anforderungen erfüllt. Wenn die Camera2/X-Versionen nicht unterstützt werden, können Sie eine inkompatible Version wie 99.0.0 zurückgeben, um die Erweiterungen zu deaktivieren.

Initialisierung der Herstellerbibliothek

Nach Überprüfung der von der OEM extensions-interface startet Camera2/X den Initialisierungsprozess. Die Methode InitializerImpl.init() signalisiert der OEM-Bibliothek, dass eine App versucht, Erweiterungen zu verwenden.

Camera2/X führt keine weiteren Aufrufe an die OEM-Bibliothek durch (abgesehen von der Versionsprüfung), bis die OEM-Lieferantenbibliothek OnExtensionsInitializedCallback.onSuccess() , um den Abschluss der Initialisierung zu benachrichtigen.

Sie müssen InitializerImpl ab extensions-interface 1.1.0 implementieren. Camera2/X überspringt den Schritt der Bibliotheksinitialisierung, wenn die Bibliothek des OEM-Anbieters extensions-interface 1.0.0 implementiert.

Basic Extender im Vergleich zu Advanced Extender

Es gibt zwei Arten von extensions-interface : Basic Extender und Advanced Extender. Advanced Extender wird seit extensions-interface 1.2.0 unterstützt.

Implementieren Sie Basic Extender für Erweiterungen, die Bilder in der Kamera-HAL verarbeiten, oder verwenden Sie einen Postprozessor, der YUV-Streams verarbeiten kann.

Implementieren Sie Advanced Extender für Erweiterungen, die die Camera2-Stream-Konfiguration anpassen und bei Bedarf Aufnahmeanforderungen senden müssen.

Den Vergleich finden Sie in der folgenden Tabelle:

Basis-Extender Erweiterter Extender
Stream-Konfigurationen Fest
Vorschau: PRIVATE oder YUV_420_888 (falls Prozessor vorhanden)
Standbildaufnahme: JPEG oder YUV_420_888 (falls Prozessor vorhanden)
Anpassbar durch OEM.
Capture-Anfrage wird gesendet Nur Camera2/X kann Aufnahmeanfragen senden. Diese Anforderungen können Sie parametrieren. Wenn der Prozessor für die Bilderfassung bereitgestellt wird, kann Camera2/X mehrere Erfassungsanfragen senden und alle Bilder und Erfassungsergebnisse an den Prozessor senden. Eine RequestProcessorImpl -Instanz wird Ihnen bereitgestellt, um die Camera2-Erfassungsanforderung auszuführen und Ergebnisse und Bild abzurufen.

Camera2/X ruft startRepeating und startCapture auf SessionProcessorImpl auf, um dem OEM zu signalisieren, die wiederholte Anforderung für die Vorschau zu starten bzw. die Standbildaufnahmesequenz zu starten.

Haken in der Kamera-Pipeline
  • onPresetSession stellt Sitzungsparameter bereit.
  • onEnableSession sendet direkt nach der Konfiguration von CameraCaptureSession eine einzelne Anfrage.
  • onDisableSession sendet eine einzelne Anfrage, bevor CameraCaptureSession geschlossen wird.
  • initSession initialisiert und gibt eine angepasste Kamera2-Sitzungskonfiguration zum Erstellen der Aufnahmesitzung zurück.
  • onCaptureSessionStart wird unmittelbar nach der Konfiguration von CameraCaptureSession aufgerufen.
  • onCaptureSessionEnd wird aufgerufen, bevor CameraCaptureSession geschlossen wird.
Passend für Erweiterungen in der Kamera-HAL oder in einem Prozessor implementiert, der YUV-Bilder verarbeitet.
  • Hat Camera2-basierte Implementierungen für die Effekte.
  • Benötigt angepasste Stream-Konfiguration wie RAW-Stream.
  • Benötigt eine interaktive Aufnahmesequenz.
Unterstützte API-Version Camera2-Erweiterungen: Android 13 oder höher
CameraX Extensions: camera-extensions 1.1.0 oder höher
Camera2-Erweiterungen: Android 12L oder höher
CameraX camera-extensions 1.2.0-alpha03 oder höher

App-Flows

Die folgende Tabelle zeigt drei Arten von App-Flows und ihre entsprechenden API-Aufrufe für Kameraerweiterungen. Während Camera2/X diese APIs bereitstellt, müssen Sie die Herstellerbibliothek ordnungsgemäß implementieren, um diese Abläufe zu unterstützen, die wir in einem späteren Abschnitt ausführlicher beschreiben.

Camera2-Erweiterungen CameraX-Erweiterungen
Verfügbarkeit von Abfrageerweiterungen CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Informationen abfragen CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX verarbeitet den Rest der Informationen innerhalb der Bibliothek.

Vorschau und Standbildaufnahme mit aktivierter Erweiterung CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

bindToLifecycle(lifecycleOwner, cameraSelector, Vorschau, ...)

Basis-Extender

Die Basic Extender-Schnittstelle bietet Hooks an mehreren Stellen in der Kamera-Pipeline. Jeder Erweiterungstyp hat entsprechende Extender-Klassen, die OEMs implementieren müssen.

Die folgende Tabelle listet die Extender-Klassen auf, die OEMs für jede Erweiterung implementieren müssen:

Zu implementierende Extender-Klassen
Nacht NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

Auto AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

Bokeh BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

Gesichtsretusche BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

Im folgenden Beispiel verwenden wir PreviewExtenderImpl und ImageCaptureExtenderImpl als Platzhalter. Ersetzen Sie diese durch die Namen der tatsächlichen Dateien, die Sie implementieren.

Basic Extender hat die folgenden Fähigkeiten:

  • Fügen Sie Sitzungsparameter ein, wenn Sie CameraCaptureSession ( onPresetSession ) konfigurieren.
  • Benachrichtigen Sie über die Start- und Schließereignisse der Erfassungssitzung und senden Sie eine einzelne Anforderung, um die HAL mit den zurückgegebenen Parametern ( onEnableSession , onDisableSession ) zu benachrichtigen.
  • Fügen Sie Erfassungsparameter für die Anforderung ein ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Fügen Sie Prozessoren für die Vorschau hinzu und erfassen Sie trotzdem, die den YUV_420_888 Stream verarbeiten können.

Sehen wir uns an, wie Camera2/X die extensions-interface Flows zu erreichen.

App-Flow 1: Verfügbarkeit der Erweiterung prüfen

BasicExtenderAppFlow1

Abbildung 3. App-Flow 1 auf Basic Extender

In diesem Ablauf ruft Camera2/X direkt die Methode isExtensionAvailable() von PreviewExtenderImpl und ImageCaptureExtenderImpl auf, ohne init() aufzurufen. Beide Extender-Klassen müssen true zurückgeben, um die Erweiterungen zu aktivieren.

Dies ist oft der erste Schritt für Apps, um zu prüfen, ob der angegebene Erweiterungstyp für eine bestimmte Kamera-ID unterstützt wird, bevor die Erweiterung aktiviert wird. Dies liegt daran, dass einige Erweiterungen nur von bestimmten Kamera-IDs unterstützt werden.

App-Flow 2: Informationen abfragen

BasicExtenderAppFlow2

Abbildung 4. App-Flow 2 auf Basic Extender

Nachdem festgestellt wurde, ob die Erweiterung verfügbar ist, sollten Apps die folgenden Informationen abfragen, bevor sie die Erweiterung aktivieren.

  • Latenzzeitbereich für Standbilder erfassen: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange gibt den Bereich der Erfassungslatenzzeit zurück, damit die App auswerten kann, ob es angemessen ist, die Erweiterung für das aktuelle Szenario zu aktivieren.

  • Unterstützte Größen für die Vorschau- und Erfassungsoberfläche: ImageCaptureExtenderImpl.getSupportedResolutions und PreviewExtenderImpl.getSupportedResolutions geben eine Liste mit Bildformaten und den Größen zurück, die für Oberflächenformat und -größe unterstützt werden.

  • Unterstützte Anforderungs- und Ergebnisschlüssel: Camera2/X ruft die folgenden Methoden auf, um die unterstützten Erfassungsanforderungsschlüssel und Ergebnisschlüssel aus Ihrer Implementierung abzurufen:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X ruft bei diesen Extender-Klassen immer zuerst init() auf, bevor weitere Informationen abgefragt werden.

App-Flow 3: Vorschau/Standbildaufnahme mit aktivierter Erweiterung (HAL-Implementierung)

BasicExtenderAppFlow3

Abbildung 5. App-Flow 3 auf Basic Extender

Das obige Diagramm veranschaulicht den Hauptfluss zum Aktivieren der Vorschau und Standbildaufnahme mit einer Erweiterung ohne Prozessor. Das bedeutet, dass die Kamera HAL die Erweiterung verarbeitet.

In diesem Ablauf ruft Camera2/X zuerst init() und dann onInit , wodurch Sie benachrichtigt werden, dass eine Kamerasitzung mit den angegebenen Erweiterungen beginnen wird. Sie können eine schwere Initialisierung in onInit() .

Beim Konfigurieren von CameraCaptureSession ruft Camera2/X onPresetSession auf, um die Sitzungsparameter abzurufen. Nachdem die Erfassungssitzung erfolgreich konfiguriert wurde, ruft Camera2/X onEnableSession auf und gibt eine CaptureStageImpl -Instanz zurück, die die Erfassungsparameter enthält. Camera2/X sendet sofort eine einzelne Anfrage mit diesen Aufnahmeparametern, um die HAL zu benachrichtigen. In ähnlicher Weise ruft onDisableSession /X vor dem Schließen der Erfassungssitzung onDisableSession auf und sendet dann eine einzelne Anforderung mit den zurückgegebenen Erfassungsparametern.

Die von Camera2/X ausgelöste wiederholte Anfrage enthält die von PreviewExtenderImpl.getCaptureStage() zurückgegebenen Anfrageparameter. Darüber hinaus enthält die Standbildaufnahmeanforderung die von ImageCaptureExtenderImpl.getCaptureStages() zurückgegebenen Parameter.

Schließlich ruft Camera2/X onDeInit() auf, nachdem die Kamerasitzung beendet ist. Sie können Ressourcen in onDeinit() .

Vorschauprozessor

Neben der Kamera HAL können Sie auch Erweiterungen in einem Prozessor implementieren.

Implementieren PreviewExtenderImpl.getProcessorType , um den Prozessortyp wie unten beschrieben anzugeben:

  • PROCESSOR_TYPE_NONE : Kein Prozessor. Bilder werden in der Kamera HAL verarbeitet.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY : Mit dem Prozessortyp können Sie die sich wiederholende Anforderung mit neuen Erfassungsanforderungsparametern basierend auf dem neuesten TotalCaptureResult .

    PreviewExtenderImpl.getProcessor muss eine RequestUpdateProcessorImpl Instanz zurückgeben, die die TotalCaptureResult -Instanz verarbeitet und eine CaptureStageImpl -Instanz zurückgibt, um die sich wiederholende Anforderung zu aktualisieren. PreviewExtenderImpl.getCaptureStage() sollte auch das Ergebnis der Verarbeitung widerspiegeln und das neueste CaptureStageImpl zurückgeben.

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : Mit diesem Typ können Sie einen Prozessor implementieren, um YUV_420_888 Bilder zu verarbeiten und die Ausgabe auf eine PRIVATE Oberfläche zu schreiben.

    Sie müssen eine PreviewImageProcessorImpl Instanz in PreviewExtenderImpl.getProcessor implementieren und zurückgeben. Der Prozessor ist für die Verarbeitung YUV_420_888 Eingabebildern verantwortlich. Es sollte die Ausgabe in das PRIVATE -Format der Vorschau schreiben. Camera2/X verwendet eine YUV_420_888 Oberfläche anstelle von PRIVATE , um die CameraCaptureSession für die Vorschau zu konfigurieren.

    Siehe folgende Abbildung für den Ablauf:

PreviewProcessor

Abbildung 6. Ablauf der Vorschau mit PreviewImageProcessorImpl

Die PreviewImageProcessorImpl Schnittstelle erweitert ProcessImpl und hat drei wichtige Methoden:

  • onOutputSurface(Surface surface, int imageFormat) legt die Ausgabeoberfläche für den Prozessor fest. Für PreviewImageProcessorImpl ist imageFormat ein Pixelformat wie PixelFormat.RGBA_8888 .

  • onResolutionUpdate(Size size) legt die Größe des Eingabebildes fest.

  • onImageFormatUpdate(int imageFormat) legt das Bildformat des Eingabebildes fest. Derzeit kann es nur YUV_420_888 sein.

Bilderfassungsprozessor

Für Standbilder können Sie einen Prozessor implementieren, indem Sie eine CaptureProcessorImpl Instanz mit ImageCaptureExtenderImpl.getCaptureProcessor . Der Prozessor ist dafür verantwortlich, eine Liste erfasster YUV_420_888 Bilder und TotalCaptureResult Instanzen zu verarbeiten und die Ausgabe in eine YUV_420_888 Oberfläche zu schreiben.

Sie können davon ausgehen, dass die Vorschau aktiviert ist und ausgeführt wird, bevor Sie die Standbildaufnahmeanforderung senden.

Sehen Sie sich den Ablauf im Diagramm unten an:

CaptureProcessor

Abbildung 7. Standbilderfassungsfluss mit CaptureProcessorImpl

  1. Camera2/X verwendet eine Oberfläche im YUV_420_888 -Format für die Standbildaufnahme, um die Aufnahmesitzung zu konfigurieren. Camera2/X bereitet CaptureProcessorImpl vor, indem es aufruft:

    • CaptureProcessorImpl.onImageFormatUpdate() mit YUV_420_888 .
    • CaptureProcessorImpl.onResolutionUpdate() mit der Eingabebildgröße.
    • CaptureProcessorImpl.onOutputSurface() mit einer Ausgabeoberfläche YUV_420_888 .
  2. ImageCaptureExtenderImpl.getCaptureStages gibt eine Liste von CaptureStageImpl zurück, wobei jedes Element einer CaptureRequest Instanz mit Aufnahmeparametern zugeordnet ist, die von Camera2/X gesendet werden. Wenn beispielsweise eine Liste mit drei CaptureStageImpl -Instanzen zurückgegeben wird, sendet Camera2/X drei Aufnahmeanforderungen mit entsprechenden Aufnahmeparametern unter Verwendung der captureBurst API.

  3. Die empfangenen Bilder und TotalCaptureResult Instanzen werden gebündelt und zur Verarbeitung an CaptureProcessorImpl gesendet.

  4. CaptureProcessorImpl schreibt das Ergebnisbild ( YUV_420_888 -Format) auf die durch den onOutputSurface() Aufruf angegebene Ausgabeoberfläche. Camera2/X wandelt es bei Bedarf in JPEG-Bilder um.

Support-Capture-Request-Keys und -Ergebnisse

Zusätzlich zur Kameravorschau und -aufnahme können Apps Zoom- und Blitzparameter einstellen oder ein Tap-to-Focus auslösen. Diese Parameter sind möglicherweise nicht mit Ihrer Erweiterungsimplementierung kompatibel.

Die folgenden Methoden wurden zu extensions-interface 1.3.0 hinzugefügt, damit Sie die Parameter verfügbar machen können, die Ihre Implementierung unterstützt:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() gibt die Erfassungsanforderungsschlüssel zurück, die von Ihrer Implementierung unterstützt werden.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() gibt die Erfassungsergebnisschlüssel zurück, die im Erfassungsergebnis enthalten sind.

Wenn die HAL der Kamera die Erweiterung verarbeitet, ruft Camera2/X die Erfassungsergebnisse in CameraCaptureSession.CaptureCallback ab. Wenn der Prozessor jedoch implementiert ist, ruft Camera2/X die Erfassungsergebnisse in ProcessResultImpl ab, die an die Methode process() in PreviewImageProcessorImpl und CaptureProcessorImpl . Sie sind dafür verantwortlich, das Erfassungsergebnis über ProcessResultImpl an Camera2/X zu melden.

Sehen Sie sich die Definition der CaptureProcessorImpl Schnittstelle unten als Beispiel an. In extensions-interface 1.3.0 oder höher wird der zweite Aufruf von process() aufgerufen:

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

Für gängige Kamerafunktionen wie Zoomen, Tippen zum Fokussieren, Blitz und Belichtungskorrektur empfehlen wir, die folgenden Tasten sowohl für die Aufnahmeanforderung als auch für das Aufnahmeergebnis zu unterstützen:

  • Zoomen:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Tippen zum Fokussieren:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Blinken:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Belichtungsausgleich:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Für Basic Extender, die 1.2.0 oder frühere Versionen implementieren, unterstützt die CameraX Extensions API ausdrücklich alle oben genannten Schlüssel. Für extensions-interface 1.3.0 berücksichtigen sowohl CameraX als auch Camera2 die zurückgegebene Liste und unterstützen nur die darin enthaltenen Schlüssel. Wenn Sie sich beispielsweise entscheiden, nur CaptureRequest#CONTROL_ZOOM_RATIO und CaptureRequest#SCALER_CROP_REGION in der 1.3.0-Implementierung zurückzugeben, bedeutet dies, dass nur Zoom für die App unterstützt wird, während Tap-to-Focus, Blitz und Belichtungskorrektur nicht zulässig sind.

Erweiterter Extender

Advanced Extender ist eine Art von Anbieterimplementierung, die auf der Camera2-API basiert. Dieser Extender-Typ wurde in extensions-interface 1.2.0 hinzugefügt. Je nach Gerätehersteller können Erweiterungen im App-Layer implementiert werden, was von folgenden Faktoren abhängt:

  • Benutzerdefinierte Stream- Konfiguration: Konfigurieren Sie benutzerdefinierte Streams wie RAW-Stream oder haben Sie mehrere Streams für verschiedene physische Kamera-IDs.

  • Fähigkeit zum Senden von Camera2-Anfragen: Unterstützung einer komplizierten Interaktionslogik, die Aufnahmeanfragen mit Parametern senden kann, die auf den Ergebnissen früherer Anfragen basieren.

Advanced Extender bietet einen Wrapper oder eine Zwischenschicht, sodass Sie die Stream-Konfiguration anpassen und bei Bedarf Erfassungsanforderungen senden können.

Zu implementierende Dateien

Um zur Advanced Extender-Implementierung zu wechseln, muss die Methode isAdvancedExtenderImplemented() in ExtensionVersionImpl true zurückgeben. Für jeden Erweiterungstyp müssen OEMs die entsprechenden Extender-Klassen implementieren. Die Advanced Extender-Implementierungsdateien befinden sich im Advanced -Paket.

Zu implementierende Extender-Klassen
Nacht advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Auto advanced/AutoAdvancedExtenderImpl.java
Bokeh advanced/BokehAdvancedExtenderImpl.java
Gesichtsretusche advanced/BeautyAdvancedExtenderImpl.java

Im folgenden Beispiel verwenden wir AdvancedExtenderImpl als Platzhalter. Ersetzen Sie ihn durch den Namen der Extender-Datei für die Erweiterung, die Sie implementieren.

Sehen wir uns an, wie Camera2/X die extensions-interface Flows zu erreichen.

App-Flow 1: Überprüfen Sie die Verfügbarkeit von Erweiterungen

AdvancedAppFlow1

Abbildung 8. App-Flow 1 auf Advanced Extender

Zunächst prüft die App, ob die angegebene Erweiterung unterstützt wird.

App-Flow 2: Informationen abfragen

AdvancedAppFlow2

Abbildung 9. App-Flow 2 auf Advanced Extender

Nach dem Aufruf von AdvancedExtenderImpl.init() kann die App die folgenden Informationen zu AdvancedExtenderImpl abfragen:

  • Geschätzte Standbilderfassungslatenz: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() gibt den Bereich der Erfassungslatenz zurück, damit die App auswerten kann, ob es angemessen ist, die Erweiterung für das aktuelle Szenario zu aktivieren.

  • Unterstützte Auflösungen für Vorschau und Standbildaufnahme:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() gibt eine Abbildung des Bildformats an die Größenliste zurück, die für Format und Größe der Vorschauoberfläche unterstützt werden. OEMs müssen mindestens das PRIVATE -Format unterstützen.

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() gibt das unterstützte Format und die unterstützten Größen für die Standbildaufnahmefläche zurück. OEMs müssen die Ausgabe im JPEG und YUV_420_888 -Format unterstützen.

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() gibt die unterstützten Größen für einen zusätzlichen YUV_420_888 Stream für die Bildanalyse zurück. Wenn die YUV-Oberfläche der Bildanalyse nicht unterstützt wird, sollte getSupportedYuvAnalysisResolutions() null oder eine leere Liste zurückgeben.

  • Verfügbare Erfassungsanforderungsschlüssel/Ergebnisse (hinzugefügt in extensions-interface 1.3.0): Camera2/X ruft die folgenden Methoden auf, um die unterstützten Erfassungsanforderungsschlüssel und Ergebnisschlüssel aus Ihrer Implementierung abzurufen:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Weitere Informationen finden Sie unter Schlüssel und Ergebnisse für Support-Erfassungsanforderungen .

App-Flow 3: Vorschau/Standbildaufnahme mit aktivierter Erweiterung

AdvancedAppFlow3

Abbildung 10. App-Flow 3 auf Advanced Extender

Das obige Diagramm zeigt den Hauptfluss zum Starten der Vorschau und Standbilderfassung für den Advanced Extender-Typ. Lassen Sie uns jeden Schritt durchgehen.

  1. SessionProcessorImpl Instanz

    Die Kernimplementierung von Advanced Extender befindet sich in SessionProcessorImpl , das für die Bereitstellung einer benutzerdefinierten Sitzungskonfiguration und das Senden von Erfassungsanforderungen zum Initiieren der Vorschau- und Still-Erfassungsanforderung verantwortlich ist. AdvancedExtenderImpl.createSessionProcessor() wird aufgerufen, um die SessionProcessorImpl Instanz zurückzugeben.

  2. initSession

    SessionProcessorImpl.initSession() initialisiert die Sitzung für die Erweiterung. Hier weisen Sie Ressourcen zu und geben eine Sitzungskonfiguration zum Vorbereiten einer CameraCaptureSession zurück.

    Für die Eingabeparameter spezifiziert Camera2/X die Ausgabeoberflächenkonfigurationen für Vorschau, Standbildaufnahme und eine optionale YUV-Bildanalyse. Diese Konfiguration der Ausgabeoberfläche ( OutputSurfaceImpl ) enthält die Oberfläche, die Größe und das Bildformat, die durch die folgenden Methoden in AdvancedExtenderImpl abgerufen werden:

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

    Sie müssen eine Camera2SessionConfigImpl Instanz zurückgeben, die aus einer Liste von Camera2OutputConfigImpl Instanzen und den Sitzungsparametern besteht, die zum Konfigurieren von CameraCaptureSession verwendet werden. Sie sind dafür verantwortlich, dass die korrekten Kamerabilder an die von Camera2/X übergebenen Ausgabeoberflächen ausgegeben werden. Hier sind einige Optionen, um die Ausgabe zu aktivieren:

    • Verarbeitung in Kamera-HAL: Sie können die Ausgabeoberflächen mit einer SurfaceOutputConfigImpl Implementierung direkt zu CameraCaptureSession hinzufügen. Dies konfiguriert die bereitgestellte Ausgabeoberfläche für die Kamera-Pipeline und ermöglicht der Kamera-HAL, das Bild zu verarbeiten.
    • Verarbeitung der ImageReader -Zwischenoberfläche (RAW, YUV usw.): Fügen Sie die ImageReader -Zwischenoberflächen mit einer ImageReaderOutputConfigImpl -Instanz zur CameraCaptureSession hinzu.

      Sie müssen die Zwischenbilder verarbeiten und das Ergebnisbild auf die Ausgabeoberfläche schreiben.

    • Gemeinsame Nutzung der Kamera2-Oberfläche: Verwenden Sie die gemeinsame Nutzung der Oberfläche mit einer anderen Oberfläche, indem Sie eine beliebige Camera2OutputConfigImpl Instanz zur getSurfaceSharingOutputConfigs() Methode einer anderen Camera2OutputConfigImpl Instanz hinzufügen. Das Oberflächenformat und die Größe müssen identisch sein.

    Alle Camera2OutputConfigImpl einschließlich SurfaceOutputConfigImpl und ImageReaderOutputConfigImpl müssen über eine eindeutige ID ( getId() ) verfügen, die verwendet wird, um die Zieloberfläche anzugeben und das Bild von ImageReaderOutputConfigImpl abzurufen.

  3. onCaptureSessionStart und RequestProcessorImpl

    Wenn CameraCaptureSession gestartet wird und das Kamera-Framework onConfigured() aufruft, ruft Camera2/X SessionProcessorImpl.onCaptureSessionStart() mit dem Camera2-Anforderungswrapper RequestProcessImpl auf. Camera2/X implementiert RequestProcessImpl , mit dem Sie die Aufnahmeanforderungen ausführen und Bilder abrufen können, wenn ImageReaderOutputConfigImpl verwendet wird.

    Die RequestProcessImpl -APIs ähneln den Camera2 CameraCaptureSession -APIs in Bezug auf die Ausführung von Anforderungen. Die Unterschiede sind:

    • Die Zieloberfläche wird durch die ID der Camera2OutputConfigImpl Instanz angegeben.
    • Die Fähigkeit, das Bild des ImageReader abzurufen.

    Sie können RequestProcessorImpl.setImageProcessor() mit einer angegebenen Camera2OutputConfigImpl ID aufrufen, um eine ImageProcessorImpl -Instanz zum Empfangen von Bildern zu registrieren.

    Die RequestProcessImpl -Instanz wird ungültig, nachdem Camera2/X SessionProcessorImpl.onCaptureSessionEnd() .

  4. Starten Sie die Vorschau und machen Sie ein Foto

    In der Advanced Extender-Implementierung können Sie Erfassungsanforderungen über die RequestProcessorImpl -Schnittstelle senden. Camera2/X benachrichtigt Sie, die wiederholte Anforderung für die Vorschau oder die Standbildaufnahmesequenz durch Aufrufen von SessionProcessorImpl#startRepeating bzw. SessionProcessorImpl#startCapture zu starten. Sie sollten Aufnahmeanfragen senden, um diese Vorschau- und Standbildaufnahmeanfragen zu erfüllen.

    Camera2/X legt auch die Erfassungsanforderungsparameter über SessionProcessorImpl#setParameters . Sie müssen diese Anforderungsparameter (falls Parameter unterstützt werden) sowohl für die wiederholten als auch für die einzelnen Anforderungen festlegen.

    Sie müssen mindestens CaptureRequest.JPEG_ORIENTATION und CaptureRequest.JPEG_QUALITY . extensions-interface 1.3.0 unterstützt Anforderungs- und Ergebnisschlüssel, die durch die folgenden Methoden verfügbar gemacht werden:

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

    Wenn Entwickler die Schlüssel in der Liste getAvailableCaptureRequestKeys , müssen Sie die Parameter aktivieren und sicherstellen, dass das Erfassungsergebnis die Schlüssel in der Liste getAvailableCaptureResultKeys enthält.

  5. startTrigger

    SessionProcessorImpl.startTrigger() wird aufgerufen, um den Trigger wie CaptureRequest.CONTROL_AF_TRIGGER und CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER zu starten. Sie können alle Erfassungsanforderungsschlüssel ignorieren, die nicht in AdvancedExtenderImpl.getAvailableCaptureRequestKeys() angekündigt wurden.

    startTrigger() wird seit extensions-interface 1.3.0 unterstützt. Es ermöglicht Apps, Tap-to-Focus und Flash mit Erweiterungen zu implementieren.

  6. Aufräumen

    Beim Beenden einer Aufnahmesitzung wird SessionProcessorImpl.onCaptureSessionEnd() vor dem Schließen von CameraCaptureSession aufgerufen. Nachdem die Erfassungssitzung geschlossen wurde, führt deInitSession() die Bereinigung durch.

Unterstützt Vorschau, Standbildaufnahme und Bildanalyse

Sie sollten die Erweiterung sowohl für die Vorschau- als auch für die Standbildaufnahme-Anwendungsfälle anwenden. Wenn die Latenz jedoch zu hoch ist, um die Vorschau reibungslos anzuzeigen, können Sie den Effekt nur auf die Standbildaufnahme anwenden.

Für den Basic Extender-Typ müssen Sie unabhängig davon, ob Sie den Effekt für die Vorschau aktivieren, sowohl ImageCaptureExtenderImpl als PreviewExtenderImpl für eine bestimmte Erweiterung implementieren. Often, an app also uses a YUV stream to analyze the image content such as finding QR codes or text. To better support this use case , you should support the stream combination of preview, still capture, and a YUV_420_888 stream for configuring CameraCaptureSession . This means that if you implement a processor, then you have to support the stream combination of three YUV_420_888 streams.

For Advanced Extender, Camera2/X passes three output surfaces to the SessionProcessorImpl.initSession() call. These output surfaces are for preview , still capture, and image analysis, respectively. You must ensure that preview and still capture output surfaces show the valid output. However, for the image analysis output surface, ensure it's working only when it's non-null. If your implementation can't support the image analysis stream, you can return an empty list in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . This ensures the image analysis output surface is always null in SessionProcessorImpl.initSession() .

Support video capture

The current Camera Extension architecture supports only the preview and still capture use cases. We don't support enabling the extension on the MediaCodec or MediaRecorder surfaces for recording the video. However, it's possible for apps to record the preview output.

Supporting MediaCodec and MediaRecorder surfaces is under investigation.

Extensions interface version history

The following table shows the Camera Extension interface version history. You should always implement the vendor library with the latest version.

Version Added features
1.0.0
  • Version verification
    • ExtensionVersionImpl
  • Basic Extender
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Library initialization
    • InitializerImpl
  • Expose supported resolutions
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Get estimated capture latency
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Expose supported capture request keys/results keys
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • New process() call that takes ProcessResultImpl in PreviewImageProcessorImpl and CaptureProcessorImpl
    • Support trigger type request
      • AdvancedExtenderImpl.startTrigger

Reference implementation

For a reference OEM vendor library implementation, see camera-testlib-extensions . Note that this implementation performs passthroughs without actually implementing the effects.

Set up the vendor library on a device

The OEM vendor library isn't built into an app; it's loaded from the device at runtime by Camera2/X. In CameraX, the <uses-library> tag declares that the androidx.camera.extensions.impl library, which is defined in the AndroidManifest.xml file of the camera-extensions library, is a dependency of CameraX and must be loaded at runtime. In Camera2, the framework loads an extensions service that also declares that the <uses-library> loads the same androidx.camera.extensions.impl library at runtime.

This allows third-party apps using extensions to automatically load the OEM vendor library. The OEM library is marked as optional so apps can run on devices that don't have the library on the device. Camera2/X handles this behavior automatically when an app tries to use a camera extension as long as the device manufacturer places the OEM library on the device so that it can be discovered by the app.

To set up the OEM library on a device, do the following:

  1. Add a permission file, which is required by the <uses-library> tag, using the following format: /etc/permissions/ ANY_FILENAME .xml . For example, /etc/permissions/camera_extensions.xml . The files in this directory provide a mapping of the library named in <uses-library> to the actual file path on the device.
  2. Use the example below to add the required information to the file.

    • name must be androidx.camera.extensions.impl as that's the library that CameraX searches for.
    • file is the absolute path of the file that contains the extensions implementation (for example, /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 or higher, devices supporting CameraX extensions must have the ro.camerax.extensions.enabled property set to true , which allows for querying whether a device supports extensions. To do this, add the following line in the device make file:

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

Validation

To test your implementation of the OEM vendor library during the development stage, use the example app at androidx-main/camera/integration-tests/extensionstestapp/ , which runs through various vendor extensions.

After you complete your implementation, use the Camera Extensions Validation Tool to run automated and manual tests to verify that the vendor library is implemented correctly.

Extended scene mode versus Camera Extensions

For the bokeh effect, in addition to exposing it using Camera Extensions, you can expose the effect using the extended scene mode, which is enabled through the CONTROL_EXTENDED_SCENE_MODE key. For more implementation details, see Camera Bokeh .

Extended scene mode has fewer restrictions compared to Camera Extensions for camera2 apps. For example, you can enable extended scene mode in a regular CameraCaptureSession instance that supports flexible stream combinations and capture request parameters. In contrast, camera extensions support only a fixed set of stream types and have limited support for capture request parameters.

A downside of extended scene mode is that you can only implement it in the camera HAL, which means that it must be verified to work across all orthogonal controls available to app developers.

We recommend exposing bokeh using both the extended scene mode and Camera Extensions because apps might prefer to use a particular API to enable bokeh. We recommend first using the extended scene mode because this is the most flexible way for apps to enable the bokeh effect. Then you can implement the camera extensions interface based on the extended scene mode. If implementing bokeh in the camera HAL is difficult, for example, because it requires a post processor running in the app layer to process images, we recommend implementing the bokeh effect using the Camera Extensions interface.

Frequently asked questions (FAQs)

Are there any restrictions on API levels?

Yes. This depends on the Android API feature set that's required by the OEM vendor library implementation. For example, ExtenderStateListener.onPresetSession() uses the SessionConfiguration.setSessionParameters() call to set a baseline set of tags. This call is available only on API level 28 and higher. For details on specific interface methods, see the API reference documentation .