V4L2较V4L有较大的改动,并已成为2.6的标准接口,函盖video\dvb\FM...,多数驱动都在向V4l2迁移。更好地了解V4L2先从应用入手,然后再深入到内核中,结合物理设备/接口的规范实现相应的驱动。本文先就V4L2在视频捕捉或camera方面的应用框架进行探讨。
V4L2采用流水线的方式,操作更简单直观,基本遵循打开视频设备、设置格式、处理数据、关闭设备,更多的具体操作通过ioctl函数来实现。
1.打开视频设备
在V4L2中,视频设备被看做一个文件。使用open函数打开这个设备:
// 用非阻塞模式打开摄像头设备 int cameraFd; cameraFd = open("/dev/video0", O_RDWR | O_NONBLOCK, 0); // 如果用阻塞模式打开摄像头设备,上述代码变为: //cameraFd = open("/dev/video0", O_RDWR, 0);
应用程序能够使用阻塞模式或非阻塞模式打开视频设备,如果使用非阻塞模式调用视频设备,即使尚未捕获 到信息,驱动依旧会把缓存(DQBUFF)里的东西返回给应用程序。
2. 设定属性及采集方式
打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux编程中,一般使用ioctl函数来对设备的I/O通道进行管理:
int ioctl (int __fd, unsigned long int __request, .../*args*/) ;
在进行V4L2开发 中,常用的命令标志符如下(some are optional):
- VIDIOC_REQBUFS:分配内存
- VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址
- VIDIOC_QUERYCAP:查询驱动功能
- VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式
- VIDIOC_S_FMT:设置当前驱动的频捕获格式
- VIDIOC_G_FMT:读取当前驱动的频捕获格式
- VIDIOC_TRY_FMT:验证当前驱动的显示格式
- VIDIOC_CROPCAP:查询驱动的修剪能力
- VIDIOC_S_CROP:设置视频信号的边框
- VIDIOC_G_CROP:读取视频信号的边框
- VIDIOC_QBUF:把数据从缓存中读取出来
- VIDIOC_DQBUF:把数据放回缓存队列
- VIDIOC_STREAMON:开始视频显示函数
- VIDIOC_STREAMOFF:结束视频显示函数
- VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。
2.1检查当前视频设备支持的标准
在亚洲,一般使用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: