自适应QP(Adaptive QP)

Adaptive QP

Adaptive QP是为每个CU自适应的选择QP以提升编码质量。由配置参数AdaptiveQP指定是否开启该功能。默认不开启。

("AdaptiveQP,-aq", m_bUseAdaptiveQP,false, "QP adaptation based on a psycho-visual model")

其QP计算原则是:对于平坦块选择较小的QP,对于活动性较高的块选择较大的QP

CU的活动性由其亮度分量的方差计算得到。例如,对于一个2Nx2N的CU,首先计算其4个NxN的亮度子块的方差,然后由方差计算该CU的活动性actcu:

为了实现在活动性高的区域使用较大QP,平坦区域使用较小QP,需要对图像中每个2Nx2N的CU的actcu进行归一化。假设图像f的所有2Nx2N的CU的平均活动性为actf,则归一化后的norm_actcu计算如下:

QPA由配置参数MaxQPAdaptationRange指定,默认值为6。

  ("MaxQPAdaptationRange,-aqr",m_iQPAdaptationRange,6, "QP adaptation range")

最终CU的QP计算如下:

注意:配置文件中参数MaxCuDQPDepth指定了能使用Adaptive QP的最小CU尺寸,默认为0。其值要小于最大CU深度。

以下代码是HM中Adaptive QP计算过程:

/** Compute QP for each CU
 * \param pcCU Target CU
 * \param uiDepth CU depth
 * \returns quantization parameter
 */
Int TEncCu::xComputeQP( TComDataCU* pcCU, UInt uiDepth )
{
  Int iBaseQp = pcCU->getSlice()->getSliceQp();
  Int iQpOffset = 0;
  if ( m_pcEncCfg->getUseAdaptiveQP() )
  {
    TEncPic* pcEPic = dynamic_cast<TEncPic*>( pcCU->getPic() );
    UInt uiAQDepth = min( uiDepth, pcEPic->getMaxAQDepth()-1 );
    TEncPicQPAdaptationLayer* pcAQLayer = pcEPic->getAQLayer( uiAQDepth );
    UInt uiAQUPosX = pcCU->getCUPelX() / pcAQLayer->getAQPartWidth();
    UInt uiAQUPosY = pcCU->getCUPelY() / pcAQLayer->getAQPartHeight();
    UInt uiAQUStride = pcAQLayer->getAQPartStride();
    TEncQPAdaptationUnit* acAQU = pcAQLayer->getQPAdaptationUnit();
​
    Double dMaxQScale = pow(2.0, m_pcEncCfg->getQPAdaptationRange()/6.0); //!<缩放因子s
    Double dAvgAct = pcAQLayer->getAvgActivity();  //!<平均活动性
    Double dCUAct = acAQU[uiAQUPosY * uiAQUStride + uiAQUPosX].getActivity();
    Double dNormAct = (dMaxQScale*dCUAct + dAvgAct) / (dCUAct + dMaxQScale*dAvgAct); //!<归一化
    Double dQpOffset = log(dNormAct) / log(2.0) * 6.0; //!<换底公式
    iQpOffset = Int(floor( dQpOffset + 0.49999 ));
  }
​
  return Clip3(-pcCU->getSlice()->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQp+iQpOffset );
}

感兴趣的请关注微信公众号Video Coding

猜你喜欢

转载自blog.csdn.net/Dillon2015/article/details/105265832
今日推荐