汽车记录仪中视频取证系统的研究与设计孙晓磊,潘海澄,玄祖广大连海事大学计算机学院,辽宁大连(116026)E-mail:sunxiaolei198010@163.com摘要:本文介绍了基于三星公司的ARM处理器S3C2410X为核心的嵌入式系统平台上的设计和开发。本系统设计的汽车记录仪实现了视频取证,通过摄像头采集事故发生前后车前的录像,可以真实地再现事故发生的全过程。此外,汽车行驶记录仪还具有防盗功能,也可以通过GPS全球定位系统确定汽车的位置。本系统设计中采用了嵌入式操作系统uClinux并对其移植过程进行一定的研究。关键词:S3C2410X微处理器;视频取证;汽车记录仪;嵌入式操作系统uClinux1引言汽车行驶记录仪是一种使用在汽车上的数字式电子记录装置。这种装置能对车辆的行驶速度、时间、里程以及有关车辆行驶的其他状态信息进行记录存储并可通过接口实现数据输出。该系统除了按照国家有关标准,对汽车的行驶状态的数据进行实时保存外,与同能产品相比,还更加注重视频方面特有的功能优势,通过软件和硬件芯片协调上作实现了视频图像的压缩和存储,能够循环存储数十分钟的视频图像。汽车行驶记录仪的使用,为分析、判断汽车行驶状态和交通事故提供可靠而准确的科学依据,对抑制疲劳驾驶、车辆超速等交通违章、约束驾驶人员的不良驾驶行为、保障车辆行驶安全以及道路交通事故的分析鉴定具有重要的作用[1]。目前,汽车行驶记录仪在可靠性、体积方面都有了较大的改善,从使用的效果来看,它不但可以在事故发生后准确的反映当时汽车的状态同时也在预防汽车事故方面取得了显著的效果。因此,越来越多得国家已成功地把嵌入式运用到了汽车记录仪上。笔者在本文中首先简单介绍了系统的硬件系统和软件系统,并扼要说明了系统的主要功能,然后详细描述该系统实现的过程,着重描述了图像采集模块的实现,最后对本系统中运用到的操作系统的特点进行了比较,并对整个系统做出了总结。2系统的总体结构2.1开发环境本系统采用的主要硬件是32位Samsung公司的处理器S3C2410X;一个USB从口,一个USB主口;IIC总线接口;一个CF卡接口;一个SD/MMC卡接口;1024*768分辨率的真彩液晶屏;16MFlash;64MSDRAM;串口等。系统结构如图1所示。的操作系统,软件配置包含了WinCE或Linux操作系统的内核源代码和所有的硬件驱动程序。其中,笔者使用的是webeyeV2000的USB摄像头,可对现场快速进行视频采集,通过USB接口可以大量、快速地传输数据,用于图片拍摄;CF卡接口可与PDA实现快速的无线传输网络;系统采用的信号都是通过汽车上的各个传感器直接采取,通过频压转换后送入A/D转换器进行处理;对于事故疑点数据都从FRAM中采样,将其结果存进Flash存储器中进行存储记录。2.2汽车行驶记录仪系统组成本系统以S3C2410目标板为中心,主要包括摄像头视频取证模块、GPS模块和GPRS模块。本文中主要介绍基于V4L设计的视频图像采集模块。取证摄像头负责视频取证,监控摄像头负责监视车内状况,倒车摄像头辅助车主观察车后视觉死角;GPS模块接收地理信息数据,对现场地理位置进行精确定位,以便系统上传现场趣味,有利于在紧急状况下进行有效处理。3视频图像采集的实现由于系统使用USB摄像头来采集图像,因此必须在嵌入式Linux系统中加载相应的USB摄像头驱动。在实际设计中选用的摄像头是网眼公司的V2000USB摄像头,之所以选用这个型号的摄像头是因为其使用的USB摄像头芯片是Linux内核公开支持驱动程序的ov511芯片,如果是使用其它芯片的摄像头还要自己编写驱动程序,这将大大增加系统的开发难度和时间。在Linux下使用视频采集设备需要加载Video4Linux驱动和摄像头设备驱动。Video4Linux是Linux关于视频设备的内核驱动,它为使用视频设备的应用程序提供了一系列函数接口。这将在后面详细地介绍。3.1摄像头驱动的安装笔者选用的摄像头驱动是spca5xx驱动,这是一个Linux下的通用驱动。第一步,从网站下载该驱动程序,安装步骤如下:tarxfzspca5xx-20060402.tar.gz汽车的信号数据信号处理S3C2410ARM宿主机USB主从口FLASHFRAMSDRAM第二步,内核配置首先检查LinuxKernel中是否已经添加了USB模块的支持,并且加入Video4Linux支持。Multimediadevices→<M>VideoForLinuxVideoForLinux→[*]V4Linformationinprocfilesystem在主菜单的USBSupport下还有各种摄像头的驱动,选中将要使用的摄像头芯片类型。<>USBIBM(Xirlink)C-itCamerasupport<*>USBOV511Camerasupport<>USBPhilipsCameras<>USBSE401Camerasupport<>USBSTV680(Pencam)Camerasupport<>USB3comHomeConnect(akavicam)support在USB摄像头选购时,优先考虑Linux内核公开支持的摄像头芯片,不然要额外编写相应的USB摄像头驱动程序,然后进行编译、安装。在此选用网眼公司的V2000产品,采用了OV511的芯片。在系统平台上对USB数码摄像头驱动,首先把USB控制器驱动模块静态编译进内核,使平台中支持USB接口,再在需要使用摄像头采集时,使用insmode动态加载其驱动模块,这样摄像头就可以正常工作了。3.2基于V4L设计的视频采集模块视频采集的关键时如何从USB摄像头读取数据,实现该功能主要是调用V4L的应用函数。V4L是Linux中关于视频设备的内核驱动,它为针对视频设备的应用程序编程提供了一系列接口函数。摄像头在系统中对应的设备文件为/dev/video0。Linux下视频采集流程如下[2]:(1)打开视频设备;(2)读取设备信息;(3)更改设备当前设置;(4)进行视频采集,有两种方法:一种是内存映射,另一种是直接从设备读取;(5)对采集的视频进行处理;(6)关闭视频设备。下面对其中的关键步骤进行说明[3]。1.打开视频设备。摄像头在系统中对应的设备文为/dev/video0,采用系统调用函数dev=open(/dev/video0,ORDWR)开视频设备,dev是设备打开后返回的文件描述符(打开错误返回一1),以后的系统调用函数就可用它来对设备文件进行操作了。2.读取设备中信息:ioctl(vd-fd,VIDIOCGCAP,&(vd-capability)),成功后可读取vd-capability结构中各分量的值,如printf(maxheight=%dvd-capability.maxheight);3.读video_picture中信息:ioctl(vd-fd,VmIOCGPICT,&(vd-picture));4.改变video_picture中分量的值。先为分量赋新值,再调用VTDIOCSPTCT命令,如vd-picture.colour=32768;(ioctl(vd-fd,VIDIOCSPICT;&(vd-picture))0){perror(VIDIOCSPICTERROR);return-1;}5.初始化channel。首先必须得到vd-capability结构中的信息。实现过程如下:for(i=0;ivd-capability.channels;i++){vd-channel[i].channel=i;if(ioctl(vd-fd,VIDIOCGCHAN,&(vd-channel[i})0){perror(v4l_get_channel:);return-1;}}6.视频采集。要进行视频图像的采集,必须有存放图像的地方,因此,应申请足够大的内并将其映射到用户态空间。这样,用户态空间的图像处理程序就可以使用mmap()函数,直接读写内核态帧缓冲区,减少了额外开销。要进行视频捕捉还要用到VIDIOCMCAPTURE和VIDIOCSYNC两个ioctl函数。VIDIOCGMBUF包含有所用缓冲器的设置与地址,VIDIOCMCAPTURE用于开始捕捉,VIDIOCSYNC用于等待捕捉完成。为加快数据处理速度,一般使用双缓冲设置,即buffer0捕捉数据时,buffer1传输数据:buffer1捕捉数据时,buffer0传输数据。完成以上初始化设备工作后,就可以对视频图像采集与截取了,通常情况下有两种方法:一种是read()直接读取,另外一种mmap()内存映射。read()通过内核缓冲区来读取数据,而mmap()通过把设备文件映射到内存中,绕过了内核缓冲区,最快的磁盘访问往往还是慢于最慢的内存访问,所以mmap()方式加速了I/O访问。另外,mmap()系统调用使得进程之间通过映射同一文件实现共享内存,各进程可以像访问普通内存一样对文件进行访问,访问时只需要使用指针而不用调用文件操作函数。因为mmap()的以上优点,所以在程序实现中采用了内存映射方式,即mmap()方式。利用mmap()方式对视频进行采集与裁剪的操作如下。①先使用ioctl(vd-fd,VIDIOCGMBUF,&vd-mbuf)函数获得摄像头存储缓冲区的帧信息,之后修改video_mmap中的设置,例如重新设置图像帧的垂直及水平分辨率、彩色显示格式以及当前顷的状态。可利用如下语句vd-mmap.height=120;vd-mmap.width=160;vd-mmap.format=VIDEO_PALETTE_RGB24;vd-framestat[0]=vd-framestat[1]=0;vd-frame=0;②接着把摄像头对应的设备文件映射到内存区,命令为vd-map=(unsignedchar*)mmap(O,vd-mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd-fd,0)。这样设备文件的内容就映射到内存区,该映射内容区可读可写并且不同进程间可共享。该函数成功时返回映像内存区的指针,失败时返回-1。下面对mmap函数中的每个参数进行说明。第一个参数表示共享内存享的起始地址,在此处设为0表示由系统分配。第二个参数表示映射到调用进程地址空间的字节数,此处为vd-mbuf.size。第三个参数指定共享内存的访问权限,(可读),PROT_WRITE(可写),PROT_EXEC(可执行),此处设为可读和可写。第四个参数指定共享内存的属性,MAP_SHARED,MAP_PRIVATE,MAP_FIXED三种属性,一般情况下从MAP_SHARED,MAP_PRIVATE中选一个,MAP_FIXED使用。③视频截取。把视频映射到内存后就可进行视频的截取。命令为ioctl(vd-fd,VIDI0CMCAPTURE,&(vd-mmap));若调用成功,开始一帧的截取,该操作是非阻塞的,是否截取完毕留给VIDIOCSYNC来判断。④调用VIDIOCSYNC等待一帧截取结束。if(ioctl(vd-fd,VIDIOCSYNC,&frame)0){perror(VIDIOCSYNCERROR!!”);return-1;}函数调用成功,表明一帧图像截取完成,可以开始进行下一次视频截取。其中frame是当前截取的