From 4f4273e4db637ed3bce8a58255a6bc33a4a5881c Mon Sep 17 00:00:00 2001 From: Jason Jung <jason.jung@wilusgroup.com> Date: Mon, 29 Jul 2019 22:58:52 +0900 Subject: [PATCH] Implementation of JVET-O0472 --- source/Lib/CommonLib/CommonDef.h | 5 ++++ source/Lib/CommonLib/ContextModelling.h | 30 ++++++++++++++++++++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/CommonLib/UnitTools.cpp | 4 +++ source/Lib/CommonLib/UnitTools.h | 4 +++ source/Lib/DecoderLib/CABACReader.cpp | 37 +++++++++++++++++++++---- source/Lib/DecoderLib/CABACReader.h | 4 +-- source/Lib/EncoderLib/CABACWriter.cpp | 33 ++++++++++++++++++++-- source/Lib/EncoderLib/CABACWriter.h | 2 +- source/Lib/EncoderLib/EncCu.cpp | 13 +++++++++ 10 files changed, 123 insertions(+), 11 deletions(-) diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index ec7e37790..b56ee0e5c 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -263,8 +263,13 @@ static const int FAST_UDI_MAX_RDMODE_NUM = (NUM_LUMA_MODE + MAX_NUM_MIP_MODE); / static const int MAX_LFNST_COEF_NUM = 16; +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS +static const int LFNST_LAST_SIG_LUMA = 1; +static const int LFNST_LAST_SIG_CHROMA = 1; +#else static const int LFNST_SIG_NZ_LUMA = 1; static const int LFNST_SIG_NZ_CHROMA = 1; +#endif static const int NUM_LFNST_NUM_PER_SET = 3; diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index 41190b2e1..c9773cc5f 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -427,6 +427,18 @@ class CUCtx { public: CUCtx() : isDQPCoded(false), isChromaQpAdjCoded(false), +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + qgStart(false) + { +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS + violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false; + violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; +#endif + lastScanPos[COMPONENT_Y ] = -1; + lastScanPos[COMPONENT_Cb] = -1; + lastScanPos[COMPONENT_Cr] = -1; + } +#else qgStart(false), #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS numNonZeroCoeffNonTs(0) @@ -436,9 +448,22 @@ public: } #else numNonZeroCoeffNonTs(0) {} +#endif #endif CUCtx(int _qp) : isDQPCoded(false), isChromaQpAdjCoded(false), qgStart(false), +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + qp(_qp) + { +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS + violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false; + violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; +#endif + lastScanPos[COMPONENT_Y ] = -1; + lastScanPos[COMPONENT_Cb] = -1; + lastScanPos[COMPONENT_Cr] = -1; + } +#else #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS numNonZeroCoeffNonTs(0), qp(_qp) { @@ -447,13 +472,18 @@ public: } #else numNonZeroCoeffNonTs(0), qp(_qp) {} +#endif #endif ~CUCtx() {} public: bool isDQPCoded; bool isChromaQpAdjCoded; bool qgStart; +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + int lastScanPos[MAX_NUM_COMPONENT]; +#else uint32_t numNonZeroCoeffNonTs; +#endif 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]; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 811be421c..0ee243712 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -164,6 +164,8 @@ #define JVET_O0594_BDOF_REF_SAMPLE_PADDING 1 // JVET-O0594/O0252/O0506/O0615/O0624: BDOF reference sample padding using the nearest integer sample position +#define JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS 1 // JVET-O0472: LFNST index signalling depends on the position of last significant coefficient + #define FIX_DB_MAX_TRANSFORM_SIZE 1 #define MRG_SHARELIST_SHARSIZE 32 diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 3aec86d1c..1cf58c957 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -250,6 +250,7 @@ bool CU::hasNonTsCodedBlock( const CodingUnit& cu ) return hasAnyNonTSCoded; } +#if !JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS uint32_t CU::getNumNonZeroCoeffNonTs( const CodingUnit& cu, const bool lumaFlag, const bool chromaFlag ) { uint32_t count = 0; @@ -260,6 +261,7 @@ uint32_t CU::getNumNonZeroCoeffNonTs( const CodingUnit& cu, const bool lumaFlag, return count; } +#endif #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS uint32_t CU::getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool lumaFlag, const bool chromaFlag ) @@ -4641,6 +4643,7 @@ bool TU::hasCrossCompPredInfo( const TransformUnit &tu, const ComponentID &compI (!CU::isIntra(*tu.cu) || PU::isChromaIntraModeCrossCheckMode(*tu.cs->getPU(tu.blocks[compID].pos(), toChannelType(compID))))); } +#if !JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS uint32_t TU::getNumNonZeroCoeffsNonTS( const TransformUnit& tu, const bool bLuma, const bool bChroma ) { uint32_t count = 0; @@ -4661,6 +4664,7 @@ uint32_t TU::getNumNonZeroCoeffsNonTS( const TransformUnit& tu, const bool bLuma } return count; } +#endif #if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS uint32_t TU::getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit& tu, const bool lumaFlag, const bool chromaFlag ) { diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 4423e858d..9b2365b4c 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -78,7 +78,9 @@ namespace CU PartSplit getSplitAtDepth (const CodingUnit& cu, const unsigned depth); bool hasNonTsCodedBlock (const CodingUnit& cu); +#if !JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS uint32_t getNumNonZeroCoeffNonTs ( const CodingUnit& cu, const bool lumaFlag = true, const bool chromaFlag = true ); +#endif uint32_t getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool lumaFlag = true, const bool chromaFlag = true ); #if JVET_O0106_ISP_4xN_PREDREG_FOR_1xN_2xN bool isPredRegDiffFromTB(const CodingUnit& cu, const ComponentID compID); @@ -209,7 +211,9 @@ namespace PU // TU tools namespace TU { +#if !JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS uint32_t getNumNonZeroCoeffsNonTS (const TransformUnit &tu, const bool bLuma = true, const bool bChroma = true); +#endif uint32_t getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit &tu, const bool bLuma = true, const bool bChroma = true ); bool isNonTransformedResidualRotated(const TransformUnit &tu, const ComponentID &compID); bool getCbf (const TransformUnit &tu, const ComponentID &compID); diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index f36c9684e..a82d70d2e 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -1413,6 +1413,11 @@ void CABACReader::cu_residual( CodingUnit& cu, Partitioner &partitioner, CUCtx& cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] = false; cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; #endif +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + cuCtx.lastScanPos[COMPONENT_Y ] = -1; + cuCtx.lastScanPos[COMPONENT_Cb] = -1; + cuCtx.lastScanPos[COMPONENT_Cr] = -1; +#endif ChromaCbfs chromaCbfs; if( cu.ispMode && isLuma( partitioner.chType ) ) @@ -1432,7 +1437,7 @@ void CABACReader::cu_residual( CodingUnit& cu, Partitioner &partitioner, CUCtx& transform_tree( *cu.cs, partitioner, cuCtx, chromaCbfs ); #endif } -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS residual_lfnst_mode( cu, cuCtx ); #else residual_lfnst_mode( cu ); @@ -2544,7 +2549,7 @@ void CABACReader::transform_unit( TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& c } if( cbfLuma ) { -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS residual_coding( tu, COMPONENT_Y, cuCtx ); #else residual_coding( tu, COMPONENT_Y ); @@ -2560,7 +2565,7 @@ void CABACReader::transform_unit( TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& c } if( tu.cbf[ compID ] ) { -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS residual_coding( tu, compID, cuCtx ); #else residual_coding( tu, compID ); @@ -2646,7 +2651,7 @@ void CABACReader::joint_cb_cr( TransformUnit& tu ) } #endif -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID, CUCtx& cuCtx ) #else void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID ) @@ -2704,6 +2709,12 @@ void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID ) const int maxLfnstPos = ((tu.blocks[compID].height == 4 && tu.blocks[compID].width == 4) || (tu.blocks[compID].height == 8 && tu.blocks[compID].width == 8)) ? 7 : 15; cuCtx.violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos; } +#endif +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + if( tu.mtsIdx != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 ) + { + cuCtx.lastScanPos[compID] = cctx.scanPosLast(); + } #endif // parse subblocks const int stateTransTab = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 ); @@ -2854,7 +2865,7 @@ void CABACReader::explicit_rdpcm_mode( TransformUnit& tu, ComponentID compID ) } } -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS void CABACReader::residual_lfnst_mode( CodingUnit& cu, CUCtx& cuCtx ) #else void CABACReader::residual_lfnst_mode( CodingUnit& cu ) @@ -2872,19 +2883,35 @@ void CABACReader::residual_lfnst_mode( CodingUnit& cu ) { const bool lumaFlag = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? true : false ) : true; const bool chromaFlag = CS::isDualITree( *cu.cs ) ? ( isChroma( cu.chType ) ? true : false ) : true; +#if !JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS bool nonZeroCoeffNonTs; +#endif #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] ); #else bool nonZeroCoeffNonTsCorner8x8 = CU::getNumNonZeroCoeffNonTsCorner8x8( cu, lumaFlag, chromaFlag ) > 0; #endif +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + const bool skipLfnst = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? ( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA ) : + ( cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA ) ) : + ( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA && cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA ); +#else const int nonZeroCoeffThr = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? LFNST_SIG_NZ_LUMA : LFNST_SIG_NZ_CHROMA ) : LFNST_SIG_NZ_LUMA + LFNST_SIG_NZ_CHROMA; nonZeroCoeffNonTs = CU::getNumNonZeroCoeffNonTs( cu, lumaFlag, chromaFlag ) > nonZeroCoeffThr; +#endif #if JVET_O0368_LFNST_WITH_DCT2_ONLY const bool isNonDCT2 = (TU::getCbf(*cu.firstTU, ComponentID(COMPONENT_Y)) && cu.firstTU->mtsIdx != MTS_DCT2_DCT2); +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + if( skipLfnst || nonZeroCoeffNonTsCorner8x8 || isNonDCT2 ) +#else if (!nonZeroCoeffNonTs || nonZeroCoeffNonTsCorner8x8 || isNonDCT2) +#endif +#else +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + if( skipLfnst || nonZeroCoeffNonTsCorner8x8 ) #else if( !nonZeroCoeffNonTs || nonZeroCoeffNonTsCorner8x8 ) +#endif #endif { cu.lfnstIdx = 0; diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h index 947702d7f..c6e2afa90 100644 --- a/source/Lib/DecoderLib/CABACReader.h +++ b/source/Lib/DecoderLib/CABACReader.h @@ -137,13 +137,13 @@ public: void cu_chroma_qp_offset ( CodingUnit& cu ); // residual coding (clause 7.3.8.11) -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS void residual_coding ( TransformUnit& tu, ComponentID compID, CUCtx& cuCtx ); #else void residual_coding ( TransformUnit& tu, ComponentID compID ); #endif void mts_coding ( TransformUnit& tu, ComponentID compID ); -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS void residual_lfnst_mode ( CodingUnit& cu, CUCtx& cuCtx ); #else void residual_lfnst_mode ( CodingUnit& cu ); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 8ee4580fd..e8b455a4f 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -1304,6 +1304,11 @@ void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, C cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] = false; cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false; #endif +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + cuCtx.lastScanPos[COMPONENT_Y ] = -1; + cuCtx.lastScanPos[COMPONENT_Cb] = -1; + cuCtx.lastScanPos[COMPONENT_Cr] = -1; +#endif #if !JVET_O0596_CBF_SIG_ALIGN_TO_SPEC ChromaCbfs chromaCbfs; @@ -2415,7 +2420,7 @@ void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, ChromaC } if( cbfLuma ) { -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS residual_coding( tu, COMPONENT_Y, &cuCtx ); #else residual_coding( tu, COMPONENT_Y ); @@ -2431,7 +2436,7 @@ void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, ChromaC } if( cbf[ compID ] ) { -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS residual_coding( tu, compID, &cuCtx ); #else residual_coding( tu, compID ); @@ -2518,7 +2523,7 @@ void CABACWriter::joint_cb_cr( const TransformUnit& tu ) } #endif -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx ) #else void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID) @@ -2589,6 +2594,12 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID) const int maxLfnstPos = ((tu.blocks[compID].height == 4 && tu.blocks[compID].width == 4) || (tu.blocks[compID].height == 8 && tu.blocks[compID].width == 8)) ? 7 : 15; cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos; } +#endif +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + if( cuCtx && tu.mtsIdx != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 ) + { + cuCtx->lastScanPos[compID] = cctx.scanPosLast(); + } #endif // code last coeff position last_sig_coeff( cctx, tu, compID ); @@ -2739,20 +2750,36 @@ void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx ) { const bool lumaFlag = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? true : false ) : true; const bool chromaFlag = CS::isDualITree( *cu.cs ) ? ( isChroma( cu.chType ) ? true : false ) : true; +#if !JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS bool nonZeroCoeffNonTs; +#endif #if JVET_O0094_LFNST_ZERO_PRIM_COEFFS bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] ); #else bool nonZeroCoeffNonTsCorner8x8 = CU::getNumNonZeroCoeffNonTsCorner8x8( cu, lumaFlag, chromaFlag ) > 0; #endif +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + const bool skipLfnst = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? ( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA ) : + ( cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA ) ) : + ( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA && cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA ); +#else const int nonZeroCoeffThr = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? LFNST_SIG_NZ_LUMA : LFNST_SIG_NZ_CHROMA ) : LFNST_SIG_NZ_LUMA + LFNST_SIG_NZ_CHROMA; cuCtx.numNonZeroCoeffNonTs = CU::getNumNonZeroCoeffNonTs( cu, lumaFlag, chromaFlag ); nonZeroCoeffNonTs = cuCtx.numNonZeroCoeffNonTs > nonZeroCoeffThr; +#endif #if JVET_O0368_LFNST_WITH_DCT2_ONLY const bool isNonDCT2 = (TU::getCbf(*cu.firstTU, ComponentID(COMPONENT_Y)) && cu.firstTU->mtsIdx != MTS_DCT2_DCT2); +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + if( skipLfnst || nonZeroCoeffNonTsCorner8x8 || isNonDCT2 ) +#else if (!nonZeroCoeffNonTs || nonZeroCoeffNonTsCorner8x8 || isNonDCT2 ) +#endif +#else +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + if( skipLfnst || nonZeroCoeffNonTsCorner8x8 ) #else if( !nonZeroCoeffNonTs || nonZeroCoeffNonTsCorner8x8 ) +#endif #endif { return; diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h index 6a2453e2a..2840e7b1b 100644 --- a/source/Lib/EncoderLib/CABACWriter.h +++ b/source/Lib/EncoderLib/CABACWriter.h @@ -149,7 +149,7 @@ public: void cu_chroma_qp_offset ( const CodingUnit& cu ); // residual coding (clause 7.3.8.11) -#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS +#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS void residual_coding ( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx = nullptr ); #else void residual_coding ( const TransformUnit& tu, ComponentID compID ); diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 920639e84..24c4afb77 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -1523,6 +1523,18 @@ void EncCu::xCheckRDCostIntra( CodingStructure *&tempCS, CodingStructure *&bestC xCheckDQP( *tempCS, partitioner ); // Check if low frequency non-separable transform (LFNST) is too expensive +#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS + const bool skipLfnst = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? ( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA ) : + ( cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA ) ) : + ( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA && cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA ); + if( lfnstIdx && skipLfnst ) + { + if( cuCtx.lastScanPos[ COMPONENT_Y ] > -1 || cuCtx.lastScanPos[ COMPONENT_Cb ] > -1 || cuCtx.lastScanPos[ COMPONENT_Cr ] > -1 ) + { + tempCS->cost = MAX_DOUBLE; + } + } +#else const int nonZeroCoeffThr = CS::isDualITree( *tempCS ) ? ( isLuma( partitioner.chType ) ? LFNST_SIG_NZ_LUMA : LFNST_SIG_NZ_CHROMA ) : LFNST_SIG_NZ_LUMA + LFNST_SIG_NZ_CHROMA; if( lfnstIdx && cuCtx.numNonZeroCoeffNonTs <= nonZeroCoeffThr ) { @@ -1531,6 +1543,7 @@ void EncCu::xCheckRDCostIntra( CodingStructure *&tempCS, CodingStructure *&bestC tempCS->cost = MAX_DOUBLE; } } +#endif if( mtsFlag == 0 && lfnstIdx == 0 ) { -- GitLab