依次介紹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的預測方式。