diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index a3f8e4b3f1021e855562c011dd5d3c0c36507d55..f419c4a306a13a6c47503e3766fe5a7365f174f7 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -297,6 +297,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setQuadtreeTULog2MinSize                             ( m_quadtreeTULog2MinSize );
   m_cEncLib.setQuadtreeTUMaxDepthInter                           ( m_uiQuadtreeTUMaxDepthInter );
   m_cEncLib.setQuadtreeTUMaxDepthIntra                           ( m_uiQuadtreeTUMaxDepthIntra );
+#if JVET_M0428_ENC_DB_OPT
+  m_cEncLib.setUseEncDbOpt(m_encDbOpt);
+#endif
   m_cEncLib.setUseFastLCTU                                       ( m_useFastLCTU );
   m_cEncLib.setFastInterSearchMode                               ( m_fastInterSearchMode );
   m_cEncLib.setUseEarlyCU                                        ( m_bUseEarlyCU  );
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 733a913d8590e9dea4a5fe9fd1f19aafb0d25746..d0a101fc97c548d6b5a4a0ecfe5d2ef40992f6b8 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -891,6 +891,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("WrapAroundOffset",                                m_wrapAroundOffset,                                  0u, "Offset in luma samples used for computing the horizontal wrap-around position")
 
   // ADD_NEW_TOOL : (encoder app) add parsing parameters here
+#if JVET_M0428_ENC_DB_OPT
+  ("EncDbOpt",                                        m_encDbOpt,                                       false, "Encoder optimization with deblocking filter")
+#endif
 #if JVET_M0427_INLOOP_RESHAPER
   ("LumaReshapeEnable",                               m_lumaReshapeEnable,                              false, "Enable Reshaping for Luma Channel")
   ("ReshapeSignalType",                               m_reshapeSignalType,                                 0u, "Input signal type: 0: SDR, 1:PQ, 2:HLG")
@@ -3230,6 +3233,9 @@ void EncAppCfg::xPrintParameter()
       msg(VERBOSE, "(Sigal:%s ", m_reshapeSignalType==0? "SDR" : "HDR-PQ");
       msg(VERBOSE, ") ");
     }
+#endif
+#if JVET_M0428_ENC_DB_OPT
+    msg(VERBOSE, "EncDbOpt:%d ", m_encDbOpt);
 #endif
   msg( VERBOSE, "\nFAST TOOL CFG: " );
   msg( VERBOSE, "LCTUFast:%d ", m_useFastLCTU );
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index ad9930adf8e0a0b02a1a1fbf660489b8ccdea19d..14c72592ecb99f112f263b3073d8c6545af38c6e 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -273,6 +273,9 @@ protected:
   uint32_t  m_reshapeSignalType;
   uint32_t  m_intraCMD;
   ReshapeCW m_reshapeCW;
+#endif
+#if JVET_M0428_ENC_DB_OPT
+  bool      m_encDbOpt;
 #endif
   unsigned  m_uiMaxCUWidth;                                   ///< max. CU width in pixel
   unsigned  m_uiMaxCUHeight;                                  ///< max. CU height in pixel
diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index f52f4205834c8bfafe0841b22e45451cb4462b16..bf711f3ba8f175a93ca30d842a85771171ed226a 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -751,6 +751,11 @@ void CodingStructure::initSubStructure( CodingStructure& subStruct, const Channe
 {
   CHECK( this == &subStruct, "Trying to init self as sub-structure" );
 
+#if JVET_M0428_ENC_DB_OPT
+  subStruct.useDbCost = false;
+  subStruct.costDbOffset = 0;
+#endif
+
   for( uint32_t i = 0; i < subStruct.area.blocks.size(); i++ )
   {
     CHECKD( subStruct.area.blocks[i].size() != subArea.blocks[i].size(), "Trying to init sub-structure of incompatible size" );
@@ -852,7 +857,9 @@ void CodingStructure::useSubStructure( const CodingStructure& subStruct, const C
       fracBits += subStruct.fracBits;
       dist     += subStruct.dist;
       cost     += subStruct.cost;
-
+#if JVET_M0428_ENC_DB_OPT
+      costDbOffset += subStruct.costDbOffset;
+#endif
       if( parent )
       {
         // allow this to be false at the top level
@@ -916,7 +923,9 @@ void CodingStructure::useSubStructure( const CodingStructure& subStruct, const C
   fracBits += subStruct.fracBits;
   dist     += subStruct.dist;
   cost     += subStruct.cost;
-
+#if JVET_M0428_ENC_DB_OPT
+  costDbOffset += subStruct.costDbOffset;
+#endif
   if( parent )
   {
     // allow this to be false at the top level
@@ -978,7 +987,9 @@ void CodingStructure::copyStructure( const CodingStructure& other, const Channel
   fracBits = other.fracBits;
   dist     = other.dist;
   cost     = other.cost;
-
+#if JVET_M0428_ENC_DB_OPT
+  costDbOffset = other.costDbOffset;
+#endif
   CHECKD( area != other.area, "Incompatible sizes" );
 
   const UnitArea dualITreeArea = CS::getArea( *this, this->area, chType );
@@ -1110,6 +1121,10 @@ void CodingStructure::initStructData( const int &QP, const bool &_isLosses, cons
   cost     = MAX_DOUBLE;
 #if JVET_M0102_INTRA_SUBPARTITIONS
   lumaCost = MAX_DOUBLE;
+#endif
+#if JVET_M0428_ENC_DB_OPT
+  costDbOffset = 0;
+  useDbCost = false;
 #endif
   interHad = std::numeric_limits<Distortion>::max();
 }
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index f28500a798c9a02ea29c2f58e19501540d80f94a..67ca6d94738a476430f8d78f28e61bfc22a143ce 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -179,6 +179,10 @@ public:
   static_vector<double, NUM_ENC_FEATURES> features;
 
   double      cost;
+#if JVET_M0428_ENC_DB_OPT
+  bool        useDbCost;
+  double      costDbOffset;
+#endif
 #if JVET_M0102_INTRA_SUBPARTITIONS
   double      lumaCost;
 #endif
diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp
index b3362a350a49a9171e438ec58b791a79356ab8a6..8355c91554139ec4a6a80f1a4346c56904e50c1d 100644
--- a/source/Lib/CommonLib/LoopFilter.cpp
+++ b/source/Lib/CommonLib/LoopFilter.cpp
@@ -126,7 +126,19 @@ void LoopFilter::create( const unsigned uiMaxCUDepth )
     m_aapucBS       [edgeDir].resize( numPartitions );
     m_aapbEdgeFilter[edgeDir].resize( numPartitions );
   }
+#if JVET_M0428_ENC_DB_OPT
+  m_enc = false;
+#endif
+}
+
+#if JVET_M0428_ENC_DB_OPT
+void LoopFilter::initEncPicYuvBuffer(ChromaFormat chromaFormat, int lumaWidth, int lumaHeight)
+{
+  const UnitArea picArea(chromaFormat, Area(0, 0, lumaWidth, lumaHeight));
+  m_encPicYuvBuffer.destroy();
+  m_encPicYuvBuffer.create(picArea);
 }
+#endif
 
 void LoopFilter::destroy()
 {
@@ -135,6 +147,9 @@ void LoopFilter::destroy()
     m_aapucBS       [edgeDir].clear();
     m_aapbEdgeFilter[edgeDir].clear();
   }
+#if JVET_M0428_ENC_DB_OPT
+  m_encPicYuvBuffer.destroy();
+#endif
 }
 
 /**
@@ -738,7 +753,11 @@ void LoopFilter::xEdgeFilterLuma(const CodingUnit& cu, const DeblockEdgeDir edge
   const CompArea&  lumaArea = cu.block(COMPONENT_Y);
   const PreCalcValues& pcv = *cu.cs->pcv;
 
+#if JVET_M0428_ENC_DB_OPT
+  PelBuf        picYuvRec = m_enc ? m_encPicYuvBuffer.getBuf( lumaArea ) : cu.cs->getRecoBuf( lumaArea );
+#else
   PelBuf        picYuvRec = cu.cs->getRecoBuf( lumaArea );
+#endif
   Pel           *piSrc    = picYuvRec.buf;
   const int     iStride   = picYuvRec.stride;
   Pel           *piTmpSrc = piSrc;
@@ -1010,9 +1029,13 @@ void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir ed
 
   const PreCalcValues& pcv = *cu.cs->pcv;
   unsigned  rasterIdx      = getRasterIdx( lumaPos, pcv );
-
+#if JVET_M0428_ENC_DB_OPT
+  PelBuf     picYuvRecCb = m_enc ? m_encPicYuvBuffer.getBuf(cu.block(COMPONENT_Cb)) : cu.cs->getRecoBuf(cu.block(COMPONENT_Cb));
+  PelBuf     picYuvRecCr = m_enc ? m_encPicYuvBuffer.getBuf(cu.block(COMPONENT_Cr)) : cu.cs->getRecoBuf(cu.block(COMPONENT_Cr));
+#else
   PelBuf     picYuvRecCb   = cu.cs->getRecoBuf( cu.block(COMPONENT_Cb) );
   PelBuf     picYuvRecCr   = cu.cs->getRecoBuf( cu.block(COMPONENT_Cr) );
+#endif
   Pel       *piSrcCb       = picYuvRecCb.buf;
   Pel       *piSrcCr       = picYuvRecCr.buf;
   const int  iStride       = picYuvRecCb.stride;
diff --git a/source/Lib/CommonLib/LoopFilter.h b/source/Lib/CommonLib/LoopFilter.h
index 5f2b0bafb0a13b0e004bed96061e9e07790e7529..88907e1d147c725acfe9f66793900e4f7fd5e03e 100644
--- a/source/Lib/CommonLib/LoopFilter.h
+++ b/source/Lib/CommonLib/LoopFilter.h
@@ -58,11 +58,16 @@ private:
   static_vector<char, MAX_NUM_PARTS_IN_CTU> m_aapucBS       [NUM_EDGE_DIR];         ///< Bs for [Ver/Hor][Y/U/V][Blk_Idx]
   static_vector<bool, MAX_NUM_PARTS_IN_CTU> m_aapbEdgeFilter[NUM_EDGE_DIR];
   LFCUParam m_stLFCUParam;                   ///< status structure
-
+#if JVET_M0428_ENC_DB_OPT
+  PelStorage                   m_encPicYuvBuffer;
+  bool                         m_enc;
+#endif
 private:
+#if !JVET_M0428_ENC_DB_OPT
   /// CU-level deblocking function
   void xDeblockCU                 (       CodingUnit& cu, const DeblockEdgeDir edgeDir );
-
+#endif
+  
   // set / get functions
   void xSetLoopfilterParam        ( const CodingUnit& cu );
 
@@ -111,6 +116,14 @@ public:
   LoopFilter();
   ~LoopFilter();
 
+#if JVET_M0428_ENC_DB_OPT
+  /// CU-level deblocking function
+  void xDeblockCU(CodingUnit& cu, const DeblockEdgeDir edgeDir);
+  void  initEncPicYuvBuffer(ChromaFormat chromaFormat, int lumaWidth, int lumaHeight);
+  PelStorage& getDbEncPicYuvBuffer() { return m_encPicYuvBuffer; }
+  void  setEnc(bool b) { m_enc = b; }
+#endif
+
   void  create                    ( const unsigned uiMaxCUDepth );
   void  destroy                   ();
 
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index b313f177c2e13afbcea253cf45ff6b98218425d7..d611c5ad386ee9862e17ce4155a54775712f6d94 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -54,6 +54,8 @@
 
 #define JVET_M0451_INTEROPERABILITY_POINT_SYNTAX          1 
 
+#define JVET_M0428_ENC_DB_OPT                             1 // Encoder optimization with deblocking filter
+
 #define JVET_M0055_DEBUG_CTU                              1 // DebugCTU encoder debug option
 
 #define JVET_M0297_32PT_MTS_ZERO_OUT                      1 // 32 point MTS based on skipping high frequency coefficients
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 12a54c46092c5d531f8459e13058d2960db3eb53..f63264bf2ef6082a1d275ff4be12002cb4b40712 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -288,6 +288,9 @@ protected:
   unsigned  m_reshapeSignalType;
   unsigned  m_intraCMD;
   ReshapeCW m_reshapeCW;
+#endif
+#if JVET_M0428_ENC_DB_OPT
+  bool      m_encDbOpt;
 #endif
   bool      m_useFastLCTU;
   bool      m_useFastMrg;
@@ -871,6 +874,10 @@ public:
   void      setMaxCodingDepth               ( uint32_t  u )      { m_maxTotalCUDepth = u; }
   uint32_t      getMaxCodingDepth               () const         { return m_maxTotalCUDepth; }
   void      setLog2DiffMaxMinCodingBlockSize( uint32_t  u )      { m_log2DiffMaxMinCodingBlockSize = u; }
+#if JVET_M0428_ENC_DB_OPT
+  void      setUseEncDbOpt                  ( bool  n )          { m_encDbOpt = n; }
+  bool      getUseEncDbOpt                  () const             { return m_encDbOpt; }
+#endif
 
   void      setUseFastLCTU                  ( bool  n )      { m_useFastLCTU = n; }
   bool      getUseFastLCTU                  () const         { return m_useFastLCTU; }
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 101c0cbe6706e9f99253c0354999a86c0cf6b914..6f461e435fcd5d7d694dd557f6d907786ba31105 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -318,6 +318,9 @@ void EncCu::init( EncLib* pcEncLib, const SPS& sps PARL_PARAM( const int tId ) )
   m_pcEncLib           = pcEncLib;
   m_dataId             = tId;
 #endif
+#if JVET_M0428_ENC_DB_OPT
+  m_pcLoopFilter       = pcEncLib->getLoopFilter();
+#endif
 #if JVET_M0170_MRG_SHARELIST
   m_shareState = NO_SHARE;
   m_pcInterSearch->setShareState(0);
@@ -653,6 +656,9 @@ bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS,
       std::swap( tempCS, bestCS );
       // store temp best CI for next CU coding
       m_CurrCtx->best = m_CABACEstimator->getCtx();
+#if JVET_M0428_ENC_DB_OPT
+      m_bestModeUpdated = true;
+#endif
       bestCSUpdated = true;
     }
   }
@@ -1232,7 +1238,14 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 #endif
 
   const double factor = ( tempCS->currQP[partitioner.chType] > 30 ? 1.1 : 1.075 );
+#if JVET_M0428_ENC_DB_OPT
+  tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+  if (!tempCS->useDbCost)
+    CHECK(bestCS->costDbOffset != 0, "error");
+  const double cost   = m_pcRdCost->calcRdCost( uint64_t( m_CABACEstimator->getEstFracBits() + ( ( bestCS->fracBits ) / factor ) ), Distortion( bestCS->dist / factor ) ) + bestCS->costDbOffset / factor;
+#else
   const double cost   = m_pcRdCost->calcRdCost( uint64_t( m_CABACEstimator->getEstFracBits() + ( ( bestCS->fracBits ) / factor ) ), Distortion( bestCS->dist / factor ) );
+#endif
 
   m_CABACEstimator->getCtx() = SubCtx( Ctx::SplitFlag,   ctxStartSP );
 #if JVET_M0421_SPLIT_SIG
@@ -1243,7 +1256,11 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
   m_CABACEstimator->getCtx() = SubCtx( Ctx::BTSplitFlag, ctxStartBT );
 #endif
 
+#if JVET_M0428_ENC_DB_OPT
+  if (cost > bestCS->cost + bestCS->costDbOffset)
+#else
   if( cost > bestCS->cost )
+#endif
   {
     xCheckBestMode( tempCS, bestCS, partitioner, encTestMode );
     return;
@@ -1355,6 +1372,10 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
       {
         CHECK( split == CU_QUAD_SPLIT, "Split decision reusing cannot skip quad split" );
         tempCS->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+        tempCS->costDbOffset = 0;
+        tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+#endif
         m_CurrCtx--;
         partitioner.exitCurrSplit();
         bool bestCSUpdated =
@@ -1483,9 +1504,18 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 #endif
     {
       bestCS->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+      bestCS->costDbOffset = 0;
+#endif
     }
   }
-
+#if JVET_M0428_ENC_DB_OPT
+  else
+  {
+    bestCS->costDbOffset = 0;
+  }
+  tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+#endif
 
   // RD check for sub partitioned coding structure.
   bool bestCSUpdated =
@@ -1585,6 +1615,10 @@ void EncCu::xCheckRDCostIntra( CodingStructure *&tempCS, CodingStructure *&bestC
 
     tempCS->interHad    = interHad;
 
+#if JVET_M0428_ENC_DB_OPT
+    m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
+
     if( isLuma( partitioner.chType ) )
     {
 #if JVET_M0102_INTRA_SUBPARTITIONS
@@ -1705,6 +1739,12 @@ void EncCu::xCheckRDCostIntra( CodingStructure *&tempCS, CodingStructure *&bestC
       m_modeCtrl->setBestCostWithoutSplitFlags( tmpCostWithoutSplitFlags );
     }
 #endif
+
+#if JVET_M0428_ENC_DB_OPT
+    xCalDebCost( *tempCS, partitioner );
+    tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+#endif
+
 #if !JVET_M0464_UNI_MTS
     // we save the cost of the modes for the first EMT pass
     if( !emtCuFlag ) static_cast< double& >( costSize2Nx2NemtFirstPass ) = tempCS->cost;
@@ -1804,6 +1844,11 @@ void EncCu::xCheckIntraPCM(CodingStructure *&tempCS, CodingStructure *&bestCS, P
 
   xCheckDQP( *tempCS, partitioner );
 
+#if JVET_M0428_ENC_DB_OPT
+  xCalDebCost( *tempCS, partitioner );
+  tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+#endif
+
 #if WCG_EXT
   DTRACE_MODE_COST( *tempCS, m_pcRdCost->getLambda( true ) );
 #else
@@ -1936,6 +1981,10 @@ void EncCu::xCheckRDCostHashInter( CodingStructure *&tempCS, CodingStructure *&b
     const unsigned wIdx = gp_sizeIdxInfo->idxFrom(tempCS->area.lwidth());
     double equGBiCost = MAX_DOUBLE;
 
+#if JVET_M0428_ENC_DB_OPT
+    m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
+
 #if JVET_M0464_UNI_MTS
     xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0
       , m_pImvTempCS ? m_pImvTempCS[wIdx] : NULL
@@ -1949,6 +1998,13 @@ void EncCu::xCheckRDCostHashInter( CodingStructure *&tempCS, CodingStructure *&b
       , &equGBiCost
 #endif
     );
+
+#if JVET_M0428_ENC_DB_OPT
+    if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
+    {
+      xCalDebCost( *bestCS, partitioner );
+    }
+#endif
   }
   tempCS->initStructData(encTestMode.qp, encTestMode.lossless);
 
@@ -2458,7 +2514,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
       }
     }
   }
-
+#if JVET_M0428_ENC_DB_OPT
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
 #if !JVET_M0253_HASH_ME
   const uint32_t iteration = encTestMode.lossless ? 1 : 2;
 
@@ -2669,6 +2727,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
       }
     }
   }
+#if JVET_M0428_ENC_DB_OPT
+  if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
+  {
+    xCalDebCost( *bestCS, partitioner );
+  }
+#endif
 }
 
 void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
@@ -2868,7 +2932,9 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
 
     tempCS->initStructData( encTestMode.qp, encTestMode.lossless );
   }
-
+#if JVET_M0428_ENC_DB_OPT
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
   {
 #if !JVET_M0253_HASH_ME
     const uint8_t iteration = encTestMode.lossless ? 1 : 2;
@@ -2970,6 +3036,12 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
       }// end loop mrgHADIdx
     }
   }
+#if JVET_M0428_ENC_DB_OPT
+  if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
+  {
+    xCalDebCost( *bestCS, partitioner );
+  }
+#endif
 }
 
 void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
@@ -2983,7 +3055,9 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
   {
     return;
   }
-
+#if JVET_M0428_ENC_DB_OPT
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
   const Slice &slice = *tempCS->slice;
 
   CHECK( slice.getSliceType() == I_SLICE, "Affine Merge modes not available for I-slices" );
@@ -3266,6 +3340,12 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
       }
     }
   }
+#if JVET_M0428_ENC_DB_OPT
+  if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
+  {
+    xCalDebCost( *bestCS, partitioner );
+  }
+#endif
 }
 //////////////////////////////////////////////////////////////////////////////////////////////
 // ibc merge/skip mode check
@@ -3450,6 +3530,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
         tempCS->dist = 0;
         tempCS->fracBits = 0;
         tempCS->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+        tempCS->costDbOffset = 0;
+#endif
         tempCS->initStructData(encTestMode.qp, encTestMode.lossless);
         return;
       }
@@ -3460,7 +3543,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 
 
   const unsigned int iteration = encTestMode.lossless ? 1 : 2;
-
+#if JVET_M0428_ENC_DB_OPT
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
   // 2. Pass: check candidates using full RD test
   for (unsigned int numResidualPass = 0; numResidualPass < iteration; numResidualPass++)
   {
@@ -3577,7 +3662,12 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
       }
     }
   }
-
+#if JVET_M0428_ENC_DB_OPT
+  if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
+  {
+    xCalDebCost( *bestCS, partitioner );
+  }
+#endif
 }
 
 void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode)
@@ -3589,6 +3679,10 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
 
     tempCS->initStructData(encTestMode.qp, encTestMode.lossless);
 
+#if JVET_M0428_ENC_DB_OPT
+    m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
+
     CodingUnit &cu = tempCS->addCU(CS::getArea(*tempCS, tempCS->area, partitioner.chType), partitioner.chType);
 
     partitioner.setCUData(cu);
@@ -3615,6 +3709,10 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
 
     CU::addPUs(cu);
 
+#if JVET_M0428_ENC_DB_OPT
+    m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
+
     PredictionUnit& pu = *cu.firstPU;
     cu.mmvdSkip = false;
     pu.mmvdMergeFlag = false;
@@ -3675,6 +3773,14 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
             xCheckDQP(*tempCS, partitioner);
           }
 
+#if JVET_M0428_ENC_DB_OPT
+          tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+          if ( m_bestModeUpdated )
+          {
+            xCalDebCost( *tempCS, partitioner );
+          }
+#endif
+
           DTRACE_MODE_COST(*tempCS, m_pcRdCost->getLambda());
           xCheckBestMode(tempCS, bestCS, partitioner, encTestMode);
 
@@ -3705,6 +3811,9 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
               tempCS->dist = 0;
               tempCS->fracBits = 0;
               tempCS->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+              tempCS->costDbOffset = 0;
+#endif
             }
           }
 #endif
@@ -3716,6 +3825,9 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
         tempCS->dist = 0;
         tempCS->fracBits = 0;
         tempCS->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+        tempCS->costDbOffset = 0;
+#endif
       }
     }
  // chroma CU ibc comp
@@ -3766,6 +3878,13 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
         xEncodeDontSplit(*tempCS, partitioner);
 
         xCheckDQP(*tempCS, partitioner);
+#if JVET_M0428_ENC_DB_OPT
+        tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+        if ( m_bestModeUpdated )
+        {
+          xCalDebCost( *tempCS, partitioner );
+        }
+#endif
 
         DTRACE_MODE_COST(*tempCS, m_pcRdCost->getLambda());
 
@@ -3776,6 +3895,9 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
         tempCS->dist = 0;
         tempCS->fracBits = 0;
         tempCS->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+        tempCS->costDbOffset = 0;
+#endif
       }
     }
   }
@@ -3807,6 +3929,10 @@ void EncCu::xCheckRDCostInter( CodingStructure *&tempCS, CodingStructure *&bestC
   double curBestCost = bestCS->cost;
   double equGBiCost = MAX_DOUBLE;
 
+#if JVET_M0428_ENC_DB_OPT
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
+
   for( int gbiLoopIdx = 0; gbiLoopIdx < gbiLoopNum; gbiLoopIdx++ )
   {
     if( m_pcEncCfg->getUseGBiFast() )
@@ -3911,6 +4037,12 @@ void EncCu::xCheckRDCostInter( CodingStructure *&tempCS, CodingStructure *&bestC
     break;
   }
  }  // for( UChar gbiLoopIdx = 0; gbiLoopIdx < gbiLoopNum; gbiLoopIdx++ )
+#if JVET_M0428_ENC_DB_OPT
+  if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
+  {
+    xCalDebCost( *bestCS, partitioner );
+  }
+#endif
 }
 
 
@@ -3925,6 +4057,10 @@ bool EncCu::xCheckRDCostInterIMV( CodingStructure *&tempCS, CodingStructure *&be
   CHECK( iIMV != 1 && iIMV != 2 && iIMV != 3, "Unsupported IMV Mode" );
   // Fast 4-Pel Mode
 
+#if JVET_M0428_ENC_DB_OPT
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+#endif
+
   EncTestMode encTestModeBase = encTestMode;                                        // copy for clearing non-IMV options
   encTestModeBase.opts        = EncTestModeOpts( encTestModeBase.opts & ETO_IMV );  // clear non-IMV options (is that intended?)
 
@@ -4168,6 +4304,13 @@ bool EncCu::xCheckRDCostInterIMV( CodingStructure *&tempCS, CodingStructure *&be
 #endif
  } // for( UChar gbiLoopIdx = 0; gbiLoopIdx < gbiLoopNum; gbiLoopIdx++ )
 
+#if JVET_M0428_ENC_DB_OPT
+  if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
+  {
+    xCalDebCost( *bestCS, partitioner );
+  }
+#endif
+
 #if JVET_M0246_AFFINE_AMVR
   return tempCS->slice->getSPS()->getAffineAmvrEnabledFlag() ? validMode : true;
 #else
@@ -4175,6 +4318,215 @@ bool EncCu::xCheckRDCostInterIMV( CodingStructure *&tempCS, CodingStructure *&be
 #endif
 }
 
+#if JVET_M0428_ENC_DB_OPT
+void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool calDist )
+{
+  if ( cs.cost == MAX_DOUBLE )
+  {
+    cs.costDbOffset = 0;
+  }
+
+  if ( cs.slice->getDeblockingFilterDisable() || ( !m_pcEncCfg->getUseEncDbOpt() && !calDist ) )
+  {
+    return;
+  }
+
+  m_pcLoopFilter->setEnc(true);
+  const ChromaFormat format = cs.area.chromaFormat;
+  CodingUnit*                cu = cs.getCU(partitioner.chType);
+  const Position lumaPos = cu->Y().valid() ? cu->Y().pos() : recalcPosition( format, cu->chType, CHANNEL_TYPE_LUMA, cu->blocks[cu->chType].pos() );
+  bool topEdgeAvai  = lumaPos.y > 0 && ( ( lumaPos.y % 8 ) == 0 );
+  bool leftEdgeAvai = lumaPos.x > 0 && ( ( lumaPos.x % 8 ) == 0 );
+  bool anyEdgeAvai = topEdgeAvai || leftEdgeAvai;
+  cs.costDbOffset = 0;
+
+  if ( calDist )
+  {
+    const UnitArea currCsArea = clipArea( CS::getArea( cs, cs.area, partitioner.chType ), *cs.picture );
+    ComponentID compStr = ( CS::isDualITree( cs ) && !isLuma( partitioner.chType ) ) ? COMPONENT_Cb : COMPONENT_Y;
+    ComponentID compEnd = ( CS::isDualITree( cs ) && isLuma( partitioner.chType ) ) ? COMPONENT_Y : COMPONENT_Cr;
+    Distortion finalDistortion = 0;
+    for ( int comp = compStr; comp <= compEnd; comp++ )
+    {
+      const ComponentID compID = ComponentID( comp );
+      CPelBuf org = cs.getOrgBuf( compID );
+      CPelBuf reco = cs.getRecoBuf( compID );
+      finalDistortion += getDistortionDb( cs, org, reco, compID, currCsArea.block( compID ), false );
+    }
+    //updated distortion
+    cs.dist = finalDistortion;
+  }
+
+  if ( anyEdgeAvai && m_pcEncCfg->getUseEncDbOpt() )
+  {
+    ComponentID compStr = ( CS::isDualITree( cs ) && !isLuma( partitioner.chType ) ) ? COMPONENT_Cb : COMPONENT_Y;
+    ComponentID compEnd = ( CS::isDualITree( cs ) &&  isLuma( partitioner.chType ) ) ? COMPONENT_Y : COMPONENT_Cr;
+
+    const UnitArea currCsArea = clipArea( CS::getArea( cs, cs.area, partitioner.chType ), *cs.picture );
+
+    PelStorage&          picDbBuf = m_pcLoopFilter->getDbEncPicYuvBuffer();
+
+    //deblock neighbour pixels
+    const Size     lumaSize = cu->Y().valid() ? cu->Y().size() : recalcSize( format, cu->chType, CHANNEL_TYPE_LUMA, cu->blocks[cu->chType].size() );
+
+#if  JVET_M0471_LONG_DEBLOCKING_FILTERS
+    const int verOffset = lumaPos.y > 7 ? 8 : 4;
+    const int horOffset = lumaPos.x > 7 ? 8 : 4;
+#else
+    const int verOffset = 4;
+    const int horOffset = 4;
+#endif
+    const UnitArea areaTop(  format, Area( lumaPos.x, lumaPos.y - verOffset, lumaSize.width, verOffset  ) );
+    const UnitArea areaLeft( format, Area( lumaPos.x - horOffset, lumaPos.y, horOffset, lumaSize.height ) );
+    for ( int compIdx = compStr; compIdx <= compEnd; compIdx++ )
+    {
+      ComponentID compId = (ComponentID)compIdx;
+
+      //Copy current CU's reco to Deblock Pic Buffer
+      const CompArea&  curCompArea = currCsArea.block( compId );
+      picDbBuf.getBuf( curCompArea ).copyFrom( cs.getRecoBuf( curCompArea ) );
+#if JVET_M0427_INLOOP_RESHAPER
+      if ( cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma( compId ) )
+      {
+        picDbBuf.getBuf( curCompArea ).rspSignal( m_pcReshape->getInvLUT() );
+      }
+#endif
+
+      //left neighbour
+      if ( leftEdgeAvai )
+      {
+        const CompArea&  compArea = areaLeft.block(compId);
+        picDbBuf.getBuf( compArea ).copyFrom( cs.picture->getRecoBuf( compArea ) );
+#if JVET_M0427_INLOOP_RESHAPER       
+        if ( cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma( compId ) )
+        {
+          picDbBuf.getBuf( compArea ).rspSignal( m_pcReshape->getInvLUT() );
+        }
+#endif
+      }
+      //top neighbour
+      if ( topEdgeAvai )
+      {
+        const CompArea&  compArea = areaTop.block( compId );
+        picDbBuf.getBuf( compArea ).copyFrom( cs.picture->getRecoBuf( compArea ) );
+#if JVET_M0427_INLOOP_RESHAPER
+        if ( cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma( compId ) )
+        {
+          picDbBuf.getBuf( compArea ).rspSignal( m_pcReshape->getInvLUT() );
+        }
+#endif
+      }
+    }
+
+    //deblock
+    if ( leftEdgeAvai )
+    {
+      m_pcLoopFilter->xDeblockCU( *cu, EDGE_VER );
+    }
+
+    if (topEdgeAvai)
+    {
+      m_pcLoopFilter->xDeblockCU( *cu, EDGE_HOR );
+    }
+
+    //update current CU SSE
+    Distortion distCur = 0;
+    for ( int compIdx = compStr; compIdx <= compEnd; compIdx++ )
+    {
+      ComponentID compId = (ComponentID)compIdx;
+      CPelBuf reco = picDbBuf.getBuf( currCsArea.block( compId ) );
+      CPelBuf org = cs.getOrgBuf( compId );
+      distCur += getDistortionDb( cs, org, reco, compId, currCsArea.block( compId ), true );
+    }
+
+    //calculate difference between DB_before_SSE and DB_after_SSE for neighbouring CUs
+    Distortion distBeforeDb = 0, distAfterDb = 0;
+    for (int compIdx = compStr; compIdx <= compEnd; compIdx++)
+    {
+      ComponentID compId = (ComponentID)compIdx;
+      if ( leftEdgeAvai )
+      {
+        const CompArea&  compArea = areaLeft.block( compId );
+        CPelBuf org = cs.picture->getOrigBuf( compArea );
+        CPelBuf reco = cs.picture->getRecoBuf( compArea );
+        CPelBuf recoDb = picDbBuf.getBuf( compArea );
+        distBeforeDb += getDistortionDb( cs, org, reco,   compId, compArea, false );
+        distAfterDb  += getDistortionDb( cs, org, recoDb, compId, compArea, true  );
+      }
+      if ( topEdgeAvai )
+      {
+        const CompArea&  compArea = areaTop.block( compId );
+        CPelBuf org = cs.picture->getOrigBuf( compArea );
+        CPelBuf reco = cs.picture->getRecoBuf( compArea );
+        CPelBuf recoDb = picDbBuf.getBuf( compArea );
+        distBeforeDb += getDistortionDb( cs, org, reco,   compId, compArea, false );
+        distAfterDb  += getDistortionDb( cs, org, recoDb, compId, compArea, true  );
+      }
+    }
+
+    //updated cost
+    int64_t distTmp = distCur - cs.dist + distAfterDb - distBeforeDb;
+    int sign = distTmp < 0 ? -1 : 1;
+    distTmp = distTmp < 0 ? -distTmp : distTmp;
+    cs.costDbOffset = sign * m_pcRdCost->calcRdCost( 0, distTmp );
+  }
+
+  m_pcLoopFilter->setEnc( false );
+}
+
+Distortion EncCu::getDistortionDb( CodingStructure &cs, CPelBuf org, CPelBuf reco, ComponentID compID, const CompArea& compArea, bool afterDb )
+{
+  Distortion dist = 0;
+#if WCG_EXT
+  CPelBuf orgLuma = cs.picture->getOrigBuf( compArea );
+#if JVET_M0427_INLOOP_RESHAPER
+  if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
+    m_pcEncCfg->getReshaper() && ( cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag() ) ) )
+#else
+  if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
+#endif
+  {
+#if JVET_M0427_INLOOP_RESHAPER
+    if ( compID == COMPONENT_Y && !afterDb )
+    {
+      CompArea    tmpArea( COMPONENT_Y, cs.area.chromaFormat, Position( 0, 0 ), compArea.size() );
+      PelBuf tmpRecLuma = m_tmpStorageLCU->getBuf( tmpArea );
+      tmpRecLuma.copyFrom( reco );
+      tmpRecLuma.rspSignal( m_pcReshape->getInvLUT() );
+      dist += m_pcRdCost->getDistPart( org, tmpRecLuma, cs.sps->getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma );
+    }
+    else
+#endif
+    {
+      dist += m_pcRdCost->getDistPart( org, reco, cs.sps->getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma );
+    }
+  }
+#if JVET_M0427_INLOOP_RESHAPER
+  else if ( m_pcEncCfg->getReshaper() && cs.slice->getReshapeInfo().getUseSliceReshaper() && cs.slice->isIntra() ) //intra slice
+  {
+    if ( compID == COMPONENT_Y && afterDb )
+    {
+      CompArea    tmpArea( COMPONENT_Y, cs.area.chromaFormat, Position( 0, 0 ), compArea.size() );
+      PelBuf tmpRecLuma = m_tmpStorageLCU->getBuf( tmpArea );
+      tmpRecLuma.copyFrom( reco );
+      tmpRecLuma.rspSignal( m_pcReshape->getFwdLUT() );
+      dist += m_pcRdCost->getDistPart( org, tmpRecLuma, cs.sps->getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
+    }
+    else
+    {
+      dist += m_pcRdCost->getDistPart( org, reco, cs.sps->getBitDepth(toChannelType( compID ) ), compID, DF_SSE );
+    }
+  }
+#endif
+  else
+#endif
+  {
+    dist = m_pcRdCost->getDistPart( org, reco, cs.sps->getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
+  }
+  return dist;
+}
+#endif
+
 #if JVET_M0464_UNI_MTS
 void EncCu::xEncodeInterResidual(   CodingStructure *&tempCS
                                   , CodingStructure *&bestCS
@@ -4331,6 +4683,9 @@ void EncCu::xEncodeInterResidual( CodingStructure *&tempCS, CodingStructure *&be
       tempCS->dist     = 0;
       tempCS->fracBits = 0;
       tempCS->cost     = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+      tempCS->costDbOffset = 0;
+#endif
     }
 
     reloadCU    = true; // enable cu reloading
@@ -4414,6 +4769,9 @@ void EncCu::xEncodeInterResidual( CodingStructure *&tempCS, CodingStructure *&be
       if (tempCS->getPU(partitioner.chType)->mhIntraFlag)
       {
         tempCS->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+        tempCS->costDbOffset = 0;
+#endif
         return;
       }
     }
@@ -4715,8 +5073,6 @@ void EncCu::xEncodeDontSplit( CodingStructure &cs, Partitioner &partitioner )
 #if REUSE_CU_RESULTS
 void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner )
 {
-  const SPS &sps = *tempCS->sps;
-
   BestEncInfoCache* bestEncCache = dynamic_cast<BestEncInfoCache*>( m_modeCtrl );
   CHECK( !bestEncCache, "If this mode is chosen, mode controller has to implement the mode caching capabilities" );
   EncTestMode cachedMode;
@@ -4740,6 +5096,11 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best
       xReconInter( cu );
     }
 
+#if JVET_M0428_ENC_DB_OPT
+    tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+    xCalDebCost( *tempCS, partitioner, true );
+#else
+    const SPS &sps = *tempCS->sps;
     Distortion finalDistortion = 0;
     const int  numValidComponents = getNumberValidComponents( tempCS->area.chromaFormat );
 
@@ -4782,6 +5143,7 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best
 #endif
       finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
     }
+#endif
 
     m_CABACEstimator->getCtx() = m_CurrCtx->start;
     m_CABACEstimator->resetBits();
@@ -4791,7 +5153,9 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best
     cuCtx.isChromaQpAdjCoded = true;
     m_CABACEstimator->coding_unit( cu, partitioner, cuCtx );
 
+#if JVET_M0428_ENC_DB_OPT == 0
     tempCS->dist     = finalDistortion;
+#endif
     tempCS->fracBits = m_CABACEstimator->getEstFracBits();
     tempCS->cost     = m_pcRdCost->calcRdCost( tempCS->fracBits, tempCS->dist );
 
@@ -4804,7 +5168,6 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best
     THROW( "Should never happen!" );
   }
 }
-
 #endif
 
 
diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h
index 21286871bb0c19299efbb04b73eb1ca1a768c789..31921823e27bda64cb7e5dd0ceba9277e8fc7c08 100644
--- a/source/Lib/EncoderLib/EncCu.h
+++ b/source/Lib/EncoderLib/EncCu.h
@@ -46,6 +46,9 @@
 #include "CommonLib/Unit.h"
 #include "CommonLib/UnitPartitioner.h"
 #include "CommonLib/IbcHashMap.h"
+#if JVET_M0428_ENC_DB_OPT
+#include "CommonLib/LoopFilter.h"
+#endif
 
 #if REUSE_CU_RESULTS || JVET_M0170_MRG_SHARELIST || JVET_M0427_INLOOP_RESHAPER
 #include "DecoderLib/DecCu.h"
@@ -84,7 +87,9 @@ class EncCu
 #endif
 {
 private:
-
+#if JVET_M0428_ENC_DB_OPT
+  bool m_bestModeUpdated;
+#endif
   struct CtxPair
   {
     Ctx start;
@@ -116,6 +121,9 @@ private:
   TrQuant*              m_pcTrQuant;
   RdCost*               m_pcRdCost;
   EncSlice*             m_pcSliceEncoder;
+#if JVET_M0428_ENC_DB_OPT
+  LoopFilter*           m_pcLoopFilter;
+#endif
 
   CABACWriter*          m_CABACEstimator;
   RateCtrl*             m_pcRateCtrl;
@@ -191,6 +199,11 @@ public:
 
 protected:
 
+#if JVET_M0428_ENC_DB_OPT
+  void xCalDebCost            ( CodingStructure &cs, Partitioner &partitioner, bool calDist = false );
+  Distortion getDistortionDb  ( CodingStructure &cs, CPelBuf org, CPelBuf reco, ComponentID compID, const CompArea& compArea, bool afterDb );
+#endif
+
   void xCompressCU            ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm
     , LutMotionCand *&tempMotCandLUTs
     , LutMotionCand *&bestMotCandLUTs
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index e6a11e25e7f39767d88eea7e772209f7263d729d..c975d68d8e9c510d259ed15273a0adfaa4dcb8b6 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -130,7 +130,12 @@ void EncLib::create ()
   }
 
   m_cLoopFilter.create( m_maxTotalCUDepth );
-
+#if JVET_M0428_ENC_DB_OPT
+  if ( !m_bLoopFilterDisable )
+  {
+    m_cLoopFilter.initEncPicYuvBuffer( m_chromaFormatIDC, getSourceWidth(), getSourceHeight() );
+  }
+#endif
   if( m_alf )
   {
     m_cEncALF.create( getSourceWidth(), getSourceHeight(), m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, m_bitDepth, m_inputBitDepth );
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index d95114f9ed816b2895ec4971a27e07b5e4e89d5b..2421dbdb4f6eb4426fb28b50bd23378da97a5688 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -1964,7 +1964,11 @@ bool EncModeCtrlMTnoRQT::useModeResult( const EncTestMode& encTestmode, CodingSt
   }
 
   // for now just a simple decision based on RD-cost or choose tempCS if bestCS is not yet coded
+#if JVET_M0428_ENC_DB_OPT
+  if( !cuECtx.bestCS || ( ( tempCS->features[ENC_FT_RD_COST] + ( tempCS->useDbCost ? tempCS->costDbOffset : 0 ) ) < ( cuECtx.bestCS->features[ENC_FT_RD_COST] + ( tempCS->useDbCost ? cuECtx.bestCS->costDbOffset : 0 ) ) ) )
+#else
   if( !cuECtx.bestCS || tempCS->features[ENC_FT_RD_COST] < cuECtx.bestCS->features[ENC_FT_RD_COST] )
+#endif
   {
     cuECtx.bestCS = tempCS;
     cuECtx.bestCU = tempCS->cus[0];
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index d4cab58f9f0efe39e92d5b59fcee262e28b6c893..690cc1cc4879a5df41e0be903c8193e98a24843f 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -900,6 +900,9 @@ void IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner )
       if( cu.ispMode && !csTemp->cus[0]->firstTU->cbf[COMPONENT_Y] )
       {
         csTemp->cost = MAX_DOUBLE;
+#if JVET_M0428_ENC_DB_OPT
+        csTemp->costDbOffset = 0;
+#endif
       }
 #else
       xRecurIntraCodingLumaQT( *csTemp, partitioner );