HEVC熵編碼
文章目錄
熵編碼原理
熵編碼的基本要求
- 唯一可譯編碼:碼字序列能被唯一地譯碼
- 非續長代碼:任何碼字都不是其他碼字的續長
定長熵編碼
- 每個編碼符號分配等長的碼字
- HEVC中定長編碼主要應用於NAL單元頭、Slice分割頭和參數集編碼
- HEVC中規定描述語法元素的固定 比特的預定義值
變長熵編碼 VLC
霍夫曼編碼
- 高概率符號分配短碼
- 低概率符號分配長碼
指數Golomb編碼
- 結構明確,較霍夫曼編碼簡單
- 編碼規則
- 待編碼符號的根據出現概率排列,當前符合的索引爲
算術編碼AC
- 解決了現實計算機中整數位編碼問題,算法中只有加法和移位運算
- 自適應算術編碼:符號初始概率爲均勻分佈,編碼過程不斷調整
- 二進制算術編碼:信源爲二進制化後的符號
- 基於上下文的自適應二進制算術編碼CABAC:上下文模型 + 自適應二進制算術編碼
HEVC的CABAC
HEVC的CABAC特點
- 採用二進制算術編碼,將所有語法元素轉換爲二進制符號串,無乘法運算,降低計算複雜度
- 上下文建模:根據已編碼語法元素爲待編碼語法元素建立概率模型並自適應進行概率估計和模型更新
- 旁路編碼:假定二進制0/1等概分佈進行二進制算術編碼
HEVC的CABAC框架
二進制化
- 一元碼
U
與截斷一元碼TU
:二進制化mvp_idx
,delta_qp
等語法元素 - 截斷Rice碼
TR
- k階指數Golomb碼
EGK
:二進制化mvd
等語法元素 - 定長碼
FL
上下文模型
變量定義
6
比特量化概率狀態索引 ,1
比特最大概率符號值- 上下文模型狀態 僅需要7比特數即可表示
- 量化參數
- 起始類型 ,上下文索引 ,上下文初始值
- 限幅函數 $ \text{Clip3} (a,b,c) $ 將 的值限制在 和 之間
上下文關係
-
根據已編碼相鄰塊(左側和上方)語法元素對當前語法元素進行模型預測
-
侷限於對塊和子塊類型應用,第 比特根據前面已編碼的 比特所採用的模型進行模型預測
-
僅用於殘差數據編碼,根據待編碼的殘差係數在掃描路徑中的位置進行模型預測
-
僅用於殘差數據編碼,根據已編碼係數幅度中某個特定幅度出現次數作爲參考進行模型預測
上下文模型初始化
- 上下文模型初始化負責將概率區間復原到 併爲上下文模型確定初始值
- 根據量化參數 查找上下文模型的經驗分佈,並作爲上下文模型初始值
查表確定上下文索引值和初始值
-
根據Slice的類型確定起始類型
- KaTeX parse error: Expected '}', got '_' at position 12: \text{slice_̲type == I: ini…
- KaTeX parse error: Expected '}', got '_' at position 12: \text{slice_̲type == P: init…
- KaTeX parse error: Expected '}', got '_' at position 12: \text{slice_̲type == B: init…
-
根據語法元素和起始類型 查表確定上下文索引 和初始值
確定概率狀態索引和大概率符號值
-
導出比特長度爲
4
的變量 -
計算中間變量
-
計算當前Slice的量化參數 KaTeX parse error: Expected '}', got '_' at position 35: …26 + \text{init_̲qp_minus26} + \…
-
導出狀態概率索引和最大概率符號值
上下文模型更新
-
小概率符號的概率由有限的64個索引值 表徵
-
的導出公式爲
-
概率索引值 自適應更新規則
- 出現 事件:若 ,則 ,否則 保持不變
- 出現 事件:若 ,則 ,否則 保持不變且 與 互換
- 固定用於對編碼結束判斷進行編碼
常規二進制編碼
變量定義
-
當前二進制符號
-
量化區間下限 $L,; \text{where } len(L) = 10 $ ,量化區間長度爲
-
量化範圍索引 ,量化概率索引
-
小概率符號 ,大概率符號
-
大概率符號區間長度 ,小概率符號區間長度 (在前,在後)
-
非確定延時移出高位值
基本步驟
-
子分當前概率區間
- 當前區間範圍 由量化值 近似,且需要滿足
- 將區間範圍等分爲四個部分,由量化範圍索引 表示
- 根據參數 作爲索引查找表
rangeTabLps
,取得 和 - 計算
-
確定新概率區間
- 判斷當前二進制符號 是大概率符號 還是小概率符號
- 若 ,則量化區間更新爲自 開始,長度爲
- 若 ,則量化區間更新爲自 ,長度爲
-
上下文模型概率狀態更新
- 概率索引值 自適應更新
- 根據 計算小概率符號的概率
- 根據 計算最大概率符號值
-
對 和 重歸一化:將 重新調整到 範圍內以滿足區間劃分要求,並同時調整 的下限值
-
重歸一化過程可能輸出一或多個比特,即的最終值的高位,作爲算術編碼的輸出
-
Step 1:根據 的大小判斷是否需要重歸一化:若 ,則 左端點 可以落在
區間 的任何位置,無法確定並輸出編碼的最高位,故無需重歸一化。否則轉到 Step 2
-
Step 2:根據 的值輸出編碼區間最高位並對 進位,同時保證 。可分成三種情況:
- :可知右端點 ,且編碼區間最高位爲
0
,寄存器左移輸出比特0
並將 和 左移倍乘以保持精度 - :可知右端點 ,且編碼區間最高位爲
1
,寄存器左移輸出比特1
並將 和 左移倍乘以保持精度 - :可知右端點 ,且編碼區間最高兩位可能是
10
或11
,故無法確定最高有效位。通過移出高位,判斷次高位符號的方法確定移出的高位符號是0
或1
,並將 和 左移倍乘以保持精度
- :可知右端點 ,且編碼區間最高位爲
-
旁路編碼模式
-
固定二進制符號
0
和1
等概率,概率估計和更新過程均被旁路 -
區間劃分約定
0
區間在前,且通過保持編碼區間長度不變,區間下限左移實現加倍
HM的熵編碼實現
HM與熵編碼有關的類
TEncEntropy
:熵編碼的頂層包裝類,內部調用TEncEntropyIf
類實現TEncEntropyIf
:熵編碼算法的抽象類TEncSbac
:CABAC熵編碼算法的實現類TEncCavlc
:CAVLC熵編碼算法的實現類TEncBinIf
:二進制編碼抽象類,負責實現熵編碼內部具體的二進制編碼細節TEncBinCABAC
:進行二進制編碼並將比特流寫入文件TEncBinCABACCounter
:只計算熵編碼的比特數而不將比特流寫入文件ContextModel3DBuffer
:上下文模型的包裝類ContextModel
:上下文模型
HM中熵編碼關鍵函數
-
參數集熵編碼:
- 參數集使用CAVLC編碼
TEncCavlc::encodeVPS()
,TEncCavlc::encodeSPS()
,TEncCavlc::encodePPS()
- 在
TEncGOP::compressGOP()
中調用
-
熵編碼入口函數:
TEncSlice::encodeSlice()
- 初始化熵編碼器,設置CABAC熵編碼器爲當前的熵編碼器
- 加載熵編碼器,初始化並加載上下文信息
- 遍歷片中的每一個LCU,進行如下操作:
- 定向比特流到輸出位置
- 重置熵編碼器,並更新上下文信息
- 如果使用SAO,則調用
encodeSAOBlkParam()
對SAO的參數進行編碼 - 調用
encodeCtu()
對CTU進行熵編碼
-
熵編碼初始化函數:
TEncSbac::resetEntropy()
-
根據預定義的上下文模型初始化各個語法元素的上下文模型
-
調用過程:
-
-
常規編碼核心函數
TEncBinCABAC::encodeBin()
- 語法元素通過調用
encodeBin()
進行二進制編碼 - 編碼當前比特位並將該比特對應的上下文模型設置爲已經編碼
- 根據常規二進制編碼的基本步驟編碼並更新上下文模型
- 嘗試寫入緩衝區
- 語法元素通過調用
-
旁路編碼核心函數
TEncBinCABAC::encodeBinEP()