diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp index f8044d3d7fd7e43c522531f5bd2dd04d4d0fd48b..845fba9a09835a684a39341b7deb1cf2118df09a 100644 --- a/source/Lib/CommonLib/DepQuant.cpp +++ b/source/Lib/CommonLib/DepQuant.cpp @@ -916,7 +916,7 @@ namespace DQIntern template<uint8_t numIPos> inline void updateState(const ScanInfo &scanInfo, const State *prevStates, const Decision &decision, const int baseLevel, const bool extRiceFlag); inline void updateStateEOS(const ScanInfo &scanInfo, const State *prevStates, const State *skipStates, - const Decision &decision); + const Decision &decision, const int baseLevel, const bool extRiceFlag); inline void init() { @@ -1255,7 +1255,7 @@ namespace DQIntern } inline void State::updateStateEOS(const ScanInfo &scanInfo, const State *prevStates, const State *skipStates, - const Decision &decision) + const Decision &decision, const int baseLevel, const bool extRiceFlag) { m_rdCost = decision.rdCost; if( decision.prevId > -2 ) @@ -1264,31 +1264,76 @@ namespace DQIntern if( decision.prevId >= 4 ) { CHECK( decision.absLevel != 0, "cannot happen" ); - prvState = skipStates + ( decision.prevId - 4 ); - m_numSigSbb = 0; + prvState = skipStates + ( decision.prevId - 4 ); + m_numSigSbb = 0; + m_remRegBins = prvState->m_remRegBins; ::memset( m_absLevelsAndCtxInit, 0, 16*sizeof(uint8_t) ); } else if( decision.prevId >= 0 ) { - prvState = prevStates + decision.prevId; - m_numSigSbb = prvState->m_numSigSbb + !!decision.absLevel; + prvState = prevStates + decision.prevId; + m_numSigSbb = prvState->m_numSigSbb + !!decision.absLevel; + m_remRegBins = prvState->m_remRegBins - 1; + m_remRegBins -= decision.absLevel < 2 ? (unsigned) decision.absLevel : 3; ::memcpy( m_absLevelsAndCtxInit, prvState->m_absLevelsAndCtxInit, 16*sizeof(uint8_t) ); } else { - m_numSigSbb = 1; + m_numSigSbb = 1; + int ctxBinSampleRatio = isLuma(scanInfo.chType) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA + : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA; + m_remRegBins = (effWidth * effHeight * ctxBinSampleRatio) / 16; + m_remRegBins -= decision.absLevel < 2 ? (unsigned) decision.absLevel : 3; ::memset( m_absLevelsAndCtxInit, 0, 16*sizeof(uint8_t) ); } reinterpret_cast<uint8_t*>(m_absLevelsAndCtxInit)[ scanInfo.insidePos ] = (uint8_t)std::min<TCoeff>( 255, decision.absLevel ); m_commonCtx.update( scanInfo, prvState, *this ); - TCoeff tinit = m_absLevelsAndCtxInit[ 8 + scanInfo.nextInsidePos ]; - TCoeff sumNum = tinit & 7; - TCoeff sumAbs1 = ( tinit >> 3 ) & 31; - TCoeff sumGt1 = sumAbs1 - sumNum; - m_sigFracBits = m_sigFracBitsArray[ scanInfo.sigCtxOffsetNext + std::min<TCoeff>( (sumAbs1+1)>>1, 3 ) ]; - m_coeffFracBits = m_gtxFracBitsArray[ scanInfo.gtxCtxOffsetNext + ( sumGt1 < 4 ? sumGt1 : 4 ) ]; + if (m_remRegBins >= 4) + { + TCoeff tinit = m_absLevelsAndCtxInit[8 + scanInfo.nextInsidePos]; + TCoeff sumNum = tinit & 7; + TCoeff sumAbs1 = ( tinit >> 3 ) & 31; + TCoeff sumGt1 = sumAbs1 - sumNum; + TCoeff sumAbs = tinit >> 8; + m_sigFracBits = m_sigFracBitsArray[ scanInfo.sigCtxOffsetNext + std::min<TCoeff>( (sumAbs1+1)>>1, 3 ) ]; + m_coeffFracBits = m_gtxFracBitsArray[ scanInfo.gtxCtxOffsetNext + ( sumGt1 < 4 ? sumGt1 : 4 ) ]; + + if (extRiceFlag) + { + unsigned currentShift = CoeffCodingContext::templateAbsCompare(sumAbs); + sumAbs = sumAbs >> currentShift; + int sumAll = std::max(std::min(31, (int) sumAbs - (int) baseLevel), 0); + m_goRicePar = g_goRiceParsCoeff[sumAll]; + m_goRicePar += currentShift; + } + else + { + int sumAll = std::max(std::min(31, (int) sumAbs - 4 * 5), 0); + m_goRicePar = g_goRiceParsCoeff[sumAll]; + } + } + else + { + TCoeff tinit = m_absLevelsAndCtxInit[8 + scanInfo.nextInsidePos]; + TCoeff sumAbs = tinit >> 8; + + if (extRiceFlag) + { + unsigned currentShift = CoeffCodingContext::templateAbsCompare(sumAbs); + sumAbs = sumAbs >> currentShift; + sumAbs = std::min<TCoeff>(31, sumAbs); + m_goRicePar = g_goRiceParsCoeff[sumAbs]; + m_goRicePar += currentShift; + } + else + { + sumAbs = std::min<TCoeff>(31, sumAbs); + m_goRicePar = g_goRiceParsCoeff[sumAbs]; + } + m_goRiceZero = g_goRicePosCoeff0(m_stateId, m_goRicePar); + } } } @@ -1312,16 +1357,6 @@ namespace DQIntern const int sigNSbb = ( ( scanInfo.nextSbbRight ? sbbFlags[ scanInfo.nextSbbRight ] : false ) || ( scanInfo.nextSbbBelow ? sbbFlags[ scanInfo.nextSbbBelow ] : false ) ? 1 : 0 ); currState.m_numSigSbb = 0; - if (prevState) - { - currState.m_remRegBins = prevState->m_remRegBins; - } - else - { - int ctxBinSampleRatio = isLuma(scanInfo.chType) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA - : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA; - currState.m_remRegBins = (currState.effWidth * currState.effHeight *ctxBinSampleRatio) / 16; - } currState.m_goRicePar = 0; currState.m_refSbbCtxId = currState.m_stateId; currState.m_sbbFracBits = m_sbbFlagBits[ sigNSbb ]; @@ -1470,10 +1505,10 @@ namespace DQIntern if( scanInfo.eosbb ) { m_commonCtx.swap(); - m_currStates[0].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[0] ); - m_currStates[1].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[1] ); - m_currStates[2].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[2] ); - m_currStates[3].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[3] ); + m_currStates[0].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[0], m_baseLevel, m_extRiceRRCFlag ); + m_currStates[1].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[1], m_baseLevel, m_extRiceRRCFlag ); + m_currStates[2].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[2], m_baseLevel, m_extRiceRRCFlag ); + m_currStates[3].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[3], m_baseLevel, m_extRiceRRCFlag ); ::memcpy( decisions+4, decisions, 4*sizeof(Decision) ); } else if( !zeroOut )