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