v4l2驱动框架简介
-
简介
v4l2全称是video for linux version2,是linux系统中的视频驱动框架,包括视频输入(如摄像头),视频输出(如VGA输出等),视频编解码等等数据流管理功能;本章节主要针对视频输入设备(如摄像头); -
摄像头数据流
摄像头数据从内核空间(驱动)传输到用户空间(APP)主要有两种方法:
a:通过数据拷贝的方式,用户空间通过read系统调用进入内核空间,内核空间驱动通过v4l2_file_operations->read
读函数里调用copy_to_user
函数将视频数据拷贝到用户空间,这种方法效率低下,对于图像视频这种数据量大的不是特别适合;
b:通过指针传递的方式;用户空间和内核空间之间通过数据指针进行数据传递,用户空间把处理好的视频帧指针传递内内核驱动,内核把采集的数据写到内存buffer中并返回新的buffer指针给用户空间;这种效率高,适合视频这种大数据量传输;该方法实现有两种:
①buffer内存在用户空间申请,用户空间把申请好的buffer指针传递给内核驱动层;
②buffer内存在内核空间申请,用户空间通过mmap
函数内存映射获取到buffer指针;
上图为摄像头数据流向示意图;v4l2驱动中会维护queue_list
和done_list
两个存储buffer指针的队列;
①用户空间app端会向内核申请已经写入新数据的buffer,内核空间驱动从done_list
队列中返回buffer指针;
②app得到buffer数据进行处理,处理完成后将buffer提交给内核,内核将app提交的buffer添加到queue_list
队列中;
③内核驱动从queue_list
队列中取出空闲的buffer,并写入最新的视频数据,当一帧数据更新完后,将该buffer加入到 done_list
队列中等待app获取;
-
v4l2驱动框架
通常处理器controler和subdev子设备的代码是分开的,比如摄像头驱动,cpu端camera controler部分的代码是芯片原厂实现,摄像头控制部分的代码是摄像头原厂提供,以子设备的形式注册到内核;
camera controler部分的代码其功能一般包括图像数据的采集、图像buffer管理以及子设备的管理和media数据通路管理等;子设备部分负责该子设备的设置,以及提供函数接口给camera controler端使用;
camera controler端主要抽象的结构体:
v4l2_device
:用于整个v4l2驱动的统筹管理的,包括子设备(可以由多个)、media framwork等等;
video_device
:用于生成设备节点(/dev/videoX),给用户提供操作接口,如查询/设置参数、获取buffer数据、向内核提交处理好的buffer等等;
vb2_queue
:提供一套完整的视频buffer的管理功能,包括buffer的申请,buffer在内核和用户空间之间的切换等等;
v4l2_async_notifier
:用于子设备的异步注册,subdev子设备的注册通常和controler部分设备的注册时分开的,controler部分需要通过v4l2_async_notifier
查找匹配子设备并将其注册到v4l2_device
进行统一管理;其匹配规则可以通过设备名称、自定义函数、i2c设备等;
media_device
:该结构体主要用于数据通道的控制,复杂的v4l2设备驱动可能有很多功能各异的子设备,数据流的流向控制可以通过media framwork进行控制;subdev子设备端主要抽象的结构体:
v4l2_subdev
:子设备抽象结构体,提供子设备的基本参数设置及函数接口;
v4l2_ctrl_handler
:主要用于注册子设备的ioctl(VIDIOC_G_CTRL/VIDIOC_S_CTRL)控制命令,如设置亮度等;
该节值只是简单的介绍一下v4l2驱动框架的数据流及其主要的抽象结构体的功能,后续有时间会进行展开;
更多推荐
所有评论(0)