基于嵌入式Linux的视频循环录制系统
avi文件是目前使用的最复杂的RIFF文件,它包含信息块、数据块和索引块3个子块,每个子块都按照RIFF文件结构来填充各字段。其总体结构如图4所示。
avi文件有两种基本的数据结构CHUNK和LIST,其形式如图5所示。
其中,信息块是一个以“hdrl”为标识的LIST块,定义avi文件的数据格式;数据块是一个以“movi”为标识的LIST块,它保存真正的音视频数据;索引块是一个以“idxl”为标识的LIST块,为avi文件中的媒体数据块进行索引,不是必需的。详细的avi文件格式见参考文献。
3.2 视频采集
嵌入式Linux下视频采集的实现使用Linux视频驱动接口V4L2。它的操作流程如下:打开视频设备、设置视频设备属性和采集方式、处理视频数据、关闭视频设备。把视频设备当作普通文件来打开关闭,并进行数据的读写。视频设备属性的设置是通过ioctl函数来进行的,V4L2
驱动接口包含很多控制命令,对视频采集进行控制。
3.3 视频循环录制的实现
视频的循环存储是很有必要的。一方面,因本系统特点,对于事故前很长时间的视频信息没有保存下来的必要,因而可以在保存必要视频信息的前提下,当SD卡存储满的时候对最先录制的视频进行覆盖,以充分利用存储空间。
循环录制可以只在单个文件中进行,参考文献采用此方法。该方法通过修改位置指针,对存储帧数和预定义的最大帧常量进行判断,以实现循环存储。该方法实现较为繁琐,而且由于采用avi文件存储,其单个文件最大只有2G,保存的视频数据有限。本系统采用多个文件循环存储的方法。每次录制以开始录制的时间作为avi的文件名,格式为“年月日-时分秒”形式,这样便于以后查阅检索。
3.3.1 循环存储原理
循环存储的原理简单直观,首先创建一个avi文件对视频数据进行录制,当录制到文件预定义大小时,新建一个avi文件继续存储。如此一直下去,直到SD卡存储已满。当系统检测到SD卡剩余容量小于预定义的阈值时,则查找最先录制的avi文件并删除,这样便有空闲容量继续存储视频,如此往复便可实现视频的循环录制。
3.3.2 循环存储方法
根据上面的循环存储原理,按照avi视频循环存储流程可以清楚地实现循环存储,如图6所示。
系统初始化主要是对视频采集的初始化,设定采集视频的相关信息,通过init_videoIn()函数将参数传入相应的结构体,主要代码如下;
接着创建一个avi文件,以当前日期加时间作为文件名,这样便于将来对视频文件查询检索。然后就进入程序大循环,对SD卡剩余容量判断,可以保证即使更换不同容量的SD卡也能充分利用存储空间。对于SD卡剩余容量小于预定义的RESTSIZE情况,则说明SD卡剩余容量不足,这样就需要删除最早保存的视频文件。为了获取SD卡目录里的文件信息,使用了dirent结构体,查找SD卡里最早保存的avi文件是关键,其核心代码如下:
找到最早创建的avi文件后,删除它即获得足够的容量保存新的视频。对于SD卡剩余容量足够的情况,直接往avi文件写入一帧视频,这也是本设计的一个重点,在下一节介绍。若写入视频数据失败,直接跳出大循环,系统结束工作。否则,使用stat()函数对当前视频文件大小进行判断,看该avi文件是否达到预定大小。若是,则要新建一个avi文件以保证SD卡的每个avi文件大小固定且存储多个avi文件;不是,则avi文件还未达到预定大小,继续往avi文件写入一帧视频数据。如此往复,即实现视频的循环存储功能。
3.3.3 写一帧avi视频数据
向SD卡中创建的avi文件写入一帧视频,就是按照3.1节介绍的avi文件的格式,把从摄像头采集到的一帧图像保存到相应位置,同时填写必要的avi文件头信息。
打开以日期时间命名的avi文件后,设置视频相关信息,主要是视频压缩方式、视频帧大小和帧率等,然后便是填充avi文件的头信息。avi文件的头信息是其区别于其他视频文件一个重要标志,根据参考文献,头部信息主要包括2个LIST基本结构,第一个“hdrl”LIST嵌套一个“strl”LIST,其中“hdrl”是主avi信息头数据,“strl”LIST是流的头信息数据(strl可以有多个,对应多个流),它们用于保存视频流的详细信息。每个“strl”至少包含一个“strh”块(用于说明该流的头信息)和一个“strf”块(说明该流是视频流还是音频流)。第二个LIST是“movi”列表,它用来保存真正的视频音频流数据,它以4字符码“00db”(非压缩视频流)或“00wb”(非压缩音频流)等开始作为标记,接下来存储流数据。“movi”列表后是avi文件的索引块,这部分是可选的,主要是为avi文件每个数据块进行索引。填写完avi文件头部信息后,即可将采集的视频数据保存下来。
写一帧视频数据时,首先将写指针指向avi文件头的尾部,接着调用一个write_avi_data(avi_t*AVI,char*data,unsigned long length)函数,将length长度的由指针data指向的数据写入到avi指向的文件。在写真正的流媒体数据之前,先写入4字符码“00db”指示要写的是视频数据,然后是要写入的一帧数据的长度字段,最后写入一帧视频数据。
一个avi文件只有一个头部信息,即填充完avi文件头部信息后,便不断地向文件写入一帧视频数据,直到文件大小达到预定大小时,按照循环存储规则新建avi文件。
4 系统功能测试
用Linux C实现了视频采集功能、循环存储功能,将交叉编译成功后的应用程序下载到板子的根文件系统。自动挂载SD卡后执行应用程序,功能实现正常,连续长时间运行能够实现视频的循环录制。取下SD卡,把视频复制到计算机上使用视频播放器播放,视频清晰流畅。
结语
本文用嵌入式Linux实现了行车视频录制的功能。详细介绍了视频循环存储的实现和视频文件的保存。作为独立的功能部件,本系统可以方便地安装到汽车上。经过软硬件联合测试,系统工作稳定可靠,有一定的实用价值。
- Linux嵌入式系统开发平台选型探讨(11-09)
- 嵌入式系统中文输入法的设计(03-02)
- 基于MPC755的嵌入式计算机系统设计(05-10)
- WinCE下光电编码器的驱动程序设计(04-12)
- 为什么嵌入式开发人员要使用FPGA(05-13)
- VxWorks几种常用的延时方法介绍(05-16)