2、語法元素熵編碼

正所謂工欲善其事,必先利其器;我們下面要解析vps,sps,pps,少不了的會有兩點:1、對照spec看語法元素;2根據(jù)描述解析語法元素;那么這里我要總結(jié)的是,如何解析這些語法元素;因為vps,sps,pps的信息,單獨看每個有啥含義,在這里看是沒有太多用處的;目前我們只能說了解個大概;因為這些信息是為了后面的解碼服務(wù)的;所以這里我們要看具體是怎么解析的;
首先這里我要粘貼一下書上的描述子的描述(這里有點繞。。。但是沒錯):


image.png

那么這里面就出現(xiàn)了幾個概念需要理解:
1、基于上下文的自適應(yīng)的二元算數(shù)編碼:ae(v)這里指的是可以理解為對于265就是cabac編碼
2、其他的就是哥倫布編碼以及其他等等;
所以,這節(jié)最主要的還是要看熵編碼這一塊的知識,就知道如何進(jìn)行熵解碼


一、
首先我們應(yīng)該先看看普通的變長編碼(非定長的,VLC,看一下首字母就知道怎么回事了)是怎么編碼的;來引出我們的概念:
常見的就是哈夫曼編碼,說道哈夫曼編碼,其實在這里了解一下即可;說道哈夫曼編碼就離不開哈夫曼樹,直接舉例,會比較好理解一些:
假設(shè)ABCD,加權(quán)是0.2,0.3,0.1,0.4,那么我們怎么畫哈夫曼樹呢;首先我們找最小的兩個;也就是A,C。
小概率的放到左邊,大概率的放到右邊,那么就會合成一個E,E就是0.3,然后E再和B對比,然后組成F,F(xiàn)是0.6,然后再和D對比那么D放到左邊,F(xiàn)放到右邊,所以就會有下圖:


image.png

畫的太丑了,但是很明顯就是編碼后,A是111,C是110,B是10,D是0,所以比較簡單;
舉例如果是ACBA,那么編碼出來的就是11111010111
二、
上面是代表的是變長編碼;但是算數(shù)編碼是不一樣的;變長編碼,如哈夫曼編碼,那么會是要對每個碼字都要進(jìn)行率先給一個碼字;如A是111,C是110,那么每個字符,至少也得分配一個碼字;但是算數(shù)編碼不是的;他是要對整個碼率進(jìn)行編碼;這就出現(xiàn)了概率空間的概念了舉個例子,比如AA,我可能用1一個bit就代替了,那么如果使用邊長編碼的話,那么就會出現(xiàn)1111116個bit,這樣是不是感覺算數(shù)編碼很節(jié)???
上面說了這么多,其實沒啥用,如果不舉例,其實什么都看不懂;我們還是按照上面的概率,上面ACBA舉例;那么如果是算數(shù)編碼,那么應(yīng)該是怎么樣的呢?
如下圖:


image.png

1、首先我們說,第一個碼字是A,那么就是落在的概率區(qū)間就是[0,0.2]
2、然后第二個碼字是C,那么C是在A的基礎(chǔ)之上的,所以C落在[0.1~0.12],C過后,概率區(qū)間只有0.02大小了
3、然后是B,那么B是在0.02x0.2以后,所以結(jié)合前面就是0.104~0.11之間;此時,概率區(qū)間只有0.006大小了
4、最后是A,那么A又是從0開始的,所以輸出的碼率下限就是0.104,那么我們輸出0.104,就能代表是ACBA這個碼字了
我們整理為公式的話輸出的就是0+0.2x0.5+0.2x0.1x0.2 = 0.104
那比如如果我們現(xiàn)在有了一個小數(shù),能否解碼出來呢?答案是必須且唯一的;要不學(xué)習(xí)算數(shù)編碼,無法解碼有什么用呢?
假設(shè)是一個0.105,那么0.105在0~0.2之間,也就是說第一個是A
然后我們現(xiàn)在看編碼的這個公式0+0.2x0.5+0.2x0.1x0.2 = 0.104
說明什么呢?說明下一步主要看第二加的內(nèi)容區(qū)間。所以為(0.105-0)/0.2 = 0.525,是C
以此類推,(0.525-0.5)/0.1 = 0.25,是B
(0.25-0.2)/0.3是0.166,是A
也就是最終為ACBA;
那么我們上面編碼不是0.104嘛,為啥0.105也是ACBA呢?
因為ACBA最后一個是落在0.006x0.2 = 0.0012也就是說,在0.104~0.1052之間的任意數(shù)都是0可以的;


三、
下面要看一下哥倫布指數(shù)編碼;哥倫布指數(shù)編碼,屬于變長編碼的范疇;那么我們從上面可以看出我們學(xué)習(xí)了變長編碼,算數(shù)編碼;為什么,我們要回過頭來,看哥倫布指數(shù)編碼呢?
首先,我們要看哥倫布指數(shù)編碼在265中的作用:
1、slice以上大多會用到哥倫布指數(shù)編碼(sps,vps,pps,ue(v),se(v))
2、在slice層,有一個參數(shù)要用1階哥倫布指數(shù)編碼去二值化
這兩點是不是很暈?其實還好,我大體描述一下是什么意思:
對于那些sps,vps這些,我們需要哥倫布編碼的方式編碼;就是這些值用哥倫布指數(shù)編碼編成0101的碼字即可;
但是對于slice編碼的話,就像上面描述的;用變長編碼是不是用的碼字特別多?是不是需要用算數(shù)編碼?但是算數(shù)編碼需要三步:1、二值化;2、建立概率模型;3、算數(shù)編碼;此時,變長編碼。也就是1階哥倫布指數(shù)編碼就會用到了
但是這里我得說一句,一階哥倫布指數(shù)編碼去二值化,情況很少,大部分我們不用這種方式;slice層只有一個地方會用到;所以了解即可;
終于要進(jìn)入正題了;就是如何進(jìn)行哥倫布指數(shù)編碼:
首先要看一下,無符號0階哥倫布指數(shù)編碼:


image.png

這里我是在不想寫那么多了,但是我只是總結(jié)一下;其中,圖片中codenum指的是要編碼的語法元素;如果要進(jìn)行哥倫布指數(shù)編碼,那么有兩部分組成:
1、前綴0,前綴0的話,計算就是M那個公式;
2、實際的碼字,就是codenum+1對應(yīng)的二進(jìn)制;
如果編程的話,沒有以2為底的函數(shù)的話,可以用兩個以10為底的log相除
是不是很簡單,下面還有表格,都是例子;

然后再看有符號的哥倫布指數(shù)編碼


image.png

其中V是指的要編碼的語法元素;是不是很巧妙?通過奇偶就能區(qū)分了正負(fù);可以看出,正數(shù)都是變成了奇數(shù)后再去編碼,負(fù)數(shù)和0變成了偶數(shù)去編碼;

最后看一下1階哥倫布指數(shù)編碼,再強調(diào)一點,這個只是為了二值化,所以會用1階哥倫布指數(shù)編碼
這里貼了一段程序,如下:


image.png

代碼是不是很容易就可以看懂?
其中synval代表的是要編碼的語法元素;要首先求一個絕對值;然后定義個結(jié)束的標(biāo)志位;然后k初始化為1,因為是1階哥倫布指數(shù)編碼;然后循環(huán)輸出0和1,然后輸出幾個0,或者幾個1,最終結(jié)束;
舉例14,按照上述的邏輯輸出為11100000,也就是224


講到這里,我們其實自適應(yīng)的二元算數(shù)編碼還沒有接觸。但是起碼;sps這些你能解析了;因為他們大部分是哥倫布編碼;這節(jié)寫的有點多,所以后面再寫cabac

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容