在ADSP-BF561上實(shí)現(xiàn)與優(yōu)化的H.264
目前,音視頻技術(shù)日新月異,其中,視頻實(shí)時(shí)編碼傳輸極具代表性。在視頻壓縮算法領(lǐng)域,新一代視頻壓縮標(biāo)準(zhǔn)H.264以其優(yōu)異的壓縮性能和圖像質(zhì)量使視頻實(shí)時(shí)編碼傳輸技術(shù)的實(shí)現(xiàn)成為可能。但該標(biāo)準(zhǔn)的計(jì)算復(fù)雜度高,用一般的圖像處理芯片難以達(dá)到實(shí)時(shí)編解碼的要求,它需要快速、穩(wěn)定的處理器作為硬件平臺。ADSP-BF561是ADI公司推出的高性能多媒體處理器。其主要特點(diǎn)是具有兩個(gè)ADSP-BF533處理器核心(以下簡稱核心A和核心B),最高時(shí)鐘頻率達(dá)到600MHz,其內(nèi)部采用哈佛總線結(jié)構(gòu),存儲模型層次化。其典型應(yīng)用模式是A核運(yùn)行嵌入式操作系統(tǒng),B核運(yùn)行多媒體處理算法,如H.264。本文提出了一套采用ADSP-BF561芯片實(shí)現(xiàn)H.264視頻壓縮算法的設(shè)計(jì)方案,結(jié)合該DSP平臺對算法進(jìn)行了針對性的優(yōu)化,充分發(fā)揮了ADSP-BF561強(qiáng)大的處理能力。
1 算法介紹
1.1 H.264編碼模型框架
H.264以其高壓縮比、高圖像質(zhì)量和良好的網(wǎng)絡(luò)親和性廣受業(yè)界歡迎。在同等質(zhì)量條件下,H.264的數(shù)據(jù)壓縮比比MPEG-2高2~3倍,比MPEG-4高1.5~2倍。其需要的帶寬只有MPEG-4的50%, MPEG-2的12.5%。
H.264標(biāo)準(zhǔn)采用分層體系結(jié)構(gòu),系統(tǒng)分為:視頻編碼層VCL(Video CodingLayer),負(fù)責(zé)高效的數(shù)字視頻壓縮;網(wǎng)絡(luò)抽象層NAL(Network AbstractionLayer),負(fù)責(zé)對數(shù)據(jù)進(jìn)行打包和傳送。H.264編碼圖像通常分為三種類型:I幀、P幀、B幀。I幀為幀內(nèi)編碼幀,其編碼不依賴于已編碼的圖像數(shù)據(jù)。P幀為前向預(yù)測幀,B幀為雙向預(yù)測幀,編碼時(shí)都需要根據(jù)參考幀進(jìn)行運(yùn)動(dòng)估計(jì)。同時(shí),H.264在提高圖像傳輸容錯(cuò)性方面做了大量工作,重新定義了適于圖像的結(jié)構(gòu)劃分。在編碼時(shí),圖像幀各部分被劃分到多個(gè)Slice結(jié)構(gòu)中,每個(gè)Slice都可以被獨(dú)立編碼,不受其他部分影響。Slice由圖像最基本的結(jié)構(gòu)——宏塊組成,每個(gè)宏塊包含一個(gè)16×16的亮度塊和兩個(gè)8×8的色度塊。H.264標(biāo)準(zhǔn)的整體編碼框圖如圖1所示。編碼過程中,原始數(shù)據(jù)進(jìn)入編碼器后,當(dāng)采用幀內(nèi)編碼時(shí),首先選擇相應(yīng)的幀內(nèi)預(yù)測模式進(jìn)行幀內(nèi)預(yù)測,隨后對實(shí)際值和預(yù)測值之間的差值進(jìn)行變換、量化和嫡編碼,同時(shí)編碼后的碼流經(jīng)過反量化和反變換之后重構(gòu)預(yù)測殘差圖像,再與預(yù)測值相加得出重構(gòu)幀,得出的結(jié)果經(jīng)過去塊濾波器平滑后送入幀存儲器。采用幀間編碼時(shí),輸入的圖像塊首先在參考幀中進(jìn)行運(yùn)動(dòng)估計(jì),得到運(yùn)動(dòng)矢量。運(yùn)動(dòng)估計(jì)后的殘差圖像經(jīng)整數(shù)變換、量化和嫡編碼后與運(yùn)動(dòng)矢量一起送入信道傳輸。同時(shí)另一路碼流以相同的方式重構(gòu)后,經(jīng)去塊濾波后送入幀存儲器作為下一幀編碼的參考圖像。
1.2 H.264關(guān)鍵技術(shù)
1.2.1 幀內(nèi)預(yù)測
H.264引入了幀內(nèi)預(yù)測以提高壓縮效率。幀內(nèi)預(yù)測編碼就是利用周圍鄰近的像素值來預(yù)測當(dāng)前的像素值,然后對預(yù)測誤差進(jìn)行編碼。這種預(yù)測是基于塊的。對于亮度分量,塊的大小可以在16×16和4×4之間選擇,16×16有4種預(yù)測模式,4×4有9種預(yù)測模式;對于色度分量,預(yù)測是對整個(gè)8×8塊進(jìn)行的,有4種預(yù)測模式。
1.2.2 幀間預(yù)測
幀間預(yù)測時(shí)所用塊的大小可變。假設(shè)基于塊的運(yùn)動(dòng)模型,其塊內(nèi)的所有像素都做了相同的平移,在運(yùn)動(dòng)比較劇烈或者運(yùn)動(dòng)物體的邊緣外,這一假設(shè)會與實(shí)際出入較大,從而導(dǎo)致較大的預(yù)測誤差,這時(shí)減小塊的大小可以使假設(shè)在小塊中依然成立。另外小塊所造成的塊效應(yīng)相對也小,因此,小塊可以提高預(yù)測的效果。H.264一共采用了7種方式對一個(gè)宏塊進(jìn)行分割,每種方式下塊的大小和形狀都不相同,編碼器可以根據(jù)圖像的內(nèi)容選擇最好的預(yù)測模式。與僅使用16x16塊進(jìn)行預(yù)測相比,使用不同大小和形狀的塊可以使碼率節(jié)約15%以上。
同時(shí),幀內(nèi)預(yù)測采用了更精細(xì)的預(yù)測精度,H.264中亮度分量的運(yùn)動(dòng)矢量使用1/4像素精度。色度分量的運(yùn)動(dòng)矢量使用1/8像素精度。
1.2.3 多幀參考
H.264支持多幀參考預(yù)測,最多可以有5個(gè)在當(dāng)前幀之前的解碼幀作為參考幀產(chǎn)生對當(dāng)前幀的預(yù)測,提高H.264解碼器的錯(cuò)誤恢復(fù)能力。
1.2.4 整數(shù)變換
H.264對殘差圖像的4×4整數(shù)變換技術(shù),采用定點(diǎn)運(yùn)算來代替以往DCT變換中的浮點(diǎn)運(yùn)算。以降低編碼時(shí)間,同時(shí)也更適合硬件平臺的移植。
1.2.5 熵編碼
H.264支持兩種熵編碼方法,即CAVLC(基于上下文的自適應(yīng)可變長編碼)和CABAC(基于上下文的自適應(yīng)算術(shù)編碼)。其中CAVLC的抗差錯(cuò)能力比較高,但編碼效率比CABAC低;而CABAC的編碼效率強(qiáng),但需要的計(jì)算量和存儲容量更大。
1.2.6 去方塊濾波
去方塊濾波的作用是消除經(jīng)反量化和反變換后重建圖像中由于預(yù)測誤差產(chǎn)生的塊效應(yīng),從而改善圖像的主觀質(zhì)量和預(yù)測誤差。經(jīng)過濾波后的圖像將根據(jù)需要放在緩存中用于幀間預(yù)測,而不是僅僅用來改善主觀質(zhì)量,因此該濾波器位于解碼環(huán)中。對于幀內(nèi)預(yù)測,使用的是未經(jīng)過濾波的重建圖像。
2 算法實(shí)現(xiàn)
2.1 平臺選擇
2.1.1 ADSP-BF561芯片介紹
ADSP-BF561是Blackfin系列中的一款高性能定點(diǎn)DSP視頻處理芯片。其主頻最高可達(dá)750MHz,內(nèi)核包含2個(gè)16位乘法器MAC、2個(gè)40位累加器ALU、4個(gè)8位視頻ALU,以及1個(gè)40位移位器。該芯片中的兩套數(shù)據(jù)地址產(chǎn)生器(DAG)可為同時(shí)從存儲器存取雙操作數(shù)提供地址,每秒可處理1 200兆次乘加運(yùn)算。芯片帶有專用的視頻信號處理指令以及100KB的片內(nèi)L1存儲器(16KB的指令Cache,16 KB的指令SRAM,64 KB的數(shù)據(jù)Cache/SRAM,4 KB的臨時(shí)數(shù)據(jù)SRAM)、128KB的片內(nèi)L2存儲器SRAM,同時(shí)具有動(dòng)態(tài)電源管理功能。此外,Blackfin處理器還包括豐富的外設(shè)接口,包括EBIU接口(4個(gè)128 MBSDRAM接口,4個(gè)1MB異步存儲器接口)、3個(gè)定時(shí)/計(jì)數(shù)器、1個(gè)UART、1個(gè)SPI接口、2個(gè)同步串行接口和1路并行外設(shè)接口(支持ITU-656數(shù)據(jù)格式)等。Blackfin處理器在結(jié)構(gòu)上充分體現(xiàn)了對媒體應(yīng)用(特別是視頻應(yīng)用)算法的支持。
2.1.2 ADSP-561 EZkite
ADSP-BF561視頻編碼器平臺采用ADI公司的ADSP-BF561 EZ-kitLite評估板。此評估板包括1塊ADSP-BF561處理器、32 MB SDRAM和4 MBFlash,板中的AD-V1836音頻編解碼器可外接4輸入/6輸出音頻接口;而ADV7183視頻解碼器和ADV7171視頻編碼器則可外接3輸入/3輸出視頻接口。此外,該評估板還包括1個(gè)UART接口、1個(gè)USB調(diào)試接口和1個(gè)JTAG調(diào)試接口。攝像頭輸入的模擬視頻信號經(jīng)視頻芯片ADV7183A轉(zhuǎn)化為數(shù)字信號,此信號從ADSP-BF561的PPI1(并行外部接口)進(jìn)入ADSP-BF561芯片進(jìn)行壓縮,壓縮后的碼流則經(jīng)ADV7179轉(zhuǎn)換后從ADSP-BF561的PPI2口輸出。此系統(tǒng)可通過Flash加載程序,并支持串口及網(wǎng)絡(luò)傳輸。編碼過程中的原始圖像、參考幀等數(shù)據(jù)可存儲在SDRAM中。
2.2 算法選取與優(yōu)化方案
2.2.1 算法選取
H.264實(shí)現(xiàn)的源代碼不止一種,其中最常見的有JM、X264和T264。對比這三種實(shí)現(xiàn)源代碼,X264比T264具有更高的效率。而且相比廣泛采用的JM編碼模型,X264在兼顧編碼質(zhì)量的同時(shí)大幅度地提升了編碼速度,所以選取X264作為算法原型。
2.2.2 優(yōu)化方案
該優(yōu)化方案從三個(gè)層次對算法進(jìn)行優(yōu)化:算法層次、代碼層次、平臺層次。下面介紹具體優(yōu)化方法。
2.2.2.1 編碼器具體參數(shù)的選擇
該編碼器使用main檔次,I、B、P幀量化值分別為26、31、29,流控參數(shù)選為CBR。IDR幀間隔設(shè)為50,B幀間隔為2幀。這樣的選擇是為了在速度和運(yùn)算量上取折中。選用B幀并將其量化值加大,可比baseline檔次、IPPP結(jié)構(gòu)提高約10%的壓縮率。而B幀的計(jì)算量,因其不用做參考幀,故無需進(jìn)行去塊濾波和插值計(jì)算,在31的qp下,很多塊會被判做skip模式編碼,因而多數(shù)時(shí)B幀總運(yùn)算量候反而較P幀低。
2.2.2.2 算法層次的優(yōu)化
算法層次的優(yōu)化主要是指在參數(shù)選定的情況下,對部分算法所作的替換或優(yōu)化。和參數(shù)的選擇一樣,算法層次優(yōu)化也主要受優(yōu)化策略的指導(dǎo)。如運(yùn)動(dòng)匹配準(zhǔn)則是選用SSD、SAD或SATD。如果只看中準(zhǔn)確程度,則選擇SSD最佳;如果只看中運(yùn)行速度,則選擇SAD最佳;如果要兼顧二者,則選用SATD是比較好的一個(gè)方案。在進(jìn)行算法優(yōu)化時(shí)還應(yīng)該注意一個(gè)問題,即要考慮實(shí)際運(yùn)行平臺的支持情況。如在追求速度的策略下,匹配準(zhǔn)則選用SAD,如果只計(jì)算一半的點(diǎn)則會大大降低運(yùn)算速度。但是如果考慮ADSP-BF561匯編指令的設(shè)計(jì)情況,就會發(fā)現(xiàn)這樣做反而會增加指令數(shù),會使速度更低。算法層次優(yōu)化包括如下幾個(gè)部分:
(1)除法求余。改進(jìn)策略是浮點(diǎn)型算法盡量改為整型,64位盡量改為32位,32位盡量改為16位。而對于某些計(jì)算比較多的,則改為查表計(jì)算。在ADSP-BF561平臺上,一次32位整形除法需耗時(shí)300個(gè)CYCLE,而查表僅需幾個(gè)CYCLE,這樣的改進(jìn)能顯著提高速度。
(2)飽和函數(shù)。在視頻的計(jì)算中,幾乎每次像素的計(jì)算都會調(diào)用飽和函數(shù),X264代碼的實(shí)現(xiàn)中已將這部分代碼改為查表函數(shù),在其他的編解碼器實(shí)現(xiàn)中也有將這部分改為一個(gè)判斷和幾個(gè)邏輯運(yùn)算的形式。對大部分DSP平臺,采用判斷跳轉(zhuǎn)會打斷流水線,即使平臺有比較好的跳轉(zhuǎn)預(yù)測功能,打斷流水仍然會造成stall。所以查表方法是一種高效方法。而在ADSP-BF561匯編指令中,可以通過設(shè)置指令后綴或使用某些特殊指令來進(jìn)行飽和工作。甚至不用查表,在不同的場合使用不同的飽和算法能大大提高代碼的執(zhí)行效率。
(3)MC部分函數(shù)。實(shí)測中發(fā)現(xiàn)MC部分函數(shù)運(yùn)行效率不如ffmpeg解碼器中MC部分效率高,所以將這部分代碼用ffmpeg中的相應(yīng)部分替換。此外qpel16_hv函數(shù)中計(jì)算有冗余,減少這些冗余能提高代碼運(yùn)行效率。
(4)算法替代和改進(jìn)。幀間預(yù)測的改進(jìn):關(guān)于算法的改進(jìn)主要集中在對me(motionestimation)的改進(jìn)上,流程如圖2所示。costmin1=min(cost16,cost8,cost16×8,cost8×16),costmin2=min(costmin1,costsub),依次在16×16、8×8、16×8和8×16大小宏塊的整像素位置做預(yù)測,再做次像素估計(jì)和幀內(nèi)預(yù)測,選用匹配準(zhǔn)則函數(shù)(采用sad作為匹配準(zhǔn)則函數(shù))取得最小值的模式進(jìn)行編碼。每計(jì)算一種模式,都將sad值與一個(gè)經(jīng)驗(yàn)閥值做比較。當(dāng)sad值小于這個(gè)閥值時(shí),立即結(jié)束運(yùn)動(dòng)估計(jì),從而減少運(yùn)算量。
幀內(nèi)預(yù)測的改進(jìn):H.264標(biāo)準(zhǔn)所采用的幀內(nèi)預(yù)測模式除了DC模式都具有方向性,相鄰4×4塊都具有相關(guān)性。根據(jù)這樣的相關(guān)性,只將當(dāng)前4×4塊上邊和左邊選用預(yù)測模式及其相鄰的兩種預(yù)測模式作為當(dāng)前4×4塊的預(yù)測模式,當(dāng)其閥值都大于一個(gè)經(jīng)驗(yàn)閥值時(shí),才采用DC模式。這樣的方案不用一一計(jì)算9種預(yù)測模式,在復(fù)雜度、編碼效率、質(zhì)量和速度上取了一個(gè)折中。流程如圖3所示。
2.2.2.3 代碼層次優(yōu)化
針對ADSP-BF561平臺,代碼層次的優(yōu)化工作包括以下幾個(gè)方面:
(1)內(nèi)聯(lián)函數(shù)。將經(jīng)常調(diào)用的函數(shù)體較小的函數(shù)改為內(nèi)聯(lián)。編譯條件中有關(guān)于內(nèi)聯(lián)函數(shù)優(yōu)化的選項(xiàng)。內(nèi)聯(lián)函數(shù)的使用是將代碼的大小和運(yùn)行效率取一個(gè)折中。根據(jù)實(shí)際情況,代碼的大小并非限制條件,所以應(yīng)盡可能多地使用內(nèi)聯(lián)函數(shù)。在項(xiàng)目配置中選中when declared inline選項(xiàng)。
(2)跳轉(zhuǎn)預(yù)測。ADSP-BF561采用了靜態(tài)預(yù)測的方式來預(yù)測有條件判斷情況,預(yù)測不成功會造成4~8個(gè)內(nèi)核時(shí)鐘(CCLK)的延誤。如果事先知道某些跳轉(zhuǎn)的概率,將可能性最大的分支放在最前面,可以從概率上降低預(yù)測不成功而造成的stall。
(3)使用硬件支持循環(huán)。對于大部分平臺,將一些循環(huán)體小的循環(huán)展開也能提高效率。ADSP-BF561有兩組硬件計(jì)數(shù)器用以支持循環(huán)。所以除非是展開三層以上的循環(huán),否則,展開循環(huán)體不能提高效率。
(4)內(nèi)存。嵌入式系統(tǒng)的內(nèi)存是非常寶貴的資源。避免頻繁的動(dòng)態(tài)申請和釋放內(nèi)存,能減少碎片產(chǎn)生,提高內(nèi)存的利用率。X264工程也不會頻繁地申請釋放內(nèi)存。在項(xiàng)目中,具體做法是編寫平臺相關(guān)的malloc和free函數(shù)。將經(jīng)常使用的中間數(shù)據(jù)在L1數(shù)據(jù)空間中分配。
(5)注釋不需要代碼。去掉代碼中不需要的部分,主要會去掉CAVLC以及部分碼率控制、csp、cpu、信息統(tǒng)計(jì)、調(diào)試和psnr計(jì)算等部分代碼,這樣做的目的是為了減小文件大小和去除代碼中的一些跳轉(zhuǎn)。不建議刪除代碼,可以使用注釋符或用宏切換的方式,以防止以后參數(shù)改變時(shí)需要使用未使用過的代碼。
2.2.2.4 平臺層次優(yōu)化
ADSP-BF561相應(yīng)的編程參考和硬件參考對其平臺特性有詳細(xì)介紹。一些平臺自帶的優(yōu)化功能,如CACHE的開啟和配置等不專門在此討論。
評論