日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

H264编码器13(CAVLC和CABAC简介)

發布時間:2023/12/29 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 H264编码器13(CAVLC和CABAC简介) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來自:https://blog.csdn.net/jubincn/article/details/6948334

?

CABAC/CAVLCin H.264


什么是熵編碼?
熵編碼壓縮是一種無損壓縮,其實現原理是使用新的編碼來表示輸入的數據,從而達到壓縮的效果。常用的熵編碼有游程編碼,哈夫曼編碼和CAVLC編碼等。

?

第一部分

?

CAVLC
CAVLC(Context Adaptive VariableLength Coding)是在H.264/MPEG-4AVC中使用的熵編碼方式。在H.264中,CAVLC以zig-zag順序用于對變換后的殘差塊進行編碼。CAVLC是CABAC的替代品,雖然其壓縮效率不如CABAC,但CAVLC實現簡單,并且在所有的H.264profile中都支持。

?

CAVLC的編碼過程如下:

?

1 計算非零系數(TotalCoeffs)和拖尾系數(TrailingOnes)的數目。

拖尾系數指值為+1/-1的系數,最大數目為3。如果超過3個,那么只有最后三個被視為拖尾系數。拖尾系數的數目被賦值到變量TrailingOnes。
非零系數包括所有的拖尾系數,其數目被賦值到變量TotalCoeffs)。


2 計算nC(numberCurrent,當前塊值)。

nC值由左邊塊的非零系數nA和上面塊非零系數nB來確定,計算公式為:nC=round((nA+nB)/2);若nA存在nB不存在,則nC=nA;若nA不存在而nB存在,則nC=nB;若nA和nB都不存在,則nC=0。
nC值用于選擇VLC編碼表,如下圖所示。這里體現了上下文相關(contextadaptive)的特性,例如當nC值較小即周圍塊的非零系數較少時,就會選擇比較短的碼,從而實現了數據壓縮。

?

3 查表獲得coff_token的編碼。

根據之前編碼和計算過程所得的變量TotalCoeffs、TrailingOnes和nC值可以查H.264標準附錄CAVLC碼表,即可得出coeff_token編碼序列。


4 編碼每個拖尾系數的符號,按zig-zag的逆序進行編碼。

每個符號用1個bit位來表示,0表示“+”,1表示“—”。
當拖尾系數超過三個時只有最后三個被認定為拖尾系數,引詞編碼順序為從后向前編碼。

?

5 編碼除拖尾系數之外非零系數的level(Levels)。

每個非零系數的level包括sign和magnitude,掃描順序是逆zig-zag序。
level的編碼由前綴(level_prefix)和后綴(level_suffix)組成。前綴的長度在0到6之間,后綴的長度則可通過下面的步驟來確定:
將后綴初始化為0。(若非零系數的總數超過10且拖尾系數不到3,則初始化為1)。
編碼頻率最高(即按掃描序最后)的除拖尾系數之外的非零系數。
若這個系數的magnitude超過某個門檻值(threshold),則增加后綴的長度。下表是門檻值的列表:


6 編碼最后一個非零系數之前0的個數(totalZeos)。

TotalZeros指的是在最后一個非零系數前零的數目,此非零系數指的是按照正向掃描的最后一個非零系數
根據TotalCoeffs值,H.264標準共提供了25個變長表格供查找,其中編碼亮度數據時有15個表格供查找,編碼色度DC2×2塊(4:2:0格式)有3個表格、編碼色度DC2×4塊(4:2:2格式)有7個表格。

?

7 編碼每個系數前面0的數目(run_before)。

掃描順序為zig-zag的逆序。
若∑[run_before]== total_zeros,則不需再計算run_before
掃描序中的最后一個元素不需要計算run_before
每個run_before的VLC編碼取決于run_before自身及未編碼的0的個數ZerosLeft。例如若ZerosLeft== 2,那么run_before只可能是0,1或2,因此使用兩個bit即可表示。



?

第二部分?CAVLC之手把手教你編碼

轉自:http://blog.csdn.net/sunshine1314/article/details/1685948

這篇博客使用實例對上述過程做了詳細的說明,尤其是有關Levels的計算方面做了重要的補充。下面是全文的轉載:

首先聲明本文并不是我寫的,文章來自本人同學(Sunrise),都是一起做的H264,比較了解,文章內容都是自己整理的,比較可信,因此整理到一起,我也偷個懶哈

再次聲明:文中用的標準是BS的正式標準,如果大家發現序號不對,參考著改過來就是了!

編碼過程:
假設有一個4*4數據塊
{
???0,???3,???-1,???0,
???0,???-1,???1,???0,
???1,???0,???0,???0,
???0,???0,????0,???0
}
數據重排列:0,3,0,1,-1,-1,0,1,0……

?

1)初始值設定:
非零系數的數目(TotalCoeffs)?=?5;
拖尾系數的數目(TrailingOnes)=?3;
最后一個非零系數前零的數目(Total_zeros)?=?3;
變量NC=1;
(說明:NC值的確定:色度的直流系數NC=-1;其他系數類型NC值是根據當前塊左邊4*4塊的非零系數數目(NA)當前塊上面4*4塊的非零系數數目(NB)求得的,見畢厚杰書P120表6.10)
suffixLength?=?0;
i?=?TotalCoeffs?=?5;


2)編碼coeff_token:
查標準(BS?ISO/IEC?14496-10:2003)Table?9-5,可得:
If?(TotalCoeffs?==?5?&&?TrailingOnes?==?3?&&?0?<=?NC?<?2)
??????coeff_token?=?0000?100;
??????Code?=?0000?100;


3)編碼所有TrailingOnes的符號:
逆序編碼,三個拖尾系數的符號依次是+(0),-(1),-(1);
即:
TrailingOne?sign[i--]?=?0;
TrailingOne?sign[i--]?=?1;
TrailingOne?sign[i--]?=?1;
Code?=?0000?1000?11;


4)編碼除了拖尾系數以外非零系數幅值Levels:
過程如下:
(1)將有符號的Level[i]轉換成無符號的levelCode;
如果Level[i]是正的,levelCode?=?(Level[i]<<1)?–?2;?
如果Level[i]是負的,levelCode?=?-?(Level[i]<<1)?–?1;
(2)計算level_prefix:level_prefix?=?levelCode?/?(1<<suffixLength);
???????查表9-6可得所對應的bit?string;
(3)計算level_suffix:level_suffix?=?levelCode?%?(1<<suffixLength);
(4)根據suffixLength的值來確定后綴的長度;
(5)suffixLength?updata:
If?(?suffixLength?==?0?)
suffixLength++;
?????????else?if?(?levelCode?>?(3<<suffixLength-1)?&&?suffixLength?<6)
????????????suffixLength++;

回到例子中,依然按照逆序,Level[i--]?=?1;(此時i?=?1)
levelCode?=?0;level_prefix?=?0;
查表9-6,可得level_prefix?=?0時對應的bit?string?=?1;
因為suffixLength初始化為0,故該Level沒有后綴;
因為suffixLength?=?0,故suffixLength++;
Code?=?0000?1000?111;
編碼下一個Level:Level[0]?=?3;
levelCode?=?4;level_prefix?=?2;查表得bit?string?=?001;
level_suffix?=?0;suffixLength?=?1;故碼流為0010;
Code?=?0000?1000?1110?010;
i?=?0,編碼Level結束。


5)編碼最后一個非零系數前零的數目(TotalZeros):
???查表9-7,當TotalCoeffs?=?5,total_zero?=?3時,bit?string?=?111;
???Code?=?0000?1000?1110?0101?11;


6)對每個非零系數前零的個數(RunBefore)進行編碼:
i?=?TotalCoeffs?=?5;ZerosLeft?=?Total_zeros?=?3;查表9-10:
依然按照逆序編碼
ZerosLeft?=3,?run_before?=?1?????????run_before[4]=10;
ZerosLeft?=2,?run_before?=?0?????????run_before[3]=1;
ZerosLeft?=2,?run_before?=?0?????????run_before[2]=1;
ZerosLeft?=2,?run_before?=?1?????????run_before[1]=01;
ZerosLeft?=1,?run_before?=?1?????????run_before[0]不需要碼流來表示
Code?=?0000?1000?1110?0101?1110?1101;
編碼完畢。

?

第三部分 CABAC


簡介
CABAC(ContextAdaptive Binary Arithmatic Coding)也是?H.264/MPEG-4AVC中使用的熵編碼算法。CABAC在不同的上下文環境中使用不同的概率模型來編碼。其編碼過程大致是這樣:首先,將欲編碼的符號用二進制bit表示;然后對于每個bit,編碼器選擇一個合適的概率模型,并通過相鄰元素的信息來優化這個概率模型;最后,使用算術編碼壓縮數據。

?

CABAC編碼詳情
CABAC編碼之所以能取得很高的壓縮比,是因為:a)根據每一個語法元素的上下文來選取預測模型;b)使用本地的統計數據來估計概率;c)使用算術編碼而不是變長編碼。編碼一個符號需要經過下面幾步:

?

1 二值化。

CABAC使用的算術編碼是基于二進制的算術編碼,因此非二進制形式的編碼首先要轉化為二進制的形式表示。

?

下面的2、3、4步

2 選擇上下文模型。

“上下文模型”是指對二值化后的符號中的bit位進行編碼時使用的概率模型。概率模型與最近編碼的符號相關,會有多個概率模型可供選擇。

?

3 算術編碼。

算術編碼器根據第2步選擇的概率模型對每個bit進行編碼。需要注意的是每個bit的子范圍只有兩個數:0和1。

?

4 更新預測模型。

根據實際編碼的值來更新所選擇的預測模型。例如,如果所編碼的二進制bit為1,則預測模型中的1計數要增加。

?

?編碼過程
下面將以mxdx為例解釋編碼過程,mxdx是motionvector difference in the x-direction的簡寫,通過宏塊的子塊之間運算獲得。

?

1 二值化。

對于|mvdx|<9的數,使用下表進行編碼,超過9的數使用Exp-Golomb編碼。在這里,我們稱編碼后的第一個bit為bin1,第二個bit為bin2,以此推之,可以得到bin3,bin4等。

?

2 為每個bin選擇一個上下文模型。

bin1可以在三個模型之間進行選擇,選擇的依據是相鄰的兩個mxdx的絕對值之和,ek:

ek = mxdxA+ mxdxB(A和B分別是當前塊的上方塊和左邊塊)

根據ek值從下表中為bin1選擇上下文模型:

除bin1之外的其它bit的上下文模型的選擇根據下表進行:

?

3 編碼每個bin。

所選的預測模型中有0和1的概率,從而為算術編碼器提供了概率范圍,算術編碼器使用這個概率范圍對此bin進行算術編碼。

?

4 更新上下文模型。

例如,若bin1使用上下文模型2,而bin1的值是1,那么上下文模型2中1的計數就要增加,1的概率和0的概率需要重新計算。當上下文模型中的總數超過門檻值后,0和1的計數就要除以某個值,從而使得新加入的0和1在模型中產生更大的影響。


?

總結

以上是生活随笔為你收集整理的H264编码器13(CAVLC和CABAC简介)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。