Remarque : Cette page fait référence au package Camera2. À moins que votre application ne nécessite des fonctionnalités spécifiques de bas niveau de Camera2, nous vous recommandons d'utiliser CameraX. CameraX et Camera2 sont compatibles avec Android 5.0 (niveau d'API 21) ou version ultérieure.
Les API Camera2 sont compatibles avec la capture vidéo HDR (High Dynamic Range) , ce qui vous permet de prévisualiser et d'enregistrer des contenus vidéo HDR à l'aide de votre appareil photo. Par rapport au format SDR (Standard Dynamic Range), le format HDR offre une plus large gamme de couleurs et augmente la plage dynamique du composant de luminance (de 100 cd/m2 à des milliers de cd/m2). La qualité vidéo est ainsi plus proche de la réalité, avec des couleurs plus riches, des zones claires plus lumineuses et des zones sombres plus foncées.
Découvrez comment la vidéo HDR capture un coucher de soleil avec plus de détails.
Prérequis pour l'appareil
Tous les appareils Android ne sont pas compatibles avec la capture vidéo HDR. Avant de capturer une vidéo HDR dans votre application, vérifiez que votre appareil répond aux prérequis suivants :
- Cible Android 13 (niveau d'API 33).
- Dispose d'un capteur d'appareil photo 10 bits ou plus. Pour en savoir plus sur la compatibilité HDR, consultez Vérifier la compatibilité HDR.
Étant donné que tous les appareils ne répondent pas aux prérequis, vous pouvez ajouter un chemin de code distinct lorsque vous configurez la capture vidéo HDR dans votre application. Cela permet à votre application de revenir au format SDR sur les appareils incompatibles. Envisagez également d'ajouter une option d'interface utilisateur pour le format SDR. L'utilisateur peut ensuite basculer entre les formats SDR et HDR en fonction de ses besoins d'enregistrement vidéo.
Architecture de capture HDR
Le schéma suivant montre les principaux composants de l'architecture de capture HDR.
Lorsqu'un appareil photo capture un frame au format HDR, le framework Camera2 alloue un tampon qui stocke la sortie traitée du capteur de l'appareil photo.
Il joint également les métadonnées HDR respectives si le profil HDR l'exige.
Le framework Camera2 met ensuite en file d'attente le tampon rempli pour la surface de sortie
référencée dans le CaptureRequest, comme un écran ou
un encodeur vidéo, comme illustré dans le schéma.
Vérifier la compatibilité HDR
Avant de capturer une vidéo HDR dans votre application, vérifiez si l'appareil est compatible avec le profil HDR souhaité.
Utilisez la méthode CameraManager getCameraCharacteristics() pour obtenir une
CameraCharacteristics
instance, que vous pouvez interroger pour connaître les capacités HDR de votre appareil.
Les étapes suivantes vérifient si un appareil est compatible avec le format HLG10. HLG10 est la norme HDR de référence que les fabricants d'appareils doivent prendre en charge sur les appareils photo avec une sortie 10 bits.
Tout d'abord, vérifiez si l'appareil est compatible avec les profils 10 bits (la profondeur de bits pour 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 }
Ensuite, vérifiez si l'appareil est compatible avec le format HLG10 (ou un autre profil compatible) :
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; }
Si l'appareil est compatible avec le format HDR, isHLGSupported() renvoie toujours true.
Pour en savoir plus, consultez la
CameraCharacteristics
documentation de référence.
Configurer la capture HDR
Après vous être assuré que votre appareil est compatible avec le format HDR, configurez votre application pour capturer un flux vidéo HDR brut à partir de l'appareil photo.
Utilisez setDynamicRangeProfile() pour fournir le OutputConfiguration
du flux avec un profil HDR compatible avec l'appareil, qui est ensuite transmis
au CameraCaptureSession
lors de sa création.
Consultez la liste des profils HDR compatibles.
Dans l'exemple de code suivant, setupSessionDynamicRangeProfile() vérifie d'abord que l'appareil exécute Android 13.
Ensuite, il configure le CameraCaptureSession avec le profil HDR compatible avec l'appareil en tant que 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 } }
Lorsque votre application d'appareil photo initialise l'appareil photo, elle envoie un
répété
CaptureRequest
pour prévisualiser l'enregistrement :
Kotlin
session.setRepeatingRequest(previewRequest, null, cameraHandler)
Et aussi pour démarrer l'enregistrement vidéo :
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)
Encoder le flux de la caméra HDR
Pour encoder le flux de la caméra HDR et écrire le fichier sur le disque,
utilisez MediaCodec.
Commencez par obtenir le OutputSurface,
qui correspond à un tampon stockant les données vidéo brutes.
Pour MediaCodec,
utilisez createInputSurface().
Pour initialiser MediaCodec, une application doit créer un
MediaFormat avec un profil de codec, un espace colorimétrique, une plage de couleurs et une fonction de transfert spécifiés :
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)
Pour en savoir plus sur l'implémentation, consultez
EncoderWrapper.kt de l'application exemple Camera2Video.
Formats HDR
À partir d'Android 13, les appareils photo avec des capacités de sortie 10 bits doivent être compatibles avec le format HLG10 pour la capture et la lecture HDR. De plus, les fabricants d'appareils peuvent activer n'importe quel format HDR de leur choix à l'aide de l'architecture de capture HDR.
Le tableau suivant récapitule les formats HDR disponibles et leurs capacités pour la capture vidéo HDR.
| Format | Fonction de transfert (TF) | Métadonnées | Codec | Profondeur de bit |
|---|---|---|---|---|
| HLG10 | HLG | Non | HEVC | 10 bits |
| HDR10 | PQ | Statique | HEVC | 10 bits |
| HDR10+ | PQ | Dynamique | HEVC | 10 bits |
| Dolby Vision 8.4 | HLG | Dynamique | HEVC | 10 bits |
Ressources
Pour découvrir une application fonctionnelle avec une fonctionnalité de capture vidéo HDR, consultez l' exemple Camera2Video sur GitHub.