分类: LINUX
2011-05-06 19:52:44
4)设备的控制操作
通过设备驱动程序中的函数ioctl()来完成。ioctl()的用法与具体设备密切关联,因此需要根据设备的情况进行具体分析。
5)设备的中断和轮流查询处理
由于有些硬件设备不支持中断,那么在对其读写时需要轮流查询设备状态,以便决定是否继续进行数据传输。如果硬件设备支持中断,则可以按中断方式进行操作。
4.2 视频采集
在USB 摄像头驱动被加载成功后,还要编写视频流采集应用程序。摄像头中各种I/O口的控制依靠Video4Linux 提供的应用程序接口函数实现,主要有Open、Read、Write 等。V4L 下的视频采集工作原理如图3。在本系统中,将有关摄像头的各种数据和结构封装成了一个类。
图3 V4L 下视频采集工作模型
4.2.1Video4Linux 定义的数据结构
struct video_capability capability:包含摄像头设备的基本信息(设备名称、支持的最大最小分辨率、信息等) , 分别对应着结构体中成员变量[32], maxwidth,maxheight,minwidth, minheight, channels(信号源个数),type等。
struct video_window window:包含采集到图像的各种属性,如brightness(亮度)、hue(色调)、color(颜色)、contrast(对比度)、whiteness(色度)、depth(深度)等。
struct video_channel channel:关于各个信号源的属性,如channel(信号源编号)、name(名称)、tuners(信号源通道)、type(类型)、(制式)等。
struct video_picture picture:包含关于capture area 的信息。
struct video_mmap mmap:用于内存映射。
struct video_mbuf mbuf:利用mmap 进行映射的帧信息,即输入到摄像头存储缓冲区中的帧信息,包括size(帧的大小)、s(最多支持的帧数)、offsets(每帧相对基址的偏移)。
在本系统中,程序主要用到的一些系统调用函数如下:
open (“/dev/video0”,O_RDWR):设备的打开。
close(fd):设备的关闭。
mmap(void *addr,size_t len,int prot,int flags,int fd,off_t offset):设备缓冲区到内存空间的映射。
munmap(void *addr,size_t len):采集工作结束后取消mmap 和mbuf 的绑定。
ioctl(int fd,int cmd,...):控制I/O 通道。
4.2.2 视频采集程序的实现
1)打开摄像头
首先对上面提到的类进行初始化,接下来利用系统调用函数_fd=open (“devfile”,O_RDWR),该函数的功能是打开参数devfile 指定的设备,对于摄像头用设备文件名“/dev/video0”表示,_fd 是设备打开后返回的文件描述符,以后可以直接使用它来对设备文件进行操作。
2)获取摄像头参数
通过 ioctl(_fd,VIDIOCGCAP,&capability)函数来读取struct video_capability 结构中有关摄像头的信息。ioctl(int _fd ,int cmd,...)主要是用来控制I/O 通道,函数成功返回后使用printf函数得到各成员分量信息,接着调用ioctl(_fd,VIDIOCGWIN, &window)和ioctl(_fd,VIDIOCGPICT , &picture) 函数读取struct video_window 信息和摄像头缓冲区中的video_picture 图像信息。
3)设置摄像头缓冲区中图像参数
在采集摄像头视频数据前,可根据需求修改图像参数如分辨率等,具体方法为先给分量赋新值,再调用函数ioctl(_fd,VIDIOCSPICT,&picture)。
4)视频数据的读取与 read()方式相比,mmap()方式通过把设备文件映射到内存,绕过了内核缓冲区,加速了I/O 访问。完成内存映射之后,就可以用mmap()方式实现对内存映射区域视频数据的单帧采集。此方式下真正做视频截取的为VIDIOCMCAPTURE,调用函数ioctl(_fd ,VIDIOCMCAPTURE,&mmap),激活设备并真正开始一帧图像的截取,是非阻塞的,接着调用ioctl(_fd,VIDIOCSYNC,&frame)函数等待一帧图像截取结束,成功返回表示一帧截取已完成,接着可以做下一次的VIDIOCMCAPTURE 操作。
经过上述的几个过程,系统完成了对 USB 摄像头的驱动、对视频数据的采集工作,捕获到的视频帧被映射到内存区域,如果要对视频数据进行压缩等处理工作则可通过访问内存映射区域进行。