diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 8e18cd332a697beeca3528e873a56b1c7409618f..1fe39dfaab9b4e7fbdf6060f8652d2bcd51fa840 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -89,8 +89,10 @@ Slice::Slice() , m_pcPic ( NULL ) , m_pcPicHeader ( NULL ) , m_colFromL0Flag ( true ) +#if !SPS_ID_CHECK , m_noIncorrectPicOutputFlag ( false ) -, m_handleCraAsCvsStartFlag ( false ) +, m_handleCraAsCvsStartFlag ( false ) +#endif , m_colRefIdx ( 0 ) , m_uiTLayer ( 0 ) , m_bTLayerSwitchingFlag ( false ) @@ -1939,6 +1941,11 @@ PicHeader::PicHeader() , m_gdrPicFlag ( 0 ) , m_noOutputOfPriorPicsFlag ( 0 ) , m_recoveryPocCnt ( 0 ) +#if SPS_ID_CHECK +, m_noOutputBeforeRecoveryFlag ( false ) +, m_handleCraAsCvsStartFlag ( false ) +, m_handleGdrAsCvsStartFlag ( false ) +#endif , m_spsId ( -1 ) , m_ppsId ( -1 ) #if JVET_P0116_POC_MSB diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index ca381b6f2c4c23d98d9aa210bd6591e973723787..c35b0c7bbf98f291251d2d466518b8d0ff9af73a 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -2385,6 +2385,11 @@ private: bool m_gdrPicFlag; //!< gradual decoding refresh picture flag bool m_noOutputOfPriorPicsFlag; //!< no output of prior pictures flag uint32_t m_recoveryPocCnt; //!< recovery POC count +#if SPS_ID_CHECK + bool m_noOutputBeforeRecoveryFlag; //!< NoOutputBeforeRecoveryFlag + bool m_handleCraAsCvsStartFlag; //!< HandleCraAsCvsStartFlag + bool m_handleGdrAsCvsStartFlag; //!< HandleGdrAsCvsStartFlag +#endif int m_spsId; //!< sequence parameter set ID int m_ppsId; //!< picture parameter set ID #if JVET_P0116_POC_MSB @@ -2752,6 +2757,15 @@ public: void setNumL1Weights(int b) { m_numL1Weights = b; } int getNumL1Weights() { return m_numL1Weights; } #endif + +#if SPS_ID_CHECK + void setNoOutputBeforeRecoveryFlag( bool val ) { m_noOutputBeforeRecoveryFlag = val; } + bool getNoOutputBeforeRecoveryFlag() const { return m_noOutputBeforeRecoveryFlag; } + void setHandleCraAsCvsStartFlag( bool val ) { m_handleCraAsCvsStartFlag = val; } + bool getHandleCraAsCvsStartFlag() const { return m_handleCraAsCvsStartFlag; } + void setHandleGdrAsCvsStartFlag( bool val ) { m_handleGdrAsCvsStartFlag = val; } + bool getHandleGdrAsCvsStartFlag() const { return m_handleGdrAsCvsStartFlag; } +#endif }; /// slice header class @@ -2834,8 +2848,10 @@ private: const PicHeader* m_pcPicHeader; //!< pointer to picture header structure bool m_colFromL0Flag; // collocated picture from List0 flag +#if !SPS_ID_CHECK bool m_noIncorrectPicOutputFlag; bool m_handleCraAsCvsStartFlag; +#endif uint32_t m_colRefIdx; double m_lambdas[MAX_NUM_COMPONENT]; @@ -2982,7 +2998,8 @@ public: bool getIdrPicFlag() const { return getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP; } bool isIRAP() const { return (getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL) && (getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA); } #if SPS_ID_CHECK - bool isClvssPu() const { return m_eNalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && m_eNalUnitType <= NAL_UNIT_CODED_SLICE_GDR && !m_pcPPS->getMixedNaluTypesInPicFlag(); } + // CLVSS PU is either an IRAP PU with NoOutputBeforeRecoveryFlag equal to 1 or a GDR PU with NoOutputBeforeRecoveryFlag equal to 1. + bool isClvssPu() const { return m_eNalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && m_eNalUnitType <= NAL_UNIT_CODED_SLICE_GDR && !m_pcPPS->getMixedNaluTypesInPicFlag() && m_pcPicHeader->getNoOutputBeforeRecoveryFlag(); } #endif bool isIDRorBLA() const { return (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP); } void checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic); @@ -3083,11 +3100,13 @@ public: bool isTemporalLayerSwitchingPoint( PicList& rcListPic ) const; bool isStepwiseTemporalLayerSwitchingPointCandidate( PicList& rcListPic ) const; int checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePictureList *pRPL, int rplIdx, bool printErrors) const; +#if !SPS_ID_CHECK void setNoIncorrectPicOutputFlag(bool val) { m_noIncorrectPicOutputFlag = val; } bool getNoIncorrectPicOutputFlag() const { return m_noIncorrectPicOutputFlag; } void setHandleCraAsCvsStartFlag( bool val ) { m_handleCraAsCvsStartFlag = val; } bool getHandleCraAsCvsStartFlag() const { return m_handleCraAsCvsStartFlag; } +#endif void setNumTilesInSlice( uint32_t u ) { m_sliceMap.setNumTilesInSlice( u ); } uint32_t getNumTilesInSlice() const { return m_sliceMap.getNumTilesInSlice(); } diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 84b4aa680d5b014ac65660ad80167be9bc0dc864..5c8497481fb9b2f47e437562081ba11c15385d52 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -453,16 +453,20 @@ DecLib::DecLib() , m_prevTid0POC(0) , m_bFirstSliceInPicture(true) #if JVET_P0125_EOS_LAYER_SPECIFIC - , m_bFirstSliceInSequence{ true } + , m_firstSliceInSequence{ true } #else , m_bFirstSliceInSequence(true) #endif + , m_firstSliceInBitstream(true) , m_prevSliceSkipped(false) , m_skippedPOC(0) - , m_bFirstSliceInBitstream(true) , m_lastPOCNoOutputPriorPics(-1) , m_isNoOutputPriorPics(false) +#if SPS_ID_CHECK + , m_lastNoOutputBeforeRecoveryFlag( false ) +#else , m_lastNoIncorrectPicOutputFlag(false) +#endif , m_sliceLmcsApsId(-1) , m_pDecodedSEIOutputStream(NULL) , m_decodedPictureHashSEIEnabled(false) @@ -1483,7 +1487,7 @@ void DecLib::xCheckParameterSetConstraints(const int layerId) int curLayerBitDepth = sps->getBitDepth(CHANNEL_TYPE_LUMA); #if SPS_ID_CHECK - if (slice->isClvssPu() && m_bFirstSliceInPicture) + if( slice->isClvssPu() && m_bFirstSliceInPicture ) #else if (m_layerBitDepth[curLayerIdx] == 0) #endif @@ -1755,6 +1759,30 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl m_apcSlicePilot->setAssociatedIRAPPOC(m_pocCRA); m_apcSlicePilot->setAssociatedIRAPType(m_associatedIRAPType); +#if SPS_ID_CHECK + if( m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR ) + { + // Derive NoOutputBeforeRecoveryFlag + if( !pps->getMixedNaluTypesInPicFlag() ) + { + if( m_firstSliceInSequence[nalu.m_nuhLayerId] ) + { + m_picHeader.setNoOutputBeforeRecoveryFlag( true ); + } + else if( m_apcSlicePilot->getIdrPicFlag() ) + { + m_picHeader.setNoOutputBeforeRecoveryFlag( true ); + } + else if( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) + { + m_picHeader.setNoOutputBeforeRecoveryFlag( m_picHeader.getHandleCraAsCvsStartFlag() ); + } + else if( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR ) + { + m_picHeader.setNoOutputBeforeRecoveryFlag( m_picHeader.getHandleGdrAsCvsStartFlag() ); + } + } +#else //For inference of NoOutputOfPriorPicsFlag if (m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) { @@ -1770,9 +1798,17 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl { m_apcSlicePilot->setNoIncorrectPicOutputFlag(true); } - //the inference for NoOutputPriorPicsFlag - if (!m_bFirstSliceInBitstream && - (m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) && +#endif + + //the inference for NoOutputOfPriorPicsFlag +#if SPS_ID_CHECK + if( !m_firstSliceInBitstream && m_picHeader.getNoOutputBeforeRecoveryFlag() ) + { + m_picHeader.setNoOutputOfPriorPicsFlag( true ); + } +#else + if( !m_firstSliceInBitstream && + ( m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR ) && m_apcSlicePilot->getNoIncorrectPicOutputFlag()) { if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) @@ -1780,6 +1816,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl m_picHeader.setNoOutputOfPriorPicsFlag(true); } } +#endif else { m_picHeader.setNoOutputOfPriorPicsFlag(false); @@ -1787,9 +1824,26 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) { +#if SPS_ID_CHECK + m_lastNoOutputBeforeRecoveryFlag = m_picHeader.getNoOutputBeforeRecoveryFlag(); +#else m_lastNoIncorrectPicOutputFlag = m_apcSlicePilot->getNoIncorrectPicOutputFlag(); +#endif + } +#if SPS_ID_CHECK + + if( m_picHeader.getNoOutputOfPriorPicsFlag() ) + { + m_lastPOCNoOutputPriorPics = m_apcSlicePilot->getPOC(); + m_isNoOutputPriorPics = true; + } + else + { + m_isNoOutputPriorPics = false; } } +#else + } if ((m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) && m_picHeader.getNoOutputOfPriorPicsFlag()) { m_lastPOCNoOutputPriorPics = m_apcSlicePilot->getPOC(); @@ -1799,11 +1853,20 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl { m_isNoOutputPriorPics = false; } +#endif //For inference of PicOutputFlag +#if SPS_ID_CHECK + if( !pps->getMixedNaluTypesInPicFlag() && ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL ) ) +#else if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL) +#endif { +#if SPS_ID_CHECK + if( m_lastNoOutputBeforeRecoveryFlag ) +#else if (m_lastNoIncorrectPicOutputFlag) +#endif { m_picHeader.setPicOutputFlag(false); } @@ -1827,8 +1890,13 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl } #endif - if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) && +#if SPS_ID_CHECK + //Reset POC MSB when CRA or GDR has NoOutputBeforeRecoveryFlag equal to 1 + if( !pps->getMixedNaluTypesInPicFlag() && ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR ) && m_lastNoOutputBeforeRecoveryFlag ) +#else + if( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR ) && m_lastNoIncorrectPicOutputFlag) //Reset POC MSB when CRA or GDR has NoIncorrectPicOutputFlag equal to 1 +#endif { #if !JVET_P0101_POC_MULTILAYER PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId()); @@ -1865,7 +1933,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl //we should only get a different poc for a new picture (with CTU address==0) #if JVET_P0125_EOS_LAYER_SPECIFIC - if (m_apcSlicePilot->getPOC() != m_prevPOC && !m_bFirstSliceInSequence[nalu.m_nuhLayerId] && (m_apcSlicePilot->getFirstCtuRsAddrInSlice() != 0)) + if (m_apcSlicePilot->getPOC() != m_prevPOC && !m_firstSliceInSequence[nalu.m_nuhLayerId] && (m_apcSlicePilot->getFirstCtuRsAddrInSlice() != 0)) #else if(m_apcSlicePilot->getPOC() != m_prevPOC && !m_bFirstSliceInSequence && (m_apcSlicePilot->getFirstCtuRsAddrInSlice() != 0)) #endif @@ -1899,7 +1967,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl int refPicIndex; while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL0(), 0, true, &refPicIndex, m_apcSlicePilot->getNumRefIdx(REF_PIC_LIST_0))) > 0) { +#if SPS_ID_CHECK + if( !pps->getMixedNaluTypesInPicFlag() && ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() ) +#else if ( ( (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) ) && m_apcSlicePilot->getNoIncorrectPicOutputFlag() ) +#endif { if (m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex) == 0) { @@ -1913,7 +1985,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl } while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL1(), 0, true, &refPicIndex, m_apcSlicePilot->getNumRefIdx(REF_PIC_LIST_1))) > 0) { +#if SPS_ID_CHECK + if( !pps->getMixedNaluTypesInPicFlag() && ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() ) +#else if (((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)) && m_apcSlicePilot->getNoIncorrectPicOutputFlag()) +#endif { if (m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex) == 0) { @@ -1936,12 +2012,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl #if JVET_P0125_EOS_LAYER_SPECIFIC - m_bFirstSliceInSequence[nalu.m_nuhLayerId] = false; + m_firstSliceInSequence[nalu.m_nuhLayerId] = false; #else m_bFirstSliceInSequence = false; #endif - m_bFirstSliceInBitstream = false; - + m_firstSliceInBitstream = false; Slice* pcSlice = m_pcPic->slices[m_uiSliceSegmentIdx]; pcSlice->setPic( m_pcPic ); @@ -1950,7 +2025,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl m_pcPic->referenced = true; m_pcPic->layer = nalu.m_temporalId; m_pcPic->layerId = nalu.m_nuhLayerId; - m_pcPic->subLayerNonReferencePictureDueToSTSA = false; + m_pcPic->subLayerNonReferencePictureDueToSTSA = false; pcSlice->checkCRA(pcSlice->getRPL0(), pcSlice->getRPL1(), m_pocCRA, m_associatedIRAPType, m_cListPic); diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index 3d7d4a5b92f377829bebe4d0a96231efca3f3104..1edbe9cc3acd33e78200882c731280bc58d45ec5 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -112,21 +112,21 @@ private: int m_prevTid0POC; bool m_bFirstSliceInPicture; #if JVET_P0125_EOS_LAYER_SPECIFIC - bool m_bFirstSliceInSequence[MAX_VPS_LAYERS]; + bool m_firstSliceInSequence[MAX_VPS_LAYERS]; #else bool m_bFirstSliceInSequence; #endif + bool m_firstSliceInBitstream; bool m_prevSliceSkipped; int m_skippedPOC; - bool m_bFirstSliceInBitstream; int m_lastPOCNoOutputPriorPics; bool m_isNoOutputPriorPics; - bool m_lastNoIncorrectPicOutputFlag; //value of variable NoIncorrectPicOutputFlag of the last CRA / GDR pic + bool m_lastNoOutputBeforeRecoveryFlag; //value of variable NoOutputBeforeRecoveryFlag of the last CRA / GDR pic int m_sliceLmcsApsId; //value of LmcsApsId, constraint is same id for all slices in one picture std::ostream *m_pDecodedSEIOutputStream; int m_decodedPictureHashSEIEnabled; ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message - uint32_t m_numberOfChecksumErrorsDetected; + uint32_t m_numberOfChecksumErrorsDetected; bool m_warningMessageSkipPicture; @@ -199,8 +199,8 @@ public: void setFirstSliceInPicture (bool val) { m_bFirstSliceInPicture = val; } bool getFirstSliceInPicture () const { return m_bFirstSliceInPicture; } #if JVET_P0125_EOS_LAYER_SPECIFIC - bool getFirstSliceInSequence(int layer) const { return m_bFirstSliceInSequence[layer]; } - void setFirstSliceInSequence(bool val, int layer) { m_bFirstSliceInSequence[layer] = val; } + bool getFirstSliceInSequence(int layerId) const { return m_firstSliceInSequence[layerId]; } + void setFirstSliceInSequence(bool val, int layerId) { m_firstSliceInSequence[layerId] = val; } #else bool getFirstSliceInSequence () const { return m_bFirstSliceInSequence; } void setFirstSliceInSequence (bool val) { m_bFirstSliceInSequence = val; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 09c470337f82450c19e3210b452a7cecbcf6fc96..6d8364980382ea7e5984e60228291f2629e9a3a1 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -3152,16 +3152,28 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcSlice->setRPL0idx(pcPic->slices[0]->getRPL0idx()); pcSlice->setRPL1idx(pcPic->slices[0]->getRPL1idx()); +#if SPS_ID_CHECK + picHeader->setNoOutputBeforeRecoveryFlag( false ); +#else pcSlice->setNoIncorrectPicOutputFlag(false); +#endif if (pcSlice->isIRAP()) { if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP) { +#if SPS_ID_CHECK + picHeader->setNoOutputBeforeRecoveryFlag( true ); +#else pcSlice->setNoIncorrectPicOutputFlag(true); +#endif } //the inference for NoOutputPriorPicsFlag // KJS: This cannot happen at the encoder +#if SPS_ID_CHECK + if( !m_bFirst && ( pcSlice->isIRAP() || pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_GDR ) && picHeader->getNoOutputBeforeRecoveryFlag() ) +#else if (!m_bFirst && (pcSlice->isIRAP() || pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_GDR) && pcSlice->getNoIncorrectPicOutputFlag()) +#endif { if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_GDR) {