注意:此页面指的是 Camera2 包。除非您的应用程序需要 Camera2 中的特定低级功能,否则我们建议使用 CameraX。CameraX 和 Camera2 都支持 Android 5.0(API 级别 21)及更高版本。
Camera2 API 支持高动态范围 (HDR) 视频录制,使您可以使用相机预览和录制 HDR 视频内容。与标准动态范围 (SDR) 相比,HDR 提供更广泛的色彩范围,并提高了亮度分量的动态范围(从目前的 100 cd/m2 到 1000s cd/m2)。这使得视频质量更接近现实生活,具有更丰富的色彩、更明亮的亮部和更暗的阴影。
查看 HDR 视频如何以更生动的细节捕捉日落。
设备先决条件
并非所有 Android 设备都支持 HDR 视频录制。在您的应用中录制 HDR 视频之前,请确定您的设备是否满足以下先决条件。
- 目标 Android 13(API 级别 33)。
- 具有 10 位或更高能力的摄像头传感器。有关 HDR 支持的更多信息,请参阅 检查 HDR 支持。
由于并非所有设备都满足先决条件,因此您可以在应用程序中设置 HDR 视频录制时添加单独的代码路径。这使您的应用程序可以在不兼容的设备上回退到 SDR。此外,请考虑添加 SDR 的 UI 选项。用户可以根据自己的视频录制需求在 SDR 和 HDR 之间切换。
HDR 录制架构
以下图表显示了 HDR 录制架构的主要组件。
当摄像头设备以 HDR 模式捕捉帧时,Camera2 框架会分配一个缓冲区,用于存储处理后的摄像头传感器输出。如果 HDR 配置文件需要,它还会附加相应的 HDR 元数据。然后,Camera2 框架将填充的缓冲区排队到 CaptureRequest
中引用的输出表面,例如显示器或视频编码器,如图表所示。
检查 HDR 支持
在您的应用程序中录制 HDR 视频之前,请确定设备是否支持您所需的 HDR 配置文件。
使用 CameraManager
getCameraCharacteristics()
方法获取 CameraCharacteristics
实例,您可以查询设备的 HDR 功能。
以下步骤检查设备是否支持 HLG10。HLG10 是设备制造商必须在具有 10 位输出的摄像头中支持的基线 HDR 标准。
首先,检查设备是否支持 10 位配置文件(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 }
接下来,检查设备是否支持 HLG10(或 另一个支持的配置文件)。
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; }
如果设备支持 HDR,则 isHLGSupported()
将始终返回 true
。有关更多信息,请参阅 CameraCharacteristics
参考文档。
设置 HDR 录制
确保您的设备支持 HDR 后,请设置您的应用程序以从摄像头捕捉原始 HDR 视频流。使用 setDynamicRangeProfile()
为流的 OutputConfiguration
提供设备支持的 HDR 配置文件,然后在创建时将其传递给 CameraCaptureSession
。请参阅支持的 HDR 配置文件的 列表。
在以下代码示例中,setupSessionDynamicRangeProfile()
首先检查设备是否运行 Android 13。然后,它将设备支持的 HDR 配置文件设置为 OutputConfiguration
,并设置 CameraCaptureSession
。
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 } }
}
当您的摄像头应用程序初始化摄像头时,它会发送一个重复的 CaptureRequest
来预览录制。
Kotlin
session.setRepeatingRequest(previewRequest, null, cameraHandler)
还可以启动视频录制。
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 摄像头流
要编码 HDR 摄像头流并将文件写入磁盘,请使用 MediaCodec
。
首先,获取 OutputSurface
,它映射到存储原始视频数据的缓冲区。对于 MediaCodec
,请使用 createInputSurface()
。
要初始化 MediaCodec
,应用程序必须使用指定的编解码器配置文件、色彩空间、色彩范围和传递函数创建一个 MediaFormat
。
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)
有关实现的更多详细信息,请参阅 Camera2Video 示例应用程序的 EncoderWrapper.kt
。
HDR 格式
从 Android 13 开始,具有 10 位输出能力的摄像头设备必须支持 HLG10,才能进行 HDR 录制和 播放。此外,设备制造商可以使用 HDR 录制架构 启用他们选择的任何 HDR 格式。
下表总结了可用的 HDR 格式及其在 HDR 视频录制中的功能。
格式 | 传递函数 (TF) | 元数据 | 编解码器 | 位深度 |
---|---|---|---|---|
HLG10 | HLG | 否 | HEVC | 10 位 |
HDR10 | PQ | 静态 | HEVC | 10 位 |
HDR10+ | PQ | 动态 | HEVC | 10 位 |
杜比视界 8.4 | HLG | 动态 | HEVC | 10 位 |
资源
有关具有 HDR 视频录制功能的工作应用程序,请参阅 GitHub 上的 Camera2Video 示例。