- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Linux之V4L2基础编程之内存映射:
一、 概述
Linux中操作一个设备一般都是打开(open),读取(read)和关闭(close)。使用Read的大多是一些字符型设备,然而
对于显示屏或者摄像头这种字符设备而已,挨个字的读写将使得系统调用变得频繁,众所周之,系统调用对于系统而已是个不
小的开销。于是有内存映射(mmap)等物,本例中将讲述在Linux下开发摄像头的一般过程以及使用Qt进行界面开发的实例。
V4L2支持内存映射方式(mmap)和直接读取方式(read)来采集数据,前者一般用于连续视频数据的采集,后者常用于静态图
片数据的采集。
二、 使用 mmap 方式获取摄像头数据的方式过程一般为:
V4L2采集视频操作基本按照打开视频设备、设置视频格式、启动视频采集,循环处理视频数据、停止视频采集、关闭视频
设备,具体操作通过ioctl等函数来实现。一般操作流程如下:
1. 打开视频设备文件。int fd=open(/dev/video0,O_RDWR);
2. 查询视频设备的能力,比如是否具有视频输入,或者音频输入输出等。ioctl(fd_v4l, VIDIOC_QUERYCAP, cap)
3. 设置视频采集的参数:
设置视频的制式,制式包括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)
4. 向驱动申请视频流数据的帧缓冲区
请求/申请若干个帧缓冲区,一般为不少于3个,使用ioctl(fd_v4l, VIDIOC_REQBUFS, req),查询帧缓冲区在内核空间中
的长度和偏移量 ioctl(fd_v4l, VIDIOC_QUERYBUF, buf)
5. 应用程序通过内存映射,将帧缓冲区的地址映射到用户空间,这样就可以直接操作采集到的帧了,而不必去复制。
buffers[i].start = mmap (NULL, buffers[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, fd_v4l,
buffers[i].offset);
6. 将申请到的帧缓冲全部放入视频采集输出队列,以便存放采集的数据。ioctl (fd_v4l, VIDIOC_QBUF, buf)
7. 开始视频流数据的采集。 ioctl (fd_v4l, VIDIOC_STREAMON, type)
8. 驱动将采集到的一帧视频数据存入输入队列第一个帧缓冲区,存完后将该帧缓冲区移至视频采集输出队列。
9. 应用程序从视频采集输出队列中取出已含有采集数据的帧缓冲区。ioctl (fd_v4l, VIDIOC_DQBUF, buf) ,应用程序
处理该帧缓冲区的原始视频数据。
10. 处理完后,应用程序的将该帧缓冲区重新排入输入队列,这样便可以循环采集数据。ioctl (fd_v4l, VIDIOC_QBUF,
buf)重复上述步骤8到10,直到停止采集数据。
11. 停止视频的采集。ioctl (fd_v4l, VIDIOC_STREAMOFF, type)
12. 释放申请的视频帧缓冲区 unmap,关闭视频设备文件 close(fd_v4l)。
以上的程序流程,包含了视频设备采集连续的视频数据的逻辑关系。而在实际运用中,往往还要加入对视频数据进行处理(如
压缩编码)的工作,否则,视频流数据量相当大,需要很大的存储空间和传输带宽。
Mmap就是所谓内存映射。很多设备带有自己的数据缓冲区,或者驱动本身在内核空间中维护一片内存区域,为了让用户空
间程序安全地访问,内核往往要从设备 内存或者内核空间内存复制数据到用户空间。这样一来便多了复制内存这个环节,浪费
了时间。因此 mmap 就将目标存储区域映射到一个用户空间的一片内存,这样用户进程访问这片内存时,内核将自动转换为访
问这个目标存储区。这种转换往往是地址的线性变化而已(很多设备的存储空间在所
文档评论(0)