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
咱们以一次拍照为例,看看数据是怎么流动的。我建议你把这个流程记在脑子里,以后看代码会轻松很多。
- App 发起请求:App 通过 Camera2 API 创建一个
CaptureRequest,里面包含了拍照的各种参数,比如曝光、对焦、输出尺寸等。 - Framework 处理:Framework 层的
CameraManager和CameraDeviceImpl接手,检查权限,然后把请求封装成更底层的格式,发给 Camera Service。 - Camera Service 调度:Camera Service 是核心调度器。它会管理多个 App 的请求,确保优先级正确。然后通过 Binder IPC 把请求传给 HAL 层。
- HAL 层执行:HAL 层收到请求后,会调用底层驱动去配置传感器、ISP 等硬件。硬件开始采集数据,生成原始图像帧。
- 数据回传:HAL 把处理好的图像数据(比如 YUV 或 JPEG)通过回调函数,一层层往上返回。最终 App 在
ImageReader的onImageAvailable回调里拿到数据。
核心要点:整个流程是典型的「请求-响应」模式。App 下发请求,HAL 返回结果。中间每一层都在做「翻译」和「调度」的工作。
1.3 各层职责详解
光说流程还不够,咱们得把每一层具体干什么搞清楚。我根据自己的经验,给你拆解一下。
1.3.1 Application 层
这一层离用户最近。它的职责很简单:调用 API,处理结果。但坑也不少。我曾经见过一个 App,在 onImageAvailable 里直接做 JPEG 编码,导致 UI 线程卡死。记住,耗时的图像处理一定要放到后台线程。
1.3.2 Framework 层
这一层是 Android 系统的核心。它提供了 CameraManager、CameraDevice、CameraCaptureSession 等关键类。它的职责包括:
- 权限管理:检查 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_t 和 camera3_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/ 这两个目录,先大致浏览一下文件结构。不用看懂代码,混个脸熟就行。