Nota: Esta página hace referencia al paquete Camera2. A menos que la app requiera funciones específicas y de bajo nivel de Camera2, te recomendamos que uses CameraX. CameraX y Camera2 admiten Android 5.0 (nivel de API 21) y versiones posteriores.
Compatibilidad con las APIs de Camera2 Captura de video de alto rango dinámico (HDR), que te permite obtener una vista previa y Graba contenido de video en HDR con la cámara. En comparación con los anuncios dinámicos estándar (SDR), HDR ofrece una gama más amplia de colores y aumenta el del componente de luminancia (desde los 100 cd/m2 actuales hasta miles de cd/m2). Esto da como resultado una calidad de video que se acerca más a la vida real, con colores más intensos, zonas brillantes más brillantes y sombras más oscuras.
Descubre cómo los videos HDR capturan una puesta de sol con más detalles vibrantes.
Requisitos previos del dispositivo
No todos los dispositivos Android admiten la captura de video HDR. Antes de capturar video HDR en la app, determina si el dispositivo cumple con los los siguientes requisitos previos:
- Se orienta a Android 13 (nivel de API 33).
- Tenga un sensor de cámara capaz de 10 bits o más. Más información sobre HDR Para obtener ayuda, consulta Cómo verificar la compatibilidad con HDR.
Como no todos los dispositivos cumplen con los requisitos previos, puedes agregar un código independiente cuando configures la captura de video HDR en tu app. Esto permite que tu app recurra a SDR en dispositivos no compatibles. Además, considera agregar una opción de IU para SDR. Luego, el usuario puede activar o desactivar entre SDR y HDR para sus necesidades de grabación de video.
Arquitectura de captura HDR
En el siguiente diagrama, se muestran los componentes principales de la arquitectura de captura HDR.
Cuando un dispositivo de cámara captura un fotograma en HDR, el framework de Camera2 asigna
un búfer que almacena la salida procesada del sensor de la cámara.
También se adjuntan los metadatos de HDR correspondientes si el perfil de HDR lo requiere.
El framework de Camera2 luego pone en cola el búfer propagado para la superficie de salida
a las que se hace referencia en el CaptureRequest
, como una pantalla
de video, como se muestra en el diagrama.
Cómo comprobar si es compatible con HDR
Antes de capturar videos HDR en la app, determina si el dispositivo es compatible el perfil HDR deseado.
Usa el método CameraManager
getCameraCharacteristics()
para obtener un
CameraCharacteristics
que puedes consultar para conocer las capacidades HDR de tu dispositivo.
Los siguientes pasos pueden verificar si un dispositivo es compatible con HLG10. HLG10 es el estándar de referencia HDR que deben admitir los fabricantes de dispositivos en cámaras con salida de 10 bits.
Primero, comprueba si el dispositivo admite perfiles de 10 bits (la profundidad de bits para 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 }
Luego, comprueba si el dispositivo es compatible con HLG10 (o otro perfil 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 el dispositivo es compatible con HDR, isHLGSupported()
siempre mostrará true
.
Para obtener más información, consulta la
CameraCharacteristics
documentación de referencia.
Cómo configurar la captura HDR
Después de asegurarte de que el dispositivo sea compatible con HDR, configura la app para que capture
una transmisión de video HDR sin procesar desde la cámara.
Usa setDynamicRangeProfile()
para proporcionar el OutputConfiguration
de la transmisión.
con un perfil HDR compatible con el dispositivo, que luego se pasa
al CameraCaptureSession
después de su creación.
Consulta la lista de perfiles HDR compatibles.
En la siguiente muestra de código, setupSessionDynamicRangeProfile()
primero verifica
de que el dispositivo ejecute Android 13.
Luego, configura el CameraCaptureSession
con la biblioteca
Perfil HDR como 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 } }
}
Cuando la app de cámara inicializa la cámara, envía
recurrente
CaptureRequest
para obtener una vista previa de la grabación:
Kotlin
session.setRepeatingRequest(previewRequest, null, cameraHandler)
Además, sigue estos pasos para comenzar a grabar el 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)
Codifica la transmisión de la cámara HDR
Para codificar la transmisión de la cámara HDR y escribir el archivo en el disco, haz lo siguiente:
usa MediaCodec
.
Primero, obtén OutputSurface
,
que se asigna a un búfer que almacena
datos de video sin procesar.
Para MediaCodec
,
usa createInputSurface()
.
Para inicializar MediaCodec
, una app debe crear un
MediaFormat
por un valor especificado
perfil de códec, espacio de color, rango de color y función de transferencia:
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)
Para obtener más información sobre la implementación, consulta la documentación de la app de ejemplo de Camera2Video
EncoderWrapper.kt
Formatos HDR
A partir de Android 13, los dispositivos de cámara con capacidades de salida de 10 bits debe ser compatible con HLG10 para captura HDR y reproducción. Además, los fabricantes de dispositivos pueden habilitar cualquier formato HDR que deseen con la arquitectura de captura HDR.
En la siguiente tabla, se resumen los formatos HDR disponibles y sus capacidades para la captura de video HDR.
Formato | Función de transferencia (TF) | Metadatos | Códec | Profundidad de bits |
---|---|---|---|---|
HLG10 | HLG | No | HEVC | 10 bits |
HDR10 | PQ | Estático | HEVC | 10 bits |
HDR10+ | PQ | Dinámico | HEVC | 10 bits |
Dolby Vision 8.4 | HLG | Dinámico | HEVC | 10 bits |
Recursos
Para ver una app que funcione y tenga la función de captura de video HDR, consulta la Ejemplo de Camera2Video en GitHub.