Android Camera HAL3 - Multi Camera(1)

本文详细介绍了Android系统从Android 9开始支持的Multi-Camera特性,包括逻辑摄像头设备和物理摄像头设备的概念,以及在Android R中Camera HAL 3的新增功能。深入探讨了逻辑摄像头设备如何包含多个物理摄像头设备,以及Vendor HAL在实现多摄像头功能时的内部逻辑。此外,还讲解了如何通过logical multi-camera capability表明设备支持多摄像头,以及在构建Vendor HAL的CameraCharacteristics时需要遵循的步骤。

本文介绍下 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 硬件处理子模块也是会出现的,总是这玩意儿的需求变化太快了,任务每年都很繁重。


<think>嗯,用户让我介绍一下Android Camera2 HAL3。我得先回忆一下自己对这个主题的了解。Android的相机架构经历过几次大的变化,特别是从Camera1Camera2,HAL3应该是其中的关键部分。 首先,HAL是硬件抽象层,负责Android框架和硬件驱动程序之间的通信。Camera2 API是在Android 5.0引入的,取代了旧的Camera1 API。HAL3应该对应的是Camera2的支持,可能带来了更多的功能和更好的性能。 需要区分HAL1HAL3的不同。HAL1可能对应旧的相机架构,而HAL3引入了更灵活的管道模型,允许应用更直接地控制相机硬件,比如手动调节曝光、对焦等。这可能涉及到像Request这样的概念,应用通过发送捕获请求来操作相机。 另外,HAL3可能支持更多的数据流,比如同时处理预览、拍照和录像,而不会像以前那样有性能问题。还有,可能提到的是每个请求可以配置不同的参数,并且有更精细的控制,比如每个帧的元数据。 记得HAL3引入了更结构化的元数据,使用类似标签的系统,让应用可以查询相机的能力,比如支持的分辨率、帧率范围等。这可能涉及到CameraCharacteristics类,应用在打开相机前会先获取这些信息。 可能还需要解释一下HAL3的管道模型,比如将相机设备视为一个处理管道,处理来自应用的请求,生成结果。每个请求会指定输出Surface,比如用于预览的SurfaceView或者用于拍照的ImageReader。 不过,用户可能还想知道HAL3带来的优势,比如低延迟、更好的性能、更高效的资源利用。同时,可能也需要注意兼容性问题,因为旧设备可能不支持HAL3,仍然使用HAL1,这会导致应用需要处理不同的情况。 另外,HAL3CameraX的关系,CameraX是Jetpack库,可能基于HAL3,但提供了更简化的API,帮助开发者处理兼容性问题。不过用户的问题主要是HAL3本身,所以可能需要集中在HAL3的结构和功能上。 可能还需要提到一些关键类或接口,比如CameraDevice、CameraCaptureSession,以及如何通过HAL3进行会话的配置和请求的提交。比如,应用创建一个CaptureRequest,设置参数,然后提交给相机设备,然后处理返回的结果。 还有,HAL3如何处理3A(自动对焦、自动曝光、自动白平衡),允许应用更精细地控制这些过程,或者设置回调来监听状态变化。 需要确保技术术语使用正确,比如HAL3的正确名称,是否称为Camera HAL3,或者Android Camera HAL 3.0版本。可能正确的术语是Camera HAL3,对应Camera2 API的实现。 可能还要提到HAL3的配置方式,比如在设备厂商的实现中,如何通过HIDL接口或者AIDL进行交互,不过这部分可能属于系统内部细节,用户作为开发者可能更关注API层面的使用。 总结一下,回答的结构应该是先介绍HAL3是什么,它在Android相机架构中的位置,然后对比HAL1HAL3的主要区别,接着详细说明HAL3的关键特性,比如管道模型、请求机制、元数据、多流支持等,最后可能提到开发中的使用方式或注意事项。 要避免错误的信息,比如HAL3是否支持某些特定功能,或者时间线是否正确。比如确认HAL3是从Android 5.0开始引入的,而Camera2 API也是同时推出的。此外,HAL3是否必须由设备支持,还是可选,可能需要说明兼容性情况,比如从某个Android版本开始要求必须支持HAL3,但实际设备可能仍有差异。 还要注意术语的正确使用,比如“管道模型”是否正确,或者是否有其他术语,比如“基于请求的模型”更准确。可能需要查阅相关资料确认,但根据记忆,HAL3确实引入了更灵活的请求处理模型,允许应用发送多个请求,每个请求可以有不同的设置,并且相机设备按顺序处理。 最后,确保回答结构清晰,分点说明主要概念,帮助用户逐步理解HAL3的结构和优势,同时结合实际开发中的例子,比如如何使用Camera2 API与HAL3交互,这样用户能更好地应用这些知识。</think>### Android Camera2 HAL3 介绍 #### 1. **基本概念** - **HAL(硬件抽象层)**:负责连接 Android 框架与硬件驱动,确保上层 API 与底层硬件解耦。 - **Camera2 API**:从 Android 5.0(Lollipop)引入,取代旧版 Camera1 API,提供更精细的控制能力。 - **HAL3**:专为 Camera2 API 设计的硬件抽象层(版本 3.x),支持**基于请求的模型**和**多数据流处理**。 --- #### 2. **HAL3 的核心改进(对比 HAL1)** | **特性** | **HAL1 (Camera1)** | **HAL3 (Camera2)** | |-------------------|---------------------------|-----------------------------| | **控制模式** | 基于“预设场景”的自动模式 | 基于“请求(Request)”的手动控制 | | **数据流** | 单数据流(预览/拍照二选一) | 多数据流并行(如同时预览+拍照) | | **性能** | 延迟高,资源利用率低 | 低延迟,更高效的硬件资源调度 | | **元数据** | 固定元数据,灵活性差 | 动态元数据(如每帧参数可配置) | --- #### 3. **HAL3 关键架构与组件** 1. **管道模型(Pipeline Model)** - 将相机硬件抽象为一个处理管道,接收来自应用的**捕获请求(CaptureRequest)**。 - 每个请求包含: - **参数配置**(如曝光时间、对焦模式)。 - **输出目标**(如 `Surface` 用于预览、拍照或录像)。 $$ \text{应用} \xrightarrow{\text{Request}} \text{相机管道} \xrightarrow{\text{Result}} \text{返回图像+元数据} $$ 2. **多流支持(Multi-Stream)** - 允许同时输出到多个 `Surface`(如预览 + 高分辨率拍照)。 - 硬件自动优化数据流路径(Bypass冗余处理)。 3. **动态元数据(Dynamic Metadata)** - 通过 `CameraCharacteristics` 查询设备能力(如支持的分辨率、帧率范围)。 - 每帧返回 `CaptureResult`,包含实时参数(如传感器时间戳、3A状态)。 --- #### 4. **开发中的核心类与流程** 1. **CameraDevice** - 表示物理相机设备,通过 `createCaptureSession()` 创建会话。 2. **CameraCaptureSession** - 管理数据流和请求,通过 `setRepeatingRequest()` 持续发送请求(如预览)。 3. **CaptureRequest** - 定义单次请求的参数(如对焦模式 `CONTROL_AF_MODE_AUTO`)。 ```java // 示例:创建一个拍照请求 CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); requestBuilder.addTarget(imageReader.getSurface()); requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); CaptureRequest request = requestBuilder.build(); ``` --- #### 5. **优势与挑战** - **优势**: - **精细控制**:支持手动调节 ISO、曝光时间等参数。 - **低延迟**:通过多流并行减少数据拷贝。 - **扩展性**:兼容深度相机、多摄像头等新型硬件。 - **挑战**: - **兼容性**:旧设备可能仅支持 HAL1,需用 `CameraManager.getCameraCharacteristics()` 检测能力。 - **复杂度**:需要处理异步回调、线程管理等细节。 --- #### 6. **实际应用建议** - **使用 CameraX**:Google 推荐的 Jetpack 库,基于 HAL3 封装,简化兼容性问题。 - **性能优化**: - 复用 `CaptureRequest` 减少开销。 - 限制输出分辨率(根据 `StreamConfigurationMap` 选择最优配置)。 --- #### 7. **总结** HAL3Android 相机系统的重大升级,通过**请求-响应模型**和**多流架构**,为开发者提供了接近硬件层的控制能力。尽管学习曲线较高,但能实现更专业的拍摄功能(如 RAW 捕获、实时 HDR)。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值