Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1368)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1369)
@@ -224,4 +224,5 @@
   Int*      m_aidQP;
   UInt      m_uiDeltaQpRD;
+  Bool      m_bFastDeltaQP;
 
   Bool      m_bUseConstrainedIntraPred;
@@ -663,4 +664,5 @@
   Void      setdQPs                         ( Int*  p )     { m_aidQP       = p; }
   Void      setDeltaQpRD                    ( UInt  u )     {m_uiDeltaQpRD  = u; }
+  Void      setFastDeltaQp                  ( Bool  b )     {m_bFastDeltaQP = b; }
   Bool      getUseASR                       ()      { return m_bUseASR;     }
   Bool      getUseHADME                     ()      { return m_bUseHADME;   }
@@ -711,6 +713,7 @@
   Void setIntraSmoothingDisabledFlag               (Bool bValue) { m_intraSmoothingDisabledFlag=bValue; }
 
-  Int*      getdQPs                         ()      { return m_aidQP;       }
-  UInt      getDeltaQpRD                    ()      { return m_uiDeltaQpRD; }
+  Int*      getdQPs                         ()       { return m_aidQP;       }
+  UInt      getDeltaQpRD                    () const { return m_uiDeltaQpRD; }
+  Bool      getFastDeltaQp                  () const { return m_bFastDeltaQP; }
 
   //====== Slice ========
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncCu.cpp	(revision 1368)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncCu.cpp	(revision 1369)
@@ -100,4 +100,5 @@
   m_stillToCodeChromaQpOffsetFlag  = false;
   m_cuChromaQpOffsetIdxPlus1       = 0;
+  m_bFastDeltaQP                   = false;
 
   // initialize partition order.
@@ -365,7 +366,7 @@
 */
 #if AMP_ENC_SPEEDUP
-Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth DEBUG_STRING_FN_DECLARE(sDebug_), PartSize eParentPartSize )
-#else
-Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth )
+Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const UInt uiDepth DEBUG_STRING_FN_DECLARE(sDebug_), PartSize eParentPartSize )
+#else
+Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const UInt uiDepth )
 #endif
 {
@@ -374,10 +375,10 @@
   const TComPPS &pps=*(rpcTempCU->getSlice()->getPPS());
   const TComSPS &sps=*(rpcTempCU->getSlice()->getSPS());
+  
+  // These are only used if getFastDeltaQp() is true
+  const UInt fastDeltaQPCuMaxSize    = Clip3(sps.getMaxCUHeight()>>sps.getLog2DiffMaxMinCodingBlockSize(), sps.getMaxCUHeight(), 32u);
 
   // get Original YUV data from picture
   m_ppcOrigYuv[uiDepth]->copyFromPicYuv( pcPic->getPicYuvOrg(), rpcBestCU->getCtuRsAddr(), rpcBestCU->getZorderIdxInCtu() );
-
-    // variable for Early CU determination
-  Bool    bSubBranch = true;
 
   // variable for Cbf fast mode PU decision
@@ -385,9 +386,9 @@
   Bool    earlyDetectionSkipMode = false;
 
-  Bool bBoundary = false;
-  UInt uiLPelX   = rpcBestCU->getCUPelX();
-  UInt uiRPelX   = uiLPelX + rpcBestCU->getWidth(0)  - 1;
-  UInt uiTPelY   = rpcBestCU->getCUPelY();
-  UInt uiBPelY   = uiTPelY + rpcBestCU->getHeight(0) - 1;
+  const UInt uiLPelX   = rpcBestCU->getCUPelX();
+  const UInt uiRPelX   = uiLPelX + rpcBestCU->getWidth(0)  - 1;
+  const UInt uiTPelY   = rpcBestCU->getCUPelY();
+  const UInt uiBPelY   = uiTPelY + rpcBestCU->getHeight(0) - 1;
+  const UInt uiWidth   = rpcBestCU->getWidth(0);
 
   Int iBaseQP = xComputeQP( rpcBestCU, uiDepth );
@@ -436,12 +437,11 @@
 
   TComSlice * pcSlice = rpcTempCU->getPic()->getSlice(rpcTempCU->getPic()->getCurrSliceIdx());
-  // We need to split, so don't try these modes.
 #if SVC_EXTENSION
-  if ( ( uiRPelX < rpcBestCU->getSlice()->getPicWidthInLumaSamples() ) &&
-       ( uiBPelY < rpcBestCU->getSlice()->getPicHeightInLumaSamples() ) )
-#else
-  if ( ( uiRPelX < sps.getPicWidthInLumaSamples() ) &&
-       ( uiBPelY < sps.getPicHeightInLumaSamples() ) )
-#endif
+  const Bool bBoundary = !( uiRPelX < rpcBestCU->getSlice()->getPicWidthInLumaSamples() && uiBPelY < rpcBestCU->getSlice()->getPicHeightInLumaSamples() );
+#else
+  const Bool bBoundary = !( uiRPelX < sps.getPicWidthInLumaSamples() && uiBPelY < sps.getPicHeightInLumaSamples() );
+#endif
+
+  if ( !bBoundary )
   {
 #if HIGHER_LAYER_IRAP_SKIP_FLAG
@@ -774,32 +774,22 @@
     }
 
-    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]);
-    m_pcEntropyCoder->resetBits();
-    m_pcEntropyCoder->encodeSplitFlag( rpcBestCU, 0, uiDepth, true );
-    rpcBestCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
-    rpcBestCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
-    rpcBestCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcBestCU->getTotalBits(), rpcBestCU->getTotalDistortion() );
-    m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]);
-
-    // Early CU determination
-    if( m_pcEncCfg->getUseEarlyCU() && rpcBestCU->isSkipped(0) )
-    {
-      bSubBranch = false;
-    }
-    else
-    {
-      bSubBranch = true;
-    }
+    if( rpcBestCU->getTotalCost()!=MAX_DOUBLE )
+    {
+      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]);
+      m_pcEntropyCoder->resetBits();
+      m_pcEntropyCoder->encodeSplitFlag( rpcBestCU, 0, uiDepth, true );
+      rpcBestCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
+      rpcBestCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
+      rpcBestCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcBestCU->getTotalBits(), rpcBestCU->getTotalDistortion() );
+      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]);
+    }
+
 #if HIGHER_LAYER_IRAP_SKIP_FLAG
     }
 #endif
   }
-  else
-  {
-    bBoundary = true;
-  }
-
-  // copy orginal YUV samples to PCM buffer
-  if( rpcBestCU->isLosslessCoded(0) && (rpcBestCU->getIPCMFlag(0) == false))
+
+  // copy original YUV samples to PCM buffer
+  if( rpcBestCU->getTotalCost()!=MAX_DOUBLE && rpcBestCU->isLosslessCoded(0) && (rpcBestCU->getIPCMFlag(0) == false))
   {
     xFillPCMBuffer(rpcBestCU, m_ppcOrigYuv[uiDepth]);
@@ -840,13 +830,15 @@
   }
 
-  for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
-  {
-    const Bool bIsLosslessMode = false; // False at this level. Next level down may set it to true.
-
-    rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );
-
+  const Bool bSubBranch = bBoundary || !( m_pcEncCfg->getUseEarlyCU() && rpcBestCU->getTotalCost()!=MAX_DOUBLE && rpcBestCU->isSkipped(0) );
+
+  if( bSubBranch && uiDepth < sps.getLog2DiffMaxMinCodingBlockSize() && (!getFastDeltaQp() || uiWidth > fastDeltaQPCuMaxSize || bBoundary))
+  {
     // further split
-    if( bSubBranch && uiDepth < sps.getLog2DiffMaxMinCodingBlockSize() )
-    {
+    for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
+    {
+      const Bool bIsLosslessMode = false; // False at this level. Next level down may set it to true.
+
+      rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );
+
       UChar       uhNextDepth         = uiDepth+1;
       TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
@@ -876,5 +868,5 @@
 #if AMP_ENC_SPEEDUP
           DEBUG_STRING_NEW(sChild)
-          if ( !rpcBestCU->isInter(0) )
+          if ( !(rpcBestCU->getTotalCost()!=MAX_DOUBLE && rpcBestCU->isInter(0)) )
           {
             xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth DEBUG_STRING_PASS_INTO(sChild), NUMBER_OF_PART_SIZES );
@@ -951,19 +943,22 @@
       // This can be achieved by forcing the decision to be that of the rpcTempCU.
       // The exception is each slice / slice-segment must have at least one CTU.
-      const Bool isEndOfSlice        =    pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES
-                                       && ((pcSlice->getSliceBits()+rpcBestCU->getTotalBits())>pcSlice->getSliceArgument()<<3)
-                                       && rpcBestCU->getCtuRsAddr() != pcPic->getPicSym()->getCtuTsToRsAddrMap(pcSlice->getSliceCurStartCtuTsAddr())
-                                       && rpcBestCU->getCtuRsAddr() != pcPic->getPicSym()->getCtuTsToRsAddrMap(pcSlice->getSliceSegmentCurStartCtuTsAddr());
-      const Bool isEndOfSliceSegment =    pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES
-                                       && ((pcSlice->getSliceSegmentBits()+rpcBestCU->getTotalBits()) > pcSlice->getSliceSegmentArgument()<<3)
-                                       && rpcBestCU->getCtuRsAddr() != pcPic->getPicSym()->getCtuTsToRsAddrMap(pcSlice->getSliceSegmentCurStartCtuTsAddr());
-                                           // Do not need to check slice condition for slice-segment since a slice-segment is a subset of a slice.
-      if(isEndOfSlice||isEndOfSliceSegment)
-      {
-        rpcBestCU->getTotalCost()=MAX_DOUBLE;
+      if (rpcBestCU->getTotalCost()!=MAX_DOUBLE)
+      {
+        const Bool isEndOfSlice        =    pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES
+                                         && ((pcSlice->getSliceBits()+rpcBestCU->getTotalBits())>pcSlice->getSliceArgument()<<3)
+                                         && rpcBestCU->getCtuRsAddr() != pcPic->getPicSym()->getCtuTsToRsAddrMap(pcSlice->getSliceCurStartCtuTsAddr())
+                                         && rpcBestCU->getCtuRsAddr() != pcPic->getPicSym()->getCtuTsToRsAddrMap(pcSlice->getSliceSegmentCurStartCtuTsAddr());
+        const Bool isEndOfSliceSegment =    pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES
+                                         && ((pcSlice->getSliceSegmentBits()+rpcBestCU->getTotalBits()) > pcSlice->getSliceSegmentArgument()<<3)
+                                         && rpcBestCU->getCtuRsAddr() != pcPic->getPicSym()->getCtuTsToRsAddrMap(pcSlice->getSliceSegmentCurStartCtuTsAddr());
+                                             // Do not need to check slice condition for slice-segment since a slice-segment is a subset of a slice.
+        if(isEndOfSlice||isEndOfSliceSegment)
+        {
+          rpcBestCU->getTotalCost()=MAX_DOUBLE;
+        }
       }
 
       xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTempDebug) DEBUG_STRING_PASS_INTO(false) ); // RD compare current larger prediction
-                                                                                       // with sub partitioned prediction.
+                                                                                                                                                       // with sub partitioned prediction.
     }
   }
@@ -1299,4 +1294,8 @@
 {
   assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );
+  if(getFastDeltaQp())
+  {
+    return;   // never check merge in fast deltaqp mode
+  }
   TComMvField  cMvFieldNeighbours[2 * MRG_MAX_NUM_CANDS]; // double length for mv of both lists
   UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
@@ -1447,4 +1446,14 @@
   DEBUG_STRING_NEW(sTest)
 
+  if(getFastDeltaQp())
+  {
+    const TComSPS &sps=*(rpcTempCU->getSlice()->getSPS());
+    const UInt fastDeltaQPCuMaxSize = Clip3(sps.getMaxCUHeight()>>(sps.getLog2DiffMaxMinCodingBlockSize()), sps.getMaxCUHeight(), 32u);
+    if(ePartSize != SIZE_2Nx2N || rpcTempCU->getWidth( 0 ) > fastDeltaQPCuMaxSize)
+    {
+      return; // only check necessary 2Nx2N Inter in fast deltaqp mode
+    }
+  }
+
   // prior to this, rpcTempCU will have just been reset using rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );
   UChar uhDepth = rpcTempCU->getDepth( 0 );
@@ -1501,4 +1510,14 @@
   DEBUG_STRING_NEW(sTest)
 
+  if(getFastDeltaQp())
+  {
+    const TComSPS &sps=*(rpcTempCU->getSlice()->getSPS());
+    const UInt fastDeltaQPCuMaxSize = Clip3(sps.getMaxCUHeight()>>(sps.getLog2DiffMaxMinCodingBlockSize()), sps.getMaxCUHeight(), 32u);
+    if(rpcTempCU->getWidth( 0 ) > fastDeltaQPCuMaxSize)
+    {
+      return; // only check necessary 2Nx2N Intra in fast deltaqp mode
+    }
+  }
+
   UInt uiDepth = rpcTempCU->getDepth( 0 );
 
@@ -1563,4 +1582,14 @@
 Void TEncCu::xCheckIntraPCM( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
 {
+  if(getFastDeltaQp())
+  {
+    const TComSPS &sps=*(rpcTempCU->getSlice()->getSPS());
+    const UInt fastDeltaQPCuMaxPCMSize = Clip3((UInt)1<<sps.getPCMLog2MinSize(), (UInt)1<<sps.getPCMLog2MaxSize(), 32u);
+    if (rpcTempCU->getWidth( 0 ) > fastDeltaQPCuMaxPCMSize)
+    {
+      return;   // only check necessary PCM in fast deltaqp mode
+    }
+  }
+  
   UInt uiDepth = rpcTempCU->getDepth( 0 );
 
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncCu.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncCu.h	(revision 1368)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncCu.h	(revision 1369)
@@ -81,4 +81,5 @@
   //  Data : encoder control
   Bool                    m_bEncodeDQP;
+  Bool                    m_bFastDeltaQP;
   Bool                    m_stillToCodeChromaQpOffsetFlag; //indicates whether chroma QP offset flag needs to coded at this particular CU granularity.
   Int                     m_cuChromaQpOffsetIdxPlus1; // if 0, then cu_chroma_qp_offset_flag will be 0, otherwise cu_chroma_qp_offset_flag will be 1.
@@ -122,10 +123,12 @@
   Int   updateCtuDataISlice ( TComDataCU* pCtu, Int width, Int height );
 
+  Void setFastDeltaQp       ( Bool b)                 { m_bFastDeltaQP = b;         }
+
 protected:
   Void  finishCU            ( TComDataCU*  pcCU, UInt uiAbsPartIdx );
 #if AMP_ENC_SPEEDUP
-  Void  xCompressCU         ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth DEBUG_STRING_FN_DECLARE(sDebug), PartSize eParentPartSize = NUMBER_OF_PART_SIZES );
+  Void  xCompressCU         ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const UInt uiDepth DEBUG_STRING_FN_DECLARE(sDebug), PartSize eParentPartSize = NUMBER_OF_PART_SIZES );
 #else
-  Void  xCompressCU         ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth        );
+  Void  xCompressCU         ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const UInt uiDepth        );
 #endif
   Void  xEncodeCU           ( TComDataCU*  pcCU, UInt uiAbsPartIdx,           UInt uiDepth        );
@@ -162,4 +165,6 @@
   Void setdQPFlag           ( Bool b )                { m_bEncodeDQP = b;           }
 
+  Bool getFastDeltaQp       () const                  { return m_bFastDeltaQP;      }
+
   Bool getCodeChromaQpAdjFlag() { return m_stillToCodeChromaQpOffsetFlag; }
   Void setCodeChromaQpAdjFlag( Bool b ) { m_stillToCodeChromaQpOffsetFlag = b; }
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1368)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1369)
@@ -2492,5 +2492,5 @@
       {
         m_pcSliceEncoder->precompressSlice( pcPic );
-        m_pcSliceEncoder->compressSlice   ( pcPic, false );
+        m_pcSliceEncoder->compressSlice   ( pcPic, false, false );
 
         const UInt curSliceSegmentEnd = pcSlice->getSliceSegmentCurEndCtuTsAddr();
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 1368)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 1369)
@@ -677,5 +677,5 @@
 
     // try compress
-    compressSlice   ( pcPic, true );
+    compressSlice   ( pcPic, true, m_pcCfg->getFastDeltaQp());
 
     UInt64 uiPicDist        = m_uiPicDist; // Distortion, as calculated by compressSlice.
@@ -749,5 +749,5 @@
 /** \param pcPic   picture class
  */
-Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bCompressEntireSlice )
+Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bCompressEntireSlice, const Bool bFastDeltaQP )
 {
   // if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed,
@@ -779,4 +779,6 @@
   TComBitCounter  tempBitCounter;
   const UInt      frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus();
+  
+  m_pcCuEncoder->setFastDeltaQp(bFastDeltaQP);
 
   //------------------------------------------------------------------------------
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.h	(revision 1368)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.h	(revision 1369)
@@ -125,5 +125,5 @@
   // compress and encode slice
   Void    precompressSlice    ( TComPic* pcPic                                     );      ///< precompress slice for multi-loop slice-level QP opt.
-  Void    compressSlice       ( TComPic* pcPic, const Bool bCompressEntireSlice    );      ///< analysis stage of slice
+  Void    compressSlice       ( TComPic* pcPic, const Bool bCompressEntireSlice, const Bool bFastDeltaQP );      ///< analysis stage of slice
   Void    calCostSliceI       ( TComPic* pcPic );
   Void    encodeSlice         ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded );
