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

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

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

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

 其中,,視頻移動終端通過Anrdoid平臺提供的api實(shí)時獲取攝像頭捕獲的視頻流,,并通過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í)時視頻流數(shù)據(jù),。流媒體服務(wù)器則用于將應(yīng)用服務(wù)器接收的視頻流數(shù)據(jù)封裝成流媒體格式并實(shí)時發(fā)布,。
 視頻監(jiān)控端采用Android平臺構(gòu)建,可以通過RTSP和HTTP兩種協(xié)議訪問流媒體服務(wù)器以獲得觀看實(shí)時視頻的效果,。
1.2 視頻采集和編碼
 本系統(tǒng)采集的實(shí)時視頻來源于Android系統(tǒng)支持的攝像頭,。考慮到無線網(wǎng)絡(luò)帶寬的限制,,本系統(tǒng)采用H.264標(biāo)準(zhǔn)進(jìn)行壓縮編碼,。由于H.264編碼對硬件要求較高,編碼的速度會受到一定的影響,,這樣采集到的視頻可能不夠連貫。本系統(tǒng)采用多線程加緩沖隊(duì)列的方法進(jìn)行采集和編碼,。視頻采集線程將捕獲的每一幀數(shù)據(jù)放入一個緩沖隊(duì)列中,,視頻編碼線程從隊(duì)列中獲取視頻幀集合來完成編碼和傳輸?shù)墓ぷ鳌>唧w流程圖如圖2所示,。

 其中視頻采集線程的偽代碼如下:
Begin:
//初始化攝像頭,,設(shè)置視頻采集參數(shù);
While(視頻采集處于激活狀態(tài)){
從攝像頭獲取一幀數(shù)據(jù),;
while(緩沖隊(duì)列已滿)
wait,;//將線程掛起以等待隊(duì)列可寫
將一幀數(shù)據(jù)壓入幀緩沖隊(duì)列;
Notify,;//通知編碼線程隊(duì)列可讀
}
End
視頻編碼線程的偽代碼如下:
Begin:
//設(shè)置編碼參數(shù)(H.264),,初始化編碼對象;
While(編碼標(biāo)志位為真){
While(緩沖隊(duì)列為空)
wait,;//將線程掛起以等待隊(duì)列可讀
從緩沖隊(duì)列取一幀數(shù)據(jù),;
Notify;//通知采集線程隊(duì)列可寫
JNI調(diào)用native代碼對數(shù)據(jù)幀進(jìn)行編碼,;
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ù)進(jìn)行壓縮編碼和解碼,;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)的要求,采用非交錯模式按照編碼的視頻流順序進(jìn)行組包,,適用于延時較低的實(shí)時系統(tǒng),。
 由于H.264編碼對CPU消耗較大,如果放在java層則會大幅度影響系統(tǒng)性能,。本系統(tǒng)將H.264編碼模塊放在native層,,用C/C++實(shí)現(xiàn),通過jni調(diào)用編碼接口,,然后通過RTP傳輸,。
1.4 服務(wù)器設(shè)計(jì)
 服務(wù)器端采用雙緩沖文件實(shí)現(xiàn)流媒體的生成和發(fā)布。傳統(tǒng)的實(shí)時視頻監(jiān)控一般采用socket連接實(shí)現(xiàn)邊傳輸邊播放視頻,,視頻數(shù)據(jù)并不會被緩存,,并且如果要有新的客戶端加入監(jiān)控,則必須要新建一個socket連接,。本系統(tǒng)通過加入流媒體服務(wù)器作為視頻中轉(zhuǎn),,很好地解決了這一問題。由于流媒體服務(wù)器發(fā)布實(shí)時流媒體需要實(shí)時的視頻源,,本系統(tǒng)的應(yīng)用服務(wù)器將接收的實(shí)時視頻流數(shù)據(jù)寫入一個緩沖文件作為流媒體服務(wù)器的視頻源,,此緩沖文件通過linux命名管道實(shí)現(xiàn)。此外,,流媒體服務(wù)器發(fā)布流媒體也需要一個緩沖文件,,用于存放被編碼成流媒體格式后的視頻流數(shù)據(jù),以供客戶端調(diào)用,。服務(wù)器的工作流程圖如圖3所示,。

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

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

 


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


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

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