【摘要】v4L2(VideoForLinuxTwo)是Linux系统下进行图象、视频开发的应用编程插口。本文首先剖析V4L2的图象采集驱动和流程,之后在Linux环境下设计并实现视频采集终端程序设计,并在天嵌S3C2440的ARM板开发平台上移植嵌入式视频采集终端。与此同时,还在ARM开发板上实现实时动态采集视频图象的播放。本文对视频采集的设计方式和监控系统的前端处理具有实用价值。
【关键词】V4L2;嵌入式;Linux
一、引言
嵌入式系统是将操作系统和功能软件集成于计算机硬件系统中,进而实现软件与硬件一体化的计算机系统。嵌入式系统的容积小、功能专情、裁剪性能好、功耗低、可靠性能高、集成度高。随着微电子技术和计算机软件技术的发展,嵌入式系统不但在军事和工业控制领域得到广泛应用,而且在通讯、办公手动化和消费电子领域也获得普及[2]。每年在全球范围内的电子产品产值大约在20亿左右,其中80%以上应用于各种专用性很强的嵌入式系统中。
二、本文的设计研究方向和目的
人类传递信息主要借助的是语音和图象。在人类接受信息过程中,通过视觉得到的信息抢占一半以上,所以作为信息传递的重要媒体的图象信息占有非常重要的地位。本文正是针对人们对图象信息的需求以视频监控系统为研究背景,设计了基于Linux的嵌入式视频采集系统。本文通过ARM板作为硬件开发平台,熟悉基于嵌入式Linux操作系统的视频图象采集,把握嵌入式系统开发的基本技术。本文研究的内容,适应当前嵌入式开发领域的发展,能丰富嵌入式技术的内容,具有一定的研究价值。
三、嵌入式Linux视频采集系统设计
在Liunx系统下,所有外设都被看成是一种特殊的文件,称为设备文件[3]。V4L2是VideoForLinuxTwo的简称作为Linux系统下的一种通用视频构架,应用于许多嵌入式视频设备之中,V4L2为Linux的视频驱动提供了统一的插口,使应用程序可以使用统一的API函数操作不同的视频设备。
V4L2图象采集程序流程过程分为打开视频设备、设置图片格式、分配缓冲区、读取数据、关闭设备等步骤[4]。以下是本文通过使用V4L2应用编程插口提供的有关数据结构定义和函数,编撰的视频图象采集程序。程序流程如图1所示。
(一)打开视频设备文件:i
打开视频设备后,open()函数获得文件描述intfd.。使用阻塞模式,只有数据打算充分时驱动才可以把缓存的数据返回给应用程序。本系统保持默认的阻塞模式。
(二)读取视频设备的属性:
在Linux程序设计中,ioctl调用提供了一个用于控制设备及其描述符行为和配置底层服务的插口,对设备的I/O通道进行管理,其句型为:ioctl(intfd,intrequest,void*argp)。其中fd为设备文件描述符linux 虚拟主机,通过open()函数获得;request为系统调用命令类型,用于告诉系统要完成的任务(即向系统发出的命令);argp为用户数据表针,用于传递参数或接收数据。以下是几种常用的命令类型和对应的数据结构,这种类型都在videodev.h中进行了定义[1]:
VIDIOC_QUERYCAP,获取视频设备的属性,主要包括驱动名称,设备名称,设备在系统中的位置等。数据类型为structv4l2_capablility。
VIDIOC_ENUM_FMT,显示视频设备所有支持的格式,主要参数包括:要查询的格式序号,帧类型,是否为压缩格式等。数据类型为structv4l2_fmtdesc。
VIDIOC_G_FMT/VIDIOC_S_FMT,获取/设置数据格式,主要是图片的宽高、每象素所占bit和象素格式。数据类型为structv4l2_format。
VIDIOC_REQBUFS,用于显存映射方法,该命令可以在驱动层申请多个缓冲区储存采集到的图片。须要注意的是须要使用mmap将其映射到用户空间能够访问。数据结构类型为v4l2_requestbuffers。
VIDIOC_QUERYBUF,用于显存映射方法,该命令可以查询由VIDIOC_REQBUFS申请到的缓冲区的大小和偏斜地址,这两个热阻会作为参数传给mmap。数据结构类型为structv4l2_buffer。
VIDIOC_QBUF,用于显存映射方法,该命令的作用是将VIDIOC_REQBUFS申请的缓冲区装入采集队列,只有这样驱动就会将采集到的数据写入缓冲区。数据结构为structv4l2_buffer。
VIDIOC_DQBUF,用于显存映射方法嵌入式linux应用程序开发标准教程,该命令的作用是将填充数据的一个缓冲区取出队列。须要注意的是,应用程序处理完数据后,须要使用VIDIOC_QBUF重新将该缓冲区装入采集队列。
VIDIOC_STREAMON/VIDIOC_STREAMOFF,这两个命令用于启动/停止视频数据的采集或输出。数据结构为enumv4l2_buf_type。
(三)设置图象采集格式
将fmt结构填入适当的值,之后通过传递VIDIOC_S_FMT命令参数对设备的图象采集格式进行初始化,如上所示,将视频图象采集格式设为YUYV格式,大小设为176x144。
(四)分配缓冲区
1.在显存中申请缓冲区来储存读取的视频图象
V4L2支持三种数据交换模式,分别是:直接读取设备文件形式(read/write)、用户表针形式(userptr)以及mmap映射方法[5]。mmap映射方法:这些方法与用户表针方法类似,只是采用了逆向操作。首先在内核空间申请多个缓冲区,之后将每位缓冲区通过mmap映射到用户空间,这样驱动和应用程序共享那些缓冲区,在进行数据处理时不须要进行拷贝,大大提升了效率。在本文设计中,采取mmap映射方法。
调用ioctl()函数采用VIDIOC_REQBUFS命令分配自定义的缓存数目,这在初始化中是必须的一步,以下为视频采集分配显存的结构体函数:
分配用户显存,之后借助for循环中分别对各个缓存进行映射,其偏斜量和缓存大小在命令在VIDIOC_QUERYBUF命令参数额ioctl函数中定义,最后用mmap()函数将在设备缓存和应用程序所分配显存见构建映射,并返回应用程序显存的首地址。
2.获取申请到的缓冲帧地址
调用VIDIOC_QBUF命令参数的ioctl函数在for循环上将空缓存加入等待输入缓存队列,在缓存加入等待输入队列后。
(五)启动采集过程,读取数据
调用ioctl的VIDIOC_STREAMON命令开始视频采集。这儿采用mmap映射方法。把设备里的显存映射到应用程序中的显存控件,直接处理设备显存。
V4L2有一个数据缓存,储存req.count数目的缓存数据。数据缓存采用FIFO的方法,当应用程序调用缓存数据时,缓存队列将最先采集到的视频数据缓存送出,并重新采集一张视频数据。
(六)结束视频采集
当视频采集活动结束的时侯,须要使用VIDIOC_STREAMOFF命令停止视频采集linux 内核,调用close函数关掉视频设备。
ioctl(fd,VIDIOC_STREAMOFF,&type);//停止视频采集
close(fd);//关掉视频设备
因为ARM开发板不能直接播放YUYV格式的视频流,须要把采集到的YUYV格式的图象转化为ARM还能辨识和播放的RGB格式。图2为ARM板的显示屏上为系统传输的实时图象。
四、结束语
本文通过对视频采集系统的设计与实现,实现了视频图象的实时传输与播放,借以深入地了解了嵌入式Linux视频采集系统工作流程和Linux操作系统的构架原理。本文的视频采集系统具有结构组成简单,运行快捷,调试便捷,成本低廉等特征,为现有的视频监控提供系统的提够了一套简洁的视频采集方式,同时为嵌入式系统视频采集系统的设计开发提供一条简单的思路。
参考文献
[1]华清远见嵌入式培训中心.嵌入式Linux应用程序开发标准教程(第二版)[M].南京:人民邮电出版社,2009.
[2]韦东山.嵌入式Linux应用开发完全指南[M].上海:人民邮电出版社,2008.
[3]王红200.操作系统原理及应用(Linux)[M].上海:中国水利出版社,2005.
[4]杨路明.C语言程序设计教程[M].上海:上海邮电学院出版社,2005:65-67.
[5]陈亮,裴海龙嵌入式linux应用程序开发标准教程,伍越.基于Video4Linux2的图象采集程序设计[J].数采与检测,2009(22).
作者简介:
陈少祥(1986—),男,江苏南通人,硕士研究生,现就读于西安科技学院。
李临生(1959—),男,西安科技学院院长,研究方向:现代数字讯号处理,DSP应用和小波讯号剖析。