Commit b46623fd authored by Frank Bossen's avatar Frank Bossen

Merge branch 'JVET_S0258_SUBPIC_CONSTRAINTS' into 'master'

JVET-S0258: Sub-picture constraints

See merge request jvet/VVCSoftware_VTM!1724
parents eaf1eb77 ec6f0bea
......@@ -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;
}
......
......@@ -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];
......
......@@ -61,6 +61,8 @@
#define JVET_S0049_ASPECT4 1 // JVET-S0049 aspect 4: Constrain the value of pps_alf_info_in_ph_flag to be equal to 0 when the PH is in the SH
#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_S0234_ACT_CRS_FIX 1 // JVET-S0234: perform chroma residual scaling in RGB domain when ACT is on
......
......@@ -155,18 +155,46 @@ 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;
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++)
{
#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
{
isAllRefSameSubpicLayout = false;
refList = numRefList;
......@@ -174,12 +202,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);
......@@ -187,6 +229,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
}
}
}
......@@ -199,8 +249,13 @@ 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++)
{
#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
}
}
}
......
......@@ -2223,6 +2223,14 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
checkPicTypeAfterEos();
#endif
// 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();
......@@ -2235,6 +2243,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();
}
......@@ -2255,6 +2264,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.
......@@ -2301,6 +2311,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
}
}
}
#endif
if (!pcSlice->isIntra())
{
......
......@@ -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);
......
......@@ -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);
......@@ -2801,7 +2810,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);
......
......@@ -1553,7 +1553,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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment