Uwaga: ta strona dotyczy pakietu Aparat2. Jeśli Twoja aplikacja nie wymaga konkretnych, niskopoziomowych funkcji z Aparatu 2, zalecamy używanie AparatuX. Aparaty CameraX i Aparat 2 obsługują Androida 5.0 (poziom interfejsu API 21) i nowsze wersje.
Obsługa interfejsów API Camera2 Nagrywanie filmów High Dynamic Range (HDR) pozwala wyświetlać podgląd nagrywać filmy HDR za pomocą aparatu. W porównaniu do standardowych kreacji dynamicznych Zakres (SDR) zapewnia szerszy zakres kolorów i wzmacnia zakres składnika luminancji (od bieżącego 100 cd/m2 do 1000 s w przypadku cd/m2). Dzięki temu jakość wideo jest bardziej zgodna z rzeczywistością, bogatsze kolory, jaśniejsze podświetlenia i ciemniejsze cienie.
Zobacz, jak w trybie HDR uwieczniasz zachód słońca w bardziej wyrazistych szczegółach.
Wymagania wstępne dla urządzenia
Nie wszystkie urządzenia z Androidem obsługują nagrywanie filmów HDR. Zanim nagrasz film HDR w aplikacji, sprawdź, czy Twoje urządzenie spełnia spełnić te wymagania wstępne:
- Jest kierowana na Androida 13 (poziom API 33).
- wyposażony w 10-bitowy lub większy czujnik aparatu, Więcej informacji o HDR Pomoc znajdziesz w artykule Sprawdzanie obsługi HDR.
Nie wszystkie urządzenia spełniają wymagania wstępne, więc możesz dodać oddzielny kod. podczas konfigurowania nagrywania filmu HDR w aplikacji. Dzięki temu aplikacja może wrócić do trybu SDR na niezgodnych urządzeniach. Zastanów się też nad dodaniem w interfejsie opcji SDR. Użytkownik może wtedy przełączyć między SDR a HDR.
Architektura przechwytywania HDR
Poniższy diagram przedstawia główne elementy architektury przechwytywania HDR.
Gdy aparat rejestruje klatkę w trybie HDR, platforma Camera2 przydziela
bufor, który zapisuje przetworzone dane wyjściowe z czujnika aparatu.
Dołącza też odpowiednie metadane HDR, jeśli wymaga tego profil HDR.
Platforma Camera2 umieszcza następnie zapełniony bufor w kolejce na powierzchni wyjściowej.
wspomniane w CaptureRequest
, takie jak wyświetlacz czy
zgodnie z ilustracją.
Sprawdź, czy obsługuje HDR
Zanim nagrasz film HDR w aplikacji, sprawdź, czy urządzenie obsługuje wybranego profilu HDR.
Użyj metody CameraManager
getCameraCharacteristics()
, aby uzyskać
CameraCharacteristics
, o które można zapytać o możliwości HDR na Twoim urządzeniu.
Aby sprawdzić, czy urządzenie obsługuje HLG10, wykonaj te czynności. HLG10 to bazowy standard HDR, który musi obsługiwać producenci urządzeń w przypadku aparatów z wyjściem 10-bitowym.
Najpierw sprawdź, czy urządzenie obsługuje 10-bitowe profile (z głębią bitową w przypadku 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 }
Następnie sprawdź, czy urządzenie obsługuje HLG10 (lub inny obsługiwany profil):
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; }
Jeśli urządzenie obsługuje HDR, funkcja isHLGSupported()
zawsze zwraca wartość true
.
Więcej informacji:
CameraCharacteristics
dokumentacji referencyjnej.
Konfigurowanie nagrywania HDR
Gdy upewnisz się, że Twoje urządzenie obsługuje HDR, skonfiguruj aplikację, aby nagrywać
nieprzetworzony strumień wideo HDR
z kamery.
Użyj setDynamicRangeProfile()
, aby podać OutputConfiguration
transmisji
za pomocą profilu HDR obsługiwanego przez urządzenie,
do CameraCaptureSession
podczas tworzenia.
Zobacz listę obsługiwanych profili HDR.
W tym przykładowym kodzie setupSessionDynamicRangeProfile()
najpierw sprawdza się
że na urządzeniu jest zainstalowany Android 13.
Następnie skonfiguruje urządzenie CameraCaptureSession
przy użyciu
Profil HDR jako OutputConfiguration
:
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 } }
}
Gdy aplikacja aparatu uruchamia kamerę, wysyła
powtarzanie
CaptureRequest
aby wyświetlić podgląd nagrania:
Kotlin
session.setRepeatingRequest(previewRequest, null, cameraHandler)
Aby rozpocząć nagrywanie filmu:
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)
Kodowanie transmisji z kamery HDR
Aby zakodować strumień HDR z kamery i zapisać plik na dysku:
użyj MediaCodec
.
Najpierw pobierz OutputSurface
,
który jest mapowany do bufora, w którym przechowywane są nieprzetworzone dane wideo.
W przypadku usługi MediaCodec
,
użyj funkcji createInputSurface()
.
Aby zainicjować MediaCodec
, aplikacja musi utworzyć
MediaFormat
z określoną wartością
profil kodeka, przestrzeń kolorów, zakres kolorów i funkcję transferu:
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)
Więcej informacji o wdrażaniu znajdziesz w przykładowej aplikacji Camera2Video
EncoderWrapper.kt
Formaty HDR
Urządzenia z aparatami z możliwością wyjścia 10-bitowego (począwszy od Androida 13) muszą obsługiwać HLG10 w celu przechwytywania HDR. playback. Producenci urządzeń mogą też włączyć dowolny format HDR. korzystając z architektury przechwytywania HDR.
W tabeli poniżej znajdziesz podsumowanie dostępnych formatów HDR i ich możliwości. w trybie HDR.
Format | Funkcja transferu (TF) | Metadane | Kodek | Głębia bitowa |
---|---|---|---|---|
HLG10 | protokół HLG | Nie | protokół HEVC | 10-bitowy |
HDR10 | PQ | Statyczny | protokół HEVC | 10-bitowy |
HDR10+ | PQ | Dynamiczne | protokół HEVC | 10-bitowy |
Dolby Vision 8.4 | protokół HLG | Dynamiczne | protokół HEVC | 10-bitowy |
Materiały
Informacje o działającej aplikacji z funkcją nagrywania filmów HDR znajdziesz w Przykład z aparatu Camera2Video w GitHubie.