v4l2 buffer轮转

VIDIOC_REQBUFS

demo

struct v4l2_requestbuffers req = {0};
req.count = x;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE / V4L2_BUF_TYPE_VIDEO_OUTPUT;
req.memory = V4L2_MEMORY_MMAP/V4L2_MEMORY_DMABUF;
ioctl(fd, VIDIOC_REQBUFS, &req);

memory

V4L2_MEMORY_MMAP: 由内核申请buffer;用户使用mmap获取虚拟地址,或者export获取fd以访问buffer内容
V4L2_MEMORY_DMABUF: 由外部申请buffer,VIDIOC_REQBUFS只用来申请占位符

type

V4L2_BUF_TYPE_VIDEO_CAPTURE: 设备->内存;或者说writer对应的buffer
V4L2_BUF_TYPE_VIDEO_OUTPUT: 内存->设备,或者说reader对应的buffer
为什么要分开?buffer分两个队列维护,两个队列分别针对读和写,格式不同,方向不同,分开处理更加方便;

memory和type 组合

V4L2_BUF_TYPE_VIDEO_CAPTURE V4L2_BUF_TYPE_VIDEO_OUTPUT
V4L2_MEMORY_MMAP 内核申请buf,VIDIOC_QUERYBUF获取buf信息;通过qbuf送给设备空buffer,dqbuf取回数据,用户侧mmap/export使用 内核申请buf,VIDIOC_QUERYBUF获取buf信息;用户侧mmap/export填充数据,通过qbuf送给设备使用
V4L2_MEMORY_DMABUF 外部以fd形式申请并传递buf,qbuf送给设备以供设备填充,dqbuf取回数据,用户侧可直接使用fd 外部以fd形式申请并传递带有数据的buf,qbuf送给设备显示

VIDIOC_EXPBUF和mmap区别

VIDIOC_EXPBUF: 获取dma buf fd
mmap: 获取dma buf 虚拟地址

fd

  • fd 是用户态用来在内核各驱动之间传递内存引用的凭证
  • 用户VIDIOC_REQBUFS后,通过VIDIOC_EXPBUF获取dma fd —— 这相当于从内核获取fd信息,因此VIDIOC_EXPBUF必须和V4L2_MEMORY_MMAP搭配(不能是外部传入fd)
  • 用户拿到dma fd,可以直接下发给GPU,ISP等 —— 驱动可以直接使用fd
  • 驱动拿到fd,通过import转化为DMA虚拟地址(IOVA),可以直接在内核访问该地址,比如写入isp output addr寄存器,填充图像数据
  • 用户QBUF,其实就是给驱动传递dma fd
  • 用户侧当然可以通过dma fd -> mmap -> VA

posted @ 2026-09-21 19:21  moonのsun  阅读(3)  评论(0)    收藏  举报