由于宏JVET_L0632_AFFINE_MERGE默认开启,因此删减了函数中一些无用代码。
xCheckRDCostAffineMerge2Nx2N函数的流程和普通Merge模式的函数流程基本完全一样。都是先获取候模式选列表,然后SATD,再RDO选最优。
Affine_Merge模式要求,块的大小长宽必须都大于8.
其中调用getAffineMergeCand函数获取AffineMerge候选列表,长度为5,存储在AffineMergeCtx中。
void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
{
if( m_modeCtrl->getFastDeltaQp() )
{
return;
}
//Affine merge模式块长宽均要大于等于8
if ( bestCS->area.lumaSize().width < 8 || bestCS->area.lumaSize().height < 8 )
{
return;
}
const Slice &slice = *tempCS->slice;
CHECK( slice.getSliceType() == I_SLICE, "Affine Merge modes not available for I-slices" );
tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); //tempCS清空初始化
AffineMergeCtx affineMergeCtx; //AffineMerge模式的候选列表,长度为5,最大存储5组3控制点的MV
const SPS &sps = *tempCS->sps;
#if JVET_L0369_SUBBLOCK_MERGE
MergeCtx mrgCtx;
if ( sps.getSpsNext().getUseSubPuMvp() )
{
Size bufSize = g_miScaling.scale( tempCS->area.lumaSize() );
mrgCtx.subPuMvpMiBuf = MotionBuf( m_SubPuMiBuf, bufSize );
affineMergeCtx.mrgCtx = &mrgCtx; //merge候选列表,主要记录ATMVP模式的一些信息,包含在AffineMerge候选列表中
}
#endif
{
// first get merge candidates
CodingUnit cu( tempCS->area );
cu.cs = tempCS;
cu.partSize = SIZE_2Nx2N; //tempCS添加cu、pu
cu.predMode = MODE_INTER;
cu.slice = tempCS->slice;
#if HEVC_TILES_WPP
cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() );
#endif
#if JVET_L0054_MMVD
cu.mmvdSkip = false;
#endif
PredictionUnit pu( tempCS->area );
pu.cu = &cu;
pu.cs = tempCS;
PU::getAffineMergeCand( pu, affineMergeCtx ); //构造Affine_Merge候选列表
if ( affineMergeCtx.numValidMergeCand <= 0 )
{
return;
}
}
bool candHasNoResidual[AFFINE_MRG_MAX_NUM_CANDS];
for ( uint32_t ui = 0; ui < affineMergeCtx.numValidMergeCand; ui++ )
{
candHasNoResidual[ui] = false;
}
bool bestIsSkip = false;
uint32_t uiNumMrgSATDCand = affineMergeCtx.numValidMergeCand;
PelUnitBuf acMergeBuffer[AFFINE_MRG_MAX_NUM_CANDS]; //记录5组AffineMerge候选分别经MC得到的pred像素
static_vector<uint32_t, AFFINE_MRG_MAX_NUM_CANDS> RdModeList;
bool mrgTempBufSet = false;</