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
Kopieren Sie die camera-extensions-stub
-Dateien in ein Systembibliotheksprojekt, um die OEM-Anbieterbibliothek zu implementieren. 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 die 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-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-Ablauf anhand der Night-Erweiterung als Beispiel:
Abbildung 2. Nachterweiterung implementieren
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 findest du unter Basic Extender und Advanced Extender.
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 Hauptarbeit sollte erst kurz vor Beginn der Kamerasitzung erledigt werden, z. B. wennonInit()
im Basic Extender oderinitSession()
im Advanced Extender aufgerufen wird.Für die Erweiterung "Night" werden die folgenden Extender-Klassen für den Basic Extender-Typ instanziiert:
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
Für den erweiterten Extendertyp:
NightAdvancedExtenderImpl.java
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.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 die unterstützten Lösungen abzurufen, trotzdem die geschätzte Latenz zu erfassen und Anfrageschlüssel vom Extender zu erfassen, um die Aktivierung der Erweiterung vorzubereiten.
Erweiterung auf dem Extender aktivieren:
Die Extender-Klasse bietet alle erforderlichen Schnittstellen, um die Klasse zu aktivieren. 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.
extensions-interface
verwendet die semantische Versionsverwaltung, 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-Anbieterbibliotheken, die mit früheren extensions-interface
-Versionen erstellt wurden. Wenn Kamera2/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.
Aufwä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.
InitializerImpl
muss ab extensions-interface
1.1.0 implementiert werden. 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. Advanced 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)
|
Anpassbar durch OEM. |
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. | Es wird eine RequestProcessorImpl -Instanz bereitgestellt, um die Kamera2-Erfassungsanfrage auszuführen und Ergebnisse und Bilder abzurufen.
Camera2/X ruft |
Aufhänger 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 entsprechenden Camera Extensions API-Aufrufe aufgeführt. Camera2/X bietet zwar diese APIs, 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
|
Informationen zur Suchanfrage | CameraExtensionCharacteristics.
getExtensionSupportedSizes
CameraExtensionCharacteristics.
getEstimatedCaptureLatencyRangeMillis
CameraExtensionCharacteristics.
getAvailableCaptureRequestKeys
CameraExtensionCharacteristics.
getAvailableCaptureResultKeys
|
ExtensionsManager.
getEstimatedCaptureLatencyRange
Die restlichen Informationen innerhalb der Bibliothek werden von CameraX verarbeitet. |
Vorschau und Fotoaufnahme 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 dem Basic 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.
Dies ist oft der erste Schritt von Apps, um zu prüfen, ob der jeweilige 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 dem Basic 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 Erfassungsparametern, 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. Darüber hinaus enthält die Erfassungsanfrage 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
Zusätzlich zum Kamera-HAL können Sie auch Erweiterungen in einem Prozessor implementieren.
Implementieren Sie PreviewExtenderImpl.getProcessorType
, um den Prozessortyp wie unten beschrieben anzugeben:
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 im VorschauformatPRIVATE
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 von:CaptureProcessorImpl.onImageFormatUpdate()
mitYUV_420_888
.CaptureProcessorImpl.onResolutionUpdate()
durch die Größe des eingegebenen Bilds.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 Erfassungsanfragen mit entsprechenden Erfassungsparametern über diecaptureBurst
API.Die empfangenen Bilder und
TotalCaptureResult
-Instanzen werden gebündelt und zur Verarbeitung anCaptureProcessorImpl
gesendet.CaptureProcessorImpl
schreibt das Ergebnisbild (FormatYUV_420_888
) in die durch den AufrufonOutputSurface()
angegebene Ausgabeoberflä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 Parameter bereitstellen können, die von Ihrer Implementierung unterstützt werden:
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.
Du bist dafür verantwortlich, das Aufnahmeergebnis über ProcessResultImpl
an Camera2/X zu melden.
Unten finden Sie ein Beispiel in der Definition der CaptureProcessorImpl
-Schnittstelle.
Ab extensions-interface
1.3.0 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 Kameravorgänge wie Zoomen, Tippen für Fokus, 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
- 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 die 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 extensions-interface
aufruft, um die drei App-Abläufe auszuführen.
App-Ablauf 1: Verfügbarkeit von Erweiterungen prüfen
Abbildung 8. App-Ablauf 1 auf Advanced Extender
Zuerst wird geprüft, ob die angegebene Erweiterung unterstützt wird.
App-Ablauf 2: Informationen abfragen
Abbildung 9. App-Ablauf 2 auf Advanced 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 an die Größenliste zurück, die für das Format und die Größe der Vorschauoberfläche unterstützt wird. OEMs müssen mindestens das FormatPRIVATE
unterstützen.AdvancedExtenderImpl.getSupportedCaptureOutputResolutions()
gibt das unterstützte Format und die unterstützten Größen für die Oberfläche für Standbilder 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 Erfassungsanfragen (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-Ablauf 3: Vorschau/Aufnahme mit aktivierter Erweiterung
Abbildung 10. App-Ablauf 3 auf Advanced Extender
Das obige Diagramm zeigt den Hauptablauf zum Starten der Vorschau und zum Aufnehmen von Standbildern für den erweiterten Extender-Typ. 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 zur Konfiguration vonCameraCaptureSession
verwendet werden. Es liegt in Ihrer Verantwortung, die richtigen Kamerabilder an die 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 Instanz
Camera2OutputConfigImpl
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 Instanz
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 wiederholte 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. Für diesen Anwendungsfall sollten Sie die Stream-Kombination aus „Vorschau“, „Trotzdem“ erfassen und einen YUV_420_888
-Stream zum Konfigurieren 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 übergibt Camera2/X drei Ausgabeoberflächen an den SessionProcessorImpl.initSession()
-Aufruf. 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 Ausgabeoberfläche der 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
bzw. 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 derzeit geprüft.
Erweiterungsspezifische Metadaten
Ab Android 14 können mit erweiterungsspezifischen Metadaten Kameraerweiterungsclients erweiterungsspezifische Aufnahmeanfrageeinstellungen und -ergebnisse festlegen und empfangen. Insbesondere können Kameraerweiterungsclients mit dem Erfassungsanfrageparameter EXTENSION_STRENGTH
die Erweiterungsstärke steuern und mit dem Erfassungsergebnis EXTENSION_CURRENT_TYPE
den aktivierten Erweiterungstyp angeben.
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
: Steuert das Ausmaß der Unschärfe.HDR
undNIGHT
: Damit wird die Anzahl der zusammengeführten Bilder und die Helligkeit des Endbilds gesteuert.FACE_RETOUCH
: Hiermit wird das Maß an kosmetischen Optimierung und Hautglättung festgelegt.
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 mit Version 1.3.0 der Oberfläche der Erweiterungsbibliothek eingeführt wurden. Weitere Informationen finden Sie unter getAvailableCaptureRequestKeys()
.
Ergebnisse erfassen
Mithilfe des Erfassungsergebnisses von EXTENSION_CURRENT_TYPE
können Erweiterungsimplementierungen Clients über den aktiven Erweiterungstyp benachrichtigen.
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 von Kameraerweiterungen 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 den folgenden Code verwenden, um diese Funktion zu integrieren:
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:
- Einfache 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 die 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 CTS-Modul SurfaceViewExtensionPreviewTest.java
aus, um zu prüfen, ob dies unterstützt wird.
Anbieterspezifische Sitzungstypen
Mit dieser Funktion können Sie bei der Implementierung von Anbietererweiterungen einen anbieterspezifischen Sitzungstyp auswählen, 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
: Eine Kameraerweiterungs-OEM-Bibliothek für Camera2- und CameraX-Erweiterungs-APIs, dieExtensions-Interface
implementieren. 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 integriert. Sie wird zur Laufzeit von Camera2/X vom Gerät geladen. In CameraX deklariert das Tag <uses-library>
, dass die Bibliothek androidx.camera.extensions.impl
, die in der Datei AndroidManifest.xml
der Bibliothek camera-extensions
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 Beispiel unten, 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 „Marke“ des Geräts ein:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
Zertifizierungsstufe
Um die Implementierung der OEM-Anbieterbibliothek während der Entwicklungsphase zu testen, 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 Erfassungsanfrageparameter unterstützt. Kameraerweiterungen hingegen unterstützen nur einen festen Satz von Streamtypen und nur begrenzte Unterstützung für Parameter für Erfassungsanfragen.
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 Schnittstellenmethoden finden Sie in der API-Referenzdokumentation.