xCompressCU
Xcompresscu 主要完成块划分(包括CU,PU,TU划分),pu预测模式选择,期间继续调用函数完成帧间预测帧内预测,PCM模式测试。包括1.帧间预测xCheckRDCostInter、xCheckRDCostMerge2Nx2N2.帧内预测xCheckRDCostIntra3.PCM模式xCheckIntraPCM
整个xcompressCU之中完成了一个LCU所有可能的CU划分模式,以及pu(或tu)所有的模式。并且进行了其中PU的帧间帧内PCM的所有预测模式,搜有以上提到的这些过程都通过率失真优化技术,选择出最优的划分模式以及选择模式.下图是整个函数的流程图。
代码如下:
#if AMP_ENC_SPEEDUP
Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const UInt uiDepth DEBUG_STRING_FN_DECLARE(sDebug_), PartSize eParentPartSize )
#else
Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const UInt uiDepth )
#endif
{
TComPic* pcPic = rpcBestCU->getPic();
DEBUG_STRING_NEW(sDebug)
const TComPPS &pps=*(rpcTempCU->getSlice()->getPPS());
const TComSPS &sps=*(rpcTempCU->getSlice()->getSPS());
// These are only used if getFastDeltaQp() is true
const UInt fastDeltaQPCuMaxSize = Clip3(sps.getMaxCUHeight()>>sps.getLog2DiffMaxMinCodingBlockSize(), sps.getMaxCUHeight(), 32u);
// get Original YUV data from picture
m_ppcOrigYuv[uiDepth]->copyFromPicYuv( pcPic->getPicYuvOrg(), rpcBestCU->getCtuRsAddr(), rpcBestCU->getZorderIdxInCtu() );
// variable for Cbf fast mode PU decision
Bool doNotBlockPu = true;
Bool earlyDetectionSkipMode = false;
const UInt uiLPelX = rpcBestCU->getCUPelX();
const UInt uiRPelX = uiLPelX + rpcBestCU->getWidth(0) - 1;
const UInt uiTPelY = rpcBestCU->getCUPelY();
const UInt uiBPelY = uiTPelY + rpcBestCU->getHeight(0) - 1;
const UInt uiWidth = rpcBestCU->getWidth(0);
Int iBaseQP = xComputeQP( rpcBestCU, uiDepth );
Int iMinQP;
Int iMaxQP;
Bool isAddLowestQP = false;
const UInt numberValidComponents = rpcBestCU->getPic()->getNumberValidComponents();
if( uiDepth <= pps.getMaxCuDQPDepth() )
{
Int idQP = m_pcEncCfg->getMaxDeltaQP();
iMinQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP-idQP );
iMaxQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP+idQP );
}
else
{
iMinQP = rpcTempCU->getQP(0);
iMaxQP = rpcTempCU->getQP(0);
}
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
{
if ( uiDepth <= pps.getMaxCuDQPDepth() )
{
// keep using the same m_QP_LUMA_OFFSET in the same CTU
m_lumaQPOffset = calculateLumaDQP(rpcTempCU, 0, m_ppcOrigYuv[uiDepth]);
}
iMinQP = Clip3(-sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP - m_lumaQPOffset);
iMaxQP = iMinQP; // force encode choose the modified QO
}
if ( m_pcEncCfg->getUseRateCtrl() )
{
iMinQP = m_pcRateCtrl->getRCQP();
iMaxQP = m_pcRateCtrl->getRCQP();
}
// transquant-bypass (TQB) processing loop variable initialisation ---
const Int lowestQP = iMinQP; // For TQB, use this QP which is the lowest non TQB QP tested (rather than QP'=0) - that way delta QPs are smaller, and TQB can be tested at all CU levels.
if ( (pps.getTransquantBypassEnabledFlag()) )
{
isAddLowestQP = true; // mark that the first iteration is to cost TQB mode.
iMinQP = iMinQP - 1; // increase loop variable range by 1, to allow testing of TQB mode along with other QPs
if ( m_pcEncCfg->getCUTransquantBypassFlagForceValue() )
{
iMaxQP = iMinQP;
}
}
TComSlice * pcSlice = rpcTempCU->getPic()->getSlice(rpcTempCU->getPic()->getCurrSliceIdx());
const Bool bBoundary = !( uiRPelX < sps.getPicWidthInLumaSamples() && uiBPelY < sps.getPicHeightInLumaSamples() );
if ( !bBoundary )
{
for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
{
const Bool bIsLosslessMode = isAddLowestQP && (iQP == iMinQP);
if (bIsLosslessMode)
{
iQP = lowestQP;
}
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() && uiDepth <= pps.getMaxCuDQPDepth() )
{
getSliceEncoder()->updateLambda(pcSlice, iQP);
}
m_cuChromaQpOffsetIdxPlus1 = 0;
if (pcSlice->getUseChromaQpAdj())
{
/* Pre-estimation of chroma QP based on input block activity may be performed
* here, using for example m_ppcOrigYuv[uiDepth] */
/* To exercise the current code, the index used for adjustment is based on
* block position
*/
Int lgMinCuSize = sps.getLog2MinCodingBlockSize() +
std::max<Int>(0, sps.getLog2DiffMaxMinCodingBlockSize()-Int(pps.getPpsRangeExtension().getDiffCuChromaQpOffsetDepth()));
m_cuChromaQpOffsetIdxPlus1 = ((uiLPelX >> lgMinCuSize) + (uiTPelY >> lgMinCuSize)) % (pps.getPpsRangeExtension().getChromaQpOffsetListLen() + 1);
}
rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );
// do inter modes, SKIP and 2Nx2N
if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
{
// 2Nx2N
if(m_pcEncCfg->getUseEarlySkipDetection())
{
xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N DEBUG_STRING_PASS_INTO(sDebug) );
rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );//by Competition for inter_2Nx2N
}
// SKIP
xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU DEBUG_STRING_PASS_INTO(sDebug), &earlyDetectionSkipMode );//by Merge for inter_2Nx2N
rpcTempCU->in