【IPC】V4L2 数据结构详解

目录

一、前言

二、核心数据结构体

[1. struct v4l2_capability](#1. struct v4l2_capability)

[2. struct v4l2_format](#2. struct v4l2_format)

[子结构:struct v4l2_pix_format](#子结构:struct v4l2_pix_format)

[3. struct v4l2_requestbuffers](#3. struct v4l2_requestbuffers)

[4. struct v4l2_buffer](#4. struct v4l2_buffer)

[5. struct v4l2_control / struct v4l2_ext_controls](#5. struct v4l2_control / struct v4l2_ext_controls)

[6.struct v4l2_fmtdesc](#6.struct v4l2_fmtdesc)

[7.struct v4l2_frmsizeenum / struct v4l2_frmivalenum](#7.struct v4l2_frmsizeenum / struct v4l2_frmivalenum)

三、核心枚举类型

[1. enum v4l2_buf_type](#1. enum v4l2_buf_type)

[注意:单平面 vs 多平面格式需匹配正确类型!](#注意:单平面 vs 多平面格式需匹配正确类型!)

[2. enum v4l2_memory](#2. enum v4l2_memory)

[3. enum v4l2_field](#3. enum v4l2_field)

[建议:IPC 摄像头基本都是逐行,设为 V4L2_FIELD_NONE。](#建议:IPC 摄像头基本都是逐行,设为 V4L2_FIELD_NONE。)

[4. enum v4l2_colorspace](#4. enum v4l2_colorspace)

[5. 像素格式枚举(__u32 pixelformat)](#5. 像素格式枚举(__u32 pixelformat))

[6. 控制 ID 枚举(V4L2_CID_*)](#6. 控制 ID 枚举(V4L2_CID_*))

[四、核心 VIDIOC_* 命令详解](#四、核心 VIDIOC_* 命令详解)

[五、ioctl 方向说明](#五、ioctl 方向说明)


一、前言

V4L2(Video for Linux 2)通过一组精心设计的 ioctl 命令配套的数据结构/枚举类型,实现了对视频采集设备的统一抽象。

二、核心数据结构体

1. struct v4l2_capability

作用:查询设备基本信息和能力(只读)

cpp 复制代码
struct v4l2_capability {
    __u8  driver[16];      // 驱动名称(如 "uvcvideo")
    __u8  card[32];        // 设备名(如 "USB Camera: USB Camera")
    __u8  bus_info[32];    // 总线信息(如 "usb-0000:00:14.0-1")
    __u32 version;         // 驱动版本(主<<16 | 次<<8 | 修订)
    __u32 capabilities;    // 设备支持的功能位掩码
    __u32 device_caps;     // 当前设备节点的具体能力(Linux 3.1+)
    __u32 reserved[3];
};

关键字段说明

  • capabilities:常用标志位包括:

    • V4L2_CAP_VIDEO_CAPTURE:支持视频采集(IPC 必需)
    • V4L2_CAP_STREAMING:支持流式 I/O(mmap/userptr)
    • V4L2_CAP_READWRITE:支持 read/write 接口(性能差,不推荐)
  • 使用方式

    cpp 复制代码
    struct v4l2_capability cap;
    ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        fprintf(stderr, "Not a capture device!\n");
    }

2. struct v4l2_format

作用:设置或获取视频格式(分辨率、像素格式等)

cpp 复制代码
struct v4l2_format {
    enum v4l2_buf_type type; // 缓冲区类型(如 V4L2_BUF_TYPE_VIDEO_CAPTURE)
    union {
        struct v4l2_pix_format         pix;     // 用于视频帧
        struct v4l2_pix_format_mplane  pix_mp;  // 多平面格式(如 NV12)
        struct v4l2_window             win;     // Overlay 输出(已弃用)
        struct v4l2_vbi_format         vbi;     // 垂直消隐期数据
        struct v4l2_sliced_vbi_format  sliced;  // 切片 VBI
        __u8 raw_data[200];                     // 原始数据
    };
};
子结构:struct v4l2_pix_format
cpp 复制代码
struct v4l2_pix_format {
    __u32          width;        // 图像宽度(像素)
    __u32          height;       // 图像高度(像素)
    __u32          pixelformat;  // 像素格式(四字符编码,如 'YUYV')
    __u32          field;        // 场序(逐行/隔行)
    __u32          bytesperline; // 每行字节数(可为 0 表示由驱动计算)
    __u32          sizeimage;    // 单帧图像总大小(字节)
    __u32          colorspace;   // 色彩空间(如 sRGB、Rec.709)
    __u32          priv;         // 私有数据(已弃用,改用 flags)
    __u32          flags;        // 格式标志(如 V4L2_PIX_FMT_FLAG_PREMUL_ALPHA)
};


##
IPC 开发注意:
设置后务必检查返回值!驱动可能调整 width/height/sizeimage。
bytesperline 若设为 0,驱动会自动对齐(通常按 16 字节对齐)。

3. struct v4l2_requestbuffers

作用:请求内核分配缓冲区队列

cpp 复制代码
struct v4l2_requestbuffers {
    __u32                     count;    // 请求的缓冲区数量(≥2)
    enum v4l2_buf_type        type;     // 缓冲区类型
    enum v4l2_memory          memory;   // 内存类型(mmap / userptr / dmabuf)
    __u32                     reserved[2];
};

关键点

  • count:通常设为 3~8。太少易丢帧,太多增加延迟。
  • memory:IPC 最常用 V4L2_MEMORY_MMAP(零拷贝)。

4. struct v4l2_buffer

作用:描述单个缓冲区的状态(入队/出队/元数据)

cpp 复制代码
struct v4l2_buffer {
    __u32                    index;        // 缓冲区索引(0 ~ count-1)
    enum v4l2_buf_type       type;         // 类型
    __u32                    bytesused;    // 实际数据字节数(关键!)
    __u32                    flags;        // 状态标志(如时间戳有效性)
    enum v4l2_field          field;        // 场信息
    struct timeval           timestamp;    // 帧捕获时间戳
    struct v4l2_timecode     timecode;     // 时间码(专业视频)
    __u32                    sequence;     // 帧序号(从0开始递增)
    enum v4l2_memory         memory;       // 内存类型
    union {
        __u32                offset;       // mmap 偏移量
        unsigned long        userptr;     // 用户指针地址
        struct v4l2_plane    *planes;     // 多平面指针
        __s32                fd;           // dma-buf 文件描述符
    } m;
    __u32                    length;       // 缓冲区总大小(字节)
    __u32                    reserved2;
    __u32                    reserved;
};

IPC 关键字段

  • index:标识是哪个缓冲区(对应 mmap 映射数组)
  • bytesused实际帧大小(对 MJPEG/H.264 至关重要)
  • timestamp:用于计算帧率、同步
  • sequence:检测丢帧(应连续递增)

5. struct v4l2_control / struct v4l2_ext_controls

作用:控制摄像头参数(曝光、增益、白平衡等)

cpp 复制代码
struct v4l2_control {
    __u32 id;    // 控制 ID(如 V4L2_CID_BRIGHTNESS)
    __s32 value; // 控制值
};

// 批量控制(推荐)
struct v4l2_ext_controls {
    __u32 ctrl_class;     // 控制类别(如 V4L2_CTRL_CLASS_CAMERA)
    __u32 count;          // 控制项数量
    __u32 error_idx;      // 出错项索引
    __u32 reserved[2];
    struct v4l2_ext_control *controls; // 控制数组
};

struct v4l2_ext_control {
    __u32 id;
    __u32 size;           // 用于字符串控件
    __u32 reserved2[1];
    union {
        __s32 value;               // 整数值
        __s64 value64;             // 64位值
        char *string;              // 字符串(如 camera name)
        __u8 *p_u8;                // 8位数组
        __u16 *p_u16;              // 16位数组
        __u32 *p_u32;              // 32位数组
        void *ptr;                 // 通用指针
    };
};

IPC 常用控制 ID

  • V4L2_CID_EXPOSURE_AUTO:自动曝光开关
  • V4L2_CID_EXPOSURE:手动曝光值
  • V4L2_CID_GAIN:模拟增益
  • V4L2_CID_WHITE_BALANCE_TEMPERATURE:色温(K)

6.struct v4l2_fmtdesc

作用:枚举设备支持的所有像素格式

cpp 复制代码
struct v4l2_fmtdesc {
    __u32 index;              // 格式索引(从0开始)
    enum v4l2_buf_type type;  // 类型
    __u32 flags;              // 格式标志(如压缩)
    __u8 description[32];     // 格式描述字符串
    __u32 pixelformat;        // 像素格式 FourCC
    __u32 reserved[4];
};

用法

cpp 复制代码
struct v4l2_fmtdesc fmtdesc = {0};
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
for (fmtdesc.index = 0; ; fmtdesc.index++) {
    if (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) break;
    printf("Format %d: %.4s (%s)\n", fmtdesc.index,
           (char*)&fmtdesc.pixelformat, fmtdesc.description);
}

7.struct v4l2_frmsizeenum / struct v4l2_frmivalenum

作用:枚举某格式支持的分辨率和帧率

cpp 复制代码
// 查询分辨率
struct v4l2_frmsizeenum fsize = {0};
fsize.pixel_format = V4L2_PIX_FMT_YUYV;
for (fsize.index = 0; ; fsize.index++) {
    if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fsize) < 0) break;
    if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
        printf("Resolution: %dx%d\n", fsize.discrete.width, fsize.discrete.height);
    }
}

// 查询帧率(需先指定分辨率)
struct v4l2_frmivalenum fival = {0};
fival.pixel_format = V4L2_PIX_FMT_YUYV;
fival.width = 640; fival.height = 480;
for (fival.index = 0; ; fival.index++) {
    if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) < 0) break;
    if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
        printf("FPS: %d/%d = %.2f\n",
               fival.discrete.denominator, fival.discrete.numerator,
               (double)fival.discrete.denominator / fival.discrete.numerator);
    }
}

8.struct v4l2_queryctrl

作用:查询 control 能力的 ioctl 命令

cpp 复制代码
struct v4l2_queryctrl {
    __u32  id;               // 控制ID(如 V4L2_CID_BRIGHTNESS)
    __u32  type;             // 控制类型(见下表)
    __u8   name[32];         // 控制名称(如 "Brightness")
    __s32  minimum;          // 最小值
    __s32  maximum;          // 最大值
    __s32  step;             // 步长
    __s32  default_value;    // 默认值
    __u32  flags;            // 标志(如 disabled)
    __u32  reserved[2];
};

三、核心枚举类型

1. enum v4l2_buf_type

作用:指定缓冲区用途类型

枚举值 说明
V4L2_BUF_TYPE_VIDEO_CAPTURE 视频采集(IPC 主要用此)
V4L2_BUF_TYPE_VIDEO_OUTPUT 视频输出(如 HDMI 输出)
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE 多平面采集(如 NV12 分 Y/UV 平面)
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE 多平面输出

注意:单平面 vs 多平面格式需匹配正确类型!

2. enum v4l2_memory

作用:指定缓冲区内存管理方式

枚举值 说明 IPC 适用性
V4L2_MEMORY_MMAP 内核分配,用户 mmap 映射 最常用,零拷贝
V4L2_MEMORY_USERPTR 用户分配内存,传指针给驱动 需物理连续内存(ARM 通常不可用)
V4L2_MEMORY_DMABUF 使用 dma-buf 共享缓冲区 适用于多进程/硬件加速(如 GPU/NPU)

3. enum v4l2_field

作用:指定视频场序(逐行 or 隔行)

枚举值 说明
V4L2_FIELD_NONE 逐行扫描(IPC 绝大多数用此)
V4L2_FIELD_INTERLACED 隔行扫描(先顶场后底场)
V4L2_FIELD_TOP / V4L2_FIELD_BOTTOM 单一场

建议 :IPC 摄像头基本都是逐行,设为 V4L2_FIELD_NONE

4. enum v4l2_colorspace

作用:定义色彩空间标准

枚举值 说明
V4L2_COLORSPACE_SRGB sRGB(普通摄像头)
V4L2_COLORSPACE_REC709 HDTV(Rec.709)
V4L2_COLORSPACE_JPEG Full-range YUV(0-255)
V4L2_COLORSPACE_SMPTE170M SDTV(NTSC/PAL)

注意 :错误的色彩空间会导致颜色失真!通常摄像头默认为 V4L2_COLORSPACE_SRGBV4L2_COLORSPACE_JPEG

5. 像素格式枚举(__u32 pixelformat

虽然不是 C 枚举,但以宏形式定义,本质是四字符编码(FourCC):

FourCC 说明
V4L2_PIX_FMT_YUYV 'YUYV' YUV 4:2:2 packed(最通用)
V4L2_PIX_FMT_UYVY 'UYVY' 同上,UV 顺序不同
V4L2_PIX_FMT_MJPEG 'MJPG' Motion JPEG(压缩流)
V4L2_PIX_FMT_H264 'H264' H.264 码流(需硬件编码器)
V4L2_PIX_FMT_RGB24 'RGB3' 24-bit RGB(低效,慎用)
V4L2_PIX_FMT_GREY 'GREY' 8-bit 灰度图
V4L2_PIX_FMT_SRGGB8 'RGGB' Bayer RAW 格式(R-G-G-B 排列)
V4L2_PIX_FMT_NV12 'NV12' YUV 4:2:0 planar(Y 平面 + UV interleaved)

IPC 提示

  • UVC 摄像头常用 YUYVMJPEG
  • SoC ISP 输出常用 NV12(节省带宽)
  • AI 推理常需 RGBGRAY,需软件转换

6. 控制 ID 枚举(V4L2_CID_*

部分常用控制 ID:

控制 ID 类型 说明
V4L2_CID_BRIGHTNESS integer 亮度
V4L2_CID_CONTRAST integer 对比度
V4L2_CID_SATURATION integer 饱和度
V4L2_CID_HUE integer 色调
V4L2_CID_AUTO_WHITE_BALANCE boolean 自动白平衡开关
V4L2_CID_WHITE_BALANCE_TEMPERATURE integer 色温(单位:K)
V4L2_CID_EXPOSURE_AUTO menu 自动曝光模式
V4L2_CID_EXPOSURE integer 手动曝光时间(单位依赖驱动)
V4L2_CID_GAIN integer 模拟增益
V4L2_CID_ZOOM_ABSOLUTE integer 数字变焦

查询控制范围

cpp 复制代码
struct v4l2_queryctrl qctrl = {.id = V4L2_CID_EXPOSURE};
ioctl(fd, VIDIOC_QUERYCTRL, &qctrl);
printf("Exposure: min=%d, max=%d, step=%d\n", qctrl.minimum, qctrl.maximum, qctrl.step);

四、核心 VIDIOC_* 命令详解

V4L2(Video for Linux 2)框架中用于 ioctl 系统调用的命令标识符(ioctl command codes)

每个 VIDIOC_XXX 对应一个唯一的整数,用于告诉内核:"我要执行 XXX 操作"。

  • 命名规则VIDIOC = V ideo I/O Control
  • 用途 :用户空间程序通过 ioctl(fd, VIDIOC_XXX, &arg) 与 V4L2 驱动通信。
  • 本质 :是一组预定义的宏(#define),由内核提供。
  • 位置 :所有 VIDIOC_* 宏均定义在 Linux 内核头文件中:#include <linux/videodev2.h>
宏名称 全称 / 含义 ioctl 方向 参数类型 主要作用 使用阶段
VIDIOC_QUERYCAP QUERY CAPability _IOR(只读) struct v4l2_capability* 查询设备基本信息和能力(是否支持 capture/streaming 等) 初始化
VIDIOC_S_FMT S et FMT (format) _IOWR(读写) struct v4l2_format* 设置视频格式(分辨率、像素格式、场序等) 初始化
VIDIOC_G_FMT G et FMT _IOR struct v4l2_format* 获取当前视频格式 调试/初始化
VIDIOC_TRY_FMT TRY FMT _IOWR struct v4l2_format* 测试格式是否支持(不实际设置) 初始化前验证
VIDIOC_REQBUFS REQ uest BUF ferS _IOWR struct v4l2_requestbuffers* 请求内核分配缓冲区队列(mmap/userptr) 缓冲区准备
VIDIOC_QUERYBUF QUERY BUFfer _IOWR struct v4l2_buffer* 查询缓冲区元数据(如 offset、length),用于 mmap 缓冲区映射
VIDIOC_QBUF Q ueue BUFfer _IOW struct v4l2_buffer* 将空缓冲区入队,交给驱动填充 流启动后循环使用
VIDIOC_DQBUF D eQ ueue BUFfer _IOWR struct v4l2_buffer* 出队已填充的帧缓冲区 主采集循环
VIDIOC_STREAMON STREAM ON _IOW enum v4l2_buf_type* 启动视频流(开始 DMA 传输) 流控制
VIDIOC_STREAMOFF STREAM OFF _IOW enum v4l2_buf_type* 停止视频流(停止 DMA) 流控制 / 退出
VIDIOC_QUERYCTRL QUERY CTRL (control) _IOWR struct v4l2_queryctrl* 查询某个 control(如曝光、增益)的能力信息(范围、类型、是否禁用) 控制参数配置
VIDIOC_G_CTRL G et CTRL _IOWR struct v4l2_control* 获取单个 control 的当前值 控制读取
VIDIOC_S_CTRL S et CTRL _IOWR struct v4l2_control* 设置单个 control 的值 控制写入
VIDIOC_G_EXT_CTRLS G et EXT ended CTRLS _IOWR struct v4l2_ext_controls* 批量获取 controls 值(推荐) 高级控制
VIDIOC_S_EXT_CTRLS S et EXT ended CTRLS _IOWR struct v4l2_ext_controls* 批量设置 controls 值(推荐) 高级控制
VIDIOC_ENUM_FMT ENUM erate FMT _IOWR struct v4l2_fmtdesc* 枚举设备支持的所有像素格式 调试 / 自适应
VIDIOC_ENUM_FRAMESIZES ENUM erate FRAME SIZES _IOWR struct v4l2_frmsizeenum* 枚举某格式支持的分辨率 调试
VIDIOC_ENUM_FRAMEINTERVALS ENUM erate FRAME INTERVALS _IOWR struct v4l2_frmivalenum* 枚举某分辨率下的帧率 调试

五、ioctl 方向说明

1.位置:(来自 <asm/ioctl.h>

  • _IO(type, nr):无数据传递
  • _IOR(type, nr, data_type)从内核读取数据到用户空间(Read)
  • _IOW(type, nr, data_type)向内核写入数据(Write)
  • _IOWR(type, nr, data_type)先写入再读出(Write-Read),最常见

2、实例:

cpp 复制代码
// VIDIOC_QUERYCAP 是只读:内核填写 capability 结构体返回给用户
#define VIDIOC_QUERYCAP     _IOR('V',  0, struct v4l2_capability)

// VIDIOC_S_FMT 是读写:用户传入期望格式,内核返回实际生效格式
#define VIDIOC_S_FMT        _IOWR('V',  5, struct v4l2_format)
相关推荐
CQ_YM19 天前
Linux管道通信
linux·c语言·管道·ipc·管道通信
加勒比之杰克21 天前
【操作系统原理】进程间通信之管道
网络·管道·ipc
metaRTC1 个月前
webRTC IPC客户端UniApp版编程指南
uni-app·webrtc·ipc
赖small强1 个月前
【音视频开发】Linux V4L2 零拷贝 (Zero-Copy) 机制深度解析
v4l2·dma-buf·zero-copy·dma-fd
赖small强1 个月前
【音视频开发】Linux UVC (USB Video Class) 驱动框架深度解析
linux·音视频·v4l2·uvc
赖small强1 个月前
【音视频开发】Linux V4L2 (Video for Linux 2) 驱动框架深度解析白皮书
linux·音视频·v4l2·设备节点管理·视频缓冲队列·videobuf2
赖small强1 个月前
【音视频开发】CMOS Sensor图像采集原理及Linux主控ISP处理流程
linux·音视频·cmos·isp·v4l2
chen_zn952 个月前
V4L2框架介绍
linux·usb·摄像头·v4l2·视频设备
metaRTC2 个月前
webRTC IPC客户端Flutter版编程指南
flutter·webrtc·ipc