量化參數,簡稱QP,是解碼中反量化過程中最重要的參數,我覺得HEVC解碼的中Qp的計算有那一點複雜,標準有那麼一點晦澀,這裏來一起探討下。
1.參數
PPS中關於Qp的參數:
init_qp_minus26:加上26表示初始Qp,範圍[-26,25]。
cu_qp_delta_enabled_flag:1表示語法元素diff_cu_qp_delta_depth(PPS中)存在,而cu_qp_delta_abs(TU)中可能存在。
diff_cu_qp_delta_depth:給出CTU的尺寸和使用相同的cu_qp_delta_abs和 cu_qp_delta_sign_flag的coding block的尺寸差。範圍[0, log2_diff_max_min_luma_coding_block_size]。默認值爲0。
變量Log2MinCuQpDeltaSize =CtbLog2SizeY −diff_cu_qp_delta_depth
pps_cb_qp_offset和pps_cr_qp_offset:給出cb,cr的Qp相對於y的Qp的offset,範圍爲[-12,12]
pps_slice_chroma_qp_offsets_present_flag:表明語法元素slice_cb_qp_offset 和slice_cr_qp_offset存在於相應的slice header中。
Sliceheader中關於Qp的參數:
slice_qp_delta:給出本slice中CU使用的Qpy的初值sliceQpy。範圍[0,51]。
sliceQpy = 26 + init_qp_minus26 +slice_qp_delta。
slice_cb_qp_offset:計算CU使用的cb量化參數Qpcb的offset,範圍[-12,12]。這個offset等於pps_cb_qp_offset+ slice_cb_qp_offset。加過之後的範圍也應爲[-12,12]。
slice_cr_qp_offset:同上,cr相關。
TU中關於qp的參數:
cu_qp_delta_abs:通過此參數計算得出CuQpDeltaVal,CuQpDeltaVal表示當前CU的Qp和其預測Qp的差。
cu_qp_delta_sign_flag:計算CuQpDeltaVal時使用。
CuQpDeltaVal = cu_qp_delta_abs * ( 1−2 * cu_qp_delta_sign_flag )
如果cu_qp_delta_abs存在,則變量IsCuQpDeltaCoded設爲1。表明cu_qp_delta_abs已經解碼過了。
如果cu_qp_delta_enabled_flag(見前文)爲0,則sliceQpy爲此slice中的每個CU的亮度量化參數Qpy。HM代碼中通過函數pcCU->initCU()(在函數decompressSlice()中)來實現。每個CU在初始化的時候就已經獲得了Qpy的值,注意:每個CU使用相同的Qpy
反之,如果cu_qp_delta_enabled_flag爲1,則cu_qp_delta_abs和cu_qp_delta_sign_flag可能存在。
其存在的條件:
(1)當前的TU有係數。
(2)對於當前TU所在的quantization group(量化組,真是渣翻譯,大家忍一下吧),IsCuQpDeltaCoded爲0。一旦當前的quantization group解碼過一次cu_qp_delta_abs,則IsCuQpDeltaCoded設爲1。
這裏引入了quantization group的概念。其尺寸爲Log2MinCuQpDeltaSize,表示在一個CTU中共享一個相同的qPY_PRED的區域的大小。
Log2MinCuQpDeltaSize= CtbLog2SizeY(CTU尺寸的對數表示) −diff_cu_qp_delta_depth
2.QP的計算
qPY_PRED的計算步驟如下:
(1)計算變量qPY_PREV
– 下列條件如果有一條或更多條滿足,則 qPY_PREV等於SliceQpY:
– 當前量化組是slice中的第一個量化組
– 當前量化組是tile中的第一個量化組
– 當前量化組是ctb行中的第一個量化組且 變量entropy_coding_sync_enabled_flag 等於1.
否則, qPY_PREV等於解碼順序中上一個量化組中最後一個coding unit的QpY
(2)進行6.4.1的available過程,當前CU位置設爲 ( xCb, yCb ) 鄰塊位置設爲 ( xQg −1, yQg )得到availableA. 變量qPY_A由以下步驟得到((xQg, yQg)爲CU所在量化組的左上角座標):
– 下列條件如果有一條或更多條滿足,則qPY_A等於qPY_PREV:
– availableA 爲FALSE.
– 含有位置( xQg −1, yQg )的ctb的地址ctbAddrA 不等於 CtbAddrInTs, 其中ctbAddrA 的計算如下:
– 否則, qPY_A等於包含位置( xQg−1, yQg )的解碼塊的QpY。
(3)available過程,當前位置設爲 ( xCb, yCb ) 鄰塊位置設爲 ( xQg , yQg - 1 )得到availableA. 變量qPY_B由以下步驟得到:
–下列條件如果有一條或更多條滿足,則qPY_B等於qPY_PREV:
– availableB爲FALSE.
– 含有位置( xQg, yQg - 1 )的ctb的地址ctbAddrB 不等於 CtbAddrInTs, 其中ctbAddrB 的計算如下:
– 否則, qPY_B等於包含位置( xQg , yQg - 1)的解碼塊的QpY。
(4)預測量化參數qPY_PRED由以下步驟得到:
qPY_PRED= ( qPY_A+ qPY_B+ 1 ) >> 1
QpY由下式計算得到:
變量Qp′Y由下式計算得到:
對於8bit的碼流,QpBdOffsetY = 0。
變量qPCb和qPCr分別基於qPiCb和qPiCr根據表1設爲QpC qPiCband 其中qPiCb和qPiCr可有以下得到:
查詢 qPc的表格
Qp′Cb和Qp′Cr計算如下:
對於8bit的碼流來說,offset相關的變量都爲0,計算更加簡化。
3.QP計算流程圖
整個過程用流程圖表示:
還有兩條有用的結論:
1. CU中所有的TU共用一個Qpy。
2. quantization group的尺寸可能小於CU,但是沒有意義。