搭建一个和linux开发者知识共享和学习的平台
分类: 嵌入式
2022-09-30 14:21:46
按照V4L2标准,将一个数据流设备抽象成一个videoX节点,从属的子设备对应着各自的v4l2_subdev实现,并通过media controller进行统一管理。
a) 打开video设备
在需要进行视频数据流的操作之前,首先要通过标准的字符设备操作接口open方法来打开一个video设备,并且将返回的字符设备句柄存在本地,之后一系列操作都是基于该句柄。
b) 查看并设置设备
在打开设备获取文件句柄之后,就需要查询设备的属性,该动作主要通过ioctl传入VIDIOC_QUERYCAP参数来完成,其中该系列属性通过v4l2_capability结构体来表达,除此之外还可以通过传入VIDIOC_ENUM_FMT来枚举支持的数据格式,通过传入VIDIOC_G_FMT/VIDIOC_S_FMT来分别获取和设置当前的数据格式,通过VIDIOC_G_PARM/VIDIOC_S_PARM来分别获取和设置参数。
c) 申请帧缓冲区
完成设备的配置后,便可以开始向设备申请多个用于盛装图像数据的帧缓冲区,该动作通过调用ioctl并且传入VIDIOC_REQBUFS命令来完成,{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}最佳佳佳佳佳佳佳佳后将缓冲区通过mmap方式映射到用户空间。
d) 将帧缓冲区入队
申请好帧缓冲区之后,通过调用ioctl方法传入VIDIOC_QBUF命令将帧缓冲区加入到v4l2框架中的缓冲区队列中,静等硬件模块将图像数据填充到缓冲区中。
e) 开启数据流
将所有的缓冲区加入队列中之后便可以调用ioctl并且传入VIDIOC_STREAMON命令,来通知整个框架开始进行数据传输,其中大致包括了通知各个子设备开始进行工作,{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}{BANNED}最佳佳佳佳佳佳佳佳终将数据填充到V4L2框架中的缓冲区队列中。
f) 将帧缓冲区出队
一旦数据开始进行流转了,我们就可以通过调用ioctl下发VIDIOC_DQBUF命令来获取帧缓冲区,并且将缓冲区的图像数据取出,进行预览、拍照或者录像的处理,处理完成之后,需要将此次缓冲区再次放入V4L2框架中的队列中等待下次的图像数据的填充。
v4l2_device作为顶层管理者,一方面通过嵌入到一个video_device中,提供video设备节点给用户空间进行控制,另一方面,video_device内部会创建一个media_entity作为在media controller中的抽象体,被加入到media_device中的entitie链表中,此外,为了保持对所有从属设备的控制,内部还维护了一个挂载了所有子设备的subdevs链表。
v4l2_subdev定义了一个v4l2_subdev_ops结构体,其实现交由不同的硬件模块来具体完成。
在v4l2框架内部,会将video_device嵌入到一个具有特定主设备号的字符设备中,其方法集在操作节点时被调用到。
在v4l2框架中,{BANNED}{BANNED}最佳佳为核心的是图像数据缓冲区的管理,而这个管理工作便是由vb2_queue来完成的,vb2_queue通常在打开设备的时候被创建,其结构体的vb2_ops可以由驱动自己实现,而vb2_mem_ops代表了内存分配的方法集,另外,还有一个用于管理用户空间和内核空间的相互传递的方法集buf_ops,vb2_queue通过一个vb2_buffer的数组来管理申请的所有数据缓冲区,并且通过queued_list来管理入队状态的所有buffer,通过done_list来管理被填充了数据等待消费的所有buffer。