【摘 要】本文是在閱讀了講解H.264/AVC中熵編碼相關(guān)內(nèi)容的書籍后的感想,主要介紹了熵編碼的基本原理,H.264/AVC中熵編碼的方法,重點介紹了基于上下文自適應(yīng)的可變長編碼(CAVLC),并將它和基于上下文二進(jìn)制算術(shù)編碼(CABAC)進(jìn)行了比較。
【關(guān)鍵詞】熵編碼;編碼算法;編碼比較
H.264是在網(wǎng)絡(luò)技術(shù)和視頻業(yè)務(wù)不斷發(fā)展的情況下產(chǎn)生的新一代視頻壓縮編碼標(biāo)準(zhǔn),它是由國際標(biāo)準(zhǔn)化組織與國際電訊聯(lián)盟組成的聯(lián)合視頻小組開發(fā)的。與原有標(biāo)準(zhǔn)相比,H.264提出了許多新技術(shù),在諸多方面都超越了原有的視頻技術(shù),減少了占用的硬件資源,降低了實現(xiàn)復(fù)雜性。其中就包括全新的熵編碼技術(shù)。
1、熵編碼編碼
使用長度不同的比特串對字母進(jìn)行編碼有一定的困難。尤其是幾乎所有幾率的熵都是一個有理數(shù)。
使用整數(shù)位元(bit)
哈夫曼編碼建議了一種將位元進(jìn)位成整數(shù)的算法,但這個算法在特定情況下無法達(dá)到最佳結(jié)果。為此有人加以改進(jìn),提供最佳整數(shù)位元數(shù)。這個算法使用二叉樹來設(shè)立一個編碼。這個二叉樹的終端節(jié)點代表被編碼的字母,根節(jié)點代表使用的位元。
熵編碼模型
要確定每個字母的比特數(shù)算法需要盡可能精確地知道每個字母的出現(xiàn)機(jī)率。模型的任務(wù)是提供這個數(shù)據(jù)。模型的預(yù)言越好壓縮的結(jié)果就越好。此外模型必須在壓縮和恢復(fù)時提出同樣的數(shù)據(jù)。在歷史上有許多不同的模型。
靜態(tài)模型
靜態(tài)模型在壓縮前對整個文字進(jìn)行分析計算每個字母的機(jī)率。這個計算結(jié)果用于整個文字上。
優(yōu)點:編碼表只需計算一次,因此編碼速度高。除在解碼時所需要的機(jī)率值外結(jié)果肯定不比原文長。
缺點:計算的機(jī)率必須附加在編碼后的文字上,這使得整個結(jié)果加長。計算的機(jī)率是整個文字的機(jī)率,因此無法對部分地區(qū)的有序數(shù)列進(jìn)行優(yōu)化。
動態(tài)模型
在這個模型里機(jī)率隨編碼過程而不斷變化。多種算法可以達(dá)到這個目的:
前向動態(tài):機(jī)率按照已經(jīng)被編碼的字母來計算,每次一個字母被編碼后它的機(jī)率就增高。
反向動態(tài):在編碼前計算每個字母在剩下的還未編碼的部分的機(jī)率。隨著編碼的進(jìn)行最后越來越多的字母不再出現(xiàn),它們的機(jī)率成為0,而剩下的字母的機(jī)率升高,為它們編碼的比特數(shù)降低。壓縮率不端增高,以至于最后一個字母只需要0比特來編碼。
優(yōu)點:模型按照不同部位的特殊性優(yōu)化;在前向模型中機(jī)率數(shù)據(jù)不需要輸送。
缺點:每個字母被處理后機(jī)率要重算,因此比較慢。計算出來的機(jī)率與實際的機(jī)率不一樣,在最壞狀態(tài)下壓縮的數(shù)據(jù)比實際原文還要長。
一般在動態(tài)模型中不使用機(jī)率,而使用每個字母出現(xiàn)的次數(shù)。除上述的前向和反向模型外還有其它的動態(tài)模型計算方法。比如在前向模型中可以不時減半出現(xiàn)過的字母的次數(shù)來降低一開始的字母的影響力。對于尚未出現(xiàn)過的字母的處理方法也有許多不同的手段:比如假設(shè)每個字母正好出現(xiàn)一次,這樣所有的字母均可被編碼。
模型度
模型度說明模型顧及歷史上多少個字母。比如模型度0說明模型顧及整個原文。模型度1說明模型顧及原文中的上一個字母并不斷改變其機(jī)率。模型度可以無限高,但是對于大的原文來說模型度越高其需要的計算內(nèi)存也越多。
熵編碼基本原理
熵編碼是無損壓縮編碼方法,它生成的碼流可以經(jīng)過解碼無失真地恢復(fù)出原數(shù)據(jù)。熵編碼是建立在隨機(jī)過程的統(tǒng)計特性基礎(chǔ)上的。
對信息源X的各符號的自信息量取統(tǒng)計平均,可得到平均信息量H(X)。H(X)稱為信息源X的熵(entropy),單位是bit/符號。
H.264標(biāo)準(zhǔn)中定義了三種熵編碼,分別是指數(shù)哥倫布編碼(Exp-Golomb)、基于上下文的自適應(yīng)可變長編碼(CAVLC)、基于上下文的自適應(yīng)二進(jìn)制算術(shù)編碼(CABAC)。指數(shù)哥倫布編碼用于對句法元素的編碼,把所有句法元素映像到統(tǒng)一的可擴(kuò)展碼字表,不單獨對每個句法元素設(shè)計不同的碼字表,這有助于降低編解碼的復(fù)雜度。對于量化后的差值變換系數(shù),可以根據(jù)不同的檔次來決定使用CAVLC還是CABAC。CABAC的壓縮率與CAVLC相比較高,但計算量也更大。
下面主要介紹CAVLC。
2、CAVLC(基于上下文自適應(yīng)的可變長編碼)
2.1 CAVLC是用于亮度和色度殘差數(shù)據(jù)的編碼
利用相鄰已編碼符號所提供的相關(guān)性,為所要編碼的符號選擇合適的上下文模型。利用合適的上下文模型就可以大大降低符號間的冗余度。在CAVLC中,上下文模型的選擇主要體現(xiàn)在兩個方面:非零系數(shù)編碼所需表格的選擇以及拖尾系數(shù)后綴長度的更新。
CAVLC之所以代替早期草案中提出的UVLC(統(tǒng)一的可變長編碼)對殘差數(shù)據(jù)進(jìn)行熵編碼,它的根本原因有如下幾點:
1.CAVLC可以全面的提高編碼的質(zhì)量。
2.應(yīng)用鋸齒形(zig-zag)掃描的方法,將非零系數(shù)值(Level)和零行程(Run)分開編碼,可提高編碼的自適應(yīng)性,有助于提高編碼的效率。
3.將Level和Run分開編碼可降低對存儲數(shù)據(jù)的復(fù)雜度。
CAVLC熵編碼的對象是經(jīng)DCT變換和量化后得到的亮度和色度殘差數(shù)據(jù),量化后的4×4塊殘差數(shù)據(jù)具有如下特征:
(1)經(jīng)過幀間、幀內(nèi)預(yù)測、DCT變換、量化后,殘差塊僅僅含有少許能量,除了低頻部分含有非零系數(shù)外,宏塊系數(shù)基本上為0。CAVLC使用游程編碼的方式來表示連續(xù)的零,有效的提高了編碼的壓縮效率。
(2)量化的數(shù)據(jù)經(jīng)Zigzag掃描之后,低頻部分非零系數(shù)幅值較大,而高頻部分經(jīng)常是由+1、-1等拖尾系數(shù)組成的序列,CAVLC對此類拖尾系數(shù)采用了與其他非零系數(shù)不同的編碼方式。
2.2 CAVLC編碼算法分析
2.2.1 CAVLC涉及的語法元素分析
CAVLC 算法共涉及到5個語法元素需要編碼,即coeff_token,total_zeros,level_prefix,level_suffix,run_before,每一個語法元素的具體含義如下:
coeff_token,編碼非零系數(shù)(total_coeffs)和拖尾系數(shù)(TrailingOnes)的個數(shù);
level-prefix,除拖尾系數(shù)外非零系數(shù)(level)的前綴部分;
level_suffix,除拖尾系數(shù)外非零系數(shù)(level)的后綴部分;
total_zeros,在逆Zig-zag 掃描順序下,最后一個非零系數(shù)前零的總數(shù);
run_before,在逆Zig-zag 掃描順序下待編碼非零系數(shù)前零的個數(shù).
CAVLC在編碼前對4x4數(shù)據(jù)矩陣經(jīng)過系數(shù)重排變成一維數(shù)據(jù)序列,為提高編碼效率,CAVLC將整個殘差塊的系數(shù)分成三類,即拖尾系數(shù)(TrailingOnes)、除拖尾系數(shù)外的非零系數(shù)(level)和零值。level的碼流由level_prefix和level_suffix兩個語法元素組成。根據(jù)非零系數(shù)在一維數(shù)據(jù)序列中的分布,利用total_zeros和run_before 兩個語法元素聯(lián)合查表可得。因此,對一個4x4殘差數(shù)據(jù)塊的編碼,CAVLC編碼器應(yīng)該首先完成游程長度的編碼,然后再是語法元素的編碼。
CAVLC編碼流程及相應(yīng)碼流形成過程
H.264中塊編碼是基于4x4塊的大小,通過幀間、幀內(nèi)預(yù)測、變換、量化、Zigzag掃描后形成重排后的塊殘差數(shù)據(jù),經(jīng)過編碼前的相應(yīng)語法元素的初始化,各語法元素的編碼等過程最終形成編碼碼流。
2.2.2 下面對CAVLC算法編碼流程進(jìn)行具體分析:
(1) 編碼前語法元素(TotalCoeff,TrailingOnes)和變量(nC)的初始化對于4×4的殘差塊而言,非零系數(shù)總數(shù)(TotalCoeff)的取值范圍為[0,16],而拖尾系數(shù)(TrailingOnes)個數(shù)在H.264/AVC中規(guī)定為[0,3],如果編碼塊最后±1個數(shù)超過3,則只有最后3個作為拖尾系數(shù)處理,其他的則作為正常非零系數(shù)處理。通過查表決定非零系數(shù)個數(shù)和拖尾系數(shù)個數(shù)的編碼方式。查找表的選擇方式取決于當(dāng)前塊的左邊塊和上方塊已經(jīng)編碼的非零系數(shù)值,體現(xiàn)了語法元素的上下文相關(guān)性。
(2) 編碼coeff_token語法元素并形成相應(yīng)比特流
根據(jù)輸入的非零系數(shù)數(shù)目和拖尾系數(shù)數(shù)目以及變量nC的值,查找相應(yīng)的編碼表格,得到映射到非零系數(shù)數(shù)目和尾系數(shù)數(shù)目的值coeff_token,將coeff_token形成的比特流存入編碼緩沖區(qū)中。
(3) 編碼TrailingOnes的符號并形成相應(yīng)比特流
為提高編碼效率,對每個拖尾系數(shù)(±1)只需要編碼其符號,用0 代表+,1代表-,按照反向掃描的順序,依次對拖尾系數(shù)的符號進(jìn)行編碼并存儲編碼緩沖區(qū)。
(4) 編碼各個level 值并形成相應(yīng)比特流
殘差塊中除拖尾系數(shù)外余下的非零系數(shù)的幅值(level)按照逆序進(jìn)行編碼。編碼后的碼字包含一個前綴(level_prefix)和一個后綴(level_suffix)。其中變量suffixLength 表示后綴的長度,levelCode 表示修正后幅值,i表示除拖尾系數(shù)外非零系數(shù)數(shù)目。
(5) 編碼total_zeros語法元素并形成相應(yīng)比特流
在Zig-zag掃描后的序列中,最高非零系數(shù)前所有零的個數(shù)(total_zeros)用VLC方式進(jìn)行編碼,該碼字表示塊中所有零的個數(shù)(其值可以通過查表獲得)。
(6) 編碼run_before 語法元素并形成相應(yīng)比特流對每個非零系數(shù)前零的個數(shù)的編碼依賴于變量zerosLeft 的值,zerosLeft表示當(dāng)非零系數(shù)左邊所有零的個數(shù),其初值為TotalZeros,在每個非零系數(shù)的run_before 值編碼后進(jìn)行更新。
2.2.3 CAVLC編碼算法的特點
CAVLC利用相鄰已編碼符號所提供的相關(guān)性,動態(tài)調(diào)整編碼中的碼表,為編碼符號選擇合適的上下文模型,大大降低了符號間的冗余度,取得較高的壓縮比,從而有利于軟硬件的實現(xiàn)。但CAVLC采用固定碼表,不能隨視頻源的統(tǒng)計特性自適應(yīng)性變化,而且CAVLC最小編碼位為1位,對概率大于0.5的編碼符號,編碼效率降低,因此H.264又提出了一種新的熵編碼算法即CABAC 編碼算法。
在H.264中,兩種熵編碼的功能是可以互相取代的,然而CABAC的壓縮性能要好于CAVLC,它基于以下幾點實現(xiàn)高壓縮率:1.基于語法元素的上下文信息為其選擇合適的概率模型;2.基于統(tǒng)計的自適應(yīng)概率估計更新;3.使用算術(shù)編碼替代變長編碼。
視頻圖像在經(jīng)過預(yù)測、變換和量化編碼后,需要經(jīng)過Zig-zag掃描和重新的排序過程,為后序的CAVLC編碼進(jìn)行準(zhǔn)備。
CAVLC熵編碼處理流程
1、TotalCoeffs和TrailingOnes的編碼
從碼流的起始位置開始計算整個編碼塊中非零系數(shù)的數(shù)目(TotalCoeffs),非零系數(shù)的數(shù)目為從0-16,非零系數(shù)的數(shù)目被賦值給變量TotalCoeffs。
拖尾系數(shù)是指碼流中正或者負(fù)1的個數(shù)(+/-1)。拖尾系數(shù)的數(shù)目(TrailingOnes)被限定在3個以內(nèi),如果+/-1的數(shù)目超過3個,則只有最后3個被視為拖尾系數(shù),其余的被視為普通的非零系數(shù),拖尾系數(shù)的數(shù)目被賦值為變量TrailingOnes。
2、判斷計算nC值
nC(Number Current當(dāng)前塊值)值的計算集中體現(xiàn)了CAVLC的基于上下文的思想,通過nC值選擇不同H.264標(biāo)準(zhǔn)附錄CAVLC碼表。
3、查表獲得coeff_token編碼
根據(jù)之前編碼和計算過程所得的變量TotalCoeffs、TrailingOnes和nC值可以查H.264標(biāo)準(zhǔn)附錄CAVLC碼表,即可得出coeff_token編碼序列。
4、編碼每個拖尾系數(shù)的符號:前面的coeff_token編碼中已經(jīng)包含了拖尾系數(shù)的總數(shù),還需進(jìn)一步對拖尾系數(shù)的符號進(jìn)行編碼。由于拖尾系數(shù)符合為正(+)或負(fù)(-),因此,在H.264標(biāo)準(zhǔn)中規(guī)定用0表示正1(+1)、1表示負(fù)1(-1)。當(dāng)拖尾系數(shù)的數(shù)目超過3個只有最后3個被認(rèn)定為拖尾系數(shù),因此對符號的編碼順序應(yīng)按照反向掃描的順序進(jìn)行。
5、編碼除拖尾系數(shù)之外的非零系數(shù)的幅值(Levels)
非零系數(shù)的幅值(Levels)由兩個部分組成:前綴(level_prefix)和后綴(level_suffix)。levelCode、levelSuffixsSize和suffixLength是編碼過程中需要使用的三個變量,其中l(wèi)evelCode是中間過程中用到的無符號數(shù),levelSuffixsSize表示后綴長度位數(shù),suffixLength代表Level的碼表序號。
6、編碼最后一個非零系數(shù)前零的數(shù)目(TotalZeros)
TotalZeros指的是在最后一個非零系數(shù)前零的數(shù)目,此非零系數(shù)指的是按照正向掃描的最后一個非零系數(shù)。因為非零系數(shù)數(shù)目(TotalCoeffs)是已知,這就決定了TotalZeros可能的最大值。根據(jù)TotalCoeffs值,H.264標(biāo)準(zhǔn)共提供了25個變長表格供查找,其中編碼亮度數(shù)據(jù)時有15個表格供查找,編碼色度DC 2×2塊(4:2:0格式)有3個表格、編碼色度DC 2×4塊(4:2:2格式)有7個表格。
7、編碼每個非零系數(shù)前零的個數(shù)(RunBefore)
在CAVLC中,變量 ZerosLeft表示當(dāng)前非零系數(shù)左邊的所有零的個數(shù),ZerosLeft的初始值等于TotalZeros。每個非零系數(shù)前零的個數(shù)(RunBefore)是按照反序來進(jìn)行編碼的,從最高頻的非零系數(shù)開始。H.264標(biāo)準(zhǔn)中根據(jù)不同ZerosLeft和RunBefore,構(gòu)建了RunBefore編碼表格供編碼查找使用。根據(jù)表格每編碼完一個RunBefore,對ZerosLeft的值進(jìn)行更新,繼續(xù)編碼下一個RunBefore,直至全部完成所有非零系數(shù)前零的個數(shù)的編碼。當(dāng)ZerosLeft=0即沒有剩余0需要編碼時或者只有一個非零系數(shù)時,均不需要再進(jìn)行RunBefore編碼。
綜上,本文主要是在閱讀了講解H.264/AVC中熵編碼相關(guān)內(nèi)容的書籍后的感想,著重介紹了熵編碼的基本原理,H.264/AVC中熵編碼的方法,重點介紹了基于上下文自適應(yīng)的可變長編碼(CAVLC),并將其和基于上下文二進(jìn)制算術(shù)編碼(CABAC)進(jìn)行了比較。另外,還了解到相關(guān)領(lǐng)域研究者對CAVLC算法的一些優(yōu)化工作,在此不詳細(xì)說明。
參考文獻(xiàn)
[1]畢厚杰,王健,編.新一代視頻壓縮編碼標(biāo)準(zhǔn):H.264/AVC(第2版)[M],人民郵電出版社,2009