Loading source/Lib/CommonLib/ContextModelling.h +21 −2 Original line number Diff line number Diff line Loading @@ -293,10 +293,26 @@ class CUCtx public: CUCtx() : isDQPCoded(false), isChromaQpAdjCoded(false), qgStart(false), #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS numNonZeroCoeffNonTs(0) { violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false; violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; } #else numNonZeroCoeffNonTs(0) {} #endif CUCtx(int _qp) : isDQPCoded(false), isChromaQpAdjCoded(false), qgStart(false), #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS numNonZeroCoeffNonTs(0), qp(_qp) { violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false; violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; } #else numNonZeroCoeffNonTs(0), qp(_qp) {} #endif ~CUCtx() {} public: bool isDQPCoded; Loading @@ -304,6 +320,9 @@ public: bool qgStart; uint32_t numNonZeroCoeffNonTs; int8_t qp; // used as a previous(last) QP and for QP prediction #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS bool violatesLfnstConstrained[MAX_NUM_CHANNEL_TYPE]; #endif }; class MergeCtx Loading source/Lib/CommonLib/DepQuant.cpp +59 −2 Original line number Diff line number Diff line Loading @@ -882,13 +882,17 @@ namespace DQIntern m_goRicePar = 0; m_goRiceZero = 0; } #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB ) const #else void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB, bool zeroOut ) const #endif { const int32_t* goRiceTab = g_goRiceBits[m_goRicePar]; int64_t rdCostA = m_rdCost + pqDataA.deltaDist; int64_t rdCostB = m_rdCost + pqDataB.deltaDist; int64_t rdCostZ = m_rdCost; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( zeroOut ) { rdCostZ = m_rdCost; Loading Loading @@ -924,6 +928,7 @@ namespace DQIntern } else { #endif if( m_remRegBins >= 4 ) { if( pqDataA.absLevel < 4 ) Loading Loading @@ -988,7 +993,9 @@ namespace DQIntern decisionB.prevId = m_stateId; } } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } #endif inline void checkRdCostStart(int32_t lastOffset, const PQData &pqData, Decision &decision) const { Loading Loading @@ -1409,15 +1416,36 @@ namespace DQIntern { ::memcpy( decisions, startDec, 8*sizeof(Decision) ); #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( zeroOut ) { if( spt==SCAN_EOCSBB ) { m_skipStates[0].checkRdCostSkipSbbZeroOut( decisions[0] ); m_skipStates[1].checkRdCostSkipSbbZeroOut( decisions[1] ); m_skipStates[2].checkRdCostSkipSbbZeroOut( decisions[2] ); m_skipStates[3].checkRdCostSkipSbbZeroOut( decisions[3] ); } return; } #endif PQData pqData[4]; m_quant.preQuantCoeff( absCoeff, pqData, quanCoeff ); #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS m_prevStates[0].checkRdCosts( spt, pqData[0], pqData[2], decisions[0], decisions[2]); m_prevStates[1].checkRdCosts( spt, pqData[0], pqData[2], decisions[2], decisions[0]); m_prevStates[2].checkRdCosts( spt, pqData[3], pqData[1], decisions[1], decisions[3]); m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1]); #else m_prevStates[0].checkRdCosts( spt, pqData[0], pqData[2], decisions[0], decisions[2], zeroOut ); m_prevStates[1].checkRdCosts( spt, pqData[0], pqData[2], decisions[2], decisions[0], zeroOut ); m_prevStates[2].checkRdCosts( spt, pqData[3], pqData[1], decisions[1], decisions[3], zeroOut ); m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1], zeroOut ); #endif if( spt==SCAN_EOCSBB ) { #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( zeroOut ) { m_skipStates[0].checkRdCostSkipSbbZeroOut( decisions[0] ); Loading @@ -1427,17 +1455,25 @@ namespace DQIntern } else { #endif m_skipStates[0].checkRdCostSkipSbb( decisions[0] ); m_skipStates[1].checkRdCostSkipSbb( decisions[1] ); m_skipStates[2].checkRdCostSkipSbb( decisions[2] ); m_skipStates[3].checkRdCostSkipSbb( decisions[3] ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } #endif } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( !zeroOut ) { #endif m_startState.checkRdCostStart( lastOffset, pqData[0], decisions[0] ); m_startState.checkRdCostStart( lastOffset, pqData[2], decisions[2] ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } #endif } void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, int quantCoeff ) Loading @@ -1459,7 +1495,11 @@ namespace DQIntern m_currStates[3].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[3] ); ::memcpy( decisions+4, decisions, 4*sizeof(Decision) ); } #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS else if( !zeroOut ) #else else #endif { switch( scanInfo.nextNbInfoSbb.num ) { Loading Loading @@ -1544,10 +1584,17 @@ namespace DQIntern zeroOutforThres = zeroOut || (32 < tuPars.m_height || 32 < tuPars.m_width); //===== find first test position ===== int firstTestPos = numCoeff - 1; #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && width >= 4 && height >= 4 ) { firstTestPos = ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) ? 7 : 15 ; } #else if( lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) ) { firstTestPos = 7; } #endif const TCoeff defaultQuantisationCoefficient = (TCoeff)m_quant.getQScale(); const TCoeff thres = m_quant.getLastThreshold(); for( ; firstTestPos >= 0; firstTestPos-- ) Loading Loading @@ -1594,6 +1641,7 @@ namespace DQIntern for( int scanIdx = firstTestPos; scanIdx >= 0; scanIdx-- ) { const ScanInfo& scanInfo = tuPars.m_scanInfo[ scanIdx ]; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS bool lfnstZeroOut = lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && width >= 4 && height >= 4 && ( ( ( ( width >= 8 && height >= 8 ) && scanIdx >= 16 ) || ( ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) && scanIdx >= 8 ) ) && scanIdx < 48 ); if (enableScalingLists) Loading @@ -1603,6 +1651,15 @@ namespace DQIntern } else xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)) || lfnstZeroOut, defaultQuantisationCoefficient ); #else if (enableScalingLists) { m_quant.initQuantBlock(tu, compID, cQP, lambda, quantCoeff[scanInfo.rasterPos]); xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), quantCoeff[scanInfo.rasterPos] ); } else xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), defaultQuantisationCoefficient ); #endif } //===== find best path ===== Loading source/Lib/CommonLib/TrQuant.cpp +60 −4 Original line number Diff line number Diff line Loading @@ -366,13 +366,15 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID ) #endif bool transposeFlag = getTransposeFlag( intraMode ); const int sbSize = whge3 ? 8 : 4; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int subGrpXMax = ( height == 4 && width > 8 ) ? 2 : 1; const int subGrpYMax = ( width == 4 && height > 8 ) ? 2 : 1; #endif bool tu4x4Flag = ( width == 4 && height == 4 ); bool tu8x8Flag = ( width == 8 && height == 8 ); TCoeff* lfnstTemp; TCoeff* coeffTemp; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS for( int subGroupX = 0; subGroupX < subGrpXMax; subGroupX++ ) { for( int subGroupY = 0; subGroupY < subGrpYMax; subGroupY++ ) Loading @@ -382,7 +384,11 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID ) int y; lfnstTemp = m_tempInMatrix; // inverse spectral rearrangement coeffTemp = m_plTempCoeff + offsetX + offsetY; #else int y; lfnstTemp = m_tempInMatrix; // inverse spectral rearrangement coeffTemp = m_plTempCoeff; #endif TCoeff * dst = lfnstTemp; const ScanElement * scanPtr = scan; for( y = 0; y < 16; y++ ) Loading Loading @@ -433,8 +439,10 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID ) coeffTemp += width; } } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } } // subGroupX #endif } } } Loading Loading @@ -464,14 +472,17 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons bool transposeFlag = getTransposeFlag( intraMode ); const int sbSize = whge3 ? 8 : 4; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int subGrpXMax = ( height == 4 && width > 8 ) ? 2 : 1; const int subGrpYMax = ( width == 4 && height > 8 ) ? 2 : 1; #endif bool tu4x4Flag = ( width == 4 && height == 4 ); bool tu8x8Flag = ( width == 8 && height == 8 ); TCoeff* lfnstTemp; TCoeff* coeffTemp; TCoeff* tempCoeff = loadTr ? m_mtsCoeffs[ tu.mtsIdx ] : m_plTempCoeff; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS for( int subGroupX = 0; subGroupX < subGrpXMax; subGroupX++ ) { for( int subGroupY = 0; subGroupY < subGrpYMax; subGroupY++ ) Loading @@ -481,6 +492,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons int y; lfnstTemp = m_tempInMatrix; // forward low frequency non-separable transform coeffTemp = tempCoeff + offsetX + offsetY; #else int y; lfnstTemp = m_tempInMatrix; // forward low frequency non-separable transform coeffTemp = tempCoeff; #endif if( transposeFlag ) { Loading Loading @@ -524,8 +540,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons fwdLfnstNxN( m_tempInMatrix, m_tempOutMatrix, g_lfnstLut[ intraMode ], lfnstIdx - 1, sbSize, ( tu4x4Flag || tu8x8Flag ) ? 8 : 16 ); lfnstTemp = m_tempOutMatrix; // forward spectral rearrangement #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS coeffTemp = tempCoeff + offsetX + offsetY; #else coeffTemp = tempCoeff; #endif const ScanElement * scanPtr = scan; int lfnstCoeffNum = ( sbSize == 4 ) ? sbSize * sbSize : 48; for( y = 0; y < lfnstCoeffNum; y++ ) Loading @@ -533,8 +552,10 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons coeffTemp[ scanPtr->idx ] = *lfnstTemp++; scanPtr++; } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } } // subGroupX #endif } } } Loading Loading @@ -823,8 +844,26 @@ void TrQuant::xT( const TransformUnit &tu, const ComponentID &compID, const CPel getTrTypes ( tu, compID, trTypeHor, trTypeVer ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; const int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; #else int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; if( tu.cs->sps->getUseLFNST() && tu.cu->lfnstIdx ) { if( (width == 4 && height > 4) || (width > 4 && height == 4) ) { skipWidth = width - 4; skipHeight = height - 4; } else if( (width >= 8 && height >= 8) ) { skipWidth = width - 8; skipHeight = height - 8; } } #endif #if RExt__DECODER_DEBUG_TOOL_STATISTICS if ( trTypeHor != DCT2 ) Loading Loading @@ -890,9 +929,26 @@ void TrQuant::xIT( const TransformUnit &tu, const ComponentID &compID, const CCo int trTypeVer = DCT2; getTrTypes ( tu, compID, trTypeHor, trTypeVer ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; const int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; #else int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; if( tu.cs->sps->getUseLFNST() && tu.cu->lfnstIdx ) { if( (width == 4 && height > 4) || (width > 4 && height == 4) ) { skipWidth = width - 4; skipHeight = height - 4; } else if( (width >= 8 && height >= 8) ) { skipWidth = width - 8; skipHeight = height - 8; } } #endif TCoeff *block = ( TCoeff * ) alloca( width * height * sizeof( TCoeff ) ); Loading source/Lib/CommonLib/TypeDef.h +2 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,8 @@ #define JVET_O0364_PDPC_DC 1 // JVET-O0364 Part 4: align PDPC process for DC with the one for Planar #define JVET_O0364_PDPC_ANGULAR 1 // JVET-O0364 Part 5: simplify PDPC process for angular modes #define JVET_O0094_LFNST_ZERO_PRIM_COEFFS 1 // JVET-O0049: CE6-2.1a, LFNST involves zeroing of primary only coefficient positions #define JVET_O0294_TRANSFORM_CLEANUP 1 // JVET-O0294: Context modelling for MTS index #define JVET_O1124_ALLOW_CCLM_COND 1 // JVET-O1124/JVET-O0196: CCLM restriction to reduce luma-chroma latency for chroma separate tree Loading source/Lib/CommonLib/UnitTools.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ uint32_t CU::getNumNonZeroCoeffNonTs( const CodingUnit& cu, const bool lumaFlag, return count; } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS uint32_t CU::getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool lumaFlag, const bool chromaFlag ) { uint32_t count = 0; Loading @@ -271,6 +272,7 @@ uint32_t CU::getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool return count; } #endif bool CU::divideTuInRows( const CodingUnit &cu ) { Loading Loading @@ -4552,7 +4554,7 @@ uint32_t TU::getNumNonZeroCoeffsNonTS( const TransformUnit& tu, const bool bLuma } return count; } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS uint32_t TU::getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit& tu, const bool lumaFlag, const bool chromaFlag ) { const uint32_t lumaWidth = tu.blocks[ 0 ].width, chromaWidth = tu.blocks[ 1 ].width; Loading Loading @@ -4594,6 +4596,7 @@ uint32_t TU::getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit& tu, const b } return count; } #endif bool TU::needsSqrt2Scale( const TransformUnit &tu, const ComponentID &compID ) { Loading Loading
source/Lib/CommonLib/ContextModelling.h +21 −2 Original line number Diff line number Diff line Loading @@ -293,10 +293,26 @@ class CUCtx public: CUCtx() : isDQPCoded(false), isChromaQpAdjCoded(false), qgStart(false), #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS numNonZeroCoeffNonTs(0) { violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false; violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; } #else numNonZeroCoeffNonTs(0) {} #endif CUCtx(int _qp) : isDQPCoded(false), isChromaQpAdjCoded(false), qgStart(false), #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS numNonZeroCoeffNonTs(0), qp(_qp) { violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false; violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; } #else numNonZeroCoeffNonTs(0), qp(_qp) {} #endif ~CUCtx() {} public: bool isDQPCoded; Loading @@ -304,6 +320,9 @@ public: bool qgStart; uint32_t numNonZeroCoeffNonTs; int8_t qp; // used as a previous(last) QP and for QP prediction #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS bool violatesLfnstConstrained[MAX_NUM_CHANNEL_TYPE]; #endif }; class MergeCtx Loading
source/Lib/CommonLib/DepQuant.cpp +59 −2 Original line number Diff line number Diff line Loading @@ -882,13 +882,17 @@ namespace DQIntern m_goRicePar = 0; m_goRiceZero = 0; } #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB ) const #else void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB, bool zeroOut ) const #endif { const int32_t* goRiceTab = g_goRiceBits[m_goRicePar]; int64_t rdCostA = m_rdCost + pqDataA.deltaDist; int64_t rdCostB = m_rdCost + pqDataB.deltaDist; int64_t rdCostZ = m_rdCost; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( zeroOut ) { rdCostZ = m_rdCost; Loading Loading @@ -924,6 +928,7 @@ namespace DQIntern } else { #endif if( m_remRegBins >= 4 ) { if( pqDataA.absLevel < 4 ) Loading Loading @@ -988,7 +993,9 @@ namespace DQIntern decisionB.prevId = m_stateId; } } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } #endif inline void checkRdCostStart(int32_t lastOffset, const PQData &pqData, Decision &decision) const { Loading Loading @@ -1409,15 +1416,36 @@ namespace DQIntern { ::memcpy( decisions, startDec, 8*sizeof(Decision) ); #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( zeroOut ) { if( spt==SCAN_EOCSBB ) { m_skipStates[0].checkRdCostSkipSbbZeroOut( decisions[0] ); m_skipStates[1].checkRdCostSkipSbbZeroOut( decisions[1] ); m_skipStates[2].checkRdCostSkipSbbZeroOut( decisions[2] ); m_skipStates[3].checkRdCostSkipSbbZeroOut( decisions[3] ); } return; } #endif PQData pqData[4]; m_quant.preQuantCoeff( absCoeff, pqData, quanCoeff ); #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS m_prevStates[0].checkRdCosts( spt, pqData[0], pqData[2], decisions[0], decisions[2]); m_prevStates[1].checkRdCosts( spt, pqData[0], pqData[2], decisions[2], decisions[0]); m_prevStates[2].checkRdCosts( spt, pqData[3], pqData[1], decisions[1], decisions[3]); m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1]); #else m_prevStates[0].checkRdCosts( spt, pqData[0], pqData[2], decisions[0], decisions[2], zeroOut ); m_prevStates[1].checkRdCosts( spt, pqData[0], pqData[2], decisions[2], decisions[0], zeroOut ); m_prevStates[2].checkRdCosts( spt, pqData[3], pqData[1], decisions[1], decisions[3], zeroOut ); m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1], zeroOut ); #endif if( spt==SCAN_EOCSBB ) { #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( zeroOut ) { m_skipStates[0].checkRdCostSkipSbbZeroOut( decisions[0] ); Loading @@ -1427,17 +1455,25 @@ namespace DQIntern } else { #endif m_skipStates[0].checkRdCostSkipSbb( decisions[0] ); m_skipStates[1].checkRdCostSkipSbb( decisions[1] ); m_skipStates[2].checkRdCostSkipSbb( decisions[2] ); m_skipStates[3].checkRdCostSkipSbb( decisions[3] ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } #endif } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( !zeroOut ) { #endif m_startState.checkRdCostStart( lastOffset, pqData[0], decisions[0] ); m_startState.checkRdCostStart( lastOffset, pqData[2], decisions[2] ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } #endif } void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, int quantCoeff ) Loading @@ -1459,7 +1495,11 @@ namespace DQIntern m_currStates[3].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[3] ); ::memcpy( decisions+4, decisions, 4*sizeof(Decision) ); } #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS else if( !zeroOut ) #else else #endif { switch( scanInfo.nextNbInfoSbb.num ) { Loading Loading @@ -1544,10 +1584,17 @@ namespace DQIntern zeroOutforThres = zeroOut || (32 < tuPars.m_height || 32 < tuPars.m_width); //===== find first test position ===== int firstTestPos = numCoeff - 1; #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS if( lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && width >= 4 && height >= 4 ) { firstTestPos = ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) ? 7 : 15 ; } #else if( lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) ) { firstTestPos = 7; } #endif const TCoeff defaultQuantisationCoefficient = (TCoeff)m_quant.getQScale(); const TCoeff thres = m_quant.getLastThreshold(); for( ; firstTestPos >= 0; firstTestPos-- ) Loading Loading @@ -1594,6 +1641,7 @@ namespace DQIntern for( int scanIdx = firstTestPos; scanIdx >= 0; scanIdx-- ) { const ScanInfo& scanInfo = tuPars.m_scanInfo[ scanIdx ]; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS bool lfnstZeroOut = lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && width >= 4 && height >= 4 && ( ( ( ( width >= 8 && height >= 8 ) && scanIdx >= 16 ) || ( ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) && scanIdx >= 8 ) ) && scanIdx < 48 ); if (enableScalingLists) Loading @@ -1603,6 +1651,15 @@ namespace DQIntern } else xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)) || lfnstZeroOut, defaultQuantisationCoefficient ); #else if (enableScalingLists) { m_quant.initQuantBlock(tu, compID, cQP, lambda, quantCoeff[scanInfo.rasterPos]); xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), quantCoeff[scanInfo.rasterPos] ); } else xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), defaultQuantisationCoefficient ); #endif } //===== find best path ===== Loading
source/Lib/CommonLib/TrQuant.cpp +60 −4 Original line number Diff line number Diff line Loading @@ -366,13 +366,15 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID ) #endif bool transposeFlag = getTransposeFlag( intraMode ); const int sbSize = whge3 ? 8 : 4; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int subGrpXMax = ( height == 4 && width > 8 ) ? 2 : 1; const int subGrpYMax = ( width == 4 && height > 8 ) ? 2 : 1; #endif bool tu4x4Flag = ( width == 4 && height == 4 ); bool tu8x8Flag = ( width == 8 && height == 8 ); TCoeff* lfnstTemp; TCoeff* coeffTemp; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS for( int subGroupX = 0; subGroupX < subGrpXMax; subGroupX++ ) { for( int subGroupY = 0; subGroupY < subGrpYMax; subGroupY++ ) Loading @@ -382,7 +384,11 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID ) int y; lfnstTemp = m_tempInMatrix; // inverse spectral rearrangement coeffTemp = m_plTempCoeff + offsetX + offsetY; #else int y; lfnstTemp = m_tempInMatrix; // inverse spectral rearrangement coeffTemp = m_plTempCoeff; #endif TCoeff * dst = lfnstTemp; const ScanElement * scanPtr = scan; for( y = 0; y < 16; y++ ) Loading Loading @@ -433,8 +439,10 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID ) coeffTemp += width; } } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } } // subGroupX #endif } } } Loading Loading @@ -464,14 +472,17 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons bool transposeFlag = getTransposeFlag( intraMode ); const int sbSize = whge3 ? 8 : 4; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int subGrpXMax = ( height == 4 && width > 8 ) ? 2 : 1; const int subGrpYMax = ( width == 4 && height > 8 ) ? 2 : 1; #endif bool tu4x4Flag = ( width == 4 && height == 4 ); bool tu8x8Flag = ( width == 8 && height == 8 ); TCoeff* lfnstTemp; TCoeff* coeffTemp; TCoeff* tempCoeff = loadTr ? m_mtsCoeffs[ tu.mtsIdx ] : m_plTempCoeff; #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS for( int subGroupX = 0; subGroupX < subGrpXMax; subGroupX++ ) { for( int subGroupY = 0; subGroupY < subGrpYMax; subGroupY++ ) Loading @@ -481,6 +492,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons int y; lfnstTemp = m_tempInMatrix; // forward low frequency non-separable transform coeffTemp = tempCoeff + offsetX + offsetY; #else int y; lfnstTemp = m_tempInMatrix; // forward low frequency non-separable transform coeffTemp = tempCoeff; #endif if( transposeFlag ) { Loading Loading @@ -524,8 +540,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons fwdLfnstNxN( m_tempInMatrix, m_tempOutMatrix, g_lfnstLut[ intraMode ], lfnstIdx - 1, sbSize, ( tu4x4Flag || tu8x8Flag ) ? 8 : 16 ); lfnstTemp = m_tempOutMatrix; // forward spectral rearrangement #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS coeffTemp = tempCoeff + offsetX + offsetY; #else coeffTemp = tempCoeff; #endif const ScanElement * scanPtr = scan; int lfnstCoeffNum = ( sbSize == 4 ) ? sbSize * sbSize : 48; for( y = 0; y < lfnstCoeffNum; y++ ) Loading @@ -533,8 +552,10 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons coeffTemp[ scanPtr->idx ] = *lfnstTemp++; scanPtr++; } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS } } // subGroupX #endif } } } Loading Loading @@ -823,8 +844,26 @@ void TrQuant::xT( const TransformUnit &tu, const ComponentID &compID, const CPel getTrTypes ( tu, compID, trTypeHor, trTypeVer ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; const int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; #else int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; if( tu.cs->sps->getUseLFNST() && tu.cu->lfnstIdx ) { if( (width == 4 && height > 4) || (width > 4 && height == 4) ) { skipWidth = width - 4; skipHeight = height - 4; } else if( (width >= 8 && height >= 8) ) { skipWidth = width - 8; skipHeight = height - 8; } } #endif #if RExt__DECODER_DEBUG_TOOL_STATISTICS if ( trTypeHor != DCT2 ) Loading Loading @@ -890,9 +929,26 @@ void TrQuant::xIT( const TransformUnit &tu, const ComponentID &compID, const CCo int trTypeVer = DCT2; getTrTypes ( tu, compID, trTypeHor, trTypeVer ); #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS const int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; const int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; #else int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; if( tu.cs->sps->getUseLFNST() && tu.cu->lfnstIdx ) { if( (width == 4 && height > 4) || (width > 4 && height == 4) ) { skipWidth = width - 4; skipHeight = height - 4; } else if( (width >= 8 && height >= 8) ) { skipWidth = width - 8; skipHeight = height - 8; } } #endif TCoeff *block = ( TCoeff * ) alloca( width * height * sizeof( TCoeff ) ); Loading
source/Lib/CommonLib/TypeDef.h +2 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,8 @@ #define JVET_O0364_PDPC_DC 1 // JVET-O0364 Part 4: align PDPC process for DC with the one for Planar #define JVET_O0364_PDPC_ANGULAR 1 // JVET-O0364 Part 5: simplify PDPC process for angular modes #define JVET_O0094_LFNST_ZERO_PRIM_COEFFS 1 // JVET-O0049: CE6-2.1a, LFNST involves zeroing of primary only coefficient positions #define JVET_O0294_TRANSFORM_CLEANUP 1 // JVET-O0294: Context modelling for MTS index #define JVET_O1124_ALLOW_CCLM_COND 1 // JVET-O1124/JVET-O0196: CCLM restriction to reduce luma-chroma latency for chroma separate tree Loading
source/Lib/CommonLib/UnitTools.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ uint32_t CU::getNumNonZeroCoeffNonTs( const CodingUnit& cu, const bool lumaFlag, return count; } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS uint32_t CU::getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool lumaFlag, const bool chromaFlag ) { uint32_t count = 0; Loading @@ -271,6 +272,7 @@ uint32_t CU::getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool return count; } #endif bool CU::divideTuInRows( const CodingUnit &cu ) { Loading Loading @@ -4552,7 +4554,7 @@ uint32_t TU::getNumNonZeroCoeffsNonTS( const TransformUnit& tu, const bool bLuma } return count; } #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS uint32_t TU::getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit& tu, const bool lumaFlag, const bool chromaFlag ) { const uint32_t lumaWidth = tu.blocks[ 0 ].width, chromaWidth = tu.blocks[ 1 ].width; Loading Loading @@ -4594,6 +4596,7 @@ uint32_t TU::getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit& tu, const b } return count; } #endif bool TU::needsSqrt2Scale( const TransformUnit &tu, const ComponentID &compID ) { Loading