一 V4L2概念
V4L2(Video for Linux 2)是Linux内核中关于视频设备驱动的框架,对上向应用层提供统一的接口,对下支持各类复杂硬件的灵活扩展,用户可按照V4L2框架编写相关应用代码,调用V4L2相关API就可以实现像读写文件一样操作视频设备,比如从摄像头取流等。目前V4L2主要运用于Camera驱动。
二 V4L2 Camera取流框架
用户需要按照上图V4L2框架进行取流,具体步骤如下所示:
1.打开设备
int fd = open(DEVNAME, O_RDWR);
2.查询设备属性
struct v4l2_capability cap;
int ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
3.获取摄像头属性
struct v4l2_fmtdesc fmtdesc;
ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc);
4.设置摄像头格式
struct v4l2_format vfmt;
int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);
5.请求内核缓冲区
struct v4l2_requestbuffers req = { 0 };
ioctl(fd, VIDIOC_REQBUFS, &req)
6.将内核缓冲区插入V4L2取流队列
struct v4l2_buffer mapbuffer;
ioctl(fd, VIDIOC_QUERYBUF, &mapbuffer);
// 内存映射 获取缓冲区在内核的地址
ioctl (fd, VIDIOC_QBUF, &mapbuffer);
7.开始设备
int type = CAPTURE_TYPE;
ioctl (fd, VIDIOC_STREAMON, &type);
8.取流:从队列取帧=》重新将缓冲区插入队列
struct v4l2_buffer readbuffer = { 0 };
int ret = ioctl(fd, VIDIOC_DQBUF, &readbuffer); // fetch a buffer frame from the buffer
ret = ioctl(fd, VIDIOC_QBUF, &readbuffer);
9.停止取流:关闭设备=》断开内存映射=》关闭设备fd
int type = CAPTURE_TYPE;
int ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
munmap(mptr[i], size[i]);
close(fd);
三 V4L2 Camera取流代码
1.开发语言
C/C++
2.编译环境
Ubuntu20.04桌面版 NDK r21-e
3.git路径
GitHub - wangzhicheng2013/v4l2_camera