最近android 14更新了beta1版本,迫不及待总结了下camera2 api部分的改动,从camera extension和camera2 api 两部分来说明新的变化,总体看变化不大。
在android 14中,google对camera extension进一步做了增强,为如下4个功能新增了一些apis(看样子google想推camerax的决心还是很强的):
- 获取still capture latency
- 支持postview
- 支持获取拍照进度
- 支持设置extension strength
获取still capture latency
为了衡量一次still capture拍照的性能(通过cameraextensionsession.capture
方法完成),新增了cameraextensionsession.stillcapturelatency
类。
这个类提供了2个方法来获取不同阶段的耗时:
方法 | 描述 |
---|---|
getcapturelatency() | 返回extensioncapturecallback#oncapturestarted到extensioncapturecallback#oncaptureprocessstarted的时长。 衡量的是:抓下原始未处理输入图像的耗时。 |
getprocessinglatency() | 返回extensioncapturecallback#oncaptureprocessstarted到收到处理后的图像的时长。 衡量的是:跑后处理算法和压jpeg的耗时。 |
如何获取到stillcapturelatency对象?
- 调用
cameraextensionsession.getrealtimestillcapturelatency()
方法,如果不支持则返回null。 - 从文档看,并没有说明在什么时候调用该api,理论上是等app收到该still capture request处理完后调用才有效。
支持postview
postview可以理解成拍照最终产生图片的一个预览版本,大家也经常称之为“小图”,将最终产生的图片称之为“大图”。
postview图片的用途?
- postview图片与最终图片相比,postview图片会提前产生,因此可以用于更新缩略图。
- 或在快拍流程中,当成小图先插入数据库占位,给用户拍照很快的感觉。
camera extension中如何使用postview功能?
分类 | 说明 |
---|---|
判断是否支持postview | 调用cameraextensioncharacteristics#ispostviewavailable (int extension)判断当前的extension是否支持postview |
postview支持哪些size | 调用cameraextensioncharacteristics#getpostviewsupportedsizes (int extension, size capturesize, int format) 获取指定extension、拍照size和format对应支持的postview size列表。 返回的postview size是小于等于capturesize的。 still capture和postview的buffer format必须相同。 |
如何使用postview功能 | postview可以理解为单独的一路流,因此使用它需要创建一个outputconfiguration。在创建好的extensionsessionconfiguration对象上调用setpostviewoutputconfiguration(outputconfiguration),然后在request阶段带上对应的surface即可。 |
支持获取拍照进度
通常extension拍照都是比较耗时的,因此有必要增加一个api来实时反馈拍照的的进度。
为了衡量一次still capture的过程,在cameraextensionsession.extensioncapturecallback中新增了一个回调:oncaptureprocessprogressed (cameraextensionsession session, capturerequest request, int progress)。
如何使用呢?
分类 | 说明 |
---|---|
判断是否支持拍照进度上报 | 调用cameraextensioncharacteristics.html#iscaptureprocessprogressavailable(int)判断某个extension是否支持上报拍照进度。 |
如何获取进度 | 接受cameraextensionsession.extensioncapturecallback#oncaptureprocessprogressed回调。 这个回调可能会被调用多次,api规定至少调用一次,如果调用一次的话,progress参数值是100. |
支持设置extension strength
在android 14中,google支持对某个后处理的extension通过capturerequest设置strength,范围从0到100。
- 0:表示extension的后处理不要生效
- 100是默认值
该strength在不同的extension中含义不一样
extension | strength |
---|---|
bokeh | 模糊程度 |
hdr 或 night | 融合图像的数量和最终图像的亮度 |
face_retouch | 美艳强度和皮肤平滑强度 |
注:使用前,要先通过cameraextensioncharacteristics.getavailablecapturerequestkeys(int)判断是否支持。
在android 14中,google对camera2 api做了如下5方面的增强:
- 新功能autoframing的支持
- 新增cropped raw stream usecase(in-sensor zoom控制)
- 优化参数生效的latency,支持override settings
- 优化录像效果,支持输出readout timestamp
- 支持设置color space
新功能autoframing的支持
google在android 14中新增了一个功能:autoframing。
autoframing是指camera hal会动态裁剪、缩放、移动画面以确保画面中的人占据合理的viewport。使能autoframing后,zoom和eis功能会被禁用。autoframing的应用场景是在视频通话中。(感觉不太实用的一个功能^^,不确定是否有芯片/手机厂商愿意实现该功能)
如何使用autoframing?
分类 | 说明 |
---|---|
判断是否支持autoframing | 从cameracharacteristics获取control_autoframing_available的值,如果为true则表示支持。 |
如何控制autoframing | 通过设置capturerequest的control_autoframing来控制autoframing。可以设置为on、off、auto三种值。 on: 打开autoframing off:关闭autoframing auto:hal自己决定打开/关闭autoframing。 |
如何监控autoframing的状态 | 通过读取captureresult的control_autoframing_state来判断当前autoframing的状态,包括如下状态: converged: autoframing到达稳定状态,场景不变的情况下,画面和fov不会变化了。 framing: 正在autoframing过程中 inactive: autoframing未触发。 |
新增cropped raw stream usecase(in-sensor zoom控制)
新增了一种stream usecase:cropped raw,当app控制crop region时通过应用到raw图上来实现。
看上去如果设置了这种stream usecase,就是让camera hal走in-sensor zoom的逻辑。
什么是in-sensor zoom?
in-sensor zoom顾名思义是指在sensor中完成zoom操作,这样做的好处是可以提高zoom后的图像解析力。
下面以2x zoom为例,介绍下默认的zoom与in-sensor zoom的差异:
默认的2x zoom
- sensor 走binning mode输出4000×3000的图像,然后isp先crop 出2000×1500的图像,再upscale到4000×3000,从而完成2x zoom的功能
in-sensor zoom
- sensor走full remosaic模式,输出即为裁剪后的2x zoom,对于这种zoom,isp不需要进行crop和upscale
- 当zoom大于2x时,对于in-insensor zoom方式,isp比默认zoom方式需要更小的upscale,因为少做了upscale,因此图像的解析力得到了保证。
如何控制cropped raw stream usecase?
分类 | 描述 |
---|---|
判断是否支持 | 从cameracharacteristics获取scaler_available_stream_use_cases,看是否包含scaler_available_stream_use_cases_cropped_raw,如果包含则支持 |
使能cropped raw stream | 调用outputconfiguration的setstreamusecase |
获取raw crop region | 从captureresult种读取scaler_raw_crop_region |
优化参数生效的latency,支持override settings
capturerequest包含很多参数,并不要求所有参数都当帧生效的,因此camera hal可以提前设置某个/些参数,从而能加速其生效,降低latency。比如zoom。
下面以zoom为例(假设zoom能提前1帧设置),解释下override settings的工作原理:
case1:override从off–>zoom
camera session created
request 1 (zoom=1.0x, override=zoom) ->
request 2 (zoom=1.2x, override=zoom) ->
request 3 (zoom=1.4x, override=zoom) -> result 1 (zoom=1.2x, override=zoom)
request 4 (zoom=1.6x, override=zoom) -> result 2 (zoom=1.4x, override=zoom)
request 5 (zoom=1.8x, override=zoom) -> result 3 (zoom=1.6x, override=zoom)
-> result 4 (zoom=1.8x, override=zoom)
-> result 5 (zoom=1.8x, override=off)
可以看到,我们从request 2开始设置zoom为1.2x,实际在result 1就生效了1.2x,因此对应的result override setting为zoom(该功能只建议在repeating request中,不要在拍照/连拍的时候用,因为会导致不可预期的zoom行为)。
case2:override从off–>zoom–>off
request 1 (zoom=1.0x, override=off)
request 2 (zoom=1.2x, override=off)
request 3 (zoom=1.4x, override=zoom) -> result 1 (zoom=1.0x, override=off)
request 4 (zoom=1.6x, override=zoom) -> result 2 (zoom=1.4x, override=zoom)
request 5 (zoom=1.8x, override=off) -> result 3 (zoom=1.6x, override=zoom)
-> result 4 (zoom=1.6x, override=off)
-> result 5 (zoom=1.8x, override=off)
可以看到
- request 3打开zoom override,因此result 2就生效了request 3的1.4x zoom。
-
request 5关闭了zoom override,而且request 4的1.6x在result 3就生效了,因此result 4继续保持1.6x的zoom。
如何使用override settings?
分类 | 描述 |
---|---|
获取那些settings支持override | 从cameracharacteristics种读取control_available_settings_overrides的值,能看到哪些settings能够通过override机制来降低latency |
控制要override哪些settings | 通过设置capturerequest.control_settings_override来控制要override哪些settings |
获取哪些settings被override了 | 通过读取captureresult.control_settings_override来获取该result被override了哪些settings |
优化录像效果,支持输出readout timestamp
在android 14上新增了readout的timestamp,这样的话,app在一个request中能获取到两个timestamp了
- start of exposure,开始曝光的时间点
- start of readout,sensor开始readout的时间点
具体的关系如下:
对于平台而言,start of exposure和start of readout都是根据sof timestamp推算出来的,比如推算start of exposure的公式:
static_cast(softimestamp - linereadouttime - currentexposure - (m_psensordata->resolutioninfo->resolutiondata[resolutionindex].adcreadouttime * 1000000));
readout timestamp有什么用?
- google文档上说是为了优化录像效果,我的理解是为了更精确地做av(audio/video) sync,可能用readout做为video的timestamp对av sync效果更好(特别是曝光时间比较长的情况下)
如何使用readout timestamp?
分类 | 说明 |
---|---|
判断是否支持sensor readout timestamp | 从cameracharacteristics中读取sensor_readout_timestamp的值,如果包含hardware则支持。 |
如何切换某路stream的timestamp为readout timestamp | 调用outputconfiguration的setreadouttimestampenabled(boolean)方法,按照google的建议,video stream就应该必须要做这件事了 |
如何获取sensor readout timestamp | 在cameracapturesession.capturecallback的onreadoutstarted回调中,可以收到当前这帧的readout timestamp。而且readout timestamp – startofexposure timestamp就基本上等于当前这帧的曝光时间了。 |
支持设置color space
在android 14上,google新增了colorspaceprofiles类用于描述当前camera设备支持的color space profile信息。同时开放了接口让app可以设置color space,这在10bit hdr场景下是非常有用的。
color space profile由3部分组成,可以根据image format或dynamic range profile来获取支持的color space。
- color space(调用 colorspaceprofiles#getsupportedcolorspaces或 colorspaceprofiles#getsupportedcolorspacesfordynamicrange获取支持的list)
- image format
- dynamic range profile(如果当前设备不支持request_available_capabilities_dynamic_range_ten_bit,该profile为dynamicrangeprofiles.standard)
如何使用color space profile?
分类 | 描述 |
---|---|
判断当前camera设备支持哪些color space profile | 通过读取cameracharacteristics的request_available_color_space_profiles来获取colorspaceprofiles |
如何设置color space | 创建session时调用sessionconfiguration.setcolorspace方法来设置 |