From 79e6cd28411c27a2150cfb850e2e17fe230c7fa9 Mon Sep 17 00:00:00 2001 From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de> Date: Fri, 27 Mar 2020 19:04:26 +0100 Subject: [PATCH] Improved encoder configuration for Subpicture Level Information SEI - new pattern: create a class to collect all parameters related to this SEI - existing code can be refactored to use the same pattern for grouping to avoid endless assignments Note: fixes executable flags for some unrelated config files --- cfg/sei_vui/equirectangular.cfg | 0 cfg/sei_vui/omni_viewport.cfg | 0 cfg/sei_vui/region_wise_packing.cfg | 0 cfg/sei_vui/sample_aspect_ratio.cfg | 0 cfg/sei_vui/sphere_rotation.cfg | 0 cfg/sei_vui/subpicture_level.cfg | 6 ++- cfg/sei_vui/timing.cfg | 0 doc/software-manual.tex | 18 ++++++- source/App/EncoderApp/EncApp.cpp | 4 ++ source/App/EncoderApp/EncAppCfg.cpp | 46 ++++++++++++++++++ source/App/EncoderApp/EncAppCfg.h | 5 ++ source/Lib/CommonLib/TypeDef.h | 2 + source/Lib/EncoderLib/EncCfg.h | 11 +++++ source/Lib/EncoderLib/EncCfgParam.h | 71 ++++++++++++++++++++++++++++ source/Lib/EncoderLib/EncGOP.cpp | 4 ++ source/Lib/EncoderLib/SEIEncoder.cpp | 22 +++++++++ 16 files changed, 187 insertions(+), 2 deletions(-) mode change 100755 => 100644 cfg/sei_vui/equirectangular.cfg mode change 100755 => 100644 cfg/sei_vui/omni_viewport.cfg mode change 100755 => 100644 cfg/sei_vui/region_wise_packing.cfg mode change 100755 => 100644 cfg/sei_vui/sample_aspect_ratio.cfg mode change 100755 => 100644 cfg/sei_vui/sphere_rotation.cfg mode change 100755 => 100644 cfg/sei_vui/subpicture_level.cfg mode change 100755 => 100644 cfg/sei_vui/timing.cfg create mode 100644 source/Lib/EncoderLib/EncCfgParam.h diff --git a/cfg/sei_vui/equirectangular.cfg b/cfg/sei_vui/equirectangular.cfg old mode 100755 new mode 100644 diff --git a/cfg/sei_vui/omni_viewport.cfg b/cfg/sei_vui/omni_viewport.cfg old mode 100755 new mode 100644 diff --git a/cfg/sei_vui/region_wise_packing.cfg b/cfg/sei_vui/region_wise_packing.cfg old mode 100755 new mode 100644 diff --git a/cfg/sei_vui/sample_aspect_ratio.cfg b/cfg/sei_vui/sample_aspect_ratio.cfg old mode 100755 new mode 100644 diff --git a/cfg/sei_vui/sphere_rotation.cfg b/cfg/sei_vui/sphere_rotation.cfg old mode 100755 new mode 100644 diff --git a/cfg/sei_vui/subpicture_level.cfg b/cfg/sei_vui/subpicture_level.cfg old mode 100755 new mode 100644 index 46a3dce7a..5c59cbf10 --- a/cfg/sei_vui/subpicture_level.cfg +++ b/cfg/sei_vui/subpicture_level.cfg @@ -1,2 +1,6 @@ -SEISubpicureLevelInfo: 1 +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) diff --git a/cfg/sei_vui/timing.cfg b/cfg/sei_vui/timing.cfg old mode 100755 new mode 100644 diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 4e71fb8d9..99f1f3b45 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -3936,12 +3936,28 @@ Enables (true) or disables (false) the insertion of Frame-Field Information SEI \end{OptionTableNoShorthand} \begin{OptionTableNoShorthand}{Subpicture Level Information SEI message encoder parameters}{tab:sei-subpic-level} -\Option{SEISubpictureLevelInfo} & +\Option{SEISubpictLevelInfoEnabled} & \Default{false} & Enables (true) or disables (false) the insertion of Subpicture Level Information SEI message. 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. +\\ +\Option{SEISubpicLevelInfoRefLevelFractions} & +\Default{none} & +List of fractions of levels to be signalled. List is ordered by subpicture then level. +\\ \end{OptionTableNoShorthand} diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index e7e62e08b..9af6405cb 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -752,7 +752,11 @@ void EncApp::xInitLibCfg() m_cEncLib.setGcmpSEIGuardBandBoundaryType ( m_gcmpSEIGuardBandBoundaryType ); #endif m_cEncLib.setGcmpSEIGuardBandSamplesMinus1 ( (uint8_t)m_gcmpSEIGuardBandSamplesMinus1 ); +#if JVET_SUBPIC_LEVEL_CFG + m_cEncLib.setSubpicureLevelInfoSEICfg (m_cfgSubpictureLevelInfoSEI); +#else m_cEncLib.setSubpicureLevelInfoSEIEnabled (m_subpicureLevelInfoSEIEnabled); +#endif m_cEncLib.setSampleAspectRatioInfoSEIEnabled (m_sampleAspectRatioInfoSEIEnabled); m_cEncLib.setSariCancelFlag (m_sariCancelFlag); m_cEncLib.setSariPersistenceFlag (m_sariPersistenceFlag); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index a13fdf541..a39da9464 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -446,6 +446,24 @@ bool SMultiValueInput<bool>::readValue(const char *&pStr, bool &bSuccess) return val!=0; } +template<> +Level::Name SMultiValueInput<Level::Name>::readValue(const char *&cStr, bool &success) +{ + // first parse the value from the map, using iostreams + std::istringstream str (cStr); + Level::Name val = Level::NONE; + readStrToEnum(strToLevel, sizeof(strToLevel)/sizeof(*strToLevel), str, val); + + // now read a double to forward the string pointer ignoring the returned value + char *eptr; + strtod(cStr, &eptr); + cStr=eptr; + + success=!(*eptr!=0 && !isspace(*eptr) && *eptr!=',') && !((int)val<int(minValIncl) || (int)val>int(maxValIncl)); + return val; +} + + template <class T> istream& SMultiValueInput<T>::readValues(std::istream &in) { @@ -736,6 +754,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<uint32_t> cfg_subPicTreatedAsPicFlag(0, 1, 0, MAX_NUM_SUB_PICS); SMultiValueInput<uint32_t> cfg_loopFilterAcrossSubpicEnabledFlag(0, 1, 0, MAX_NUM_SUB_PICS); SMultiValueInput<uint32_t> cfg_subPicId(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + +#if JVET_SUBPIC_LEVEL_CFG + SMultiValueInput<int> cfg_sliFractions(0, 100, 0, std::numeric_limits<int>::max()); + SMultiValueInput<Level::Name> cfg_sliRefLevels(Level::NONE, Level::LEVEL8_5, 0, 8); +#endif + int warnUnknowParameter = 0; #if ENABLE_TRACING @@ -1356,7 +1380,15 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("SEIGcmpGuardBandBoundaryType", m_gcmpSEIGuardBandBoundaryType, false, "Indicate which face boundaries contain guard bands") #endif ("SEIGcmpGuardBandSamplesMinus1", m_gcmpSEIGuardBandSamplesMinus1, 0u, "Specifies the number of guard band samples minus1 used in the cubemap projected picture") +#if JVET_SUBPIC_LEVEL_CFG + ("SEISubpicLevelInfoEnabled", m_cfgSubpictureLevelInfoSEI.m_enabled, false, "Control generation of Subpicture Level Information SEI messages") + ("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") + ("SEISubpicLevelInfoRefLevelFractions", cfg_sliFractions, cfg_sliFractions, "List of fractions for Subpicture Level Information SEI messages") +#else ("SEISubpicureLevelInfo", m_subpicureLevelInfoSEIEnabled, false, "Control generation of 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") @@ -1685,6 +1717,20 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) CHECK( m_rprEnabled, "RPR and subpictures cannot be enabled together" ); #endif } + +#if JVET_SUBPIC_LEVEL_CFG + if (m_cfgSubpictureLevelInfoSEI.m_enabled) + { + CHECK (m_numSubPics != m_cfgSubpictureLevelInfoSEI.m_numSubpictures, "NumSubPics must be equal to SEISubpicLevelInfoNumSubpics" ); + 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."); + } + } +#endif + if( m_picPartitionFlag ) { // store tile column widths diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index a8430efd5..9897961ac 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -39,6 +39,7 @@ #define __ENCAPPCFG__ #include "CommonLib/CommonDef.h" +#include "EncoderLib/EncCfgParam.h" #include <map> template <class T1, class T2> @@ -629,7 +630,11 @@ protected: #endif uint32_t m_gcmpSEIGuardBandSamplesMinus1; +#if JVET_SUBPIC_LEVEL_CFG + EncCfgParam::CfgSEISubpictureLevel m_cfgSubpictureLevelInfoSEI; +#else bool m_subpicureLevelInfoSEIEnabled; +#endif bool m_sampleAspectRatioInfoSEIEnabled; bool m_sariCancelFlag; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 1c7b98b41..5b4834e61 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -299,6 +299,8 @@ #define JVET_Q0630_SUBPIC_LEVEL 1 // JVET-Q0630 parsing dependency fix for subpicture level info SEI +#define JVET_SUBPIC_LEVEL_CFG 1 // improved configuration of subpicture level info SEI + typedef std::pair<int, bool> TrMode; typedef std::pair<int, int> TrCost; diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 789880e63..d8969e265 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -47,6 +47,8 @@ #include "CommonLib/Unit.h" +#include "EncCfgParam.h" + #if JVET_O0756_CALCULATE_HDRMETRICS #include "HDRLib/inc/DistortionMetric.H" #endif @@ -621,7 +623,11 @@ protected: bool m_gcmpSEIGuardBandBoundaryType; #endif uint8_t m_gcmpSEIGuardBandSamplesMinus1; +#if JVET_SUBPIC_LEVEL_CFG + EncCfgParam::CfgSEISubpictureLevel m_cfgSubpictureLevelInfoSEI; +#else bool m_subpicureLevelInfoSEIEnabled; +#endif bool m_sampleAspectRatioInfoSEIEnabled; bool m_sariCancelFlag; bool m_sariPersistenceFlag; @@ -1676,8 +1682,13 @@ public: #endif void setGcmpSEIGuardBandSamplesMinus1( uint8_t u ) { m_gcmpSEIGuardBandSamplesMinus1 = u; } uint8_t getGcmpSEIGuardBandSamplesMinus1() { return m_gcmpSEIGuardBandSamplesMinus1; } +#if JVET_SUBPIC_LEVEL_CFG + const EncCfgParam::CfgSEISubpictureLevel getSubpicureLevelInfoSEICfg() const { return m_cfgSubpictureLevelInfoSEI; } + void setSubpicureLevelInfoSEICfg(EncCfgParam::CfgSEISubpictureLevel cfg) { m_cfgSubpictureLevelInfoSEI = cfg; } +#else bool getSubpicureLevelInfoSEIEnabled() const { return m_subpicureLevelInfoSEIEnabled; } void setSubpicureLevelInfoSEIEnabled(bool val) { m_subpicureLevelInfoSEIEnabled = val; } +#endif bool getSampleAspectRatioInfoSEIEnabled() const { return m_sampleAspectRatioInfoSEIEnabled; } void setSampleAspectRatioInfoSEIEnabled(const bool val) { m_sampleAspectRatioInfoSEIEnabled = val; } bool getSariCancelFlag() const { return m_sariCancelFlag; } diff --git a/source/Lib/EncoderLib/EncCfgParam.h b/source/Lib/EncoderLib/EncCfgParam.h new file mode 100644 index 000000000..fb1671afd --- /dev/null +++ b/source/Lib/EncoderLib/EncCfgParam.h @@ -0,0 +1,71 @@ + +/* The copyright in this software is being made available under the BSD + * License, included below. This software may be subject to other third party + * and contributor rights, including patent rights, and no such rights are + * granted under this license. + * + * Copyright (c) 2010-2020, ITU/ISO/IEC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __ENCCFGPARAMS__ +#define __ENCCFGPARAMS__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "CommonLib/CommonDef.h" + +namespace EncCfgParam { + +#if JVET_SUBPIC_LEVEL_CFG +class CfgSEISubpictureLevel +{ +public: + + CfgSEISubpictureLevel() + : m_enabled (false) + , m_explicitFraction (false) + , m_numSubpictures (1) + {} + + virtual ~CfgSEISubpictureLevel(){} + + bool m_enabled; + std::vector<Level::Name> m_refLevels; + bool m_explicitFraction; + int m_numSubpictures; + std::vector<int> m_fractions; +}; +#endif + +} + + +#endif // __ENCCFGPARAMS__ diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 4ec7307c9..8888ffe26 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -714,7 +714,11 @@ void EncGOP::xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const SPS m_seiEncoder.initSEIGcmp(sei); seiMessages.push_back(sei); } +#if JVET_SUBPIC_LEVEL_CFG + if (m_pcCfg->getSubpicureLevelInfoSEICfg().m_enabled) +#else if (m_pcCfg->getSubpicureLevelInfoSEIEnabled()) +#endif { SEISubpicureLevelInfo *seiSubpicureLevelInfo = new SEISubpicureLevelInfo; m_seiEncoder.initSEISubpictureLevelInfo(seiSubpicureLevelInfo, sps); diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 53188a432..ddbcee89a 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -621,6 +621,27 @@ void SEIEncoder::initSEIContentColourVolume(SEIContentColourVolume *seiContentCo } void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SPS *sps) { +#if JVET_SUBPIC_LEVEL_CFG + const EncCfgParam::CfgSEISubpictureLevel &cfgSubPicLevel = m_pcCfg->getSubpicureLevelInfoSEICfg(); + + 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); + for (int subpic=0; subpic<sei->m_numSubpics; subpic++) + { + sei->m_refLevelFraction[level][subpic] = cfgSubPicLevel.m_fractions[cnt++]; + } + } + } +#else // subpicture level information should be specified via config file // unfortunately the implementation of subpictures is still not available // TODO: implement config file parameters and intialization @@ -636,6 +657,7 @@ void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SP sei->m_refLevelIdc[0] = Level::LEVEL4; sei->m_refLevelIdc[1] = Level::LEVEL8_5; sei->m_explicitFractionPresentFlag = false; +#endif } -- GitLab