Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1297)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1298)
@@ -1325,4 +1325,7 @@
   ("RDOQ",                                            m_useRDOQ,                                         true)
   ("RDOQTS",                                          m_useRDOQTS,                                       true)
+#if T0196_SELECTIVE_RDOQ
+  ("SelectiveRDOQ",                                   m_useSelectiveRDOQ,                               false, "Enable selective RDOQ")
+#endif
   ("RDpenalty",                                       m_rdPenalty,                                          0,  "RD-penalty for 32x32 TU for intra in non-intra slices. 0:disabled  1:RD-penalty  2:maximum RD-penalty")
 
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1297)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1298)
@@ -268,4 +268,7 @@
   Bool      m_useRDOQ;                                       ///< flag for using RD optimized quantization
   Bool      m_useRDOQTS;                                     ///< flag for using RD optimized quantization for transform skip
+#if T0196_SELECTIVE_RDOQ
+  Bool      m_useSelectiveRDOQ;                               ///< flag for using selective RDOQ
+#endif
   Int       m_rdPenalty;                                      ///< RD-penalty for 32x32 TU for intra in non-intra slices (0: no RD-penalty, 1: RD-penalty, 2: maximum RD-penalty)
   Int       m_iFastSearch;                                    ///< ME mode, 0 = full, 1 = diamond, 2 = PMVFAST
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1297)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1298)
@@ -435,4 +435,7 @@
     m_acTEncTop[layer].setUseRDOQ                                          ( m_useRDOQ     );
     m_acTEncTop[layer].setUseRDOQTS                                        ( m_useRDOQTS   );
+#if T0196_SELECTIVE_RDOQ
+    m_acTEncTop[layer].setUseSelectiveRDOQ                                 ( m_useSelectiveRDOQ );
+#endif
     m_acTEncTop[layer].setRDpenalty                                        ( m_rdPenalty );
     m_acTEncTop[layer].setMaxCUWidth                                       ( m_acLayerCfg[layer].m_uiMaxCUWidth );
@@ -867,4 +870,7 @@
   m_cTEncTop.setUseRDOQ                                           ( m_useRDOQ     );
   m_cTEncTop.setUseRDOQTS                                         ( m_useRDOQTS   );
+#if T0196_SELECTIVE_RDOQ
+  m_cTEncTop.setUseSelectiveRDOQ                                  ( m_useSelectiveRDOQ );
+#endif
   m_cTEncTop.setRDpenalty                                         ( m_rdPenalty );
   m_cTEncTop.setMaxCUWidth                                        ( m_uiMaxCUWidth );
Index: /branches/SHM-dev/source/Lib/TLibCommon/TComTrQuant.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TComTrQuant.cpp	(revision 1297)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TComTrQuant.cpp	(revision 1298)
@@ -1161,8 +1161,20 @@
   if ( useRDOQ && (isLuma(compID) || RDOQ_CHROMA) )
   {
+#if T0196_SELECTIVE_RDOQ
+    if ( !m_useSelectiveRDOQ || xNeedRDOQ( rTu, piCoef, compID, cQP ) )
+    {
+#endif
 #if ADAPTIVE_QP_SELECTION
-    xRateDistOptQuant( rTu, piCoef, pDes, pArlDes, uiAbsSum, compID, cQP );
+      xRateDistOptQuant( rTu, piCoef, pDes, pArlDes, uiAbsSum, compID, cQP );
 #else
-    xRateDistOptQuant( rTu, piCoef, pDes, uiAbsSum, compID, cQP );
+      xRateDistOptQuant( rTu, piCoef, pDes, uiAbsSum, compID, cQP );
+#endif
+#if T0196_SELECTIVE_RDOQ
+    }
+    else
+    {
+      memset( pDes, 0, sizeof( TCoeff ) * uiWidth *uiHeight );
+      uiAbsSum = 0;
+    }
 #endif
   }
@@ -1249,4 +1261,63 @@
   //return;
 }
+
+#if T0196_SELECTIVE_RDOQ
+Bool TComTrQuant::xNeedRDOQ( TComTU &rTu, TCoeff * pSrc, const ComponentID compID, const QpParam &cQP )
+{
+  const TComRectangle &rect = rTu.getRect(compID);
+  const UInt uiWidth        = rect.width;
+  const UInt uiHeight       = rect.height;
+  TComDataCU* pcCU          = rTu.getCU();
+  const UInt uiAbsPartIdx   = rTu.GetAbsPartIdxTU();
+  const Int channelBitDepth = pcCU->getSlice()->getSPS()->getBitDepth(toChannelType(compID));
+
+  TCoeff* piCoef    = pSrc;
+
+  const Bool useTransformSkip      = pcCU->getTransformSkip(uiAbsPartIdx, compID);
+  const Int  maxLog2TrDynamicRange = pcCU->getSlice()->getSPS()->getMaxLog2TrDynamicRange(toChannelType(compID));
+
+  const UInt uiLog2TrSize = rTu.GetEquivalentLog2TrSize(compID);
+
+  Int scalingListType = getScalingListType(pcCU->getPredictionMode(uiAbsPartIdx), compID);
+  assert(scalingListType < SCALING_LIST_NUM);
+  Int *piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem, uiLog2TrSize-2);
+
+  const Bool enableScalingLists             = getUseScalingList(uiWidth, uiHeight, (pcCU->getTransformSkip(uiAbsPartIdx, compID) != 0));
+  const Int  defaultQuantisationCoefficient = g_quantScales[cQP.rem];
+
+  /* for 422 chroma blocks, the effective scaling applied during transformation is not a power of 2, hence it cannot be
+    * implemented as a bit-shift (the quantised result will be sqrt(2) * larger than required). Alternatively, adjust the
+    * uiLog2TrSize applied in iTransformShift, such that the result is 1/sqrt(2) the required result (i.e. smaller)
+    * Then a QP+3 (sqrt(2)) or QP-3 (1/sqrt(2)) method could be used to get the required result
+    */
+
+  // Represents scaling through forward transform
+  Int iTransformShift = getTransformShift(channelBitDepth, uiLog2TrSize, maxLog2TrDynamicRange);
+  if (useTransformSkip && pcCU->getSlice()->getSPS()->getUseExtendedPrecision())
+  {
+    iTransformShift = std::max<Int>(0, iTransformShift);
+  }
+
+  const Int iQBits = QUANT_SHIFT + cQP.per + iTransformShift;
+  // QBits will be OK for any internal bit depth as the reduction in transform shift is balanced by an increase in Qp_per due to QpBDOffset
+
+  // iAdd is different from the iAdd used in normal quantization
+  const Int iAdd   = (compID == COMPONENT_Y ? 171 : 256) << (iQBits-9);
+  const Int qBits8 = iQBits - 8;
+
+  for( Int uiBlockPos = 0; uiBlockPos < uiWidth*uiHeight; uiBlockPos++ )
+  {
+    const TCoeff iLevel   = piCoef[uiBlockPos];
+    const Int64  tmpLevel = (Int64)abs(iLevel) * (enableScalingLists ? piQuantCoeff[uiBlockPos] : defaultQuantisationCoefficient);
+    const TCoeff quantisedMagnitude = TCoeff((tmpLevel + iAdd ) >> iQBits);
+
+    if ( quantisedMagnitude != 0 )
+    {
+      return true;
+    }
+  } // for n
+  return false;
+}
+#endif
 
 Void TComTrQuant::xDeQuant(       TComTU        &rTu,
@@ -1376,4 +1447,7 @@
                           Bool  bUseRDOQ,
                           Bool  bUseRDOQTS,
+#if T0196_SELECTIVE_RDOQ
+                          Bool  useSelectiveRDOQ,
+#endif
                           Bool  bEnc,
                           Bool  useTransformSkipFast
@@ -1387,4 +1461,7 @@
   m_useRDOQ      = bUseRDOQ;
   m_useRDOQTS    = bUseRDOQTS;
+#if T0196_SELECTIVE_RDOQ
+  m_useSelectiveRDOQ = useSelectiveRDOQ;
+#endif
 #if ADAPTIVE_QP_SELECTION
   m_bUseAdaptQpSelect = bUseAdaptQpSelect;
Index: /branches/SHM-dev/source/Lib/TLibCommon/TComTrQuant.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TComTrQuant.h	(revision 1297)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TComTrQuant.h	(revision 1298)
@@ -106,4 +106,7 @@
                               Bool useRDOQ                = false,
                               Bool useRDOQTS              = false,
+#if T0196_SELECTIVE_RDOQ
+                              Bool useSelectiveRDOQ       = false,
+#endif
                               Bool bEnc                   = false,
                               Bool useTransformSkipFast   = false
@@ -216,4 +219,7 @@
   Bool     m_useRDOQ;
   Bool     m_useRDOQTS;
+#if T0196_SELECTIVE_RDOQ
+  Bool     m_useSelectiveRDOQ;
+#endif
 #if ADAPTIVE_QP_SELECTION
   Bool     m_bUseAdaptQpSelect;
@@ -247,4 +253,11 @@
                const ComponentID   compID,
                const QpParam      &cQP );
+
+#if T0196_SELECTIVE_RDOQ
+  Bool xNeedRDOQ(    TComTU       &rTu,
+                     TCoeff      * pSrc,
+               const ComponentID   compID,
+               const QpParam      &cQP );
+#endif
 
   // RDOQ functions
Index: /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1297)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1298)
@@ -162,4 +162,5 @@
 // Tool Switches
 // ====================================================================================================================
+#define T0196_SELECTIVE_RDOQ                              1 ///< selective RDOQ
 
 #define HARMONIZE_GOP_FIRST_FIELD_COUPLE                  1
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1297)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1298)
@@ -196,4 +196,7 @@
   Bool      m_useRDOQ;
   Bool      m_useRDOQTS;
+#if T0196_SELECTIVE_RDOQ
+  Bool      m_useSelectiveRDOQ;
+#endif
   UInt      m_rdPenalty;
   Bool      m_bUseFastEnc;
@@ -618,4 +621,7 @@
   Void      setUseRDOQ                      ( Bool  b )     { m_useRDOQ    = b; }
   Void      setUseRDOQTS                    ( Bool  b )     { m_useRDOQTS  = b; }
+#if T0196_SELECTIVE_RDOQ
+  Void      setUseSelectiveRDOQ             ( Bool b )      { m_useSelectiveRDOQ = b; }
+#endif
   Void      setRDpenalty                 ( UInt  b )     { m_rdPenalty  = b; }
   Void      setUseFastEnc                   ( Bool  b )     { m_bUseFastEnc = b; }
@@ -637,4 +643,7 @@
   Bool      getUseRDOQ                      ()      { return m_useRDOQ;    }
   Bool      getUseRDOQTS                    ()      { return m_useRDOQTS;  }
+#if T0196_SELECTIVE_RDOQ
+  Bool      getUseSelectiveRDOQ             ()      { return m_useSelectiveRDOQ; }
+#endif
   Int       getRDpenalty                    ()      { return m_rdPenalty;  }
   Bool      getUseFastEnc                   ()      { return m_bUseFastEnc; }
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1297)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1298)
@@ -250,4 +250,7 @@
                    m_useRDOQ,
                    m_useRDOQTS,
+#if T0196_SELECTIVE_RDOQ
+                   m_useSelectiveRDOQ,
+#endif
                    true
                   ,m_useTransformSkipFast
