diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 1743354a6f60810c618b34380e67504ed4dce4ca..21d80063e3c767809c5d561cfc87fd00dad42271 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -1519,10 +1519,10 @@ Indicates that all OLSs are using the same (not nested) picture timing SEI messa be included in scalable nesting SEI messages (if scalable nesting SEI is enabled). \\ -\Option{MaxTidILRefPicsPlus1} & +\Option{MaxTidILRefPicsPlusOneLayerId\emph{i}} & %\ShortOption{\None} & -\Default{-1} & -Specifies the maximum temporal ID for inter-layer reference pictures plus 1. The value 0 allows only to use IRAP pictures for inter-layer prediction. +\Default{""} & +Specifies a list of the maximum temporal ID of the reference layers of the i-th layer plus 1 (with i an integer greater than 0). The value 0 allows only to use IRAP pictures for inter-layer prediction. \\ \Option{AvoidIntraInDepLayer} & diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp index e0fac0f85051573c2feb47b6283688d4e13b2ed9..ae5b5336c42cc8b9b2c52cabc6bf1b9bdaabbf3f 100644 --- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp @@ -461,6 +461,22 @@ void BitstreamExtractorApp::xWritePPS(PPS *pps, std::ostream& out, int layerId, writeAnnexBNalUnit(out, naluWithHeader, true); } +#if JVET_S0219_ASPECT1 +void BitstreamExtractorApp::xWriteAPS(APS *aps, std::ostream& out, int layerId, int temporalId, const bool isPrefixNUT) +{ + OutputNALUnit naluOut(isPrefixNUT ? NAL_UNIT_PREFIX_APS : NAL_UNIT_SUFFIX_APS, layerId, temporalId); + + // write the PPS to the newly created NAL unit buffer + m_hlSyntaxWriter.setBitstream(&naluOut.m_Bitstream); + m_hlSyntaxWriter.codeAPS(aps); +#if JVET_R0294_SUBPIC_HASH + NALUnitEBSP naluWithHeader(naluOut); + writeAnnexBNalUnit(out, naluWithHeader, true); +#endif +} + +#endif + // returns true, if the NAL unit is to be discarded bool BitstreamExtractorApp::xCheckNumSubLayers(InputNALUnit &nalu, VPS *vps) { @@ -771,15 +787,15 @@ uint32_t BitstreamExtractorApp::decode() msg (VERBOSE, "APS Info: APS ID = %d Type = %d Layer = %d\n", aps->getAPSId(), aps->getAPSType(), nalu.m_nuhLayerId); int apsId = aps->getAPSId(); int apsType = aps->getAPSType(); + // note: storeAPS may invalidate the aps pointer! + m_parameterSetManager.storeAPS(aps, nalu.getBitstream().getFifo()); + // get APS back + aps = m_parameterSetManager.getAPS(apsId, apsType); #if JVET_S0219_ASPECT1 if (writeInpuNalUnitToStream) { -#endif - // note: storeAPS may invalidate the aps pointer! - m_parameterSetManager.storeAPS(aps, nalu.getBitstream().getFifo()); - // get APS back - aps = m_parameterSetManager.getAPS(apsId, apsType); -#if JVET_S0219_ASPECT1 + xWriteAPS(aps, bitstreamFileOut, nalu.m_nuhLayerId, nalu.m_temporalId, nalu.m_nalUnitType == NAL_UNIT_PREFIX_APS); + writeInpuNalUnitToStream = false; } #endif } diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h index 345aac94a1eb289a166b6c607d8d8e15c01a533a..1c2eea3f1722bfcba3c11e0a1f90c6762c3869a3 100644 --- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h @@ -86,6 +86,9 @@ protected: void xWriteVPS(VPS *vps, std::ostream& out, int layerId, int temporalId); void xWriteSPS(SPS *sps, std::ostream& out, int layerId, int temporalId); void xWritePPS(PPS *pps, std::ostream& out, int layerId, int temporalId); +#if JVET_S0219_ASPECT1 + void xWriteAPS(APS *aps, std::ostream& out, int layerId, int temporalId, const bool isPrefixNUT); +#endif ParameterSetManager m_parameterSetManager; HLSyntaxReader m_hlSynaxReader; diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 09ae16c54b3b309bf27cbe53e42ad1c08ba1b558..5bcb85c6d6d78a5230e81896d1a7b44d5df34500 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -117,6 +117,9 @@ void EncApp::xInitLibCfg() } } +#if JVET_R0193 + m_cfgVPSParameters.m_maxTidILRefPicsPlus1.resize(vps.getMaxLayers(), std::vector<uint32_t>(vps.getMaxLayers(), NOT_VALID)); +#endif for (int i = 0; i < vps.getMaxLayers(); i++) { vps.setGeneralLayerIdx( m_layerId[i], i ); @@ -140,22 +143,20 @@ void EncApp::xInitLibCfg() { vps.setDirectRefLayerFlag(i, j, false); } + } #if JVET_R0193 - bool bSetMaxTid = false; - for (int t = 0; t < vps.getMaxSubLayers(); t++) - { - if (m_cfgVPSParameters.m_maxTidILRefPicsPlus1Str[i].find(to_string(t)) != std::string::npos) - { - vps.setMaxTidIlRefPicsPlus1(i, j, t); - bSetMaxTid = true; - } - } - if (!bSetMaxTid) - { - vps.setMaxTidIlRefPicsPlus1(i, j, vps.getMaxSubLayers()); - } -#endif + //m_cfgVPSParameters.m_maxTidILRefPicsPlus1[i][j] = vps.getMaxSubLayers(); + + string::size_type beginStr = m_maxTidILRefPicsPlus1Str[i].find_first_not_of(" ", 0); + string::size_type endStr = m_maxTidILRefPicsPlus1Str[i].find_first_of(" ", beginStr); + int t = 0; + while (string::npos != beginStr || string::npos != endStr) + { + m_cfgVPSParameters.m_maxTidILRefPicsPlus1[i][t++] = std::stoi(m_maxTidILRefPicsPlus1Str[i].substr(beginStr, endStr - beginStr)); + beginStr = m_maxTidILRefPicsPlus1Str[i].find_first_not_of(" ", endStr); + endStr = m_maxTidILRefPicsPlus1Str[i].find_first_of(" ", beginStr); } +#endif } } } diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index d95d6e29468f3c11e620a69bd3a0b225695f0549..faea0ed16167c400a79673b7c9a56ddfb8089c9d 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1401,7 +1401,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ( "NumPTLsInVPS", m_numPtlsInVps, 1, "Number of profile_tier_level structures in VPS" ) ( "AvoidIntraInDepLayers", m_avoidIntraInDepLayer, true, "Replaces I pictures in dependent layers with B pictures" ) #if JVET_R0193 - ( "MaxTidILRefPicsPlusOneLayerId%d", m_cfgVPSParameters.m_maxTidILRefPicsPlus1Str, string(""), MAX_VPS_LAYERS, "Maximum temporal ID for inter-layer reference pictures plus 1 of i-th layer, 0 for IRAP only") + ( "MaxTidILRefPicsPlusOneLayerId%d", m_maxTidILRefPicsPlus1Str, string(""), MAX_VPS_LAYERS, "Maximum temporal ID for inter-layer reference pictures plus 1 of i-th layer, 0 for IRAP only") #else ( "MaxTidILRefPicsPlus1", m_cfgVPSParameters.m_maxTidILRefPicsPlus1, -1, "Maximum temporal ID for inter-layer reference pictures plus 1, 0 for IRAP only" ) #endif diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index ff82dd03ba707c754d5025349363ff59d4bcc3e9..7f8d114143fcd8d48b52a476efc032c74f59c3fd 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -725,6 +725,9 @@ protected: int m_olsModeIdc; int m_numOutputLayerSets; std::string m_olsOutputLayerStr[MAX_VPS_LAYERS]; +#if JVET_R0193 + std::string m_maxTidILRefPicsPlus1Str[MAX_VPS_LAYERS]; +#endif int m_numPtlsInVps; diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index b9280bfd77a10fafbd031d2db4245be14586b2ad..a0dd315dfb7c9b01da9f969f0bbc6b96938e026e 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -2206,10 +2206,6 @@ VPS::VPS() { m_vpsDirectRefLayerFlag[i][j] = 0; m_directRefLayerIdx[i][j] = MAX_VPS_LAYERS; -#if JVET_R0193 - m_vpsMaxTidIlRefPicsPlus1[i][j] = 7; -#endif - m_interLayerRefIdx[i][i] = NOT_VALID; } } diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 5721b74ebe9998f545f09bedd7bddc9ae95b1d64..a068cdfd8cc2e661e78620dd6d893630580d6492 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -938,7 +938,7 @@ private: bool m_vpsIndependentLayerFlag[MAX_VPS_LAYERS]; bool m_vpsDirectRefLayerFlag[MAX_VPS_LAYERS][MAX_VPS_LAYERS]; #if JVET_R0193 - uint32_t m_vpsMaxTidIlRefPicsPlus1[MAX_VPS_LAYERS][MAX_VPS_LAYERS]; + std::vector<std::vector<uint32_t>> m_vpsMaxTidIlRefPicsPlus1; #else uint32_t m_vpsMaxTidIlRefPicsPlus1[MAX_VPS_LAYERS]; #endif @@ -1018,6 +1018,7 @@ public: #if JVET_R0193 uint32_t getMaxTidIlRefPicsPlus1(uint32_t layerIdx, uint32_t refLayerIdx) const { return m_vpsMaxTidIlRefPicsPlus1[layerIdx][refLayerIdx]; } void setMaxTidIlRefPicsPlus1(uint32_t layerIdx, uint32_t refLayerIdx, uint32_t i) { m_vpsMaxTidIlRefPicsPlus1[layerIdx][refLayerIdx] = i; } + void setMaxTidIlRefPicsPlus1(std::vector<std::vector<uint32_t>> i) { m_vpsMaxTidIlRefPicsPlus1 = i; } #else uint32_t getMaxTidIlRefPicsPlus1(uint32_t layerIdx) const { return m_vpsMaxTidIlRefPicsPlus1[layerIdx]; } void setMaxTidIlRefPicsPlus1(uint32_t layerIdx, uint32_t i) { m_vpsMaxTidIlRefPicsPlus1[layerIdx] = i; } diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 5497d189331faf02a7af0c18cf990053e03c7c80..9cb9e2152dfc9808106aa0c7a7b43f7984e4f3fa 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2174,6 +2174,11 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) pcVPS->setEachLayerIsAnOlsFlag(0); } } +#if JVET_R0193 + std::vector<std::vector<uint32_t>> maxTidilRefPicsPlus1; + maxTidilRefPicsPlus1.resize(pcVPS->getMaxLayers(), std::vector<uint32_t>(pcVPS->getMaxLayers(), NOT_VALID)); + pcVPS->setMaxTidIlRefPicsPlus1(maxTidilRefPicsPlus1); +#endif for (uint32_t i = 0; i < pcVPS->getMaxLayers(); i++) { READ_CODE(6, uiCode, "vps_layer_id"); pcVPS->setLayerId(i, uiCode); diff --git a/source/Lib/EncoderLib/EncCfgParam.h b/source/Lib/EncoderLib/EncCfgParam.h index 418cd1a089c2b05b3c2db26847115b04af555cee..f15644b04519af6de5eb5701c9c00927c04c10fd 100644 --- a/source/Lib/EncoderLib/EncCfgParam.h +++ b/source/Lib/EncoderLib/EncCfgParam.h @@ -56,7 +56,7 @@ public: virtual ~CfgVPSParameters(){} #if JVET_R0193 - std::string m_maxTidILRefPicsPlus1Str[MAX_VPS_LAYERS]; + std::vector<std::vector<uint32_t>> m_maxTidILRefPicsPlus1; #else int m_maxTidILRefPicsPlus1; #endif diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index b1ab472beb375dace0e6b4ee2c4fe425bbeebd0d..d022dd096098d84203b1319a46d9c02a2f7db4ec 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1039,10 +1039,26 @@ void EncLib::xInitVPS( const SPS& sps ) m_vps->m_olsHrdParams.resize(m_vps->getNumOlsTimingHrdParamsMinus1(), std::vector<OlsHrdParams>(m_vps->getMaxSubLayers())); ProfileLevelTierFeatures profileLevelTierFeatures; profileLevelTierFeatures.extractPTLInformation( sps ); - +#if JVET_R0193 + m_vps->setMaxTidIlRefPicsPlus1(m_cfgVPSParameters.m_maxTidILRefPicsPlus1); + /*temp.resize(m_vps->getMaxLayers(), std::vector<uint32_t>(m_vps->getMaxLayers(), NOT_VALID)); + m_vps->getMaxTidIlRefPicsPlus1().resize(m_vps->getMaxLayers(), std::vector<uint32_t>(m_vps->getMaxLayers(), NOT_VALID)); + for (int i = 0; i < m_vps->getMaxLayers(); i++) + { + if (!m_vps->getIndependentLayerFlag(i)) + { + for (int j = 0; j < i; j++) + { + m_vps->setMaxTidIlRefPicsPlus1(i, j, m_cfgVPSParameters.m_maxTidILRefPicsPlus1[i][j]); + } + } + } + */ +#endif m_vps->deriveOutputLayerSets(); m_vps->deriveTargetOutputLayerSet( m_vps->m_targetOlsIdx ); + // number of the DPB parameters is set equal to the number of OLS containing multi layers if( !m_vps->getEachLayerIsAnOlsFlag() ) {