From 25e0d1ad1483990164f7034be923c6e1d1e21a35 Mon Sep 17 00:00:00 2001 From: Tangi Poirier <tangi.poirier@interdigital.com> Date: Tue, 7 Dec 2021 02:38:57 +0000 Subject: [PATCH] Add check of reference frame structure to detect low delay configuration --- source/App/EncoderApp/EncApp.cpp | 1 + source/App/EncoderApp/EncAppCfg.cpp | 4 ++++ source/App/EncoderApp/EncAppCfg.h | 1 + source/Lib/EncoderLib/EncCfg.h | 4 ++++ source/Lib/EncoderLib/EncCu.cpp | 4 ++-- source/Lib/EncoderLib/EncLib.cpp | 11 ++++++----- source/Lib/EncoderLib/EncSlice.cpp | 2 +- source/Lib/EncoderLib/InterSearch.cpp | 4 ++-- 8 files changed, 21 insertions(+), 10 deletions(-) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index eb4ea5113..fd349f1bf 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -597,6 +597,7 @@ void EncApp::xInitLibCfg() m_cEncLib.setEnablePictureHeaderInSliceHeader ( m_enablePictureHeaderInSliceHeader ); m_cEncLib.setMaxTempLayer ( m_maxTempLayer ); + m_cEncLib.setIsLowDelay ( m_isLowDelay ); //===== Slice ======== diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 8f7e8e384..4eaba3123 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -3529,6 +3529,7 @@ bool EncAppCfg::xCheckParameter() xConfirmPara( m_fastLocalDualTreeMode < 0 || m_fastLocalDualTreeMode > 2, "FastLocalDualTreeMode must be in range [0..2]" ); int extraRPLs = 0; + bool hasFutureRef = false; //start looping through frames in coding order until we can verify that the GOP structure is correct. while (!verifiedGOP && !errorGOP) { @@ -3738,6 +3739,7 @@ bool EncAppCfg::xCheckParameter() for (int i = 0; i< m_RPLList0[curGOP].m_numRefPics; i++) { int absPOC = curPOC - m_RPLList0[curGOP].m_deltaRefPics[i]; + hasFutureRef |= (m_RPLList0[curGOP].m_deltaRefPics[i] < 0); if (absPOC >= 0) { refList[numRefs] = absPOC; @@ -3747,6 +3749,7 @@ bool EncAppCfg::xCheckParameter() for (int i = 0; i< m_RPLList1[curGOP].m_numRefPics; i++) { int absPOC = curPOC - m_RPLList1[curGOP].m_deltaRefPics[i]; + hasFutureRef |= (m_RPLList1[curGOP].m_deltaRefPics[i] < 0); if (absPOC >= 0) { bool alreadyExist = false; @@ -3769,6 +3772,7 @@ bool EncAppCfg::xCheckParameter() } checkGOP++; } + m_isLowDelay = !hasFutureRef && m_iIntraPeriod != 1; xConfirmPara(errorGOP, "Invalid GOP structure given"); m_maxTempLayer = 1; diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index a52f68234..90725a554 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -317,6 +317,7 @@ protected: bool m_bUseWPSNR; ///< Flag to output perceptually weighted peak SNR (WPSNR) instead of PSNR #endif int m_maxTempLayer; ///< Max temporal layer + bool m_isLowDelay; // coding unit (CU) definition unsigned m_uiCTUSize; diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 2d6adad24..948b3791a 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -299,6 +299,7 @@ protected: // TODO: We need to have a common sliding mechanism used by both the encoder and decoder int m_maxTempLayer; ///< Max temporal layer + bool m_isLowDelay; unsigned m_CTUSize; bool m_subPicInfoPresentFlag; uint32_t m_numSubPics; @@ -1127,6 +1128,9 @@ public: int getMaxTempLayer () { return m_maxTempLayer; } void setMaxTempLayer ( int maxTempLayer ) { m_maxTempLayer = maxTempLayer; } + bool getIsLowDelay () { return m_isLowDelay; } + void setIsLowDelay ( bool isLowDelay ) { m_isLowDelay = isLowDelay; } + void setCTUSize ( unsigned u ) { m_CTUSize = u; } void setMinQTSizes ( unsigned* minQT) { m_uiMinQT[0] = minQT[0]; m_uiMinQT[1] = minQT[1]; m_uiMinQT[2] = minQT[2]; } void setMaxBTSizes ( unsigned* maxBT) { m_uiMaxBT[0] = maxBT[0]; m_uiMaxBT[1] = maxBT[1]; m_uiMaxBT[2] = maxBT[2]; } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 2bd9df9e6..32265733b 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -4243,7 +4243,7 @@ void EncCu::xCheckRDCostInter( CodingStructure *&tempCS, CodingStructure *&bestC if (m_pcEncCfg->getUseBcwFast()) { - if (isEqualUni == true && m_pcEncCfg->getIntraPeriod() == -1) + if (isEqualUni == true && m_pcEncCfg->getIsLowDelay()) { break; } @@ -4498,7 +4498,7 @@ bool EncCu::xCheckRDCostInterIMV(CodingStructure *&tempCS, CodingStructure *&bes if( m_pcEncCfg->getUseBcwFast() ) { - if( isEqualUni == true && m_pcEncCfg->getIntraPeriod() == -1 ) + if( isEqualUni == true && m_pcEncCfg->getIsLowDelay()) { break; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index fa906fcec..76ab64ae4 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -2019,7 +2019,7 @@ void EncLib::xInitRPL(SPS &sps) void EncLib::getActiveRefPicListNumForPOC(const SPS *sps, int POCCurr, int GOPid, uint32_t *activeL0, uint32_t *activeL1) { - if (m_intraPeriod < 0) //Only for RA + if (m_isLowDelay) //Only for RA { *activeL0 = *activeL1 = 0; return; @@ -2030,7 +2030,7 @@ void EncLib::getActiveRefPicListNumForPOC(const SPS *sps, int POCCurr, int GOPid int fullListNum = m_iGOPSize; int partialListNum = getRPLCandidateSize(0) - m_iGOPSize; int extraNum = fullListNum; - if (m_intraPeriod < 0) + if (m_isLowDelay) { if (POCCurr < (2 * m_iGOPSize + 2)) { @@ -2093,11 +2093,12 @@ void EncLib::selectReferencePictureList(Slice* slice, int POCCurr, int GOPid, in } } - if (rplPeriod < 0) + if (m_isLowDelay) { - if (POCCurr < (2 * m_iGOPSize + 2)) + const int currPOCsinceLastIDR = POCCurr - slice->getLastIDR(); + if (currPOCsinceLastIDR < (2 * m_iGOPSize + 2)) { - int candidateIdx = (POCCurr + m_iGOPSize - 1 >= fullListNum + partialListNum) ? GOPid : POCCurr + m_iGOPSize - 1; + int candidateIdx = (currPOCsinceLastIDR + m_iGOPSize - 1 >= fullListNum + partialListNum) ? GOPid : currPOCsinceLastIDR + m_iGOPSize - 1; slice->setRPL0idx(candidateIdx); slice->setRPL1idx(candidateIdx); } diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 8c0560d07..3cc7f917d 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1684,7 +1684,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons (pcSlice->getSPS()->getIBCFlag() && m_pcCuEncoder->getEncCfg()->getIBCHashSearch())) { m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap(cs.picture->getTrueOrigBuf()); - if (m_pcCfg->getIntraPeriod() != -1) + if (!m_pcCfg->getIsLowDelay()) { int hashBlkHitPerc = m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y()); cs.slice->setDisableSATDForRD(hashBlkHitPerc > 59); diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index 039078e9e..80feb43aa 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -265,7 +265,7 @@ void InterSearch::init( EncCfg* pcEncCfg, m_tmpAffiDeri[0] = new int[MAX_CU_SIZE * MAX_CU_SIZE]; m_tmpAffiDeri[1] = new int[MAX_CU_SIZE * MAX_CU_SIZE]; m_pTempPel = new Pel[maxCUWidth*maxCUHeight]; - m_affMVListMaxSize = (pcEncCfg->getIntraPeriod() == (uint32_t)-1) ? AFFINE_ME_LIST_SIZE_LD : AFFINE_ME_LIST_SIZE; + m_affMVListMaxSize = pcEncCfg->getIsLowDelay() ? AFFINE_ME_LIST_SIZE_LD : AFFINE_ME_LIST_SIZE; if (!m_affMVList) { m_affMVList = new AffineMVInfo[m_affMVListMaxSize]; @@ -8702,7 +8702,7 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu, // 8 nearest neighbor search int testPos[8][2] = { { -1, 0 },{ 0, -1 },{ 0, 1 },{ 1, 0 },{ -1, -1 },{ -1, 1 },{ 1, 1 },{ 1, -1 } }; - const int maxSearchRound = (pu.cu->imv) ? 3 : ((m_pcEncCfg->getUseAffineAmvrEncOpt() && m_pcEncCfg->getIntraPeriod() == (uint32_t)-1) ? 2 : 3); + const int maxSearchRound = (pu.cu->imv) ? 3 : ((m_pcEncCfg->getUseAffineAmvrEncOpt() && m_pcEncCfg->getIsLowDelay()) ? 2 : 3); for (int rnd = 0; rnd < maxSearchRound; rnd++) { -- GitLab