注意:本页介绍的是 Camera2 软件包。除非您的应用需要 Camera2 中的特定低级别功能,否则我们建议使用 CameraX。CameraX 和 Camera2 都支持 Android 5.0(API 级别 21)及更高版本。
Camera2 API 支持高动态范围 (HDR) 视频拍摄功能,可允许您使用相机来预览和录制 HDR 视频内容。与标准动态范围 (SDR) 相比,HDR 提供了更广泛的颜色范围,并增加了亮度分量的动态范围(从当前的 100 cd/m2 增加到 1000 cd/m2)。 这样可以确保视频画质更符合现实世界,颜色更丰富,亮度更高,阴影更暗。
了解 HDR 视频如何以更鲜艳的细节拍摄日落。
设备前提条件
并非所有 Android 设备都支持拍摄 HDR 视频。 在应用中拍摄 HDR 视频之前,请确定设备是否满足以下前提条件:
- 以 Android 13(API 级别 33)为目标平台。
- 具备 10 位或更高色深的相机传感器。如需详细了解 HDR 支持,请参阅检查 HDR 支持情况。
由于并非所有设备都满足前提条件,因此您可以在应用中设置 HDR 视频捕获时添加单独的代码路径。这样,您的应用就可以在不兼容的设备上回退到 SDR。此外,还可以考虑添加 SDR 的界面选项。然后,用户可以根据自己的视频录制需求在 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。
然后,它将 CameraCaptureSession 设置为设备支持的 HDR 配置,作为 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 } }
当相机应用初始化相机时,它会发送重复的 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 示例。