安防视频之录像存储 |
您所在的位置:网站首页 › 监控录像怎样调取视频信息呢 › 安防视频之录像存储 |
需求: 1。按时间存储 2。循环存储(指定天数以及指定空间) 3。指定空间存储 4。录像计划的制定 5.每一段录像的存储大小
设计思路: 1.动态生成摄像机索引表,每一路摄像机一张表 2.文件块的管理,初始化的时候,就先把磁盘直接占满,以后不再进行磁盘的删除操作,一切都在应用层处理 3.文件快从头开始写入视频数据,图像索引从后往前写 4。每个文件通过xml的形式组建文件块,并进行重新进行命名,生成新的文件大小 5.循环存储分为按照时间存储以及按照空间存储,如果大小不够,直接开始循环 6.为了能够快速索引,需要能够很好的标识关键帧的位置, 7.需要能够适应时间跳变的问题 8.需要考虑正在录像还未形成一段文件的录像如何检索以及查看 模块划分: 第一步先完成如下任务: 1.数据库建表 2.文件存储格式定义 3.文件xml的定义
文件存储格式定义如下: 文件块大小为64M,视频帧裸数据从前往后写,视频的索引数据从后往前写,中间会有大约10K个字节的空隙,但是是可以接受的。 这里有个问题,就是海康的40字节头数据,我不打算每个文件再开始写的时候,都保存一份海康字节头,我计划保存再数据库里面。这样写文件的代码可以做到统一。就是来什么数据就写什么数据,而不需要做一些特殊处理了。 下面是每个字段的介绍: DecoderId:解码ID FrameRealTime:时间戳 M:标识是否为关键帧 Pt:音频为0,视频为1,解码头为2 lenth:当前帧的长度 SeekPos:当前帧位于文件的位置 索引个数:整个帧的数量 insigma:结束符 文件块的组织成文件的xml格式: 256 2019-02-26 10:00:00 2019-02-26 11:00:00 1 d://1.mp4 40 1 d://2.mp4 40推荐一款xml编辑工具: http://tools.jb51.net/code/xmlcodeformat
数据库设计: 每个录像卷一张表,并单独保存64M的文件块的信息 每个通道一张表,并单独保存录像文件的索引 另外就是录像计划的安排
需要开发的任务如下: 1.配置 2.回放服务 3.平台对接dll 4.录像服务 暂时不做配置的动态生效,放到第二期来开发。 文件块的申请与释放是整个系统的核心的核心,不依耐操作系统的文件系统,只能靠自己的文件块的管理。 每一个录像块的文件块数量巨大,大到百万级别,如何在这样一个数量级的文件块中设计出一套简单,使用的文件块的申请与回收的方法,显得尤为重要。 大概流程为: 申请文件块:申请的文件块可能会由于程序的异常关闭,或者系统的异常关闭,导致最终没有使用,当系统再次重启之后,应该还能再次被申请。 消耗文件块:当文件块消耗掉之后,需要确保文件块的标志位设置为被消耗。 回收文件块:当文件块块枯竭之后,需要能够把消耗的文件块释放出来使用。 整个录像服务核心就是围绕着文件块的申请,消耗,回收在运转。所以文件块状态表使用频率及其高。 申请文件块:需要设置文件块状态为被申请 消耗文件块:需要设置文件块状态为被消耗 回收文件块:需要设置文件块状态为回收 我们假设100路高清视频,计算一下文件块的表的使用频率: 假设视频一路4M,那么64M的文件块需要128s才能消耗掉。当录满之后,又需要再回收一个文件块 所以: 128秒需要操作文件块表:3*100 = 300次。 平均每秒操作3次 为了降低数据库的更新操作,我把申请文件块的状态备注在内存里面,假设100路视频,那么每次只有100个块处于被申请状态, 这样会存在一个问题,当我再次去数据库获取空闲的状态块的时候,此时获取到的状态是空闲,会出现状态不一致的情况,这种时候,我们需要进行二次计算,同步这种状态,使得他的状态还是被申请状态,这样就可以完美的减少一次数据库的更新操作,可以把文件块的状态表减少到每秒2次。 另外,计算一下假设保证系统时刻有1000个空闲文件块的话,计算一下大小:64M*1000 = 64G的空间,就是每个录像块需要时刻保持64G的空闲空间。这里如果时刻保持1000个空闲文件块的话,有一种场景比较麻烦,当录像卷里面只有一个摄像机的时候,怎么办呢?所以,我现在重新思考了一下,决定把空闲文件块设置为摄像机数量*10的个数。这样就可以弹性伸缩。 录像服务的设计: 如下图:
思路如下: 1.每个录像块一个类 2.录像块类又包含设备类,块管理类 3。设备类又分为取流和写文件两个线程 4.块管理类包括数据库类,实现数据库的插入和写入,以及空闲文件块的回收与申请,单线程作业
************************************2019-03-07*********************************** 今天看了下微软的api,写文件可以通过异步方式进行写,这样的话,我就不需要另外开一个线程去控制写了。 直接回调出来,直接业务逻辑控制写。 但是带来了一个很大的问题: 比较难控制了,同步写的时候,代码逻辑简单,关闭文件都比较方便。 举个简单的例子: 我的录像计划设置录像录1分钟,那么1分钟到了,我取流关闭了,我什么时候去关闭文件呢? 如果关闭取流了,就立马去关闭文件,肯定不行了,因为可能异步写还没结束啊。 如果可以解决异步写的控制问题,我想尝试一下异步写这个函数。 如果采用同步方式的话,我会设置一个写的队列,然后一直在写,还可以监视队列的缓存情况。 对于异步写的话,我也需要感知我现在有几个文件在执行异步写,这里我设置一个int 的数,当异步写一个值后, 这个值加一,当异步操作完成之后,这个值减一,当这个值超过一个阈值之后,我们要开始考虑丢帧策略了。 另外还有一个是当一个文件块的使命完成之后,我们需要关闭这个文件块,再重新申请这个文件块。如果采用异步写的话, 可能所有的写操作还没有完成,这个时候,我们需要调用FlushAsync强制刷新,等待结束之后,所有的写操作即完成。 另外,控制文件关闭,我想放在一个单独的监控线程在做操作,通过一个标志位来标识这个文件已经完成了使命,然后把文件关闭,再执行后续的数据库操作。这一块放在单独的线程来执行。 **************************如何写文件新思路******************** 我不准备在回调里面直接写文件,而是以一个gop为间隔,把视频流保存起来,然后再外面开启一个线程,比如每隔一秒,定期的去检查缓存情况,符合要求,即写文件。 这样的好处如下: 1。可以很好的控制文件申请与释放,单线程控制文件操作,不需要担心多线程同步。 2.业务处理起来十分简单,不会应为视频码流没了,而影响其他操作。 3。在做丢帧策略时候也什么方便 ********************************20190301*************************** 今天写了下写录像的逻辑图,发现居然业务逻辑如此复杂,把图记录下来,作为后面的编码参考。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |