最近在做关于摄像头测试程序相关的一些开发,主要是想要实现在摄像头采集视频的过程中,通过按键来实现拍照,然后将拍照得到的数据保存到一个文件中,通过了解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. ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)

    题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...

  2. 【吃炸弹的鸽子UVA10765-双联通模板】

    ·从前有一个鸽子Lence,它吃了一个炸弹,然后有人出了这道题. ·英文题,述大意:        给出一张连通无向图,求出:对于每个点,删去这个点(以及它相连的边以后)时,当前图中的连通块数量,这个 ...

  3. ScalaPB(0): 找寻合适的内部系统微服务集成工具

    前一段时间我们探讨了SDP的一个基于集群的综合数据平台解决方案,由多种数据库组成,包括:JDBC, Cassandra 及MongoDB.其中Cassandra和MongoDB属于分布式数据库,可以在 ...

  4. Linux查看系统版本号及关机命令各种方法归纳

    shutdown -h now 立即关机halt 立即关机init 0 立即关机poweroff 立即关机shutdown -r now 重启reboot 重启logout 注销su - 命令切换身份 ...

  5. jquery easyui combobox 高度自适应

    data-options="required:true,editable:false,panelHeight:'auto'"  加上panelHeight:'auto'即可 列合并 ...

  6. logback 三

    一.LoggerFactory.gerLogger()使用: private Logger vitalLogger= LoggerFactory.getLogger("vitalReques ...

  7. python学习之路网络编程篇(第二篇)

    新课程知识的引入:python作用域 #python中无块级别作用域 if 1 == 1 : name = 'alex' print(name) for i in range(10): name = ...

  8. 跟着小菜学习RabbitMQ启动和基础(系列一)

    前言 今天开始我们正式进入RabbitMQ系列学习,在这系列博客中也会发表.NET Core和EF Core文章,网上关于RabbitMQ例子比比皆是,我将综合网上所提供的信息并加上我个人的理解来详细 ...

  9. leetcode刷题笔记326 3的幂

    题目描述: 给出一个整数,写一个函数来确定这个数是不是3的一个幂. 后续挑战:你能不使用循环或者递归完成本题吗? 题目分析: 既然不使用循环或者递归,那我可要抖机灵了 如果某个数n为3的幂 ,则k=l ...

  10. Docker常见仓库Ubuntu

    Ubuntu 基本信息 Ubuntu 是流行的 Linux 发行版,其自带软件版本往往较新一些. 该仓库提供了 Ubuntu从12.04 ~ 14.10 各个版本的镜像. 使用方法 默认会启动一个最小 ...