精华内容
下载资源
问答
  • 视频应用可以通过两种方式从V4L2驱动申请buffer 1. USERPTR, 顾名思义是用户空间指针的意思,应用层负责分配需要的内存空间,然后以指针的形式传递给V4L2驱动层,V4L2驱动会把capture的内容保存到指针所指的空间 ...

    视频应用可以通过两种方式从V4L2驱动申请buffer

    1. USERPTR, 顾名思义是用户空间指针的意思,应用层负责分配需要的内存空间,然后以指针的形式传递给V4L2驱动层,V4L2驱动会把capture的内容保存到指针所指的空间

    一般来说,应用层需要确保这个内存空间物理上是连续的(IPU处理单元的需求),在android系统可以通过PMEM驱动来分配大块的连续物理内存。应用层在不需要的时候要负责释放申请的PMEM内存。

    2. MMAP方式,内存映射模式,应用调用VIDIOC_REQBUFS ioctl分配设备buffers,参数标识需要的数目和类型。这个ioctl也可以用来改变buffers的数据以及释放分配的内存,当然这个内存空间一般也是连续的。在应用空间能够访问这些物理地址之前,必须调用mmap函数把这些物理空间映射为用户虚拟地址空间。

    虚拟地址空间是通过munmap函数释放的; 而物理内存的释放是通过VIDIOC_REQBUFS来实现的(设置参数buf count为(0)),物理内存的释放是实现特定的,mx51 v4l2是在关闭设备时进行释放的。

    所以二者都是申请连续的物理内存,只是申请和释放的方式不同

    展开全文
  • v4l2tools 这是基于libv4l2cpp的简单V4L2工具 依存关系 liblog4cpp5-dev(可选) libvpx-dev(适用于v4l2compress) libx264-dev(适用于v4l2compress) libx265-dev(用于v4l2compress) libjpeg-dev(适用于...
  • v4l2rtspserver 这是来自的流媒体供稿: 支持H264,HEVC,JPEG,VP8或VP9捕获的Video4Linux设备。 支持PCM S16_BE,S16_LE,S32_BE或S32_LE的ALSA设备 RTSP服务器支持: RTP / UDP单播 RTP / UDP多播 RTP / TCP ...
  • v4l2loopback_tricks v4l2loopback技巧 基于v4l2loopback内核模块的技巧/工具 设置 对v4l2loopback内核模块和ffmpeg的严格要求 Python模块 pip install ffmpeg-python pip install PyQt5 (if using the gui.py) ...
  • 使用V4L2驱动USB摄像头

    2019-08-27 22:47:50
    博客链接为:https://blog.csdn.net/qq_42449351/article/details/100097810,通过V4L2框架来操作摄像头
  • v4l2-ctl工具

    2020-10-10 09:10:49
    v4l2-ctl命令: //显示Camera所有信息(分辨率:Width/Height) # v4l2-ctl -d /dev/video0 --all //显示Camera信息 # v4l-ctl -D //查看支持的设备 # v4l2-ctl --list-devices *** *** ***
  • Native层打开 V4L2 video0摄像头-V4L2_MEMORY_DMABUF-YUYV格式-1plane.cpp 本文链接:《[Native层打开 V4L2 video0摄像头-V4L2_MEMORY_DMABUF-YUYV格式-1plane]...
  • V4L2使用与运行机制

    2013-12-03 23:10:59
    v4l2 操作实际上就是 open() 设备, close() 设备,以及中间过程的 ioctl() 操作。对于 ioctl 的调用,要注意对 errno 的判断,如果调用被其他信号中断,即 errno 等于 EINTR 的时候,要重新调用。
  • v4l2loopback, v4l2环回设备 v4l2loopback-- 创建V4L2环回设备的内核 MODULE这里 MODULE 允许你创建"虚拟视频设备"普通( v4l2 ) 应用程序将读取这些设备,如同普通视频设备一样,但是视频不会从 比如 读取,而是由...
  • v4l2—嵌入式linux编程人员使用参考书,豆丁上弄的文档,英文版,v4l2结构及API相关介绍。
  • drm+v4l2零拷贝

    2020-06-14 13:40:10
    嵌入式Linux平台实现v4l2和DRM实现零拷贝直接v4l2获取camera数据直接显示,v4l2获取camera数据直接显示欢迎大家下载使用
  • v4l2基本使用

    2020-10-14 10:21:02
    struct v4l2_capability cap; ioctl(camrea_fd, VIDIOC_QUERYCAP, &cap); 2获取设备支持的标准制式 std struct v4l2_standard std; ioctl(camrea_fd, VIDIOC_ENUMSTD, &std) 3显示所有支持的帧...

    1获取设备信息cap

    struct v4l2_capability cap;

    ioctl(camrea_fd, VIDIOC_QUERYCAP, &cap);

    2获取设备支持的标准制式 std

    struct v4l2_standard std;

    ioctl(camrea_fd, VIDIOC_ENUMSTD, &std)

    3显示所有支持的帧格式 VIDIOC_ENUM_FMT

    struct v4l2_fmtdesc fmtdesc;

    ioctl(camrea_fd, VIDIOC_ENUM_FMT, &fmtdesc)

    4查询当前帧格式  VIDIOC_G_FMT

    struct v4l2_format fmt;

    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    ioctl(camrea_fd, VIDIOC_G_FMT, &fmt)

    5设置帧格式 VIDIOC_S_FMT

    struct v4l2_format fmt;

          fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

          fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; // 采样类型,如 RGB 8:8:8    V4L2_PIX_FMT_JPEG;//YUYV格式

          fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

          fmt.fmt.pix.width = width;

    fmt.fmt.pix.height = height;

    ioctl(camrea_fd, VIDIOC_S_FMT, &fmt)

    6查询帧率 VIDIOC_G_PARM

    *timeperframe 表示平均每一帧所占的时间,由其元素 numerator denominator 共同决定

     *capturemode 则表示采集模式,采集高质量图片值为 1,一般设为 0

     

    struct v4l2_streamparm parm;

    parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    ioctl(camrea_fd, VIDIOC_G_PARM, &parm)

    7向驱动申请帧缓冲 VIDIOC_REQBUFS

    struct v4l2_requestbuffers reqbuf;

    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

         reqbuf.memory = V4L2_MEMORY_MMAP;

    reqbuf.count = count;

    ioctl(camrea_fd, VIDIOC_REQBUFS, &reqbuf)

     

    8建立内存映射

    VIDIOC_QUERYBUF 来获取内核空间的视频缓冲区信息,

    然后调用函数 mmap把内核空间地址映射到用户空间,

    这样应用程序才能够访问位于内核空间的视频缓冲区

    struct v4l2_buffer bufinfo;

    bufinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

             bufinfo.memory = V4L2_MEMORY_MMAP;

         bufinfo.index = i;

    ioctl(camrea_fd, VIDIOC_QUERYBUF, &bufinfo)

     

    buffers[i].length = bufinfo.length;

    buffers[i].start = mmap(NULL, bufinfo.length, PROT_READ | PROT_WRITE,MAP_SHARED, camrea_fd, bufinfo.m.offset);

     

    9释放内存映射

    munmap(buffers[i].start, buffers[i].length)

    10打开视频捕获 VIDIOC_QBUF

    struct v4l2_buffer buf;

    //申请了多少个缓冲区循环设置多少次

    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

             buf.memory = V4L2_MEMORY_MMAP;

    buf.index = i;

     

    ioctl(camrea_fd, VIDIOC_QBUF, &buf)

    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    ioctl(camrea_fd, VIDIOC_STREAMON, &type)

     

    11关闭视频捕获VIDIOC_STREAMOFF

    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    ioctl(camrea_fd, VIDIOC_STREAMOFF, &type)

    12获取一帧数据

    struct v4l2_buffer buf;

    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

             buf.memory = V4L2_MEMORY_MMAP;

    ioctl(camrea_fd, VIDIOC_DQBUF, &buf)

    *frame_buf = buffers[buf.index].start;//buffers是映射到的地址

             current_index = buf.index;

     

    13释放一帧数据 VIDIOC_QBUF

    struct v4l2_buffer buf;

    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

             buf.memory = V4L2_MEMORY_MMAP;

    buf.index = current_index;

    ioctl(camrea_fd, VIDIOC_QBUF, &buf)

     

    关于ioctl(camrea_fd, VIDIOC_S_FMT, &fmt);设置再读取v4l2_format没变化的问题

    使用VIDIOC_S_FMT设置时如果该设备不支持该模式内核会自动把fmt设置成支持的数据

     

     

    main函数的结构

    camera_init();//初始化摄像头

     

        get_v4l2_info();

     

        set_cam_format(640, 480);//长,

     

        cam_req_bufs(3); //申请缓冲区

     

        cam_mmap(); //用户地址映射

     

        cam_start(); //开始视频捕获

     

        char * jpg_buf = malloc(480*640*3);

        int i;

        //jpg_buf 里存的就是图片数据

        printf("nr_buffers:%d\n",nr_buffers);

        for(i = 0;i<10;i++)

        {

            cam_get_frame(&jpg_buf);

            printf("buf : %x\n",jpg_buf);

            cam_free_frame();

        }

     

        cam_munmap();

        cam_stop();

     

    close(camrea_fd);

    展开全文
  • Native层打开 V4L2 video0摄像头 - V4L2_MEMORY_USERPTR - NV12格式 - 2plane.cpp https://ciellee.blog.csdn.net/article/details/109687749
  • v4l2grab, 从V4L2设备抓取jpeg的工具 v4l2grab 这是一个小的命令行 工具,用于抓取V4L2设备的jpeg格式( 比如 。 USB摄像头) 。对于安装,请按照 Wiki的说明进行操作。如果你已经安装了 ./v4l2grab -h 或者 v4l2grab ...
  • camset:v4l2-ctl的GUI-源码

    2021-05-25 11:03:11
    example_ioctl文件夹包含使用v4l2 Python绑定库读取和设置V4L值(等效于v4l2-ctl --list-formats-ext , v4l2-ctl -L和v4l2-ctl -c )的直接ioctl调用的一些示例。 对该库进行了少许修改,以使其与最新的Python版本...
  • 全志T7 v4l2开发测试代码
  • v4l2-onvif 这是尝试实现ONVIF服务器的尝试: 对于V4L2捕获设备(NVT / NVS), 适用于V4L2输出设备(NVD)。 Web服务数据绑定是使用生成的。...您可以使用以下方法从主机公开V4L2设备: docker run --dev
  • 具体操作如下:直接解压,make编译,V4L2的封装类会直接被编译成so库,test.cpp为程序程序,调用封装的v4l2接口获取50帧图像并保存为camera.yuv里面,使用7yuv软件可以查看帧图像。我们可以通过这个V4L2的封装接口...
  • 使用原始的RGB数据构造Opencv中的Mat对象。该资源使用Linux系统中的V4L2接口读取摄像头MJPEG图像数据,解码成RGB数据,再转换为Opencv中的Mat对象所使用的BGR格式
  • Linux V4L2驱动详解

    2019-10-15 02:11:56
    嵌入式Linux中V4L2驱动详解 目录 一、API介绍 二、注册和open 三、基本ioctl处理 四、输入和输出 五、颜色与格式 六、格式协商 七、基本的帧IO 八、流IO 九、控制
  • 这样的代码不应该需要太多积分,但时间久了积分上去了,特意来减少所需积分,希望大家喜欢。...linux下 ffmpeg使用的2.5.2的库 在编译时要下载x264的库 增加编译选项--enable libx264,否则会报264编码器未找到
  • 使用v4l2在qt实时显示摄像头数据。未使用opencv。uvc摄像头都可使用。 这样的代码不应该需要太多积分,但时间久了积分上去了,特意来减少所需积分,希望大家喜欢。
  • 本资源利用v4l2打开摄像头,无需安装opencv库,直接在Linux下编译即可!可手动调节摄像头输出分辨率。
  • 使用V4L2实现摄像头的视频读取,为提高视频刷新速度,采用了freambuffer实现视频的显示,比直接用QT lable显示快一个等级。 因需要在嵌入式运行,QT已配置好交叉编译环境,所以代码使用了qt的工程。如果不使用qt可...
  • v4l2+opencv

    2018-03-08 13:09:24
    V4L2+OpenCV3.1以MJPG格式读取USB摄像头图像并实时显示
  • V4L2 是专门为 linux 设备设计的一套视频框架,其主体框架在 linux 内核,可以理解为是整个 linux 系统上面的视频源捕获驱动框架。本资源就是根据linux内核总结出的V4L2框架代码流程。仅供参考,所有权为Clay Ding
  • v4l2读取USB摄像头

    2018-03-08 13:13:54
    V4l2读取USB摄像头MJPG和yuyv数据,并实时显示摄像头的数据
  • V4L2_MEMORY_MMAP 导出 fd 需要使用 vb2_ioctl_expbuf (只能使用于VB2_MEMORY_MMAP 方式)。 int buffer_export(int v4lfd, enum v4l2_buf_type bt, int index, int *dmafd) { struct v4l2_exportbuffer expbuf; ...

    V4L2_MEMORY_MMAP 导出 fd 需要使用 vb2_ioctl_expbuf (只能使用于VB2_MEMORY_MMAP 方式)。

    int buffer_export(int v4lfd, enum v4l2_buf_type bt, int index, int *dmafd)
    {
        struct v4l2_exportbuffer expbuf;
    
        memset(&expbuf, 0, sizeof(expbuf));
        expbuf.type = bt;
        expbuf.index = index;
        if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
            perror("VIDIOC_EXPBUF");
            return -1;
        }
    
        *dmafd = expbuf.fd;
    
        return 0;
    }
    
    int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
    		unsigned int index, unsigned int plane, unsigned int flags)
    {
    	struct vb2_buffer *vb = NULL;
    	struct vb2_plane *vb_plane;
    	int ret;
    	struct dma_buf *dbuf;
    
    	if (q->memory != VB2_MEMORY_MMAP) {
    		dprintk(1, "queue is not currently set up for mmap\n");
    		return -EINVAL;
    	}
    
    	if (!q->mem_ops->get_dmabuf) {
    		dprintk(1, "queue does not support DMA buffer exporting\n");
    		return -EINVAL;
    	}
    
    	if (flags & ~(O_CLOEXEC | O_ACCMODE)) {
    		dprintk(1, "queue does support only O_CLOEXEC and access mode flags\n");
    		return -EINVAL;
    	}
    
    	if (type != q->type) {
    		dprintk(1, "invalid buffer type\n");
    		return -EINVAL;
    	}
    
    	if (index >= q->num_buffers) {
    		dprintk(1, "buffer index out of range\n");
    		return -EINVAL;
    	}
    
    	vb = q->bufs[index];
    
    	if (plane >= vb->num_planes) {
    		dprintk(1, "buffer plane out of range\n");
    		return -EINVAL;
    	}
    
    	if (vb2_fileio_is_active(q)) {
    		dprintk(1, "expbuf: file io in progress\n");
    		return -EBUSY;
    	}
    
    	vb_plane = &vb->planes[plane];
    
    	dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv,
    				flags & O_ACCMODE);
    	if (IS_ERR_OR_NULL(dbuf)) {
    		dprintk(1, "failed to export buffer %d, plane %d\n",
    			index, plane);
    		return -EINVAL;
    	}
    
    	ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE);
    	if (ret < 0) {
    		dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
    			index, plane, ret);
    		dma_buf_put(dbuf);
    		return ret;
    	}
    
    	dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
    		index, plane, ret);
    	*fd = ret;
    
    	return 0;
    }
    EXPORT_SYMBOL_GPL(vb2_core_expbuf);
    

    这里以 https://elixir.bootlin.com/linux/v4.1/source/drivers/media/v4l2-core/videobuf2-dma-sg.c
    的buffer 申请方式为例说明。
    在reqbuf 后 使用 VIDIOC_EXPBUF 得到buffer fd ,使用的是 vb2_dma_sg_get_dmabuf。

    static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags)
    {
    	struct vb2_dma_sg_buf *buf = buf_priv;
    	struct dma_buf *dbuf;
    	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
    
    	exp_info.ops = &vb2_dma_sg_dmabuf_ops;
    	exp_info.size = buf->size;
    	exp_info.flags = flags;
    	exp_info.priv = buf;
    
    	if (WARN_ON(!buf->dma_sgt))
    		return NULL;
    
    	dbuf = dma_buf_export(&exp_info);
    	if (IS_ERR(dbuf))
    		return NULL;
    
    	/* dmabuf keeps reference to vb2 buffer */
    	atomic_inc(&buf->refcount);
    
    	return dbuf;
    }
    

    将此 dmafd 传递给kernel ,则kernel对此dma_buf 的 attach 等操作皆使用vb2_dma_sg_dmabuf_ops 。

    static struct dma_buf_ops vb2_dma_sg_dmabuf_ops = {
    	.attach = vb2_dma_sg_dmabuf_ops_attach,
    	.detach = vb2_dma_sg_dmabuf_ops_detach,
    	.map_dma_buf = vb2_dma_sg_dmabuf_ops_map,
    	.unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap,
    	.kmap = vb2_dma_sg_dmabuf_ops_kmap,
    	.kmap_atomic = vb2_dma_sg_dmabuf_ops_kmap,
    	.vmap = vb2_dma_sg_dmabuf_ops_vmap,
    	.mmap = vb2_dma_sg_dmabuf_ops_mmap,
    	.release = vb2_dma_sg_dmabuf_ops_release,
    };
    

    对此方式的一些想法:
    使用 V4L2_MEMORY_MMAP 方式 申请后得到的fd 这种方式获取fd 的方式可以送给display去显示,这样用的都是camera 申请的buffer ,做到buffer 共享。但是目前的camera 框架都是从display 的surface去申请buffer,在去使用dma buf fd 的方式去到camera 共享,这种方式目前在应用上应该比较少。

    展开全文
  • hal层代码,测试前kernel驱动应该调试好。直接测试kernel层驱动,对于学习android cemera数据流buffer很有研究价值。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,099
精华内容 8,039
关键字:

v4l2的使用