diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index 5a6e6967c3d3bce45687cf08069ca82cb0178028..7a2b496c3489814bbedca2bce31b4daa81dcb79f 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -152,8 +152,11 @@ public: unsigned parityCtxIdAbs ( uint8_t offset ) const { return m_parFlagCtxSet ( offset ); } unsigned greater1CtxIdAbs ( uint8_t offset ) const { return m_gtxFlagCtxSet[1]( offset ); } unsigned greater2CtxIdAbs ( uint8_t offset ) const { return m_gtxFlagCtxSet[0]( offset ); } - +#if JVET_N0188_UNIFY_RICEPARA + unsigned templateAbsSum( int scanPos, const TCoeff* coeff, int baseLevel ) +#else unsigned templateAbsSum( int scanPos, const TCoeff* coeff ) +#endif { const uint32_t posY = m_scan[scanPos].y; const uint32_t posX = m_scan[scanPos].x; @@ -179,7 +182,11 @@ public: sum += abs(pData[m_width << 1]); } } +#if JVET_N0188_UNIFY_RICEPARA + return std::max(std::min(sum - 5 * baseLevel, 31), 0); +#else return std::min(sum, 31); +#endif } diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp index 8d46daf033252a13f098cbfa59a39d2e13198be8..86ecec0010fc112f4bf0dbbbabe945375a9b0888 100644 --- a/source/Lib/CommonLib/DepQuant.cpp +++ b/source/Lib/CommonLib/DepQuant.cpp @@ -1059,11 +1059,13 @@ namespace DQIntern m_goRicePar = prvState->m_goRicePar; if( m_remRegBins >= 4 ) { +#if !JVET_N0188_UNIFY_RICEPARA TCoeff rem = (decision.absLevel - 4) >> 1; if( m_goRicePar < 3 && rem > (3<<m_goRicePar)-1 ) { m_goRicePar++; } +#endif m_remRegBins -= (decision.absLevel < 2 ? decision.absLevel : 3); } ::memcpy( m_absLevelsAndCtxInit, prvState->m_absLevelsAndCtxInit, 48*sizeof(uint8_t) ); @@ -1080,7 +1082,9 @@ namespace DQIntern { m_remRegBins = MAX_NUM_REG_BINS_4x4SUBBLOCK - (decision.absLevel < 2 ? decision.absLevel : 3); } +#if !JVET_N0188_UNIFY_RICEPARA m_goRicePar = ( ((decision.absLevel - 4) >> 1) > (3<<0)-1 ? 1 : 0 ); +#endif ::memset( m_absLevelsAndCtxInit, 0, 48*sizeof(uint8_t) ); } @@ -1127,6 +1131,44 @@ namespace DQIntern TCoeff sumGt1 = sumAbs1 - sumNum; m_sigFracBits = m_sigFracBitsArray[scanInfo.sigCtxOffsetNext + (sumAbs1 < 5 ? sumAbs1 : 5)]; m_coeffFracBits = m_gtxFracBitsArray[scanInfo.gtxCtxOffsetNext + (sumGt1 < 4 ? sumGt1 : 4)]; + +#if JVET_N0188_UNIFY_RICEPARA + TCoeff sumAbs = m_absLevelsAndCtxInit[8 + scanInfo.nextInsidePos] >> 8; +#define UPDATE(k) {TCoeff t=levels[scanInfo.nextNbInfoSbb.inPos[k]]; sumAbs+=t; } + if (numIPos == 1) + { + UPDATE(0); + } + else if (numIPos == 2) + { + UPDATE(0); + UPDATE(1); + } + else if (numIPos == 3) + { + UPDATE(0); + UPDATE(1); + UPDATE(2); + } + else if (numIPos == 4) + { + UPDATE(0); + UPDATE(1); + UPDATE(2); + UPDATE(3); + } + else if (numIPos == 5) + { + UPDATE(0); + UPDATE(1); + UPDATE(2); + UPDATE(3); + UPDATE(4); + } +#undef UPDATE + int sumAll = std::max(std::min(31, (int)sumAbs - 4 * 5), 0); + m_goRicePar = g_auiGoRiceParsCoeff[sumAll]; +#endif } else { diff --git a/source/Lib/CommonLib/QuantRDOQ.cpp b/source/Lib/CommonLib/QuantRDOQ.cpp index b844ae48d4320200b8c2457e54fe67991d4af0c7..f0c880324ed192c26afa429e0e037ae94bc72a56 100644 --- a/source/Lib/CommonLib/QuantRDOQ.cpp +++ b/source/Lib/CommonLib/QuantRDOQ.cpp @@ -763,7 +763,11 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID, uint32_t goRiceZero = 0; if( remRegBins < 4 ) { +#if JVET_N0188_UNIFY_RICEPARA + unsigned sumAbs = cctx.templateAbsSum( iScanPos, piDstCoeff, 0 ); +#else unsigned sumAbs = cctx.templateAbsSum( iScanPos, piDstCoeff ); +#endif goRiceParam = g_auiGoRiceParsCoeff [ sumAbs ]; goRiceZero = g_auiGoRicePosCoeff0[0][ sumAbs ]; } @@ -826,11 +830,16 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID, } else if( remRegBins >= 4 ) { +#if JVET_N0188_UNIFY_RICEPARA + int sumAll = cctx.templateAbsSum(iScanPos, piDstCoeff, 4); + goRiceParam = g_auiGoRiceParsCoeff[sumAll]; +#else const uint32_t baseLevel = 4; if( goRiceParam < 3 && ((uiLevel-baseLevel)>>1) > (3<<goRiceParam)-1 ) { goRiceParam++; } +#endif remRegBins -= (uiLevel < 2 ? uiLevel : 3) + (iScanPos != iLastScanPos); } } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 46c32deb691170d6667c2509ef865e2458831985..dc4a2bb999116529b5f521737ef4f7079c4379bc 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -56,6 +56,8 @@ #define JVET_N600_AMVR_TPM_CTX_REDUCTION 1 +#define JVET_N0188_UNIFY_RICEPARA 1 + #define JVET_N0334_MVCLIPPING 1 // prevention of MV stroage overflow and alignment with spec of MV/CPMV modular for AMVP mode #define JVET_N0481_BCW_CONSTRUCTED_AFFINE 1 diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 6fa451665a24aa881d020b81ad286b5d97e55bb7..fbcc65da2807c33f2766f0f709739f6bb8144bfa 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -2715,6 +2715,10 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co unsigned ricePar = 0; for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- ) { +#if JVET_N0188_UNIFY_RICEPARA + int sumAll = cctx.templateAbsSum(scanPos, coeff, 4); + ricePar = g_auiGoRiceParsCoeff[sumAll]; +#endif TCoeff& tcoeff = coeff[ cctx.blockPos( scanPos ) ]; if( tcoeff >= 4 ) { @@ -2722,17 +2726,23 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co int rem = m_BinDecoder.decodeRemAbsEP( ricePar, cctx.extPrec(), cctx.maxLog2TrDRange() ); DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar ); tcoeff += (rem<<1); +#if !JVET_N0188_UNIFY_RICEPARA if( ricePar < 3 && rem > (3<<ricePar)-1 ) { ricePar++; } +#endif } } //===== coeff bypass ==== for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- ) { +#if JVET_N0188_UNIFY_RICEPARA + int sumAll = cctx.templateAbsSum(scanPos, coeff, 0); +#else int sumAll = cctx.templateAbsSum(scanPos, coeff); +#endif int rice = g_auiGoRiceParsCoeff [sumAll]; int pos0 = g_auiGoRicePosCoeff0[std::max(0, state - 1)][sumAll]; int rem = m_BinDecoder.decodeRemAbsEP( rice, cctx.extPrec(), cctx.maxLog2TrDRange() ); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 4aa704fb80230a567c42e2db76a943fc06969653..349e94627bf4a0b89038cf4af8d4a3b53c440fbd 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2594,16 +2594,22 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe unsigned ricePar = 0; for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- ) { +#if JVET_N0188_UNIFY_RICEPARA + int sumAll = cctx.templateAbsSum(scanPos, coeff, 4); + ricePar = g_auiGoRiceParsCoeff[sumAll]; +#endif unsigned absLevel = abs( coeff[ cctx.blockPos( scanPos ) ] ); if( absLevel >= 4 ) { unsigned rem = ( absLevel - 4 ) >> 1; m_BinEncoder.encodeRemAbsEP( rem, ricePar, cctx.extPrec(), cctx.maxLog2TrDRange() ); DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar ); +#if !JVET_N0188_UNIFY_RICEPARA if( ricePar < 3 && rem > (3<<ricePar)-1 ) { ricePar++; } +#endif } } @@ -2612,7 +2618,11 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe { TCoeff Coeff = coeff[ cctx.blockPos( scanPos ) ]; unsigned absLevel = abs( Coeff ); +#if JVET_N0188_UNIFY_RICEPARA + int sumAll = cctx.templateAbsSum(scanPos, coeff, 0); +#else int sumAll = cctx.templateAbsSum(scanPos, coeff); +#endif int rice = g_auiGoRiceParsCoeff [sumAll]; int pos0 = g_auiGoRicePosCoeff0[std::max(0, state - 1)][sumAll]; unsigned rem = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );