From ec5d4edbebcef7e01b7528b03844ac63b3f6a4e1 Mon Sep 17 00:00:00 2001 From: Vadim Seregin <vseregin@qti.qualcomm.com> Date: Wed, 8 Jul 2020 20:01:43 -0700 Subject: [PATCH 1/3] Sub-picture constraints --- source/Lib/CommonLib/Picture.cpp | 2 ++ source/Lib/CommonLib/Picture.h | 7 ++++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/CommonLib/UnitTools.cpp | 53 +++++++++++++++++++++++++++++- source/Lib/DecoderLib/DecLib.cpp | 11 +++++++ source/Lib/DecoderLib/DecSlice.cpp | 9 +++++ source/Lib/EncoderLib/EncGOP.cpp | 13 ++++++++ source/Lib/EncoderLib/EncSlice.cpp | 5 +++ 8 files changed, 101 insertions(+), 1 deletion(-) diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index 7ddff73e57..8d05d1087d 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -193,7 +193,9 @@ Picture::Picture() m_spliceIdx = NULL; m_ctuNums = 0; layerId = NOT_VALID; +#if !JVET_S0258_SUBPIC_CONSTRAINTS numSubpics = 1; +#endif numSlices = 1; } diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index ee32fa54c7..7e9e44ffae 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -216,12 +216,17 @@ public: int poc; uint32_t temporalId; int layerId; +#if JVET_S0258_SUBPIC_CONSTRAINTS + std::vector<SubPic> subPictures; + int numSlices; +#else int numSubpics; std::vector<int> subpicWidthInCTUs; std::vector<int> subpicHeightInCTUs; std::vector<int> subpicCtuTopLeftX; std::vector<int> subpicCtuTopLeftY; int numSlices; +#endif std::vector<int> sliceSubpicIdx; bool subLayerNonReferencePictureDueToSTSA; @@ -232,7 +237,9 @@ public: std::vector<bool> m_lossylosslessSliceArray; bool interLayerRefPicFlag; +#if !JVET_S0258_SUBPIC_CONSTRAINTS std::vector<int> subPicIDs; +#endif #if ENABLE_SPLIT_PARALLELISM PelStorage m_bufs[PARL_SPLIT_MAX_NUM_JOBS][NUM_PIC_TYPES]; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 4a8190ad9f..3324e449ae 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -52,6 +52,8 @@ //########### place macros to be removed in next cycle below this line ############### +#define JVET_S0258_SUBPIC_CONSTRAINTS 1 // JVET-S0258: sub-picture constraints + #define JVET_S0074_SPS_REORDER 1 // JVET-S0074: aspect 1, rearrange some syntax elements in SPS #define JVET_S0132_HLS_REORDER 1 // Rearrange syntax elements in SPS and PPS diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 753a70c2c5..57546d9332 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -135,7 +135,28 @@ bool CU::getRprScaling( const SPS* sps, const PPS* curPPS, Picture* refPic, int& void CU::checkConformanceILRP(Slice *slice) { - const int numRefList = (slice->getSliceType() == B_SLICE) ? (2) : (1); + const int numRefList = slice->isInterB() ? 2 : 1; + +#if JVET_S0258_SUBPIC_CONSTRAINTS + int currentSubPicIdx = NOT_VALID; + + // derive sub-picture index for the current slice + for( int subPicIdx = 0; subPicIdx < slice->getPic()->cs->sps->getNumSubPics(); subPicIdx++ ) + { + if( slice->getPic()->cs->pps->getSubPic( subPicIdx ).getSubPicID() == slice->getSliceSubPicId() ) + { + currentSubPicIdx = subPicIdx; + break; + } + } + + CHECK( currentSubPicIdx == NOT_VALID, "Sub-picture was not found" ); + + if( !slice->getPic()->cs->sps->getSubPicTreatedAsPicFlag( currentSubPicIdx ) ) + { + return; + } +#endif //constraint 1: The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] has the same subpicture layout as the current picture bool isAllRefSameSubpicLayout = true; @@ -146,7 +167,11 @@ void CU::checkConformanceILRP(Slice *slice) { const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic; +#if JVET_S0258_SUBPIC_CONSTRAINTS + if( refPic->subPictures.size() != slice->getPic()->cs->pps->getNumSubPics() ) +#else if (refPic->numSubpics != slice->getPic()->cs->pps->getNumSubPics()) +#endif { isAllRefSameSubpicLayout = false; refList = numRefList; @@ -154,12 +179,26 @@ void CU::checkConformanceILRP(Slice *slice) } else { +#if JVET_S0258_SUBPIC_CONSTRAINTS + for( int i = 0; i < refPic->subPictures.size(); i++ ) + { + const SubPic& refSubPic = refPic->subPictures[i]; + const SubPic& curSubPic = slice->getPic()->cs->pps->getSubPic( i ); + + if( refSubPic.getSubPicWidthInCTUs() != curSubPic.getSubPicWidthInCTUs() + || refSubPic.getSubPicHeightInCTUs() != curSubPic.getSubPicHeightInCTUs() + || refSubPic.getSubPicCtuTopLeftX() != curSubPic.getSubPicCtuTopLeftX() + || refSubPic.getSubPicCtuTopLeftY() != curSubPic.getSubPicCtuTopLeftY() + || ( refPic->layerId != slice->getPic()->layerId && refSubPic.getSubPicID() != curSubPic.getSubPicID() ) + || refSubPic.getTreatedAsPicFlag() != curSubPic.getTreatedAsPicFlag()) +#else for (int i = 0; i < refPic->numSubpics; i++) { if (refPic->subpicWidthInCTUs[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicWidthInCTUs() || refPic->subpicHeightInCTUs[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicHeightInCTUs() || refPic->subpicCtuTopLeftX[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftX() || refPic->subpicCtuTopLeftY[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftY()) +#endif { isAllRefSameSubpicLayout = false; refIdx = slice->getNumRefIdx(eRefPicList); @@ -167,6 +206,14 @@ void CU::checkConformanceILRP(Slice *slice) break; } } + +#if JVET_S0258_SUBPIC_CONSTRAINTS + // A picture with different sub-picture ID of the collocated sub-picture cannot be used as an active reference picture in the same layer + if( refPic->layerId == slice->getPic()->layerId ) + { + isAllRefSameSubpicLayout = isAllRefSameSubpicLayout && refPic->subPictures[currentSubPicIdx].getSubPicID() == slice->getSliceSubPicId(); + } +#endif } } } @@ -180,7 +227,11 @@ void CU::checkConformanceILRP(Slice *slice) for (int refIdx = 0; refIdx < slice->getNumRefIdx(eRefPicList); refIdx++) { const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic; +#if JVET_S0258_SUBPIC_CONSTRAINTS + CHECK( refPic->layerId == slice->getPic()->layerId || refPic->subPictures.size() > 1, "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture" ); +#else CHECK(!(refPic->layerId != slice->getPic()->layerId && refPic->numSubpics == 1), "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture"); +#endif } } } diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 13db0951a4..3d93fb2118 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -2163,6 +2163,14 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl m_decodingOrderCounter++; m_pcPic->setPictureType(nalu.m_nalUnitType); // store sub-picture numbers, sizes, and locations with a picture +#if JVET_S0258_SUBPIC_CONSTRAINTS + pcSlice->getPic()->subPictures.clear(); + + for( int subPicIdx = 0; subPicIdx < sps->getNumSubPics(); subPicIdx++ ) + { + pcSlice->getPic()->subPictures.push_back( pps->getSubPic( subPicIdx ) ); + } +#else pcSlice->getPic()->numSubpics = sps->getNumSubPics(); pcSlice->getPic()->subpicWidthInCTUs.clear(); pcSlice->getPic()->subpicHeightInCTUs.clear(); @@ -2175,6 +2183,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl pcSlice->getPic()->subpicCtuTopLeftX.push_back(pps->getSubPic(subPicIdx).getSubPicCtuTopLeftX()); pcSlice->getPic()->subpicCtuTopLeftY.push_back(pps->getSubPic(subPicIdx).getSubPicCtuTopLeftY()); } +#endif pcSlice->getPic()->numSlices = pps->getNumSlicesInPic(); pcSlice->getPic()->sliceSubpicIdx.clear(); } @@ -2195,6 +2204,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl pcSlice->scaleRefPicList( scaledRefPic, m_pcPic->cs->picHeader, m_parameterSetManager.getAPSs(), m_picHeader.getLmcsAPS(), m_picHeader.getScalingListAPS(), true ); +#if !JVET_S0258_SUBPIC_CONSTRAINTS // For each value of i in the range of 0 to sps_num_subpics_minus1, inclusive, when the value of SubpicIdVal[ i ] of a current picture is not equal to the value of SubpicIdVal[ i ] of a reference picture, // the active entries of the RPLs of the coded slices in the i-th subpicture of the current picture shall not include that reference picture. @@ -2241,6 +2251,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl } } } +#endif if (!pcSlice->isIntra()) { diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index f70fb73f55..ed1b390a9a 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -127,7 +127,11 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb DTRACE( g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC() ); +#if JVET_S0258_SUBPIC_CONSTRAINTS + if( slice->getSliceType() != I_SLICE && slice->getRefPic( REF_PIC_LIST_0, 0 )->subPictures.size() > 1 ) +#else if (slice->getSliceType() != I_SLICE && slice->getRefPic(REF_PIC_LIST_0, 0)->numSubpics > 1) +#endif { clipMv = clipMvInSubpic; } @@ -166,7 +170,12 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb for (int idx = 0; idx < n; idx++) { Picture *refPic = slice->getRefPic((RefPicList)rlist, idx); + +#if JVET_S0258_SUBPIC_CONSTRAINTS + if( !refPic->getSubPicSaved() && refPic->subPictures.size() > 1 ) +#else if (!refPic->getSubPicSaved() && refPic->numSubpics > 1) +#endif { refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 2ca92dcdce..6d5bb2e456 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2265,6 +2265,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcSlice->constructRefPicList(rcListPic); // store sub-picture numbers, sizes, and locations with a picture +#if JVET_S0258_SUBPIC_CONSTRAINTS + pcSlice->getPic()->subPictures.clear(); + + for( int subPicIdx = 0; subPicIdx < pcPic->cs->pps->getNumSubPics(); subPicIdx++ ) + { + pcSlice->getPic()->subPictures.push_back( pcPic->cs->pps->getSubPic( subPicIdx ) ); + } +#else pcSlice->getPic()->numSubpics = pcPic->cs->pps->getNumSubPics(); pcSlice->getPic()->subpicWidthInCTUs.clear(); pcSlice->getPic()->subpicHeightInCTUs.clear(); @@ -2277,6 +2285,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcSlice->getPic()->subpicCtuTopLeftX.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftX()); pcSlice->getPic()->subpicCtuTopLeftY.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftY()); } +#endif const VPS* vps = pcPic->cs->vps; int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx(pcPic->layerId); @@ -2756,7 +2765,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } m_pcSliceEncoder->setLosslessSlice(pcPic, isLossless); +#if JVET_S0258_SUBPIC_CONSTRAINTS + if( pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic( REF_PIC_LIST_0, 0 )->subPictures.size() > 1 ) +#else if (pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic(REF_PIC_LIST_0, 0)->numSubpics > 1) +#endif { clipMv = clipMvInSubpic; m_pcEncLib->getInterSearch()->setClipMvInSubPic(true); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 3ae1632bfe..b59fe3ad2e 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1550,7 +1550,12 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons for (int idx = 0; idx < n; idx++) { Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx); + +#if JVET_S0258_SUBPIC_CONSTRAINTS + if( !refPic->getSubPicSaved() && refPic->subPictures.size() > 1 ) +#else if (!refPic->getSubPicSaved() && refPic->numSubpics > 1) +#endif { refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); -- GitLab From b24639f0e2000ea856856795849f8420470bd9e2 Mon Sep 17 00:00:00 2001 From: Vadim Seregin <vseregin@qti.qualcomm.com> Date: Thu, 9 Jul 2020 18:37:15 -0700 Subject: [PATCH 2/3] use non scaled ref pic --- source/Lib/CommonLib/UnitTools.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 44004ea271..0b46b91630 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -163,13 +163,16 @@ void CU::checkConformanceILRP(Slice *slice) for (int refList = 0; refList < numRefList; refList++) // loop over l0 and l1 { RefPicList eRefPicList = (refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0); + for (int refIdx = 0; refIdx < slice->getNumRefIdx(eRefPicList); refIdx++) { - const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic; - #if JVET_S0258_SUBPIC_CONSTRAINTS + const Picture* refPic = slice->getRefPic( eRefPicList, refIdx ); + if( refPic->subPictures.size() != slice->getPic()->cs->pps->getNumSubPics() ) #else + const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic; + if (refPic->numSubpics != slice->getPic()->cs->pps->getNumSubPics()) #endif { @@ -226,10 +229,11 @@ void CU::checkConformanceILRP(Slice *slice) RefPicList eRefPicList = (refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0); for (int refIdx = 0; refIdx < slice->getNumRefIdx(eRefPicList); refIdx++) { - const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic; #if JVET_S0258_SUBPIC_CONSTRAINTS + const Picture* refPic = slice->getRefPic( eRefPicList, refIdx ); CHECK( refPic->layerId == slice->getPic()->layerId || refPic->subPictures.size() > 1, "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture" ); #else + const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic; CHECK(!(refPic->layerId != slice->getPic()->layerId && refPic->numSubpics == 1), "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture"); #endif } -- GitLab From 282e50775f77e6246f060c32083fdb544fce9010 Mon Sep 17 00:00:00 2001 From: Vadim Seregin <vseregin@qti.qualcomm.com> Date: Sun, 19 Jul 2020 18:47:17 -0700 Subject: [PATCH 3/3] revert function return type --- source/Lib/CommonLib/UnitTools.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 68805c4895..b73d2d5d77 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -121,7 +121,7 @@ namespace CU uint8_t numSbtModeRdo (uint8_t sbtAllowed); bool isSbtMode (const uint8_t sbtInfo); bool isSameSbtSize (const uint8_t sbtInfo1, const uint8_t sbtInfo2); - void getRprScaling ( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale, int& yScale ); + bool getRprScaling ( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale, int& yScale ); void checkConformanceILRP (Slice *slice); } // PU tools -- GitLab