Gerätehersteller können Erweiterungen wie Bokeh, Nachtmodus und HDR über die von der OEM-Anbieterbibliothek bereitgestellte Camera Extensions-Schnittstelle für Drittanbieter-Entwickler verfügbar machen. Entwickler können über die Camera2 Extensions API und die CameraX Extensions API auf die in der OEM-Anbieterbibliothek implementierten Erweiterungen zugreifen.
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 in der Problemverfolgung.
Auf dieser Seite wird beschrieben, wie Sie die OEM-Anbieterbibliothek auf Geräten implementieren und aktivieren.
Architektur
Das folgende Diagramm beschreibt die Architektur der Camera Extensions-Schnittstelle oder extensions-interface
:
Abbildung 1: Architekturdiagramm für Kamera-Erweiterungen
Wie im Diagramm dargestellt, müssen Sie zur Unterstützung von Kameraerweiterungen die extensions-interface
implementieren, die von der OEM-Anbieterbibliothek bereitgestellt werden. Die OEM-Anbieterbibliothek ermöglicht zwei APIs: die CameraX Extensions API und die Camera2 Extensions API. Diese werden von CameraX- bzw. 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 Systembibliotheks-Projekt. Diese Dateien definieren die Camera Extensions-Schnittstelle.
Die camera-extensions-stub
-Dateien sind in folgende Kategorien unterteilt:
Wichtige Schnittstellendateien (nicht ändern)
PreviewExtenderImpl.java
ImageCaptureExtenderImpl.java
ExtenderStateListener.java
ProcessorImpl.java
PreviewImageProcessorImpl.java
CaptureProcessorImpl.java
CaptureStageImpl.java
RequestUpdateProcessorImpl.java
ProcessResultImpl.java
advanced/AdvancedExtenderImpl.java
advanced/Camera2OutputConfigImpl.java
advanced/Camera2SessionConfigImpl.java
advanced/ImageProcessorImpl.java
advanced/ImageReaderOutputConfigImpl.java
advanced/ImageReferenceImpl.java
advanced/MultiResolutionImageReaderOutputConfigImpl.java
advanced/OutputSurfaceImpl.java
advanced/RequestProcessorImpl.java
advanced/SessionProcessorImpl.java
advanced/SurfaceOutputConfigImpl.java
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
Klassen für die Nachtverlängerung (implementieren, wenn die Nachtverlängerung 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-Erweiterungsklassen (implementieren, wenn die HDR-Erweiterung unterstützt wird)
HdrImageCaptureExtenderImpl.java
HdrPreviewExtenderImpl.java
advanced/HdrAdvancedExtenderImpl.java
Erweiterungsklassen für die Gesichtsretusche (implementieren, wenn die Erweiterung „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 vornehmen. Wenn Sie keine Erweiterung implementieren, legen Sie isExtensionAvailable()
so fest, dass false
zurückgegeben wird, 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 Extensions APIs mit der Anbieterbibliothek interagieren, um eine Erweiterung zu ermöglichen. Das folgende Diagramm veranschaulicht den End-to-End-Ablauf am Beispiel der Erweiterung „Nacht“:
Abbildung 2: Implementierung der Nachtfunktion
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()
, mit der die Anbieterbibliothek initialisiert wird. Camera2/X schließt die Initialisierung ab, bevor auf die Extender-Klassen zugegriffen wird.Extender-Klassen instanziieren:
Instanziiert die Extender-Klassen für die Erweiterung. Es gibt zwei Arten von Extendern: Basic Extender und Advanced Extender. Sie müssen einen Extender-Typ für alle Erweiterungen implementieren. Weitere Informationen finden Sie unter Basic Extender im Vergleich zu Advanced Extender.
Camera2/X instanziiert die Extender-Klassen und interagiert mit ihnen, um Informationen abzurufen und die Erweiterung zu aktivieren. Bei einer bestimmten Erweiterung kann Camera2/X die Extender-Klassen mehrmals instanziieren. Führen Sie daher keine rechenintensiven Initialisierungen im Konstruktor oder im
init()
-Aufruf durch. Führe die rechenintensiven Aufgaben erst aus, wenn die Kamerasitzung gestartet wird, z. B. wennonInit()
im Basic Extender oderinitSession()
im Advanced Extender aufgerufen wird.Für die Night-Erweiterung werden die folgenden Extender-Klassen für den Basic Extender-Typ instanziiert:
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
Für den Advanced Extender-Typ:
NightAdvancedExtenderImpl.java
Verfügbarkeit von Erweiterungen prüfen:
Bevor die Erweiterung aktiviert wird, prüft
isExtensionAvailable()
über die Extender-Instanz, ob die Erweiterung für die angegebene Kamera-ID verfügbar ist.Extender mit Kamerainformationen initialisieren:
Camera2/X ruft
init()
in der Extender-Instanz auf und übergibt ihr die Kamera-ID undCameraCharacteristics
.Informationen zur Anfrage:
Ruft die Extender-Klasse auf, um Informationen wie unterstützte Auflösungen und die geschätzte Latenz abzurufen und Anforderungsschlü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, um die OEM-Implementierung in die Camera2-Pipeline einzubinden, z. B. durch Einfügen von Parametern für Aufnahmeanfragen 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()
für den Extender aufgerufen wird.
In den folgenden Abschnitten wird der Ablauf der Erweiterung genauer 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.
Für die extensions-interface
wird die semantische Versionierung verwendet, z. B. MAJOR.MINOR.PATCH, also 1.1.0 oder 1.2.0. Bei der Versionsüberprüfung werden jedoch nur die Haupt- und Nebenversion verwendet.
Zur Überprüfung der Version ruft Camera2/X ExtensionVersionImpl.checkApiVersion()
mit der unterstützten Version extensions-interface
auf. Camera2/X verwendet dann die von der OEM-Bibliothek gemeldete Version, um zu bestimmen, ob die Erweiterung aktiviert werden kann und welche Funktionen sie aufrufen soll.
Kompatibilität mit Hauptversionen
Wenn sich die Hauptversionen der extension-interface zwischen Camera2/X und der Anbieterbibliothek unterscheiden, gilt die Erweiterung als inkompatibel und wird 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 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 Camera2/X nach der Implementierung einer bestimmten Version der Anbieterbibliothek dafür sorgt, dass die Bibliothek mit zukünftigen extension-interface
-Versionen abwärtskompatibel ist.
Vorwärtskompatibilität
Die Vorwärtskompatibilität mit Anbieterbibliotheken neuerer extensions-interface
hängt von Ihnen als OEM ab. Wenn Sie bestimmte 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.
Anbieterbibliothek initialisieren
Nachdem die vom OEM implementierte extensions-interface
-Version überprüft wurde, startet Camera2/X den Initialisierungsvorgang. Die Methode InitializerImpl.init()
signalisiert der OEM-Bibliothek, dass eine App versucht, Erweiterungen zu verwenden.
Camera2/X führt keine anderen Aufrufe an die OEM-Bibliothek aus (abgesehen von der Versionsprüfung), bis die OEM-Anbieterbibliothek OnExtensionsInitializedCallback.onSuccess()
aufruft, um den Abschluss der Initialisierung zu melden.
Sie müssen InitializerImpl
ab extensions-interface
1.1.0 implementieren. Bei Camera2/X wird der Schritt zur Initialisierung der Bibliothek übersprungen, wenn die OEM-Anbieterbibliothek extensions-interface
1.0.0 implementiert.
Basic Extender im Vergleich zu Advanced Extender
Es gibt zwei Arten der extensions-interface
-Implementierung: Basic Extender und Advanced Extender. Der Advanced Extender wird seit extensions-interface
1.2.0 unterstützt.
Implementieren Sie Basic Extender für Erweiterungen, die Bilder im Kamera-HAL verarbeiten oder einen Postprozessor verwenden, der YUV-Streams verarbeiten kann.
Implementieren Sie „Advanced Extender“ für Erweiterungen, die die Camera2-Streamkonfiguration anpassen und bei Bedarf Aufnahmeanfragen senden müssen.
Die folgende Tabelle zeigt einen Vergleich:
Basic Extender | Erweiterter Extender | |
---|---|---|
Streamkonfigurationen | Fest Vorschau: PRIVATE oder YUV_420_888 (falls Prozessor vorhanden) Standbild: JPEG oder YUV_420_888 (falls Prozessor vorhanden)
|
Kann vom OEM angepasst werden. |
Aufnahmeanfrage wird gesendet | 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. | Eine RequestProcessorImpl -Instanz wird Ihnen zur Verfügung gestellt, um die camera2-Aufnahmeanfrage auszuführen und Ergebnisse und ein Bild zu erhalten.
Camera2/X ruft |
Hooks in der Kamerapipeline |
|
|
Geeignet für | Erweiterungen, die in der Kamera-HAL oder in einem Prozessor implementiert sind, der YUV-Bilder verarbeitet. |
|
Unterstützte API-Version | Camera2-Erweiterungen: Android 13 oder höher CameraX-Erweiterungen: camera-extensions 1.1.0 oder höher |
Camera2-Erweiterungen: Android 12L oder höher CameraX-Erweiterungen: 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, Sie müssen die Anbieterbibliothek jedoch richtig implementieren, um diese Abläufe zu unterstützen. Das wird in einem späteren Abschnitt genauer beschrieben.
Camera2-Erweiterungen | CameraX-Erweiterungen | |
---|---|---|
Verfügbarkeit von Abfrageerweiterungen prüfen | 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 Standbildaufnahme mit aktivierter Erweiterung | CameraDevice.
createExtensionSession
|
val cameraSelector = ExtensionsManager.
getExtensionEnabledCameraSelector
|
Basic Extender
Die Basic Extender-Schnittstelle bietet Hooks an mehreren Stellen 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 Extender-Klassen | |
---|---|
Nacht | NightPreviewExtenderImpl.java
|
HDR | HdrPreviewExtenderImpl.java
|
Automatisch | AutoPreviewExtenderImpl.java
|
Bokeh | BokehPreviewExtenderImpl.java
|
Gesichtsretusche | BeautyPreviewExtenderImpl.java
|
Im folgenden Beispiel verwenden wir PreviewExtenderImpl
und ImageCaptureExtenderImpl
als Platzhalter. Ersetzen Sie diese durch die Namen der tatsächlichen Dateien, die Sie implementieren.
Basic Extender bietet die folgenden Funktionen:
- Fügen Sie Sitzungsparameter ein, wenn Sie
CameraCaptureSession
(onPresetSession
) konfigurieren. - Sie werden über den Start und das Schließen der Aufnahmesitzung benachrichtigt und senden eine einzelne Anfrage, um die HAL mit den zurückgegebenen Parametern (
onEnableSession
,onDisableSession
) zu benachrichtigen. - Erfassen Sie Parameter für die Anfrage (
PreviewExtenderImpl.getCaptureStage
,ImageCaptureExtenderImpl.getCaptureStages
). - Fügen Sie Prozessoren für die Vorschau und die Aufnahme von Standbildern 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 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, damit die Erweiterungen aktiviert werden.
Dies ist oft der erste Schritt für Apps, um zu prüfen, ob der angegebene Erweiterungstyp für eine bestimmte Kamera-ID unterstützt wird, bevor die Erweiterung aktiviert wird. 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 Basic Extender
Nachdem festgestellt wurde, ob die Erweiterung verfügbar ist, sollten Apps die folgenden Informationen abfragen, bevor sie die Erweiterung aktivieren.
Still capture latency range (Latenzbereich für Standbildaufnahme):
ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
gibt den Bereich der Aufnahmelatenz für die App zurück, um zu bewerten, ob es angemessen ist, die Erweiterung für das aktuelle Szenario zu aktivieren.Unterstützte Größen für die Vorschau- und Aufnahmefläche:Mit
ImageCaptureExtenderImpl.getSupportedResolutions
undPreviewExtenderImpl.getSupportedResolutions
wird eine Liste der Bildformate und der 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 Ergebnisse aus Ihrer Implementierung abzurufen:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
Camera2/X ruft immer zuerst init()
für diese Extender-Klassen auf, bevor weitere Informationen angefordert werden.
App-Ablauf 3: Vorschau/Standbildaufnahme mit aktivierter Erweiterung (HAL-Implementierung)
Abbildung 5: App-Ablauf 3 auf Basic Extender
Das obige Diagramm veranschaulicht den Hauptablauf zum Aktivieren der Vorschau und zum Aufnehmen 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. Dadurch werden Sie darüber informiert, dass eine Kamerasitzung mit den angegebenen Erweiterungen gestartet wird.
Sie können die Initialisierung 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 das HAL zu benachrichtigen. Bevor die Aufnahmesitzung geschlossen wird, ruft Camera2/X onDisableSession
auf und sendet dann eine einzelne Anfrage mit den zurückgegebenen Aufnahmeparametern.
Die wiederholte Anfrage, die von Camera2/X ausgelöst wird, enthält die von PreviewExtenderImpl.getCaptureStage()
zurückgegebenen Anfrageparameter. Außerdem enthält die Anfrage zum Aufnehmen eines Standbilds die von ImageCaptureExtenderImpl.getCaptureStages()
zurückgegebenen Parameter.
Schließlich ruft Camera2/X onDeInit()
auf, nachdem die Kamerasitzung beendet wurde.
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 anzugeben, wie unten beschrieben:
PROCESSOR_TYPE_NONE
:Kein Prozessor. Bilder werden im Kamera-HAL verarbeitet.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY
:Mit dem Prozessortyp können Sie die wiederholte Anfrage mit neuen Parametern für die Aufnahme aktualisieren, die auf dem neuestenTotalCaptureResult
basieren.PreviewExtenderImpl.getProcessor
muss eineRequestUpdateProcessorImpl
-Instanz zurückgeben, die dieTotalCaptureResult
-Instanz verarbeitet und eineCaptureStageImpl
-Instanz zurückgibt, um die wiederholte 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 Prozessor ist für die Verarbeitung vonYUV_420_888
-Eingabebildern verantwortlich. Die Ausgabe sollte imPRIVATE
-Format der Vorschau erfolgen. Camera2/X verwendet anstelle vonPRIVATE
eineYUV_420_888
-Oberfläche, umCameraCaptureSession
für die Vorschau zu konfigurieren.Die folgende Abbildung zeigt den Ablauf:
Abbildung 6 Ablauf mit PreviewImageProcessorImpl
in der Vorschau ansehen
Die PreviewImageProcessorImpl
-Schnittstelle erweitert ProcessImpl
und hat drei wichtige Methoden:
Mit
onOutputSurface(Surface surface, int imageFormat)
wird die Ausgabefläche für den Prozessor festgelegt. FürPreviewImageProcessorImpl
istimageFormat
ein Pixelformat wiePixelFormat.RGBA_8888
.Mit
onResolutionUpdate(Size size)
wird die Größe des Eingabebilds festgelegt.Mit
onImageFormatUpdate(int imageFormat)
wird das Bildformat des Eingabebilds festgelegt. Derzeit kann nurYUV_420_888
ausgewählt werden.
Prozessor für die Bildaufnahme
Für die Aufnahme von Standbildern 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 ist und läuft, bevor Sie die Anfrage zum Aufnehmen eines Standbilds senden.
Der Ablauf ist im Diagramm unten dargestellt:
Abbildung 7. Still Capture-Ablauf mit CaptureProcessorImpl
Camera2/X verwendet für die Aufnahme von Standbildern eine Oberfläche im Format
YUV_420_888
, um die Aufnahmesitzung zu konfigurieren. Camera2/X bereitetCaptureProcessorImpl
durch Aufruf von Folgendem vor:CaptureProcessorImpl.onImageFormatUpdate()
mitYUV_420_888
.CaptureProcessorImpl.onResolutionUpdate()
durch die Größe des Eingabebilds.CaptureProcessorImpl.onOutputSurface()
mit einer AusgabeflächeYUV_420_888
.
ImageCaptureExtenderImpl.getCaptureStages
gibt eine Liste vonCaptureStageImpl
zurück, wobei jedes Element einerCaptureRequest
-Instanz mit Erfassungsparametern entspricht, die von Camera2/X gesendet werden. Wenn beispielsweise eine Liste mit dreiCaptureStageImpl
-Instanzen zurückgegeben wird, sendet Camera2/X drei Aufnahmeanfragen mit entsprechenden Aufnahmeparametern über diecaptureBurst
-API.Die empfangenen Bilder und
TotalCaptureResult
-Instanzen werden zusammengefasst und zur Verarbeitung anCaptureProcessorImpl
gesendet.CaptureProcessorImpl
schreibt das Ergebnis „Bild“ (YUV_420_888
-Format) auf die Ausgabefläche, die durch denonOutputSurface()
-Aufruf angegeben wird. Camera2/X konvertiert es bei Bedarf in JPEG-Bilder.
Erfassung von Anfrageschlüsseln und ‑ergebnissen unterstützen
Neben der Kameravorschau und der Aufnahme können Apps auch Zoom- und Blitzparameter festlegen oder einen Tap-to-Focus-Vorgang auslösen. 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 verfügbar machen können:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()
gibt die von Ihrer Implementierung unterstützten Schlüssel für Erfassungsanfragen zurück.ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()
gibt die Schlüssel für das Aufnahmeergebnis zurück, die im Aufnahmeergebnis 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 Methode process()
in PreviewImageProcessorImpl
und CaptureProcessorImpl
übergeben wird.
Sie sind dafür verantwortlich, das Aufnahmeergebnis über ProcessResultImpl
an Camera2/X zu melden.
Unten sehen Sie ein Beispiel für die Definition der CaptureProcessorImpl
-Schnittstelle.
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 häufige Kameravorgänge wie Zoom, Tippen zum Fokussieren, Blitz und Belichtungskorrektur empfehlen wir, die folgenden Tasten sowohl für die Aufnahmeanfrage als auch für das Aufnahmeergebnis 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
- Blitz:
CaptureRequest#CONTROL_AE_MODE
CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
CaptureRequest#FLASH_MODE
- Belichtungskorrektur:
CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION
Für Basic Extenders, die Version 1.2.0 oder frühere Versionen implementieren, werden alle oben genannten Schlüssel von der CameraX Extensions API explizit unterstützt. Bei extensions-interface
1.3.0 berücksichtigen sowohl CameraX als auch Camera2 die zurückgegebene Liste und unterstützen nur die darin enthaltenen Schlüssel. Wenn Sie beispielsweise in der Implementierung von Version 1.3.0 nur CaptureRequest#CONTROL_ZOOM_RATIO
und CaptureRequest#SCALER_CROP_REGION
zurückgeben, wird für die App nur das Zoomen unterstützt. Tippen zum Fokussieren, Blitz und Belichtungskorrektur sind dann nicht zulässig.
Erweiterter Extender
Advanced Extender ist eine Art von Anbieterimplementierung, die auf der Camera2 API basiert.
Dieser Extender-Typ wurde in extensions-interface
1.2.0 hinzugefügt. Je nach Gerätehersteller können Erweiterungen in der App-Ebene implementiert werden. Dies hängt von den folgenden Faktoren ab:
Benutzerdefinierte Streamkonfiguration:Sie können benutzerdefinierte Streams wie RAW-Streams konfigurieren oder mehrere Streams für verschiedene physische Kamera-IDs verwenden.
Möglichkeit zum Senden von Camera2-Anfragen:Unterstützung einer komplexen Interaktionslogik, mit der Erfassungsanfragen mit Parametern gesendet werden können, die auf den Ergebnissen vorheriger Anfragen basieren.
Advanced Extender bietet einen Wrapper oder eine Zwischenschicht, mit der Sie die Streamkonfiguration anpassen und Aufnahmeanfragen bei Bedarf senden können.
Zu implementierende Dateien
Wenn Sie zur Implementierung des erweiterten Extenders wechseln möchten, muss die Methode isAdvancedExtenderImplemented()
in ExtensionVersionImpl
true
zurückgeben. Für jeden Erweiterungstyp müssen OEMs die entsprechenden Extender-Klassen implementieren. Die Implementierungsdateien für Advanced 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 sie durch den Namen der Extender-Datei für die Erweiterung, die Sie implementieren.
Sehen wir uns an, wie Camera2/X die extensions-interface
aufruft, um die drei App-Abläufe zu ermöglichen.
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 Aufrufen 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 Aufnahme-Latenz für die App zurück, um zu bewerten, ob es angemessen ist, die Erweiterung für das aktuelle Szenario zu aktivieren.Unterstützte Auflösungen für Vorschau und Standbildaufnahme:
AdvancedExtenderImpl.getSupportedPreviewOutputResolutions()
gibt eine Map des Bildformats zur Liste der Größen zurück, die für das Vorschauoberflächenformat und die Vorschauoberflächengröße unterstützt werden. OEMs must support at least thePRIVATE
format.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 für Erfassungsanfragen/Ergebnisse (hinzugefügt in
extensions-interface
1.3.0): Camera2/X ruft die folgenden Methoden auf, um die unterstützten Schlüssel für Erfassungsanfragen und Ergebnisschlüssel aus Ihrer Implementierung abzurufen:AdvancedExtenderImpl.getAvailableCaptureRequestKeys
AdvancedExtenderImpl.getAvailableCaptureResultKeys
Weitere Informationen finden Sie unter Support Capture-Anfrageschlüssel und ‑Ergebnisse.
App-Ablauf 3: Vorschau/Standbildaufnahme mit aktivierter Erweiterung
Abbildung 10. App-Ablauf 3 auf Advanced Extender
Das obige Diagramm zeigt den Hauptablauf für das Starten der Vorschau und das Aufnehmen von Standbildern für den erweiterten Extender-Typ. Sehen wir uns die einzelnen Schritte an.
SessionProcessorImpl
-InstanzDie Kernimplementierung von Advanced Extender befindet sich in
SessionProcessorImpl
. Diese Klasse ist dafür verantwortlich, eine benutzerdefinierte Sitzungskonfiguration bereitzustellen und Erfassungsanfragen zu senden, um die Vorschau und die Standbildaufnahme zu starten.AdvancedExtenderImpl.createSessionProcessor()
wird aufgerufen, um dieSessionProcessorImpl
-Instanz zurückzugeben.initSession
Mit
SessionProcessorImpl.initSession()
wird die Sitzung für die Erweiterung initialisiert. Hier weisen Sie Ressourcen zu und geben eine Sitzungskonfiguration für die Vorbereitung einesCameraCaptureSession
zurück.Für die Eingabeparameter gibt Camera2/X die Ausgabeflächenkonfigurationen für die Vorschau, die Aufnahme von Standbildern und eine optionale YUV-Bildanalyse an. Diese Konfiguration der Ausgabefläche (
OutputSurfaceImpl
) enthält die Fläche, Größe und das Bildformat, die mit den folgenden Methoden inAdvancedExtenderImpl
abgerufen werden:getSupportedPreviewOutputResolutions()
getSupportedCaptureOutputResolutions()
getSupportedYuvAnalysisResolutions()
Sie müssen 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 die Ausgabeflächen auszugeben, die von Camera2/X übergeben werden. Hier sind einige Optionen zum Aktivieren der Ausgabe:- Verarbeitung in der Kamera-HAL:Sie können die Ausgabeflächen direkt mit einer
SurfaceOutputConfigImpl
-Implementierung zuCameraCaptureSession
hinzufügen. Dadurch wird die bereitgestellte Ausgabefläche für die Kamerapipeline konfiguriert und das Kamera-HAL kann das Bild verarbeiten. Verarbeiten der Zwischenoberfläche
ImageReader
(RAW, YUV usw.): Fügen Sie die ZwischenoberflächenImageReader
demCameraCaptureSession
mit einerImageReaderOutputConfigImpl
-Instanz hinzu.Sie müssen die Zwischenbilder verarbeiten und das Ergebnisbild auf die Ausgabefläche schreiben.
- Camera2-Oberflächenfreigabe verwenden:Sie können die Oberflächenfreigabe mit einer anderen Oberfläche verwenden, indem Sie eine beliebige
Camera2OutputConfigImpl
-Instanz dergetSurfaceSharingOutputConfigs()
-Methode einer anderenCamera2OutputConfigImpl
-Instanz hinzufügen. Das Oberflächenformat und die Größe müssen identisch sein.
Alle
Camera2OutputConfigImpl
, einschließlichSurfaceOutputConfigImpl
undImageReaderOutputConfigImpl
, müssen eine eindeutige ID (getId()
) haben, mit der die Zieloberflä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
, sodass Sie Aufnahmeanfragen ausführen und Bilder abrufen können, wennImageReaderOutputConfigImpl
verwendet wird.Die
RequestProcessImpl
-APIs ähneln den Camera2-CameraCaptureSession
-APIs in Bezug auf die Ausführung von Anfragen. Die Unterschiede sind:- Die Zieloberfläche wird durch die ID der
Camera2OutputConfigImpl
-Instanz angegeben. - Die Möglichkeit, das Bild des
ImageReader
abzurufen.
Sie können
RequestProcessorImpl.setImageProcessor()
mit einer angegebenenCamera2OutputConfigImpl
-ID aufrufen, um eineImageProcessorImpl
-Instanz für den Empfang von Bildern zu registrieren.Die
RequestProcessImpl
-Instanz wird nach Camera2/X-Aufrufen vonSessionProcessorImpl.onCaptureSessionEnd()
ungültig.- Die Zieloberfläche wird durch die ID der
Vorschau starten und Foto aufnehmen
Bei der erweiterten Extender-Implementierung können Sie Erfassungsanfragen über die
RequestProcessorImpl
-Schnittstelle senden. Camera2/X benachrichtigt Sie, dass Sie den sich wiederholenden Antrag für die Vorschau oder die Sequenz für die Aufnahme von Standbildern starten müssen, indem SieSessionProcessorImpl#startRepeating
bzw.SessionProcessorImpl#startCapture
aufrufen. Sie sollten Erfassungsanfragen senden, um diese Vorschau- und Standbildanfragen zu erfüllen.Camera2/X legt die Parameter für die Aufnahmeanfrage auch über
SessionProcessorImpl#setParameters
fest. Sie müssen diese Anfrageparameter (sofern Parameter unterstützt werden) sowohl für die wiederholten als auch für die einzelnen Anfragen festlegen.Sie müssen mindestens
CaptureRequest.JPEG_ORIENTATION
undCaptureRequest.JPEG_QUALITY
unterstützen.extensions-interface
1.3.0 unterstützt Anforderungs- und Ergebnisschlüssel, die von den folgenden Methoden bereitgestellt 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 Erfassungsresultat 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
. Sie können alle Schlüssel für Erfassungsanfragen ignorieren, die nicht inAdvancedExtenderImpl.getAvailableCaptureRequestKeys()
beworben wurden.startTrigger()
wird seitextensions-interface
1.3.0 unterstützt. Damit können Apps mit Erweiterungen die Funktionen „Fokus durch Tippen“ und „Blitz“ implementieren.Aufräumen
Wenn Sie eine Aufzeichnungssitzung beenden, wird
SessionProcessorImpl.onCaptureSessionEnd()
vor dem Schließen vonCameraCaptureSession
aufgerufen. Nachdem die Aufnahmesitzung geschlossen wurde, führtdeInitSession()
die Bereinigung durch.
Unterstützung von Vorschau, Standbildaufnahme 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 Erweiterung nur für die Aufnahme von Standbildern verwenden.
Beim 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 für die Konfiguration von CameraCaptureSession
unterstützen. Wenn Sie einen Prozessor implementieren, müssen Sie also die Streamkombination von drei YUV_420_888
-Streams unterstützen.
Bei Advanced Extender übergibt Camera2/X drei Ausgabeflächen an den SessionProcessorImpl.initSession()
-Aufruf. Diese Ausgabeflächen sind für die Vorschau, die Aufnahme von Einzelbildern bzw. die Bildanalyse vorgesehen. Sie müssen dafür sorgen, dass auf den Ausgabeflächen für Vorschau und Standbild die gültige Ausgabe angezeigt wird. Achten Sie jedoch darauf, dass die Ausgabefläche für die Bildanalyse nur funktioniert, wenn sie nicht null ist. Wenn Ihre Implementierung den Bildanalysestream 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.
Videoaufnahmen unterstützen
Die aktuelle Camera Extension-Architektur unterstützt nur die Anwendungsfälle „Vorschau“ und „Standbildaufnahme“. Die Aktivierung der Erweiterung auf den Plattformen MediaCodec
oder MediaRecorder
zur Aufzeichnung des Videos wird nicht unterstützt. Es ist jedoch möglich, dass Apps die Vorschauausgabe aufzeichnen.
Die Unterstützung von MediaCodec
- und MediaRecorder
-Oberflächen wird untersucht.
Erweiterungsspezifische Metadaten
Unter Android 14 und höher können Kameraerweiterungsclients mit erweiterungsspezifischen Metadaten erweiterungsspezifische Einstellungen für Aufnahmeanfragen festlegen und Ergebnisse empfangen. Insbesondere können Kameraerweiterungsclients den Erfassungsanfrageparameter EXTENSION_STRENGTH
verwenden, um die Stärke der Erweiterung zu steuern, und das Erfassungsergebnis EXTENSION_CURRENT_TYPE
, um den aktivierten Erweiterungstyp anzugeben.
Anfragen erfassen
Mit dem Erfassungsanfrageparameter
EXTENSION_STRENGTH
wird die Stärke des Effekts der Erweiterungsnachbearbeitung gesteuert. Das entsprechende Aufnahmeergebnis 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
: Hiermit wird die Stärke der Unschärfe gesteuert.HDR
undNIGHT
: Hiermit wird die Anzahl der zusammengefügten Bilder und die Helligkeit des endgültigen Bilds gesteuert.FACE_RETOUCH
: Steuert das Ausmaß der kosmetischen Optimierung und der Hautglättung.
Der unterstützte Bereich für den Parameter EXTENSION_STRENGTH
liegt zwischen 0
und 100
. 0
steht für keine Erweiterungsverarbeitung oder einfaches Passthrough und 100
für die maximale Erweiterungsstärke des Verarbeitungseffekts.
Wenn Sie Unterstützung für EXTENSION_STRENGTH
hinzufügen möchten, verwenden Sie die anbieterspezifischen Parameter-APIs, die in Version 1.3.0 der Erweiterungsbibliothekschnittstelle eingeführt wurden. Weitere Informationen finden Sie unter getAvailableCaptureRequestKeys()
.
Ergebnisse erfassen
Mit dem Erfassungsresultat EXTENSION_CURRENT_TYPE
können Erweiterungsimplementierungen Clients über den aktiven Erweiterungstyp informieren.
Da Erweiterungen vom Typ AUTO
je nach Szenenbedingungen dynamisch zwischen Erweiterungstypen wie HDR
und NIGHT
wechseln, können Kameraerweiterungs-Apps EXTENSION_CURRENT_TYPE
verwenden, um Informationen zur aktuellen Erweiterung anzuzeigen, die von der Erweiterung vom Typ AUTO
ausgewählt wurde.
Geschätzte Latenz bei der Aufnahme von Standbildern in Echtzeit
Unter Android 14 und höher können Kameraerweiterungsclients mithilfe von getRealtimeStillCaptureLatency()
Echtzeit-Schätzungen der Latenz bei der Aufnahme von Standbildern basierend auf der Szene und den Umgebungsbedingungen abfragen. Diese Methode liefert genauere Schätzungen als die statische getEstimatedCaptureLatencyRangeMillis()
-Methode. Anhand der Latenzschätzung können Apps entscheiden, ob die Verarbeitung der Erweiterung übersprungen oder den Nutzern ein Hinweis auf einen lang andauernden Vorgang angezeigt werden soll.
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 Latenzschätzungen für die Echtzeit-Standbildaufnahme zu unterstützen, müssen Sie Folgendes implementieren:
- Einfache Erweiterungen:
ImageCaptureExtenderImpl.getRealtimeCaptureLatency()
- Erweiterte Erweiterungen:
SessionProcessorImpl.getRealtimeCaptureLatency
Callbacks für den Fortschritt der Erfassung verarbeiten
Unter Android 14 und höher können Kameraerweiterungs-Clients Rückrufe für den Fortschritt von lang andauernden Verarbeitungsvorgängen für Standbilder erhalten. Apps können den aktuellen Fortschritt für Nutzer anzeigen, um die allgemeine Nutzerfreundlichkeit 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 für den Fortschritt der Erfassung 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()
Postview-Standbild
Unter Android 14 und höher können Kameraerweiterungen mit setPostviewOutputConfiguration
eine Postview (Vorschaubild) bereitstellen.
Um die Nutzerfreundlichkeit zu verbessern, können Apps ein Postview-Bild als Platzhalter anzeigen, wenn bei einer Erweiterung eine erhöhte Verarbeitungslatenz auftritt. Das Bild kann dann ersetzt werden, wenn das endgültige Bild verfügbar ist. Apps können Post-View-Erfassungsanfragen mit dem folgenden Referenzcode 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 Aufnahme von Standbildern nach der Aufnahme unterstützt wird, muss in der Implementierung des Anbieters Folgendes implementiert werden:
Einfache Erweiterungen:
CaptureProcessorImpl.onPostviewOutputSurface
undCaptureProcessorImpl.processWithPostview
Erweiterte Erweiterungen:
SessionProcessorImpl.startCaptureWithPostview
SurfaceView-Ausgabe unterstützen
Unter Android 14 und höher können Kameraerweiterungsclients energie- und leistungsoptimierte Vorschau-Renderpfade verwenden, indem sie eine SurfaceView
-Instanz für die Vorschauausgabe für wiederholte Anfragen registrieren.
Damit die Ausgabe SurfaceView
unterstützt wird, muss Ihre Anbietererweiterung in der Lage sein, Vorschauen 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 Implementierungen von Anbietererweiterungen einen anbieterspezifischen Sitzungstyp auswählen, der anstelle des Standardwerts in der internen Kameraaufnahmesitzung festgelegt wird.
Die Funktion wird vollständig innerhalb des Frameworks und des Anbieter-Stacks ausgeführt und hat keine Auswirkungen auf clientseitige oder öffentliche APIs.
Wenn Sie einen anbieterspezifischen Sitzungstyp auswählen möchten, implementieren Sie für Ihre Erweiterungsbibliotheken Folgendes:
* ExtenderStateListener.onSessionType()
für einfache Erweiterungen
* Camera2SessionConfigImpl.getSessionType()
für erweiterte Erweiterungen
Versionsverlauf der Erweiterungsschnittstelle
In der folgenden Tabelle ist der Versionsverlauf der Camera Extension-Schnittstelle aufgeführt. 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 der OEM-Anbieterbibliothek sind in frameworks/ex
verfügbar.
advancedSample
: Eine einfache Implementierung von Advanced Extender.sample
: Eine einfache Implementierung von Basic Extender.service_based_sample
: Eine Implementierung, die zeigt, wie Kameraerweiterungen in einemService
gehostet werden. Diese Implementierung enthält die folgenden Komponenten:oem_library
: Eine OEM-Bibliothek für Kameraerweiterungen für die Camera2- und CameraX-Erweiterungs-APIs, dieExtensions-Interface
implementiert. Dies dient als Passthrough, der Aufrufe vonExtensions-Interface
an den Dienst weiterleitet. Diese Bibliothek bietet auch AIDL-Dateien und Wrapper-Klassen für die Kommunikation mit dem Dienst.Der erweiterte Repeater ist standardmäßig aktiviert. Wenn Sie den Basic Extender aktivieren möchten, ändern Sie
ExtensionsVersionImpl#isAdvancedExtenderImplemented
so, dassfalse
zurückgegeben wird.extensions_service
: Eine Beispielimplementierung des Extensions Service. Fügen Sie hier Ihre Implementierung hinzu. Die im Dienst zu implementierende Schnittstelle ähnelt derExtensions-Interface
. Die Implementierung vonIAdvancedExtenderImpl.Stub
führt beispielsweise dieselben Vorgänge aus wieAdvancedExtenderImpl
.ImageWrapper
undTotalCaptureResultWrapper
sind erforderlich, damitImage
undTotalCaptureResult
parcelable sind.
Anbieterbibliothek auf einem Gerät einrichten
Die OEM-Anbieterbibliothek ist nicht in eine App eingebunden, sondern wird zur Laufzeit von Camera2/X vom Gerät geladen. In CameraX deklariert das <uses-library>
-Tag, 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 deklariert, dass die <uses-library>
zur Laufzeit dieselbe androidx.camera.extensions.impl
-Bibliothek lädt.
Dadurch können Drittanbieter-Apps, die Erweiterungen verwenden, die OEM-Anbieterbibliothek automatisch laden. Die OEM-Bibliothek ist als optional gekennzeichnet, damit Apps auf Geräten ausgeführt werden können, auf denen die Bibliothek nicht vorhanden 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 erkannt werden kann.
So richten Sie die OEM-Bibliothek auf einem Gerät ein:
- Fügen Sie eine Berechtigungsdatei hinzu, die für das
<uses-library>
-Tag erforderlich ist, und verwenden Sie dabei das folgende Format:/etc/permissions/ANY_FILENAME.xml
. Beispiel:/etc/permissions/camera_extensions.xml
Die Dateien in diesem Verzeichnis enthalten eine Zuordnung der in<uses-library>
genannten Bibliothek zum tatsächlichen Dateipfad auf dem Gerät. Verwenden Sie das folgende Beispiel, um der Datei die erforderlichen Informationen hinzuzufügen.
name
mussandroidx.camera.extensions.impl
sein, da CameraX nach dieser Bibliothek sucht.file
ist der absolute Pfad der Datei, die die Implementierung der Erweiterungen 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>
In Android 12 oder höher muss für Geräte, die CameraX-Erweiterungen unterstützen, die Eigenschaft ro.camerax.extensions.enabled
auf true
festgelegt sein. So kann abgefragt werden, ob ein Gerät Erweiterungen unterstützt.
Fügen Sie dazu der Make-Datei des Geräts die folgende Zeile hinzu:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
Zertifizierungsstufe
Um Ihre Implementierung der OEM-Anbieterbibliothek während der Entwicklungsphase zu testen, verwenden Sie die Beispiel-App unter androidx-main/camera/integration-tests/extensionstestapp/
, in der verschiedene Anbietererweiterungen durchlaufen werden.
Nachdem Sie die Implementierung abgeschlossen haben, können Sie mit dem Validierungstool für Kameraerweiterungen automatisierte und manuelle Tests durchführen, um zu prüfen, ob die Anbieterbibliothek richtig implementiert wurde.
Erweiterter Szenenmodus im Vergleich zu Kameraerweiterungen
Für die Bokeh-Erweiterung können Sie sie nicht nur über Kameraerweiterungen, sondern auch über den erweiterten Szenenmodus verfügbar machen, der über den Schlüssel 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 beispielsweise den erweiterten Szenenmodus in einer regulären CameraCaptureSession
-Instanz aktivieren, die flexible Streamkombinationen und Parameter für Erfassungsanfragen unterstützt. Im Gegensatz dazu unterstützen Kameraerweiterungen nur eine feste Anzahl von Streamtypen und nur eine begrenzte Anzahl von Parametern für Erfassungsanfragen.
Ein Nachteil des erweiterten Szenenmodus ist, dass er nur im Kamera-HAL implementiert werden kann. Das bedeutet, dass er für alle orthogonalen Steuerelemente, die App-Entwicklern zur Verfügung stehen, verifiziert werden muss.
Wir empfehlen, Bokeh sowohl über den erweiterten Szenenmodus als auch über Camera Extensions verfügbar zu machen, da Apps möglicherweise eine bestimmte API bevorzugen, 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 Kameraerweiterungsschnittstelle basierend auf dem erweiterten Szenenmodus implementieren. Wenn die Implementierung von Bokeh in der Kamera-HAL schwierig ist, z. B. weil ein Postprozessor in der App-Ebene zum Verarbeiten von Bildern erforderlich ist, empfehlen wir, die Bokeh-Erweiterung über die Camera Extensions-Schnittstelle zu implementieren.
Häufig gestellte Fragen
Gibt es Einschränkungen hinsichtlich der API-Ebenen?
Ja. Das hängt von den Android API-Funktionen ab, die für die Implementierung der OEM-Anbieterbibliothek erforderlich sind. ExtenderStateListener.onPresetSession()
verwendet beispielsweise den Aufruf SessionConfiguration.setSessionParameters()
, um eine Baseline-Gruppe 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.