V4L2是Video for linux2的简称,为linux中关于视频设备的内核驱动。
在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,
摄像头在/dev/video*下,如果只有一个视频设备,通常为/dev/video0。
V4L2在设计时,是要支持很多广泛的设备的,它们之中只有一部分在本质上是真正的视频设备。
【摘自百度百科】
VIDIOC_S_STD | 设置视频的制式 PAL/NTSC |
VIDIOC_S_CROP | 设置视频图像的采集窗口的大小, v4l2_crop.type, v4l2_crop.c struct v4l2_crop { __u32 type; struct v4l2_rect c; }; struct v4l2_rect { __s32 left; __s32 top; __s32 width; __s32 height; }; |
VIDIOC_S_FMT | 帧格式 V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_YVU420等 V4L2_FIELD_INTERLACED 隔行交替 V4L2_FIELD_TOP : PAL则先传输top field V4L2_FIELD_BOTTOM : NTSC首先传输bottom |
VIDIOC_S_PARM | 设置帧率 V4L2_BUF_TYPE_VIDEO_CAPTURE, struct v4l2_streamparm* setfps; setfps->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; setfps->parm.capture.timeperframe.numerator=1; setfps->parm.capture.timeperframe.denominator=10; ioctl(video_fd, VIDIOC_S_PARM, setfps); |
VIDIOC_S_CTRL | 旋转方式 v4l2_control.id=V4L2_CID_VFLIP,value=0 struct v4l2_control ctrl; // V4L2_CID_HFLIP 水平或者垂直翻转 ctrl.id = V4L2_CID_VFLIP; ctrl.value = 0; // 0 或者 1 翻转或者不翻转 ioctl(video_fd, VIDIOC_S_CTRL, &ctrl); |
VIDIOC_REQBUFS | 向驱动申请视频的帧缓冲区,一般不会超过5个 struct v4l2_requestbuffers req; req.count = 2; // 一般不会超过5个 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_USERPTR; ioctl(fd, VIDIOC_REQBUFS, &req) |
VIDIOC_QUERYBUF | 向驱动查询帧缓冲区在内核空间中的长度和偏移量 struct v4l2_buffer querybuffer ; querybuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; querybuffer.memory = V4L2_MEMORY_MMAP ; querybuffer.index = index ; // index=0--3 ioctl(video_fd , VIDIOC_QUERYBUF , &querybuffer); yuv[i] = mmap(0,querybuffer.length); |
VIDIOC_QBUF | 将申请到的帧缓冲放入视频采集输出队列 用于存放采集的数据 struct v4l2_buffer queuebuffer ; queuebuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; queuebuffer.memory = V4L2_MEMORY_MMAP ; queuebuffer.index = i ; ioctl(video_fd , VIDIOC_QBUF , &queuebuffer); |
VIDIOC_STREAMON | 启动视频流数据的采集, 采集到的帧数据缓存到队列中等待读出 int on = 1 ; ioctl(video_fd , VIDIOC_STREAMON , &on); |
VIDIOC_DQBUF | 从已经采集完成的帧缓存队列中读出帧数据 struct v4l2_buffer enqueue; ioctl(video_fd , VIDIOC_DQBUF , &dequeue); memcpy(buffer , yuv[dequeue.index] , dequeue.length); enqueue.index = dequeue.index ; ioctl(video_fd , VIDIOC_QBUF , &enqueue); // 再重新放回 |
VIDIOC_STREAMOFF | 停止视频的采集 int off= 1 ; ioctl(video_fd , VIDIOC_STREAMOFF, &off); |