??? 摘? 要: 提出了一個(gè)完整的AVS變字長解碼器的硬件架構(gòu),在設(shè)計(jì)中采用加入FIFO的方法構(gòu)成流水結(jié)構(gòu),并盡量減少變字長解碼器中各子模塊的運(yùn)行節(jié)拍,大大提高了系統(tǒng)的運(yùn)行速度。本設(shè)計(jì)已經(jīng)通了FPGA驗(yàn)證。該變字長解碼器不僅可以成為其他AVS解碼器的硬件加速器,同時(shí)由于視頻編解碼標(biāo)準(zhǔn)的相似性,稍加改動即可應(yīng)用在其他的視頻標(biāo)準(zhǔn)中。?
??? 關(guān)鍵詞: AVS;變字長解碼器;FPGA
?
??? AVS(Audio Video coding Standard)是我國具備自主知識產(chǎn)權(quán)的第二代信源編碼標(biāo)準(zhǔn),是《信息技術(shù)先進(jìn)音視頻編碼》系列標(biāo)準(zhǔn)的簡稱。2006年2月底,AVS標(biāo)準(zhǔn)被正式批準(zhǔn)為數(shù)字音視頻國家標(biāo)準(zhǔn),并于2006年3月1日起正式實(shí)施。它與現(xiàn)今國際上最先進(jìn)的視頻編碼標(biāo)準(zhǔn)H.264相比,在實(shí)現(xiàn)同等壓縮性能的前提下,其計(jì)算復(fù)雜度有明顯降低。雖然復(fù)雜度較H.264有所降低,但用軟件實(shí)現(xiàn)解碼仍然很難達(dá)到實(shí)時(shí)解碼的效果,因此需要采用硬件解碼器。?
??? 根據(jù)AVS標(biāo)準(zhǔn)[1]設(shè)計(jì)的基于硬件的解碼器框圖如圖1所示。?
?
?
??? 解碼器由系統(tǒng)控制器和各功能模塊組成,模塊與模塊之間加入FIFO,使得模塊間可以以8×8塊的大小進(jìn)行流水處理??傮w結(jié)構(gòu)的組成模塊為:系統(tǒng)控制模塊(Sym_controller)、變字長解碼模塊(VLD)、反量化模塊(IQ)、反變換模塊(IICT)、幀內(nèi)預(yù)測模塊(Intra_pred)、幀間預(yù)測模塊(Inter_pred)、環(huán)路濾波模塊(Deblock)、存儲模塊(Restore)等。系統(tǒng)控制模塊控制各個(gè)模塊的工作狀態(tài)和模塊與模塊之間的通信。為了節(jié)省片上資源,將輸入碼流、已解碼的幀和參考幀等需要大量存儲空間的部分都存放在片外存儲器內(nèi)。片外存儲器與片內(nèi)模塊之間通信的數(shù)據(jù)寬度設(shè)為128 bit,以減少片內(nèi)與片外數(shù)據(jù)交互所耗費(fèi)的時(shí)間。?
??? 在整個(gè)解碼器結(jié)構(gòu)中,變字長解碼器(VLD)位于此硬件解碼器的第一級,因此其速度要求較高。本文針對AVS變長碼字解碼的特殊性設(shè)計(jì)了一種適用于AVS解碼的VLD結(jié)構(gòu)。?
1 變字長解碼器的設(shè)計(jì)?
1.1 變字長解碼器的功能和結(jié)構(gòu)?
??? 變字長解碼器的功能是將輸入的碼流解析成一系列語法元素,主要包括:序列頭信息、幀頭信息、宏塊頭信息及宏塊亮度色度系數(shù)。解析出的宏塊層以上的語法元素加以存儲,宏塊層以下的語法元素則直接傳送入下一級模塊進(jìn)行處理。?
??? 變字長解碼器的硬件結(jié)構(gòu)主要由三部分組成:預(yù)處理模塊(pre_process)、解析模塊(parsing)和FIFO。在兩個(gè)功能模塊之間加入FIFO,目的是使預(yù)處理模塊和解析模塊能夠?qū)崿F(xiàn)并行操作,提高變字長解碼器的運(yùn)行速度。從外部存儲器中以128 bit的位寬將碼流輸入到第一級FIFO中,經(jīng)過預(yù)處理模塊處理后的數(shù)據(jù)進(jìn)入第二級FIFO緩存,最終經(jīng)過解析模塊后完成變字長解碼功能。?
1.2 變字長解碼器的設(shè)計(jì)?
??? 變字長解碼器的功能決定了其解碼速度,但由于其解析的大部分語法元素的長度是不固定的,需要解完一個(gè)語法元素才可以知道它的長度,然后進(jìn)行下一個(gè)語法元素的解析,所以很難采用并行操作,給設(shè)計(jì)增加了難度。本設(shè)計(jì)一方面考慮盡量減少VLD各子模塊的運(yùn)行節(jié)拍,另一方面從架構(gòu)入手,通過適當(dāng)使用FIFO構(gòu)成流水結(jié)構(gòu),來達(dá)到整體運(yùn)行速度的提高。?
1.2.1 預(yù)處理模塊的設(shè)計(jì)?
??? 預(yù)處理模塊的功能是去除起始碼前綴以及偽起始碼的插入位。?
??? 起始碼:起始碼標(biāo)志著一個(gè)單元的開始,同時(shí)又意味著前一個(gè)單元的結(jié)束。起始碼包括起始碼前綴和起始碼的值兩部分。起始碼前綴為固定比特串0x000001,起始碼的值是一個(gè)有特定意義的8 bit整數(shù)。起始碼前綴在碼流中起到一個(gè)標(biāo)識符的作用,但在解碼過程中沒有實(shí)際的意義,因此需要在解碼時(shí)將其去除。?
??? 偽起始碼:當(dāng)部分語法元素取特定值時(shí)就會在單元內(nèi)部出現(xiàn)與起始碼前綴相同的比特串,如果不做處理,就會在解碼過程中出現(xiàn)誤讀起始碼,從而導(dǎo)致解碼錯(cuò)誤。因此在編碼時(shí),對這種情況做了特殊處理,其過程為在每寫入一位時(shí),如果該位是一個(gè)字節(jié)的第二最低有效位,檢查該位之前寫入的22位,如果這22位均為‘0’,則在該位之前插入兩位的‘10’,而該位成為下一個(gè)字節(jié)的最高有效位。因此在解碼過程中,遇到偽起始碼時(shí)應(yīng)將其添加的‘10’去除。?
??? 預(yù)處理模塊的設(shè)計(jì)結(jié)構(gòu)如圖2所示。?
?
?
??? 圖2中reg_c為32位寄存器,用來接收來自fifo_in的32位數(shù)據(jù),reg_c通過控制器controller輸出的移位控制進(jìn)行相應(yīng)的移位操作,將數(shù)據(jù)移入24位寄存器reg_b中。檢測器detector檢測寄存器reg_b中的數(shù)據(jù)是否為起始碼前綴或偽起始碼,并將檢測結(jié)果送入控制器,控制器根據(jù)檢測結(jié)果發(fā)出相應(yīng)的控制信號。經(jīng)過檢測處理后的數(shù)據(jù)送入40位寄存器reg_a等待輸出。加法器add_a和加法器add_c的作用是對寄存器reg_a和寄存器reg_c進(jìn)行計(jì)數(shù)。當(dāng)加法器add_a計(jì)數(shù)達(dá)到32時(shí),表明寄存器reg_a中已經(jīng)有32 bit的數(shù)據(jù)等待輸出,此時(shí)加法器add_a進(jìn)位,控制器發(fā)出fifo_out的寫信號,將reg_a中的32位數(shù)據(jù)送入fifo_out中;當(dāng)加法器add_c計(jì)數(shù)達(dá)到32時(shí),表明reg_c已空,此時(shí)加法器add_c進(jìn)位,控制器發(fā)出fifo_in的讀信號,從fifo_in中讀取新的32 bit數(shù)據(jù)放入寄存器reg_c中。?
1.2.2 解析模塊的設(shè)計(jì)?
??? 解析模塊的功能是作定長、變長碼字的解碼。解析幀內(nèi)預(yù)測模式、運(yùn)動向量、參考幀索引和殘差系數(shù)。?
??? 設(shè)計(jì)中解析模塊主要由以下幾個(gè)部分構(gòu)成:變字長解碼控制器(VLD_controller),桶形移位器(B_shifter),長度檢測器(length_detector),code_num計(jì)算器(code_num),查表模塊(look_up_table)。其結(jié)構(gòu)如圖3所示。?
?
?
??? 解析模塊的輸入碼流為經(jīng)過預(yù)處理后的數(shù)據(jù)。變字長解碼控制器由狀態(tài)機(jī)來控制整個(gè)解析定長及變長語法元素的過程。當(dāng)解析的語法元素為定長時(shí),控制器輸出此語法元素的長度len,同時(shí)接收來自桶形移位器的輸出碼流數(shù)據(jù)data_out,將數(shù)據(jù)data_out右移(32-len)后即可得到語法元素的值。與此同時(shí),桶形移位器將解碼過的長度為len的數(shù)據(jù)移出,并準(zhǔn)備好下次需要解碼的數(shù)據(jù);當(dāng)解析的語法元素為變長時(shí),控制器控制桶形移位器輸出數(shù)據(jù)data_out給長度檢測器,經(jīng)檢測后得到變長碼的長度vlc_len,之后將數(shù)據(jù)輸入碼字值計(jì)算模塊,計(jì)算得到碼字的code_num,若為非殘差數(shù)據(jù),則將數(shù)據(jù)返回給控制模塊,若為殘差數(shù)據(jù),則將解得的code_num作為查表模塊的輸入,查表得到相應(yīng)的(run,level)對后,經(jīng)過反掃描反變換后得到殘差數(shù)據(jù),同時(shí)桶形移位器將解碼過的長度為vlc_len的數(shù)據(jù)移出并準(zhǔn)備好下次需要解碼的數(shù)據(jù)。下面介紹解析模塊(parsing)中各功能模塊的結(jié)構(gòu)。?
??? (1)桶形移位器的設(shè)計(jì)?
??? 桶形移位器的作用是將已經(jīng)解碼過的數(shù)據(jù)移出,并保證每次輸出的數(shù)據(jù)均為未解碼的數(shù)據(jù)。它在解析模塊中非常重要,桶形移位器準(zhǔn)確快速的移位是能夠正確解碼的前提。本文所設(shè)計(jì)的桶形移位器狀態(tài)機(jī)結(jié)構(gòu)如圖4所示。?
?
?
??? wait & data_out:等待狀態(tài)?
??? 當(dāng)桶形移位器在此狀態(tài)時(shí)表明移位器可用,并且移位器輸出引腳上的數(shù)據(jù)data_out為未解碼的數(shù)據(jù)。當(dāng)長度使能信號len_en為低電平時(shí),表明沒有長度信號輸入,保持在此狀態(tài);當(dāng)長度使能信號len_en為高電平時(shí),則表明有長度信號輸入,此時(shí)進(jìn)入寄存器數(shù)據(jù)移位狀態(tài)。?
??? reg_shift:寄存器數(shù)據(jù)移位狀態(tài)?
??? 將接收到的長度信號(若為定長,接收到長度為len,若為變長,則需要經(jīng)過長度檢測(length_detect)得到變長碼字長度vlc_len)作為移位的長度,將桶形移位器中數(shù)據(jù)左移。此操作將已經(jīng)解碼過的數(shù)據(jù)移出移位寄存器。同時(shí),將接收到的長度送入累加器。當(dāng)累加器的值沒有達(dá)到32時(shí),轉(zhuǎn)到等待狀態(tài);當(dāng)累加器的值達(dá)到32時(shí),累加器發(fā)生溢出,其溢出位作為FIFO的讀信號,進(jìn)入FIFO讀狀態(tài)。?
??? fifo_read:FIFO讀狀態(tài)?
??? 當(dāng)累加器溢出,則進(jìn)入FIFO讀狀態(tài)。在此狀態(tài)向FIFO發(fā)出讀取信號,讀取FIFO中的32位數(shù)據(jù)裝入桶形移位器,并回到等待狀態(tài)。?
??? length_detect:長度檢測狀態(tài)?
??? 當(dāng)需要解碼的語法元素為變長時(shí),則需要經(jīng)過長度檢測狀態(tài)。長度檢測器在此狀態(tài)檢測出變長碼字的長度,并將其送入移位器進(jìn)行移位(由于長度檢測狀態(tài)取決于長度檢測器,因此用虛線標(biāo)出)。?
??? 由圖4中的狀態(tài)跳轉(zhuǎn)可以看出,當(dāng)桶形移位器不需要從FIFO中讀取數(shù)據(jù)時(shí),僅需要兩個(gè)時(shí)鐘周期即可完成數(shù)據(jù)的輸出、長度接收、移位和碼字值計(jì)算,而當(dāng)移位器需要從FIFO中讀取數(shù)據(jù)時(shí),也僅需要三個(gè)時(shí)鐘周期即可回到可用狀態(tài),這是因?yàn)樵谠O(shè)計(jì)時(shí),對于定長碼,將其數(shù)據(jù)輸出與長度接收并行執(zhí)行;而對于變長碼,將桶形移位器的移位操作和碼字值計(jì)算器的計(jì)算操作并行執(zhí)行。這種設(shè)計(jì)不僅簡化了移位器的工作節(jié)拍,而且模塊間并行執(zhí)行的思想也使整個(gè)解析模塊的解碼速度得以提高。?
??? (2)長度檢測器的設(shè)計(jì)?
??? 長度檢測器用來檢測指數(shù)哥倫布碼字的長度。本文根據(jù)基于H.264的長度檢測器[2]并結(jié)合AVS指數(shù)哥倫布解碼的要求設(shè)計(jì)了一個(gè)符合AVS標(biāo)準(zhǔn)的長度檢測器,其結(jié)構(gòu)如圖5所示。?
?
?
??? 圖中優(yōu)先編碼器電路priority_encoder用Verilog可以描述為:?
reg [1:0] priority_out;?
always @ (data_in)?
begin?
??? casez (data_in)?
??? 4′b1???:priority_out=0;?
??? 4′b01??:priority_out=1;?
??? 4′b001?:priority_out=2;?
??? 4′b0001:priority_out=3;?
??? default:?? priority_out=0;?
??? endcase?
end?
??? 由于AVS碼字長度不會超過32 bit,因此其前導(dǎo)零的長度最大為15 bit,所以只需檢測16 bit即可得到指數(shù)哥倫布碼的前導(dǎo)零的個(gè)數(shù),進(jìn)而得到碼字的長度。檢測過程為:先將16 bit數(shù)據(jù)以4 bit為單位分成四組,分別輸入到4個(gè)或門中,再經(jīng)過優(yōu)先編碼器1(priority_encoder1)就可以知道第一個(gè)“1”在哪一組中,然后通知復(fù)用器將這一組的4位數(shù)據(jù)輸出,經(jīng)過優(yōu)先編碼器2(priority_encoder2)即可檢測出這一組中第一個(gè)“1”的位置,最后根據(jù)這個(gè)組在整個(gè)16 bit數(shù)據(jù)中所處的位置以及第一個(gè)“1”在此組中的位置就可以計(jì)算出其前導(dǎo)零的長度M,結(jié)合變字長碼控制器給出指數(shù)哥倫布碼的階數(shù)K,由公式len=2M+1+K即可求出指數(shù)哥倫布碼字的長度。?
??? (3)碼字值計(jì)算器的設(shè)計(jì)?
??? 對于K階指數(shù)哥倫布,其碼字值的計(jì)算公式為:?
??? code_num=2M+K-2K+INFO?
??? 對于0階指數(shù)哥倫布,若其語法元素的描述子為ue(v),語法元素的值等于K=0時(shí)的碼字值;若其語法元素的描述子為se(v),語法元素與碼字值code_num的對應(yīng)關(guān)系如下:?
??? 語法元素值=(-1)code_num+1×ceil(code_num÷2);?
??? 若其語法元素的描述子為me(v),則先求出0階指數(shù)哥倫布碼字值再根據(jù)AVS標(biāo)準(zhǔn)[1]中的表15和表16求MbCBP和MbCBP422的值;若其語法元素的描述子為ce(v)時(shí),則將計(jì)算出的碼字值送入查表模塊解析殘差系數(shù)。?
??? (4)查表模塊的設(shè)計(jì)?
??? 經(jīng)過碼字值計(jì)算器計(jì)算得出的code_num作為查表模塊的輸入,得到(run,level)對,將level值反量化后進(jìn)行游程解碼再經(jīng)過反變換后即可得到8×8塊的殘差系數(shù)矩陣。之所以將反量化過程在游程解碼之前進(jìn)行是因?yàn)榻?jīng)過變換編碼的一個(gè)像素塊中大部分?jǐn)?shù)據(jù)均為0,如果對所有系數(shù)均進(jìn)行反量化處理則會產(chǎn)生較大的時(shí)間冗余,因此在進(jìn)行游程解碼之前僅將非零系數(shù)進(jìn)行反量化[3],反量化過程結(jié)束之后進(jìn)行游程解碼。游程解碼結(jié)構(gòu)如圖6所示。?
?
?
??? 游程解碼的過程是由圖6中的寄存器堆完成的。此寄存器堆有以下四種工作模式:?
??? reg_mode:寄存器模式?
??? 當(dāng)寄存器堆處在此模式時(shí),寄存器堆中數(shù)據(jù)保持不變。?
??? chain_mode:鏈模式?
??? 當(dāng)寄存器堆處在此模式時(shí),即進(jìn)行游程解碼的過程。寄存器中的值按照虛線箭頭所指的方向進(jìn)行數(shù)據(jù)移動。具體解碼過程為:當(dāng)需要游程解碼時(shí),讀一對(level,run)數(shù)據(jù),先把level數(shù)據(jù)進(jìn)行反量化,然后將反量化之后的level值輸入標(biāo)號為0的寄存器reg_0,將與level相對應(yīng)的run值作為計(jì)數(shù)初值,每當(dāng)主時(shí)鐘上升沿到來時(shí)將計(jì)數(shù)值減1,并將原來放在reg_0中的數(shù)據(jù)根據(jù)虛線箭頭所指的方向進(jìn)行寄存器的賦值,而原來存放level值的寄存器清零。重復(fù)操作,直至計(jì)數(shù)值減為0,再進(jìn)行下一輪(level,run)的求解。在前面求解level、run時(shí),塊的結(jié)束以向FIFO輸入一個(gè)全1為標(biāo)志。因此在游程解碼過程中,如果遇到全1標(biāo)志則表明一個(gè)塊已經(jīng)解碼結(jié)束,此時(shí)就可以進(jìn)入idct模式進(jìn)行數(shù)據(jù)的idct處理。?
??? idct_mode:idct模式?
??? 當(dāng)寄存器堆處在此模式時(shí),寄存器堆向idct模塊輸入相應(yīng)數(shù)據(jù),并接收idct之后的數(shù)據(jù)。?
??? row_mode:列模式?
??? 當(dāng)寄存器堆處在此模式時(shí),寄存器中的值按照實(shí)線箭頭所指方向進(jìn)行數(shù)據(jù)移位,此時(shí)即將寄存器堆中數(shù)據(jù)以行為單位組合,共用8個(gè)時(shí)鐘周期,將8行數(shù)據(jù)送入下一級FIFO緩存,等待下一步處理。?
??? 在解碼過程中,根據(jù)需要從這四種模式中切換,最終將解碼后的殘差數(shù)據(jù)存入下一級FIFO中。?
2 變字長解碼器仿真結(jié)果?
??? 本文設(shè)計(jì)的變字長解碼器結(jié)構(gòu)用Verilog HDL描述,在Xilinx的ISE環(huán)境下進(jìn)行了綜合,并用Modelsim6.2進(jìn)行了軟件仿真。利用AVS標(biāo)準(zhǔn)參考軟件rm5.2j產(chǎn)生測試碼流數(shù)據(jù),將碼流數(shù)據(jù)輸入到所設(shè)計(jì)的模型中,然后將輸出數(shù)據(jù)與標(biāo)準(zhǔn)輸出進(jìn)行對比,測試功能的正確性及完整性。軟件仿真正確之后則進(jìn)行開發(fā)板的驗(yàn)證。本設(shè)計(jì)采用的是Xilinx公司的Virtex4系列XC4VSX35型FPGA開發(fā)板進(jìn)行驗(yàn)證,用FPGA調(diào)試工具ChipScop Pro觀察信號在FPGA開發(fā)板上的運(yùn)行情況。經(jīng)過多次數(shù)據(jù)勘測,結(jié)果表明本文設(shè)計(jì)的變字長解碼器在FPGA開發(fā)板中運(yùn)行結(jié)果正確。結(jié)果如圖7所示。?
?
?
??? 該變字長解碼器不僅可以成為其他AVS解碼器的硬件加速器,同時(shí)由于視頻編解碼標(biāo)準(zhǔn)的相似性,稍加改動即可應(yīng)用在其他的視頻標(biāo)準(zhǔn)中,具有很好的應(yīng)用價(jià)值。?
參考文獻(xiàn)?
[1] 數(shù)字音視頻編碼技術(shù)標(biāo)準(zhǔn)工作組.信息技術(shù) 先進(jìn)音視頻編碼 第2部分:視頻(GB/T 200090.2-2006).中國國家標(biāo)準(zhǔn)化管理委會,2006.?
[2] 顏明,陳詠恩.高效的H.264指數(shù)哥倫布解碼器設(shè)計(jì).現(xiàn)代電子技術(shù),2007(3):71-73.?
[3] 趙策,劉佩林.AVS游程解碼、反掃描、反量化和反變換優(yōu)化設(shè)計(jì).信息技術(shù),2007(2):54-57.?
[4] 戴春泉,李錦濤,黃晁.適用于H.264視頻解碼器的VLD設(shè)計(jì).計(jì)算機(jī)工程,2005(13):162-164.?
[5] WU Di,GAO Wen,Hu Ming Zeng,et al.An Exp-Golomb?encoder and decoder architecture for JVT/AVS.?
[6] SHENG Bin,GAO Wen,XIE Don,et al.An efficient VLSI?architecture of VLD for AVS HDTV decoder.IEEE,Transactions on Consumer Electronics,52,2,2006:696-701.