Gerätehersteller können Drittanbietern über die Kameraerweiterungs-Schnittstelle der OEM-Anbieterbibliothek Erweiterungen wie Bokeh, Nachtmodus und HDR zur Verfügung stellen. Entwickler können die Camera2 Extensions API und die CameraX Extensions API verwenden, um auf die in der OEM-Anbieterbibliothek implementierten Erweiterungen zuzugreifen.
Eine Liste der unterstützten Erweiterungen, die für Camera2 und CameraX identisch ist, finden Sie unter CameraX Extensions API. Wenn Sie eine Erweiterung hinzufügen möchten, melden Sie einen Fehler über den Issue Tracker.
Auf dieser Seite wird beschrieben, wie Sie die OEM-Anbieterbibliothek auf Geräten implementieren und aktivieren.
Architektur
Das folgende Diagramm beschreibt die Architektur der Kameraerweiterungs-API oder extensions-interface
:
Abbildung 1. Architekturdiagramm für Kameraerweiterungen
Wie im Diagramm dargestellt, müssen Sie die extensions-interface
implementieren, die von der OEM-Anbieterbibliothek bereitgestellt wird, um Kameraerweiterungen zu unterstützen. Ihre OEM-Anbieterbibliothek ermöglicht zwei APIs: die CameraX Extensions API und die Camera2 Extensions API. Sie werden von CameraX- und Camera2-Apps verwendet, um auf Anbietererweiterungen zuzugreifen.
OEM-Anbieterbibliothek implementieren
Um die OEM-Anbieterbibliothek zu implementieren, kopieren Sie die Dateien camera-extensions-stub
in ein Systembibliotheksprojekt. Diese Dateien definieren die Benutzeroberfläche der Kameraerweiterungen.
Die camera-extensions-stub
-Dateien sind in die folgenden Kategorien unterteilt:
Wichtige Benutzeroberflächendateien (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
Erforderliche Implementierungen (Implementierung hinzufügen)
ExtensionVersionImpl.java
InitializerImpl.java
Bokeh-Erweiterungsklassen (implementieren, wenn Bokeh-Erweiterung unterstützt wird)
BokehImageCaptureExtenderImpl.java
BokehPreviewExtenderImpl.java
advanced/BokehAdvancedExtenderImpl.java
Kurse für die Nachtzeiterweiterung (implementieren, wenn die Nachtzeiterweiterung unterstützt wird)
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
advanced/NightAdvancedExtenderImpl.java
Auto-Extender-Klassen (implementieren, wenn die automatische Erweiterung unterstützt wird)
AutoImageCaptureExtenderImpl.java
AutoPreviewExtenderImpl.java
advanced/AutoAdvancedExtenderImpl.java
HDR-Extender-Klassen (implementieren, wenn HDR-Erweiterung unterstützt wird)
HdrImageCaptureExtenderImpl.java
HdrPreviewExtenderImpl.java
advanced/HdrAdvancedExtenderImpl.java
Erweiterungsklassen für die Gesichtsretusche (implementieren, wenn die Erweiterung für die Gesichtsretusche 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 Sie fest, dass isExtensionAvailable()
false
zurückgibt, oder entfernen Sie die entsprechenden Extender-Klassen. Die Camera2- und CameraX-Erweiterungen-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-Ablauf anhand der Night-Erweiterung:
Abbildung 2. Implementierung der Nachterweiterung
Versionsüberprüfung:
Camera2/X ruft
ExtensionVersionImpl.checkApiVersion()
auf, um sicherzustellen, dass die vom OEM implementierteextensions-interface
-Version mit den von Camera2/X unterstützten Versionen kompatibel ist.Initialisierung der Anbieterbibliothek:
InitializerImpl
hat eine Methodeinit()
, die die Anbieterbibliothek initialisiert. Camera2/X führt die Initialisierung durch, bevor auf die Extender-Klassen zugegriffen wird.Erstellen Sie Extender-Klassen:
Instantiiert die Extender-Klassen für die Erweiterung. Es gibt zwei Arten von Extendern: Basic Extender und Advanced Extender. Sie müssen einen Erweiterungstyp für alle Erweiterungen implementieren. Weitere Informationen finden Sie unter Einfache und erweiterte Extender vergleichen.
Camera2/X erstellt Instanzen der Extender-Klassen und interagiert mit ihnen, 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 aufwendigen Initialisierungen im Konstruktor oder im
init()
-Aufruf durch. Die aufwendigen Aufgaben sollten Sie erst dann ausführen, wenn die Kamerasitzung kurz bevorsteht, z. B. wennonInit()
im Basic Extender oderinitSession()
im Advanced Extender aufgerufen wird.Für die Nachterweiterung werden die folgenden Extender-Klassen für den Typ „Basic Extender“ instanziiert:
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
Für den erweiterten Extendertyp:
NightAdvancedExtenderImpl.java
Verfügbarkeit der Erweiterung prüfen:
Bevor die Erweiterung aktiviert wird, prüft
isExtensionAvailable()
, ob sie über die Extender-Instanz für die angegebene Kamera-ID verfügbar ist.Erweiterer mit Kamerainformationen initialisieren:
Camera2/X ruft
init()
in der Extender-Instanz auf und übergibt die Kamera-ID undCameraCharacteristics
.Abfrageinformationen:
Ruft die Extender-Klasse auf, um Informationen wie unterstützte Auflösungen abzurufen, die geschätzte Latenz zu erfassen und Anfrageschlüssel vom Extender zu erfassen, um die Erweiterung zu aktivieren.
Erweiterung auf dem Extender aktivieren:
Die Extender-Klasse stellt alle Schnittstellen bereit, die zum Aktivieren der Klasse erforderlich sind. Es bietet einen Mechanismus, mit dem die OEM-Implementierung in die Camera2-Pipeline eingebunden werden kann, z. B. durch Einschleusen von Aufnahmeanfrageparametern oder Aktivieren eines Postprozessors.
Beim erweiterten Extender-Typ interagiert Camera2/X mit
SessionProcessorImpl
, um die Erweiterung zu aktivieren. Camera2/X ruft dieSessionProcessorImpl
-Instanz ab, indemcreateSessionProcessor()
auf dem Extender aufgerufen wird.
In den folgenden Abschnitten wird der Ablauf der Erweiterung ausführlicher beschrieben.
Versionsüberprüfung
Beim Laden der OEM-Anbieterbibliothek vom Gerät zur Laufzeit prüft Camera2/X, ob die Bibliothek mit der extensions-interface
-Version kompatibel ist.
Die extensions-interface
verwendet die semantische Versionierung, also MAJOR.MINOR.PATCH, z. B. 1.1.0 oder 1.2.0. Bei der Versionsüberprüfung werden jedoch nur die Haupt- und die Nebenversion verwendet.
Zur Überprüfung der Version ruft Camera2/X ExtensionVersionImpl.checkApiVersion()
mit der unterstützten extensions-interface
-Version auf. Camera2/X verwendet dann die von der OEM-Bibliothek gemeldete Version, um zu ermitteln, ob die Erweiterung aktiviert werden kann und welche Funktionen sie aufrufen soll.
Kompatibilität mit Hauptversionen
Wenn sich die Hauptversionen der Erweiterungsoberfläche zwischen Camera2/X und der Anbieterbibliothek unterscheiden, wird sie als nicht kompatibel eingestuft und deaktiviert.
Abwärtskompatibilität
Solange die Hauptversion identisch ist, sorgt Camera2/X für Abwärtskompatibilität mit OEM-Bibliotheken von Anbietern, die mit früheren extensions-interface
-Versionen erstellt wurden. Wenn Camera2/X beispielsweise extensions-interface
1.3.0 unterstützt, sind die OEM-Anbieterbibliotheken, die 1.0.0, 1.1.0 und 1.2.0 implementiert haben, weiterhin kompatibel. Das bedeutet auch, dass nach der Implementierung einer bestimmten Version der Anbieterbibliothek Camera2/X dafür sorgt, dass die Bibliothek abwärtskompatibel mit zukünftigen extension-interface
-Versionen ist.
Vorwärtskompatibilität
Die zukünftige Kompatibilität mit Anbieterbibliotheken neuerer extensions-interface
hängt von Ihnen als OEM ab. Wenn Sie einige Funktionen für die Implementierung der Erweiterungen benötigen, sollten Sie die Erweiterungen ab einer bestimmten Version aktivieren. In diesem Fall können Sie die unterstützte extensions-interface
-Version zurückgeben, wenn die Camera2/X-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 Anbieterbibliothek
Nachdem die von der OEM-Bibliothek implementierte extensions-interface
-Version überprüft wurde, startet Camera2/X den Initialisierungsprozess. Die Methode InitializerImpl.init()
signalisiert der OEM-Bibliothek, dass eine App versucht, Erweiterungen zu verwenden.
Camera2/X ruft die OEM-Bibliothek (abgesehen von der Versionsprüfung) nicht noch einmal auf, bis die OEM-Anbieterbibliothek OnExtensionsInitializedCallback.onSuccess()
aufruft, um über den Abschluss der Initialisierung zu informieren.
Sie müssen InitializerImpl
ab extensions-interface
1.1.0 implementieren. Camera2/X überspringt den Schritt zur Bibliothekinitialisierung, wenn die OEM-Anbieterbibliothek extensions-interface
1.0.0 implementiert.
Einfacher und erweiterter Repeater im Vergleich
Es gibt zwei Arten von extensions-interface
-Implementierungen: Basic Extender und Advanced Extender. Der erweiterte Extender wird seit extensions-interface
1.2.0 unterstützt.
Implementieren Sie den Basic Extender für Erweiterungen, die Bilder in der HAL der Kamera verarbeiten, oder verwenden Sie einen Postprozessor, der YUV-Streams verarbeiten kann.
Implementieren Sie den erweiterten Extender für Erweiterungen, bei denen die Camera2-Streamkonfiguration angepasst und nach Bedarf Aufnahmeanfragen gesendet werden müssen.
In der folgenden Tabelle finden Sie einen Vergleich:
Einfacher Extender | Erweiterter Extender | |
---|---|---|
Streamkonfigurationen | Gefixt Vorschau: PRIVATE oder YUV_420_888 (falls Prozessor vorhanden) Standbildaufnahme: JPEG oder YUV_420_888 (falls Prozessor vorhanden)
|
Von OEMs anpassbar. |
Aufzeichnungsanfrage senden | Nur Camera2/X kann Aufnahmeanfragen senden. Sie können die Parameter für diese Anfragen festlegen. Wenn der Prozessor für die Bildaufnahme bereitgestellt wird, kann Camera2/X mehrere Aufnahmeanfragen senden und alle Bilder und Aufnahmeergebnisse an den Prozessor senden. | Sie erhalten eine RequestProcessorImpl -Instanz, um die camera2-Aufnahmeanfrage auszuführen und Ergebnisse und Bilder zu erhalten.
Camera2/X ruft |
Hooks in der Kamerapipeline |
|
|
Geeignet für | Erweiterungen, die in der HAL der Kamera oder in einem Prozessor implementiert sind, der YUV-Bilder verarbeitet. |
|
Unterstützte API-Version | Camera2 Extensions: Android 13 oder höher CameraX Extensions: camera-extensions 1.1.0 oder höher |
Camera2 Extensions: Android 12L oder höher CameraX Extensions: camera-extensions 1.2.0-alpha03 oder höher |
App-Abläufe
In der folgenden Tabelle sind drei Arten von App-Abläufen und die zugehörigen Camera Extensions API-Aufrufe aufgeführt. Camera2/X stellen diese APIs bereit, aber Sie müssen die Anbieterbibliothek richtig implementieren, um diese Abläufe zu unterstützen. Wie das geht, wird in einem späteren Abschnitt ausführlicher beschrieben.
Camera2-Erweiterungen | CameraX-Erweiterungen | |
---|---|---|
Verfügbarkeit von Suchanfragenerweiterungen | CameraExtensionCharacteristics
.getSupportedExtensions
|
ExtensionsManager.
isExtensionAvailable
|
Abfrageinformationen | CameraExtensionCharacteristics.
getExtensionSupportedSizes
CameraExtensionCharacteristics.
getEstimatedCaptureLatencyRangeMillis
CameraExtensionCharacteristics.
getAvailableCaptureRequestKeys
CameraExtensionCharacteristics.
getAvailableCaptureResultKeys
|
ExtensionsManager.
getEstimatedCaptureLatencyRange
CameraX verarbeitet die restlichen Informationen in der Bibliothek. |
Vorschau und Standbilder mit aktivierter Erweiterung | CameraDevice.
createExtensionSession
|
val cameraSelector = ExtensionsManager.
getExtensionEnabledCameraSelector
|
Einfacher Extender
Die Basic Extender-Oberfläche bietet mehrere Anknüpfungspunkte in der Kamerapipeline. Für jeden Erweiterungstyp gibt es entsprechende Extender-Klassen, die OEMs implementieren müssen.
In der folgenden Tabelle sind die Extender-Klassen aufgeführt, die OEMs für jede Erweiterung implementieren müssen:
Zu implementierende Erweiterungsklassen | |
---|---|
Nacht | NightPreviewExtenderImpl.java
|
HDR | HdrPreviewExtenderImpl.java
|
Automatisch | AutoPreviewExtenderImpl.java
|
Bokeh | BokehPreviewExtenderImpl.java
|
Gesichtsretusche | BeautyPreviewExtenderImpl.java
|
Im folgenden Beispiel werden PreviewExtenderImpl
und ImageCaptureExtenderImpl
als Platzhalter verwendet. Ersetzen Sie diese durch die Namen der tatsächlichen Dateien, die Sie implementieren.
Der einfache Extender bietet folgende Funktionen:
- Füge Sitzungsparameter ein, wenn du
CameraCaptureSession
(onPresetSession
) konfigurierst. - Sie werden über die Ereignisse zum Starten und Schließen der Aufnahmesitzung benachrichtigt und es wird eine einzelne Anfrage gesendet, um die HAL mit den zurückgegebenen Parametern (
onEnableSession
,onDisableSession
) zu benachrichtigen. - Fügen Sie Erfassungsparameter für die Anfrage ein (
PreviewExtenderImpl.getCaptureStage
,ImageCaptureExtenderImpl.getCaptureStages
). - Fügen Sie Prozessoren für die Vorschau und die Aufzeichnung hinzu, die den
YUV_420_888
-Stream verarbeiten können.
Sehen wir uns an, wie Camera2/X die extensions-interface
aufruft, um die drei oben genannten App-Abläufe zu erreichen.
App-Ablauf 1: Verfügbarkeit der Erweiterung prüfen
Abbildung 3 App-Ablauf 1 auf Basis-Extender
In diesem Ablauf ruft Camera2/X die isExtensionAvailable()
-Methode von PreviewExtenderImpl
und ImageCaptureExtenderImpl
direkt auf, ohne init()
aufzurufen. Beide Extender-Klassen müssen true
zurückgeben, um die Erweiterungen zu aktivieren.
Häufig ist dies der erste Schritt, bei dem Apps prüfen, ob der angegebene Erweiterungstyp für eine bestimmte Kamera-ID unterstützt wird, bevor die Erweiterung aktiviert wird. Das liegt daran, dass einige Erweiterungen nur für bestimmte Kamera-IDs unterstützt werden.
App-Ablauf 2: Informationen abfragen
Abbildung 4 App-Ablauf 2 auf einfachem Extender
Nachdem festgestellt wurde, ob die Erweiterung verfügbar ist, sollten Apps die folgenden Informationen abfragen, bevor sie die Erweiterung aktivieren.
Bereich der Latenz bei der Aufnahme von Standbildern:
ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
gibt den Bereich der Aufnahmelatenz für die App zurück, um zu beurteilen, ob die Verlängerung für das aktuelle Szenario aktiviert werden soll.Unterstützte Größen für die Vorschau- und Aufnahmefläche:Mit
ImageCaptureExtenderImpl.getSupportedResolutions
undPreviewExtenderImpl.getSupportedResolutions
wird eine Liste der Bildformate und ‑größen zurückgegeben, die für das Oberflächenformat und die Oberflächengröße unterstützt werden.Unterstützte Anfrage- und Ergebnisschlüssel:Camera2/X ruft die folgenden Methoden auf, um die unterstützten Schlüssel für Aufnahmeanfragen und Ergebnisschlüssel aus Ihrer Implementierung abzurufen:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
Camera2/X ruft immer zuerst init()
für diese Extender-Klassen auf, bevor weitere Informationen abgefragt werden.
App-Ablauf 3: Vorschau/Standbildaufnahme mit aktivierter Erweiterung (HAL-Implementierung)
Abbildung 5. App-Ablauf 3 auf einem einfachen Extender
Das obige Diagramm veranschaulicht den Hauptablauf zum Aktivieren der Vorschau und der Aufnahme von Standbildern 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
auf, wodurch Sie benachrichtigt werden, dass eine Kamerasitzung mit den angegebenen Erweiterungen gestartet wird.
Die aufwendige Initialisierung können Sie in onInit()
vornehmen.
Bei der Konfiguration von CameraCaptureSession
ruft Camera2/X onPresetSession
auf, um die Sitzungsparameter abzurufen. Nachdem die Aufnahmesitzung erfolgreich konfiguriert wurde, ruft Camera2/X onEnableSession
auf und gibt eine CaptureStageImpl
-Instanz zurück, die die Aufnahmeparameter enthält. Camera2/X sendet sofort eine einzelne Anfrage mit diesen Aufnahmeparametern, um den HAL zu benachrichtigen. Ähnlich wird vor dem Schließen der Aufnahmesitzung onDisableSession
von Camera2/X aufgerufen und dann eine einzelne Anfrage mit den zurückgegebenen Aufnahmeparametern gesendet.
Die von Camera2/X ausgelöste wiederholte Anfrage enthält die von PreviewExtenderImpl.getCaptureStage()
zurückgegebenen Anfrageparameter. Außerdem enthält die Anfrage zur Aufnahme von Standbildern 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()
freigeben.
Vorschauprozessor
Neben der HAL für die Kamera können Sie auch Erweiterungen in einem Prozessor implementieren.
Implementieren Sie PreviewExtenderImpl.getProcessorType
, um den Prozessortyp anzugeben, wie unten beschrieben:
PROCESSOR_TYPE_NONE
:Kein Prozessor. Bilder werden im HAL der Kamera verarbeitet.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY
:Mit dem Prozessortyp können Sie die wiederkehrende Anfrage mit neuen Parametern für die Erfassungsanfrage basierend auf der neuestenTotalCaptureResult
aktualisieren.PreviewExtenderImpl.getProcessor
muss eineRequestUpdateProcessorImpl
-Instanz zurückgeben, die dieTotalCaptureResult
-Instanz verarbeitet und eineCaptureStageImpl
-Instanz zurückgibt, um die wiederkehrende Anfrage zu aktualisieren.PreviewExtenderImpl.getCaptureStage()
sollte auch das Ergebnis der Verarbeitung widerspiegeln und den neuestenCaptureStageImpl
zurückgeben.PROCESSOR_TYPE_IMAGE_PROCESSOR
:Mit diesem Typ können Sie einen Prozessor implementieren, umYUV_420_888
-Bilder zu verarbeiten und die Ausgabe auf einePRIVATE
-Oberfläche zu schreiben.Sie müssen eine
PreviewImageProcessorImpl
-Instanz inPreviewExtenderImpl.getProcessor
implementieren und zurückgeben. Der Zahlungsabwickler ist für die Verarbeitung vonYUV_420_888
Eingabebildern verantwortlich. Die Ausgabe sollte imPRIVATE
-Format der Vorschau geschrieben werden. In Camera2/X wird anstelle vonPRIVATE
eineYUV_420_888
-Oberfläche verwendet, um dieCameraCaptureSession
für die Vorschau zu konfigurieren.Der Ablauf ist in der folgenden Abbildung dargestellt:
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. BeiPreviewImageProcessorImpl
istimageFormat
ein Pixelformat wiePixelFormat.RGBA_8888
.Mit
onResolutionUpdate(Size size)
wird die Größe des Eingabebilds festgelegt.onImageFormatUpdate(int imageFormat)
legt das Bildformat des Eingabebilds fest. Derzeit ist nurYUV_420_888
zulässig.
Bilderfassungsprozessor
Für die Standbildaufnahme können Sie einen Prozessor implementieren, indem Sie mit ImageCaptureExtenderImpl.getCaptureProcessor
eine CaptureProcessorImpl
-Instanz zurückgeben. Der Prozessor ist dafür verantwortlich, eine Liste der erfassten YUV_420_888
-Bilder und TotalCaptureResult
-Instanzen zu verarbeiten und die Ausgabe auf eine YUV_420_888
-Oberfläche zu schreiben.
Sie können davon ausgehen, dass die Vorschau aktiviert und aktiv ist, bevor Sie die Anfrage für die Aufnahme eines Standbilds senden.
Siehe Diagramm unten:
Abbildung 7. Ablauf weiterhin mit CaptureProcessorImpl
erfassen
Camera2/X verwendet eine Oberfläche im
YUV_420_888
-Format für die Aufnahme von Standbildern, um die Aufnahmesitzung zu konfigurieren. Camera2/X bereitetCaptureProcessorImpl
durch Aufruf vonCaptureProcessorImpl.onImageFormatUpdate()
mitYUV_420_888
.CaptureProcessorImpl.onResolutionUpdate()
durch die Größe des Eingabebilds.CaptureProcessorImpl.onOutputSurface()
mit einer AusgabeYUV_420_888
-Oberfläche.
ImageCaptureExtenderImpl.getCaptureStages
gibt eine Liste vonCaptureStageImpl
zurück, wobei jedes Element einerCaptureRequest
-Instanz mit Aufnahmeparametern zugeordnet ist, die von Camera2/X gesendet werden. Wenn beispielsweise eine Liste mit dreiCaptureStageImpl
-Instanzen zurückgegeben wird, sendet Camera2/X drei Aufnahmeanfragen mit den entsprechenden Aufnahmeparametern über diecaptureBurst
API.Die empfangenen Bilder und
TotalCaptureResult
-Instanzen werden zusammengefasst und zur Verarbeitung anCaptureProcessorImpl
gesendet.CaptureProcessorImpl
schreibt das Ergebnisbild (YUV_420_888
-Format) in die vomonOutputSurface()
-Aufruf angegebene Ausgabefläche. Camera2/X konvertiert sie bei Bedarf in JPEG-Bilder.
Schlüssel und Ergebnisse für die Erfassungsanfrage unterstützen
Neben der Kameravorschau und -aufnahme können Apps auch den Zoom, die Blitzparameter oder das Fokussieren per Tippen festlegen. Diese Parameter sind möglicherweise nicht mit Ihrer Erweiterungsimplementierung kompatibel.
Die folgenden Methoden wurden extensions-interface
1.3.0 hinzugefügt, damit Sie die von Ihrer Implementierung unterstützten Parameter freigeben können:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()
gibt die von deiner Implementierung unterstützten Schlüssel für Erfassungsanfragen zurück.ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()
gibt die Schlüssel des Erfassungsergebnisses zurück, die im Erfassungsergebnis enthalten sind.
Wenn die Kamera-HAL die Erweiterung verarbeitet, ruft Camera2/X die Aufnahmeergebnisse in CameraCaptureSession.CaptureCallback
ab. Wenn der Prozessor jedoch implementiert ist, ruft Camera2/X die Aufnahmeergebnisse in ProcessResultImpl
ab, die an die process()
-Methode in PreviewImageProcessorImpl
und CaptureProcessorImpl
übergeben werden.
Sie sind dafür verantwortlich, das Aufnahmeergebnis über ProcessResultImpl
an Camera2/X zu melden.
Unten findest du ein Beispiel für die Definition der CaptureProcessorImpl
-Benutzeroberfläche.
In extensions-interface
1.3.0 oder höher wird der zweite process()
-Aufruf 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 Zoom, Fokussieren durch Tippen, Blitz und Belichtungskorrektur empfehlen wir, sowohl für die Aufnahmeanfrage als auch für das Aufnahmeergebnis die folgenden Tasten zu unterstützen:
- Zoom:
CaptureRequest#CONTROL_ZOOM_RATIO
CaptureRequest#SCALER_CROP_REGION
- Zum Fokussieren tippen:
CaptureRequest#CONTROL_AF_MODE
CaptureRequest#CONTROL_AF_TRIGGER
CaptureRequest#CONTROL_AF_REGIONS
CaptureRequest#CONTROL_AE_REGIONS
CaptureRequest#CONTROL_AWB_REGIONS
- Flash:
CaptureRequest#CONTROL_AE_MODE
CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
CaptureRequest#FLASH_MODE
- Belichtungskorrektur:
CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION
Für grundlegende Extender, die Version 1.2.0 oder älter implementieren, werden alle oben genannten Schlüssel ausdrücklich von der CameraX Extensions API unterstützt. Bei extensions-interface
1.3.0 werden sowohl von CameraX als auch von Camera2 die zurückgegebenen Listen berücksichtigt und nur die darin enthaltenen Schlüssel unterstützt. Wenn Sie beispielsweise in der Implementierung von Version 1.3.0 nur CaptureRequest#CONTROL_ZOOM_RATIO
und CaptureRequest#SCALER_CROP_REGION
zurückgeben, bedeutet das, dass nur der Zoom für die App unterstützt wird, während das Fokussieren durch Tippen, der Blitz und die Belichtungskorrektur nicht zulässig sind.
Erweiterter Extender
„Advanced Extender“ ist eine Art Anbieterimplementierung, die auf der Camera2 API basiert.
Dieser Extendertyp wurde in extensions-interface
1.2.0 hinzugefügt. Je nach Gerätehersteller werden Erweiterungen möglicherweise in der App-Ebene implementiert. Das hängt von den folgenden Faktoren ab:
Benutzerdefinierte Streamkonfiguration:Sie können benutzerdefinierte Streams wie einen RAW-Stream konfigurieren oder mehrere Streams für verschiedene physische Kamera-IDs verwenden.
Möglichkeit zum Senden von Camera2-Anfragen:Unterstützt eine komplizierte Interaktionslogik, mit der Aufnahmeanfragen mit Parametern gesendet werden können, die auf den Ergebnissen vorheriger Anfragen basieren.
Der erweiterte Extender bietet einen Wrapper oder eine Zwischenschicht, mit der du die Streamkonfiguration anpassen und Aufzeichnungsanfragen bei Bedarf senden kannst.
Zu implementierende Dateien
Wenn du zur erweiterten Implementierung des Extenders wechseln möchtest, muss die isAdvancedExtenderImplemented()
-Methode in ExtensionVersionImpl
true
zurückgeben. Für jeden Erweiterungstyp müssen OEMs die entsprechenden Extender-Klassen implementieren. Die Implementierungsdateien für den erweiterten Extender befinden sich im Paket advanced.
Zu implementierende Extender-Klassen | |
---|---|
Nacht | advanced/NightAdvancedExtenderImpl.java
|
HDR | advanced/HdrAdvancedExtenderImpl.java
|
Automatisch | 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 implementierte Erweiterung.
Sehen wir uns an, wie Camera2/X die extensions-interface
aufruft, um die drei App-Abläufe zu erreichen.
App-Ablauf 1: Verfügbarkeit von Erweiterungen prüfen
Abbildung 8. App-Ablauf 1 auf erweitertem Extender
Zuerst wird geprüft, ob die angegebene Erweiterung unterstützt wird.
App-Ablauf 2: Informationen abfragen
Abbildung 9. App-Ablauf 2 auf erweitertem Extender
Nach dem Aufruf von AdvancedExtenderImpl.init()
kann die App die folgenden Informationen zu AdvancedExtenderImpl
abfragen:
Geschätzte Latenz bei der Aufnahme von Standbildern:
AdvancedExtenderImpl.getEstimatedCaptureLatencyRange()
gibt den Bereich der Aufnahmelatenz für die App zurück, um zu beurteilen, ob die Erweiterung für das aktuelle Szenario aktiviert werden sollte.Unterstützte Auflösungen für die Vorschau und die Aufnahme von Standbildern:
AdvancedExtenderImpl.getSupportedPreviewOutputResolutions()
gibt eine Zuordnung des Bildformats zu der Liste der Größen zurück, die für das Format und die Größe der Vorschaufläche unterstützt werden. OEMs müssen mindestens dasPRIVATE
-Format unterstützen.AdvancedExtenderImpl.getSupportedCaptureOutputResolutions()
gibt das unterstützte Format und die unterstützten Größen für die Oberfläche für die Standbildaufnahme zurück. OEMs müssen sowohl die Ausgabe imJPEG
- als auch imYUV_420_888
-Format unterstützen.AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
gibt die unterstützten Größen für einen zusätzlichenYUV_420_888
-Stream für die Bildanalyse zurück. Wenn die YUV-Oberfläche für die Bildanalyse nicht unterstützt wird, solltegetSupportedYuvAnalysisResolutions()
null
oder eine leere Liste zurückgeben.
Verfügbare Schlüssel/Ergebnisse für Aufnahmeanfragen (in
extensions-interface
1.3.0 hinzugefügt): Camera2/X ruft die folgenden Methoden auf, um die unterstützten Schlüssel für Aufnahmeanfragen und Ergebnisschlüssel aus Ihrer Implementierung abzurufen:AdvancedExtenderImpl.getAvailableCaptureRequestKeys
AdvancedExtenderImpl.getAvailableCaptureResultKeys
Weitere Informationen finden Sie unter Unterstützung für Anfrageschlüssel und Ergebnisse für die Erfassung.
App-Vorgang 3: Vorschau/Standbildaufnahme mit aktivierter Erweiterung
Abbildung 10. App-Ablauf 3 auf erweitertem Extender
Das obige Diagramm zeigt den Hauptablauf zum Starten der Vorschau und zum Aufnehmen von Standbildern für den erweiterten Extender. Sehen wir uns die einzelnen Schritte an.
SessionProcessorImpl
-InstanzDie Hauptimplementierung des erweiterten Extenders befindet sich in
SessionProcessorImpl
. Dieser ist für die Bereitstellung einer benutzerdefinierten Sitzungskonfiguration und das Senden von Erfassungsanfragen zur Initiierung der Vorschau und der Still-Aufnahme verantwortlich.AdvancedExtenderImpl.createSessionProcessor()
wird aufgerufen, um dieSessionProcessorImpl
-Instanz zurückzugeben.initSession
SessionProcessorImpl.initSession()
initialisiert die Sitzung für die Erweiterung. Hier weisen Sie Ressourcen zu und geben eine Sitzungskonfiguration für die Vorbereitung einerCameraCaptureSession
zurück.Für die Eingabeparameter gibt Camera2/X die Ausgabeoberflächenkonfigurationen für die Vorschau, die Standbildaufnahme und eine optionale YUV-Bildanalyse an. Diese Ausgabeoberflächenkonfiguration (
OutputSurfaceImpl
) enthält die Oberfläche, Größe und das Bildformat, die inAdvancedExtenderImpl
mit den folgenden Methoden abgerufen werden:getSupportedPreviewOutputResolutions()
getSupportedCaptureOutputResolutions()
getSupportedYuvAnalysisResolutions()
Du musst eine
Camera2SessionConfigImpl
-Instanz zurückgeben, die aus einer Liste vonCamera2OutputConfigImpl
-Instanzen und den Sitzungsparametern besteht, die zum Konfigurieren vonCameraCaptureSession
verwendet werden. Sie sind dafür verantwortlich, die richtigen Kamerabilder auf den von Camera2/X übergebenen Ausgabeoberflächen auszugeben. So aktivieren Sie die Ausgabe:- Verarbeitung in der Kamera-HAL:Sie können die Ausgabeoberflächen mit einer
SurfaceOutputConfigImpl
-Implementierung direkt zuCameraCaptureSession
hinzufügen. Dadurch wird die bereitgestellte Ausgabeoberfläche für die Kamerapipeline konfiguriert und die HAL der Kamera kann das Bild verarbeiten. Zwischenfläche
ImageReader
verarbeiten (RAW, YUV usw.): Füge die ZwischenflächenImageReader
mit einerImageReaderOutputConfigImpl
-Instanz demCameraCaptureSession
hinzu.Sie müssen die Zwischenbilder verarbeiten und das Ergebnisbild auf die Ausgabefläche schreiben.
- Camera2-Oberflächenfreigabe verwenden:Wenn Sie die Oberflächenfreigabe mit einer anderen Oberfläche verwenden möchten, fügen Sie der
getSurfaceSharingOutputConfigs()
-Methode einer anderenCamera2OutputConfigImpl
-Instanz eine beliebigeCamera2OutputConfigImpl
-Instanz hinzu. Format und Größe der Oberfläche müssen identisch sein.
Alle
Camera2OutputConfigImpl
, einschließlichSurfaceOutputConfigImpl
undImageReaderOutputConfigImpl
, müssen eine eindeutige ID (getId()
) haben, mit der die Zielfläche angegeben und das Bild ausImageReaderOutputConfigImpl
abgerufen wird.onCaptureSessionStart
undRequestProcessorImpl
Wenn
CameraCaptureSession
gestartet wird und das Kamera-FrameworkonConfigured()
aufruft, ruft Camera2/XSessionProcessorImpl.onCaptureSessionStart()
mit dem Camera2-Anfrage-WrapperRequestProcessImpl
auf. Camera2/X implementiertRequestProcessImpl
, mit dem Sie Aufnahmeanfragen ausführen und Bilder abrufen können, wennImageReaderOutputConfigImpl
verwendet wird.Die
RequestProcessImpl
APIs ähneln den Camera2CameraCaptureSession
APIs bei der Ausführung von Anfragen. Die Unterschiede sind:- Die Zieloberfläche wird durch die ID der
Camera2OutputConfigImpl
-Instanz angegeben. - Die Möglichkeit, das Bild der
ImageReader
abzurufen.
Sie können
RequestProcessorImpl.setImageProcessor()
mit einer bestimmtenCamera2OutputConfigImpl
-ID aufrufen, um eineImageProcessorImpl
-Instanz für den Empfang von Bildern zu registrieren.Die
RequestProcessImpl
-Instanz wird ungültig, nachdem Camera2/XSessionProcessorImpl.onCaptureSessionEnd()
aufgerufen hat.- Die Zieloberfläche wird durch die ID der
Vorschau starten und ein Foto aufnehmen
Bei der erweiterten Extender-Implementierung kannst du Aufnahmeanfragen über die
RequestProcessorImpl
-Oberfläche senden. Camera2/X benachrichtigt Sie, dass Sie die wiederholte Anfrage für die Vorschau oder die Sequenz für die Standbildaufnahme starten können, indem Sie jeweilsSessionProcessorImpl#startRepeating
undSessionProcessorImpl#startCapture
aufrufen. Sie sollten Aufnahmeanfragen senden, um diese Vorschau- und Standbildanfragen zu erfüllen.Camera2/X setzt auch die Parameter der Aufnahmeanfrage über
SessionProcessorImpl#setParameters
. Sie müssen diese Anfrageparameter (sofern unterstützt) sowohl für wiederkehrende als auch für einzelne Anfragen festlegen.Sie müssen mindestens
CaptureRequest.JPEG_ORIENTATION
undCaptureRequest.JPEG_QUALITY
unterstützen.extensions-interface
1.3.0 unterstützt Anfrage- und Ergebnisschlüssel, die über die folgenden Methoden freigegeben werden:AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
AdvancedExtenderImpl.getAvailableCaptureResultKeys()
Wenn Entwickler die Schlüssel in der Liste
getAvailableCaptureRequestKeys
festlegen, müssen Sie die Parameter aktivieren und dafür sorgen, dass das Erfassungsergebnis die Schlüssel in der ListegetAvailableCaptureResultKeys
enthält.startTrigger
SessionProcessorImpl.startTrigger()
wird aufgerufen, um den Trigger zu starten, z. B.CaptureRequest.CONTROL_AF_TRIGGER
undCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER
. Schlüssel für Erfassungsanfragen, die nicht inAdvancedExtenderImpl.getAvailableCaptureRequestKeys()
beworben wurden, können Sie ignorieren.startTrigger()
wird seitextensions-interface
1.3.0 unterstützt. Sie ermöglicht es Apps, die Funktion „Auf das Display tippen, um den Fokus zu setzen“ und das Blitzen mit Erweiterungen zu implementieren.Aufräumen
Wenn eine Aufnahmesitzung beendet wird, wird
SessionProcessorImpl.onCaptureSessionEnd()
aufgerufen, bevorCameraCaptureSession
geschlossen wird. Nach dem Schließen der Aufnahmesitzung führtdeInitSession()
die Bereinigung durch.
Unterstützung von Vorschau, Standbildern und Bildanalyse
Sie sollten die Erweiterung sowohl für die Vorschau als auch für die Erfassung von Anwendungsfällen anwenden. Wenn die Latenz jedoch zu hoch ist, um die Vorschau flüssig anzuzeigen, können Sie die Verlängerung nur für die Aufnahme von Standbildern anwenden.
Für den Typ „Basic Extender“ müssen Sie unabhängig davon, ob Sie die Erweiterung für die Vorschau aktivieren, sowohl ImageCaptureExtenderImpl
als auch PreviewExtenderImpl
für eine bestimmte Erweiterung implementieren. Häufig verwendet eine App auch einen YUV-Stream, um den Bildinhalt zu analysieren, z. B. um QR-Codes oder Text zu finden. Um diesen Anwendungsfall besser zu unterstützen, sollten Sie die Streamkombination aus Vorschau, Standbildaufnahme und einem YUV_420_888
-Stream zur Konfiguration von CameraCaptureSession
unterstützen. Wenn du also einen Prozessor implementierst, musst du die Streamkombination aus drei YUV_420_888
-Streams unterstützen.
Bei Advanced Extender gibt Camera2/X drei Ausgabeoberflächen an den SessionProcessorImpl.initSession()
-Aufruf weiter. Diese Ausgabeoberflächen dienen jeweils der Vorschau, der Aufnahme von Standbildern und der Bildanalyse. Sie müssen dafür sorgen, dass in der Vorschau und in den Ausgabeoberflächen für Standbilder die gültige Ausgabe zu sehen ist. Achten Sie jedoch darauf, dass die Ausgabefläche für die Bildanalyse nur funktioniert, wenn der Wert nicht null ist. Wenn Ihre Implementierung den Stream für die Bildanalyse nicht unterstützt, können Sie in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
eine leere Liste zurückgeben. So wird sichergestellt, dass die Ausgabeoberfläche der Bildanalyse in SessionProcessorImpl.initSession()
immer null ist.
Videoaufnahme unterstützen
Die aktuelle Architektur der Kameraerweiterung unterstützt nur die Vorschau und die Aufnahme von Standbildern. Die Aktivierung der Erweiterung auf den Oberflächen MediaCodec
oder MediaRecorder
für die Videoaufzeichnung wird nicht unterstützt. Es ist jedoch möglich, dass Apps die Vorschauausgabe aufzeichnen.
Die Unterstützung von MediaCodec
- und MediaRecorder
-Oberflächen wird geprüft.
Erweiterungsspezifische Metadaten
Unter Android 14 und höher können Kamera-Erweiterungs-Clients mithilfe von erweiterungsspezifischen Metadaten Einstellungen und Ergebnisse für erweiterungsspezifische Aufnahmeanfragen festlegen und empfangen. Insbesondere können Kameraerweiterungs-Clients den Parameter EXTENSION_STRENGTH
der Aufnahmeanfrage verwenden, um die Stärke der Erweiterung zu steuern, und das Aufnahmeergebnis EXTENSION_CURRENT_TYPE
, um den aktivierten Erweiterungstyp anzugeben.
Anfragen erfassen
Mit dem Parameter für die Aufnahmeanfrage EXTENSION_STRENGTH
wird die Stärke des Effekts der Nachverarbeitung der Erweiterung gesteuert. Das entsprechende Erfassungsergebnis enthält den Standardwert für die Stärke, wenn dieser Parameter nicht explizit vom Client festgelegt wird. Dieser Parameter kann für die folgenden Erweiterungstypen so angewendet werden:
BOKEH
: Damit wird die Unschärfe gesteuert.HDR
undNIGHT
: Damit wird die Anzahl der zusammengeführten Bilder und die Helligkeit des Endbilds gesteuert.FACE_RETOUCH
: Damit wird die Intensität der kosmetischen Verbesserung und Hautglättung gesteuert.
Der unterstützte Bereich für den Parameter EXTENSION_STRENGTH
liegt zwischen 0
und 100
. 0
steht für keine Erweiterungsverarbeitung oder einfache Weiterleitung und 100
für die maximale Erweiterungsstärke des Verarbeitungseffekts.
Wenn Sie EXTENSION_STRENGTH
unterstützen möchten, verwenden Sie die anbieterspezifischen Parameter-APIs, die in Version 1.3.0 der Erweiterungsbibliotheksoberfläche eingeführt wurden. Weitere Informationen finden Sie unter getAvailableCaptureRequestKeys()
.
Ergebnisse erfassen
Mit dem Erfassungsergebnis EXTENSION_CURRENT_TYPE
können Erweiterungsimplementierungen Clients über den aktiven Erweiterungstyp informieren.
Da Erweiterungen vom Typ AUTO
je nach den Aufnahmebedingungen dynamisch zwischen Erweiterungstypen wie HDR
und NIGHT
wechseln, können Kamera-Erweiterungs-Apps EXTENSION_CURRENT_TYPE
verwenden, um Informationen zur aktuellen Erweiterung anzuzeigen, die von der AUTO
-Erweiterung ausgewählt wurde.
Schätzung der Latenz bei der Aufnahme von Standbildern in Echtzeit
Unter Android 14 und höher können Kameraerweiterungs-Clients mithilfe von getRealtimeStillCaptureLatency()
Echtzeit-Schätzungen der Latenz für die Aufnahme von Standbildern basierend auf den Szenen- und Umgebungsbedingungen abfragen. Diese Methode liefert genauere Schätzungen als die statische Methode getEstimatedCaptureLatencyRangeMillis()
. Basierend auf der geschätzten Latenz können Apps entscheiden, die Erweiterungsverarbeitung zu überspringen oder eine Anzeige zu schalten, um Nutzer über einen langwierigen Vorgang zu informieren.
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();
Um Echtzeit-Schätzungen für die Latenz bei der Aufnahme von Standbildern zu unterstützen, implementieren Sie Folgendes:
- Grundlegende Erweiterungen:
ImageCaptureExtenderImpl.getRealtimeCaptureLatency()
- Erweiterte Erweiterungen:
SessionProcessorImpl.getRealtimeCaptureLatency
Callbacks für den Verarbeitungsfortschritt erfassen
Unter Android 14 und höher können Clients der Kameraerweiterung Rückrufe zum Fortschritt lang laufender Verarbeitungsvorgänge für Standbilder erhalten. Apps können Nutzern den aktuellen Fortschritt anzeigen, um die Nutzerfreundlichkeit insgesamt zu verbessern.
Apps können diese Funktion mit dem folgenden Code einbinden:
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
}
}
…
}
Um Rückrufe zum Fortschritt der Aufnahmeverarbeitung zu unterstützen, muss die Implementierung Ihres Erweiterungsanbieters die folgenden Rückrufe mit dem aktuellen Fortschrittswert aufrufen:
- Grundlegende Erweiterungen:
ProcessResultImpl.onCaptureProcessProgressed()
- Erweiterte Erweiterungen:
CaptureCallback.onCaptureProcessProgressed()
Standbild bei Post-View-Interaktionen
Unter Android 14 und höher können Kameraerweiterungen eine Postview (Vorschaubild) mit setPostviewOutputConfiguration
bereitstellen.
Um die Nutzerfreundlichkeit zu verbessern, können Apps ein Postview-Bild als Platzhalter anzeigen, wenn bei einer Erweiterung eine längere Verarbeitungslatenz auftritt, und das Bild ersetzen, sobald das endgültige Bild verfügbar ist. Mit dem folgenden Referenzcode können Sie in Apps Postview-Aufzeichnungsanfragen konfigurieren und senden:
{
…
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();
…
}
Damit die Aufzeichnung von Standbildern nach der Wiedergabe unterstützt wird, muss Ihre Anbieterimplementierung Folgendes umfassen:
Grundlegende Erweiterungen:
CaptureProcessorImpl.onPostviewOutputSurface
undCaptureProcessorImpl.processWithPostview
Erweiterte Erweiterungen:
SessionProcessorImpl.startCaptureWithPostview
SurfaceView-Ausgabe unterstützen
Unter Android 14 und höher können Kameraerweiterungs-Clients energie- und leistungsoptimierte Vorschau-Renderpfade verwenden, indem sie eine SurfaceView
-Instanz für die Vorschauausgabe für wiederholte Anfragen registrieren.
Damit SurfaceView
-Ausgabe unterstützt wird, muss die Implementierung der Anbietererweiterung in der Lage sein, eine Vorschau an SurfaceView
-Instanzen zu streamen und auszugeben. Führen Sie das SurfaceViewExtensionPreviewTest.java
-CTS-Modul aus, um zu prüfen, ob dies unterstützt wird.
Anbieterspezifische Sitzungstypen
Mit dieser Funktion können bei der Implementierung von Anbietererweiterungen ein Anbieterspezifischer Sitzungstyp ausgewählt werden, der anstelle des Standardwerts in der internen Kameraaufnahmesitzung festgelegt wird.
Die Funktion funktioniert vollständig innerhalb des Frameworks und des Anbieter-Stacks und hat keine Auswirkungen auf die client-/öffentlich sichtbare API.
Wenn Sie einen anbieterspezifischen Sitzungstyp auswählen möchten, implementieren Sie Folgendes für Ihre Erweiterungsbibliotheken:
* ExtenderStateListener.onSessionType()
für grundlegende Erweiterungen
* Camera2SessionConfigImpl.getSessionType()
für erweiterte Erweiterungen
Versionsverlauf der Erweiterungsoberfläche
In der folgenden Tabelle finden Sie die Versionsgeschichte der Kameraerweiterungsoberfläche. Sie sollten die Anbieterbibliothek immer mit der neuesten Version implementieren.
Version | Hinzugefügte Funktionen |
---|---|
1.0.0 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
1.4.0 |
|
Referenzimplementierung
Die folgenden Referenzimplementierungen von OEM-Bibliotheken sind in frameworks/ex
verfügbar.
advancedSample
: Eine grundlegende Implementierung von Advanced Extender.sample
: Eine einfache Implementierung des Basic Extenders.service_based_sample
: Eine Implementierung, die zeigt, wie Kameraerweiterungen in einerService
gehostet werden. Diese Implementierung enthält die folgenden Komponenten:oem_library
: OEM-Bibliothek für Kameraerweiterungen für die Camera2 und CameraX Extensions APIs, dieExtensions-Interface
implementiert. Dies dient als Passthrough, über das Aufrufe vonExtensions-Interface
an den Dienst weitergeleitet werden. Diese Bibliothek bietet außerdem AIDL-Dateien und Wrapper-Klassen für die Kommunikation mit dem Dienst.Der erweiterte Extender ist standardmäßig aktiviert. Wenn Sie den einfachen Extender aktivieren möchten, ändern Sie
ExtensionsVersionImpl#isAdvancedExtenderImplemented
infalse
zurück.extensions_service
: Eine Beispielimplementierung des Erweiterungsdiensts. Fügen Sie Ihre Implementierung hier hinzu. Die im Dienst zu implementierende Schnittstelle ähnelt derExtensions-Interface
. Wenn Sie beispielsweiseIAdvancedExtenderImpl.Stub
implementieren, werden dieselben Vorgänge wie beiAdvancedExtenderImpl
ausgeführt.ImageWrapper
undTotalCaptureResultWrapper
sind erforderlich, damitImage
undTotalCaptureResult
parzelliert werden können.
Anbieterbibliothek auf einem Gerät einrichten
Die OEM-Anbieterbibliothek ist nicht in eine App eingebunden, sondern wird von Camera2/X zur Laufzeit vom Gerät geladen. In CameraX wird mit dem <uses-library>
-Tag angegeben, dass die androidx.camera.extensions.impl
-Bibliothek, die in der Datei AndroidManifest.xml
der camera-extensions
-Bibliothek definiert ist, eine Abhängigkeit von CameraX ist und zur Laufzeit geladen werden muss. In Camera2 lädt das Framework einen Erweiterungsdienst, der auch angibt, dass die <uses-library>
zur Laufzeit dieselbe androidx.camera.extensions.impl
-Bibliothek lädt.
So können Drittanbieter-Apps, die Erweiterungen verwenden, die OEM-Bibliothek automatisch laden. Die OEM-Bibliothek ist als optional gekennzeichnet, damit Apps auch auf Geräten ausgeführt werden können, auf denen die Bibliothek nicht installiert ist. Camera2/X verarbeitet dieses Verhalten automatisch, wenn eine App versucht, eine Kameraerweiterung zu verwenden, sofern der Gerätehersteller die OEM-Bibliothek auf dem Gerät platziert, damit sie von der App gefunden werden kann.
So richten Sie die OEM-Bibliothek auf einem Gerät ein:
- Füge eine Berechtigungsdatei hinzu, die für das
<uses-library>
-Tag erforderlich ist. Sie muss das folgende Format haben:/etc/permissions/ANY_FILENAME.xml
. Beispiel:/etc/permissions/camera_extensions.xml
. Die Dateien in diesem Verzeichnis stellen eine Zuordnung der in<uses-library>
genannten Bibliothek zum tatsächlichen Dateipfad auf dem Gerät bereit. Verwenden Sie das folgende Beispiel, um der Datei die erforderlichen Informationen hinzuzufügen.
name
mussandroidx.camera.extensions.impl
sein, da dies die Bibliothek ist, nach der CameraX sucht.file
ist der absolute Pfad der Datei, die die Erweiterungsimplementierung enthält (z. B./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>
Unter Android 12 oder höher muss die Eigenschaft ro.camerax.extensions.enabled
auf true
festgelegt sein, damit Geräte, die CameraX-Erweiterungen unterstützen, abgefragt werden können.
Fügen Sie dazu die folgende Zeile in die Datei „device make“ ein:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
Zertifizierungsstufe
Wenn Sie die Implementierung der OEM-Anbieterbibliothek während der Entwicklungsphase testen möchten, verwenden Sie die Beispiel-App unter androidx-main/camera/integration-tests/extensionstestapp/
, die verschiedene Anbietererweiterungen durchläuft.
Führen Sie nach Abschluss der Implementierung mit dem Validierungstool für Kameraerweiterungen automatisierte und manuelle Tests durch, um zu prüfen, ob die Anbieterbibliothek richtig implementiert ist.
Erweiterter Szenenmodus im Vergleich zu Kameraerweiterungen
Sie können die Bokeh-Erweiterung nicht nur mithilfe von Kameraerweiterungen belichten, sondern auch mit dem erweiterten Szenenmodus, der über die Taste CONTROL_EXTENDED_SCENE_MODE
aktiviert wird.
Weitere Informationen zur Implementierung finden Sie unter Kamera-Bokeh.
Der erweiterte Szenenmodus hat weniger Einschränkungen als Kameraerweiterungen für camera2-Apps. Sie können den erweiterten Szenenmodus beispielsweise in einer regulären CameraCaptureSession
-Instanz aktivieren, die flexible Streamkombinationen und Aufnahmeanfrageparameter unterstützt. Kameraerweiterungen unterstützen dagegen nur eine feste Anzahl von Streamtypen und nur eingeschränkt die Parameter für Aufnahmeanfragen.
Ein Nachteil des erweiterten Szenenmodus ist, dass er nur in der Kamera-HAL implementiert werden kann. Das bedeutet, dass überprüft werden muss, ob er für alle orthogonalen Steuerelemente funktioniert, die App-Entwicklern zur Verfügung stehen.
Wir empfehlen, Bokeh sowohl mit dem erweiterten Szenenmodus als auch mit Kameraerweiterungen zu belichten, da Apps möglicherweise eine bestimmte API verwenden, um Bokeh zu aktivieren. Wir empfehlen, zuerst den erweiterten Szenenmodus zu verwenden, da dies die flexibelste Möglichkeit für Apps ist, die Bokeh-Erweiterung zu aktivieren. Anschließend können Sie die Benutzeroberfläche für Kameraerweiterungen basierend auf dem erweiterten Szenenmodus implementieren. Wenn die Implementierung von Bokeh in der Kamera-HAL schwierig ist, z. B. weil für die Verarbeitung von Bildern ein Nachbearbeiter in der App-Ebene erforderlich ist, empfehlen wir, die Bokeh-Erweiterung über die Kamera-Erweiterungen-Schnittstelle zu implementieren.
Häufig gestellte Fragen
Gibt es Einschränkungen für API-Ebenen?
Ja. Das hängt von den Android API-Funktionen ab, die für die Implementierung der OEM-Anbieterbibliothek erforderlich sind. In ExtenderStateListener.onPresetSession()
wird beispielsweise der Aufruf SessionConfiguration.setSessionParameters()
verwendet, um einen Basissatz von Tags festzulegen. Dieser Aufruf ist nur auf API-Level 28 und höher verfügbar. Weitere Informationen zu bestimmten Methoden der Benutzeroberfläche finden Sie in der API-Referenzdokumentation.