Index: trunk/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 11)
+++ trunk/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 125)
@@ -4,5 +4,5 @@
  * granted under this license.  
  *
- * Copyright (c) 2010-2012, ITU/ISO/IEC
+ * Copyright (c) 2010-2013, ITU/ISO/IEC
  * All rights reserved.
  *
@@ -63,13 +63,10 @@
 TEncSlice::~TEncSlice()
 {
-#if DEPENDENT_SLICES
   for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
   {
     delete (*i);
   }
-#endif
 }
 
-#if DEPENDENT_SLICES
 Void TEncSlice::initCtxMem(  UInt i )                
 {   
@@ -81,5 +78,4 @@
   CTXMem.resize(i); 
 }
-#endif
 
 Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
@@ -173,6 +169,6 @@
  .
  \param pcPic         picture class
- \param iPOCLast      POC of last picture
- \param uiPOCCurr     current POC
+ \param pocLast       POC of last picture
+ \param pocCurr       current POC
  \param iNumPicRcvd   number of received pictures
  \param iTimeOffset   POC offset for hierarchical structure
@@ -182,5 +178,5 @@
  \param pPPS          PPS associated with the slice
  */
-Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
+Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
 {
   Double dQP;
@@ -192,5 +188,5 @@
   rpcSlice->setSliceBits(0);
   rpcSlice->setPic( pcPic );
-#if SET_SLICE_LAYER_ID
+#if SVC_EXTENSION
   rpcSlice->initSlice( pcPic->getLayerId() );
 #else
@@ -198,28 +194,23 @@
 #endif
   rpcSlice->setPicOutputFlag( true );
-  rpcSlice->setPOC( uiPOCCurr );
-  
-#if SVC_EXTENSION && !SET_SLICE_LAYER_ID
-  rpcSlice->setLayerId( pcPic->getLayerId());
-#endif
-
+  rpcSlice->setPOC( pocCurr );
+  
   // depth computation based on GOP size
-  int iDepth;
-  {
-    Int i, j;
-    Int iPOC = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
-    if ( iPOC == 0 )
-    {
-      iDepth = 0;
+  Int depth;
+  {
+    Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
+    if ( poc == 0 )
+    {
+      depth = 0;
     }
     else
     {
-      Int iStep = m_pcCfg->getGOPSize();
-      iDepth    = 0;
-      for( i=iStep>>1; i>=1; i>>=1 )
-      {
-        for ( j=i; j<m_pcCfg->getGOPSize(); j+=iStep )
-        {
-          if ( j == iPOC )
+      Int step = m_pcCfg->getGOPSize();
+      depth    = 0;
+      for( Int i=step>>1; i>=1; i>>=1 )
+      {
+        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
+        {
+          if ( j == poc )
           {
             i=0;
@@ -227,6 +218,6 @@
           }
         }
-        iStep>>=1;
-        iDepth++;
+        step >>= 1;
+        depth++;
       }
     }
@@ -237,5 +228,5 @@
   
   eSliceType=B_SLICE;
-  eSliceType = (iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
   
   rpcSlice->setSliceType    ( eSliceType );
@@ -245,6 +236,5 @@
   // ------------------------------------------------------------------------------------------------------------------
   
-#if TEMPORAL_LAYER_NON_REFERENCE
-  if(iPOCLast == 0)
+  if(pocLast == 0)
   {
     rpcSlice->setTemporalLayerNonReferenceFlag(false);
@@ -255,16 +245,4 @@
   }
   rpcSlice->setReferenced(true);
-#else
-  rpcSlice->setReferenced(m_pcCfg->getGOPEntry(iGOPid).m_refPic);
-#endif
-#if !REMOVE_NAL_REF_FLAG
-  rpcSlice->setNalRefFlag(m_pcCfg->getGOPEntry(iGOPid).m_refPic);
-#endif
-#if !TEMPORAL_LAYER_NON_REFERENCE
-  if(eSliceType==I_SLICE)
-  {
-    rpcSlice->setReferenced(true);
-  }
-#endif
   
   // ------------------------------------------------------------------------------------------------------------------
@@ -287,8 +265,10 @@
     dQP += pdQPs[ rpcSlice->getPOC() ];
   }
+#if !RATE_CONTROL_LAMBDA_DOMAIN
   if ( m_pcCfg->getUseRateCtrl())
   {
     dQP = m_pcRateCtrl->getFrameQP(rpcSlice->isReferenced(), rpcSlice->getPOC());
   }
+#endif
   // ------------------------------------------------------------------------------------------------------------------
   // Lambda computation
@@ -309,5 +289,5 @@
     Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
 #if FULL_NBIT
-    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
+    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
 #else
     Int    bitdepth_luma_qp_scale = 0;
@@ -325,5 +305,5 @@
     dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
 
-    if ( iDepth>0 )
+    if ( depth>0 )
     {
 #if FULL_NBIT
@@ -335,5 +315,5 @@
     
     // if hadamard is used in ME process
-    if ( !m_pcCfg->getUseHADME() )
+    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
     {
       dLambda *= 0.95;
@@ -363,9 +343,16 @@
   // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
   Double weight = 1.0;
-  if(iQP >= 0)
-  {
-    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
-  }
-  m_pcRdCost ->setChromaDistortionWeight( weight );     
+  Int qpc;
+  Int chromaQPOffset;
+
+  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
+  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
+  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCbDistortionWeight(weight);
+
+  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
+  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
+  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCrDistortionWeight(weight);
 #endif
 
@@ -377,6 +364,6 @@
 #endif
 
-#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
-// For ALF or SAO
+#if SAO_CHROMA_LAMBDA
+// For SAO
   rpcSlice   ->setLambda( dLambda, dLambda / weight );  
 #else
@@ -386,5 +373,6 @@
 #if HB_LAMBDA_FOR_LDC
   // restore original slice type
-  eSliceType = (iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+  
 #if REF_IDX_FRAMEWORK
   if(m_pcCfg->getLayerId() > 0)
@@ -396,5 +384,4 @@
 #endif
   
-#if RECALCULATE_QP_ACCORDING_LAMBDA
   if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
   {
@@ -402,5 +389,4 @@
     iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );    
   }
-#endif
 
   rpcSlice->setSliceQp          ( iQP );
@@ -409,8 +395,6 @@
 #endif
   rpcSlice->setSliceQpDelta     ( 0 );
-#if CHROMA_QP_EXTENSION
   rpcSlice->setSliceQpDeltaCb   ( 0 );
   rpcSlice->setSliceQpDeltaCr   ( 0 );
-#endif
   rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
   rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
@@ -424,12 +408,29 @@
     if ( !rpcSlice->getDeblockingFilterDisable())
     {
+      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
+      {
+        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
+        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
+        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
+        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
+      }
+      else
+      {
       rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
       rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
       rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
       rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
-    }
-  }
-
-  rpcSlice->setDepth            ( iDepth );
+      }
+    }
+  }
+  else
+  {
+    rpcSlice->setDeblockingFilterOverrideFlag( false );
+    rpcSlice->setDeblockingFilterDisable( false );
+    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
+    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
+  }
+
+  rpcSlice->setDepth            ( depth );
   
   pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
@@ -447,11 +448,54 @@
   rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
   rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
-  rpcSlice->setDependentSliceMode     ( m_pcCfg->getDependentSliceMode()     );
-  rpcSlice->setDependentSliceArgument ( m_pcCfg->getDependentSliceArgument() );
+  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
+  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
   rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
   xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
 }
 
-
+#if RATE_CONTROL_LAMBDA_DOMAIN
+Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
+{
+  TComSlice* slice = pic->getSlice(0);
+
+  // store lambda
+  slice->setSliceQp( sliceQP );
+#if L0033_RC_BUGFIX
+  slice->setSliceQpBase ( sliceQP );
+#endif
+  m_pcRdCost ->setLambda( lambda );
+#if WEIGHTED_CHROMA_DISTORTION
+  // for RDO
+  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
+  Double weight;
+  Int qpc;
+  Int chromaQPOffset;
+
+  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
+  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
+  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCbDistortionWeight(weight);
+
+  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
+  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
+  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCrDistortionWeight(weight);
+#endif
+
+#if RDOQ_CHROMA_LAMBDA 
+  // for RDOQ
+  m_pcTrQuant->setLambda( lambda, lambda / weight );
+#else
+  m_pcTrQuant->setLambda( lambda );
+#endif
+
+#if SAO_CHROMA_LAMBDA
+  // For SAO
+  slice   ->setLambda( lambda, lambda / weight );
+#else
+  slice   ->setLambda( lambda );
+#endif
+}
+#else
 /**
  - lambda re-computation based on rate control QP
@@ -475,5 +519,5 @@
     Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
 #if FULL_NBIT
-    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
+    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
 #else
     Int    bitdepth_luma_qp_scale = 0;
@@ -529,9 +573,16 @@
   // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
   Double weight = 1.0;
-  if(qp >= 0)
-  {
-    weight = pow( 2.0, (qp-g_aucChromaScale[qp])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
-  }
-  m_pcRdCost ->setChromaDistortionWeight( weight );     
+  Int qpc;
+  Int chromaQPOffset;
+
+  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
+  qpc = Clip3( 0, 57, qp + chromaQPOffset);
+  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCbDistortionWeight(weight);
+
+  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
+  qpc = Clip3( 0, 57, qp + chromaQPOffset);
+  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCrDistortionWeight(weight);
 #endif
 
@@ -543,6 +594,6 @@
 #endif
 
-#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
-  // For ALF or SAO
+#if SAO_CHROMA_LAMBDA
+  // For SAO
   pcSlice   ->setLambda( lambda, lambda / weight );  
 #else
@@ -550,4 +601,5 @@
 #endif
 }
+#endif
 // ====================================================================================================================
 // Public member functions
@@ -588,4 +640,12 @@
     return;
   }
+
+#if RATE_CONTROL_LAMBDA_DOMAIN
+  if ( m_pcCfg->getUseRateCtrl() )
+  {
+    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
+    assert(0);
+  }
+#endif
   
   TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
@@ -595,5 +655,5 @@
   Double dFrameLambda;
 #if FULL_NBIT
-  Int    SHIFT_QP = 12 + 6 * (g_uiBitDepth - 8);
+  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
 #else
   Int    SHIFT_QP = 12;
@@ -622,11 +682,18 @@
     // for RDO
     // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
-    int iQP = m_piRdPicQp    [uiQpIdx];
+    Int iQP = m_piRdPicQp    [uiQpIdx];
     Double weight = 1.0;
-    if(iQP >= 0)
-    {
-      weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
-    }
-    m_pcRdCost    ->setChromaDistortionWeight( weight );     
+    Int qpc;
+    Int chromaQPOffset;
+
+    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
+    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
+    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+    m_pcRdCost->setCbDistortionWeight(weight);
+
+    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
+    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
+    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+    m_pcRdCost->setCrDistortionWeight(weight);
 #endif
 
@@ -637,6 +704,6 @@
     m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
 #endif
-#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
-    // For ALF or SAO
+#if SAO_CHROMA_LAMBDA
+    // For SAO
     pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
 #else
@@ -671,11 +738,18 @@
 #if WEIGHTED_CHROMA_DISTORTION
   // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
-  int iQP = m_piRdPicQp    [uiQpIdxBest];
+  Int iQP = m_piRdPicQp    [uiQpIdxBest];
   Double weight = 1.0;
-  if(iQP >= 0)
-  {
-    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
-  }
-  m_pcRdCost ->setChromaDistortionWeight( weight );     
+  Int qpc;
+  Int chromaQPOffset;
+
+  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
+  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
+  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCbDistortionWeight(weight);
+
+  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
+  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
+  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
+  m_pcRdCost->setCrDistortionWeight(weight);
 #endif
 
@@ -686,6 +760,6 @@
   m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
 #endif
-#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
-  // For ALF or SAO
+#if SAO_CHROMA_LAMBDA
+  // For SAO
   pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
 #else
@@ -701,5 +775,5 @@
   UInt   uiStartCUAddr;
   UInt   uiBoundingCUAddr;
-  rpcPic->getSlice(getSliceIdx())->setDependentSliceCounter(0);
+  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
   TEncBinCABAC* pppcRDSbacCoder = NULL;
   TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
@@ -745,5 +819,5 @@
     //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
     //------------------------------------------------------------------------------
-    if ( pcSlice->getSliceMode()==2 || pcSlice->getDependentSliceMode()==2 )
+    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
     {
       printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
@@ -782,5 +856,5 @@
     m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
     m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
-    for (int ui = 0; ui < uiTilesAcross; ui++)
+    for (Int ui = 0; ui < uiTilesAcross; ui++)
     {
       m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
@@ -802,5 +876,5 @@
     m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
     m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
-    for (int ui = 0; ui < uiTilesAcross; ui++)
+    for (Int ui = 0; ui < uiTilesAcross; ui++)
     {
       m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
@@ -820,26 +894,15 @@
 #endif
 
-
-#if DEPENDENT_SLICES
-  Bool bAllowDependence = false;
-#if TILES_WPP_ENTROPYSLICES_FLAGS
-  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getEntropySliceEnabledFlag()) )
-#else
-  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getCabacIndependentFlag()) )
-#endif
-  {
-    bAllowDependence = true;
-  }
-  if( bAllowDependence )
-  {
-    if(pcSlice->getDependentSliceCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())
+  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
+  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
+  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
+  if( depSliceSegmentsEnabled )
+  {
+    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
     {
       if( m_pcCfg->getWaveFrontsynchro() )
       {
+        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
         m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
-      }
-      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
-      if (pcSlice->getPPS()->getNumSubstreams() > 1)
-      {
         Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
         uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
@@ -847,5 +910,15 @@
         uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
           + uiLin%iNumSubstreamsPerTile;
-      }
+        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
+        {
+          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
+          uiCol     = uiCUAddr % uiWidthInLCUs;
+          if(uiCol==uiTileStartLCU)
+          {
+            CTXMem[0]->loadContexts(m_pcSbacCoder);
+          }
+        }
+      }
+      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
       ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
     }
@@ -859,8 +932,6 @@
     }
   }
-#endif
   // for every CU in slice
   UInt uiEncCUOrder;
-  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
   for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
        uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
@@ -874,4 +945,5 @@
 #endif
 
+#if !RATE_CONTROL_LAMBDA_DOMAIN
     if(m_pcCfg->getUseRateCtrl())
     {
@@ -881,4 +953,5 @@
       }
     }
+#endif
     // inherit from TR if necessary, select substream to use.
     if( m_pcCfg->getUseSBACRD() )
@@ -902,9 +975,5 @@
         uiSubStrm = uiLin % iNumSubstreams;
       }
-#if DEPENDENT_SLICES
-      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || bAllowDependence ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
-#else
-      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
-#endif
+      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
       {
         // We'll sync if the TR is available.
@@ -920,17 +989,7 @@
              (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
              ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
-             )||
-             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
-             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getDependentSliceCurStartCUAddr()) ||
-             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
              )
            )
         {
-#if DEPENDENT_SLICES
-          if ( (uiCUAddr != 0) && (pcCUTR->getSCUAddr()+uiMaxParts-1 >= pcSlice->getSliceCurStartCUAddr())  && bAllowDependence)
-          {
-            ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
-          }
-#endif
           // TR not available.
         }
@@ -947,7 +1006,5 @@
     if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
         uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
-#if DEPENDENT_SLICES
-        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getDependentSliceCurStartCUAddr())/rpcPic->getNumPartInCU() &&
-#endif
+        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
         uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
     {
@@ -970,6 +1027,73 @@
       
       ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
+
+#if RATE_CONTROL_LAMBDA_DOMAIN
+      Double oldLambda = m_pcRdCost->getLambda();
+      if ( m_pcCfg->getUseRateCtrl() )
+      {
+        Int estQP        = pcSlice->getSliceQp();
+        Double estLambda = -1.0;
+        Double bpp       = -1.0;
+
+        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
+        {
+          estQP = pcSlice->getSliceQp();
+        }
+        else
+        {
+          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
+          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
+          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
+          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
+
+          m_pcRdCost->setLambda(estLambda);
+        }
+
+        m_pcRateCtrl->setRCQP( estQP );
+#if L0033_RC_BUGFIX
+        pcCU->getSlice()->setSliceQpBase( estQP );
+#endif
+      }
+#endif
+
       // run CU encoder
       m_pcCuEncoder->compressCU( pcCU );
+
+#if RATE_CONTROL_LAMBDA_DOMAIN
+      if ( m_pcCfg->getUseRateCtrl() )
+      {
+        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
+        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
+        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
+        Double MAD = (Double)SAD / (Double)(height * width);
+        MAD = MAD * MAD;
+        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
+
+        Int actualQP        = g_RCInvalidQPValue;
+        Double actualLambda = m_pcRdCost->getLambda();
+        Int actualBits      = pcCU->getTotalBits();
+        Int numberOfEffectivePixels    = 0;
+        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
+        {
+          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
+          {
+            numberOfEffectivePixels = numberOfEffectivePixels + 16;
+            break;
+          }
+        }
+
+        if ( numberOfEffectivePixels == 0 )
+        {
+          actualQP = g_RCInvalidQPValue;
+        }
+        else
+        {
+          actualQP = pcCU->getQP( 0 );
+        }
+        m_pcRdCost->setLambda(oldLambda);
+
+        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
+      }
+#endif
       
       // restore entropy coder to an initial stage
@@ -984,12 +1108,12 @@
 
       pppcRDSbacCoder->setBinCountingEnableFlag( false );
-      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
+      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
       {
         pcSlice->setNextSlice( true );
         break;
       }
-      if (m_pcCfg->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE && pcSlice->getDependentSliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getDependentSliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getDependentSliceCurEndCUAddr())
-      {
-        pcSlice->setNextDependentSlice( true );
+      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
+      {
+        pcSlice->setNextSliceSegment( true );
         break;
       }
@@ -999,9 +1123,5 @@
        
          //Store probabilties of second LCU in line into buffer
-#if DEPENDENT_SLICES
-         if ( ( uiCol == uiTileLCUX+1) && (bAllowDependence || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
-#else
-        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
-#endif
+         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
         {
           m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
@@ -1014,12 +1134,12 @@
       m_pcCuEncoder->compressCU( pcCU );
       m_pcCuEncoder->encodeCU( pcCU );
-      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
+      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
       {
         pcSlice->setNextSlice( true );
         break;
       }
-      if (m_pcCfg->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE && pcSlice->getDependentSliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getDependentSliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getDependentSliceCurEndCUAddr())
-      {
-        pcSlice->setNextDependentSlice( true );
+      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
+      {
+        pcSlice->setNextSliceSegment( true );
         break;
       }
@@ -1029,4 +1149,5 @@
     m_dPicRdCost     += pcCU->getTotalCost();
     m_uiPicDist      += pcCU->getTotalDistortion();
+#if !RATE_CONTROL_LAMBDA_DOMAIN
     if(m_pcCfg->getUseRateCtrl())
     {
@@ -1034,15 +1155,11 @@
       m_pcRateCtrl->updataRCUnitStatus();
     }
-  }
-#if DEPENDENT_SLICES
-  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !bAllowDependence)
-#else
-  if (pcSlice->getPPS()->getNumSubstreams() > 1)
-#endif
+#endif
+  }
+  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
   {
     pcSlice->setNextSlice( true );
   }
-#if DEPENDENT_SLICES
-  if( bAllowDependence )
+  if( depSliceSegmentsEnabled )
   {
     if (m_pcCfg->getWaveFrontsynchro())
@@ -1052,10 +1169,11 @@
      CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
   }
-#endif
   xRestoreWPparam( pcSlice );
+#if !RATE_CONTROL_LAMBDA_DOMAIN
   if(m_pcCfg->getUseRateCtrl())
   {
     m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
   }
+#endif
 }
 
@@ -1071,6 +1189,6 @@
   TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
 
-  uiStartCUAddr=pcSlice->getDependentSliceCurStartCUAddr();
-  uiBoundingCUAddr=pcSlice->getDependentSliceCurEndCUAddr();
+  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
+  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
   // choose entropy coder
   {
@@ -1121,17 +1239,13 @@
   UInt uiTileStartLCU = 0;
   UInt uiTileLCUX     = 0;
-#if DEPENDENT_SLICES
-  Bool bAllowDependence = false;
-#if TILES_WPP_ENTROPYSLICES_FLAGS
-  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getEntropySliceEnabledFlag()) )
-#else
-  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getCabacIndependentFlag()) )
-#endif
-  {
-    bAllowDependence = true;
-  }
-  if( bAllowDependence )
-  {
-    if(pcSlice->isNextSlice())
+  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
+  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
+                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
+                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
+  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
+  if( depSliceSegmentsEnabled )
+  {
+    if( pcSlice->isNextSlice()||
+        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
     {
       if(m_pcCfg->getWaveFrontsynchro())
@@ -1145,23 +1259,25 @@
       if(m_pcCfg->getWaveFrontsynchro())
       {
+        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
         m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
-      }
-      if(pcSlice->getPPS()->getNumSubstreams() > 1)
-      {
         Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
-        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
         uiLin     = uiCUAddr / uiWidthInLCUs;
         uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
           + uiLin%iNumSubstreamsPerTile;
+        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
+        {
+          uiCol     = uiCUAddr % uiWidthInLCUs;
+          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
+          if(uiCol==uiTileLCUX)
+          {
+            CTXMem[0]->loadContexts(m_pcSbacCoder);
+          }
+        }
       }
       pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
     }
   }
-#endif
 
   UInt uiEncCUOrder;
-  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
-                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
-                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
   for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
        uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
@@ -1191,9 +1307,5 @@
       m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
       // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
-#if DEPENDENT_SLICES
-      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || bAllowDependence) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
-#else
-      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
-#endif
+      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
       {
         // We'll sync if the TR is available.
@@ -1210,18 +1322,7 @@
              (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
              ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
-             ))||
-             (true/*bEnforceDependentSliceRestriction*/ &&
-             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
-             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getDependentSliceCurStartCUAddr()) ||
-             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
              ))
            )
         {
-#if DEPENDENT_SLICES
-          if ( (uiCUAddr != 0) && ( pcCUTR->getSCUAddr()+uiMaxParts-1 >= pcSlice->getSliceCurStartCUAddr() ) && bAllowDependence)
-          {
-            pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
-          }
-#endif
           // TR not available.
         }
@@ -1237,7 +1338,5 @@
     if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
         uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
-#if DEPENDENT_SLICES
-        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getDependentSliceCurStartCUAddr())/rpcPic->getNumPartInCU() &&
-#endif
+        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
         uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
     {
@@ -1258,11 +1357,6 @@
           }
           m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
-#if BYTE_ALIGNMENT
           // Byte-alignment in slice_data() when new tile
           pcSubstreams[uiSubStrm].writeByteAlignment();
-#else
-          pcSubstreams[uiSubStrm].write( 1, 1 );
-          pcSubstreams[uiSubStrm].writeAlignZero();
-#endif
         }
       }
@@ -1313,15 +1407,7 @@
 
     TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );    
-#if !SAO_LUM_CHROMA_ONOFF_FLAGS
-    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoEnabledFlag() )
-#else
     if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
-#endif
-    {
-#if REMOVE_APS
+    {
       SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
-#else
-      SAOParam *saoParam = pcSlice->getAPS()->getSaoParam();
-#endif
       Int iNumCuInWidth     = saoParam->numCuInWidth;
       Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
@@ -1346,12 +1432,7 @@
       }
       Int addr = pcCU->getAddr();
-#if SAO_SINGLE_MERGE
       allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
       allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
-#if SAO_TYPE_SHARING
       if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
-#else
-      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] || saoParam->bSaoFlag[2])
-#endif
       {
         Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
@@ -1359,9 +1440,5 @@
         if (allowMergeLeft)
         {
-#if SAO_MERGE_ONE_CTX
           m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
-#else
-          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMergeLeft(mergeLeft, 0); 
-#endif
         }
         else
@@ -1373,9 +1450,5 @@
           if (allowMergeUp)
           {
-#if SAO_MERGE_ONE_CTX
             m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
-#else
-            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMergeUp(mergeUp);
-#endif
           }
           else
@@ -1387,15 +1460,7 @@
             for (Int compIdx=0;compIdx<3;compIdx++)
             {
-#if SAO_TYPE_SHARING
             if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
-#else
-            if( saoParam->bSaoFlag[compIdx])
-#endif
               {
-#if SAO_TYPE_SHARING
                 m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
-#else
-                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr]);
-#endif
               }
             }
@@ -1403,29 +1468,32 @@
         }
       }
-#else
-      m_pcEntropyCoder->encodeSaoUnitInterleaving(0, saoParam->bSaoFlag[0], rx, ry, &(saoParam->saoLcuParam[0][addr]), iCUAddrInSlice, iCUAddrUpInSlice, allowMergeLeft, allowMergeUp);
-      m_pcEntropyCoder->encodeSaoUnitInterleaving(1, saoParam->bSaoFlag[1], rx, ry, &(saoParam->saoLcuParam[1][addr]), iCUAddrInSlice, iCUAddrUpInSlice, allowMergeLeft, allowMergeUp);
-      m_pcEntropyCoder->encodeSaoUnitInterleaving(2, saoParam->bSaoFlag[2], rx, ry, &(saoParam->saoLcuParam[2][addr]), iCUAddrInSlice, iCUAddrUpInSlice, allowMergeLeft, allowMergeUp);
-#endif
+    }
+    else if (pcSlice->getSPS()->getUseSAO())
+    {
+      Int addr = pcCU->getAddr();
+      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
+      for (Int cIdx=0; cIdx<3; cIdx++)
+      {
+        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
+        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
+        {
+          saoLcuParam->mergeUpFlag   = 0;
+          saoLcuParam->mergeLeftFlag = 0;
+          saoLcuParam->subTypeIdx    = 0;
+          saoLcuParam->typeIdx       = -1;
+          saoLcuParam->offset[0]     = 0;
+          saoLcuParam->offset[1]     = 0;
+          saoLcuParam->offset[2]     = 0;
+          saoLcuParam->offset[3]     = 0;
+        }
+      }
     }
 #if ENC_DEC_TRACE
     g_bJustDoIt = g_bEncDecTraceEnable;
 #endif
-#if !REMOVE_ALF
-    if( pcSlice->getSPS()->getUseALF())
-    {
-      for(Int compIdx=0; compIdx< 3; compIdx++)
-      {
-        if(pcSlice->getAlfEnabledFlag(compIdx))
-        {
-          m_pcEntropyCoder->encodeAlfCtrlFlag(compIdx, pcCU->getAlfLCUEnabled(compIdx)?1:0);
-        }
-      }
-    }
-#endif
-    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getDependentSliceMode()!=0) &&
+    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
       uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
     {
-      m_pcCuEncoder->encodeCU( pcCU, true );
+      m_pcCuEncoder->encodeCU( pcCU );
     }
     else
@@ -1442,9 +1510,5 @@
 
        //Store probabilties of second LCU in line into buffer
-#if DEPENDENT_SLICES
-       if ( (bAllowDependence || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
-#else
-      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
-#endif
+       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
       {
         m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
@@ -1452,6 +1516,5 @@
     }
   }
-#if DEPENDENT_SLICES
-  if( bAllowDependence )
+  if( depSliceSegmentsEnabled )
   {
     if (m_pcCfg->getWaveFrontsynchro())
@@ -1461,5 +1524,4 @@
     CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
   }
-#endif
 #if ADAPTIVE_QP_SELECTION
   if( m_pcCfg->getUseAdaptQpSelect() )
@@ -1470,5 +1532,5 @@
   if (pcSlice->getPPS()->getCabacInitPresentFlag())
   {
-    if  (pcSlice->getPPS()->getDependentSliceEnabledFlag())
+    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
     {
       pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
@@ -1485,5 +1547,5 @@
  * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
  */
-Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
+Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
 {
   TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
@@ -1503,13 +1565,13 @@
     switch (m_pcCfg->getSliceMode())
     {
-    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
+    case FIXED_NUMBER_OF_LCU:
       uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
       uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
-    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
+    case FIXED_NUMBER_OF_BYTES:
       uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
       uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
       break;
-    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
+    case FIXED_NUMBER_OF_TILES:
       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
         rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
@@ -1524,9 +1586,5 @@
           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
-#if REMOVE_FGS
           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
-#else
-          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
-#endif
         }
       }
@@ -1539,4 +1597,9 @@
       break;
     } 
+    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
+    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
+    {
+      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
+    }
     pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
   }
@@ -1546,9 +1609,9 @@
     switch (m_pcCfg->getSliceMode())
     {
-    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
+    case FIXED_NUMBER_OF_LCU:
       uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
       uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
-    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
+    case FIXED_NUMBER_OF_TILES:
       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
         rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
@@ -1563,9 +1626,5 @@
           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
-#if REMOVE_FGS
           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
-#else
-          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
-#endif
         }
       }
@@ -1578,8 +1637,8 @@
       break;
     } 
-    // set the slice end address to the end of the SCU row if the slice does not start at the beginning of an SCU row
+    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
     if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
     {
-      uiBoundingCUAddrSlice = uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU());
+      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
     }
     pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
@@ -1587,5 +1646,5 @@
 
   Bool tileBoundary = false;
-  if ((m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE || m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE) && 
+  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
       (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
   {
@@ -1610,29 +1669,28 @@
 
   // Dependent slice
-  UInt uiStartCUAddrDependentSlice, uiBoundingCUAddrDependentSlice;
-  uiStartCUAddrDependentSlice    = pcSlice->getDependentSliceCurStartCUAddr();
-  uiBoundingCUAddrDependentSlice = uiNumberOfCUsInFrame;
+  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
+  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
+  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
   if (bEncodeSlice) 
   {
     UInt uiCUAddrIncrement;
-    switch (m_pcCfg->getDependentSliceMode())
-    {
-    case SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE:
-      uiCUAddrIncrement               = m_pcCfg->getDependentSliceArgument();
-      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
+    switch (m_pcCfg->getSliceSegmentMode())
+    {
+    case FIXED_NUMBER_OF_LCU:
+      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
+      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
-    case SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE:
+    case FIXED_NUMBER_OF_BYTES:
       uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
-      uiBoundingCUAddrDependentSlice    = pcSlice->getDependentSliceCurEndCUAddr();
+      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
       break;
-#if DEPENDENT_SLICES
-    case FIXED_NUMBER_OF_TILES_IN_DEPENDENT_SLICE:
+    case FIXED_NUMBER_OF_TILES:
       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
-        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getDependentSliceCurStartCUAddr()/rpcPic->getNumPartInCU())
+        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
         );
       uiCUAddrIncrement        = 0;
       tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
 
-      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getDependentSliceArgument(); tileIdxIncrement++)
+      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
       {
         if((tileIdx + tileIdxIncrement) < tileTotalCount)
@@ -1640,39 +1698,38 @@
           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
-#if REMOVE_FGS
           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
-#else
-          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
-#endif
-        }
-      }
-      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
+        }
+      }
+      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
-#endif
     default:
       uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
-      uiBoundingCUAddrDependentSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
+      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
     } 
-    pcSlice->setDependentSliceCurEndCUAddr( uiBoundingCUAddrDependentSlice );
+    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
+    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
+    {
+      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
+    }
+    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
   }
   else
   {
     UInt uiCUAddrIncrement;
-    switch (m_pcCfg->getDependentSliceMode())
-    {
-    case SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE:
-      uiCUAddrIncrement               = m_pcCfg->getDependentSliceArgument();
-      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
+    switch (m_pcCfg->getSliceSegmentMode())
+    {
+    case FIXED_NUMBER_OF_LCU:
+      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
+      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
-#if DEPENDENT_SLICES
-    case FIXED_NUMBER_OF_TILES_IN_DEPENDENT_SLICE:
+    case FIXED_NUMBER_OF_TILES:
       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
-        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getDependentSliceCurStartCUAddr()/rpcPic->getNumPartInCU())
+        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
         );
       uiCUAddrIncrement        = 0;
       tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
 
-      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getDependentSliceArgument(); tileIdxIncrement++)
+      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
       {
         if((tileIdx + tileIdxIncrement) < tileTotalCount)
@@ -1680,29 +1737,52 @@
           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
-#if REMOVE_FGS
           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
-#else
-          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
-#endif
-        }
-      }
-      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
+        }
+      }
+      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
-#endif
     default:
       uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
-      uiBoundingCUAddrDependentSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
+      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
       break;
     } 
-    pcSlice->setDependentSliceCurEndCUAddr( uiBoundingCUAddrDependentSlice );
-  }
-  if(uiBoundingCUAddrDependentSlice>uiBoundingCUAddrSlice)
-  {
-    uiBoundingCUAddrDependentSlice = uiBoundingCUAddrSlice;
-    pcSlice->setDependentSliceCurEndCUAddr(uiBoundingCUAddrSlice);
-  }
+    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
+    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
+    {
+      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
+    }
+    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
+  }
+  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
+    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
+  {
+    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
+    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
+    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
+    UInt tileBoundingCUAddrSlice = 0;
+    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
+    {
+      lcuEncAddr++;
+      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
+    }
+    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
+
+    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
+    {
+      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
+      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
+      tileBoundary = true;
+    }
+  }
+
+  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
+  {
+    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
+    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
+  }
+
   //calculate real dependent slice start address
-  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
-  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
+  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
+  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
   UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
   UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
@@ -1722,6 +1802,6 @@
   UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
   
-  pcSlice->setDependentSliceCurStartCUAddr(uiRealStartAddress);
-  uiStartCUAddrDependentSlice=uiRealStartAddress;
+  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
+  startCUAddrSliceSegment=uiRealStartAddress;
   
   //calculate real slice start address
@@ -1749,6 +1829,6 @@
   
   // Make a joint decision based on reconstruction and dependent slice bounds
-  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrDependentSlice   );
-  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrDependentSlice);
+  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
+  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
 
 
@@ -1757,29 +1837,27 @@
     // For fixed number of LCU within an entropy and reconstruction slice we already know whether we will encounter end of entropy and/or reconstruction slice
     // first. Set the flags accordingly.
-    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE)
-      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE)
-      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getDependentSliceMode()==0) 
-      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE)
-      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getDependentSliceMode()==0) 
-#if DEPENDENT_SLICES
-      || (m_pcCfg->getDependentSliceMode()==FIXED_NUMBER_OF_TILES_IN_DEPENDENT_SLICE && m_pcCfg->getSliceMode()==0)
-#endif
+    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
+      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
+      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
+      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
+      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
+      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
       || tileBoundary
 )
     {
-      if (uiBoundingCUAddrSlice < uiBoundingCUAddrDependentSlice)
+      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
       {
         pcSlice->setNextSlice       ( true );
-        pcSlice->setNextDependentSlice( false );
-      }
-      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrDependentSlice)
+        pcSlice->setNextSliceSegment( false );
+      }
+      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
       {
         pcSlice->setNextSlice       ( false );
-        pcSlice->setNextDependentSlice( true );
+        pcSlice->setNextSliceSegment( true );
       }
       else
       {
         pcSlice->setNextSlice       ( true );
-        pcSlice->setNextDependentSlice( true );
+        pcSlice->setNextSliceSegment( true );
       }
     }
@@ -1787,15 +1865,13 @@
     {
       pcSlice->setNextSlice       ( false );
-      pcSlice->setNextDependentSlice( false );
+      pcSlice->setNextSliceSegment( false );
     }
   }
 }
 
-#if RECALCULATE_QP_ACCORDING_LAMBDA
 Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
 {
   return 4.2005*log(lambda) + 13.7122;
 }
-#endif
 
 //! \}
