diff --git a/cfg/multi-layer/two_layers_ELonlyILP.cfg b/cfg/multi-layer/two_layers_ELonlyILP.cfg index 3bca520408a3c6e28347100c6e9e4d1b6c4924b7..f4310ca78506ecc8767c4259a0b40f275b62a2a8 100644 --- a/cfg/multi-layer/two_layers_ELonlyILP.cfg +++ b/cfg/multi-layer/two_layers_ELonlyILP.cfg @@ -3,10 +3,10 @@ MaxLayers : 2 MaxSublayers : 1 AllLayersSameNumSublayersFlag : 0 AllIndependentLayersFlag : 0 -AllowablePredDirection : 1 1 1 1 1 # equal to 0 specifies the picture in the i-th temporal layer is allowed to use both inter-layer and intra-layer preditions - # equal to 1 specifies the picture in the i-th temporal layer is allowed to use inter-layer predition only - # equal to 2 specifies the picture in the i-th temporal layer is allowed to use intra-layer predition only - +AllowablePredDirection : 1 1 1 1 1 # equal to 0 specifies the picture in the i-th temporal layer is allowed to use both inter-layer and intra-layer preditions + # equal to 1 specifies the picture in the i-th temporal layer is allowed to use inter-layer predition only + # equal to 2 specifies the picture in the i-th temporal layer is allowed to use intra-layer predition only + #======== OLSs =============== EachLayerIsAnOlsFlag : 0 OlsModeIdc : 2 diff --git a/cfg/sei_vui/subpicture_level.cfg b/cfg/sei_vui/subpicture_level.cfg index 5c59cbf100f19e9a2513438e82234a2673cbf71e..a3e1b0b42b8eb4607e60ddc69bd87d5d99f773d2 100644 --- a/cfg/sei_vui/subpicture_level.cfg +++ b/cfg/sei_vui/subpicture_level.cfg @@ -1,6 +1,13 @@ -SEISubpicLevelInfoEnabled: 1 -SEISubpicLevelInfoRefLevels: 4.1 # list of levels to be included -SEISubpicLevelInfoExplicitFraction: 1 # enable sending of explicit fractions -SEISubpicLevelInfoNumSubpics: 2 # number of subpictures - needs to be aligned with NumSubpics -SEISubpicLevelInfoRefLevelFractions: 40 30 # list of fractions: iterates over subpictures and levels (subpictures first) +SEISubpicLevelInfoEnabled: 1 +SEISubpicLevelInfoExplicitFraction: 1 # enable sending of explicit fractions +SEISubpicLevelInfoNumSubpics: 2 # number of subpictures - has to be equal to NumSubpics +SEISubpicLevelInfoMaxSublayers: 7 # number of sublayers - has to be equal to vps_max_sublayers_minus1 + 1 +SEISubpicLevelInfoSublayerInfoPresentFlag: 0 # 0: all sublayers use the same level information, 1: each sublayer shall specify its own level information + +SEISubpicLevelInfoRefLevels: 4.1 # see software manual for list format + +SEISubpicLevelInfoRefLevelFractions: 40 30 # see software manual for list format + + + diff --git a/doc/software-manual.tex b/doc/software-manual.tex index ddc4700e57d53ae99824fadf4d8637d65cb64212..3180971ee7f19c4b56e71e99a83eee7392076e7d 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -4375,21 +4375,44 @@ Enables (true) or disables (false) the insertion of Subpicture Level Information Note, currently no other configuration options are available, because this depends on the number of subpictures, which are still not supported in the software. An example SEI with dummy values is generated, when the option is enabled. \\ -\Option{SEISubpicLevelInfoRefLevels} & -\Default{none} & -List of reference levels to be signalled. -\\ \Option{SEISubpicLevelInfoExplicitFraction} & \Default{false} & Enable signalling of explicit fraction for each level and subpicture \\ \Option{SEISubpicLevelInfoNumSubpics} & \Default{1} & -Number of subpictures in context of the SEI. Has to be equal to NumSubpics. +Number of subpictures in context of the SEI. Has to be equal to NumSubpics +\\ +\Option{SEISubpicLevelInfoMaxSublayers} & +\Default{1} & +Number of sublayers in context of the SEI. Has to be equal to vps_max_sublayers_minus1 + 1 +\\ +\Option{SEISubpicLevelInfoSublayerInfoPresentFlag} & +\Default{false} & +Enable signalling of level information for each sublayer +\par +\begin{tabular}{cp{0.45\textwidth}} +1 & Each sublayer specifies its own level information \\ +0 & All sublayers use the same level information \\ +\end{tabular} +\\ +\Option{SEISubpicLevelInfoRefLevels} & +\Default{""} & +List of reference levels to be signalled. +\par +\begin{tabular}{p{0.49\columnwidth}} +When sli_sublayer_info_present_flag = 0, the number of input elements shall be equal to numReflevels. List is ordered by level.\\ +When sli_sublayer_info_present_flag = 1, the number of input elements shall be equal to numReflevels * maxSublayers. List is ordered by level then sublayer. For example, let Amn denotes the reference level indices for the m-th sublayer and and n-th reference level, the first N elements (A00...A0n-1) denotes the RefLevelFractions for N levels in the 0-th sublayer, and the following N elements (A10...A1n-1) denotes the RefLevelFractions for N levels in the 1st sublayer, and so on, untill all MxN elements specified.\\ +\end{tabular} \\ \Option{SEISubpicLevelInfoRefLevelFractions} & -\Default{none} & -List of fractions of levels to be signalled. List is ordered by subpicture then level. +\Default{""} & +List of fractions of levels to be signalled. +\par +\begin{tabular}{p{0.49\columnwidth}} +When sli_sublayer_info_present_flag = 0, the number of input elements shall be equal to numSubpics * numReflevels. List is ordered by subpicture then level.\\ +When sli_sublayer_info_present_flag = 1, the number of elements shall be equal to numSubpics * numReflevels * maxSublayers. List is ordered by subpicture then level then sublayer. For example, let Bmnk denotes the reference level fractions for the m-th sublayer and n-th reference level and k-th subpicture, the first K elements (B000...B00k-1) denotes the RefLevelFractions for K subpictures in the 0-th levels and 0-th sublayer, and followed by K elements (B010...B0n-1k-1) denotes the RefLevelFractions for K subpictures in the 1st level and 0-th sublayer, and so on, untill all M*N*K elements specified. In another word, among all the specified M*N*K elements, the first N*K elements specify RefLevelFractions for N*K subpictures of N levels in the 0-th sublayer, and the following N*K elements specify RefLevelFractions for N*K subpictures of N levels in the 1st sublayer, and etc.\\ +\end{tabular} \\ \end{OptionTableNoShorthand} diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index a07a813b085b86d0876e5cf21b79eb0904e7a753..a94c6c7a218554ffee8a77a3b4b85eb6ceb5a619 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -664,7 +664,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<uint32_t> cfg_subPicId(0, std::numeric_limits<uint16_t>::max(), 0, MAX_NUM_SUB_PICS); SMultiValueInput<int> cfg_sliFractions(0, 100, 0, std::numeric_limits<int>::max()); +#if JVET_S0176_SLI_SEI + SMultiValueInput<Level::Name> cfg_sliRefLevels(Level::NONE, Level::LEVEL15_5, 0, 8 * MAX_VPS_SUBLAYERS); +#else SMultiValueInput<Level::Name> cfg_sliRefLevels(Level::NONE, Level::LEVEL15_5, 0, 8); +#endif int warnUnknowParameter = 0; @@ -1303,6 +1307,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("SEISubpicLevelInfoRefLevels", cfg_sliRefLevels, cfg_sliRefLevels, "List of reference levels for Subpicture Level Information SEI messages") ("SEISubpicLevelInfoExplicitFraction", m_cfgSubpictureLevelInfoSEI.m_explicitFraction, false, "Enable sending of explicit fractions in Subpicture Level Information SEI messages") ("SEISubpicLevelInfoNumSubpics", m_cfgSubpictureLevelInfoSEI.m_numSubpictures, 1, "Number of subpictures for Subpicture Level Information SEI messages") +#if JVET_S0176_SLI_SEI + ("SEISubpicLevelInfoMaxSublayers", m_cfgSubpictureLevelInfoSEI.m_sliMaxSublayers, 1, "Number of sublayers for Subpicture Level Information SEI messages") + ("SEISubpicLevelInfoSublayerInfoPresentFlag", m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag, false, "Enable sending of level information for all sublayers in Subpicture Level Information SEI messages") +#endif ("SEISubpicLevelInfoRefLevelFractions", cfg_sliFractions, cfg_sliFractions, "List of fractions for Subpicture Level Information SEI messages") ("SEISampleAspectRatioInfo", m_sampleAspectRatioInfoSEIEnabled, false, "Control generation of Sample Aspect Ratio Information SEI messages") ("SEISARICancelFlag", m_sariCancelFlag, false, "Indicates that Sample Aspect Ratio Information SEI message cancels the persistence or follows") @@ -1694,12 +1702,34 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) if (m_cfgSubpictureLevelInfoSEI.m_enabled) { CHECK (m_numSubPics != m_cfgSubpictureLevelInfoSEI.m_numSubpictures, "NumSubPics must be equal to SEISubpicLevelInfoNumSubpics" ); +#if JVET_S0176_SLI_SEI + CHECK (m_cfgSubpictureLevelInfoSEI.m_sliMaxSublayers != m_maxSublayers, "SEISubpicLevelInfoMaxSublayers must be equal to vps_max_sublayers"); + if (m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag) + { + CHECK(cfg_sliRefLevels.values.size() < m_maxSublayers, "when sliSublayerInfoPresentFlag = 1, the number of reference levels must be greater than or equal to sublayers"); + } if (m_cfgSubpictureLevelInfoSEI.m_explicitFraction) { m_cfgSubpictureLevelInfoSEI.m_fractions = cfg_sliFractions.values; m_cfgSubpictureLevelInfoSEI.m_refLevels = cfg_sliRefLevels.values; - CHECK (cfg_sliRefLevels.values.size() * m_cfgSubpictureLevelInfoSEI.m_numSubpictures != cfg_sliFractions.values.size(), "Number of subpicture level fractions must be equal to the numer of subpictures times the number of reference levels."); + if (m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag) + { + CHECK((int)cfg_sliRefLevels.values.size() / m_maxSublayers * m_cfgSubpictureLevelInfoSEI.m_numSubpictures * m_cfgSubpictureLevelInfoSEI.m_sliMaxSublayers != cfg_sliFractions.values.size(), + "when sliSublayerInfoPresentFlag = 1, the number of subpicture level fractions must be equal to the numer of subpictures times the number of reference levels times the number of sublayers"); + } + else + { + CHECK((int)cfg_sliRefLevels.values.size() * m_cfgSubpictureLevelInfoSEI.m_numSubpictures != cfg_sliFractions.values.size(), "when sliSublayerInfoPresentFlag = 0, the number of subpicture level fractions must be equal to the numer of subpictures times the number of reference levels"); + } } +#else + if (m_cfgSubpictureLevelInfoSEI.m_explicitFraction) + { + m_cfgSubpictureLevelInfoSEI.m_fractions = cfg_sliFractions.values; + m_cfgSubpictureLevelInfoSEI.m_refLevels = cfg_sliRefLevels.values; + CHECK (cfg_sliRefLevels.values.size() * m_cfgSubpictureLevelInfoSEI.m_numSubpictures != cfg_sliFractions.values.size(), "when sliSublayerInfoPresentFlag = 0, the number of subpicture level fractions must be equal to the numer of subpictures times the number of reference levels."); + } +#endif } if (m_costMode != COST_LOSSLESS_CODING && m_mixedLossyLossless) diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h index 872e599243a9fcee22b9626b75e012432a18142d..a7c09c82290ad7513444f1e8264061e9a0b6181c 100644 --- a/source/Lib/CommonLib/SEI.h +++ b/source/Lib/CommonLib/SEI.h @@ -648,6 +648,10 @@ public: , m_explicitFractionPresentFlag (false) , m_cbrConstraintFlag (false) , m_numSubpics(0) +#if JVET_S0176_SLI_SEI + , m_sliMaxSublayers(1) + , m_sliSublayerInfoPresentFlag(false) +#endif {} virtual ~SEISubpicureLevelInfo() {} @@ -655,8 +659,15 @@ public: bool m_explicitFractionPresentFlag; bool m_cbrConstraintFlag; int m_numSubpics; +#if JVET_S0176_SLI_SEI + int m_sliMaxSublayers; + bool m_sliSublayerInfoPresentFlag; + std::vector<std::vector<Level::Name>> m_refLevelIdc; + std::vector<std::vector<std::vector<int>>> m_refLevelFraction; +#else std::vector<Level::Name> m_refLevelIdc; std::vector<std::vector<int>> m_refLevelFraction; +#endif }; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 659c8f93a59136a0d3770c465995ac45c2b8b020..fd07951543f7cfd6df0fa1c2eae3632b361d07ca 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -125,6 +125,8 @@ #define JVET_S0178_GENERAL_SEI_CHECK 1 // JVET-S0178: General SEI semantics and constraints +#define JVET_S0176_SLI_SEI 1 // JVET-S0176: On the subpicture level information SEI message + #define JVET_S0186_SPS_CLEANUP 1 // JVET-S0186: Proposal 1, move sps_chroma_format_idc and sps_log2_ctu_size_minus5 to take place sps_reserved_zero_4bits #define JVET_S0181_PROPOSAL2_BUFFERING_PERIOD_CLEANUP 1 // JVET-S0181 Proposal2: Move signalling of bp_max_sublayers_minus1 and conditionally signal bp_cpb_removal_delay_deltas_present_flag, bp_num_cpb_removal_delay_deltas_minus1, and bp_cpb_removal_delay diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index b0841821af23d4ef4d70fb99cabbe166d0b084bf..5a2c59def0a418357842025cdec1c8625d666a5d 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -958,8 +958,7 @@ void DecLib::checkLayerIdIncludedInCvss() return; } - if (m_audIrapOrGdrAuFlag && - (m_isFirstAuInCvs || m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL)) + if (m_audIrapOrGdrAuFlag && (m_isFirstAuInCvs || m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL)) { // store layerIDs in the first AU m_firstAccessUnitPicInfo.assign(m_accessUnitPicInfo.begin(), m_accessUnitPicInfo.end()); diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index 608f84febdb4834dc840971618ff1519100143b4..091b8c984bf1f757d9bbf3e2992b4066e55f336b 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -1501,6 +1501,10 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_ if (sei.m_explicitFractionPresentFlag) { sei_read_uvlc(pDecodedMessageOutputStream, val, "sli_num_subpics_minus1"); sei.m_numSubpics = val + 1; +#if JVET_S0176_SLI_SEI + sei_read_code(pDecodedMessageOutputStream, 3, val, "sli_max_sublayers_minus1" ); sei.m_sliMaxSublayers = val + 1; + sei_read_flag(pDecodedMessageOutputStream, val, "sli_sublayer_info_present_flag"); sei.m_sliSublayerInfoPresentFlag = val; +#endif while (!isByteAligned()) { sei_read_flag( pDecodedMessageOutputStream, val, "sli_alignment_zero_bit" ); CHECK (val != 0, "sli_alignment_zero_bit not equal to zero" ); @@ -1508,24 +1512,86 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_ } sei.m_refLevelIdc.resize(sei.m_numRefLevels); +#if JVET_S0176_SLI_SEI + // sei parameters initialization + for (int i = 0; i < sei.m_numRefLevels; i++) + { + sei.m_refLevelIdc[i].resize(sei.m_sliMaxSublayers); + for (int k = 0; k < sei.m_sliMaxSublayers; k++) + { + sei.m_refLevelIdc[i][k] = Level::LEVEL15_5; + } + } if (sei.m_explicitFractionPresentFlag) { sei.m_refLevelFraction.resize(sei.m_numRefLevels); + for (int i = 0; i < sei.m_numRefLevels; i++) + { + sei.m_refLevelFraction[i].resize(sei.m_numSubpics); + for (int j = 0; j < sei.m_numSubpics; j++) + { + sei.m_refLevelFraction[i][j].resize(sei.m_sliMaxSublayers); + for (int k = 0; k < sei.m_sliMaxSublayers; k++) + { + sei.m_refLevelFraction[i][j][k] = 0; + } + } + } } - for( int i = 0; i < sei.m_numRefLevels; i++ ) + // parsing + for (int k = sei.m_sliSublayerInfoPresentFlag ? 0 : sei.m_sliMaxSublayers - 1; k < sei.m_sliMaxSublayers; k++) + { + for (int i = 0; i < sei.m_numRefLevels; i++) + { + sei_read_code(pDecodedMessageOutputStream, 8, val, "sli_ref_level_idc[i][k]"); sei.m_refLevelIdc[i][k] = (Level::Name) val; + + if (sei.m_explicitFractionPresentFlag) + { + for (int j = 0; j < sei.m_numSubpics; j++) + { + sei_read_code(pDecodedMessageOutputStream, 8, val, "sli_ref_level_fraction_minus1[i][j][k]"); sei.m_refLevelFraction[i][j][k] = val; + } + } + } + } + + // update the inference of m_refLevelIdc[][] and m_refLevelFraction[][][] + if (!sei.m_sliSublayerInfoPresentFlag) + { + for (int k = sei.m_sliMaxSublayers - 2; k >= 0; k--) + { + for (int i = 0; i < sei.m_numRefLevels; i++) + { + sei.m_refLevelIdc[i][k] = sei.m_refLevelIdc[i][sei.m_sliMaxSublayers - 1]; + if (sei.m_explicitFractionPresentFlag) + { + for (int j = 0; j < sei.m_numSubpics; j++) + { + sei.m_refLevelFraction[i][j][k] = sei.m_refLevelFraction[i][j][sei.m_sliMaxSublayers - 1]; + } + } + } + } + } +#else + if (sei.m_explicitFractionPresentFlag) + { + sei.m_refLevelFraction.resize(sei.m_numRefLevels); + } + for (int i = 0; i < sei.m_numRefLevels; i++) { 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, "sli_ref_level_fraction_minus1[i][j]" ); sei.m_refLevelFraction[i][j]= val; } } } +#endif } void SEIReader::xParseSEISampleAspectRatioInfo(SEISampleAspectRatioInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) diff --git a/source/Lib/EncoderLib/EncCfgParam.h b/source/Lib/EncoderLib/EncCfgParam.h index 161400c44ed96f85230b8663c9127f873658abfd..6e011727cae40e13bbdee93fe36f281eedc69939 100644 --- a/source/Lib/EncoderLib/EncCfgParam.h +++ b/source/Lib/EncoderLib/EncCfgParam.h @@ -64,6 +64,10 @@ public: : m_enabled (false) , m_explicitFraction (false) , m_numSubpictures (1) +#if JVET_S0176_SLI_SEI + , m_sliMaxSublayers(1) + , m_sliSublayerInfoPresentFlag (false) +#endif {} virtual ~CfgSEISubpictureLevel(){} @@ -73,6 +77,10 @@ public: bool m_explicitFraction; int m_numSubpictures; std::vector<int> m_fractions; +#if JVET_S0176_SLI_SEI + int m_sliMaxSublayers; + bool m_sliSublayerInfoPresentFlag; +#endif }; } diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 8ef6a69da3e559a4588bb84166ea9a28d97edd15..ab36a8d3eca3f6107bf5eb8e349d03f1f1d19620 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -690,14 +690,83 @@ void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SP { const EncCfgParam::CfgSEISubpictureLevel &cfgSubPicLevel = m_pcCfg->getSubpicureLevelInfoSEICfg(); - sei->m_numRefLevels = (int) cfgSubPicLevel.m_refLevels.size(); - sei->m_refLevelIdc = cfgSubPicLevel.m_refLevels; +#if JVET_S0176_SLI_SEI + sei->m_sliSublayerInfoPresentFlag = cfgSubPicLevel.m_sliSublayerInfoPresentFlag; + sei->m_sliMaxSublayers = cfgSubPicLevel.m_sliMaxSublayers; + sei->m_numRefLevels = cfgSubPicLevel.m_sliSublayerInfoPresentFlag ? (int)cfgSubPicLevel.m_refLevels.size() / cfgSubPicLevel.m_sliMaxSublayers : (int)cfgSubPicLevel.m_refLevels.size(); + sei->m_numSubpics = cfgSubPicLevel.m_numSubpictures; sei->m_explicitFractionPresentFlag = cfgSubPicLevel.m_explicitFraction; - if (cfgSubPicLevel.m_explicitFraction) + + // sei parameters initialization + sei->m_refLevelIdc.resize(sei->m_numRefLevels); + for (int level = 0; level < sei->m_numRefLevels; level++) + { + sei->m_refLevelIdc[level].resize(sei->m_sliMaxSublayers); + for (int sublayer = 0; sublayer < sei->m_sliMaxSublayers; sublayer++) + { + sei->m_refLevelIdc[level][sublayer] = Level::LEVEL15_5; + } + } + if (sei->m_explicitFractionPresentFlag) { - CHECK (sps->getNumSubPics() != cfgSubPicLevel.m_numSubpictures, "Number of subpictures must be equal in SPS and subpicture level information SEI" ); - sei->m_numSubpics = cfgSubPicLevel.m_numSubpictures; sei->m_refLevelFraction.resize(sei->m_numRefLevels); + for (int level = 0; level < sei->m_numRefLevels; level++) + { + sei->m_refLevelFraction[level].resize(sei->m_numSubpics); + for (int subpic = 0; subpic < sei->m_numSubpics; subpic++) + { + sei->m_refLevelFraction[level][subpic].resize(sei->m_sliMaxSublayers); + for (int sublayer = 0; sublayer < sei->m_sliMaxSublayers; sublayer++) + { + sei->m_refLevelFraction[level][subpic][sublayer] = 0; + } + } + } + } + + // set sei parameters according to the configured values + for (int sublayer = sei->m_sliSublayerInfoPresentFlag ? 0 : sei->m_sliMaxSublayers - 1, cnta = 0, cntb = 0; sublayer < sei->m_sliMaxSublayers; sublayer++) + { + for (int level = 0; level < sei->m_numRefLevels; level++) + { + sei->m_refLevelIdc[level][sublayer] = cfgSubPicLevel.m_refLevels[cnta++]; + if (sei->m_explicitFractionPresentFlag) + { + for (int subpic = 0; subpic < sei->m_numSubpics; subpic++) + { + sei->m_refLevelFraction[level][subpic][sublayer] = cfgSubPicLevel.m_fractions[cntb++]; + } + } + } + } + + // update the inference of m_refLevelIdc[][] and m_refLevelFraction[][][] + if (!sei->m_sliSublayerInfoPresentFlag) + { + for (int sublayer = sei->m_sliMaxSublayers - 2; sublayer >= 0; sublayer--) + { + for (int level = 0; level < sei->m_numRefLevels; level++) + { + sei->m_refLevelIdc[level][sublayer] = sei->m_refLevelIdc[level][sei->m_sliMaxSublayers - 1]; + if (sei->m_explicitFractionPresentFlag) + { + for (int subpic = 0; subpic < sei->m_numSubpics; subpic++) + { + sei->m_refLevelFraction[level][subpic][sublayer] = sei->m_refLevelFraction[level][subpic][sei->m_sliMaxSublayers - 1]; + } + } + } + } + } +#else + sei->m_numRefLevels = (int)cfgSubPicLevel.m_refLevels.size(); + sei->m_refLevelIdc = cfgSubPicLevel.m_refLevels; + sei->m_explicitFractionPresentFlag = cfgSubPicLevel.m_explicitFraction; + if (cfgSubPicLevel.m_explicitFraction) + { + CHECK(sps->getNumSubPics() != cfgSubPicLevel.m_numSubpictures, "Number of subpictures must be equal in SPS and subpicture level information SEI"); + sei->m_numSubpics = cfgSubPicLevel.m_numSubpictures; + sei->m_refLevelFraction.resize(sei->m_numRefLevels); for (int level=0, cnt=0; level < sei->m_numRefLevels; level++) { sei->m_refLevelFraction[level].resize(sei->m_numSubpics); @@ -707,6 +776,7 @@ void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SP } } } +#endif } diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp index cff4f5c5bd9d9a572d6eecd36040ce1f4d7592d0..34d4e6881cbbf59779453e42aa6efc57625906df 100644 --- a/source/Lib/EncoderLib/SEIwrite.cpp +++ b/source/Lib/EncoderLib/SEIwrite.cpp @@ -804,13 +804,34 @@ void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei) if (sei.m_explicitFractionPresentFlag) { WRITE_UVLC( sei.m_numSubpics -1 , "sli_num_subpics_minus1"); +#if JVET_S0176_SLI_SEI + WRITE_CODE( (uint32_t)sei.m_sliMaxSublayers - 1, 3, "sli_max_sublayers_minus1"); + WRITE_FLAG( sei.m_sliSublayerInfoPresentFlag, "sli_sublayer_info_present_flag"); +#endif while (!isByteAligned()) { WRITE_FLAG( 0, "sli_alignment_zero_bit"); } } - for (int i=0; i<sei.m_numRefLevels; i++) +#if JVET_S0176_SLI_SEI + for (int k = sei.m_sliSublayerInfoPresentFlag ? 0 : sei.m_sliMaxSublayers - 1; k < sei.m_sliMaxSublayers; k++) + { + for (int i = 0; i < sei.m_numRefLevels; i++) + { + WRITE_CODE((uint32_t)sei.m_refLevelIdc[i][k], 8, "sli_ref_level_idc[i][k]"); + 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][k], 8, "sli_ref_level_fraction_minus1[i][j][k]"); + } + } + } + } +#else + for (int i = 0; i < sei.m_numRefLevels; i++) { WRITE_CODE( (uint32_t)sei.m_refLevelIdc[i], 8, "sli_ref_level_idc[i]"); if (sei.m_explicitFractionPresentFlag) @@ -822,6 +843,7 @@ void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei) } } } +#endif } void SEIWriter::xWriteSEISampleAspectRatioInfo(const SEISampleAspectRatioInfo &sei)