Hinweis: Auf dieser Seite wird auf das Camera2-Paket verwiesen. Wenn Ihre App keine bestimmten Low-Level-Funktionen von Camera2 erfordert, empfehlen wir die Verwendung von CameraX. Sowohl CameraX als auch Camera2 unterstützen Android 5.0 (API-Level 21) und höher.
Die Camera2 APIs unterstützen die HDR-Videoaufnahme (High Dynamic Range). So können Sie HDR-Videoinhalte mit Ihrer Kamera in der Vorschau ansehen und aufnehmen. Im Vergleich zu SDR (Standard Dynamic Range) bietet HDR eine größere Farbpalette und erhöht den Dynamikbereich der Luminanzkomponente (von derzeit 100 cd/m2 auf Tausende von cd/m2). Das Ergebnis ist eine Videoqualität, die der Realität näher kommt, mit satteren Farben, helleren Lichtern und dunkleren Schatten.
Hier sehen Sie, wie ein Sonnenuntergang in einem HDR-Video mit lebendigeren Details aufgenommen wird.
Gerätevoraussetzungen
Nicht alle Android-Geräte unterstützen die HDR-Videoaufnahme. Bevor Sie in Ihrer App HDR-Videos aufnehmen, prüfen Sie, ob Ihr Gerät die folgenden Voraussetzungen erfüllt:
- Android 13 (API-Level 33) als Ziel.
- Ein Kamerasensor mit 10 Bit oder höher. Weitere Informationen zur HDR Unterstützung finden Sie unter HDR-Unterstützung prüfen.
Da nicht alle Geräte die Voraussetzungen erfüllen, können Sie beim Einrichten der HDR-Videoaufnahme in Ihrer App einen separaten Codepfad hinzufügen. So kann Ihre App auf inkompatiblen Geräten auf SDR zurückgreifen. Sie sollten auch eine UI-Option für SDR hinzufügen. Der Nutzer kann dann je nach Bedarf zwischen SDR und HDR für seine Videoaufnahmen wechseln.
Architektur für die HDR-Aufnahme
Das folgende Diagramm zeigt die Hauptkomponenten der Architektur für die HDR-Aufnahme.
Wenn ein Kameragerät ein Bild in HDR aufnimmt, weist das Camera2-Framework einen Puffer zu, in dem die verarbeitete Ausgabe des Kamerasensors gespeichert wird.
Außerdem werden die entsprechenden HDR-Metadaten angehängt, wenn dies vom HDR-Profil erforderlich ist.
Das Camera2-Framework stellt den gefüllten Puffer dann für die Ausgabefläche
in die Warteschlange, auf die in der CaptureRequest verwiesen wird, z. B. ein Display oder
ein Video-Encoder, wie im Diagramm dargestellt.
HDR-Unterstützung prüfen
Bevor Sie in Ihrer App HDR-Videos aufnehmen, prüfen Sie, ob das Gerät Ihr gewünschtes HDR-Profil unterstützt.
Verwenden Sie die CameraManager getCameraCharacteristics() Methode, um eine
CameraCharacteristics
Instanz abzurufen, mit der Sie die HDR-Funktionen Ihres Geräts abfragen können.
In den folgenden Schritten wird geprüft, ob ein Gerät HLG10 unterstützt. HLG10 ist der HDR-Standard, den Gerätehersteller auf Kameras mit 10-Bit-Ausgabe unterstützen müssen.
Prüfen Sie zuerst, ob das Gerät 10-Bit-Profile unterstützt (die Bittiefe für HLG10):
Kotlin
private fun isTenBitProfileSupported(cameraId: String): Boolean { val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) val availableCapabilities = cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) for (capability in availableCapabilities!!) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) { return true } } return false }
Prüfen Sie als Nächstes, ob das Gerät HLG10 (oder ein anderes unterstütztes Profil) unterstützt:
Kotlin
@RequiresApi(api = 33) private fun isHLGSupported(cameraId: String): Boolean { if (isTenBitProfileSupported(cameraId)) { Val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) val availableProfiles = cameraCharacteristics .get(CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES)!! .getSupportedProfiles() // Checks for the desired profile, in this case HLG10 return availableProfiles.contains(DynamicRangeProfiles.HLG10) } return false; }
Wenn das Gerät HDR unterstützt, gibt isHLGSupported() immer true zurück.
Weitere Informationen finden Sie in der
CameraCharacteristics
Referenzdokumentation.
HDR-Aufnahme einrichten
Nachdem Sie geprüft haben, ob Ihr Gerät HDR unterstützt, richten Sie Ihre App so ein, dass ein roher HDR-Videostream von der Kamera aufgenommen wird.
Verwenden Sie setDynamicRangeProfile(), um die OutputConfiguration
des Streams mit einem vom Gerät unterstützten HDR-Profil zu versehen, das dann
bei der Erstellung an die CameraCaptureSession
übergeben wird.
Hier finden Sie eine Liste der unterstützten HDR-Profile.
Im folgenden Codebeispiel prüft setupSessionDynamicRangeProfile() zuerst, ob auf dem Gerät Android 13 ausgeführt wird.
Anschließend wird die CameraCaptureSession mit dem vom Gerät unterstützten HDR-Profil als OutputConfiguration eingerichtet:
Kotlin
/** * Creates a [CameraCaptureSession] with a dynamic range profile. */ private fun setupSessionWithDynamicRangeProfile( dynamicRange: Long, device: CameraDevice, targets: List, handler: Handler? = null, stateCallback: CameraCaptureSession.StateCallback ): Boolean { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { val outputConfigs = mutableListOf () for (target in targets) { val outputConfig = OutputConfiguration(target) //sets the dynamic range profile, for example DynamicRangeProfiles.HLG10 outputConfig.setDynamicRangeProfile(dynamicRange) outputConfigs.add(outputConfig) } device.createCaptureSessionByOutputConfigurations( outputConfigs, stateCallback, handler ) return true } else { device.createCaptureSession(targets, stateCallback, handler) return false } }
Wenn Ihre Kamera-App die Kamera initialisiert, sendet sie eine
wiederholte
CaptureRequest
um eine Vorschau der Aufnahme zu erhalten:
Kotlin
session.setRepeatingRequest(previewRequest, null, cameraHandler)
Und auch, um die Videoaufnahme zu starten:
Kotlin
// Start recording repeating requests, which stops the ongoing preview // repeating requests without having to explicitly call // `session.stopRepeating` session.setRepeatingRequest(recordRequest, object : CameraCaptureSession.CaptureCallback() { override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) { if (currentlyRecording) { encoder.frameAvailable() } } }, cameraHandler)
HDR-Kamerastream codieren
Verwenden Sie MediaCodec, um den HDR-Kamerastream zu codieren und die Datei auf die Festplatte zu schreiben,
.
Rufen Sie zuerst die OutputSurface,
die einem Puffer zugeordnet ist, in dem Rohvideodaten gespeichert werden, ab.
Verwenden Sie für MediaCodec,
die Funktion createInputSurface().
Um MediaCodec zu initialisieren, muss eine App ein
MediaFormat mit einem angegebenen
Codec-Profil, Farbraum, Farbbereich und einer Übertragungsfunktion erstellen:
Kotlin
val mimeType = when { dynamicRange == DynamicRangeProfiles.STANDARD -> MediaFormat.MIMETYPE_VIDEO_AVC dynamicRange < DynamicRangeProfiles.PUBLIC_MAX -> MediaFormat.MIMETYPE_VIDEO_HEVC else -> throw IllegalArgumentException("Unknown dynamic range format") } val codecProfile = when { dynamicRange == DynamicRangeProfiles.HLG10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 dynamicRange == DynamicRangeProfiles.HDR10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 dynamicRange == DynamicRangeProfiles.HDR10_PLUS -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus else -> -1 } // Failing to correctly set color transfer causes quality issues // for example, washout and color clipping val transferFunction = when (codecProfile) { MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 -> MediaFormat.COLOR_TRANSFER_HLG MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 -> MediaFormat.COLOR_TRANSFER_ST2084 MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus -> MediaFormat.COLOR_TRANSFER_ST2084 else -> MediaFormat.COLOR_TRANSFER_SDR_VIDEO } val format = MediaFormat.createVideoFormat(mimeType, width, height) // Set some properties. Failing to specify some of these can cause the MediaCodec // configure() call to throw an exception. format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface) format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate) format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate) format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL) if (codecProfile != -1) { format.setInteger(MediaFormat.KEY_PROFILE, codecProfile) format.setInteger(MediaFormat.KEY_COLOR_STANDARD, MediaFormat.COLOR_STANDARD_BT2020) format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED) format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, transferFunction) format.setFeatureEnabled(MediaCodecInfo.CodecCapabilities.FEATURE_HdrEditing, true) } mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
Weitere Informationen zur Implementierung finden Sie in der Beispiel-App Camera2Video unter
EncoderWrapper.kt.
HDR-Formate
Ab Android 13 müssen Kamerageräte mit 10-Bit-Ausgabe HLG10 für die HDR-Aufnahme und Wiedergabe unterstützen. Außerdem können Gerätehersteller mit der Architektur für die HDR-Aufnahme jedes beliebige HDR-Format aktivieren.
In der folgenden Tabelle sind die verfügbaren HDR-Formate und ihre Funktionen für die HDR-Videoaufnahme zusammengefasst.
| Format | Übertragungsfunktion (TF) | Metadaten | Codec | Bittiefe |
|---|---|---|---|---|
| HLG10 | HLG | Nein | HEVC | 10 Bit |
| HDR10 | PQ | Statisch | HEVC | 10 Bit |
| HDR10+ | PQ | Dynamisch | HEVC | 10 Bit |
| Dolby Vision 8.4 | HLG | Dynamisch | HEVC | 10 Bit |
Ressourcen
Eine funktionierende App mit HDR-Videoaufnahmefunktion finden Sie im Camera2Video-Beispiel auf GitHub.