嵌入式Linux:V4L2视频采集操作流程和接口说明

baskMMU 2011-05-08

一般操作流程(视频设备):

1. 打开设备文件。 int fd=open("/dev/video0",O_RDWR);
2. 取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability
3. 选择视频输入,一个视频设备可以有多个视频输入。VIDIOC_S_INPUT,struct v4l2_input
4. 设置视频的制式和帧格式,制式包括PAL,NTSC,帧的格式个包括宽度和高度等。
VIDIOC_S_STD,VIDIOC_S_FMT,struct v4l2_std_id,struct v4l2_format
5. 向驱动申请帧缓冲,一般不超过5个。struct v4l2_requestbuffers
6. 将申请到的帧缓冲映射到用户空间,这样就可以直接操作采集到的帧了,而不必去复制。mmap
7. 将申请到的帧缓冲全部入队列,以便存放采集到的数据.VIDIOC_QBUF,struct v4l2_buffer
8. 开始视频的采集。VIDIOC_STREAMON
9. 出队列以取得已采集数据的帧缓冲,取得原始采集数据。VIDIOC_DQBUF
10. 将缓冲重新入队列尾,这样可以循环采集。VIDIOC_QBUF
11. 停止视频的采集。VIDIOC_STREAMOFF
12. 关闭视频设备。close(fd);

常用的结构体(参见/usr/include/linux/videodev2.h):

struct v4l2_requestbuffers reqbufs;//向驱动申请帧缓冲的请求,里面包含申请的个数
struct v4l2_capability cap;//这个设备的功能,比如是否是视频输入设备
struct v4l2_input input; //视频输入
struct v4l2_standard std;//视频的制式,比如PAL,NTSC
struct v4l2_format fmt;//帧的格式,比如宽度,高度等

struct v4l2_buffer buf;//代表驱动中的一帧
v4l2_std_id stdid;//视频制式,例如:V4L2_STD_PAL_B
struct v4l2_queryctrl query;//某一类型的控制
struct v4l2_control control;//具体控制的值

1。User controlls其实就是一些用户可以用来进行设置的一些属性,如视频中的brightness等,

video4linux就提取出了最常见的一些设 置,给他们分配了ID,这样大家对于这些常见的设置,

就是用这些ID就可以了,可以察看当前设备对该设置的值,也可以给该设置新值,此外,

由于某些设置包 含很多子设置项,因此就又有了menu的含义,即对于一个具体的control,

我们在列举他的属性时,发现其类型是包含了menu的,那么我们就可以以 这个control的id为参数,

察看其menu及各自的值。当然用户可以由自定义的control以及extended control。

好像是Camera Control ID中就有可以设置focus聚焦的control id,这个可以看一看。

2。Data format 应用是可以和device针对通信的数据进行谈判的,即可以设置device所使用的数据的格式,

可以获得设备所使用的数据的格式,也可以尝试一下某种格 式的数据设备是否支持。

使用 VIDIOC_G_FMT and VIDIOC_S_FMT ioctls,而VIDIOC_TRY_FMT 就是用来试一下某设置是否被设备支持,

而且只是 测试,并不会起作用。我们还是可以用VIDIOC_ENUM_FMT来列举设备所支持的所有的image的格式的。

关于数据格式,在video中就会涉及到image的格式,大小(宽度,高度),等信息。
3. crapping和scaling
就是把得到的数据作一定的剪裁,和伸缩,剪裁可以只取样我们可以得到的图像大小的一部分,
剪裁的主要参数是位置和长度以及宽度,而scale的设置是通过VIDIOC_G_FMT and VIDIOC_S_FMT 来获得和
设置当前的image的长度,宽度来实现的。看下图

我们可以假设bounds是最大的能捕捉到的图像范围,defrect是我们的设备能够得到的最大的范围,
这个可以通过VIDIOC_CROPCAP的ioctl来获得设备的crap相关的属性 v4l2_cropcap ,
其中的bounds就是这个bounds,其实就是上限。每个设备都有个默认的取样范围,就是defrect,
就是default rect的意思,它比bounds要小一些。这个范围也是通过VIDIOC_CROPCAP的ioctl来
获得的 v4l2_cropcap 结构中的defrect来表示的,我们可以通过 VIDIOC_G_CROP and VIDIOC_S_CROP
来获取和设置设备当前的crop设置。

相关推荐