Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1432)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1433)
@@ -399,4 +399,13 @@
 };
 
+#if U0132_TARGET_BITS_SATURATION
+UInt g_uiMaxCpbSize[2][21] =
+{
+  //         LEVEL1,        LEVEL2,LEVEL2_1,     LEVEL3, LEVEL3_1,      LEVEL4, LEVEL4_1,       LEVEL5,  LEVEL5_1,  LEVEL5_2,    LEVEL6,  LEVEL6_1,  LEVEL6_2 
+  { 0, 0, 0, 350000, 0, 0, 1500000, 3000000, 0, 6000000, 10000000, 0, 12000000, 20000000, 0,  25000000,  40000000,  60000000,  60000000, 120000000, 240000000 },
+  { 0, 0, 0,      0, 0, 0,       0,       0, 0,       0,        0, 0, 30000000, 50000000, 0, 100000000, 160000000, 240000000, 240000000, 480000000, 800000000 }
+};
+#endif
+
 static const struct MapStrToCostMode
 {
@@ -826,4 +835,10 @@
   Int*    cfg_RCInitialQP          [MAX_LAYERS];
   Bool*   cfg_RCForceIntraQP       [MAX_LAYERS];
+
+#if U0132_TARGET_BITS_SATURATION
+  Bool*   cfg_RCCpbSaturationEnabled[MAX_LAYERS];
+  UInt*   cfg_RCCpbSize             [MAX_LAYERS];
+  Double* cfg_RCInitialCpbFullness  [MAX_LAYERS];
+#endif
 #endif
 
@@ -916,4 +931,10 @@
     cfg_RCInitialQP[layer]           = &m_apcLayerCfg[layer]->m_RCInitialQP;
     cfg_RCForceIntraQP[layer]        = &m_apcLayerCfg[layer]->m_RCForceIntraQP;
+
+#if U0132_TARGET_BITS_SATURATION
+    cfg_RCCpbSaturationEnabled[layer] = &m_apcLayerCfg[layer]->m_RCCpbSaturationEnabled;
+    cfg_RCCpbSize[layer]              = &m_apcLayerCfg[layer]->m_RCCpbSize;
+    cfg_RCInitialCpbFullness[layer]   = &m_apcLayerCfg[layer]->m_RCInitialCpbFullness;
+#endif
 #endif
 
@@ -1248,6 +1269,5 @@
   ("Profile",                                         extendedProfile,                                   NONE, "Profile name to use for encoding. Use main (for main), main10 (for main10), main-still-picture, main-RExt (for Range Extensions profile), any of the RExt specific profile names, or none")
   ("Level",                                           m_level,                                    Level::NONE, "Level limit to be used, eg 5.1, or none")
-  ("Tier",                                            m_levelTier,                                Level::MAIN, "Tier to use for interpretation of --Level (main or high only)")  
-
+  ("Tier",                                            m_levelTier,                                Level::MAIN, "Tier to use for interpretation of --Level (main or high only)")
   ("MaxBitDepthConstraint",                           m_bitDepthConstraint,                                0u, "Bit depth to use for profile-constraint for RExt profiles. 0=automatically choose based upon other parameters")
   ("MaxChromaFormatConstraint",                       tmpConstraintChromaFormat,                            0, "Chroma-format to use for the profile-constraint for RExt profiles. 0=automatically choose based upon other parameters")
@@ -1449,4 +1469,9 @@
   ("InitialQP%d",                                     cfg_RCInitialQP,                         0, m_numLayers, "Rate control: initial QP")
   ("RCForceIntraQP%d",                                cfg_RCForceIntraQP,                  false, m_numLayers, "Rate control: force intra QP to be equal to initial QP")
+#if U0132_TARGET_BITS_SATURATION
+  ( "RCCpbSaturation%d",                              cfg_RCCpbSaturationEnabled,          false, m_numLayers, "Rate control: enable target bits saturation to avoid CPB overflow and underflow" )
+  ( "RCCpbSize%d",                                    cfg_RCCpbSize,                          0u, m_numLayers, "Rate control: CPB size" )
+  ( "RCInitialCpbFullness%d",                         cfg_RCInitialCpbFullness,              0.9, m_numLayers, "Rate control: initial CPB fullness" )
+#endif
 #else
   ( "RateControl",                                    m_RCEnableRateControl,                            false, "Rate control: enable rate control" )
@@ -1457,4 +1482,9 @@
   ( "InitialQP",                                      m_RCInitialQP,                                        0, "Rate control: initial QP" )
   ( "RCForceIntraQP",                                 m_RCForceIntraQP,                                 false, "Rate control: force intra QP to be equal to initial QP" )
+#if U0132_TARGET_BITS_SATURATION
+  ( "RCCpbSaturation",                                m_RCCpbSaturationEnabled,                         false, "Rate control: enable target bits saturation to avoid CPB overflow and underflow" )
+  ( "RCCpbSize",                                      m_RCCpbSize,                                         0u, "Rate control: CPB size" )
+  ( "RCInitialCpbFullness",                           m_RCInitialCpbFullness,                             0.9, "Rate control: initial CPB fullness" )
+#endif
 #endif
 
@@ -4199,6 +4229,22 @@
       }
     }
-  }
-  xConfirmPara( m_uiDeltaQpRD > 0, "Rate control cannot be used together with slice level multiple-QP optimization!\n" );
+    xConfirmPara( m_uiDeltaQpRD > 0, "Rate control cannot be used together with slice level multiple-QP optimization!\n" );
+#if U0132_TARGET_BITS_SATURATION
+    Int layerPTLIdx = m_apcLayerCfg[layerIdx]->m_layerPTLIdx;
+
+    if( m_apcLayerCfg[layerIdx]->m_RCCpbSaturationEnabled && m_levelList[layerPTLIdx]!=Level::NONE && m_profileList[layerPTLIdx]!=Profile::NONE )
+    {
+      UInt uiLevelIdx = (m_levelList[layerPTLIdx] / 10) + (UInt)((m_levelList[layerPTLIdx] % 10) / 3);    // (m_level / 30)*3 + ((m_level % 10) / 3);
+      xConfirmPara( m_apcLayerCfg[layerIdx]->m_RCCpbSize > g_uiMaxCpbSize[m_levelTierList[layerPTLIdx]][uiLevelIdx], "RCCpbSize should be smaller than or equal to Max CPB size according to tier and level");
+      xConfirmPara( m_apcLayerCfg[layerIdx]->m_RCInitialCpbFullness > 1, "RCInitialCpbFullness should be smaller than or equal to 1");
+    }
+#endif
+  }
+#if U0132_TARGET_BITS_SATURATION
+  else
+  {
+    xConfirmPara( m_apcLayerCfg[layerIdx]->m_RCCpbSaturationEnabled != 0, "Target bits saturation cannot be processed without Rate control" );
+  }
+#endif
 #else
   if ( m_RCEnableRateControl )
@@ -4213,5 +4259,19 @@
     }
     xConfirmPara( m_uiDeltaQpRD > 0, "Rate control cannot be used together with slice level multiple-QP optimization!\n" );
-  }
+#if U0132_TARGET_BITS_SATURATION
+    if ((m_RCCpbSaturationEnabled) && (m_level!=Level::NONE) && (m_profile!=Profile::NONE))
+    {
+      UInt uiLevelIdx = (m_level / 10) + (UInt)((m_level % 10) / 3);    // (m_level / 30)*3 + ((m_level % 10) / 3);
+      xConfirmPara(m_RCCpbSize > g_uiMaxCpbSize[m_levelTier][uiLevelIdx], "RCCpbSize should be smaller than or equal to Max CPB size according to tier and level");
+      xConfirmPara(m_RCInitialCpbFullness > 1, "RCInitialCpbFullness should be smaller than or equal to 1");
+    }
+#endif
+  }
+#if U0132_TARGET_BITS_SATURATION
+  else
+  {
+    xConfirmPara( m_RCCpbSaturationEnabled != 0, "Target bits saturation cannot be processed without Rate control" );
+  }
+#endif
 #endif
 
@@ -4504,4 +4564,12 @@
     printf("InitialQP                              : %d\n", m_RCInitialQP );
     printf("ForceIntraQP                           : %d\n", m_RCForceIntraQP );
+#if U0132_TARGET_BITS_SATURATION
+    printf("CpbSaturation                          : %d\n", m_RCCpbSaturationEnabled );
+    if (m_RCCpbSaturationEnabled)
+    {
+      printf("CpbSize                                : %d\n", m_RCCpbSize);
+      printf("InitalCpbFullness                      : %.2f\n", m_RCInitialCpbFullness);
+    }
+#endif
   }
 #endif
@@ -4571,5 +4639,5 @@
 
   printf(" SignBitHidingFlag:%d ", m_signHideFlag);
-  printf("RecalQP:%d ", m_recalculateQPAccordingToLambda ? 1 : 0 );
+  printf("RecalQP:%d", m_recalculateQPAccordingToLambda ? 1 : 0 );
 
 #if SVC_EXTENSION
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1432)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1433)
@@ -407,4 +407,9 @@
   Int       m_RCInitialQP;                        ///< inital QP for rate control
   Bool      m_RCForceIntraQP;                     ///< force all intra picture to use initial QP or not
+#if U0132_TARGET_BITS_SATURATION
+  Bool      m_RCCpbSaturationEnabled;             ///< enable target bits saturation to avoid CPB overflow and underflow
+  UInt      m_RCCpbSize;                          ///< CPB size
+  Double    m_RCInitialCpbFullness;               ///< initial CPB fullness 
+#endif
 #endif
 #if !SVC_EXTENSION
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncLayerCfg.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncLayerCfg.cpp	(revision 1432)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncLayerCfg.cpp	(revision 1433)
@@ -266,4 +266,12 @@
     printf("InitialQP                         : %d\n", m_RCInitialQP );
     printf("ForceIntraQP                      : %d\n", m_RCForceIntraQP );
+#if U0132_TARGET_BITS_SATURATION
+    printf("CpbSaturation                          : %d\n", m_RCCpbSaturationEnabled );
+    if (m_RCCpbSaturationEnabled)
+    {
+      printf("CpbSize                                : %d\n", m_RCCpbSize);
+      printf("InitalCpbFullness                      : %.2f\n", m_RCInitialCpbFullness);
+    }
+#endif
   }
 #endif
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncLayerCfg.h
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncLayerCfg.h	(revision 1432)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncLayerCfg.h	(revision 1433)
@@ -85,4 +85,9 @@
   Int       m_RCInitialQP;                        ///< inital QP for rate control
   Bool      m_RCForceIntraQP;                     ///< force all intra picture to use initial QP or not
+#if U0132_TARGET_BITS_SATURATION
+  Bool      m_RCCpbSaturationEnabled;             ///< enable target bits saturation to avoid CPB overflow and underflow
+  UInt      m_RCCpbSize;                          ///< CPB size
+  Double    m_RCInitialCpbFullness;               ///< initial CPB fullness 
+#endif
 #endif
 
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1432)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1433)
@@ -493,4 +493,10 @@
     Int           m_RCInitialQP                                = m_apcLayerCfg[layer]->getRCInitialQP();
     Bool          m_RCForceIntraQP                             = m_apcLayerCfg[layer]->getRCForceIntraQP();
+
+#if U0132_TARGET_BITS_SATURATION
+    Bool          m_RCCpbSaturationEnabled                     = m_apcLayerCfg[layer]->m_RCCpbSaturationEnabled;
+    UInt          m_RCCpbSize                                  = m_apcLayerCfg[layer]->m_RCCpbSize;
+    Double        m_RCInitialCpbFullness                       = m_apcLayerCfg[layer]->m_RCInitialCpbFullness;
+#endif
 
     ScalingListMode m_useScalingListId                         = m_apcLayerCfg[layer]->m_useScalingListId;
@@ -789,4 +795,9 @@
   m_cTEncTop.setInitialQP                                         ( m_RCInitialQP );
   m_cTEncTop.setForceIntraQP                                      ( m_RCForceIntraQP );
+#if U0132_TARGET_BITS_SATURATION
+  m_cTEncTop.setCpbSaturationEnabled                              ( m_RCCpbSaturationEnabled );
+  m_cTEncTop.setCpbSize                                           ( m_RCCpbSize );
+  m_cTEncTop.setInitialCpbFullness                                ( m_RCInitialCpbFullness );
+#endif
   m_cTEncTop.setTransquantBypassEnableFlag                        ( m_TransquantBypassEnableFlag );
   m_cTEncTop.setCUTransquantBypassFlagForceValue                  ( m_CUTransquantBypassFlagForce );
Index: /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1433)
@@ -200,4 +200,5 @@
 #endif
 
+#define U0132_TARGET_BITS_SATURATION                      1 ///< Rate control with target bits saturation method
 
 // ====================================================================================================================
Index: /branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 1433)
@@ -3575,5 +3575,5 @@
   READ_UVLC( uiChromaInputBitDepthM8 , "cm_input_chroma_bit_depth_minus8" );
   READ_UVLC( uiOutputBitDepthM8, "cm_output_luma_bit_depth_minus8" );
-  READ_UVLC( uiChromaOutputBitDepthM8  "cm_output_chroma_bit_depth_minus8" );
+  READ_UVLC( uiChromaOutputBitDepthM8,  "cm_output_chroma_bit_depth_minus8" );
   READ_CODE( 2, uiResQaunBit, "cm_res_quant_bit" );
 
@@ -3681,5 +3681,5 @@
             for( Int nVertexIdx = 0; nVertexIdx < 4; nVertexIdx++ )
             {
-              pc3DAsymLUT->setCuboidVertexResTree( yIdx + y, uIdx +  , vIdx + v, nVertexIdx, 0, 0, 0 );
+              pc3DAsymLUT->setCuboidVertexResTree( yIdx + y, uIdx + u, vIdx + v, nVertexIdx, 0, 0, 0 );
 #if R0164_CGS_LUT_BUGFIX_CHECK
               pc3DAsymLUT->xSetFilled( yIdx + y, uIdx + u, vIdx + v );
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1433)
@@ -339,4 +339,9 @@
   Int       m_RCInitialQP;
   Bool      m_RCForceIntraQP;
+#if U0132_TARGET_BITS_SATURATION
+  Bool      m_RCCpbSaturationEnabled;
+  UInt      m_RCCpbSize;
+  Double    m_RCInitialCpbFullness;
+#endif
   Bool      m_TransquantBypassEnableFlag;                     ///< transquant_bypass_enable_flag setting in PPS.
   Bool      m_CUTransquantBypassFlagForce;                    ///< if transquant_bypass_enable_flag, then, if true, all CU transquant bypass flags will be set to true.
@@ -936,4 +941,12 @@
   Bool         getForceIntraQP        ()                             { return m_RCForceIntraQP;        }
   Void         setForceIntraQP        ( Bool b )                     { m_RCForceIntraQP = b;           }
+#if U0132_TARGET_BITS_SATURATION
+  Bool         getCpbSaturationEnabled()                             { return m_RCCpbSaturationEnabled;}
+  Void         setCpbSaturationEnabled( Bool b )                     { m_RCCpbSaturationEnabled = b;   }
+  UInt         getCpbSize             ()                             { return m_RCCpbSize;}
+  Void         setCpbSize             ( UInt ui )                    { m_RCCpbSize = ui;   }
+  Double       getInitialCpbFullness  ()                             { return m_RCInitialCpbFullness;  }
+  Void         setInitialCpbFullness  (Double f)                     { m_RCInitialCpbFullness = f;     }
+#endif
   Bool         getTransquantBypassEnableFlag()                       { return m_TransquantBypassEnableFlag; }
   Void         setTransquantBypassEnableFlag(Bool flag)              { m_TransquantBypassEnableFlag = flag; }
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1433)
@@ -2432,4 +2432,26 @@
       estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
 
+#if U0132_TARGET_BITS_SATURATION
+      if (m_pcRateCtrl->getCpbSaturationEnabled() && frameLevel != 0)
+      {
+        Int estimatedCpbFullness = m_pcRateCtrl->getCpbState() + m_pcRateCtrl->getBufferingRate();
+
+        // prevent overflow
+        if (estimatedCpbFullness - estimatedBits > (Int)(m_pcRateCtrl->getCpbSize()*0.9f))
+        {
+          estimatedBits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.9f);
+        }
+
+        estimatedCpbFullness -= m_pcRateCtrl->getBufferingRate();
+        // prevent underflow
+        if (estimatedCpbFullness - estimatedBits < (Int)(m_pcRateCtrl->getCpbSize()*0.1f))
+        {
+          estimatedBits = max(200, estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.1f));
+        }
+
+        m_pcRateCtrl->getRCPic()->setTargetBits(estimatedBits);
+      }
+#endif
+
       Int sliceQP = m_pcCfg->getInitialQP();
 #if SVC_EXTENSION
@@ -2455,4 +2477,25 @@
           Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
           bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
+
+#if U0132_TARGET_BITS_SATURATION
+          if (m_pcRateCtrl->getCpbSaturationEnabled() )
+          {
+            Int estimatedCpbFullness = m_pcRateCtrl->getCpbState() + m_pcRateCtrl->getBufferingRate();
+
+            // prevent overflow
+            if (estimatedCpbFullness - bits > (Int)(m_pcRateCtrl->getCpbSize()*0.9f))
+            {
+              bits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.9f);
+            }
+
+            estimatedCpbFullness -= m_pcRateCtrl->getBufferingRate();
+            // prevent underflow
+            if (estimatedCpbFullness - bits < (Int)(m_pcRateCtrl->getCpbSize()*0.1f))
+            {
+              bits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.1f);
+            }
+          }
+#endif
+
           if ( bits < 200 )
           {
@@ -2846,4 +2889,11 @@
         m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
       }
+#if U0132_TARGET_BITS_SATURATION
+      if (m_pcRateCtrl->getCpbSaturationEnabled())
+      {
+        m_pcRateCtrl->updateCpbState(actualTotalBits);
+        printf(" [CPB %6d bits]", m_pcRateCtrl->getCpbState());
+      }
+#endif
     }
 
@@ -4256,5 +4306,5 @@
 #endif
 #endif
-Void TEncGOP::xFilterImg( Pel *src, Int iSrcStride, Pel *dst, Int iDstStride, Int height1, Int width1, BitDepths& bitDepth, ComponentID comp )
+Void TEncGOP::xFilterImg( Pel *src, Int iSrcStride, Pel *dst, Int iDstStride, Int height, Int width, BitDepths& bitDepth, ComponentID comp )
 {
   Int height2, width2;
@@ -4264,14 +4314,14 @@
   Int length = m_cgsFilterLength;
   Int shift  = bitDepth.recon[CHANNEL_TYPE_LUMA] - bitDepth.recon[CHANNEL_TYPE_CHROMA];
-  Int shift2 = 2*7+shift;
+  Int shift2 = 2*7 + shift;
   Int roundingOffset = (1 << (shift2 - 1));
   Int maxVal = (1<<(bitDepth.recon[toChannelType(comp)]-shift))-1;
-  height2 = (height1 * m_cgsFilterPhases) / m_iN;
-  width2  = (width1  * m_cgsFilterPhases) / m_iN;
+  height2 = (height * m_cgsFilterPhases) / m_iN;
+  width2  = (width  * m_cgsFilterPhases) / m_iN;
 
   m_phaseFilter = comp == COMPONENT_Y ? m_phaseFilterLuma : m_phaseFilterChroma;
 
   // horizontal filtering
-  for( Int j1 = 0; j1 < height1; j1++ )
+  for( Int j1 = 0; j1 < height; j1++ )
   {
     Int i0 = -m_iN;
@@ -4302,5 +4352,5 @@
   }
 
-  for( Int k = height1; k < (height1 + (length>>1)); k++)
+  for( Int k = height; k < (height + (length>>1)); k++)
   {
     memcpy(m_temp[k], m_temp[k-1], (width2) * sizeof(Int));
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1433)
@@ -292,5 +292,5 @@
   inline Short xClip( Short x, Int bitdepth );
   Void xInitDs( const Int iWidth, const Int iHeight, const Bool allIntra, const Int posScalingFactorX);
-  Void xFilterImg( Pel *src, Int iSrcStride, Pel *dst, Int iDstStride, Int height1, Int width1, BitDepths& bitDepth, ComponentID comp );
+  Void xFilterImg( Pel *src, Int iSrcStride, Pel *dst, Int iDstStride, Int height, Int width, BitDepths& bitDepth, ComponentID comp );
 
   Int  xCreate2DArray(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX);
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncRateCtrl.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncRateCtrl.cpp	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncRateCtrl.cpp	(revision 1433)
@@ -1379,4 +1379,10 @@
     m_encRCSeq->initLCUPara();
   }
+#if U0132_TARGET_BITS_SATURATION
+  m_CpbSaturationEnabled = false;
+  m_cpbSize              = targetBitrate;
+  m_cpbState             = (UInt)(m_cpbSize*0.5f);
+  m_bufferingRate        = (Int)(targetBitrate / frameRate);
+#endif
 
   delete[] bitsRatio;
@@ -1396,4 +1402,34 @@
 }
 
+#if U0132_TARGET_BITS_SATURATION
+Int  TEncRateCtrl::updateCpbState(Int actualBits)
+{
+  Int cpbState = 1;
+
+  m_cpbState -= actualBits;
+  if (m_cpbState < 0)
+  {
+    cpbState = -1;
+  }
+
+  m_cpbState += m_bufferingRate;
+  if (m_cpbState > m_cpbSize)
+  {
+    cpbState = 0;
+  }
+
+  return cpbState;
+}
+
+Void TEncRateCtrl::initHrdParam(const TComHRD* pcHrd, Int iFrameRate, Double fInitialCpbFullness)
+{
+  m_CpbSaturationEnabled = true;
+  m_cpbSize = (pcHrd->getCpbSizeValueMinus1(0, 0, 0) + 1) << (4 + pcHrd->getCpbSizeScale());
+  m_cpbState = (UInt)(m_cpbSize*fInitialCpbFullness);
+  m_bufferingRate = (UInt)(((pcHrd->getBitRateValueMinus1(0, 0, 0) + 1) << (6 + pcHrd->getBitRateScale())) / iFrameRate);
+  printf("\nHRD - [Initial CPB state %6d] [CPB Size %6d] [Buffering Rate %6d]\n", m_cpbState, m_cpbSize, m_bufferingRate);
+}
+#endif
+
 Void TEncRateCtrl::destroyRCGOP()
 {
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncRateCtrl.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncRateCtrl.h	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncRateCtrl.h	(revision 1433)
@@ -265,4 +265,7 @@
   TRCLCU& getLCU( Int LCUIdx )                            { return m_LCUs[LCUIdx]; }
   Int  getPicActualHeaderBits()                           { return m_picActualHeaderBits; }
+#if U0132_TARGET_BITS_SATURATION
+  Void setBitLeft(Int bits)                               { m_bitsLeft = bits; }
+#endif
   Void setTargetBits( Int bits )                          { m_targetBits = bits; m_bitsLeft = bits;}
   Void setTotalIntraCost(Double cost)                     { m_totalCostIntra = cost; }
@@ -322,4 +325,12 @@
   TEncRCPic* getRCPic()          { assert ( m_encRCPic != NULL ); return m_encRCPic; }
   list<TEncRCPic*>& getPicList() { return m_listRCPictures; }
+#if U0132_TARGET_BITS_SATURATION
+  Bool       getCpbSaturationEnabled()  { return m_CpbSaturationEnabled;  }
+  UInt       getCpbState()              { return m_cpbState;       }
+  UInt       getCpbSize()               { return m_cpbSize;        }
+  UInt       getBufferingRate()         { return m_bufferingRate;  }
+  Int        updateCpbState(Int actualBits);
+  Void       initHrdParam(const TComHRD* pcHrd, Int iFrameRate, Double fInitialCpbFullness);
+#endif
 
 private:
@@ -329,7 +340,13 @@
   list<TEncRCPic*> m_listRCPictures;
   Int        m_RCQP;
-};
-
+#if U0132_TARGET_BITS_SATURATION
+  Bool       m_CpbSaturationEnabled;    // Enable target bits saturation to avoid CPB overflow and underflow
+  Int        m_cpbState;                // CPB State 
+  UInt       m_cpbSize;                 // CPB size
+  UInt       m_bufferingRate;           // Buffering rate
 #endif
-
-
+};
+
+#endif
+
+
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1432)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1433)
@@ -228,4 +228,10 @@
   xInitVPS();
 
+#if U0132_TARGET_BITS_SATURATION
+  if (m_RCCpbSaturationEnabled)
+  {
+    m_cRateCtrl.initHrdParam(m_cSPS.getVuiParameters()->getHrdParameters(), m_iFrameRate, m_RCInitialCpbFullness);
+  }
+#endif
   m_cRdCost.setCostMode(m_costMode);
 
@@ -1002,5 +1008,10 @@
     m_cSPS.setUsedByCurrPicLtSPSFlag(k, 0);
   }
+
+#if U0132_TARGET_BITS_SATURATION
+  if( getPictureTimingSEIEnabled() || getDecodingUnitInfoSEIEnabled() || getCpbSaturationEnabled() )
+#else
   if( getPictureTimingSEIEnabled() || getDecodingUnitInfoSEIEnabled() )
+#endif
   {
     xInitHrdParameters();
@@ -1025,4 +1036,20 @@
 }
 
+#if U0132_TARGET_BITS_SATURATION
+// calculate scale value of bitrate and initial delay
+Int calcScale(Int x)
+{
+  UInt iMask = 0xffffffff;
+  Int ScaleValue = 32;
+
+  while ((x&iMask) != 0)
+  {
+    ScaleValue--;
+    iMask = (iMask >> 1);
+  }
+
+  return ScaleValue;
+}
+#endif
 Void TEncTop::xInitHrdParameters()
 {
@@ -1030,6 +1057,11 @@
   Int  bitRate         = getTargetBitrate();
   Bool isRandomAccess  = getIntraPeriod() > 0;
-
+# if U0132_TARGET_BITS_SATURATION
+  Int cpbSize          = getCpbSize();
+
+  if( !getVuiParametersPresentFlag() && !getCpbSaturationEnabled() )
+#else
   if( !getVuiParametersPresentFlag() )
+#endif
   {
     return;
@@ -1075,5 +1107,4 @@
   hrd->setNalHrdParametersPresentFlag( rateCnt );
   hrd->setVclHrdParametersPresentFlag( rateCnt );
-
   hrd->setSubPicCpbParamsPresentFlag( useSubCpbParams );
 
@@ -1090,6 +1121,27 @@
   }
 
+#if U0132_TARGET_BITS_SATURATION
+  if (calcScale(bitRate) <= 6)
+  {
+    hrd->setBitRateScale(0);
+  }
+  else
+  {
+    hrd->setBitRateScale(calcScale(bitRate) - 6);
+  }
+
+  if (calcScale(cpbSize) <= 4)
+  {
+    hrd->setCpbSizeScale(0);
+  }
+  else
+  {
+    hrd->setCpbSizeScale(calcScale(cpbSize) - 4);
+  }
+#else
   hrd->setBitRateScale( 4 );                                       // in units of 2^( 6 + 4 ) = 1,024 bps
   hrd->setCpbSizeScale( 6 );                                       // in units of 2^( 4 + 6 ) = 1,024 bit
+#endif
+
   hrd->setDuCpbSizeScale( 6 );                                     // in units of 2^( 4 + 6 ) = 1,024 bit
 
@@ -1123,5 +1175,10 @@
     bitrateValue = bitRate / (1 << (6 + hrd->getBitRateScale()) );      // bitRate is in bits, so it needs to be scaled down
     // CpbSize[ i ] = ( cpb_size_value_minus1[ i ] + 1 ) * 2^( 4 + cpb_size_scale )
+#if U0132_TARGET_BITS_SATURATION
+    cpbSizeValue = cpbSize / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
+#else
     cpbSizeValue = bitRate / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
+#endif
+
 
     // DU CPB size could be smaller (i.e. bitrateValue / number of DUs), but we don't know 
