Android Camera HAL3 - Multi Camera
Posted 嵌入式Max
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Camera HAL3 - Multi Camera相关的知识,希望对你有一定的参考价值。
本文介绍下 Google android 在其文档中对于 Multi-Camera 的描述,以及 Android R 中对 Camera HAL3 的一些新增内容,Multi-Camera 从 Android 9 也就是 P 开始就已经有相关的支持描述了,只不过还是比较简单的要求,并不是十分的完备。
Android HAL 特指 Google 自己实现的 framework HAL 层级代码,也就是承接 APP/Framework 和 Vendor HAL 的这部分代码。下面是 Android 中国区的网址,做的非常好了可以说(文章里面很多的数据类型都可以从这些网站上面找到):
Multi-Camera(来自 Android Develop doc)
Android 9 开始支持一种逻辑多摄像头设备,需要注意下 Logic camera device 和 Physical camera device 的区别:
- Logical camera device:假设手机上面有三个后摄,那么一个逻辑摄像头设备可能包含了其中任意两个或者三个,至于我本次 request 究竟应该从哪一个或者几个物理摄像头设备获取图像用于显示,这是属于 Vendor HAL implementation 的内容,对于 Android HAL 来讲暴露出来的设备就是一个逻辑摄像头设备,一个逻辑摄像头设备包含了一个或者多个物理摄像头设备。
- Physical camera device:假设同上,背面的三个物理摄像头设备就是 physical camera device,一对一的关系,所以可以认为 Logical camera device 是 Physical camera device 的超集。
Logical camera device 和 Physical camera device 一样,对于 Android HAL 来讲,它们都是同样的抽象接口,都会用 CameraDevice/CaptureSession 来进行描述,但是实际 Vendor HAL 那边内部的逻辑相差还是比较大的。当然 APP 也可以可选地通过 Logical camera device 来控制到 Physical camera device,可以由 stream、meta 以及其它的参数或者接口方法进行控制,某些情况下 Logical stream 和 Physical stream 是可以同时回传到 Android HAL 的。
Multi-Camera 设备需要通过 logical multi-camera capability 来表明这是一个 Multi-camera 设备,该 metadata 的枚举类型是 REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
,我们在构建 Vendor HAL 的 CameraCharacteristics 的时候需要将这一项写入到 REQUEST_AVAILABLE_CAPABLITIES
里面,在 Android 的 developer 文档里面,该项 metadata 的值可能是以下几种的集合:
BACKWARD_COMPATIBLE
MANUAL_SENSOR
MANUAL_POST_PROCESSING
RAW
PRIVATE_REPROCESSING
READ_SENSOR_SETTINGS
BURST_CAPTURE
YUV_REPROCESSING
DEPTH_OUTPUT
CONSTRAINED_HIGH_SPEED_VIDEO
MOTION_TRACKING
LOGICAL_MULTI_CAMERA
MONOCHROME
SECURE_IMAGE_DATA
SYSTEM_CAMERA
OFFLINE_PROCESSING
Tips: CameraCharacteristics 在 get_camera_info 的时候就被 push 到 Android HAL 那边了,返回的 camera_info 结构体里面就包含了这部分信息,而这部分信息一般情况在 Vendor HAL 初始化的时候就构建完成了,需要注意的是在 API29 以及 API28 上面,camera_info 都是针对逻辑摄像头设备来说的,只不过有的逻辑摄像头设备是只包含有一个 physical camera 设备,这部分只包含一个 physical camera 设备的在一定程度上来讲也就可以看作是物理摄像头设备了。
API28 的时候,所有的 physical camera 设备都必须要通过 CameraManager.getCameraIdList()
来 post 出来,但是在 API29 的时候,支持一些并不能独立 post 出来的 physcial camera 设备不通过这个接口来 post 给 framework,但是这部分设备还是可以使用 CameraManager.getCameraCharacteristics(String)
来进行属性查询的。对比与之前的 API29,API30 添加了 onPhysicalCameraAvailable
以及 onPhysicalCameraUnavailable
的回调,这个是在 CameraManager.AvailabilityCallback
里面的,这部分没有仔细研究过,需要后续学习。
之前每一个 Logica camera 的 info 里面包含的 Characteristics 中保存了该 device 下面的 physical camera Id 列表,可以使用 CameraCharacteristics.getPhysicalCameraIds()
来获取。每一个 Logical camera 下属的 physical camera device 可能拥有不同的属性,使用 CameraCharacteristics.getAvailablePhysicalCameraRequestKeys
可以获取到这部分的信息。Physical camera stream 不支持 reprocess 类型的请求,且只支持 monochrome 以及普通的 Bayer sensor。
Check list
为了有一个基本的验证流程,Google 给出了一个检查列表来表明是否支持 Multi-Camera,这部分就是起一个目录大纲的作用,具体的细节当然还是有一大堆需要进行验证实现的。
- 添加
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
枚举,这个在前面提到过,对于 Vendor HAL 来讲就是放在REQUEST_AVAILABLE_CAPABLITIES
里面的。 - 填充
ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS
,这部分我理解是需要为每一个 Logical camera 进行填充的,会放在相对应的 camera_info 固定属性里面去。 - 填充与深度相关的信息,深度翻译不太准确,英文就是 Depth-related 信息,包含
ANDROID_LENS_POSE_ROTATION
,ANDROID_LENS_POSE_TRANSLATION
,ANDROID_LENS_INTRINSIC_CALIBRATION
,ANDROID_LENS_DISTORTION
,ANDROID_LENS_POSE_REFERENCE
,这里面每一个都是与具体的 physical camera device 相关的,所以肯定需要是一个个的数组,里面的设备顺序应该是 Vendor HAL 内部进行顺序排定的。 - 设置 StaticCharacteristics 的
ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
参数,取值有两个:ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE
:表示是 Master-Master 模式的 sensor 同步方式,字义理解就是全部靠软件来进行实现,硬件级别没有什么硬件电路来做相关的同步措施。ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED
:表示 Master-Slave 模式的同步方式,既有软件也有硬件级别的同步,硬件需要进行 shutter 和曝光时间的双重同步,这部分是有专门的硬件电路的。
- 设置
ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS
这一个参数只在支持对一个 Logical camera device 下属的 Physical camera device 单独请求 request 的时候需要设置,如果不支持的话可以放着不写,置空即可。 - 如果单独请求这部分是支持的话,
physicalCameraSettings
与physicalCameraMetadata
就可以对应进行 request 和 result 的属性设置和返回结果。这部分在下一小节说明,HAL3.5 加了一些接口来完成这部分功能。 - 对于 HAL3.5 (也就是 Android 10) 开始,需要在返回的 result 里面设置
ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID
参数,这个是表明当前 request 对应的 Logical camera 下属有哪些 Physical camera 是处于 active 状态的。
性能和耗电:对于一些配置了 Physical stream 的 request 来讲,可能会拖慢 Logical stream 的处理速度,导致整体帧率的降低,同时也将会导致更多的耗电量。一句话就是并不保证完全流畅的处理请求,一般情况下是指不保证所有平台所有 Physical stream 配置方式都能够实现非常流畅的 request 处理效果,不过我想对于大部分旗舰产品来讲这部分流畅处理应该是必要的,不然竞争力就可能会下降。
HAL 3.5
简单的来说 HAL3.5 增加了对 Physical camera 更全面的支持,也就是增加了多 Physical camera 操作的部分,其中最明显的就是并发预览,比如同时打开三个摄像头并且输出三路数据给到 APP 同时显示在 UI 上面,也支持同时多路录像,总之 HAL3.5 最明显的就是开放对于 Physical camera 的更加灵活的控制能力。
- StreamCombinationSupport
- 并发预览
- Camera module HAL 结构体新的接口
对于 CAMERA_MODULE_API_VERSION 来讲,2.5 以后在原来的 camera_module_t
结构体里面新增了 get_physical_camera_info
和 is_stream_combination_supported
两个函数。前者是用于获取非独立 Physical camera device 的 Characteristics 信息的,但是传入的 camera id 是比较特别的,他并不是属于 get_number_of_cameras
函数返回值范围内的,而是大于那个返回值得一个数,相关的 Physical camera 信息在 ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS
里面存放,是相对于 Logical camera 来讲的。后者是用于判断组合起来的 stream 是否支持,这些 stream 包含输入的和输出的 stream,以往使用的时候一般都是协商好的 stream 组合然后进行配置,这个项相当于是增加了一个灵活配置项,我可以运行时判断是否支持,比如说我现在这一个 request 中包含了一个 input stream,还有分别对应三个 Physical camera 的 output stream,那么很多平台可能就是无法支持的,这个时候就可以通过该函数来进行判定,避免配置一个不支持的 stream 进去。这两个接口也可以在 /platform/hardware/interfaces/camera/device/3.5/ICameraDevice.hal
这里找到定义。
并发预览前面稍微介绍过,最主要的体现可以在原来的 camera3_capture_result_t
和 camera3_capture_request_t
,HAL3.5 新增或者改变了一下几个成员变量:
typedef struct camera3_stream
/**
* The physical camera id this stream belongs to.
*
* <= CAMERA_DEVICE_API_VERISON_3_4:
*
* Not defined and must not be accessed.
*
* >= CAMERA_DEVICE_API_VERISON_3_5:
*
* Always set by camera service. If the camera device is not a logical
* multi camera, or if the camera is a logical multi camera but the stream
* is not a physical output stream, this field will point to a 0-length
* string.
*
* A logical multi camera is a camera device backed by multiple physical
* cameras that are also exposed to the application. And for a logical
* multi camera, a physical output stream is an output stream specifically
* requested on an underlying physical camera.
*
* For an input stream, this field is guaranteed to be a 0-length string.
*/
const char* physical_camera_id;
camera3_stream_t;
typedef struct camera3_capture_request
uint32_t num_physcam_settings;
const char **physcam_id;
const camera_metadata_t **physcam_settings;
camera3_capture_request_t;
在 configure_stream 的时候,新增了 Android HAL 层必须设置的成员变量 physical_camera_id
,用于标识该 camera stream 是属于哪一个 Physical stream 的,如果是 Logical stream 的话就会设置为 0 长度的字符串。该成员变量配合 camera3_capture_request
结构体里面个 output buffer 以及 physical settings 来对每一个 physical camera 进行区分,达到并发预览的目的。
End
本文对 Multi camera 所支持的主要特性和细节点做了一个简单的描述,实现起来当然还是有非常多的细节去深究的,这里也分了系列来进行介绍,下一篇应该会是 CameraX 的部分介绍,这个是在 Android 11 上面新发布的一个特性,释放了更多的标准化功能给到三方 camera app 去使用。随着 5G 时代的到来,短视频越来越多的被使用,与之对应的拍摄能力也是在不断变换着需求,尤其是对于视频防抖的要求比较急需,以后还会有更多越来越标准化的算法也下放到 camera 硬件里面去做,从底层来为视频拍摄提供更方便的处理方式,camera 智能化也是一个趋势,引入硬件化的 camera AI 硬件处理子模块也是会出现的,总是这玩意儿的需求变化太快了,任务每年都很繁重。
以上是关于Android Camera HAL3 - Multi Camera的主要内容,如果未能解决你的问题,请参考以下文章
Android Camera HAL3 - Multi Camera
Android : Camera HAL3的参数传递(CameraMetadata)
Android : Camera2/HAL3 ????????????