Commit 74a26608 authored by Xiaoyu Xiu's avatar Xiaoyu Xiu

JVET-N0334: MV Overflow Prevention

parent b6e0728a
......@@ -524,5 +524,16 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
pu.cu->GBiIdx = (interDirNeighbours[fPosBaseIdx] == 3) ? GBiIdx[fPosBaseIdx] : GBI_DEFAULT;
#if JVET_N0334_MVCLIPPING
for (int refList = 0; refList < 2; refList++)
{
if (pu.refIdx[refList] >= 0)
{
pu.mv[refList].clipToStorageBitDepth();
}
}
#endif
PU::restrictBiPredMergeCandsOne(pu);
}
......@@ -1767,6 +1767,10 @@ void InterPrediction::xProcessDMVR(PredictionUnit& pu, PelUnitBuf &pcYuvDst, con
subPu.mv[0] = mergeMv[REF_PIC_LIST_0] + pu.mvdL0SubPu[num];
subPu.mv[1] = mergeMv[REF_PIC_LIST_1] - pu.mvdL0SubPu[num];
#if JVET_N0334_MVCLIPPING
subPu.mv[0].clipToStorageBitDepth();
subPu.mv[1].clipToStorageBitDepth();
#endif
m_cYuvRefBuffSubCuDMVRL0 = m_cYuvRefBuffDMVRL0.subBuf(UnitAreaRelative(pu, subPu));
m_cYuvRefBuffSubCuDMVRL1 = m_cYuvRefBuffDMVRL1.subBuf(UnitAreaRelative(pu, subPu));
xFinalPaddedMCForDMVR(subPu, srcPred0, srcPred1, m_cYuvRefBuffSubCuDMVRL0, m_cYuvRefBuffSubCuDMVRL1, bioApplied, mergeMv);
......
......@@ -61,6 +61,10 @@ class Mv
{
private:
static const MvPrecision m_amvrPrecision[3];
#if JVET_N0334_MVCLIPPING
static const int mvClipPeriod = (1 << 18);
static const int halMvClipPeriod = (1 << 17);
#endif
public:
int hor; ///< horizontal component of motion vector
......@@ -213,6 +217,15 @@ public:
hor = Clip3( -(1 << 17), (1 << 17) - 1, hor );
ver = Clip3( -(1 << 17), (1 << 17) - 1, ver );
}
#if JVET_N0334_MVCLIPPING
void mvCliptoStorageBitDepth() // periodic clipping
{
hor = (hor + mvClipPeriod) & (mvClipPeriod - 1);
hor = (hor >= halMvClipPeriod) ? (hor - mvClipPeriod) : hor;
ver = (ver + mvClipPeriod) & (mvClipPeriod - 1);
ver = (ver >= halMvClipPeriod) ? (ver - mvClipPeriod) : ver;
}
#endif
};// END CLASS DEFINITION MV
namespace std
......
......@@ -50,6 +50,8 @@
#include <assert.h>
#include <cassert>
#define JVET_N0334_MVCLIPPING 1 // prevention of MV stroage overflow and alignment with spec of MV/CPMV modular for AMVP mode
#define JVET_N0477_LMCS_CLEANUP 1
#define JVET_N0220_LMCS_SIMPLIFICATION 1
......
......@@ -87,6 +87,10 @@ void CS::setRefinedMotionField(CodingStructure &cs)
subPu.mv[1] = pu.mv[1];
subPu.mv[REF_PIC_LIST_0] += pu.mvdL0SubPu[num];
subPu.mv[REF_PIC_LIST_1] -= pu.mvdL0SubPu[num];
#if JVET_N0334_MVCLIPPING
subPu.mv[REF_PIC_LIST_0].clipToStorageBitDepth();
subPu.mv[REF_PIC_LIST_1].clipToStorageBitDepth();
#endif
pu.mvdL0SubPu[num].setZero();
num++;
PU::spanMotionInfo(subPu);
......@@ -3182,16 +3186,25 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
case 1: // 1 : LT, RT, RB
cMv[l][2].hor = cMv[l][3].hor + cMv[l][0].hor - cMv[l][1].hor;
cMv[l][2].ver = cMv[l][3].ver + cMv[l][0].ver - cMv[l][1].ver;
#if JVET_N0334_MVCLIPPING
cMv[l][2].clipToStorageBitDepth();
#endif
break;
case 2: // 2 : LT, LB, RB
cMv[l][1].hor = cMv[l][3].hor + cMv[l][0].hor - cMv[l][2].hor;
cMv[l][1].ver = cMv[l][3].ver + cMv[l][0].ver - cMv[l][2].ver;
#if JVET_N0334_MVCLIPPING
cMv[l][1].clipToStorageBitDepth();
#endif
break;
case 3: // 3 : RT, LB, RB
cMv[l][0].hor = cMv[l][1].hor + cMv[l][2].hor - cMv[l][3].hor;
cMv[l][0].ver = cMv[l][1].ver + cMv[l][2].ver - cMv[l][3].ver;
#if JVET_N0334_MVCLIPPING
cMv[l][0].clipToStorageBitDepth();
#endif
break;
case 4: // 4 : LT, RT
......@@ -3202,6 +3215,9 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
vy = (cMv[l][0].ver << shift) - ((cMv[l][2].hor - cMv[l][0].hor) << shiftHtoW);
roundAffineMv( vx, vy, shift );
cMv[l][1].set( vx, vy );
#if JVET_N0334_MVCLIPPING
cMv[l][1].clipToStorageBitDepth();
#endif
break;
default:
......@@ -3625,7 +3641,11 @@ void PU::setAllAffineMvField( PredictionUnit &pu, MvField *mvField, RefPicList e
pu.refIdx[eRefList] = mvField[0].refIdx;
}
#if JVET_N0334_MVCLIPPING
void PU::setAllAffineMv(PredictionUnit& pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList, bool setHighPrec, bool clipCPMVs)
#else
void PU::setAllAffineMv( PredictionUnit& pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList, bool setHighPrec)
#endif
{
int width = pu.Y().width;
int shift = MAX_CU_DEPTH;
......@@ -3635,6 +3655,17 @@ void PU::setAllAffineMv( PredictionUnit& pu, Mv affLT, Mv affRT, Mv affLB, RefPi
affRT.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
affLB.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
}
#if JVET_N0334_MVCLIPPING
if (clipCPMVs)
{
affLT.mvCliptoStorageBitDepth();
affRT.mvCliptoStorageBitDepth();
if (pu.cu->affineType == AFFINEMODEL_6PARAM)
{
affLB.mvCliptoStorageBitDepth();
}
}
#endif
int deltaMvHorX, deltaMvHorY, deltaMvVerX, deltaMvVerY;
deltaMvHorX = (affRT - affLT).getHor() << (shift - g_aucLog2[width]);
deltaMvHorY = (affRT - affLT).getVer() << (shift - g_aucLog2[width]);
......@@ -4039,6 +4070,9 @@ void PU::applyImv( PredictionUnit& pu, MergeCtx &mrgCtx, InterPrediction *interP
pu.mvpIdx[0] = mvp_idx;
pu.mv [0] = amvpInfo.mvCand[mvp_idx] + pu.mvd[0];
pu.mv[0].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[0].mvCliptoStorageBitDepth();
#endif
}
if (pu.interDir != 1 /* PRED_L0 */)
......@@ -4054,6 +4088,9 @@ void PU::applyImv( PredictionUnit& pu, MergeCtx &mrgCtx, InterPrediction *interP
pu.mvpIdx[1] = mvp_idx;
pu.mv [1] = amvpInfo.mvCand[mvp_idx] + pu.mvd[1];
pu.mv[1].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[1].mvCliptoStorageBitDepth();
#endif
}
}
else
......
......@@ -160,6 +160,9 @@ namespace PU
void setAllAffineMvField ( PredictionUnit &pu, MvField *mvField, RefPicList eRefList );
void setAllAffineMv ( PredictionUnit &pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList
, bool setHighPrec = false
#if JVET_N0334_MVCLIPPING
, bool clipCPMVs = false
#endif
);
bool getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx &mrgCtx, bool& LICFlag, const int count
, int mmvdList
......
......@@ -745,7 +745,11 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
mvLB.changePrecision( MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL );
}
}
#if JVET_N0334_MVCLIPPING
PU::setAllAffineMv(pu, mvLT, mvRT, mvLB, eRefList, false, true);
#else
PU::setAllAffineMv( pu, mvLT, mvRT, mvLB, eRefList );
#endif
}
}
}
......@@ -761,6 +765,9 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
mvd <<= 2;
pu.mv[REF_PIC_LIST_0] = amvpInfo.mvCand[pu.mvpIdx[REF_PIC_LIST_0]] + mvd;
pu.mv[REF_PIC_LIST_0].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[REF_PIC_LIST_0].mvCliptoStorageBitDepth();
#endif
}
else
{
......@@ -774,6 +781,9 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
pu.mvpNum [eRefList] = amvpInfo.numCand;
pu.mv[eRefList] = amvpInfo.mvCand[pu.mvpIdx[eRefList]] + pu.mvd[eRefList];
pu.mv[eRefList].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[eRefList].mvCliptoStorageBitDepth();
#endif
}
}
}
......
......@@ -3784,6 +3784,34 @@ void EncCu::xEncodeInterResidual( CodingStructure *&tempCS
}
}
}
#if JVET_N0334_MVCLIPPING
// avoid MV exceeding 18-bit dynamic range
const int maxMv = 1 << 17;
if (!cu->affine && !pu.mergeFlag)
{
if ( (pu.refIdx[0] >= 0 && (pu.mv[0].getAbsHor() >= maxMv || pu.mv[0].getAbsVer() >= maxMv))
|| (pu.refIdx[1] >= 0 && (pu.mv[1].getAbsHor() >= maxMv || pu.mv[1].getAbsVer() >= maxMv)))
{
return;
}
}
if (cu->affine && !pu.mergeFlag)
{
for (int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++)
{
if (pu.refIdx[refList] >= 0)
{
for (int ctrlP = 1 + (cu->affineType == AFFINEMODEL_6PARAM); ctrlP >= 0; ctrlP--)
{
if (pu.mvAffi[refList][ctrlP].getAbsHor() >= maxMv || pu.mvAffi[refList][ctrlP].getAbsVer() >= maxMv)
{
return;
}
}
}
}
}
#endif
const bool mtsAllowed = tempCS->sps->getUseInterMTS() && CU::isInter( *cu ) && partitioner.currArea().lwidth() <= MTS_INTER_MAX_CU_SIZE && partitioner.currArea().lheight() <= MTS_INTER_MAX_CU_SIZE;
uint8_t sbtAllowed = cu->checkAllowedSbt();
uint8_t numRDOTried = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment