视频监控系统的android终端设计与实现
2017-01-12冯金哲殷海兵
冯金哲,殷海兵
(中国计量大学 信息工程学院,浙江 杭州 310018)
视频监控系统的android终端设计与实现
冯金哲,殷海兵
(中国计量大学 信息工程学院,浙江 杭州 310018)
采用跨平台开源视音频解决方案FFMPEG,设计了一个处理x264编码的RTSP(Real Time Streaming Protocol)视频监控终端(接收、解码与播放).通过FFMPEG解码库裁剪与优化后交叉编译成单一库,来提升终端启动的加载速度.分析了H264视频数据的解码流程;实现了视频像素YUV转RGB并在android平台的显示,解码和显示采用多线程机制,进一步提升了系统性能.测试结果表明,此android流媒体接收端播放效果良好.
Android平台;FFMPEG解码库;视频监控;流媒体
如今,随着移动通信技术和多媒体技术的迅速发展,智能手机的应用越来越广泛,人们不再满足其单一的打电话和发短信等基本功能[1],依靠智能手机观看视频成了当下新的趋势,特别是在智能监控领域,通过个人智能手机实时查看视频监控信息成为了关注热点.
就目前的国内外的研究现状来看,德国Complexx公司的ViewKa监控设备已经成功应用到了小型企业或家庭中,国内的海康威视公司也有了自己的一整套手机监控产品的应用,以及有名的随身眼手机监控产品都出现在了人们的日常生活中.手机视频监控应用已经成为一种趋势,国内三大运营商也都相继推出了自己的业务品牌,像电信的“全球眼”、移动的“守望者”和联通的“宽视界”,可以说,视频监控流媒体已经成为了当下研究的热点.
我们采用开源多媒体编解码框架FFMPEG,基于分层体系结构设计流媒体接收端.由于android原生多媒体库OPENCORE支持播放的视频格式有限,解码效率不够高效.针对播放基于H264编码的RTSP视频流,只能对其原生编解码库进行扩展.FFMPEG是一个跨平台、功能齐全的视音频解决方案,其编解码质量高且具有可靠的移植性.鉴于以上FFMPEG的优点,我们通过对FFMPEG进行剪裁、优化并移植到android系统,设计一个流媒体接收终端.该接收终端可以完美实现对H264格式的RTSP视频流进行解码并播放,达到了视频监控终端的设计要求.
1 Android平台介绍
Android是Google开发的基于Linux平台的开源手机操作系统.经过几年的发展,android智能手机受到全世界人们的喜爱,且具有特别高的市场占有率.
Android的系统架构和其他操作系统一样,采用了分层的架构.Android从高到低分为应用程序层、应用程序框架层、系统运行库层和Linux核心层等四层,如图1.
图1 Android系统架构图Figure 1 Android system architecture diagram
Android开发的应用程序主要是通过编写JAVA语言来调用android的API接口来实现的.但对于相对复杂或者对系统开销过大的应用,往往采用C/C++语言来实现.JNI(Java Native Interface,Java本地调用)技术完美地实现了Java语言和C/C++语言的交互通信.通过这种“Java+C”的编程方式,android开发者开发了诸多应用性很广的产品.
2 RTSP视频流接收端的整体结构设计
我们实现的流媒体接收终端包括3个处理阶段,分别是媒体流的获取、媒体流的解码、解码后的媒体数据显示[2-4].流媒体接收终端整体结构如图2.
图2 流媒体接收终端整体结构图Figure 2 Whole structure of streaming media client
图2中,接收模块主要负责对RTSP视频流的获取并进行预处理,然后送往解码模块进行解码.具体预处理过程为:解协议获取RTP数据头部的媒体信息,并对媒体信息进行格式的统一处理.解码模块是对接收的H264视频数据进行解码,解码后的YUV数据并通过FFMPEG进行RGB格式转换.显示模块主要重写了一个继承android中SurfaceView的类,通过此类实现了对转换后图像数据的动画显示.
3 流媒体接收端的具体实现
3.1 FFMPEG简介
FFMPEG是一个开源且功能非常强大的视音频数据处理工具.不仅支持几乎所有的视音频数据封装格式,而且集编码、解码和视频格式转换等功能,能够支持多达90种的解码格式,对解码H264格式的视频数据具有很高的效率.FFMPEG主要包括libavcodec、libavformat、libavutil、libavdevice、libpostproc、libavfilter、libswresample、libswscale等库文件[5].其中libavcodec视音频解码库模块,libavformat视音频封装格式的复用与解复用模块,libswscale色彩映射转换处理模块和libavutil公共工具函数模块属于主要的库文件.我们主要用到了FFMPEG的解码模块和数据格式转换模块,其中FFMPEG的解码过程如图3.
图3 FFMPEG解码过程图Figure 3 Decoding process diagram of FFMPEG
3.2 FFMPEG移植android
针对android手机内存小、CPU处理能力不高,所以首先对FFMPEG进行裁剪优化,只保留需要的支持RTSP协议和H264解码的部分,把其他没用的部分屏蔽掉.同时,优化一般编译FFMPEG生成多个动态库的方法,我们编译FFMPEG生成单一动态库libffmpeg.so.提升终端软件的加载启动速度.
FFMPEG源码基于C语言开发,而android应用程序基于java语言实现,这就增加了FFMPEG移植android难度.但是Google android提供了功能强大的交叉编译工具NDK,可以实现so库和java应用打包为apk.这样,FFMPEG移植android的难题就完美解决了.
我们编译环境是在windows下进行的.Windows中需要采用Cygwin和NDK来编译FFMPEG.Cygwin是一个windows平台运行的类UNIX模拟环境,这样就轻松实现了windows下进行Linux环境的编译.编译FFMPEG为单一动态库,只需要在FFMPEG源码中配置好一个脚本文件就好.这里分析一下脚本config.sh.
1)添加NDK环境变量
NDK_HOME=C:/android-ndk-r9d-windows-x86/android-ndk-r9d
PREBUILT=$NDK_HOME/toolchains/arm-linux-androideabi-4.6/prebuilt/windows
PLATFORM=$NDK_HOME/platforms/android-9/arch-arm
这里是配置的NDK路径,Cygwin环境中配置的路径必须是对应的本地路径.
2)配置FFMPEG源码,包括对源码的裁剪和优化,启用的解封装和解码功能.
--enable-network
--enable-decoder=h264
--enable-demuxer=rtsp
--enable-protocol=rtp
这部分主要是针对我们的需要进行裁剪和优化.
3)将编译生成的静态库链接成一个动态库
$PREBUILT/bin/arm-linux-androideabi-ld-rpath-link=$PLATFORM/usr/lib-L$PLATFORM/usr/lib -soname libffmpeg.so -shared -o $PLATFORM/usr/libffmpeg.so libavcodec/libavcodec.a libavfilter/libavfilter.a libavresample/libavresample.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc-lm-lz-ldl-llog $PREBUILT/lib/gcc/arm-linux-androideabi/4.6/libgcc.a
以上就是config.sh脚本文件的主要部分.具体的操作实现如图4.
图4 操作实现图Figure 4 Operation process diagram
运行后就生成了我们需要的动态链接库libffmpeg.so.
3.3 流媒体接收端的实现
本接收端的实现主要分为两块,一块是java层的实现,一块是C语言层实现.其中C层主要实现了rtsp视频流的接收和解码过程;java层主要是解码数据的显示过程.
3.3.1 流媒体接收端本地方法的实现
由android系统框架结构可知,需要把FFMPEG框架放在android的本地框架层,通过JNI工具和应用程序框架层的类进行交互[6-7],这里采用C++语言,封装了一个处理流媒体流的类FFMPEG,并构造了三个函数方法:FFmpeg::initial()及FFmpeg::h264Decodec()和FFmpeg::fillPicture().其中FFmpeg::initial()函数主要实现了对rtsp数据流的接收和分析,然后通过FFmpeg::h264Decodec()函数进行解码.解码具体用到的FFMPEG的API函数[8]如图5.
主要介绍几个重要的函数:
avformat_open_input(),该函数用于打开多媒体数据并且获得一些相关的信息.
avformat_find_stream_info(),该函数可以读取一部分视音频数据并且获得一些相关的信息.
avcodec_find_decoder()用于查找我们的H264解码器.
av_read_frame()函数的主要作用是获取一帧视频的压缩数据后对数据进行解码.我们知道,经过x264编码一帧图像是产生多个slice,即一个完整的帧包含几个NAL(slice).此函数保证了每次读到的是一个完整的帧数据,保证了解码的正确性.
avcodec_decode_video2()函数的作用是解码一帧视频数据.
图5 FFMPEG解码函数图Figure 5 Flow chart of decoding function about FFMPEG
3.3.2 视频像素转换
这里FFMPEG解码视频数据后得到的视频数据是yuv420p格式的,而android提供的SurfaceView仅支持RGB格式的渲染,因此需要对数据进行转换.
YUV转RGB的算法很多,两者的转换公式如下:
R=Y+1.407 5×(V-128),
G=Y-0.345 5×(U-128)-0.716 9×(V-128),
B=Y+1.779×(U-128).
公式牵涉浮点运算,所以一般从整型运算或查表两个方向考虑,目前主要有四种实现的算法,如查表法、数组、asm汇编法,CSCC.lib库.以上主要针对低分辨率情况效果尚可,当然FFMPEG也同样实现了这个功能,其libswscale库能够实现各种图像像素格式的转换以及图像大小缩放功能,而且其对相应指令集进行优化,转换效率比一般设计的算法[9-11]高很多.其sws_scale函数使用了好几种不同算法对图像进行处理.通过对不同算法的测试发现,SWS_BICUBIC性能相对较好,这里测试分辨率640×480,实时性非常好,在一般的视频监控场景下,基本满足了需求.主要测试的三个算法性能如表1.
表1 sws_scale算法测试Table 1 Algorithm tests of sws_scale
sws_scale()函数进行YUV和RGB的转换后[12-14],通过FFmpeg::fillPicture()函数填充bitmap图像数据.在java层开启一个专门线程进行对bitmap的刷新显示.这里另外创建一个rtspclient.cpp的文件用来实现java层中定义的两个本地接口.
3.3.3 流媒体接收端的java层方法的实现
Java端主要实现一继承自SurfaceView的类Videoplay,在Videoplay类中设计了两个调用本地代码函数的JNI接口,分别如下:
public native void initialWithUrl(String url);
public native void play(Bitmap bitmap).
其中initialWithUrl接口主要实现了对FFMPEG的初始化,通过接收rtsp数据流来获取图像尺寸参数对H264解码器初始化及对bitmap进行初始化.另一个play接口是解码接口,对接收的视频数据按bitmap的设定进行H264解码,解码后的数据进行格式转换后送给fillpicture函数.在Videoplay类中采用多线程编程,视频数据处理一个线程,SurfaceView实现bitmap属于另一个线程.多线程机制的使用,进一步提高了系统性能.
Java层通过System.loadLibrary("ffmpeg");System.loadLibrary("rtspclient");函数调用我们生成的动态链接库,来完成java程序对本地代码的调用.
该流媒体接收终端通过在android4.2.2系统的手机上进行验证测试,流媒体接收终端的播放效果如图6和图7,嵌入式流媒体服务端如图8,整个系统基本实现了摄像头采集视频编码流媒体传输与客户端实时接收显示.
图6 接收界面图Figure 6 Receiving interface
图7 播放效果图Figure 7 Playing interface
图8 嵌入式服务器端Figure 8 Embedded server
4 结 语
主要分析了流媒体接收终端的整体设计方案,其中详细描述了具体实现过程,包括FFMPEG移植android生成单一动态库,C语言层编写了FFMPEG类并实现其三个方法,作为JNI供java层的调用,最后实现了含有native方法的java类,进行视频数据的显示.其中采用的视频像素转换方法提高了视频渲染的效率,且多线程机制的采用进一步提升了系统性能.在一般视频监控环境下,如家用等,在分辨率640×480左右情况下基本实现了实时性的监控查看.
[1] 傅晓茜,何加铭.基于Android平台流媒体播放器的研究与实现[J].移动通信,2014,38(18):74-78. FU Xiaoqian, HE Jiaming. Research and implementation of streaming media player based on android platform[J]. Mobile Communications,2014,38(18):74-78.
[2] CHU D, JIANG C H, HAO Z B, et al. The design and implementation of video surveillance system based on H.264, SIP, RTP/RTCP and RTSP[C]//Proceedings of ISCID 6th International Symposium on Hangzhou. Hangzhou:IEEE,2013:39-43.
[3] LIU Y, DU B, WANG S, et al. Design and implementation of performance testing utility for RTSP streaming media server[C]//Proceedings of PCSPA First International conference on Harbin. Harbin:IEEE,2010:193-196.
[4] 郝明磊,何加铭,冯波,等.基于Android的流媒体播放器的设计与实现[J].无线电通信技术,2014,40(1):86-89. HAO Minglei, HE Jiaming, FENG Bo, et al. Design and implementation of streaming media player based on android platform[J]. Radio Communications Technology,2014,40(1):86-89.
[5] 魏涛,彭涛,郑建宏,等.基于Android的流媒体播放器的研究与设计[J].电视技术,2014,38(5):89-91,108. WEI Tao, PENG Tao, ZHENG Jianhong, et al. Research and design of streaming media player based on android[J]. Video Engineering,2014,38(5):89-91,108.
[6] 胡泽,赵新梅.流媒体技术与应用[M].北京:中国广播电视出版社,2006:189-192.
[7] RUPALWALA S S. ARM 11 based real-time video streaming server using RTSP protocol[C]//Proceedings of EESCO
International Conference on Visakhapatnam. Visakhapatnam:IEEE,2015:1-5.
[8] 单俊丽.基于Android的流媒体客户端的研究与设计[D].西安:西安电子科技大学,2013.DAN Junli. Android-based research and design of streaming media client[D]. Xi’an Electronic and Science University,2013
[9] 李向军,张小菲,王书阵.一种基于Android平台的移动终端多媒体播放器的扩展设计[J].微电子学与计算机,2014,31(2):118-121. LI Xiangjun, ZHANG Xiaofei, WANG Shuzhen. An extension design of multi-media player system for terminal based on android[J]. Microelectronic& Computer,2014,31(2):118-121.
[10] 马建设,赵雪江,苏萍,等.基于Android系统的视频播放器开发[J].计算机应用与软件,2013,30(11):136-137,175. MA Jianshe, ZHAO Xuejiang, SU Ping, et al. Development of android-based video player[J]. Computer Application and Software,2013,30(11):136-137,175.
[11] 李炜锋.基于Android的有身份识别功能的流媒体播放器的设计与实现[D].杭州:电子科技大学,2014. LI Weifeng. The design and implementation of streaming media player with identification based on android[D]. Hangzhou: University of Electronic Science and Technology of China,2014.
[12] JI Q, YU H, CHEN H. A smart Android based remote monitoring system[C]//Proceedings of the Third International Conference on Beirut. Beirut:IEEE,2015:181-184.
[13] 邵丹,韩家伟.YUV与RGB之间的转换[J].长春大学学报,2004,14(4):51-53. SHAO Dan, HAN Jiawei. Inter-transformation between YUV and RGB[J]. Journal of Changchun University,2004,14(4):51-53.
[14] 任俊伟,林东岱.JNI技术实现跨平台开发的研究[J].计算机应用研究,2005,22(7):180-184. REN Junwei, LIN Dongdai. Research of platform independent programming using JNI technology[J]. Application Research of Computers,2005,22(7):180-184.
Design and implementation of Android clients based on video surveillance systems
FENG Jinzhe, YIN Haibing
(College of Information Engineering, China Jiliang University, Hangzhou 310018, China)
A video monitoring client (receiving, decoding, and playing) for receiving RTSP streams of H.264 video data was designed based on FFMPEG, which is an open-source cross-platform design for audio and video. By using the optimized FFMPEG and cross-compiling to a single dynamic library, the loading speed of mobile phone terminals was improved. We analyzed the decoding process of H264 video data. The YUV video pixels were converted into RGB and the display of the Android platform was realized. A multi-thread mechanism for decoding and displaying was used to enhance system performance. The experiment results show that the Android streaming media terminal has a good performance.
Android platform; FFMPEG decoding library; video monitor; streaming media
2096-2835(2016)04-0441-06
10.3969/j.issn.2096-2835.2016.04.015
2016-06-13 《中国计量大学学报》网址:zgjl.cbpt.cnki.net
国家自然科学基金面上项目(No.61572449),浙江省自然科学基金资助项目(No.LY15F020022).
TP393
A