diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp index 152fe036d39b71d6d30e1c68b7ba0a52d2e9cd90..cf2b3e241b5bd0edc685c6b7617a8b3a0d98a9c1 100644 --- a/source/Lib/CommonLib/DepQuant.cpp +++ b/source/Lib/CommonLib/DepQuant.cpp @@ -679,7 +679,11 @@ namespace DQIntern { CHECKD( lambda <= 0.0, "Lambda must be greater than 0" ); +#if JVET_O0919_TS_MIN_QP + const int qpDQ = cQP.Qp(tu.mtsIdx==MTS_SKIP && isLuma(compID)) + 1; +#else const int qpDQ = cQP.Qp + 1; +#endif const int qpPer = qpDQ / 6; const int qpRem = qpDQ - 6 * qpPer; const SPS& sps = *tu.cs->sps; @@ -748,7 +752,11 @@ namespace DQIntern } //----- set dequant parameters ----- +#if JVET_O0919_TS_MIN_QP + const int qpDQ = cQP.Qp(tu.mtsIdx==MTS_SKIP && isLuma(compID)) + 1; +#else const int qpDQ = cQP.Qp + 1; +#endif const int qpPer = qpDQ / 6; const int qpRem = qpDQ - 6 * qpPer; const SPS& sps = *tu.cs->sps; @@ -1721,7 +1729,11 @@ void DepQuant::quant( TransformUnit &tu, const ComponentID &compID, const CCoeff if( tu.cs->slice->getDepQuantEnabledFlag() && (tu.mtsIdx != MTS_SKIP || !isLuma(compID)) ) { //===== scaling matrix ==== +#if JVET_O0919_TS_MIN_QP + const int qpDQ = cQP.Qp(tu.mtsIdx==MTS_SKIP && isLuma(compID)) + 1; +#else const int qpDQ = cQP.Qp + 1; +#endif const int qpPer = qpDQ / 6; const int qpRem = qpDQ - 6 * qpPer; const CompArea &rect = tu.blocks[compID]; @@ -1744,7 +1756,11 @@ void DepQuant::dequant( const TransformUnit &tu, CoeffBuf &dstCoeff, const Compo { if( tu.cs->slice->getDepQuantEnabledFlag() && (tu.mtsIdx != MTS_SKIP || !isLuma(compID)) ) { +#if JVET_O0919_TS_MIN_QP + const int qpDQ = cQP.Qp(tu.mtsIdx==MTS_SKIP && isLuma(compID)) + 1; +#else const int qpDQ = cQP.Qp + 1; +#endif const int qpPer = qpDQ / 6; const int qpRem = qpDQ - 6 * qpPer; const CompArea &rect = tu.blocks[compID]; diff --git a/source/Lib/CommonLib/Quant.cpp b/source/Lib/CommonLib/Quant.cpp index 94ca3df437c07fc540e513e4b95ad6d5e498382d..e597d9da311f7dcb8266bf115f77161828092920 100644 --- a/source/Lib/CommonLib/Quant.cpp +++ b/source/Lib/CommonLib/Quant.cpp @@ -65,6 +65,9 @@ QpParam::QpParam(const int qpy, const ChannelType chType, const int qpBdOffset, +#if JVET_O0919_TS_MIN_QP + const int minQpMinus4, +#endif const int chromaQPOffset, const ChromaFormat chFmt, const int dqp ) @@ -91,9 +94,26 @@ QpParam::QpParam(const int qpy, baseQp = Clip3( 0, MAX_QP+qpBdOffset, baseQp + dqp ); +#if JVET_O0919_TS_MIN_QP + Qps[0] =baseQp; + pers[0]=baseQp/6; + rems[0]=baseQp%6; + + int baseQpTS = baseQp; + + if( isLuma( chType ) ) + { + baseQpTS = std::max(baseQpTS , 4 + minQpMinus4); + } + + Qps[1] = baseQpTS; + pers[1] = baseQpTS / 6; + rems[1] = baseQpTS % 6; +#else Qp =baseQp; per=baseQp/6; rem=baseQp%6; +#endif } QpParam::QpParam(const TransformUnit& tu, const ComponentID &compIDX, const int QP /*= -MAX_INT*/) @@ -126,7 +146,11 @@ QpParam::QpParam(const TransformUnit& tu, const ComponentID &compIDX, const int int dqp = 0; +#if JVET_O0919_TS_MIN_QP + *this = QpParam(QP <= -MAX_INT ? tu.cu->qp : QP, toChannelType(compID), tu.cs->sps->getQpBDOffset(toChannelType(compID)), tu.cs->sps->getMinQpMinus4(toChannelType(compID)), chromaQpOffset, tu.chromaFormat, dqp); +#else *this = QpParam(QP <= -MAX_INT ? tu.cu->qp : QP, toChannelType(compID), tu.cs->sps->getQpBDOffset(toChannelType(compID)), chromaQpOffset, tu.chromaFormat, dqp); +#endif } @@ -397,8 +421,13 @@ void Quant::dequant(const TransformUnit &tu, const bool needSqrtAdjustment = TU::needsBlockSizeTrafoScale( tu, compID ); const int iTransformShift = (bClipTransformShiftTo0 ? std::max<int>(0, originalTransformShift) : originalTransformShift) + (needSqrtAdjustment?-1:0); +#if JVET_O0919_TS_MIN_QP + const int QP_per = cQP.per( tu.mtsIdx==MTS_SKIP && isLuma(compID) ); + const int QP_rem = cQP.rem( tu.mtsIdx==MTS_SKIP && isLuma(compID) ); +#else const int QP_per = cQP.per; const int QP_rem = cQP.rem; +#endif const int rightShift = (IQUANT_SHIFT - (iTransformShift + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0); @@ -943,7 +972,11 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list"); const uint32_t uiLog2TrWidth = g_aucLog2[uiWidth]; const uint32_t uiLog2TrHeight = g_aucLog2[uiHeight]; +#if JVET_O0919_TS_MIN_QP + int *piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem(useTransformSkip), uiLog2TrWidth, uiLog2TrHeight); +#else int *piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem, uiLog2TrWidth, uiLog2TrHeight); +#endif const bool enableScalingLists = getUseScalingList(uiWidth, uiHeight, useTransformSkip); @@ -951,7 +984,11 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf // 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 ); +#if JVET_O0919_TS_MIN_QP + const int defaultQuantisationCoefficient = g_quantScales[needSqrtAdjustment?1:0][cQP.rem(useTransformSkip)]; +#else 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()) @@ -960,7 +997,11 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf } +#if JVET_O0919_TS_MIN_QP + const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + iTransformShift; +#else const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift; +#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 const int64_t iAdd = int64_t(tu.cs->slice->isIRAP() ? 171 : 85) << int64_t(iQBits - 9); @@ -1014,7 +1055,11 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff const uint32_t uiLog2TrWidth = g_aucLog2[uiWidth]; const uint32_t uiLog2TrHeight = g_aucLog2[uiHeight]; +#if JVET_O0919_TS_MIN_QP + int *piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem(useTransformSkip), uiLog2TrWidth, uiLog2TrHeight); +#else int *piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem, uiLog2TrWidth, uiLog2TrHeight); +#endif const bool enableScalingLists = getUseScalingList(uiWidth, uiHeight, (useTransformSkip != 0)); @@ -1024,7 +1069,11 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff * 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 ); +#if JVET_O0919_TS_MIN_QP + const int defaultQuantisationCoefficient = g_quantScales[needSqrtAdjustment?1:0][cQP.rem(useTransformSkip)]; +#else 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()) @@ -1033,7 +1082,11 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff } +#if JVET_O0919_TS_MIN_QP + const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + iTransformShift; +#else const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift; +#endif assert(iQBits>=0); // 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 @@ -1066,13 +1119,22 @@ void Quant::transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &co const int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange); const int scalingListType = getScalingListType(tu.cu->predMode, compID); const bool enableScalingLists = getUseScalingList(uiWidth, uiHeight, true); +#if JVET_O0919_TS_MIN_QP + const bool useTransformSkip = tu.mtsIdx == MTS_SKIP && isLuma(compID); + const int defaultQuantisationCoefficient = g_quantScales[0][cQP.rem(useTransformSkip)]; +#else const int defaultQuantisationCoefficient = g_quantScales[0][cQP.rem]; +#endif CHECK( scalingListType >= SCALING_LIST_NUM, "Invalid scaling list" ); const uint32_t uiLog2TrWidth = g_aucLog2[uiWidth]; const uint32_t uiLog2TrHeight = g_aucLog2[uiHeight]; +#if JVET_O0919_TS_MIN_QP + const int *const piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem(useTransformSkip), uiLog2TrWidth, uiLog2TrHeight); +#else const int *const piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem, uiLog2TrWidth, uiLog2TrHeight); +#endif /* 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 @@ -1080,7 +1142,11 @@ void Quant::transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &co * Then a QP+3 (sqrt(2)) or QP-3 (1/sqrt(2)) method could be used to get the required result */ +#if JVET_O0919_TS_MIN_QP + const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + iTransformShift; +#else const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift; +#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 const int iAdd = int64_t(bUseHalfRoundingPoint ? 256 : (tu.cs->slice->isIRAP() ? 171 : 85)) << int64_t(iQBits - 9); TCoeff transformedCoefficient; @@ -1117,8 +1183,13 @@ void Quant::invTrSkipDeQuantOneSample(TransformUnit &tu, const ComponentID &comp const CompArea &rect = tu.blocks[compID]; const uint32_t uiWidth = rect.width; const uint32_t uiHeight = rect.height; +#if JVET_O0919_TS_MIN_QP + const int QP_per = cQP.per(tu.mtsIdx==MTS_SKIP && isLuma(compID)); + const int QP_rem = cQP.rem(tu.mtsIdx==MTS_SKIP && isLuma(compID)); +#else const int QP_per = cQP.per; const int QP_rem = cQP.rem; +#endif const int maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(toChannelType(compID)); const int channelBitDepth = sps.getBitDepth(toChannelType(compID)); const int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange); diff --git a/source/Lib/CommonLib/Quant.h b/source/Lib/CommonLib/Quant.h index b53de50b4884da9a9f8f4b2c5238beaf5eb56078..5c26400cca277a918f61c24d9d71513f98572215 100644 --- a/source/Lib/CommonLib/Quant.h +++ b/source/Lib/CommonLib/Quant.h @@ -67,15 +67,24 @@ struct TrQuantParams /// QP struct struct QpParam { +#if JVET_O0919_TS_MIN_QP + int Qps[2]; + int pers[2]; + int rems[2]; +#else int Qp; int per; int rem; +#endif private: QpParam(const int qpy, const ChannelType chType, const int qpBdOffset, +#if JVET_O0919_TS_MIN_QP + const int qpBdOffsetInput, +#endif const int chromaQPOffset, const ChromaFormat chFmt, const int dqp ); @@ -84,6 +93,12 @@ public: QpParam(const TransformUnit& tu, const ComponentID &compID, const int QP = -MAX_INT); +#if JVET_O0919_TS_MIN_QP + int Qp ( const bool ts ) const { return Qps [ts?1:0]; } + int per( const bool ts ) const { return pers[ts?1:0]; } + int rem( const bool ts ) const { return rems[ts?1:0]; } +#endif + }; // END STRUCT DEFINITION QpParam /// transform and quantization class diff --git a/source/Lib/CommonLib/QuantRDOQ.cpp b/source/Lib/CommonLib/QuantRDOQ.cpp index 30e3ba2e25340ca6c46e851055c8e5b475cb26b3..d21646a22f860e9c8280efcaeb8b5717402837f3 100644 --- a/source/Lib/CommonLib/QuantRDOQ.cpp +++ b/source/Lib/CommonLib/QuantRDOQ.cpp @@ -628,13 +628,28 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID, const bool needSqrtAdjustment= TU::needsBlockSizeTrafoScale( tu, compID ); +#if JVET_O0919_TS_MIN_QP + const bool isTransformSkip = tu.mtsIdx==MTS_SKIP && isLuma(compID); + const double *const pdErrScale = xGetErrScaleCoeffSL(scalingListType, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip)); + const int *const piQCoef = getQuantCoeff(scalingListType, cQP.rem(isTransformSkip), uiLog2BlockWidth, uiLog2BlockHeight); +#else const double *const pdErrScale = xGetErrScaleCoeffSL(scalingListType, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem); const int *const piQCoef = getQuantCoeff(scalingListType, cQP.rem, uiLog2BlockWidth, uiLog2BlockHeight); const bool isTransformSkip = tu.mtsIdx==MTS_SKIP && isLuma(compID); +#endif const bool enableScalingLists = getUseScalingList(uiWidth, uiHeight, isTransformSkip); +#if JVET_O0919_TS_MIN_QP + const int defaultQuantisationCoefficient = g_quantScales[ needSqrtAdjustment ?1:0][cQP.rem(isTransformSkip)]; + const double defaultErrorScale = xGetErrScaleCoeffNoScalingList(scalingListType, (uiLog2BlockWidth-1), (uiLog2BlockHeight-1), cQP.rem(isTransformSkip)); +#else const int defaultQuantisationCoefficient = g_quantScales[ needSqrtAdjustment ?1:0][cQP.rem]; const double defaultErrorScale = xGetErrScaleCoeffNoScalingList(scalingListType, (uiLog2BlockWidth-1), (uiLog2BlockHeight-1), cQP.rem); +#endif +#if JVET_O0919_TS_MIN_QP + const int iQBits = QUANT_SHIFT + cQP.per(isTransformSkip) + iTransformShift + (needSqrtAdjustment?-1:0); // Right shift of non-RDOQ quantizer; level = (coeff*uiQ + offset)>>q_bits +#else const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift + (needSqrtAdjustment?-1:0); // Right shift of non-RDOQ quantizer; level = (coeff*uiQ + offset)>>q_bits +#endif const TCoeff entropyCodingMinimum = -(1 << maxLog2TrDynamicRange); @@ -1078,9 +1093,18 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID, if( cctx.signHiding() && uiAbsSum>=2) { +#if JVET_O0919_TS_MIN_QP + const double inverseQuantScale = double(g_invQuantScales[0][cQP.rem(isTransformSkip)]); +#else const double inverseQuantScale = double(g_invQuantScales[0][cQP.rem]); +#endif +#if JVET_O0919_TS_MIN_QP + int64_t rdFactor = (int64_t)(inverseQuantScale * inverseQuantScale * (1 << (2 * cQP.per(isTransformSkip))) / m_dLambda / 16 + / (1 << (2 * DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth))) +#else int64_t rdFactor = (int64_t)(inverseQuantScale * inverseQuantScale * (1 << (2 * cQP.per)) / m_dLambda / 16 / (1 << (2 * DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth))) +#endif + 0.5); int lastCG = -1; @@ -1252,9 +1276,16 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI #endif 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); + const int qBits = QUANT_SHIFT + qp.per(isTransformSkip) + 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(isTransformSkip)]; + const double errorScale = xGetErrScaleCoeff( TU::needsSqrt2Scale( tu, compID ), width, height, qp.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth ); +#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]; const double errorScale = xGetErrScaleCoeff( TU::needsSqrt2Scale( tu, compID ), width, height, qp.rem, maxLog2TrDynamicRange, channelBitDepth ); +#endif const TCoeff entropyCodingMaximum = ( 1 << maxLog2TrDynamicRange ) - 1; @@ -1500,13 +1531,25 @@ void QuantRDOQ::forwardRDPCM( TransformUnit &tu, const ComponentID &compID, cons #endif 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); + const int qBits = QUANT_SHIFT + qp.per(isTransformSkip) + 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(isTransformSkip)]; + const double errorScale = xGetErrScaleCoeff(TU::needsSqrt2Scale(tu, compID), width, height, qp.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth); +#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]; const double errorScale = xGetErrScaleCoeff(TU::needsSqrt2Scale(tu, compID), width, height, qp.rem, maxLog2TrDynamicRange, channelBitDepth); +#endif TrQuantParams trQuantParams; +#if JVET_O0919_TS_MIN_QP + trQuantParams.rightShift = (IQUANT_SHIFT - (transformShift + qp.per(isTransformSkip))); + trQuantParams.qScale = g_invQuantScales[needsSqrt2Scale ? 1 : 0][qp.rem(isTransformSkip)]; +#else trQuantParams.rightShift = (IQUANT_SHIFT - (transformShift + qp.per)); trQuantParams.qScale = g_invQuantScales[needsSqrt2Scale ? 1 : 0][qp.rem]; +#endif const TCoeff entropyCodingMaximum = (1 << maxLog2TrDynamicRange) - 1; diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index a4f18555dbd1ee3941c359f800dac838e474f48f..fbdddaca2b5f7e21935c5c0ce3ee4816add0972b 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -735,6 +735,9 @@ private: // Parameter BitDepths m_bitDepths; int m_qpBDOffset[MAX_NUM_CHANNEL_TYPE]; +#if JVET_O0919_TS_MIN_QP + int m_minQpMinus4[MAX_NUM_CHANNEL_TYPE]; // QP_internal - QP_input; +#endif int m_pcmBitDepths[MAX_NUM_CHANNEL_TYPE]; bool m_bPCMFilterDisableFlag; @@ -929,6 +932,10 @@ public: int getDifferentialLumaChromaBitDepth() const { return int(m_bitDepths.recon[CHANNEL_TYPE_LUMA]) - int(m_bitDepths.recon[CHANNEL_TYPE_CHROMA]); } int getQpBDOffset(ChannelType type) const { return m_qpBDOffset[type]; } void setQpBDOffset(ChannelType type, int i) { m_qpBDOffset[type] = i; } +#if JVET_O0919_TS_MIN_QP + int getMinQpMinus4(ChannelType type) const { return m_minQpMinus4[type]; } + void setMinQpMinus4(ChannelType type, int i) { m_minQpMinus4[type] = i; } +#endif void setSAOEnabledFlag(bool bVal) { m_saoEnabledFlag = bVal; } bool getSAOEnabledFlag() const { return m_saoEnabledFlag; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 950943b0355ecdadb289900397fd4c0a576300a5..a10f888f7e1a9b82bd41d2c5673efb2da59734c9 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -62,6 +62,8 @@ #define JVET_O0366_AFFINE_BCW 1 // JVET-O0366: Simplifications on BCW index derivation process +#define JVET_O0919_TS_MIN_QP 1 // JVET-O0919: Minimum QP for Transform Skip Mode + #define JVET_O1168_CU_CHROMA_QP_OFFSET 1 // JVET-O1168: cu chroma QP offset #define JVET_O0368_LFNST_WITH_DCT2_ONLY 1 // JVET-O0368/O0292/O0521/O0466: disable LFNST for non-DCT2 MTS candidates normatively diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index dbfaff778578a45855f7f6aee357da9923c808a9..51003b3cb4edb7829aa3d207820a119bf762f4b5 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1090,6 +1090,10 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) pcSPS->setBitDepth(CHANNEL_TYPE_LUMA, 8 + uiCode); pcSPS->setQpBDOffset(CHANNEL_TYPE_LUMA, (int) (6*uiCode) ); +#if JVET_O0919_TS_MIN_QP + READ_UVLC( uiCode, "min_qp_luma_minus4" ); + pcSPS->setMinQpMinus4(CHANNEL_TYPE_LUMA, uiCode); +#endif READ_UVLC( uiCode, "bit_depth_chroma_minus8" ); CHECK(uiCode > 8, "Invalid chroma bit depth signalled"); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index ce97ff3119d935a3e1285c6efe55d32a056a4ef0..c905446a5e17daca3dcac32bdb6974d7ed112e55 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -976,6 +976,9 @@ void EncLib::xInitSPS(SPS &sps) { sps.setBitDepth (ChannelType(channelType), m_bitDepth[channelType] ); sps.setQpBDOffset (ChannelType(channelType), (6 * (m_bitDepth[channelType] - 8))); +#if JVET_O0919_TS_MIN_QP + sps.setMinQpMinus4(ChannelType(channelType), (6 * (m_bitDepth[channelType] - m_inputBitDepth[channelType]))); +#endif sps.setPCMBitDepth (ChannelType(channelType), m_PCMBitDepth[channelType] ); } diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 090b22b84f6a144e8c39f3af8849a93fcb82007c..2239266d1c6f9ca65fe8bcdcbef2e6ed89fd2cb2 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -732,6 +732,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } WRITE_UVLC( pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8, "bit_depth_luma_minus8" ); +#if JVET_O0919_TS_MIN_QP + WRITE_UVLC( pcSPS->getMinQpMinus4(CHANNEL_TYPE_LUMA), "min_qp_luma_minus4" ); +#endif const bool chromaEnabled = isChromaEnabled(format); WRITE_UVLC( chromaEnabled ? (pcSPS->getBitDepth(CHANNEL_TYPE_CHROMA) - 8):0, "bit_depth_chroma_minus8" );