...
 
Commits (19)
# example cfg file, assuming an 832x480 input sequence with CTU size = 128x128, split to 4 rectangular slices, each slice include one tile,and set sps_subpic_same_size_flag equal to 1
# example 2 subpictures in a 832x480 picture:
#----------
#| | |
#| | |
#|----|---|--> horizontally divided into 2 subpicture, each subpicture contains two slices
#| | |
#| | |
#----------
#
SubPicInfoPresentFlag : 1 # subpicture information present flag(0: OFF, 1: ON)
NumSubPics : 2 # number of subpictures in a picture
SubPicSameSizeFlag : 1 # subpicture same size flag (1: all subpictures are same size)
SubPicWidth : 7 # specifies the width of the i-th subpicture in units of CtbSizeY
SubPicHeight : 2 # specifies the height of the i-th subpicture in units of CtbSizeY
SubPicTreatedAsPicFlag : 1 1 # equal to 1 specifies that the i-th subpicture of each coded picture in the CLVS is treated as a picture in the decoding process excluding in-loop filtering operations
LoopFilterAcrossSubpicEnabledFlag : 0 0 # equal to 1 specifies that in-loop filtering operations may be performed across the boundaries of the i-th subpicture in each coded picture in the CLVS
SubPicIdMappingExplicitlySignalledFlag : 0 # equal to 1 specifies that the subpicture ID mapping is explicitly signalled, either in the SPS or in the PPSs
SubPicIdMappingInSpsFlag : 0 # specifies that subpicture ID mapping is signalled in the SPS(0: OFF, 1: ON)
SubPicIdLen : 0 # the number of bits used to represent the syntax element sps_subpic_id[ i ]
SubPicId : 0 # subpicture ID of the i-th subpicture
#============ Tiles / Slices ================
EnablePicPartitioning : 1 # Enable picture partitioning (0: single tile, single slice, 1: multiple tiles/slices can be used)
# 24 tiles and 6 rectangular slices
TileColumnWidthArray : 4 # Tile column widths in units of CTUs. Last column width will be repeated uniformly to cover any remaining picture width
TileRowHeightArray : 2 # Tile row heights in units of CTUs. Last row height will be repeated uniformly to cover any remaining picture height
RasterScanSlices : 0 # Raster-scan or rectangular slices (0: rectangular, 1: raster-scan)
RectSliceFixedWidth : 1 # Fixed rectangular slice width in units of tiles (0: disable this feature and use RectSlicePositions instead)
RectSliceFixedHeight : 1 # Fixed rectangular slice height in units of tiles (0: disable this feature and use RectSlicePositions instead)
DisableLoopFilterAcrossTiles : 1 # Loop filtering (DBLK/SAO/ALF) applied across tile boundaries or not (0: filter across tile boundaries 1: do not filter across tile boundaries)
DisableLoopFilterAcrossSlices : 1 # Loop filtering (DBLK/SAO/ALF) applied across slice boundaries or not (0: filter across slice boundaries 1: do not filter across slice boundaries)
......@@ -2106,6 +2106,12 @@ Enables conding of subpictures.
Number of subpictures. Must be greater that zero, if SubPicInfoPresentFlag is enabled.
\\
\Option{SubPicSameSizeFlag} &
%\ShortOption{\None} &
\Default{0} &
Setting of sps_subpic_same_size_flag for subpicture layout. If enabled that all subpictures in the CLVS have the same width specified by sps_subpic_width_minus1[ 0 ] and the same height specified by sps_subpic_height_minus1[ 0 ].
\\
\Option{SubPicCtuTopLeftX} &
%\ShortOption{\None} &
\Default{\None} &
......
......@@ -432,6 +432,9 @@ void EncApp::xInitLibCfg()
if(m_subPicInfoPresentFlag)
{
m_cEncLib.setNumSubPics ( m_numSubPics );
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
m_cEncLib.setSubPicSameSizeFlag ( m_subPicSameSizeFlag );
#endif
m_cEncLib.setSubPicCtuTopLeftX ( m_subPicCtuTopLeftX );
m_cEncLib.setSubPicCtuTopLeftY ( m_subPicCtuTopLeftY );
m_cEncLib.setSubPicWidth ( m_subPicWidth );
......
......@@ -845,6 +845,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("Log2MinCuSize", m_log2MinCuSize, 2u, "Log2 min CU size")
("SubPicInfoPresentFlag", m_subPicInfoPresentFlag, false, "equal to 1 specifies that subpicture parameters are present in in the SPS RBSP syntax")
("NumSubPics", m_numSubPics, 0u, "specifies the number of subpictures")
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
("SubPicSameSizeFlag", m_subPicSameSizeFlag, false, "equal to 1 specifies that all subpictures in the CLVS have the same width specified by sps_subpic_width_minus1[ 0 ] and the same height specified by sps_subpic_height_minus1[ 0 ].")
#endif
("SubPicCtuTopLeftX", cfg_subPicCtuTopLeftX, cfg_subPicCtuTopLeftX, "specifies horizontal position of top left CTU of i-th subpicture in unit of CtbSizeY")
("SubPicCtuTopLeftY", cfg_subPicCtuTopLeftY, cfg_subPicCtuTopLeftY, "specifies vertical position of top left CTU of i-th subpicture in unit of CtbSizeY")
("SubPicWidth", cfg_subPicWidth, cfg_subPicWidth, "specifies the width of the i-th subpicture in units of CtbSizeY")
......@@ -1583,11 +1586,28 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
}
if ( m_subPicInfoPresentFlag )
{
CHECK( m_numSubPics > MAX_NUM_SUB_PICS || m_numSubPics < 1, "Number of subpicture must be within 1 to 2^16" );
CHECK( m_numSubPics > MAX_NUM_SUB_PICS || m_numSubPics < 1, "Number of subpicture must be within 1 to 2^16" )
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
if (!m_subPicSameSizeFlag)
{
CHECK(cfg_subPicCtuTopLeftX.values.size() != m_numSubPics, "Number of SubPicCtuTopLeftX values must be equal to NumSubPics");
CHECK(cfg_subPicCtuTopLeftY.values.size() != m_numSubPics, "Number of SubPicCtuTopLeftY values must be equal to NumSubPics");
CHECK(cfg_subPicWidth.values.size() != m_numSubPics, "Number of SubPicWidth values must be equal to NumSubPics");
CHECK(cfg_subPicHeight.values.size() != m_numSubPics, "Number of SubPicHeight values must be equal to NumSubPics");
}
else
{
CHECK(cfg_subPicCtuTopLeftX.values.size() != 0, "Number of SubPicCtuTopLeftX values must be equal to 0");
CHECK(cfg_subPicCtuTopLeftY.values.size() != 0, "Number of SubPicCtuTopLeftY values must be equal to 0");
CHECK(cfg_subPicWidth.values.size() != 1, "Number of SubPicWidth values must be equal to 1");
CHECK(cfg_subPicHeight.values.size() != 1, "Number of SubPicHeight values must be equal to 1");
}
#else
CHECK( cfg_subPicCtuTopLeftX.values.size() != m_numSubPics, "Number of SubPicCtuTopLeftX values must be equal to NumSubPics");
CHECK( cfg_subPicCtuTopLeftY.values.size() != m_numSubPics, "Number of SubPicCtuTopLeftY values must be equal to NumSubPics");
CHECK( cfg_subPicWidth.values.size() != m_numSubPics, "Number of SubPicWidth values must be equal to NumSubPics");
CHECK( cfg_subPicHeight.values.size() != m_numSubPics, "Number of SubPicHeight values must be equal to NumSubPics");
#endif
CHECK( cfg_subPicTreatedAsPicFlag.values.size() != m_numSubPics, "Number of SubPicTreatedAsPicFlag values must be equal to NumSubPics");
CHECK( cfg_loopFilterAcrossSubpicEnabledFlag.values.size() != m_numSubPics, "Number of LoopFilterAcrossSubpicEnabledFlag values must be equal to NumSubPics");
if (m_subPicIdMappingExplicitlySignalledFlag)
......@@ -1607,11 +1627,31 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
m_subPicId[i] = cfg_subPicId.values[i];
}
}
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
uint32_t tmpWidthVal = (m_iSourceWidth + m_uiCTUSize - 1) / m_uiCTUSize;
uint32_t tmpHeightVal = (m_iSourceHeight + m_uiCTUSize - 1) / m_uiCTUSize;
if (!m_subPicSameSizeFlag)
{
for (int i = 0; i < m_numSubPics; i++)
{
CHECK(m_subPicCtuTopLeftX[i] + m_subPicWidth[i] > tmpWidthVal, "Subpicture must not exceed picture boundary");
CHECK(m_subPicCtuTopLeftY[i] + m_subPicHeight[i] > tmpHeightVal, "Subpicture must not exceed picture boundary");
}
}
else
{
uint32_t numSubpicCols = tmpWidthVal / m_subPicWidth[0];
CHECK(tmpWidthVal % m_subPicWidth[0] != 0, "subpic_width_minus1[0] is invalid.");
CHECK(tmpHeightVal % m_subPicHeight[0] != 0, "subpic_height_minus1[0] is invalid.");
CHECK(numSubpicCols * (tmpHeightVal / m_subPicHeight[0]) != m_numSubPics, "when sps_subpic_same_size_flag is equal to, sps_num_subpics_minus1 is invalid");
}
#else
for(int i = 0; i < m_numSubPics; i++)
{
CHECK(m_subPicCtuTopLeftX[i] + m_subPicWidth[i] > (m_iSourceWidth + m_uiCTUSize - 1) / m_uiCTUSize, "Subpicture must not exceed picture boundary");
CHECK(m_subPicCtuTopLeftY[i] + m_subPicHeight[i] > (m_iSourceHeight + m_uiCTUSize - 1) / m_uiCTUSize, "Subpicture must not exceed picture boundary");
}
#endif
// automatically determine subpicture ID lenght in case it is not specified
if (m_subPicIdLen == 0)
{
......@@ -3649,14 +3689,31 @@ void EncAppCfg::xPrintParameter()
if (m_subPicInfoPresentFlag)
{
msg(DETAILS, "number of subpictures : %d\n", m_numSubPics);
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
msg(DETAILS, "subpicture size same flag : %d\n", m_subPicSameSizeFlag);
if (m_subPicSameSizeFlag)
{
msg(DETAILS, "[0]th subpictures size :[%d %d]\n", m_subPicWidth[0], m_subPicHeight[0]);
}
for (int i = 0; i < m_numSubPics; i++)
{
if (!m_subPicSameSizeFlag)
{
msg(DETAILS, "[%d]th subpictures location :[%d %d]\n", i, m_subPicCtuTopLeftX[i], m_subPicCtuTopLeftY[i]);
msg(DETAILS, "[%d]th subpictures size :[%d %d]\n", i, m_subPicWidth[i], m_subPicHeight[i]);
}
msg(DETAILS, "[%d]th subpictures treated as picture flag :%d\n", i, m_subPicTreatedAsPicFlag[i]);
msg(DETAILS, "loop filter cross [%d]th subpictures enabled flag :%d\n", i, m_loopFilterAcrossSubpicEnabledFlag[i]);
}
#else
for (int i = 0; i < m_numSubPics; i++)
{
msg(DETAILS, "[%d]th subpictures location :[%d %d]\n", i, m_subPicCtuTopLeftX[i], m_subPicCtuTopLeftY[i]);
msg(DETAILS, "[%d]th subpictures size :[%d %d]\n", i, m_subPicWidth[i], m_subPicHeight[i]);
msg(DETAILS, "[%d]th subpictures treated as picture flag :%d\n", i, m_subPicTreatedAsPicFlag[i]);
msg(DETAILS, "loop filter cross [%d]th subpictures enabled flag :%d\n", i, m_loopFilterAcrossSubpicEnabledFlag[i]);
}
#endif
}
msg(DETAILS, "subpicture ID present flag : %d\n", m_subPicIdMappingExplicitlySignalledFlag);
......
......@@ -285,6 +285,9 @@ protected:
unsigned m_uiCTUSize;
bool m_subPicInfoPresentFlag;
unsigned m_numSubPics;
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
bool m_subPicSameSizeFlag;
#endif
std::vector<uint32_t> m_subPicCtuTopLeftX;
std::vector<uint32_t> m_subPicCtuTopLeftY;
std::vector<uint32_t> m_subPicWidth;
......
......@@ -140,7 +140,7 @@ public:
void checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals )
{
int apsId = aps->getAPSId() + MAX_NUM_APS * aps->getAPSType();
int apsId = ( aps->getAPSId() << NUM_APS_TYPE_LEN ) + aps->getAPSType();
if( std::find( accessUnitApsNals.begin(), accessUnitApsNals.end(), apsId ) != accessUnitApsNals.end() )
{
......
......@@ -186,6 +186,10 @@ Picture::Picture()
fieldPic = false;
topField = false;
precedingDRAP = false;
#if JVET_S0124_UNAVAILABLE_REFERENCE
nonReferencePictureFlag = false;
#endif
for( int i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
{
m_prevQP[i] = -1;
......@@ -197,6 +201,7 @@ Picture::Picture()
numSubpics = 1;
#endif
numSlices = 1;
unscaledPic = nullptr;
}
void Picture::create( const ChromaFormat &_chromaFormat, const Size &size, const unsigned _maxCUSize, const unsigned _margin, const bool _decoder, const int _layerId )
......@@ -214,7 +219,6 @@ void Picture::create( const ChromaFormat &_chromaFormat, const Size &size, const
M_BUFS( 0, PIC_TRUE_ORIGINAL ). create( _chromaFormat, a );
}
#if !KEEP_PRED_AND_RESI_SIGNALS
m_ctuArea = UnitArea( _chromaFormat, Area( Position{ 0, 0 }, Size( _maxCUSize, _maxCUSize ) ) );
#endif
m_hashMap.clearAll();
......
......@@ -212,6 +212,9 @@ public:
bool fieldPic;
int m_prevQP[MAX_NUM_CHANNEL_TYPE];
bool precedingDRAP; // preceding a DRAP picture in decoding order
#if JVET_S0124_UNAVAILABLE_REFERENCE
bool nonReferencePictureFlag;
#endif
int poc;
uint32_t temporalId;
......
......@@ -637,6 +637,88 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
int irapPOC = getAssociatedIRAPPOC();
#if JVET_S0124_UNAVAILABLE_REFERENCE
const int numEntries[] = { pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(), pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures() };
const int numActiveEntries[] = { getNumRefIdx( REF_PIC_LIST_0 ), getNumRefIdx( REF_PIC_LIST_1 ) };
const ReferencePictureList* rpl[] = { pRPL0, pRPL1 };
const bool fieldSeqFlag = getSPS()->getFieldSeqFlag();
const int layerIdx = m_pcPic->cs->vps == nullptr ? 0 : m_pcPic->cs->vps->getGeneralLayerIdx( m_pcPic->layerId );
for( int refPicList = 0; refPicList < 2; refPicList++ )
{
for( int i = 0; i < numEntries[refPicList]; i++ )
{
if( rpl[refPicList]->isInterLayerRefPic( i ) )
{
int refLayerId = m_pcPic->cs->vps->getLayerId( m_pcPic->cs->vps->getDirectRefLayerIdx( layerIdx, rpl[refPicList]->getInterLayerRefPicIdx( i ) ) );
pcRefPic = xGetRefPic( rcListPic, getPOC(), refLayerId );
refPicPOC = pcRefPic->getPOC();
}
else if( !rpl[refPicList]->isRefPicLongterm( i ) )
{
refPicPOC = getPOC() - rpl[refPicList]->getRefPicIdentifier( i );
pcRefPic = xGetRefPic( rcListPic, refPicPOC, m_pcPic->layerId );
}
else
{
int pocBits = getSPS()->getBitsForPOC();
int pocMask = ( 1 << pocBits ) - 1;
int ltrpPoc = rpl[refPicList]->getRefPicIdentifier( i ) & pocMask;
if( rpl[refPicList]->getDeltaPocMSBPresentFlag( i ) )
{
ltrpPoc += getPOC() - rpl[refPicList]->getDeltaPocMSBCycleLT( i ) * ( pocMask + 1 ) - ( getPOC() & pocMask );
}
pcRefPic = xGetLongTermRefPic( rcListPic, ltrpPoc, rpl[refPicList]->getDeltaPocMSBPresentFlag( i ), m_pcPic->layerId );
refPicPOC = pcRefPic->getPOC();
}
refPicDecodingOrderNumber = pcRefPic->getDecodingOrderNumber();
if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_CRA || m_eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP )
{
CHECK( refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "When the current picture, with nuh_layer_id equal to a particular value layerId, "
"is an IRAP picture, there shall be no picture referred to by an entry in RefPicList[ 0 ] that precedes, in output order or decoding order, any preceding IRAP picture "
"with nuh_layer_id equal to layerId in decoding order (when present)." );
}
if( irapPOC < getPOC() && !fieldSeqFlag )
{
CHECK( refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "When the current picture follows an IRAP picture having the same value "
"of nuh_layer_id and the leading pictures, if any, associated with that IRAP picture, in both decoding order and output order, there shall be no picture referred "
"to by an entry in RefPicList[ 0 ] or RefPicList[ 1 ] that precedes that IRAP picture in output order or decoding order." );
}
#if JVET_S0124_UNAVAILABLE_REFERENCE
// Generated reference picture does not have picture header
const bool isGeneratedRefPic = pcRefPic->slices[0]->getPicHeader() ? false : true;
const bool nonReferencePictureFlag = isGeneratedRefPic ? pcRefPic->slices[0]->getPicHeader()->getNonReferencePictureFlag() : pcRefPic->nonReferencePictureFlag;
CHECK( pcRefPic == m_pcPic || nonReferencePictureFlag, "The picture referred to by each entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall not be the current picture and shall have ph_non_ref_pic_flag equal to 0" );
#endif
if( i < numActiveEntries[refPicList] )
{
if( irapPOC < getPOC() )
{
CHECK( refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "When the current picture follows an IRAP picture having the same value "
"of nuh_layer_id in both decoding order and output order, there shall be no picture referred to by an active entry in RefPicList[ 0 ] or RefPicList[ 1 ] that "
"precedes that 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" );
}
#if JVET_S0124_UNAVAILABLE_REFERENCE
CHECK( pcRefPic->temporalId > m_pcPic->temporalId, "The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall be present in the DPB and shall have TemporalId less than or equal to that of the current picture." );
#endif
}
}
}
#else
// remove spagetti code, RPL0 and RPL1 checks are the same
int numEntriesL0 = pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures();
int numEntriesL1 = pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures();
......@@ -695,6 +777,12 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
"to by an entry in RefPicList[ 0 ] or RefPicList[ 1 ] that precedes that IRAP picture in output order or decoding order.");
}
#if JVET_S0124_UNAVAILABLE_REFERENCE
// Generated reference picture does not have picture header
bool nonReferencePictureFlag = pcRefPic->slices[0]->getPicHeader() ? pcRefPic->slices[0]->getPicHeader()->getNonReferencePictureFlag() : pcRefPic->nonReferencePictureFlag;
CHECK( pcRefPic == m_pcPic || nonReferencePictureFlag, "The picture referred to by each entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall not be the current picture and shall have ph_non_ref_pic_flag equal to 0" );
#endif
if (i < numActiveEntriesL0)
{
if (irapPOC < getPOC())
......@@ -710,6 +798,10 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
{
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");
}
#if JVET_S0124_UNAVAILABLE_REFERENCE
CHECK( pcRefPic->temporalId > m_pcPic->temporalId, "The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall be present in the DPB and shall have TemporalId less than or equal to that of the current picture." );
#endif
}
}
......@@ -754,6 +846,12 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
"by an entry in RefPicList[ 0 ] or RefPicList[ 1 ] that precedes that IRAP picture in output order or decoding order.");
}
#if JVET_S0124_UNAVAILABLE_REFERENCE
// Generated reference picture does not have picture header
bool nonReferencePictureFlag = pcRefPic->slices[0]->getPicHeader() ? pcRefPic->slices[0]->getPicHeader()->getNonReferencePictureFlag() : pcRefPic->nonReferencePictureFlag;
CHECK( pcRefPic == m_pcPic || nonReferencePictureFlag, "The picture referred to by each entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall not be the current picture and shall have ph_non_ref_pic_flag equal to 0" );
#endif
if (i < numActiveEntriesL1)
{
if (irapPOC < getPOC())
......@@ -766,8 +864,13 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
{
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");
}
#if JVET_S0124_UNAVAILABLE_REFERENCE
CHECK( pcRefPic->temporalId > m_pcPic->temporalId, "The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall be present in the DPB and shall have TemporalId less than or equal to that of the current picture." );
#endif
}
}
#endif
}
void Slice::checkSTSA(PicList& rcListPic)
......@@ -2712,6 +2815,9 @@ SPS::SPS()
, m_subPicInfoPresentFlag (false)
, m_numSubPics(1)
, m_independentSubPicsFlag (false)
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
, m_subPicSameSizeFlag (false)
#endif
, m_subPicIdMappingExplicitlySignalledFlag ( false )
, m_subPicIdMappingInSpsFlag ( false )
, m_subPicIdLen(16)
......@@ -4190,6 +4296,8 @@ void Slice::scaleRefPicList( Picture *scaledRefPic[ ], PicHeader *picHeader, APS
CU::getRprScaling( sps, pps, m_apcRefPicList[refList][rIdx], xScale, yScale );
m_scalingRatio[refList][rIdx] = std::pair<int, int>( xScale, yScale );
CHECK( m_apcRefPicList[refList][rIdx]->unscaledPic == nullptr, "unscaledPic is not properly set" );
if( m_apcRefPicList[refList][rIdx]->isRefScaled( pps ) == false )
{
refPicIsSameRes = true;
......
......@@ -1383,6 +1383,9 @@ private:
bool m_subPicInfoPresentFlag; // indicates the presence of sub-picture info
uint32_t m_numSubPics; //!< number of sub-pictures used
bool m_independentSubPicsFlag;
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
bool m_subPicSameSizeFlag;
#endif
std::vector<uint32_t> m_subPicCtuTopLeftX;
std::vector<uint32_t> m_subPicCtuTopLeftY;
std::vector<uint32_t> m_subPicWidth;
......@@ -1581,6 +1584,10 @@ public:
}
void setIndependentSubPicsFlag(bool b) { m_independentSubPicsFlag = b; }
bool getIndependentSubPicsFlag() const { return m_independentSubPicsFlag; }
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
void setSubPicSameSizeFlag(bool b) { m_subPicSameSizeFlag = b; }
bool getSubPicSameSizeFlag() const { return m_subPicSameSizeFlag; }
#endif
uint32_t getNumSubPics( ) const { return m_numSubPics; }
void setSubPicCtuTopLeftX( int i, uint32_t u ) { m_subPicCtuTopLeftX[i] = u; }
uint32_t getSubPicCtuTopLeftX( int i ) const { return m_subPicCtuTopLeftX[i]; }
......
......@@ -80,6 +80,10 @@
#define JVET_S0052_RM_SEPARATE_COLOUR_PLANE 1 // JVET-S0052: Remove separate colour plane coding from VVC version 1
#define JVET_S0123_IDR_UNAVAILABLE_REFERENCE 1 // JVET-S0123: Invoke the generation of unavailable reference picture for an IDR picture that has RPLs.
// Change the process for deriving empty RPLs when sps_idr_rpl_present_flag is equal to 0 and nal_unit_type is equal to IDR_W_RADL or IDR_N_LP to involve pps_rpl_info_in_ph_flag.
#define JVET_S0124_UNAVAILABLE_REFERENCE 1 // JVET-S0124: Add TemporalId, ph_non_ref_pic_flag, and ph_pic_parameter_set_id for generating unavailable reference pictures
#define JVET_S0063_VPS_SIGNALLING 1 // Modifications to VPS signalling - conditionally signal vps_num_ptls_minus1
#define JVET_S0065_SPS_INFERENCE_RULE 1 // JVET_S0065_PROPOSAL1: Inference rule for sps_virtual_boundaries_present_flag
......@@ -91,6 +95,8 @@
#define JVET_S0160_ASPECT1_ASPECT9 1 // JVET-S0160: Aspect 1 Infer the value of pps_loop_filter_across_tiles_enabled_flag to be equal to 0 (instead of 1) when not present
// Aspect 9 The value of ph_poc_msb_cycle_present_flag is required to be equal to 0 when vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id]] is equal to 0 and there is an ILRP entry in RefPicList[0] or RefPicList[1] of a slice of the current picture
#define JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT 1 // JVET-S0071 : shortcut when all subpictures have the same size
#define JVET_S0048_SCALING_OFFSET 1 // JVET-S0048 Aspect2: change the constraint on the value ranges of scaling window offsets to be more flexible
#define JVET_S0248_HRD_CLEANUP 1 // JVET-S0248 Aspect7: When bp_alt_cpb_params_present_flag is equal to 1, the value of bp_du_hrd_params_present_flag shall be equal to 0.
......@@ -123,6 +129,10 @@
#define JVET_S0185_PROPOSAl1_PICTURE_TIMING_CLEANUP 1 // JVET-S0185: Proposal 1, put syntax element pt_cpb_removal_delay_minus1[] first, followed by similar information for sub-layers, followed by pt_dpb_output_delay
#define JVET_S0183_VPS_INFORMATION_SIGNALLING 1 // JVET-S0183: Proposal 1, signal vps_num_output_layer_sets_minus1 as vps_num_output_layer_sets_minus2
#define JVET_S0184_VIRTUAL_BOUNDARY_CONSTRAINT 1 // JVET-S0184: Conformance constraints regarding virtual boundary signalling when subpictures are present
//########### place macros to be be kept below this line ###############
#define JVET_S0257_DUMP_360SEI_MESSAGE 1 // Software support of 360 SEI messages
......
......@@ -869,7 +869,11 @@ void DecLib::xCreateLostPicture( int iLostPoc, const int layerId )
}
#if JVET_S0124_UNAVAILABLE_REFERENCE
void DecLib::xCreateUnavailablePicture( const PPS *pps, const int iUnavailablePoc, const bool longTermFlag, const int temporalId, const int layerId, const bool interLayerRefPicFlag )
#else
void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const int layerId, const bool interLayerRefPicFlag)
#endif
{
msg(INFO, "\ninserting unavailable poc : %d\n", iUnavailablePoc);
Picture* cFillPic = xGetNewPicBuffer( *( m_parameterSetManager.getFirstSPS() ), *( m_parameterSetManager.getFirstPPS() ), 0, layerId );
......@@ -892,6 +896,14 @@ void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, c
xUpdatePreviousTid0POC(cFillPic->slices[0]);
cFillPic->reconstructed = true;
cFillPic->neededForOutput = false;
#if JVET_S0124_UNAVAILABLE_REFERENCE
// picture header is not derived for generated reference picture
cFillPic->slices[0]->setPicHeader( nullptr );
cFillPic->temporalId = temporalId;
cFillPic->nonReferencePictureFlag = false;
cFillPic->slices[0]->setPPS( pps );
#endif
if (m_pocRandomAccess == MAX_INT)
{
m_pocRandomAccess = iUnavailablePoc;
......@@ -2186,11 +2198,19 @@ 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( !pps->getMixedNaluTypesInPicFlag() && ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() )
if( !pps->getMixedNaluTypesInPicFlag() && (
#if JVET_S0123_IDR_UNAVAILABLE_REFERENCE
( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP ) && ( sps->getIDRRefParamListPresent() || pps->getRplInfoInPhFlag() ) ) ||
#endif
( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() ) ) )
{
if (m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex) == 0)
{
#if JVET_S0124_UNAVAILABLE_REFERENCE
xCreateUnavailablePicture( m_apcSlicePilot->getPPS(), lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getPic()->temporalId, m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL0()->isInterLayerRefPic( refPicIndex ) );
#else
xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex));
#endif
}
}
else
......@@ -2200,11 +2220,19 @@ 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( !pps->getMixedNaluTypesInPicFlag() && ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() )
if( !pps->getMixedNaluTypesInPicFlag() && (
#if JVET_S0123_IDR_UNAVAILABLE_REFERENCE
( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP ) && ( sps->getIDRRefParamListPresent() || pps->getRplInfoInPhFlag() ) ) ||
#endif
( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() ) ) )
{
if (m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex) == 0)
{
#if JVET_S0124_UNAVAILABLE_REFERENCE
xCreateUnavailablePicture( m_apcSlicePilot->getPPS(), lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getPic()->temporalId, m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL1()->isInterLayerRefPic( refPicIndex ) );
#else
xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex));
#endif
}
}
else
......@@ -2328,7 +2356,6 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
pcSlice->setPrevGDRSubpicPOC(m_prevGDRSubpicPOC[nalu.m_nuhLayerId][currSubPicIdx]);
pcSlice->setPrevIRAPSubpicPOC(m_prevIRAPSubpicPOC[nalu.m_nuhLayerId][currSubPicIdx]);
pcSlice->setPrevIRAPSubpicType(m_prevIRAPSubpicType[nalu.m_nuhLayerId][currSubPicIdx]);
pcSlice->setPrevIRAPSubpicType(m_prevIRAPSubpicType[nalu.m_nuhLayerId][currSubPicIdx]);
pcSlice->checkSubpicTypeConstraints(m_cListPic, pcSlice->getRPL0(), pcSlice->getRPL1(), m_prevIRAPSubpicDecOrderNo[nalu.m_nuhLayerId][currSubPicIdx]);
pcSlice->checkRPL(pcSlice->getRPL0(), pcSlice->getRPL1(), m_associatedIRAPDecodingOrderNumber[nalu.m_nuhLayerId], m_cListPic);
pcSlice->checkSTSA(m_cListPic);
......
......@@ -279,7 +279,11 @@ protected:
Picture * xGetNewPicBuffer( const SPS &sps, const PPS &pps, const uint32_t temporalLayer, const int layerId );
void xCreateLostPicture( int iLostPOC, const int layerId );
#if JVET_S0124_UNAVAILABLE_REFERENCE
void xCreateUnavailablePicture( const PPS *pps, const int iUnavailablePoc, const bool longTermFlag, const int temporalId, const int layerId, const bool interLayerRefPicFlag );
#else
void xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const int layerId, const bool interLayerRefPicFlag);
#endif
void checkParameterSetsInclusionSEIconstraints(const InputNALUnit nalu);
void xActivateParameterSets( const InputNALUnit nalu );
void xCheckParameterSetConstraints( const int layerId );
......
......@@ -1507,12 +1507,85 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
pcSPS->setSubPicHeight( 0, ( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1 ) >> floorLog2( pcSPS->getCTUSize() ) );
pcSPS->setIndependentSubPicsFlag(1);
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
pcSPS->setSubPicSameSizeFlag(0);
#endif
pcSPS->setSubPicTreatedAsPicFlag(0, 1);
pcSPS->setLoopFilterAcrossSubpicEnabledFlag(0, 0);
}
else
{
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
READ_FLAG(uiCode, "sps_independent_subpics_flag"); pcSPS->setIndependentSubPicsFlag(uiCode != 0);
READ_FLAG(uiCode, "sps_subpic_same_size_flag"); pcSPS->setSubPicSameSizeFlag(uiCode);
uint32_t tmpWidthVal = (pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) / pcSPS->getCTUSize();
uint32_t tmpHeightVal = (pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) / pcSPS->getCTUSize();
uint32_t numSubpicCols = 1;
for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++)
{
if (!pcSPS->getSubPicSameSizeFlag() || picIdx == 0)
{
if ((picIdx > 0) && (pcSPS->getMaxPicWidthInLumaSamples() > pcSPS->getCTUSize()))
{
READ_CODE(ceilLog2(tmpWidthVal), uiCode, "subpic_ctu_top_left_x[ i ]");
pcSPS->setSubPicCtuTopLeftX(picIdx, uiCode);
}
else
{
pcSPS->setSubPicCtuTopLeftX(picIdx, 0);
}
if ((picIdx > 0) && (pcSPS->getMaxPicHeightInLumaSamples() > pcSPS->getCTUSize()))
{
READ_CODE(ceilLog2(tmpHeightVal), uiCode, "subpic_ctu_top_left_y[ i ]");
pcSPS->setSubPicCtuTopLeftY(picIdx, uiCode);
}
else
{
pcSPS->setSubPicCtuTopLeftY(picIdx, 0);
}
if (picIdx <pcSPS->getNumSubPics() - 1 && pcSPS->getMaxPicWidthInLumaSamples() > pcSPS->getCTUSize())
{
READ_CODE(ceilLog2(tmpWidthVal), uiCode, "subpic_width_minus1[ i ]");
pcSPS->setSubPicWidth(picIdx, uiCode + 1);
}
else
{
pcSPS->setSubPicWidth(picIdx, tmpWidthVal - pcSPS->getSubPicCtuTopLeftX(picIdx));
}
if (picIdx <pcSPS->getNumSubPics() - 1 && pcSPS->getMaxPicHeightInLumaSamples() > pcSPS->getCTUSize())
{
READ_CODE(ceilLog2(tmpHeightVal), uiCode, "subpic_height_minus1[ i ]");
pcSPS->setSubPicHeight(picIdx, uiCode + 1);
}
else
{
pcSPS->setSubPicHeight(picIdx, tmpHeightVal - pcSPS->getSubPicCtuTopLeftY(picIdx));
}
if (pcSPS->getSubPicSameSizeFlag())
{
numSubpicCols = tmpWidthVal / pcSPS->getSubPicWidth(0);
CHECK(!(tmpWidthVal % pcSPS->getSubPicWidth(0) == 0), "subpic_width_minus1[0] is invalid.");
CHECK(!(tmpHeightVal % pcSPS->getSubPicHeight(0) == 0), "subpic_height_minus1[0] is invalid.");
CHECK(!(numSubpicCols * (tmpHeightVal / pcSPS->getSubPicHeight(0)) == pcSPS->getNumSubPics()), "when sps_subpic_same_size_flag is equal to, sps_num_subpics_minus1 is invalid");
}
}
else
{
pcSPS->setSubPicCtuTopLeftX(picIdx, (picIdx % numSubpicCols) * pcSPS->getSubPicWidth(0));
pcSPS->setSubPicCtuTopLeftY(picIdx, (picIdx / numSubpicCols) * pcSPS->getSubPicHeight(0));
pcSPS->setSubPicWidth(picIdx, pcSPS->getSubPicWidth(0));
pcSPS->setSubPicHeight(picIdx, pcSPS->getSubPicHeight(0));
}
if (!pcSPS->getIndependentSubPicsFlag())
{
READ_FLAG(uiCode, "subpic_treated_as_pic_flag[ i ]");
pcSPS->setSubPicTreatedAsPicFlag(picIdx, uiCode);
READ_FLAG(uiCode, "loop_filter_across_subpic_enabled_flag[ i ]");
pcSPS->setLoopFilterAcrossSubpicEnabledFlag(picIdx, uiCode);
}
}
#else
READ_FLAG(uiCode, "sps_independent_subpics_flag"); pcSPS->setIndependentSubPicsFlag(uiCode != 0);
for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++)
{
......@@ -1560,6 +1633,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
pcSPS->setLoopFilterAcrossSubpicEnabledFlag(picIdx, uiCode);
}
}
#endif
}
READ_UVLC( uiCode, "sps_subpic_id_len_minus1" ); pcSPS->setSubPicIdLen( uiCode + 1 );
......@@ -2326,7 +2400,11 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
}
if (pcVPS->getOlsModeIdc() == 2)
{
#if JVET_S0183_VPS_INFORMATION_SIGNALLING
READ_CODE(8, uiCode, "num_output_layer_sets_minus2"); pcVPS->setNumOutputLayerSets(uiCode + 2);
#else
READ_CODE(8, uiCode, "num_output_layer_sets_minus1"); pcVPS->setNumOutputLayerSets(uiCode + 1);
#endif
for (uint32_t i = 1; i <= pcVPS->getNumOutputLayerSets() - 1; i++)
{
for (uint32_t j = 0; j < pcVPS->getMaxLayers(); j++)
......@@ -2819,7 +2897,9 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
{
READ_FLAG( uiCode, "ph_virtual_boundaries_present_flag" );
picHeader->setVirtualBoundariesPresentFlag( uiCode != 0 );
#if !JVET_S0184_VIRTUAL_BOUNDARY_CONSTRAINT
CHECK( sps->getSubPicInfoPresentFlag() && picHeader->getVirtualBoundariesPresentFlag(), "When the subpicture info is present, the signalling of the virtual boundary position, if present, shall be in SPS" );
#endif
if( picHeader->getVirtualBoundariesPresentFlag() )
{
READ_CODE( 2, uiCode, "ph_num_ver_virtual_boundaries"); picHeader->setNumVerVirtualBoundaries( uiCode );
......@@ -3509,6 +3589,10 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
#if !JVET_S0052_RM_SEPARATE_COLOUR_PLANE
CHECK(pcSlice->getPictureHeaderInSliceHeader() && sps->getSeparateColourPlaneFlag() == 1, "when separate_colour_plane_flag is equal to 1, the value of picture_header_in_slice_header_flag shall be equal to 0");
#endif
#if JVET_S0184_VIRTUAL_BOUNDARY_CONSTRAINT
CHECK(sps->getSubPicInfoPresentFlag() == 1 && sps->getVirtualBoundariesEnabledFlag() == 1 && sps->getVirtualBoundariesPresentFlag() == 0,
"when sps_subpic_info_present_flag is equal to 1 and sps_virtual_boundaries_enabled_flag is equal to 1, sps_virtual_boundaries_present_flag shall be equal 1");
#endif
const ChromaFormat chFmt = sps->getChromaFormatIdc();
const uint32_t numValidComp=getNumberValidComponents(chFmt);
......
......@@ -60,8 +60,8 @@ static std::vector<uint32_t> writeAnnexB(std::ostream& out, const AccessUnit& au
static const uint8_t start_code_prefix[] = {0,0,0,1};
if (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_DCI || nalu.m_nalUnitType == NAL_UNIT_SPS || nalu.m_nalUnitType == NAL_UNIT_VPS || nalu.m_nalUnitType == NAL_UNIT_PPS)
if (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_DCI || nalu.m_nalUnitType == NAL_UNIT_VPS || nalu.m_nalUnitType == NAL_UNIT_SPS
|| nalu.m_nalUnitType == NAL_UNIT_PPS || nalu.m_nalUnitType == NAL_UNIT_PREFIX_APS || nalu.m_nalUnitType == NAL_UNIT_SUFFIX_APS)
{
/* From AVC, When any of the following conditions are fulfilled, the
* zero_byte syntax element shall be present:
......
......@@ -284,6 +284,9 @@ protected:
unsigned m_CTUSize;
bool m_subPicInfoPresentFlag;
uint32_t m_numSubPics;
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
bool m_subPicSameSizeFlag;
#endif
std::vector<uint32_t> m_subPicCtuTopLeftX;
std::vector<uint32_t> m_subPicCtuTopLeftY;
std::vector<uint32_t> m_subPicWidth;
......@@ -982,17 +985,26 @@ public:
m_loopFilterAcrossSubpicEnabledFlag.resize(m_numSubPics);
m_subPicId.resize(m_numSubPics);
}
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
void setSubPicSameSizeFlag (bool b) { m_subPicSameSizeFlag = b; }
#endif
void setSubPicCtuTopLeftX (uint32_t u, int i) { m_subPicCtuTopLeftX[i] = u; }
void setSubPicCtuTopLeftY (uint32_t u, int i) { m_subPicCtuTopLeftY[i] = u; }
void setSubPicWidth (uint32_t u, int i) { m_subPicWidth[i] = u; }
void setSubPicHeight (uint32_t u, int i) { m_subPicHeight[i] = u; }
void setSubPicTreatedAsPicFlag (bool b, int i) { m_subPicTreatedAsPicFlag[i] = b; }
void setLoopFilterAcrossSubpicEnabledFlag (bool b, int i) { m_loopFilterAcrossSubpicEnabledFlag[i] = b; }
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
void setSubPicCtuTopLeftX (const std::vector<uint32_t> &v) { CHECK(v.size() != (m_subPicSameSizeFlag ? 0 : m_numSubPics), "number of vector entries must be equal to numSubPics(subPicSameSize=0) or 0(subPicSameSize=1)"); m_subPicCtuTopLeftX = v; }
void setSubPicCtuTopLeftY (const std::vector<uint32_t> &v) { CHECK(v.size() != (m_subPicSameSizeFlag ? 0 : m_numSubPics), "number of vector entries must be equal to numSubPics(subPicSameSize=0) or 0(subPicSameSize=1)"); m_subPicCtuTopLeftY = v; }
void setSubPicWidth (const std::vector<uint32_t> &v) { CHECK(v.size() != (m_subPicSameSizeFlag ? 1 : m_numSubPics), "number of vector entries must be equal to numSubPics(subPicSameSize=0) or 1(subPicSameSize=1)"); m_subPicWidth = v; }
void setSubPicHeight (const std::vector<uint32_t> &v) { CHECK(v.size() != (m_subPicSameSizeFlag ? 1 : m_numSubPics), "number of vector entries must be equal to numSubPics(subPicSameSize=0) or 1(subPicSameSize=1)"); m_subPicHeight = v; }
#else
void setSubPicCtuTopLeftX (const std::vector<uint32_t> &v) { CHECK(v.size()!=m_numSubPics, "number of vector entries must be equal to numSubPics") ;m_subPicCtuTopLeftX = v; }
void setSubPicCtuTopLeftY (const std::vector<uint32_t> &v) { CHECK(v.size()!=m_numSubPics, "number of vector entries must be equal to numSubPics") ;m_subPicCtuTopLeftY = v; }
void setSubPicWidth (const std::vector<uint32_t> &v) { CHECK(v.size()!=m_numSubPics, "number of vector entries must be equal to numSubPics") ;m_subPicWidth = v; }
void setSubPicHeight (const std::vector<uint32_t> &v) { CHECK(v.size()!=m_numSubPics, "number of vector entries must be equal to numSubPics") ;m_subPicHeight = v; }
#endif
void setSubPicTreatedAsPicFlag (const std::vector<bool> &v) { CHECK(v.size()!=m_numSubPics, "number of vector entries must be equal to numSubPics") ;m_subPicTreatedAsPicFlag = v; }
void setLoopFilterAcrossSubpicEnabledFlag (const std::vector<bool> &v) { CHECK(v.size()!=m_numSubPics, "number of vector entries must be equal to numSubPics") ;m_loopFilterAcrossSubpicEnabledFlag = v; }
......@@ -1003,6 +1015,9 @@ public:
void setSubPicId (const std::vector<uint16_t> &v) { CHECK(v.size()!=m_numSubPics, "number of vector entries must be equal to numSubPics"); m_subPicId = v; }
bool getSubPicInfoPresentFlag () { return m_subPicInfoPresentFlag; }
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
bool getSubPicSameSizeFlag () { return m_subPicSameSizeFlag; }
#endif
uint32_t getNumSubPics () { return m_numSubPics; }
uint32_t getSubPicCtuTopLeftX (int i) { return m_subPicCtuTopLeftX[i]; }
uint32_t getSubPicCtuTopLeftY (int i) { return m_subPicCtuTopLeftY[i]; }
......
......@@ -2495,6 +2495,8 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
for( int refIdx = 0; refIdx < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); refIdx++ )
{
CHECK( pcSlice->getRefPic( REF_PIC_LIST_0, refIdx )->unscaledPic == nullptr, "unscaledPic is not set for L0 reference picture" );
if( pcSlice->getRefPic( REF_PIC_LIST_0, refIdx )->isRefScaled( pcSlice->getPPS() ) == false )
{
colRefIdxL0 = refIdx;
......@@ -2506,6 +2508,8 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
{
for( int refIdx = 0; refIdx < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); refIdx++ )
{
CHECK( pcSlice->getRefPic( REF_PIC_LIST_1, refIdx )->unscaledPic == nullptr, "unscaledPic is not set for L1 reference picture" );
if( pcSlice->getRefPic( REF_PIC_LIST_1, refIdx )->isRefScaled( pcSlice->getPPS() ) == false )
{
colRefIdxL1 = refIdx;
......@@ -2528,6 +2532,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
refPicL1 = refPicL1->unscaledPic;
}
CHECK( !refPicL0->slices.size(), "Wrong L0 reference picture" );
CHECK( !refPicL1->slices.size(), "Wrong L1 reference picture" );
const uint32_t uiColFromL0 = refPicL0->slices[0]->getSliceQp() > refPicL1->slices[0]->getSliceQp();
picHeader->setPicColFromL0Flag( uiColFromL0 );
pcSlice->setColFromL0Flag( uiColFromL0 );
......
......@@ -1411,10 +1411,32 @@ void EncLib::xInitSPS( SPS& sps )
if (m_subPicInfoPresentFlag)
{
sps.setNumSubPics(m_numSubPics);
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
sps.setSubPicSameSizeFlag(m_subPicSameSizeFlag);
if (m_subPicSameSizeFlag)
{
uint32_t numSubpicCols = (m_iSourceWidth + m_CTUSize - 1) / m_CTUSize / m_subPicWidth[0];
for (unsigned int i = 0; i < m_numSubPics; i++)
{
sps.setSubPicCtuTopLeftX(i, (i % numSubpicCols) * m_subPicWidth[0]);
sps.setSubPicCtuTopLeftY(i, (i / numSubpicCols) * m_subPicHeight[0]);
sps.setSubPicWidth(i, m_subPicWidth[0]);
sps.setSubPicHeight(i, m_subPicHeight[0]);
}
}
else
{
sps.setSubPicCtuTopLeftX(m_subPicCtuTopLeftX);
sps.setSubPicCtuTopLeftY(m_subPicCtuTopLeftY);
sps.setSubPicWidth(m_subPicWidth);
sps.setSubPicHeight(m_subPicHeight);
}
#else
sps.setSubPicCtuTopLeftX(m_subPicCtuTopLeftX);
sps.setSubPicCtuTopLeftY(m_subPicCtuTopLeftY);
sps.setSubPicWidth(m_subPicWidth);
sps.setSubPicHeight(m_subPicHeight);
#endif
sps.setSubPicTreatedAsPicFlag(m_subPicTreatedAsPicFlag);
sps.setLoopFilterAcrossSubpicEnabledFlag(m_loopFilterAcrossSubpicEnabledFlag);
sps.setSubPicIdLen(m_subPicIdLen);
......
......@@ -895,6 +895,39 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
WRITE_UVLC(pcSPS->getNumSubPics() - 1, "sps_num_subpics_minus1");
if( pcSPS->getNumSubPics() > 1 )
{
#if JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT
WRITE_FLAG(pcSPS->getIndependentSubPicsFlag(), "sps_independent_subpics_flag");
WRITE_FLAG(pcSPS->getSubPicSameSizeFlag(), "sps_subpic_same_size_flag");
uint32_t tmpWidthVal = (pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) / pcSPS->getCTUSize();
uint32_t tmpHeightVal = (pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) / pcSPS->getCTUSize();
for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++)
{
if (!pcSPS->getSubPicSameSizeFlag() || picIdx == 0)
{
if ((picIdx > 0) && (pcSPS->getMaxPicWidthInLumaSamples() > pcSPS->getCTUSize()))
{
WRITE_CODE(pcSPS->getSubPicCtuTopLeftX(picIdx), ceilLog2(tmpWidthVal), "subpic_ctu_top_left_x[ i ]");
}
if ((picIdx > 0) && (pcSPS->getMaxPicHeightInLumaSamples() > pcSPS->getCTUSize()))
{
WRITE_CODE(pcSPS->getSubPicCtuTopLeftY(picIdx), ceilLog2(tmpHeightVal), "subpic_ctu_top_left_y[ i ]");
}
if (picIdx<pcSPS->getNumSubPics() - 1 && pcSPS->getMaxPicWidthInLumaSamples() > pcSPS->getCTUSize())
{
WRITE_CODE(pcSPS->getSubPicWidth(picIdx) - 1, ceilLog2(tmpWidthVal), "subpic_width_minus1[ i ]");
}
if (picIdx<pcSPS->getNumSubPics() - 1 && pcSPS->getMaxPicHeightInLumaSamples() > pcSPS->getCTUSize())
{
WRITE_CODE(pcSPS->getSubPicHeight(picIdx) - 1, ceilLog2(tmpHeightVal), "subpic_height_minus1[ i ]");
}
}
if (!pcSPS->getIndependentSubPicsFlag())
{
WRITE_FLAG(pcSPS->getSubPicTreatedAsPicFlag(picIdx), "subpic_treated_as_pic_flag[ i ]");
WRITE_FLAG(pcSPS->getLoopFilterAcrossSubpicEnabledFlag(picIdx), "loop_filter_across_subpic_enabled_flag[ i ]");
}
}
#else
WRITE_FLAG(pcSPS->getIndependentSubPicsFlag(), "sps_independent_subpics_flag");
for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++)
{
......@@ -920,6 +953,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
WRITE_FLAG( pcSPS->getLoopFilterAcrossSubpicEnabledFlag(picIdx), "loop_filter_across_subpic_enabled_flag[ i ]" );
}
}
#endif
}
CHECK(pcSPS->getSubPicIdLen() < 1, "SPS: SubPicIdLen cannot be less than 1");
......@@ -1461,7 +1495,11 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
}
if (pcVPS->getOlsModeIdc() == 2)
{
#if JVET_S0183_VPS_INFORMATION_SIGNALLING
WRITE_CODE(pcVPS->getNumOutputLayerSets() - 2, 8, "num_output_layer_sets_minus2");
#else
WRITE_CODE(pcVPS->getNumOutputLayerSets() - 1, 8, "num_output_layer_sets_minus1");
#endif
for (uint32_t i = 1; i < pcVPS->getNumOutputLayerSets(); i++)
{
for (uint32_t j = 0; j < pcVPS->getMaxLayers(); j++)
......