From 76b64c4fc49b3911b09844346524fc61233fc1c6 Mon Sep 17 00:00:00 2001
From: Takeshi Tsukuba <takeshi.tsukuba@sony.com>
Date: Thu, 3 Oct 2019 19:23:19 +0900
Subject: [PATCH] changes for P0272

---
 source/Lib/CommonLib/ChromaFormat.h        |  1 -
 source/Lib/CommonLib/Quant.cpp             | 31 +++++++++++++---
 source/Lib/CommonLib/QuantRDOQ.cpp         | 30 +++++++++++++---
 source/Lib/CommonLib/QuantRDOQ.h           |  4 +++
 source/Lib/CommonLib/TrQuant.cpp           | 41 ++++++++++++++++++++--
 source/Lib/CommonLib/TypeDef.h             |  2 ++
 source/Lib/CommonLib/dtrace_codingstruct.h | 19 ++++++++++
 7 files changed, 115 insertions(+), 13 deletions(-)

diff --git a/source/Lib/CommonLib/ChromaFormat.h b/source/Lib/CommonLib/ChromaFormat.h
index d6930043..d643fd8f 100644
--- a/source/Lib/CommonLib/ChromaFormat.h
+++ b/source/Lib/CommonLib/ChromaFormat.h
@@ -113,7 +113,6 @@ static inline int getTransformShift(const int channelBitDepth, const Size size,
   return maxLog2TrDynamicRange - channelBitDepth - ( ( floorLog2(size.width) + floorLog2(size.height) ) >> 1 );
 }
 
-
 //------------------------------------------------
 #if !JVET_O0650_SIGNAL_CHROMAQP_MAPPING_TABLE
 static inline int getScaledChromaQP(int unscaledChromaQP, const ChromaFormat chFmt)
diff --git a/source/Lib/CommonLib/Quant.cpp b/source/Lib/CommonLib/Quant.cpp
index a34a4faf..6a4b5ae5 100644
--- a/source/Lib/CommonLib/Quant.cpp
+++ b/source/Lib/CommonLib/Quant.cpp
@@ -467,7 +467,11 @@ void Quant::dequant(const TransformUnit &tu,
   const int QP_rem = cQP.rem;
 #endif
 
+#if SONY_SIMPLE_TS
+  const int  rightShift = (IQUANT_SHIFT - ( (isTransformSkip? 0 : iTransformShift) + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
+#else
   const int  rightShift = (IQUANT_SHIFT - (iTransformShift + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
+#endif
 
   if(enableScalingLists)
   {
@@ -531,6 +535,7 @@ void Quant::dequant(const TransformUnit &tu,
         const Intermediate_Int iCoeffQ   = (Intermediate_Int(clipQCoef) * scale + iAdd) >> rightShift;
 
         piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
+
       }
     }
     else
@@ -543,6 +548,7 @@ void Quant::dequant(const TransformUnit &tu,
         const Intermediate_Int iCoeffQ   = (Intermediate_Int(clipQCoef) * scale) << leftShift;
 
         piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
+
       }
     }
   }
@@ -1033,16 +1039,20 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
 #else
     const int defaultQuantisationCoefficient    = g_quantScales[needSqrtAdjustment?1:0][cQP.rem];
 #endif
-    int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange) + ( needSqrtAdjustment?-1:0);
+    //                    
+    int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange) + (needSqrtAdjustment ? -1 : 0);
 
     if (useTransformSkip && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag())
     {
       iTransformShift = std::max<int>(0, iTransformShift);
     }
 
-
 #if JVET_O0919_TS_MIN_QP
+#if SONY_SIMPLE_TS
+    const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + (useTransformSkip ? 0 : iTransformShift);
+#else
     const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + iTransformShift;
+#endif
 #else
     const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift;
 #endif
@@ -1072,6 +1082,7 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
       const TCoeff quantisedCoefficient = quantisedMagnitude * iSign;
 
       piQCoef.buf[uiBlockPos] = Clip3<TCoeff>( entropyCodingMinimum, entropyCodingMaximum, quantisedCoefficient );
+
     } // for n
     if( tu.cu->bdpcmMode && isLuma(compID) )
     {
@@ -1090,6 +1101,7 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
 
 bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, const QpParam &cQP)
 {
+
   const SPS &sps            = *tu.cs->sps;
   const CompArea &rect      = tu.blocks[compID];
   const uint32_t uiWidth        = rect.width;
@@ -1126,7 +1138,6 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff
   const int defaultQuantisationCoefficient    = g_quantScales[needSqrtAdjustment?1:0][cQP.rem];
 #endif
   int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange) + (needSqrtAdjustment?-1:0);
-
   if (useTransformSkip && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag())
   {
     iTransformShift = std::max<int>(0, iTransformShift);
@@ -1194,7 +1205,11 @@ void Quant::transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &co
   */
 
 #if JVET_O0919_TS_MIN_QP
+#if SONY_SIMPLE_TS
+  const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + (useTransformSkip ? 0 : iTransformShift);
+#else
   const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + iTransformShift;
+#endif
 #else
   const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift;
 #endif
@@ -1249,7 +1264,12 @@ void Quant::invTrSkipDeQuantOneSample(TransformUnit &tu, const ComponentID &comp
 
   CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list");
 
+#if SONY_SIMPLE_TS
+  const bool isTransformSkip = tu.mtsIdx == MTS_SKIP && isLuma(compID);
+  const int rightShift = (IQUANT_SHIFT - ((isTransformSkip? 0: iTransformShift) + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
+#else
   const int rightShift = (IQUANT_SHIFT - (iTransformShift + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
+#endif
 
   const TCoeff transformMinimum = -(1 << maxLog2TrDynamicRange);
   const TCoeff transformMaximum =  (1 << maxLog2TrDynamicRange) - 1;
@@ -1315,7 +1335,9 @@ void Quant::invTrSkipDeQuantOneSample(TransformUnit &tu, const ComponentID &comp
   }
 
   // Inverse transform-skip
-
+#if SONY_SIMPLE_TS
+  reconSample = Pel(dequantisedSample);
+#else
   if (iTransformShift >= 0)
   {
     const TCoeff offset = iTransformShift == 0 ? 0 : (1 << (iTransformShift - 1));
@@ -1326,6 +1348,7 @@ void Quant::invTrSkipDeQuantOneSample(TransformUnit &tu, const ComponentID &comp
     const int iTrShiftNeg = -iTransformShift;
     reconSample = Pel(dequantisedSample << iTrShiftNeg);
   }
+#endif
 }
 
 
diff --git a/source/Lib/CommonLib/QuantRDOQ.cpp b/source/Lib/CommonLib/QuantRDOQ.cpp
index 3cc44627..25c20522 100644
--- a/source/Lib/CommonLib/QuantRDOQ.cpp
+++ b/source/Lib/CommonLib/QuantRDOQ.cpp
@@ -378,8 +378,6 @@ void QuantRDOQ::setScalingList(ScalingList *scalingList, const int maxLog2TrDyna
   }
 }
 
-
-
 double QuantRDOQ::xGetErrScaleCoeff(const bool needsSqrt2, SizeType width, SizeType height, int qp, const int maxLog2TrDynamicRange, const int channelBitDepth)
 {
   const int iTransformShift = getTransformShift(channelBitDepth, Size(width, height), maxLog2TrDynamicRange);
@@ -1286,9 +1284,18 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI
   const bool   needsSqrt2Scale = TU::needsSqrt2Scale( tu, compID );  // should always be false - transform-skipped blocks don't require sqrt(2) compensation.
 #if JVET_O0919_TS_MIN_QP
   const bool   isTransformSkip = tu.mtsIdx==MTS_SKIP && isLuma(compID);
+#if SONY_SIMPLE_TS
+  const int    qBits = QUANT_SHIFT + qp.per(isTransformSkip) + (isTransformSkip ? 0 : transformShift) + (needsSqrt2Scale ? -1 : 0);  // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
+#else
   const int    qBits = QUANT_SHIFT + qp.per(isTransformSkip) + transformShift + ( needsSqrt2Scale ? -1 : 0 );  // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
+#endif
   const int    quantisationCoefficient = g_quantScales[needsSqrt2Scale?1:0][qp.rem(isTransformSkip)];
+#if SONY_SIMPLE_TS
+  const double errorScale              = xGetErrScaleCoeff(TU::needsSqrt2Scale(tu, compID), width, height, qp.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth) * pow(2, 2*transformShift);
+#else
   const double errorScale              = xGetErrScaleCoeff( TU::needsSqrt2Scale( tu, compID ), width, height, qp.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth );
+#endif
+
 #else
   const int    qBits = QUANT_SHIFT + qp.per + transformShift + (needsSqrt2Scale?-1:0);  // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
   const int    quantisationCoefficient = g_quantScales[needsSqrt2Scale?1:0][qp.rem];
@@ -1343,10 +1350,10 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI
       uint32_t upAbsLevel = std::min<uint32_t>(uint32_t(entropyCodingMaximum), downAbsLevel + 1);
 
       m_testedLevels = 0;
-      coeffLevels[m_testedLevels++] = roundAbsLevel;
+      coeffLevels[m_testedLevels++] = roundAbsLevel; // 0: round
 
       if (minAbsLevel != roundAbsLevel)
-        coeffLevels[m_testedLevels++] = minAbsLevel;
+        coeffLevels[m_testedLevels++] = minAbsLevel; //1: min
 
       int rightPixel, belowPixel, predPixel;
 
@@ -1354,7 +1361,7 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI
       predPixel = cctx.deriveModCoeff(rightPixel, belowPixel, upAbsLevel, 0);
 
       if (upAbsLevel != roundAbsLevel && upAbsLevel != minAbsLevel && predPixel == 1)
-        coeffLevels[m_testedLevels++] = upAbsLevel;
+        coeffLevels[m_testedLevels++] = upAbsLevel; // 2: up
 
       double dErr = double(levelDouble);
       coeffLevelError[0] = dErr * dErr * errorScale;
@@ -1541,9 +1548,18 @@ void QuantRDOQ::forwardRDPCM( TransformUnit &tu, const ComponentID &compID, cons
   const bool   needsSqrt2Scale = TU::needsSqrt2Scale(tu, compID);  // should always be false - transform-skipped blocks don't require sqrt(2) compensation.
 #if JVET_O0919_TS_MIN_QP
   const bool   isTransformSkip = tu.mtsIdx==MTS_SKIP && isLuma(compID);
+#if SONY_SIMPLE_TS
+  const int    qBits = QUANT_SHIFT + qp.per(isTransformSkip) + (isTransformSkip? 0 : transformShift) + (needsSqrt2Scale ? -1 : 0);  // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
+#else
   const int    qBits = QUANT_SHIFT + qp.per(isTransformSkip) + transformShift + ( needsSqrt2Scale ? -1 : 0 );  // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
+#endif
   const int    quantisationCoefficient = g_quantScales[needsSqrt2Scale ? 1 : 0][qp.rem(isTransformSkip)];
+#if SONY_SIMPLE_TS
+  const double errorScale = xGetErrScaleCoeff(TU::needsSqrt2Scale(tu, compID), width, height, qp.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth) * pow(2, 2 * transformShift);
+#else
   const double errorScale = xGetErrScaleCoeff(TU::needsSqrt2Scale(tu, compID), width, height, qp.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth);
+#endif
+
 #else
   const int    qBits = QUANT_SHIFT + qp.per + transformShift + (needsSqrt2Scale ? -1 : 0);  // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
   const int    quantisationCoefficient = g_quantScales[needsSqrt2Scale ? 1 : 0][qp.rem];
@@ -1552,7 +1568,11 @@ void QuantRDOQ::forwardRDPCM( TransformUnit &tu, const ComponentID &compID, cons
 
   TrQuantParams trQuantParams;
 #if JVET_O0919_TS_MIN_QP
+#if SONY_SIMPLE_TS
+  trQuantParams.rightShift = (IQUANT_SHIFT - ((isTransformSkip ? 0 : transformShift) + qp.per(isTransformSkip)));
+#else
   trQuantParams.rightShift = (IQUANT_SHIFT - (transformShift + qp.per(isTransformSkip)));
+#endif
   trQuantParams.qScale = g_invQuantScales[needsSqrt2Scale ? 1 : 0][qp.rem(isTransformSkip)];
 #else
   trQuantParams.rightShift = (IQUANT_SHIFT - (transformShift + qp.per));
diff --git a/source/Lib/CommonLib/QuantRDOQ.h b/source/Lib/CommonLib/QuantRDOQ.h
index 0010d40c..23083b1d 100644
--- a/source/Lib/CommonLib/QuantRDOQ.h
+++ b/source/Lib/CommonLib/QuantRDOQ.h
@@ -69,7 +69,11 @@ public:
 
 private:
   double* xGetErrScaleCoeffSL            ( uint32_t list, uint32_t sizeX, uint32_t sizeY, int qp ) { return m_errScale[sizeX][sizeY][list][qp]; };  //!< get Error Scale Coefficent
+#if SONY_SIMPLTE_TS_FIX_RDOQ
+  double  xGetErrScaleCoeff              ( const bool needsSqrt2, SizeType width, SizeType height, int qp, const int maxLog2TrDynamicRange, const int channelBitDepth, const bool isTrSkip);
+#else
   double  xGetErrScaleCoeff              ( const bool needsSqrt2, SizeType width, SizeType height, int qp, const int maxLog2TrDynamicRange, const int channelBitDepth);
+#endif
   double& xGetErrScaleCoeffNoScalingList ( uint32_t list, uint32_t sizeX, uint32_t sizeY, int qp ) { return m_errScaleNoScalingList[sizeX][sizeY][list][qp]; };  //!< get Error Scale Coefficent
   void    xInitScalingList               ( const QuantRDOQ* other );
   void    xDestroyScalingList            ();
diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp
index e498dd0f..f85e1f93 100644
--- a/source/Lib/CommonLib/TrQuant.cpp
+++ b/source/Lib/CommonLib/TrQuant.cpp
@@ -1009,11 +1009,22 @@ void TrQuant::xITransformSkip(const CCoeffBuf     &pCoeff,
   {
     iTransformShift = std::max<int>( 0, iTransformShift );
   }
-
+#if !SONY_SIMPLE_TS
   int iWHScale = 1;
-
+#endif
   const bool rotateResidual = TU::isNonTransformedResidualRotated( tu, compID );
 
+#if SONY_SIMPLE_TS
+
+  for (uint32_t y = 0; y < height; y++)
+  {
+      for (uint32_t x = 0; x < width; x++)
+      {
+          pResidual.at(x, y) = Pel((rotateResidual ? pCoeff.at(pCoeff.width - x - 1, pCoeff.height - y - 1) : pCoeff.at(x, y)));
+      }
+  }
+
+#else
   if( iTransformShift >= 0 )
   {
     const TCoeff offset = iTransformShift == 0 ? 0 : ( 1 << ( iTransformShift - 1 ) );
@@ -1038,6 +1049,7 @@ void TrQuant::xITransformSkip(const CCoeffBuf     &pCoeff,
       }
     }
   }
+#endif
 }
 
 void TrQuant::xQuant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, TCoeff &uiAbsSum, const QpParam &cQP, const Ctx& ctx)
@@ -1100,6 +1112,18 @@ void TrQuant::transformNxN( TransformUnit &tu, const ComponentID &compID, const
     {
       scaleSAD=1.0/1.414213562; // compensate for not scaling transform skip coefficients by 1/sqrt(2)
     }
+#if SONY_SIMPLE_TS
+    if (tu.mtsIdx == MTS_SKIP) {
+        int trShift = getTransformShift(tu.cu->slice->getSPS()->getBitDepth(toChannelType(compID)), rect.size(), tu.cu->slice->getSPS()->getMaxLog2TrDynamicRange(toChannelType(compID)));
+        if(trShift>=0){
+            scaleSAD *= (double)(1<<abs(trShift));
+        }
+        else{
+            scaleSAD /= (double)(1<<abs(trShift));
+        }
+    }
+#endif
+
     trCosts.push_back( TrCost( int(sumAbs*scaleSAD), pos++ ) );
     it++;
   }
@@ -1407,11 +1431,21 @@ void TrQuant::xTransformSkip(const TransformUnit &tu, const ComponentID &compID,
     iTransformShift = std::max<int>( 0, iTransformShift );
   }
 
+#if !SONY_SIMPLE_TS
   int iWHScale = 1;
-
+#endif
   const bool rotateResidual = TU::isNonTransformedResidualRotated( tu, compID );
   const uint32_t uiSizeMinus1 = ( width * height ) - 1;
 
+#if SONY_SIMPLE_TS
+  for (uint32_t y = 0, coefficientIndex = 0; y < height; y++)
+  {
+      for (uint32_t x = 0; x < width; x++, coefficientIndex++)
+      {
+          psCoeff[rotateResidual ? uiSizeMinus1 - coefficientIndex : coefficientIndex] = TCoeff(resi.at(x, y));
+      }
+  }
+#else
   if( iTransformShift >= 0 )
   {
     for( uint32_t y = 0, coefficientIndex = 0; y < height; y++ )
@@ -1435,6 +1469,7 @@ void TrQuant::xTransformSkip(const TransformUnit &tu, const ComponentID &compID,
       }
     }
   }
+#endif
 }
 
 //! \}
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 88063fe2..7b592fbe 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define SONY_SIMPLE_TS                                    1
+
 #define JVET_O1164_RPR                                    1  // JVET-O1164: Reference picture resampling
 #if JVET_O1164_RPR
 #define JVET_O1164_PS                                     1
diff --git a/source/Lib/CommonLib/dtrace_codingstruct.h b/source/Lib/CommonLib/dtrace_codingstruct.h
index eafc916e..306d4bc6 100644
--- a/source/Lib/CommonLib/dtrace_codingstruct.h
+++ b/source/Lib/CommonLib/dtrace_codingstruct.h
@@ -97,6 +97,24 @@ inline void dtraceModeCost(CodingStructure &cs, double lambda)
     intraModeC = 68;
   int imvVal = 0;
   imvVal = cs.cus[0]->imv;
+#if SONY_DBG_FIX_MODE_COST
+  DTRACE(g_trace_ctx, D_MODE_COST, "ModeCost: %6lld %3d @(%4d,%4d) [%2dx%2d] %d (qp%d,pm%d,skip%d,mrg%d,fruc%d,obmc%d,ic%d,imv%d,affn%d,intraModeL%d,intraModeC%d, mtsIdx%d) tempCS = %lld (%d,%d)\n",
+      DTRACE_GET_COUNTER(g_trace_ctx, D_MODE_COST),
+      cs.slice->getPOC(),
+      cs.area.Y().x, cs.area.Y().y,
+      cs.area.Y().width, cs.area.Y().height,
+      cs.cus[0]->qtDepth,
+      cs.cus[0]->qp,
+      cs.cus[0]->predMode,
+      cs.cus[0]->skip,
+      cs.pus[0]->mergeFlag,
+      0, 0,
+      imvVal,
+      0, 0,
+      intraModeL, intraModeC,
+      cs.tus[0]->mtsIdx,
+      tempCost, tempBits, tempDist);
+#else
   DTRACE( g_trace_ctx, D_MODE_COST, "ModeCost: %6lld %3d @(%4d,%4d) [%2dx%2d] %d (qp%d,pm%d,skip%d,mrg%d,fruc%d,obmc%d,ic%d,imv%d,affn%d,%d,%d) tempCS = %lld (%d,%d)\n",
     DTRACE_GET_COUNTER( g_trace_ctx, D_MODE_COST ),
     cs.slice->getPOC(),
@@ -112,6 +130,7 @@ inline void dtraceModeCost(CodingStructure &cs, double lambda)
     0, 0,
           intraModeL, intraModeC,
           tempCost, tempBits, tempDist );
+#endif
 }
 
 inline void dtraceBestMode(CodingStructure *&tempCS, CodingStructure *&bestCS, double lambda)
-- 
2.17.0.windows.1

