Android Camera HAL3 - Multi Camera(1)

本文介绍下 Google Android 在其文档中对于 Multi-Camera 的描述,以及 Android R 中对 Camera HAL3 的一些新增内容,Multi-Camera 从 Android 9 也就是 P 开始就已经有相关的支持描述了,只不过还是比较简单的要求,并不是十分的完备。

Android HAL 特指 Google 自己实现的 framework HAL 层级代码,也就是承接 APP/Framework 和 Vendor HAL 的这部分代码。下面是 Android 中国区的网址,做的非常好了可以说(文章里面很多的数据类型都可以从这些网站上面找到):

  1. https://source.android.google.cn/devices/camera
  2. https://developer.android.google.cn/training/camera

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 的时候需要设置,如果不支持的话可以放着不写,置空即可。
  • 如果单独请求这部分是支持的话,physicalCameraSettingsphysicalCameraMetadata 就可以对应进行 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 的更加灵活的控制能力。

  1. StreamCombinationSupport
  2. 并发预览
  3. Camera module HAL 结构体新的接口

对于 CAMERA_MODULE_API_VERSION 来讲,2.5 以后在原来的 camera_module_t 结构体里面新增了 get_physical_camera_infois_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_tcamera3_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(1)_第1张图片

你可能感兴趣的:(Android,Camera,android,camera,HAL3)