1. 相机系统全景总览:Android相机架构演进、Camera HAL发展史、整体软件栈分层、核心组件介绍

大家好,我是你们的老朋友。今天咱们正式开讲《Android相机系统深度解析》的第一章。

说实话,Android相机系统这玩意儿,我刚入行那会儿也觉得它就是个「黑盒子」——上层调个API,底层咔擦一张照片,完事。直到后来我在一个项目里被相机启动延迟折磨了整整两周,才意识到这背后的水有多深。

嗯,咱们今天就把这个「黑盒子」拆开,看看里面到底藏着什么。

1.1 从单核到多摄:Android相机架构的演进之路

Android相机架构不是一天建成的。它经历了几个关键阶段,我按时间线给你捋一捋。

1.1.1 早期阶段(Android 1.0 ~ 4.4)

那时候的相机架构,说白了就是个「直通车」。应用层直接通过Binder调用CameraService,CameraService再往下走HAL。架构简单,但问题也明显——扩展性差,厂商想加个美颜滤镜都得大动干戈。

我记得当时有个项目,客户要求在预览流里叠加AR特效。我们翻遍了源码,最后只能在HAL层硬塞代码。那代码写得,我自己后来都不敢看。

1.1.2 转折点:Android 5.0 的 Camera HAL v3

Android 5.0是个分水岭。Google终于意识到,老架构撑不住了。于是Camera HAL v3诞生了。

v3的核心变化是什么?流水线化。它把拍照拆成了一个个独立的「捕获请求」(Capture Request),每个请求可以指定不同的参数——分辨率、帧率、对焦模式、甚至传感器输出格式。这给了上层极大的灵活性。

举个例子,你可以同时发两个请求:一个给预览用(低分辨率、高帧率),一个给拍照用(高分辨率、低帧率)。这在v2时代想都不敢想。

1.1.3 现代架构:Android 8.0+ 的 Treble 与 HIDL

Android 8.0引入了Treble,把framework和vendor实现彻底解耦。Camera HAL从以前的「直接链接」变成了通过HIDL接口通信。这意味着什么?厂商升级系统时,不用再重写整个相机驱动了。

我个人觉得,这是Google做过最正确的决定之一。你想想看,以前每次Android大版本升级,手机厂商的相机团队都要加班加点适配。有了Treble,至少底层驱动可以「一次编写,多次运行」。

1.1.4 最新趋势:Android 14+ 的 Camera HAL v4 与多摄协同

到了Android 14,Camera HAL v4开始崭露头角。它最大的亮点是原生支持多摄协同——比如同时使用主摄和超广角做融合拍照,或者在不同摄像头之间无缝切换变焦。

我在项目中遇到过一个问题:双摄切换时画面会「跳一下」。后来发现是HAL层没有处理好同步时间戳。嗯,这种坑,只有踩过才知道疼。

1.2 Camera HAL 发展史:从 v1 到 v4 的进化

咱们单独聊聊HAL。毕竟它是整个相机系统的「心脏」。

版本 Android版本 核心特点 我的评价
HAL v1 1.0 ~ 4.4 简单、直接、但僵硬 「能用,但别想玩花样」
HAL v2 4.4(实验性) 尝试引入流模型,但未普及 「生不逢时」
HAL v3 5.0 ~ 至今 捕获请求模型、灵活配置 「经典之作,至今仍在用」
HAL v4 14+(逐步推广) 多摄协同、AI集成、低延迟 「未来已来」

这里我想多说一句:HAL v3虽然叫「v3」,但它其实是从v1直接跳过来的。v2只在Android 4.4里短暂出现过,因为太复杂,几乎没有厂商采用。Google后来也学乖了——与其搞个完美的架构,不如搞个「够用且能落地」的。

避坑指南: 我曾经在HAL v3的validateStream()函数里踩过一个坑——如果配置的流格式不匹配,它不会报错,而是直接返回一个「看起来正常」的结果。结果预览画面全是绿的。后来我养成了一个习惯:每次配置完流,一定要抓一帧数据验证一下。

1.3 整体软件栈分层:从 App 到 Sensor

Android相机系统的软件栈,从上到下大概分这么几层。我画了一张图,帮你直观理解。

Android 相机系统软件栈分层 应用层 (App) Camera2 API / CameraX / 第三方相机App Framework 层 CameraService / CameraProvider / 权限管理 HAL 层 Camera HAL v3/v4 / HIDL 接口 内核驱动层 (Kernel) V4L2 / ISP驱动 / Sensor驱动 硬件层 (Hardware) CMOS Sensor / ISP芯片 / 镜头模组 用户空间 内核空间 硬件

这张图你应该能看明白。从上到下,每一层都依赖下一层提供的服务。但有意思的是,数据流是双向的——上层下发配置和请求,下层回传图像数据和事件。

我习惯把整个流程想象成「点菜」:App是顾客,CameraService是服务员,HAL是大厨,Kernel是厨房设备,硬件就是食材。顾客点菜(发起请求),服务员传单(Binder通信),大厨按单做菜(处理请求),设备运转(驱动执行),最后端上桌(返回图像数据)。

1.4 核心组件介绍

咱们挑几个关键组件,深入聊聊。

1.4.1 CameraService

CameraService是framework层的「大管家」。它负责管理所有摄像头设备、处理来自App的连接请求、协调权限检查、以及分发事件通知。

它的核心代码在 frameworks/av/services/camera/libcameraservice/ 下。如果你有兴趣,可以看看 CameraService.cpp 里的 connect() 方法——那是整个相机服务的入口。

关键点: CameraService 内部维护了一个 CameraProviderManager,它负责发现和枚举所有可用的 CameraProvider(每个Provider对应一个HAL实现)。这意味着,如果你的设备有多个摄像头,它们可能来自不同的Provider。

1.4.2 CameraProvider

CameraProvider是Treble架构引入的概念。它运行在一个独立的进程中(通常是 cameraserver),通过HIDL与CameraService通信。

为什么要搞这么复杂?说白了就是为了隔离。以前CameraService直接加载HAL的so库,一旦HAL崩溃,整个系统都得跟着遭殃。现在Provider跑在独立进程里,HAL挂了,大不了重启Provider,不影响系统其他服务。

1.4.3 Camera HAL

HAL是硬件抽象层,也是厂商最「爱恨交加」的部分。爱的是,它给了厂商极大的定制空间;恨的是,Google的CTS测试越来越严,稍微改点东西就可能过不了测。

HAL v3的核心接口是 camera3_device_tcamera3_callback_ops_t。前者定义了设备操作(open、close、process_capture_request等),后者定义了回调函数(通知上层数据就绪)。

// HAL v3 核心结构体(简化版)
typedef struct camera3_device {
    hw_device_t common;
    
    // 初始化设备
    int (*initialize)(const struct camera3_device *,
                      const camera3_callback_ops_t *callback_ops);
    
    // 处理捕获请求
    int (*process_capture_request)(const struct camera3_device *,
                                   camera3_capture_request_t *request);
    
    // 刷新所有待处理请求
    int (*flush)(const struct camera3_device *);
} camera3_device_t;

你看,接口其实不多。但每个接口背后的实现,那可就千差万别了。我见过有的厂商在 process_capture_request 里塞了上千行代码,各种if-else判断。说实话,这种代码维护起来真的很痛苦。

1.4.4 图像流与Buffer管理

相机系统里,图像数据是以「流」的形式传递的。每个流对应一个 Surface,App通过 SurfaceTextureSurfaceView 消费这些数据。

Buffer的管理是性能的关键。Android使用 Gralloc 分配图形缓冲区,通过 IONDMA-BUF 在内核空间管理内存。这里有个常见的性能瓶颈:如果Buffer分配和回收不及时,预览就会卡顿。

注意: 我曾经在一个项目里发现,预览帧率从30fps掉到了15fps。排查了半天,最后发现是Gralloc的BufferQueue满了,导致HAL层在等Buffer释放。解决方案是增大BufferPool的容量,或者优化App侧的消费速度。

1.5 小结

好了,第一章的内容就到这里。咱们把Android相机系统的「全景图」铺开来看了一遍——从架构演进到HAL发展史,从软件栈分层到核心组件。你可能会觉得信息量有点大,没关系,后面每一章都会深入讲解其中一个模块。

我个人建议,如果你刚开始接触相机系统,先把这张「分层图」记在脑子里。以后遇到任何问题,先问自己一句:「这个问题出在哪一层?」——是App层?Framework层?HAL层?还是硬件层?定位清楚了,解决问题就事半功倍。

嗯,下一章咱们会深入 Camera2 API 的细节,看看App到底是怎么跟相机系统打交道的。到时候见。


公众号:蓝海资料掘金营,微信deep3321