v4l2应用框架-摄像头v4l2编程(01)_概述
v4l2概述
可以参考:
(127条消息) Linux - 使用V4L2(总结)_喜闻樂见的博客-CSDN博客_linux v4l2
什么是V4L2
概述: Video for linux 2(简称V4L2),是linux中关于视频设备的内核驱动。(文件编程接口)
它也是 linux操作系统下用于采集图片、视频和音频数据的 API接口,配合适当的视频采集设备和相应的驱动程序;
**作用: **支持许多USB 网络摄像头,电视调谐器和相关设备,使它们的输出标准化,因此程序员可以轻松地向其应用程序添加视频支持。MythTV,tvtime和Tvheadend是使用V4L框架的典型应用程序;
可以实现图片、视频、音频等的采集。在远程会议、可视电话、视频监控系统和嵌入式多媒体终端中都有广泛的应用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8whbeLnk-1661764432753)(vx_images/366920709232771.png =200x)]
存放位置: Linux中,一切皆文件,视频设备为设备文件,可以像普通文件一样进行读写操作,而采用 V4L2驱动的摄像头设备文件是 /dev/v4l/video0,为了通用,可以建立到一个和普通摄像头一样的 /dev/video0的链接。
V4L2是内核提供给应用程序的音视频访问的统一接口,在Linux上,免驱摄像头是通过UVC(USB video class)挂载到V4L框架上实现的免驱。
什么是UVC
USB video class(又称为USB video device class or UVC)就是USB device class视频产品在不需要安装任何的驱动程序下即插即用,包括摄像头、数字摄影机、模拟视频转换器、电视卡及静态视频相机。
最新的UVC版本为UVC 1.5,由USB-IF(USB Implementers Forum)定义包括基本协议及负载格式.
两者之间的关系
简单的讲V4L2就是用来管理UVC设备的并且能够提供视频相关的一些应用程序接口。
v4l2采集原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8YfdbZi-1661764432754)(vx_images/429973916245288.png =200x)]
从上图可知,当视频采集的时候,驱动程序从视频采集输入队列取出一个帧缓冲区填充图像buffer,这个帧缓冲区填充完毕之后会放入视频采集输出队列,交由应用程序处理,应用程序处理完这个帧缓冲区之后在将已经处理过的帧缓冲区交由驱动程序,从而循环往复采集图像数据
v4l2的操作流程
- 打开设备文件。(int fd=open(“/dev/video0”,O_RDWR);)
- 查询设备属性:取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。(ioctl(fd_v4l, VIDIOC_QUERYCAP, &cap);)
- 选择视频输入,一个视频设备可以有多个视频输入。(VIDIOC_S_INPUT, struct v4l2_input)
- 设置视频采集的参数。 —设置视频的制式,制式包括PAL/NTSC,使用 ioctl(fd_v4l, VIDIOC_S_STD, &std_id)
—设置视频图像的采集窗口的大小,使用 ioctl(fd_v4l, VIDIOC_S_CROP, &crop)
—设置视频帧格式,包括帧的点阵格式,宽度和高度等,使用 ioctl(fd_v4l, VIDIOC_S_FMT, &fmt)
—设置视频的帧率,使用 ioctl(fd_v4l, VIDIOC_S_PARM, &parm)
—设置视频的旋转方式,使用 ioctl(fd_v4l, VIDIOC_S_CTRL, &ctrl) - 向驱动申请帧缓冲,一般不超过5个。(ioctl(fd_v4l, VIDIOC_REQBUFS, &req);)
- 查询帧缓冲区在内核空间中的长度和偏移量 (ioctl(fd_v4l, VIDIOC_QUERYBUF, &buf);)
- 将申请到的帧缓冲映射到用户空间 mmap,这样就可以直接操作采集到的帧了,而不必去复制。(buffers[i].start = mmap (NULL, buffers[i].length, PROT_READ | PROT_WRITE, MAP_SHARED,fd_v4l, buffers[i].offset); )
- 将申请到的帧缓冲全部入队列,以便存放采集到的数据。(ioctl (fd_v4l, VIDIOC_QBUF, &buf) )
- 开始视频的采集。(ioctl (fd_v4l, VIDIOC_STREAMON, &type) )
- 出队列以取得已采集数据的帧缓冲,取得原始采集数据。(ioctl (fd_v4l, VIDIOC_DQBUF, &buf) )
- 处理完后, 将该帧缓冲重新入队列尾,这样可以循环采集(循环步骤8-10),直到停止采集。
- 停止视频的采集。(ioctl (fd_v4l, VIDIOC_STREAMOFF, &type) ;)
- 释放申请的视频帧缓冲区 unmap,关闭视频设备。(close(fd_v4l);)