×
嵌入式 > 技术百科 > 详情

数字硬盘录像系统录像功能模块的设计与实现

发布时间:2021-05-14 发布时间:
|

数字监控技术在经过几年的快速发展后已深入应用到各行各业,并发挥着越来越重要的作用。但是,以往数字监控系统的录像功能在时间的精确度、稳定性等方面的指标离人们所期望的标准还有一定的距离。录像过程如图1所示,摄像机将采集到的模拟音视频信号送到音视频编码卡,编码卡完成对信号的编码、压缩,计算机将经过编码压缩后的数据进行存储管理。可以看出,录像的过程实时性较强,数据量较大,对硬盘操作很密集。由于计算机系统是一种多任务的系统,对硬盘的操作时间较长,所以录像时间精度一般都不是很高。比如,录像文件分割,从第一个通道开始到最后一个通道结束,在时间上会出现较大的误差,误差因计算机性能的差别一般在几秒至几十秒之间,这在一般的应用中是可以容忍的,但是在某些特定的应用场合下对时间精度则有更高的要求,例如要求各通道同步回放,那么各通道录像时间必须实现精确同步,这时候这个误差就不能容忍。针对应用中的各种需求,本文介绍了一种数字硬盘录像系统录像功能模块的设计和实现方案。

1设计目标为了满足各种不同的应用需求,录像功能模块应达到以下要求:(1)录像时间精确控制,主要包括2个方面:一是从启动录像到开始录像时间的误差,特别是当多个通道在同一时刻同时启动录像的情况下的误差控制;二是各通道录像文件分割时间的误差,即从第一通道开始分割到最后一个通道分割完毕的时间差控制。(2)录像分割无重复、无丢失,即前一个录像文件和后一个录像文件之间内容没有任何的重复或丢失。(3)录像控制稳定性高,录像文件管理完整性好,具有较强的容错功能。监控系统要求能够长期地稳定地工作,录像功能模块作为监控系统的核心部分,其稳定性要求更高,在各种情况下应都能稳定工作,录像文件管理要完整,不能因停电、死机等异常情况而出现一些无效文件或是空的数据库记录,在计算机出现故障时应尽量减小损失,比如正录像时出现硬盘故障,这时应该将新的数据转录到另一可用的硬盘。 (4)预录功能,在出现警报时能够将警报前一段时间的音视频数据记录下来。(5)功能模块具有透明性和通用性。对外只提供调用的接口,在使用时不必考虑内部结构,具有相对的独立性。

2几个主要问题及解决思路

2.1 启动录像为了保证在录像过程中数据不丢失,录像文件的存储一般采用多线程技术,并开辟内存缓冲区,如图2所示,线程1负责将经过编码的音视频数据放入缓冲区,线程2负责将缓冲区中的数据写入存储器。

在启动录像时,不仅要创建录像文件,还要写数据库记录,然后才能将录像数据写入存储器。由于外存储器的操作速度较慢,并且是一种共享设备,所以在创建文件和写数据库操作时都会有一定的时延,特别在是系统比较繁忙的时候时延会较大。比如,有多路录像同时启动,时延会更长,若是顺序启动,最后一路通道启动录像的时间则和第一路通道相差很大。产生误差的根本原因在于录像启动时创建文件的时间过长,这可以通过启动后先暂时将数据写到内存、最后再创建文件的办法加以解决。可以为每个录像通道分配一段内存缓冲区,启动录像后将数据先写入缓冲区,并不直接创建文件,更改录像状态的标识位后,继续启动下个通道的录像,直至所有通道启动完毕。创建文件的任务则由一个后台等待的线程来完成,当文件创建完成之后再将数据写入文件,只要缓冲区足够,则能够保证数据不会丢失。因为对内存的操作速度非常快,所以即使同时启动多个通道的录像,也能在极短的时间之内启动录像,保证录像启动时间的精确度,同时也保证了同时启动的多个通道录像启动时间的精确同步,为实现录像的同步回放提供了保证。

2.2 录像文件分割录像文件分割的目的在于避免一个录像文件过大。录像文件分割首先要关闭当前正在写入的文件,并操作数据库,记录下录像文件的结束时间,然后再创建一个新文件,在数据库中记录下创建的新录像文件的信息,并将新的数据写入新创建的文件。录像文件的分割主要有两个问题要解决,一是保证分割前后的录像文件要连续;二是保证各个通道分割时间要基本相同。第一个问题通过设置缓冲区则可以很好地解决,在分割文件过程中可以将录像数据暂存在内存缓冲区中,等分割完毕后再将缓冲区的数据写到新的文件中去;第二个问题可用类似于解决启动录像时延的方法来解决,在开始启动分割的时刻记下当前缓冲区的位置(这个位置之前存放的是分割前的数据,这个位置之后存放的则为分割之后的数据),并继续进行录像,新的录像数据则暂时存放在缓冲区分割记录点之后的区域,而保存并关闭前一个录像文件、操作数据库、创建新文件等较费时的任务则交由另一个后台线程来完成,等后台线程完成所有任务之后再将缓冲区中暂存的数据写入新的文件。

2.3差错以及故障的处理在计算机长期的运行过程中可能出现硬件故障或停电等各种异常情况,这对监控系统的正常运行会出现不良的影响,所以监控系统的设计必须尽最大可能地减少这些负面影响,把损失降到最低。硬盘是计算机中故障率较高的硬件,如果在进行录像时突然出现硬盘故障,要保证能够持续录像,这时系统应该能够自动在其他可用的硬盘上创建新的文件并持续录像。断电、死机、非正常关机则可能产生一些无效文件、空数据库记录。按写数据库记录的时机不同可分为2种情况:(1)写数据库记录在录像文件创建之前。当在已经开始录像但录像文件又还没有创建的时候断电,就会造成空的数据库记录;如果在文件已经创建但还没写入任何数据时断电,那么这个文件也是无效的空文件。(2)写数据库记录在录像文件创建之后或是在录像文件关闭之后。当在已经创建文件之后断电,这时就会出现无效文件,因为这个文件没有对应的数据库索引,将无法再被找到和使用,而且会永久地占用着存储器的空间。 通过在数据库创建一张临时的录像文件表可以很好地解决这些问题,在创建录像文件之前将些文件相关信息存人临时的表中,等到该录像文件正常关闭以后,再将该文件的信息写入数据库正式的录像文件表中,并将临时的表中的记录删除。这样,无论在任何情况下,只要在每次系统启动的时候检查这个临时表,并作相应的处理则可保证数据库中录像文件的记录与存储器中的文件保持一致。在启动时如果临时表中无记录,则表明所有录像都正常的结束;如果有记录,则分别检查每一条记录所对应的录像文件,有以下几种情况: (1)文件不存在,则该记录是是条空记录,将其删除;(2)文件存在,但文件的大小为零,则将文件和该条的记录都删除;(3)文件存在,文件大小不为零,该文件有效,则在正式录像文件表中加入此文件的记录,并删除临时表中的记录。

3设计与实现

3.1 录像功能模块的结构模块的所有功能由两个互相协作的类来实现,如图3所示,图中列出了类的部分重要函数,CRecordFile类负责实现对文件的操作和管理缓冲区,CRecorder类负责实现任务队列、运行后台任务执行线程、对外提供接口,管理标识位等其他任务。

模块整体的结构如图4所示,每一个CRecorder。类的实例中包括一个任务队列,一个后台线程,N个CRecordFile类实例,和记录每个通道录像状态的若干标识位。任务队列用于存放还没有处理的磁盘操作任务,后台程序按顺序处理这些等待的任务,N个CRecordFile类的实例分别对应N个录像的通道。在CRecorder类实例初始化时完成内存的分配,线程的启动以及标识位的初始化等任务。磁盘操作任务有3种不同的类型:(1)启动录像,主要是创建文件、写数据库;(2)录像文件分割,主要是关闭当前文件,写数据库和创建新的文件;(3)停止录像,主要是关闭当前正在录像的文件并写数据库。

启动录像,调用CRecorder类的StartRecord(),首先函数将对应通道的标识位设置为录像状态,这时经过编码的音视频数据可以开始存入对应通道的缓冲区,然后在任务队列里插入一个启动录像的新任务,当这个任务最后被后台进程执行以后,文件已经被创建好了,这时就可以周期性地将缓冲区的数据存入磁盘。文件分割,主线程通过周期性调用DivideUp()函数将正在录像的文件进行分割,DivideUp()函数首先将对应通道的标识位设置为正在分割状态,同时(用临界信号量互斥来保证)CRecordFile类会把缓冲区当前指针的位置记录下来(分割点指针),然后会将一个录像文件分割的磁盘操作的任务加入到任务队列,DividelUp()函数因为只是对内存进行操作,所以完成一次调用的时间极短。CRecord-er类的后台线程会从任务队列中取出这个任务并执行,主要完成以下任务:首先是将缓冲区中分割点指针之前的数据保存到当前打开的文件中并且关闭该文件,其次是保存数据库记录,然后再创建一个新的文件,并将新文件的信息记录到临时的录像文件数据库表,最后将分割点指针之后的数据保存到新的文件中。后台任务完成后则完成了文件的分割。停止录像与启动录像、文件分割的过程类似,停止录像的后台任务主要完成文件的关闭和数据库的更新,当队列中对应的任务被执行后则操作完成。

3.2 录像状态控制为了各个线程能够相互协调地工作,在程序中必须设置必要的标识位来保存各个通道的状态和录像文件的状态。由于录像的启动、停止和录像文件的分割采用了异步的方式,所以这里每个通道设置了两个状态位(内部状态和外部状态)来记录录像的状态。外部状态表明实际录像状态的转换,分为Idle(空闲)和Recording(录像)两个状态。内部状态表明录像启动、停止、文件分割的具体过程,分为7个状态:Idle(空闲),Starting(正在启动录像,数据写入缓冲区),Starring FileCreated(正在启动录像、录像文件创建完毕,缓冲区数据可写入磁盘),Recording(正常录像),Dividing(文件分割),Dividing FileCreated(分割进行中、新录像文件创建完毕),Stopping(停止录像)。外部状态表明当前是否在进行录像,从启动录像时刻到停止录像的时间段内都是录像状态,其余时间为空闲状态。外部状态转换和内部状态转换如图5和图6所示,明确状态是为了让各个线程协调工作,主要有3个线程:主线程、后台任务线程、写磁盘的线程。主线程主要负责启动、停止录像、录像分割和将经过编码的数据写入缓冲区。后台任务线程是负责处理3种磁盘操作任务,每个CRecorder类实例中包含一个后台磁盘操作任务线程。写磁盘的线程负责周期性地将缓冲区中的数据保存到磁盘。

执行每一个操作都有一定的条件限制,一个操作必须在一定的状态下才能执行。启动录像的条件是内部状态和外部状态都为Idle状态,文件分割的条件是内部状态和外部状态都为Recording状态,停止录像的条件是外部状态为Recording状态,内部状态为Recording,Dividing或DiVidig FileCreate状态。表1中列出了所有的有效的状态组合、当前状态下可执行的操作和程序运行的主要状况,表中的状态从上至下是以启动录像、文件分割、停止录像的顺序排列。

4录像时间测试为了验证此方案录像时间、各通道同步的精度,分别对启动录像和录像分割进行了测试。测试环境:主板:华北工控 740GVE(Intel 865 G);处理器:Intel P4 2.0 G;内存:256 M D13R266*2;硬盘:迈拓DiamondMax Plus9 120G ATAl33;视频编码卡:海康DS-4004HC*2。在系统不同繁忙程度下,分别对8路通道同时启动录像和分割时间进行了测试。表2,表3是对录像启动时间和录像分割时间的测试结果,设启动录像或启动分割的触发时间为0时刻,时间单位为ms。从测试的结果可以看出,即使在系统非常繁忙时,也能在极短的时间之内完成所有通道的启动和分割(10~30 ms),而后台硬盘操作任务的完成时间则因系统的繁忙程度不同从零点几秒到几秒最多需要十几秒。

5 结 语该方案已经用VC++6.O实现并应用到DVR系统中,经实践验证,达到了设计目标的要求。该方案优点是能够满足绝大多数应用的需求,提高了录像时间精确度和各通道同步录像的精确度,提高了录像功能模块的稳定性和容错性。该方案的缺点是对内存的容量有着更高的要求,但随着计算机的硬件性价比的不断提高,该缺点已可忽略不计,在当前主流配置的计算机上,此方案已能够很流畅地运行。


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
物联传感与Atmel强强联手 达成智能家居战略合作协议