【H264/AVC 句法和語義詳解】(五):Exp-Golomb指數哥倫布編碼(理論篇)

原文鏈接:https://www.jianshu.com/p/f4f3b0764cec

本篇隸屬於文集:《H264/AVC 句法和語義詳解》,查看文集全部文章,請點擊文字鏈接。
想看最新文章,可以直接關注微信公衆號:金架構

上篇我們說過,學習描述子是解析h264句法元素的第一步。而在描述子中,除了順序讀取若干比特的b(8)、f(n)、i(n)、u(n),指數哥倫布編碼也是使用頻率很高的編解碼方法。

因爲指數哥倫布編碼(Exponential-Golomb)屬於熵編碼(Entropy encoding),所以我們先大致介紹一下熵編碼,然後再進行細化。

  1. 熵編碼(Entropy encoding)
    熵(shang)編碼屬於無損編碼,它聽着很高大上,其實簡單來說,就是代表了一類編碼方法。熵編碼包括的編碼方法有:香農-範諾編碼、霍夫曼編碼、算術編碼、指數哥倫布編碼、CAVLC、CABAC等,這一類編碼方法的宗旨,就是找到一種編碼,使得碼字的平均碼長達到熵極限。

具體實施起來就是,對出現概率較大的符號,取較短的碼長,而對出現概率較小的符號取較大的碼長。這就是熵編碼的中心思想,只要我們記住這一點,即使不瞭解“熵”是指啥,也能掌握上述幾種熵編碼。

不過我們還是簡單介紹一下,“熵”是指啥?

1.1 熵
熵在熱力學中,是表示分子狀態混亂程度的物理量,這時的熵稱爲熱熵。後來信息論之父香農(C. E. Shannon)把“熵”這一詞引入到信息論中,稱爲“信息熵”,信息越是隨機,它的熵值越高。信息熵也是我們在h264這樣的數字圖像編碼中使用的概念。因爲我們待編碼的圖像像素信息、碼流的各個句法元素值,其實都屬於信息。

而信息熵,就是爲了解決信息的量化度量問題,它描述了整個信源的平均信息量。信息熵在我們的熵編碼中,表示了信源無損編碼後平均碼長的下限。所以我們上面才說,熵編碼就是爲了使編碼後,碼字的平均碼長儘量達到熵極限。而且平均碼長越接近熵,說明熵編碼的壓縮效率越高。

1.2 熵和熵編碼
如果第一次接觸熵,確實不好理解。因爲它不僅涉及到信息學的知識,還有概率論的知識。不過雖然熵不好理解,但是熵編碼很好掌握。熵其實就相當於內功,而熵編碼是招式。待我們學過熵編碼,再來理解熵,就容易多了。

1.3 熵編碼分類
爲了便於理解,上述說的多個熵編碼方法,還可以分爲以下兩類:

(1)變長編碼:香農範諾編碼、霍夫曼編碼、指數哥倫布編碼、CAVLC

(2)算術編碼、CABAC等算術編碼

而且這些熵編碼方法中,在H.264中應用的有:指數哥倫布編碼、CAVLC、算術編碼、CABAC。

  1. 指數哥倫布編碼(編碼過程)
    指數哥倫布編碼是一種較簡單的編碼方法,正常來說,它可以拓展至K階,也即K階指數哥倫布編碼。而在H.264中使用的,是0階指數哥倫布編碼,也即K等於0。下面我們就重點介紹0階指數哥倫布編碼,理解了0階,K階自然而然就懂了。

值得注意的是,在H.264中,0階指數哥倫布編碼,對應的描述子是ue(v)。只不過ue(v)代表的是解碼過程,而我們下面先從編碼開始。

2.1 0階指數哥倫布編碼
這個編碼過程如下圖所示:
在這裏插入圖片描述
0階指數哥倫布編碼過程
圖中應該寫的很清楚,我們以待編碼碼號code_num = 3爲例:

第一步:將code_num +1, 即3+1 = 4

第二步:將4寫爲二進制的形式:100

第三步:計算100的比特個數爲3,在100前面寫(3-1)個0,得到編碼碼字:00100

並且圖中背景爲灰色區域,表示連續的碼字長度一樣,總結起來如下:
在這裏插入圖片描述
0階碼號與碼字總結
可以看到,碼字的結構形式可以表示爲,中間比特爲1,兩端比特個數對稱的平衡結構:

[N個0][1][INFO] 或者 [Prefix 前綴][1][Suffix 後綴]
2.2 K階指數哥倫布編碼
由上述的0階,我們可以輕鬆拓展至K階,還是剛纔那個步驟,只不過將第一步稍微改變一下:

(1)K階的第一步:將code_num 加上2k

(2)將code_num + 2k 寫爲二進制的形式

(3) 計算二進制的比特個數 M,並在前面加上M-1個0,得到編碼碼字。

如果要驗證一下,則將k=0代入上述步驟,就可以得到0階編碼的碼字。比如以K=0、K=1、K=2或K=3舉例如下:
在這裏插入圖片描述
K階指數哥倫布編碼舉例
表中x即爲上述的待編碼碼號code_num。

  1. 指數哥倫布編碼(解碼過程)
    講過了編碼過程,我們就從解碼過程考慮考慮,這一過程描述在h264協議的9.1節,這也是我們今天的重點。因爲H.264中的描述子,代表瞭解碼過程。所以下面我們就以描述子爲主線,依次介紹H.264中的4個指數哥倫布編碼描述子:ue(v)、se(v)、me(v)、te(v)。

3.1 ue(v)
在h264中,ue(v)就代表了0階指數哥倫布編碼,通常被稱爲無符號指數哥倫布編碼。對比我們上述的0階編碼過程,我們可以反過來研究研究解碼過程。如下圖:
在這裏插入圖片描述
ue(v)解碼
如圖,如果我們仔細觀察推理,就會發現碼字和code_num之間,有以下公式:

codeNum = 2leadingzerobits − 1 + read_bits( leadingZeroBits )
其中leadingZeroBits爲中間1前面,0的個數。所以在解碼的時候,如果遇到描述子爲ue(v),則可以先數0的個數,數到1爲止,其中0的個數即爲leadingZeroBits。而公式中的read_bits( leadingZeroBits ),則爲從中間1開始,往後順序數leadingZeroBits個比特位。

利用上述公式,就可以計算出codeNum的值。

所以上表的解碼過程爲:
在這裏插入圖片描述
ue(v)解碼過程
當描述子爲ue(v)時,codeNum的值即爲語法元素的值。

3.2 se(v)
se(v)也稱有符號指數哥倫布編碼,所以當描述子爲se(v)時,它的輸出有可能爲負。而且當描述子爲se(v)時,它的輸入爲上述過程解析出來的codeNum。意思是什麼呢?如果遇到se(v),需要先調用ue(v),得出codeNum的值。然後調用se(v)的解析過程,se(v)的輸出即爲語法元素的值。

se(v)的計算過程
如上表所示,表中第一列codeNum爲輸入,第二列爲輸出。計算公式則爲:
在這裏插入圖片描述
語法元素值 = (−1)k+1 Ceil( k÷2 )
式中Ceil爲向上取整,k爲codeNum的值,代入即可計算出語法元素的值。

3.3 me(v)
me(v)也稱映射指數哥倫布編碼,聽着很高大上,其實就是拿着codeNum的值去查表。而且在H.264中,只有語法元素coded_block_pattern的值,是使用me(v)解析的。

而且當句法元素ChromaArrayType的值爲1或2時,查表a。ChromaArrayType的值爲0或3時,查表b。當宏塊預測模式爲Intra_4x4(幀內4x4)、Intra_8x8(幀內8x8)或者Inter(幀間編碼)時,輸出的coded_block_pattern的值也不同。

部分a表如下:
在這裏插入圖片描述
me(v) 表(a)部分數據
注意輸入爲codeNum,輸出爲coded_block_pattern的值。

3.4 te(v)
te(v)也稱截斷(舍位)指數哥倫布編碼,之所以這麼說呢,是因爲它的編碼分爲兩段。在H.264協議中,只有7.3.5.1節的宏塊預測和7.3.5.2節的子宏塊預測中,使用這種模式編碼,我們先看看它的編碼過程。

3.4.1 te(v)編碼過程
編碼時:

如果語法元素的值爲0,則編碼爲1,如果語法元素值爲1,則編碼爲0,此時佔用1個比特位。

如果語法元素的值大於1,則使用ue(v)進行編碼。

3.4.2 te(v)解碼過程
知道了編碼過程,解碼過程就好理解了。解碼時,需要先判斷語法元素值的取值範圍的上限,其中取值範圍爲[0,x]。

如果上限值x大於1,那麼te(v)的輸出,也即語法元素的值,和ue(v)的輸出相同。

否則上限值x等於1,那麼te(v)的輸出,也即語法元素的值,等於讀入下一位比特值的取反,也即:

b = read_bits( 1 )

codeNum = !b

其中codeNum爲te(v)輸出值,也即語法元素值。

  1. 總結
    其實由上面的分析,就可以看出,指數哥倫布編碼的壓縮率其實是比較低的,有時候甚至沒有壓縮效果。所以指數哥倫布編碼在H.264中,主要應用在部分語法元素的編解碼和二值化(將語法元素的值轉爲二進制),而在h264中壓縮比比較高的熵編碼方法,是還未介紹的CAVLC和CABAC。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章