前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >相机10bit HDR录制

相机10bit HDR录制

作者头像
雪月清
发布2023-02-13 14:51:29
9370
发布2023-02-13 14:51:29
举报
文章被收录于专栏:雪月清的随笔

对于搭载Android13(T)及更高版本的设备来说,Android支持通过动态范围配置文件进行10bit相机输出

相机客户端可以在创建session时给配置的某一路输出流添加Dynamic range profile

设备制造商可以添加对HLG10、HDR10、HDR10+和杜比视界等10bit动态范围配置文件的支持(当然首先需要设备具有10位或者更高色深的相机传感器以及相应的ISP支持)

(10bit具有更多的色彩数目,颜色过渡更平滑)

接下来我们从相机预览录制两个阶段来讲述10bit HDR视频是如何录制的

预览

step1: 在预览配置之前,需要检查设备是否支持10bit

代码语言:txt
复制
CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES

如果设备支持10bit输出,可以在Capabilities中找到

代码语言:txt
复制
REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT

在支持10bit的前提下,获取可用的profiles

代码语言:javascript
复制
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

代码语言:javascript
复制
/**
 * 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

代码语言:javascript
复制
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编码录制是一样的,这里也不细说

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 雪月清的随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档