diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index e1d4d022692f07f5423cb9d2c0eaf093ffcb10c8..279bd7cda11ef14cf98d4571800790f5eec9a9ad 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -3366,6 +3366,24 @@ void ParameterSetMap<VPS>::setID(VPS* parameterSet, const int psId) parameterSet->setVPSId(psId); } +#if JVET_Q0814_DPB +std::unordered_map<Level::Name, TierLevelLimits> ProfileTierLevel::m_tierLevelLimits = { + { Level::Name::LEVEL1, TierLevelLimits( Level::Name::LEVEL1, 36864, std::pair<int, int>( 350, -1 ), 16, 1, 1 ) }, + { Level::Name::LEVEL2, TierLevelLimits( Level::Name::LEVEL2, 122880, std::pair<int, int>( 1500, -1 ), 16, 1, 1 ) }, + { Level::Name::LEVEL2_1, TierLevelLimits( Level::Name::LEVEL2_1, 245760, std::pair<int, int>( 3000, -1 ), 20, 1, 1 ) }, + { Level::Name::LEVEL3, TierLevelLimits( Level::Name::LEVEL3, 552960, std::pair<int, int>( 6000, -1 ), 30, 2, 2 ) }, + { Level::Name::LEVEL3_1, TierLevelLimits( Level::Name::LEVEL3_1, 983040, std::pair<int, int>( 10000, -1 ), 40, 3, 3 ) }, + { Level::Name::LEVEL4, TierLevelLimits( Level::Name::LEVEL4, 2228224, std::pair<int, int>( 12000, 30000 ), 75, 5, 5 ) }, + { Level::Name::LEVEL4_1, TierLevelLimits( Level::Name::LEVEL4_1, 2228224, std::pair<int, int>( 20000, 50000 ), 75, 5, 5 ) }, + { Level::Name::LEVEL5, TierLevelLimits( Level::Name::LEVEL5, 8912896, std::pair<int, int>( 25000, 100000 ), 200, 11, 10 ) }, + { Level::Name::LEVEL5_1, TierLevelLimits( Level::Name::LEVEL5_1, 8912896, std::pair<int, int>( 40000, 160000 ), 200, 11, 10 ) }, + { Level::Name::LEVEL5_2, TierLevelLimits( Level::Name::LEVEL5_2, 8912896, std::pair<int, int>( 60000, 240000 ), 200, 11, 10 ) }, + { Level::Name::LEVEL6, TierLevelLimits( Level::Name::LEVEL6, 35651584, std::pair<int, int>( 60000, 240000 ), 600, 22, 20 ) }, + { Level::Name::LEVEL6_1, TierLevelLimits( Level::Name::LEVEL6_1, 35651584, std::pair<int, int>( 120000, 480000 ), 600, 22, 20 ) }, + { Level::Name::LEVEL6_2, TierLevelLimits( Level::Name::LEVEL6_2, 35651584, std::pair<int, int>( 240000, 800000 ), 600, 22, 20 ) } +}; +#endif + ProfileTierLevel::ProfileTierLevel() : m_tierFlag (Level::MAIN) , m_profileIdc (Profile::NONE) @@ -3377,6 +3395,31 @@ ProfileTierLevel::ProfileTierLevel() ::memset(m_subLayerLevelIdc, Level::NONE, sizeof(m_subLayerLevelIdc )); } + +#if JVET_Q0814_DPB +uint32_t ProfileTierLevel::getMaxDpbSize( uint32_t picSizeMaxInSamplesY ) const +{ + const uint32_t maxDpbPicBuf = 8; + const uint32_t maxLumaPs = m_tierLevelLimits[m_levelIdc].maxLumaPs; + uint32_t maxDpbSize = maxDpbPicBuf; + + if( picSizeMaxInSamplesY <= ( maxLumaPs >> 2 ) ) + { + maxDpbSize = std::min<uint32_t>( 4 * maxDpbPicBuf, 16 ); + } + else if( picSizeMaxInSamplesY <= ( maxLumaPs >> 1 ) ) + { + maxDpbSize = std::min<uint32_t>( 2 * maxDpbPicBuf, 16 ); + } + else if( picSizeMaxInSamplesY <= ( ( 3 * maxLumaPs ) >> 2 ) ) + { + maxDpbSize = std::min<uint32_t>( ( 4 * maxDpbPicBuf ) / 3, 16 ); + } + + return maxDpbSize; +} +#endif + void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData) { if (!bChanged) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 6b6ceebf602e2fba995c6cedbda18c3e8d588943..6c24c8d3242aabcfcc25c40365b6e2de558c8eeb 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -446,8 +446,34 @@ public: void setNoApsConstraintFlag(bool bVal) { m_noApsConstraintFlag = bVal; } }; +#if JVET_Q0814_DPB +struct TierLevelLimits +{ + TierLevelLimits() {} + + TierLevelLimits( Level::Name _level, uint32_t _maxLumaPs, std::pair<int, int> _maxCPBsize, int _maxSlicesPerPictue, int _maxTileRows, int _maxTileColumns ) + : level( _level ) + , maxLumaPs( _maxLumaPs ) + , maxCPBsize( _maxCPBsize ) + , maxSlicesPerPictue( _maxSlicesPerPictue ) + , maxTileRows( _maxTileRows ) + , maxTileColumns( _maxTileColumns ) + { } + + Level::Name level; + uint32_t maxLumaPs; + std::pair<int, int> maxCPBsize; // main tiers, high tiers + int maxSlicesPerPictue; + int maxTileRows; + int maxTileColumns; +}; +#endif + class ProfileTierLevel { +#if JVET_Q0814_DPB + static std::unordered_map<Level::Name, TierLevelLimits> m_tierLevelLimits; +#endif Level::Tier m_tierFlag; Profile::Name m_profileIdc; uint8_t m_numSubProfile; @@ -486,6 +512,10 @@ public: Level::Name getSubLayerLevelIdc(int i) const { return m_subLayerLevelIdc[i]; } void setSubLayerLevelIdc(int i, Level::Name x) { m_subLayerLevelIdc[i] = x; } + +#if JVET_Q0814_DPB + uint32_t getMaxDpbSize( uint32_t picSizeMaxInSamplesY ) const; +#endif }; diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 7fdc71e6db44916ff34e2cdd36faccccd97a06a3..a1d4113adb3c65dffc2928dc7d41b7560dcff540 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -986,6 +986,7 @@ void EncLib::xInitVPS( const SPS& sps ) m_vps->deriveOutputLayerSets(); m_vps->deriveTargetOutputLayerSet( m_vps->m_targetOlsIdx ); + // number of the DPB parameters is set equal to the number of OLS if( !m_vps->getAllIndependentLayersFlag() ) { m_vps->m_numDpbParams = m_vps->m_totalNumOLSs; @@ -1001,8 +1002,21 @@ void EncLib::xInitVPS( const SPS& sps ) m_vps->m_dpbMaxTemporalId.resize( m_vps->m_numDpbParams ); } + for( int olsIdx = 0; olsIdx < m_vps->m_numOutputLayersInOls.size(); olsIdx++ ) + { + if( std::find( m_vps->m_layerIdInOls[olsIdx].begin(), m_vps->m_layerIdInOls[olsIdx].end(), m_layerId ) != m_vps->m_layerIdInOls[olsIdx].end() ) + { + m_vps->setOlsDpbPicWidth( olsIdx, std::max<int>( sps.getMaxPicWidthInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).width ) ); + m_vps->setOlsDpbPicHeight( olsIdx, std::max<int>( sps.getMaxPicHeightInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).height ) ); + } + + m_vps->setOlsDpbParamsIdx( olsIdx, olsIdx ); + } + for( int i = 0; i < m_vps->m_numDpbParams; i++ ) { + int olsIdx = i; + if( m_vps->getMaxSubLayers() == 1 ) { // When vps_max_sublayers_minus1 is equal to 0, the value of dpb_max_temporal_id[ i ] is inferred to be equal to 0. @@ -1021,41 +1035,24 @@ void EncLib::xInitVPS( const SPS& sps ) } } - // accumulate DPB paramters from the SPS referring by each layer, inlucded into i-th OLS - if( std::find( m_vps->m_layerIdInOls[i].begin(), m_vps->m_layerIdInOls[i].end(), m_layerId ) != m_vps->m_layerIdInOls[i].end() ) + for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? 0 : m_vps->m_dpbMaxTemporalId[i] ); j <= m_vps->m_dpbMaxTemporalId[i]; j++ ) { - for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? 0 : m_vps->m_dpbMaxTemporalId[i] ); j <= m_vps->m_dpbMaxTemporalId[i]; j++ ) - { - m_vps->m_dpbParameters[i].m_maxDecPicBuffering[j] += sps.getMaxDecPicBuffering( j ); - m_vps->m_dpbParameters[i].m_numReorderPics[j] += sps.getNumReorderPics( j ); - m_vps->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] += sps.getMaxLatencyIncreasePlus1( j ); - - CHECK( m_vps->m_dpbParameters[i].m_maxDecPicBuffering[j] >= MAX_NUM_REF_PICS, "max_dec_pic_buffering_minus1 exceeded MaxDpbSize" ); - } - - for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? m_vps->m_dpbMaxTemporalId[i] : 0 ); j < m_vps->m_dpbMaxTemporalId[i]; j++ ) - { - // When max_dec_pic_buffering_minus1[ i ] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_dec_pic_buffering_minus1[ maxSubLayersMinus1 ]. - m_vps->m_dpbParameters[i].m_maxDecPicBuffering[j] = m_vps->m_dpbParameters[i].m_maxDecPicBuffering[m_vps->m_dpbMaxTemporalId[i]]; - - // When max_num_reorder_pics[ i ] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_num_reorder_pics[ maxSubLayersMinus1 ]. - m_vps->m_dpbParameters[i].m_numReorderPics[j] = m_vps->m_dpbParameters[i].m_numReorderPics[m_vps->m_dpbMaxTemporalId[i]]; - - // When max_latency_increase_plus1[ i ] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_latency_increase_plus1[ maxSubLayersMinus1 ]. - m_vps->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] = m_vps->m_dpbParameters[i].m_maxLatencyIncreasePlus1[m_vps->m_dpbMaxTemporalId[i]]; - } + m_vps->m_dpbParameters[i].m_maxDecPicBuffering[j] = sps.getProfileTierLevel()->getMaxDpbSize( m_vps->getOlsDpbPicSize( olsIdx ).width * m_vps->getOlsDpbPicSize( olsIdx ).height ); + m_vps->m_dpbParameters[i].m_numReorderPics[j] = m_vps->m_dpbParameters[i].m_maxDecPicBuffering[j]; + m_vps->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] = 0; } - } - for( int olsIdx = 0; olsIdx < m_vps->m_numOutputLayersInOls.size(); olsIdx++ ) - { - if( std::find( m_vps->m_layerIdInOls[olsIdx].begin(), m_vps->m_layerIdInOls[olsIdx].end(), m_layerId ) != m_vps->m_layerIdInOls[olsIdx].end() ) + for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? m_vps->m_dpbMaxTemporalId[i] : 0 ); j < m_vps->m_dpbMaxTemporalId[i]; j++ ) { - m_vps->setOlsDpbPicWidth( olsIdx, std::max<int>( sps.getMaxPicWidthInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).width ) ); - m_vps->setOlsDpbPicHeight( olsIdx, std::max<int>( sps.getMaxPicHeightInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).height ) ); - } + // When max_dec_pic_buffering_minus1[ i ] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_dec_pic_buffering_minus1[ maxSubLayersMinus1 ]. + m_vps->m_dpbParameters[i].m_maxDecPicBuffering[j] = m_vps->m_dpbParameters[i].m_maxDecPicBuffering[m_vps->m_dpbMaxTemporalId[i]]; - m_vps->setOlsDpbParamsIdx( olsIdx, olsIdx ); + // When max_num_reorder_pics[ i ] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_num_reorder_pics[ maxSubLayersMinus1 ]. + m_vps->m_dpbParameters[i].m_numReorderPics[j] = m_vps->m_dpbParameters[i].m_numReorderPics[m_vps->m_dpbMaxTemporalId[i]]; + + // When max_latency_increase_plus1[ i ] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_latency_increase_plus1[ maxSubLayersMinus1 ]. + m_vps->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] = m_vps->m_dpbParameters[i].m_maxLatencyIncreasePlus1[m_vps->m_dpbMaxTemporalId[i]]; + } } } #else