From 10fb0840f0b7624fd7e6af6b0379140828d11d24 Mon Sep 17 00:00:00 2001
From: Frank Bossen <fbossen@gmail.com>
Date: Mon, 28 Jan 2019 17:14:38 -0500
Subject: [PATCH] JVET-M0512: TMVP storage reduction using floating-point
 representation

---
 source/Lib/CommonLib/CommonDef.h   |  8 ++++++
 source/Lib/CommonLib/TypeDef.h     |  1 +
 source/Lib/CommonLib/UnitTools.cpp | 46 ++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index 27d76437a5..2c2191cf71 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -403,6 +403,14 @@ static const int IBC_FAST_METHOD_NOINTRA_IBCCBF0 = 0x01;
 static const int IBC_FAST_METHOD_BUFFERBV = 0X02;
 static const int IBC_FAST_METHOD_ADAPTIVE_SEARCHRANGE = 0X04;
 
+#if JVET_M0512_MOTION_BUFFER_COMPRESSION
+static constexpr int MV_EXPONENT_BITCOUNT    = 4;
+static constexpr int MV_MANTISSA_BITCOUNT    = 6;
+static constexpr int MV_MANTISSA_UPPER_LIMIT = ((1 << (MV_MANTISSA_BITCOUNT - 1)) - 1);
+static constexpr int MV_MANTISSA_LIMIT       = (1 << (MV_MANTISSA_BITCOUNT - 1));
+static constexpr int MV_EXPONENT_MASK        = ((1 << MV_EXPONENT_BITCOUNT) - 1);
+#endif
+
 // ====================================================================================================================
 // Macro functions
 // ====================================================================================================================
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 0add5d415e..4cacde0959 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -98,6 +98,7 @@ typedef std::pair<int, int>  TrCost;
 
 // clang-format off
 #define JVET_M0453_CABAC_ENGINE                           1
+#define JVET_M0512_MOTION_BUFFER_COMPRESSION              1
 
 #define JVET_M0409_ATMVP_FIX                              1
 
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 0559434c4c..ed3f55c354 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -1501,6 +1501,44 @@ static int xGetDistScaleFactor(const int &iCurrPOC, const int &iCurrRefPOC, cons
     return iScale;
   }
 }
+
+#if JVET_M0512_MOTION_BUFFER_COMPRESSION
+int convertMvFixedToFloat(int32_t val)
+{
+  int sign  = val >> 31;
+  int scale = floorLog2((val ^ sign) | MV_MANTISSA_UPPER_LIMIT) - (MV_MANTISSA_BITCOUNT - 1);
+
+  int exponent;
+  int mantissa;
+  if (scale >= 0)
+  {
+    int round = (1 << scale) >> 1;
+    int n     = (val + round) >> scale;
+    exponent  = scale + ((n ^ sign) >> (MV_MANTISSA_BITCOUNT - 1));
+    mantissa  = (n & MV_MANTISSA_UPPER_LIMIT) | (sign << (MV_MANTISSA_BITCOUNT - 1));
+  }
+  else
+  {
+    exponent = 0;
+    mantissa = val;
+  }
+
+  return exponent | (mantissa << MV_EXPONENT_BITCOUNT);
+}
+
+int convertMvFloatToFixed(int val)
+{
+  int exponent = val & MV_EXPONENT_MASK;
+  int mantissa = val >> MV_EXPONENT_BITCOUNT;
+  return exponent == 0 ? mantissa : (mantissa ^ MV_MANTISSA_LIMIT) << (exponent - 1);
+}
+
+int roundMvComp(int x)
+{
+  return convertMvFloatToFixed(convertMvFixedToFloat(x));
+}
+#endif
+
 int PU::getDistScaleFactor(const int &currPOC, const int &currRefPOC, const int &colPOC, const int &colRefPOC)
 {
   return xGetDistScaleFactor(currPOC, currRefPOC, colPOC, colRefPOC);
@@ -1627,6 +1665,10 @@ bool PU::getColocatedMVP(const PredictionUnit &pu, const RefPicList &eRefPicList
 
   // Scale the vector.
   Mv cColMv = mi.mv[eColRefPicList];
+#if JVET_M0512_MOTION_BUFFER_COMPRESSION
+  cColMv.setHor(roundMvComp(cColMv.getHor()));
+  cColMv.setVer(roundMvComp(cColMv.getVer()));
+#endif
 
   if (bIsCurrRefLongTerm /*|| bIsColRefLongTerm*/)
   {
@@ -3277,6 +3319,10 @@ static bool deriveScaledMotionTemporal( const Slice&      slice,
     iCurrRefPOC = slice.getRefPic(eCurrRefPicList, 0)->getPOC();
     // Scale the vector.
     cColMv = mi.mv[eColRefPicList];
+#if JVET_M0512_MOTION_BUFFER_COMPRESSION
+    cColMv.setHor(roundMvComp(cColMv.getHor()));
+    cColMv.setVer(roundMvComp(cColMv.getVer()));
+#endif
     //pcMvFieldSP[2*iPartition + eCurrRefPicList].getMv();
     // Assume always short-term for now
     iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iColPOC, iColRefPOC);
-- 
GitLab