量化参数,简称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,但是没有意义。