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的編碼過程如下:
計算非零係數(TotalCoeffs)和拖尾係數(TrailingOnes)的數目。
拖尾係數指值為 +1/-1的係數,最大數目為 3。如果超過 3個,那麼只有最後三個被視為拖尾係數。拖尾係數的數目被賦值到變數 TrailingOnes。
非零係數包括所有的拖尾係數,其數目被賦值到變數 TotalCoeffs)。
計算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值較小即周圍塊的非零係數較少時,就會選擇比較短的碼,從而實現了資料壓縮。
查表獲得coff_token的編碼。
根據之前編碼和計算過程所得的變數 TotalCoeffs 、 TrailingOnes 和 nC 值可以查 H.264 標準附錄 CAVLC 碼錶,即可得出 coeff_token 編碼序列。
編碼每個拖尾係數的符號,按zig-zag的逆序進行編碼。
每個符號用 1個 bit位來表示, 0表示“ +”, 1表示“—”。
當拖尾係數超過三個時只有最後三個被認定為拖尾係數,引詞編碼順序為從後向前編碼。
編碼除拖尾係數之外非零係數的level(Levels)。
每個非零係數的 level包括 sign和 magnitude,掃描順序是逆 zig-zag序。 level的編碼由首碼 (level_prefix)和尾碼 (level_suffix)組成。首碼的長度在 0到 6之間,尾碼的長度則可通過下面的步驟來確定: 將尾碼初始化為 0。(若非零係數的總數超過 10且拖尾係數不到 3,則初始化為 1)。 編碼頻率最高(即按掃描序最後)的除拖尾係數之外的非零係數。 若這個係數的 magnitude 超過某個門檻值 (threshold) ,則增加尾碼的長度。下表是門檻值的列表:
編碼最後一個非零係數之前0的個數(totalZeos)。
TotalZeros 指的是在最後一個非零係數前零的數目,此非零係數指的是按照正向掃描的最後一個非零係數
根據 TotalCoeffs 值, H.264 標準共提供了 25 個變長表格供尋找,其中編碼亮度資料時有 15 個表格供尋找,編碼色度 DC2 × 2 塊( 4 : 2:0 格式)有 3 個表格、編碼色度 DC2 × 4 塊( 4 : 2:2 格式)有 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