Linux V4l2子系统分析1

Linux V4l2子系统分析1(基于Linux6.6)---系统概述

一、Linux V4L2(Video for Linux 2)子系统框架概述

V4L2(Video for Linux 2)是 Linux 内核中用于视频设备驱动程序的 API。它提供了一种标准的接口,使得应用程序能够访问视频捕获、播放、以及视频设备控制功能。V4L2 支持多种视频设备,包括摄像头、电视卡、视频捕捉卡等。V4L2 是 Linux 上视频设备的核心组成部分,尤其是对 UVC(USB Video Class)设备、数字视频设备等的支持。

1.1、V4L2 子系统的组成

V4L2 子系统在 Linux 内核中提供了从硬件到应用程序之间的标准化接口。它的核心组成包括以下几个部分:

  1. V4L2 核心(Core)

    • V4L2 核心是整个子系统的基础,提供了与视频设备的管理和控制有关的 API。
    • 负责管理设备节点、驱动程序与用户空间的交互,以及与视频设备的控制、数据流、缓冲区管理等。
  2. 视频设备驱动(Device Drivers)

    • 每个硬件设备都需要一个驱动程序来支持 V4L2 接口。驱动程序为设备提供具体的功能实现,例如视频捕获、视频播放、控制设置等。
    • 驱动程序通过实现 V4L2 定义的接口与 V4L2 核心进行交互,处理视频设备的操作。
  3. V4L2 用户空间接口

    • 用户空间通过标准的文件操作(如 open()read()write() 等)来与 V4L2 设备进行交互。
    • 应用程序可以使用 ioctl() 系统调用来进行设备控制、配置参数、获取视频流数据等操作。
  4. V4L2 API 接口

    • 提供给用户空间程序访问和控制视频设备的标准接口。
    • 包括各种函数和数据结构,如 v4l2_capabilityv4l2_formatv4l2_buffer 等,定义了设备的能力、格式设置、缓冲区管理等。

1.2、V4L2 核心组件

  1. 视频设备类(Video Device Class)

    • V4L2 定义了一个 video_device 结构体,表示一个视频设备。它包含设备的基本信息、能力、格式支持、输入输出方式等。
    • 每个视频设备都会有一个与之对应的 video_device 结构,驱动程序可以通过该结构来向用户空间提供设备信息。
  2. IOCTL 接口

    • V4L2 提供了一套丰富的 IOCTL 操作,允许用户空间与内核之间进行各种控制命令的交互。
    • 通过 ioctl(),应用程序可以控制视频设备的各种属性(如分辨率、帧率、亮度、对比度等)以及数据流的配置(如捕获模式、输出模式等)。
  3. 缓冲区管理(Buffer Management)

    • 视频捕获设备通常需要缓冲区来存储图像数据,V4L2 通过缓冲区队列管理机制来处理数据的传输。
    • V4L2 支持两种缓冲区管理模式:内存映射缓冲区(MMAP)用户指针缓冲区(User Pointer)
    • 这些缓冲区通常使用队列进行管理,可以通过 VIDIOC_QBUFVIDIOC_DQBUF 等 IOCTL 来进行缓冲区的排队和出队操作。
  4. 视频流(Video Streaming)

    • V4L2 支持视频流的传输,允许通过设备获取视频帧或者向设备提供视频帧。这些视频流可以通过捕获、回放等方式进行处理。
    • V4L2 规定了帧缓冲和流的格式,以确保视频流的正确性。
  5. 多路复用与异步(Select and Poll)

    • V4L2 还支持 select()poll() 等系统调用,用于实现异步操作,允许应用程序在等待视频设备数据时进行事件监听。
    • 通过这些机制,应用程序可以在多个设备上同时等待数据的到达,处理异步的输入输出。

1.3、V4L2 关键数据结构

  1. v4l2_capability

    • 描述了视频设备的能力信息,如支持的功能、设备类型(捕获、回放等)以及 API 版本。
  • struct v4l2_capability {
        __u8  driver[16];
        __u8  card[32];
        __u8  bus_info[32];
        __u32 version;
        __u32 capability;
        __u32 device_caps;
        __u32 reserved[4];
    };
    
  • v4l2_format

    • 用于设置或获取视频流的格式信息,如像素格式、图像宽度、高度等。
  • struct v4l2_format {
        __u32 type;
        union {
            struct v4l2_pix_format pix;
            struct v4l2_vbi_format vbi;
            struct v4l2_sliced_vbi_cap sliced;
        } fmt;
    };
    
  • v4l2_buffer

    • 表示一个视频缓冲区,包含缓冲区的地址、大小、状态等信息。
  • struct v4l2_buffer {
        __u32 index;
        __u32 type;
        __u32 bytesused;
        __u32 flags;
        __u32 field;
        __u32 timestamp;
        struct v4l2_timecode timecode;
        __u32 sequence;
        __u32 memory;
        union {
            __u32 offset;
            unsigned long userptr;
            struct v4l2_plane *planes;
        } m;
    };
    
  • v4l2_input

    • 用于表示视频输入端口(例如摄像头的不同输入源)。
  1. struct v4l2_input {
        __u32 index;
        __u8 name[32];
        __u32 type;
        __u32 audioset;
        __u32 capabilities;
        __u32 reserved[4];
    };
    

1.4、V4L2 子系统的工作流程

  1. 设备初始化

    • 驱动程序在初始化时,会注册设备并为其提供 video_device 结构,该结构包含了设备的信息和能力。
    • 驱动程序需要实现一些关键的接口,如打开、关闭、读写、IOCTL 操作等。
  2. 设备操作

    • 用户空间程序可以通过标准的文件操作接口打开设备,并使用 IOCTL 命令进行设备控制、设置格式、获取流数据等。
    • 数据传输一般使用缓冲区队列,通过 VIDIOC_QBUFVIDIOC_DQBUF 控制缓冲区的入队和出队。
  3. 异步处理

    • 应用程序可以使用 select()poll() 等异步机制,等待数据的到来或设备的响应。
  4. 清理与释放

    • 当设备不再使用时,应用程序会通过 close() 关闭设备并释放资源,驱动程序也会相应地释放与设备相关的资源。

1.5、V4L2 的常见应用

  • 摄像头应用:通过 V4L2 驱动和 API,应用程序可以访问和控制电脑或嵌入式设备上的摄像头,进行视频捕获。
  • 视频会议系统:通过 V4L2,视频会议软件可以捕捉视频流并进行显示或传输。
  • 视频监控:V4L2 可以用来管理和操作视频监控设备,处理实时视频流。
  • 视频流媒体:支持从视频源采集视频流,并通过 V4L2 播放或转码。

二、系统框架图

如下即为v4l2子系统框架,针对v4l2子系统而言,其主要通过字符设备节点与应用层交互:

  1. 通过字符设备文件,应用程序可通过字符设备文件完成与具体v4l2 device的通信;

而在v4l2子系统内部,则主要包括如下几方面的内容:

  1. video_device结构体用于创建v4l2 device对应的字符设备节点,该数据结构包含了指向v4l2-dev的指针、字符设备指针(struct cdev类型)、字符设备文件相关的操作接口指针、v4l2 control handler、v4l2_fh;
  2. v4l2_dev则是对一个v4l2_dev的抽象,该v4l2_dev管理该device下所有的子设备(即v4l2_subdev),若该v4l2_dev没有子设备,则v4l2_dev的作用应该不大,基本上针对没有子设备的v4l2,借助video_device操作,即可完成针对该v4l2_dev的访问操作(通过字符设备的读、写、ioctl接口即可);
  3. V4l2_subdev则代表一个v4l2 dev的子设备,针对一个v4l2 dev,可以完成各种任务操作,但通常他们负责音视频复用和编解码。如网络摄像头的子设备通常是传感器和摄像头控制器。 针对v4l2_subdev则提供了该子设备的操作接口等信息,可实现与子设备的通信操作;
  4. V4l2_fh则对应一个已打开的v4l2_dev字符设备file,可以理解为该打开字符设备file的handler,一般为该字符设备文件的私有v4l2_dev变量;通过v4l2_fh,可以使用v4l2子系统提供的v4l2 control handler以及v4l2 event相关机制;
  5. V4l2 event机制主要实现将v4l2 dev的触发事件发送给应用程序,主要借助poll 、wait机制实现。
  6. v4l2_ctrl_handler是v4l2设备控制方法集的结构体,可通过字符设备文件提供的ioctl接口访问对应的方法
  7. videobuff用于v4l2的buff操作,针对v4l2 device,主要有三种IO访问方法(read/write)、内存映射缓冲区(内核驱动申请缓存并mmap至应用层)、USERPTR(应用层负责分配内存空间,通过指针的形式传递给V4L2子系统驱动,V4L2 device driver会把捕获的内容保存至指针所指的空间)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值