从 IMX415 摄像头驱动理解 Media Controller 框架

在嵌入式 Linux 摄像头驱动开发中,经常会遇到几个关键词:

复制代码
V4L2
Subdev
Media Controller
Media Entity
Pad
Link
/dev/videoX
/dev/v4l-subdevX

刚开始看摄像头驱动时,很容易把它们混在一起。比如我们在 IMX415 或 IMX219 这类 sensor 驱动中,经常能看到类似代码:

cpp 复制代码
imx415->pad.flags = MEDIA_PAD_FL_SOURCE; 
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; 
ret = media_entity_pads_init(&sd->entity, 1, &imx415->pad);

这几行代码看起来不复杂,但背后其实就是 Linux 摄像头链路中的 Media Controller 框架

本文就从一个最常见的问题讲起:为什么摄像头驱动里需要 Media Controller?

一、为什么需要 Media Controller?

以前理解摄像头时,很多人会认为:

复制代码
摄像头驱动加载成功
    ↓
生成 /dev/video0
    ↓
用户程序直接读取图像

但在现代 SoC 平台上,尤其是 Rockchip、NXP、TI、全志、瑞芯微等嵌入式平台中,摄像头系统通常不是一个单独模块,而是一整条硬件链路。

以 IMX415 为例,一帧图像大概会经过:

复制代码
IMX415 Sensor
    ↓
MIPI CSI-2 DPHY
    ↓
MIPI CSI-2 Receiver
    ↓
CIF / ISP
    ↓
Video Capture
    ↓
/dev/video0

这里面每一部分都可能是一个独立驱动:

复制代码
IMX415 sensor 驱动
MIPI DPHY 驱动
CSI 接收器驱动
ISP 驱动
video capture 驱动

于是问题来了:

复制代码
内核怎么知道 IMX415 接到了哪个 CSI?
CSI 后面又接到了哪个 ISP?
用户打开 /dev/video0 时,应该启动哪些子设备?
每一级的数据格式、分辨率、RAW 排列是否匹配?

这些事情就需要 Media Controller 来管理。

Linux 官方文档中也说明,Media Controller API 的目标之一就是发现设备内部拓扑,并在运行时配置它;硬件设备和内核接口会被建模为一张有方向的图。

所以一句话概括:

复制代码
Media Controller 是 Linux 用来描述和管理复杂多媒体硬件链路的框架。

二、Media Controller 到底是什么?

Media Controller 可以理解为摄像头系统中的 链路拓扑管理器

它不直接采集图像,也不直接处理图像,而是负责描述:

复制代码
系统中有哪些模块;
每个模块有哪些输入/输出端口;
这些模块之间怎么连接;
数据从哪里流向哪里。

它把整个摄像头系统抽象成一张图:

复制代码
[IMX415 Sensor] ---> [MIPI CSI2] ---> [ISP] ---> [/dev/video0]

在这张图里面,有三个最核心的概念:

entity,pad,link

可以这样类比:

复制代码
entity = 一个硬件模块
pad    = 模块上的输入/输出端口
link   = 两个端口之间的连接线

如果用电路图来类比:

复制代码
entity 像一个芯片;
pad 像芯片上的引脚;
link 像两个芯片引脚之间的连线。

三、entity:摄像头链路中的一个模块

entity 是 Media Controller 图中的一个节点。

比如:

复制代码
IMX415 Sensor 是一个 entity
MIPI CSI2 Receiver 是一个 entity
ISP 是一个 entity
Video Capture 也是一个 entity

在 IMX415 驱动中,sensor 对应的 V4L2 subdev 内部就带有一个 media entity:

复制代码
struct v4l2_subdev *sd = &imx415->subdev;

其中:

复制代码
sd->entity

就是这个 sensor 在 Media Controller 框架中的实体。

驱动里通常会设置:

复制代码
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;

这句话的意思是:

复制代码
告诉 Media Controller:
这个 entity 的功能是 camera sensor。

类似地,IMX219 驱动中也会把 sensor 设置为 MEDIA_ENT_F_CAM_SENSOR,并初始化一个 source pad,这说明这类 camera sensor 驱动都会把自己注册进 media graph 中。


四、pad:模块的输入/输出端口

只有 entity 还不够。因为一个模块可能有输入,也可能有输出。

比如 IMX415 是图像源头,它只往外输出 RAW 图像数据,所以它一般只有一个输出端口:

复制代码
imx415->pad.flags = MEDIA_PAD_FL_SOURCE;

这里的 MEDIA_PAD_FL_SOURCE 表示:

复制代码
这个 pad 是 source pad,也就是输出端口。

IMX415 可以画成:

复制代码
+----------------------+
|       IMX415         |
|                      |
|   pad0: SOURCE  -----|---->
+----------------------+

而 MIPI CSI2 Receiver 通常既有输入,也有输出:

复制代码
+--------------------------+
|      MIPI CSI2 RX        |
|                          |
|  ---> pad0: SINK         |
|       pad1: SOURCE  -----|---->
+--------------------------+

所以完整连接关系是:

复制代码
IMX415 source pad  --->  CSI2 receiver sink pad

Linux 官方文档中对 pad 的描述也很明确:pad 是 entity 与其他 entity 交互的连接端点,数据从 entity 的输出流向一个或多个输入。


五、link:两个 pad 之间的连接

link 表示两个 pad 之间的连接线。

比如:

复制代码
IMX415 pad0 source  --->  MIPI CSI2 pad0 sink

这就是一条 media link。

完整摄像头链路可以表示为:

复制代码
[IMX415 Sensor]
    pad0: source
        |
        | link
        v
[MIPI CSI2 Receiver]
    pad0: sink
    pad1: source
        |
        | link
        v
[ISP]
    pad0: sink
    pad1: source
        |
        | link
        v
[Video Capture]
    /dev/video0

Linux 文档中也说明,link 是两个 pad 之间有方向的点对点连接,数据从 source pad 流向 sink pad。

所以 entity、pad、link 三者关系可以总结为:

复制代码
entity 是模块;
pad 是模块的端口;
link 是端口之间的连接。
相关推荐
worilb1 小时前
Java/JVM 常见诊断文件对比
java·开发语言
ttwuai1 小时前
Go 后台初始化 MySQL 脚本失败怎么办?先查 DDL 还是生成配置
开发语言·mysql·golang
cpp_learner1 小时前
C++ 实现责任链模式(Chain of Responsibility):从一堆 if-else 到可插拔的处理管道
c++·设计模式
2601_962885721 小时前
如何用 Python 做 A 股全市场扫描选股?(多条件筛选实战)
开发语言·python
Discipline~Hai1 小时前
Linux网络编程03-HTTP协议
linux·运维·服务器·网络·网络协议·http·linux网络编程
奈斯先生Vector1 小时前
AIGC 视频生成换个拍法:用 Kling Video 把一张人物图变成可剪辑的短故事
开发语言·人工智能·windows·python·aigc·音视频
一木 之林1 小时前
五、C++ 新特性、关键字与编译原理(进阶)(一)
c语言·开发语言·c++
2601_962298272 小时前
交易开拓者通常使用什么编程语言?这种语言如何帮助自动化交易?
java·c++·python·编程语言·自动化交易
秋名RG2 小时前
Java IO 体系深度剖析:从流式编程到 JDK 21 高并发陷阱
java·开发语言
码匠许师傅2 小时前
【设计模式精讲】23.备忘录模式(Memento)
c++·设计模式·软件工程·uml·备忘录模式