5. 控制命令VIDIOC_QUERYBUF
功能: 查询已经分配的V4L2的视频缓冲区的相关信息,包括视频缓冲区的使用状态、在内核空间的偏移地址、缓冲区长度等。在应用程序设计中通过调VIDIOC_QUERYBUF来获取内核空间的视频缓冲区信息,然后调用函数mmap把内核空间地址映射到用户空间,这样应用程序才能够访问位于内核空间的视频缓冲区。
参数说明:参数类型为V4L2缓冲区数据结构类型 struct v4l2_buffer ;
返回值说明: 执行成功时,函数返回值为 0;struct v4l2_buffer结构体变量中保存了指令的缓冲区的相关信息;
一般情况下,应用程序中调用VIDIOC_QUERYBUF取得了内核缓冲区信息后,紧接着调用mmap函数把内核空间地址映射到用户空间,方便用户空间应用程序的访问。
使用举例:
-------------------------------------------------------------------------------------------------------
struct v4l2_buffer tV4L2buf;
memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));
tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;
tV4L2buf.index = i; // 要获取内核视频缓冲区的信息编号
iret = ioctl(fd_usbcam, VIDIOC_QUERYBUF, &tV4L2buf);
// 把内核空间缓冲区映射到用户空间缓冲区
AppBufLength = tV4L2buf.length;
AppBufStartAddr = mmap(NULL /* start anywhere */ ,
tV4L2buf.length,
PROT_READ | PROT_WRITE /* access privilege */ ,
MAP_SHARED /* recommended */ ,
fd_usbcam, tV4L2buf.m.offset);
-------------------------------------------------------------------------------------------------------
上述代码在通过调用VIDIOC_QUERYBUF取得内核空间的缓冲区信息后,接着调用mmap函数把内核空间缓冲区映射到用户空间;关于mmap函数的用法,请读者查询相关资料;
6. 控制命令VIDIOC_QBUF
功能: 投放一个空的视频缓冲区到视频缓冲区输入队列中 ;
参数说明:参数类型为V4L2缓冲区数据结构类型 struct v4l2_buffer ;
返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,指令(指定)的视频缓冲区进入视频输入队列,在启动视频设备拍摄图像时,相应的视频数据被保存到视频输入队列相应的视频缓冲区中。
使用举例:
-------------------------------------------------------------------------------------------------------
struct v4l2_buffer tV4L2buf;
memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));
tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;
tV4L2buf.index = i; //指令(指定)要投放到视频输入队列中的内核空间视频缓冲区的编号;
iret = ioctl(fd_usbcam, VIDIOC_QBUF, &tV4L2buf);
7. 控制命令VIDIOC_STREAMON
功能: 启动视频采集命令,应用程序调用VIDIOC_STREAMON启动视频采集命令后,视频设备驱动程序开始采集视频数据,并把采集到的视频数据保存到视频驱动的视频缓冲区中。
参数说明:参数类型为V4L2的视频缓冲区类型 enum v4l2_buf_type ;
返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,视频设备驱动程序开始采集视频数据,此时应用程序一般通过调用select函数来判断一帧视频数据是否采集完成,当视频设备驱动完成一帧视频数据采集并保存到视频缓冲区中时,select函数返回,应用程序接着可以读取视频数据;否则select函数阻塞直到视频数据采集完成。Select函数的使用请读者参考相关资料。
使用举例:
----------------------------------------------------------------------------------------------------------
enum v4l2_buf_type v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fd_set fds ;
struct timeval tv;
iret = ioctl(fd_usbcam, VIDIOC_STREAMON, &v4l2type);
FD_ZERO(&fds);
FD_SET(fd_usbcam, &fds);
tv.tv_sec = 2; /* Timeout. */
tv.tv_usec = 0;
iret = select(fd_usbcam+ 1, &fds, NULL, NULL, &tv);
----------------------------------------------------------------------------------------------------------
8. 控制命令VIDIOC_DQBUF //第二个D是删除的意思
功能: 从视频缓冲区的输出队列中取得一个已经保存有一帧视频数据的视频缓冲区;
参数说明:参数类型为V4L2缓冲区数据结构类型 struct v4l2_buffer ;
返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,相应的内核视频缓冲区中保存有当前拍摄到的视频数据,应用程序可以通过访问用户空间来读取该视频数据。(前面已经通过调用函数mmap做了用户空间和内核空间的内存映射).
使用举例:
----------------------------------------------------------------------------------------------------------
struct v4l2_buffer tV4L2buf;
memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));
tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;
iret = ioctl(fd_usbcam, VIDIOC_DQBUF, &tV4L2buf);
Sasoritattoo注释:VIDIOC_DQBUF命令结果 使从队列删除的缓冲帧信息 传给了此tVL2buf。V4L2_buffer结构体的作用就相当于申请的缓冲帧的代理,找缓冲帧的都要先问问它,通过它来联系缓冲帧,起了中间桥梁的作用。
----------------------------------------------------------------------------------------------------------
9. 控制命令VIDIOC_STREAMOFF
功能: 停止视频采集命令,应用程序调用VIDIOC_ STREAMOFF停止视频采集命令后,视频设备驱动程序不在采集视频数据。
参数说明:参数类型为V4L2的视频缓冲区类型 enum v4l2_buf_type ;
返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,视频设备停止采集视频数据。
使用举例:
----------------------------------------------------------------------------------------------------------
enum v4l2_buf_type v4l2type;
v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
iret = ioctl(fd_usbcam, VIDIOC_STREAMOFF, &v4l2type);
-----------------------------------------------------------------------------------------------------------
以上就是Linux 视频设备驱动V4L2最常用的控制命令使用说明,通过使用以上控制命令,可以完成一幅视频数据的采集过程。V4L2更多的控制命令使用说明请参考:http://v4l2spec.bytesex.org/spec/book1.htm
希望本文对大家理解linux下的视频驱动编程有所帮助。
*******************************我是分割线,你看不见我********************************************
这些其实没什么好讲的,就是这些,你绕不过去的,这些都是精华,我当时每样都看了起码十五遍以上吧,并不是说你拿着它上来就读个十五遍,而是在看中学,在学中用,在用中又学,好东西就得慢慢品,这味道就出来了,这过程就是成长的过程。当你写的程序能够真正采集到一张图像的时候,那么你已经完成了万里长征的一小半了
我前段时间上传了一个也是基于v4l2视频架构的采集程序,是别人写的,我注释了一下,上面搞定了可以去下一下看看,另外,在学习的过程中,我还从网上找了许多关于这方面的硕士论文,现在回头一看,那也能叫硕士论文??没啥含量,纯粹就是瞎胡闹,东西估计都没做出来,就自己在那儿吹,有些抄别人的抄错了都不知道,,还好我从没想过要考研,现在上大学我都觉得没意思还考研??可笑,可笑。。。