diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
index 98799f22ce344576a78a10319d5eede7958ca07a..9d48966856874fd4929890729b6381bc791b4ce6 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
@@ -487,9 +487,14 @@ EncAdaptiveLoopFilter::EncAdaptiveLoopFilter( int& apsIdStart )
 
 }
 
-void EncAdaptiveLoopFilter::create( const EncCfg* encCfg, const int picWidth, const int picHeight, const ChromaFormat chromaFormatIDC, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE], const int internalBitDepth[MAX_NUM_CHANNEL_TYPE] )
+void EncAdaptiveLoopFilter::create( const EncCfg* encCfg, const int picWidth, const int picHeight, const ChromaFormat chromaFormatIDC, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE], const int internalBitDepth[MAX_NUM_CHANNEL_TYPE], bool createEncData )
 {
-  AdaptiveLoopFilter::create( picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxCUDepth, inputBitDepth );
+  if( !createEncData )
+  {
+    AdaptiveLoopFilter::create( picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxCUDepth, inputBitDepth );
+    return;
+  }
+
   CHECK( encCfg == nullptr, "encCfg must not be null" );
   m_encCfg = encCfg;
 
@@ -755,12 +760,20 @@ void EncAdaptiveLoopFilter::create( const EncCfg* encCfg, const int picWidth, co
   m_chromaSampleCountNearMidPoint = new uint64_t[m_numCTUsInPic];
 }
 
-void EncAdaptiveLoopFilter::destroy()
+void EncAdaptiveLoopFilter::destroy( bool destroyEncData )
 {
   if (!m_created)
   {
     return;
   }
+
+  // !m_created guarantees common data, encoder data is guaranteed by create/destroy before/after ALFProcess
+  if (!destroyEncData)
+  {
+    AdaptiveLoopFilter::destroy();
+    return;
+  }
+
   for( int channelIdx = 0; channelIdx < MAX_NUM_CHANNEL_TYPE; channelIdx++ )
   {
     if( m_alfCovarianceFrame[channelIdx] )
@@ -1069,8 +1082,6 @@ void EncAdaptiveLoopFilter::destroy()
     delete[] m_chromaSampleCountNearMidPoint;
     m_chromaSampleCountNearMidPoint = nullptr;
   }
-
-  AdaptiveLoopFilter::destroy();
 }
 
 void EncAdaptiveLoopFilter::initCABACEstimator( CABACEncoder* cabacEncoder, CtxCache* ctxCache, Slice* pcSlice
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
index b9233ceb498875e1783b892ce531a8fd28547cc2..344b50719b169f091baa4805dc6dff13d0b2fe29 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
@@ -393,8 +393,8 @@ public:
   void getDistNewFilter( AlfParam& alfParam );
   int getNewCcAlfApsId( CodingStructure &cs, int cIdx );
   void initCABACEstimator( CABACEncoder* cabacEncoder, CtxCache* ctxCache, Slice* pcSlice, ParameterSetMap<APS>* apsMap );
-  void create( const EncCfg* encCfg, const int picWidth, const int picHeight, const ChromaFormat chromaFormatIDC, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE], const int internalBitDepth[MAX_NUM_CHANNEL_TYPE] );
-  void destroy();
+  void create( const EncCfg* encCfg, const int picWidth, const int picHeight, const ChromaFormat chromaFormatIDC, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE], const int internalBitDepth[MAX_NUM_CHANNEL_TYPE], bool createEncData = false );
+  void destroy( bool destroyEncData = false );
   void setApsIdStart( int i) { m_apsIdStart = i; }
 #if ALF_IMPROVEMENT
   static int lengthGolomb(int coeffVal, int k, bool signed_coeff = true);
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 55b708e770c0f9788c677fb3656c3c56d1e66245..27092641b5342aed92164fa92cae2ebfffd2c568 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -3499,9 +3499,11 @@ void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std:
       }
 #endif
 
-#if RPR_ENABLE
       // create SAO object based on the picture size
       if( pcSlice->getSPS()->getSAOEnabledFlag()
+#if JVET_W0066_CCSAO
+          || pcSlice->getSPS()->getCCSAOEnabledFlag()
+#endif
 #if JVET_V0094_BILATERAL_FILTER
           || pcSlice->getPPS()->getUseBIF()
 #endif
@@ -3511,20 +3513,21 @@ void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std:
           )
       {
         Size saoSize = m_pcSAO->getSaoSize();
-        if ( saoSize.width != picWidth || saoSize.height != picHeight ) {
-          const uint32_t widthInCtus = (picWidth + maxCUWidth - 1) / maxCUWidth;
-          const uint32_t heightInCtus = (picHeight + maxCUHeight - 1) / maxCUHeight;
-          const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
-          const uint32_t  log2SaoOffsetScaleLuma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - MAX_SAO_TRUNCATED_BITDEPTH);
-          const uint32_t  log2SaoOffsetScaleChroma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - MAX_SAO_TRUNCATED_BITDEPTH);
+        const uint32_t widthInCtus = (picWidth + maxCUWidth - 1) / maxCUWidth;
+        const uint32_t heightInCtus = (picHeight + maxCUHeight - 1) / maxCUHeight;
+        const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
+        const uint32_t  log2SaoOffsetScaleLuma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - MAX_SAO_TRUNCATED_BITDEPTH);
+        const uint32_t  log2SaoOffsetScaleChroma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - MAX_SAO_TRUNCATED_BITDEPTH);
 
+        m_pcSAO->destroyEncData();
+        m_pcSAO->createEncData(m_pcCfg->getSaoCtuBoundary(), numCtuInFrame);
+
+        if ( saoSize.width != picWidth || saoSize.height != picHeight ) 
+        {
           m_pcSAO->create(picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma);
-          m_pcSAO->destroyEncData();
-          m_pcSAO->createEncData(m_pcCfg->getSaoCtuBoundary(), numCtuInFrame);
           m_pcSAO->setReshaper(m_pcReshaper);
         }
       }
-#endif
 
       if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
       {
@@ -3679,6 +3682,15 @@ void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std:
       m_pcSAO->jointClipSaoBifCcSao( cs );
 #endif
 
+      if( pcSlice->getSPS()->getSAOEnabledFlag()
+#if JVET_W0066_CCSAO
+       || pcSlice->getSPS()->getCCSAOEnabledFlag()
+#endif
+        )
+      {
+        m_pcSAO->destroyEncData();
+      }
+
 #if RPR_ENABLE && !JVET_AA0095_ALF_WITH_SAMPLES_BEFORE_DBF
       // create ALF object based on the picture size
       if ( pcSlice->getSPS()->getALFEnabledFlag() )
@@ -3692,6 +3704,12 @@ void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std:
       }
 #endif
 
+      if ( pcSlice->getSPS()->getALFEnabledFlag() )
+      {
+        // create ALF object based on the picture size
+        m_pcALF->create(m_pcCfg, picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, m_pcCfg->getBitDepth(), m_pcCfg->getInputBitDepth(), true);
+      }
+
       if( pcSlice->getSPS()->getALFEnabledFlag() )
       {
         for (int s = 0; s < uiNumSliceSegments; s++)
@@ -3751,6 +3769,7 @@ void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std:
           pcPic->slices[s]->m_ccAlfFilterControl[0] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cb);
           pcPic->slices[s]->m_ccAlfFilterControl[1] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cr);
         }
+        m_pcALF->destroy(true);
       }
       DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 1 ) ) );
       if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef())
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 8e77d03cf1735ec67945ae78cb9a88985b44fc59..bf7bb134cc1d72b8628e80fb8397f4d6e60af99b 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -239,7 +239,6 @@ void EncLib::destroy ()
   {
     m_cEncALF.destroy();
   }
-  m_cEncSAO.            destroyEncData();
   m_cEncSAO.            destroy();
   m_cLoopFilter.        destroy();
   m_cRateCtrl.          destroy();
diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
index 00e812d030a4e6f73349059f015193bbbc0e0323..74df2581a152cb798c517853c2f0700e21cc72c5 100644
--- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
+++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
@@ -107,7 +107,6 @@ EncSampleAdaptiveOffset::EncSampleAdaptiveOffset()
 
 EncSampleAdaptiveOffset::~EncSampleAdaptiveOffset()
 {
-  destroyEncData();
 }
 
 void EncSampleAdaptiveOffset::createEncData(bool isPreDBFSamplesUsed, uint32_t numCTUsPic)