陈沧毅,路林吉
目前视频监控和录制主要采用摄像头、硬盘录像机、录像等组成视频监控网,该类视频监控网络具有工作稳定可靠的优点。但是在某些特殊工作现场,如无人值守的仓库、大规模的森林,以及高速的交通工具等,当发生事故或灾情后,往往由于现场的破坏和时效性,而难以分清责任和分析事故原因。因此,对事故易发点的连续视频监控就尤为重要。
比如在高速行驶的机动车上发生车祸,绝大多数情况需要掌握的事故原因集中在事故之前很短的一段时间。因此,分清事故责任和分析事故原因,所需要的视频信息大部分在事故时间点之前的几十分钟之内。换句话说,除了这几十分钟的信息,其它几天、几个月,甚至几年的视频监控信息都属于冗余信息。
有鉴于此,本文提出了利用嵌入式系统,实现视频信息的循环录制,只保留最后时刻视频信息的便携式连续视频监控系统,并在Linux系统的基础上得以实现[1]。
在本系统研究中,采用了目前比较常见的MINI2440开发板,是目前国内性价比较高的一款学习板;它采用Samsung S3C2440为微处理器,并采用专业稳定的CPU 内核电源芯片和复位芯片来保证系统运行时的稳定性。在处理器丰富资源的基础上,对系统硬件进行了相关的配置和扩展,平台配置了64MB的Flash和64MB的SDRAM,通过USB接口外接USB摄像头和U盘,实现了整个硬件平台的搭建[2]。
Video4Linux是Linux系统视频采集软件的总接口。各种网络摄像头,视频采集卡,电视卡以及类似的设备均归类于视频采集领域,Video4Linux为此提供了一整套相应的API接口。由于各个设备均有自己独立的特性,Unix系统均在此基础上进行了抽象,本着一切均是文件的设计思想,只需要进行 open()方法即可打开设备文件,read()/write()分别是对该设备进行读写传输数据,ioctl()则是对设备参数配置。
除了 read()/write()读写的方法,Video4Linux特别提供了内存映射接口 mmap()直接将设备内存映射到用户进程的地址空间中,这样用户可以直接在进程中读写内存来控制设备,为视频压缩争取了时间,有效地提高了视频采集速度。
FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案。FFmpeg的开发是基于 Linux操作系统,但是可以在大多数操作系统中编译和使用,包括windows系统等。FFmpeg支持MPEG、DivX、MPEG-4、AC3、DV、FLV等40多种编码,AVI、MPEG、OGG、Matroska、ASF等90多种解码。
FFmpeg库支持多平台运行,包括Linux、Windows和M ac OS等系统。本设计将FFmpeg移植到ARM9架构的系统上,通过交叉编译生成运行库[4]。
FFmpeg主目录下主要有 libavcodec、libavformat和libavutil等子目录。其中 libavcodec用于存放各个encode/decode模块,libavformat用于存放 muxer/demuxer模块,libavutil用于存放内存操作等常用模块。
利用ffmpeg库生成视频文件,需要用到两个贯穿始终的数据结构:struct AVFormatContext和struct AVStream。
图1 用FFmpeg库生成视频文件的基本流程
struct AVFormatContext包含了一个视频流的格式内容,如所采用的编码器(本文采用的是MJPEG的格式)等重要信息。而struct AVStream则包含了“流”这个概念中的一些数据,比如:帧率、基本时间计量单位、首帧位置、持续时间、帧数以及帧数据本身等等。基于FFmpeg库生成视频文件的基本流程见图一。
为了编译成 ARM 上执行的二进制程序,需要对configure文件和 Makefile文件进行手动修改,./configure–help命令可以得到有用的信息。
然后执行make,make install。此步后,将生成所需要的二进制工具ffmpeg和ffserver。其中ffmpeg用于对媒体文件进行处理或视音频设备进行操作,ffserver是一个http的流媒体服务器。另外生成两个库文件 libavcodec.so和libavformat.so。这两个库文件将是未来设计的重点。
这部分的工作是整个设计的核心。一般来说对视频信息的循环录制均采用日志处理的方法,即通过多文件实现循环录制。这种方式经常伴随着一个明显的缺陷是两个文件中间存在视频数据丢失现象。另外一种方案是通过对索引块信息进行修改,使其达到随机存取的能力,这种方式编程繁琐,效果欠佳,尤其在FFmpeg体系下,时间轴控制起来涉及较底层代码,这里不推荐采纳。笔者认为,采用第一种方案存在丢帧现象完全可以从软件代码设计有效避免,且通过该方案可以清楚记录下每一段视频的拍摄时间,极大方便了未来的查阅检索。如果觉得多文件观察起来较为繁琐,该设计还提供了视频自动按照时间顺序合成的脚本。
3.3.1 检测日志文件及读取记录
为了达到循环录制的功能,需要在 U盘空间吃紧时删除早些时间录制的文件,因而获取当前删除序号数至关重要,保证了日志文件与现有视频的数据同步。
3.3.2 FFmpeg重要函数解析
表1 FFmpeg基本函数功能简介
av_write_frame(AVFormatCo ntext *s,AVPacket *pkt)件int av_write_trailer(AVFormatCo ntext *s)写入流结尾信息到指定输出文件并释放内存数据。
表1列举了部分FFmpeg库重要函数的功能,具体可以参见源码。这些函数均是基于FFmpeg编程的基础。
3.3.3 采用MJPEG编码方式
Motion JPEG(MJPEG)是一种视频压缩格式,其中每一帧图象都分别使用JPEG编码。同样格式的MJPEG视频压缩不同于帧间压缩,因为压缩位元率比较低,所以编码与解码相对比较容易,并不需要过多的运算能力,符合ARM嵌入式的设计需求。此外,一些移动设备,如手机、数码相机也常使用MJPEG来进行短片的编码。该编码的主要缺陷是压缩效率不高,文件尺寸相对较大,但由于现在 U盘设备价格已经十分低廉,因而在对硬件系统要求不高的地方应用还是相当广泛的。
MPEG-4是另外一种较为成熟的编码方式,主要针对视频会议、可视电话的超低比特率编码需求,一般在嵌入式系统中应用需采用专用的压缩芯片完成,成本较高,这也是本设计没有采纳的主要原因[6]。
3.3.4 实现循环录制功能
文献[1]中提到使用多文件录制视频会存在丢帧现象,可能是因为某些视频录像机录制文件时,针对每一个文件均是同样的处理流程,换句话说,就是每次录制过程均是上一次过程的简单重复,这样势必导致在处理视频文件结尾的时候部分帧丢失,前后文件不连续等现象。
本系统采取的方法是多线程帧控制法,即当视频将达到指定帧数时,开辟新线程对新的文件进行初始化;当视频达到指定帧数时,开辟新线程作后期处理并关闭文件。如此循环往复,自然将每一帧信息均完整保存下来。
3.3.5 系统主体设计流程概览
图2 主线程运行流程图
图3 视频采集线程工作流程
图4 按键监听线程工作流程
程序编写完成后,就可以通过宿主机使用交叉编译器编译连接生成可执行文件,并向目标机移植后运行。
软件参数设定:
窗口大小:640×480
帧率:15fps
单个文件帧数:9000
通过长达5个多小时的视频录制测试,软件工作正常,视频质量稳定,从未出现丢帧或花屏现象,清晰度流畅性极佳。当达到硬盘空间极限时,系统自动删除早期文件,对视频正常录制过程没有任何影响。实验表明,在嵌入式Linux系统上实现循环录制是完全可行的。
本文根据特殊工作现场对循环视频监控系统要求,在嵌入式Linux系统中实现了视频循环录制的功能。程序运行结果表明该设计方案运行可靠,符合实际工程需求,其主要特点如下:
1. 系统采用一般的USB摄像头,价格低廉,极大节约了成本。
2. 采用基于 Linux的嵌入式视频监控系统解决方案,功能扩展性强,能支持多种硬件接口。
3. 系统可进行循环录制,即自动探测U盘空间,删除早期数据,实现滚动更新功能。用户可随时选择时间段下载数据。
4. 整个系统体积小巧,安装方便,适合各种工作场合。
[1]刘少刚,王学军.基于嵌入式Linux系统的单个AVI文件视频循环录制的研究[J].哈尔滨:林业机械与木工设备,2008.
[2]广东友善之臂计算机科技有限公司 Mini2440用户手册[Z].2007.
[3]陈云鹤.基于嵌入式Linux的视频信号实时采集系统的设计[D].华中科技大学2006.
[4]吴张顺,张旬.基于FFmpeg的视频编码存储研究与实现[J].杭州:杭州电子科技大学学报.2006.
[5]Epplin J,Linux as an Embedded Operating System[M],Embedded Systems Programming,1997.