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;