HEVC的算數編碼

【重頭戲,視頻編碼中最難啃的硬骨頭,或許沒有之一。今天這個還是文獻的閱讀記錄,後面幾篇會深入挖掘它的參考文獻和JCT-VC的相關提案,爭取借這次機會徹底把視頻編碼中的算數編碼搞懂。這次的參考文獻是:High Throughput CABAC Entropy Coding in HEVC,IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY, VOL. 22, NO. 12, DECEMBER 2012。】
HEVC的算數編碼

H.264和HEVC採用了CABAC以極大幅度地提高了算法的壓縮比率。由於H.264中所採用的算法存在較強的數據依賴性,因此算法的數據吞吐量收到一定的限制。在HEVC中採用的CABAC算法充分考慮了算法的壓縮比率和並行化程度。經過優化的CABAC可以在保持相當高的壓縮比率的同時,顯著提高處理速度並降低了硬件處理的需求。

1、CABAC熵編碼
熵編碼是視頻編碼的最後一步和解碼的第一步所使用的一種無損編碼。熵編碼所處理的對象,是在前期的預測、變換階段所產生的一系列語法元素(Syntax Elements),包括預測模式和殘差數據等。這些語法元素描述了CU,PU,TU和LF等多種語法元素的特性。對CU,有塊結構信息以及幀內/幀間預測模式;對PU,描述了幀內預測模式和運動信息等;對TU,主要包含殘差信息的變換系數等;LF語法元素在每一個最大編碼單元LCU中傳輸一次,描述了環路濾波中SAO的類型和偏移量。CABAC主要包括三大步驟,即二值化、上下文建模和算數編碼。
(1)二值化。
二值化的作用是將語法元素映射爲二進制符號(bin)。HEVC中的二值化採用幾種不同的方式,與H.264類似,主要有一元(Unary),截斷一元(Truncated Unary),k階指數哥倫布編碼(EGK)和定長(Fixed Length)。這幾種不同模式的區別體現在將某個無符號整數N二值化的結果的不同,具體如下圖所示:
該表中的例子表述了大部分情況所採用的二值化方法,另外可能存在多種方法的組合,以及一些特定化的二值化方法。在實際應用中,具體採用哪一種二值化模式取決於語法元素的類型,或者之前處理過的語法元素的值以及條帶參數中的設置。
(2)上下文模型
CABAC之所以在壓縮比率上可以取得巨大提高,關鍵就是因爲上下文模型的引入爲編碼過程提供了精確的概率估計。CABAC採用的上下文模型是高度自適應的,不同二進制碼元採用的模型不同,而且可以依據之前處理的二值化碼流進行模型更新。每一個bin的上下文模型的選擇依據包括語法元素類型、bin的位置、亮度/色度和相鄰塊信息等。CABAC的概率模型採用7bit結構,其中6bit的概率狀態位和1bit的最大概率模型位,在HEVC中其概率模型更新方法與H.264的類似,而改進了上下文選擇的邏輯以提高數據處理效率。
(3)算數編碼
算數編碼是一種基於區間的遞歸劃分的熵編碼方法。一個初始化爲[0,1]的區間根據bin的概率分佈劃分爲兩個子區間,並且依照bin的取值選取兩個區間之一。該區間更新爲選擇的子區間,並進行下一次分割,依此循環往復。爲防止下溢出,當區間長度小於某個值時,停止遞歸併重新進行區間歸一化。
在編碼的過程中,可以使用概率估計(上下文編碼)和等概率模式(旁路編碼)。旁路編碼中,區間劃分由某個偏移量實現,而上下文編碼的bin需查表。HEVC的編碼過程與H.264類似。

2、CABAC的輸出瓶頸
下圖爲CABAC解碼器中的反饋環路。由該圖中可以看出主要存在一下幾種反饋機制:
(1)遞歸區間分割中的區間範圍更新;(2)精確概率估計對上下文的更新;(3)上下文的選擇依賴於語法元素的類型;(4)上下文的選擇依賴於bin在語法元素中的位置。
在上圖中,1、2環路比較簡單,因此對吞吐量沒有造成過大影響。如果某一個bin的上下文依賴於並行處理的另一個bin,則會造成較大影響。隨着並行bin個數的增加,“預測運算”量將會呈指數增長。因此,吞吐量的瓶頸主要在於上下文選擇過程中的依賴性。

3、HEVC的CABAC所做的改進
爲提高數據的吞吐量,HEVC主要在前期的CABAC的基礎上做了如下改進:
(1)減少上下文編碼的bin數量;上下文編碼所帶來的數據依賴性限制了數據吞吐量,而旁路編碼由於沒有因爲上下文選擇帶來的數據依賴問題所以更適於並行處理。另外,由於不需要查表,旁路模式的算數編碼過程也更爲簡單。
(2)聚合旁路編碼的bin;比特流中連續出現的一串旁路編碼bin可以在同一個循環中進行處理。
(3)聚合相同上下文的bin;參考相同上下文的bin聚合在一起,可以減少“預測運算”,同時減少上下文切換次數。
(4)減少上下文選擇的依賴性;由於上下文選擇過程中的數據依賴性,循環解碼多個bin需要大量“預測操作”;減少此類依賴性可以簡化上下文選擇的過程並減少“預測操作”數量。
(5)減少bin的總量;主要考慮降低算數編碼本身的負載;
(6)減少解析的依賴性;儘量隔離CABAC解析同其他所有的處理過程;
(7)減少內存需求;減少內存的需求也就是降低了內存的存取時間;

4、編碼預測單元PU
PU中主要包含了幀內和幀間預測信息,並取得了比H.264更高的編碼效率。
(1)對運動信息的編碼
該部分主要包括減少解析塊合併的依賴、減少運動矢量預測的依賴、減少上下文編碼bin和減小內存需求。
①減小塊合併的依賴:
HEVC中的塊合併功能可以通過時空鄰域信息獲取預測方向、參考索引和運動矢量等運動信息。在該模式中,merge_idx表示該從哪一個候選中獲取運動信息,該變量採用截斷一元編碼。理論上其最大長度cMax應設爲PU中用於合併的候選列表的長度。但是這需要建立列表以獲取表長度,增加解析過程的依賴性。另外,建立候選塊列表所需的運算量也相當大,因此該方法效果不佳。
在HEVC中cMax在條帶頭中標記,並不依賴與表的長度。爲了彌補定長cMax帶來的效率損失,在表長度不足的情況下,將聯合/零合併候選塊加入表中。
②減小運動矢量預測的依賴:
在未開啓塊合併模式下,運動矢量由鄰域塊的MV進行預測,並通過MVP和MVD記錄。在H.264中採用了單一MV預測,採用左、上和右上三個方向的鄰域塊的中值作爲運動矢量預測值;在HEVC中採用了“先進運動矢量預測”(AMVP)的方法,從時間和空間鄰域中選定多個候選塊數據,經過優化處理,保留兩個較優的候選塊。mvp−l0−flag標識哪一個候選的MV選作了MVP,並且即使列表中只有一個候選塊該標識也會存在。默認候選爲0矢量,因此列表永不爲空。
③減少上下文編碼的bin:HEVC中,上下文編碼的bin被極大減少,對MVD的編碼,只有前兩個bin是上下文編碼,其餘是一階指數哥倫布編碼bin的旁路編碼。
④減少內存需求:HEVC通過改進上下文選擇的邏輯,減少了行緩存大小。通過對比每個鄰域塊的MV信息和閾值16的比較來選擇上下文,可以將每個鄰域塊的MV緩存需求減少1bit。
⑤聚合旁路編碼bin:mvd的x和y分量的旁路編碼bin將聚合在一起進行處理,以最大化快速旁路編碼的效率。
(2)幀內模式的編碼
HEVC採用了新的最大概率模式提高編碼效率,採用定長爲3的由左、上鄰域塊構建的候選表(可以加入DC、平面等候補選擇)。如果採用最大概率模式,使用mpm_idx變量說明採用了哪一個候選。
與幀間模式的編碼類似,CABAC編碼幀內信息曹勇了減少上下文編碼bin和聚合旁路編碼bin等技術。

5、編碼變換單元TU
在CABAC中,變換系數的位置以“關鍵度表”的形式編碼,關鍵度表表明瞭非零係數的位置。係數的level信息只在大於1的係數信息中包含,而所有非零係數信息都包含係數的符號。
(1)關鍵度表:
在H.264中,會傳遞一個標誌位significant_coeff_flat(SCF)來指示每一個非零係數(採用之字形掃描),隨後會傳遞一個標誌last_significant_coeff_flag指示當前是否是最後一個SCF。對4×4和8×8TU中不同位置以及bin是否表示SCF和LSCF,採用不同的上下文。SCF和LSCF是交錯分佈的,因此在上下文選擇過程中,H.264的算法存在大量的二進制依賴關係。
爲了減小這種依賴關係,HEVC採用了減少參考鄰域的做法,在HM模型不同的階段,採用了10、8、6、5個等不同的參考鄰域。在HM2.0及其以前的版本中,由於關鍵度表採用之字形掃描,所以取消對角方向的塊作爲參考鄰域會造成比較明顯的影響。
在HM4.0模型中,採用了對角線掃描的方式處理SCF。此方法對編碼效率有一定的影響,但是卻解除了SCF處理中的依賴關係。在HM7.0中,對16×16和32×32TU進行了分割處理,將TU分割成了4×4的子塊,並引入了coded_sub_block_flag這個參數。在HM8.0中8×8TU也被分割成了4×4子塊,因此之後所有的TU都是基於4×4子塊組成的。
在對8×8、16×16和32×32TU的處理中,每個塊都被劃分爲DC、低頻區和高頻區三部分,每部分都採用不同的上下文。同時爲了節約內存,16×16和32×32的SCF共享內存空間。
對於處理幀內預測的CU時,引入了一種“依賴模式係數掃描”(MDCS),根據幀內預測模式選擇水平、垂直和對角線掃描。
“最末位”編碼:
由於H.264的SCF和LSCF相互交錯,它們之間存在較強的相互依賴性。主要解決方法有:將數個SCF組合,併爲這N個SCF傳遞一個LSCF;或者避免將SCF和LSCF交替出現;以及將一個LSCF分離成x,y兩個分量傳輸。“最末位”由一個前綴和後綴兩部分組成。前綴對x和y分別採用cMax的截斷一元編碼碼,以TU的寬度和高度爲上下文;後綴採用定長旁路編碼。
編碼子塊標誌位(CSBF):
每一個TU被分割成4×4大小的子塊。CSBF用於標識某個子塊是否包含非零係數。若該參數爲1,則該子塊中含有SCF;反之,若子塊中僅僅包含0係數,則不存在SCF的值。該方法在HM7.0中擴展,用以降低16×16和32×32TU的上下文選擇中的依賴性,並且在HM8.0中應用到了8×8TU中。同時,分別採用了四種模式,將不同位置的鄰域子塊中的元素同上下文模型的選擇結合,以解除對其的依賴性。
(2)係數的等級和符號
在H.264中,係數等級由兩部分組成。前14位由截斷一元二值化生成,採用上下文編碼,剩餘位由0階指數哥倫布編碼產生,採用旁路編碼。在係數等級編碼完成後,採用旁路編碼處理係數的符號。
①等級編碼:
在HEVC中,係數等級僅僅有前兩位(coeff_abs_level_greater1_flag和coeff_abs_level_greater2_flag)採用上下文編碼,剩餘部分(coeff_abs_level_ramaining)採用旁路編碼。這樣可以極大程度地降低了整個CABAC中上下文編碼的碼子數量。coeff_abs_level_ramaining的前綴的二值化方法採用一元碼,後綴則採用定長碼,碼長取決於前綴的值。同時,定長碼子的數目還依賴於cRiceParam這個參數,該參數根據之前的非零係數的等級變化。coeff_abs_level_ramaining的最大取值爲32.
對於每一個4×4子塊而言,每一個子塊最多包含8個coeff_abs_level_greater1_flag和1個coeff_abs_level_greater2_flag。減少這兩個flag的數量將有效減少上下文的的數量。
對係數等級進行上下文選擇,主要經過以下步驟:
1)對子塊中的16個係數進行掃描;——>2)根據前一個子塊中大於1的係數的個數,爲當前子塊選定上下文集合;——>3)根據當前塊內的1係數,在集合中選擇上下文模型。
在HM3.0中,每個上下文集合包含5個上下文,共6種集合備選;低頻/非低頻部分,亮度/色度分量,以及coeff_abs_level_greater1_flag和coeff_abs_level_greater2_flag均需要不同的上下文,因此共需要120種不同的上下文模型。而發展到了HM6.0,所需的上下文模型減少到了僅需要30個。
②符號編碼:
每一個4×4子塊內的16個係數的符號被聚合在一起處理,這些係數的符號位碼元位於coeff−abs−level−remaining的碼元之前,並且在該元素解碼完成之後可以立刻獲取。
除此之外,還採用了數據隱藏的方法提高編碼的效率。若一個子塊內非0係數的個數超過了某一閾值,則符號位可由非零係數個數的奇偶性推測。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章