xInheritedAffineMv函数在getAffineMergeCand函数构造AffineMerge候选列表中被调用,来得到AffineMerge模式的“继承的MVP”,即在从Affine模式的相邻pu继承得到CPMVP。
pu为当前pu,puNeighbour为当前块的相邻pu,eRefPicList为L0或L1,
rcMv[3]即为需要计算的当前块的Affine继承候选,即3个控制点的mv。
void PU::xInheritedAffineMv( const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3] )
{
int posNeiX = puNeighbour->Y().pos().x;
int posNeiY = puNeighbour->Y().pos().y;
int posCurX = pu.Y().pos().x;
int posCurY = pu.Y().pos().y; //当前pu和相邻pu的x、y坐标
int neiW = puNeighbour->Y().width;
int curW = pu.Y().width;
int neiH = puNeighbour->Y().height;
int curH = pu.Y().height; //当前pu和相邻pu的长宽
Mv mvLT, mvRT, mvLB;
mvLT = puNeighbour->mvAffi[eRefPicList][0]; //相邻Affine模式pu的三个控制点的mv
mvRT = puNeighbour->mvAffi[eRefPicList][1];
mvLB = puNeighbour->mvAffi[eRefPicList][2];
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP
bool isTopCtuBoundary = false; //相邻pu为当前块左上或右上ctu的最底层边沿cu
if ( (posNeiY + neiH) % pu.cs->sps->getSpsNext().getCTUSize() == 0 && (posNeiY + neiH) == posCurY )
{
// use bottom-left and bottom-right sub-block MVs for inheritance
const Position posRB = puNeighbour->Y().bottomRight();
const Position posLB = puNeighbour->Y().bottomLeft();
mvLT = puNeighbour->getMotionInfo( posLB ).mv[eRefPicList]; //LT->LB RT->RB
mvRT = puNeighbour->getMotionInfo( posRB ).mv[eRefPicList]; //相邻pu的左下和右下的mv用来计算继承Affine候选
posNeiY += neiH;
isTopCtuBoundary = true;
}
#endif
int shift = MAX_CU_DEPTH; //7
int iDMvHorX, iDMvHorY, iDMvVerX, iDMvVerY;
iDMvHorX = (mvRT - mvLT).getHor() << (shift - g_aucLog2[neiW]);
iDMvHorY = (mvRT - mvLT).getVer() << (shift - g_aucLog2[neiW]);
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP // degrade to 4-parameter model
if ( puNeighbour->cu->affineType == AFFINEMODEL_6PARAM && !isTopCtuBoundary )
#else //相邻pu为6参数Affine,并且相邻pu不是isTopCtuBoundary
if ( puNeighbour->cu->affineType == AFFINEMODEL_6PARAM )
#endif
{
iDMvVerX = (mvLB - mvLT).getHor() << (shift - g_aucLog2[neiH]);
iDMvVerY = (mvLB - mvLT).getVer() << (shift - g_aucLog2[neiH]);
}
else
{
iDMvVerX = -iDMvHorY;
iDMvVerY = iDMvHorX;
}
int iMvScaleHor = mvLT.getHor() << shift;
int iMvScaleVer = mvLT.getVer() << shift;
int horTmp, verTmp;
// v0 第一个控制点的mv
horTmp = iMvScaleHor + iDMvHorX * (posCurX - posNeiX) + iDMvVerX * (posCurY - posNeiY);
verTmp = iMvScaleVer + iDMvHorY * (posCurX - posNeiX) + iDMvVerY * (posCurY - posNeiY);
roundAffineMv( horTmp, verTmp, shift );
#if REMOVE_MV_ADAPT_PREC
rcMv[0].hor = horTmp;
rcMv[0].ver = verTmp;
#else
rcMv[0] = Mv(horTmp, verTmp, true);
#endif
// v1 第二个控制点的mv
horTmp = iMvScaleHor + iDMvHorX * (posCurX + curW - posNeiX) + iDMvVerX * (posCurY - posNeiY);
verTmp = iMvScaleVer + iDMvHorY * (posCurX + curW - posNeiX) + iDMvVerY * (posCurY - posNeiY);
roundAffineMv( horTmp, verTmp, shift );
#if REMOVE_MV_ADAPT_PREC
rcMv[1].hor = horTmp;
rcMv[1].ver = verTmp;
#else
rcMv[1] = Mv(horTmp, verTmp, true);
#endif
// v2 第三个控制点的mv
if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
{
horTmp = iMvScaleHor + iDMvHorX * (posCurX - posNeiX) + iDMvVerX * (posCurY + curH - posNeiY);
verTmp = iMvScaleVer + iDMvHorY * (posCurX - posNeiX) + iDMvVerY * (posCurY + curH - posNeiY);
roundAffineMv( horTmp, verTmp, shift );
#if REMOVE_MV_ADAPT_PREC
rcMv[2].hor = horTmp;
rcMv[2].ver = verTmp;
#else
rcMv[2] = Mv(horTmp, verTmp, true);
#endif
}
}