diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index a7dd52f49d4cd47145ff3dfe94d5ed0fba710df1..c11e8fe78a8c888b5b302071341f3d18832dbfa3 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -97,7 +97,8 @@ void EncCu::create( EncCfg* encCfg )
       unsigned width  = gp_sizeIdxInfo->sizeFrom( w );
       unsigned height = gp_sizeIdxInfo->sizeFrom( h );
 
-      if( gp_sizeIdxInfo->isCuSize( width ) && gp_sizeIdxInfo->isCuSize( height ) )
+      if( gp_sizeIdxInfo->isCuSize( width ) && gp_sizeIdxInfo->isCuSize( height ) 
+        && width <= uiMaxWidth && height <= uiMaxHeight)
       {
         m_pTempCS[w][h] = new CodingStructure(m_unitPool);
         m_pBestCS[w][h] = new CodingStructure(m_unitPool);
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index fd1b407df40d901789b3b18a3330b63e2b3dcf35..74f771230cd7810dcce71dd9c851b15f9c83ac55 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -331,9 +331,10 @@ int EncModeCtrl::calculateLumaDQPsmooth(const CPelBuf& rcOrg, int baseQP, double
   return qp;
 }
 
-void CacheBlkInfoCtrl::create()
+void CacheBlkInfoCtrl::create(int maxCuSize)
 {
-  const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
+  const unsigned numPos = maxCuSize >> MIN_CU_LOG2;
+  m_maxCuSize = maxCuSize;
 
   m_numWidths  = gp_sizeIdxInfo->numWidths();
   m_numHeights = gp_sizeIdxInfo->numHeights();
@@ -348,7 +349,7 @@ void CacheBlkInfoCtrl::create()
 
       for( int wIdx = 0; wIdx < gp_sizeIdxInfo->numWidths(); wIdx++ )
       {
-        if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
+        if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= (maxCuSize >> MIN_CU_LOG2 ) ) )
         {
           m_codedCUInfo[x][y][wIdx] = nullptr;
           continue;
@@ -366,7 +367,7 @@ void CacheBlkInfoCtrl::create()
 
         for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
         {
-          if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
+          if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= (maxCuSize >> MIN_CU_LOG2 ) ) )
           {
             m_codedCUInfo[x][y][wIdx][hIdx] = nullptr;
             continue;
@@ -389,7 +390,7 @@ void CacheBlkInfoCtrl::create()
 
 void CacheBlkInfoCtrl::destroy()
 {
-  const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
+  const unsigned numPos = m_maxCuSize >> MIN_CU_LOG2;
 
   for( unsigned x = 0; x < numPos; x++ )
   {
@@ -418,7 +419,7 @@ void CacheBlkInfoCtrl::destroy()
 
 void CacheBlkInfoCtrl::init( const Slice &slice )
 {
-  const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
+  const unsigned numPos = m_maxCuSize >> MIN_CU_LOG2;
 
   for( unsigned x = 0; x < numPos; x++ )
   {
@@ -507,10 +508,11 @@ void SaveLoadEncInfoSbt::init( const Slice &slice )
   m_sliceSbt = &slice;
 }
 
-void SaveLoadEncInfoSbt::create()
+void SaveLoadEncInfoSbt::create(int maxCuSize)
 {
   int numSizeIdx = gp_sizeIdxInfo->idxFrom( SBT_MAX_SIZE ) - MIN_CU_LOG2 + 1;
-  int numPosIdx = MAX_CU_SIZE >> MIN_CU_LOG2;
+  int numPosIdx = maxCuSize >> MIN_CU_LOG2;
+  m_maxCuSize = maxCuSize;
 
   m_saveLoadSbt = new SaveLoadStructSbt***[numPosIdx];
 
@@ -531,7 +533,7 @@ void SaveLoadEncInfoSbt::create()
 void SaveLoadEncInfoSbt::destroy()
 {
   int numSizeIdx = gp_sizeIdxInfo->idxFrom( SBT_MAX_SIZE ) - MIN_CU_LOG2 + 1;
-  int numPosIdx = MAX_CU_SIZE >> MIN_CU_LOG2;
+  int numPosIdx = m_maxCuSize >> MIN_CU_LOG2;
 
   for( int xIdx = 0; xIdx < numPosIdx; xIdx++ )
   {
@@ -587,7 +589,7 @@ bool SaveLoadEncInfoSbt::saveBestSbt(const UnitArea &area, const uint32_t curPuS
 void SaveLoadEncInfoSbt::resetSaveloadSbt( int maxSbtSize )
 {
   int numSizeIdx = gp_sizeIdxInfo->idxFrom( maxSbtSize ) - MIN_CU_LOG2 + 1;
-  int numPosIdx = MAX_CU_SIZE >> MIN_CU_LOG2;
+  int numPosIdx = m_maxCuSize >> MIN_CU_LOG2;
 
   for( int xIdx = 0; xIdx < numPosIdx; xIdx++ )
   {
@@ -662,9 +664,10 @@ static bool isTheSameNbHood( const CodingUnit &cu, const CodingStructure& cs, co
   return true;
 }
 
-void BestEncInfoCache::create( const ChromaFormat chFmt )
+void BestEncInfoCache::create( const ChromaFormat chFmt, int maxCuSize)
 {
-  const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
+  const unsigned numPos = maxCuSize >> MIN_CU_LOG2;
+  m_maxCuSize = maxCuSize;
 
   m_numWidths  = gp_sizeIdxInfo->numWidths();
   m_numHeights = gp_sizeIdxInfo->numHeights();
@@ -679,7 +682,7 @@ void BestEncInfoCache::create( const ChromaFormat chFmt )
 
       for( int wIdx = 0; wIdx < gp_sizeIdxInfo->numWidths(); wIdx++ )
       {
-        if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
+        if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= (m_maxCuSize >> MIN_CU_LOG2 ) ) )
         {
           m_bestEncInfo[x][y][wIdx] = nullptr;
           continue;
@@ -697,7 +700,7 @@ void BestEncInfoCache::create( const ChromaFormat chFmt )
 
         for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
         {
-          if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
+          if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= (m_maxCuSize >> MIN_CU_LOG2 ) ) )
           {
             m_bestEncInfo[x][y][wIdx][hIdx] = nullptr;
             continue;
@@ -740,7 +743,7 @@ void BestEncInfoCache::create( const ChromaFormat chFmt )
 
 void BestEncInfoCache::destroy()
 {
-  const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
+  const unsigned numPos = m_maxCuSize >> MIN_CU_LOG2;
 
   for( unsigned x = 0; x < numPos; x++ )
   {
@@ -786,7 +789,7 @@ void BestEncInfoCache::init( const Slice &slice )
   {
     if (slice.getSliceQp() != m_sliceQp)
     {
-      const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
+      const unsigned numPos = m_maxCuSize >> MIN_CU_LOG2;
       for (unsigned x = 0; x < numPos; x++)
       {
         for (unsigned y = 0; y < numPos; y++)
@@ -811,7 +814,7 @@ void BestEncInfoCache::init( const Slice &slice )
     return;
   }
 
-  const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
+  const unsigned numPos = slice.getSPS()->getMaxCUWidth() >> MIN_CU_LOG2;
 
   m_numWidths  = gp_sizeIdxInfo->numWidths();
   m_numHeights = gp_sizeIdxInfo->numHeights();
@@ -1072,11 +1075,11 @@ void EncModeCtrlMTnoRQT::create( const EncCfg& cfg )
 #if GDR_ENABLED
   m_encCfg = cfg;
 #endif
-  CacheBlkInfoCtrl::create();
+  CacheBlkInfoCtrl::create(cfg.getCTUSize());
 #if REUSE_CU_RESULTS
-  BestEncInfoCache::create( cfg.getChromaFormatIdc() );
+  BestEncInfoCache::create( cfg.getChromaFormatIdc(), cfg.getCTUSize());
 #endif
-  SaveLoadEncInfoSbt::create();
+  SaveLoadEncInfoSbt::create(cfg.getCTUSize());
 }
 
 void EncModeCtrlMTnoRQT::destroy()
diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h
index a1106812f11b8504234da2b0cd68d367a3029995..dbd2b6a3a6de00fcacbb276444af5c8237ce04dd 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.h
+++ b/source/Lib/EncoderLib/EncModeCtrl.h
@@ -717,12 +717,13 @@ class SaveLoadEncInfoSbt
 {
 protected:
   void init( const Slice &slice );
-  void create();
+  void create(int maxCuSize);
   void destroy();
 
 private:
   SaveLoadStructSbt ****m_saveLoadSbt;
   Slice const       *m_sliceSbt;
+  int m_maxCuSize;
 
 public:
   virtual  ~SaveLoadEncInfoSbt() { }
@@ -769,10 +770,11 @@ private:
   Slice const     *m_slice_chblk;
   // x in CTU, y in CTU, width, height
   CodedCUInfo   ***m_codedCUInfo[MAX_CU_SIZE >> MIN_CU_LOG2][MAX_CU_SIZE >> MIN_CU_LOG2];
+  int m_maxCuSize;
 
 protected:
 
-  void create   ();
+  void create   (int maxCuSize);
   void destroy  ();
   void init     ( const Slice &slice );
 
@@ -823,10 +825,11 @@ private:
   PLTRunMode*         m_runType;
   XuPool              m_dummyPool;
   CodingStructure     m_dummyCS;
+  int                 m_maxCuSize;
 
 protected:
 
-  void create   ( const ChromaFormat chFmt );
+  void create   ( const ChromaFormat chFmt, int maxCuSize);
   void destroy  ();
 
   bool setFromCs( const CodingStructure& cs, const Partitioner& partitioner );
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index f07176dfaa159879b2a7597fa51c7469bfb92f3d..4f8dcc2e1f9e681bee0cc540aa6202481af1b6bb 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -102,7 +102,8 @@ void IntraSearch::destroy()
     {
       for( uint32_t height = 0; height < numHeights; height++ )
       {
-        if( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( width ) ) && gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( height ) ) )
+        if( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( width ) ) && gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( height ) ) 
+          && gp_sizeIdxInfo->sizeFrom(width) <= m_pcEncCfg->getMaxCUWidth() && gp_sizeIdxInfo->sizeFrom(height) <= m_pcEncCfg->getMaxCUHeight())
         {
           for (uint32_t layer = 0; layer < numLayersToAllocateSplit; layer++)
           {
@@ -207,12 +208,12 @@ void IntraSearch::init(EncCfg *pcEncCfg, TrQuant *pcTrQuant, RdCost *pcRdCost, C
   const ChromaFormat cform = pcEncCfg->getChromaFormatIdc();
 
   IntraPrediction::init(cform, pcEncCfg->getBitDepth(ChannelType::LUMA));
-  m_tmpStorageCtu.create(UnitArea(cform, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE)));
-  m_colorTransResiBuf.create(UnitArea(cform, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE)));
+  m_tmpStorageCtu.create(UnitArea(cform, Area(0, 0, maxCUWidth, maxCUHeight)));
+  m_colorTransResiBuf.create(UnitArea(cform, Area(0, 0, maxCUWidth, maxCUHeight)));
 
   for( uint32_t ch = 0; ch < MAX_NUM_TBLOCKS; ch++ )
   {
-    m_pSharedPredTransformSkip[ch] = new Pel[MAX_CU_SIZE * MAX_CU_SIZE];
+    m_pSharedPredTransformSkip[ch] = new Pel[maxCUWidth * maxCUHeight];
   }
 
   const uint32_t numWidths  = gp_sizeIdxInfo->numWidths();
@@ -237,7 +238,8 @@ void IntraSearch::init(EncCfg *pcEncCfg, TrQuant *pcTrQuant, RdCost *pcRdCost, C
 
     for( uint32_t height = 0; height < numHeights; height++ )
     {
-      if(  gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( width ) ) && gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( height ) ) )
+      if(  gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( width ) ) && gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( height ) ) 
+        && gp_sizeIdxInfo->sizeFrom(width) <= maxCUWidth && gp_sizeIdxInfo->sizeFrom(height) <= maxCUHeight)
       {
         m_pBestCS[width][height] = new CodingStructure(m_unitPool);
         m_pTempCS[width][height] = new CodingStructure(m_unitPool);