1. Camera驱动全景概览:从硬件接口到软件栈,理解Camera子系统全貌
做Camera驱动开发这些年,我最大的感触是——很多人一上来就扎进代码里,结果越调越懵。其实,搞懂Camera子系统,你得先看清它长什么样。说白了,就是硬件怎么连、数据怎么流、软件怎么管这三件事。
今天这一章,我带你把Camera子系统的全貌捋一遍。不追求一次全记住,但求脑子里有个清晰的地图。
1.1 硬件接口:Camera是怎么连上SoC的?
Camera模组和SoC之间,靠的是硬件接口。目前主流的接口就几种,我列个表,你一看就明白。
| 接口类型 | 数据通道 | 典型带宽 | 常见场景 |
|---|---|---|---|
| MIPI CSI-2 | 1-4 Lane | 每Lane ~1.5Gbps | 手机、平板、车载 |
| Parallel | 8-16 bit并行 | ~100Mbps | 低端摄像头、监控 |
| USB | UVC协议 | USB 3.0 ~5Gbps | 外接摄像头、PC |
| LVDS | 串行差分 | ~1Gbps | 工业相机、车载 |
我个人习惯,拿到一个新平台,第一件事就是确认MIPI CSI的Lane配置。为什么?因为带宽不够,后面所有优化都是白搭。我曾经在一个项目里,Sensor输出4K@60fps,结果只配了2 Lane MIPI,数据根本传不过来。嗯,这种坑踩过一次就记住了。
1.2 软件栈:从Sensor到应用,数据经历了什么?
Camera软件栈,我习惯把它分成三层:底层驱动、中间件、上层应用。每一层都有自己的活,也都有自己的坑。
1.2.1 底层驱动层
这一层直接跟硬件打交道。主要包含:
- Sensor驱动:初始化Sensor、配置分辨率/帧率、控制曝光和增益。说白了,就是让Sensor开始干活。
- CSI/ISP驱动:负责接收MIPI数据,做初步的RAW数据预处理。比如坏点校正、黑电平校正。
- V4L2框架:Linux下Camera驱动的标准接口。你写驱动,最终都是要注册到V4L2里的。
你想想看,底层驱动如果没写好,上层再怎么调也是白费力气。我见过一个团队,花了两周调ISP效果,结果发现Sensor的PCLK配置错了,数据全是乱的。所以,底层一定要稳。
1.2.2 中间件层
中间件是承上启下的关键。常见的有:
- HAL层:Android的Camera HAL,封装底层接口,提供统一API给上层。
- ISP算法库:3A算法(AE/AWB/AF)、降噪、锐化、HDR等。这部分最吃算力,也最影响画质。
- Buffer管理:分配和回收图像Buffer,避免内存抖动。我习惯用ION或DMA-BUF,效率高。
重点提醒:中间件的延迟往往是整个Camera pipeline的瓶颈。尤其是Buffer分配和3A算法,稍不注意就会引入几帧的延迟。
1.2.3 上层应用层
这一层就是用户能看到的了。比如相机App、视频通话、扫码等。应用层通过Framework调用底层,拿到图像数据后做显示、编码或分析。
嗯,这里要注意:应用层对延迟最敏感。用户按下快门,到看到照片,中间超过200ms,就会觉得卡。所以,优化最终要落到应用层的体验上。
1.3 数据流:一帧图像是怎么走完的?
我画个简单的数据流,你跟着走一遍:
- Sensor曝光:Sensor开始采集光线,生成RAW数据。
- MIPI传输:RAW数据通过MIPI CSI接口,传到SoC的ISP模块。
- ISP处理:ISP做RAW域处理,输出YUV或RGB数据。
- Buffer排队:处理完的数据放入Buffer队列,等待上层取走。
- 应用消费:应用从Buffer队列拿到数据,显示或编码。
整个过程,从Sensor曝光到应用拿到数据,就是Camera pipeline的延迟。我做过一个项目,从Sensor曝光到屏幕显示,延迟控制在30ms以内。怎么做到的?后面章节我会详细讲。
我的经验:优化延迟,核心就是减少Buffer拷贝和等待。能走零拷贝就走零拷贝,能用硬件加速就别用CPU。
1.4 关键概念:你必须要懂的几个术语
做Camera驱动,有几个术语你绕不开。我挑最重要的说:
- 帧率(FPS):每秒输出多少帧。30fps是基础,60fps算流畅,120fps以上是高刷。
- 延迟(Latency):从Sensor曝光到应用拿到数据的时间。单位是毫秒。
- Pipeline深度:数据流中同时处理的帧数。深度越大,延迟越高,但吞吐量也大。
- 3A算法:自动曝光(AE)、自动白平衡(AWB)、自动对焦(AF)。这三个算法直接影响画质。
我曾经在一个项目中,为了降低延迟,把Pipeline深度从4降到2。结果延迟降了,但帧率也掉了。后来发现是Buffer分配没跟上。所以,深度和延迟之间要找到平衡点。
1.5 常见问题与避坑指南
避坑1:MIPI信号完整性
我曾经遇到一个项目,Sensor输出图像偶尔出现条纹。查了两天,最后发现是MIPI走线太长,信号衰减了。解决办法:缩短走线,或者加Repeater。
避坑2:Buffer饥饿
高帧率场景下,如果Buffer分配不够快,会导致Pipeline空转。我建议预留至少3个Buffer做乒乓操作,避免饥饿。
避坑3:ISP参数配置
ISP的寄存器配置,一定要按照Sensor的datasheet来。我见过有人把黑电平校正值配反了,结果图像整体偏色。嗯,这种低级错误,犯一次就够了。
1.6 本章小结
这一章,我们走了一遍Camera子系统的全貌。从硬件接口(MIPI、Parallel、USB),到软件栈(驱动、中间件、应用),再到数据流和关键概念。说白了,就是让你脑子里有个地图,知道Camera系统长什么样。
下一章,我会带你深入V4L2框架,看看驱动是怎么注册、怎么控制Sensor的。到时候,我们手写一个简单的Sensor驱动,你就能真正理解底层是怎么工作的了。
好,今天就到这儿。有问题随时交流。