diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h index 7332c37aa236b5feed26ec9ac9721d1aacd2b8ec..2e7e2d92c2d7896c83ace8eb49aa67c86e3e49af 100644 --- a/source/Lib/CommonLib/SEI.h +++ b/source/Lib/CommonLib/SEI.h @@ -638,15 +638,27 @@ class SEISubpicureLevelInfo : public SEI public: PayloadType payloadType() const { return SUBPICTURE_LEVEL_INFO; } SEISubpicureLevelInfo() +#if !JVET_Q0630_SUBPIC_LEVEL : m_sliSeqParameterSetId(0) , m_numRefLevels(0) +#else + : m_numRefLevels(0) +#endif , m_explicitFractionPresentFlag (false) +#if JVET_Q0630_SUBPIC_LEVEL + , m_numSubpics(0) +#endif {} virtual ~SEISubpicureLevelInfo() {} +#if !JVET_Q0630_SUBPIC_LEVEL int m_sliSeqParameterSetId; +#endif int m_numRefLevels; bool m_explicitFractionPresentFlag; +#if JVET_Q0630_SUBPIC_LEVEL + int m_numSubpics; +#endif 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 7fb93a074e9ab7f4c344238a363e6da780549156..1c7b98b412edf649d60ff25e4b364c27eb7a1103 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -297,6 +297,8 @@ #define JVET_Q0399_SCALING_INFERENCE 1 // JVET-Q0399 infer scaling window to conformance window, if not present +#define JVET_Q0630_SUBPIC_LEVEL 1 // JVET-Q0630 parsing dependency fix for subpicture level info SEI + typedef std::pair<int, bool> TrMode; typedef std::pair<int, int> TrCost; diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index 93e605a10d56ef5533f12d61513e477f4d38c9ef..21d429643540883e8e9fd12bf7fea196a84fae43 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -286,7 +286,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType break; case SEI::SUBPICTURE_LEVEL_INFO: sei = new SEISubpicureLevelInfo; +#if JVET_Q0630_SUBPIC_LEVEL + xParseSEISubpictureLevelInfo((SEISubpicureLevelInfo&) *sei, payloadSize, pDecodedMessageOutputStream); +#else xParseSEISubpictureLevelInfo((SEISubpicureLevelInfo&) *sei, sps, payloadSize, pDecodedMessageOutputStream); +#endif break; case SEI::SAMPLE_ASPECT_RATIO_INFO: sei = new SEISampleAspectRatioInfo; @@ -1308,19 +1312,37 @@ void SEIReader::xParseSEIGeneralizedCubemapProjection(SEIGeneralizedCubemapProje } } +#if JVET_Q0630_SUBPIC_LEVEL +void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) +#else void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, const SPS *sps, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) +#endif { output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize); +#if !JVET_Q0630_SUBPIC_LEVEL if (sps == nullptr) { fprintf (stderr, "no SPS available, not parsing Subpicture level information SEI"); return; } +#endif uint32_t val; +#if !JVET_Q0630_SUBPIC_LEVEL sei_read_code( pDecodedMessageOutputStream, 4, val, "sli_seq_parameter_set_id" ); sei.m_sliSeqParameterSetId = val; +#endif 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; - +#if JVET_Q0630_SUBPIC_LEVEL + if (sei.m_explicitFractionPresentFlag) + { + sei_read_uvlc(pDecodedMessageOutputStream, val, "sli_num_subpics_minus1"); sei.m_numSubpics = val + 1; + while (!isByteAligned()) + { + sei_read_flag( pDecodedMessageOutputStream, val, "sli_alignment_zero_bit" ); CHECK (val != 0, "sli_alignment_zero_bit not equal to zero" ); + } + } +#endif + sei.m_refLevelIdc.resize(sei.m_numRefLevels); if (sei.m_explicitFractionPresentFlag) { @@ -1332,10 +1354,16 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, const S sei_read_code( pDecodedMessageOutputStream, 8, val, "ref_level_idc[i]" ); sei.m_refLevelIdc[i] = (Level::Name) val; if( sei.m_explicitFractionPresentFlag ) { +#if !JVET_Q0630_SUBPIC_LEVEL int numSubPics = sps->getNumSubPics(); sei.m_refLevelFraction[i].resize(numSubPics); for( int j = 0; j < numSubPics; j++ ) +#else + sei.m_refLevelFraction[i].resize(sei.m_numSubpics); + + for( int j = 0; j < sei.m_numSubpics; j++ ) +#endif { sei_read_code( pDecodedMessageOutputStream, 8, val, "ref_level_fraction_minus1[i][j]" ); sei.m_refLevelFraction[i][j]= val; } diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h index 7003ff09bd027c7c3ac96fc99837640b6703813e..287c6a287a4ff297b82641f36d25ac84099e688e 100644 --- a/source/Lib/DecoderLib/SEIread.h +++ b/source/Lib/DecoderLib/SEIread.h @@ -95,7 +95,11 @@ protected: void xParseSEIOmniViewport (SEIOmniViewport& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIRegionWisePacking (SEIRegionWisePacking& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIGeneralizedCubemapProjection (SEIGeneralizedCubemapProjection &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); +#if JVET_Q0630_SUBPIC_LEVEL + void xParseSEISubpictureLevelInfo (SEISubpicureLevelInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); +#else void xParseSEISubpictureLevelInfo (SEISubpicureLevelInfo& sei, const SPS *sps, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); +#endif void xParseSEISampleAspectRatioInfo (SEISampleAspectRatioInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIUserDataRegistered (SEIUserDataRegistered& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIFilmGrainCharacteristics (SEIFilmGrainCharacteristics& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 330d8a070b16fe3bb94abeabc60dcbde55f0671b..53188a432c40100ac6e7b8dfc98b14386549f569 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -626,7 +626,11 @@ void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SP // TODO: implement config file parameters and intialization fprintf(stderr, "SEISubpicureLevelInfo depends on subpictures! Initializing to dummy values!\n"); +#if !JVET_Q0630_SUBPIC_LEVEL sei->m_sliSeqParameterSetId = sps->getSPSId(); +#else + sei->m_numSubpics = sps->getNumSubPics(); +#endif sei->m_numRefLevels = 2; sei->m_refLevelIdc.resize(2); sei->m_refLevelIdc[0] = Level::LEVEL4; diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp index 0ca296cb795d95fb78ab8965102b26e08af58b46..c6020968afed2dc7d65ac95198e59e4078b28a6f 100644 --- a/source/Lib/EncoderLib/SEIwrite.cpp +++ b/source/Lib/EncoderLib/SEIwrite.cpp @@ -121,7 +121,11 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI& sei, const xWriteSEIContentColourVolume(*static_cast<const SEIContentColourVolume*>(&sei)); break; case SEI::SUBPICTURE_LEVEL_INFO: +#if JVET_Q0630_SUBPIC_LEVEL + xWriteSEISubpictureLevelInfo(*static_cast<const SEISubpicureLevelInfo*>(&sei)); +#else xWriteSEISubpictureLevelInfo(*static_cast<const SEISubpicureLevelInfo*>(&sei), sps); +#endif break; case SEI::SAMPLE_ASPECT_RATIO_INFO: xWriteSEISampleAspectRatioInfo(*static_cast<const SEISampleAspectRatioInfo*>(&sei)); @@ -703,9 +707,15 @@ void SEIWriter::xWriteSEIGeneralizedCubemapProjection(const SEIGeneralizedCubema } } +#if JVET_Q0630_SUBPIC_LEVEL +void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei) +#else void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei, const SPS* sps) +#endif { +#if !JVET_Q0630_SUBPIC_LEVEL WRITE_CODE( (uint32_t)sei.m_sliSeqParameterSetId, 4, "sli_seq_parameter_set_id"); +#endif CHECK(sei.m_numRefLevels < 1, "SEISubpicureLevelInfo: numRefLevels must be greater than zero"); CHECK(sei.m_numRefLevels != (int)sei.m_refLevelIdc.size(), "SEISubpicureLevelInfo: numRefLevels must be equal to the number of levels"); if (sei.m_explicitFractionPresentFlag) @@ -714,14 +724,29 @@ void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei, c } WRITE_CODE( (uint32_t)sei.m_numRefLevels - 1, 3, "num_ref_levels_minus1"); WRITE_FLAG( sei.m_explicitFractionPresentFlag, "explicit_fraction_present_flag"); +#if JVET_Q0630_SUBPIC_LEVEL + if (sei.m_explicitFractionPresentFlag) + { + WRITE_UVLC( sei.m_numSubpics -1 , "sli_num_subpics_minus1"); + while (!isByteAligned()) + { + WRITE_FLAG( 0, "sli_alignment_zero_bit"); + } + } +#endif for (int i=0; i<sei.m_numRefLevels; i++) { WRITE_CODE( (uint32_t)sei.m_refLevelIdc[i], 8, "ref_level_idc[i]"); if (sei.m_explicitFractionPresentFlag) { +#if !JVET_Q0630_SUBPIC_LEVEL CHECK(sps->getNumSubPics() != (int)sei.m_refLevelFraction[i].size(), "SEISubpicureLevelInfo: number of fractions differs from number of subpictures"); for (int j = 0; j < sps->getNumSubPics(); j++) +#else + 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++) +#endif { WRITE_CODE( (uint32_t)sei.m_refLevelFraction[i][j], 8, "ref_level_fraction_minus1[i][j]"); } diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h index 4e3e18d2d523f839aeca2d575cf7746d2b7a500d..fe174dbda888accb199b08e3c40002f8775467e1 100644 --- a/source/Lib/EncoderLib/SEIwrite.h +++ b/source/Lib/EncoderLib/SEIwrite.h @@ -72,7 +72,11 @@ protected: void xWriteSEIOmniViewport (const SEIOmniViewport& sei); void xWriteSEIRegionWisePacking (const SEIRegionWisePacking &sei); void xWriteSEIGeneralizedCubemapProjection (const SEIGeneralizedCubemapProjection &sei); +#if JVET_Q0630_SUBPIC_LEVEL + void xWriteSEISubpictureLevelInfo (const SEISubpicureLevelInfo &sei); +#else void xWriteSEISubpictureLevelInfo (const SEISubpicureLevelInfo &sei, const SPS* sps); +#endif void xWriteSEISampleAspectRatioInfo (const SEISampleAspectRatioInfo &sei); void xWriteSEIUserDataRegistered(const SEIUserDataRegistered& sei);