摄像头数据如何在Linux内核中走完"采集→处理→显示"全程?本文用一张全景图+一次采集追踪,讲清楚V4L2、DRM/DMABUF三者的关系,每个模块标注输入输出,1分钟搞懂Linux视频管线。
一、三层架构全景图
视频数据在Linux内核中流经三个子系统:V4L2负责采集,DRM负责显示,DMA-BUF负责零拷贝桥接。
三层职责速记:
| | |
|---|
| /dev/video0+ vb2_queue | |
| EXPBUF + PRIME | |
| FB → Plane → CRTC → Connector | |
二、一次采集请求的完整旅程
摄像头按下录制键,数据走了一条怎样的路?追踪一帧图像从镜头到屏幕的完整路径。
- 镜头光信号 → CMOS 传感器 → MIPI CSI-2 串行传输
- ISP 完成 Bayer 解码/去噪/白平衡 → 原始图像
open("/dev/video0") → VIDIOC_S_FMT 设置格式(1920×1080 NV12)VIDIOC_REQBUFS + VIDIOC_QBUF 申请并入队缓冲区VIDIOC_STREAMON 启动流 → 驱动开始填充帧VIDIOC_DQBUF 出队 → 拿到已填充帧的句柄VIDIOC_EXPBUF 导出 DMA-BUF fd → 零拷贝关键drmPrimeFDToHandle 导入 fd → 创建 Framebuffer
三、V4L2 三种缓冲区模式对比
四、DMA-BUF 零拷贝 vs 传统拷贝路径
五、总结
记一个口诀:采集入队→DQBUF取帧→EXPBUF导出→PRIME导入→CRTC扫描。
整个Linux视频管线的本质就是零拷贝句柄传递:数据从摄像头到屏幕全程是DMA句柄流转,不触发一次CPU拷贝。理解这个传递链,就理解了V4L2和DRM的协作方式。