《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計應(yīng)用 > Android實時流媒體監(jiān)控的關(guān)鍵技術(shù)研究
Android實時流媒體監(jiān)控的關(guān)鍵技術(shù)研究
來源:微型機與應(yīng)用2013年第19期
周晶晶1,舒 翔2,龍 濤2,桂良啟2
(1.武漢軍械士官學校 火控雷達教研室,湖北 武漢 430074; 2.華中科技大學 電子與信息工程
摘要: 以視頻監(jiān)控系統(tǒng)在物聯(lián)網(wǎng)中的應(yīng)用為背景,介紹了如何在Android平臺上進行實時的視頻監(jiān)控系統(tǒng)的開發(fā)。在對Android操作系統(tǒng)進行深入分析的基礎(chǔ)之上,提出了一個基于Android的流媒體監(jiān)控方案,此方案通過移植X264開源庫,實現(xiàn)了Android視頻的H.264編碼,并通過雙緩沖文件搭建流媒體服務(wù)器對實時視頻流進行發(fā)布。通過對系統(tǒng)的測試,指出了值得改進的方向,為今后的研究工作提供參考。
Abstract:
Key words :

摘  要:視頻監(jiān)控系統(tǒng)在物聯(lián)網(wǎng)中的應(yīng)用為背景,介紹了如何在Android平臺上進行實時的視頻監(jiān)控系統(tǒng)的開發(fā)。在對Android操作系統(tǒng)進行深入分析的基礎(chǔ)之上,提出了一個基于Android的流媒體監(jiān)控方案,此方案通過移植X264開源庫,實現(xiàn)了Android視頻的H.264編碼,并通過雙緩沖文件搭建流媒體服務(wù)器對實時視頻流進行發(fā)布。通過對系統(tǒng)的測試,指出了值得改進的方向,為今后的研究工作提供參考。
關(guān)鍵詞: Android;視頻監(jiān)控;H.264;雙緩沖技術(shù);流媒體服務(wù)器

 終端平臺的智能化和3G網(wǎng)絡(luò)的覆蓋帶來了移動互聯(lián)網(wǎng)時代,這對當今不斷壯大的物聯(lián)網(wǎng)帶來了很多的便利。比如對物流車輛進行隨時、隨地、隨身的視頻監(jiān)控,相比傳統(tǒng)的PC機監(jiān)控更加方便和高效。在移動終端上進行視頻監(jiān)控系統(tǒng)的開發(fā),由于其硬件資源和網(wǎng)絡(luò)環(huán)境的限制,開發(fā)難度遠大于PC機,并且對移動終端和網(wǎng)絡(luò)都有很高的要求。本文通過分析流媒體服務(wù)器的特點,在服務(wù)器上實現(xiàn)了一個雙緩沖機制來達到實時發(fā)布流媒體的要求,通過服務(wù)器多線程的方式實現(xiàn)邊采集邊傳輸并實時的發(fā)布。
 本文采用Android操作系統(tǒng)作為終端視頻采集的平臺,借助Android系統(tǒng)平臺開發(fā)的優(yōu)點,可以很好地進行推廣及后期應(yīng)用。此外,為了保證數(shù)據(jù)傳輸?shù)馁|(zhì)量,本文通過在Android中移植X264開源庫來實現(xiàn)流媒體視頻的編碼,并通過雙緩沖文件優(yōu)化流媒體傳輸機制以實現(xiàn)實時視頻和移動監(jiān)控的融合。
1 系統(tǒng)分析與設(shè)計
1.1 系統(tǒng)總體架構(gòu)設(shè)計

 系統(tǒng)由視頻移動終端、流媒體服務(wù)器、視頻監(jiān)控端3部分組成,系統(tǒng)組成框圖如圖1所示。

 其中,視頻移動終端通過Anrdoid平臺提供的api實時獲取攝像頭捕獲的視頻流,并通過JNI的方式調(diào)用底層的native代碼以完成H.264的編碼工作,之后通過socket傳輸?shù)揭曨l監(jiān)控服務(wù)器。
 視頻監(jiān)控服務(wù)器包括應(yīng)用服務(wù)器和流媒體服務(wù)器兩部分。其中應(yīng)用服務(wù)器作為整個系統(tǒng)的服務(wù)端,用于處理視頻監(jiān)控端的視頻請求以及接收視頻移動終端發(fā)來的實時視頻流數(shù)據(jù)。流媒體服務(wù)器則用于將應(yīng)用服務(wù)器接收的視頻流數(shù)據(jù)封裝成流媒體格式并實時發(fā)布。
 視頻監(jiān)控端采用Android平臺構(gòu)建,可以通過RTSP和HTTP兩種協(xié)議訪問流媒體服務(wù)器以獲得觀看實時視頻的效果。
1.2 視頻采集和編碼
 本系統(tǒng)采集的實時視頻來源于Android系統(tǒng)支持的攝像頭??紤]到無線網(wǎng)絡(luò)帶寬的限制,本系統(tǒng)采用H.264標準進行壓縮編碼。由于H.264編碼對硬件要求較高,編碼的速度會受到一定的影響,這樣采集到的視頻可能不夠連貫。本系統(tǒng)采用多線程加緩沖隊列的方法進行采集和編碼。視頻采集線程將捕獲的每一幀數(shù)據(jù)放入一個緩沖隊列中,視頻編碼線程從隊列中獲取視頻幀集合來完成編碼和傳輸?shù)墓ぷ?。具體流程圖如圖2所示。

 其中視頻采集線程的偽代碼如下:
Begin:
//初始化攝像頭,設(shè)置視頻采集參數(shù);
While(視頻采集處于激活狀態(tài)){
從攝像頭獲取一幀數(shù)據(jù);
while(緩沖隊列已滿)
wait;//將線程掛起以等待隊列可寫
將一幀數(shù)據(jù)壓入幀緩沖隊列;
Notify;//通知編碼線程隊列可讀
}
End
視頻編碼線程的偽代碼如下:
Begin:
//設(shè)置編碼參數(shù)(H.264),初始化編碼對象;
While(編碼標志位為真){
While(緩沖隊列為空)
wait;//將線程掛起以等待隊列可讀
從緩沖隊列取一幀數(shù)據(jù);
Notify;//通知采集線程隊列可寫
JNI調(diào)用native代碼對數(shù)據(jù)幀進行編碼;
If(編碼成功){
調(diào)用RTP組件對數(shù)據(jù)打包;
通過UDP傳輸RTP包;
}
}
End
1.3 H.264視頻流傳輸控制模型
 H.264的定義由視頻編碼層(VCL)和網(wǎng)絡(luò)提取層(NAL)兩部分組成。其中VCL作為H.264的核心算法引擎對視頻數(shù)據(jù)進行壓縮編碼和解碼;NAL層則根據(jù)不同的網(wǎng)絡(luò)把數(shù)據(jù)打包成相應(yīng)的格式并通過網(wǎng)絡(luò)傳送出去。為了保證較低的延時,需要將H.264視頻流數(shù)據(jù)打包成RTP包,并加上時間戳和序列號等信息,然后通過UDP傳輸?shù)椒?wù)器。RTP的打包模式有3種:單NAL單元模式、非交錯模式和交錯模式。本文根據(jù)系統(tǒng)的要求,采用非交錯模式按照編碼的視頻流順序進行組包,適用于延時較低的實時系統(tǒng)。
 由于H.264編碼對CPU消耗較大,如果放在java層則會大幅度影響系統(tǒng)性能。本系統(tǒng)將H.264編碼模塊放在native層,用C/C++實現(xiàn),通過jni調(diào)用編碼接口,然后通過RTP傳輸。
1.4 服務(wù)器設(shè)計
 服務(wù)器端采用雙緩沖文件實現(xiàn)流媒體的生成和發(fā)布。傳統(tǒng)的實時視頻監(jiān)控一般采用socket連接實現(xiàn)邊傳輸邊播放視頻,視頻數(shù)據(jù)并不會被緩存,并且如果要有新的客戶端加入監(jiān)控,則必須要新建一個socket連接。本系統(tǒng)通過加入流媒體服務(wù)器作為視頻中轉(zhuǎn),很好地解決了這一問題。由于流媒體服務(wù)器發(fā)布實時流媒體需要實時的視頻源,本系統(tǒng)的應(yīng)用服務(wù)器將接收的實時視頻流數(shù)據(jù)寫入一個緩沖文件作為流媒體服務(wù)器的視頻源,此緩沖文件通過linux命名管道實現(xiàn)。此外,流媒體服務(wù)器發(fā)布流媒體也需要一個緩沖文件,用于存放被編碼成流媒體格式后的視頻流數(shù)據(jù),以供客戶端調(diào)用。服務(wù)器的工作流程圖如圖3所示。

2 系統(tǒng)實現(xiàn)
2.1 Android Camera視頻采集

 為了實時捕獲Android攝像頭的畫面,需要用到Android Camera。Android Camera包含取景和拍照兩個功能,它實際上是建立在C/S架構(gòu)上的。Camera運行的時候,可以大致分成服務(wù)器和客戶端兩個部分,他們分別運行在兩個不同的進程中,通過Binder機制來完成進程間通信。這種Android特有的Binder機制可以保證客戶端和服務(wù)器獨立的變化,客戶端調(diào)用接口AIDL定義的接口,功能則在服務(wù)器中實現(xiàn),并且進程間通信的部分對上層程序不可見。
 具體實現(xiàn)中,通過Android Framework提供的android.hardware.Camera類來完成和Camera Service服務(wù)端通信。由于需要對采集到的每一幀畫面進行壓縮編碼處理,可以通過調(diào)用Camera對象的setPreviewCallback函數(shù)來設(shè)置一個回調(diào)對象,此回調(diào)對象中的onPreviewFrame函數(shù)可用于完成對當前幀的捕獲,這樣就可以在此函數(shù)中對采集到的視頻進行編碼的處理了。
2.2 JNI調(diào)用X264庫
 考慮到無線網(wǎng)絡(luò)環(huán)境的不穩(wěn)定性和帶寬有限的問題。本文對采集到的視頻進行H.264標準的高效壓縮編碼。H.264是目前一個廣泛使用的具有高壓縮比的視頻編碼格式,具有較高的視頻壓縮性能,適合用窄帶傳輸,適用于移動互聯(lián)網(wǎng)和流媒體播放。本文采用X264開源庫來對實時視頻進行壓縮編碼。首先需要在Android操作系統(tǒng)上移植X264庫。
 由于X264是用C語言寫的一個開源庫,為了能夠被Android平臺使用,需要用到NDK工具對其進行編譯。NDK是用來編譯本地代碼的工具,作為Android SDK的一個補充,用于將原生的C/C++代碼集成到應(yīng)用中,并通過JNI的方式被上層java程序調(diào)用。本文采用JNI方式調(diào)用X264庫的步驟如下所示。
 (1)JNI接口設(shè)計
 設(shè)計調(diào)用本地代碼的函數(shù)接口。本文需要對采集的視頻進行H.264編碼,編碼部分需要定義3個接口。分別如下:
 private native long CompressBegin(int width,int height);
 private native int CompressBuffer(long encoder,int type,byte[] in,int insize,byte[]out);
 private native int CompressEnd(long encoder);
 其中native關(guān)鍵表明這3個函數(shù)來自于native代碼。CompressBegin接口是編碼初始化接口,通過傳遞視頻畫面的寬和高來對H.264編碼器進行初始化設(shè)定;CompressBuffer接口是編碼接口,通過傳遞encoder編碼器結(jié)構(gòu)和視頻流字節(jié)數(shù)組來對當前幀的視頻流數(shù)據(jù)進行H.264編碼,編碼后的結(jié)果存儲在out數(shù)組中;CompressEnd接口用于釋放編碼資源。
?。?)實現(xiàn)本地方法
 JNI接口設(shè)計完畢之后,需要用C語言實現(xiàn)接口。創(chuàng)建一個H264Android.c的文件,用來實現(xiàn)第一步中定義的3個接口。
 (3)生成動態(tài)鏈接庫
 實現(xiàn)JNI接口之后,需要生成.so的動態(tài)鏈接庫以供java程序調(diào)用。為了生成動態(tài)鏈接庫,需要編寫Android.mk文件并通過NDK工具對本地代碼進行交叉編譯。交叉編譯時需要針對X264庫編寫相應(yīng)的Android.mk文件,核心內(nèi)容如下所示:
include $(CLEAR_VARS)
LOCAL_C_INCLUDES+=libx264/include
LOCAL_MODULE:=H264Android
LOCAL_SRC_FILES:=H264Android.c
LOCAL_LDFLAGS+=$(LOCAL_PATH)/libx264/lib/libx264.a
LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib-lgcc
include$(BUILD_SHARED_LIBRARY)
 其中,LOCAL_C_INCLUDES標明了編譯需要的外部頭文件路徑;LOCAL_MODULE標明了當前生成模塊名稱;LOCAL_SRC_FILES標明了編譯需要用到的源文件;LOCAL_LDFLAGS標明了編譯需要用到的外部靜態(tài)庫;LOCAL_LDLIBS標明了引用的外部庫文件。
 通過引用X264的靜態(tài)庫,即可將X264編譯到native代碼中,并被上層java程序調(diào)用。編譯成功之后,會在Android項目的根目錄下的libs文件夾中形成一個libH264Android.so的動態(tài)鏈接庫,編譯完成。
?。?)Java程序調(diào)用本地代碼
 Android中的Java程序可以通過System.loadLibrary("H264Android")函數(shù)調(diào)用第3步中生成libH264Android.so動態(tài)鏈接庫。并使用聲明的native方法來完成視頻編碼的功能。
2.3 視頻傳輸?shù)膶崿F(xiàn)
 視頻傳輸通過TCP和UDP兩種方式配合實現(xiàn)。為了保證視頻采集終端和服務(wù)器之間有可靠的通信機制,采用TCP連接來進行控制信息的傳輸,當視頻終端收到有效的傳輸視頻的控制信息之后,采用UDP連接發(fā)送實時的視頻流到服務(wù)器。服務(wù)器視頻接收線程會將收到的有效視頻數(shù)據(jù)寫入到一個緩沖文件Camera.h264中,此文件被作為流媒體服務(wù)器的視頻源。
2.4 FFmpeg流媒體服務(wù)器架設(shè)

 


 服務(wù)器端采用FFmpeg作為流媒體服務(wù)器。FFmpeg是一個開源免費跨平臺的視頻和音頻流方案,屬于自由軟件,采用LGPL或GPL許可證。FFmpeg既可以對視頻進行編解碼,也可以搭建基于http和rtsp協(xié)議的流媒體服務(wù)器。
 本系統(tǒng)服務(wù)器利用Camera.h264緩沖文件作為FFmpeg的視頻源進行流媒體的發(fā)布。由于ffmpeg發(fā)布流媒體需要用到其中的FFserver組件,ffserver組件的啟動需要編寫相應(yīng)的ffserver.conf配置文件,主要配置如下所示:
Port 8090//配置RTSP端口號
BindAddress 0.0.0.0//綁定本地IP地址
MaxClients 1000//配置最大連接數(shù)
<Feed feed1.ffm>//配置流媒體緩沖文件
File/tmp/feed1.ffm
FileMaxSize 200 KB//緩沖文件大小為200 KB
</Feed>
<Stream camera.asf>//配置發(fā)布的流媒體格式
Feed feed1.ffm
Format asf
VideoFrameRate 15
VideoSize 352x240
</Stream>
 其中,Port指定了流媒體服務(wù)器綁定的端口。<Feed feed1.ffm>標簽定義了流媒體服務(wù)器運行所需要的一個緩沖文件,大小為200 KB。<Stream camera.asf>標簽定義了流媒體服務(wù)器輸出的視頻格式以及視頻相關(guān)的參數(shù)。如本系統(tǒng)輸出的流媒體格式為.asf格式。
 在ffserver啟動時,會根據(jù)ffserver.conf文件中的配置新建一個feed1.ffm緩沖文件。此緩沖文件用于存放來自視頻源文件的實時視頻流。FFmpeg會根據(jù)配置文件中的視頻輸出格式將視頻源中的文件進行轉(zhuǎn)換,轉(zhuǎn)換之后的數(shù)據(jù)會寫入feed1.ffm文件中。本系統(tǒng)中,feed1.ffm文件大小被限制在200 KB,當200 KB的空間被用完后,新數(shù)據(jù)會從文件的開頭進行寫入。這樣可以保證當有新的客戶端加入監(jiān)控時,觀看到的是最新的視頻。
3 系統(tǒng)測試
 為了驗證H.264視頻在無線網(wǎng)絡(luò)中的傳輸性能,本系統(tǒng)選取了2臺Android 2.3系統(tǒng)的手機進行測試。測試環(huán)境如下:
 視頻終端:Google Nexus S
 CPU主頻:1 GHz
 內(nèi)存:512 MB
 操作系統(tǒng):Android 2.3
 服務(wù)器采用Ubuntu10.04搭建。
 表1對雙緩沖和無緩沖的流媒體傳輸機制進行了測試和對比,顯示了隨著分辨率和每秒傳輸幀數(shù)/(F/S)的變化導致的丟包率和延時的變化。


 經(jīng)過測試,在采用了雙緩沖機制發(fā)布流媒體之后,客戶端能夠以更小的延時播放流媒體服務(wù)器發(fā)布的H.264視頻流。由于丟包率主要取決于傳輸帶寬,改變傳輸模式對丟包率的提升并不是很大。
 在高速移動互聯(lián)網(wǎng)的環(huán)境下進行視頻監(jiān)控成為了物聯(lián)網(wǎng)行業(yè)一個比較熱門的應(yīng)用。本文在流媒體服務(wù)器的搭建上采用雙緩沖文件技術(shù),有效地保證了視頻源的實時性,降低了網(wǎng)絡(luò)傳輸?shù)难訒r。此外,考慮到無線網(wǎng)絡(luò)環(huán)境中視頻數(shù)據(jù)傳輸?shù)睦щy,本文采用H.264標準對實時視頻進行壓縮編碼,有效地提高了帶寬利用率。由于本文傳輸視頻數(shù)據(jù)采用的RTP組包模式[5]并沒有考慮到實際的應(yīng)用背景,會產(chǎn)生一定程度的數(shù)據(jù)丟包,因此只是和應(yīng)用與對實時畫面要求不高的場景,比如物聯(lián)網(wǎng)物流行業(yè)等,如果要實時傳輸更清晰的視頻數(shù)據(jù),則需要采用良好的失序和擁塞處理技術(shù),并重寫RTP的組包算法,這樣可以保證視頻數(shù)據(jù)的穩(wěn)定性和完整性,這也是今后要研究和改進的方向。
參考文獻
[1] SCHULZRINNE H, CASNER S. RTP: A Transport Protocol for Real-Time Application[M]. RFC3550, 2003.
[2] WENGER S, HANNUKSEL M M. RTP Payload Format for H.264 Video[M]. RFC3984, 2005.
[3] 王立青.基于X264和流媒體的嵌入式視頻監(jiān)控系統(tǒng)[J].計算機安全,2010(7):13-15.
[4] 任嚴.基于FFMPEG的視頻轉(zhuǎn)換與發(fā)布系統(tǒng)[J].計算機工程與設(shè)計,2007,28(20):4962-4967.
[5] 魏聰穎.基于實時流媒體傳輸系統(tǒng)的H.264組包算法研究[J].計算機科學,2007,34(8):41-44.

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。