最近在做关于摄像头测试程序相关的一些开发,主要是想要实现在摄像头采集视频的过程中,通过按键来实现拍照,然后将拍照得到的数据保存到一个文件中,通过了解V4L2的一些相关操作,原来,拍照后的数据是保存在一个buf里,而这股数据流便是熟悉的YUYV,要看到相应的图片,还需要特定的转换才能将YUYV的数据转换成bmp图片。

那么,在摄像头中,是怎么获取到图片的呢?

通过V4L2的官方手册,我们得知是该控制命令VIDIOC_DQBUF

那么这个命令的作用是什么呢?

功能: 从视频缓冲区的输出队列中取得一个已经保存有一帧视频数据的视频缓冲区;
参数说明:参数类型为V4L2缓冲区数据结构类型 struct v4l2_buffer ;
返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,相应的内核视频缓冲区中保存有当前拍摄到的视频数据,应用程序可以通过访问用户空间来读取该视频数据。

举个简单的例子:

struct v4l2_buffer cfilledbuffer1;
cfilledbuffer1.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
cfilledbuffer1.memory = V4L2_MEMORY_OVERLAY;
if (ioctl(iCamFd, VIDIOC_DQBUF, &cfilledbuffer1) < 0)
{
	printf("%s VIDIOC_DQBUF Failed!!! \n",__FUNCTION__);
	err = -1;
	goto exit;
}	

上面的这段代码中,cfilledbuffer1就是相应的视频缓冲区,这里面就保存了当前拍摄到的视频数据。

那么,应用程序是怎么访问用户空间的呢?

原来,在应用程序设计中通过调VIDIOC_QUERYBUF来获取内核空间的视频缓冲区信息,然后调用函数mmap把内核空间地址映射到用户空间,这样应用程序才能够访问位于内核空间的视频缓冲区。

那么这个参数的具体作用是什么呢?

参数说明:参数类型为V4L2缓冲区数据结构类型 struct v4l2_buffer ;
返回值说明: 执行成功时,函数返回值为 0;struct v4l2_buffer结构体变量中保存了指令的缓冲区的相关信息;
一般情况下,应用程序中调用VIDIOC_QUERYBUF取得了内核缓冲区信息后,紧接着调用mmap函数把内核空间地址映射到用户空间,方便用户空间应用程序的访问。

举个例子:

m_v4l2Buffer[0] =(unsigned char *) mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, iPmemFd, 0);//映射
if (m_v4l2Buffer[0] == MAP_FAILED) {
     printf(" m_v4l2Buffer[0] mmap failed\n");
    err = -1;
     goto exit2;
}
struct v4l2_buffer buffer;
buffer.type = creqbuf.type;
buffer.memory = creqbuf.memory;
buffer.index = i;// 要获取内核视频缓冲区的信息编号
if (ioctl(iCamFd, VIDIOC_QUERYBUF, &buffer) < 0) {
  printf("%s VIDIOC_QUERYBUF Failed\n",__FUNCTION__);
  goto fail_loop;
}

以上就是我本次做这个项目需要了解的东西,同时,通过参考一些写过V4L2的大神们写过的一些文章,我摘取了其中的部分优秀的文段作为总结,并了解V4L2驱动摄像头的基本流程:

一般操作流程(视频设备):
1. 打开设备文件。 int fd=open("/dev/video0",O_RDWR);
 2. 取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability
 3. 选择视频输入,一个视频设备可以有多个视频输入。VIDIOC_S_INPUT,struct v4l2_input
 4. 设置视频的制式和帧格式,制式包括PAL,NTSC,帧的格式个包括宽度和高度等。
 VIDIOC_S_STD,VIDIOC_S_FMT,struct v4l2_std_id,struct v4l2_format
 5. 向驱动申请帧缓冲,一般不超过5个。struct v4l2_requestbuffers
 6. 将申请到的帧缓冲映射到用户空间,这样就可以直接操作采集到的帧了,而不必去复制。mmap
 7. 将申请到的帧缓冲全部入队列,以便存放采集到的数据.VIDIOC_QBUF,struct v4l2_buffer
 8. 开始视频的采集。VIDIOC_STREAMON
 9. 出队列以取得已采集数据的帧缓冲,取得原始采集数据。VIDIOC_DQBUF
 10. 将缓冲重新入队列尾,这样可以循环采集。VIDIOC_QBUF
 11. 停止视频的采集。VIDIOC_STREAMOFF
 12. 关闭视频设备。close(fd);

关于V4L2中操作比较重要的几个命令以及一般操作流程总结的更多相关文章

  1. Python中操作mysql的pymysql模块详解

    Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...

  2. JQuery中操作Css样式的方法

    JQuery中操作Css样式的方法//1.获取和设置样式 $("#tow").attr("class")获取ID为tow的class属性 $("#tw ...

  3. C#中操作Word(1)—— word对象模型介绍

    一.开发环境布置 C#中添加对Word的支持,只需添加对Microsoft.Office.Interop.Word的命名空间,如下图所示,右键点击“引用”,在弹出的“添加引用”对话框中选中COM标签页 ...

  4. VC++中操作XML(MFC、SDK)转

    [转]VC++中操作XML(MFC.SDK) XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++ ...

  5. VBA中操作XML

    OFFICE2007之后使用了OpenXml标准(伟大的改变),定制文本级的Ribbon可以通过修改压缩包内的xml文件来实现. 先学习一下VBA中操作XML的方法 先引用Microsoft XML ...

  6. VC线程中操作控件,引起程序卡死的问题。

    [问题还原] 线程中操作控件,具体为控制一个按键的使能,使能后结束线程. 主程序中有一个死循环,等待线程结束. 然后,就没有然后了-- [解决方案] 在主程序死循环中,如果检测到界面消息,优先处理掉.

  7. c#中操作word文档-四、对象模型

    转自:http://blog.csdn.net/ruby97/article/details/7406806 Word对象模型  (.Net Perspective) 本文主要针对在Visual St ...

  8. C#中操作WMI的类库-实现远程登录共享

    WMI是Windows Management Instrumentation的简称,即:视窗管理规范.在Windows 2000或以后的版本中均安装得有,NT4.0则需要安装WMI的核心组件.通过WM ...

  9. VC++中操作XMLWin32实例

    摘要:VC++中操作XML XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++里操作XML有两个 ...

随机推荐

  1. 【bzoj4444 scoi2015】国旗计划

    题目描述 A 国正在开展一项伟大的计划 —— 国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这项计划需要多名边防战士以接力的形式共同完成,为此,国土安全局已经挑选了 NN 名优秀的边防 ...

  2. [BZOJ]1093 最大半连通子图(ZJOI2007)

    挺有意思的一道图论. Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:∀u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v ...

  3. bzoj3685普通van Emde Boas树 线段树

    3685: 普通van Emde Boas树 Time Limit: 9 Sec  Memory Limit: 128 MBSubmit: 1932  Solved: 626[Submit][Stat ...

  4. python dataframe数据条件筛选

    一般情况下我们从一堆数据中选择我们获取想要的数据会通过一下方式: (1)创建链表或数组: (2)用for 循环遍历所有数据,将想要的存入链表或数组. 但是python中我们不需要这么做,我们可以用Pa ...

  5. PTA 字符串关键字的散列映射(25 分)

    7-17 字符串关键字的散列映射(25 分) 给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义的散列函数H(Key)将关键字Key中的最后3个字符映射为整数,每个字符占5位:再用除留余 ...

  6. RabbitMQ用户管理

    rabbitmq常用命令 add_user        <UserName> <Password> delete_user     <UserName> chan ...

  7. Button 使用Command 按钮置灰未更新

    当Button绑定了Command,按钮在窗口弹出.或者其它事件时,会自动置灰. 有时,异步执行时间较长时,界面一些绑定了命令的Button,State不会变化,会一直置灰. 直到再次转移Focus. ...

  8. 31. Next Permutation(中等,搞清楚啥是 next permutation)

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  9. Java Socket通信代码片

    package zhang; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOExcept ...

  10. sourceTree+gerrit管理代码

    第一次接触gerrit,会对这种代码管理方式非常排斥,尤其是习惯了用sourceTree配合git进行代码管理的同学.不爽归不爽,代码还得写,我们的目标是让开发过程爽起来. 关于gerrit的知识,移 ...