1. V4L2概述:架构、定位与设备节点

V4L2(Video for Linux 2)是 Linux 内核中用于视频设备捕获、输出和处理的统一接口框架。自 Linux 2.6 内核起成为标准视频子系统,广泛应用于摄像头、电视调谐器、视频采集卡等设备。理解 V4L2 的架构层次、在多媒体栈中的位置以及设备节点管理方式,是掌握帧采集机制的基础。

1.1 V4L2 架构分层

V4L2 采用分层设计,从上到下依次为:用户空间应用层、系统调用层、V4L2 核心层、设备驱动层。每一层职责清晰,通过标准接口解耦。

架构要点:用户空间通过 open/ioctl/mmap/poll/close 等 POSIX 系统调用与 V4L2 交互;核心层负责设备注册、ioctl 分发、缓冲区管理;驱动层实现硬件操作。
V4L2 分层架构图 V4L2 分层架构 用户空间应用层 应用程序(GStreamer、FFmpeg、自定义采集程序) 系统调用层 open / ioctl / mmap / poll / close V4L2 核心层 设备注册 / ioctl 分发 / 缓冲区管理 / 事件通知 设备驱动层 硬件操作 / 中断处理 / DMA 传输

1.2 V4L2 在 Linux 多媒体框架中的位置

Linux 多媒体生态包含多个子系统,V4L2 处于底层硬件抽象与上层多媒体框架之间。下表列出主要多媒体组件及其与 V4L2 的关系:

层次 组件 与 V4L2 的关系
应用层 GStreamer、FFmpeg、OpenCV 通过 V4L2 插件/源码驱动访问摄像头
中间层 libv4l2、libv4lconvert 封装 V4L2 ioctl,提供格式转换、裁剪等辅助功能
内核层 V4L2 核心 + videobuf2 提供统一的视频缓冲区管理框架
硬件层 Camera sensor、ISP、USB Video Class 通过 V4L2 驱动注册到内核
提示:V4L2 不仅支持视频捕获(CAPTURE),还支持输出(OUTPUT)、覆盖(OVERLAY)、调谐器(TUNER)等类型。本课程聚焦 CAPTURE 类型的帧采集。
V4L2 在 Linux 多媒体框架中的位置 V4L2 在 Linux 多媒体框架中的位置 应用层 GStreamer · FFmpeg · OpenCV · 自定义采集程序 中间层 libv4l2 · libv4lconvert · libv4l2rds 内核层 V4L2 核心 · videobuf2 · V4L2 设备驱动 硬件层 Camera Sensor · ISP · USB Camera · 采集卡

1.3 V4L2 设备节点

V4L2 设备在用户空间以字符设备节点形式呈现,通常位于 /dev 目录下。主设备号为 81,次设备号标识具体设备类型和实例。

常见设备节点类型

设备节点 类型 主设备号 次设备号范围 典型用途
/dev/video0 视频捕获/输出 81 0–63 摄像头、采集卡
/dev/vbi0 VBI 数据 81 224–255 电视图文、隐藏字幕
/dev/radio0 无线电调谐器 81 64–127 FM/AM 收音
/dev/swradio0 软件无线电 81 192–223 SDR 接收
注意:并非所有 /dev/video* 节点都是 V4L2 设备。部分显卡驱动(如 NVIDIA、AMD)也会注册 video 节点,但使用 DRM/V4L2 混合接口。可通过 v4l2-ctl --list-devices 确认设备类型。

设备节点发现与验证

在嵌入式开发板上,常用以下命令查看 V4L2 设备:

# 列出所有 V4L2 设备
v4l2-ctl --list-devices

# 查看指定设备的能力
v4l2-ctl -d /dev/video0 --all

# 查看设备支持的格式
v4l2-ctl -d /dev/video0 --list-formats

# 查看设备支持的帧尺寸
v4l2-ctl -d /dev/video0 --list-framesizes=YUYV

设备节点生命周期

V4L2 设备节点的创建与销毁由内核自动管理,遵循以下流程:

  1. 驱动加载:硬件插入或驱动模块加载时,驱动调用 video_register_device() 注册设备。
  2. 节点创建:内核在 /dev 下创建对应字符设备节点,并关联 file_operations 结构。
  3. 应用打开:用户程序调用 open("/dev/video0", O_RDWR) 获取文件描述符。
  4. IO 操作:通过 ioctl/mmap/poll 进行帧采集控制。
  5. 应用关闭:调用 close() 释放文件描述符。
  6. 驱动卸载:调用 video_unregister_device() 移除节点。
V4L2 设备节点生命周期 V4L2 设备节点生命周期 驱动加载 video_register_device() 节点创建 /dev/video0 生成 应用打开 open() 获取 fd IO 操作 ioctl / mmap / poll 应用关闭 close() 释放 fd 驱动卸载 → video_unregister_device()

1.4 核心数据结构与 ioctl 体系

V4L2 通过一组标准数据结构描述设备能力、格式、缓冲区等。以下是最常用的几个结构体:

结构体 用途 关键字段
struct v4l2_capability 查询设备能力 driver, card, bus_info, capabilities
struct v4l2_format 设置/获取图像格式 type, fmt.pix.width, height, pixelformat
struct v4l2_requestbuffers 申请缓冲区 count, type, memory
struct v4l2_buffer 描述单个缓冲区 index, bytesused, flags, timestamp
struct v4l2_plane 多平面缓冲区描述 bytesused, length, data_offset

对应的 ioctl 命令遵循 VIDIOC_* 命名规范,例如:

VIDIOC_QUERYCAP      // 查询设备能力
VIDIOC_S_FMT         // 设置格式
VIDIOC_REQBUFS       // 申请缓冲区
VIDIOC_QUERYBUF      // 查询缓冲区信息(用于 mmap)
VIDIOC_QBUF          // 入队缓冲区
VIDIOC_DQBUF         // 出队缓冲区
VIDIOC_STREAMON      // 启动流
VIDIOC_STREAMOFF     // 停止流
关键理解:V4L2 的帧采集本质上是“申请缓冲区 → 入队 → 启动流 → 出队(获取帧)→ 处理 → 再入队”的循环。mmap 用于建立用户空间与内核缓冲区的共享映射,poll 用于等待帧就绪事件。

1.5 本章小结

  • V4L2 是 Linux 视频设备的标准内核框架,采用四层架构:应用层 → 系统调用层 → V4L2 核心层 → 驱动层。
  • 在多媒体栈中,V4L2 位于内核层,向上通过 libv4l2 服务 GStreamer/FFmpeg 等框架,向下对接各类视频硬件。
  • 设备节点为 /dev/video*,主设备号 81,通过 v4l2-ctl 工具可快速验证设备能力。
  • 核心 ioctl 命令和数据结构构成了帧采集的编程基础,后续章节将逐一深入。