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