Android 14(UpsideDownCake) Camera API New Changes尝鲜
最近Android 14更新了Beta1版本,迫不及待总结了下Camera2 API部分的改动,从Camera Extension和Camera2 API 两部分来说明新的变化,总体看变化不大。
Camera Extension部分
在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)判断是否支持。
Camera2 API部分
在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<UINT64>(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方法来设置 |