1. Camera HAL 架构概览

做 Camera 开发这么多年,我经常被问到同一个问题:“HAL 层到底在 Android 相机系统里扮演什么角色?” 说白了,它就是连接上层应用和底层硬件的桥梁。没有它,Framework 不知道如何操作你的摄像头传感器,硬件也不知道上层想要什么。

今天我们就从架构分层开始,一步步拆解这个桥梁是怎么搭起来的。

1.1 Android Camera 架构分层

Android 相机系统从上到下,大致可以分为四层:

  • 应用层(App):用户直接接触的相机应用,比如系统相机、第三方美颜 App。
  • Framework 层:提供 Camera API(Camera2、CameraX),管理相机生命周期、会话、请求等。
  • HAL 层:硬件抽象层,定义了一套标准接口,让 Framework 无需关心具体硬件实现。
  • Kernel 层:驱动层,直接与传感器、ISP 等硬件交互。

嗯,这里要注意:HAL 层是 Android 相机性能调优的关键战场。我在项目中遇到过很多次,上层 API 调用没问题,但底层 HAL 实现有 bug,导致预览卡顿、拍照延迟。说白了,HAL 层写得好不好,直接决定了用户体验。

1.2 HAL 接口定义

Android 从 8.0 开始强制使用 Treble 架构,HAL 接口被标准化为 android.hardware.camera 这个 HIDL(或 AIDL)服务。你想想看,这意味着什么?意味着芯片厂商(Qualcomm、MTK、Rockchip)必须实现一套统一的接口,Google 才能保证兼容性。

核心接口包括:

接口名称 作用
ICameraDevice 代表一个物理或逻辑摄像头设备,负责打开、关闭、配置流
ICameraDeviceSession 一次相机会话,管理 Capture Request 和 Result 的流转
ICameraProvider 负责枚举摄像头、提供设备实例
ICameraDeviceCallback HAL 向 Framework 上报事件(如错误、帧到达)的回调接口

我个人习惯在写 HAL 实现时,先理清楚 ICameraDeviceSession 的生命周期。因为 一次拍照或录像,本质上就是一次 Session 的创建、配置、请求、销毁。我曾经在一个项目里,因为 Session 的 close() 没有正确释放 DMA buffer,导致连续拍照 10 次后内存泄漏——嗯,那是个让人头大的下午。

1.3 HAL 与 Framework 的交互流程

交互流程其实不复杂,我画了一张图帮你理解:

应用层 (App) Framework 层 (Camera2 API) HAL 层 (Camera HAL) Kernel 层 (驱动 + 硬件) openCamera() configureStreams() processCaptureRequest() ioctl / buffer 操作 onCaptureCompleted() Framework 回调处理

流程大致是这样的:

  1. App 发起请求:比如用户点击拍照按钮,App 通过 Camera2 API 调用 capture()。
  2. Framework 构造 CaptureRequest:Framework 把 App 的意图(曝光、对焦、输出格式等)打包成一个 CaptureRequest。
  3. HAL 接收请求:Framework 调用 HAL 的 processCaptureRequest() 接口,把请求传给 HAL。
  4. HAL 处理并返回结果:HAL 驱动硬件完成拍照,然后把 CaptureResult 通过回调 onCaptureCompleted() 返回给 Framework。
  5. Framework 回调 App:Framework 把结果封装成 TotalCaptureResult,通过 CameraCaptureSession.CaptureCallback 通知 App。

关键点:整个流程中,processCaptureRequest() 是性能瓶颈的高发区。我建议你在实现这个函数时,尽量减少锁的持有时间,把耗时的 ISP 处理放到工作线程里。否则,一旦阻塞,预览帧率会直接掉到 15fps 以下。

我的小技巧:在调试 HAL 性能时,我会在 processCaptureRequest() 入口和出口加时间戳日志。这样能快速定位是哪个环节拖慢了整体流程。我曾经靠这个办法,把一个拍照延迟从 200ms 优化到了 80ms。

避坑指南:我曾经在对接某款传感器时,发现 HAL 返回的 CaptureResult 里 sensor_timestamp 总是错的。查了半天,原来是 HAL 层在填充结果时,用了系统时间而不是硬件时间戳。记住:时间戳一定要用硬件提供的,否则会影响 3A 算法和视频稳像。

1.4 小结

这一章我们聊了 Camera HAL 的架构分层、接口定义和交互流程。说白了,HAL 层就是那个“翻译官”——把 Framework 的标准化请求,翻译成硬件能懂的指令。你想想看,没有这个翻译官,上层开发者得直接面对各种传感器的寄存器操作,那得多痛苦?

下一章我们会深入 ICameraDeviceSession 的实现细节,聊聊如何高效管理 Stream 和 Buffer。嗯,到时候我会分享一个我踩过的坑——关于 buffer 死锁的,保证让你印象深刻。

可可精品资料库