From d8e32ddc0738930c57a9e37d146cb5ac98c826e6 Mon Sep 17 00:00:00 2001 From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de> Date: Fri, 3 Jul 2020 16:19:55 +0200 Subject: [PATCH 1/3] Support for dependent layer IDR pictures using B slices - set slice type properly - fix coding tool conditions that check for IRAP, but should be checking for intra --- source/Lib/EncoderLib/EncGOP.cpp | 12 +++++------- source/Lib/EncoderLib/EncModeCtrl.cpp | 12 ++++++------ source/Lib/EncoderLib/EncSlice.cpp | 25 ++++++++++++++----------- source/Lib/EncoderLib/EncSlice.h | 4 +--- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 6d43cf0f71..d4da556652 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2070,9 +2070,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcPic->allocateNewSlice(); m_pcSliceEncoder->setSliceSegmentIdx(0); - m_pcSliceEncoder->initEncSlice(pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField - , isEncodeLtRef - ); + m_pcSliceEncoder->initEncSlice(pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField, isEncodeLtRef, m_pcEncLib->getLayerId() ); DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "poc", pocCurr ) ) ); DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 0 ) ) ); @@ -2219,7 +2217,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 || (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) ) - || (!pcSlice->isIRAP() && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId()))) + || (/* !pcSlice->isIRAP() && */ pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId()))) ) { xCreateExplicitReferencePictureSetFromReference( pcSlice, rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1() ); @@ -2333,7 +2331,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if( m_pcCfg->getUseAMaxBT() ) { - if( !pcSlice->isIRAP() ) + if( !pcSlice->isIntra() ) { int refLayer = pcSlice->getDepth(); if( refLayer > 9 ) refLayer = 9; // Max layer is 10 @@ -2531,7 +2529,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false ); // set adaptive search range for non-intra-slices - if (m_pcCfg->getUseASR() && !pcSlice->isIRAP()) + if (m_pcCfg->getUseASR() && !pcSlice->isIntra()) { m_pcSliceEncoder->setSearchRange(pcSlice); } @@ -3131,7 +3129,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, { for( const CodingUnit *cu : pcPic->cs->cus ) { - if( !pcSlice->isIRAP() ) + if( !pcSlice->isIntra() ) { m_uiBlkSize[pcSlice->getDepth()] += cu->Y().area(); m_uiNumBlk [pcSlice->getDepth()]++; diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp index fbfddcc9f1..864b74c6ae 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.cpp +++ b/source/Lib/EncoderLib/EncModeCtrl.cpp @@ -1324,12 +1324,12 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru // add intra modes if( tryIntraRdo ) { - if (cs.slice->getSPS()->getPLTMode() && (partitioner.treeType != TREE_D || cs.slice->isIRAP() || (cs.area.lwidth() == 4 && cs.area.lheight() == 4)) && getPltEnc()) + if (cs.slice->getSPS()->getPLTMode() && (partitioner.treeType != TREE_D || cs.slice->isIntra() || (cs.area.lwidth() == 4 && cs.area.lheight() == 4)) && getPltEnc()) { m_ComprCUCtxList.back().testModes.push_back({ ETM_PALETTE, ETO_STANDARD, qp }); } m_ComprCUCtxList.back().testModes.push_back( { ETM_INTRA, ETO_STANDARD, qp } ); - if (cs.slice->getSPS()->getPLTMode() && partitioner.treeType == TREE_D && !cs.slice->isIRAP() && !(cs.area.lwidth() == 4 && cs.area.lheight() == 4) && getPltEnc()) + if (cs.slice->getSPS()->getPLTMode() && partitioner.treeType == TREE_D && !cs.slice->isIntra() && !(cs.area.lwidth() == 4 && cs.area.lheight() == 4) && getPltEnc()) { m_ComprCUCtxList.back().testModes.push_back({ ETM_PALETTE, ETO_STANDARD, qp }); } @@ -1346,7 +1346,7 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru } // add first pass modes - if ( !m_slice->isIRAP() && !( cs.area.lwidth() == 4 && cs.area.lheight() == 4 ) && tryInterRdo ) + if ( !m_slice->isIntra() && !( cs.area.lwidth() == 4 && cs.area.lheight() == 4 ) && tryInterRdo ) { for( int qpLoop = maxQP; qpLoop >= minQP; qpLoop-- ) { @@ -1520,7 +1520,7 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt { return true; } - if( !( slice.isIRAP() || bestMode.type == ETM_INTRA || !cuECtx.bestTU || + if( !( slice.isIntra() || bestMode.type == ETM_INTRA || !cuECtx.bestTU || ((!m_pcEncCfg->getDisableIntraPUsInInterSlices()) && (!relatedCU.isInter || !relatedCU.isIBC) && ( ( cuECtx.bestTU->cbf[0] != 0 ) || ( ( numComp > COMPONENT_Cb ) && cuECtx.bestTU->cbf[1] != 0 ) || @@ -1540,7 +1540,7 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt if( lastTestMode().type != ETM_INTRA && cuECtx.bestCS && cuECtx.bestCU && interHadActive( cuECtx ) ) { // Get SATD threshold from best Inter-CU - if (!cs.slice->isIRAP() && m_pcEncCfg->getUsePbIntraFast() && !cs.slice->getDisableSATDForRD()) + if (!cs.slice->isIntra() && m_pcEncCfg->getUsePbIntraFast() && !cs.slice->getDisableSATDForRD()) { CodingUnit* bestCU = cuECtx.bestCU; if (bestCU && !CU::isIntra(*bestCU)) @@ -1552,7 +1552,7 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt } } } - if (bestMode.type == ETM_PALETTE && !slice.isIRAP() && partitioner.treeType == TREE_D && !(partitioner.currArea().lumaSize().width == 4 && partitioner.currArea().lumaSize().height == 4)) // inter slice + if (bestMode.type == ETM_PALETTE && !slice.isIntra() && partitioner.treeType == TREE_D && !(partitioner.currArea().lumaSize().width == 4 && partitioner.currArea().lumaSize().height == 4)) // inter slice { return false; } diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 60d94c0dd8..2f40055f6d 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -315,9 +315,8 @@ static int applyQPAdaptationChroma (Picture* const pcPic, Slice* const pcSlice, \param rpcSlice slice header class \param isField true for field coding */ -void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr, const int iGOPid, Slice*& rpcSlice, const bool isField - , bool isEncodeLtRef -) +void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr, const int iGOPid, Slice*& rpcSlice, const bool isField, + bool isEncodeLtRef, int layerId) { double dQP; double dLambda; @@ -329,6 +328,8 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr rpcSlice->setPic( pcPic ); rpcSlice->setPicHeader( picHeader ); rpcSlice->initSlice(); + rpcSlice->setNalUnitLayerId(layerId); + int multipleFactor = m_pcCfg->getUseCompositeRef() ? 2 : 1; if (m_pcCfg->getUseCompositeRef() && isEncodeLtRef) { @@ -432,17 +433,18 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr SliceType eSliceType; eSliceType=B_SLICE; + const bool ilRefAvilable = rpcSlice->getPic()->cs->vps && m_pcCfg->getNumRefLayers(rpcSlice->getPic()->cs->vps->getGeneralLayerIdx(layerId)); if (m_pcCfg->getIntraPeriod() > 0 ) { if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled()) { if(m_pcCfg->getDecodingRefreshType() == 3) { - eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; } else { - eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; } } } @@ -599,17 +601,17 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr { // restore original slice type - if (m_pcCfg->getIntraPeriod() > 0) + if (m_pcCfg->getIntraPeriod() > 0 ) { - if (!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled()) + if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled()) { - if (m_pcCfg->getDecodingRefreshType() == 3) + if(m_pcCfg->getDecodingRefreshType() == 3) { - eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; } else { - eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; } } } @@ -617,6 +619,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->setSliceType ( eSliceType ); } @@ -1631,7 +1634,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons else { bpp = pRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->isIRAP()); - if ( pcPic->slices[0]->isIRAP()) + if ( pcPic->slices[0]->isIntra()) { estLambda = pRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP); } diff --git a/source/Lib/EncoderLib/EncSlice.h b/source/Lib/EncoderLib/EncSlice.h index be28672cc3..44e6b9fc71 100644 --- a/source/Lib/EncoderLib/EncSlice.h +++ b/source/Lib/EncoderLib/EncSlice.h @@ -118,9 +118,7 @@ public: /// preparation of slice encoding (reference marking, QP and lambda) void initEncSlice ( Picture* pcPic, const int pocLast, const int pocCurr, - const int iGOPid, Slice*& rpcSlice, const bool isField - , bool isEncodeLtRef - ); + const int iGOPid, Slice*& rpcSlice, const bool isField, bool isEncodeLtRef, int layerId ); void resetQP ( Picture* pic, int sliceQP, double lambda ); -- GitLab From eaa16215a41c8268cd0eb83cc8fc5bb077fa8841 Mon Sep 17 00:00:00 2001 From: Taoran Lu <tlu@dolby.com> Date: Fri, 3 Jul 2020 16:36:11 +0200 Subject: [PATCH 2/3] Fix for LMCS model estimation, which used to depend on intra slices --- source/Lib/EncoderLib/EncGOP.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index d4da556652..292d3e9c33 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1803,7 +1803,13 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice) { if (slice->getSPS()->getUseLmcs()) { - const SliceType sliceType = slice->getSliceType(); + const SliceType realSliceType = slice->getSliceType(); + SliceType condSliceType = realSliceType; + + if (condSliceType != I_SLICE && slice->getNalUnitLayerId() > 0 && (slice->getNalUnitType()>= NAL_UNIT_CODED_SLICE_IDR_W_RADL && slice->getNalUnitType()<= NAL_UNIT_CODED_SLICE_CRA)) + { + condSliceType = I_SLICE; + } m_pcReshaper->getReshapeCW()->rspTid = slice->getTLayer() + (slice->isIntra() ? 0 : 1); m_pcReshaper->getReshapeCW()->rspSliceQP = slice->getSliceQp(); @@ -1814,18 +1820,18 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice) if (m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_PQ) { - m_pcReshaper->preAnalyzerHDR(pic, sliceType, m_pcCfg->getReshapeCW(), m_pcCfg->getDualITree()); + m_pcReshaper->preAnalyzerHDR(pic, condSliceType, m_pcCfg->getReshapeCW(), m_pcCfg->getDualITree()); } else if (m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_SDR || m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_HLG) { - m_pcReshaper->preAnalyzerLMCS(pic, m_pcCfg->getReshapeSignalType(), sliceType, m_pcCfg->getReshapeCW()); + m_pcReshaper->preAnalyzerLMCS(pic, m_pcCfg->getReshapeSignalType(), condSliceType, m_pcCfg->getReshapeCW()); } else { THROW("Reshaper for other signal currently not defined!"); } - if (sliceType == I_SLICE ) + if (condSliceType == I_SLICE ) { if (m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_PQ) { @@ -1846,7 +1852,10 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice) } m_pcReshaper->setCTUFlag(false); - + if (realSliceType != condSliceType) + { + m_pcReshaper->setCTUFlag(true); + } } else { -- GitLab From 437068e33460efaaa024b0b9c6d75270544a8760 Mon Sep 17 00:00:00 2001 From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de> Date: Fri, 3 Jul 2020 17:18:58 +0200 Subject: [PATCH 3/3] Create a config file option for this mode --- doc/software-manual.tex | 6 ++++++ source/App/EncoderApp/EncApp.cpp | 2 ++ source/App/EncoderApp/EncAppCfg.cpp | 1 + source/App/EncoderApp/EncAppCfg.h | 1 + source/Lib/EncoderLib/EncCfg.h | 4 ++++ source/Lib/EncoderLib/EncGOP.cpp | 2 +- source/Lib/EncoderLib/EncLib.cpp | 4 ++++ source/Lib/EncoderLib/EncSlice.cpp | 10 +++++----- 8 files changed, 24 insertions(+), 6 deletions(-) diff --git a/doc/software-manual.tex b/doc/software-manual.tex index fd102af34c..c3c9f495a5 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -1188,6 +1188,12 @@ be included in scalable nesting SEI messages (if scalable nesting SEI is enabled \Default{-1} & Specifies the maximum temporal ID for inter-layer reference pictures plus 1. The value 0 allows only to use IRAP pictures for inter-layer prediction. \\ + +\Option{AvoidIntraInDepLayer} & +%\ShortOption{\None} & +\Default{1} & +Replaces I slices in dependent layers with B slices, except for all-intra configuration (IntraPeriod=1). +\\ \end{OptionTableNoShorthand} diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index d992059502..3dead3da67 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -263,6 +263,8 @@ void EncApp::xInitLibCfg() m_cEncLib.setUpscaledOutput ( m_upscaledOutput ); m_cEncLib.setFramesToBeEncoded ( m_framesToBeEncoded ); + m_cEncLib.setAvoidIntraInDepLayer ( m_avoidIntraInDepLayer ); + //====== SPS constraint flags ======= #if STILL_PICTURE_PROFILES m_cEncLib.setOnePictureOnlyConstraintFlag ( m_onePictureOnlyConstraintFlag ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index fd69291907..dc381d00e3 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1429,6 +1429,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ( "NumOutputLayerSets", m_numOutputLayerSets, 1, "Number of output layer sets") ( "OlsOutputLayer%d", m_olsOutputLayerStr, string(""), MAX_VPS_LAYERS, "Output layer index of i-th OLS") ( "NumPTLsInVPS", m_numPtlsInVps, 1, "Number of profile_tier_level structures in VPS" ) + ( "AvoidIntraInDepLayers", m_avoidIntraInDepLayer, true, "Replaces I pictures in dependent layers with B pictures" ) #if JVET_Q0398_SUBLAYER_DEP ( "MaxTidILRefPicsPlus1", m_cfgVPSParameters.m_maxTidILRefPicsPlus1, -1, "Maximum temporal ID for inter-layer reference pictures plus 1, 0 for IRAP only" ) #endif diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index a8ae374f1f..9907d6e676 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -725,6 +725,7 @@ protected: double m_fractionOfFrames; ///< encode a fraction of the frames as specified in FramesToBeEncoded int m_switchPocPeriod; int m_upscaledOutput; ////< Output upscaled (2), decoded cropped but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR. + bool m_avoidIntraInDepLayer; bool m_gopBasedTemporalFilterEnabled; ///< GOP-based Temporal Filter enable/disable bool m_gopBasedTemporalFilterFutureReference; ///< Enable/disable future frame references in the GOP-based Temporal Filter diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 39080be669..fee7fac40f 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -780,6 +780,7 @@ protected: int m_switchPocPeriod; int m_upscaledOutput; int m_numRefLayers[MAX_VPS_LAYERS]; + bool m_avoidIntraInDepLayer; public: EncCfg() @@ -1981,6 +1982,9 @@ public: void setNumRefLayers( int* numRefLayers ) { std::memcpy( m_numRefLayers, numRefLayers, sizeof( m_numRefLayers ) ); } int getNumRefLayers( int layerIdx ) const { return m_numRefLayers[layerIdx]; } + void setAvoidIntraInDepLayer(bool b) { m_avoidIntraInDepLayer = b; } + bool getAvoidIntraInDepLayer() const { return m_avoidIntraInDepLayer; } + #if JVET_Q0398_SUBLAYER_DEP const CfgVPSParameters& getVPSParameters() const { return m_cfgVPSParameters; } void setVPSParameters(const CfgVPSParameters& cfg) { m_cfgVPSParameters = cfg; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 292d3e9c33..6d40fcdd17 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2226,7 +2226,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 || (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) ) - || (/* !pcSlice->isIRAP() && */ pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId()))) + || ((m_pcEncLib->getAvoidIntraInDepLayer() || !pcSlice->isIRAP()) && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId()))) ) { xCreateExplicitReferencePictureSetFromReference( pcSlice, rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1() ); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 974e02f465..7c6f71f8d3 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -219,6 +219,10 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) aps0.setAPSId( 0 ); aps0.setAPSType( SCALING_LIST_APS ); + if (getAvoidIntraInDepLayer() && getNumRefLayers(m_vps->getGeneralLayerIdx( getLayerId())) > 0) + { + setIDRRefParamListPresent(true); + } // initialize SPS xInitSPS( sps0 ); xInitVPS( sps0 ); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 2f40055f6d..0d0e751012 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -433,18 +433,18 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr SliceType eSliceType; eSliceType=B_SLICE; - const bool ilRefAvilable = rpcSlice->getPic()->cs->vps && m_pcCfg->getNumRefLayers(rpcSlice->getPic()->cs->vps->getGeneralLayerIdx(layerId)); + const bool useIlRef = m_pcCfg->getAvoidIntraInDepLayer() && rpcSlice->getPic()->cs->vps && m_pcCfg->getNumRefLayers(rpcSlice->getPic()->cs->vps->getGeneralLayerIdx(layerId)); if (m_pcCfg->getIntraPeriod() > 0 ) { if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled()) { if(m_pcCfg->getDecodingRefreshType() == 3) { - eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType; } else { - eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType; } } } @@ -607,11 +607,11 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr { if(m_pcCfg->getDecodingRefreshType() == 3) { - eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType; } else { - eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!ilRefAvilable) ? I_SLICE : eSliceType; + eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType; } } } -- GitLab