V4L2 && Media Controller
定义
V4L2 Linux内核中关于视频设备驱动的框架,对上向应用层提供统一的接口,对下支持各类复杂硬件的灵活扩展,
负责访问视频设备的节点,比如 /dev/videoX 或 /dev/v4l-subdevX 等;
MC (Media Controller) 是为了解决设备拓扑复杂时的控制问题,提供了一个图(Graph)结构来描述各模块间的连接关系。
传统摄像头驱动中,一个设备节点 /dev/video0 就能代表整个,但现实中的图像系统非常复杂,比如
[Sensor] → [MIPI-CSI] → [Adapter] → [ISP ] → [Scaler ] → [Video Output]
模块之间是模块化和可配置的,单靠 /dev/videoX 很难表示清楚。所以 Linux 提出了 Media Controller 框架,把整个图像通路抽象成“图”。
在很多主流平台上,每个平台只有一个 /dev/media0; 所有 entity 都挂在这个 media_device 上。
在复杂多模块平台(多 ISP / 多 VPU)有些更复杂的 SoC,或加载了多个驱动模块的 Linux 系统中,可能存在多个 mediaX 节点;
Media Controller 框架核心结构
-
media_entity(实体)表示一个视频模块,
例如:摄像头 Sensor(V4L2 subdev)MIPI-CSI(V4L2 subdev)等 每个 Entity 会在驱动中注册,
并带有一个或多个 pad(端点)。 -
media_pad(Pad,端点)
用于描述 Entity 的输入输出;分为:Sink Pad(输入端),Source Pad(输出端)
举例:Sensor 只有一个 source pad;MIPI-CSI 有 sink pad 和 source pad。 -
media_link(连接)
将两个 pad 连起来,构成有向图;
可设置 Link 是否 enable,用来动态切换数据通路; -
media_interface(接口)
每个 entity(比如 sensor、ISP、CSI、video output)可能会通过 media_interface 结构体暴露给用户空间;
不是每个 entity 都有接口节点,只有那些对用户空间开放的 entity 才会注册对应的 interface。
举例说明:
1.Sink/Source Pad
/*
Sink Pad(输入):数据“流入”这个模块。CSI_PAD_SINK 表示 CSI 接收外部图像数据的输入 pad,通常来自 sensor。
Source Pad(输出):数据“流出”这个模块。CSI_PAD_SRC 才是 CSI 处理后往下一个模块传递数据的输出 pad。
*/
[sensor]--sensor_source_pad → link → csi_sink_pad--[CSI controller]--csi_source_pad→ link →Adapter_sink _pad-[Adapter]
2.Media Graph实例图

-
0,1,2...表示每个实体的pad,剪头(即link)表示数据流向;
-
4个v4l2-subdev节点(子设备节点):sensor/csi/adapter/isp/ 对应四个media_entity;
-
8个video设备节点(主视频节点):ddr-input/param/stats/output0~output3/raw/;
注:/dev/v4l2-subdev* 和 /dev/video*的区别
| 项目 | /dev/videoX | /dev/v4l_subdevX |
|---|---|---|
| 类型 | Video Device | Subdev Device |
| 来源 | video_device | v4l2_subdev |
| IO 功能 | 采集/输出视频流(可读写帧) | 配置模块参数(不可读写帧) |
| 接口操作 | VIDIOC_STREAMON, VIDIOC_DQBUF, ... | VIDIOC_SUBDEV_S_FMT, VIDIOC_SUBDEV_ROUTING, ... |
| 常见用途 | 抓图 / 录像 / 预览 / 视频采集 | 设置分辨率 / AE / AWB / 路由 / 流格式 |
| 是否一定在 media graph 中 | 是 | 是 |
| 是否一定对应 entity | 是 | 是 |
| 是否一定有 pad | 有,一个 pad | 有,通常多个 pad(输入/输出) |
V4L2 + MC 框架结构图
+----------------------------------------------------------+
| Userspace 应用层 |
| media-ctl | v4l2-ctl | GStreamer | 自定义 app |
+----------------------------------------------------------+
⇅ ioctl(), open(), mmap()
+----------------------------------------------------------+
| Kernel: V4L2 Core + Media Controller |
| v4l2-dev.c | v4l2-subdev.c | media-entity.c | mc-core.c |
+----------------------------------------------------------+
⇅ 注册 media_entity、pad、link
+----------------------------------------------------------+
| V4L2 驱动层(Sensor、ISP、Scaler) |
| ov5640.c | csi.c | imx219.c |adapter.c | isp.c | ... |
+----------------------------------------------------------+
⇅ 通过 platform/i2c/spi 访问硬件
+----------------------------------------------------------+
| 底层 SoC 硬件 |
| 摄像头模块 | ISP IP核 | MIPI Rx | DMA Engine |
+----------------------------------------------------------+
工具
- media-ctl 查看拓扑图或设置格式
media-ctl --device /dev/media0 --get-topology //获取media0 的拓扑图
- v4l2-ctl 控制视频采集
/*
从/dev/video0 设备采集 100 帧图像数据,使用 MMAP 方式分配缓冲区并读取帧,图像格式1280*720/NV12
*/
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=NV12 --stream-mmap --stream-count=100
参考链接:
https://blog.csdn.net/cqxcool66/article/details/119389845
https://zhuanlan.zhihu.com/p/105548113
https://zhuanlan.zhihu.com/p/638020445
https://zhuanlan.zhihu.com/p/613738305
https://www.cnblogs.com/arnoldlu/p/18126416
https://blog.csdn.net/bai915290475/article/details/138805985
浙公网安备 33010602011771号