xPredAffineBlk函数在pu块的运动补偿的时候被调用,处理Affine模式时的运动补偿任务,根据控制点运动信息CPMVP获取预测像素pred。
_mv为affine模式2或3个控制点的CPMVP,dstPic为需要得到的Affine模式预测像素。
运动补偿函数见:VTM3.0代码阅读:motionCompensation函数
void InterPrediction::xPredAffineBlk( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv* _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng )
{
if ( (pu.cu->affineType == AFFINEMODEL_6PARAM && _mv[0] == _mv[1] && _mv[0] == _mv[2])
|| (pu.cu->affineType == AFFINEMODEL_4PARAM && _mv[0] == _mv[1])
) //如果Affine模式控制点的mvp都相同,说明块进行的是平移运动,直接用普通帧间的运动补偿函数
{
Mv mvTemp = _mv[0];
clipMv( mvTemp, pu.cu->lumaPos(), *pu.cs->sps );
xPredInterBlk( compID, pu, refPic, mvTemp, dstPic, bi, clpRng
#if JVET_L0256_BIO
, false
#endif
#if JVET_L0293_CPR
, false
#endif
);
return;
}
JVET_J0090_SET_REF_PICTURE( refPic, compID );
const ChromaFormat chFmt = pu.chromaFormat;
int iScaleX = ::getComponentScaleX( compID, chFmt ); //采样方式ChromaFormat造成的尺度缩放
int iScaleY = ::getComponentScaleY( compID, chFmt );
Mv mvLT =_mv[0]; //3个控制点的CPMVP
Mv mvRT =_mv[1];
Mv mvLB =_mv[2];
#if !REMOVE_MV_ADAPT_PREC
mvLT.setHighPrec();
mvRT.setHighPrec();
mvLB.setHighPrec();
#endif
// get affine sub-block width and height
const int width = pu.Y().width;
const int height = pu.Y().height;
int blockWidth = AFFINE_MIN_BLOCK_SIZE; // Affine模式中小块的尺寸为4x4
int blockHeight = AFFINE_MIN_BLOCK_SIZE;
blockWidth >>= iScaleX; //根据ChromaFormat进行Affine最小块的尺寸缩放
blockHeight >>= iScaleY;
#if JVET_L0265_AFF_MINIMUM4X4
blockWidth = std::max(blockWidth, AFFINE_MIN_BLOCK_SIZE);
blockHeight = std::max(blockHeight<