From d9f620a6887b9f7b037dc304efc5ad70c6b61517 Mon Sep 17 00:00:00 2001 From: Rickard Sjoberg <rickard.sjoberg@ericsson.com> Date: Mon, 2 Mar 2020 10:12:03 +0100 Subject: [PATCH] JVET-P0978 Adding RPL related bitstream constraints --- source/App/DecoderApp/DecApp.cpp | 3 + source/Lib/CommonLib/Picture.h | 10 +++ source/Lib/CommonLib/Slice.cpp | 133 +++++++++++++++++++++++++++++++ source/Lib/CommonLib/Slice.h | 7 ++ source/Lib/CommonLib/TypeDef.h | 2 + source/Lib/DecoderLib/DecLib.cpp | 33 +++++++- source/Lib/DecoderLib/DecLib.h | 7 ++ 7 files changed, 194 insertions(+), 1 deletion(-) diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index b56261db8..95f599c85 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -247,6 +247,9 @@ uint32_t DecApp::decode() #endif } +#if JVET_P0978_RPL_RESTRICTIONS + m_cDecLib.UpdateAssociatedIRAP(); +#endif } else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) && #if JVET_P0125_EOS_LAYER_SPECIFIC diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index 911786f94..65cb8790f 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -148,6 +148,12 @@ struct Picture : public UnitArea void finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHeader *picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps ); int getPOC() const { return poc; } +#if JVET_P0978_RPL_RESTRICTIONS + int getDecodingOrderNumber() const { return m_decodingOrderNumber; } + void setDecodingOrderNumber(const int val) { m_decodingOrderNumber = val; } + NalUnitType getPictureType() const { return m_PictureType; } + void setPictureType(const NalUnitType val) { m_PictureType = val; } +#endif void setBorderExtension( bool bFlag) { m_bIsBorderExtended = bFlag;} Pel* getOrigin( const PictureType &type, const ComponentID compID ) const; @@ -170,6 +176,10 @@ struct Picture : public UnitArea private: Window m_conformanceWindow; Window m_scalingWindow; +#if JVET_P0978_RPL_RESTRICTIONS + int m_decodingOrderNumber; + NalUnitType m_PictureType; +#endif public: #if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 1fe39dfaa..cbb479f07 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -594,7 +594,11 @@ void Slice::checkColRefIdx(uint32_t curSliceSegmentIdx, const Picture* pic) } } +#if JVET_P0978_RPL_RESTRICTIONS +void Slice::checkCRA(const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, const int pocCRA, PicList& rcListPic) +#else void Slice::checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic) +#endif { if (pocCRA < MAX_UINT && getPOC() > pocCRA) { @@ -637,6 +641,7 @@ void Slice::checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureLi } } } +#if !JVET_P0978_RPL_RESTRICTIONS if (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP) // IDR picture found { pocCRA = getPOC(); @@ -647,7 +652,135 @@ void Slice::checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureLi pocCRA = getPOC(); associatedIRAPType = getNalUnitType(); } +#endif +} + +#if JVET_P0978_RPL_RESTRICTIONS +void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, const int associatedIRAPDecodingOrderNumber, PicList& rcListPic) +{ + Picture* pcRefPic; + int refPicPOC; + int refPicDecodingOrderNumber; + + int irapPOC = getAssociatedIRAPPOC(); + + int numEntriesL0 = pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(); + int numEntriesL1 = pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures(); + + int numActiveEntriesL0 = getNumRefIdx(REF_PIC_LIST_0); + int numActiveEntriesL1 = getNumRefIdx(REF_PIC_LIST_1); + +#if JVET_Q0042_VUI + bool fieldSeqFlag = getSPS()->getFieldSeqFlag(); +#else + bool fieldSeqFlag = getSPS()->getVuiParameters() && getSPS()->getVuiParameters()->getFieldSeqFlag(); +#endif + + int current_picture_is_trailing = 0; + if (getPic()->getDecodingOrderNumber() > associatedIRAPDecodingOrderNumber) + { + switch (m_eNalUnitType) + { + case NAL_UNIT_CODED_SLICE_STSA: + case NAL_UNIT_CODED_SLICE_IDR_W_RADL: + case NAL_UNIT_CODED_SLICE_IDR_N_LP: + case NAL_UNIT_CODED_SLICE_CRA: + case NAL_UNIT_CODED_SLICE_RADL: + case NAL_UNIT_CODED_SLICE_RASL: + current_picture_is_trailing = 0; + break; + default: + current_picture_is_trailing = 1; + } + } + + for (int i = 0; i < numEntriesL0; i++) + { + if (!pRPL0->isRefPicLongterm(i)) + { + refPicPOC = getPOC() - pRPL0->getRefPicIdentifier(i); + pcRefPic = xGetRefPic(rcListPic, refPicPOC, m_pcPic->layerId); + } + else + { + pcRefPic = xGetLongTermRefPic(rcListPic, pRPL0->getRefPicIdentifier(i), pRPL0->getDeltaPocMSBPresentFlag(i), m_pcPic->layerId); + refPicPOC = pcRefPic->getPOC(); + } + refPicDecodingOrderNumber = pcRefPic->getDecodingOrderNumber(); + + // Checking this: "When the current picture is a CRA picture, there shall be no entry in RefPicList[0] or RefPicList[1] + // that precedes, in output order or decoding order, any preceding IRAP picture in decoding order (when present)" + if (m_eNalUnitType == NAL_UNIT_CODED_SLICE_CRA) + { + CHECK(refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "CRA picture detected that violate the rule that no entry in RefPicList[] shall precede, in output order or decoding order, any preceding IRAP picture in decoding order (when present)."); + } + + // Checking this: "When the current picture is a trailing picture that follows in both decoding orderand output order one + // or more leading pictures associated with the same IRAP picture, if any, there shall be no picture referred to by an + // entry in RefPicList[0] or RefPicList[1] that precedes the associated IRAP picture in output order or decoding order" + // Note that when not in field coding, we know that all leading pictures of an IRAP precedes all trailing pictures of the + // same IRAP picture. + if (current_picture_is_trailing && !fieldSeqFlag) // + { + CHECK(refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "Trailing picture detected that follows one or more leading pictures, if any, and violates the rule that no entry in RefPicList[] shall precede the associated IRAP picture in output order or decoding order."); + } + + if (i < numActiveEntriesL0) + { + // Checking this "When the current picture is a trailing picture, there shall be no picture referred to by an active + // entry in RefPicList[ 0 ] or RefPicList[ 1 ] that precedes the associated IRAP picture in output order or decoding order" + if (current_picture_is_trailing) + { + CHECK(refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "Trailing picture detected that violate the rule that no active entry in RefPicList[] shall precede the associated IRAP picture in output order or decoding order"); + } + + // Checking this: "When the current picture is a RADL picture, there shall be no active entry in RefPicList[ 0 ] or + // RefPicList[ 1 ] that is any of the following: A picture that precedes the associated IRAP picture in decoding order" + if (m_eNalUnitType == NAL_UNIT_CODED_SLICE_RADL) + { + CHECK(refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "RADL picture detected that violate the rule that no active entry in RefPicList[] shall precede the associated IRAP picture in decoding order"); + } + } + } + + for (int i = 0; i < numEntriesL1; i++) + { + if (!pRPL1->isRefPicLongterm(i)) + { + refPicPOC = getPOC() - pRPL1->getRefPicIdentifier(i); + pcRefPic = xGetRefPic(rcListPic, refPicPOC, m_pcPic->layerId); + } + else + { + pcRefPic = xGetLongTermRefPic(rcListPic, pRPL0->getRefPicIdentifier(i), pRPL0->getDeltaPocMSBPresentFlag(i), m_pcPic->layerId); + refPicPOC = pcRefPic->getPOC(); + } + refPicDecodingOrderNumber = pcRefPic->getDecodingOrderNumber(); + + if (m_eNalUnitType == NAL_UNIT_CODED_SLICE_CRA) + { + CHECK(refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "CRA picture detected that violate the rule that no entry in RefPicList[] shall precede, in output order or decoding order, any preceding IRAP picture in decoding order (when present)."); + } + if (current_picture_is_trailing && !fieldSeqFlag) + { + CHECK(refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "Trailing picture detected that follows one or more leading pictures, if any, and violates the rule that no entry in RefPicList[] shall precede the associated IRAP picture in output order or decoding order."); + } + + if (i < numActiveEntriesL1) + { + if (current_picture_is_trailing) + { + CHECK(refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "Trailing picture detected that violate the rule that no active entry in RefPicList[] shall precede the associated IRAP picture in output order or decoding order"); + } + if (m_eNalUnitType == NAL_UNIT_CODED_SLICE_RADL) + { + CHECK(refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "RADL picture detected that violate the rule that no active entry in RefPicList[] shall precede the associated IRAP picture in decoding order"); + } + } + } } +#endif + void Slice::checkSTSA(PicList& rcListPic) { diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 0749dfce9..2e566b941 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -3000,8 +3000,15 @@ public: 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); } +#if JVET_P0978_RPL_RESTRICTIONS + void checkCRA(const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, const int pocCRA, PicList& rcListPic); +#else void checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic); +#endif void checkSTSA(PicList& rcListPic); +#if JVET_P0978_RPL_RESTRICTIONS + void checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, const int associatedIRAPDecodingOrderNumber, PicList& rcListPic); +#endif void decodingRefreshMarking(int& pocCRA, bool& bRefreshPending, PicList& rcListPic, const bool bEfficientFieldIRAPEnabled); void setSliceType( SliceType e ) { m_eSliceType = e; } void setSliceQp( int i ) { m_iSliceQp = i; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 5340766aa..914135e46 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -90,6 +90,8 @@ #define JVET_P0116_POC_MSB 1 // JVET-P0116: use POC MSB cycle signalling for independent layers,to support of mixed IRAP and non-IRAP pictures within an AU +#define JVET_P0978_RPL_RESTRICTIONS 1 // JVET-P0978: A set of RPL-related bitstream conformance restrictions + #define JVET_Q0468_Q0469_MIN_LUMA_CB_AND_MIN_QT_FIX 1 // JVET-Q0468: add support of min Luma coding block size; JVET-Q0469: fix for signaling of Intra Chroma Min QT size #define JVET_Q0260_CONFORMANCE_WINDOW_IN_SPS 1 // JVET-Q0260: Conformance cropping window in the SPS that applies to the max picture size diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index d8ddbcc10..b552b76d0 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -426,6 +426,9 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri DecLib::DecLib() : m_iMaxRefPicNum(0) , m_associatedIRAPType(NAL_UNIT_INVALID) +#if JVET_P0978_RPL_RESTRICTIONS + , m_associatedIRAPDecodingOrderNumber(0) +#endif , m_pocCRA(0) , m_pocRandomAccess(MAX_INT) , m_lastRasPoc(MAX_INT) @@ -478,13 +481,14 @@ DecLib::DecLib() , m_vps( nullptr ) , m_scalingListUpdateFlag(true) , m_PreScalingListAPSId(-1) - #if JVET_Q0044_SLICE_IDX_WITH_SUBPICS , m_maxDecSubPicIdx(0) , m_maxDecSliceAddrInSubPic(-1) #endif #if JVET_Q0117_PARAMETER_SETS_CLEANUP , m_dci(NULL) +#if JVET_P0978_RPL_RESTRICTIONS + , m_decodingOrderCounter(0) #endif { #if ENABLE_SIMD_OPT_BUFFER @@ -2027,8 +2031,22 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl m_pcPic->subLayerNonReferencePictureDueToSTSA = false; +#if JVET_P0978_RPL_RESTRICTIONS + if (m_bFirstSliceInPicture) + { + m_pcPic->setDecodingOrderNumber(m_decodingOrderCounter); + m_decodingOrderCounter++; + m_pcPic->setPictureType(nalu.m_nalUnitType); + } + + pcSlice->checkCRA(pcSlice->getRPL0(), pcSlice->getRPL1(), m_pocCRA, m_cListPic); +#else pcSlice->checkCRA(pcSlice->getRPL0(), pcSlice->getRPL1(), m_pocCRA, m_associatedIRAPType, m_cListPic); +#endif pcSlice->constructRefPicList(m_cListPic); +#if JVET_P0978_RPL_RESTRICTIONS + pcSlice->checkRPL(pcSlice->getRPL0(), pcSlice->getRPL1(), m_associatedIRAPDecodingOrderNumber, m_cListPic); +#endif pcSlice->checkSTSA(m_cListPic); pcSlice->scaleRefPicList( scaledRefPic, m_pcPic->cs->picHeader, m_parameterSetManager.getAPSs(), m_picHeader.getLmcsAPS(), m_picHeader.getScalingListAPS(), true ); @@ -2261,6 +2279,19 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl return false; } +#if JVET_P0978_RPL_RESTRICTIONS +void DecLib::UpdateAssociatedIRAP() +{ + const NalUnitType pictureType = m_pcPic->getPictureType(); + if (pictureType == NAL_UNIT_CODED_SLICE_IDR_W_RADL || pictureType == NAL_UNIT_CODED_SLICE_IDR_N_LP || pictureType == NAL_UNIT_CODED_SLICE_CRA) + { + m_associatedIRAPDecodingOrderNumber = m_pcPic->getDecodingOrderNumber(); + m_pocCRA = m_pcPic->getPOC(); + m_associatedIRAPType = pictureType; + } +} +#endif + void DecLib::xDecodeVPS( InputNALUnit& nalu ) { m_vps = new VPS(); diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index 1edbe9cc3..64a891ad7 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -71,6 +71,10 @@ private: int m_iMaxRefPicNum; NalUnitType m_associatedIRAPType; ///< NAL unit type of the associated IRAP picture +#if JVET_P0978_RPL_RESTRICTIONS + int m_associatedIRAPDecodingOrderNumber; ///< Decoding order number of the associated IRAP picture + int m_decodingOrderCounter; +#endif int m_pocCRA; ///< POC number of the latest CRA picture int m_pocRandomAccess; ///< POC number of the random access point (the first IDR or CRA picture) int m_lastRasPoc; @@ -192,6 +196,9 @@ public: void finishPictureLight(int& poc, PicList*& rpcListPic ); void checkNoOutputPriorPics (PicList* rpcListPic); void checkNalUnitConstraints( uint32_t naluType ); +#if JVET_P0978_RPL_RESTRICTIONS + void UpdateAssociatedIRAP(); +#endif bool getNoOutputPriorPicsFlag () const { return m_isNoOutputPriorPics; } -- GitLab