📹 Linux V4L2子系统分析(一) - 系统概述
一、V4L2 子系统框架概述
V4L2(Video for Linux 2)是 Linux 内核提供的一套用于访问和控制视频设备的 API。其主要作用包括:
- 视频捕获(摄像头)
- 视频输出(显示)
- 视频控制(亮度/对比度等)
V4L2 支持设备:
- 摄像头(UVC)
- 电视卡
- 视频捕捉卡
1.1 子系统组成
📌 V4L2 Core(核心)
- 管理设备节点(/dev/videoX)
- 驱动与用户空间通信桥梁
- 管理缓冲区、数据流等
📌 视频设备驱动
- 向上实现标准 V4L2 接口
- 向下控制硬件
📌 用户空间接口
open()
read()
write()
ioctl()
等系统调用
📌 API 接口
v4l2_capability
:设备能力v4l2_format
:视频格式v4l2_buffer
:缓冲区管理v4l2_input
:输入源
1.2 核心组件
🧱 video_device
- 每个设备对应一个
video_device
结构体 - 描述能力、格式、操作函数、注册字符设备节点等
⚙ IOCTL 接口
- 使用
VIDIOC_*
系列宏与设备交互- 如:
VIDIOC_QUERYCAP
,VIDIOC_S_FMT
,VIDIOC_REQBUFS
- 如:
📦 缓冲区管理(Buffer Queue)
VIDIOC_REQBUFS
: 请求缓冲区VIDIOC_QBUF
: 入队VIDIOC_DQBUF
: 出队
支持方式:
- MMAP
- USERPTR
📽 视频流
- 视频帧采集/播放处理
- 格式/帧率可配置
🔄 异步机制
- 使用
select()
或poll()
监听数据到达 - 支持多路复用
1.3 关键数据结构
struct v4l2_capability
描述设备能力:
struct v4l2_capability {
__u8 driver[16];
__u8 card[32];
__u8 bus_info[32];
__u32 version;
__u32 capability;
__u32 device_caps;
__u32 reserved[4];
};
struct v4l2_format
配置视频格式:
struct v4l2_format {
__u32 type; // 视频类型(视频流、VBI等)
union {
struct v4l2_pix_format pix; // 视频帧格式
struct v4l2_vbi_format vbi;
struct v4l2_sliced_vbi_cap sliced;
} fmt;
};
struct v4l2_buffer
表示一个缓冲区:
struct v4l2_buffer {
__u32 index;
__u32 type;
__u32 bytesused;
__u32 flags;
__u32 field;
struct timeval timestamp;
struct v4l2_timecode timecode;
__u32 sequence;
__u32 memory; // MMAP/USERPTR
union {
__u32 offset;
unsigned long userptr;
struct v4l2_plane *planes;
} m;
};
struct v4l2_input
描述输入源:
struct v4l2_input {
__u32 index;
__u8 name[32];
__u32 type;
__u32 audioset;
__u32 capabilities;
__u32 reserved[4];
};
1.4 工作流程
📌 初始化
驱动注册:
- 创建
video_device
- 初始化操作接口
- 注册字符设备
/dev/videoX
📌 用户操作
应用通过如下方式交互:
int fd = open("/dev/video0", O_RDWR);
ioctl(fd, VIDIOC_QUERYCAP, ...);
ioctl(fd, VIDIOC_S_FMT, ...);
ioctl(fd, VIDIOC_REQBUFS, ...);
ioctl(fd, VIDIOC_QBUF, ...);
ioctl(fd, VIDIOC_STREAMON, ...);
📌 数据流处理
- 数据通过缓冲区从设备流入/流出
- 使用
DQBUF
读取帧,QBUF
重新投递
📌 异步事件
- 利用
select/poll
等等待事件发生 - 如数据可读、帧准备好
📌 清理资源
close(fd)
关闭设备,释放资源
1.5 应用场景
- 摄像头图像采集
- 视频会议捕捉与预览
- 视频监控图像流处理
- 视频流转码与播放
二、V4L2 系统框架图解说明
应用程序
│
└──> open/read/write/ioctl/poll
│
[字符设备节点] -> /dev/video0
│
video_device <--- 注册设备、操作函数
│
v4l2_dev <--- V4L2核心管理结构
│
┌───────┴─────────────┐
│ │
v4l2_fh v4l2_ctrl_handler
(文件句柄) (控制命令集)
│
v4l2_event <--- 事件通知机制(poll/wait)
│
Subdevs(如sensor、codec)
│
v4l2_subdev <--- 子设备抽象结构,处理 ISP、Sensor、Codec 等
三、核心模块简要说明
结构体 | 作用 |
---|---|
video_device | 视频设备主结构体,注册字符设备节点,提供操作接口 |
v4l2_device | V4L2 管理器,管理多个 subdev |
v4l2_subdev | 子设备(sensor、codec),通过 bus 与主设备通信 |
v4l2_fh | file handler,用于管理每个打开的文件句柄 |
v4l2_ctrl_handler | 控制器,用于管理亮度、对比度等控制命令 |
videobuf | V4L2 缓冲区管理工具(支持 mmap、read、userptr) |
四、缓冲区管理方式对比
模式 | 描述 |
---|---|
MMAP | 内核分配 buffer,并 mmap 到用户空间 |
USERPTR | 用户分配 buffer,通过指针传入 |
READ/WRITE | 简单的 read/write 调用,适合测试 |
📌 提示:使用 V4L2 调试工具如
v4l2-ctl
可帮助快速测试设备能力和格式设置。
v4l2-ctl --all
v4l2-ctl -d /dev/video0 --list-formats