diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index bd9f28465e6dae6314c570b5422f2f9da85e11d1..9e314bba2e0919e16993448fe43ef43543718739 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -197,8 +197,10 @@ static const int MLS_GRP_NUM =                                   1024; ///< Max
 
 static const int MLS_CG_SIZE =                                      4; ///< Coefficient group size of 4x4; = MLS_CG_LOG2_WIDTH + MLS_CG_LOG2_HEIGHT
 
+#if !JVET_N0246_MODIFIED_QUANTSCALES
 static const int ADJ_QUANT_SHIFT =                                  7;
 static const int ADJ_DEQUANT_SHIFT =            ( ADJ_QUANT_SHIFT + 1 );
+#endif
 
 static const int RVM_VCEGAM10_M =                                   4;
 
diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp
index 5331f35170ed9aee33fca88227beff634b9d0909..2ef44c47c65832dfb5b562dc6090aa2d094eaa72 100644
--- a/source/Lib/CommonLib/DepQuant.cpp
+++ b/source/Lib/CommonLib/DepQuant.cpp
@@ -757,11 +757,19 @@ namespace DQIntern
     const int         maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange( chType );
     const int         nomTransformShift     = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange );
     const bool        clipTransformShift    = ( tu.mtsIdx==1 && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() );
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    const bool    needsSqrt2ScaleAdjustment = TU::needsSqrt2Scale(tu, compID);
+    const int         transformShift        = ( clipTransformShift ? std::max<int>( 0, nomTransformShift ) : nomTransformShift ) + (needsSqrt2ScaleAdjustment?-1:0);
+#else
     const int         transformShift        = ( clipTransformShift ? std::max<int>( 0, nomTransformShift ) : nomTransformShift );
-
+#endif
     // quant parameters
     m_QShift                    = QUANT_SHIFT  - 1 + qpPer + transformShift;
     m_QAdd                      = -( ( 3 << m_QShift ) >> 1 );
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    Intermediate_Int  invShift  = IQUANT_SHIFT + 1 - qpPer - transformShift;
+    m_QScale                    = g_quantScales[needsSqrt2ScaleAdjustment?1:0][ qpRem ];
+#else // JVET_N0246_MODIFIED_QUANTSCALES
 #if HM_QTBT_AS_IN_JEM_QUANT
     Intermediate_Int  invShift  = IQUANT_SHIFT + 1 - qpPer - transformShift + ( TU::needsBlockSizeTrafoScale( tu, compID ) ? ADJ_DEQUANT_SHIFT : 0 );
     m_QScale                    = ( TU::needsSqrt2Scale( tu, compID ) ? ( g_quantScales[ qpRem ] * 181 ) >> 7 : g_quantScales[ qpRem ] );
@@ -769,12 +777,18 @@ namespace DQIntern
     Intermediate_Int  invShift  = IQUANT_SHIFT + 1 - qpPer - transformShift;
     m_QScale                    = g_quantScales   [ qpRem ];
 #endif
+#endif // JVET_N0246_MODIFIED_QUANTSCALES
     const unsigned    qIdxBD    = std::min<unsigned>( maxLog2TrDynamicRange + 1, 8*sizeof(Intermediate_Int) + invShift - IQUANT_SHIFT - 1 );
     m_maxQIdx                   = ( 1 << (qIdxBD-1) ) - 4;
     m_thresLast                 = TCoeff( ( int64_t(3) << m_QShift ) / ( 4 * m_QScale ) );
     m_thresSSbb                 = TCoeff( ( int64_t(3) << m_QShift ) / ( 4 * m_QScale ) );
 
     // distortion calculation parameters
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    const int64_t qScale        = m_QScale;
+    const int nomDShift =
+      SCALE_BITS - 2 * (nomTransformShift + DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth)) + m_QShift + (needsSqrt2ScaleAdjustment ? 1 : 0);
+#else // JVET_N0246_MODIFIED_QUANTSCALES
     const int64_t qScale        = g_quantScales[ qpRem ];
 #if HM_QTBT_AS_IN_JEM_QUANT
     const int nomDShift =
@@ -783,6 +797,7 @@ namespace DQIntern
     const int nomDShift = SCALE_BITS - 2 * (nomTransformShift + DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth))
                           + m_QShift + (TU::needsQP3Offset(tu, compID) ? 1 : 0);
 #endif
+#endif // JVET_N0246_MODIFIED_QUANTSCALES
     const double  qScale2       = double( qScale * qScale );
     const double  nomDistFactor = ( nomDShift < 0 ? 1.0/(double(int64_t(1)<<(-nomDShift))*qScale2*lambda) : double(int64_t(1)<<nomDShift)/(qScale2*lambda) );
     const int64_t pow2dfShift   = (int64_t)( nomDistFactor * qScale2 ) + 1;
@@ -845,6 +860,12 @@ namespace DQIntern
     const TCoeff      maxTCoeff             =  ( 1 << maxLog2TrDynamicRange ) - 1;
     const int         nomTransformShift     = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange );
     const bool        clipTransformShift    = ( tu.mtsIdx==1 && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() );
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    const bool    needsSqrt2ScaleAdjustment = TU::needsSqrt2Scale(tu, compID);
+    const int         transformShift        = ( clipTransformShift ? std::max<int>( 0, nomTransformShift ) : nomTransformShift ) + (needsSqrt2ScaleAdjustment?-1:0);
+    Intermediate_Int  shift                 = IQUANT_SHIFT + 1 - qpPer - transformShift;
+    Intermediate_Int  invQScale             = g_invQuantScales[needsSqrt2ScaleAdjustment?1:0][ qpRem ];
+#else // JVET_N0246_MODIFIED_QUANTSCALES
     const int         transformShift        = ( clipTransformShift ? std::max<int>( 0, nomTransformShift ) : nomTransformShift );
 #if HM_QTBT_AS_IN_JEM_QUANT
     Intermediate_Int  shift                 = IQUANT_SHIFT + 1 - qpPer - transformShift + ( TU::needsBlockSizeTrafoScale( tu, compID ) ? ADJ_DEQUANT_SHIFT : 0 );
@@ -853,6 +874,7 @@ namespace DQIntern
     Intermediate_Int  shift                 = IQUANT_SHIFT + 1 - qpPer - transformShift;
     Intermediate_Int  invQScale             = g_invQuantScales[ qpRem ];
 #endif
+#endif // JVET_N0246_MODIFIED_QUANTSCALES
     if( shift < 0 )
     {
       invQScale <<= -shift;
diff --git a/source/Lib/CommonLib/Quant.cpp b/source/Lib/CommonLib/Quant.cpp
index 449d5b75f2d73c0b3a1d1dce5cdd9d379ba2d7b7..1b61df49ee3759f6e99437de4596bcd693aaa4a9 100644
--- a/source/Lib/CommonLib/Quant.cpp
+++ b/source/Lib/CommonLib/Quant.cpp
@@ -295,7 +295,8 @@ void Quant::dequant(const TransformUnit &tu,
   const TCoeff          transformMinimum   = -(1 << maxLog2TrDynamicRange);
   const TCoeff          transformMaximum   =  (1 << maxLog2TrDynamicRange) - 1;
 #if HEVC_USE_SCALING_LISTS
-  const bool            enableScalingLists = getUseScalingList(uiWidth, uiHeight, (tu.transformSkip[compID] != 0));
+  const bool            isTransformSkip = tu.mtsIdx==1 && isLuma(compID);
+  const bool            enableScalingLists = getUseScalingList(uiWidth, uiHeight, isTransformSkip);
   const int             scalingListType    = getScalingListType(tu.cu->predMode, compID);
 #endif
   const int             channelBitDepth    = sps->getBitDepth(toChannelType(compID));
@@ -308,11 +309,23 @@ void Quant::dequant(const TransformUnit &tu,
   // Represents scaling through forward transform
   const bool bClipTransformShiftTo0 = tu.mtsIdx!=1 && sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag();
   const int  originalTransformShift = getTransformShift(channelBitDepth, area.size(), maxLog2TrDynamicRange);
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const bool needSqrtAdjustment     = TU::needsBlockSizeTrafoScale( tu, compID );
+  const int  iTransformShift        = (bClipTransformShiftTo0 ? std::max<int>(0, originalTransformShift) : originalTransformShift) + (needSqrtAdjustment?-1:0);
+#else
   const int  iTransformShift        = bClipTransformShiftTo0 ? std::max<int>(0, originalTransformShift) : originalTransformShift;
+#endif
 
   const int QP_per = cQP.per;
   const int QP_rem = cQP.rem;
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+#if HEVC_USE_SCALING_LISTS
+  const int  rightShift = (IQUANT_SHIFT - (iTransformShift + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
+#else
+  const int  rightShift = (IQUANT_SHIFT - (iTransformShift + QP_per));
+#endif
+#else
 #if HM_QTBT_AS_IN_JEM_QUANT
   const bool needsScalingCorrection = TU::needsBlockSizeTrafoScale( tu, compID );
   const int  NEScale    = TU::needsSqrt2Scale( tu, compID ) ? 181 : 1;
@@ -328,6 +341,7 @@ void Quant::dequant(const TransformUnit &tu,
   const int  rightShift = (IQUANT_SHIFT - (iTransformShift + QP_per));
 #endif
 #endif
+#endif // JVET_N0246_MODIFIED_QUANTSCALES
 
 #if HEVC_USE_SCALING_LISTS
   if(enableScalingLists)
@@ -352,7 +366,7 @@ void Quant::dequant(const TransformUnit &tu,
       for( int n = 0; n < numSamplesInBlock; n++ )
       {
         const TCoeff           clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, piQCoef[n]));
-#if HM_QTBT_AS_IN_JEM_QUANT
+#if HM_QTBT_AS_IN_JEM_QUANT && !JVET_N0246_MODIFIED_QUANTSCALES
         const Intermediate_Int iCoeffQ   = ((Intermediate_Int(clipQCoef) * piDequantCoef[n] * NEScale) + iAdd ) >> rightShift;
 #else
         const Intermediate_Int iCoeffQ   = ((Intermediate_Int(clipQCoef) * piDequantCoef[n]) + iAdd ) >> rightShift;
@@ -368,7 +382,7 @@ void Quant::dequant(const TransformUnit &tu,
       for( int n = 0; n < numSamplesInBlock; n++ )
       {
         const TCoeff           clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, piQCoef[n]));
-#if HM_QTBT_AS_IN_JEM_QUANT
+#if HM_QTBT_AS_IN_JEM_QUANT && !JVET_N0246_MODIFIED_QUANTSCALES
         const Intermediate_Int iCoeffQ   = (Intermediate_Int(clipQCoef) * piDequantCoef[n] * NEScale) << leftShift;
 #else
         const Intermediate_Int iCoeffQ   = (Intermediate_Int(clipQCoef) * piDequantCoef[n]) << leftShift;
@@ -381,10 +395,14 @@ void Quant::dequant(const TransformUnit &tu,
   else
   {
 #endif
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    const int scale     = g_invQuantScales[needSqrtAdjustment?1:0][QP_rem];
+#else
 #if HM_QTBT_AS_IN_JEM_QUANT
     const int scale     = g_invQuantScales[QP_rem] * NEScale;
 #else
     const int scale     = g_invQuantScales[QP_rem];
+#endif
 #endif
     const int scaleBits = ( IQUANT_SHIFT + 1 );
 
@@ -514,7 +532,12 @@ void Quant::xSetScalingListEnc(ScalingList *scalingList, uint32_t listId, uint32
   int *coeff  = scalingList->getScalingListAddress(sizeId,listId);
   quantcoeff  = getQuantCoeff(listId, qp, sizeId, sizeId);
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const bool blockIsNotPowerOf4 = ((g_aucLog2[width] + g_aucLog2[height]) & 1) == 1;
+  int quantScales = g_quantScales[blockIsNotPowerOf4?1:0][qp];
+#else
   int quantScales = g_quantScales[qp];
+#endif
 
   processScalingListEnc(coeff,
                         quantcoeff,
@@ -541,7 +564,12 @@ void Quant::xSetScalingListDec(const ScalingList &scalingList, uint32_t listId,
 
   dequantcoeff = getDequantCoeff(listId, qp, sizeId, sizeId);
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const bool blockIsNotPowerOf4 = ((g_aucLog2[width] + g_aucLog2[height]) & 1) == 1;
+  int invQuantScale = g_invQuantScales[blockIsNotPowerOf4?1:0][qp];
+#else
   int invQuantScale = g_invQuantScales[qp];
+#endif
 
   processScalingListDec(coeff,
                         dequantcoeff,
@@ -585,8 +613,14 @@ void Quant::xSetFlatScalingList(uint32_t list, uint32_t sizeX, uint32_t sizeY, i
   int *quantcoeff;
   int *dequantcoeff;
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const bool blockIsNotPowerOf4 = ((g_aucLog2[g_scalingListSizeX[sizeX]] + g_aucLog2[g_scalingListSizeX[sizeY]]) & 1) == 1;
+  int quantScales    = g_quantScales   [blockIsNotPowerOf4?1:0][qp];
+  int invQuantScales = g_invQuantScales[blockIsNotPowerOf4?1:0][qp] << 4;
+#else
   int quantScales    = g_quantScales   [qp];
   int invQuantScales = g_invQuantScales[qp] << 4;
+#endif
 
   quantcoeff   = getQuantCoeff(list, qp, sizeX, sizeY);
   dequantcoeff = getDequantCoeff(list, qp, sizeX, sizeY);
@@ -747,6 +781,15 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
 
     const bool enableScalingLists             = getUseScalingList(uiWidth, uiHeight, useTransformSkip);
 #endif
+#if JVET_N0246_MODIFIED_QUANTSCALES
+
+    // for blocks that where width*height != 4^N, the effective scaling applied during transformation cannot be
+    // compensated by a bit-shift (the quantised result will be sqrt(2) * larger than required).
+    // The quantScale table and shift is used to compensate for this.
+    const bool needSqrtAdjustment= TU::needsBlockSizeTrafoScale( tu, compID );
+    const int defaultQuantisationCoefficient    = g_quantScales[needSqrtAdjustment?1:0][cQP.rem];
+    int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange) + ( needSqrtAdjustment?-1:0);
+#else
     const int  defaultQuantisationCoefficient = g_quantScales[cQP.rem];
 
     /* for 422 chroma blocks, the effective scaling applied during transformation is not a power of 2, hence it cannot be
@@ -756,12 +799,14 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
      */
     // Represents scaling through forward transform
     int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);
+#endif
 
     if (useTransformSkip && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag())
     {
       iTransformShift = std::max<int>(0, iTransformShift);
     }
 
+#if !JVET_N0246_MODIFIED_QUANTSCALES
     int iWHScale = 1;
 #if HM_QTBT_AS_IN_JEM_QUANT
     if( TU::needsBlockSizeTrafoScale( tu, compID ) )
@@ -769,6 +814,7 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
       iTransformShift += ADJ_QUANT_SHIFT;
       iWHScale = 181;
     }
+#endif
 #endif
 
     const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift;
@@ -790,9 +836,16 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
       const int64_t  tmpLevel = (int64_t)abs(iLevel) * defaultQuantisationCoefficient;
 #endif
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+      const TCoeff quantisedMagnitude = TCoeff((tmpLevel + iAdd ) >> iQBits);
+#if HEVC_USE_SIGN_HIDING
+      deltaU[uiBlockPos] = (TCoeff)((tmpLevel - ((int64_t)quantisedMagnitude<<iQBits) )>> qBits8);
+#endif
+#else
       const TCoeff quantisedMagnitude = TCoeff((tmpLevel * iWHScale + iAdd ) >> iQBits);
 #if HEVC_USE_SIGN_HIDING
       deltaU[uiBlockPos] = (TCoeff)((tmpLevel * iWHScale - ((int64_t)quantisedMagnitude<<iQBits) )>> qBits8);
+#endif
 #endif
 
       uiAbsSum += quantisedMagnitude;
@@ -838,6 +891,17 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff
 
   const bool enableScalingLists             = getUseScalingList(uiWidth, uiHeight, (useTransformSkip != 0));
 #endif
+#if JVET_N0246_MODIFIED_QUANTSCALES
+
+  /* for 422 chroma blocks, the effective scaling applied during transformation is not a power of 2, hence it cannot be
+    * implemented as a bit-shift (the quantised result will be sqrt(2) * larger than required). Alternatively, adjust the
+    * uiLog2TrSize applied in iTransformShift, such that the result is 1/sqrt(2) the required result (i.e. smaller)
+    * Then a QP+3 (sqrt(2)) or QP-3 (1/sqrt(2)) method could be used to get the required result
+    */
+  const bool needSqrtAdjustment= TU::needsBlockSizeTrafoScale( tu, compID );
+  const int defaultQuantisationCoefficient    = g_quantScales[needSqrtAdjustment?1:0][cQP.rem];
+  int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange) + (needSqrtAdjustment?-1:0);
+#else
   const int  defaultQuantisationCoefficient = g_quantScales[cQP.rem];
 
   /* for 422 chroma blocks, the effective scaling applied during transformation is not a power of 2, hence it cannot be
@@ -848,12 +912,14 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff
 
   // Represents scaling through forward transform
   int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);
+#endif
 
   if (useTransformSkip && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag())
   {
     iTransformShift = std::max<int>(0, iTransformShift);
   }
 
+#if !JVET_N0246_MODIFIED_QUANTSCALES
   int iWHScale = 1;
 #if HM_QTBT_AS_IN_JEM_QUANT
   if( TU::needsBlockSizeTrafoScale( tu, compID ) )
@@ -861,9 +927,13 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff
     iTransformShift += ADJ_QUANT_SHIFT;
     iWHScale = 181;
   }
+#endif
 #endif
 
   const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift;
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  assert(iQBits>=0);
+#endif
   // QBits will be OK for any internal bit depth as the reduction in transform shift is balanced by an increase in Qp_per due to QpBDOffset
 
   // iAdd is different from the iAdd used in normal quantization
@@ -877,7 +947,11 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff
 #else
     const int64_t  tmpLevel = (int64_t)abs(iLevel) * defaultQuantisationCoefficient;
 #endif
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    const TCoeff quantisedMagnitude = TCoeff((tmpLevel + iAdd ) >> iQBits);
+#else
     const TCoeff quantisedMagnitude = TCoeff((tmpLevel * iWHScale + iAdd ) >> iQBits);
+#endif
 
     if (quantisedMagnitude != 0)
     {
@@ -903,7 +977,11 @@ void Quant::transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &co
   const int            scalingListType                = getScalingListType(tu.cu->predMode, compID);
   const bool           enableScalingLists             = getUseScalingList(uiWidth, uiHeight, true);
 #endif
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const int            defaultQuantisationCoefficient = g_quantScales[0][cQP.rem];
+#else
   const int            defaultQuantisationCoefficient = g_quantScales[cQP.rem];
+#endif
 
 #if HEVC_USE_SCALING_LISTS
   CHECK( scalingListType >= SCALING_LIST_NUM, "Invalid scaling list" );
@@ -1018,7 +1096,11 @@ void Quant::invTrSkipDeQuantOneSample(TransformUnit &tu, const ComponentID &comp
   else
   {
 #endif
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    const int scale = g_invQuantScales[0][QP_rem];
+#else
     const int scale = g_invQuantScales[QP_rem];
+#endif
     const int scaleBits = (IQUANT_SHIFT + 1);
 
     const uint32_t             targetInputBitDepth = std::min<uint32_t>((maxLog2TrDynamicRange + 1), (((sizeof(Intermediate_Int) * 8) + rightShift) - scaleBits));
diff --git a/source/Lib/CommonLib/Quant.h b/source/Lib/CommonLib/Quant.h
index 4877a59aa20e58887ec4f1ca797005dfbe31261e..3844bad1aeed32c5d06f5707e88f680bb5cda872 100644
--- a/source/Lib/CommonLib/Quant.h
+++ b/source/Lib/CommonLib/Quant.h
@@ -118,8 +118,13 @@ public:
   bool getUseScalingList         ( const uint32_t width, const uint32_t height, const bool isTransformSkip){ return m_scalingListEnabledFlag && (!isTransformSkip || ((width == 4) && (height == 4))); };
 
   void setScalingListDec         ( const ScalingList &scalingList);
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  void processScalingListEnc     ( int *coeff, int *quantcoeff, int qpMod6, uint32_t height, uint32_t width, uint32_t ratio, int sizuNum, uint32_t dc);
+  void processScalingListDec     ( const int *coeff, int *dequantcoeff, int qpMod6, uint32_t height, uint32_t width, uint32_t ratio, int sizuNum, uint32_t dc);
+#else
   void processScalingListEnc     ( int *coeff, int *quantcoeff, int quantScales, uint32_t height, uint32_t width, uint32_t ratio, int sizuNum, uint32_t dc);
   void processScalingListDec     ( const int *coeff, int *dequantcoeff, int invQuantScales, uint32_t height, uint32_t width, uint32_t ratio, int sizuNum, uint32_t dc);
+#endif
 
   virtual void setFlatScalingList( const int maxLog2TrDynamicRange[MAX_NUM_CHANNEL_TYPE], const BitDepths &bitDepths);
   virtual void setScalingList    ( ScalingList *scalingList, const int maxLog2TrDynamicRange[MAX_NUM_CHANNEL_TYPE], const BitDepths &bitDepths);
diff --git a/source/Lib/CommonLib/QuantRDOQ.cpp b/source/Lib/CommonLib/QuantRDOQ.cpp
index cdeea7d257e47cd513192cf38c8a93c2d5fdb963..286e285b249e5fe5bf16a47f36d993376b77e155 100644
--- a/source/Lib/CommonLib/QuantRDOQ.cpp
+++ b/source/Lib/CommonLib/QuantRDOQ.cpp
@@ -381,6 +381,18 @@ void QuantRDOQ::setScalingList(ScalingList *scalingList, const int maxLog2TrDyna
 #endif
 #else
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+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);
+  double    dErrScale       = (double)( 1 << SCALE_BITS );                                // Compensate for scaling of bitcount in Lagrange cost function
+  double    dTransShift     = (double)iTransformShift + ( needsSqrt2 ? -0.5 : 0.0 );
+  dErrScale                 = dErrScale*pow( 2.0, ( -2.0*dTransShift ) );                     // Compensate for scaling through forward transform
+  const int  QStep          = g_quantScales[needsSqrt2?1:0][qp];
+  double    finalErrScale = dErrScale / QStep / QStep / (1 << (DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth) << 1));
+  return    finalErrScale;
+}
+#else
 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);
@@ -398,6 +410,7 @@ double QuantRDOQ::xGetErrScaleCoeff( const bool needsSqrt2, SizeType width, Size
   return    finalErrScale;
 }
 #endif
+#endif
 
 
 
@@ -426,7 +439,11 @@ void QuantRDOQ::xSetErrScaleCoeff( uint32_t list, uint32_t sizeX, uint32_t sizeY
 #if HM_QTBT_AS_IN_JEM_QUANT
   double dErrScale = (double)( 1 << SCALE_BITS );                                // Compensate for scaling of bitcount in Lagrange cost function
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const bool needsSqrt2 = ((g_aucLog2[width] + g_aucLog2[height]) & 1) == 1;
+#else // !JVET_N0246_MODIFIED_QUANTSCALES
   bool   needsSqrt2 = TU::needsBlockSizeTrafoScale( Size( g_scalingListSizeX[sizeX], g_scalingListSizeX[sizeY] ) );// ( ( (sizeX+sizeY) & 1 ) !=0 );
+#endif // JVET_N0246_MODIFIED_QUANTSCALES
   double dTransShift = (double)iTransformShift + ( needsSqrt2 ? -0.5 : 0.0 );
   dErrScale = dErrScale*pow( 2.0, ( -2.0*dTransShift ) );                     // Compensate for scaling through forward transform
 
@@ -436,7 +453,11 @@ void QuantRDOQ::xSetErrScaleCoeff( uint32_t list, uint32_t sizeX, uint32_t sizeY
                     / (1 << (DISTORTION_PRECISION_ADJUSTMENT(bitDepths.recon[channelType]) << 1));
   }
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  int QStep = g_quantScales[needsSqrt2][qp];
+#else
   int QStep = ( needsSqrt2 ? ( ( g_quantScales[qp] * 181 ) >> 7 ) : g_quantScales[qp] );
+#endif
 
   xGetErrScaleCoeffNoScalingList(list, sizeX, sizeY, qp) =
     dErrScale / QStep / QStep / (1 << (DISTORTION_PRECISION_ADJUSTMENT(bitDepths.recon[channelType]) << 1));
@@ -652,6 +673,22 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
 #endif
 
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const bool needSqrtAdjustment= TU::needsBlockSizeTrafoScale( tu, compID );
+#if HEVC_USE_SCALING_LISTS
+  const double *const pdErrScale = xGetErrScaleCoeff(scalingListType, (uiLog2BlockWidth-1), (uiLog2BlockHeight-1), cQP.rem);
+  const int    *const piQCoef    = getQuantCoeff(scalingListType, cQP.rem, (uiLog2BlockWidth-1), (uiLog2BlockHeight-1));
+  const bool   isTransformSkip = tu.mtsIdx==1 && isLuma(compID);
+  const bool   enableScalingLists             = getUseScalingList(uiWidth, uiHeight, isTransformSkip);
+  const int    defaultQuantisationCoefficient = g_quantScales[ needSqrtAdjustment ?1:0][cQP.rem];
+  const double defaultErrorScale              = xGetErrScaleCoeffNoScalingList(scalingListType, (uiLog2BlockWidth-1), (uiLog2BlockHeight-1), cQP.rem);
+  const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift + (needSqrtAdjustment?-1:0);                   // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
+#else
+  const int quantisationCoefficient    = g_quantScales[needSqrtAdjustment?1:0][cQP.rem];
+  const double errorScale = xGetErrScaleCoeff( TU::needsSqrt2Scale( tu, compID ), uiWidth, uiHeight, cQP.rem, maxLog2TrDynamicRange, channelBitDepth );
+  const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift + (needSqrtAdjustment?-1:0);                   // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
+#endif // HEVC_USE_SCALING_LISTS
+#else // JVET_N0246_MODIFIED_QUANTSCALES
   const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift;                   // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
 
 #if HEVC_USE_SCALING_LISTS
@@ -677,6 +714,7 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
   const double errorScale              = blkErrScale * xGetErrScaleCoeff( uiWidth, uiHeight, cQP.rem, maxLog2TrDynamicRange, channelBitDepth );
 #endif
 #endif//HEVC_USE_SCALING_LISTS
+#endif // JVET_N0246_MODIFIED_QUANTSCALES
 
 
 #if HEVC_USE_SIGN_HIDING
@@ -1108,7 +1146,11 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
 #if HEVC_USE_SIGN_HIDING
   if( cctx.signHiding() && uiAbsSum>=2)
   {
+#if JVET_N0246_MODIFIED_QUANTSCALES
+    const double inverseQuantScale = double(g_invQuantScales[0][cQP.rem]);
+#else
     const double inverseQuantScale = double(g_invQuantScales[cQP.rem]);
+#endif
     int64_t rdFactor = (int64_t)(inverseQuantScale * inverseQuantScale * (1 << (2 * cQP.per)) / m_dLambda / 16
                                / (1 << (2 * DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth)))
 #if HM_QTBT_AS_IN_JEM_QUANT
@@ -1288,6 +1330,13 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI
   memset( m_pdCostCoeff,  0, sizeof( double ) *  maxNumCoeff );
   memset( m_pdCostSig,    0, sizeof( double ) *  maxNumCoeff );
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+  const bool   needsSqrt2Scale = TU::needsSqrt2Scale( tu, compID );  // should always be false - transform-skipped blocks don't require sqrt(2) compensation.
+  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];
+  const double errorScale              = xGetErrScaleCoeff( TU::needsSqrt2Scale( tu, compID ), width, height, qp.rem, maxLog2TrDynamicRange, channelBitDepth );
+#else
+
   const int qBits = QUANT_SHIFT + qp.per + transformShift;                   // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
 
 #if HM_QTBT_AS_IN_JEM_QUANT
@@ -1297,6 +1346,7 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI
   const double blkErrScale             = ( TU::needsQP3Offset( tu, compID ) ? 2.0 : 1.0 );
   const int    quantisationCoefficient = g_quantScales[qp.rem];
   const double errorScale              = blkErrScale * xGetErrScaleCoeff( width, height, qp.rem, maxLog2TrDynamicRange, channelBitDepth );
+#endif
 #endif
 
   const TCoeff entropyCodingMaximum = ( 1 << maxLog2TrDynamicRange ) - 1;
diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp
index cdc5fa930fb9418b144694b2a70e39fe12fdcc58..93f56a94890a79d9aa64f29816f66e6462b25cf3 100644
--- a/source/Lib/CommonLib/Rom.cpp
+++ b/source/Lib/CommonLib/Rom.cpp
@@ -538,6 +538,19 @@ void destroyROM()
 // Data structure related table & variable
 // ====================================================================================================================
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+const int g_quantScales[2][SCALING_LIST_REM_NUM] = // can be represented as a 9 element table
+{
+    { 26214,23302,20560,18396,16384,14564 },
+    { 18396,16384,14564,13107,11651,10280 } // Note: last 3 values of second row == half of the first 3 values of the first row
+};
+
+const int g_invQuantScales[2][SCALING_LIST_REM_NUM] = // can be represented as a 9 element table
+{
+  { 40,45,51,57,64,72 },
+  { 57,64,72,80,90,102 } // Note: last 3 values of second row == double of the first 3 values of the first row
+};
+#else
 const int g_quantScales[SCALING_LIST_REM_NUM] =
 {
   26214,23302,20560,18396,16384,14564
@@ -547,6 +560,7 @@ const int g_invQuantScales[SCALING_LIST_REM_NUM] =
 {
   40,45,51,57,64,72
 };
+#endif
 
 //--------------------------------------------------------------------------------------------------
 //structures
diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h
index d23aca95df3bf80404c4f292f986c79b3937049d..879e473144e9b57f20f1245499c404368446033d 100644
--- a/source/Lib/CommonLib/Rom.h
+++ b/source/Lib/CommonLib/Rom.h
@@ -77,8 +77,13 @@ extern ScanElement
   *g_scanOrder[2][SCAN_NUMBER_OF_GROUP_TYPES][SCAN_NUMBER_OF_TYPES][MAX_CU_SIZE / 2 + 1][MAX_CU_SIZE / 2 + 1];
 #endif
 
+#if JVET_N0246_MODIFIED_QUANTSCALES
+extern const int g_quantScales   [2/*0=4^n blocks, 1=2*4^n blocks*/][SCALING_LIST_REM_NUM];          // Q(QP%6)
+extern const int g_invQuantScales[2/*0=4^n blocks, 1=2*4^n blocks*/][SCALING_LIST_REM_NUM];          // IQ(QP%6)
+#else
 extern const int g_quantScales   [SCALING_LIST_REM_NUM];          // Q(QP%6)
 extern const int g_invQuantScales[SCALING_LIST_REM_NUM];          // IQ(QP%6)
+#endif
 
 static const int g_numTransformMatrixSizes = 6;
 static const int g_transformMatrixShift[TRANSFORM_NUMBER_OF_DIRECTIONS] = {  6, 6 };
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 0733b52db2f6f57b5fa7aaa573556322da778452..273d364c9849176dd3f806bddf3d7fc39e2335a1 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -171,6 +171,8 @@ typedef std::pair<int, int>  TrCost;
 #define HEVC_TOOLS                                        0
 #endif
 
+#define JVET_N0246_MODIFIED_QUANTSCALES                   1
+
 #ifndef JVET_J0090_MEMORY_BANDWITH_MEASURE
 #define JVET_J0090_MEMORY_BANDWITH_MEASURE                0
 #endif
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index c842c6d8f35c817701c4bf1f838613158af44873..cfac8acd6178d3dc2ae6af18838a348e4146d68a 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -988,7 +988,11 @@ static bool applyQPAdaptation (Picture* const pcPic,       Slice* const pcSlice,
         }
 
 #endif
+#if JVET_N0246_MODIFIED_QUANTSCALES
+        const uint32_t uRefScale  = g_invQuantScales[0][iQPAdapt % 6] << ((iQPAdapt / 6) + bitDepth - 4);
+#else
         const uint32_t uRefScale  = g_invQuantScales[iQPAdapt % 6] << ((iQPAdapt / 6) + bitDepth - 4);
+#endif
         const CompArea subArea    = clipArea (CompArea (COMPONENT_Y, pcPic->chromaFormat, Area ((ctuRsAddr % pcv.widthInCtus) * pcv.maxCUWidth, (ctuRsAddr / pcv.widthInCtus) * pcv.maxCUHeight, pcv.maxCUWidth, pcv.maxCUHeight)), pcPic->Y());
         const Pel*     pSrc       = pcPic->getOrigBuf (subArea).buf;
         const SizeType iSrcStride = pcPic->getOrigBuf (subArea).stride;