From 400b5e49283ff5f708b6a94f2557cdfaa919a3fe Mon Sep 17 00:00:00 2001 From: Frank Bossen <frank@bossentech.com> Date: Fri, 4 Nov 2022 15:42:04 +0000 Subject: [PATCH] Clean up adaptive BT size related code --- source/Lib/CommonLib/Slice.cpp | 4 +- source/Lib/CommonLib/Slice.h | 6 +- source/Lib/EncoderLib/EncGOP.cpp | 96 ++++++++----------- source/Lib/EncoderLib/EncGOP.h | 12 ++- source/Lib/EncoderLib/EncModeCtrl.cpp | 11 ++- .../EncoderLib/EncSampleAdaptiveOffset.cpp | 16 ++-- source/Lib/EncoderLib/EncSlice.cpp | 14 +-- 7 files changed, 75 insertions(+), 84 deletions(-) diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 9a1f9aedc..e2c07e90c 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -82,7 +82,7 @@ Slice::Slice() , m_biDirPred(false) , m_lmChromaCheckDisable(false) , m_iSliceQpDelta(0) - , m_iDepth(0) + , m_hierPredLayerIdx(0) , m_pcSPS(nullptr) , m_pcPPS(nullptr) , m_pcPic(nullptr) @@ -958,7 +958,7 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll) } if (cpyAlmostAll) { - m_iDepth = pSrc->m_iDepth; + m_hierPredLayerIdx = pSrc->m_hierPredLayerIdx; } // access channel diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 064b232a3..44a1d4972 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -2744,7 +2744,7 @@ private: Picture* m_apcRefPicList [NUM_REF_PIC_LIST_01][MAX_NUM_REF+1]; int m_aiRefPOCList [NUM_REF_PIC_LIST_01][MAX_NUM_REF+1]; bool m_bIsUsedAsLongTerm[NUM_REF_PIC_LIST_01][MAX_NUM_REF+1]; - int m_iDepth; + int m_hierPredLayerIdx; // hierarchical prediction layer index Picture* m_scaledRefPicList[NUM_REF_PIC_LIST_01][MAX_NUM_REF + 1]; Picture* m_savedRefPicList[NUM_REF_PIC_LIST_01][MAX_NUM_REF + 1]; std::pair<int, int> m_scalingRatio[NUM_REF_PIC_LIST_01][MAX_NUM_REF_PICS]; @@ -2882,7 +2882,7 @@ public: const Picture* getPic() const { return m_pcPic; } Picture * getRefPic(RefPicList e, int refIdx) const { return m_apcRefPicList[e][refIdx]; } int getRefPOC(RefPicList e, int refIdx) const { return m_aiRefPOCList[e][refIdx]; } - int getDepth() const { return m_iDepth; } + int getHierPredLayerIdx() const { return m_hierPredLayerIdx; } bool getColFromL0Flag() const { return m_colFromL0Flag; } uint32_t getColRefIdx() const { return m_colRefIdx; } void checkColRefIdx(uint32_t curSliceSegmentIdx, const Picture* pic); @@ -2933,7 +2933,7 @@ public: void setNumRefIdx( RefPicList e, int i ) { m_aiNumRefIdx[e] = i; } void setPic( Picture* p ) { m_pcPic = p; } - void setDepth( int iDepth ) { m_iDepth = iDepth; } + void setHierPredLayerIdx(int idx) { m_hierPredLayerIdx = idx; } void constructRefPicList(PicList& rcListPic); void setRefPOCList(); diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 1b4de3b8a..7a1dbb29a 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2704,33 +2704,33 @@ void EncGOP::compressGOP(int pocLast, int numPicRcvd, PicList &rcListPic, std::l xPicInitHashME( pcPic, pcSlice->getPPS(), rcListPic ); - if( m_pcCfg->getUseAMaxBT() ) + if (m_pcCfg->getUseAMaxBT()) { + const SliceType sliceType = pcSlice->getSliceType(); + const SPS *sps = pcSlice->getSPS(); + if (!pcSlice->isIRAP()) { - int refLayer = pcSlice->getDepth(); - if (refLayer > 9) - { - refLayer = 9; // Max layer is 10 - } + const int hierPredLayerIdx = std::min<int>(pcSlice->getHierPredLayerIdx(), (int) m_blkStat.size() - 1); if (m_initAMaxBt && pcSlice->getPOC() > m_prevISlicePoc) { - m_blkSize.fill(0); - m_numBlks.fill(0); + m_blkStat.fill({ 0, 0 }); m_initAMaxBt = false; } - if (refLayer >= 0 && m_numBlks[refLayer] != 0) + if (hierPredLayerIdx >= 0 && m_blkStat[hierPredLayerIdx].count != 0) { picHeader->setSplitConsOverrideFlag(true); - double dBlkSize = sqrt((double) m_blkSize[refLayer] / m_numBlks[refLayer]); - unsigned int newMaxBtSize = picHeader->getMaxBTSize(pcSlice->getSliceType(), CHANNEL_TYPE_LUMA); - if( dBlkSize < AMAXBT_TH32 ) + + const double avgBlkSize = (double) m_blkStat[hierPredLayerIdx].area / m_blkStat[hierPredLayerIdx].count; + + unsigned newMaxBtSize; + if (avgBlkSize < AMAXBT_TH32 * AMAXBT_TH32) { newMaxBtSize = 32; } - else if( dBlkSize < AMAXBT_TH64 ) + else if (avgBlkSize < AMAXBT_TH64 * AMAXBT_TH64) { newMaxBtSize = 64; } @@ -2738,64 +2738,51 @@ void EncGOP::compressGOP(int pocLast, int numPicRcvd, PicList &rcListPic, std::l { newMaxBtSize = 128; } - newMaxBtSize = Clip3(picHeader->getMinQTSize(pcSlice->getSliceType()), pcPic->cs->sps->getCTUSize(), newMaxBtSize); + newMaxBtSize = Clip3(picHeader->getMinQTSize(sliceType), sps->getCTUSize(), newMaxBtSize); picHeader->setMaxBTSize(1, newMaxBtSize); - m_blkSize[refLayer] = 0; - m_numBlks[refLayer] = 0; + m_blkStat[hierPredLayerIdx] = { 0, 0 }; } } else { if (m_initAMaxBt) { - m_blkSize.fill(0); - m_numBlks.fill(0); + m_blkStat.fill({ 0, 0 }); } m_prevISlicePoc = pcSlice->getPOC(); m_initAMaxBt = true; } - bool identicalToSPS=true; - const SPS* sps =pcSlice->getSPS(); - if (picHeader->getPicInterSliceAllowedFlag()) + bool identicalToSps = true; + + if (identicalToSps && picHeader->getPicInterSliceAllowedFlag()) { - if (picHeader->getMinQTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMinQTSize(pcSlice->getSliceType()) || - picHeader->getMaxMTTHierarchyDepth(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxMTTHierarchyDepth() || - picHeader->getMaxBTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxBTSize() || - picHeader->getMaxTTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxTTSize() - ) - { - identicalToSPS=false; - } + identicalToSps = picHeader->getMinQTSize(sliceType) == sps->getMinQTSize(sliceType) + && picHeader->getMaxMTTHierarchyDepth(sliceType) == sps->getMaxMTTHierarchyDepth() + && picHeader->getMaxBTSize(sliceType) == sps->getMaxBTSize() + && picHeader->getMaxTTSize(sliceType) == sps->getMaxTTSize(); } - if (identicalToSPS && picHeader->getPicIntraSliceAllowedFlag()) + if (identicalToSps && picHeader->getPicIntraSliceAllowedFlag()) { - if (picHeader->getMinQTSize(I_SLICE) != sps->getMinQTSize(I_SLICE) || - picHeader->getMaxMTTHierarchyDepth(I_SLICE) != sps->getMaxMTTHierarchyDepthI() || - picHeader->getMaxBTSize(I_SLICE) != sps->getMaxBTSizeI() || - picHeader->getMaxTTSize(I_SLICE) != sps->getMaxTTSizeI() - ) - { - identicalToSPS=false; - } + identicalToSps = picHeader->getMinQTSize(I_SLICE) == sps->getMinQTSize(I_SLICE) + && picHeader->getMaxMTTHierarchyDepth(I_SLICE) == sps->getMaxMTTHierarchyDepthI() + && picHeader->getMaxBTSize(I_SLICE) == sps->getMaxBTSizeI() + && picHeader->getMaxTTSize(I_SLICE) == sps->getMaxTTSizeI(); - if (identicalToSPS && sps->getUseDualITree()) + if (identicalToSps && sps->getUseDualITree()) { - if (picHeader->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) || - picHeader->getMaxMTTHierarchyDepth(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxMTTHierarchyDepthIChroma() || - picHeader->getMaxBTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxBTSizeIChroma() || - picHeader->getMaxTTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxTTSizeIChroma() - ) - { - identicalToSPS=false; - } + identicalToSps = + picHeader->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) == sps->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) + && picHeader->getMaxMTTHierarchyDepth(I_SLICE, CHANNEL_TYPE_CHROMA) == sps->getMaxMTTHierarchyDepthIChroma() + && picHeader->getMaxBTSize(I_SLICE, CHANNEL_TYPE_CHROMA) == sps->getMaxBTSizeIChroma() + && picHeader->getMaxTTSize(I_SLICE, CHANNEL_TYPE_CHROMA) == sps->getMaxTTSizeIChroma(); } } - if (identicalToSPS) + if (identicalToSps) { picHeader->setSplitConsOverrideFlag(false); } @@ -3654,15 +3641,14 @@ void EncGOP::compressGOP(int pocLast, int numPicRcvd, PicList &rcListPic, std::l pcSlice->freeScaledRefPicList( scaledRefPic ); - if( m_pcCfg->getUseAMaxBT() ) + if (m_pcCfg->getUseAMaxBT() && !pcSlice->isIntra()) { - for( const CodingUnit *cu : pcPic->cs->cus ) + const int hierPredLayerIdx = std::min<int>(pcSlice->getHierPredLayerIdx(), (int) m_blkStat.size() - 1); + + for (const CodingUnit *cu: pcPic->cs->cus) { - if( !pcSlice->isIntra() ) - { - m_blkSize[pcSlice->getDepth()] += cu->Y().area(); - m_numBlks[pcSlice->getDepth()]++; - } + m_blkStat[hierPredLayerIdx].area += cu->Y().area(); + m_blkStat[hierPredLayerIdx].count++; } } diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index 89ad652e1..3ddf1258c 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -185,10 +185,14 @@ private: int m_DBParam[MAX_ENCODER_DEBLOCKING_QUALITY_LAYERS][4]; //[layer_id][0: available; 1: bDBDisabled; 2: Beta Offset Div2; 3: Tc Offset Div2;] // members needed for adaptive max BT size - std::array<uint32_t, 8> m_blkSize; - std::array<uint32_t, 8> m_numBlks; - uint32_t m_prevISlicePoc; - bool m_initAMaxBt; + struct BlkStat + { + uint32_t area; + uint32_t count; + }; + std::array<BlkStat, 8> m_blkStat; + uint32_t m_prevISlicePoc; + bool m_initAMaxBt; AUWriterIf* m_AUWriterIf; #if GDR_ENABLED diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp index 2b1181701..128e18eea 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.cpp +++ b/source/Lib/EncoderLib/EncModeCtrl.cpp @@ -1103,11 +1103,12 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru const CodingUnit* cuLeft = cs.getCU( cs.area.blocks[partitioner.chType].pos().offset( -1, 0 ), partitioner.chType ); const CodingUnit* cuAbove = cs.getCU( cs.area.blocks[partitioner.chType].pos().offset( 0, -1 ), partitioner.chType ); - const bool qtBeforeBt = ( ( cuLeft && cuAbove && cuLeft ->qtDepth > partitioner.currQtDepth && cuAbove->qtDepth > partitioner.currQtDepth ) - || ( cuLeft && !cuAbove && cuLeft ->qtDepth > partitioner.currQtDepth ) - || ( !cuLeft && cuAbove && cuAbove->qtDepth > partitioner.currQtDepth ) - || ( !cuAbove && !cuLeft && cs.area.lwidth() >= ( 32 << cs.slice->getDepth() ) ) ) - && ( cs.area.lwidth() > ( cs.pcv->getMinQtSize( *cs.slice, partitioner.chType ) << 1 ) ); + const bool qtBeforeBt = + ((cuLeft && cuAbove && cuLeft->qtDepth > partitioner.currQtDepth && cuAbove->qtDepth > partitioner.currQtDepth) + || (cuLeft && !cuAbove && cuLeft->qtDepth > partitioner.currQtDepth) + || (!cuLeft && cuAbove && cuAbove->qtDepth > partitioner.currQtDepth) + || (!cuAbove && !cuLeft && cs.area.lwidth() >= (32 << cs.slice->getHierPredLayerIdx()))) + && (cs.area.lwidth() > (cs.pcv->getMinQtSize(*cs.slice, partitioner.chType) << 1)); // set features ComprCUCtx &cuECtx = m_ComprCUCtxList.back(); diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp index 42a5fca38..717c6ad2e 100644 --- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp +++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp @@ -356,7 +356,7 @@ void EncSampleAdaptiveOffset::decidePicParams(const Slice& slice, bool* sliceEna } } - const int picTempLayer = slice.getDepth(); + const int hierPredLayerIdx = slice.getHierPredLayerIdx(); //decide sliceEnabled[compIdx] const int numberOfComponents = m_numberOfComponents; @@ -375,8 +375,9 @@ void EncSampleAdaptiveOffset::decidePicParams(const Slice& slice, bool* sliceEna if (saoEncodingRateChroma>0.0) { // decide slice-level on/off based on previous results - if( (picTempLayer > 0) - && (m_saoDisabledRate[compIdx][picTempLayer-1] > ((compIdx==COMPONENT_Y) ? saoEncodingRate : saoEncodingRateChroma)) ) + if (hierPredLayerIdx > 0 + && (m_saoDisabledRate[compIdx][hierPredLayerIdx - 1] + > ((compIdx == COMPONENT_Y) ? saoEncodingRate : saoEncodingRateChroma))) { sliceEnabled[compIdx] = false; } @@ -384,8 +385,7 @@ void EncSampleAdaptiveOffset::decidePicParams(const Slice& slice, bool* sliceEna else { // decide slice-level on/off based on previous results - if( (picTempLayer > 0) - && (m_saoDisabledRate[COMPONENT_Y][0] > saoEncodingRate) ) + if (hierPredLayerIdx > 0 && (m_saoDisabledRate[COMPONENT_Y][0] > saoEncodingRate)) { sliceEnabled[compIdx] = false; } @@ -1103,7 +1103,7 @@ void EncSampleAdaptiveOffset::disabledRate( CodingStructure& cs, SAOBlkParam* re { const PreCalcValues& pcv = *cs.pcv; const uint32_t numberOfComponents = getNumberValidComponents( cs.picture->chromaFormat ); - int picTempLayer = cs.slice->getDepth(); + const int hierPredLayerIdx = cs.slice->getHierPredLayerIdx(); int numCtusForSAOOff[MAX_NUM_COMPONENT]; for (int compIdx = 0; compIdx < numberOfComponents; compIdx++) @@ -1121,10 +1121,10 @@ void EncSampleAdaptiveOffset::disabledRate( CodingStructure& cs, SAOBlkParam* re { for (int compIdx = 0; compIdx < numberOfComponents; compIdx++) { - m_saoDisabledRate[compIdx][picTempLayer] = (double)numCtusForSAOOff[compIdx]/(double)pcv.sizeInCtus; + m_saoDisabledRate[compIdx][hierPredLayerIdx] = (double) numCtusForSAOOff[compIdx] / (double) pcv.sizeInCtus; } } - else if (picTempLayer == 0) + else if (hierPredLayerIdx == 0) { m_saoDisabledRate[COMPONENT_Y][0] = (double)(numCtusForSAOOff[COMPONENT_Y]+numCtusForSAOOff[COMPONENT_Cb]+numCtusForSAOOff[COMPONENT_Cr])/(double)(pcv.sizeInCtus *3); } diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 62fdc3322..af6750f0e 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -382,7 +382,7 @@ void EncSlice::initEncSlice(Picture *pcPic, const int pocLast, const int pocCurr #endif // depth computation based on GOP size - int depth; + int hierPredLayerIdx; { int poc = rpcSlice->getPOC(); if(isField) @@ -396,12 +396,12 @@ void EncSlice::initEncSlice(Picture *pcPic, const int pocLast, const int pocCurr if ( poc == 0 ) { - depth = 0; + hierPredLayerIdx = 0; } else { int step = m_pcCfg->getGOPSize() * multipleFactor; - depth = 0; + hierPredLayerIdx = 0; for( int i=step>>1; i>=1; i>>=1 ) { for (int j = i; j<(m_pcCfg->getGOPSize() * multipleFactor); j += step) @@ -413,7 +413,7 @@ void EncSlice::initEncSlice(Picture *pcPic, const int pocLast, const int pocCurr } } step >>= 1; - depth++; + hierPredLayerIdx++; } } @@ -421,7 +421,7 @@ void EncSlice::initEncSlice(Picture *pcPic, const int pocLast, const int pocCurr { if (isField && ((rpcSlice->getPOC() % 2) == 1)) { - depth++; + hierPredLayerIdx++; } } } @@ -462,7 +462,7 @@ void EncSlice::initEncSlice(Picture *pcPic, const int pocLast, const int pocCurr eSliceType = (pocLast == 0 || pocCurr == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; } - rpcSlice->setDepth ( depth ); + rpcSlice->setHierPredLayerIdx(hierPredLayerIdx); rpcSlice->setSliceType ( eSliceType ); // ------------------------------------------------------------------------------------------------------------------ @@ -870,7 +870,7 @@ double EncSlice::initializeLambda(const Slice* slice, const int GOPid, const int dLambda = dQPFactor * pow(2.0, (dQP + bitDepthShift) / 3.0); - if (slice->getDepth() > 0 && !m_pcCfg->getLambdaFromQPEnable()) + if (slice->getHierPredLayerIdx() > 0 && !m_pcCfg->getLambdaFromQPEnable()) { dLambda *= Clip3(2.0, 4.0, ((refQP + bitDepthShift) / 6.0)); } -- GitLab