openh264--熵編碼

依次介紹CAVLC,CABAC

CAVLC

1 獲取coeff_token

g_kuiVlcCoeffToken是CoeffToken,TotalCoff,TrailingOnes的映射關係,是個標準表,

例:If (TotalCoeffs == 5 && TrailingOnes == 3 && 0 <= NC < 2),可得 coeff_token = 0000 100;  ,如下圖高亮的部分,4表示值,7表示bit數。

//g_kuiVlcCoeffToken[nc][total-coeff][trailing-ones][0--value, 1--bit count]
const uint8_t g_kuiVlcCoeffToken[5][17][4][2] = {
  {
    //0<=nc<2
    { { 1,  1}, { 0,  0}, { 0,  0}, { 0,  0} },//0
    { { 5,  6}, { 1,  2}, { 0,  0}, { 0,  0} },//1
    { { 7,  8}, { 4,  6}, { 1,  3}, { 0,  0} },//2
    { { 7,  9}, { 6,  8}, { 5,  7}, { 3,  5} },//3
    { { 7, 10}, { 6,  9}, { 5,  8}, { 3,  6} },//4
    { { 7, 11}, { 6, 10}, { 5,  9}, { 4,  7} },//5
    { {15, 13}, { 6, 11}, { 5, 10}, { 4,  8} },//6
  },

.........

一個完整的例子:

1 計算非零係數(TotalCoeffs)和拖尾係數(TrailingOnes)的數目。
2 計算nC(numberCurrent,當前塊值)。
3 查表獲得coff_token的編碼。
4 編碼每個拖尾係數的符號,按zig-zag的逆序進行編碼。
5 編碼除拖尾係數之外非零係數的level(Levels)。
6 編碼最後一個非零係數之前0的個數(totalZeos)。
7 編碼每個係數前面0的數目(run_before)。

假設有一個4*4數據塊NC=1,
{
   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……,
即:
第一步:TotalCoeffs = 5, TrailingOnes = 3, Total_zeros = 3.
第二步: 如果不是色度直流,NC=(NA+NB)/2=1,如果是色度直流,NC=-1.
查表得:
If (TotalCoeffs == 5 && TrailingOnes == 3 && 0 <= NC < 2)
      coeff_token = 0000 100;
      Code = 0000 100;
第三步:逆序編碼,三個拖尾係數的符號依次是+(0),-(1),-(1);
即:
TrailingOne sign[i--] = 0;
TrailingOne sign[i--] = 1;
TrailingOne sign[i--] = 1;
Code = 0000 1000 11;
第四步:編碼除了拖尾係數以外非零係數幅值Levels:
這步需要再分析下。
結果:
 Code = 0000 1000 1110 010;
第五步:編碼最後一個非零係數前零的數目(TotalZeros)。
   查表,當TotalCoeffs = 5,total_zero = 3時,bit string = 111;

  Code = 0000 1000 1110 0101 11;
第六步:對每個非零係數前零的個數(RunBefore)進行編碼:
i = TotalCoeffs = 5;ZerosLeft = Total_zeros = 3;查表:
依然按照逆序編碼
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

I宏塊類型的二值化

I宏塊類型包含類型名稱,預測方式,色度CBP,亮度CBP,幀內16X16的預測模式,I宏塊類型的二值化最多生成7個BIT,各BIT位的意義如下:

第一位: 0表示I_4X4,1表示非I_4X4,可以是I_16X16,I_PCM。

第二位:0表示I_16X16,1表示I_PCM。

接下來是色度CBP,色度CBP最多需要兩個BIT,0表示所有殘差都不被傳送,解碼器把所有殘差系統賦爲0,1表示只有DC係數被傳送,解碼器把所有AC係數賦爲0,2表示所有殘差係數(包括DC,AC)都被傳送,解碼器用接收到的殘差係數重建圖像。

當色度CBP小於2時,

第三位:值爲0時,表示所有殘差都不被傳送;值爲1時,表示只有DC係數被傳送。

第四位:該位表示亮度CBP,由於非I_16X16的宏塊不單獨編碼DC係數,所有這個變量只指明兩種編碼方案:該位等於0表示對應子宏塊殘差全部不被傳送,該位等於1表示對應子宏塊殘差係數被傳送,0表示殘差全部不編碼,1表示殘差全部編碼。

第五,六位爲幀內16X16的預測方式,共四種,佔兩位。

當色度CBP等於2時,

第四,五位合起來表示所有殘差係數都被傳送。

第六,七位爲幀內16X16的預測方式。

 

 

 

發佈了246 篇原創文章 · 獲贊 80 · 訪問量 93萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章