許建東,彭 宏
(浙江省通信網(wǎng)應(yīng)用技術(shù)研究重點實驗室,浙江杭州310023)
隨著3G網(wǎng)絡(luò)的不斷普及,人們已經(jīng)不再僅僅滿足2G網(wǎng)絡(luò)中的聲音,圖像等多媒體體驗,大量的視頻應(yīng)用應(yīng)運而生。如Android平臺上常見的視頻應(yīng)用有:視頻通話;視頻上傳分享;視頻點播觀看;視頻監(jiān)控等各種豐富生活的應(yīng)用[1]。然而,盡管3G網(wǎng)絡(luò)在上下行速度上相較于2G網(wǎng)絡(luò)提升了許多,但未經(jīng)壓縮過的視頻數(shù)據(jù)所需帶寬比3G網(wǎng)絡(luò)能夠提供的帶寬還是大很多。因此將原始的視頻數(shù)據(jù)直接進行傳輸是不現(xiàn)實的。為了使現(xiàn)有的網(wǎng)絡(luò)帶寬支持視頻傳輸,視頻數(shù)據(jù)在傳輸前一般都要進行壓縮編碼處理。本文中所采用的H.264編碼所具有的高效壓縮比,高圖像質(zhì)量,良好網(wǎng)絡(luò)適應(yīng)性等優(yōu)點將為視頻應(yīng)用帶來更好的用戶體驗。本文介紹的H.264編碼的視頻前端模塊,可以很方便地嵌入到各種視頻應(yīng)用中。
H.264視頻前端模塊完成的功能描述如下:
(1)采集手機終端攝像頭所獲取的視頻數(shù)據(jù)。通過android.hardware.Camera類來控制攝像頭設(shè)備,攝像頭采集視頻時的參數(shù)可以通過Camera對象的getParameters()函數(shù)來得到一個android.hardware.Camera.Parameters對象設(shè)置;
(2)將視頻數(shù)據(jù)送入編碼庫進行編碼。編碼庫提供的編碼參數(shù)包括:視頻寬度,視頻高度,幀率。本文的開發(fā)環(huán)境雖然為Android平臺,但是考慮到視頻編解碼的效率問題,因此編碼具體是由C語言實現(xiàn)的,通過搭建NDK環(huán)境,可以很方便地在Android平臺上實現(xiàn)C語言代碼的利用;
(3)最終將得到的編碼結(jié)果分片,以便在網(wǎng)絡(luò)中傳輸。最終得到的H.264視頻編碼信息即NAL(網(wǎng)絡(luò)抽象層),往往是比3G網(wǎng)絡(luò)的MTU(網(wǎng)絡(luò)傳輸最大包大小)大很多的,因此,發(fā)送視頻數(shù)據(jù)之前,應(yīng)該進行數(shù)據(jù)分片操作,將每個發(fā)送的包控制在MTU大小之下。
模塊的整個示意圖如圖1所示。
圖1 模塊示意圖
整個模塊最終得到的結(jié)果是可以直接作為負載傳輸?shù)臄?shù)據(jù)。但是考慮到視頻數(shù)據(jù)流大,數(shù)據(jù)傳輸質(zhì)量難以保證,因此視頻數(shù)據(jù)往往不會以裸數(shù)據(jù)的形式進行傳輸,比較常見的方法是利用RTP(實時傳輸協(xié)議)來進行封裝之后再進行傳輸。經(jīng)過分片之后的數(shù)據(jù)即可直接作為RTP負載,進行實時視頻流傳輸。
本地開發(fā)包(Native Development Kit,DNK)提供了一系列的工具,幫助開發(fā)者快速開發(fā)C(或C++)的動態(tài)庫,使開發(fā)者能夠最大程度的源碼再利用[2]。在開發(fā)有關(guān)音視頻編解碼的應(yīng)用中,使用C/C++的編解碼代碼,往往比使用Java來進行編解碼能夠帶來更好的性能。使用要求:(1)一套交叉編譯工具(編譯器,連接器等),可以產(chǎn)生本地的ARM二進制文件在Linux,OS X和Windows操作系統(tǒng)運用,推薦使用Cygwin;(2)一套系統(tǒng)頭符合于Android平臺支持的穩(wěn)定本地API列表。Android SDK版本需要在1.5以上。
使用NDK生成一個可以在Android平臺上調(diào)用的動態(tài)庫.SO如下步驟:(1)下載Windows版本NDK,解壓即可。下載安裝Cygwin,可以通過gcc-v與make-v分別查看gcc與makeflie編譯工具是否安裝正常;(2)配置Cygwin。找到Cygwin的安裝目錄下的home文件夾,將home文件夾中的.bash_profile文件用文本編輯器打開,添加上ANDROID_NDK_ROOT=/cygdrive/NDK目錄export ANDROID_NDK_ROOT。其中NDK目錄根據(jù)自己解壓的NDK目錄設(shè)置;(3)在NDK中新建一個項目并且寫好這個項目的makefile文件,使用Cygwin進入這個項目目錄,執(zhí)行ndk-build即可生成動態(tài)庫.SO文件。
由模塊分析可知,整個模塊主要分為3個功能模塊:采集模塊;壓縮模塊;分片模塊。3個模塊完成各自不同的功能,同時最大限度的保證整個模塊的實用性。
這部分完成Android終端視頻數(shù)據(jù)的獲取以及壓縮工作。視頻數(shù)據(jù)的獲取工作可以根據(jù)Google提供的Android API來完成。為保證模塊的實用性,壓縮過程中需要保證參數(shù)集的確定。
參數(shù)集是H.264標準引入的一個新概念。H.264取消了序列層和圖像層,而將原本包含于上述兩層的信息游離出來并放入?yún)?shù)集中。序列和圖像頭信息是非常關(guān)鍵的信息,它們對后續(xù)的解碼工作至關(guān)重要[4]。參數(shù)集序列分為序列參數(shù)集和圖像參數(shù)集。序列參數(shù)集包括一個視頻序列的所有信息,如幀數(shù)、參考幀數(shù)目、解碼圖像尺寸等;圖像參數(shù)集包括一個圖像的所有分片的相關(guān)信息,如片組數(shù)目、熵編碼模式選擇標識、初始量化參數(shù)、去方塊濾波系數(shù)調(diào)整標識等[4]。因此,在編碼端控制好參數(shù)集可以為后續(xù)的解碼工作提供反饋調(diào)節(jié)。解碼端可以通過發(fā)送參數(shù)集數(shù)據(jù)來調(diào)整編碼端的編碼質(zhì)量。
最大傳輸包(Maximum Transmission Unit,MTU)。即網(wǎng)絡(luò)上傳送的最大數(shù)據(jù)包,單位為字節(jié)。
大部分網(wǎng)絡(luò)設(shè)備的MTU都是1 500。如果本機的MTU比網(wǎng)關(guān)的MTU大,大的數(shù)據(jù)包就會被拆開來傳送,這樣會產(chǎn)生很多數(shù)據(jù)包碎片,增加丟包率,降低網(wǎng)絡(luò)速度。把本機的MTU設(shè)成比網(wǎng)關(guān)的MTU小或相同,就可以減少丟包。因此,設(shè)置合理的MTU值對于實時系統(tǒng),如實時監(jiān)控系統(tǒng),實時通話系統(tǒng),將會有很大的影響??紤]到H.264在Android上的應(yīng)用大多是會有傳輸過程,本文為了提高實用性,加上了傳輸前必須做的分片處理。根據(jù)實際統(tǒng)計,一個完整的NAL通常在4-7k字節(jié)左右,而以太網(wǎng)等網(wǎng)絡(luò)的MTU為1 500字節(jié)。因此無法一次發(fā)送整個NAL數(shù)據(jù)。根據(jù)多次實踐,本文系統(tǒng)將MTU的值確定在1 000到1 100之間時,系統(tǒng)的丟包率比較理想。
本文采用的測試環(huán)境為Android系統(tǒng)2.3的HTC wildfire機型,cpu為600Mhz。壓縮分辨率為qcif(177×144),壓縮幀率可以在10-12幀之間。測試畫面如圖2所示,右下角小圖為壓縮之后的視頻。
本文提出的H.264前端采集壓縮分片模塊高度集成了H.264視頻流應(yīng)用的前端工作,可以非常方便,快速地嵌入到所開發(fā)的整套系統(tǒng)中。并且為了提高實用性,在實現(xiàn)過程中保留了參數(shù)集選項,同時考慮了實際發(fā)送過程中的分包處理,具有很大的實際意義。
圖2 測試壓縮圖
[1]楊鑫,牛建偉,胡建平.一種基于H.264的智能手機監(jiān)控系統(tǒng)的設(shè)計與實現(xiàn)[J].微電子學與計算機,2006,23(9):118-119.
[2]呂雪.基于網(wǎng)絡(luò)的視頻監(jiān)控系統(tǒng)研究[J].國外建材科技,2006,27(2):64-65.
[3]公磊,周聰.基于Android的移動終端應(yīng)用程序的開發(fā)與研究[J].計算機與現(xiàn)代化,2008,12(8)86-89.
[4]楊偉偉.基于H.264的移動視頻監(jiān)控系統(tǒng)的設(shè)計與實現(xiàn)[D].杭州:浙江工業(yè)大學,2011:28-29.
[5]楊志文.Google Android程序設(shè)計指南[M].北京:電子工業(yè)出版社,2009:4-6.