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