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 框架核心结构

  1. media_entity(实体)表示一个视频模块,
    例如:摄像头 Sensor(V4L2 subdev)MIPI-CSI(V4L2 subdev)等 每个 Entity 会在驱动中注册,
    并带有一个或多个 pad(端点)。

  2. media_pad(Pad,端点)
    用于描述 Entity 的输入输出;分为:Sink Pad(输入端),Source Pad(输出端)
    举例:Sensor 只有一个 source pad;MIPI-CSI 有 sink pad 和 source pad。

  3. media_link(连接)
    将两个 pad 连起来,构成有向图;
    可设置 Link 是否 enable,用来动态切换数据通路;

  4. 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 |
+----------------------------------------------------------+

工具

  1. media-ctl 查看拓扑图或设置格式
media-ctl --device /dev/media0 --get-topology //获取media0 的拓扑图
  1. 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

posted @ 2025-04-18 10:36  chivalrySun  阅读(325)  评论(0)    收藏  举报