郭 昕,蘇寒松
(天津大學電子信息工程學院,天津300072)
H.264是ITU-T的視頻編碼專家組(VCEG)和ISO/IEC的活動圖像專家組(MPEG)聯合制定的視頻壓縮標準,引入了更多的新的高效的編碼技術,在相同圖像質量下,編碼效率提高了50%,但同時帶來了巨大的編碼運算復雜度,影響了實時的要求。DSP的運行速度已經可以滿足H.264對圖像進行實時處理的要求。本文采用合眾達公司基于TI達芬奇(DaVinci)DSP TMS320DM6446視頻處理模板Seed-DVS6446[1]來進行移植工作,由于 H.264 直接移植到DSP平臺上編碼效率很低,需對其進行優化才能達到實時編碼的要求。
德州儀器(TI)推出的TMS320DM6446采用Da-Vinci技術。TMS320DM6446采用雙核架構集成了一個時鐘頻率為594 MHz的C64x+DSP內核和一個297 MHz的ARM926EJ-S內核。TMS320DM6446是定點DSP,便于進行視頻處理的任務。由于其內部有一個ARM內核采用精簡指令集,所以可以對DSP進行精確的控制,實現DSP的高速處理。并且集成了豐富的外設接口,如DDR2存儲器接口、視頻處理前端模塊VPFE和視頻顯示設備連接的視頻處理后端模塊VPBE等,方便進行視頻處理[2]。
其中,TMS320C64x+DSP是 TMS320C6000系列里最高性能的定點DSP平臺,基于第二代高性能超長指令字結構,使其更適合數字多媒體的應用TMS320C64x+DSP處理器集成了64個32 bit通用寄存器、8個高性能獨立功能單元—2個乘法器和6個算術邏輯單元。TMS320DM6446采用二級Cache結構,L1程序Cache為256 kbit直接映射Cache、L1數據Cache為640 kbit的雙向配置Cache、L2存儲/Cache包含一個512 kbit的存儲器空間由程序和數據共享[3]。
H264的實現版本主要有3種:JM、X264、T264,相比較而言,作為官方測試源碼,JM更偏重于學術研究,編碼復雜度高,不宜實用;T264是國內組織自行編寫的代碼,速度遠高于JM,但目前還不甚完善;而X264結合了JM和T264的各自優點,所以本文選用 X264 作為算法原型[4]。X264 編碼流程[5-6]如圖1所示。

圖1 X264編碼流程
Baseline檔次已經具備所需要的功能[7],所以刪除程序中Baseline檔次以外的功能模塊(包括cabac.c和eval.c等),以及源程序中的解碼部分;因為實時編碼應用的環境要求低緩存延遲,而B幀預測需要較大緩存,決定去除B幀;采用幀方式,而去除和場方式有關的代碼和數據;muxers.c文件的一些函數主要是定義了對 yuv、mp4、y4m、mkv文件格式的輸入輸出支持,將yuv部分單獨提出來在X264.c中重寫,這樣重寫的代碼就只針對yuv視頻;由于主處理器TMS320DM6446是定點DSP,然而在X264中存在一定比例的浮點運算,浮點運算是很費時的,因此保留計算 Y、U、V三種分量的PSNR值浮點運算外,其它的都需要刪除;在源程序中,使用了大量的語句進行調試和測試,用于觀察編譯器的狀態并防止一些異常情況,如assert函數printf函數、exit函數以及用于help提示信息、文件操作、用戶界面操作和Debug信息等,在能夠確保程序正確執行的前提上,基本上可以去除;此外很多函數和數據在整個系統中,雖然被定義和聲明了,卻從來沒有被真正使用過,對于這一點,CCS的編譯器給出了警告,把這一部分也刪除。
(1)X264程序是在VC環境下開發的,包含大量適用于VC環境下的頭文件,由于TMS320C6000實時支持庫包括ISO標準庫以及與DSP硬件相關的特殊指令庫,與VC的實時支持庫不盡相同,一些VC支持的庫不被C6000系統所支持,例如VC中支持的malloc、calloc等動態存儲分布函數,在CCS中都包含在stdlib庫中,因此必須對原來的include文件進行修改;CCS中沒有timeb.h只能用DSP/BIOS中的CSL庫函數CLK_getltime實現原有的計時系統。需要根據TMS320C6000的優化編譯器用戶手冊在CCS庫中匹配到與之功能相類似的文件和函數。
(2)CCS只兼容ANSIC代碼,所以需要對非標準C部分的代碼進行修改,使之能在CCS環境下運行的C代碼。
(3)在VC中,編譯器對所有的未初始化的變量默認統一賦上了初值0。而CCS同樣會對未初始化的變量進行系統賦值,但賦的值決定于相應存儲器位置的原有數據,會造成程序的重大錯誤。因此,必須在移植時對所有變量進行初始化。
(4)CCS和VC環境下的數據類型并不完全相同,兩者數據類型對比見表1。在CCS中,長整型變量long在存儲器中被分配了40 bit。從節約CPU處理時間角度考慮應對其進行相應的數據類型調整。

表1 數據類型對比
C語言定義了bool數據類型,而CCS中并未定義數據類型bool,所以如果在CCS中用到bool數據類型時,需要預定義。
(5)原始的X264代碼是基于PC平臺的,程序通過采用MMX和SSE語言編寫SAD、DCT等函數使X264具有很高的編碼速度,然而DSP和微處理的體系結構不同使得這些技術不能應用在DSP中,在X264代碼中將HAVE_MMX編譯選項屏蔽,同時將代碼中與該編譯選項相關的代碼注釋掉,只保留用標準C函數編寫的部分。
在CCS中,設置程序和數據在寄存器中的存放是由編寫.cmd文件來完成的,也可以通過MEM配置工具將每一個段指定到某個邏輯存儲器空間中去。除了這種按段整體的分配之外,CCS還提供了一些類似預編譯的宏指令如#PRAGMA CODE_SECTION()#PRAGMA DATA_SECTION,可以在代碼中把某個函數或者數據指定到某個虛擬存儲器空間中去。把進行編碼計算中可能被調用頻繁的程序段(如DCT變換、SAD)放在片內程序存儲區中,把頻繁用到的數據段分配到片內數據存儲器中,把其他程序和數據段放在片外存儲器中,另外,考慮到一幀圖像的數據量很大,故將參考幀和當前幀的數據放到片外,在需要用到當前塊和參考幀數據時,再將它們從外存讀入到內存中,提高效率。
堆(heap)和棧(stack)的默認值為1 kB(kbyte)。可以在編譯選項中修改其默認值,也可以用.cmd文件來對系統中的-heap和-stack進行配置。由于X264編碼器中存在大量的動態存儲空間的分配和函數的頻繁嵌套調用,在代碼移植初期,應盡量將heap和stack設置的足夠大,以防止分配的存儲空間不夠,優化時再根據具體情況做相應的調整。
在代碼調試過程中編譯器選項設置為-g-kpm-op0-o3-fr"$(Proj_dir)"-d"_DEBUG"-mt-mw-mh-ms0-mv6400+
-g選項使能符號調試和匯編源語句調試。no debug:生成的程序較精簡,但不能對其進行調試。對程序調試完成后可以選擇此項。
-o3選項使編譯器執行各種優化循環的方法,比如軟件流水、循環展開和SIMD(單指令多數據流)等技術,使編碼時間大概減少到未優化之前的1/2左右,并且和-g選項一起使用時,程序優化不會出現錯誤。
-k選項選擇后,編譯器將保留編譯過程產生的asm文件,在asm文件中,編譯器的缺省的反饋信息也同時保留下來。-mw選項也可以生成詳細的消息反饋,反饋信息基本上集中于循環的分析以及如何對循環進行流水編排從而提高性能。用戶可以依照其對程序進行修改。
-pm選項表示程序級優化,編譯器在編譯時可以從整個程序的角度來優化程序。-op(n):通常和-pm一起聯合使用,控制程序級的優化。-op0選項說明有外部變量引用和函數調用。
-mt選項向編譯器說明代碼中沒有使用混迭技術,打開-pm和-mt選項后可以提高編碼一幀的時間3 ms~4 ms。
-mh:-mh[n]:去掉流水線 epilog(排空),減小程序的大小。
-ms0選項不使用冗余進行優化,減少程序的大小。一般推薦-o與-ms0和-ms1聯合使用,表示性能優化最重要,同時要考慮代碼尺寸。
X264編碼器提供了4種整像素運動估計搜索算法:X264_ME_DIA(鉆石搜索算法);X264_ME_HEX(六邊形搜索算法);X264_ME_UMH(非對稱十字型多層次六邊形格點搜索算法);X264_ME_ESA(全搜索算法)。X264_ME_ESA算法的PSNR(峰值信噪比)最高,X264_ME_UMH,X264_ME_HEX算法依次降低,X264_ME_DIA算法最低,但相互之間的質量差別并不大,碼率差別也很小,但編碼速度上X264_ME_DIA算法最快,為了滿足實時的要求,選用X264_ME_DIA算法并對其改進[10]。
(1)匹配準則
運動估計一般的匹配準則是采用率失真最優化,準則匹配誤差函數為:

其中SAD(絕對差值和)計算公式如下:

式中:M、N分別表示當前編碼宏塊的長寬尺寸R(MV-PMV)代表了對運動矢量差編碼所需比特數;λmotion為拉格朗日常數[11]。文中將J(MV λmotion)最小的點記為最小誤差點MBD(Minimum Block Distortion)。
(2)搜索起點
候選的 MV包括:當前塊的預測運動矢量PMV;當前塊左、左上、上、右上塊的運動矢量MV參考幀(本文只采用一個參考幀)中的當前位置塊、右邊塊、下邊塊運動矢量乘以時間差權重之后的MV;還有(0,0)。在候選 MV中選擇使得J(MV,λmotion)最小的為最佳MV,該MV對應的點為運動估計的搜索起點.
(3)搜索方法的改進:以(2)中所得的搜索起點為中心點,對搜索區域內的點以如圖2(a)所示的小菱形模板(模板半徑為1),進行搜索,即對中心和菱形四個頂點計算匹配誤差,得到MBD點,并記最小代價為bcost。若MBD點在菱形的中心,則這個點就是整個搜索域內的最優匹配點,若不是,則以現在的MBD點為中心進行小菱形搜索,直到MBD點落在中心點[12]。
在搜索過程中會出現某些點的重復搜索,例如,從圖2(b)中可以看出 a、b、c、d、e為搜索過程中重復搜索的點,重復搜索必然造成運動估計效率低下。采用無重復搜索的小鉆石搜索法時,第1次搜索5點,第2次搜索3點(△表示),第3次搜索2點(□表示),第4次搜索2點(◆表示),只需12次搜索,可以省去不少計算量。

圖2 鉆石搜索模板及搜索路徑舉例
(4)提前終止:當計算16×16模塊時,由計算SAD的代碼可知每個塊需要計算pixl[x]-pix2[x]減法16×16次,在程序中添加if(i_sum>=bcost)條件判定,若滿足提前終止循環計算,即在i_sum的值大于或等于最優的代價時跳出循環,節省多余的計算量,具體程序十分簡單不在此贅述。
視頻編碼需要處理較大的數據量,如一幀CIF格式的YUV數據約有150 kB,而X264除了原始數據輸入外,處理完圖像數據的傳出圖像、插值數據輸出、圖像上下邊界擴展、運動估計時參考幀圖像的傳入等都涉及到大量的數據搬移,但DSP對不同的存儲器的訪問速度相差數倍。為了提高編碼器的運行效率,節省DSP核對各個模塊訪問所消耗的時鐘周期,需要啟用DSP的DMA作為數據在兩個存儲器之間的傳輸通路。C64x+在外部存儲器與內部存儲器之間的數據傳遞可以通過增強型DMA(EDMA)實現。在片內存儲器L2中開辟兩個大小相同的緩沖區Pingbuffer和Pongbuffer,兩個緩沖區輪流交替工作。當EDMA傳輸數據到Pingbuffer時,CPU處理Pongbuffer中的數據;當CPU和EDMA操作完畢后,Pingbuffer和Pongbuffer緩沖區互換,EDMA繼續傳輸數據覆蓋 Pongbuffer中的數據,CPU處理Pingbuffer中的數據。由于傳輸時間小于編碼運算的時間,則EDMA完全獨立于CPU在后臺運行,不耗費一個時鐘周期,實現了數據傳輸和CPU并行提高了代碼的運行效率。
(1)內聯函數優化:C6000編譯器提供了許多內聯函數intrinsics,可迅速優化C代碼,使用時與普通函數一樣調用,它們與C6000匯編指令一一對應,直接使用內聯函數可以快速實現SIMD[14],如未使用內聯函數優化前X264程序計算16×16模塊的SAD的函數每次只能計算一個像素點的絕對值差,而使用內聯函數_mem4()、_subabs4()等進行優化后,一次可以計算4個像素點的絕對值差,大大提高了運算速度。
(2)循環優化:C語言中使用偽指令#pragma MUST_ITERATE(min,max,multiple)可以明確告訴編譯器循環次數或最小循環次數,從而防止冗余循環產生,也便于編譯器將循環展開,此外,由于在編譯器進行優化時只會在最內層循環中形成一個pipeline,盡量將多重循環拆開形成一個單層循環不要使用多重循環,這樣循環語句才能充分利用編譯器的軟件流水線。
TMS320DM6446的時鐘頻率為594 MHz,選取100幀、CIF格式(352×288)的測試序列container foreman、mobile,量化步長取 27,視頻為 Y:U:V 4:2 0格式,采用IPPP…編碼模式。表2為優化前后各視頻序列的結果比較,從表中可以看出,優化后的編碼器幀率比優化前有了較大幅度的提高,基本能夠實現CIF格式實時編碼,PSNR值在優化前后并沒有明顯變化,說明優化后編碼質量未受到大的影響

表2 優化前后對比
本文結合DM6446的硬件結構特點,將X264編碼器在DM6446上成功地進行了移植,并對編譯器選項、運動估計、內聯函數及DSP在編碼時的數據搬移等方面進行了優化,基本可達到CIF格式序列的實時編碼要求。
[1]SEED-DVS6446 用戶指南[S].Texas Instruments,2008.10.
[2]TMS320DM644x DMSoC VPBE User’s Guide[S].Texas Instruments,2007.04.
[3]李方慧,王飛,何佩琨.TMS320C6000系列DSPs原理及應用[M].電子工業出版社,2003.
[4]李博丞,嚴勝剛,曲鵬.基于TMS320DM6446的H.264編碼器實現與優化[J].電子設計工程,2009,17(05):122-123.
[5]畢厚杰.新一代視頻壓縮編碼標準——H.264/AVC[M].北京:人民郵電出版社,2005.
[6]劉仕翔.基于DM642 DSP的x264編碼器研究及實現[D].西南交通大學,2010.17-18.
[7]王鶴,H.264視頻編碼算法在DM6446上的研究與實現[D].內蒙古大學,2011.40-41.
[8]Video Encoding Optimization on TMS320DM64x/C64x[S].Texas Instruments,2004.10
[9]TMS320C6000 Optimizing Compiler User’s Guide[S].Texas In struments,2002
[10]王宏志,蘇令華,王曉紅.基于達芬奇平臺的視頻編碼器實現[J].計算機測量與控制,2011,19(05):1159-1160
[11]石迎波,吳成柯.基于H264的多參考幀運動估計快速算法[J].計算機工程,2008,34(10):218-220
[12]錢瑛.基于X264的運動估計算法研究[J].硅谷,2008,24
[13]TMS320C6000 DSP Enhanced Direct Memory Access(EDMA Controller Reference Guide(SPRU234A)[S].Texas Instrument.
[14]劉定佳.H.264視頻編碼算法研究及DSP實現[D].西安電子科技大學,2010.49-50.