1. Android Camera 架构总览:从 App 到 HAL 的完整数据流,以及各层职责

大家好,我是你们的讲师。今天咱们正式开始啃 Camera HAL 这块硬骨头。第一节课,我先带大家把整个 Android Camera 的架构捋一遍。说白了,就是搞清楚一张照片从你按下快门,到最终存到手机里,中间到底经历了什么。

我个人习惯,在深入任何模块之前,先看全局。你想想看,如果连数据流怎么走的都不知道,后面 debug 起来会非常痛苦。我在项目中遇到过好几次,新人一上来就扎进 HAL 代码里,结果连是上层没传参数还是底层没回调都分不清,浪费大量时间。

1.1 整体架构分层

Android Camera 架构,从顶层到最底层,大致可以分为这么几层:

  • Application 层:也就是我们写的 App,调用 Camera2 API。
  • Framework 层:Android 系统服务,负责管理权限、协调资源、分发数据。
  • Camera Service 层:核心服务,管理 Camera 设备、处理请求。
  • Camera HAL 层:硬件抽象层,连接 Framework 和硬件驱动。
  • Kernel 层:Linux 内核驱动,直接操作传感器、ISP 等硬件。

嗯,这里要注意,HAL 层是我们这门课的重点。它就像一个翻译官,把上层统一的 API 调用,翻译成底层各种芯片厂商私有的指令。

1.2 数据流全景:从 App 到 HAL

咱们以一次拍照为例,看看数据是怎么流动的。我建议你把这个流程记在脑子里,以后看代码会轻松很多。

  1. App 发起请求:App 通过 Camera2 API 创建一个 CaptureRequest,里面包含了拍照的各种参数,比如曝光、对焦、输出尺寸等。
  2. Framework 处理:Framework 层的 CameraManagerCameraDeviceImpl 接手,检查权限,然后把请求封装成更底层的格式,发给 Camera Service。
  3. Camera Service 调度:Camera Service 是核心调度器。它会管理多个 App 的请求,确保优先级正确。然后通过 Binder IPC 把请求传给 HAL 层。
  4. HAL 层执行:HAL 层收到请求后,会调用底层驱动去配置传感器、ISP 等硬件。硬件开始采集数据,生成原始图像帧。
  5. 数据回传:HAL 把处理好的图像数据(比如 YUV 或 JPEG)通过回调函数,一层层往上返回。最终 App 在 ImageReaderonImageAvailable 回调里拿到数据。

核心要点:整个流程是典型的「请求-响应」模式。App 下发请求,HAL 返回结果。中间每一层都在做「翻译」和「调度」的工作。

1.3 各层职责详解

光说流程还不够,咱们得把每一层具体干什么搞清楚。我根据自己的经验,给你拆解一下。

1.3.1 Application 层

这一层离用户最近。它的职责很简单:调用 API,处理结果。但坑也不少。我曾经见过一个 App,在 onImageAvailable 里直接做 JPEG 编码,导致 UI 线程卡死。记住,耗时的图像处理一定要放到后台线程。

1.3.2 Framework 层

这一层是 Android 系统的核心。它提供了 CameraManagerCameraDeviceCameraCaptureSession 等关键类。它的职责包括:

  • 权限管理:检查 App 是否有相机权限。
  • 设备管理:打开/关闭 Camera 设备。
  • 会话管理:创建和管理 Capture Session。
  • 请求分发:把 App 的请求转换成 HAL 能理解的格式。

避坑指南:我曾经在调试一个预览黑屏的问题时,发现是 Framework 层的 Surface 配置错了。App 要求的是 NV21 格式,但 Framework 默认配成了 YV12。这种问题在 HAL 层根本看不出来,只能一层层往上查。

1.3.3 Camera Service 层

这一层是真正的「大管家」。它运行在独立的进程中(cameraserver),负责:

  • 管理多个 Camera 设备实例。
  • 处理来自不同 App 的并发请求。
  • 与 HAL 层通过 HIDL 或 AIDL 通信。

说白了,它就是 App 和 HAL 之间的桥梁。没有它,App 根本不知道哪个 HAL 设备可用。

1.3.4 Camera HAL 层

这是我们这门课的主战场。HAL 层是硬件厂商实现的,它必须遵循 Android 定义的接口规范。目前主流的是 Camera HAL3 规范。它的核心接口是 camera3_device_tcamera3_callback_ops_t

HAL 层的核心职责:

  • 实现 process_capture_request 函数,处理来自上层的拍照请求。
  • 管理硬件资源,比如 sensor、ISP、flash 等。
  • 生成 CaptureResult,包含元数据(如 AE/AWB 状态)和图像缓冲区。
  • 通过回调函数把结果返回给 Camera Service。

注意:HAL 层是运行在 Camera Service 进程中的。如果你的 HAL 实现有内存泄漏或死锁,整个 cameraserver 都会挂掉,导致所有 App 都无法使用相机。我曾经在调试一个第三方 HAL 时,发现它每次拍照都申请 DMA buffer 但不释放,结果系统跑了半小时后直接 OOM 重启。

1.3.5 Kernel 层

这一层是硬件驱动的天下。它负责:

  • 控制 sensor 曝光、增益、帧率。
  • 处理 ISP 的图像处理管线(去噪、锐化、色彩校正)。
  • 管理 V4L2 视频设备节点。

嗯,这里要提一句,Kernel 层的代码通常由芯片厂商(高通、MTK、展锐)提供,我们一般不会去改它。但理解它的工作原理,对调试 HAL 层问题非常有帮助。

1.4 数据流中的关键数据结构

在整个数据流中,有几个数据结构你必须要熟悉。我整理了一个表格,方便你对照。

数据结构 所在层 作用
CaptureRequest App / Framework 包含拍照参数(曝光、对焦、输出尺寸等)
CaptureResult Framework / HAL 包含拍照结果(元数据 + 图像数据)
camera3_capture_request_t HAL HAL 层接收的请求,包含 settings 和 output buffers
camera3_stream_buffer_t HAL 描述一个图像缓冲区(格式、尺寸、地址)
camera_metadata_t Framework / HAL 键值对形式的元数据,用于传递参数和结果

你想想看,这些数据结构就像快递包裹。App 把需求写在 CaptureRequest 里,HAL 把结果装在 CaptureResult 里。中间每一层都在拆包、检查、重新打包。

1.5 小结与思考

好了,第一节课的内容就到这里。我们梳理了 Android Camera 的完整架构,从 App 到 HAL 的数据流,以及每一层的职责。我个人觉得,理解这个架构是学好 Camera HAL 的第一步。以后我们讲到的每一个模块,你都可以在这个架构图上找到它的位置。

最后留个思考题:如果 App 拍照后一直收不到回调,你觉得问题可能出在哪几层? 下一节课,我们会深入 HAL 层的核心接口,看看 process_capture_request 到底是怎么工作的。

学习建议:我建议你打开 AOSP 源码,找到 frameworks/av/camera/camera2/hardware/interfaces/camera/ 这两个目录,先大致浏览一下文件结构。不用看懂代码,混个脸熟就行。