diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp index 1d3bb355664971dd1a992a38d1f2428c5d88c2f3..8f46d322742348941f82192bc3cb73048a625260 100644 --- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp @@ -369,6 +369,9 @@ uint32_t BitstreamExtractorApp::decode() bitstreamFileIn.seekg( 0, std::ios::beg ); int unitCnt = 0; +#if JVET_Q0404_CBR_SUBPIC + bool lastSliceWritten= false; // stores status of previous slice for associated filler data NAL units +#endif VPS *vpsIdZero = new VPS(); std::vector<uint8_t> empty; @@ -441,8 +444,8 @@ uint32_t BitstreamExtractorApp::decode() } uint32_t numOlss = vps->getNumOutputLayerSets(); CHECK(m_targetOlsIdx <0 || m_targetOlsIdx >= numOlss, "target Ols shall be in the range of OLSs specified by the VPS"); - std::vector<int> LayerIdInOls = vps->getLayerIdsInOls(m_targetOlsIdx); - bool isIncludedInTargetOls = std::find(LayerIdInOls.begin(), LayerIdInOls.end(), nalu.m_nuhLayerId) != LayerIdInOls.end(); + std::vector<int> layerIdInOls = vps->getLayerIdsInOls(m_targetOlsIdx); + bool isIncludedInTargetOls = std::find(layerIdInOls.begin(), layerIdInOls.end(), nalu.m_nuhLayerId) != layerIdInOls.end(); writeInpuNalUnitToStream &= (isSpecialNalTypes || isIncludedInTargetOls); #if JVET_Q0394_TIMING_SEI m_removeTimingSEI = !vps->getGeneralHrdParameters()->getGeneralSamePicTimingInAllOlsFlag(); @@ -627,7 +630,12 @@ uint32_t BitstreamExtractorApp::decode() // check for subpicture ID writeInpuNalUnitToStream = xCheckSliceSubpicture(nalu, m_subPicId); } - +#if JVET_Q0404_CBR_SUBPIC + if (nalu.m_nalUnitType == NAL_UNIT_FD) + { + writeInpuNalUnitToStream = lastSliceWritten; + } +#endif } unitCnt++; @@ -649,6 +657,21 @@ uint32_t BitstreamExtractorApp::decode() // write with start code emulation prevention writeNaluContent (bitstreamFileOut, out); } + +#if JVET_Q0404_CBR_SUBPIC + // update status of previous slice + if (nalu.isSlice()) + { + if (writeInpuNalUnitToStream) + { + lastSliceWritten = true; + } + else + { + lastSliceWritten=false; + } + } +#endif } } diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h index cf110acd3902688bb76a9627848278210de73c9f..fa88f605289daa69a956ee76c70a0c74ecde5819 100644 --- a/source/Lib/CommonLib/SEI.h +++ b/source/Lib/CommonLib/SEI.h @@ -634,12 +634,18 @@ public: SEISubpicureLevelInfo() : m_numRefLevels(0) , m_explicitFractionPresentFlag (false) +#if JVET_Q0404_CBR_SUBPIC + , m_cbrConstraintFlag (false) +#endif , m_numSubpics(0) {} virtual ~SEISubpicureLevelInfo() {} int m_numRefLevels; bool m_explicitFractionPresentFlag; +#if JVET_Q0404_CBR_SUBPIC + bool m_cbrConstraintFlag; +#endif int m_numSubpics; std::vector<Level::Name> m_refLevelIdc; std::vector<std::vector<int>> m_refLevelFraction; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 72e20051c9e619b97a689a17071276e28e7aeef0..63dbd53dfde0a232e7276118ee7521f2a5721f26 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -171,6 +171,8 @@ #define JVET_Q0394_TIMING_SEI 1 // JVET_Q0394: Picture timing for OLSs +#define JVET_Q0404_CBR_SUBPIC 1 // JVET_Q0404: Constant bitrate extraction for subpictures + #define JVET_R0100 1 // JVET-R0100: Proposal 1 DUI Signalling and inference #define JVET_R0413_HRD_TIMING_INFORMATION 1 // JVET-R0413: HRD timing parameters signalling diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index 416b8b24040ce09ced420eebaae3ad16e6c2e580..93846dff5340faba5df904d04e559ef3ee92d478 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -1365,8 +1365,11 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_ { output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize); uint32_t val; - sei_read_code( pDecodedMessageOutputStream, 3, val, "num_ref_levels_minus1" ); sei.m_numRefLevels = val + 1; - sei_read_flag( pDecodedMessageOutputStream, val, "explicit_fraction_present_flag" ); sei.m_explicitFractionPresentFlag = val; + sei_read_code( pDecodedMessageOutputStream, 3, val, "sli_num_ref_levels_minus1" ); sei.m_numRefLevels = val + 1; +#if JVET_Q0404_CBR_SUBPIC + sei_read_flag( pDecodedMessageOutputStream, val, "sli_cbr_constraint_flag" ); sei.m_cbrConstraintFlag = val; +#endif + sei_read_flag( pDecodedMessageOutputStream, val, "sli_explicit_fraction_present_flag" ); sei.m_explicitFractionPresentFlag = val; if (sei.m_explicitFractionPresentFlag) { sei_read_uvlc(pDecodedMessageOutputStream, val, "sli_num_subpics_minus1"); sei.m_numSubpics = val + 1; @@ -1384,14 +1387,14 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_ for( int i = 0; i < sei.m_numRefLevels; i++ ) { - sei_read_code( pDecodedMessageOutputStream, 8, val, "ref_level_idc[i]" ); sei.m_refLevelIdc[i] = (Level::Name) val; + sei_read_code( pDecodedMessageOutputStream, 8, val, "sli_ref_level_idc[i]" ); sei.m_refLevelIdc[i] = (Level::Name) val; if( sei.m_explicitFractionPresentFlag ) { sei.m_refLevelFraction[i].resize(sei.m_numSubpics); for( int j = 0; j < sei.m_numSubpics; j++ ) { - sei_read_code( pDecodedMessageOutputStream, 8, val, "ref_level_fraction_minus1[i][j]" ); sei.m_refLevelFraction[i][j]= val; + sei_read_code( pDecodedMessageOutputStream, 8, val, "sli_ref_level_fraction_minus1[i][j]" ); sei.m_refLevelFraction[i][j]= val; } } } diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp index 404788b6d842b72ec30cd27b6fcb7884e6621868..2160886524c39252c3198ea84d4bbcc70a67db4e 100644 --- a/source/Lib/EncoderLib/SEIwrite.cpp +++ b/source/Lib/EncoderLib/SEIwrite.cpp @@ -737,8 +737,11 @@ void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei) { CHECK(sei.m_numRefLevels != (int)sei.m_refLevelFraction.size(), "SEISubpicureLevelInfo: numRefLevels must be equal to the number of fractions"); } - WRITE_CODE( (uint32_t)sei.m_numRefLevels - 1, 3, "num_ref_levels_minus1"); - WRITE_FLAG( sei.m_explicitFractionPresentFlag, "explicit_fraction_present_flag"); + WRITE_CODE( (uint32_t)sei.m_numRefLevels - 1, 3, "sli_num_ref_levels_minus1"); +#if JVET_Q0404_CBR_SUBPIC + WRITE_FLAG( sei.m_cbrConstraintFlag, "sli_cbr_constraint_flag"); +#endif + WRITE_FLAG( sei.m_explicitFractionPresentFlag, "sli_explicit_fraction_present_flag"); if (sei.m_explicitFractionPresentFlag) { WRITE_UVLC( sei.m_numSubpics -1 , "sli_num_subpics_minus1"); @@ -750,13 +753,13 @@ void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei) for (int i=0; i<sei.m_numRefLevels; i++) { - WRITE_CODE( (uint32_t)sei.m_refLevelIdc[i], 8, "ref_level_idc[i]"); + WRITE_CODE( (uint32_t)sei.m_refLevelIdc[i], 8, "sli_ref_level_idc[i]"); if (sei.m_explicitFractionPresentFlag) { CHECK(sei.m_numSubpics != (int)sei.m_refLevelFraction[i].size(), "SEISubpicureLevelInfo: number of fractions differs from number of subpictures"); for (int j = 0; j < sei.m_numSubpics; j++) { - WRITE_CODE( (uint32_t)sei.m_refLevelFraction[i][j], 8, "ref_level_fraction_minus1[i][j]"); + WRITE_CODE( (uint32_t)sei.m_refLevelFraction[i][j], 8, "sli_ref_level_fraction_minus1[i][j]"); } } }