相机10bit HDR录制

对于搭载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支持的,详情见

Android相机延时摄影是如何实现的

Android手机如何实现慢动作录制

通过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编码录制是一样的.

更多精彩好文欢迎关注:雪月清的随笔(公众号) 音视频,Camera,OpenGL技术分享和读书分享.

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论