在Linux下,基于v4l2通过Map映射方式使用USB摄像头,流程有点复杂,刚开始每次看都仿佛看懂了,过一段时间就会蒙圈,直到我发现一个很好的比喻……这里简要介绍一下思路。
关键字:Linux,v4l2,Map,USB摄像头,比喻理解
0. 你有一台生产机器
我们把USB摄像头比作生产机器,摄像头产生的数据就是产品。
我们的目的就是把摄像头产生的数据读到内存,甚至读到文件中,就好像我们要把机器产生的产品通过物流中心送到客户手中。
1. 为这台机器申请库房(VIDIOC_REQBUFS)
首先,我们需要为机器生产的产品申请库房,而且还是多个库房,以保证机器不间断工作的产品可以有效输出。一旦库房不够,机器产生的产品摆放不下,机器必须停止工作或者必须舍弃一些产品——这和我们对视频连续采集的要求不符!
基于V4l2,首先为摄像头申请物理缓存:
//从网上下载“库房申请表模板(v4l2_requestbuffers结构体)”,并打印申请表(rb)
struct v4l2_requestbuffers rb; //库房的申请表,我们需要在申请表中填好信息
int ret;
memset(&rb, 0, sizeof rb);
rb.count = nbufs; //库房数量
rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //库房要储存的产品类型
rb.memory = V4L2_MEMORY_MMAP; //库房输出产品的方式
ret = ioctl(dev, VIDIOC_REQBUFS, &rb); //开始申请(VIDIOC_REQBUFS)
if (ret < 0) {
printf("Unable to allocate buffers: %d.\n", errno);
return ret;
}
2. 给库房起名字(VIDIOC_QUERYBUF)
库房代表实际的物理缓存,我们称呼的时候,不能只用手指着说这个库房,辣个库房。没有名称,不管是系统还是用户,根本无法对申请到的