本文链接:https://blog.csdn.net/coroutines/article/details/70141086

可参考:http://www.it610.com/article/4522348.htm   //v4l2官方翻译

基于V4L2的应用,通常面临着大块数据的读取与拷贝等问题。尤其在嵌入式系统中,对于实时性能要求较高的应用,拷贝会花上几十个ms的时间,这通常轻则造成用户体验差,重则导致产品质量不达标。V4L2 Framework定义了几种不同的方式,用于从设备中读取数据,这篇文章简要介绍下在Streaming I/O模式下,如何使用这几种数据的获取与使用方法。Streaming I/O设计的目的就是为了减少在数据处理的各个环节中,拷贝的次数,从而实现各阶段硬件的无缝配合。
本文针对的是USB Camera (Capture)设备。
1. 设备支持

对于设备特性来说,需要设备支持Streaming能力,这个需要通过V4L2的Capability来判断,方式如下:

struct v4l2_capability _cap;
ioctl( _fd, VIDIOC_QUERYCAP, &_cap );

其中,_fd是打开的V4L2设备的描述符,通过:

if( (_cap.capabilities & V4L2_CAP_STREAMING) != 0 ) {
    printf( " V4L2_CAP_STREAMING" );
}

判断是否支持Streaming方式访问。
2 Memory Map

通过Memory Map访问V4L2设备驱动中分配的内存。设备收到的数据存在驱动内的Buffer中,通过Map方式,将内存Map到用户空间。使用这种方式只有指向这段内存的用户空间指针在各个处理环节中传递,不会发生真实的数据拷贝。

struct v4l2_requestbuffers reqbuf;
struct {
    void *start;
    size_t length;
} *buffers;
unsigned int i;

memset(&reqbuf, 0, sizeof(reqbuf));
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
reqbuf.count = 20;

if (-1 == ioctl (fd, VIDIOC_REQBUFS, &reqbuf)) {
    if (errno == EINVAL)
        printf("Video capturing or mmap-streaming is not supported\\n");
    else
        perror("VIDIOC_REQBUFS");

exit(EXIT_FAILURE);
}

/* We want at least five buffers. */

if (reqbuf.count < 5) {
    /* You may need to free the buffers here. */
    printf("Not enough buffer memory\\n");
    exit(EXIT_FAILURE);
}

buffers = calloc(reqbuf.count, sizeof(*buffers));
assert(buffers != NULL);

for (i = 0; i < reqbuf.count; i++) {
    struct v4l2_buffer buffer;

memset(&buffer, 0, sizeof(buffer));
    buffer.type = reqbuf.type;
    buffer.memory = V4L2_MEMORY_MMAP;
    buffer.index = i;

if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buffer)) {
        perror("VIDIOC_QUERYBUF");
        exit(EXIT_FAILURE);
    }

buffers[i].length = buffer.length; /* remember for munmap() */

buffers[i].start = mmap(NULL, buffer.length,
                PROT_READ | PROT_WRITE, /* recommended */
                MAP_SHARED,             /* recommended */
                fd, buffer.m.offset);

if (MAP_FAILED == buffers[i].start) {
        /* If you do not exit here you should unmap() and free()
           the buffers mapped so far. */
        perror("mmap");
        exit(EXIT_FAILURE);
    }
}

/* Cleanup. */

for (i = 0; i < reqbuf.count; i++)
    munmap(buffers[i].start, buffers[i].length);

用户程序首先需要通过VIDIOC_REQBUFS,通知驱动进行驱动内内存分配;之后通过VIDIOC_QUERYBUF取得驱动中各内存块的基本信息,主要是Buffer长度和Offset;取得这些信息后,通过mmap,将内存map到User Space中使用。在驱动中,V4L2对于Buffer的使用是队列形式,Buffer出队后,再次入队之前,驱动无法再使用这个Buffer,因此申请的Buffer个数通常是多个,避免数据丢失。
在使用过程中,需要通过poll操作,判断是否有数据到达,然后通过VIDIOC_DQBUF,取得当前有数据的Buffer,通过Buffer的Index属性,找到对应的User Space指针,交由下个环节处理;处理完成后,通过VIDIOC_QBUF,将Buffer重新入队。
3 User Pointers

User Pointers方式会将用户空间分配的内存指针及长度传递给V4L2驱动(虽然是用户空间分配,但不一定是在堆空间上分配的内存,可以是通过其它方式映射出来的内存,比如从另一个设备驱动中),这样数据到达后,可以直接传递这个指针到下个环节中处理。初始化方式如下:

struct v4l2_requestbuffers reqbuf;

memset (&reqbuf, 0, sizeof (reqbuf));
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_USERPTR;

if (ioctl (fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
    if (errno == EINVAL)
        printf ("Video capturing or user pointer streaming is not supported\\n");
    else
        perror ("VIDIOC_REQBUFS");

exit (EXIT_FAILURE);
}

4 DMA buffer importing

DMA方式的初始化方式如下:

struct v4l2_requestbuffers reqbuf;

memset(&reqbuf, 0, sizeof (reqbuf));
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_DMABUF;
reqbuf.count = 1;

if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
    if (errno == EINVAL)
        printf("Video capturing or DMABUF streaming is not supported\\n");
    else
        perror("VIDIOC_REQBUFS");

exit(EXIT_FAILURE);
}

DMA方式的传输基于文件描述符进行,fd的传递是通过VIDIOC_QBUF中的描述符设置:

int buffer_queue(int v4lfd, int index, int dmafd)
{
    struct v4l2_buffer buf;

memset(&buf, 0, sizeof buf);
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_DMABUF;
    buf.index = index;
    buf.m.fd = dmafd;

if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
        perror("VIDIOC_QBUF");
        return -1;
    }

return 0;
}

poll操作返回后,可以通过这个dmafd进行下一步处理。

V4L2- Memory相关推荐

  1. Android RK3399 UVC摄像头格式异常

    Android RK3399 UVC摄像头格式异常 前言 分析 处理方式 结论 前言 厂商提供了一个摄像头,接入后dev/video节点已生成,打开也成功了,但是黑屏,无法预览.最终查了HAL层代码才 ...

  2. android驱动USB摄像头了

    终于搞定android驱动USB摄像头了! 2014-05-28  liuwei200...  文章来源  阅 7655  转 5 转藏到我的图书馆 微信 分享: 多亏了stackoverflow看到 ...

  3. V4L2获取usb视频流测试代码

    Video4Linux2(Video for Linux Two, 简称V4L2)是Linux中关于视频设备的驱动框架,为上层访问底层的视频设备提供统一接口.V4L2主要支持三类设备:视频输入输出设备 ...

  4. Android Camera 通过V4L2与kernel driver的完整交互过程

    Android Camera 通过V4L2与kernel driver的完整交互过程 之前在  Android Camera 的执行流程   http://blog.chinaunix.net/uid ...

  5. 【Linux开发】V4L2应用程序框架

    V4L2应用程序框架 V4L2较V4L有较大的改动,并已成为2.6的标准接口,函盖video\dvb\FM...,多数驱动都在向V4l2迁移.更好地了解V4L2先从应用入手,然后再深入到内核中结合物理 ...

  6. Linux的视频编程(V4L2编程)【转】

    本文转载自:http://blog.csdn.net/tommy_wxie/article/details/11472073 一.什么是video4linux Video4linux2(简称V4L2) ...

  7. NanoPi NEO Air使用十五:使用V4L2驱动USB摄像头

    USB摄像头初识   Linux UVC driver(uvc) 该驱动适用于符合USB视频类(USB Video Class)规范的摄像头设备,它包括V4L2内核设备驱动和用户空间工具补丁.大多数大 ...

  8. V4L2编程 视频采集

    V4L2编程 以前做的智能家居的项目用的是Linux2.6.13的核,使用的中星微的摄像头,移植了spcaview进行图像的获取,后来用了2.6.29的核,发现以前移植的spcaview不能用了,后来 ...

  9. 嵌入式Linux下Camera编程--V4L2【转】

    转自:http://blog.csdn.net/fwqlzz/article/details/51126653 版权声明:本文为博主原创文章,未经博主允许不得转载.USB video class(又称 ...

  10. V4L2框架分析学习

    Author:CJOK Contact:cjok.liao#gmail.com SinaWeibo:@廖野cjok 1.概述 Video4Linux2是Linux内核中关于视频设备的内核驱动框架,为上 ...

最新文章

  1. 操作系统常用词典(一)
  2. join,和循环删除,fromkeys,集合,拷贝
  3. Spring-AOP @AspectJ进阶之访问连接点信息
  4. YOLOX——Win10下训练自定义VOC数据集
  5. 能量平衡_能量平衡原则
  6. url去除掉一个参数php,php怎样去掉url中的参数_后端开发
  7. 一个java类可以有_一个.java文件中可以有几个同级类?
  8. firewalld防火墙简介
  9. 视觉SLAM笔记(14) Eigen几何模块
  10. opencv4 c++ 提取图片中的白色区域_【从零学习OpenCV 4】点集拟合
  11. 论文笔记_S2D.48_2017-IEEE RAL_单视图和多视图深度融合
  12. Xshell连接新浪云服务器
  13. 网站分享:7个非常好用的电子书网站
  14. 数据分析总结一:数据分析思维
  15. 放大电路的静态工作点
  16. Failed to calculate the value of task ‘:unityLibrary:compileDebugJavaWithJavac‘
  17. 克里金插值在气象数据方向的应用
  18. 全网最全安全加固指南
  19. 太极分布式事务处理框架TJDTP使用指南
  20. 脑与认知神经科学Matlab Psytoolbox认知科学实验设计——实验设计二

热门文章

  1. U-Net模型搭建python实现
  2. 绘图 | G2色块图
  3. 陶森大学计算机专业收入水平,2016PayScale美国大学计算机专业本科毕业生薪酬排名...
  4. 九章量子计算机 知乎,量子计算机《九章》问世 知乎微博消息: 北京时间 12 月 4 日凌晨 3 点,一篇重要文章以 First Releas... - 雪球...
  5. 【githubshare】开源的小说下载与阅读工具:Uncle 小说。目录解析与书源结合,支持有声小说与文本小说,可下载 mobi、epub、txt 格式文本小说
  6. 单片机C语言九个重要的知识点总结
  7. 【MySQL基础】Mysql 复制表结构包括索引
  8. kk每日一句:第一句
  9. 各类顶尖经典电影500部,先收着,待有空的时候慢慢看吧!
  10. 解决方案:rabbitmq使用场景-超时未支付订单处理