Nota: questa pagina si riferisce al pacchetto Camera2. A meno che la tua app non richieda funzionalità specifiche di basso livello di Camera2, ti consigliamo di utilizzare CameraX. Sia CameraX sia Camera2 supportano Android 5.0 (livello API 21) e versioni successive.
Le API Camera2 supportano l'acquisizione di video HDR (High Dynamic Range), che ti consente di visualizzare l'anteprima e registrare contenuti video HDR utilizzando la videocamera. Rispetto all'SDR (Standard Dynamic Range), l'HDR offre una gamma di colori più ampia e aumenta la gamma dinamica del componente di luminanza (dalle attuali 100 cd/m2 a migliaia di cd/m2). Il risultato è una qualità video più simile alla realtà, con colori più ricchi, luci più luminose e ombre più scure.
Scopri come i video HDR catturano un tramonto con dettagli più vivaci.
Prerequisiti del dispositivo
Non tutti i dispositivi Android supportano l'acquisizione di video HDR. Prima di acquisire video HDR nella tua app, determina se il dispositivo soddisfa i seguenti prerequisiti:
- Ha come target Android 13 (livello API 33).
- Ha un sensore della videocamera a 10 bit o superiore. Per saperne di più sul supporto HDR, consulta Controllare il supporto HDR.
Poiché non tutti i dispositivi soddisfano i prerequisiti, puoi aggiungere un percorso di codice separato quando configuri l'acquisizione di video HDR nella tua app. In questo modo, la tua app può eseguire il fallback a SDR sui dispositivi incompatibili. Inoltre, valuta la possibilità di aggiungere un'opzione dell'interfaccia utente per SDR. L'utente può quindi passare da SDR a HDR in base alle proprie esigenze di registrazione video.
Architettura di acquisizione HDR
Il seguente diagramma mostra i componenti principali dell'architettura di acquisizione HDR.
Quando un dispositivo con videocamera acquisisce un frame in HDR, il framework Camera2 alloca un buffer che memorizza l'output del sensore della videocamera elaborato.
Se richiesto dal profilo HDR, allega anche i rispettivi metadati HDR.
Il framework Camera2 mette quindi in coda il buffer compilato per la superficie di output
a cui fa riferimento CaptureRequest, ad esempio un display o
un codificatore video, come mostrato nel diagramma.
Controllare il supporto HDR
Prima di acquisire video HDR nella tua app, determina se il dispositivo supporta il profilo HDR che ti interessa.
Utilizza il metodo CameraManager getCameraCharacteristics() per ottenere un'
CameraCharacteristics
istanza, che puoi interrogare per verificare le funzionalità HDR del tuo dispositivo.
I passaggi seguenti controllano se un dispositivo supporta HLG10. HLG10 è lo standard HDR di base che i produttori di dispositivi devono supportare sulle videocamere con output a 10 bit.
Innanzitutto, controlla se il dispositivo supporta i profili a 10 bit (la profondità di bit per 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 }
Poi, controlla se il dispositivo supporta HLG10 (o un altro profilo supportato):
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; }
Se il dispositivo supporta l'HDR, isHLGSupported() restituisce sempre true.
Per saperne di più, consulta la
CameraCharacteristics
documentazione di riferimento.
Configurare l'acquisizione HDR
Dopo aver verificato che il dispositivo supporta l'HDR, configura la tua app per acquisire un flusso video HDR non elaborato dalla videocamera.
Utilizza setDynamicRangeProfile() per fornire a OutputConfiguration
del flusso un profilo HDR supportato dal dispositivo, che viene poi passato
a CameraCaptureSession
al momento della creazione.
Consulta l'elenco dei profili HDR supportati.
Nell'esempio di codice seguente, setupSessionDynamicRangeProfile() controlla innanzitutto che il dispositivo esegua Android 13.
Poi, configura CameraCaptureSession con il profilo HDR supportato dal dispositivo come 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 } }
Quando l'app della videocamera inizializza la videocamera, invia un
ripetuto
CaptureRequest
per visualizzare l'anteprima della registrazione:
Kotlin
session.setRepeatingRequest(previewRequest, null, cameraHandler)
E anche per avviare la registrazione video:
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)
Codificare il flusso della videocamera HDR
Per codificare lo stream della videocamera HDR e scrivere il file su disco, utilizza MediaCodec.
Innanzitutto, recupera OutputSurface,
che esegue il mapping a un buffer che memorizza i dati video non elaborati.
Per MediaCodec,
utilizza createInputSurface().
Per inizializzare MediaCodec, un'app deve creare un
MediaFormat con un profilo codec, uno spazio colore, una gamma di colori e una funzione di trasferimento specificati:
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)
Per maggiori dettagli sull'implementazione, consulta l'app di esempio Camera2Video
EncoderWrapper.kt.
Formati HDR
A partire da Android 13, i dispositivi con videocamera con funzionalità di output a 10 bit devono supportare HLG10 per l'acquisizione e la riproduzione HDR. Inoltre, i produttori di dispositivi possono attivare qualsiasi formato HDR di loro scelta utilizzando l'architettura di acquisizione HDR.
La tabella seguente riassume i formati HDR disponibili e le relative funzionalità per l'acquisizione di video HDR.
| Formato | Funzione di trasferimento (TF) | Metadati | Codec | Profondità di bit |
|---|---|---|---|---|
| HLG10 | HLG | No | HEVC | 10 bit |
| HDR10 | PQ | Statico | HEVC | 10 bit |
| HDR10+ | PQ | Dinamico | HEVC | 10 bit |
| Dolby Vision 8.4 | HLG | Dinamico | HEVC | 10 bit |
Risorse
Per un'app funzionante con funzionalità di acquisizione di video HDR, consulta l' esempio Camera2Video su GitHub.