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
本文来自博客园,作者:moonのsun,转载请注明原文链接:https://www.cnblogs.com/moon-sun-blog/p/23068428

浙公网安备 33010602011771号