一、Camera整体架构概览:从上层APP到底层Sensor的完整数据通路
做Camera驱动也有些年头了,每次带新人时,我总喜欢先画一张整体架构图。为什么?因为Camera这玩意儿,说复杂也复杂,说简单也简单——无非就是「上层要拍照,底层去取图」。但中间这一大坨,才是真正考验人的地方。
今天咱们就来聊聊,在瑞芯微平台上,一张照片从你按下快门到最终显示在屏幕上,到底经历了哪些环节。
1.1 完整数据通路:从APP到Sensor
先看一条最核心的链路。你打开相机App,点下拍照按钮,数据是怎么走的?
APP (Camera2 API)
↓
Framework (Android Camera Service)
↓
HAL (Camera HAL3 + RK扩展)
↓
Kernel (V4L2 + Rockchip ISP驱动)
↓
Sensor (物理摄像头模组)
这条链路,说白了就是「命令往下传,数据往上送」。上层发一个「拍照」指令,底层Sensor开始曝光、输出RAW图,然后一路经过ISP处理、HAL封装,最终回到APP显示。
我个人习惯把这条通路分成两段来看:
- 控制通路:APP → Framework → HAL → Kernel → Sensor。这是命令流,比如设置曝光、对焦、帧率。
- 数据通路:Sensor → Kernel → HAL → Framework → APP。这是图像流,RAW图、YUV、JPEG都在这里跑。
嗯,这里要注意,两条通路是并行的,但互相影响。比如你调了曝光时间,下一帧的数据就会变化。我在项目中遇到过一个问题:上层设置了HDR模式,但底层Sensor根本没切过去,结果拍出来的照片过曝得一塌糊涂。后来查了半天,发现是HAL层把命令给吞了,没往下传。
1.2 RK平台Camera软件栈分层
瑞芯微的Camera软件栈,和主流Android平台基本一致,但有一些自己的特色。我把它分成三层来讲:
Framework层
这一层是Android原生的,说白了就是Google定好的规矩。它定义了Camera2 API,提供了CameraService、CameraDevice这些核心类。你写APP时调用的openCamera()、capture(),最终都会走到这里。
Framework层不关心你用的是OV还是SONY的Sensor,它只认HAL层提供的接口。所以,Framework和HAL之间,有一份「契约」——就是HAL3的接口定义。
HAL层
这是RK平台的重头戏,也是咱们这门课的核心。HAL层在系统中处于什么位置?我打个比方:
Framework是「甲方」,Kernel是「施工队」,HAL就是「项目经理」。
甲方说「我要一张1080P、30fps的照片」,项目经理得去协调施工队,看看Sensor能不能支持这个分辨率,ISP能不能处理这个帧率,然后给出一个可行的方案。
在RK平台上,HAL层不仅仅是实现Android定义的camera3_device_ops_t,还做了大量扩展:
- 多Camera协同管理(比如双摄、三摄)
- RK自研的ISP算法集成(降噪、HDR、3A)
- Buffer管理(ION/DMA-BUF)
- Sensor配置下发与状态同步
我曾经在一个项目里,HAL层没处理好Buffer的申请时机,导致预览画面卡顿。后来加了一个预分配池,问题就解决了。说白了,HAL层就是那个「兜底」的,上层不管的、底层做不了的,都得HAL来扛。
Kernel层
Kernel层主要包含V4L2框架和Rockchip的ISP驱动。V4L2是Linux下视频设备的标准接口,Sensor、CSI控制器、ISP都注册成V4L2子设备。HAL层通过ioctl来和它们打交道。
RK的ISP驱动比较特殊,它不仅仅做图像处理,还负责统计信息的收集(比如AE/AWB的统计数据)。这些统计信息会回传给HAL层的3A算法库,形成闭环控制。
小提示:调试时,我习惯先在Kernel层确认Sensor能否正常出图。用media-ctl和v4l2-ctl工具,直接抓一帧RAW图看看。如果Kernel层就出问题了,那HAL层再折腾也没用。
1.3 HAL层在系统中的核心位置与作用
为什么说HAL层是「核心」?你想想看,整个Camera系统中,谁最了解硬件?是Framework吗?不是。是Kernel吗?也不是。Kernel只管把数据从Sensor搬出来,它不关心这帧数据是预览用的还是拍照用的。
真正知道「什么时候该做什么事」的,是HAL层。它要处理的事情包括:
| 职责 | 说明 |
|---|---|
| Pipeline管理 | 管理从Sensor到ISP再到输出的完整流水线,包括Stream配置、Buffer分配 |
| 3A控制 | AE/AWB/AF算法的调度与参数下发,这部分RK有自己的算法库 |
| 格式转换 | Sensor输出的RAW图,经过ISP处理后,转成YUV或JPEG给上层 |
| 异常处理 | Sensor掉线、帧率不稳、Buffer超时等,HAL层要能兜住 |
| 性能优化 | 减少内存拷贝、复用Buffer、降低延迟 |
我举个例子你就明白了。有一次客户反馈,相机预览时偶尔会黑屏几秒钟。我排查后发现,是HAL层在切换分辨率时,没有处理好Stream的停启顺序。Sensor还在出图,HAL就把Buffer给释放了,导致上层拿到的是空数据。
修复方法很简单:先停掉数据流,等所有Buffer都回收了,再重新配置Stream。但如果你不了解HAL层在整个链路中的位置,你根本想不到问题出在这里。
避坑指南:我曾经在调试双摄时,发现主摄和副摄的帧率不同步。原因是HAL层给两个Sensor下发的配置时间差太大。后来我改成在同一个线程里串行下发,并加了同步信号量,问题才解决。记住,HAL层是「协调者」,不是「传话筒」。
1.4 整体架构图
下面这张图,是我自己画的RK平台Camera整体架构。它把上面讲的内容串在了一起,建议你多看几遍。
这张图里,我特意把控制流和数据流分开画了。你注意看,控制流是从上往下的,数据流是从下往上的。HAL层正好卡在中间,既要接住上层的命令,又要管好下层的输出。
说白了,HAL层就是整个Camera系统的「大脑」。它不直接干活,但所有活都得经过它协调。Framework说「我要拍照」,HAL就去安排Sensor曝光、ISP处理、Buffer流转,最后把照片交回去。
嗯,这一章的内容就到这里。理解了整体架构,后面咱们再深入每一层的细节,就会轻松很多。