From bdb945b3ef3fd11f1f79d60fdbb6364cd669010c Mon Sep 17 00:00:00 2001
From: Karl Sharman <karl.sharman@sony.com>
Date: Thu, 5 Mar 2020 10:38:05 +0000
Subject: [PATCH] Added Encoder-side DPB check

The encoder will now warn if it is likely that the decoder's DPB will be
exceeded. In addition it will display the state of the DPB (excluding
the current frame being decoded).
---
 source/App/TAppEncoder/TAppEncCfg.cpp         | 114 ++++++++++
 source/App/TAppEncoder/TAppEncCfg.h           |   3 +
 .../Lib/TLibCommon/TComProfileTierLevel.cpp   | 210 ++++++++++++++++++
 source/Lib/TLibCommon/TComProfileTierLevel.h  | 161 ++++++++++++++
 source/Lib/TLibCommon/TypeDef.h               |   2 +
 source/Lib/TLibDecoder/TDecConformance.cpp    |  36 ++-
 source/Lib/TLibDecoder/TDecConformance.h      |   7 +
 7 files changed, 532 insertions(+), 1 deletion(-)
 create mode 100644 source/Lib/TLibCommon/TComProfileTierLevel.cpp
 create mode 100644 source/Lib/TLibCommon/TComProfileTierLevel.h

diff --git a/source/App/TAppEncoder/TAppEncCfg.cpp b/source/App/TAppEncoder/TAppEncCfg.cpp
index 8d43bf51a..b28e0f23a 100644
--- a/source/App/TAppEncoder/TAppEncCfg.cpp
+++ b/source/App/TAppEncoder/TAppEncCfg.cpp
@@ -45,6 +45,9 @@
 #include <map>
 
 #include "TLibCommon/TComRom.h"
+#if DPB_ENCODER_USAGE_CHECK
+#include "TLibCommon/TComProfileTierLevel.h"
+#endif
 
 template <class T1, class T2>
 static inline std::istream& operator >> (std::istream &in, std::map<T1, T2> &map);
@@ -335,12 +338,14 @@ strToLevel[] =
   {"8.5", Level::LEVEL8_5},
 };
 
+#if !DPB_ENCODER_USAGE_CHECK
 UInt g_uiMaxCpbSize[2][21] =
 {
   //         LEVEL1,        LEVEL2,LEVEL2_1,     LEVEL3, LEVEL3_1,      LEVEL4, LEVEL4_1,       LEVEL5,  LEVEL5_1,  LEVEL5_2,    LEVEL6,  LEVEL6_1,  LEVEL6_2 
   { 0, 0, 0, 350000, 0, 0, 1500000, 3000000, 0, 6000000, 10000000, 0, 12000000, 20000000, 0,  25000000,  40000000,  60000000,  60000000, 120000000, 240000000 },
   { 0, 0, 0,      0, 0, 0,       0,       0, 0,       0,        0, 0, 30000000, 50000000, 0, 100000000, 160000000, 240000000, 240000000, 480000000, 800000000 }
 };
+#endif
 
 static const struct MapStrToCostMode
 {
@@ -2217,6 +2222,13 @@ Void TAppEncCfg::xCheckParameter()
   }
 #endif
 
+#if DPB_ENCODER_USAGE_CHECK
+  ProfileLevelTierFeatures profileLevelTierFeatures;
+  profileLevelTierFeatures.activate(m_profile, m_bitDepthConstraint, m_chromaFormatConstraint, m_intraConstraintFlag, m_onePictureOnlyConstraintFlag,
+                                    m_level, m_levelTier,
+                                    m_uiMaxCUWidth, m_internalBitDepth[CHANNEL_TYPE_LUMA], m_internalBitDepth[CHANNEL_TYPE_CHROMA], m_chromaFormatIDC);
+#endif
+
   xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA  ] < m_inputBitDepth[CHANNEL_TYPE_LUMA  ]), "MSB-extended bit depth for luma channel (--MSBExtendedBitDepth) must be greater than or equal to input bit depth for luma channel (--InputBitDepth)" );
   xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA] < m_inputBitDepth[CHANNEL_TYPE_CHROMA]), "MSB-extended bit depth for chroma channel (--MSBExtendedBitDepthC) must be greater than or equal to input bit depth for chroma channel (--InputBitDepthC)" );
 
@@ -2532,6 +2544,9 @@ Void TAppEncCfg::xCheckParameter()
       else
       {
         //create a new GOPEntry for this frame containing all the reference pictures that were available (POC > 0)
+#if DPB_ENCODER_USAGE_CHECK
+        assert(m_iGOPSize+m_extraRPSs < MAX_GOP);
+#endif
         m_GOPList[m_iGOPSize+m_extraRPSs]=m_GOPList[curGOP];
         Int newRefs=0;
         for(Int i = 0; i< m_GOPList[curGOP].m_numRefPics; i++)
@@ -2728,6 +2743,21 @@ Void TAppEncCfg::xCheckParameter()
     m_maxDecPicBuffering[MAX_TLAYER-1] = m_numReorderPics[MAX_TLAYER-1] + 1;
   }
 
+#if DPB_ENCODER_USAGE_CHECK
+  // Check DPB Usage:
+  Int dpbSize=profileLevelTierFeatures.getMaxDPBNumFrames(m_iSourceWidth*m_iSourceHeight);
+  if (dpbSize!=-1)
+  {
+    Int dpbUsage=xDPBUsage(0);
+
+    if (dpbUsage > dpbSize)
+    {
+      std::cout << "WARNING - DPB SIZE (" << dpbSize << " pictures) IS LIKELY TO HAVE BEEN EXCEEDED:\n";
+      xDPBUsage(&(std::cout));
+    }
+  }
+#endif
+
   if(m_vuiParametersPresentFlag && m_bitstreamRestrictionFlag)
   {
     Int PicSizeInSamplesY =  m_iSourceWidth * m_iSourceHeight;
@@ -2849,10 +2879,16 @@ Void TAppEncCfg::xCheckParameter()
       }
     }
     xConfirmPara( m_uiDeltaQpRD > 0, "Rate control cannot be used together with slice level multiple-QP optimization!\n" );
+#if DPB_ENCODER_USAGE_CHECK
+    if ((m_RCCpbSaturationEnabled) && profileLevelTierFeatures.getCpbSizeInBits()!=0)
+    {
+      xConfirmPara(m_RCCpbSize > profileLevelTierFeatures.getCpbSizeInBits(), "RCCpbSize should be smaller than or equal to Max CPB size according to tier and level");
+#else
     if ((m_RCCpbSaturationEnabled) && (m_level!=Level::NONE) && (m_profile!=Profile::NONE))
     {
       UInt uiLevelIdx = (m_level / 10) + (UInt)((m_level % 10) / 3);    // (m_level / 30)*3 + ((m_level % 10) / 3);
       xConfirmPara(m_RCCpbSize > g_uiMaxCpbSize[m_levelTier][uiLevelIdx], "RCCpbSize should be smaller than or equal to Max CPB size according to tier and level");
+#endif
       xConfirmPara(m_RCInitialCpbFullness > 1, "RCInitialCpbFullness should be smaller than or equal to 1");
     }
   }
@@ -2980,6 +3016,84 @@ const TChar *profileToString(const Profile::Name profile)
   return "";
 }
 
+#if DPB_ENCODER_USAGE_CHECK
+
+Int TAppEncCfg::xDPBUsage(std::ostream *pOs)
+{
+  Int minimumOffset=0;
+
+  // Calculate minimum delay caused by the gop structure - i.e. the biggest positive difference between the decoding and display order.
+
+  for(Int gopEntry=0; gopEntry<m_iGOPSize; gopEntry++)
+  {
+    Int poc=m_GOPList[gopEntry].m_POC;
+    minimumOffset=std::max<Int>(minimumOffset, gopEntry-poc);
+  }
+
+  if (pOs)
+  {
+    (*pOs) << "POCs marked with 'r' are reference frames. '!' are awaiting output.\n";
+  }
+
+  Int maxNumInDPB=0;
+  for(Int gopEntry=0; gopEntry<m_iGOPSize; gopEntry++)
+  {
+    if (pOs)
+    {
+      (*pOs) << "DPB Usage for GOP#" << std::setw(3) << gopEntry+1 << ": POC="
+             << std::setw(3) << m_GOPList[gopEntry].m_POC << " Decoder output POC=" << std::setw(4) << gopEntry-minimumOffset << " frames= ";
+      for(Int i=0; i<m_GOPList[gopEntry].m_numRefPics; i++)
+      {
+        Int rplPoc=m_GOPList[gopEntry].m_referencePics[i]+m_GOPList[gopEntry].m_POC;
+        (*pOs) << "  r" << std::setw(3) << rplPoc;
+      }
+    }
+    Int numInDPB=m_GOPList[gopEntry].m_numRefPics + 1; // 1 additional one required for the frame currently being decoded.
+    // When decoding gopEntry N, the decoder will be outputing POC N-minimumOffset, and we must make sure all POCs in the range (POC N-minimumOffset to POC N) are allocated space in the DPB.
+    // When decoding gopEntry N+minimumOffset, the decoder will be outputing POC N
+    for(Int n=gopEntry-minimumOffset; n<=gopEntry; n++)
+    {
+      // check if 'n' exists in the reference picture lists:
+      Bool bNeeded=true;
+      for(Int i=0; i<m_GOPList[gopEntry].m_numRefPics && bNeeded; i++)
+      {
+        Int rplPoc=m_GOPList[gopEntry].m_referencePics[i]+m_GOPList[gopEntry].m_POC;
+        bNeeded=(rplPoc!=n);
+      }
+      if (bNeeded && n>=0)
+      {
+        // 'n' is positive, so check that it has already been decoded within this GOP.
+        bNeeded=false;
+        for(Int i=0; i<gopEntry && !bNeeded; i++)
+        {
+          bNeeded=m_GOPList[i].m_POC == n;
+        }
+
+      }
+      if (bNeeded)
+      {
+        numInDPB++;
+        if (pOs)
+        {
+          (*pOs) << "  !" << std::setw(3)<< n;
+        }
+      }
+    }
+    maxNumInDPB=std::max(maxNumInDPB, numInDPB);
+    if (pOs)
+    {
+      (*pOs) << std::endl;
+    }
+  }
+  if (pOs)
+  {
+    (*pOs) << "Maximum number of pictures required in DPB:" << maxNumInDPB << std::endl;
+  }
+
+  return maxNumInDPB;
+}
+#endif
+
 Void TAppEncCfg::xPrintParameter()
 {
   printf("\n");
diff --git a/source/App/TAppEncoder/TAppEncCfg.h b/source/App/TAppEncoder/TAppEncCfg.h
index 95057ff31..983caca1c 100644
--- a/source/App/TAppEncoder/TAppEncCfg.h
+++ b/source/App/TAppEncoder/TAppEncCfg.h
@@ -527,6 +527,9 @@ protected:
   Void  xCheckParameter ();                                   ///< check validity of configuration values
   Void  xPrintParameter ();                                   ///< print configuration values
   Void  xPrintUsage     ();                                   ///< print usage
+#if DPB_ENCODER_USAGE_CHECK
+  Int   xDPBUsage(std::ostream *pOs);                         ///> Calculates maximum number of frames stored in DPB. Can optionally output usage to a stream
+#endif
 public:
   TAppEncCfg();
   virtual ~TAppEncCfg();
diff --git a/source/Lib/TLibCommon/TComProfileTierLevel.cpp b/source/Lib/TLibCommon/TComProfileTierLevel.cpp
new file mode 100644
index 000000000..50387ee28
--- /dev/null
+++ b/source/Lib/TLibCommon/TComProfileTierLevel.cpp
@@ -0,0 +1,210 @@
+/* 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.
+*/
+
+/** \file     TComProfileTierLevel.cpp
+    \brief    Common profile tier level functions
+*/
+
+#include "TComProfileTierLevel.h"
+#include "TLibCommon/TComSlice.h"
+//#include "TLibCommon/TComPic.h"
+//#include "TLibCommon/TComPicSym.h"
+#include <math.h>
+
+UInt
+LevelTierFeatures::getMaxPicWidthInLumaSamples()  const
+{
+  return UInt(sqrt(maxLumaPs*8.0));
+}
+
+UInt
+LevelTierFeatures::getMaxPicHeightInLumaSamples() const
+{
+  return UInt(sqrt(maxLumaPs*8.0));
+}
+
+static const UInt64 MAX_CNFUINT64 = std::numeric_limits<UInt64>::max();
+
+static const LevelTierFeatures mainLevelTierInfo[] =
+{
+    { Level::LEVEL1  ,    36864, {      350,        0 },       16,        1,        1,     552960ULL, {     128,        0 }, { 2, 2} },
+    { Level::LEVEL2  ,   122880, {     1500,        0 },       16,        1,        1,    3686400ULL, {    1500,        0 }, { 2, 2} },
+    { Level::LEVEL2_1,   245760, {     3000,        0 },       20,        1,        1,    7372800ULL, {    3000,        0 }, { 2, 2} },
+    { Level::LEVEL3  ,   552960, {     6000,        0 },       30,        2,        2,   16588800ULL, {    6000,        0 }, { 2, 2} },
+    { Level::LEVEL3_1,   983040, {    10000,        0 },       40,        3,        3,   33177600ULL, {   10000,        0 }, { 2, 2} },
+    { Level::LEVEL4  ,  2228224, {    12000,    30000 },       75,        5,        5,   66846720ULL, {   12000,    30000 }, { 4, 4} },
+    { Level::LEVEL4_1,  2228224, {    20000,    50000 },       75,        5,        5,  133693440ULL, {   20000,    50000 }, { 4, 4} },
+    { Level::LEVEL5  ,  8912896, {    25000,   100000 },      200,       11,       10,  267386880ULL, {   25000,   100000 }, { 6, 4} },
+    { Level::LEVEL5_1,  8912896, {    40000,   160000 },      200,       11,       10,  534773760ULL, {   40000,   160000 }, { 8, 4} },
+    { Level::LEVEL5_2,  8912896, {    60000,   240000 },      200,       11,       10, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
+    { Level::LEVEL6  , 35651584, {    60000,   240000 },      600,       22,       20, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
+    { Level::LEVEL6_1, 35651584, {   120000,   480000 },      600,       22,       20, 2139095040ULL, {  120000,   480000 }, { 8, 4} },
+    { Level::LEVEL6_2, 35651584, {   240000,   800000 },      600,       22,       20, 4278190080ULL, {  240000,   800000 }, { 6, 4} },
+    { Level::LEVEL8_5, MAX_UINT, { MAX_UINT, MAX_UINT }, MAX_UINT, MAX_UINT, MAX_UINT, MAX_CNFUINT64, {MAX_UINT, MAX_UINT }, { 0, 0} },
+    { Level::NONE                   }
+};
+
+static const ProfileFeatures validProfiles[] =
+{   //  profile,                   pNameString,             maxBitDepth, maxChrFmt, intra, 1pic,   lowerBR,                   RExtTools,                 ExtPrec ,                  ChrmQPOf,                  align,                     HBRFactor,   , wve+t,  tiles,, lvl8.5, cpbvcl, cpbnal, fcf*1000, mincr*10
+    { Profile::MAIN,               "Main",                            8, CHROMA_420, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1        , false, 256, 64, false,   1000,   1100,     1500,   10    , mainLevelTierInfo },
+    { Profile::MAIN10,             "Main10",                         10, CHROMA_420, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1        , false, 256, 64, false,   1000,   1100,     1875,   10    , mainLevelTierInfo },
+    { Profile::MAIN10,             "Main10 Still Picture",           10, CHROMA_420, false,  true, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1        , false, 256, 64, true ,   1000,   1100,     1875,   10    , mainLevelTierInfo },
+    { Profile::MAINSTILLPICTURE,   "Main Still Picture",              8, CHROMA_420, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1        , false, 256, 64, true ,   1000,   1100,     1500,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Monochrome",                      8, CHROMA_400, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,    667,    733,     1000,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Monochrome 12",                  12, CHROMA_400, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1000,   1100,     1500,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Monochrome 16",                  16, CHROMA_400, false, false, ProfileFeatures::ENABLED , ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1333,   1467,     2000,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 12",                        12, CHROMA_420, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1500,   1650,     2250,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:2:2 10",                  10, CHROMA_422, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1667,   1833,     2500,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:2:2 12",                  12, CHROMA_422, false, false, ProfileFeatures::ENABLED , ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   2000,   2200,     3000,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4",                      8, CHROMA_444, false, false, ProfileFeatures::ENABLED , ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   2000,   2200,     3000,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 10",                  10, CHROMA_444, false, false, ProfileFeatures::ENABLED , ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   2500,   2750,     3750,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 12",                  12, CHROMA_444, false, false, ProfileFeatures::ENABLED , ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   3000,   3300,     4500,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main Intra",                      8, CHROMA_420, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1000,   1100,     1500,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 10 Intra",                  10, CHROMA_420, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1000,   1100,     1875,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 12 Intra",                  12, CHROMA_420, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1500,   1650,     2250,   10    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:2:2 10 Intra",            10, CHROMA_422, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   1667,   1833,     2500,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:2:2 12 Intra",            12, CHROMA_422, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   2000,   2200,     3000,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 Intra",                8, CHROMA_444, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   2000,   2200,     3000,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 10 Intra",            10, CHROMA_444, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   2500,   2750,     3750,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 12 Intra",            12, CHROMA_444, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   3000,   3300,     4500,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 16 Intra",            16, CHROMA_444, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, false,   4000,   4400,     6000,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 Still Picture",        8, CHROMA_444, true , true , ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, true ,   2000,   2200,     3000,    5    , mainLevelTierInfo },
+    { Profile::MAINREXT,           "Main 4:4:4 16 Still Picture",    16, CHROMA_444, true , true , ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::DISABLED, HBR_1_OR_2   , false, 256, 64, true ,   4000,   4400,     6000,    5    , mainLevelTierInfo },
+    { Profile::HIGHTHROUGHPUTREXT, "High Throughput 4:4:4 16 Intra", 16, CHROMA_444, true , false, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::OPTIONAL, ProfileFeatures::ENABLED , HBR_12_OR_24 , true , 256, 64, false,   4000,   4400,     6000,    5    , mainLevelTierInfo },
+    { Profile::NONE, 0 }
+};
+
+
+
+
+Void
+ProfileLevelTierFeatures::activate(const TComSPS &sps)
+{
+  const ProfileTierLevel ptl=*(sps.getPTL()->getGeneralPTL());
+  activate(ptl.getProfileIdc(),
+           ptl.getBitDepthConstraint(),
+           ptl.getChromaFormatConstraint(),
+           ptl.getIntraConstraintFlag(),
+           ptl.getOnePictureOnlyConstraintFlag(),
+           ptl.getLevelIdc(),
+           ptl.getTierFlag(),
+           sps.getMaxCUWidth(),
+           sps.getBitDepth(CHANNEL_TYPE_LUMA),
+           sps.getBitDepth(CHANNEL_TYPE_CHROMA),
+           sps.getChromaFormatIdc());
+}
+
+Void
+ProfileLevelTierFeatures::activate(const Profile::Name profileIdc,
+                                   const UInt          bitDepthConstraint,
+                                   const ChromaFormat  chromaFormatConstraint,
+                                   const Bool          intraConstraintFlag,
+                                   const Bool          onePictureOnlyConstraintFlag,
+                                   const Level::Name   level,
+                                   const Level::Tier   tier,
+                                   const UInt          ctbSizeY,
+                                   const UInt          bitDepthY,
+                                   const UInt          bitDepthC,
+                                   const ChromaFormat  chFormat)
+{
+  m_tier = tier;
+
+  for(Int i=0; validProfiles[i].profile != Profile::NONE; i++)
+  {
+    if (profileIdc == validProfiles[i].profile &&
+        bitDepthConstraint == validProfiles[i].maxBitDepth &&
+        chromaFormatConstraint == validProfiles[i].maxChromaFormat &&
+        intraConstraintFlag == validProfiles[i].generalIntraConstraintFlag &&
+        onePictureOnlyConstraintFlag == validProfiles[i].generalOnePictureOnlyConstraintFlag )
+    {
+      m_pProfile = &(validProfiles[i]);
+      break;
+    }
+  }
+
+  if (m_pProfile != 0)
+  {
+    // Now identify the level:
+    const LevelTierFeatures *pLTF = m_pProfile->pLevelTiersListInfo;
+    const Level::Name spsLevelName = level;
+    if (spsLevelName!=Level::LEVEL8_5 || m_pProfile->bCanUseLevel8p5)
+    {
+      for(Int i=0; pLTF[i].level!=Level::NONE; i++)
+      {
+        if (pLTF[i].level == spsLevelName)
+        {
+          m_pLevelTier = &(pLTF[i]);
+        }
+      }
+    }
+  }
+
+  {
+    const UInt ctbWidthC  = ctbSizeY >> getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, chFormat);
+    const UInt ctbHeightC = ctbSizeY >> getChannelTypeScaleY(CHANNEL_TYPE_CHROMA, chFormat);
+
+    const UInt rawCtuBits = ctbSizeY*ctbSizeY*bitDepthY+2*(ctbWidthC*ctbHeightC)*bitDepthC;
+    m_maxRawCtuBits=(rawCtuBits*5)/3;
+  }
+
+}
+
+Int ProfileLevelTierFeatures::getMaxDPBNumFrames(const UInt PicSizeInSamplesY) // returns -1 if no limit, otherwise a limit of DPB pictures is indicated.
+{
+  Int MaxDpbSize=-1;
+
+  if (m_pLevelTier!=0)
+  {
+    UInt MaxLumaPs=m_pLevelTier->maxLumaPs;
+    Int maxDpbPicBuf=6; // SCC profiles may set this to 7.
+
+    if( PicSizeInSamplesY <= ( MaxLumaPs >> 2 ) )
+    {
+       MaxDpbSize = min( 4 * maxDpbPicBuf, 16 );
+    }
+    else if( PicSizeInSamplesY <= ( MaxLumaPs >> 1 ) )
+    {
+       MaxDpbSize = min( 2 * maxDpbPicBuf, 16 );
+    }
+    else if( PicSizeInSamplesY <= ( ( 3 * MaxLumaPs ) >> 2 ) )
+    {
+       MaxDpbSize = min( ( 4 * maxDpbPicBuf ) / 3, 16 );
+    }
+    else
+    {
+       MaxDpbSize = maxDpbPicBuf;
+    }
+  }
+  return MaxDpbSize;
+}
+
diff --git a/source/Lib/TLibCommon/TComProfileTierLevel.h b/source/Lib/TLibCommon/TComProfileTierLevel.h
new file mode 100644
index 000000000..571537812
--- /dev/null
+++ b/source/Lib/TLibCommon/TComProfileTierLevel.h
@@ -0,0 +1,161 @@
+/* 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.
+ */
+
+/** \file     TComProfileTierLevel.h
+    \brief    Common profile tier level functions (header)
+*/
+
+#ifndef __TCOMPROFILETIERLEVEL__
+#define __TCOMPROFILETIERLEVEL__
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "TLibCommon/CommonDef.h"
+#include <stdio.h>
+#include <iostream>
+
+
+// Forward declarations
+class TComSPS;
+class ProfileTierLevel;
+
+
+typedef enum HBRFACTOREQN
+{
+  HBR_1 = 0,
+  HBR_1_OR_2 = 1,
+  HBR_12_OR_24 = 2
+} HBRFACTOREQN;
+
+
+struct LevelTierFeatures
+{
+  Level::Name level;
+  UInt        maxLumaPs;
+  UInt        maxCpb[Level::NUMBER_OF_TIERS];    // in units of CpbVclFactor or CpbNalFactor bits
+  UInt        maxSliceSegmentsPerPicture;
+  UInt        maxTileRows;
+  UInt        maxTileCols;
+  UInt64      maxLumaSr;
+  UInt        maxBr[Level::NUMBER_OF_TIERS];     // in units of BrVclFactor or BrNalFactor bits/s
+  UInt        minCrBase[Level::NUMBER_OF_TIERS];
+  UInt        getMaxPicWidthInLumaSamples()  const;
+  UInt        getMaxPicHeightInLumaSamples() const;
+};
+
+
+struct ProfileFeatures
+{
+
+  typedef enum TRISTATE
+  {
+    DISABLED=0,
+    OPTIONAL=1,
+    ENABLED=2
+  } TRISTATE;
+
+  Profile::Name            profile;
+  const TChar            *pNameString;
+  UInt                     maxBitDepth;
+  ChromaFormat             maxChromaFormat;
+  Bool                     generalIntraConstraintFlag;
+  Bool                     generalOnePictureOnlyConstraintFlag;
+  TRISTATE                 generalLowerBitRateConstraint;
+  TRISTATE                 generalRExtToolsEnabled;
+  TRISTATE                 extendedPrecisionProcessingFlag;
+  TRISTATE                 chromaQpOffsetListEnabledFlag;
+  TRISTATE                 cabacBypassAlignmentEnabledFlag;
+  HBRFACTOREQN             hbrFactorEqn;
+  Bool                     bWavefrontsAndTilesCanBeUsedSimultaneously;
+
+  UInt                     minTileColumnWidthInLumaSamples;
+  UInt                     minTileRowHeightInLumaSamples;
+  Bool                     bCanUseLevel8p5;
+  UInt                     cpbVclFactor;
+  UInt                     cpbNalFactor;                // currently not used for checking
+  UInt                     formatCapabilityFactorx1000; // currently not used for checking
+  UInt                     minCrScaleFactorx10;         // currently not used for checking
+  const LevelTierFeatures *pLevelTiersListInfo;
+
+  Bool chromaFormatValid(ChromaFormat chFmt) const { return (profile == Profile::MAINREXT || profile == Profile::HIGHTHROUGHPUTREXT) ? chFmt<=maxChromaFormat : (chFmt == maxChromaFormat ); }
+  Bool onlyIRAPPictures()                    const { return generalIntraConstraintFlag; }
+  UInt getHbrFactor(Bool bLowerBitRateConstraintFlag) const    // currently not used for checking
+  {
+    return hbrFactorEqn==HBR_1_OR_2   ? (2-(bLowerBitRateConstraintFlag?1:0)) :
+          (hbrFactorEqn==HBR_12_OR_24 ? 12*(2-(bLowerBitRateConstraintFlag?1:0)) :
+                                        1);
+  }
+};
+
+
+class ProfileLevelTierFeatures
+{
+  private:
+    const ProfileFeatures   *m_pProfile;
+    const LevelTierFeatures *m_pLevelTier;
+    UInt                     m_hbrFactor;               // currently not used for checking
+    Level::Tier              m_tier;
+    UInt                     m_maxRawCtuBits;
+  public:
+    ProfileLevelTierFeatures() : m_pProfile(0), m_pLevelTier(0), m_hbrFactor(0), m_tier(Level::MAIN), m_maxRawCtuBits(0) { }
+
+    Void activate(const Profile::Name profileIdc,
+                  const UInt          bitDepthConstraint,
+                  const ChromaFormat  chromaFormatConstraint,
+                  const Bool          intraConstraintFlag,
+                  const Bool          onePictureOnlyConstraintFlag,
+                  const Level::Name   level,
+                  const Level::Tier   tier,
+                  const UInt          ctbSizeY,
+                  const UInt          bitDepthY,
+                  const UInt          bitDepthC,
+                  const ChromaFormat  chFormat);
+
+    Void activate(const TComSPS &sps);
+
+    const ProfileFeatures     *getProfileFeatures()   const { return m_pProfile; }
+    const LevelTierFeatures   *getLevelTierFeatures() const { return m_pLevelTier; }
+    Level::Tier                getTier() const { return m_tier; }
+    UInt64 getCpbSizeInBits()            const { return (m_pLevelTier!=0 && m_pProfile!=0) ? UInt64(m_pProfile->cpbVclFactor) * m_pLevelTier->maxCpb[m_tier?1:0] : UInt64(0); }
+    Double getMinCr()                    const { return (m_pLevelTier!=0 && m_pProfile!=0) ? (m_pProfile->minCrScaleFactorx10 * m_pLevelTier->minCrBase[m_tier?1:0])/10.0 : 0.0 ; }   // currently not used for checking
+    UInt   getMaxRawCtuBits()            const { return m_maxRawCtuBits; }
+    Int    getMaxDPBNumFrames(const UInt PicSizeInSamplesY); // returns -1 if no limit, otherwise a limit of DPB pictures is indicated.
+
+};
+
+
+#endif
diff --git a/source/Lib/TLibCommon/TypeDef.h b/source/Lib/TLibCommon/TypeDef.h
index 17fe3dde2..f532e65ff 100644
--- a/source/Lib/TLibCommon/TypeDef.h
+++ b/source/Lib/TLibCommon/TypeDef.h
@@ -116,6 +116,8 @@
 #define FIXSAORESETAFTERIRAP                              1 // Fix the reset mechanism for SAO after an IRAP for the case of IRAP period equal to gop size.
 #define ADD_RESET_ENCODER_DECISIONS_AFTER_IRAP            1 // Add support to reseting encoder decisions after IRAP, to enable independent/parallel coding of randomaccess configuration intra-periods.
 
+#define DPB_ENCODER_USAGE_CHECK                           1 ///< Adds DPB encoder usage check.
+
 // ====================================================================================================================
 // Tool Switches
 // ====================================================================================================================
diff --git a/source/Lib/TLibDecoder/TDecConformance.cpp b/source/Lib/TLibDecoder/TDecConformance.cpp
index b1af8093c..030ac2bf8 100644
--- a/source/Lib/TLibDecoder/TDecConformance.cpp
+++ b/source/Lib/TLibDecoder/TDecConformance.cpp
@@ -42,6 +42,7 @@
 #include "NALread.h"
 #include <math.h>
 
+#if !DPB_ENCODER_USAGE_CHECK
 UInt
 LevelTierFeatures::getMaxPicWidthInLumaSamples()  const
 {
@@ -53,6 +54,7 @@ LevelTierFeatures::getMaxPicHeightInLumaSamples() const
 {
   return UInt(sqrt(maxLumaPs*8.0));
 }
+#endif
 
 UInt
 TDecConformanceCheck::getMinLog2CtbSize(const TComPTL &ptl,
@@ -89,6 +91,7 @@ TDecConformanceCheck::TDecConformanceCheck()
 
 #if DECODER_PARTIAL_CONFORMANCE_CHECK != 0
 
+#if !DPB_ENCODER_USAGE_CHECK
 static const UInt64 MAX_CNFUINT64 = std::numeric_limits<UInt64>::max();
 
 static const LevelTierFeatures mainLevelTierInfo[] =
@@ -139,6 +142,7 @@ static const ProfileFeatures validProfiles[] =
     { Profile::HIGHTHROUGHPUTREXT, "High Throughput 4:4:4 16 Intra", 16, CHROMA_444, true , false, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL, ENABLED , HBR_12_OR_24 , true , 256, 64, false,   4000,   4400,     6000,    5    , mainLevelTierInfo },
     { Profile::NONE, 0 }
 };
+#endif
 
 
 
@@ -256,7 +260,7 @@ checkPPS(const TComSPS &sps,
   checkTiles(sps, pps, pic, features);
 }
 
-
+#if !DPB_ENCODER_USAGE_CHECK
 Void
 ProfileLevelTierFeatures::activate(const TComSPS &sps)
 {
@@ -306,6 +310,7 @@ ProfileLevelTierFeatures::activate(const TComSPS &sps)
   }
 
 }
+#endif
 
 
 static Void
@@ -313,10 +318,17 @@ checkToolAvailability(const TComSPS &sps,
                       const TComPPS &pps,
                       const ProfileLevelTierFeatures &features)
 {
+#if DPB_ENCODER_USAGE_CHECK
+  const ProfileFeatures::TRISTATE rextToolsEnabled = features.getProfileFeatures()->generalRExtToolsEnabled;
+  if ( rextToolsEnabled != ProfileFeatures::OPTIONAL)
+  {
+    const Bool bWantedFlagState = rextToolsEnabled == ProfileFeatures::ENABLED;
+#else
   const TRISTATE rextToolsEnabled = features.getProfileFeatures()->generalRExtToolsEnabled;
   if ( rextToolsEnabled != OPTIONAL)
   {
     const Bool bWantedFlagState = rextToolsEnabled == ENABLED;
+#endif
     std::string flags;
     if (sps.getSpsRangeExtension().getTransformSkipRotationEnabledFlag()      != bWantedFlagState) flags+=", transform_skip_rotation_enabled_flag";
     if (sps.getSpsRangeExtension().getTransformSkipContextEnabledFlag()       != bWantedFlagState) flags+=", transform_skip_context_enabled_flag";
@@ -324,7 +336,11 @@ checkToolAvailability(const TComSPS &sps,
     if (sps.getSpsRangeExtension().getRdpcmEnabledFlag(RDPCM_SIGNAL_EXPLICIT) != bWantedFlagState) flags+=", explicit_rdpcm_enabled_flag";
     if (sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag()            != bWantedFlagState) flags+=", intra_smoothing_disabled_flag";
     if (sps.getSpsRangeExtension().getPersistentRiceAdaptationEnabledFlag()   != bWantedFlagState) flags+=", persistent_rice_adaptation_enabled_flag";
+#if DPB_ENCODER_USAGE_CHECK
+    if (pps.getPpsRangeExtension().getLog2MaxTransformSkipBlockSize()         != 2 && rextToolsEnabled==ProfileFeatures::DISABLED ) flags+=", log2_max_transform_skip_block_size_minus2";
+#else
     if (pps.getPpsRangeExtension().getLog2MaxTransformSkipBlockSize()         != 2 && rextToolsEnabled==DISABLED ) flags+=", log2_max_transform_skip_block_size_minus2";
+#endif
 
     if (!flags.empty())
     {
@@ -337,9 +353,15 @@ checkToolAvailability(const TComSPS &sps,
     TDecConformanceCheck::checkRange<UInt>(pps.getPpsRangeExtension().getLog2MaxTransformSkipBlockSize()-2, "log2_max_transform_skip_block_size_minus2", 0, sps.getQuadtreeTULog2MaxSize()-2);
   }
 
+#if DPB_ENCODER_USAGE_CHECK
+  if (features.getProfileFeatures()->extendedPrecisionProcessingFlag != ProfileFeatures::OPTIONAL)
+  {
+    const Bool bWantedFlagState = features.getProfileFeatures()->extendedPrecisionProcessingFlag == ProfileFeatures::ENABLED;
+#else
   if (features.getProfileFeatures()->extendedPrecisionProcessingFlag != OPTIONAL)
   {
     const Bool bWantedFlagState = features.getProfileFeatures()->extendedPrecisionProcessingFlag == ENABLED;
+#endif
     if (sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() != bWantedFlagState)
     {
       TDecConformanceCheck::getStream() << "extended_precision_processing_flag must be " << (bWantedFlagState ? "1" : "0") << " in the profile '" << features.getProfileFeatures()->pNameString << "' conformance point\n";
@@ -347,9 +369,15 @@ checkToolAvailability(const TComSPS &sps,
     }
   }
 
+#if DPB_ENCODER_USAGE_CHECK
+  if (features.getProfileFeatures()->chromaQpOffsetListEnabledFlag != ProfileFeatures::OPTIONAL)
+  {
+    const Bool bWantedFlagState = features.getProfileFeatures()->chromaQpOffsetListEnabledFlag == ProfileFeatures::ENABLED;
+#else
   if (features.getProfileFeatures()->chromaQpOffsetListEnabledFlag != OPTIONAL)
   {
     const Bool bWantedFlagState = features.getProfileFeatures()->chromaQpOffsetListEnabledFlag == ENABLED;
+#endif
     if (pps.getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() != bWantedFlagState)
     {
       TDecConformanceCheck::getStream() << "chroma_qp_offset_list_enabled_flag must be " << (bWantedFlagState ? "1" : "0") << " in the profile '" << features.getProfileFeatures()->pNameString << "' conformance point\n";
@@ -361,9 +389,15 @@ checkToolAvailability(const TComSPS &sps,
     TDecConformanceCheck::checkRange<UInt>(pps.getPpsRangeExtension().getDiffCuChromaQpOffsetDepth(), "diff_cu_chroma_qp_offset_depth", 0, sps.getLog2DiffMaxMinCodingBlockSize());
   }
 
+#if DPB_ENCODER_USAGE_CHECK
+  if (features.getProfileFeatures()->cabacBypassAlignmentEnabledFlag != ProfileFeatures::OPTIONAL)
+  {
+    const Bool bWantedFlagState = features.getProfileFeatures()->cabacBypassAlignmentEnabledFlag == ProfileFeatures::ENABLED;
+#else
   if (features.getProfileFeatures()->cabacBypassAlignmentEnabledFlag != OPTIONAL)
   {
     const Bool bWantedFlagState = features.getProfileFeatures()->cabacBypassAlignmentEnabledFlag == ENABLED;
+#endif
     if (sps.getSpsRangeExtension().getCabacBypassAlignmentEnabledFlag() != bWantedFlagState)
     {
       TDecConformanceCheck::getStream() << "cabac_bypass_alignment_enabled_flag must be " << (bWantedFlagState ? "1" : "0") << " in the profile '" << features.getProfileFeatures()->pNameString << "' conformance point\n";
diff --git a/source/Lib/TLibDecoder/TDecConformance.h b/source/Lib/TLibDecoder/TDecConformance.h
index a9771d47e..e4993d59d 100644
--- a/source/Lib/TLibDecoder/TDecConformance.h
+++ b/source/Lib/TLibDecoder/TDecConformance.h
@@ -50,6 +50,9 @@
 #endif // _MSC_VER > 1000
 
 #include "TLibCommon/CommonDef.h"
+#if DPB_ENCODER_USAGE_CHECK
+#include "TLibCommon/TComProfileTierLevel.h"
+#endif
 #include <stdio.h>
 #include <iostream>
 #if DECODER_PARTIAL_CONFORMANCE_CHECK == 2
@@ -59,12 +62,15 @@
 
 // Forward declarations
 class TComSlice;
+#if !DPB_ENCODER_USAGE_CHECK
 class TComSPS;
 class TComPPS;
+#endif
 class InputNALUnit;
 class TComPTL;
 class TComPic;
 
+#if !DPB_ENCODER_USAGE_CHECK
 typedef enum TRISTATE
 {
   DISABLED=0,
@@ -153,6 +159,7 @@ class ProfileLevelTierFeatures
     Double getMinCr()                    const { return (m_pLevelTier!=0 && m_pProfile!=0) ? (m_pProfile->minCrScaleFactorx10 * m_pLevelTier->minCrBase[m_tier?1:0])/10.0 : 0.0 ; }   // currently not used for checking
     UInt getMaxRawCtuBits()              const { return m_maxRawCtuBits; }
 };
+#endif
 
 
 class TDecConformanceCheck
-- 
GitLab