天天看點

CAVLC編碼過程詳解[熵編碼]

編碼過程:

假設有一個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;

編碼完畢。

老畢書上120頁表6.10中第2行和第三行的NA和NB是不是給弄反了

應該是弄反了

trailing ones是指所有絕對值為1的系數的個數還是連續絕對值為1的系數的個數

倒數三個 +/-1

“如果Level[ i ]是負的,levelCode = - (Level[ i ]<<1) – 1”

假如Level[ i ]=-3,levelCode值是多少啊?

levelcode應該是5,level先乘2為-6,再取反減1

解碼時因為levelcode為奇數,level = (‐levelCode‐1)/2

在CAVLC編碼中,從右往左看,算trailing_ones時,在右邊不能有abs()>1的數,還有算trailing_ones的個數的話,也不能被别的abs()>1的數隔斷,如果隔斷的話,隻能計數到隔斷數為止,而且要保證個數<=3。例如。。。。2,3,0,0,0,1,1,1,0,0,2 ,這個序列中triailing_ones是沒有的。還有。。。。。1,0,0,-1,3,1,0,0,0,0,算trailing_ones 個數時,隻能有一個也就是3後面的“1”算一個,3前面的-1和1由于被3隔斷,是以不能算入其中。

ZerosLeft =1, run_before = 1      run_before[0]不需要碼流來表示

畢厚傑P123,6.8.6節中所給例子是否有誤?是否應如下編碼?

0        0        -1        0

5        2        0        0

3        0        0        0

1        0        0        0        

資料重排:0,0,5,3,2,-1,0,0,0,1……

其中TotalCoeffs = 5, TrailingOnes = 2, Total_zeros = 5, NC = 3

最終編碼輸出:0000,1011,0010,0000,1010,1010,111

請問:為什麼不需要碼流來表示?

是因為是最後一位嗎?

查表知:此時 run_before[0]=0