【v4l2】Linux多媒体框架 - v4l2 core详解

发布时间 2023-04-01 20:27:18作者: -zx-

简介

V4L2是Video for linux2的简称,是Linux中关于视频设备的内核驱动框架。

常用结构体:

定义在include/linux/videodev2.h

struct v4l2_requestbuffers      // 申请帧缓冲,对应命令VIDIOC_REQBUFS
struct v4l2_capability          // 视频设备的功能,对应命令VIDIOC_QUERYCAP
struct v4l2_input               // 视频输入信息,对应命令VIDIOC_ENUMSTD
struct v4l2_standard            // 视频的制式,如PAL,NTSC,对应命令VIDIOC_ENUMSTD
struct v4l2_buffer              // 驱动中的一帧图像的缓存,对应命令VIDIC_QUERYBUF
struct v4l2_format              // 帧的格式,对应命令VIDIOC_G_FMT、VIDIOC_S_FMT等
struct v4l2_crop                // 视频信号矩形边框

接口:

V4L2规范中不仅定义了通用API元素(Common API Elements),图像的格式(Image Formats),输入/输出方法(Input/Output),还定义了Linux内核驱动处理视频信息的一系列接口:

Video Capture Interface : 视频采集接口,应用于摄像头
Video  Output Interface:视频输出接口,将静止图像或图像序列编码为模拟视频接口
Video overlay Interface : 视频覆盖/预览接口,可以将采集到的视频数据直接传输到显示设备,无需cpu参与,这种方式显示图像的效率比其他方式更高
Video Output Overlay Interface :视频输出覆盖接口
Codec Interface : 编解码接口

数据采集:

V4L2支持内存映射方式(mmap)和直接读取方式(read)来采集数据,欠着用于连续视频数据的采集,后者常用于静态图像数据的采集:

  • 帧传输:使用read和write方法,每一帧都要通过I/O操作在用户和内核空间之间拷贝数据
  • 流传输:用户与内核空间之间交换缓冲区指针,这些缓冲区将被映射到应用的地址空间

v4l2-core

V4L2是Linux内核中的关于视频设备驱动的框架,对上向应用层提供统一的接口,对下支持各类复杂硬件的灵活扩展;v4l2框架,主要包括v4l2-core、media framework,videobuf2等模块。

应用角度

从应用角度使用v4l2:

img

如果要进行视频数据采集,大致步骤如下:

1.打开设备文件/dev/videoX
2.根据打开的设备,查询设备能力集
3.设置视频数据的格式、参数等
4.分配buffer
5.开始视频流采集工作
6.将Buffer dequeue到v4l2框架
7.进程使用buffer块后,重新Buffer enqueue入队到v4l2框架

常见的硬件拓扑结构:

img

通常一个Camera的模组就是这样,包括镜头,感光元件,MIPI(CSI)接口,Soc的Mipi接口对应Camera模组传输视频数据,通过I2C/SPI传输控制数据配置Camera模组,Camera模组一般也会包含ISP(视频处理单元)对图像进行处理,有的Soc还会集成其他处理模块对camera的raw数据进行格式转换及缩放等图像处理。

数据结构

v4l2框架以v4l2_device和v4l2_subdev进行抽象,以v4l2_device代表整个输入设备,以v4l2_subdev代表子模块,比如CSI、Sensor等。

img

1.v4l2_device:对视频设备的整体进行抽象,可以看成是一个纽带,将各个子设备联系在一起,通常它会嵌入在其他结构体中以提供v4l2框架的功能;
2.v4l2_subdev:对子设备进行抽象,结构体中包含的struct v4l2_subdev_ops是一个完备的操作函数集,用于对接各种不同的子设备,比如video,audio,sensor等,同时还有一个核心的函数集struct v4l2_subdev_core_ops,提供更通用的功能。子设备驱动根据设备特点实现该函数集的某些函数即可
3.video_device:用于向系统注册字符设备节点,以便用户空间可以进行交互,各类设置以及数据Buffer的获取等,在该结构体中能看到struct v4l2_ioctl_ops和struct vb2_queue结构体字段,这些与上文中的应用层代码相关。video_device可以内嵌在其他结构体中,以便提供与用户层交互的功能

流程分析

内部注册及调用流程如下:

img

1.在驱动的实现中,驱动结构体中内嵌struct video_device,同时实现struct v4l2_file_operations结构体中的函数,最终通过video_register_device向应用层提供注册
2.v4l2_register_device函数通过cdev_add向系统注册字符设备,并指定了file_operation,用户空间调用open/read/write/ioctl等接口,便可回调到驱动实现中;
3.v4l2_register_device函数中,通过device_register向系统注册设备,会在/sys文件系统下创建节点;

完成注册后,用户空间可通过文件描述符进行访问,从应用层看,大部分都是通过ioctl接口来完成,流程如下:

img

用户层的ioctl回调到__video_do_ioctl,该函数会对系统提供的strauct v4l2_ioctl_info v4l2_ioctls[]表进行查询,找到对应的项后进行调用;驱动做的工作就是填空题,实现对应的回调,在合适的时候被调用;













参考文章:

https://www.cnblogs.com/LoyenWang/p/15456230.html