劉 誠,段紅光,巴 義
(重慶郵電大學 移動通信重點實驗室,重慶 400065)
視頻監(jiān)控以其方便、直觀、信息內(nèi)容豐富而廣泛應用于民用安全、城市交通等各個領域。移動視頻監(jiān)控是視頻監(jiān)控在移動網(wǎng)絡和移動終端上的應用,有廣闊的應用前景,與傳統(tǒng)網(wǎng)絡視頻監(jiān)控相比,具有使用方便、網(wǎng)絡覆蓋面廣、實時性高等優(yōu)點[1]。
移動視頻監(jiān)控技術對網(wǎng)絡帶寬、實時性等方面有嚴格的要求,由于目前移動網(wǎng)絡還不完善、移動終端性能還需要提升,在實際的應用中上述性能要求還不能完全得到滿足,因此,對移動視頻監(jiān)控客戶端進行研究和設計就顯得非常重要。由于視頻監(jiān)控應用數(shù)據(jù)量大、視頻解碼算法復雜,加之移動終端在處理能力、內(nèi)存容量等方面又受到極大限制,因而在移動終端上觀看視頻經(jīng)常會出現(xiàn)畫面模糊、停頓等問題。為解決這些問題,有必要對移動流媒體傳輸技術和視頻解碼技術這兩項關鍵技術進行研究,本文正是在此基礎上,設計并實現(xiàn)一個移動視頻監(jiān)控系統(tǒng)客戶端,從而為用戶提供穩(wěn)定、流暢的視頻監(jiān)控服務。
本文借鑒傳統(tǒng)的C/S設計模式,提出了一種更輕巧、簡便的系統(tǒng)設計方案,如圖1所示。
該設計方案有效結合了嵌入式技術與流媒體技術,向開發(fā)板中移植流媒體服務器和Web服務器,從而將采集端和服務端所有工作都集中在ARM開發(fā)板上。而在客戶端,可以通過Android手機播放實時視頻的方式對交通情況進行實時監(jiān)控。該系統(tǒng)運行穩(wěn)定,成本低廉,具有理論的可行性和實際的可用性。本文側重對客戶端進行研究和設計。
移動互聯(lián)網(wǎng)目前應用最廣泛的3種流媒體協(xié)議為:HTTP漸進下載流媒體協(xié)議,基于RTSP/RTP的實時流媒體協(xié)議棧,以及HTTP Live Streaming協(xié)議[2]。移動流媒體所需的緩存小,對實時性要求很高,HTTP漸進下載和HTTP LIVE STREAMING均不能很好的滿足這些要求?;赗TSP的協(xié)議棧的實時性,控制傳輸流的能力以及對網(wǎng)絡帶寬的自適應能力都很強,因而能在較大程度上提高流媒體播放的質(zhì)量。除此之外,RTSP還能提供用于音視頻流的VCR遠程控制功能。
移動視頻監(jiān)控系統(tǒng)屬于低延遲實時流媒體系統(tǒng),因此本文決定采用RTSP協(xié)議棧對客戶端進行設計。RTSP協(xié)議棧如圖2所示。
Android自帶的Media Player支持的媒體格式僅局限于OpenCore中所支持的媒體格式。FFmpeg是一個開源免費解決方案,能夠提供錄制、轉換、音/視頻編解碼等功能。其中的FFmpeg libavcodec是一個音/視頻編解碼類庫,能支持MPEG,MPEG-4等29多種編碼格式以及AVI,MPEG等90多種解碼格式。由于FFmpeg在軟件結構設計上,將應用層和編解碼實現(xiàn)層分離開來,同時在編解碼實現(xiàn)層中又分別處理文件解析和視頻流編解碼這兩個過程[3],因此向FFmpeg中添加格式就非常方便,具有良好的可擴充性。另外,F(xiàn)Fmpeg還能夠很好地解決Android平臺直播的問題。因此,本文將FFmpeg作為解碼方案移植到Android平臺上。
客戶端主要完成如下功能:1)實現(xiàn)監(jiān)控視頻的播放/暫停;2)獲取服務端發(fā)送的視頻數(shù)據(jù),并通過RTCP協(xié)議實時反饋RTP接收情況;3)實現(xiàn)遠程控制云臺的轉動。根據(jù)上述功能需求,將整個客戶端設計分成四大模塊[4],即主控制模塊、RTP數(shù)據(jù)傳輸模塊、視頻解碼模塊以及UI模塊??蛻舳塑浖軜嬋鐖D3所示。
主控制模塊是客戶端軟件的核心模塊,主要負責各模塊間的控制與通信。主模塊包括地址解析模塊、播放會話控制模塊等幾個子模塊。
3.1.1 媒體流解析控制
實時媒體流是基于RTP和RTCP的傳輸流,其解析控制流程比較復雜。首先地址解析模塊對從UI模塊發(fā)送來的文件路徑進行解析,解析成功后,地址解析模塊會根據(jù)文件路徑判斷媒體流類型,如果是實時媒體流,則調(diào)用協(xié)議棧線程訪問播放會話控制模塊。其中的子模塊SDP解析模塊會將URL根據(jù)SDP協(xié)議封裝成RTSP可以識別的格式,并發(fā)送給RTSP協(xié)議模塊。RTSP協(xié)議模塊根據(jù)TCP/IP協(xié)議向遠程流媒體服務器發(fā)送URL查詢請求。最終地址解析模塊將服務器反饋的查詢結果發(fā)送到UI模塊。UI模塊根據(jù)查詢結果,進行相應的操作,如果查詢結果為同意訪問,則UI模塊開始執(zhí)行實時媒體流所支持的一些VCR功能。
3.1.2 RTCP協(xié)議模塊
該模塊實現(xiàn)并封裝了RTCP協(xié)議,主要用來配合RTP數(shù)據(jù)的傳輸。在整個RTP數(shù)據(jù)傳輸過程中,RTCP模塊會周期性地向遠程流媒體服務器發(fā)送RTCP報文包,這些報文包包含了已發(fā)送以及已丟失的RTP數(shù)據(jù)包的數(shù)目等信息。這樣,遠程流媒體服務器就可以根據(jù)這些信息動態(tài)改變傳輸速率,從而為媒體視頻的播放提供QoS保證。
3.1.3 云臺控制模塊
云臺控制模塊的作用是控制云臺的轉動方向,并對鏡頭進行變焦、聚焦和光圈控制,從而做到多角度更全面的監(jiān)控[5]。
使用HTTP/TCP協(xié)議作為客戶端和服務器端之間的通信協(xié)議,保證了控制信號的可靠性。使用PELCO-D作為云臺控制協(xié)議,作為服務器和云臺解碼器之間的溝通協(xié)議。PELCO-D協(xié)議包括PTZ命令和擴展命令,本文主要使用PTZ命令實現(xiàn)轉動控制。該模塊的主要工作是根據(jù)PELCO-D協(xié)議把用戶UI操作封裝成數(shù)據(jù)包,然后利用TCP協(xié)議傳輸至Web服務器。
RTP數(shù)據(jù)包包含了序列號、時間戳等信息,這些信息主要用于RTP數(shù)據(jù)包的同步處理。視頻數(shù)據(jù)在遠程流媒體服務器端被分割成一個個RTP數(shù)據(jù)包,然后通過RTP/UDP/IP發(fā)送到客戶端,客戶端根據(jù)包頭中的信息,對數(shù)據(jù)包重新排序并丟棄重復的數(shù)據(jù)包。根據(jù)對RTP數(shù)據(jù)包處理過程,本文將RTP數(shù)據(jù)傳輸模塊劃分成3個子模塊,即RTP數(shù)據(jù)接收模塊、RTP包失序處理模塊、RTP包重組幀模塊。
3.2.1 RTP數(shù)據(jù)接收模塊
該模塊用于接收UDP協(xié)議模塊發(fā)送來的數(shù)據(jù)包并轉發(fā)出去。接收數(shù)據(jù)包之前,先查詢數(shù)據(jù)包的相關信息,例如包的類型、格式、大小等。該模塊只接收RTP數(shù)據(jù)包和RTCP報文包,其他類型的包丟棄。
3.2.2 RTP包失序處理模塊
在數(shù)據(jù)傳輸過程中,網(wǎng)絡延遲和抖動等因素會導致數(shù)據(jù)包的到達順序發(fā)生混亂,因而必須對這些RTP數(shù)據(jù)包重新排序。在模塊中設置一個排序緩沖區(qū),RTP數(shù)據(jù)包先進入排序緩沖區(qū),然后再進行重新排序。
3.2.3 RTP包重組幀模塊
在網(wǎng)絡傳輸中,一幀視頻數(shù)據(jù)無法打包進單個UDP報文,必須拆分并裝到幾個序列號連續(xù)、具有相同時間戳的RTP包中。已到達的RTP包先進入一段緩沖隊列,后到的RTP包根據(jù)序列號插入到隊列中對應的位置。RTP包重組幀模塊負責將緩沖隊列中具有相同時間戳的RTP包取出,并組合成一個完整的視頻幀,送到視頻解碼模塊中。
FFmpeg解決了Android OpenCore對播放格式支持的不足,同時能夠很好地解決Android平臺直播的問題,所以本文將FFmpeg作為解碼方案移植到Android平臺上。
3.3.1 視頻解碼流程
FFmpeg提供了一系列多媒體數(shù)據(jù)處理函數(shù)[6],利用這些函數(shù)可以完成視頻解碼。FFmpeg解碼流程如圖4所示。
圖3 FFmpeg解碼流程
av_register_all():完成FFmpeg系統(tǒng)支持的解碼格式注冊。av_find_stream_info():從文件中提取流信息。avcodec_find_decoder():尋找視頻流的解碼器。avcodec_open():打開解碼器。avcodec_alloc_frame():為解出的每幀視頻分配一個緩存。av_get_frame():從待解碼緩沖區(qū)中提取一幀數(shù)據(jù)。avcodec_decode_video():以av_get_frame()的一幀數(shù)據(jù)為參數(shù)并將該幀數(shù)據(jù)解碼。av_set_frame():將解碼后的一幀數(shù)據(jù)封裝后,放入待播放緩沖區(qū)。av_has_next_frame():判斷帶解碼緩沖區(qū)是否還有數(shù)據(jù)幀,若有跳回av_get_frame()繼續(xù)往下執(zhí)行,若無則調(diào)用avcodec_close(),釋放解碼器,整個解碼流程結束。
3.3.2 FFmpeg到Android平臺的移植
FFmpeg代碼的開發(fā)是基于Linux操作系統(tǒng)的,而Android終端受到處理能力和內(nèi)存容量等諸多限制,因此在移植時對FFmpeg代碼進行修剪及優(yōu)化是十分必要的。修剪及優(yōu)化工作主要從以下3個方面進行:1)只保留和文件解封裝和視頻解碼相關的代碼;2)修改configure文件,選擇適當?shù)膬?yōu)化參數(shù),將需要的文件封裝格式及其解碼格式編譯到鏈接庫;3)減少全局變量的使用、注意程序中字節(jié)對齊、不同類型間強制轉換、內(nèi)存分配等問題。
Android的SDK基于Java實現(xiàn),而FFmpeg是由C語言編寫完成的。利用NDK能夠幫助開發(fā)者快速開發(fā)C或C++的動態(tài)庫[7],并能自動將.so文件和Java應用一起打包成apk。移植時需要根據(jù)NDK中的Android.mk語法修改FFmpeg中自帶的makefile,然后使用NDK中的交叉編譯器進行編譯。
該模塊實現(xiàn)了用戶交互與圖像顯示功能,將解碼輸出的YUV數(shù)據(jù)轉換成RGB數(shù)據(jù),然后在屏幕上繪制出Bitmap圖片。除顯示圖片之外,還實現(xiàn)了一些額外功能,例如圖片縮放、云臺控制以及圖像抓拍等。本客戶端的界面是基于Android的GUI系統(tǒng)設計的,包括登錄界面和監(jiān)控界面?;贏ndroid平臺的手機是沒有外設按鍵的,針對云臺控制、圖像抓拍等功能,本文采用軟鍵盤的控制方法。在客戶端播放監(jiān)控視頻時,可以通過點擊MENU鍵調(diào)出隱藏式選單,如圖5所示。
在WiFi環(huán)境下,使用Android SDK 2.3模擬器進行功能測試。按照圖6所示,完成登陸界面的配置,經(jīng)服務器驗證通過后便出現(xiàn)監(jiān)控界面,如圖7所示。經(jīng)分析,用戶驗證登陸、WiFi無線網(wǎng)絡遠程監(jiān)控等功能均滿足預期設計。
本文在對移動流媒體傳輸、視頻解碼這兩個關鍵技術研究的基礎上,設計了一個基于Android平臺的視頻監(jiān)控客戶端,能夠較好地提供遠程監(jiān)控服務,同時給基于其他平臺的監(jiān)控客戶端研究與設計提供重要的參考價值。因此該客戶端具有一定的實際意義和商業(yè)價值。
[1]賀禮,唐倫,陳前斌,等.移動視頻監(jiān)控系統(tǒng)的設計與實現(xiàn)[J].電視技術,2007,31(6):59-62.
[2]霍龍社,甘震.移動流媒體協(xié)議綜述[J].信息通信技術,2010(4):6-10.
[3]劉潔彬,宋茂強.基于Android平臺的流媒體播放器的設計[EB/OL].[2012-06-20].http://wenku.baidu.com/view/b0051b00a6c30c2259019 e1f.html.
[4]閆卓.基于展訊TD_SCDMA平臺的手機流媒體播放軟件的設計與實現(xiàn)[D].西安:西安電子科技大學,2011.
[5]潘國輝.安防天下:智能網(wǎng)絡視頻監(jiān)控技術詳解與實踐[M].北京:清華大學出版社,2010.
[6]胡成,任平安,李文莉.基于Android系統(tǒng)的FFmpeg多媒體同步傳輸算法研究[J].計算機技術與發(fā)展,2011,21(10):85-88.
[7]井洪亮.基于Android的H.264/AVC解碼器的設計與實現(xiàn)[D].哈爾濱:哈爾濱工業(yè)大學,2010.