色度分量的帧内预测
入口函数
对色度分量进行帧内预测的入口函数是:estIntraPredChromaQT
1、调用getAllowedChromaDir构造色度分量的帧内预测候选模式列表2、遍历候选模式列表,对于每一个模式,调用xRecurIntraChromaCodingQT进行预测、变换量化操作,并得出率失真代价
3、通过比较率失真代价得到最优的模式
Void TEncSearch::estIntraPredChromaQT( TComDataCU* pcCU,
TComYuv* pcOrgYuv,
TComYuv* pcPredYuv,
TComYuv* pcResiYuv,
TComYuv* pcRecoYuv,
UInt uiPreCalcDistC )
{
UInt uiDepth = pcCU->getDepth(0);
UInt uiBestMode = 0;
UInt uiBestDist = 0;
Double dBestCost = MAX_DOUBLE;
//----- init mode list -----
UInt uiMinMode = 0;
UInt uiModeList[ NUM_CHROMA_MODE ];
pcCU->getAllowedChromaDir( 0, uiModeList );
UInt uiMaxMode = NUM_CHROMA_MODE;
//----- check chroma modes -----
for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )
{
//----- restore context models -----
m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
//----- chroma coding -----
UInt uiDist = 0;
pcCU->setChromIntraDirSubParts ( uiModeList[uiMode], 0, uiDepth );
xRecurIntraChromaCodingQT ( pcCU, 0, 0, pcOrgYuv, pcPredYuv, pcResiYuv, uiDist );
if( pcCU->getSlice()->getPPS()->getUseTransformSkip() )
{
m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
}
UInt uiBits = xGetIntraBitsQT( pcCU, 0, 0, false, true, false );
Double dCost = m_pcRdCost->calcRdCost( uiBits, uiDist );
//----- compare -----
if( dCost < dBestCost )
{
dBestCost = dCost;
uiBestDist = uiDist;
uiBestMode = uiModeList[uiMode];
UInt uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
xSetIntraResultChromaQT( pcCU, 0, 0, pcRecoYuv );
::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
::memcpy( m_puhQTTempTransformSkipFlag[1], pcCU->getTransformSkip( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
::memcpy( m_puhQTTempTransformSkipFlag[2], pcCU->getTransformSkip( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
}
}
//----- set data -----
UInt uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPN * sizeof( UChar ) );
::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPN * sizeof( UChar ) );
::memcpy( pcCU->getTransformSkip( TEXT_CHROMA_U ), m_puhQTTempTransformSkipFlag[1], uiQPN * sizeof( UChar ) );
::memcpy( pcCU->getTransformSkip( TEXT_CHROMA_V ), m_puhQTTempTransformSkipFlag[2], uiQPN * sizeof( UChar ) );
pcCU->setChromIntraDirSubParts( uiBestMode, 0, uiDepth );
pcCU->getTotalDistortion () += uiBestDist - uiPreCalcDistC;
//----- restore context models -----
m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
}
建立候选模式列表
1、色度模式的候选模式是:planar模式,DC模式、水平模式、垂直模式,对应的亮度分量的模式
2、调整模式:如果对应的亮度分量的模式和(planar,DC、水平、垂直)这几种模式中的一个重复了,那么把对应亮度分量模式改成模式34
3、遍历候选的模式,选出最优的模式,然后直接对色度分量的模式的编号进行编码(会经过一定的判断和调整,细节就不说了)。附色度分量的模式的编号:
模式0:planar
模式1:垂直模式(即角度模式26)
模式2:水平模式(即角度模式10)
模式3::DC模式
模式4:对应亮度分量模式
Void TComDataCU::getAllowedChromaDir( UInt uiAbsPartIdx, UInt* uiModeList )
{
uiModeList[0] = PLANAR_IDX;
uiModeList[1] = VER_IDX;
uiModeList[2] = HOR_IDX;
uiModeList[3] = DC_IDX;
uiModeList[4] = DM_CHROMA_IDX;
UInt uiLumaMode = getLumaIntraDir( uiAbsPartIdx );
for( Int i = 0; i < NUM_CHROMA_MODE - 1; i++ )
{
if( uiLumaMode == uiModeList[i] )
{
uiModeList[i] = 34; // VER+8 mode
break;
}
}
}
预测操作
这一步其实还做了变换量化相关的处理,相关的函数是xRecurIntraChromaCodingQT(顺带变换和量化),它和xRecurIntraCodingQT函数是类似的,这里不再细说了,可以参考HM编码器代码阅读(38)——帧内预测(五)帧内预测之正式的预测操作