From 0a24c42a1df64dff9d5843e97b8385288bb31814 Mon Sep 17 00:00:00 2001 From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de> Date: Thu, 30 Jul 2020 17:38:43 +0200 Subject: [PATCH] JVET-S0098 Item 3: Add non_subpic_layers_fraction syntax element --- cfg/sei_vui/subpicture_level.cfg | 1 + doc/software-manual.tex | 9 +++++++++ source/App/EncoderApp/EncAppCfg.cpp | 24 ++++++++++++++++++++++-- source/Lib/CommonLib/SEI.h | 3 +++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/DecoderLib/SEIread.cpp | 12 ++++++++++++ source/Lib/EncoderLib/EncCfgParam.h | 3 +++ source/Lib/EncoderLib/SEIEncoder.cpp | 12 ++++++++++++ source/Lib/EncoderLib/SEIwrite.cpp | 3 +++ 9 files changed, 67 insertions(+), 2 deletions(-) diff --git a/cfg/sei_vui/subpicture_level.cfg b/cfg/sei_vui/subpicture_level.cfg index a3e1b0b42..db05a2b73 100644 --- a/cfg/sei_vui/subpicture_level.cfg +++ b/cfg/sei_vui/subpicture_level.cfg @@ -4,6 +4,7 @@ SEISubpicLevelInfoNumSubpics: 2 # number of subpictur 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 +SEISubpicLevelInfoNonSubpicLayersFractions: 100 # see software manual for list format 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 3180971ee..c5db86d64 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -4396,6 +4396,15 @@ Enable signalling of level information for each sublayer 0 & All sublayers use the same level information \\ \end{tabular} \\ +\Option{SEISubpicLevelInfoNonSubpicLayersFractions} & +\Default{""} & +List of fraction of levels to be signalled for non-subpicture layers. +\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{SEISubpicLevelInfoRefLevels} & \Default{""} & List of reference levels to be signalled. diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index a94c6c7a2..2b29049d2 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -663,7 +663,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<bool> cfg_loopFilterAcrossSubpicEnabledFlag(0, 1, 0, MAX_NUM_SUB_PICS); 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()); + SMultiValueInput<int> cfg_sliFractions(0, 100, 0, std::numeric_limits<int>::max()); +#if JVET_S0098_SLI_FRACTION + SMultiValueInput<int> cfg_sliNonSubpicLayersFractions(0, 100, 0, std::numeric_limits<int>::max()); +#endif + #if JVET_S0176_SLI_SEI SMultiValueInput<Level::Name> cfg_sliRefLevels(Level::NONE, Level::LEVEL15_5, 0, 8 * MAX_VPS_SUBLAYERS); #else @@ -1311,7 +1315,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("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") + ("SEISubpicLevelInfoRefLevelFractions", cfg_sliFractions, cfg_sliFractions, "List of subpicture level fractions for Subpicture Level Information SEI messages") +#if JVET_S0098_SLI_FRACTION + ("SEISubpicLevelInfoNonSubpicLayersFractions", cfg_sliNonSubpicLayersFractions, cfg_sliNonSubpicLayersFractions, "List of level fractions for non-subpicture layers in Subpicture Level Information SEI messages") +#endif ("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") ("SEISARIPersistenceFlag", m_sariPersistenceFlag, true, "Specifies the persistence of the Sample Aspect Ratio Information SEI message") @@ -1722,6 +1729,19 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) 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"); } } +#if JVET_S0098_SLI_FRACTION + m_cfgSubpictureLevelInfoSEI.m_nonSubpicLayersFraction = cfg_sliNonSubpicLayersFractions.values; + if (m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag) + { + CHECK((int)cfg_sliNonSubpicLayersFractions.values.size() != ( cfg_sliRefLevels.values.size() * m_cfgSubpictureLevelInfoSEI.m_numSubpictures ), + "when sliSublayerInfoPresentFlag = 1, the number of non-subpicture level fractions must be equal to the numer of reference levels times the number of sublayers"); + } + else + { + CHECK((int)cfg_sliNonSubpicLayersFractions.values.size() != ( cfg_sliRefLevels.values.size() ), + "when sliSublayerInfoPresentFlag = 0, the number of non-subpicture level fractions must be equal to the numer of reference levels"); + } +#endif #else if (m_cfgSubpictureLevelInfoSEI.m_explicitFraction) { diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h index a7c09c822..033f88754 100644 --- a/source/Lib/CommonLib/SEI.h +++ b/source/Lib/CommonLib/SEI.h @@ -662,6 +662,9 @@ public: #if JVET_S0176_SLI_SEI int m_sliMaxSublayers; bool m_sliSublayerInfoPresentFlag; +#if JVET_S0098_SLI_FRACTION + std::vector<std::vector<int>> m_nonSubpicLayersFraction; +#endif std::vector<std::vector<Level::Name>> m_refLevelIdc; std::vector<std::vector<std::vector<int>>> m_refLevelFraction; #else diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index fd0795154..2ae7cbbb6 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -103,6 +103,8 @@ #define JVET_S0071_SAME_SIZE_SUBPIC_LAYOUT 1 // JVET-S0071 : shortcut when all subpictures have the same size +#define JVET_S0098_SLI_FRACTION 1 // JVET-S0098 Item 3: Add non_subpic_layers_fraction syntax element + #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. diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index 091b8c984..b82a55655 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -1513,9 +1513,15 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_ sei.m_refLevelIdc.resize(sei.m_numRefLevels); #if JVET_S0176_SLI_SEI +#if JVET_S0098_SLI_FRACTION + sei.m_nonSubpicLayersFraction.resize(sei.m_numRefLevels); +#endif // sei parameters initialization for (int i = 0; i < sei.m_numRefLevels; i++) { +#if JVET_S0098_SLI_FRACTION + sei.m_nonSubpicLayersFraction[i].resize(sei.m_sliMaxSublayers); +#endif sei.m_refLevelIdc[i].resize(sei.m_sliMaxSublayers); for (int k = 0; k < sei.m_sliMaxSublayers; k++) { @@ -1544,6 +1550,9 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_ { for (int i = 0; i < sei.m_numRefLevels; i++) { +#if JVET_S0098_SLI_FRACTION + sei_read_code(pDecodedMessageOutputStream, 8, val, "sli_non_subpic_layers_fraction[i][k]"); sei.m_nonSubpicLayersFraction[i][k] = (Level::Name) val; +#endif sei_read_code(pDecodedMessageOutputStream, 8, val, "sli_ref_level_idc[i][k]"); sei.m_refLevelIdc[i][k] = (Level::Name) val; if (sei.m_explicitFractionPresentFlag) @@ -1563,6 +1572,9 @@ void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_ { for (int i = 0; i < sei.m_numRefLevels; i++) { +#if JVET_S0098_SLI_FRACTION + sei.m_nonSubpicLayersFraction[i][k] = sei.m_nonSubpicLayersFraction[i][sei.m_sliMaxSublayers - 1]; +#endif sei.m_refLevelIdc[i][k] = sei.m_refLevelIdc[i][sei.m_sliMaxSublayers - 1]; if (sei.m_explicitFractionPresentFlag) { diff --git a/source/Lib/EncoderLib/EncCfgParam.h b/source/Lib/EncoderLib/EncCfgParam.h index 6e011727c..28e023897 100644 --- a/source/Lib/EncoderLib/EncCfgParam.h +++ b/source/Lib/EncoderLib/EncCfgParam.h @@ -76,6 +76,9 @@ public: std::vector<Level::Name> m_refLevels; bool m_explicitFraction; int m_numSubpictures; +#if JVET_S0098_SLI_FRACTION + std::vector<int> m_nonSubpicLayersFraction; +#endif std::vector<int> m_fractions; #if JVET_S0176_SLI_SEI int m_sliMaxSublayers; diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index ab36a8d3e..7aec5025a 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -698,9 +698,15 @@ void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SP sei->m_explicitFractionPresentFlag = cfgSubPicLevel.m_explicitFraction; // sei parameters initialization +#if JVET_S0098_SLI_FRACTION + sei->m_nonSubpicLayersFraction.resize(sei->m_numRefLevels); +#endif sei->m_refLevelIdc.resize(sei->m_numRefLevels); for (int level = 0; level < sei->m_numRefLevels; level++) { +#if JVET_S0098_SLI_FRACTION + sei->m_nonSubpicLayersFraction[level].resize(sei->m_sliMaxSublayers); +#endif sei->m_refLevelIdc[level].resize(sei->m_sliMaxSublayers); for (int sublayer = 0; sublayer < sei->m_sliMaxSublayers; sublayer++) { @@ -729,6 +735,9 @@ void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SP { for (int level = 0; level < sei->m_numRefLevels; level++) { +#if JVET_S0098_SLI_FRACTION + sei->m_nonSubpicLayersFraction[level][sublayer] = cfgSubPicLevel.m_nonSubpicLayersFraction[cnta]; +#endif sei->m_refLevelIdc[level][sublayer] = cfgSubPicLevel.m_refLevels[cnta++]; if (sei->m_explicitFractionPresentFlag) { @@ -747,6 +756,9 @@ void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SP { for (int level = 0; level < sei->m_numRefLevels; level++) { +#if JVET_S0098_SLI_FRACTION + sei->m_nonSubpicLayersFraction[level][sublayer] = sei->m_nonSubpicLayersFraction[level][sei->m_sliMaxSublayers - 1]; +#endif sei->m_refLevelIdc[level][sublayer] = sei->m_refLevelIdc[level][sei->m_sliMaxSublayers - 1]; if (sei->m_explicitFractionPresentFlag) { diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp index 34d4e6881..085fce9de 100644 --- a/source/Lib/EncoderLib/SEIwrite.cpp +++ b/source/Lib/EncoderLib/SEIwrite.cpp @@ -819,6 +819,9 @@ void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei) { for (int i = 0; i < sei.m_numRefLevels; i++) { +#if JVET_S0098_SLI_FRACTION + WRITE_CODE((uint32_t)sei.m_nonSubpicLayersFraction[i][k], 8, "sli_non_subpic_layers_fraction[i][k]"); +#endif WRITE_CODE((uint32_t)sei.m_refLevelIdc[i][k], 8, "sli_ref_level_idc[i][k]"); if (sei.m_explicitFractionPresentFlag) { -- GitLab