memorycleaner汉化版(v4l2 userptr)

本文链接:https://blog.csdn.net/coroutines/article/details/70141086可参考:http://www.it610.com/article/4522348.htm//v4l2官方翻译基于V4L2的应用,通常面临着大块数据的读取与拷贝等问题。尤其在嵌入式系统中,对于实时性能要求较高的应用,拷贝会花上几十个ms…

大家好,又见面了,我是你们的朋友全栈君。

本文链接: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进行下一步处理。
 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128001.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Idea激活码最新教程2023.2.8版本,永久有效激活码,亲测可用,记得收藏

    Idea激活码最新教程2023.2.8版本,永久有效激活码,亲测可用,记得收藏Idea 激活码教程永久有效 2023 2 8 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2023 2 8 成功激活

    2025年5月29日
    4
  • 家用计算机如何关机,win7如何快速关机_win7快速关机的方法

    家用计算机如何关机,win7如何快速关机_win7快速关机的方法现在阶段随着系统的不断更新 用户们的需求也是越来越多了 我们在追求开机速度的同时 也在追求着快速关机的功能 不然等到别人都走了 而自己的电脑还没有完全关闭的状态 很是烦人 那么 win7 系统怎么实现快速关机呢 可以通过设置注册表来实现快速关机 今天小编就来满足大家这一需求 具体方法 1 主要通修改注册表的方法来实现快速关机 在电脑上使用快捷键 win R 在弹出运行窗口中输入 regedit 2 按确

    2025年10月2日
    0
  • python sendfile_sendfile详解(转)[通俗易懂]

    python sendfile_sendfile详解(转)[通俗易懂]在apache,nginx,lighttpd等web服务器当中,都有一项sendfile相关的配置,在一些网上的资料都有谈到sendfile会提升文件传输性能,那sendfile到底是什么呢?它的原理又是如何呢?在传统的文件传输里面(read/write方式),在实现上其实是比较复杂的,需要经过多次上下文的切换,我们看一下如下两行代码:read(file,tmp_buf,len);write(…

    2022年6月6日
    91
  • android studio飞机大战游戏带注释源码教程(多线程)[通俗易懂]

    android studio飞机大战游戏带注释源码教程(多线程)[通俗易懂]第一次发博客,学了3天的androidstudio还有一点以前的java基础做了个飞机大战的游戏游戏比较简单大概就这几个功能1.会动的背景2.我的飞机3.发射子弹3.敌人飞机第一步新建一个项目我用的是Android4.4版本新建好项目之后xml文件之类的什么都不用管先新建个类叫做huahua.javapackagecom.dahuijii.liziguo;importandroid.c…

    2022年4月29日
    329
  • 操作系统概念第六章部分作业题答案

    操作系统概念第六章部分作业题答案题目一:如果将peterson算法中的flag[i]=true与turn=j两条语句交换顺序,会导致求解临界区问题所需三个要求(互斥、有空让进、有限等待)中的哪些要求得不到满足?请举例并分析说明得不到满足的情况解答:假设两个进程i和j:进程i的进入区代码是这样的flag[i]=TRUE;turn=j;while(flag[j]==TRUE&&…

    2022年7月14日
    14
  • python for循环多个参数处理_python for循环嵌套

    python for循环多个参数处理_python for循环嵌套实际上,“使用for循环遍历数组的最简单方法”(Python类型被命名为“list”BTW)是第二种方法,即foriteminsomelist:do_something_with(item)哪个FWIW适用于所有iterable(列表、元组、集合、dict、迭代器、生成器等)。基于范围的C风格版本被认为是非常不通俗的,并且只适用于列表或类似列表的iterable。WhatIwouldl…

    2022年8月12日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号