对于搭载Android13(T)及更高版本的设备来说,Android支持通过动态范围配置文件进行10bit相机输出
相机客户端可以在创建session时给配置的某一路输出流添加Dynamic range profile
设备制造商可以添加对HLG10、HDR10、HDR10+和杜比视界等10bit动态范围配置文件的支持(当然首先需要设备具有10位或者更高色深的相机传感器以及相应的ISP支持)
(10bit具有更多的色彩数目,颜色过渡更平滑)
接下来我们从相机预览和录制两个阶段来讲述10bit HDR视频是如何录制的
预览
step1: 在预览配置之前,需要检查设备是否支持10bit
CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
如果设备支持10bit输出,可以在Capabilities中找到
REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT
在支持10bit的前提下,获取可用的profiles
var dynamicRangeProfiles: DynamicRangeProfiles? = null
// DynamicRangeProfiles is introduced in android Tiramisu. If the SDK residing on
// our device is older, do not call the non-existant paths.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
dynamicRangeProfiles = characteristics.get(
CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES
)
}
REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE这个tag可以获取到推荐使用的Dynamic range profile,此选项能在性能/内存/功耗做到最佳(最平衡)
step2: 创建session时给输出流设置Dynamic range profile
/**
* Creates a [CameraCaptureSession] with the dynamic range profile set.
*/
private fun setupSessionWithDynamicRangeProfile(
device: CameraDevice,
targets: List<Surface>,
handler: Handler? = null,
stateCallback: CameraCaptureSession.StateCallback
): Boolean {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
val outputConfigs = mutableListOf<OutputConfiguration>()
for (target in targets) {
val outputConfig = OutputConfiguration(target)
outputConfig.setDynamicRangeProfile(args.dynamicRange)
outputConfigs.add(outputConfig)
}
device.createCaptureSessionByOutputConfigurations(
outputConfigs, stateCallback, handler
)
return true
} else {
device.createCaptureSession(targets, stateCallback, handler)
return false
}
}
能设置Dynamic range profile的输出流的format只能是
ImageFormat#YCBCR_P010或ImageFormat#PRIVATE
DynamicRangeProfile目前有12种类型,可以看到有10bit HDR还有8bit HDR,其中8bit HDR是功耗优化模式
默认STANDARD是8bit标准profile,关于HLG10、HDR10、HDR10_PLUS主要是transfer不同,这里不深入讲解,感兴趣的同学可以自行百度
其它的流程(比如打开camera、启动预览等)和普通预览流程是一样的了,这里不继续赘述
录制
10bit HDR的录制目前只能通过MediaCodec自己编码预览流,且需要采用HEVC编码
MediaRecorder是不支持10bit HDR录制的
这点和前面的关于延时摄影、慢动作功能的录制不同,这两个能力是通过MediaRecorder支持的,详情见
通过MediaCodec编码预览流进行录制也是目前市场上美颜类相机、短视频app(抖音、快手等)采用的技术方案
关于10bit HDR录制的关键点,配置MediaForamt时需要添加如下k-v
val codecProfile = when {
args.dynamicRange == DynamicRangeProfiles.HLG10 ->
MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10
args.dynamicRange == DynamicRangeProfiles.HDR10 ->
MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10
args.dynamicRange == DynamicRangeProfiles.HDR10_PLUS ->
MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus
else -> -1
}
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, getTransferFunction(codecProfile))
}
其它流程和普通预览模式通过MediaCodec编码录制是一样的,这里也不细说