From 08b39fc294c25161329799a95cd4bf84bac66777 Mon Sep 17 00:00:00 2001
From: Philippe Hanhart <Philippe.Hanhart@InterDigital.com>
Date: Mon, 28 Jan 2019 11:56:55 -0800
Subject: [PATCH] JVET-M0145 Missing clipping for MV storage in affine

---
 source/Lib/CommonLib/InterPrediction.cpp |  6 ++++++
 source/Lib/CommonLib/Mv.h                |  8 ++++++++
 source/Lib/CommonLib/TypeDef.h           |  2 ++
 source/Lib/CommonLib/UnitTools.cpp       | 17 +++++++++++++++++
 source/Lib/EncoderLib/InterSearch.cpp    |  9 +++++++++
 5 files changed, 42 insertions(+)

diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index 205d74394..629426aa7 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -724,6 +724,12 @@ void InterPrediction::xPredAffineBlk( const ComponentID& compID, const Predictio
         iMvScaleTmpHor = iMvScaleHor + iDMvHorX * (iHalfBW + w) + iDMvVerX * (iHalfBH + h);
         iMvScaleTmpVer = iMvScaleVer + iDMvHorY * (iHalfBW + w) + iDMvVerY * (iHalfBH + h);
         roundAffineMv(iMvScaleTmpHor, iMvScaleTmpVer, shift);
+#if JVET_M0145_AFFINE_MV_CLIP
+        Mv tmpMv(iMvScaleTmpHor, iMvScaleTmpVer);
+        tmpMv.clipToStorageBitDepth();
+        iMvScaleTmpHor = tmpMv.getHor();
+        iMvScaleTmpVer = tmpMv.getVer();
+#endif
 
         // clip and scale
         if (sps.getWrapAroundEnabledFlag())
diff --git a/source/Lib/CommonLib/Mv.h b/source/Lib/CommonLib/Mv.h
index 56287bec0..15326e1fd 100644
--- a/source/Lib/CommonLib/Mv.h
+++ b/source/Lib/CommonLib/Mv.h
@@ -213,6 +213,14 @@ public:
     return Mv(tarMvPred.hor - hor + curMvPred.hor, tarMvPred.ver - ver + curMvPred.ver);
   }
 #endif
+
+#if JVET_M0145_AFFINE_MV_CLIP
+  void clipToStorageBitDepth()
+  {
+    hor = Clip3( -(1 << 17), (1 << 17) - 1, hor );
+    ver = Clip3( -(1 << 17), (1 << 17) - 1, ver );
+  }
+#endif
 };// END CLASS DEFINITION MV
 
 namespace std
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index da702eae6..0add5d415 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define JVET_M0145_AFFINE_MV_CLIP                         1 // Missing clipping for MV storage in affine
+
 #define JVET_M0381_ONE_CTX_FOR_SUBBLOCK_MRG_IDX           1 // CE2.2.2 a: one context for subblock Merge index
 
 #define JVET_M0118_M0185_TRIANGLE_FLAG_FIX                1 // Avoid signaling triangle flag if a CU uses MMVD or CIIP
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 5bb6c0362..0559434c4 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -2095,6 +2095,9 @@ void PU::xInheritedAffineMv( const PredictionUnit &pu, const PredictionUnit* puN
   roundAffineMv( horTmp, verTmp, shift );
   rcMv[0].hor = horTmp;
   rcMv[0].ver = verTmp;
+#if JVET_M0145_AFFINE_MV_CLIP
+  rcMv[0].clipToStorageBitDepth();
+#endif
 
   // v1
   horTmp = iMvScaleHor + iDMvHorX * (posCurX + curW - posNeiX) + iDMvVerX * (posCurY - posNeiY);
@@ -2102,6 +2105,9 @@ void PU::xInheritedAffineMv( const PredictionUnit &pu, const PredictionUnit* puN
   roundAffineMv( horTmp, verTmp, shift );
   rcMv[1].hor = horTmp;
   rcMv[1].ver = verTmp;
+#if JVET_M0145_AFFINE_MV_CLIP
+  rcMv[1].clipToStorageBitDepth();
+#endif
 
   // v2
   if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
@@ -2111,6 +2117,9 @@ void PU::xInheritedAffineMv( const PredictionUnit &pu, const PredictionUnit* puN
     roundAffineMv( horTmp, verTmp, shift );
     rcMv[2].hor = horTmp;
     rcMv[2].ver = verTmp;
+#if JVET_M0145_AFFINE_MV_CLIP
+    rcMv[2].clipToStorageBitDepth();
+#endif
   }
 }
 
@@ -3182,13 +3191,21 @@ void PU::setAllAffineMv( PredictionUnit& pu, Mv affLT, Mv affRT, Mv affLB, RefPi
       mvScaleTmpHor = mvScaleHor + deltaMvHorX * (halfBW + w) + deltaMvVerX * (halfBH + h);
       mvScaleTmpVer = mvScaleVer + deltaMvHorY * (halfBW + w) + deltaMvVerY * (halfBH + h);
       roundAffineMv( mvScaleTmpHor, mvScaleTmpVer, shift );
+#if JVET_M0145_AFFINE_MV_CLIP
+      Mv curMv(mvScaleTmpHor, mvScaleTmpVer);
+      curMv.clipToStorageBitDepth();
+#endif
 
       for ( int y = (h >> MIN_CU_LOG2); y < ((h + blockHeight) >> MIN_CU_LOG2); y++ )
       {
         for ( int x = (w >> MIN_CU_LOG2); x < ((w + blockWidth) >> MIN_CU_LOG2); x++ )
         {
+#if JVET_M0145_AFFINE_MV_CLIP
+          mb.at(x, y).mv[eRefList] = curMv;
+#else
           mb.at(x, y).mv[eRefList].hor = mvScaleTmpHor;
           mb.at(x, y).mv[eRefList].ver = mvScaleTmpVer;
+#endif
         }
       }
     }
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index cad55ecf9..81ac4b337 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -3572,6 +3572,9 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
           vy = mvScaleVer + dMvHorY * (pu.Y().x - mvInfo->x) + dMvVerY * (pu.Y().y - mvInfo->y);
           roundAffineMv(vx, vy, shift);
           mvTmp[0] = Mv(vx, vy);
+#if JVET_M0145_AFFINE_MV_CLIP
+          mvTmp[0].clipToStorageBitDepth();
+#endif
           clipMv(mvTmp[0], pu.cu->lumaPos(),
                  pu.cu->lumaSize(),
                  *pu.cs->sps);
@@ -3580,6 +3583,9 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
           vy = mvScaleVer + dMvHorY * (pu.Y().x + pu.Y().width - mvInfo->x) + dMvVerY * (pu.Y().y - mvInfo->y);
           roundAffineMv(vx, vy, shift);
           mvTmp[1] = Mv(vx, vy);
+#if JVET_M0145_AFFINE_MV_CLIP
+          mvTmp[1].clipToStorageBitDepth();
+#endif
           clipMv(mvTmp[1], pu.cu->lumaPos(),
                  pu.cu->lumaSize(),
                  *pu.cs->sps);
@@ -3611,6 +3617,9 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         vy2 >>= shift;
         mvFour[2].hor = vx2;
         mvFour[2].ver = vy2;
+#if JVET_M0145_AFFINE_MV_CLIP
+        mvFour[2].clipToStorageBitDepth();
+#endif
         mvFour[2].roundToPrecision(MV_PRECISION_INTERNAL, MV_PRECISION_QUARTER);
         for (int i = 0; i < 3; i++)
         {
-- 
GitLab