V4L2 简介
1.什么是video4linux
为程序定义的数据结构 1 typedef struct v4l_struct 2 { 3 int fd; 4 struct video_capability capability; 5 struct video_channel channel[4]; 6 struct video_picture picture; 7 struct video_window window; 8 struct video_capture capture; 9 struct video_buffer buffer; 10 struct video_mmap mmap; 11 struct video_mbuf mbuf; 12 unsigned char *map; 13 int frame; 14 int framestat[2]; 15 }vd;
(3)video_channel 关于各个信号源的属性
(4)video_window //包含关于capture area的信息
(5)video_mbuf //利用mmap进行映射的帧的信息
(6)video_buffer 最底层对buffer的描述
(7)video_mmap //用于mmap
4.关键步骤介绍
(2)读video_capability 中信息
(3)读video_picture中信息
(4)改变video_picture中分量的值 (可以不做的)
(5)初始化channel (可以不做的)
重点:截取图象的两种方法
(1)设置picture的属性
(2) 初始化video_mbuf,以得到所映射的buffer的信息
(3)可以修改video_mmap和帧状态的当前设置
(4)将mmap与video_mbuf绑定
(5)Mmap方式下真正做视频截取的 VIDIOCMCAPTURE
(6)调用VIDIOCSYNC等待一帧截取结束
2,视频截取的第二种方法:直接读设备
什么是video4linux 一Video4linux2(简称V4L2),是linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video0下。
二、一般操作流程(视频设备):
三、常用的结构体(参见/usr/include/linux/videodev2.h): struct v4l2_requestbuffers reqbufs;//向驱动申请帧缓冲的请求,里面包含申请的个数 struct v4l2_buffer buf;//代表驱动中的一帧
下面具体说明开发流程(网上找的啦,也在学习么)
打开视频设备 在V4L2中,视频设备被看做一个文件。使用open函数打开这个设备: // 用非阻塞模式打开摄像头设备 int cameraFd; cameraFd = open(“/dev/video0″, O_RDWR | O_NONBLOCK, 0); // 如果用阻塞模式打开摄像头设备,上述代码变为: //cameraFd = open(”/dev/video0″, O_RDWR, 0);
关于阻塞模式和非阻塞模式 应用程序能够使用阻塞模式或非阻塞模式打开视频设备,如果使用非阻塞模式调用视频设备,即使尚未捕获到信息,驱动依旧会把缓存(DQBUFF)里的东西返回给应用程序。
设定属性及采集方式 打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux编程中,一般使用ioctl函数来对设备的I/O通道进行管理: extern int ioctl (int __fd, unsigned long int __request, …) __THROW; __fd:设备的ID,例如刚才用open函数打开视频通道后返回的cameraFd; __request:具体的命令标志符。 在进行V4L2开发中,一般会用到以下的命令标志符:
这些IO调用,有些是必须的,有些是可选择的。
检查当前视频设备支持的标准 在亚洲,一般使用PAL(720X576)制式的摄像头,而欧洲一般使用NTSC(720X480),使用VIDIOC_QUERYSTD来检测: v4l2_std_id std; do { ret = ioctl(fd, VIDIOC_QUERYSTD, &std); } while (ret == -1 && errno == EAGAIN); switch (std) { case V4L2_STD_NTSC: //…… case V4L2_STD_PAL: //…… }
设置视频捕获格式 当检测完视频设备支持的标准后,还需要设定视频捕获格式: struct v4l2_format fmt; memset ( &fmt, 0, sizeof(fmt) ); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = 720; fmt.fmt.pix.height = 576; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) { return -1; } v4l2_format结构体定义如下: struct v4l2_format { enum v4l2_buf_type type; // 数据流类型,必须永远是//V4L2_BUF_TYPE_VIDEO_CAPTURE union { struct v4l2_pix_format pix; struct v4l2_window win; struct v4l2_vbi_format vbi; __u8 raw_da } fmt; }; struct v4l2_pix_format { __u32 width; // 宽,必须是16的倍数 __u32 height; // 高,必须是16的倍数 __u32 pixelformat; // 视频数据存储类型,例如是//YUV4:2:2还是RGB enum v4l2_field field; __u32 bytesperline; __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; };
附官方V4L2详细API手册http://www.51soc.com/pdf/v4l2.pdf |