diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index e187f42429b453ffb1fefad9ccce2b6ffb86ec2c..ad04968c430c57583f3f84fe6617df6b4427b8ab 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -70,6 +70,10 @@ public: int cgPosX () const { return m_subSetPosX; } unsigned width () const { return m_width; } unsigned height () const { return m_height; } +#if JVET_M0297_32PT_MTS_ZERO_OUT + unsigned log2CGWidth () const { return m_log2CGWidth; } + unsigned log2CGHeight () const { return m_log2CGHeight; } +#endif unsigned log2CGSize () const { return m_log2CGSize; } unsigned log2BlockWidth () const { return m_log2BlockWidth; } unsigned log2BlockHeight () const { return m_log2BlockHeight; } diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp index b50575d4089947065b4264e2c3af08bb25783fd3..6b1c5e9c7418f31b2d6240b12226d6ddeef8c346 100644 --- a/source/Lib/CommonLib/DepQuant.cpp +++ b/source/Lib/CommonLib/DepQuant.cpp @@ -87,6 +87,10 @@ namespace DQIntern NbInfoSbb nextNbInfoSbb; int nextSbbRight; int nextSbbBelow; +#if JVET_M0297_32PT_MTS_ZERO_OUT + int posX; + int posY; +#endif }; class Rom; @@ -468,6 +472,10 @@ namespace DQIntern scanInfo.spt = SCAN_SOCSBB; else if( scanInfo.eosbb && scanIdx > 0 && scanIdx < m_numCoeff - m_sbbSize ) scanInfo.spt = SCAN_EOCSBB; +#if JVET_M0297_32PT_MTS_ZERO_OUT + scanInfo.posX = m_scanId2PosX[ scanIdx ]; + scanInfo.posY = m_scanId2PosY[ scanIdx ]; +#endif if( scanIdx ) { const int nextScanIdx = scanIdx - 1; @@ -1034,12 +1042,66 @@ namespace DQIntern m_goRiceZero = 0; } +#if JVET_M0297_32PT_MTS_ZERO_OUT + void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB, bool zeroFix) const +#else void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB) const +#endif { const int32_t* goRiceTab = g_goRiceBits[m_goRicePar]; +#if JVET_M0297_32PT_MTS_ZERO_OUT + int64_t rdCostA; + int64_t rdCostB; + int64_t rdCostZ; +#else int64_t rdCostA = m_rdCost + pqDataA.deltaDist; int64_t rdCostB = m_rdCost + pqDataB.deltaDist; int64_t rdCostZ = m_rdCost; +#endif +#if JVET_M0297_32PT_MTS_ZERO_OUT + if( zeroFix ) + { + rdCostZ = m_rdCost; +#if JVET_M0173_MOVE_GT2_TO_FIRST_PASS + if( m_remRegBins >= 4 ) +#else + if( m_remRegBins >= 3 ) +#endif + { + if( spt == SCAN_ISCSBB ) + { + rdCostZ += m_sigFracBits.intBits[0]; + } + else if( spt == SCAN_SOCSBB ) + { + rdCostZ += m_sbbFracBits.intBits[1] + m_sigFracBits.intBits[0]; + } + else if( m_numSigSbb ) + { + rdCostZ += m_sigFracBits.intBits[0]; + } + else + { + rdCostZ = decisionA.rdCost; + } + } + else + { + rdCostZ += goRiceTab[m_goRiceZero]; + } + if( rdCostZ < decisionA.rdCost ) + { + decisionA.rdCost = rdCostZ; + decisionA.absLevel = 0; + decisionA.prevId = m_stateId; + } + } + else + { + rdCostA = m_rdCost + pqDataA.deltaDist; + rdCostB = m_rdCost + pqDataB.deltaDist; + rdCostZ = m_rdCost; +#endif #if JVET_M0173_MOVE_GT2_TO_FIRST_PASS if( m_remRegBins >= 4 ) #else @@ -1107,6 +1169,9 @@ namespace DQIntern decisionB.absLevel = pqDataB.absLevel; decisionB.prevId = m_stateId; } +#if JVET_M0297_32PT_MTS_ZERO_OUT + } +#endif } inline void checkRdCostStart(int32_t lastOffset, const PQData &pqData, Decision &decision) const @@ -1140,6 +1205,16 @@ namespace DQIntern } } +#if JVET_M0297_32PT_MTS_ZERO_OUT + inline void checkRdCostSkipSbbZeroFix(Decision &decision) const + { + int64_t rdCost = m_rdCost + m_sbbFracBits.intBits[0]; + decision.rdCost = rdCost; + decision.absLevel = 0; + decision.prevId = 4 + m_stateId; + } +#endif + private: int64_t m_rdCost; uint16_t m_absLevelsAndCtxInit[24]; // 16x8bit for abs levels + 16x16bit for ctx init id @@ -1450,8 +1525,13 @@ namespace DQIntern void dequant ( const TransformUnit& tu, CoeffBuf& recCoeff, const ComponentID compID, const QpParam& cQP ) const; private: +#if JVET_M0297_32PT_MTS_ZERO_OUT + void xDecideAndUpdate ( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroFix ); + void xDecide ( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions, bool zeroFix ); +#else void xDecideAndUpdate ( const TCoeff absCoeff, const ScanInfo& scanInfo ); void xDecide ( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions ); +#endif private: CommonCtx m_commonCtx; @@ -1489,34 +1569,73 @@ namespace DQIntern #undef DINIT +#if JVET_M0297_32PT_MTS_ZERO_OUT + void DepQuant::xDecide( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions, bool zeroFix) +#else void DepQuant::xDecide( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions) +#endif { ::memcpy( decisions, startDec, 8*sizeof(Decision) ); PQData pqData[4]; m_quant.preQuantCoeff( absCoeff, pqData ); +#if JVET_M0297_32PT_MTS_ZERO_OUT + m_prevStates[0].checkRdCosts( spt, pqData[0], pqData[2], decisions[0], decisions[2], zeroFix); + m_prevStates[1].checkRdCosts( spt, pqData[0], pqData[2], decisions[2], decisions[0], zeroFix); + m_prevStates[2].checkRdCosts( spt, pqData[3], pqData[1], decisions[1], decisions[3], zeroFix); + m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1], zeroFix); +#else 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]); +#endif if( spt==SCAN_EOCSBB ) { +#if JVET_M0297_32PT_MTS_ZERO_OUT + if( zeroFix ) + { + m_skipStates[0].checkRdCostSkipSbbZeroFix( decisions[0] ); + m_skipStates[1].checkRdCostSkipSbbZeroFix( decisions[1] ); + m_skipStates[2].checkRdCostSkipSbbZeroFix( decisions[2] ); + m_skipStates[3].checkRdCostSkipSbbZeroFix( decisions[3] ); + } + 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_M0297_32PT_MTS_ZERO_OUT + } +#endif } +#if JVET_M0297_32PT_MTS_ZERO_OUT + if (!zeroFix) { +#endif m_startState.checkRdCostStart( lastOffset, pqData[0], decisions[0] ); m_startState.checkRdCostStart( lastOffset, pqData[2], decisions[2] ); +#if JVET_M0297_32PT_MTS_ZERO_OUT + } +#endif } +#if JVET_M0297_32PT_MTS_ZERO_OUT + void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroFix ) +#else void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo ) +#endif { Decision* decisions = m_trellis[ scanInfo.scanIdx ]; std::swap( m_prevStates, m_currStates ); +#if JVET_M0297_32PT_MTS_ZERO_OUT + xDecide( scanInfo.spt, absCoeff, lastOffset(scanInfo.scanIdx), decisions, zeroFix ); +#else xDecide( scanInfo.spt, absCoeff, lastOffset(scanInfo.scanIdx), decisions); +#endif if( scanInfo.scanIdx ) { @@ -1592,6 +1711,12 @@ namespace DQIntern ::memset( tu.getCoeffs( compID ).buf, 0x00, numCoeff*sizeof(TCoeff) ); absSum = 0; +#if JVET_M0297_32PT_MTS_ZERO_OUT + const CompArea& area = tu.blocks[compID]; + const uint32_t width = area.width; + const uint32_t height = area.height; +#endif + //===== find first test position ===== int firstTestPos = numCoeff - 1; const TCoeff thres = m_quant.getLastThreshold(); @@ -1616,12 +1741,28 @@ namespace DQIntern } m_startState.init(); +#if JVET_M0297_32PT_MTS_ZERO_OUT + int effWidth = width, effHeight = height; +#if JVET_M0464_UNI_MTS + if( tu.mtsIdx > 1 && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#else + if( tu.cu->emtFlag && !tu.transformSkip[compID] && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#endif + { + effHeight = ( height == 32 ) ? 16 : height; + effWidth = ( width == 32 ) ? 16 : width; + } +#endif //===== populate trellis ===== for( int scanIdx = firstTestPos; scanIdx >= 0; scanIdx-- ) { const ScanInfo& scanInfo = tuPars.m_scanInfo[ scanIdx ]; +#if JVET_M0297_32PT_MTS_ZERO_OUT + xDecideAndUpdate( abs( tCoeff[ scanInfo.rasterPos ] ), scanInfo, ( effWidth < width || effHeight < height ) && ( scanInfo.posX >= effWidth || scanInfo.posY >= effHeight ) ); +#else xDecideAndUpdate( abs( tCoeff[ scanInfo.rasterPos ] ), scanInfo ); +#endif } //===== find best path ===== diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp index 3c4bfcc9cc9b72b095a7bda88d6d4271cd7478f3..90ee07004beed6b048c7a8237aafe8346d18dc6e 100644 --- a/source/Lib/CommonLib/TrQuant.cpp +++ b/source/Lib/CommonLib/TrQuant.cpp @@ -365,8 +365,10 @@ void TrQuant::xT( const TransformUnit &tu, const ComponentID &compID, const CPel const int shift_2nd = (g_aucLog2[height]) + TRANSFORM_MATRIX_SHIFT + COM16_C806_TRANS_PREC; const uint32_t transformWidthIndex = g_aucLog2[width ] - 1; // nLog2WidthMinus1, since transform start from 2-point const uint32_t transformHeightIndex = g_aucLog2[height] - 1; // nLog2HeightMinus1, since transform start from 2-point +#if !JVET_M0297_32PT_MTS_ZERO_OUT const int skipWidth = width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; const int skipHeight = height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; +#endif CHECK( shift_1st < 0, "Negative shift" ); CHECK( shift_2nd < 0, "Negative shift" ); @@ -375,6 +377,11 @@ void TrQuant::xT( const TransformUnit &tu, const ComponentID &compID, const CPel int trTypeVer = DCT2; getTrTypes ( tu, compID, trTypeHor, trTypeVer ); + +#if JVET_M0297_32PT_MTS_ZERO_OUT + 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; +#endif #if RExt__DECODER_DEBUG_TOOL_STATISTICS if ( trTypeHor != DCT2 ) @@ -433,8 +440,10 @@ void TrQuant::xIT( const TransformUnit &tu, const ComponentID &compID, const CCo const int shift_2nd = ( TRANSFORM_MATRIX_SHIFT + maxLog2TrDynamicRange - 1 ) - bitDepth + COM16_C806_TRANS_PREC; const uint32_t transformWidthIndex = g_aucLog2[width ] - 1; // nLog2WidthMinus1, since transform start from 2-point const uint32_t transformHeightIndex = g_aucLog2[height] - 1; // nLog2HeightMinus1, since transform start from 2-point +#if !JVET_M0297_32PT_MTS_ZERO_OUT const int skipWidth = width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0; const int skipHeight = height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0; +#endif CHECK( shift_1st < 0, "Negative shift" ); CHECK( shift_2nd < 0, "Negative shift" ); @@ -443,6 +452,11 @@ void TrQuant::xIT( const TransformUnit &tu, const ComponentID &compID, const CCo int trTypeVer = DCT2; getTrTypes ( tu, compID, trTypeHor, trTypeVer ); + +#if JVET_M0297_32PT_MTS_ZERO_OUT + 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; +#endif #if !JVET_M0102_INTRA_SUBPARTITIONS TCoeff *tmp = ( TCoeff * ) alloca( width * height * sizeof( TCoeff ) ); diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 9589707dcb7c3e3142f3e28d38e90243deee805b..f1d9a117d4cdedcc7ed5e19b9d9305de6f1f9c99 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_M0297_32PT_MTS_ZERO_OUT 1 // 32 point MTS based on skipping high frequency coefficients + #define JVET_M0126_HMVP_MRG_PRUNING 1 // HMVP merge candidates pruning simplification #define JVET_M0483_IBC 1 // Block level flag signaling and independent IBC mode diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 3ff8a9a798246a5dac50c56d1faa2795063c08fc..aba455f6b03cde8d5212b170f76cc2bcefe2cfdf 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -2708,7 +2708,11 @@ void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID ) #endif // parse last coeff position +#if JVET_M0297_32PT_MTS_ZERO_OUT + cctx.setScanPosLast( last_sig_coeff( cctx, tu, compID ) ); +#else cctx.setScanPosLast( last_sig_coeff( cctx ) ); +#endif // parse subblocks const int stateTransTab = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 ); @@ -2725,7 +2729,11 @@ void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID ) for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--) { cctx.initSubblock ( subSetId ); +#if JVET_M0297_32PT_MTS_ZERO_OUT + residual_coding_subblock( cctx, coeff, stateTransTab, state, tu, compID ); +#else residual_coding_subblock( cctx, coeff, stateTransTab, state ); +#endif #if !JVET_M0464_UNI_MTS if (useEmt) { @@ -2959,11 +2967,44 @@ void CABACReader::explicit_rdpcm_mode( TransformUnit& tu, ComponentID compID ) } +#if JVET_M0297_32PT_MTS_ZERO_OUT +int CABACReader::last_sig_coeff( CoeffCodingContext& cctx, TransformUnit& tu, ComponentID compID ) +#else int CABACReader::last_sig_coeff( CoeffCodingContext& cctx ) +#endif { RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET_SIZE2( STATS__CABAC_BITS__LAST_SIG_X_Y, Size( cctx.width(), cctx.height() ), cctx.compID() ); unsigned PosLastX = 0, PosLastY = 0; +#if JVET_M0297_32PT_MTS_ZERO_OUT + unsigned maxLastPosX = cctx.maxLastPosX(); + unsigned maxLastPosY = cctx.maxLastPosY(); + +#if JVET_M0464_UNI_MTS + if( tu.mtsIdx > 1 && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#else + if( tu.cu->emtFlag && !tu.transformSkip[ compID ] && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#endif + { + maxLastPosX = ( tu.blocks[ compID ].width == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosX; + maxLastPosY = ( tu.blocks[ compID ].height == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosY; + } + + for( ; PosLastX < maxLastPosX; PosLastX++ ) + { + if( !m_BinDecoder.decodeBin( cctx.lastXCtxId( PosLastX ) ) ) + { + break; + } + } + for( ; PosLastY < maxLastPosY; PosLastY++ ) + { + if( !m_BinDecoder.decodeBin( cctx.lastYCtxId( PosLastY ) ) ) + { + break; + } + } +#else for( ; PosLastX < cctx.maxLastPosX(); PosLastX++ ) { if( ! m_BinDecoder.decodeBin( cctx.lastXCtxId( PosLastX ) ) ) @@ -2978,6 +3019,7 @@ int CABACReader::last_sig_coeff( CoeffCodingContext& cctx ) break; } } +#endif if( PosLastX > 3 ) { uint32_t uiTemp = 0; @@ -3024,7 +3066,11 @@ int CABACReader::last_sig_coeff( CoeffCodingContext& cctx ) +#if JVET_M0297_32PT_MTS_ZERO_OUT +void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* coeff, const int stateTransTable, int& state, TransformUnit& tu, ComponentID compID ) +#else void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* coeff, const int stateTransTable, int& state ) +#endif { // NOTE: All coefficients of the subblock must be set to zero before calling this function #if RExt__DECODER_DEBUG_BIT_STATISTICS @@ -3047,7 +3093,23 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co bool sigGroup = ( isLast || !minSubPos ); if( !sigGroup ) { +#if JVET_M0297_32PT_MTS_ZERO_OUT +#if JVET_M0464_UNI_MTS + if( tu.mtsIdx > 1 && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#else + if( tu.cu->emtFlag && !tu.transformSkip[ compID ] && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#endif + { + sigGroup = ( ( tu.blocks[compID].height == 32 && cctx.cgPosY() >= ( 16 >> cctx.log2CGHeight() ) ) + || ( tu.blocks[compID].width == 32 && cctx.cgPosX() >= ( 16 >> cctx.log2CGWidth() ) ) ) ? 0 : m_BinDecoder.decodeBin( cctx.sigGroupCtxId() ); + } + else + { + sigGroup = m_BinDecoder.decodeBin(cctx.sigGroupCtxId()); + } +#else sigGroup = m_BinDecoder.decodeBin( cctx.sigGroupCtxId() ); +#endif } if( sigGroup ) { diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h index 941be20b9b125d72668365312bc8fb603a9a2a49..44c00027d786ecea1db896871fccfb608fbd1641 100644 --- a/source/Lib/DecoderLib/CABACReader.h +++ b/source/Lib/DecoderLib/CABACReader.h @@ -153,8 +153,13 @@ public: void isp_mode ( CodingUnit& cu ); #endif void explicit_rdpcm_mode ( TransformUnit& tu, ComponentID compID ); +#if JVET_M0297_32PT_MTS_ZERO_OUT + int last_sig_coeff ( CoeffCodingContext& cctx, TransformUnit& tu, ComponentID compID ); + void residual_coding_subblock ( CoeffCodingContext& cctx, TCoeff* coeff, const int stateTransTable, int& state, TransformUnit& tu, ComponentID compID ); +#else int last_sig_coeff ( CoeffCodingContext& cctx ); void residual_coding_subblock ( CoeffCodingContext& cctx, TCoeff* coeff, const int stateTransTable, int& state ); +#endif // cross component prediction (clause 7.3.8.12) void cross_comp_pred ( TransformUnit& tu, ComponentID compID ); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 85f257b789db7f4f4a633f9b270623627202681a..999b5977767cd1356b5b3838aa9ad15e3f24def8 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2529,7 +2529,11 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID ) cctx.setScanPosLast(scanPosLast); // code last coeff position +#if JVET_M0297_32PT_MTS_ZERO_OUT + last_sig_coeff( cctx, tu, compID ); +#else last_sig_coeff( cctx ); +#endif // code subblocks const int stateTab = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 ); @@ -2545,7 +2549,11 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID ) for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--) { cctx.initSubblock ( subSetId, sigGroupFlags[subSetId] ); +#if JVET_M0297_32PT_MTS_ZERO_OUT + residual_coding_subblock( cctx, coeff, stateTab, state, tu, compID ); +#else residual_coding_subblock( cctx, coeff, stateTab, state ); +#endif #if !JVET_M0464_UNI_MTS if (useEmt) @@ -2751,7 +2759,11 @@ void CABACWriter::explicit_rdpcm_mode( const TransformUnit& tu, ComponentID comp } +#if JVET_M0297_32PT_MTS_ZERO_OUT +void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID ) +#else void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx ) +#endif { unsigned blkPos = cctx.blockPos( cctx.scanPosLast() ); unsigned posX, posY; @@ -2772,11 +2784,30 @@ void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx ) unsigned GroupIdxX = g_uiGroupIdx[ posX ]; unsigned GroupIdxY = g_uiGroupIdx[ posY ]; +#if JVET_M0297_32PT_MTS_ZERO_OUT + unsigned maxLastPosX = cctx.maxLastPosX(); + unsigned maxLastPosY = cctx.maxLastPosY(); + +#if JVET_M0464_UNI_MTS + if( tu.mtsIdx > 1 && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#else + if( tu.cu->emtFlag && !tu.transformSkip[ compID ] && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#endif + { + maxLastPosX = ( tu.blocks[compID].width == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosX; + maxLastPosY = ( tu.blocks[compID].height == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosY; + } +#endif + for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ ) { m_BinEncoder.encodeBin( 1, cctx.lastXCtxId( CtxLast ) ); } +#if JVET_M0297_32PT_MTS_ZERO_OUT + if( GroupIdxX < maxLastPosX ) +#else if( GroupIdxX < cctx.maxLastPosX() ) +#endif { m_BinEncoder.encodeBin( 0, cctx.lastXCtxId( CtxLast ) ); } @@ -2784,7 +2815,11 @@ void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx ) { m_BinEncoder.encodeBin( 1, cctx.lastYCtxId( CtxLast ) ); } +#if JVET_M0297_32PT_MTS_ZERO_OUT + if( GroupIdxY < maxLastPosY ) +#else if( GroupIdxY < cctx.maxLastPosY() ) +#endif { m_BinEncoder.encodeBin( 0, cctx.lastYCtxId( CtxLast ) ); } @@ -2808,7 +2843,11 @@ void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx ) +#if JVET_M0297_32PT_MTS_ZERO_OUT +void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeff* coeff, const int stateTransTable, int& state, const TransformUnit& tu, ComponentID compID ) +#else void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeff* coeff, const int stateTransTable, int& state ) +#endif { //===== init ===== const int minSubPos = cctx.minSubPos(); @@ -2819,6 +2858,21 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe //===== encode significant_coeffgroup_flag ===== if( !isLast && cctx.isNotFirst() ) { +#if JVET_M0297_32PT_MTS_ZERO_OUT +#if JVET_M0464_UNI_MTS + if( tu.mtsIdx > 1 && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#else + if( tu.cu->emtFlag && !tu.transformSkip[ compID ] && !tu.cu->transQuantBypass && compID == COMPONENT_Y ) +#endif + { + if( ( tu.blocks[compID].height == 32 && cctx.cgPosY() >= ( 16 >> cctx.log2CGHeight() ) ) + || ( tu.blocks[compID].width == 32 && cctx.cgPosX() >= ( 16 >> cctx.log2CGWidth() ) ) ) + { + return; + } + } +#endif + if( cctx.isSigGroup() ) { m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId() ); diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h index 8ddd3c5fcb0eae3260426fcd6a559e17bb859de3..15100b68149d6ec05bd40cc3f1f5c7b0867388fc 100644 --- a/source/Lib/EncoderLib/CABACWriter.h +++ b/source/Lib/EncoderLib/CABACWriter.h @@ -167,8 +167,13 @@ public: void isp_mode ( const CodingUnit& cu ); #endif void explicit_rdpcm_mode ( const TransformUnit& tu, ComponentID compID ); +#if JVET_M0297_32PT_MTS_ZERO_OUT + void last_sig_coeff ( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID ); + void residual_coding_subblock ( CoeffCodingContext& cctx, const TCoeff* coeff, const int stateTransTable, int& state, const TransformUnit& tu, ComponentID compID); +#else void last_sig_coeff ( CoeffCodingContext& cctx ); - void residual_coding_subblock ( CoeffCodingContext& cctx, const TCoeff* coeff, const int stateTransTable, int& state ); + void residual_coding_subblock ( CoeffCodingContext& cctx, const TCoeff* coeff, const int stateTransTable, int& state ); +#endif // cross component prediction (clause 7.3.8.12) void cross_comp_pred ( const TransformUnit& tu, ComponentID compID );