文獻標識碼: A
DOI:10.16157/j.issn.0258-7998.2016.06.033
中文引用格式: 王浩,韓敏,董杰. 基于Android平臺的車載視頻智能監(jiān)控系統(tǒng)的研究[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 引言
車載視頻智能監(jiān)控是智能交通領域的一個重要研究課題,它能方便用戶實時、直觀地監(jiān)控車輛安全情況。傳統(tǒng)的車載視頻監(jiān)控系統(tǒng)一般采用固定的PC監(jiān)控方式,因而需要在指定的地點,并且在有專用網(wǎng)絡設備支持的情況下才能對目標現(xiàn)場進行監(jiān)控,這大大限制了監(jiān)控系統(tǒng)的應用范圍和靈活性[1]。近些年隨著移動互聯(lián)網(wǎng)的普及,市面上也出現(xiàn)了移動車載視頻監(jiān)控的解決方案,但是又存在視頻畫質(zhì)不理想、整體用戶體驗較差的問題,同時車輛的移動性也對網(wǎng)絡資源利用率提出了更高的要求。
本文在Android平臺下提出了車載視頻智能監(jiān)控的解決方案。利用該方案,通過實現(xiàn)NAT穿透和P2P、C/S混合網(wǎng)絡架構,提高了網(wǎng)絡健壯性和資源利用率;通過設置緩沖區(qū)和調(diào)用FFmpeg多媒體解碼框架,提高了高清實時監(jiān)控性能。實踐表明該方案能適應不同網(wǎng)絡條件,滿足了實際項目播放需求,具有良好的用戶體驗。
1 系統(tǒng)整體結構
本系統(tǒng)是基于Android平臺開發(fā)的車載視頻監(jiān)控系統(tǒng)。該系統(tǒng)主要由三部分組成,即車載端、視頻傳輸網(wǎng)絡和監(jiān)控端。系統(tǒng)整體框架如圖1所示。
車載端基于Android平臺開發(fā),首先車載端會采集視頻數(shù)據(jù),然后對采集的數(shù)據(jù)進行H.264編碼和實時傳輸協(xié)議(Real-time Transport Protocol,RTP)封包處理,最后將處理后的視頻數(shù)據(jù)通過網(wǎng)絡傳輸?shù)奖O(jiān)控端;視頻傳輸網(wǎng)絡基于點對點網(wǎng)絡(peer-to-peer,P2P)和客戶機、服務器結構(Client/Server,C/S)的混合網(wǎng)絡架構,其傳輸方式會優(yōu)先選擇P2P連接,當P2P連接無法對網(wǎng)絡地址轉(zhuǎn)換(Network Address Translation,NAT)成功穿透而連接失敗后,再通過中轉(zhuǎn)服務器進行數(shù)據(jù)中轉(zhuǎn),有效節(jié)省網(wǎng)絡帶寬,提高網(wǎng)絡資源利用率;監(jiān)控端基于Android平臺開發(fā),首先監(jiān)控端在異步線程接收到網(wǎng)絡傳來的包數(shù)據(jù),并對這些數(shù)據(jù)進行RTP解包和FFmpeg解碼,最后將解碼后得到的圖像通過ImageView實時更新顯示給監(jiān)控者。
2 系統(tǒng)實現(xiàn)原理
2.1 視頻車載端
2.1.1 視頻采集和編碼
視頻采集過程中,預覽圖像會占用大量內(nèi)存,內(nèi)存占用過大會導致內(nèi)存溢出,嚴重時會造成程序崩潰,本系統(tǒng)通過Camera.PreviewCallback的onPreviewFrame回調(diào)函數(shù),實時截取每幀視頻流數(shù)據(jù),并以setPreviewCallbackWithBuffer(Camera.PreviewCallback)的方式使用上述回調(diào),提供一個字節(jié)數(shù)組作為緩沖區(qū),用于保存預覽圖像數(shù)據(jù),以有效管理預覽圖像時內(nèi)存的分配和銷毀。
移動網(wǎng)絡的帶寬有限,為了呈現(xiàn)高質(zhì)量的監(jiān)控畫面,需要實現(xiàn)高編碼壓縮比。H.264充分地利用了各種冗余來達到高效的數(shù)據(jù)壓縮比率,同時還具備高質(zhì)量流通的圖形,采用高度負責的算法,使其成為當前在低碼率下壓縮比率最高的視頻編碼標準[2]。所以本系統(tǒng)通過H.264技術來進行數(shù)據(jù)編碼。
2.1.2 視頻封包
數(shù)據(jù)包到達時間隨機性是視頻數(shù)據(jù)傳輸中很關鍵的問題,本系統(tǒng)采用RTP[3]協(xié)議來負責視頻數(shù)據(jù)封包,利用數(shù)據(jù)包的時間戳、發(fā)送序號等字段來控制數(shù)據(jù)流的傳輸。
但如果RTP包大于最大傳輸單元(Maximum Transmission Unit,MTU),會導致底層協(xié)議任意拆包,這會使RTP包被分割后丟失的可能性增大,以致影響接收端數(shù)據(jù)的恢復,因而一般采用對網(wǎng)絡抽象層(Network Abstract Layer,NAL)單元進行分類處理,共有單一NAL單元模式、組合封包模式和分片封包模式3種封包策略。
本系統(tǒng)因不存在音頻數(shù)據(jù),而H.264 NAL單元都含有較大數(shù)據(jù)量,故沒必要采用組合封包模式。本系統(tǒng)將RTP包長設定為1 024 B,將超過1 024 B的NAL單元采用分片封包模式,不超過的采用單一NAL單元模式。
2.2 視頻傳輸網(wǎng)絡
視頻傳輸網(wǎng)絡在監(jiān)控系統(tǒng)中占有至關重要的地位,視頻數(shù)據(jù)傳輸質(zhì)量的好壞直接影響了監(jiān)控系統(tǒng)的使用效果。本系統(tǒng)采用面向無連接的用戶數(shù)據(jù)報協(xié)議(User Datagram Protocol,UDP)來負責視頻傳輸工作,并在傳統(tǒng)C/S模式的基礎上混合P2P傳輸技術,減少網(wǎng)絡帶寬的消耗,提高網(wǎng)絡資源利用率。網(wǎng)絡傳輸?shù)暮喴ぷ髁鞒倘鐖D2所示。
2.2.1 心跳機制
系統(tǒng)網(wǎng)絡傳輸?shù)臄?shù)據(jù)發(fā)送和接收都是通過SOCKET來進行,但倘若此SOCKET是斷開狀態(tài),則在發(fā)送和接收數(shù)據(jù)時就不能保證數(shù)據(jù)能有效到達,所以本系統(tǒng)通過搭建狀態(tài)服務器來管理各車載端和監(jiān)控端的在線狀態(tài)(即SOCKET連接狀態(tài))。狀態(tài)服務器會進行如下操作:
(1)啟動新線程A1,監(jiān)聽端口4112,接收車載端每隔30 s發(fā)來的心跳包,處理心跳包中的JSON數(shù)據(jù)并更新內(nèi)存N2中車載端的狀態(tài)。
(2)啟動新線程A2,監(jiān)聽端口4113,接收監(jiān)控端每隔30 s發(fā)來的心跳包,處理心跳包中的JSON數(shù)據(jù)并更新內(nèi)存N1中監(jiān)控端的狀態(tài)。同步返回監(jiān)控端對應的車載端的JSON格式的數(shù)據(jù)集合,以便監(jiān)控端在界面上更新車載端的狀態(tài)顯示。
(3)啟動新線程A3,每隔60 s執(zhí)行一次,循環(huán)N1中的監(jiān)控端和N2中的車載端,根據(jù)時間戳判斷監(jiān)控端或車載端是否已掉線,如掉線則更新對應的內(nèi)存中的狀態(tài)。
2.2.2 NAT穿透
在實際網(wǎng)絡環(huán)境下由于IPv4地址短缺,使得許多客戶機都是通過NAT技術來共用一個公網(wǎng)IP地址[4]。NAT隱藏了參與構建P2P網(wǎng)絡的大量用戶節(jié)點,使得NAT穿透往往是制約P2P成功連接的關鍵。
NAT[5]可分成圓錐型NAT和對稱型NAT兩種類型。對于圓錐型NAT,本系統(tǒng)采用UDP對NAT的簡單穿越(simple traversal of UDP through NAT,STUN)方式能很好地解決UDP穿透問題,但因STUN方式對于對稱型 NAT不能提供有效的外部IP地址和端口號,所以無法成功穿透。
針對無法穿透對稱型NAT的缺陷,本系統(tǒng)采用基于端口預測的方法來解決,能夠在較多的場合盡可能地建立P2P連接。本系統(tǒng)對項目中存在的對稱型 NAT網(wǎng)絡環(huán)境進行分析發(fā)現(xiàn),對稱型 NAT對于從內(nèi)部網(wǎng)絡依次接收到的新連接,分配的輸出端口大致有兩種情況:
依照空閑端口按序連續(xù)分配的情況。因為在穿透過程中,車載端兩次數(shù)據(jù)的發(fā)送間隔不會很長,NAT為其分配的新輸出端口號相對于其原端口號的偏移量是一個較小范圍內(nèi)的正數(shù),因此系統(tǒng)可以在監(jiān)控端執(zhí)行端口探測,當收到車載端對該UDP報文的回復就意味著穿透成功。
在一定端口范圍內(nèi)隨機分配的情況。雖然車載端NAT兩次輸出端口號間的偏移量具有隨機性,并且不同的設備和網(wǎng)絡環(huán)境也會產(chǎn)生較大的區(qū)別,但實際上每次分配的端口號之間都會具有一定的函數(shù)關系或統(tǒng)計上的關聯(lián)性。因此,可以通過研究其分布特性來預測,實施試探性穿透。
2.3 視頻監(jiān)控端
2.3.1 視頻解包
由于網(wǎng)絡傳輸時受到MTU的限制,因此視頻數(shù)據(jù)在發(fā)送時被分割成一個個獨立的數(shù)據(jù)包進行傳輸。監(jiān)控端收到這些數(shù)據(jù)包后,必須按一定規(guī)則將這些包重新組合還原,然后才能進行解碼播放。但當網(wǎng)絡傳輸不穩(wěn)定時,系統(tǒng)易出現(xiàn)包亂序和丟包現(xiàn)象。
對于包亂序處理,當監(jiān)控端收到的RTP數(shù)據(jù)包沒有正確排序時,本系統(tǒng)就需要按照包序列號進行重排。本系統(tǒng)在內(nèi)存中建立雙向鏈表來充當緩沖區(qū),當接收到數(shù)據(jù)包后就按包頭的序列號插入至對應位置。比如,接收到一個序列號SN=3的RTP包,就從鏈表尾開始搜索并插入到2、4節(jié)點中間。本系統(tǒng)緩沖區(qū)的最大長度設置為30時,能起到較好的緩沖效果,同時也能避免對設備內(nèi)存造成較大負擔。
對于丟包處理,在H.264編碼標準中,共定義了I幀、P幀、B幀3種幀。I幀為關鍵幀,存放完整的數(shù)據(jù);而P、B幀是輔助幀,存放運動矢量或邊緣信息,需要對關鍵幀進行參考。所以,本系統(tǒng)在數(shù)據(jù)傳輸過程中,如關鍵幀數(shù)據(jù)丟失,對其他的P幀和B幀數(shù)據(jù)都會造成影響,因此必須將關鍵幀連同其他相關幀全部舍棄。如果輔助幀數(shù)據(jù)丟失,只會對當前幀數(shù)據(jù)產(chǎn)生影響,則只需將當前幀直接舍棄。
2.3.2 視頻解碼和播放
Android自帶的Media Player支持的媒體格式僅局限于OpenCore中所支持的媒體格式。FFmpeg是一種包含音視頻錄制、轉(zhuǎn)換以及編解碼等功能的開源解決方案,其支持包括H.264在內(nèi)的多種編碼格式的編解碼,具有較高的執(zhí)行效率。
系統(tǒng)采用交叉編譯的方式將FFmpeg引入到Android中來實現(xiàn)H.264解碼,F(xiàn)Fmpeg編譯模塊編譯生成libffmpeg.so文件之后,供Android系統(tǒng)的Java本地接口(Java Native Interface,JNI)層調(diào)用。
libffmpeg.so文件的調(diào)用較為復雜,本系統(tǒng)采用重新編譯生成一個so文件進行調(diào)用。這個so文件包含的是jni方法,這些方法能通過Java層進行調(diào)用,而方法中用到的函數(shù)則來自于libffmpeg.so文件。
首先需要編輯android.mk文件,文件具體內(nèi)容如下:
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文件,此文件包含本地定義的方法,這些方法調(diào)用ffmpeg解碼庫函數(shù),可解碼H.264格式的視頻數(shù)據(jù)。
com_act1_H264.c文件編輯成功后,就可執(zhí)行ndk-build語句進行編譯,編譯完將生成libffmpegutilDecode.so庫文件。
在項目中通過如下語句加載libffmpegutilDecode.so庫文件。
static{
System.loadLibrary("ffmpegutilDecode");
}
libffmpegutilDecode.so庫文件載入完畢后,就能通過調(diào)用本地定義的方法解碼視頻數(shù)據(jù)。本地定義解碼函數(shù)如下所示:
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界面的大量工作放在主線程進行,可能會造成線程阻塞、視頻卡頓等問題。因此本系統(tǒng)另啟子線程來完成數(shù)據(jù)的接收和解碼等耗時操作。視頻解碼播放流程如圖3所示。
目前,上海某公司已采用此系統(tǒng)進行試用,監(jiān)控端顯示界面如圖4所示。
3 系統(tǒng)性能測試
本系統(tǒng)針對100M帶寬WiFi、4G、3G這3種不同網(wǎng)絡條件進行了系統(tǒng)性能的綜合測試,監(jiān)控端視頻圖像分辨率為640×480,每種網(wǎng)絡條件分別測試20次,計算平均值。以Android監(jiān)控端統(tǒng)計的網(wǎng)絡時延、抖動、丟包率和整體P2P連通率作為系統(tǒng)性能的考量依據(jù)。WiFi、4G、3G下系統(tǒng)測試結果如表1所示。
從表1可以看出,該系統(tǒng)在3種網(wǎng)絡條件下都能實現(xiàn)較低的時延、抖動、丟包率和較高P2P連通率,能滿足監(jiān)控的高清實時性能需求。
4 結論
移動互聯(lián)網(wǎng)時代的到來為車載視頻智能監(jiān)控系統(tǒng)在智能交通領域的發(fā)展升級帶來了新的機遇。針對傳統(tǒng)車載監(jiān)控系統(tǒng)存在的高清實時性能較差、網(wǎng)絡資源利用率低的問題,本文提出一種基于Android平臺的車載視頻智能監(jiān)控解決方案,采用P2P和C/S混合網(wǎng)絡架構,并利用多線程分別解決視頻的接收、解碼,通過緩沖機制解決視頻卡頓問題。經(jīng)過實驗測試驗證,本系統(tǒng)能適應不同網(wǎng)絡條件,能實現(xiàn)以較滿意的網(wǎng)絡資源利用率和視頻監(jiān)控質(zhì)量對車輛進行實時監(jiān)控。
參考文獻
[1] 李佳毅,徐曉輝,蘇彥莽,等.基于Android平臺的智能溫室視頻無線監(jiān)控系統(tǒng)[J].農(nóng)機化研究,2013,35(8):188-191.
[2] 羅歡,謝云,李丕杉.基于Android智能電視的視頻監(jiān)控的設計[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,F(xiàn)RANCIS P.The IP network address translator(NAT),RFC1631[Z].IETF,1996.