执法记录仪录像模块的设计

Posted 「已注销」

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了执法记录仪录像模块的设计相关的知识,希望对你有一定的参考价值。

录像功能是执法仪的核心功能.为满足执勤要求,长时间稳定摄录是关键.根基我个人几年的执法仪开发经验,总结出如下的设计指引,希望能对读者有所启发.如有不完善之处欢迎讨论.

录像模块架构如下:

整个架构分为两个进程,主进程和Muxer进程.

  • 主进程

    主进程就是数据采集和编码进程,从摄像头和mic采集到视音频数据,再通过MediaCodec编码器,分别编码成视频和音频媒体帧.

    为了保证媒体帧流畅和逻辑简单,将这两个媒体做线程隔离,音频编码和视频编码分别运行在各自线程.

  • Muxer进程

    Muxer进程的工作应保证最简化,这样才能最大程度保证视频文件的完整性.其工作就是写入视频帧到录像文件.

    为了可控,我们没有使用安卓原生的MediaMuxer类来操作,而是选择编译ffmpeg库实现.

    注:我们测试,安卓远程的MediaMuxer在一些设备上,即便整个录像过程一切顺利,也有可能产生无法播放的媒体文件,偶然性大,原因未知,不好排查.我们最终放弃了MediaMuxer,转而使用ffmpeg库来封装.

我们通过下面的系列问题和功能点加以详述.

文件完整性

MP4文件合流(mux)需要遵循:

写入头(Header)->持续写入媒体帧(Frame)->写入尾(Tail)

的完整过程,只有该过程正常执行,文件才能播放.整个过程由唯一录像句柄串联,如果Mux中遇到异常,Mux过程中断,句柄丢失,录像文件会损坏,无法播放.

因此Mux过程非常重要,这就是分进程的目的.通过一个Muxer进程来单独执行mux过程,该进程逻辑简单,不会出bug导致异常中断.

Mux的过程可参考ffmpeg官方示例:https://ffmpeg.org/doxygen/2.0/doc_2examples_2muxing_8c-example.html

分辨率设置

录像的分辨率即为摄像头采集的原始分辨率,这个部分在摄像头采集测更改,不再说明.

码率

码率在编码器测修改,有些编码器的码率跟配置的帧率相关(比如三星的一些老款猎户座处理器),但是现在已经很少见了.执法仪已MTK方案居多,码率配置基本还是准的.
有些编码器对码率限制在一个合理区间,比如4K录像,需要保证一个码率下限,因此码率设置要相对合理.不同分辨率的码率设置经验值如下:

帧率

帧率需要由采集测来保证,执法仪的摄像头往往比较低端,难以保证稳定高帧率运行,录像过程中,不要在采集线程做耗时操作,这样会降低帧率.

有些摄像头,在暗光下面帧率偏低,测试时应该在亮光环境测试.

有些编码库效率也比较低,如果同步设计则会阻塞摄像头采集,降低了帧率,带来了延迟,因此编码库和摄像头最好分线程,或使用异步模式来编码.

录像分段

一个录像文件最长定在15分钟是合适的.录像的时长在开始录像时起算,写入关键帧时判断当前的持续时间,来决定是否更换文件.如需更换,停止当前muxer,重新创建新的muxer来继续录像.

国标要求分段之间的视频不能有100?毫秒以上的丢失,需要注意两点:

  • 切换文件时,把上个文件的最后一帧写入新文件,保证视频完全连续,不丢一帧.
  • 写入关键帧时才切换文件.这是为了满足上一条需求,因为一个新视频要保证第一帧是关键帧.

重要文件标记

国标要求在录像过程中可标记当前文件为重要文件,重要文件应以IMP开头.当前录像的文件已经被打开,被写入帧,无法马上更改名称,所以先记下来.等文件录制完成后再改.

文件管理

录像需要有文件管理来进行回放.还需要有按日期分类,排序,搜索等功能.

录像时抓拍

国标要求录像时能够抓拍,抓拍图的分辨率等于当前录像分辨率.我们已经取到摄像头的原始YUV数据了,直接用YuvImage来存成jpeg.

分流

执法仪可能需要在录像的同时分流,比如说录像同时推流给指挥中心.需要注意如下问题:

通常推流的视频码率要低于录像的码率,不能公用一个编码器.应该创建新的编码器进行推流作业.

推流的分辨率跟当前录像的分辨率可能也不一样,这需要对当前的YUV进行裁剪操作.

分流后,不能影响摄像头线程.

分流比较复杂,需要单独起一篇专门介绍.

文字叠加

国标要求执法仪录像文件叠加当前时间,拍摄人等信息.有些执法仪在HAL层做了处理了,这种模式的叠加内容相对固定,无法灵活修改.

可通过应用层对摄像头的原始数据进行叠加,这个应该发生在YUV数据帧取到后立刻叠加.因此由应用层进行叠加

文字叠加的算法其实并不复杂,也不耗资源.第三方开源库有freetype等.

预录

国标要求录像时可录制前10秒的视频片段,这就要求在未启动录像之前将音视频数据记下来.

  • 音视频数据量比较大,且实时更改,写文件不可能,所以要存在内存中.

  • 裸音视频帧数据量太大,内存无法承受,所以要存编码后的媒体帧.如下面示意图:

  • 一个视频序列是一个以关键帧开头的帧序列,期间任何一帧丢了都可能导致花屏和马赛克.所以这10秒的视频要是一个连续的可播放的媒体序列,视频帧的相关性要保证.丢帧逻辑稍显复杂:如果发生了丢帧,应该保证丢弃到下一个关键帧为止.

  • 当录像开始时,要把缓冲中的数据先写入muxer进行录制,缓冲区数据写完后,再写入实时帧.

延录

有些需求需要支持延录,所谓延录是指在录像停止后的一段时间内依然能录制音视频到文件.
这个需求,在按下停止录像键时,延迟一段时间停止录像即可.

性能以及功耗

本录像模块性能强劲,经测试4K录像30fps无压力.
功耗方面,720P录像时长在8个小时左右.

开源计划

本文所列技术以及相关代码后续会逐步开源,敬请期待!

参考资料

  • 执法记录仪介绍设计篇
  • 执法记录仪介绍功能篇
  • MP4文件格式 https://developer.apple.com/standards/qtff-2001.pdf
  • FFMPEG

以上是关于执法记录仪录像模块的设计的主要内容,如果未能解决你的问题,请参考以下文章

执法记录仪录像模块的设计

全球通大屏4G单兵执法记录仪BC310用户手册

全球通大屏4G单兵执法记录仪BC310用户手册

全球通大屏4G单兵执法记录仪BC310用户手册

全球通大屏4G单兵执法记录仪BC310用户手册

关于移动视频-无线图传产品中的录像-云端录像-录像计划等说明