From fe257605d0d53135f5944f84b7ccf8ec802ecb39 Mon Sep 17 00:00:00 2001
From: Laroche Guillaume <guillaume.laroche@crf.canon.fr>
Date: Fri, 19 Oct 2018 10:21:45 +0200
Subject: [PATCH] JVET-L0191: Cross-component linear model simplification

---
 source/Lib/CommonLib/IntraPrediction.cpp | 134 ++++++++++++++++++++++-
 source/Lib/CommonLib/Rom.cpp             |  67 +++++++++++-
 source/Lib/CommonLib/Rom.h               |   4 +
 source/Lib/CommonLib/TypeDef.h           |   2 +
 4 files changed, 205 insertions(+), 2 deletions(-)

diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp
index 76f6f43d3..66a724286 100644
--- a/source/Lib/CommonLib/IntraPrediction.cpp
+++ b/source/Lib/CommonLib/IntraPrediction.cpp
@@ -1257,7 +1257,139 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom
     pRecSrc0 += iRecStride2;
   }
 }
+#if JVET_L0191_LM_WO_LMS
+void IntraPrediction::xGetLMParameters(const PredictionUnit &pu, const ComponentID compID,
+                                              const CompArea &chromaArea,
+                                              int &a, int &b, int &iShift)
+{
+  CHECK(compID == COMPONENT_Y, "");
+
+  const SizeType cWidth  = chromaArea.width;
+  const SizeType cHeight = chromaArea.height;
+
+  const Position posLT = chromaArea;
+
+  CodingStructure & cs = *(pu.cs);
+  const CodingUnit &cu = *(pu.cu);
+
+  const SPS &        sps           = *cs.sps;
+  const uint32_t     tuWidth     = chromaArea.width;
+  const uint32_t     tuHeight    = chromaArea.height;
+  const ChromaFormat nChromaFormat = sps.getChromaFormatIdc();
+
+  const int baseUnitSize = 1 << MIN_CU_LOG2;
+  const int unitWidth    = baseUnitSize >> getComponentScaleX(chromaArea.compID, nChromaFormat);
+  const int unitHeight   = baseUnitSize >> getComponentScaleX(chromaArea.compID, nChromaFormat);
+
+  const int tuWidthInUnits  = tuWidth / unitWidth;
+  const int tuHeightInUnits = tuHeight / unitHeight;
+  const int aboveUnits      = tuWidthInUnits;
+  const int leftUnits       = tuHeightInUnits;
+
+  bool neighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + 1];
+
+  memset(neighborFlags, 0, 1 + leftUnits + aboveUnits);
+
+  bool aboveAvailable, leftAvailable;
+
+  int availableUnit =
+    isAboveAvailable(cu, CHANNEL_TYPE_CHROMA, posLT, aboveUnits, unitWidth, (neighborFlags + leftUnits + 1));
+  aboveAvailable = availableUnit == tuWidthInUnits;
+
+  availableUnit =
+    isLeftAvailable(cu, CHANNEL_TYPE_CHROMA, posLT, leftUnits, unitHeight, (neighborFlags + leftUnits - 1));
+  leftAvailable = availableUnit == tuHeightInUnits;
+
+  Pel *srcColor0, *curChroma0;
+  int  srcStride, curStride;
+
+  PelBuf temp;
+  srcStride = MAX_CU_SIZE + 1;
+  temp        = PelBuf(m_piTemp + srcStride + 1, srcStride, Size(chromaArea));
+  srcColor0 = temp.bufAt(0, 0);
+  curChroma0 = getPredictorPtr(compID);
+
+  curStride = m_topRefLength + 1;
+
+  curChroma0 += curStride + 1;
+
+  unsigned internalBitDepth = sps.getBitDepth(CHANNEL_TYPE_CHROMA);
+
+  int minLuma[2] = { MAX_INT, 0 };
+  int maxLuma[2] = { -MAX_INT, 0 };
+
+  Pel *src = srcColor0 - srcStride;
+  Pel *cur = curChroma0 - curStride;
+
+  int minDim = leftAvailable && aboveAvailable ? 1 << g_aucPrevLog2[std::min(cHeight, cWidth)]
+                                                   : 1 << g_aucPrevLog2[leftAvailable ? cHeight : cWidth];
+  int numSteps = minDim;
+
+  if (aboveAvailable)
+  {
+    for (int j = 0; j < numSteps; j++)
+    {
+      int idx = (j * cWidth) / minDim;
+
+      if (minLuma[0] > src[idx])
+      {
+        minLuma[0] = src[idx];
+        minLuma[1] = cur[idx];
+      }
+      if (maxLuma[0] < src[idx])
+      {
+        maxLuma[0] = src[idx];
+        maxLuma[1] = cur[idx];
+      }
+    }
+  }
+
+  if (leftAvailable)
+  {
+    src = srcColor0 - 1;
+    cur = curChroma0 - 1;
+
+    for (int i = 0; i < numSteps; i++)
+    {
+      int idx = (i * cHeight) / minDim;
 
+      if (minLuma[0] > src[srcStride * idx])
+      {
+        minLuma[0] = src[srcStride * idx];
+        minLuma[1] = cur[curStride * idx];
+      }
+      if (maxLuma[0] < src[srcStride * idx])
+      {
+        maxLuma[0] = src[srcStride * idx];
+        maxLuma[1] = cur[curStride * idx];
+      }
+    }
+  }
+
+  if ((leftAvailable || aboveAvailable))
+  {
+    a         = 0;
+    iShift    = 16;
+    int shift = (internalBitDepth > 8) ? internalBitDepth - 9 : 0;
+    int add   = shift ? 1 << (shift - 1) : 0;
+    int diff  = (maxLuma[0] - minLuma[0] + add) >> shift;
+    if (diff > 0)
+    {
+      int div = ((maxLuma[1] - minLuma[1]) * g_aiLMDivTableLow[diff - 1] + 32768) >> 16;
+      a       = (((maxLuma[1] - minLuma[1]) * g_aiLMDivTableHigh[diff - 1] + div + add) >> shift);
+    }
+    b = minLuma[1] - ((a * minLuma[0]) >> iShift);
+  }
+  else
+  {
+    a = 0;
+
+    b = 1 << (internalBitDepth - 1);
+
+    iShift = 0;
+  }
+}
+#else
 static int GetFloorLog2( unsigned x )
 {
   int bits = -1;
@@ -1466,6 +1598,6 @@ void IntraPrediction::xGetLMParameters(const PredictionUnit &pu, const Component
     b = avgY - ( ( a * avgX ) >> iShift );
   }
 }
-
+#endif
 
 //! \}
diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp
index e2f8ccaca..f54d507c0 100644
--- a/source/Lib/CommonLib/Rom.cpp
+++ b/source/Lib/CommonLib/Rom.cpp
@@ -180,7 +180,72 @@ public:
     return rtn;
   }
 };
-
+#if JVET_L0191_LM_WO_LMS
+int g_aiLMDivTableLow[] = {
+  0,     0,     21845, 0,     13107, 43690, 18724, 0,     50972, 39321, 53620, 21845, 15123, 9362,  4369,  0,     3855,
+  58254, 17246, 52428, 49932, 59578, 25644, 43690, 28835, 40329, 16990, 37449, 56496, 34952, 4228,  0,     61564, 34695,
+  29959, 29127, 15941, 41391, 26886, 26214, 28771, 24966, 6096,  29789, 23301, 45590, 25098, 21845, 30761, 47185, 1285,
+  20164, 34622, 41263, 36938, 18724, 49439, 61016, 51095, 17476, 23635, 2114,  16644, 0,     16131, 63550, 9781,  50115,
+  52238, 14979, 2769,  14563, 49376, 40738, 53302, 20695, 7660,  13443, 37330, 13107, 5663,  14385, 38689, 12483, 771,
+  3048,  18832, 47662, 23563, 11650, 11522, 22795, 45100, 12549, 55878, 43690, 41213, 48148, 64212, 23592, 57100, 33410,
+  17815, 10082, 9986,  17311, 31849, 53399, 16233, 51237, 27159, 9362,  63216, 57487, 57557, 63276, 8962,  25547, 47362,
+  8738,  40621, 11817, 53281, 33825, 18874, 8322,  2064,  0,     2032,  8065,  18009, 31775, 49275, 4890,  29612, 57825,
+  23918, 58887, 31589, 7489,  52056, 34152, 19248, 7281,  63728, 57456, 53944, 53137, 54979, 59419, 868,   10347, 22273,
+  36598, 53274, 6721,  27967, 51433, 11540, 39321, 3663,  35599, 4020,  39960, 12312, 52112, 28255, 6241,  51575, 33153,
+  16479, 1524,  53792, 42184, 32206, 23831, 17031, 11781, 8054,  5825,  5069,  5761,  7878,  11397, 16295, 22550, 30139,
+  39042, 49238, 60707, 7891,  21845, 37012, 53374, 5377,  24074, 43912, 64874, 21406, 44564, 3260,  28550, 54882, 16705,
+  45075, 8907,  39258, 5041,  37314, 4993,  39135, 8655,  44613, 15924, 53648, 26699, 604,   40884, 16458, 58386, 35585,
+  13579, 57895, 37449, 17767, 64376, 46192, 28743, 12019, 61546, 46244, 31638, 17720, 4481,  57448, 45541, 34288, 23681,
+  13710, 4369,  61185, 53078, 45578, 38676, 32366, 26640, 21491, 16912, 12896, 9437,  6527,  4161,  2331,  1032,  257,
+  0,     255,   1016,  2277,  4032,  6277,  9004,  12210, 15887, 20031, 24637, 29699, 35213, 41173, 47574, 54411, 61680,
+  3840,  11959, 20494, 29443, 38801, 48562, 58724, 3744,  14693, 26028, 37746, 49844, 62316, 9624,  22834, 36408, 50342,
+  64632, 13737, 28728, 44063, 59740, 10219, 26568, 43249, 60257, 12055, 29709, 47682, 434,   19033, 37941, 57155, 11136,
+  30953, 51067, 5938,  26637, 47624, 3360,  24916, 46751, 3328,  25716, 48376, 5770,  28967, 52428, 10616, 34599, 58840,
+  17799, 42547, 2010,  27256, 52748, 12947, 38924, 65140, 26056, 52743, 14127, 41277, 3120,  30726, 58555, 21072, 49344,
+  12300, 41007, 4394,  33530, 62876, 26896, 56659, 21092, 51264, 16103, 46678, 11915, 42886, 8515,  39875, 5890,  37632,
+  4027,  36145, 2912,  35400, 2534,  35385, 2880,  36089, 3939,  37500, 5698,  39605, 8147,  42395, 11275, 45857, 15069,
+  49982, 19521, 54758, 24619, 60175, 30353, 688,   36713, 7357,  43690, 14639, 51274, 22522, 59455, 30999, 2688,  40059,
+  12037, 49693, 21956, 59894, 32437, 5117,  43471, 16425, 55050, 28273, 1630,  40655, 14275, 53561, 27441, 1449,  41120,
+  15382, 55305, 29818, 4453,  44748, 19629, 60166, 35288, 10529, 51425, 26902, 2496,  43742, 19567, 61042, 37095, 13261,
+  55074, 31463, 7962,  50106, 26824, 3649,  46117, 23157, 302,   43088, 20442, 63436, 40997, 18660, 61961, 39826, 17792,
+  61393, 39557, 17819, 61715, 40171, 18724, 62908, 41651, 20489, 64956, 43980, 23096, 2304,  47139, 26529, 6009,  51115,
+  30773, 10519, 55890, 35811, 15819, 61448, 41628, 21892, 2240,  48208, 28724, 9322,  55538, 36301, 17144, 63604, 44608,
+  25692, 6855,  53632, 34952, 16349, 63360, 44911, 26539, 8242,  55557, 37410, 19338, 1340,  48951, 31099, 13320, 61149,
+  43513, 25949, 8456,  56569, 39216, 21932, 4718,  53109, 36031, 19022, 2080,  50741, 33933, 17191, 516,   49441, 32896,
+  16416, 0,
+};
+int g_aiLMDivTableHigh[] = {
+  65536, 32768, 21845, 16384, 13107, 10922, 9362, 8192, 7281, 6553, 5957, 5461, 5041, 4681, 4369, 4096, 3855, 3640,
+  3449,  3276,  3120,  2978,  2849,  2730,  2621, 2520, 2427, 2340, 2259, 2184, 2114, 2048, 1985, 1927, 1872, 1820,
+  1771,  1724,  1680,  1638,  1598,  1560,  1524, 1489, 1456, 1424, 1394, 1365, 1337, 1310, 1285, 1260, 1236, 1213,
+  1191,  1170,  1149,  1129,  1110,  1092,  1074, 1057, 1040, 1024, 1008, 992,  978,  963,  949,  936,  923,  910,
+  897,   885,   873,   862,   851,   840,   829,  819,  809,  799,  789,  780,  771,  762,  753,  744,  736,  728,
+  720,   712,   704,   697,   689,   682,   675,  668,  661,  655,  648,  642,  636,  630,  624,  618,  612,  606,
+  601,   595,   590,   585,   579,   574,   569,  564,  560,  555,  550,  546,  541,  537,  532,  528,  524,  520,
+  516,   512,   508,   504,   500,   496,   492,  489,  485,  481,  478,  474,  471,  468,  464,  461,  458,  455,
+  451,   448,   445,   442,   439,   436,   434,  431,  428,  425,  422,  420,  417,  414,  412,  409,  407,  404,
+  402,   399,   397,   394,   392,   390,   387,  385,  383,  381,  378,  376,  374,  372,  370,  368,  366,  364,
+  362,   360,   358,   356,   354,   352,   350,  348,  346,  344,  343,  341,  339,  337,  336,  334,  332,  330,
+  329,   327,   326,   324,   322,   321,   319,  318,  316,  315,  313,  312,  310,  309,  307,  306,  304,  303,
+  302,   300,   299,   297,   296,   295,   293,  292,  291,  289,  288,  287,  286,  284,  283,  282,  281,  280,
+  278,   277,   276,   275,   274,   273,   271,  270,  269,  268,  267,  266,  265,  264,  263,  262,  261,  260,
+  259,   258,   257,   256,   255,   254,   253,  252,  251,  250,  249,  248,  247,  246,  245,  244,  243,  242,
+  241,   240,   240,   239,   238,   237,   236,  235,  234,  234,  233,  232,  231,  230,  229,  229,  228,  227,
+  226,   225,   225,   224,   223,   222,   222,  221,  220,  219,  219,  218,  217,  217,  216,  215,  214,  214,
+  213,   212,   212,   211,   210,   210,   209,  208,  208,  207,  206,  206,  205,  204,  204,  203,  202,  202,
+  201,   201,   200,   199,   199,   198,   197,  197,  196,  196,  195,  195,  194,  193,  193,  192,  192,  191,
+  191,   190,   189,   189,   188,   188,   187,  187,  186,  186,  185,  185,  184,  184,  183,  183,  182,  182,
+  181,   181,   180,   180,   179,   179,   178,  178,  177,  177,  176,  176,  175,  175,  174,  174,  173,  173,
+  172,   172,   172,   171,   171,   170,   170,  169,  169,  168,  168,  168,  167,  167,  166,  166,  165,  165,
+  165,   164,   164,   163,   163,   163,   162,  162,  161,  161,  161,  160,  160,  159,  159,  159,  158,  158,
+  157,   157,   157,   156,   156,   156,   155,  155,  154,  154,  154,  153,  153,  153,  152,  152,  152,  151,
+  151,   151,   150,   150,   149,   149,   149,  148,  148,  148,  147,  147,  147,  146,  146,  146,  145,  145,
+  145,   144,   144,   144,   144,   143,   143,  143,  142,  142,  142,  141,  141,  141,  140,  140,  140,  140,
+  139,   139,   139,   138,   138,   138,   137,  137,  137,  137,  136,  136,  136,  135,  135,  135,  135,  134,
+  134,   134,   134,   133,   133,   133,   132,  132,  132,  132,  131,  131,  131,  131,  130,  130,  130,  130,
+  129,   129,   129,   129,   128,   128,   128,  128,
+};
+#endif
 const int g_aiNonLMPosThrs[] = {  3,  1,  0 };
 
 
diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h
index e8c0c5acb..987ce1633 100644
--- a/source/Lib/CommonLib/Rom.h
+++ b/source/Lib/CommonLib/Rom.h
@@ -209,6 +209,10 @@ extern const uint32_t g_scalingListSizeX[SCALING_LIST_SIZE_NUM];
 
 extern MsgLevel g_verbosity;
 
+#if JVET_L0191_LM_WO_LMS
+extern int g_aiLMDivTableLow[];
+extern int g_aiLMDivTableHigh[];
+#endif
 
 extern const int g_aiNonLMPosThrs[];
 
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 167b00da9..dbf6cabfb 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define JVET_L0191_LM_WO_LMS                              1 // NO LMS regression. min/max are used instead
+
 #define JVET_L0392_ALF_INIT_STATE                         1
 
 #define JVET_L0664_ALF_REMOVE_LUMA_5x5                    1
-- 
GitLab