diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index cc2258ac1985888d3af916c9b51064e324fd8be4..36dd1f45f6e57e451bd2341e0eb4e08a7ec53c80 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -326,7 +326,6 @@ static const int MAX_GR_ORDER_RESIDUAL = 10; static const int AFFINE_MIN_BLOCK_SIZE = 4; ///< Minimum affine MC block size - static const int MMVD_REFINE_STEP = 8; ///< max number of distance step static const int MMVD_MAX_REFINE_NUM = (MMVD_REFINE_STEP * 4); ///< max number of candidate from a base candidate static const int MMVD_BASE_MV_NUM = 2; ///< max number of base candidate @@ -454,6 +453,11 @@ static constexpr int MV_BITS = 18; static constexpr int MV_MAX = (1 << (MV_BITS - 1)) - 1; static constexpr int MV_MIN = -(1 << (MV_BITS - 1)); +#if JVET_O0567_MVDRange_Constraint +static const int MVD_MAX = (1 << 17) - 1; +static const int MVD_MIN = -(1 << 17); +#endif + static const int PIC_ANALYZE_CW_BINS = 32; static const int PIC_CODE_CW_BINS = 16; #if JVET_O0272_LMCS_SIMP_INVERSE_MAPPING diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index a0dd80f7442eb090d6950fa775aa730a191d36a1..5cbc8d6a413b0a7bc4b86707191964ba206a6d1c 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -155,6 +155,7 @@ #define JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG 1 // JVET-O1140 slice level disable flag for BDOF and DMVR +#define JVET_O0567_MVDRange_Constraint 1 // JVET-O0567: constrain the signalled MVD value to the range of [-2^17, 2^17-1] #define JVET_O0596_CBF_SIG_ALIGN_TO_SPEC 1 // JVET-O0596 align cbf signaling with specification #define JVET_O0193_REMOVE_TR_DEPTH_IN_CBF_CTX 1 // JVET-O0193/JVET-O0375: remove transform depth in cbf context modeling diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index bbaa74461ca11d1987c3e834c45b5d02949224cb..1f0f7ce6360dddf9590d5b41b0e2864f56ce43df 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -1642,6 +1642,9 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx ) { RefPicList eCurRefList = (RefPicList)(pu.cu->smvdMode - 1); pu.mvd[1 - eCurRefList].set( -pu.mvd[eCurRefList].hor, -pu.mvd[eCurRefList].ver ); +#if JVET_O0567_MVDRange_Constraint + CHECK(!((pu.mvd[1 - eCurRefList].getHor() >= MVD_MIN) && (pu.mvd[1 - eCurRefList].getHor() <= MVD_MAX)) || !((pu.mvd[1 - eCurRefList].getVer() >= MVD_MIN) && (pu.mvd[1 - eCurRefList].getVer() <= MVD_MAX)), "Illegal MVD value"); +#endif pu.refIdx[1 - eCurRefList] = pu.cs->slice->getSymRefIdx( 1 - eCurRefList ); } @@ -2390,6 +2393,9 @@ void CABACReader::mvd_coding( Mv &rMvd ) } } rMvd = Mv(horAbs, verAbs); +#if JVET_O0567_MVDRange_Constraint + CHECK(!((horAbs >= MVD_MIN) && (horAbs <= MVD_MAX)) || !((verAbs >= MVD_MIN) && (verAbs <= MVD_MAX)), "Illegal MVD value"); +#endif } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 482d694b75ec11fc62d8a80afaa889ed232917b2..920639e84e3cdeca4df4199424c3236e0fcab6c0 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -3901,6 +3901,36 @@ void EncCu::xEncodeInterResidual( CodingStructure *&tempCS bool swapped = false; // avoid unwanted data copy bool reloadCU = false; +#if JVET_O0567_MVDRange_Constraint + const PredictionUnit& pu = *cu->firstPU; + const int affineShiftTab[3] = { MV_PRECISION_INTERNAL - MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL - MV_PRECISION_SIXTEENTH, MV_PRECISION_INTERNAL - MV_PRECISION_INT }; + const int normalShiftTab[3] = { MV_PRECISION_INTERNAL - MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL - MV_PRECISION_INT, MV_PRECISION_INTERNAL - MV_PRECISION_4PEL }; + int mvShift; + + for (int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++) + { + if (pu.refIdx[refList] >= 0) + { + if (!cu->affine) + { + mvShift = normalShiftTab[cu->imv]; + Mv signaledmvd(pu.mvd[refList].getHor() >> mvShift, pu.mvd[refList].getVer() >> mvShift); + if (!((signaledmvd.getHor() >= MVD_MIN) && (signaledmvd.getHor() <= MVD_MAX)) || !((signaledmvd.getVer() >= MVD_MIN) && (signaledmvd.getVer() <= MVD_MAX))) + return; + } + else + { + for (int ctrlP = 1 + (cu->affineType == AFFINEMODEL_6PARAM); ctrlP >= 0; ctrlP--) + { + mvShift = affineShiftTab[cu->imv]; + Mv signaledmvd(pu.mvdAffi[refList][ctrlP].getHor() >> mvShift, pu.mvdAffi[refList][ctrlP].getVer() >> mvShift); + if (!((signaledmvd.getHor() >= MVD_MIN) && (signaledmvd.getHor() <= MVD_MAX)) || !((signaledmvd.getVer() >= MVD_MIN) && (signaledmvd.getVer() <= MVD_MAX))) + return; + } + } + } + } +#else // Not allow very big |MVd| to avoid CABAC crash caused by too large MVd. Normally no impact on coding performance. const int maxMvd = 1 << 15; const PredictionUnit& pu = *cu->firstPU; @@ -3928,6 +3958,7 @@ void EncCu::xEncodeInterResidual( CodingStructure *&tempCS } } } +#endif // avoid MV exceeding 18-bit dynamic range const int maxMv = 1 << 17; if (!cu->affine && !pu.mergeFlag)