【Qt开发】V4L2 API详解 Buffer的准备和数据读取

前面主要介绍的是:V4L2 的一些设置接口,如亮度,饱和度,曝光时间,帧数,增益,白平衡等。今天看看V4L2 得到数据的几个关键ioctl,Buffer的申请和数据的抓取。


1. 初始化 Memory Mapping 或 User Pointer I/O.
申请数据Buffer。
int ioctl(int fd, int requestbufstruct v4l2_requestbuffers * argp);
参数一:open()所产生的句柄。
参数二:VIDIOC_REQBUFS
参数三:in/out结构体。
struct v4l2_requestbuffers
{
__u32 count;
enum v4l2_buf_type type;
enum v4l2_memory memory; //Applications set this field to V4L2_MEMORY_MMAP or V4L2_MEMORY_USERPTR
 __u32 reserved[2];
};

注意,有两种方式的I/O。 Memory Mapping 和User Pointer。
Memory Mapping的Buffer由Driver申请为物理连续的内存空间(Kernel空间)。在此ioctl调用时被分配,需要早于mmap()动作将他们映射到用户空间。

1.1:Memory Mapping模式详解:
在使用Memory Mapping模式时,参数三中结构体内每个field都需要设置。


__u32 count;   //当memory=V4L2_MEMORY_MMAP时,此处才有效。表明要申请的buffer个数。
enum v4l2_buf_type type;  //Stream 或者Buffer的类型。此处肯定为V4L2_BUF_TYPE_VIDEO_CAPTURE
enum v4l2_memory memory;  //既然是Memory Mapping模式,则此处设置为:V4L2_MEMORY_MMAP


注意:count是个输入输出函数。因为你所申请到的Buffer个数不一定就是你所输入的Number。所以在ioctl执行后,driver会将真实申请到的buffer个数填充到此field. 这个数目有可能大于你想要申请的,也可能小与,甚至可能是0个。
应用程序可以再次调用ioctl--VIDIOC_REQBUFS 来修改buffer个数。但前提是必须先释放已经 mapped  buffer ,可以先 munmap ,然后设置参数 count  0 来释放所有的 buffer


支持Memory  Mapping  I/O方式的前提是:v4l2_capability  中支持V4L2_CAP_STREAMING。
在这个模式下,数据本身不会被Copy,只是在Kernel和用户态之间交换。在应用程序想要访问到这些数据之前,它必须调用mmap()影射到用户态。

同时也要注意,通过ioctl申请的内存,是物理内存,无法被交换入Disk,所以一定要释放:munmap()。



1.2:User Pointer模式:
User Pointer模式时,应用程序实现申请。
只需要填充Type=V4L2_BUF_TYPE_VIDEO_CAPTURE, memory=V4L2_MEMORY_USERPTR




2. 询问Buffer状态:
int ioctl(int fd, int request, struct v4l2_buffer* argp);
参数一:open()所产生的句柄。
参数二:VIDIOC_QUERYBUF
参数三:v4l2_buffer 结构体。(IN/OUT参数)

注意,此ioctl是Memory Mapping的I/O方法之一。User Pointer模式不需要。在Buffer在ioctl-VIDIOC_REQBUFS执行时创建后,随时都可以调用此Ioctl得到buffer信息。
视频缓冲区的使用状态、在内核空间的偏移地址、缓冲区长度等。在应用程序设计中通过调VIDIOC_QUERYBUF来获取内核空间的视频缓冲区信息,然后调用函数mmap把内核空间地址映射到用户空间,这样应用程序才能够访问位于内核空间的视频缓冲区

我们首先通过v4l2_buffer结构体看看参数三这个输入输出参数需要输入些什么,以及能够得到什么信息。

struct v4l2_buffer
{
__u32 index;
enum v4l2_buf_type type;
__u32 bytesused;
__u32 flags;
enum v4l2_field field;
struct timeval timestamp;
struct v4l2_timecode timecode;
__u32 sequence;

enum v4l2_memory memory;
union {
__u32 offset;
unsigned long userptr;
} m;
__u32 length;
__u32 input;
__u32 reserved;
};

在调用ioctl--VIDIOC_QUERYBUF时,需要写入的项目有:
enum v4l2_buf_type type; //V4L2_BUF_TYPE_VIDEO_CAPTURE
__u32 index;  // 这里需要解释一下,因为在调用ioctl-VIDIOC_REQBUFS时,建立了count个Buffer。所以,这里index的有效范围是:0到count-1.


在调用ioctl-VIDIOC_QUERYBUF后,Driver会填充v4l2_buffer 结构体内所有信息供用户使用。
如果一些正常:
1. flags 中:V4L2_BUF_FLAG_MAPPEDV4L2_BUF_FLAG_QUEUED and V4L2_BUF_FLAG_DONE被设置。
2. memory中,V4L2_MEMORY_MMAP被设置。
3. m.offset中,从将要mapping 的device memory头到数据头的offset.
4. length 中,填充当前Buffer长度。
5。其它的Field有可能设置,也有可能不被设置。


这样,mmap()想要有的信息就全了。而mmap()之后,Device Driver 申请的或者Device Memory就能映射到用户空间。数据就可以被应用程序使用了。这才是ioctl-VIDIOC_QUERYBUF的关键作用。



3.和Driver交换buffer: 
对Camera这样的捕获设备来说,Device将数据放到Buffer中,用户得到数据。Device再次将数据放到Buffer中。
那么Device Driver 怎样知道哪个Buffer是可以存放数据的呢?这就用到当前这两个ioctl-VIDIOC_QBUF, ioctl-VIDIOC_DQBUF.

ioctl-VIDIOC_QBUF: 将指定的Buffer放到输入队列中,即向Device表明这个Buffer可以存放东西。
ioctl-VIDIOC_DQBUF: 将输出队列中的数据 buffer取出。

 driver 内部管理着两个 buffer queues ,一个输入队列,一个输出队列。对于 capture device 来说,当输入队列中的 buffer 被塞满数据以后会自动变为输出队列,等待调用 VIDIOC_DQBUF 将数据进行处理以后重新调用 VIDIOC_QBUF  buffer 重新放进输入队列.


用法:
ioctl--VIDIOC_QBUF:
int ioctl(int fd, int request, struct v4l2_buffer* argp);
参数一:open()所产生的句柄。
参数二:VIDIOC_QBUF
参数三:v4l2_buffer 结构体。(IN/OUT参数)

参数三是IN/OUT 参数。需要填充
enum v4l2_buf_type type; //V4L2_BUF_TYPE_VIDEO_CAPTURE
__u32 index;  // 这里需要解释一下,因为在调用ioctl-VIDIOC_REQBUFS时,建立了count个Buffer。所以,这里index的有效范围是:0到count-1. 
memory: V4L2_MEMORY_MMAP.

则这个结构体指明的buffer被送入输出队列,表明此Buffer可以被device 填充数据。

用法:
ioctl--VIDIOC_DQBUF:
int ioctl(int fd, int request, struct v4l2_buffer* argp);
参数一:open()所产生的句柄。
参数二:VIDIOC_DQBUF
参数三:v4l2_buffer 结构体。(IN/OUT参数)

从输出队列中取出一个有数据的Buffer。这个Buffer中的数据被处理后,此Buffer可以通过ioctl-VIDIOC_QBUF再次放入输入队列中去。




4. 开始和结束捕获:
ioctl--VIDIOC_STREAMON. ioctl--VIDIOC_STREAMOFF

非常简单的调用。就是开始和结束。

转载于:https://www.cnblogs.com/huty/p/8518249.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

halcon File文件算子,持续更新

目录File文件Images图像read_imageread_sequencewrite_imagedeserialize_imageserialize_imagelist_image_fileparse_filenameMisc混合体copy_filedelete_filefile_existsget_current_dirlist_filesmake_dirread_world_fileremove_dirset_current_dirObject对象deserialize_obj…

Nginx 之一:编译安装nginx 1.8.1 及配置

转http://www.cnblogs.com/zhang-shijie/p/5294162.html 一:基介绍 官网地址www.nginx.org,nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的,开发工作最早从2002年开始,第一次公开发布时间…

PI校正环节的程序实现推导过程

PI校正环节在经典控制论中非常有用,特别是对负反馈控制系统,基本上都有PI校正环节。1.下面分别说明比例环节和积分环节的作用,以阶跃信号为例。①比例环节单独作用以上分析说明,若只有比例环节的控制系统,阶跃响应也是…

XML文档注释(C#)

目录XML文档编译器识别的标记添加XLM注释的方法添加XLM注释的例子XML文档 C#可以根据特定的注释自动创建XML格式的文档说明。 这些注释都是单行注释&#xff0c;但都以三条斜杠开头 编译器识别的标记 标记说明<C>把行中的文本标记为代码&#xff0c;例如<c>int …

vs里根据json快速创建对应类的方法

有时候,我们在调用别人接口的时候,服务端返回了一个json格式的字符串,我们要获取json里面的数据的话一般有两种方式: 1.通过正则 2.反序列化成一个对象 第一种方式这里不再多说,主要说一下第二种,(为什么呢&#xff0c;你看到后面 你也会喜欢上第二种) 有人肯定会说, json字符串…

德鲁克的《卓有成效的管理者》

是一本很好的书&#xff0c;对我有诸多的启发&#xff0c;这本书我在短期内连看两遍呢。 现将一些我觉得有启发性的句子发给大家分享。 1. 一个人的有效性&#xff0c;与他的智力、想象力或知识之间&#xff0c;几乎没有太大的关联。有才能的人往往最为无效&#xff0c;因为他们…

人工智能之基于face_recognition的人脸检测与识别

不久乘高铁出行&#xff0c;看见高铁火车站已经实现了“刷脸进站”&#xff0c;而且效率很高&#xff0c;很感兴趣&#xff0c;今天抽时间研究一下&#xff0c;其实没那么复杂。 我基本上是基于https://github.com/ageitgey/face_recognition上的资料和源码做一些尝试和试验。 …

iOS 升级https的方案选择

我的选择是将UIWebView统一替换为WKWebView WKWebView AFN SDWebImage https的支持之前的博客都有涉及转载于:https://www.cnblogs.com/Jusive/p/6867531.html

预处理指令(C#)

目录预处理指令简介#define、#undef#if、#elif、#else、#endif#warning、#error#region、#endregion#line、#line default#pragma预处理指令简介 微软对预处理指令解释链接 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/preprocessor-directives/index…

NSWindowController的初始化创建代码

-(PRAboutWindowController*)aboutCtrl{ if(_aboutCtrl nil){ _aboutCtrl [[PRAboutWindowController alloc]initWithWindowNibName:"PRAboutWindowController"]; } return _aboutCtrl ; } 转载于:https://www.cnblogs.com/PJXWang/p/5816675.html

对CMMI3的学习和思考

原文出处&#xff1a; http://tech.it168.com/m/2007-08-02/200708020957750.shtml本文请勿转载。近来笔者所在公司正在为过CMMI3做各种准备&#xff0c;对公司的员工进行了一些相关的培训&#xff0c;作为项目管理人员的我&#xff0c;在学习CMMI3的过程中&#xff0c;也有了自…

Python3抓取糗百、不得姐

​点击关注 异步图书&#xff0c;置顶公众号 每天与你分享 IT好书 技术干货 职场知识 重要提示1:本文所列程序均基于Python3.6,低于Python3.6的Python版本可能无法运行.重要提示2:因所抓取的网站可能随时更改展示内容,因此程序也需及时跟进.重要提示3:本程序仅供学习,不能拿去做…

halcon边缘检测的方法及各种方法的适用范围

目录一、边缘提取二、BLOB分析检测三、赃物检测一、边缘提取 1、设置ROI兴趣区域 2、快速二值化&#xff0c;并连接相邻区域。 这样做的目的是进一步减少目标区域&#xff0c;通过二值化将目标区域大概轮廓提取出来 3、提取最接近目标区域的轮廓 常用函数有boundary&#xff0…

Oracle优化-表设计

前言  绝大多数的Oracle数据库性能问题都是由于数据库设计不合理造成的&#xff0c;只有少部分问题根植于Database Buffer、Share Pool、Redo Log Buffer等内存模块配置不合理&#xff0c;I/O争用&#xff0c;CPU争用等DBA职责范围上。所以除非是面对一个业已完成不可变更的系…

Win10远程桌面 出现 身份验证错误,要求的函数不受支持,这可能是由于CredSSP加密Oracle修正 解决方法...

升级至win10 最新版本10.0.17134&#xff0c;远程桌面连接Window Server时报错信息如下&#xff1a; 出现身份验证错误&#xff0c;要求的函数不正确&#xff0c;这可能是由于CredSSP加密Oracle修正。 解决方法&#xff1a; 运行 gpedit.msc 本地组策略&#xff1a; 计算机配置…

CMM2

原文出处&#xff1a;http://hi.baidu.com/seaweaver/blog/item/e80e7af427f674d9f2d3854a.html CMM2的六个KPA 1、需求管理 &#xff08;RM&#xff0c;Requirement Management&#xff09; 2、软件项目计划 &#xff08;SPP&#xff0c;Software Project Planning&#…

查看linux系统核数

查看linux系统核数&#xff1a; grep ^processor /proc/cpuinfo | wc -l转载于:https://www.cnblogs.com/myyan/p/5822368.html

Rsyslog 日志相关内容

[rootserver vusers_home]# rpm -ql rsyslog|more ###.so结尾为模块&#xff0c;模块有分im为输入模块&#xff0c;om 为输出模块/etc/logrotate.d/syslog/etc/pki/rsyslog/etc/rc.d/init.d/rsyslog/etc/rsyslog.conf/etc/rsyslog.d/etc/sysconfig/rsyslog/lib64/rsyslog…

MFC导出对话框类DLL的实现

1.新建基于对话框的应用程序 2.新建MFC DLL工程 3.选择MFC DLL 4.选择扩展Dll选项&#xff08;重要&#xff01;&#xff01;&#xff01;&#xff09; 5.为Dll工程添加一个MFC类&#xff0c;基类为CDialogEx 6.Dll新建的MFC 类中添加resource.h防止编译出错…

中国如何引进CMM评估,促进软件产业发展

北京软件行业协会 &#xff08;本文转载自软件工程专家网www.21cmm.com&#xff09; 一、CMM的含义及作用   CMM&#xff08;软件能力成熟度模型&#xff1a;Capability Maturity Model For Software&#xff09;是由美国卡内基梅 隆大学的软件工程研究所&#xff08;SEI&a…