Index: branches/SHM-dev/source/Lib/TLibCommon/CommonDef.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/CommonDef.h	(revision 1544)
+++ branches/SHM-dev/source/Lib/TLibCommon/CommonDef.h	(revision 1545)
@@ -257,4 +257,8 @@
 static const Int LAST_SIGNIFICANT_GROUPS =                        10 ;
 
+#if W0038_DB_OPT
+static const Int MAX_ENCODER_DEBLOCKING_QUALITY_LAYERS =           8 ;
+#endif
+
 #if SVC_EXTENSION
 static const Int CGS_FILTER_LENGTH =                               13;
Index: branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1544)
+++ branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1545)
@@ -209,4 +209,6 @@
 #define V0078_ADAPTIVE_LOWER_BOUND                        1 ///< Target bits saturation with adaptive lower bound
 #endif
+#define W0038_DB_OPT                                      1 ///< adaptive DB parameter selection, LoopFilterOffsetInPPS and LoopFilterDisable are set to 0 and DeblockingFilterMetric=2;
+#define W0038_CQP_ADJ                                     1 ///< chroma QP adjustment based on TL, CQPTLAdjustEnabled is set to 1;
 
 // ====================================================================================================================
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1544)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1545)
@@ -51,4 +51,8 @@
   Int m_POC;
   Int m_QPOffset;
+#if W0038_CQP_ADJ
+  Int m_CbQPoffset;
+  Int m_CrQPoffset;
+#endif
   Double m_QPFactor;
   Int m_tcOffsetDiv2;
@@ -69,4 +73,8 @@
   : m_POC(-1)
   , m_QPOffset(0)
+#if W0038_CQP_ADJ
+  , m_CbQPoffset(0)
+  , m_CrQPoffset(0)
+#endif
   , m_QPFactor(0)
   , m_tcOffsetDiv2(0)
@@ -132,5 +140,5 @@
 
   //====== Coding Structure ========
-  UInt      m_uiIntraPeriod;
+  UInt      m_uiIntraPeriod;                    // TODO: make this an Int - it can be -1!
   UInt      m_uiDecodingRefreshType;            ///< the type of decoding refresh employed for the random access.
   Int       m_iGOPSize;
@@ -167,5 +175,9 @@
   Int       m_loopFilterBetaOffsetDiv2;
   Int       m_loopFilterTcOffsetDiv2;
+#if W0038_DB_OPT
+  Int       m_deblockingFilterMetric;
+#else
   Bool      m_DeblockingFilterMetric;
+#endif
   Bool      m_bUseSAO;
   Bool      m_bTestSAODisableAtPictureLevel;
@@ -192,4 +204,9 @@
   Int       m_chromaCbQpOffset;                 //  Chroma Cb QP Offset (0:default)
   Int       m_chromaCrQpOffset;                 //  Chroma Cr Qp Offset (0:default)
+#if W0038_CQP_ADJ
+  UInt      m_sliceChromaQpOffsetPeriodicity;                 ///< Used in conjunction with Slice Cb/Cr QpOffsetIntraOrPeriodic. Use 0 (default) to disable periodic nature.
+  Int       m_sliceChromaQpOffsetIntraOrPeriodic[2/*Cb,Cr*/]; ///< Chroma Cb QP Offset at slice level for I slice or for periodic inter slices as defined by SliceChromaQPOffsetPeriodicity. Replaces offset in the GOP table.
+#endif
+
   ChromaFormat m_chromaFormatIDC;
 
@@ -570,6 +587,9 @@
   Void      setLoopFilterBetaOffset         ( Int   i )      { m_loopFilterBetaOffsetDiv2  = i; }
   Void      setLoopFilterTcOffset           ( Int   i )      { m_loopFilterTcOffsetDiv2    = i; }
+#if W0038_DB_OPT
+  Void      setDeblockingFilterMetric       ( Int   i )      { m_deblockingFilterMetric = i; }
+#else
   Void      setDeblockingFilterMetric       ( Bool  b )      { m_DeblockingFilterMetric = b; }
-
+#endif
   //====== Motion search ========
   Void      setDisableIntraPUsInInterSlices ( Bool  b )      { m_bDisableIntraPUsInInterSlices = b; }
@@ -591,4 +611,9 @@
   Void      setChromaCbQpOffset             ( Int   i )      { m_chromaCbQpOffset = i; }
   Void      setChromaCrQpOffset             ( Int   i )      { m_chromaCrQpOffset = i; }
+#if W0038_CQP_ADJ
+  Void      setSliceChromaOffsetQpIntraOrPeriodic( UInt periodicity, Int sliceChromaQpOffsetIntraOrPeriodic[2]) { m_sliceChromaQpOffsetPeriodicity = periodicity; memcpy(m_sliceChromaQpOffsetIntraOrPeriodic, sliceChromaQpOffsetIntraOrPeriodic, sizeof(m_sliceChromaQpOffsetIntraOrPeriodic)); }
+  Int       getSliceChromaOffsetQpIntraOrPeriodic( Bool bIsCr) const                                            { return m_sliceChromaQpOffsetIntraOrPeriodic[bIsCr?1:0]; }
+  UInt      getSliceChromaOffsetQpPeriodicity() const                                                           { return m_sliceChromaQpOffsetPeriodicity; }
+#endif
 
   Void      setChromaFormatIdc              ( ChromaFormat cf ) { m_chromaFormatIDC = cf; }
@@ -649,5 +674,9 @@
   Int       getLoopFilterBetaOffset         ()      { return m_loopFilterBetaOffsetDiv2; }
   Int       getLoopFilterTcOffset           ()      { return m_loopFilterTcOffsetDiv2; }
+#if W0038_DB_OPT
+  Int       getDeblockingFilterMetric       ()      { return m_deblockingFilterMetric; }
+#else
   Bool      getDeblockingFilterMetric       ()      { return m_DeblockingFilterMetric; }
+#endif
 
   //==== Motion search ========
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1544)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1545)
@@ -105,4 +105,7 @@
   m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP;
   m_associatedIRAPPOC  = 0;
+#if W0038_DB_OPT
+  m_pcDeblockingTempPicYuv = NULL;
+#endif
 #if SVC_EXTENSION
   m_pocCraWithoutReset = 0;
@@ -156,4 +159,12 @@
 Void  TEncGOP::destroy()
 {
+#if W0038_DB_OPT
+  if (m_pcDeblockingTempPicYuv)
+  {
+    m_pcDeblockingTempPicYuv->destroy();
+    delete m_pcDeblockingTempPicYuv;
+    m_pcDeblockingTempPicYuv = NULL;
+  }
+#endif
 }
 
@@ -2491,5 +2502,16 @@
     if ( m_pcCfg->getDeblockingFilterMetric() )
     {
-      applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
+#if W0038_DB_OPT
+      if ( m_pcCfg->getDeblockingFilterMetric()==2 )
+      {
+        applyDeblockingFilterParameterSelection(pcPic, uiNumSliceSegments, iGOPid);
+      }
+      else
+      {
+#endif
+        applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
+#if W0038_DB_OPT
+      }
+#endif
     }
     m_pcLoopFilter->loopFilterPic( pcPic );
@@ -3691,4 +3713,125 @@
 }
 
+#if W0038_DB_OPT
+Void TEncGOP::applyDeblockingFilterParameterSelection( TComPic* pcPic, const UInt numSlices, const Int gopID )
+{
+  enum DBFltParam
+  {
+    DBFLT_PARAM_AVAILABLE = 0,
+    DBFLT_DISABLE_FLAG,
+    DBFLT_BETA_OFFSETD2,
+    DBFLT_TC_OFFSETD2,
+    //NUM_DBFLT_PARAMS
+  };
+  const Int MAX_BETA_OFFSET = 3;
+  const Int MIN_BETA_OFFSET = -3;
+  const Int MAX_TC_OFFSET = 3;
+  const Int MIN_TC_OFFSET = -3;
+
+  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
+  TComPicYuv* pcPicYuvOrg = pcPic ->getPicYuvOrg();
+
+  const Int currQualityLayer = (pcPic->getSlice(0)->getSliceType() != I_SLICE) ? m_pcCfg->getGOPEntry(gopID).m_temporalId+1 : 0;
+  assert(currQualityLayer <MAX_ENCODER_DEBLOCKING_QUALITY_LAYERS);
+
+  if(!m_pcDeblockingTempPicYuv)
+  {
+    m_pcDeblockingTempPicYuv         = new TComPicYuv;
+    m_pcDeblockingTempPicYuv->create( m_pcEncTop->getSourceWidth(), m_pcEncTop->getSourceHeight(), m_pcEncTop->getChromaFormatIdc(),  pcPic->getSlice(0)->getSPS()->getMaxCUWidth(), pcPic->getSlice(0)->getSPS()->getMaxCUHeight(), pcPic->getSlice(0)->getSPS()->getMaxTotalCUDepth(),true );
+    memset(m_DBParam, 0, sizeof(m_DBParam));
+  }
+
+  //preserve current reconstruction
+  pcPicYuvRec->copyToPic(m_pcDeblockingTempPicYuv);
+
+  const Bool bNoFiltering      = m_DBParam[currQualityLayer][DBFLT_PARAM_AVAILABLE] && m_DBParam[currQualityLayer][DBFLT_DISABLE_FLAG]==false /*&& pcPic->getTLayer()==0*/;
+  const Int  maxBetaOffsetDiv2 = bNoFiltering? Clip3(MIN_BETA_OFFSET, MAX_BETA_OFFSET, m_DBParam[currQualityLayer][DBFLT_BETA_OFFSETD2]+1) : MAX_BETA_OFFSET;
+  const Int  minBetaOffsetDiv2 = bNoFiltering? Clip3(MIN_BETA_OFFSET, MAX_BETA_OFFSET, m_DBParam[currQualityLayer][DBFLT_BETA_OFFSETD2]-1) : MIN_BETA_OFFSET;
+  const Int  maxTcOffsetDiv2   = bNoFiltering? Clip3(MIN_TC_OFFSET, MAX_TC_OFFSET, m_DBParam[currQualityLayer][DBFLT_TC_OFFSETD2]+2)       : MAX_TC_OFFSET;
+  const Int  minTcOffsetDiv2   = bNoFiltering? Clip3(MIN_TC_OFFSET, MAX_TC_OFFSET, m_DBParam[currQualityLayer][DBFLT_TC_OFFSETD2]-2)       : MIN_TC_OFFSET;
+
+  UInt64 distBetaPrevious      = std::numeric_limits<UInt64>::max();
+  UInt64 distMin               = std::numeric_limits<UInt64>::max();
+  Bool   bDBFilterDisabledBest = true;
+  Int    betaOffsetDiv2Best    = 0;
+  Int    tcOffsetDiv2Best      = 0;
+
+  for(Int betaOffsetDiv2=maxBetaOffsetDiv2; betaOffsetDiv2>=minBetaOffsetDiv2; betaOffsetDiv2--)
+  {
+    UInt64 distTcMin = std::numeric_limits<UInt64>::max();
+    for(Int tcOffsetDiv2=maxTcOffsetDiv2; tcOffsetDiv2 >= minTcOffsetDiv2; tcOffsetDiv2--)
+    {
+      for (Int i=0; i<numSlices; i++)
+      {
+        pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
+        pcPic->getSlice(i)->setDeblockingFilterDisable(false);
+        pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( betaOffsetDiv2 );
+        pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( tcOffsetDiv2 );
+      }
+      m_pcDeblockingTempPicYuv->copyToPic(pcPicYuvRec); // restore reconstruction
+      m_pcLoopFilter->loopFilterPic( pcPic );
+      const UInt64 dist = xFindDistortionFrame(pcPicYuvOrg, pcPicYuvRec, pcPic->getPicSym()->getSPS().getBitDepths());
+      if(dist < distMin)
+      {
+        distMin = dist;
+        bDBFilterDisabledBest = false;
+        betaOffsetDiv2Best  = betaOffsetDiv2;
+        tcOffsetDiv2Best = tcOffsetDiv2;
+      }
+      if(dist < distTcMin)
+      {
+        distTcMin = dist;
+      }
+      else if(tcOffsetDiv2 <-2)
+      {
+        break;
+      }
+    }
+    if(betaOffsetDiv2<-1 && distTcMin >= distBetaPrevious)
+    {
+      break;
+    }
+    distBetaPrevious = distTcMin;
+  }
+
+  //update:
+  m_DBParam[currQualityLayer][DBFLT_PARAM_AVAILABLE] = 1;
+  m_DBParam[currQualityLayer][DBFLT_DISABLE_FLAG]    = bDBFilterDisabledBest;
+  m_DBParam[currQualityLayer][DBFLT_BETA_OFFSETD2]   = betaOffsetDiv2Best;
+  m_DBParam[currQualityLayer][DBFLT_TC_OFFSETD2]     = tcOffsetDiv2Best;
+
+  m_pcDeblockingTempPicYuv->copyToPic(pcPicYuvRec); //restore reconstruction
+
+  if(bDBFilterDisabledBest)
+  {
+    for (Int i=0; i<numSlices; i++)
+    {
+      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
+      pcPic->getSlice(i)->setDeblockingFilterDisable(true);
+    }
+  }
+  else if(betaOffsetDiv2Best ==pcPic->getSlice(0)->getPPS()->getDeblockingFilterBetaOffsetDiv2() &&  tcOffsetDiv2Best==pcPic->getSlice(0)->getPPS()->getDeblockingFilterTcOffsetDiv2())
+  {
+    for (Int i=0; i<numSlices; i++)
+    {
+      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
+      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
+      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
+      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
+    }
+  }
+  else
+  {
+    for (Int i=0; i<numSlices; i++)
+    {
+      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
+      pcPic->getSlice(i)->setDeblockingFilterDisable( false );
+      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2(betaOffsetDiv2Best);
+      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(tcOffsetDiv2Best);
+    }
+  }
+}
+#endif
+
 #if SVC_EXTENSION
 #if N0383_IL_CONSTRAINED_TILE_SETS_SEI
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1544)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1545)
@@ -137,4 +137,8 @@
   Bool                    m_bufferingPeriodSEIPresentInAU;
   SEIEncoder              m_seiEncoder;
+#if W0038_DB_OPT
+  TComPicYuv*             m_pcDeblockingTempPicYuv;
+  Int                     m_DBParam[MAX_ENCODER_DEBLOCKING_QUALITY_LAYERS][4];   //[layer_id][0: available; 1: bDBDisabled; 2: Beta Offset Div2; 3: Tc Offset Div2;]
+#endif
 
 #if SVC_EXTENSION
@@ -270,4 +274,7 @@
 
   Void applyDeblockingFilterMetric( TComPic* pcPic, UInt uiNumSlices );
+#if W0038_DB_OPT
+  Void applyDeblockingFilterParameterSelection( TComPic* pcPic, const UInt numSlices, const Int gopID );
+#endif
 
 #if SVC_EXTENSION
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 1544)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 1545)
@@ -391,4 +391,25 @@
   const std::vector<Double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
 
+#if W0038_CQP_ADJ
+  if(rpcSlice->getPPS()->getSliceChromaQpFlag())
+  {
+    const Bool bUseIntraOrPeriodicOffset = rpcSlice->getSliceType()==I_SLICE || (m_pcCfg->getSliceChromaOffsetQpPeriodicity()!=0 && (rpcSlice->getPOC()%m_pcCfg->getSliceChromaOffsetQpPeriodicity())==0);
+    Int cbQP = bUseIntraOrPeriodicOffset? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(false) : m_pcCfg->getGOPEntry(iGOPid).m_CbQPoffset;
+    Int crQP = bUseIntraOrPeriodicOffset? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(true)  : m_pcCfg->getGOPEntry(iGOPid).m_CrQPoffset;
+
+    cbQP = Clip3( -12, 12, cbQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb); 
+    crQP = Clip3( -12, 12, crQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr); 
+    rpcSlice->setSliceChromaQpDelta(COMPONENT_Cb, Clip3( -12, 12, cbQP));
+    assert(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)>=-12);
+    rpcSlice->setSliceChromaQpDelta(COMPONENT_Cr, Clip3( -12, 12, crQP));
+    assert(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)>=-12);
+  }
+  else
+  {
+    rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
+    rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
+  }
+#endif
+
   Double lambdaModifier;
   if( rpcSlice->getSliceType( ) != I_SLICE || intraLambdaModifiers.empty())
@@ -446,6 +467,8 @@
 #endif
   rpcSlice->setSliceQpDelta      ( 0 );
+#if !W0038_CQP_ADJ
   rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
   rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
+#endif
   rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() );
   rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1544)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1545)
@@ -1269,4 +1269,22 @@
   m_cPPS.setQpOffset(COMPONENT_Cb, m_chromaCbQpOffset );
   m_cPPS.setQpOffset(COMPONENT_Cr, m_chromaCrQpOffset );
+#if W0038_CQP_ADJ
+  Bool bChromaDeltaQPEnabled = false;
+  {
+    bChromaDeltaQPEnabled = ( m_sliceChromaQpOffsetIntraOrPeriodic[0] || m_sliceChromaQpOffsetIntraOrPeriodic[1] );
+    if( !bChromaDeltaQPEnabled )
+    {
+      for( Int i=0; i<m_iGOPSize; i++ )
+      {
+        if( m_GOPList[i].m_CbQPoffset || m_GOPList[i].m_CrQPoffset )
+        {
+          bChromaDeltaQPEnabled = true;
+          break;
+        }
+      }
+    }
+  }
+  m_cPPS.setSliceChromaQpFlag(bChromaDeltaQPEnabled);
+#endif
 
   m_cPPS.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag );
