diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp index d38003361c4a2c4f3c5ac125a9fd54c6f586b952..ab45af5ed2e5cae336fec0a6d378c24c5bfd5bc4 100644 --- a/source/Lib/CommonLib/TrQuant.cpp +++ b/source/Lib/CommonLib/TrQuant.cpp @@ -1231,7 +1231,7 @@ void TrQuant::transformNxN( TransformUnit &tu, const ComponentID &compID, const void TrQuant::xGetCoeffEnergy( TransformUnit &tu, const ComponentID &compID, const CoeffBuf& coeffs, double* diagRatio, double* horVerRatio ) { if( nullptr == diagRatio || nullptr == horVerRatio ) return; - if( tu.cu->predMode == MODE_INTRA && !tu.cu->ispMode && isLuma( compID ) && tu.cs->sps->getUseISP() && CU::canUseISPSplit( *tu.cu, compID ) != NOT_INTRA_SUBPARTITIONS ) + if( tu.cu->predMode == MODE_INTRA && !tu.cu->ispMode && isLuma( compID ) && tu.cs->sps->getUseISP() && CU::canUseISP( *tu.cu, compID ) ) { const int width = tu.cu->blocks[compID].width; const int height = tu.cu->blocks[compID].height; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 5cbc8d6a413b0a7bc4b86707191964ba206a6d1c..4a1391b6931e120c589b3cb64bfb634c11207d41 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -424,8 +424,7 @@ enum ISPType NOT_INTRA_SUBPARTITIONS = 0, HOR_INTRA_SUBPARTITIONS = 1, VER_INTRA_SUBPARTITIONS = 2, - NUM_INTRA_SUBPARTITIONS_MODES = 3, - CAN_USE_VER_AND_HORL_SPLITS = 4 + NUM_INTRA_SUBPARTITIONS_MODES = 3 }; enum SbtIdx diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 3aec86d1c7ecd686ae3016706a192622e5ba08ab..33935de58f31d610a90801a88ecfce3bb5a7337a 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -383,7 +383,7 @@ bool CU::isISPFirst( const CodingUnit &cu, const CompArea &tuArea, const Compone return tuArea == cu.firstTU->blocks[compID]; } -ISPType CU::canUseISPSplit( const CodingUnit &cu, const ComponentID compID ) +bool CU::canUseISP( const CodingUnit &cu, const ComponentID compID ) { const int width = cu.blocks[compID].width; const int height = cu.blocks[compID].height; @@ -392,35 +392,18 @@ ISPType CU::canUseISPSplit( const CodingUnit &cu, const ComponentID compID ) #else const int maxTrSize = MAX_TB_SIZEY; #endif - return CU::canUseISPSplit( width, height, maxTrSize ); + return CU::canUseISP( width, height, maxTrSize ); } -ISPType CU::canUseISPSplit( const int width, const int height, const int maxTrSize ) +bool CU::canUseISP( const int width, const int height, const int maxTrSize ) { - bool widthCannotBeUsed = false, heightCannotBeUsed = false; - - const uint32_t minTuSizeForISP = MIN_TB_SIZEY; - bool notEnoughSamplesToSplit = ( g_aucLog2[width] + g_aucLog2[height] <= ( g_aucLog2[minTuSizeForISP] << 1 ) ); - bool cuSizeLargerThanMaxTrSize = width > maxTrSize || height > maxTrSize; - widthCannotBeUsed = cuSizeLargerThanMaxTrSize || notEnoughSamplesToSplit; - heightCannotBeUsed = cuSizeLargerThanMaxTrSize || notEnoughSamplesToSplit; - - if( !widthCannotBeUsed && !heightCannotBeUsed ) - { - return CAN_USE_VER_AND_HORL_SPLITS; //both splits can be used - } - else if( widthCannotBeUsed && !heightCannotBeUsed ) - { - return VER_INTRA_SUBPARTITIONS; //only the vertical split can be performed - } - else if( !widthCannotBeUsed && heightCannotBeUsed ) + bool notEnoughSamplesToSplit = ( g_aucLog2[width] + g_aucLog2[height] <= ( g_aucLog2[MIN_TB_SIZEY] << 1 ) ); + bool cuSizeLargerThanMaxTrSize = width > maxTrSize || height > maxTrSize; + if ( notEnoughSamplesToSplit || cuSizeLargerThanMaxTrSize ) { - return HOR_INTRA_SUBPARTITIONS; //only the horizontal split can be performed - } - else - { - return NOT_INTRA_SUBPARTITIONS; //neither of the splits can be used + return false; } + return true; } uint32_t CU::getISPSplitDim( const int width, const int height, const PartSplit ispType ) diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 4423e858dd4b5a70a93fc0c4473909a679954872..6e4773cd9bcbdea534d32cc8e48a7fc37c73cf03 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -98,8 +98,8 @@ namespace CU PartSplit getISPType ( const CodingUnit &cu, const ComponentID compID ); bool isISPLast ( const CodingUnit &cu, const CompArea &tuArea, const ComponentID compID ); bool isISPFirst ( const CodingUnit &cu, const CompArea &tuArea, const ComponentID compID ); - ISPType canUseISPSplit ( const CodingUnit &cu, const ComponentID compID ); - ISPType canUseISPSplit ( const int width, const int height, const int maxTrSize = MAX_TB_SIZEY ); + bool canUseISP ( const CodingUnit &cu, const ComponentID compID ); + bool canUseISP ( const int width, const int height, const int maxTrSize = MAX_TB_SIZEY ); uint32_t getISPSplitDim ( const int width, const int height, const PartSplit ispType ); PUTraverser traversePUs ( CodingUnit& cu); diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index ec56ab3e564a02fdfbb05529dbe4e622e59ddc15..35d2373002d699084ebcf17f54493446083da76a 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -2775,38 +2775,20 @@ void CABACReader::mts_coding( TransformUnit& tu, ComponentID compID ) void CABACReader::isp_mode( CodingUnit& cu ) { - if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() || cu.bdpcmMode ) + if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() || cu.bdpcmMode || !CU::canUseISP( cu, getFirstComponentOfChannel( cu.chType ) ) ) { cu.ispMode = NOT_INTRA_SUBPARTITIONS; return; } - const ISPType allowedSplits = CU::canUseISPSplit( cu, getFirstComponentOfChannel( cu.chType ) ); - if( allowedSplits == NOT_INTRA_SUBPARTITIONS ) - { - cu.ispMode = NOT_INTRA_SUBPARTITIONS; - return; - } + int symbol = m_BinDecoder.decodeBin(Ctx::ISPMode(0)); RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__ISP_MODE_FLAG ); - cu.ispMode = NOT_INTRA_SUBPARTITIONS; - int symbol = m_BinDecoder.decodeBin( Ctx::ISPMode( 0 ) ); if( symbol ) { - if( allowedSplits == HOR_INTRA_SUBPARTITIONS ) - { - cu.ispMode = HOR_INTRA_SUBPARTITIONS; - } - else if( allowedSplits == VER_INTRA_SUBPARTITIONS ) - { - cu.ispMode = VER_INTRA_SUBPARTITIONS; - } - else - { - RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__ISP_SPLIT_FLAG ); - cu.ispMode = 1 + m_BinDecoder.decodeBin( Ctx::ISPMode( 1 ) ); - } + RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__ISP_SPLIT_FLAG ); + cu.ispMode = 1 + m_BinDecoder.decodeBin( Ctx::ISPMode( 1 ) ); } DTRACE( g_trace_ctx, D_SYNTAX, "intra_subPartitions() etype=%d pos=(%d,%d) ispIdx=%d\n", cu.chType, cu.blocks[cu.chType].x, cu.blocks[cu.chType].y, (int)cu.ispMode ); } diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 636f6f0ab05e82cadd472379d5d70c8d0e5f117b..1a1a204abe4626140b77cc53ea2588d2ffa9f56a 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2671,26 +2671,19 @@ void CABACWriter::mts_coding( const TransformUnit& tu, ComponentID compID ) void CABACWriter::isp_mode( const CodingUnit& cu ) { - if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() || cu.bdpcmMode ) + if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() || cu.bdpcmMode || !CU::canUseISP( cu, getFirstComponentOfChannel( cu.chType ) ) ) { - CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "error: cu.intraSubPartitions != 0" ); + CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "cu.ispMode != 0" ); return; } - const ISPType allowedSplits = CU::canUseISPSplit( cu, getFirstComponentOfChannel( cu.chType ) ); - if( allowedSplits == NOT_INTRA_SUBPARTITIONS ) return; - - if( cu.ispMode == NOT_INTRA_SUBPARTITIONS ) + if ( cu.ispMode == NOT_INTRA_SUBPARTITIONS ) { m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) ); } else { m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) ); - - if( allowedSplits == CAN_USE_VER_AND_HORL_SPLITS ) - { - m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) ); - } + m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) ); } DTRACE( g_trace_ctx, D_SYNTAX, "intra_subPartitions() etype=%d pos=(%d,%d) ispIdx=%d\n", cu.chType, cu.blocks[cu.chType].x, cu.blocks[cu.chType].y, (int)cu.ispMode ); } diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index 9f501fe5b2eab56103500b47daf0a6907f0ac431..cc7c2a3bbb86529efdff2d49909b0a4f2070520d 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -317,49 +317,21 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, { mtsUsageFlag = 0; } - int nOptionsForISP = ( sps.getUseISP() && cu.mtsFlag == 0 && cu.lfnstIdx == 0 ) ? NUM_INTRA_SUBPARTITIONS_MODES : 1; - double bestCurrentCost = bestCostSoFar; - int ispOptions[NUM_INTRA_SUBPARTITIONS_MODES] = { 0 }; - if( nOptionsForISP > 1 ) - { + double bestCurrentCost = bestCostSoFar; #if MAX_TB_SIZE_SIGNALLING - auto splitsThatCanBeUsedForISP = CU::canUseISPSplit( width, height, cu.cs->sps->getMaxTbSize() ); + bool testISP = sps.getUseISP() && cu.mtsFlag == 0 && cu.lfnstIdx == 0 && CU::canUseISP( width, height, cu.cs->sps->getMaxTbSize() ); #else - auto splitsThatCanBeUsedForISP = CU::canUseISPSplit( width, height, MAX_TB_SIZEY ); + bool testISP = sps.getUseISP() && cu.mtsFlag == 0 && cu.lfnstIdx == 0 && CU::canUseISP( width, height, MAX_TB_SIZEY ); #endif - if( splitsThatCanBeUsedForISP == CAN_USE_VER_AND_HORL_SPLITS ) - { - const CodingUnit* cuLeft = cu.ispMode != NOT_INTRA_SUBPARTITIONS ? cs.getCU( cs.area.blocks[partitioner.chType].pos().offset( -1, 0 ), partitioner.chType ) : nullptr; - const CodingUnit* cuAbove = cu.ispMode != NOT_INTRA_SUBPARTITIONS ? cs.getCU( cs.area.blocks[partitioner.chType].pos().offset( 0, -1 ), partitioner.chType ) : nullptr; - bool ispHorIsFirstTest = CU::firstTestISPHorSplit( width, height, COMPONENT_Y, cuLeft, cuAbove ); - if( ispHorIsFirstTest ) - { - ispOptions[1] = HOR_INTRA_SUBPARTITIONS; - ispOptions[2] = VER_INTRA_SUBPARTITIONS; - } - else - { - ispOptions[1] = VER_INTRA_SUBPARTITIONS; - ispOptions[2] = HOR_INTRA_SUBPARTITIONS; - } - } - else if( splitsThatCanBeUsedForISP == HOR_INTRA_SUBPARTITIONS ) - { - nOptionsForISP = 2; - ispOptions[1] = HOR_INTRA_SUBPARTITIONS; - } - else if( splitsThatCanBeUsedForISP == VER_INTRA_SUBPARTITIONS ) - { - nOptionsForISP = 2; - ispOptions[1] = VER_INTRA_SUBPARTITIONS; - } - else - { - nOptionsForISP = 1; - } + bool ispHorIsFirstTest = testISP ? CU::firstTestISPHorSplit( width, height, COMPONENT_Y, nullptr, nullptr ) : true; + int ispOptions[] = { NOT_INTRA_SUBPARTITIONS, HOR_INTRA_SUBPARTITIONS, VER_INTRA_SUBPARTITIONS }; + if ( !ispHorIsFirstTest ) + { + ispOptions[1] = VER_INTRA_SUBPARTITIONS; + ispOptions[2] = HOR_INTRA_SUBPARTITIONS; } - if( nOptionsForISP > 1 ) + if( testISP ) { //variables for the full RD list without MRL modes m_rdModeListWithoutMrl .clear(); @@ -580,7 +552,7 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, } } } - if( nOptionsForISP > 1 ) + if ( testISP ) { //we save the list with no mrl modes to keep only the Hadamard selected modes (no mpms) m_rdModeListWithoutMrl = uiRdModeList; @@ -694,7 +666,7 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, CandCostList.push_back(0); } } - if( nOptionsForISP > 1 ) + if ( testISP ) { //we add the ISP MPMs to the list without mrl modes m_rdModeListWithoutMrlHor = m_rdModeListWithoutMrl; @@ -705,7 +677,7 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, m_rdModeListWithoutMrlVer[k].ispMod = VER_INTRA_SUBPARTITIONS; } static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM>* listPointer; - for( int k = 1; k < nOptionsForISP; k++ ) + for( int k = 1; k < NUM_INTRA_SUBPARTITIONS_MODES; k++ ) { cu.ispMode = ispOptions[k]; listPointer = &( cu.ispMode == HOR_INTRA_SUBPARTITIONS ? m_rdModeListWithoutMrlHor : m_rdModeListWithoutMrlVer ); @@ -790,14 +762,14 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, } } - if( nOptionsForISP > 1 ) // we remove the non-MPMs from the ISP lists + if( testISP ) // we remove the non-MPMs from the ISP lists { static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> uiRdModeListCopyHor = m_rdModeListWithoutMrlHor; m_rdModeListWithoutMrlHor.clear(); static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> uiRdModeListCopyVer = m_rdModeListWithoutMrlVer; m_rdModeListWithoutMrlVer.clear(); static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> *listPointerCopy, *listPointer; - for( int ispOptionIdx = 1; ispOptionIdx < nOptionsForISP; ispOptionIdx++ ) + for( int ispOptionIdx = 1; ispOptionIdx < NUM_INTRA_SUBPARTITIONS_MODES; ispOptionIdx++ ) { cu.ispMode = ispOptions[ispOptionIdx]; //we get the mpm cand list @@ -844,7 +816,7 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, if (maxSize > 0) { uiRdModeList.resize(std::min<size_t>(uiRdModeList.size(), maxSize)); - if (nOptionsForISP > 1) + if ( testISP ) { m_rdModeListWithoutMrlHor.resize(std::min<size_t>(m_rdModeListWithoutMrlHor.size(), maxSize)); m_rdModeListWithoutMrlVer.resize(std::min<size_t>(m_rdModeListWithoutMrlVer.size(), maxSize)); @@ -867,7 +839,7 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, } } - if ( nOptionsForISP > 1 ) + if ( testISP ) { //we create a single full RD list that includes all intra modes using regular intra, MRL and ISP auto* firstIspList = ispOptions[1] == HOR_INTRA_SUBPARTITIONS ? &m_rdModeListWithoutMrlHor : &m_rdModeListWithoutMrlVer; @@ -1827,7 +1799,7 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp const bool bUseCrossCPrediction = pps.getPpsRangeExtension().getCrossComponentPredictionEnabledFlag() && isChroma( compID ) && PU::isChromaIntraModeCrossCheckMode( pu ) && checkCrossCPrediction; const bool ccUseRecoResi = m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate(); - const bool ispSplitIsAllowed = sps.getUseISP() && CU::canUseISPSplit( *tu.cu, compID ); + const bool ispSplitIsAllowed = sps.getUseISP() && CU::canUseISP( *tu.cu, compID ); //===== init availability pattern =====