文献标识码: A
DOI:10.16157/j.issn.0258-7998.2016.06.033
中文引用格式: 王浩,韩敏,董杰. 基于Android平台的车载视频智能监控系统的研究[J].电子技术应用,2016,42(6):121-123,127.
英文引用格式: Wang Hao,Han Min,Dong Jie. Research of vehicle intelligent video surveillance system based on Android platform[J].Application of Electronic Technique,2016,42(6):121-123,127.
0 引言
车载视频智能监控是智能交通领域的一个重要研究课题,它能方便用户实时、直观地监控车辆安全情况。传统的车载视频监控系统一般采用固定的PC监控方式,因而需要在指定的地点,并且在有专用网络设备支持的情况下才能对目标现场进行监控,这大大限制了监控系统的应用范围和灵活性[1]。近些年随着移动互联网的普及,市面上也出现了移动车载视频监控的解决方案,但是又存在视频画质不理想、整体用户体验较差的问题,同时车辆的移动性也对网络资源利用率提出了更高的要求。
本文在Android平台下提出了车载视频智能监控的解决方案。利用该方案,通过实现NAT穿透和P2P、C/S混合网络架构,提高了网络健壮性和资源利用率;通过设置缓冲区和调用FFmpeg多媒体解码框架,提高了高清实时监控性能。实践表明该方案能适应不同网络条件,满足了实际项目播放需求,具有良好的用户体验。
1 系统整体结构
本系统是基于Android平台开发的车载视频监控系统。该系统主要由三部分组成,即车载端、视频传输网络和监控端。系统整体框架如图1所示。
车载端基于Android平台开发,首先车载端会采集视频数据,然后对采集的数据进行H.264编码和实时传输协议(Real-time Transport Protocol,RTP)封包处理,最后将处理后的视频数据通过网络传输到监控端;视频传输网络基于点对点网络(peer-to-peer,P2P)和客户机、服务器结构(Client/Server,C/S)的混合网络架构,其传输方式会优先选择P2P连接,当P2P连接无法对网络地址转换(Network Address Translation,NAT)成功穿透而连接失败后,再通过中转服务器进行数据中转,有效节省网络带宽,提高网络资源利用率;监控端基于Android平台开发,首先监控端在异步线程接收到网络传来的包数据,并对这些数据进行RTP解包和FFmpeg解码,最后将解码后得到的图像通过ImageView实时更新显示给监控者。
2 系统实现原理
2.1 视频车载端
2.1.1 视频采集和编码
视频采集过程中,预览图像会占用大量内存,内存占用过大会导致内存溢出,严重时会造成程序崩溃,本系统通过Camera.PreviewCallback的onPreviewFrame回调函数,实时截取每帧视频流数据,并以setPreviewCallbackWithBuffer(Camera.PreviewCallback)的方式使用上述回调,提供一个字节数组作为缓冲区,用于保存预览图像数据,以有效管理预览图像时内存的分配和销毁。
移动网络的带宽有限,为了呈现高质量的监控画面,需要实现高编码压缩比。H.264充分地利用了各种冗余来达到高效的数据压缩比率,同时还具备高质量流通的图形,采用高度负责的算法,使其成为当前在低码率下压缩比率最高的视频编码标准[2]。所以本系统通过H.264技术来进行数据编码。
2.1.2 视频封包
数据包到达时间随机性是视频数据传输中很关键的问题,本系统采用RTP[3]协议来负责视频数据封包,利用数据包的时间戳、发送序号等字段来控制数据流的传输。
但如果RTP包大于最大传输单元(Maximum Transmission Unit,MTU),会导致底层协议任意拆包,这会使RTP包被分割后丢失的可能性增大,以致影响接收端数据的恢复,因而一般采用对网络抽象层(Network Abstract Layer,NAL)单元进行分类处理,共有单一NAL单元模式、组合封包模式和分片封包模式3种封包策略。
本系统因不存在音频数据,而H.264 NAL单元都含有较大数据量,故没必要采用组合封包模式。本系统将RTP包长设定为1 024 B,将超过1 024 B的NAL单元采用分片封包模式,不超过的采用单一NAL单元模式。
2.2 视频传输网络
视频传输网络在监控系统中占有至关重要的地位,视频数据传输质量的好坏直接影响了监控系统的使用效果。本系统采用面向无连接的用户数据报协议(User Datagram Protocol,UDP)来负责视频传输工作,并在传统C/S模式的基础上混合P2P传输技术,减少网络带宽的消耗,提高网络资源利用率。网络传输的简要工作流程如图2所示。
2.2.1 心跳机制
系统网络传输的数据发送和接收都是通过SOCKET来进行,但倘若此SOCKET是断开状态,则在发送和接收数据时就不能保证数据能有效到达,所以本系统通过搭建状态服务器来管理各车载端和监控端的在线状态(即SOCKET连接状态)。状态服务器会进行如下操作:
(1)启动新线程A1,监听端口4112,接收车载端每隔30 s发来的心跳包,处理心跳包中的JSON数据并更新内存N2中车载端的状态。
(2)启动新线程A2,监听端口4113,接收监控端每隔30 s发来的心跳包,处理心跳包中的JSON数据并更新内存N1中监控端的状态。同步返回监控端对应的车载端的JSON格式的数据集合,以便监控端在界面上更新车载端的状态显示。
(3)启动新线程A3,每隔60 s执行一次,循环N1中的监控端和N2中的车载端,根据时间戳判断监控端或车载端是否已掉线,如掉线则更新对应的内存中的状态。
2.2.2 NAT穿透
在实际网络环境下由于IPv4地址短缺,使得许多客户机都是通过NAT技术来共用一个公网IP地址[4]。NAT隐藏了参与构建P2P网络的大量用户节点,使得NAT穿透往往是制约P2P成功连接的关键。
NAT[5]可分成圆锥型NAT和对称型NAT两种类型。对于圆锥型NAT,本系统采用UDP对NAT的简单穿越(simple traversal of UDP through NAT,STUN)方式能很好地解决UDP穿透问题,但因STUN方式对于对称型 NAT不能提供有效的外部IP地址和端口号,所以无法成功穿透。
针对无法穿透对称型NAT的缺陷,本系统采用基于端口预测的方法来解决,能够在较多的场合尽可能地建立P2P连接。本系统对项目中存在的对称型 NAT网络环境进行分析发现,对称型 NAT对于从内部网络依次接收到的新连接,分配的输出端口大致有两种情况:
依照空闲端口按序连续分配的情况。因为在穿透过程中,车载端两次数据的发送间隔不会很长,NAT为其分配的新输出端口号相对于其原端口号的偏移量是一个较小范围内的正数,因此系统可以在监控端执行端口探测,当收到车载端对该UDP报文的回复就意味着穿透成功。
在一定端口范围内随机分配的情况。虽然车载端NAT两次输出端口号间的偏移量具有随机性,并且不同的设备和网络环境也会产生较大的区别,但实际上每次分配的端口号之间都会具有一定的函数关系或统计上的关联性。因此,可以通过研究其分布特性来预测,实施试探性穿透。
2.3 视频监控端
2.3.1 视频解包
由于网络传输时受到MTU的限制,因此视频数据在发送时被分割成一个个独立的数据包进行传输。监控端收到这些数据包后,必须按一定规则将这些包重新组合还原,然后才能进行解码播放。但当网络传输不稳定时,系统易出现包乱序和丢包现象。
对于包乱序处理,当监控端收到的RTP数据包没有正确排序时,本系统就需要按照包序列号进行重排。本系统在内存中建立双向链表来充当缓冲区,当接收到数据包后就按包头的序列号插入至对应位置。比如,接收到一个序列号SN=3的RTP包,就从链表尾开始搜索并插入到2、4节点中间。本系统缓冲区的最大长度设置为30时,能起到较好的缓冲效果,同时也能避免对设备内存造成较大负担。
对于丢包处理,在H.264编码标准中,共定义了I帧、P帧、B帧3种帧。I帧为关键帧,存放完整的数据;而P、B帧是辅助帧,存放运动矢量或边缘信息,需要对关键帧进行参考。所以,本系统在数据传输过程中,如关键帧数据丢失,对其他的P帧和B帧数据都会造成影响,因此必须将关键帧连同其他相关帧全部舍弃。如果辅助帧数据丢失,只会对当前帧数据产生影响,则只需将当前帧直接舍弃。
2.3.2 视频解码和播放
Android自带的Media Player支持的媒体格式仅局限于OpenCore中所支持的媒体格式。FFmpeg是一种包含音视频录制、转换以及编解码等功能的开源解决方案,其支持包括H.264在内的多种编码格式的编解码,具有较高的执行效率。
系统采用交叉编译的方式将FFmpeg引入到Android中来实现H.264解码,FFmpeg编译模块编译生成libffmpeg.so文件之后,供Android系统的Java本地接口(Java Native Interface,JNI)层调用。
libffmpeg.so文件的调用较为复杂,本系统采用重新编译生成一个so文件进行调用。这个so文件包含的是jni方法,这些方法能通过Java层进行调用,而方法中用到的函数则来自于libffmpeg.so文件。
首先需要编辑android.mk文件,文件具体内容如下:
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -lffmpeg-llog
LOCAL_MODULE := ffmpegutilDecode
#LOCAL_SHARED_LIBRARIES := ffmpeg
LOCAL_SRC_FILES := com_act1_H264.c
LOCAL_C_INCLUDES:=/cygdrive/d/android/android-ndk-r8b/ffmpeg/jni/include $(BUILD_SHARED_LIBRARY)
成功编译android.mk文件后需编辑com_act1_H264.c文件,此文件包含本地定义的方法,这些方法调用ffmpeg解码库函数,可解码H.264格式的视频数据。
com_act1_H264.c文件编辑成功后,就可执行ndk-build语句进行编译,编译完将生成libffmpegutilDecode.so库文件。
在项目中通过如下语句加载libffmpegutilDecode.so库文件。
static{
System.loadLibrary("ffmpegutilDecode");
}
libffmpegutilDecode.so库文件载入完毕后,就能通过调用本地定义的方法解码视频数据。本地定义解码函数如下所示:
public native boolean InitCodec(Surface surface);
public native byte[] FFInputFrame(byte[] data,int len);
public native void DeleteCodec();
public native void SetBitmap(Bitmap bitmap,byte[]data,int len);
在解码成功后生成的Bitmap需要实时显示,所以ImageView作为图像容器类必须进行实时更新。如果实时更新UI界面的大量工作放在主线程进行,可能会造成线程阻塞、视频卡顿等问题。因此本系统另启子线程来完成数据的接收和解码等耗时操作。视频解码播放流程如图3所示。
目前,上海某公司已采用此系统进行试用,监控端显示界面如图4所示。
3 系统性能测试
本系统针对100M带宽WiFi、4G、3G这3种不同网络条件进行了系统性能的综合测试,监控端视频图像分辨率为640×480,每种网络条件分别测试20次,计算平均值。以Android监控端统计的网络时延、抖动、丢包率和整体P2P连通率作为系统性能的考量依据。WiFi、4G、3G下系统测试结果如表1所示。
从表1可以看出,该系统在3种网络条件下都能实现较低的时延、抖动、丢包率和较高P2P连通率,能满足监控的高清实时性能需求。
4 结论
移动互联网时代的到来为车载视频智能监控系统在智能交通领域的发展升级带来了新的机遇。针对传统车载监控系统存在的高清实时性能较差、网络资源利用率低的问题,本文提出一种基于Android平台的车载视频智能监控解决方案,采用P2P和C/S混合网络架构,并利用多线程分别解决视频的接收、解码,通过缓冲机制解决视频卡顿问题。经过实验测试验证,本系统能适应不同网络条件,能实现以较满意的网络资源利用率和视频监控质量对车辆进行实时监控。
参考文献
[1] 李佳毅,徐晓辉,苏彦莽,等.基于Android平台的智能温室视频无线监控系统[J].农机化研究,2013,35(8):188-191.
[2] 罗欢,谢云,李丕杉.基于Android智能电视的视频监控的设计[J].电视技术,2013(22):85-87.
[3] PERKINS C.Rtp:Audio and video for the internet[M].Addison-Wesley Professional,2003.
[4] SRISURENSH P,NETWORKS J,EGEVANG K.Traditional IP network address translator(traditional NAT),RFC 3022[Z].IETF,2001.
[5] EGEVANG K,FRANCIS P.The IP network address translator(NAT),RFC1631[Z].IETF,1996.