Index: /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_2view+depth.cfg
===================================================================
--- /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_2view+depth.cfg	(revision 426)
+++ /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_2view+depth.cfg	(revision 427)
@@ -151,5 +151,6 @@
 ALFPicBasedEncode              : 1                                 # ALF LCU-based or picture-based encoding (0: LCU-based, 1: Picture-based)  
 MaxNumOffsetsPerPic            : 2048                              # default
-SAOInterleaving                : 0                                 # SAO interleaving flag (0: SAO parameter in APS, 1: SAO parameter in slice data) 
+SAOLcuBoundary              : 0                                 # 0: right/bottom LCU boundary areas skipped from SAO parameter estimation, 1: non-deblocked pixels are used for those areas
+SAOLcuBasedOptimization : 1                                  # 0: SAO picture-based optimization, 1: SAO LCU-based optimization
 ConstrainedIntraPred           : 0                                 # Constrained Intra Prediction
 weighted_pred_flag             : 0                                 # weighted prediction flag (P-Slices)
@@ -199,4 +200,6 @@
 FCO                        : 0                                     # Flexible coding order flag in 3DV
 FCOCodingOrder             : T0D0D1T1                              # Coding order for Flexible coding order in 3DV
+UseVSPCompensation         : 1                                     # Depth dependent tools: BVSP
+UseDVPRefine               : 1                                     # Depth dependent tools: DoNBDV
 
 
Index: /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_2view.cfg
===================================================================
--- /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_2view.cfg	(revision 426)
+++ /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_2view.cfg	(revision 427)
@@ -145,5 +145,6 @@
 ALFPicBasedEncode              : 1                                 # ALF LCU-based or picture-based encoding (0: LCU-based, 1: Picture-based)  
 MaxNumOffsetsPerPic            : 2048                              # default
-SAOInterleaving                : 0                                 # SAO interleaving flag (0: SAO parameter in APS, 1: SAO parameter in slice data) 
+SAOLcuBoundary              : 0                                 # 0: right/bottom LCU boundary areas skipped from SAO parameter estimation, 1: non-deblocked pixels are used for those areas
+SAOLcuBasedOptimization : 1                                  # 0: SAO picture-based optimization, 1: SAO LCU-based optimization
 ConstrainedIntraPred           : 0                                 # Constrained Intra Prediction
 weighted_pred_flag             : 0                                 # weighted prediction flag (P-Slices)
Index: /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_3view+depth.cfg
===================================================================
--- /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_3view+depth.cfg	(revision 426)
+++ /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_3view+depth.cfg	(revision 427)
@@ -155,5 +155,6 @@
 ALFPicBasedEncode              : 1                                 # ALF LCU-based or picture-based encoding (0: LCU-based, 1: Picture-based)  
 MaxNumOffsetsPerPic            : 2048                              # default
-SAOInterleaving                : 0                                 # SAO interleaving flag (0: SAO parameter in APS, 1: SAO parameter in slice data) 
+SAOLcuBoundary              : 0                                 # 0: right/bottom LCU boundary areas skipped from SAO parameter estimation, 1: non-deblocked pixels are used for those areas
+SAOLcuBasedOptimization : 1                                  # 0: SAO picture-based optimization, 1: SAO LCU-based optimization
 ConstrainedIntraPred           : 0                                 # Constrained Intra Prediction
 weighted_pred_flag             : 0                                 # weighted prediction flag (P-Slices)
@@ -203,5 +204,6 @@
 FCO                        : 0                                      # Flexible coding order flag in 3DV
 FCOCodingOrder             : T0D0D1D2T1T2                           # Coding order for Flexible coding order in 3DV
-
+UseVSPCompensation         : 1                                     # Depth dependent tools: BVSP
+UseDVPRefine               : 1                                     # Depth dependent tools: DoNBDV
 
 #========== depth coding tools ==========
Index: /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_3view.cfg
===================================================================
--- /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_3view.cfg	(revision 426)
+++ /branches/HTM-6.2-dev0/CommonTestConditionsCfgs/baseCfg_3view.cfg	(revision 427)
@@ -147,5 +147,6 @@
 ALFPicBasedEncode              : 1                                 # ALF LCU-based or picture-based encoding (0: LCU-based, 1: Picture-based)  
 MaxNumOffsetsPerPic            : 2048                              # default
-SAOInterleaving                : 0                                 # SAO interleaving flag (0: SAO parameter in APS, 1: SAO parameter in slice data) 
+SAOLcuBoundary              : 0                                 # 0: right/bottom LCU boundary areas skipped from SAO parameter estimation, 1: non-deblocked pixels are used for those areas
+SAOLcuBasedOptimization : 1                                  # 0: SAO picture-based optimization, 1: SAO LCU-based optimization 
 ConstrainedIntraPred           : 0                                 # Constrained Intra Prediction
 weighted_pred_flag             : 0                                 # weighted prediction flag (P-Slices)
Index: /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 427)
@@ -389,4 +389,8 @@
 #endif
 #endif
+#if MTK_D0156
+  ("UseVSPCompensation", m_bUseVSPCompensation,   true, "Depth dependent tools: BVSP" )
+  ("UseDVPRefine", m_bUseDVPRefine,   true, "Depth dependent tools: DoNBDV" )
+#endif
 
   /* Coding tools */
@@ -396,5 +400,10 @@
   ("SAO", m_abUseSAO, std::vector<Bool>(1, true), "SAO")
   ("MaxNumOffsetsPerPic", m_maxNumOffsetsPerPic, 2048, "2048: default")   
+#if LGE_SAO_MIGRATION_D0091
+  ("SAOLcuBoundary",          m_saoLcuBoundary,          false, "0: right/bottom LCU boundary areas skipped from SAO parameter estimation, 1: non-deblocked pixels are used for those areas")
+  ("SAOLcuBasedOptimization", m_saoLcuBasedOptimization, true, "0: SAO picture-based optimization, 1: SAO LCU-based optimization ")
+#else
   ("SAOInterleaving", m_saoInterleavingFlag, false, "0: SAO Picture Mode, 1: SAO Interleaving ")   
+#endif
 
   ("ALFEncodePassReduction", m_iALFEncodePassReduction, 0, "0:Original 16-pass, 1: 1-pass, 2: 2-pass encoding")
@@ -1637,5 +1646,9 @@
   printf("CIP:%d ", m_bUseConstrainedIntraPred);
   printf("PCM:%d ", (m_usePCM && (1<<m_uiPCMLog2MinSize) <= m_uiMaxCUWidth)? 1 : 0);
+#if LGE_SAO_MIGRATION_D0091
+  printf("SAOLcuBasedOptimization:%d ", (m_saoLcuBasedOptimization)?(1):(0));
+#else
   printf("SAOInterleaving:%d ", (m_saoInterleavingFlag)?(1):(0));
+#endif
 #if LOSSLESS_CODING
   printf("LosslessCuEnabled:%d ", (m_useLossless)? 1:0 );
@@ -1723,4 +1736,10 @@
   printf("DLT:%d ", m_bUseDLT ? 1 : 0 );
 #endif
+
+#if MTK_D0156
+  printf("BVSP:%d ", m_bUseVSPCompensation ? 1 : 0 );
+  printf("DoNBDV:%d ",  m_bUseDVPRefine ? 1 : 0 );
+#endif
+
 #if LGE_WVSO_A0119
   if ( m_bUseWVSO )
Index: /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncCfg.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncCfg.h	(revision 427)
@@ -165,5 +165,10 @@
 #endif
   Int       m_maxNumOffsetsPerPic;                            ///< SAO maximun number of offset per picture
+#if LGE_SAO_MIGRATION_D0091
+  Bool      m_saoLcuBoundary;                                 ///< SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
+  Bool      m_saoLcuBasedOptimization;                        ///< SAO LCU-based optimization
+#else
   Bool      m_saoInterleavingFlag;                            ///< SAO interleaving flag
+#endif
   // coding tools (loop filter)
   vector<Bool> m_abUseALF;                                    ///< flag for using adaptive loop filter [0] - video, [1] - depth
@@ -321,4 +326,13 @@
 #endif
 
+#if MTK_D0156
+
+#if MERL_VSP_COMPENSATION_C0152
+  Bool      m_bUseVSPCompensation;
+#endif
+
+  Bool      m_bUseDVPRefine;
+#endif
+
   // internal member functions
   Void  xSetGlobal      ();                                   ///< set global variables
Index: /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncTop.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/App/TAppEncoder/TAppEncTop.cpp	(revision 427)
@@ -230,4 +230,10 @@
 #endif
 #endif
+#if MTK_D0156
+#if MERL_VSP_COMPENSATION_C0152
+    m_acTEncTopList[iViewIdx]->setUseVSPCompensation           ( iViewIdx ? m_bUseVSPCompensation : 0 );
+#endif
+    m_acTEncTopList[iViewIdx]->setUseDVPRefine                  ( iViewIdx ? m_bUseDVPRefine : 0 );
+#endif
 
   //====== Tool list ========
@@ -308,5 +314,10 @@
 #endif
     m_acTEncTopList[iViewIdx]->setMaxNumOffsetsPerPic (m_maxNumOffsetsPerPic);
+#if LGE_SAO_MIGRATION_D0091
+    m_acTEncTopList[iViewIdx]->setSaoLcuBoundary (m_saoLcuBoundary);
+    m_acTEncTopList[iViewIdx]->setSaoLcuBasedOptimization (m_saoLcuBasedOptimization);
+#else
     m_acTEncTopList[iViewIdx]->setSaoInterleavingFlag (m_saoInterleavingFlag);
+#endif
     m_acTEncTopList[iViewIdx]->setPCMInputBitDepthFlag  ( m_bPCMInputBitDepthFlag); 
     m_acTEncTopList[iViewIdx]->setPCMFilterDisableFlag  ( m_bPCMFilterDisableFlag); 
@@ -573,4 +584,12 @@
 #endif
 #endif
+#if MTK_D0156
+
+#if MERL_VSP_COMPENSATION_C0152
+      m_acTEncDepthTopList[iViewIdx]->setUseVSPCompensation           ( iViewIdx ? true : false );
+#endif
+
+      m_acTEncDepthTopList[iViewIdx]->setUseDVPRefine                 ( iViewIdx ? true : false );
+#endif
 
       //====== Weighted Prediction ========
@@ -615,5 +634,10 @@
 #endif
       m_acTEncDepthTopList[iViewIdx]->setMaxNumOffsetsPerPic (m_maxNumOffsetsPerPic);
+#if LGE_SAO_MIGRATION_D0091
+      m_acTEncDepthTopList[iViewIdx]->setSaoLcuBoundary (m_saoLcuBoundary);
+      m_acTEncDepthTopList[iViewIdx]->setSaoLcuBasedOptimization (m_saoLcuBasedOptimization);
+#else
       m_acTEncDepthTopList[iViewIdx]->setSaoInterleavingFlag (m_saoInterleavingFlag);
+#endif
       m_acTEncDepthTopList[iViewIdx]->setPCMInputBitDepthFlag  ( m_bPCMInputBitDepthFlag); 
       m_acTEncDepthTopList[iViewIdx]->setPCMFilterDisableFlag  ( m_bPCMFilterDisableFlag); 
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/ContextTables.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/ContextTables.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/ContextTables.h	(revision 427)
@@ -101,4 +101,8 @@
 #define NUM_ALF_SVLC_CTX              3       ///< number of context models for ALF SVLC (filter coeff.)
 
+#if LGE_SAO_MIGRATION_D0091
+#define NUM_SAO_MERGE_FLAG_CTX        1       ///< number of context models for SAO merge flags
+#define NUM_SAO_TYPE_IDX_CTX          1       ///< number of context models for SAO type index
+#else
 #define NUM_SAO_FLAG_CTX              1       ///< number of context models for SAO flag
 #define NUM_SAO_UVLC_CTX              2       ///< number of context models for SAO UVLC
@@ -108,4 +112,5 @@
 #define NUM_SAO_MERGE_UP_FLAG_CTX     1       ///< number of context models for AO SVLC (filter coeff.)
 #define NUM_SAO_TYPE_IDX_CTX          2       ///< number of context models for AO SVLC (filter coeff.)
+#endif
 #define CNU                          154      ///< dummy initialization value for unused context models 'Context model Not Used'
 
@@ -376,5 +381,21 @@
   { 141,  154,  159, }, 
 };
-
+#if LGE_SAO_MIGRATION_D0091
+static const UChar
+INIT_SAO_MERGE_FLAG[3][NUM_SAO_MERGE_FLAG_CTX] =
+{
+  { 153,  },
+  { 153,  },
+  { 153,  },
+};
+
+static const UChar 
+INIT_SAO_TYPE_IDX[3][NUM_SAO_TYPE_IDX_CTX] = 
+{
+  { 200, },
+  { 185, },
+  { 160, },
+};
+#else
 static const UChar 
 INIT_SAO_FLAG[3][NUM_SAO_FLAG_CTX] =  
@@ -424,4 +445,5 @@
   { 200,  140, }, 
 };
+#endif
 
 static const UChar 
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComDataCU.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComDataCU.cpp	(revision 427)
@@ -53,7 +53,14 @@
 #if MERL_VSP_C0152
 
+#if MTK_D0156
+#define CHECK_ADD_YET(pcCURef,uiIdx,vspIdx) && ( (!m_pcSlice->getSPS()->getUseVSPCompensation()) || (!( (pcCURef)->getVSPIndex(uiIdx) == vspIdx && bVspMvZeroDone[vspIdx-1] )))
+#else
 #define CHECK_ADD_YET(pcCURef,uiIdx,vspIdx) && !( (pcCURef)->getVSPIndex(uiIdx) == vspIdx && bVspMvZeroDone[vspIdx-1] )
+#endif
 
 inline Void TComDataCU::xInheritVspMode( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo
+#if QC_BVSP_CleanUP_D0191
+  , UChar *puhInterDirNeighbours
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
     , Int*     iVSPDirTrue
@@ -61,4 +68,11 @@
     )
 {
+#if MTK_D0156
+    if( !m_pcSlice->getSPS()->getUseVSPCompensation() )
+    {
+        return;
+    }
+#endif
+
   Int vspIdx = (Int) pcCURef->getVSPIndex(uiIdx);
   if( vspIdx != 0 )
@@ -73,4 +87,7 @@
     if (vspIdx < 4)
     {
+#if QC_BVSP_CleanUP_D0191
+      puhInterDirNeighbours[ iCount] = 1;
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
       if(pDInfo->iN > 0 )
@@ -126,11 +143,30 @@
 }
 
-inline Bool TComDataCU::xAddVspMergeCand( UChar ucVspMergePos, Int vspIdx, Bool* bVspMvZeroDone, UInt uiDepth, Bool* abCandIsInter, Int& iCount,
-                                          UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDInfo
+inline Bool TComDataCU::xAddVspMergeCand(
+ UChar ucVspMergePos,
+#if !LGE_VSP_INHERIT_D0092
+ Int vspIdx,
+ Bool* bVspMvZeroDone,
+#endif
+ UInt uiDepth,
+ Bool* abCandIsInter,
+ Int& iCount,
+ UChar* puhInterDirNeighbours,
+ TComMvField* pcMvFieldNeighbours,
+ Int* iVSPIndexTrue,
+ Int mrgCandIdx,
+ DisInfo* pDInfo
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
-                                        , Int*  iVspDirTrue
+ , Int*  iVspDirTrue
 #endif
                                           )
 {
+#if MTK_D0156
+    if( !m_pcSlice->getSPS()->getUseVSPCompensation() )
+    {
+        return true;
+    }
+#endif
+
 #if MTK_LGE_VSP_DEPTH_OFF_D0105_D0139
   if (getSlice()->getSPS()->isDepth())
@@ -149,11 +185,19 @@
   if( ucVspMergePos == VSP_MERGE_POS )
   {
+#if !LGE_VSP_INHERIT_D0092
     Int idx = vspIdx - 1;
-    {
+#endif
+    {
+#if LGE_VSP_INHERIT_D0092
+      if( getSlice()->getSPS()->getViewId() != 0 )
+#else
       if( getSlice()->getSPS()->getViewId() != 0 && bVspMvZeroDone[idx] == false )
+#endif
       {
         {
           abCandIsInter [iCount] = true;
+#if !LGE_VSP_INHERIT_D0092
           bVspMvZeroDone[idx] = true;
+#endif
 
           // get Inter Dir
@@ -161,4 +205,19 @@
             (getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 0 ? 1 : 2));
           puhInterDirNeighbours[iCount] = iInterDir; // The direction information does not matter
+#if QC_BVSP_CleanUP_D0191
+         puhInterDirNeighbours[iCount] = 1;
+#endif
+#if LGE_VSP_INHERIT_D0092
+         Int iRefIdx = NOT_VALID;
+#if QC_BVSP_CleanUP_D0191
+         iRefIdx = getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==getSlice()->getPOC() ? 0: getSlice()->getNewRefIdx(REF_PIC_LIST_0);
+#endif
+         pcMvFieldNeighbours[iCount<<1].setMvField(pDInfo->m_acMvCand[0], iRefIdx );
+         if ( getSlice()->isInterB() )
+         {
+             pcMvFieldNeighbours[(iCount<<1)+1].setMvField( pDInfo->m_acMvCand[0], iRefIdx );
+         }
+         iVSPIndexTrue[iCount] = 1;
+#else
           // get Mv using checked disparity vector
           if (vspIdx < 4) // spatial
@@ -200,4 +259,5 @@
           }
           iVSPIndexTrue[idx] = iCount;
+#endif
           if ( mrgCandIdx == iCount )
           {
@@ -3239,6 +3299,25 @@
   UInt iNumbPart;
 
+#if SHARP_ILLUCOMP_PARSE_D0060
+  if (!(getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N))
+  {
+    return false;
+  }
+  if (getSlice()->getIcSkipParseFlag())
+  {
+    if (getMergeFlag(uiAbsPartIdx) && getMergeIndex(uiAbsPartIdx) == 0)
+    {
+      return false;
+    }
+  }
+  if (getMergeFlag(uiAbsPartIdx))
+  {
+    return true;
+  }
+#endif
+#if !SHARP_ILLUCOMP_PARSE_D0060
   if(!getSlice()->getIsDepth())
   {
+#endif
     Int iWidth, iHeight;
 
@@ -3261,4 +3340,5 @@
       }
     }
+#if !SHARP_ILLUCOMP_PARSE_D0060
   }
   else
@@ -3282,4 +3362,5 @@
     }
   }
+#endif
 
   return false;
@@ -3292,4 +3373,21 @@
   Int iWidth, iHeight;
 
+#if SHARP_ILLUCOMP_PARSE_D0060
+  if (!(getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N))
+  {
+    return false;
+  }
+  if (getSlice()->getIcSkipParseFlag())
+  {
+    if (getMergeFlag(uiAbsPartIdx) && getMergeIndex(uiAbsPartIdx) == 0)
+    {
+      return false;
+    }
+  }
+  if (getMergeFlag(uiAbsPartIdx))
+  {
+    return true;
+  }
+#endif
   UInt uiPartMode = getPartitionSize(uiAbsPartIdx);
 
@@ -3810,5 +3908,5 @@
   this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092
   Bool bVspMvZeroDone[3] = {false, false, false};
 #endif
@@ -3996,5 +4094,5 @@
         }
       }
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152  && !QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092
 #if !MTK_LGE_VSP_DEPTH_OFF_D0105_D0139
       xInheritVspMode( pcTextureCU, uiPartIdxCenter, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
@@ -4077,4 +4175,5 @@
 #endif //  H3D_IVMP
 
+#if !FIX_MERGE_D
 #if MERL_VSP_COMPENSATION_C0152
   //===== vsp 0 ===== 
@@ -4088,4 +4187,5 @@
       return;
 #endif
+#endif
 
   //left
@@ -4104,5 +4204,5 @@
   {
     if ( pcCULeft && !pcCULeft->isIntra( uiLeftPartIdx )
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092
       CHECK_ADD_YET(pcCULeft, uiLeftPartIdx, 1)
 #endif
@@ -4153,9 +4253,19 @@
 #endif
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+        if (pcCULeft->getVSPIndex(uiLeftPartIdx)==1)
+        {
+            iVSPIndexTrue[iCount] = 1;
+        }
+#else
         xInheritVspMode( pcCULeft, uiLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if QC_BVSP_CleanUP_D0191
+        ,puhInterDirNeighbours
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
          , iVSPDirTrue
 #endif
                 );
+#endif
 #endif
         if ( mrgCandIdx == iCount )
@@ -4182,5 +4292,5 @@
     }
   if ( pcCUAbove && !pcCUAbove->isIntra( uiAbovePartIdx ) 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092
     CHECK_ADD_YET(pcCUAbove, uiAbovePartIdx, 1)
 #endif
@@ -4230,9 +4340,19 @@
 #endif
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+    if (pcCUAbove->getVSPIndex(uiAbovePartIdx)==1)
+    {
+        iVSPIndexTrue[iCount] = 1;
+    }
+#else
      xInheritVspMode( pcCUAbove, uiAbovePartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if QC_BVSP_CleanUP_D0191
+        ,puhInterDirNeighbours
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
        , iVSPDirTrue
 #endif
              ) ;
+#endif
 #endif
     if ( mrgCandIdx == iCount )
@@ -4258,5 +4378,5 @@
   }
   if ( pcCUAboveRight && !pcCUAboveRight->isIntra( uiAboveRightPartIdx ) 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092
     CHECK_ADD_YET(pcCUAboveRight, uiAboveRightPartIdx, 1)
 #endif
@@ -4283,9 +4403,19 @@
 #endif
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+    if (pcCUAboveRight->getVSPIndex(uiAboveRightPartIdx)==1)
+    {
+        iVSPIndexTrue[iCount] = 1;
+    }
+#else
     xInheritVspMode( pcCUAboveRight, uiAboveRightPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if QC_BVSP_CleanUP_D0191
+        ,puhInterDirNeighbours
+#endif 
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
        , iVSPDirTrue
 #endif
             ) ;
+#endif
 #endif
     if ( mrgCandIdx == iCount )
@@ -4345,4 +4475,26 @@
 #endif // H3D_IVMP 
 
+#if MERL_VSP_COMPENSATION_C0152
+  //===== vsp 3 =====
+#if LGE_VSP_INHERIT_D0092
+    if ( !xAddVspMergeCand(3, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) )
+#else
+    if( iCount < 4 + extraMergeCand )
+        if ( !xAddVspMergeCand(3, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) )
+#endif
+            return;
+#endif
+
+#if MERL_VSP_C0152
+#if VSP_MERGE_POS < 4
+#if H3D_IVMP
+    if( iCount < 4 + extraMergeCand )
+#else
+    if( iCount < 4 )
+#endif
+    {
+#endif
+#endif
+
   //left bottom
   UInt uiLeftBottomPartIdx = 0;
@@ -4357,5 +4509,5 @@
   }
   if ( pcCULeftBottom && !pcCULeftBottom->isIntra( uiLeftBottomPartIdx ) 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092
     CHECK_ADD_YET(pcCULeftBottom, uiLeftBottomPartIdx, 1)
 #endif
@@ -4382,5 +4534,14 @@
 #endif
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+    if (pcCULeftBottom->getVSPIndex(uiLeftBottomPartIdx)==1)
+    {
+        iVSPIndexTrue[iCount] = 1;
+    }
+#else
     xInheritVspMode( pcCULeftBottom, uiLeftBottomPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if QC_BVSP_CleanUP_D0191
+        ,puhInterDirNeighbours
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
        , iVSPDirTrue
@@ -4388,4 +4549,5 @@
              ) ;
 #endif
+#endif
     if ( mrgCandIdx == iCount )
     {
@@ -4394,4 +4556,10 @@
     iCount ++;
   }
+
+#if MERL_VSP_C0152  // Is this correct here?
+#if VSP_MERGE_POS < 4
+    }
+#endif
+#endif
 
   // above left
@@ -4413,5 +4581,5 @@
     }
     if( pcCUAboveLeft && !pcCUAboveLeft->isIntra( uiAboveLeftPartIdx )
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092
      CHECK_ADD_YET(pcCUAboveLeft, uiAboveLeftPartIdx, 1)
 #endif
@@ -4440,9 +4608,19 @@
 #endif
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+    if (pcCUAboveLeft->getVSPIndex(uiAboveLeftPartIdx)==1)
+    {
+        iVSPIndexTrue[iCount] = 1;
+    }
+#else
       xInheritVspMode( pcCUAboveLeft, uiAboveLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if QC_BVSP_CleanUP_D0191
+        ,puhInterDirNeighbours
+#endif 
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
        , iVSPDirTrue
 #endif
              ) ;
+#endif
 #endif
       if ( mrgCandIdx == iCount )
@@ -4457,9 +4635,17 @@
   //===== vsp 5 =====
   if( iCount < 4 + extraMergeCand )
+#if LGE_VSP_INHERIT_D0092
+    if ( !xAddVspMergeCand(5, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) 
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+         , iVSPDirTrue
+#endif
+)
+#else
     if ( !xAddVspMergeCand(5, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
          , iVSPDirTrue
 #endif
-            ) )
+            ) 
+#endif
       return;
 #endif
@@ -4651,7 +4837,19 @@
 #if MERL_VSP_C0152
       Bool bValid = true;
+#if LGE_VSP_INHERIT_D0092
+      if (iVSPIndexTrue[i]==1 || iVSPIndexTrue[j]==1) // NOT_VALID
+#else
       if (pcMvFieldNeighbours[i<<1].getRefIdx() < 0 || pcMvFieldNeighbours[(j<<1)+1].getRefIdx() < 0) // NOT_VALID
+#endif
         bValid = false;
 #endif
+
+#if MTK_D0156
+      if( !m_pcSlice->getSPS()->getUseVSPCompensation())
+      {
+          bValid = true;
+      }
+#endif
+
       if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2)
 #if MERL_VSP_C0152
@@ -4822,5 +5020,5 @@
   {
     if( pcCorner && !pcCorner->isIntra( uiCornerPUIdx ) 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
      && !pcCorner->getVSPIndex( uiCornerPUIdx )
 #endif
@@ -4968,5 +5166,5 @@
     pcTmpCU = getPULeft(uiIdx, uiPartIdxLB, true, false);
   if(pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ) )
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
   if(! pcTmpCU->getVSPIndex(uiIdx))
 #endif
@@ -4993,5 +5191,5 @@
 
   if(pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ))
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
   if(! pcTmpCU->getVSPIndex(uiIdx))
 #endif
@@ -5018,5 +5216,5 @@
       pcTmpCU = getPUAboveRight(uiIdx, uiPartIdxRT, true, false, true);
   if(pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ) )
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
   if(! pcTmpCU->getVSPIndex(uiIdx))
 #endif
@@ -5042,5 +5240,5 @@
       pcTmpCU = getPUBelowLeft(uiIdx, uiPartIdxLB, true, false);
   if(pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ))
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
   if(! pcTmpCU->getVSPIndex(uiIdx))
 #endif
@@ -5069,5 +5267,5 @@
     assert(uiPartIdxLT == (m_uiAbsIdxInLCU + uiPartAddr));
   if(pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ))
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
   if(! pcTmpCU->getVSPIndex(uiIdx))
 #endif
@@ -5277,17 +5475,30 @@
   Int iPictureWidth  = pcBaseViewDepthPicYuv->getWidth();
   Int iPictureHeight = pcBaseViewDepthPicYuv->getHeight();
-
+#if !QC_BVSP_CleanUP_D0191
+#if LGE_ROUND_OFFSET_D0135
+  Int depthPosX = Clip3(0,   iPictureWidth - iBlkWidth,  iBlkX + ((mv->getHor()+2)>>2));
+  Int depthPosY = Clip3(0,   iPictureHeight- iBlkHeight,  iBlkY + ((mv->getVer()+2)>>2));
+#else
   Int depthPosX = Clip3(0,   iPictureWidth - iBlkWidth,  iBlkX + (mv->getHor()>>2));
   Int depthPosY = Clip3(0,   iPictureHeight- iBlkHeight,  iBlkY + (mv->getVer()>>2));
+#endif
 
   Pel *pDepthPel   = pcBaseViewDepthPicYuv->getLumaAddr() + depthPosX + depthPosY * depStride;
+#endif
   Pel  maxDepthVal = 0;
 
   if ( bSimpleDvpRefine )
   {
+#if LGE_ROUND_OFFSET_D0135
+    Int depthStartPosX = Clip3(0,   iPictureWidth - iBlkWidth,  iBlkX + ((mv->getHor()+2)>>2));
+    Int depthStartPosY = Clip3(0,   iPictureHeight- iBlkHeight,  iBlkY + ((mv->getVer()+2)>>2));
+    Int depthEndPosX   = Clip3(0,   iPictureWidth - 1,  iBlkX + iBlkWidth - 1 + ((mv->getHor()+2)>>2));
+    Int depthEndPosY   = Clip3(0,   iPictureHeight - 1,  iBlkY + iBlkHeight - 1 + ((mv->getVer()+2)>>2));
+#else
     Int depthStartPosX = Clip3(0,   iPictureWidth - iBlkWidth,  iBlkX + (mv->getHor()>>2));
     Int depthStartPosY = Clip3(0,   iPictureHeight- iBlkHeight,  iBlkY + (mv->getVer()>>2));
     Int depthEndPosX   = Clip3(0,   iPictureWidth - 1,  iBlkX + iBlkWidth - 1 + (mv->getHor()>>2));
     Int depthEndPosY   = Clip3(0,   iPictureHeight - 1,  iBlkY + iBlkHeight - 1 + (mv->getVer()>>2));
+#endif
 #if !MTK_DEPTH_TO_DISP_D0138
     Int iCenterX = (depthStartPosX + depthEndPosX) >> 1;
@@ -5312,4 +5523,5 @@
     }
   }
+#if !QC_BVSP_CleanUP_D0191
   else
   {
@@ -5324,4 +5536,5 @@
     }
   }
+#endif
 
   Int iDisp = aiShiftLUT[ maxDepthVal ] << iShiftPrec;
@@ -5425,5 +5638,5 @@
         }
       }
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
       else if (pcTmpCU->getVSPIndex(uiIdx) != 0) // is VSP
       { 
@@ -5576,4 +5789,11 @@
   }
 
+#if MTK_D0156
+  if( !m_pcSlice->getSPS()->getUseDVPRefine() )
+  {
+      bDepthRefine = false;
+  }
+#endif
+
   // Get Positions  
   PartSize eCUMode    = getPartitionSize( uiPartAddr );    
@@ -5927,6 +6147,13 @@
  */
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
 Void TComDataCU::fillMvpCand ( UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, AMVPInfo* pInfo, Int iMVPIdx)
 {
+    fillMvpCandBase(uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pInfo);
+}
+#else
+Void TComDataCU::fillMvpCand ( UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, AMVPInfo* pInfo, Int iMVPIdx)
+{
+
   if (!m_pcSlice->getSPS()->getViewId() || !m_pcSlice->getSPS()->getMultiviewMvPredMode())
   {
@@ -6014,4 +6241,5 @@
   }
 }
+#endif
 
 
@@ -6312,5 +6540,5 @@
   }
  
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152&!QC_BVSP_CleanUP_D0191
   if(pcTmpCU != NULL && pcTmpCU->getVSPIndex(uiIdx))
   {
@@ -6428,5 +6656,5 @@
   }
 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 &!QC_BVSP_CleanUP_D0191
   if(pcTmpCU->getVSPIndex(uiIdx))
   {
@@ -6591,5 +6819,5 @@
   TComDataCU *pColCU = pColPic->getCU( uiCUAddr );
   iColViewIdx = pColCU->getSlice()->getViewId();
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
   if( pColCU->getCUMvField(eColRefPicList)->getRefIdx(uiAbsPartAddr) < 0)
   {
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComDataCU.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComDataCU.h	(revision 427)
@@ -282,11 +282,26 @@
   Bool          xAddMVPCandOrder      ( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir );
 #if MERL_VSP_C0152
-  inline Bool   xAddVspMergeCand      ( UChar ucVspMergePos, Int vspIdx, Bool* bVspMvZeroDone, UInt uiDepth, Bool* abCandIsInter, Int& iCount,
-                                        UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDisInfo
+  inline Bool   xAddVspMergeCand      ( 
+ UChar ucVspMergePos,
+#if !LGE_VSP_INHERIT_D0092
+ Int vspIdx,
+ Bool* bVspMvZeroDone,
+#endif
+ UInt uiDepth,
+ Bool* abCandIsInter,
+ Int& iCount,
+ UChar* puhInterDirNeighbours,
+ TComMvField* pcMvFieldNeighbours,
+ Int* iVSPIndexTrue,
+ Int mrgCandIdx,
+ DisInfo* pDisInfo
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
-                                      , Int*   iVspDirTrue = NULL
+ , Int*   iVspDirTrue = NULL
 #endif
                                         );
   inline Void   xInheritVspMode       ( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo
+#if QC_BVSP_CleanUP_D0191
+   ,UChar *puhInterDirNeighbours
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
                                       , Int *iVSPDirTrue
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComLoopFilter.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComLoopFilter.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComLoopFilter.cpp	(revision 427)
@@ -428,5 +428,5 @@
   //-- Set BS for Intra MB : BS = 4 or 3
   if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
     || pcCUP->getVSPIndex(uiPartP) || pcCUQ->getVSPIndex(uiPartQ)
 #endif
@@ -438,5 +438,5 @@
   //-- Set BS for not Intra MB : BS = 2 or 1 or 0
   if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) 
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
     && !pcCUP->getVSPIndex(uiPartP) && !pcCUQ->getVSPIndex(uiPartQ)
 #endif
@@ -534,5 +534,5 @@
   }   // enf of "if( not Intra )"
   
-#if MERL_VSP_C0152
+#if MERL_VSP_C0152 & !QC_BVSP_CleanUP_D0191
   if ( pcCUP->getVSPIndex(uiPartP) || pcCUQ->getVSPIndex(uiPartQ))
   {
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComPrediction.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComPrediction.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComPrediction.cpp	(revision 427)
@@ -927,4 +927,5 @@
   if (vspIdx != 0)
   {
+#if !QC_BVSP_CleanUP_D0191
     if (iRefIdx >= 0)
     {
@@ -932,4 +933,5 @@
     }
     assert (iRefIdx < 0); // assert (iRefIdx == NOT_VALID);
+#endif
   }
   else
@@ -1784,6 +1786,11 @@
   Int dstStride = dstPic->getStride();
   Int depStride =  pPicBaseDepth->getStride();
+#if LGE_ROUND_OFFSET_D0135
+  Int depthPosX = Clip3(0,   widthLuma - sizeX,  (posX/nTxtPerDepthX) + ((mv->getHor()+2)>>2));
+  Int depthPosY = Clip3(0,   heightLuma- sizeY,  (posY/nTxtPerDepthY) + ((mv->getVer()+2)>>2));
+#else
   Int depthPosX = Clip3(0,   widthLuma - sizeX,  (posX/nTxtPerDepthX) + (mv->getHor()>>2));
   Int depthPosY = Clip3(0,   heightLuma- sizeY,  (posY/nTxtPerDepthY) + (mv->getVer()>>2));
+#endif
   Pel *ref    = refPic->getLumaAddr() + posX + posY * refStride;
   Pel *dst    = dstPic->getLumaAddr(partAddr);
@@ -2034,5 +2041,9 @@
     nTxtPerDepthX = widthChroma / widthDepth;
     nDepthPerTxtX = 1;
+#if LGE_ROUND_OFFSET_D0135
+    depthPosX = posX / nTxtPerDepthX + ((mv->getHor()+2)>>2);        //mv denotes the disparity for VSP
+#else
     depthPosX = posX / nTxtPerDepthX + (mv->getHor()>>2);        //mv denotes the disparity for VSP
+#endif
   }
   else
@@ -2040,5 +2051,9 @@
     nTxtPerDepthX = 1;
     nDepthPerTxtX = widthDepth / widthChroma;
+#if LGE_ROUND_OFFSET_D0135
+    depthPosX = posX * nDepthPerTxtX + ((mv->getHor()+2)>>2);        //mv denotes the disparity for VSP
+#else
     depthPosX = posX * nDepthPerTxtX + (mv->getHor()>>2);        //mv denotes the disparity for VSP
+#endif
   }
   depthPosX = Clip3(0, widthDepth - (sizeX<<1), depthPosX);
@@ -2047,5 +2062,9 @@
     nTxtPerDepthY = heightChroma / heightDepth;
     nDepthPerTxtY = 1;
+#if LGE_ROUND_OFFSET_D0135
+    depthPosY = posY / nTxtPerDepthY + ((mv->getVer()+2)>>2);     //mv denotes the disparity for VSP
+#else
     depthPosY = posY / nTxtPerDepthY + (mv->getVer()>>2);     //mv denotes the disparity for VSP
+#endif
   }
   else
@@ -2053,5 +2072,9 @@
     nTxtPerDepthY = 1;
     nDepthPerTxtY = heightDepth / heightChroma;
+#if LGE_ROUND_OFFSET_D0135
+    depthPosY = posY * nDepthPerTxtY + ((mv->getVer()+2)>>2);     //mv denotes the disparity for VSP
+#else
     depthPosY = posY * nDepthPerTxtY + (mv->getVer()>>2);     //mv denotes the disparity for VSP
+#endif
   }
   depthPosY = Clip3(0, heightDepth - (sizeY<<1), depthPosY);
@@ -2764,6 +2787,11 @@
   iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
   iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
+#if LGE_ROUND_OFFSET_D0135
+  iRefX   = iCUPelX + ((pMv->getHor()+2) >> 2);
+  iRefY   = iCUPelY + ((pMv->getVer()+2) >> 2);
+#else
   iRefX   = iCUPelX + (pMv->getHor() >> 2);
   iRefY   = iCUPelY + (pMv->getVer() >> 2);
+#endif
   uiWidth = pcCU->getWidth(0);
   uiHeight = pcCU->getHeight(0);
@@ -2777,5 +2805,9 @@
   if(pcCU->getPUAbove(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelY > 0 && iRefY > 0)
   {
+#if LGE_ROUND_OFFSET_D0135
+    iRefOffset = ( (pMv->getHor()+2) >> 2 ) + ( (pMv->getVer()+2) >> 2 ) * iRefStride - iRefStride;
+#else
     iRefOffset = ( pMv->getHor() >> 2 ) + ( pMv->getVer() >> 2 ) * iRefStride - iRefStride;
+#endif
     pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
     pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
@@ -2794,5 +2826,9 @@
   if(pcCU->getPULeft(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelX > 0 && iRefX > 0)
   {
+#if LGE_ROUND_OFFSET_D0135
+    iRefOffset = ( (pMv->getHor()+2) >> 2 ) + ( (pMv->getVer()+2) >> 2 ) * iRefStride - 1;
+#else
     iRefOffset = ( pMv->getHor() >> 2 ) + ( pMv->getVer() >> 2 ) * iRefStride - 1;
+#endif
     pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
     pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
@@ -2912,6 +2948,11 @@
   iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
   iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
+#if LGE_ROUND_OFFSET_D0135
+  iRefX   = iCUPelX + ((pMv->getHor()+2) >> 2);
+  iRefY   = iCUPelY + ((pMv->getVer()+2) >> 2);
+#else
   iRefX   = iCUPelX + (pMv->getHor() >> 2);
   iRefY   = iCUPelY + (pMv->getVer() >> 2);
+#endif
   uiWidth = pcCU->getWidth(0) >> 1;
   uiHeight = pcCU->getHeight(0) >> 1;
@@ -2925,5 +2966,9 @@
   if(pcCU->getPUAbove(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelY > 0 && iRefY > 0)
   {
+#if LGE_ROUND_OFFSET_D0135
+    iRefOffset = ( (pMv->getHor()+4) >> 3 ) + ( (pMv->getVer()+4) >> 3 ) * iRefStride - iRefStride;
+#else
     iRefOffset = ( pMv->getHor() >> 3 ) + ( pMv->getVer() >> 3 ) * iRefStride - iRefStride;
+#endif
     if (iChromaId == 0) // Cb
     {
@@ -2950,5 +2995,9 @@
   if(pcCU->getPULeft(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelX > 0 && iRefX > 0)
   {
+#if LGE_ROUND_OFFSET_D0135
+    iRefOffset = ( (pMv->getHor()+4) >> 3 ) + ( (pMv->getVer()+4) >> 3 ) * iRefStride - 1;
+#else
     iRefOffset = ( pMv->getHor() >> 3 ) + ( pMv->getVer() >> 3 ) * iRefStride - 1;
+#endif
     if (iChromaId == 0) // Cb
     {
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp	(revision 427)
@@ -62,5 +62,7 @@
 TComSampleAdaptiveOffset::TComSampleAdaptiveOffset()
 {
+#if !LGE_SAO_MIGRATION_D0091
   m_pcPic = NULL;
+#endif
   m_iOffsetBo = NULL;
   m_pClipTable = NULL;
@@ -71,5 +73,7 @@
   m_iUpBufft = NULL;
   ipSwap = NULL;
+#if !LGE_SAO_MIGRATION_D0091
   m_pcYuvTmp = NULL;
+#endif
 
   m_pTmpU1 = NULL;
@@ -85,4 +89,5 @@
 }
 
+#if !LGE_SAO_MIGRATION_D0091
 const Int TComSampleAdaptiveOffset::m_aiNumPartsInRow[5] =
 {
@@ -102,4 +107,5 @@
   256  //level 4
 };
+#endif
 
 const Int TComSampleAdaptiveOffset::m_aiNumCulPartsLevel[5] =
@@ -124,5 +130,5 @@
   0
 };
-
+#if !LGE_SAO_MIGRATION_D0091
 const UInt TComSampleAdaptiveOffset::m_iWeightSao[MAX_NUM_SAO_TYPE] =
 {
@@ -146,4 +152,5 @@
   6
 };
+#endif
 
 Int TComSampleAdaptiveOffset::m_iNumClass[MAX_NUM_SAO_TYPE] =
@@ -187,4 +194,5 @@
   return idx;
 }
+#if !LGE_SAO_MIGRATION_D0091
 /** convert quadtree Idx to Level, Row, and Col
  * \param  idx,  *level,  *row,  *col
@@ -223,4 +231,5 @@
   }
 }
+#endif
 /** create SampleAdaptiveOffset memory.
  * \param 
@@ -317,5 +326,21 @@
   }
 
-
+#if LGE_SAO_MIGRATION_D0091
+  if (m_iUpBuff1)
+  {
+      m_iUpBuff1--;
+      delete [] m_iUpBuff1; m_iUpBuff1 = NULL;
+  }
+  if (m_iUpBuff2)
+  {
+      m_iUpBuff2--;
+      delete [] m_iUpBuff2; m_iUpBuff2 = NULL;
+  }
+  if (m_iUpBufft)
+  {
+      m_iUpBufft--;
+      delete [] m_iUpBufft; m_iUpBufft = NULL;
+  }
+#else
   m_iUpBuff1--;
   m_iUpBuff2--;
@@ -334,4 +359,5 @@
     delete [] m_iUpBufft; m_iUpBufft = NULL;
   }
+#endif
   if (m_pTmpL1)
   {
@@ -368,8 +394,10 @@
   initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1,  0, m_iNumCuInHeight-1,1);
   initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1,  0, m_iNumCuInHeight-1,2);
+#if !LGE_SAO_MIGRATION_D0091
   for(Int j=0;j<MAX_NUM_SAO_TYPE;j++)
   {
     pcSaoParam->iNumClass[j] = m_iNumClass[j];
   }
+#endif
   pcSaoParam->numCuInWidth  = m_iNumCuInWidth;
   pcSaoParam->numCuInHeight = m_iNumCuInHeight;
@@ -405,5 +433,9 @@
   pSaoPart->iLength     =  0;
 
+#if LGE_SAO_MIGRATION_D0091
+  pSaoPart->subTypeIdx = 0;
+#else
   pSaoPart->bandPosition = 0;
+#endif
 
   for (j=0;j<MAX_NUM_SAO_OFFSETS;j++)
@@ -514,5 +546,12 @@
   for(Int c=0; c<iNumComponet; c++)
   {
+#if LGE_SAO_MIGRATION_D0091
+    if (c<2)
+    {
     pcSaoParam->bSaoFlag[c] = 0;
+    }
+#else
+    pcSaoParam->bSaoFlag[c] = 0;
+#endif
     for(Int i=0; i< m_aiNumCulPartsLevel[m_uiMaxSplitLevel]; i++)
     {
@@ -524,5 +563,9 @@
       pcSaoParam->psSaoPart[c][i].iMinDist      = MAX_INT;
       pcSaoParam->psSaoPart[c][i].iMinRate      = MAX_INT;
+#if LGE_SAO_MIGRATION_D0091
+      pcSaoParam->psSaoPart[c][i].subTypeIdx    = 0;
+#else
       pcSaoParam->psSaoPart[c][i].bandPosition = 0;
+#endif
       for (Int j=0;j<MAX_NUM_SAO_OFFSETS;j++)
       {
@@ -557,5 +600,9 @@
   m_pcPic   = pcPic;
   m_uiNumSlicesInPic = numSlicesInPic;
+#if LGE_SAO_MIGRATION_D0091
+  m_iSGDepth         = 0;
+#else
   m_iSGDepth         = pcPic->getSliceGranularityForNDBFilter();
+#endif
   m_bUseNIF = ( pcPic->getIndependentSliceBoundaryForNDBFilter() || pcPic->getIndependentTileBoundaryForNDBFilter() );
   if(m_bUseNIF)
@@ -958,5 +1005,4 @@
           uiEdgeType = iSignDown + m_iUpBuff1[x] + 2;
           m_iUpBuff1[x]= -iSignDown;
-
           pRec[x] = m_pClipTable[pRec[x] + m_iOffsetEo[uiEdgeType]];
         }
@@ -1065,5 +1111,9 @@
 Void TComSampleAdaptiveOffset::SAOProcess(TComPic* pcPic, SAOParam* pcSaoParam)
 {
+#if LGE_SAO_MIGRATION_D0091
+  if (pcSaoParam->bSaoFlag[0] || pcSaoParam->bSaoFlag[1])
+#else
   if (pcSaoParam->bSaoFlag[0])
+#endif
   {
 #if FULL_NBIT
@@ -1077,6 +1127,9 @@
       m_pcPic->getPicYuvRec()->copyToPic(m_pcYuvTmp);
     }
-
+#if LGE_SAO_MIGRATION_D0091
+    if (m_saoLcuBasedOptimization)
+#else
     if (m_saoInterleavingFlag)
+#endif
     {
       pcSaoParam->oneUnitFlag[0] = 0;  
@@ -1085,4 +1138,15 @@
     }
     Int iY  = 0;
+#if LGE_SAO_MIGRATION_D0091
+    if (pcSaoParam->bSaoFlag[0])
+    {
+        processSaoUnitAll( pcSaoParam->saoLcuParam[iY], pcSaoParam->oneUnitFlag[iY], iY);
+    }
+    if(pcSaoParam->bSaoFlag[1])
+    {
+        processSaoUnitAll( pcSaoParam->saoLcuParam[1], pcSaoParam->oneUnitFlag[1], 1);//Cb
+        processSaoUnitAll( pcSaoParam->saoLcuParam[2], pcSaoParam->oneUnitFlag[2], 2);//Cr
+    }
+#else
     processSaoUnitAll( pcSaoParam->saoLcuParam[iY], pcSaoParam->oneUnitFlag[iY], iY);
 
@@ -1097,6 +1161,5 @@
       processSaoUnitAll( pcSaoParam->saoLcuParam[iCr], pcSaoParam->oneUnitFlag[iCr], iCr);
     }
-
-
+#endif
     m_pcPic = NULL;
   }
@@ -1154,5 +1217,9 @@
   Int  typeIdx;
 
+#if LGE_SAO_MIGRATION_D0091
+  Int offset[LUMA_GROUP_NUM+1];
+#else
   static Int offset[LUMA_GROUP_NUM+1];
+#endif
   Int idxX;
   Int idxY;
@@ -1164,6 +1231,7 @@
   Int isChroma = (yCbCr == 0) ? 0:1;
   Bool mergeLeftFlag;
-
-
+#if LGE_SAO_MIGRATION_D0091
+  offset[0] = 0;
+#endif
   for (idxY = 0; idxY< frameHeightInCU; idxY++)
   { 
@@ -1201,5 +1269,4 @@
     {
       addr = idxY * frameWidthInCU + idxX;
-
       if (oneUnitFlag)
       {
@@ -1225,5 +1292,9 @@
             for (i=0; i<saoLcuParam[addr].length; i++)
             {
+#if LGE_SAO_MIGRATION_D0091
+              offset[ (saoLcuParam[addr].subTypeIdx +i)%SAO_MAX_BO_CLASSES  +1] = saoLcuParam[addr].offset[i] << m_uiSaoBitIncrease;
+#else
               offset[ (saoLcuParam[addr].bandPosition +i)%SAO_MAX_BO_CLASSES  +1] = saoLcuParam[addr].offset[i] << m_uiSaoBitIncrease;
+#endif
             }
 
@@ -1304,5 +1375,9 @@
       saoLcuParam[i].offset[j] = 0;
     }
+#if LGE_SAO_MIGRATION_D0091
+    saoLcuParam[i].subTypeIdx   = 0;
+#else
     saoLcuParam[i].bandPosition = 0;
+#endif
   }
 }
@@ -1353,5 +1428,9 @@
       saoLcuParam[addr].partIdxTmp = (Int)partIdx; 
       saoLcuParam[addr].typeIdx    = saoQTPart[partIdx].iBestType;
+#if LGE_SAO_MIGRATION_D0091
+      saoLcuParam[addr].subTypeIdx   = saoQTPart[partIdx].subTypeIdx;
+#else
       saoLcuParam[addr].bandPosition = saoQTPart[partIdx].bandPosition;
+#endif
       if (saoLcuParam[addr].typeIdx!=-1)
       {
@@ -1365,5 +1444,9 @@
       {
         saoLcuParam[addr].length    = 0;
+#if LGE_SAO_MIGRATION_D0091
+        saoLcuParam[addr].subTypeIdx = saoQTPart[partIdx].subTypeIdx;
+#else
         saoLcuParam[addr].bandPosition = saoQTPart[partIdx].bandPosition;
+#endif
         for (j=0;j<MAX_NUM_SAO_OFFSETS;j++)
         {
@@ -1375,5 +1458,174 @@
 }
 
-
-
+#if LGE_SAO_MIGRATION_D0091
+Void TComSampleAdaptiveOffset::resetSaoUnit(SaoLcuParam* saoUnit)
+{
+  saoUnit->partIdx       = 0;
+  saoUnit->partIdxTmp    = 0;
+  saoUnit->mergeLeftFlag = 0;
+  saoUnit->mergeUpFlag   = 0;
+  saoUnit->typeIdx       = -1;
+  saoUnit->length        = 0;
+  saoUnit->subTypeIdx    = 0;
+
+  for (Int i=0;i<4;i++)
+  {
+    saoUnit->offset[i] = 0;
+  }
+}
+
+Void TComSampleAdaptiveOffset::copySaoUnit(SaoLcuParam* saoUnitDst, SaoLcuParam* saoUnitSrc )
+{
+  saoUnitDst->mergeLeftFlag = saoUnitSrc->mergeLeftFlag;
+  saoUnitDst->mergeUpFlag   = saoUnitSrc->mergeUpFlag;
+  saoUnitDst->typeIdx       = saoUnitSrc->typeIdx;
+  saoUnitDst->length        = saoUnitSrc->length;
+
+  saoUnitDst->subTypeIdx  = saoUnitSrc->subTypeIdx;
+  for (Int i=0;i<4;i++)
+  {
+    saoUnitDst->offset[i] = saoUnitSrc->offset[i];
+  }
+}
+
+/** PCM LF disable process. 
+ * \param pcPic picture (TComPic) pointer
+ * \returns Void
+ *
+ * \note Replace filtered sample values of PCM mode blocks with the transmitted and reconstructed ones.
+ */
+Void TComSampleAdaptiveOffset::PCMLFDisableProcess (TComPic* pcPic)
+{
+  xPCMRestoration(pcPic);
+}
+
+/** Picture-level PCM restoration. 
+ * \param pcPic picture (TComPic) pointer
+ * \returns Void
+ */
+Void TComSampleAdaptiveOffset::xPCMRestoration(TComPic* pcPic)
+{
+  Bool  bPCMFilter = (pcPic->getSlice(0)->getSPS()->getUsePCM() && pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag())? true : false;
+#if LOSSLESS_CODING
+  if(bPCMFilter || pcPic->getSlice(0)->getSPS()->getUseLossless())
+#else
+  if(bPCMFilter)
+#endif
+  {
+      for( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame() ; uiCUAddr++ )
+      {
+          TComDataCU* pcCU = pcPic->getCU(uiCUAddr);
+          xPCMCURestoration(pcCU, 0, 0); 
+      } 
+  }
+}
+
+/** PCM CU restoration. 
+ * \param pcCU pointer to current CU
+ * \param uiAbsPartIdx part index
+ * \param uiDepth CU depth
+ * \returns Void
+ */
+Void TComSampleAdaptiveOffset::xPCMCURestoration ( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth )
+{
+  TComPic* pcPic     = pcCU->getPic();
+  UInt uiCurNumParts = pcPic->getNumPartInCU() >> (uiDepth<<1);
+  UInt uiQNumParts   = uiCurNumParts>>2;
+
+  // go to sub-CU
+  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
+  {
+    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
+    {
+      UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
+      UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
+      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
+        xPCMCURestoration( pcCU, uiAbsZorderIdx, uiDepth+1 );
+    }
+    return;
+  }
+
+  // restore PCM samples
+  if ((pcCU->getIPCMFlag(uiAbsZorderIdx)&& pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag()) || pcCU->isLosslessCoded( uiAbsZorderIdx))
+  {
+    xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, TEXT_LUMA    );
+    xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, TEXT_CHROMA_U);
+    xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, TEXT_CHROMA_V);
+  }
+}
+
+/** PCM sample restoration. 
+ * \param pcCU pointer to current CU
+ * \param uiAbsPartIdx part index
+ * \param uiDepth CU depth
+ * \param ttText texture component type
+ * \returns Void
+ */
+Void TComSampleAdaptiveOffset::xPCMSampleRestoration (TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, TextType ttText)
+{
+  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
+  Pel* piSrc;
+  Pel* piPcm;
+  UInt uiStride;
+  UInt uiWidth;
+  UInt uiHeight;
+  UInt uiPcmLeftShiftBit; 
+  UInt uiX, uiY;
+  UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
+  UInt uiLumaOffset   = uiMinCoeffSize*uiAbsZorderIdx;
+  UInt uiChromaOffset = uiLumaOffset>>2;
+
+  if( ttText == TEXT_LUMA )
+  {
+    piSrc = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx);
+    piPcm = pcCU->getPCMSampleY() + uiLumaOffset;
+    uiStride  = pcPicYuvRec->getStride();
+    uiWidth  = (g_uiMaxCUWidth >> uiDepth);
+    uiHeight = (g_uiMaxCUHeight >> uiDepth);
+    if ( pcCU->isLosslessCoded(uiAbsZorderIdx) )
+    {
+      uiPcmLeftShiftBit = 0;
+    }
+    else
+    {
+        uiPcmLeftShiftBit = g_uiBitDepth + g_uiBitIncrement - pcCU->getSlice()->getSPS()->getPCMBitDepthLuma();
+    }
+  }
+  else
+  {
+    if( ttText == TEXT_CHROMA_U )
+    {
+      piSrc = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
+      piPcm = pcCU->getPCMSampleCb() + uiChromaOffset;
+    }
+    else
+    {
+      piSrc = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
+      piPcm = pcCU->getPCMSampleCr() + uiChromaOffset;
+    }
+
+    uiStride = pcPicYuvRec->getCStride();
+    uiWidth  = ((g_uiMaxCUWidth >> uiDepth)/2);
+    uiHeight = ((g_uiMaxCUWidth >> uiDepth)/2);
+    if ( pcCU->isLosslessCoded(uiAbsZorderIdx) )
+    {
+      uiPcmLeftShiftBit = 0;
+    }
+    else
+    {
+      uiPcmLeftShiftBit = g_uiBitDepth + g_uiBitIncrement - pcCU->getSlice()->getSPS()->getPCMBitDepthChroma();
+    }
+  }
+
+  for( uiY = 0; uiY < uiHeight; uiY++ )
+  {
+    for( uiX = 0; uiX < uiWidth; uiX++ )
+    {
+      piSrc[uiX] = (piPcm[uiX] << uiPcmLeftShiftBit);
+    }
+    piPcm += uiWidth;
+    piSrc += uiStride;
+  }
+}
+#endif
 //! \}
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSampleAdaptiveOffset.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSampleAdaptiveOffset.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSampleAdaptiveOffset.h	(revision 427)
@@ -65,10 +65,14 @@
 
   static UInt m_uiMaxDepth;
+#if !LGE_SAO_MIGRATION_D0091
   static const Int m_aiNumPartsInRow[5];
   static const Int m_aiNumPartsLevel[5];
+#endif
   static const Int m_aiNumCulPartsLevel[5];
   static const UInt m_auiEoTable[9];
+#if !LGE_SAO_MIGRATION_D0091
   static const UInt m_auiEoTable2D[9];
   static const UInt m_iWeightSao[MAX_NUM_SAO_TYPE];
+#endif
   Int *m_iOffsetBo;
   Int m_iOffsetEo[LUMA_GROUP_NUM];
@@ -107,5 +111,14 @@
   Int* m_iLcuPartIdx;
   Int     m_maxNumOffsetsPerPic;
+#if LGE_SAO_MIGRATION_D0091
+  Bool    m_saoLcuBoundary;
+  Bool    m_saoLcuBasedOptimization;
+
+  Void xPCMRestoration        (TComPic* pcPic);
+  Void xPCMCURestoration      (TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth);
+  Void xPCMSampleRestoration  (TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, TextType ttText);
+#else
   Bool    m_saoInterleavingFlag;
+#endif
 public:
   TComSampleAdaptiveOffset         ();
@@ -116,15 +129,24 @@
 
   Int  convertLevelRowCol2Idx(int level, int row, int col);
+#if !LGE_SAO_MIGRATION_D0091
   void convertIdx2LevelRowCol(int idx, int *level, int *row, int *col);
+#endif
 
   Void initSAOParam   (SAOParam *pcSaoParam, Int iPartLevel, Int iPartRow, Int iPartCol, Int iParentPartIdx, Int StartCUX, Int EndCUX, Int StartCUY, Int EndCUY, Int iYCbCr);
   Void allocSaoParam  (SAOParam* pcSaoParam);
   Void resetSAOParam  (SAOParam *pcSaoParam);
+#if LGE_SAO_MIGRATION_D0091
+  static Void freeSaoParam   (SAOParam *pcSaoParam);
+#else
   Void freeSaoParam   (SAOParam *pcSaoParam);
+#endif
+  
 
   Void SAOProcess(TComPic* pcPic, SAOParam* pcSaoParam);
   Void processSaoCu(Int iAddr, Int iSaoType, Int iYCbCr);
+#if !LGE_SAO_MIGRATION_D0091
   Void processSaoOnePart(SAOQTPart *psQTPart, UInt uiPartIdx, Int iYCbCr);
   Void processSaoQuadTree(SAOQTPart *psQTPart, UInt uiPartIdx, Int iYCbCr);
+#endif
   Pel* getPicYuvAddr(TComPicYuv* pcPicYuv, Int iYCbCr,Int iAddr = 0);
 
@@ -138,6 +160,16 @@
   Void convertOnePart2SaoUnit(SAOParam *saoParam, UInt partIdx, Int yCbCr);
   Void processSaoUnitAll(SaoLcuParam* saoLcuParam, Bool oneUnitFlag, Int yCbCr);
+#if LGE_SAO_MIGRATION_D0091
+  Void setSaoLcuBoundary (Bool bVal)  {m_saoLcuBoundary = bVal;}
+  Bool getSaoLcuBoundary ()           {return m_saoLcuBoundary;}
+  Void setSaoLcuBasedOptimization (Bool bVal)  {m_saoLcuBasedOptimization = bVal;}
+  Bool getSaoLcuBasedOptimization ()           {return m_saoLcuBasedOptimization;}
+  Void resetSaoUnit(SaoLcuParam* saoUnit);
+  Void copySaoUnit(SaoLcuParam* saoUnitDst, SaoLcuParam* saoUnitSrc );
+  Void PCMLFDisableProcess    ( TComPic* pcPic);                        ///< interface function for ALF process 
+#else
   Void setSaoInterleavingFlag (Bool bVal)  {m_saoInterleavingFlag = bVal;}
   Bool getSaoInterleavingFlag ()           {return m_saoInterleavingFlag;}
+#endif
 };
 
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSlice.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSlice.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSlice.cpp	(revision 427)
@@ -113,4 +113,7 @@
 #if LGE_ILLUCOMP_B0045
 , m_bApplyIC                      ( false )
+#if SHARP_ILLUCOMP_PARSE_D0060
+, m_icSkipParseFlag               ( false )
+#endif
 #endif
 #if INTER_VIEW_VECTOR_SCALING_C0115
@@ -822,7 +825,11 @@
 
   m_saoEnabledFlag = pSrc->m_saoEnabledFlag; 
+#if LGE_SAO_MIGRATION_D0091
+  m_saoEnabledFlagChroma = pSrc->m_saoEnabledFlagChroma;
+#else
   m_saoInterleavingFlag = pSrc->m_saoInterleavingFlag;
   m_saoEnabledFlagCb = pSrc->m_saoEnabledFlagCb;
   m_saoEnabledFlagCr = pSrc->m_saoEnabledFlagCr; 
+#endif
 #if CABAC_INIT_FLAG
   m_cabacInitFlag                = pSrc->m_cabacInitFlag;
@@ -831,4 +838,8 @@
 
   m_bLMvdL1Zero = pSrc->m_bLMvdL1Zero;
+#if SHARP_ILLUCOMP_PARSE_D0060
+  m_bApplyIC = pSrc->m_bApplyIC;
+  m_icSkipParseFlag = pSrc->m_icSkipParseFlag;
+#endif
 }
 
@@ -2109,5 +2120,7 @@
   m_scalingList = src.m_scalingList;
   m_scalingListEnabled = src.m_scalingListEnabled;
+#if !LGE_SAO_MIGRATION_D0091
   m_saoInterleavingFlag = src.m_saoInterleavingFlag;
+#endif
 
   return *this;
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSlice.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComSlice.h	(revision 427)
@@ -180,4 +180,12 @@
   Bool          m_bIVScalingFlag;
 #endif
+
+#if MTK_D0156
+#if MERL_VSP_COMPENSATION_C0152
+  Bool      m_abUseVSPCompensation[ MAX_TLAYER ];
+#endif
+  Bool      m_abUseDVPRefine[ MAX_TLAYER ];
+#endif
+
 public:
   TComVPS();
@@ -245,4 +253,13 @@
   
 #endif 
+
+#if MTK_D0156
+#if MERL_VSP_COMPENSATION_C0152
+  Bool    getUseVSPCompensation( UInt tLayer ){  return m_abUseVSPCompensation[ tLayer ];}
+  Void    setUseVSPCompensation( Bool bValue, UInt tLayer ){ m_abUseVSPCompensation[ tLayer ] = bValue;}
+#endif
+  Bool    getUseDVPRefine( UInt tLayer ){  return m_abUseDVPRefine[ tLayer ];}
+  Void    setUseDVPRefine( Bool bValue, UInt tLayer ){ m_abUseDVPRefine[ tLayer ] = bValue;}
+#endif
 };
 
@@ -403,4 +420,11 @@
 #if H3D_IVRP & !QC_ARP_D0177
   TComResidualGenerator* m_pcResidualGenerator;
+#endif
+
+#if MTK_D0156
+#if MERL_VSP_COMPENSATION_C0152
+  Bool      m_bUseVSPCompensation;
+#endif
+  Bool      m_bUseDVPRefine;
 #endif
 
@@ -681,4 +705,16 @@
   TComResidualGenerator*  getResidualGenerator()                                              { return m_pcResidualGenerator; }
 #endif
+
+#if MTK_D0156
+
+#if MERL_VSP_COMPENSATION_C0152
+  Bool    getUseVSPCompensation( ){  return m_bUseVSPCompensation;}
+  Void    setUseVSPCompensation( Bool bValue ){ m_bUseVSPCompensation = bValue;}
+#endif
+
+  Bool    getUseDVPRefine( ){  return m_bUseDVPRefine;}
+  Void    setUseDVPRefine( Bool bValue ){ m_bUseDVPRefine = bValue;}
+
+#endif
 };
 
@@ -940,6 +976,8 @@
   Bool      getScalingListEnabled ()          { return m_scalingListEnabled; }  //!< get ScalingList enabled/disabled in APS
   TComScalingList* getScalingList ()          { return m_scalingList; }         //!< get ScalingList class pointer in APS
+#if !LGE_SAO_MIGRATION_D0091
   Bool     getSaoInterleavingFlag() {return m_saoInterleavingFlag;}             //!< get SAO interleaving flag in APS
   Void     setSaoInterleavingFlag(Bool bVal) {m_saoInterleavingFlag = bVal;}    //!< set SAO interleaving flag in APS
+#endif
 
 private:
@@ -955,5 +993,7 @@
   Bool        m_scalingListEnabled;     //!< ScalingList enabled/disabled in APS (true for enabled)
   TComScalingList*     m_scalingList;   //!< ScalingList class pointer
+#if !LGE_SAO_MIGRATION_D0091
   Bool        m_saoInterleavingFlag;    //!< SAO interleaving flag
+#endif
 
 public:
@@ -987,7 +1027,11 @@
   bool       m_alfEnabledFlag;
   bool       m_saoEnabledFlag;
+#if LGE_SAO_MIGRATION_D0091
+  bool       m_saoEnabledFlagChroma;      ///< SAO Cb&Cr enabled flag
+#else
   bool       m_saoInterleavingFlag;   ///< SAO interleaving flag
   bool       m_saoEnabledFlagCb;      ///< SAO Cb enabled flag
   bool       m_saoEnabledFlagCr;      ///< SAO Cr enabled flag
+#endif
   Int         m_iPPSId;               ///< picture parameter set ID
   Bool        m_PicOutputFlag;        ///< pic_output_flag 
@@ -1118,4 +1162,7 @@
 #if LGE_ILLUCOMP_B0045
   Bool        m_bApplyIC;
+#if SHARP_ILLUCOMP_PARSE_D0060
+  Bool        m_icSkipParseFlag;
+#endif
 #endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
@@ -1181,4 +1228,8 @@
   Void      setSaoEnabledFlag(Bool s) {m_saoEnabledFlag =s; }
   Bool      getSaoEnabledFlag() { return m_saoEnabledFlag; }
+#if LGE_SAO_MIGRATION_D0091
+  Void      setSaoEnabledFlagChroma(Bool s) {m_saoEnabledFlagChroma =s; }       //!< set SAO Cb&Cr enabled flag
+  Bool      getSaoEnabledFlagChroma() { return m_saoEnabledFlagChroma; }        //!< get SAO Cb&Cr enabled flag
+#else
   Void      setSaoInterleavingFlag(Bool s) {m_saoInterleavingFlag =s; } //!< set SAO interleaving flag
   Bool      getSaoInterleavingFlag() { return m_saoInterleavingFlag;  } //!< get SAO interleaving flag
@@ -1187,4 +1238,5 @@
   Void      setSaoEnabledFlagCr(Bool s) {m_saoEnabledFlagCr =s; }       //!< set SAO Cr enabled flag
   Bool      getSaoEnabledFlagCr() { return m_saoEnabledFlagCr; }        //!< get SAO Cr enabled flag
+#endif
   Void      setRPS          ( TComReferencePictureSet *pcRPS ) { m_pcRPS = pcRPS; }
   TComReferencePictureSet*  getRPS          () { return m_pcRPS; }
@@ -1429,4 +1481,8 @@
   Bool      getApplyIC            ()  { return m_bApplyIC; }
   Void      xSetApplyIC           ();
+#if SHARP_ILLUCOMP_PARSE_D0060
+  Void      setIcSkipParseFlag( Bool b ) { m_icSkipParseFlag = b; }
+  Bool      getIcSkipParseFlag() { return m_icSkipParseFlag; }
+#endif
 #endif
 #if QC_TMVP_MRG_REFIDX_C0047
Index: /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TypeDef.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibCommon/TypeDef.h	(revision 427)
@@ -84,4 +84,5 @@
                                               // QC_C0051_FIXED_BY_MTK             1   // Bug fix for C0051 implementation
                                               // QC_AMVP_MRG_UNIFY_IVCAN_C0051     1
+#define SEC_TWO_CANDIDATES_FOR_AMVP_D0122 1   // SEC_TWO_CANDIDATES_FOR_AMVP_D0122, fixing # of AMVP candidates 3 to 2
 
 
@@ -151,4 +152,6 @@
 #endif
 
+#define SHARP_ILLUCOMP_PARSE_D0060        1   // JCT3V-D0060 Removal of IC's parsing dependency
+
 ///// ***** INTERVIEW SKIP *********
 #define HHI_INTERVIEW_SKIP                1
@@ -167,4 +170,19 @@
 #define FIX_APPENCTOP_T_ONLY              1   // For Texture-only coding
 
+#define LGE_ROUND_OFFSET_D0135            1   // JCT3V-D0135 Rounding offset
+#define LGE_SAO_MIGRATION_D0091           1
+#if LGE_SAO_MIGRATION_D0091
+#define SAO_SKIP_RIGHT                   1  ///< H1101: disallow using unavailable pixel during RDO
+#define SAO_ENCODING_CHOICE              1  ///< I0184: picture early termination
+#if SAO_ENCODING_CHOICE
+#define SAO_ENCODING_RATE                0.75
+#define SAO_ENCODING_CHOICE_CHROMA       1 ///< J0044: picture early termination Luma and Chroma are handled separatenly
+#if SAO_ENCODING_CHOICE_CHROMA
+#define SAO_ENCODING_RATE_CHROMA         0.5
+#define SAO_ENCODING_CHOICE_CHROMA_BF    1 ///  K0156: Bug fix for SAO selection consistency
+#endif
+#endif
+#endif
+
 ///// ***** FCO  *********
 #define FLEX_CODING_ORDER_M23723          1
@@ -187,7 +205,16 @@
 #if MERL_VSP_C0152
 
+
+#define FIX_MERGE_D                          1 // Fix for merge
 #define MERL_General_Fix                     1 // General fix by MERL
 
+
+
 #define MERL_VSP_C0152_BugFix_ForNoDepthCase 1 // MERL bugfix for test condition of no depth
+#define QC_BVSP_CleanUP_D0191                    1
+
+#define MTK_D0156                 1
+#define LGE_VSP_INHERIT_D0092     1
+
 #define MERL_VSP_COMPENSATION_C0152          1 // JCT3V-C0152: 1: add VSP merge candidate to merging candidate list; 0: not to add (nocand).
 
@@ -198,7 +225,9 @@
 #define MERL_CVSP_D0165                      0 // JCT3V-D0165: 1: enable CVSP; 0: disable CVSP.
 #endif
-
+#if LGE_VSP_INHERIT_D0092
+#define VSP_MERGE_POS                        3 // JCT3V-C0152: fixed position of VSP candidate in merge list, supported values: 3.
+#else
 #define VSP_MERGE_POS                        5 // JCT3V-C0152: fixed position of VSP candidate in merge list, supported values: 5.
-                                               // MTK_DVPREFINE_BVSP_BUG_FIX               1
+#endif                                               // MTK_DVPREFINE_BVSP_BUG_FIX               1
 #define MTK_DEPTH_TO_DISP_D0138              1 // JCT3V-D0138: Use max among four corners for DoNBDV and BVSP
 
@@ -370,6 +399,8 @@
 #define C2FLAG_NUMBER               1 // maximum number of largerThan2 flag coded in one chunk:  16 in HM5
 
+#if !LGE_SAO_MIGRATION_D0091
 #define REMOVE_SAO_LCU_ENC_CONSTRAINTS_1 0  ///< disable the encoder constraint that does not test SAO/BO mode for chroma in interleaved mode
 #define REMOVE_SAO_LCU_ENC_CONSTRAINTS_2 0  ///< disable the encoder constraint that reduce the range of SAO/EO for chroma in interleaved mode
+#endif
 #define REMOVE_SAO_LCU_ENC_CONSTRAINTS_3 0  ///< disable the encoder constraint that conditionally disable SAO for chroma for entire slice in interleaved mode
 #define COLLOCATED_REF_IDX      1           ///< H0442: signal collocated reference index
@@ -644,5 +675,9 @@
   Int         iBestType;
   Int         iLength;
+#if LGE_SAO_MIGRATION_D0091
+  Int         subTypeIdx ;                 ///< indicates EO class or BO band position
+#else
   Int         bandPosition ;
+#endif
   Int         iOffset[4];
   Int         StartCUX;
@@ -674,8 +709,14 @@
   Bool       mergeLeftFlag;
   Int        typeIdx;
+#if LGE_SAO_MIGRATION_D0091
+  Int        subTypeIdx;
+#else
   Int        bandPosition;
+#endif
   Int        offset[4];
+#if !LGE_SAO_MIGRATION_D0091
   Int        runDiff;
   Int        run;
+#endif
   Int        partIdx;
   Int        partIdxTmp;
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 427)
@@ -265,4 +265,5 @@
     xParseDblParam( aps );    
   }
+#if !LGE_SAO_MIGRATION_D0091
   READ_FLAG(uiCode, "aps_sao_interleaving_flag");      aps->setSaoInterleavingFlag( (uiCode==1)?true:false );
   if(!aps->getSaoInterleavingFlag())
@@ -275,4 +276,5 @@
   }
   }
+#endif
   READ_FLAG(uiCode, "aps_adaptive_loop_filter_flag");      aps->setAlfEnabled( (uiCode==1)?true:false );
   if(aps->getAlfEnabled())
@@ -307,4 +309,5 @@
   }
 }
+#if !LGE_SAO_MIGRATION_D0091
 /** parse SAO parameters
  * \param pSaoParam
@@ -532,5 +535,5 @@
   }
 }
-
+#endif
 
 Void TDecCavlc::xParseAlfParam(AlfParamSet* pAlfParamSet, Bool bSentInAPS, Int firstLCUAddr, Bool acrossSlice, Int numLCUInWidth, Int numLCUInHeight)
@@ -1623,4 +1626,16 @@
 
       }
+
+#if MTK_D0156
+
+      pcSPS->setUseVSPCompensation( false );
+      pcSPS->setUseDVPRefine( false );
+
+      //Comments: Currently, BVSP and DoNBDV are not used for depth coding
+#if MERL_VSP_COMPENSATION_C0152
+      READ_FLAG( uiCode, "view_synthesis_pred_flag" );pcSPS->setUseVSPCompensation( uiCode ? true : false );
+#endif
+      READ_FLAG( uiCode, "dv_refine_flag" );          pcSPS->setUseDVPRefine( uiCode ? true : false );
+#endif
     }
     READ_FLAG( uiCode, "sps_extension2_flag");
@@ -1686,4 +1701,11 @@
     }
     rpcSlice->setApplyIC(uiCodeTmp);
+#if SHARP_ILLUCOMP_PARSE_D0060
+    if (rpcSlice->getApplyIC())
+    {
+      READ_FLAG (uiCodeTmp, "ic_skip_mergeidx0");
+      rpcSlice->setIcSkipParseFlag(uiCodeTmp);
+    }
+#endif
   }
 #endif
@@ -1868,4 +1890,8 @@
       if (sps->getUseSAO())
       {
+#if LGE_SAO_MIGRATION_D0091
+        READ_FLAG(uiCode, "slice_sao_luma_flag");  rpcSlice->setSaoEnabledFlag((Bool)uiCode);
+        READ_FLAG(uiCode, "slice_sao_chroma_flag");  rpcSlice->setSaoEnabledFlagChroma((Bool)uiCode);
+#else
         READ_FLAG(uiCode, "slice_sao_interleaving_flag");        rpcSlice->setSaoInterleavingFlag(uiCode);
         READ_FLAG(uiCode, "slice_sample_adaptive_offset_flag");  rpcSlice->setSaoEnabledFlag((Bool)uiCode);
@@ -1880,4 +1906,5 @@
           rpcSlice->setSaoEnabledFlagCr(0);
         }
+#endif
       }
       READ_UVLC (    uiCode, "aps_id" );  rpcSlice->setAPSId(uiCode);
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCAVLC.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 427)
@@ -180,7 +180,9 @@
 protected:
   Void  xParseDblParam       ( TComAPS* aps );
+#if !LGE_SAO_MIGRATION_D0091
   Void  xParseSaoParam       ( SAOParam* pSaoParam );
   Void  xParseSaoOffset      (SaoLcuParam* saoLcuParam);
   Void  xParseSaoUnit        (Int rx, Int ry, Int compIdx, SAOParam* saoParam, Bool& repeatedRow );
+#endif
   Void  xParseAlfParam(AlfParamSet* pAlfParamSet, Bool bSentInAPS = true, Int firstLCUAddr = 0, Bool acrossSlice = true, Int numLCUInWidth= -1, Int numLCUInHeight= -1);
   Void  parseAlfParamSet(AlfParamSet* pAlfParamSet, Int firstLCUAddr, Bool alfAcrossSlice);
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCu.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCu.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecCu.cpp	(revision 427)
@@ -415,5 +415,13 @@
     UInt uiMergeIndex = pcCU->getMergeIndex(uiAbsPartIdx);
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+    Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM];
+    for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++)
+    {
+        iVSPIndexTrue[i] = 0;
+    }
+#else
     Int iVSPIndexTrue[3] = {-1, -1, -1};
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
     Int iVSPDirTrue[3]   = {-1, -1, -1};
@@ -422,6 +430,19 @@
     m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, uiMergeIndex );
 #endif
+#if MTK_D0156
+    if( !pcCU->getSlice()->getSPS()->getUseVSPCompensation() )
+    {
+        pcCU->setVSPIndexSubParts( 0, uiAbsPartIdx, 0, uiDepth ); 
+    }
+    else
+#endif
     {
       Int iVSPIdx = 0;
+#if LGE_VSP_INHERIT_D0092
+      if (iVSPIndexTrue[uiMergeIndex] == 1)
+      {
+          iVSPIdx = 1;
+      }
+#else
       Int numVspIdx;
       numVspIdx = 3;
@@ -434,7 +455,15 @@
           }
       }
+#endif
       pcCU->setVSPIndexSubParts( iVSPIdx, uiAbsPartIdx, 0, uiDepth );  // Initialize
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
       pcCU->setVSPDirSubParts( iVSPDirTrue[iVSPIdx-1], uiAbsPartIdx, 0, uiDepth );
+#endif
+#if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092
+      if(iVSPIdx != 0)
+      {
+        Int iIVCIdx = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==pcCU->getSlice()->getPOC() ? 0: pcCU->getSlice()->getNewRefIdx(REF_PIC_LIST_0);
+       cMvFieldNeighbours[ 2*uiMergeIndex].setRefIdx(iIVCIdx);
+      }
 #endif
     }
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecEntropy.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 427)
@@ -320,5 +320,13 @@
       UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx);
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+      Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM];
+      for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++)
+      {
+          iVSPIndexTrue[i] = 0;
+      }
+#else
       Int iVSPIndexTrue[3] = {-1, -1, -1};
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
       Int iVSPDirTrue[3]   = {-1, -1, -1};
@@ -344,6 +352,19 @@
       else // MPI not used
 #endif
+#if MTK_D0156
+          if( !pcCU->getSlice()->getSPS()->getUseVSPCompensation() )
+          {
+              pcCU->setVSPIndexSubParts( 0, uiSubPartIdx, uiPartIdx, uiDepth ); 
+          }
+          else
+#endif
       {
         Int iVSPIdx = 0;
+#if LGE_VSP_INHERIT_D0092
+        if (iVSPIndexTrue[uiMergeIndex] == 1)
+        {
+            iVSPIdx = 1;
+        }
+#else
         Int numVspIdx;
         numVspIdx = 3;
@@ -356,7 +377,15 @@
             }
         }
+#endif
         pcCU->setVSPIndexSubParts( iVSPIdx, uiSubPartIdx, uiPartIdx, uiDepth );               // Initialize
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
         pcCU->setVSPDirSubParts( iVSPDirTrue[iVSPIdx-1], uiSubPartIdx, uiPartIdx, uiDepth );  // Initialize
+#endif
+#if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092
+       if(iVSPIdx != 0) 
+       {
+         Int iIVCIdx = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==pcCU->getSlice()->getPOC() ? 0: pcCU->getSlice()->getNewRefIdx(REF_PIC_LIST_0);
+         cMvFieldNeighbours[ 2*uiMergeIndex].setRefIdx(iIVCIdx);
+       }
 #endif
       }
@@ -509,5 +538,9 @@
   {
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
+    const Int iNumAMVPCands = AMVP_MAX_NUM_CANDS;
+#else
     const Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcSubCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
+#endif
     m_pcEntropyDecoderIf->parseMVPIdx( iMVPIdx, iNumAMVPCands );
 #else
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecEntropy.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecEntropy.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecEntropy.h	(revision 427)
@@ -231,7 +231,9 @@
   Void setSliceGranularity (Int iSliceGranularity) {m_pcEntropyDecoderIf->setSliceGranularity(iSliceGranularity);}
 
+#if !LGE_SAO_MIGRATION_D0091
   Void decodeSaoParam         (SAOParam* saoParam);
   void decodeSaoLcu(Int rx, Int ry, Int compIdx, SAOParam* saoParam, Bool &repeatedRow );
   Void decodeSaoOneLcu(SaoLcuParam* saoLcuParam);
+#endif
 
   Void decodeFlush() { m_pcEntropyDecoderIf->decodeFlush(); }
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecGop.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecGop.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecGop.cpp	(revision 427)
@@ -372,4 +372,17 @@
     if( pcSlice->getSPS()->getUseSAO() )
     {
+#if LGE_SAO_MIGRATION_D0091
+        if(pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
+        {
+            SAOParam *saoParam = pcSlice->getAPS()->getSaoParam();
+            saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
+            saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
+            m_pcSAO->setSaoLcuBasedOptimization(1);
+            m_pcSAO->createPicSaoInfo(rpcPic, m_uiILSliceCount);
+            m_pcSAO->SAOProcess(rpcPic, saoParam);
+            m_pcSAO->PCMLFDisableProcess(rpcPic);
+            m_pcSAO->destroyPicSaoInfo();
+        }
+#else
       if(pcSlice->getSaoEnabledFlag())
       {
@@ -388,4 +401,5 @@
         m_pcSAO->destroyPicSaoInfo();
       }
+#endif
     }
 
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSbac.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSbac.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSbac.cpp	(revision 427)
@@ -91,4 +91,8 @@
 , m_cALFSvlcSCModel           ( 1,             1,               NUM_ALF_SVLC_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cCUAMPSCModel             ( 1,             1,               NUM_CU_AMP_CTX                , m_contextModels + m_numContextModels, m_numContextModels)
+#if LGE_SAO_MIGRATION_D0091
+, m_cSaoMergeSCModel          ( 1,             1,               NUM_SAO_MERGE_FLAG_CTX        , m_contextModels + m_numContextModels, m_numContextModels)
+, m_cSaoTypeIdxSCModel        ( 1,             1,               NUM_SAO_TYPE_IDX_CTX          , m_contextModels + m_numContextModels, m_numContextModels)
+#else
 , m_cSaoFlagSCModel           ( 1,             1,               NUM_SAO_FLAG_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cSaoUvlcSCModel           ( 1,             1,               NUM_SAO_UVLC_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
@@ -97,4 +101,5 @@
 , m_cSaoMergeUpSCModel        ( 1,             1,               NUM_SAO_MERGE_UP_FLAG_CTX     , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cSaoTypeIdxSCModel        ( 1,             1,               NUM_SAO_TYPE_IDX_CTX          , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
 , m_cDmmFlagSCModel           ( 1,             1,               NUM_DMM_FLAG_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
@@ -190,4 +195,8 @@
   m_cALFUvlcSCModel.initBuffer           ( sliceType, qp, (UChar*)INIT_ALF_UVLC );
   m_cALFSvlcSCModel.initBuffer           ( sliceType, qp, (UChar*)INIT_ALF_SVLC );
+#if LGE_SAO_MIGRATION_D0091
+  m_cSaoMergeSCModel.initBuffer          ( sliceType, qp, (UChar*)INIT_SAO_MERGE_FLAG );
+  m_cSaoTypeIdxSCModel.initBuffer        ( sliceType, qp, (UChar*)INIT_SAO_TYPE_IDX );
+#else
   m_cSaoFlagSCModel.initBuffer           ( sliceType, qp, (UChar*)INIT_SAO_FLAG );
   m_cSaoUvlcSCModel.initBuffer           ( sliceType, qp, (UChar*)INIT_SAO_UVLC );
@@ -196,4 +205,5 @@
   m_cSaoMergeUpSCModel.initBuffer        ( sliceType, qp, (UChar*)INIT_SAO_MERGE_UP_FLAG );
   m_cSaoTypeIdxSCModel.initBuffer        ( sliceType, qp, (UChar*)INIT_SAO_TYPE_IDX );
+#endif
 
   m_cCUTransSubdivFlagSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
@@ -280,4 +290,8 @@
   m_cALFUvlcSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_ALF_UVLC );
   m_cALFSvlcSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_ALF_SVLC );
+#if LGE_SAO_MIGRATION_D0091
+  m_cSaoMergeSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG );
+  m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
+#else
   m_cSaoFlagSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_SAO_FLAG );
   m_cSaoUvlcSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_SAO_UVLC );
@@ -286,4 +300,5 @@
   m_cSaoMergeUpSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_UP_FLAG );
   m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
+#endif
   m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
@@ -1681,5 +1696,250 @@
 }
 
-
+#if LGE_SAO_MIGRATION_D0091
+Void TDecSbac::parseSaoMaxUvlc ( UInt& val, UInt maxSymbol )
+{
+    if (maxSymbol == 0)
+    {
+        val = 0;
+        return;
+    }
+
+    UInt code;
+    Int  i;
+    m_pcTDecBinIf->decodeBinEP( code );
+    if ( code == 0 )
+    {
+        val = 0;
+        return;
+    }
+
+    i=1;
+    while (1)
+    {
+        m_pcTDecBinIf->decodeBinEP( code );
+        if ( code == 0 )
+        {
+            break;
+        }
+        i++;
+        if (i == maxSymbol)
+        {
+            break;
+        }
+    }   
+
+    val = i;
+}
+
+Void TDecSbac::parseSaoUflc (UInt uiLength, UInt&  riVal)
+{
+    m_pcTDecBinIf->decodeBinsEP ( riVal, uiLength );
+}
+
+Void TDecSbac::parseSaoMerge (UInt&  ruiVal)
+{
+    UInt uiCode;
+    m_pcTDecBinIf->decodeBin( uiCode, m_cSaoMergeSCModel.get( 0, 0, 0 ) );
+    ruiVal = (Int)uiCode;
+}
+
+Void TDecSbac::parseSaoTypeIdx (UInt&  ruiVal)
+{
+    UInt uiCode;
+    m_pcTDecBinIf->decodeBin( uiCode, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) );
+    if (uiCode == 0) 
+    {
+        ruiVal = 0;
+    }
+    else
+    {
+        m_pcTDecBinIf->decodeBinEP( uiCode ); 
+        if (uiCode == 0)
+        {
+            ruiVal = 5;
+        }
+        else
+        {
+            ruiVal = 1;
+        }
+    }
+}
+
+inline Void copySaoOneLcuParam(SaoLcuParam* psDst,  SaoLcuParam* psSrc)
+{
+    Int i;
+    psDst->partIdx = psSrc->partIdx;
+    psDst->typeIdx = psSrc->typeIdx;
+    if (psDst->typeIdx != -1)
+    {
+        psDst->subTypeIdx = psSrc->subTypeIdx ;
+        psDst->length  = psSrc->length;
+        for (i=0;i<psDst->length;i++)
+        {
+            psDst->offset[i] = psSrc->offset[i];
+        }
+    }
+    else
+    {
+        psDst->length  = 0;
+        for (i=0;i<SAO_BO_LEN;i++)
+        {
+            psDst->offset[i] = 0;
+        }
+    }
+}
+
+Void TDecSbac::parseSaoOffset(SaoLcuParam* psSaoLcuParam, UInt compIdx)
+{
+    UInt uiSymbol;
+    static Int iTypeLength[MAX_NUM_SAO_TYPE] =
+    {
+        SAO_EO_LEN,
+        SAO_EO_LEN,
+        SAO_EO_LEN,
+        SAO_EO_LEN,
+        SAO_BO_LEN
+    }; 
+
+    if (compIdx==2)
+    {
+        uiSymbol = (UInt)( psSaoLcuParam->typeIdx + 1);
+    }
+    else
+    {
+        parseSaoTypeIdx(uiSymbol);
+    }
+    psSaoLcuParam->typeIdx = (Int)uiSymbol - 1;
+
+    if (uiSymbol)
+    {
+        psSaoLcuParam->length = iTypeLength[psSaoLcuParam->typeIdx];
+#if FULL_NBIT
+        Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + (g_uiBitDepth-8)-5),5) );
+#else
+        Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + g_uiBitIncrement-5),5) );
+#endif
+
+        if( psSaoLcuParam->typeIdx == SAO_BO )
+        {
+            for(Int i=0; i< psSaoLcuParam->length; i++)
+            {
+                parseSaoMaxUvlc(uiSymbol, offsetTh -1 );
+                psSaoLcuParam->offset[i] = uiSymbol;
+            }   
+            for(Int i=0; i< psSaoLcuParam->length; i++)
+            {
+                if (psSaoLcuParam->offset[i] != 0)
+                {
+                    m_pcTDecBinIf->decodeBinEP ( uiSymbol);
+                    if (uiSymbol)
+                    {
+                        psSaoLcuParam->offset[i] = -psSaoLcuParam->offset[i] ;
+                    }
+                }
+            }
+            parseSaoUflc(5, uiSymbol );
+            psSaoLcuParam->subTypeIdx = uiSymbol;
+        }
+        else if( psSaoLcuParam->typeIdx < 4 )
+        {
+            parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[0] = uiSymbol;   
+            parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[1] = uiSymbol;
+            parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[2] = -(Int)uiSymbol;
+            parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[3] = -(Int)uiSymbol;
+            if (compIdx != 2)
+            {
+                parseSaoUflc(2, uiSymbol );
+                psSaoLcuParam->subTypeIdx = uiSymbol;
+                psSaoLcuParam->typeIdx += psSaoLcuParam->subTypeIdx;
+            }
+        }
+    }
+    else
+    {
+        psSaoLcuParam->length = 0;
+    }
+}
+
+Void TDecSbac::parseSaoOneLcuInterleaving(Int rx, Int ry, SAOParam* pSaoParam, TComDataCU* pcCU, Int iCUAddrInSlice, Int iCUAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp)
+{
+    Int iAddr = pcCU->getAddr();
+    UInt uiSymbol;
+
+    for (Int iCompIdx=0; iCompIdx<3; iCompIdx++)
+    {
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag    = 0;
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag  = 0;
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].subTypeIdx     = 0;
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].typeIdx        =-1;
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[0]      = 0;
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[1]      = 0;
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[2]      = 0;
+        pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[3]      = 0;
+    }
+    if (pSaoParam->bSaoFlag[0] || pSaoParam->bSaoFlag[1] )
+    {
+        if (rx>0 && iCUAddrInSlice!=0 && allowMergeLeft)
+        {
+            parseSaoMerge(uiSymbol); 
+            pSaoParam->saoLcuParam[0][iAddr].mergeLeftFlag = (Bool)uiSymbol;  
+        }
+        if (pSaoParam->saoLcuParam[0][iAddr].mergeLeftFlag==0)
+        {
+            if ((ry > 0) && (iCUAddrUpInSlice>=0) && allowMergeUp)
+            {
+                parseSaoMerge(uiSymbol);
+                pSaoParam->saoLcuParam[0][iAddr].mergeUpFlag = (Bool)uiSymbol;
+            }
+        }
+    }
+
+    for (Int iCompIdx=0; iCompIdx<3; iCompIdx++)
+    {
+        if ((iCompIdx == 0  && pSaoParam->bSaoFlag[0]) || (iCompIdx > 0  && pSaoParam->bSaoFlag[1]) )
+        {
+            if (rx>0 && iCUAddrInSlice!=0 && allowMergeLeft)
+            {
+                pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag = pSaoParam->saoLcuParam[0][iAddr].mergeLeftFlag;
+            }
+            else
+            {
+                pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag = 0;
+            }
+
+            if (pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag==0)
+            {
+                if ((ry > 0) && (iCUAddrUpInSlice>=0) && allowMergeUp)
+                {
+                    pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag = pSaoParam->saoLcuParam[0][iAddr].mergeUpFlag;
+                }
+                else
+                {
+                    pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag = 0;
+                }
+    
+                if (!pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag)
+                {
+                    pSaoParam->saoLcuParam[2][iAddr].typeIdx = pSaoParam->saoLcuParam[1][iAddr].typeIdx;
+                    parseSaoOffset(&(pSaoParam->saoLcuParam[iCompIdx][iAddr]), iCompIdx);
+                }
+                else
+                {
+                    copySaoOneLcuParam(&pSaoParam->saoLcuParam[iCompIdx][iAddr], &pSaoParam->saoLcuParam[iCompIdx][iAddr-pSaoParam->numCuInWidth]);
+                }
+            }
+            else
+            {
+                copySaoOneLcuParam(&pSaoParam->saoLcuParam[iCompIdx][iAddr],  &pSaoParam->saoLcuParam[iCompIdx][iAddr-1]);
+            }
+        }
+        else
+        {
+            pSaoParam->saoLcuParam[iCompIdx][iAddr].typeIdx    = -1;
+            pSaoParam->saoLcuParam[iCompIdx][iAddr].subTypeIdx = 0;
+        }
+    }
+}
+#else
 Void TDecSbac::parseSaoUvlc (UInt& ruiVal)
 {
@@ -1918,5 +2178,5 @@
   }
 }
-
+#endif
 /**
  - Initialize our contexts from the nominated source.
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSbac.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSbac.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSbac.h	(revision 427)
@@ -110,4 +110,12 @@
 #endif
   
+#if LGE_SAO_MIGRATION_D0091
+  Void  parseSaoMaxUvlc           ( UInt& val, UInt maxSymbol );
+  Void  parseSaoMerge             ( UInt&  ruiVal   );
+  Void  parseSaoTypeIdx           ( UInt&  ruiVal  );
+  Void  parseSaoUflc              ( UInt uiLength, UInt& ruiVal     );
+  Void  parseSaoOneLcuInterleaving(Int rx, Int ry, SAOParam* pSaoParam, TComDataCU* pcCU, Int iCUAddrInSlice, Int iCUAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp);
+  Void  parseSaoOffset            (SaoLcuParam* psSaoLcuParam, UInt compIdx);
+#else
   Void  parseSaoUvlc              ( UInt& ruiVal           );
   Void  parseSaoSvlc              ( Int&  riVal            );
@@ -118,4 +126,5 @@
   Void  parseSaoOneLcuInterleaving(Int rx, Int ry, SAOParam* pSaoParam, TComDataCU* pcCU, Int iCUAddrInSlice, Int iCUAddrUpInSlice, Bool bLFCrossSliceBoundaryFlag);
   Void  parseSaoOffset            (SaoLcuParam* psSaoLcuParam);
+#endif
   
 #if RWTH_SDC_DLT_B0036
@@ -251,4 +260,8 @@
   ContextModel3DBuffer m_cALFSvlcSCModel;
   ContextModel3DBuffer m_cCUAMPSCModel;
+#if LGE_SAO_MIGRATION_D0091
+  ContextModel3DBuffer m_cSaoMergeSCModel;
+  ContextModel3DBuffer m_cSaoTypeIdxSCModel;
+#else
   ContextModel3DBuffer m_cSaoFlagSCModel;
   ContextModel3DBuffer m_cSaoUvlcSCModel;
@@ -257,4 +270,5 @@
   ContextModel3DBuffer m_cSaoMergeUpSCModel;
   ContextModel3DBuffer m_cSaoTypeIdxSCModel;
+#endif
 
 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
Index: /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSlice.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSlice.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibDecoder/TDecSlice.cpp	(revision 427)
@@ -286,4 +286,37 @@
     g_bJustDoIt = g_bEncDecTraceEnable;
 #endif
+#if LGE_SAO_MIGRATION_D0091
+    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
+    {
+        SAOParam *saoParam =  pcSlice->getAPS()->getSaoParam();
+        saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
+    if (iCUAddr == iStartCUAddr)
+    {
+        saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
+    }
+    Int numCuInWidth     = saoParam->numCuInWidth;
+    Int cuAddrInSlice = iCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
+    Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
+    Int rx = iCUAddr % numCuInWidth;
+    Int ry = iCUAddr / numCuInWidth;
+    Int allowMergeLeft = 1;
+    Int allowMergeUp   = 1;
+    if (rx!=0)
+    {
+        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
+        {
+            allowMergeLeft = 0;
+        }
+    }
+    if (ry!=0)
+    {
+        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-numCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
+        {
+        allowMergeUp = 0;
+        }
+    }
+    pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, saoParam,pcCU, cuAddrInSlice, cuAddrUpInSlice, allowMergeLeft, allowMergeUp);
+    }
+#else
     if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
     {
@@ -301,4 +334,5 @@
       pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, cuAddrInSlice, cuAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag() );
     }
+#endif
 
     m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 427)
@@ -720,4 +720,12 @@
 #endif
     }
+
+#if MTK_D0156
+#if MERL_VSP_COMPENSATION_C0152
+    WRITE_FLAG( pcSPS->getUseVSPCompensation() ? 1 : 0,              "view_synthesis_pred_flag" );
+#endif
+
+    WRITE_FLAG( pcSPS->getUseDVPRefine() ? 1 : 0,                    "dv_refine_flag" );
+#endif
   }
   else
@@ -793,4 +801,10 @@
       WRITE_FLAG( pcSlice->getApplyIC() ? 1 : 0, "applying IC flag" );
     }
+#if SHARP_ILLUCOMP_PARSE_D0060
+    if (pcSlice->getApplyIC())
+    {
+      WRITE_FLAG( pcSlice->getIcSkipParseFlag() ? 1 : 0, "ic_skip_mergeidx0" );
+    }
+#endif
   }
 #endif
@@ -960,4 +974,11 @@
       if (pcSlice->getSPS()->getUseSAO())
       {
+#if LGE_SAO_MIGRATION_D0091
+        WRITE_FLAG( pcSlice->getSaoEnabledFlag(), "slice_sao_luma_flag" );
+        {
+            SAOParam *saoParam = pcSlice->getAPS()->getSaoParam();
+            WRITE_FLAG( saoParam->bSaoFlag[1], "slice_sao_chroma_flag" );
+        }
+#else
         WRITE_FLAG( pcSlice->getSaoInterleavingFlag(), "SAO interleaving flag" );
          assert (pcSlice->getSaoEnabledFlag() == pcSlice->getAPS()->getSaoEnabled());
@@ -968,4 +989,5 @@
            WRITE_FLAG( pcSlice->getAPS()->getSaoParam()->bSaoFlag[2], "SAO on/off flag for Cr in slice header" );
          }
+#endif
       }
       WRITE_UVLC( pcSlice->getAPS()->getAPSID(), "aps_id");
@@ -1499,5 +1521,5 @@
   }
 }
-
+#if !LGE_SAO_MIGRATION_D0091
 Void TEncCavlc::codeSaoFlag( UInt uiCode )
 {
@@ -1537,4 +1559,5 @@
   WRITE_CODE( uiCode, uiLength, "sao_run_diff");
 }
+#endif
 
 Void TEncCavlc::estBit( estBitsSbacStruct* pcEstBitsCabac, Int width, Int height, TextType eTType )
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCavlc.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCavlc.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCavlc.h	(revision 427)
@@ -142,4 +142,11 @@
   Void codeAPSAlflag(UInt uiCode);
   Void codeAlfFixedLengthIdx( UInt idx, UInt numFilterSetsInBuffer);
+#if LGE_SAO_MIGRATION_D0091
+  Void codeSAOSign       ( UInt code   ) { printf("Not supported\n"); assert (0); }
+  Void codeSaoMaxUvlc    ( UInt   code, UInt maxSymbol ){printf("Not supported\n"); assert (0);}
+  Void codeSaoMerge  ( UInt uiCode ){printf("Not supported\n"); assert (0);}
+  Void codeSaoTypeIdx    ( UInt uiCode ){printf("Not supported\n"); assert (0);}
+  Void codeSaoUflc       ( UInt uiLength, UInt   uiCode ){ assert(uiCode < 32); printf("Not supported\n"); assert (0);}
+#else
   Void codeSaoFlag       ( UInt uiCode );
   Void codeSaoUvlc       ( UInt uiCode );
@@ -150,4 +157,5 @@
   Void codeSaoTypeIdx    ( UInt uiCode ){ xWriteUvlc(uiCode   );}
   Void codeSaoUflc       ( UInt uiCode ){ assert(uiCode < 32); xWriteCode(uiCode, 5);}
+#endif
 
   Void codeSkipFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx );
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCfg.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCfg.h	(revision 427)
@@ -160,5 +160,10 @@
 #endif
   Int       m_maxNumOffsetsPerPic;
+#if LGE_SAO_MIGRATION_D0091
+  Bool      m_saoLcuBoundary;
+  Bool      m_saoLcuBasedOptimization;
+#else
   Bool      m_saoInterleavingFlag;
+#endif
 
   //====== Lossless ========
@@ -339,4 +344,11 @@
   UInt        m_uiMultiviewResPredMode;
 #endif
+#endif
+
+#if MTK_D0156
+#if MERL_VSP_COMPENSATION_C0152
+  Bool      m_bUseVSPCompensation;
+#endif
+  Bool      m_bUseDVPRefine;
 #endif
 
@@ -673,6 +685,13 @@
   Void  setMaxNumOffsetsPerPic                   (Int iVal)            { m_maxNumOffsetsPerPic = iVal; }
   Int   getMaxNumOffsetsPerPic                   ()                    { return m_maxNumOffsetsPerPic; }
+#if LGE_SAO_MIGRATION_D0091
+  Void  setSaoLcuBoundary              (Bool val)      { m_saoLcuBoundary = val; }
+  Bool  getSaoLcuBoundary              ()              { return m_saoLcuBoundary; }
+  Void  setSaoLcuBasedOptimization               (Bool val)            { m_saoLcuBasedOptimization = val; }
+  Bool  getSaoLcuBasedOptimization               ()                    { return m_saoLcuBasedOptimization; }
+#else
   Void  setSaoInterleavingFlag                   (bool bVal)           { m_saoInterleavingFlag = bVal; }
   Bool  getSaoInterleavingFlag                   ()                    { return m_saoInterleavingFlag; }
+#endif
   Void  setTileBehaviorControlPresentFlag        ( Int i )             { m_iTileBehaviorControlPresentFlag = i;    }
   Int   getTileBehaviorControlPresentFlag        ()                    { return m_iTileBehaviorControlPresentFlag; }
@@ -822,4 +841,16 @@
 #endif
 
+#if MTK_D0156
+
+#if MERL_VSP_COMPENSATION_C0152
+  Bool    getUseVSPCompensation( ){  return m_bUseVSPCompensation;}
+  Void    setUseVSPCompensation( Bool bValue ){ m_bUseVSPCompensation = bValue;}
+#endif
+
+
+  Bool    getUseDVPRefine( ){  return m_bUseDVPRefine;}
+  Void    setUseDVPRefine( Bool bValue ){ m_bUseDVPRefine = bValue;}
+#endif
+
 };
 
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCu.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncCu.cpp	(revision 427)
@@ -721,5 +721,9 @@
 
 #if LGE_ILLUCOMP_B0045
+#if SHARP_ILLUCOMP_PARSE_D0060
+    bICEnabled = false;
+#else
     bICEnabled = rpcBestCU->getICFlag(0);
+#endif
 #endif
 
@@ -787,8 +791,14 @@
           Bool bResPredFlag  = ( uiResPrdId > 0 );
 #if LGE_ILLUCOMP_B0045
+#if SHARP_ILLUCOMP_PARSE_D0060
+          {
+            Bool bICFlag = false;
+            rpcTempCU->setICFlagSubParts(bICFlag, 0, 0, uiDepth);
+#else
           for(UInt uiICId = 0; uiICId < (bICEnabled ? 2 : 1); uiICId++)
           {
             Bool bICFlag = (uiICId ? true : false);
             rpcTempCU->setICFlagSubParts(bICFlag, 0, 0, uiDepth);
+#endif
 #endif
 #endif
@@ -1936,5 +1946,13 @@
   rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+  Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM];
+  for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++)
+  {
+     iVSPIndexTrue[i] = 0;
+  }
+#else
   Int iVSPIndexTrue[3] = {-1, -1, -1};
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
   Int iVSPDirTrue[3]   = {-1, -1, -1};
@@ -1962,4 +1980,13 @@
     {
       TComYuv* pcPredYuvTemp = NULL;
+#if SHARP_ILLUCOMP_PARSE_D0060
+      if (rpcTempCU->getSlice()->getApplyIC() && rpcTempCU->getSlice()->getIcSkipParseFlag())
+      {
+        if (bICFlag && uiMergeCand == 0) 
+        {
+          continue;
+        }
+      }
+#endif
 #if LOSSLESS_CODING
       UInt iteration;
@@ -1998,6 +2025,20 @@
           rpcTempCU->setMergeIndexSubParts( uiMergeCand, 0, 0, uhDepth ); // interprets depth relative to LCU level
 #if MERL_VSP_C0152
+
+#if MTK_D0156
+          if( !rpcTempCU->getSlice()->getSPS()->getUseVSPCompensation() )
+          {
+              rpcTempCU->setVSPIndexSubParts( 0, 0, 0, uhDepth );
+          }
+          else
+#endif
           {
             Int iVSPIdx = 0;
+#if LGE_VSP_INHERIT_D0092
+            if (iVSPIndexTrue[uiMergeCand] == 1)
+            {
+                iVSPIdx = 1;
+            }
+#else
             Int numVSPIdx;
             numVSPIdx = 3;
@@ -2010,7 +2051,15 @@
                 }
             }
+#endif
             rpcTempCU->setVSPIndexSubParts( iVSPIdx, 0, 0, uhDepth );
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
             rpcTempCU->setVSPDirSubParts( iVSPDirTrue[iVSPIdx-1], 0, 0, uhDepth ); // interprets depth relative to LCU level
+#endif
+#if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092
+           if(iVSPIdx != 0)
+           {
+             Int iIVCIdx = rpcTempCU->getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==rpcTempCU->getSlice()->getPOC() ? 0: rpcTempCU->getSlice()->getNewRefIdx(REF_PIC_LIST_0);
+             cMvFieldNeighbours[2*uiMergeCand].setRefIdx(iIVCIdx);
+           }
 #endif
           }
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncEntropy.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 427)
@@ -54,4 +54,14 @@
   if (pcSlice->getSPS()->getUseSAO())
   {
+#if LGE_SAO_MIGRATION_D0091
+    if (pcSlice->getSPS()->getUseSAO())
+    {
+        SAOParam *saoParam = pcSlice->getAPS()->getSaoParam();
+        pcSlice->setSaoEnabledFlag     (saoParam->bSaoFlag[0]);
+        {
+            pcSlice->setSaoEnabledFlagChroma   (saoParam->bSaoFlag[1]);
+        }
+    }
+#else
     pcSlice->setSaoInterleavingFlag(pcSlice->getAPS()->getSaoInterleavingFlag());
     pcSlice->setSaoEnabledFlag     (pcSlice->getAPS()->getSaoParam()->bSaoFlag[0]);
@@ -66,4 +76,5 @@
       pcSlice->setSaoEnabledFlagCr   (0);
     }
+#endif
   }
 
@@ -1384,5 +1395,9 @@
   {
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
+    const Int iNumCands = AMVP_MAX_NUM_CANDS;
+#else
     const Int iNumCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
+#endif
     m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList, iNumCands );
 #else
@@ -1528,4 +1543,102 @@
 }
 
+#if LGE_SAO_MIGRATION_D0091
+Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam, UInt compIdx)
+{
+    UInt uiSymbol;
+    Int i;
+
+    uiSymbol = saoLcuParam->typeIdx + 1;
+    if (compIdx!=2)
+    {
+        m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol);
+    }
+
+    if (uiSymbol)
+    {
+        if (saoLcuParam->typeIdx < 4 && compIdx != 2)
+        {
+            saoLcuParam->subTypeIdx = saoLcuParam->typeIdx;
+        }
+#if FULL_NBIT
+        Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + (g_uiBitDepth-8)-5),5) );
+#else
+        Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + g_uiBitIncrement-5),5) );
+#endif
+        if( saoLcuParam->typeIdx == SAO_BO )
+        {
+            for( i=0; i< saoLcuParam->length; i++)
+            {
+                UInt absOffset = ( (saoLcuParam->offset[i] < 0) ? -saoLcuParam->offset[i] : saoLcuParam->offset[i]);
+                m_pcEntropyCoderIf->codeSaoMaxUvlc(absOffset, offsetTh-1);
+            }  
+            for( i=0; i< saoLcuParam->length; i++)
+            {
+                if (saoLcuParam->offset[i] != 0)
+                {
+                    UInt sign = (saoLcuParam->offset[i] < 0) ? 1 : 0 ;
+                    m_pcEntropyCoderIf->codeSAOSign(sign);
+                }
+            }
+            uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
+            m_pcEntropyCoderIf->codeSaoUflc(5, uiSymbol);
+        }
+        else if( saoLcuParam->typeIdx < 4 )
+        {
+            m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[0], offsetTh-1);
+            m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[1], offsetTh-1);
+            m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[2], offsetTh-1);
+            m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[3], offsetTh-1);
+
+            if (compIdx!=2)
+            {
+                uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
+                m_pcEntropyCoderIf->codeSaoUflc(2, uiSymbol);
+            }
+        }
+    }
+}
+
+/** Encode SAO unit interleaving
+* \param  rx
+* \param  ry
+* \param  pSaoParam
+* \param  pcCU
+* \param  iCUAddrInSlice
+* \param  iCUAddrUpInSlice
+* \param  bLFCrossSliceBoundaryFlag
+ */
+Void TEncEntropy::encodeSaoUnitInterleaving(Int compIdx, Bool saoFlag, Int rx, Int ry, SaoLcuParam* saoLcuParam, Int cuAddrInSlice, Int cuAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp)
+{
+    if (saoFlag)
+    {
+        if (rx>0 && cuAddrInSlice!=0 && allowMergeLeft)
+        {
+            m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeLeftFlag);
+        }
+        else
+        {
+            saoLcuParam->mergeLeftFlag = 0;
+        }
+        
+        if (saoLcuParam->mergeLeftFlag == 0)
+        {
+            if ( (ry > 0) && (cuAddrUpInSlice>=0) && allowMergeUp )
+            {
+                m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeUpFlag);
+            }
+            else
+            {
+                saoLcuParam->mergeUpFlag = 0;
+            }
+
+            if (!saoLcuParam->mergeUpFlag)
+            {
+                encodeSaoOffset(saoLcuParam, compIdx);
+            }
+        }
+    }
+}
+#else
 /** Encode SAO Offset
  * \param  saoLcuParam SAO LCU paramters
@@ -1715,4 +1828,5 @@
   }
 }
+#endif
 
 Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncEntropy.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncEntropy.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncEntropy.h	(revision 427)
@@ -157,4 +157,11 @@
 
   virtual Void codeAlfCtrlFlag      ( UInt uiSymbol ) = 0;
+#if LGE_SAO_MIGRATION_D0091
+  virtual Void codeSAOSign          ( UInt code   ) = 0;
+  virtual Void codeSaoMaxUvlc       ( UInt code, UInt maxSymbol ) = 0;
+  virtual Void codeSaoMerge         ( UInt   uiCode  ) = 0;
+  virtual Void codeSaoTypeIdx       ( UInt   uiCode) = 0;
+  virtual Void codeSaoUflc          ( UInt uiLength, UInt   uiCode ) = 0;
+#else
   virtual Void codeSaoFlag          ( UInt uiCode ) = 0;
   virtual Void codeSaoUvlc          ( UInt uiCode ) = 0;
@@ -165,4 +172,5 @@
   virtual Void codeSaoTypeIdx      ( UInt   uiCode) = 0;
   virtual Void codeSaoUflc         ( UInt   uiCode) = 0;
+#endif
   virtual Void estBit               (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType) = 0;
   
@@ -316,8 +324,13 @@
   Int golombEncode(int coeff, int k);
   Int lengthGolomb(int coeffVal, int k);
+#if LGE_SAO_MIGRATION_D0091
+  Void    encodeSaoOffset(SaoLcuParam* saoLcuParam, UInt compIdx);
+  Void    encodeSaoUnitInterleaving(Int compIdx, Bool saoFlag, Int rx, Int ry, SaoLcuParam* saoLcuParam, Int cuAddrInSlice, Int cuAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp);
+#else
   Void    encodeSaoUnit(Int rx, Int ry, Int compIdx, SAOParam* saoParam, Int repeatedRow);
   Void    encodeSaoOffset(SaoLcuParam* saoLcuParam);
   Void    encodeSaoUnitInterleaving(Int rx, Int ry, SAOParam* saoParam, TComDataCU* cu, Int cuAddrInSlice, Int cuAddrUpInSlice, Bool lfCrossSliceBoundaryFlag);
   Void    encodeSaoParam         (TComAPS*  aps);
+#endif
 
   static Int countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize );
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 427)
@@ -1264,5 +1264,7 @@
             TComAPS cAPS;
             allocAPS(&cAPS, pcSlice->getSPS());
+#if !LGE_SAO_MIGRATION_D0091
             cAPS.setSaoInterleavingFlag(m_pcCfg->getSaoInterleavingFlag());
+#endif
             // set entropy coder for RD
             m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
@@ -1272,9 +1274,21 @@
               m_pcEntropyCoder->resetEntropy();
               m_pcEntropyCoder->setBitstream( m_pcBitCounter );
+#if LGE_SAO_MIGRATION_D0091
+              m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcEncTop->getRDGoOnSbacCoder());
+#else
               m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), NULL);
+#endif
               SAOParam& cSaoParam = *(cAPS.getSaoParam());
 
 #if SAO_CHROMA_LAMBDA 
+#if LGE_SAO_MIGRATION_D0091
+#if SAO_ENCODING_CHOICE
+              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), pcPic->getSlice(0)->getDepth());
+#else
               m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma());
+#endif
+#else
+              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma());
+#endif
 #else
 #if ALF_CHROMA_LAMBDA
@@ -1561,5 +1575,7 @@
     m_pcEntropyCoder->encodeDFParams(pcAPS);
   }
+#if !LGE_SAO_MIGRATION_D0091
   m_pcEntropyCoder->encodeSaoParam(pcAPS);
+#endif
   m_pcEntropyCoder->encodeAPSAlfFlag( pcAPS->getAlfEnabled()?1:0);
   if(pcAPS->getAlfEnabled())
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 427)
@@ -43,21 +43,32 @@
 //! \ingroup TLibEncoder
 //! \{
-
+#if LGE_SAO_MIGRATION_D0091
 TEncSampleAdaptiveOffset::TEncSampleAdaptiveOffset()
 {
-  m_pcEntropyCoder = NULL;
-  m_pppcRDSbacCoder = NULL;
-  m_pcRDGoOnSbacCoder = NULL;
-  m_pppcBinCoderCABAC = NULL;            
-  m_iCount = NULL;     
-  m_iOffset = NULL;      
-  m_iOffsetOrg = NULL;  
-  m_iRate = NULL;       
-  m_iDist = NULL;        
-  m_dCost = NULL;        
-  m_dCostPartBest = NULL; 
-  m_iDistOrg = NULL;      
-  m_iTypePartBest = NULL; 
-}
+    m_pcEntropyCoder= NULL;
+    m_pppcRDSbacCoder = NULL;
+    m_pcRDGoOnSbacCoder = NULL;
+    m_pppcBinCoderCABAC = NULL;
+    m_iCount = NULL;
+    m_iOffset = NULL;
+    m_iOffsetOrg = NULL;
+    m_iRate = NULL;
+    m_iDist = NULL;
+    m_dCost = NULL;
+    m_dCostPartBest = NULL;
+    m_iDistOrg = NULL;
+    m_iTypePartBest = NULL;
+#if SAO_ENCODING_CHOICE_CHROMA
+    m_depthSaoRate[0][0] = 0;
+    m_depthSaoRate[0][1] = 0;
+    m_depthSaoRate[0][2] = 0;
+    m_depthSaoRate[0][3] = 0;
+    m_depthSaoRate[1][0] = 0;
+    m_depthSaoRate[1][1] = 0;
+    m_depthSaoRate[1][2] = 0;
+    m_depthSaoRate[1][3] = 0;
+#endif
+}
+
 TEncSampleAdaptiveOffset::~TEncSampleAdaptiveOffset()
 {
@@ -76,8 +87,8 @@
 {
 #if FULL_NBIT
-  Int bitDepthMinus8 = g_uiBitDepth - 8;
-  return ((x)>0) ? (Int)(((Int)(x)+(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)) : ((Int)(((Int)(x)-(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)));
+    Int bitDepthMinus8 = g_uiBitDepth - 8;
+    return ((x)>0) ? (Int)(((Int)(x)+(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)) : ((Int)(((Int)(x)-(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)));
 #else
-  return ((x)>0) ? (Int)(((Int)(x)+(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)) : ((Int)(((Int)(x)-(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)));
+    return ((x)>0) ? (Int)(((Int)(x)+(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)) : ((Int)(((Int)(x)-(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)));
 #endif
 }
@@ -89,252 +100,241 @@
 {
 #if FULL_NBIT
-  return (g_uiBitDepth > 8 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ;
+    return (g_uiBitDepth > 8 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ;
 #else
-  return (g_uiBitIncrement >0 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ;
-#endif
-}
-
-
+    return (g_uiBitIncrement >0 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ;
+#endif
+}
 
 /** process SAO for one partition
  * \param  *psQTPart, iPartIdx, dLambda
  */
-Void TEncSampleAdaptiveOffset::rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda)
-{
-  Int iTypeIdx;
-  Int iNumTotalType = MAX_NUM_SAO_TYPE;
-  SAOQTPart*  pOnePart = &(psQTPart[iPartIdx]);
-
-  Int64 iEstDist;
-  Int64 iOffsetOrg;
-  Int64 iOffset;
-  Int64 iCount;
-  Int iClassIdx;
-  Int uiShift = g_uiBitIncrement << 1;
-  UInt uiDepth = pOnePart->PartLevel;
-
-  m_iDistOrg [iPartIdx] =  0;
-
-  Double  bestRDCostTableBo = MAX_DOUBLE;
-  Int     bestClassTableBo    = 0;
-  Int     currentDistortionTableBo[MAX_NUM_SAO_CLASS];
-  Double  currentRdCostTableBo[MAX_NUM_SAO_CLASS];
-
-#if HHI_INTERVIEW_SKIP
-  Int iFrameWidthInCU = m_pcPic->getFrameWidthInCU();
-  Int LcuIdxX = psQTPart->StartCUX;
-  Int LcuIdxY = psQTPart->StartCUY;
-  Int iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX;
-  TComDataCU *pcCU = m_pcPic->getCU(iAddr);
-  Bool bRenderable = pcCU->getRenderable(0) ;
-
-#endif
-  for (iTypeIdx=-1; iTypeIdx<iNumTotalType; iTypeIdx++)
-  {
-    if( m_bUseSBACRD )
-    {
-      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
-      m_pcRDGoOnSbacCoder->resetBits();
+Void TEncSampleAdaptiveOffset::rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda, Int yCbCr)
+{
+    Int iTypeIdx;
+    Int iNumTotalType = MAX_NUM_SAO_TYPE;
+    SAOQTPart*  pOnePart = &(psQTPart[iPartIdx]);
+
+    Int64 iEstDist;
+    Int iClassIdx;
+    Int uiShift = g_uiBitIncrement << 1;
+    UInt uiDepth = pOnePart->PartLevel;
+
+    m_iDistOrg [iPartIdx] =  0;
+
+    Double  bestRDCostTableBo = MAX_DOUBLE;
+    Int     bestClassTableBo    = 0;
+    Int     currentDistortionTableBo[MAX_NUM_SAO_CLASS];
+    Double  currentRdCostTableBo[MAX_NUM_SAO_CLASS];
+
+    Int addr;
+    Int allowMergeLeft;
+    Int allowMergeUp;
+    Int frameWidthInCU = m_pcPic->getFrameWidthInCU();
+    SaoLcuParam  saoLcuParamRdo;
+
+    for (iTypeIdx=-1; iTypeIdx<iNumTotalType; iTypeIdx++)
+    {
+        if( m_bUseSBACRD )
+        {
+            m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
+            m_pcRDGoOnSbacCoder->resetBits();
+        }
+        else
+        {
+            m_pcEntropyCoder->resetEntropy();
+            m_pcEntropyCoder->resetBits();
+        }
+
+        iEstDist = 0;
+
+        if (iTypeIdx == -1)
+        {      
+            for (Int ry = pOnePart->StartCUY; ry<= pOnePart->EndCUY; ry++)
+            {
+                for (Int rx = pOnePart->StartCUX; rx <= pOnePart->EndCUX; rx++)
+                {
+                    addr = ry * frameWidthInCU + rx;
+                    // get bits for iTypeIdx = -1
+                    allowMergeLeft = 1;
+                    allowMergeUp   = 1;
+                    if (rx != 0)
+                    { 
+                        // check tile id and slice id 
+                        if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-1) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-1)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx()))
+                        {
+                            allowMergeLeft = 0;
+                        }
+                    }
+                    if (ry!=0)
+                    {
+                        if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-m_iNumCuInWidth) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-m_iNumCuInWidth)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx()))
+                        {
+                            allowMergeUp = 0;
+                        }
+                    }
+
+                    // reset
+                    resetSaoUnit(&saoLcuParamRdo);
+        
+                    // set merge flag
+                    saoLcuParamRdo.mergeUpFlag   = 1;
+                    saoLcuParamRdo.mergeLeftFlag = 1;
+        
+                    if (ry == pOnePart->StartCUY) 
+                    {
+                        saoLcuParamRdo.mergeUpFlag = 0;
+                    } 
+
+                    if (rx == pOnePart->StartCUX) 
+                    {
+                        saoLcuParamRdo.mergeLeftFlag = 0;
+                    }
+
+                    m_pcEntropyCoder->encodeSaoUnitInterleaving(yCbCr, 1, rx, ry,  &saoLcuParamRdo, 1,  1,  allowMergeLeft, allowMergeUp);
+
+                }
+            }
+        }
+
+        if (iTypeIdx>=0)
+        {
+            iEstDist = estSaoTypeDist(iPartIdx, iTypeIdx, uiShift, dLambda, currentDistortionTableBo, currentRdCostTableBo);
+            if( iTypeIdx == SAO_BO )
+            {
+                // Estimate Best Position
+                Double currentRDCost = 0.0;
+    
+                for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++)
+                {
+                    currentRDCost = 0.0;
+                    for(UInt uj = i; uj < i+SAO_BO_LEN; uj++)
+                    {
+                        currentRDCost += currentRdCostTableBo[uj];
+                    }
+
+                    if( currentRDCost < bestRDCostTableBo)
+                    {
+                        bestRDCostTableBo = currentRDCost;
+                        bestClassTableBo  = i;
+                    }
+                }
+
+                // Re code all Offsets
+                // Code Center
+                for(iClassIdx = bestClassTableBo; iClassIdx < bestClassTableBo+SAO_BO_LEN; iClassIdx++)
+                {
+                    iEstDist += currentDistortionTableBo[iClassIdx];
+                }
+            }
+
+            for (Int ry = pOnePart->StartCUY; ry<= pOnePart->EndCUY; ry++)
+            {
+                for (Int rx = pOnePart->StartCUX; rx <= pOnePart->EndCUX; rx++)
+                {
+                    addr = ry * frameWidthInCU + rx;          
+        
+                    // get bits for iTypeIdx = -1
+                    allowMergeLeft = 1;
+                    allowMergeUp   = 1;
+                    if (rx != 0)
+                    { 
+                        // check tile id and slice id 
+                        if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-1) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-1)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx()))
+                        {
+                            allowMergeLeft = 0;
+                        }
+                    }
+                    if (ry!=0)
+                    {
+                        if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-m_iNumCuInWidth) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-m_iNumCuInWidth)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx()))
+                        {
+                            allowMergeUp = 0;
+                        }
+                    }
+    
+                    // reset
+                    resetSaoUnit(&saoLcuParamRdo);
+
+                    // set merge flag
+                    saoLcuParamRdo.mergeUpFlag   = 1;
+                    saoLcuParamRdo.mergeLeftFlag = 1;
+    
+                    if (ry == pOnePart->StartCUY) 
+                    {
+                        saoLcuParamRdo.mergeUpFlag = 0;
+                    } 
+    
+                    if (rx == pOnePart->StartCUX) 
+                    {
+                        saoLcuParamRdo.mergeLeftFlag = 0;
+                    }
+
+                    // set type and offsets
+                    saoLcuParamRdo.typeIdx = iTypeIdx;
+                    saoLcuParamRdo.subTypeIdx = (iTypeIdx==SAO_BO)?bestClassTableBo:0;
+                    saoLcuParamRdo.length = m_iNumClass[iTypeIdx];
+                    for (iClassIdx = 0; iClassIdx < saoLcuParamRdo.length; iClassIdx++)
+                    {
+                        saoLcuParamRdo.offset[iClassIdx] = (Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx+saoLcuParamRdo.subTypeIdx+1];
+                    }
+
+                    m_pcEntropyCoder->encodeSaoUnitInterleaving(yCbCr, 1, rx, ry,  &saoLcuParamRdo, 1,  1,  allowMergeLeft, allowMergeUp);
+
+                }
+            }
+
+            m_iDist[iPartIdx][iTypeIdx] = iEstDist;
+            m_iRate[iPartIdx][iTypeIdx] = m_pcEntropyCoder->getNumberOfWrittenBits();
+
+            m_dCost[iPartIdx][iTypeIdx] = (Double)((Double)m_iDist[iPartIdx][iTypeIdx] + dLambda * (Double) m_iRate[iPartIdx][iTypeIdx]);
+
+            if(m_dCost[iPartIdx][iTypeIdx] < m_dCostPartBest[iPartIdx])
+            {
+                m_iDistOrg [iPartIdx] = 0;
+                m_dCostPartBest[iPartIdx] = m_dCost[iPartIdx][iTypeIdx];
+                m_iTypePartBest[iPartIdx] = iTypeIdx;
+                if( m_bUseSBACRD )
+                    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] );
+            }
+        }
+        else
+        {
+            if(m_iDistOrg[iPartIdx] < m_dCostPartBest[iPartIdx] )
+            {
+                m_dCostPartBest[iPartIdx] = (Double) m_iDistOrg[iPartIdx] + m_pcEntropyCoder->getNumberOfWrittenBits()*dLambda ; 
+                m_iTypePartBest[iPartIdx] = -1;
+                if( m_bUseSBACRD )
+                    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] );
+            }
+        }
+    }
+
+    pOnePart->bProcessed = true;
+    pOnePart->bSplit     = false;
+    pOnePart->iMinDist   =        m_iTypePartBest[iPartIdx] >= 0 ? m_iDist[iPartIdx][m_iTypePartBest[iPartIdx]] : m_iDistOrg[iPartIdx];
+    pOnePart->iMinRate   = (Int) (m_iTypePartBest[iPartIdx] >= 0 ? m_iRate[iPartIdx][m_iTypePartBest[iPartIdx]] : 0);
+    pOnePart->dMinCost   = pOnePart->iMinDist + dLambda * pOnePart->iMinRate;
+    pOnePart->iBestType  = m_iTypePartBest[iPartIdx];
+    if (pOnePart->iBestType != -1)
+    {
+        //     pOnePart->bEnableFlag =  1;
+        pOnePart->iLength = m_iNumClass[pOnePart->iBestType];
+        Int minIndex = 0;
+        if( pOnePart->iBestType == SAO_BO )
+        {
+            pOnePart->subTypeIdx = bestClassTableBo;
+            minIndex = pOnePart->subTypeIdx;
+        }
+        for (Int i=0; i< pOnePart->iLength ; i++)
+        {
+            pOnePart->iOffset[i] = (Int) m_iOffset[iPartIdx][pOnePart->iBestType][minIndex+i+1];
+        }
+
     }
     else
     {
-      m_pcEntropyCoder->resetEntropy();
-      m_pcEntropyCoder->resetBits();
-    }
-
-    iEstDist = 0;
-
-    m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoTypeIdx(iTypeIdx+1);
-
-    if (iTypeIdx>=0)
-    {
-
-      for(iClassIdx=1; iClassIdx < ( (iTypeIdx < SAO_BO) ?  m_iNumClass[iTypeIdx]+1 : SAO_MAX_BO_CLASSES+1); iClassIdx++)
-      {
-        if( iTypeIdx == SAO_BO)
-        {
-          currentDistortionTableBo[iClassIdx-1] = 0;
-          currentRdCostTableBo[iClassIdx-1] = dLambda;
-        }
-#if HHI_INTERVIEW_SKIP
-        if(m_iCount [iPartIdx][iTypeIdx][iClassIdx] && !bRenderable)
-#else
-        if(m_iCount [iPartIdx][iTypeIdx][iClassIdx])
-#endif
-        {
-#if FULL_NBIT
-          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitDepth-8) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease));
-#else
-          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitIncrement) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease));
-#endif
-          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = Clip3(-m_iOffsetTh, m_iOffsetTh-1, (Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
-
-          if (iTypeIdx < 4)
-          {
-            if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]<0 && iClassIdx<3 )
-            {
-              m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
-            }
-            if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]>0 && iClassIdx>=3)
-            {
-              m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
-            }
-          }
-          {
-            //Clean up, best_q_offset.
-            Int64 iIterOffset, iTempOffset;
-            Int64 iTempDist, iTempRate;
-            Double dTempCost, dTempMinCost;
-            UInt uiLength, uiTemp;
-
-            iIterOffset = m_iOffset[iPartIdx][iTypeIdx][iClassIdx];
-            m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
-            dTempMinCost = dLambda; // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 
-
-            while (iIterOffset != 0)
-            {
-              // Calculate the bits required for signalling the offset
-              uiLength = 1;
-              uiTemp = (UInt)((iIterOffset <= 0) ? ( (-iIterOffset<<1) + 1 ) : (iIterOffset<<1));
-              while( 1 != uiTemp )
-              {
-                uiTemp >>= 1;
-                uiLength += 2;
-              }
-              iTempRate = (uiLength >> 1) + ((uiLength+1) >> 1);
-
-              // Do the dequntization before distorion calculation
-              iTempOffset    =  iIterOffset << m_uiSaoBitIncrease;
-              iTempDist  = (( m_iCount [iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*iTempOffset-m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*2 ) >> uiShift);
-
-              dTempCost = ((Double)iTempDist + dLambda * (Double) iTempRate);
-              if(dTempCost < dTempMinCost)
-              {
-                dTempMinCost = dTempCost;
-                m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = iIterOffset;
-                if(iTypeIdx == SAO_BO)
-                {
-                  currentDistortionTableBo[iClassIdx-1] = (Int) iTempDist;
-                  currentRdCostTableBo[iClassIdx-1] = dTempCost;
-                }
-              }
-              iIterOffset = (iIterOffset > 0) ? (iIterOffset-1):(iIterOffset+1);
-            }
-
-          }
-        }
-        else
-        {
-          m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx] = 0;
-          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
-        }
-        if( iTypeIdx != SAO_BO )
-        {
-          iCount     =  m_iCount [iPartIdx][iTypeIdx][iClassIdx];
-          iOffset    =  m_iOffset[iPartIdx][iTypeIdx][iClassIdx] << m_uiSaoBitIncrease;
-          iOffsetOrg =  m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx];
-          iEstDist   += (( iCount*iOffset*iOffset-iOffsetOrg*iOffset*2 ) >> uiShift);
-          if (iTypeIdx < 4)
-          {
-            if (iClassIdx<3)
-            {
-              m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
-            }
-            else
-            {
-              m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)-m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
-            }
-          }
-          else
-          {
-            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
-          }
-        }
-      }
-
-      if( iTypeIdx == SAO_BO )
-      {
-        // Estimate Best Position
-        Double currentRDCost = 0.0;
-
-        for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++)
-        {
-          currentRDCost = 0.0;
-          for(UInt uj = i; uj < i+SAO_BO_LEN; uj++)
-          {
-            currentRDCost += currentRdCostTableBo[uj];
-          }
-
-          if( currentRDCost < bestRDCostTableBo)
-          {
-            bestRDCostTableBo = currentRDCost;
-            bestClassTableBo  = i;
-          }
-        }
-
-        // Re code all Offsets
-        // Code Center
-        m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUflc( (UInt) (bestClassTableBo) );
-
-        for(iClassIdx = bestClassTableBo; iClassIdx < bestClassTableBo+SAO_BO_LEN; iClassIdx++)
-        {
-          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx+1]);
-          iEstDist += currentDistortionTableBo[iClassIdx];
-        }
-      }
-
-      m_iDist[iPartIdx][iTypeIdx] = iEstDist;
-      m_iRate[iPartIdx][iTypeIdx] = m_pcEntropyCoder->getNumberOfWrittenBits();
-
-      m_dCost[iPartIdx][iTypeIdx] = (Double)((Double)m_iDist[iPartIdx][iTypeIdx] + dLambda * (Double) m_iRate[iPartIdx][iTypeIdx]);
-
-      if(m_dCost[iPartIdx][iTypeIdx] < m_dCostPartBest[iPartIdx])
-      {
-        m_iDistOrg [iPartIdx] = 0;
-        m_dCostPartBest[iPartIdx] = m_dCost[iPartIdx][iTypeIdx];
-        m_iTypePartBest[iPartIdx] = iTypeIdx;
-        if( m_bUseSBACRD )
-          m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] );
-      }
-    }
-    else
-    {
-      if(m_iDistOrg[iPartIdx] < m_dCostPartBest[iPartIdx] )
-      {
-        m_dCostPartBest[iPartIdx] = (Double) m_iDistOrg[iPartIdx] + m_pcEntropyCoder->getNumberOfWrittenBits()*dLambda ; 
-        m_iTypePartBest[iPartIdx] = -1;
-        if( m_bUseSBACRD )
-          m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] );
-      }
-    }
-  }
-
-  pOnePart->bProcessed = true;
-  pOnePart->bSplit     = false;
-  pOnePart->iMinDist   =        m_iTypePartBest[iPartIdx] >= 0 ? m_iDist[iPartIdx][m_iTypePartBest[iPartIdx]] : m_iDistOrg[iPartIdx];
-  pOnePart->iMinRate   = (Int) (m_iTypePartBest[iPartIdx] >= 0 ? m_iRate[iPartIdx][m_iTypePartBest[iPartIdx]] : 0);
-  pOnePart->dMinCost   = pOnePart->iMinDist + dLambda * pOnePart->iMinRate;
-  pOnePart->iBestType  = m_iTypePartBest[iPartIdx];
-  if (pOnePart->iBestType != -1)
-  {
-    //     pOnePart->bEnableFlag =  1;
-    pOnePart->iLength = m_iNumClass[pOnePart->iBestType];
-    Int minIndex = 0;
-    if( pOnePart->iBestType == SAO_BO )
-    {
-      pOnePart->bandPosition = bestClassTableBo;
-      minIndex = pOnePart->bandPosition;
-    }
-    for (Int i=0; i< pOnePart->iLength ; i++)
-    {
-      pOnePart->iOffset[i] = (Int) m_iOffset[iPartIdx][pOnePart->iBestType][minIndex+i+1];
-    }
-
-  }
-  else
-  {
-    //     pOnePart->bEnableFlag = 0;
-    pOnePart->iLength     = 0;
-  }
+        //     pOnePart->bEnableFlag = 0;
+        pOnePart->iLength     = 0;
+    }
 }
 
@@ -343,16 +343,16 @@
 Void TEncSampleAdaptiveOffset::disablePartTree(SAOQTPart *psQTPart, Int iPartIdx)
 {
-  SAOQTPart*  pOnePart= &(psQTPart[iPartIdx]);
-  pOnePart->bSplit      = false;
-  pOnePart->iLength     =  0;
-  pOnePart->iBestType   = -1;
-
-  if (pOnePart->PartLevel < m_uiMaxSplitLevel)
-  {
-    for (Int i=0; i<NUM_DOWN_PART; i++)
-    {
-      disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]);
-    }
-  }
+    SAOQTPart*  pOnePart= &(psQTPart[iPartIdx]);
+    pOnePart->bSplit      = false;
+    pOnePart->iLength     =  0;
+    pOnePart->iBestType   = -1;
+
+    if (pOnePart->PartLevel < m_uiMaxSplitLevel)
+    {
+        for (Int i=0; i<NUM_DOWN_PART; i++)
+        {
+            disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]);
+        }
+    }
 }
 
@@ -360,78 +360,78 @@
  * \param  iPartIdx, pcPicOrg, pcPicDec, pcPicRest, &dCostFinal
  */
-Void TEncSampleAdaptiveOffset::runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda)
-{
-  SAOQTPart*  pOnePart = &(psQTPart[iPartIdx]);
-
-  UInt uiDepth = pOnePart->PartLevel;
-  UInt uhNextDepth = uiDepth+1;
-
-  if (iPartIdx == 0)
-  {
-    dCostFinal = 0;
-  }
-
-  //SAO for this part
-  if(!pOnePart->bProcessed)
-  {
-    rdoSaoOnePart (psQTPart, iPartIdx, dLambda);
-  }
-
-  //SAO for sub 4 parts
-  if (pOnePart->PartLevel < iMaxLevel)
-  {
-    Double      dCostNotSplit = dLambda + pOnePart->dMinCost;
-    Double      dCostSplit    = dLambda;
-
-    for (Int i=0; i< NUM_DOWN_PART ;i++)
-    {
-      if( m_bUseSBACRD )  
-      {
-        if ( 0 == i) //initialize RD with previous depth buffer
-        {
-          m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
+Void TEncSampleAdaptiveOffset::runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda, Int yCbCr)
+{
+    SAOQTPart*  pOnePart = &(psQTPart[iPartIdx]);
+
+    UInt uiDepth = pOnePart->PartLevel;
+    UInt uhNextDepth = uiDepth+1;
+
+    if (iPartIdx == 0)
+    {
+        dCostFinal = 0;
+    }
+
+    //SAO for this part
+    if(!pOnePart->bProcessed)
+    {
+        rdoSaoOnePart (psQTPart, iPartIdx, dLambda, yCbCr);
+    }
+
+    //SAO for sub 4 parts
+    if (pOnePart->PartLevel < iMaxLevel)
+    {
+        Double      dCostNotSplit = dLambda + pOnePart->dMinCost;
+        Double      dCostSplit    = dLambda;
+
+        for (Int i=0; i< NUM_DOWN_PART ;i++)
+        {
+            if( m_bUseSBACRD )
+            {
+                if ( 0 == i) //initialize RD with previous depth buffer
+                {
+                    m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
+                }
+                else
+                {
+                    m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
+                }
+            }
+            runQuadTreeDecision(psQTPart, pOnePart->DownPartsIdx[i], dCostFinal, iMaxLevel, dLambda, yCbCr);
+            dCostSplit += dCostFinal;
+            if( m_bUseSBACRD )
+            {
+                m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_TEMP_BEST]);
+            }
+        }
+
+        if(dCostSplit < dCostNotSplit)
+        {
+            dCostFinal = dCostSplit;
+            pOnePart->bSplit      = true;
+            pOnePart->iLength     =  0;
+            pOnePart->iBestType   = -1;
+            if( m_bUseSBACRD )
+            {
+                m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
+            }
         }
         else
         {
-          m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
-        }
-      }  
-      runQuadTreeDecision(psQTPart, pOnePart->DownPartsIdx[i], dCostFinal, iMaxLevel, dLambda);
-      dCostSplit += dCostFinal;
-      if( m_bUseSBACRD )
-      {
-        m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_TEMP_BEST]);
-      }
-    }
-
-    if(dCostSplit < dCostNotSplit)
-    {
-      dCostFinal = dCostSplit;
-      pOnePart->bSplit      = true;
-      pOnePart->iLength     =  0;
-      pOnePart->iBestType   = -1;
-      if( m_bUseSBACRD )
-      {
-        m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
-      }
+            dCostFinal = dCostNotSplit;
+            pOnePart->bSplit = false;
+            for (Int i=0; i<NUM_DOWN_PART; i++)
+            {
+                disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]);
+            }
+            if( m_bUseSBACRD )
+            {
+                m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
+            }
+        }
     }
     else
     {
-      dCostFinal = dCostNotSplit;
-      pOnePart->bSplit = false;
-      for (Int i=0; i<NUM_DOWN_PART; i++)
-      {
-        disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]);
-      }
-      if( m_bUseSBACRD )
-      {
-        m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
-      }
-    }
-  }
-  else
-  {
-    dCostFinal = pOnePart->dMinCost;
-  }
+        dCostFinal = pOnePart->dMinCost;
+    }
 }
 
@@ -446,5 +446,5 @@
       if (m_iCount [i][j])
       {
-        delete [] m_iCount [i][j]; 
+        delete [] m_iCount [i][j];
       }
       if (m_iOffset[i][j])
@@ -454,5 +454,5 @@
       if (m_iOffsetOrg[i][j])
       {
-        delete [] m_iOffsetOrg[i][j]; 
+        delete [] m_iOffsetOrg[i][j];
       }
     }
@@ -463,5 +463,5 @@
     if (m_iDist[i])
     {
-      delete [] m_iDist[i]; 
+      delete [] m_iDist[i];
     }
     if (m_dCost[i])
@@ -471,5 +471,5 @@
     if (m_iCount [i])
     {
-      delete [] m_iCount [i]; 
+      delete [] m_iCount [i];
     }
     if (m_iOffset[i])
@@ -479,7 +479,6 @@
     if (m_iOffsetOrg[i])
     {
-      delete [] m_iOffsetOrg[i]; 
-    }
-
+      delete [] m_iOffsetOrg[i];
+    }
   }
   if (m_iDistOrg)
@@ -518,4 +517,47 @@
   {
     delete [] m_iOffsetOrg ; m_iOffsetOrg = NULL;
+  }
+  Int numLcu = m_iNumCuInWidth * m_iNumCuInHeight;
+
+  for (Int i=0;i<numLcu;i++)
+  {
+    for (Int j=0;j<3;j++)
+    {
+      for (Int k=0;k<MAX_NUM_SAO_TYPE;k++)
+      {
+        if (m_count_PreDblk [i][j][k])
+        {
+          delete [] m_count_PreDblk [i][j][k];
+        }
+        if (m_offsetOrg_PreDblk[i][j][k])
+        {
+          delete [] m_offsetOrg_PreDblk[i][j][k];
+        }
+      }
+      if (m_count_PreDblk [i][j])
+      {
+        delete [] m_count_PreDblk [i][j];
+      }
+      if (m_offsetOrg_PreDblk[i][j])
+      {
+        delete [] m_offsetOrg_PreDblk[i][j];
+      }
+    }
+    if (m_count_PreDblk [i])
+    {
+      delete [] m_count_PreDblk [i];
+    }
+    if (m_offsetOrg_PreDblk[i])
+    {
+      delete [] m_offsetOrg_PreDblk[i];
+    }
+  }
+  if (m_count_PreDblk)
+  {
+    delete [] m_count_PreDblk  ; m_count_PreDblk = NULL;
+  }
+  if (m_offsetOrg_PreDblk)
+  {
+    delete [] m_offsetOrg_PreDblk ; m_offsetOrg_PreDblk = NULL;
   }
 
@@ -546,7 +588,7 @@
 Void TEncSampleAdaptiveOffset::createEncBuffer()
 {
-  m_iDistOrg = new Int64 [m_iNumTotalParts]; 
-  m_dCostPartBest = new Double [m_iNumTotalParts]; 
-  m_iTypePartBest = new Int [m_iNumTotalParts]; 
+  m_iDistOrg = new Int64 [m_iNumTotalParts];
+  m_dCostPartBest = new Double [m_iNumTotalParts];
+  m_iTypePartBest = new Int [m_iNumTotalParts];
 
   m_iRate = new Int64* [m_iNumTotalParts];
@@ -561,16 +603,36 @@
   {
     m_iRate[i] = new Int64  [MAX_NUM_SAO_TYPE];
-    m_iDist[i] = new Int64  [MAX_NUM_SAO_TYPE]; 
-    m_dCost[i] = new Double [MAX_NUM_SAO_TYPE]; 
-
-    m_iCount [i] = new Int64 *[MAX_NUM_SAO_TYPE]; 
-    m_iOffset[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 
-    m_iOffsetOrg[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 
+    m_iDist[i] = new Int64  [MAX_NUM_SAO_TYPE];
+    m_dCost[i] = new Double [MAX_NUM_SAO_TYPE];
+
+    m_iCount [i] = new Int64 *[MAX_NUM_SAO_TYPE];
+    m_iOffset[i] = new Int64 *[MAX_NUM_SAO_TYPE];
+    m_iOffsetOrg[i] = new Int64 *[MAX_NUM_SAO_TYPE];
 
     for (Int j=0;j<MAX_NUM_SAO_TYPE;j++)
     {
-      m_iCount [i][j]   = new Int64 [MAX_NUM_SAO_CLASS]; 
-      m_iOffset[i][j]   = new Int64 [MAX_NUM_SAO_CLASS]; 
-      m_iOffsetOrg[i][j]= new Int64 [MAX_NUM_SAO_CLASS]; 
+      m_iCount [i][j]   = new Int64 [MAX_NUM_SAO_CLASS];
+      m_iOffset[i][j]   = new Int64 [MAX_NUM_SAO_CLASS];
+      m_iOffsetOrg[i][j]= new Int64 [MAX_NUM_SAO_CLASS];
+    }
+  }
+  Int numLcu = m_iNumCuInWidth * m_iNumCuInHeight;
+  m_count_PreDblk  = new Int64 ***[numLcu];
+  m_offsetOrg_PreDblk = new Int64 ***[numLcu];
+  for (Int i=0; i<numLcu; i++)
+  {
+    m_count_PreDblk[i]  = new Int64 **[3];
+    m_offsetOrg_PreDblk[i] = new Int64 **[3];
+
+    for (Int j=0;j<3;j++)
+    {
+      m_count_PreDblk [i][j] = new Int64 *[MAX_NUM_SAO_TYPE];
+      m_offsetOrg_PreDblk[i][j] = new Int64 *[MAX_NUM_SAO_TYPE];
+
+      for (Int k=0;k<MAX_NUM_SAO_TYPE;k++)
+      {
+        m_count_PreDblk [i][j][k]   = new Int64 [MAX_NUM_SAO_CLASS];
+        m_offsetOrg_PreDblk[i][j][k]= new Int64 [MAX_NUM_SAO_CLASS];
+      }
     }
   }
@@ -606,17 +668,14 @@
 
 /** Start SAO encoder
- * \param pcPic, pcEntropyCoder, pppcRDSbacCoder, pcRDGoOnSbacCoder 
+ * \param pcPic, pcEntropyCoder, pppcRDSbacCoder, pcRDGoOnSbacCoder
  */
 Void TEncSampleAdaptiveOffset::startSaoEnc( TComPic* pcPic, TEncEntropy* pcEntropyCoder, TEncSbac*** pppcRDSbacCoder, TEncSbac* pcRDGoOnSbacCoder)
 {
-  if( pcRDGoOnSbacCoder )
-    m_bUseSBACRD = true;
-  else
-    m_bUseSBACRD = false;
-
+  m_bUseSBACRD = true;
   m_pcPic = pcPic;
   m_pcEntropyCoder = pcEntropyCoder;
 
   m_pcRDGoOnSbacCoder = pcRDGoOnSbacCoder;
+  m_pcEntropyCoder->setEntropyCoder(m_pcRDGoOnSbacCoder, pcPic->getSlice(0));
   m_pcEntropyCoder->resetEntropy();
   m_pcEntropyCoder->resetBits();
@@ -672,5 +731,5 @@
       if (classIdx)
       {
-        stats[classIdx] += (pOrg[x] - pRec[x]); 
+        stats[classIdx] += (pOrg[x] - pRec[x]);
         count[classIdx] ++;
       }
@@ -685,5 +744,4 @@
   pRec   = pRecStart;
 
-
   startX = (pbBorderAvail[SGU_L]) ? 0 : 1;
   endX   = (pbBorderAvail[SGU_R]) ? width : (width -1);
@@ -693,5 +751,5 @@
     for (x=startX; x< endX; x++)
     {
-      signRight =  xSign(pRec[x] - pRec[x+1]); 
+      signRight =  xSign(pRec[x] - pRec[x+1]);
       edgeType =  signRight + signLeft + 2;
       signLeft  = -signRight;
@@ -726,5 +784,5 @@
     for (x=0; x< width; x++)
     {
-      signDown     =  xSign(pRec[x] - pRec[x+stride]); 
+      signDown     =  xSign(pRec[x] - pRec[x+stride]);
       edgeType    =  signDown + m_iUpBuff1[x] + 2;
       m_iUpBuff1[x] = -signDown;
@@ -785,5 +843,5 @@
       count[m_auiEoTable[edgeType]] ++;
 
-      m_iUpBufft[x+1] = -signDown1; 
+      m_iUpBufft[x+1] = -signDown1;
     }
     m_iUpBufft[startX] = xSign(pRec[stride+startX] - pRec[startX-1]);
@@ -931,15 +989,7 @@
       posOffset = (yPos* stride) + xPos;
 
-#if HHI_INTERVIEW_SKIP
-      if( !m_pcPic->getCU(iAddr)->getRenderable(0 ))
-      {
       calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail);
-      }
-#else
-      calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail);
-#endif
-    }
-  }
-
+    }
+  }
 }
 
@@ -974,4 +1024,2453 @@
   Int iIsChroma = (iYCbCr!=0)? 1:0;
   Int numSkipLine = iIsChroma? 2:4;
+  if (m_saoLcuBasedOptimization == 0)
+  {
+    numSkipLine = 0;
+  }
+
+#if SAO_SKIP_RIGHT
+  Int numSkipLineRight = iIsChroma? 3:5;
+  if (m_saoLcuBasedOptimization == 0)
+  {
+    numSkipLineRight = 0;
+  }
+#endif
+
+  iPicWidthTmp  = m_iPicWidth  >> iIsChroma;
+  iPicHeightTmp = m_iPicHeight >> iIsChroma;
+  iLcuWidth     = iLcuWidth    >> iIsChroma;
+  iLcuHeight    = iLcuHeight   >> iIsChroma;
+  uiLPelX       = uiLPelX      >> iIsChroma;
+  uiTPelY       = uiTPelY      >> iIsChroma;
+  uiRPelX       = uiLPelX + iLcuWidth  ;
+  uiBPelY       = uiTPelY + iLcuHeight ;
+  uiRPelX       = uiRPelX > iPicWidthTmp  ? iPicWidthTmp  : uiRPelX;
+  uiBPelY       = uiBPelY > iPicHeightTmp ? iPicHeightTmp : uiBPelY;
+  iLcuWidth     = uiRPelX - uiLPelX;
+  iLcuHeight    = uiBPelY - uiTPelY;
+
+  iStride    =  (iYCbCr == 0)? m_pcPic->getStride(): m_pcPic->getCStride();
+
+//if(iSaoType == BO_0 || iSaoType == BO_1)
+  {
+    if( m_saoLcuBasedOptimization && m_saoLcuBoundary )
+    {
+      numSkipLine = iIsChroma? 1:3;
+      numSkipLineRight = iIsChroma? 2:4;
+    }
+    iStats = m_iOffsetOrg[iPartIdx][SAO_BO];
+    iCount = m_iCount    [iPartIdx][SAO_BO];
+
+    pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);
+    pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);
+
+#if SAO_SKIP_RIGHT
+    iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth : iLcuWidth-numSkipLineRight;
+#endif
+
+    iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight : iLcuHeight-numSkipLine;
+    for (y=0; y<iEndY; y++)
+    {
+#if SAO_SKIP_RIGHT
+      for (x=0; x<iEndX; x++)
+#else
+      for (x=0; x<iLcuWidth; x++)
+#endif
+      {
+        iClassIdx = m_lumaTableBo[pRec[x]];
+        if (iClassIdx)
+        {
+          iStats[iClassIdx] += (pOrg[x] - pRec[x]); 
+          iCount[iClassIdx] ++;
+        }
+      }
+      pOrg += iStride;
+      pRec += iStride;
+    }
+
+  }
+  Int iSignLeft;
+  Int iSignRight;
+  Int iSignDown;
+  Int iSignDown1;
+  Int iSignDown2;
+
+  UInt uiEdgeType;
+
+//if (iSaoType == EO_0  || iSaoType == EO_1 || iSaoType == EO_2 || iSaoType == EO_3)
+  {
+  //if (iSaoType == EO_0)
+    {
+      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )
+      {
+        numSkipLine = iIsChroma? 1:3;
+        numSkipLineRight = iIsChroma? 3:5;
+      }
+      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_0];
+      iCount = m_iCount    [iPartIdx][SAO_EO_0];
+
+      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);
+      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);
+
+      iStartX = (uiLPelX == 0) ? 1 : 0;
+#if SAO_SKIP_RIGHT
+      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight;
+#else
+      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth;
+#endif
+      for (y=0; y<iLcuHeight-numSkipLine; y++)
+      {
+        iSignLeft = xSign(pRec[iStartX] - pRec[iStartX-1]);
+        for (x=iStartX; x< iEndX; x++)
+        {
+          iSignRight =  xSign(pRec[x] - pRec[x+1]); 
+          uiEdgeType =  iSignRight + iSignLeft + 2;
+          iSignLeft  = -iSignRight;
+
+          iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+          iCount[m_auiEoTable[uiEdgeType]] ++;
+        }
+        pOrg += iStride;
+        pRec += iStride;
+      }
+    }
+
+  //if (iSaoType == EO_1)
+    {
+      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )
+      {
+        numSkipLine = iIsChroma? 2:4;
+        numSkipLineRight = iIsChroma? 2:4;
+      }
+      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_1];
+      iCount = m_iCount    [iPartIdx][SAO_EO_1];
+
+      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);
+      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);
+
+      iStartY = (uiTPelY == 0) ? 1 : 0;
+#if SAO_SKIP_RIGHT
+      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth : iLcuWidth-numSkipLineRight;
+#endif
+      iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine;
+      if (uiTPelY == 0)
+      {
+        pOrg += iStride;
+        pRec += iStride;
+      }
+
+      for (x=0; x< iLcuWidth; x++)
+      {
+        m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride]);
+      }
+      for (y=iStartY; y<iEndY; y++)
+      {
+#if SAO_SKIP_RIGHT
+        for (x=0; x<iEndX; x++)
+#else
+        for (x=0; x<iLcuWidth; x++)
+#endif
+        {
+          iSignDown     =  xSign(pRec[x] - pRec[x+iStride]); 
+          uiEdgeType    =  iSignDown + m_iUpBuff1[x] + 2;
+          m_iUpBuff1[x] = -iSignDown;
+
+          iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+          iCount[m_auiEoTable[uiEdgeType]] ++;
+        }
+        pOrg += iStride;
+        pRec += iStride;
+      }
+    }
+  //if (iSaoType == EO_2)
+    {
+      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )
+      {
+        numSkipLine = iIsChroma? 2:4;
+        numSkipLineRight = iIsChroma? 3:5;
+      }
+      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_2];
+      iCount = m_iCount    [iPartIdx][SAO_EO_2];
+
+      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);
+      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);
+
+      iStartX = (uiLPelX == 0) ? 1 : 0;
+#if SAO_SKIP_RIGHT
+      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight;
+#else
+      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth;
+#endif
+
+      iStartY = (uiTPelY == 0) ? 1 : 0;
+      iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine;
+      if (uiTPelY == 0)
+      {
+        pOrg += iStride;
+        pRec += iStride;
+      }
+
+      for (x=iStartX; x<iEndX; x++)
+      {
+        m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride-1]);
+      }
+      for (y=iStartY; y<iEndY; y++)
+      {
+        iSignDown2 = xSign(pRec[iStride+iStartX] - pRec[iStartX-1]);
+        for (x=iStartX; x<iEndX; x++)
+        {
+          iSignDown1      =  xSign(pRec[x] - pRec[x+iStride+1]) ;
+          uiEdgeType      =  iSignDown1 + m_iUpBuff1[x] + 2;
+          m_iUpBufft[x+1] = -iSignDown1; 
+          iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+          iCount[m_auiEoTable[uiEdgeType]] ++;
+        }
+        m_iUpBufft[iStartX] = iSignDown2;
+        ipSwap     = m_iUpBuff1;
+        m_iUpBuff1 = m_iUpBufft;
+        m_iUpBufft = ipSwap;
+
+        pRec += iStride;
+        pOrg += iStride;
+      }
+    } 
+  //if (iSaoType == EO_3  )
+    {
+      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )
+      {
+        numSkipLine = iIsChroma? 2:4;
+        numSkipLineRight = iIsChroma? 3:5;
+      }
+      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_3];
+      iCount = m_iCount    [iPartIdx][SAO_EO_3];
+
+      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);
+      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);
+
+      iStartX = (uiLPelX == 0) ? 1 : 0;
+#if SAO_SKIP_RIGHT
+      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight;
+#else
+      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth;
+#endif
+
+      iStartY = (uiTPelY == 0) ? 1 : 0;
+      iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine;
+      if (iStartY == 1)
+      {
+        pOrg += iStride;
+        pRec += iStride;
+      }
+
+      for (x=iStartX-1; x<iEndX; x++)
+      {
+        m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride+1]);
+      }
+
+      for (y=iStartY; y<iEndY; y++)
+      {
+        for (x=iStartX; x<iEndX; x++)
+        {
+          iSignDown1      =  xSign(pRec[x] - pRec[x+iStride-1]) ;
+          uiEdgeType      =  iSignDown1 + m_iUpBuff1[x] + 2;
+          m_iUpBuff1[x-1] = -iSignDown1; 
+          iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+          iCount[m_auiEoTable[uiEdgeType]] ++;
+        }
+        m_iUpBuff1[iEndX-1] = xSign(pRec[iEndX-1 + iStride] - pRec[iEndX]);
+
+        pRec += iStride;
+        pOrg += iStride;
+      } 
+    } 
+  }
+}
+
+
+Void TEncSampleAdaptiveOffset::calcSaoStatsCu_BeforeDblk( TComPic* pcPic )
+{
+  Int addr, yCbCr;
+  Int x,y;
+  TComSPS *pTmpSPS =  pcPic->getSlice(0)->getSPS();
+
+  Pel* pOrg;
+  Pel* pRec;
+  Int stride;
+  Int lcuWidth  = pTmpSPS->getMaxCUHeight();
+  Int lcuHeight = pTmpSPS->getMaxCUWidth();
+  UInt rPelX;
+  UInt bPelY;
+  Int64* stats;
+  Int64* count;
+  Int classIdx;
+  Int picWidthTmp = 0;
+  Int picHeightTmp = 0;
+  Int startX;
+  Int startY;
+  Int endX;
+  Int endY;
+  Int firstX, firstY;
+
+  Int idxY;
+  Int idxX;
+  Int frameHeightInCU = m_iNumCuInHeight;
+  Int frameWidthInCU  = m_iNumCuInWidth;
+  Int j, k;
+
+  Int isChroma;
+  Int numSkipLine, numSkipLineRight;
+
+  UInt lPelX, tPelY;
+  TComDataCU *pTmpCu;
+
+  for (idxY = 0; idxY< frameHeightInCU; idxY++)
+  {
+    for (idxX = 0; idxX< frameWidthInCU; idxX++)
+    {
+      lcuWidth  = pTmpSPS->getMaxCUHeight();
+      lcuHeight = pTmpSPS->getMaxCUWidth();
+      addr     = idxX  + frameWidthInCU*idxY;
+      pTmpCu = pcPic->getCU(addr);
+      lPelX   = pTmpCu->getCUPelX();
+      tPelY   = pTmpCu->getCUPelY();
+      for( yCbCr = 0; yCbCr < 3; yCbCr++ )
+      {
+        isChroma = (yCbCr!=0)? 1:0;
+
+        for ( j=0;j<MAX_NUM_SAO_TYPE;j++)
+        {
+          for ( k=0;k< MAX_NUM_SAO_CLASS;k++)
+          {
+            m_count_PreDblk    [addr][yCbCr][j][k] = 0;
+            m_offsetOrg_PreDblk[addr][yCbCr][j][k] = 0;
+          }  
+        }
+        if( yCbCr == 0 )
+        {
+          picWidthTmp  = m_iPicWidth;
+          picHeightTmp = m_iPicHeight;
+        }
+        else if( yCbCr == 1 )
+        {
+          picWidthTmp  = m_iPicWidth  >> isChroma;
+          picHeightTmp = m_iPicHeight >> isChroma;
+          lcuWidth     = lcuWidth    >> isChroma;
+          lcuHeight    = lcuHeight   >> isChroma;
+          lPelX       = lPelX      >> isChroma;
+          tPelY       = tPelY      >> isChroma;
+        }
+        rPelX       = lPelX + lcuWidth  ;
+        bPelY       = tPelY + lcuHeight ;
+        rPelX       = rPelX > picWidthTmp  ? picWidthTmp  : rPelX;
+        bPelY       = bPelY > picHeightTmp ? picHeightTmp : bPelY;
+        lcuWidth     = rPelX - lPelX;
+        lcuHeight    = bPelY - tPelY;
+
+        stride    =  (yCbCr == 0)? pcPic->getStride(): pcPic->getCStride();
+
+        //if(iSaoType == BO)
+
+        numSkipLine = isChroma? 1:3;
+        numSkipLineRight = isChroma? 2:4;
+
+        stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_BO];
+        count = m_count_PreDblk[addr][yCbCr][SAO_BO];
+
+        pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr);
+        pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr);
+
+        startX   = (rPelX == picWidthTmp) ? lcuWidth : lcuWidth-numSkipLineRight;
+        startY   = (bPelY == picHeightTmp) ? lcuHeight : lcuHeight-numSkipLine;
+
+        for (y=0; y<lcuHeight; y++)
+        {
+          for (x=0; x<lcuWidth; x++)
+          {
+            if( x < startX && y < startY )
+              continue;
+
+            classIdx = m_lumaTableBo[pRec[x]];
+            if (classIdx)
+            {
+              stats[classIdx] += (pOrg[x] - pRec[x]); 
+              count[classIdx] ++;
+            }
+          }
+          pOrg += stride;
+          pRec += stride;
+        }
+
+        Int signLeft;
+        Int signRight;
+        Int signDown;
+        Int signDown1;
+        Int signDown2;
+
+        UInt uiEdgeType;
+
+        //if (iSaoType == EO_0)
+
+        numSkipLine = isChroma? 1:3;
+        numSkipLineRight = isChroma? 3:5;
+
+        stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_0];
+        count = m_count_PreDblk[addr][yCbCr][SAO_EO_0];
+
+        pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr);
+        pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr);
+
+        startX   = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth-numSkipLineRight;
+        startY   = (bPelY == picHeightTmp) ? lcuHeight : lcuHeight-numSkipLine;
+        firstX   = (lPelX == 0) ? 1 : 0;
+        endX   = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth;
+
+        for (y=0; y<lcuHeight; y++)
+        {
+          signLeft = xSign(pRec[firstX] - pRec[firstX-1]);
+          for (x=firstX; x< endX; x++)
+          {
+            signRight =  xSign(pRec[x] - pRec[x+1]); 
+            uiEdgeType =  signRight + signLeft + 2;
+            signLeft  = -signRight;
+
+            if( x < startX && y < startY )
+              continue;
+
+            stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+            count[m_auiEoTable[uiEdgeType]] ++;
+          }
+          pOrg += stride;
+          pRec += stride;
+        }
+
+        //if (iSaoType == EO_1)
+
+        numSkipLine = isChroma? 2:4;
+        numSkipLineRight = isChroma? 2:4;
+
+        stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_1];
+        count = m_count_PreDblk[addr][yCbCr][SAO_EO_1];
+
+        pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr);
+        pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr);
+
+        startX   = (rPelX == picWidthTmp) ? lcuWidth : lcuWidth-numSkipLineRight;
+        startY   = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight-numSkipLine;
+        firstY = (tPelY == 0) ? 1 : 0;
+        endY   = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight;
+        if (firstY == 1)
+        {
+          pOrg += stride;
+          pRec += stride;
+        }
+
+        for (x=0; x< lcuWidth; x++)
+        {
+          m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride]);
+        }
+        for (y=firstY; y<endY; y++)
+        {
+          for (x=0; x<lcuWidth; x++)
+          {
+            signDown     =  xSign(pRec[x] - pRec[x+stride]); 
+            uiEdgeType    =  signDown + m_iUpBuff1[x] + 2;
+            m_iUpBuff1[x] = -signDown;
+
+            if( x < startX && y < startY )
+              continue;
+
+            stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+            count[m_auiEoTable[uiEdgeType]] ++;
+          }
+          pOrg += stride;
+          pRec += stride;
+        }
+
+        //if (iSaoType == EO_2)
+
+        numSkipLine = isChroma? 2:4;
+        numSkipLineRight = isChroma? 3:5;
+
+        stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_2];
+        count = m_count_PreDblk[addr][yCbCr][SAO_EO_2];
+
+        pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr);
+        pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr);
+
+        startX   = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth-numSkipLineRight;
+        startY   = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight-numSkipLine;
+        firstX   = (lPelX == 0) ? 1 : 0;
+        firstY = (tPelY == 0) ? 1 : 0;
+        endX   = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth;
+        endY   = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight;
+        if (firstY == 1)
+        {
+          pOrg += stride;
+          pRec += stride;
+        }
+
+        for (x=firstX; x<endX; x++)
+        {
+          m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride-1]);
+        }
+        for (y=firstY; y<endY; y++)
+        {
+          signDown2 = xSign(pRec[stride+startX] - pRec[startX-1]);
+          for (x=firstX; x<endX; x++)
+          {
+            signDown1      =  xSign(pRec[x] - pRec[x+stride+1]) ;
+            uiEdgeType      =  signDown1 + m_iUpBuff1[x] + 2;
+            m_iUpBufft[x+1] = -signDown1; 
+
+            if( x < startX && y < startY )
+              continue;
+
+            stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+            count[m_auiEoTable[uiEdgeType]] ++;
+          }
+          m_iUpBufft[firstX] = signDown2;
+          ipSwap     = m_iUpBuff1;
+          m_iUpBuff1 = m_iUpBufft;
+          m_iUpBufft = ipSwap;
+
+          pRec += stride;
+          pOrg += stride;
+        }
+
+        //if (iSaoType == EO_3)
+
+        numSkipLine = isChroma? 2:4;
+        numSkipLineRight = isChroma? 3:5;
+
+        stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_3];
+        count = m_count_PreDblk[addr][yCbCr][SAO_EO_3];
+
+        pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr);
+        pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr);
+
+        startX   = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth-numSkipLineRight;
+        startY   = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight-numSkipLine;
+        firstX   = (lPelX == 0) ? 1 : 0;
+        firstY = (tPelY == 0) ? 1 : 0;
+        endX   = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth;
+        endY   = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight;
+        if (firstY == 1)
+        {
+          pOrg += stride;
+          pRec += stride;
+        }
+
+        for (x=firstX-1; x<endX; x++)
+        {
+          m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride+1]);
+        }
+
+        for (y=firstY; y<endY; y++)
+        {
+          for (x=firstX; x<endX; x++)
+          {
+            signDown1      =  xSign(pRec[x] - pRec[x+stride-1]) ;
+            uiEdgeType      =  signDown1 + m_iUpBuff1[x] + 2;
+            m_iUpBuff1[x-1] = -signDown1; 
+
+            if( x < startX && y < startY )
+              continue;
+
+            stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);
+            count[m_auiEoTable[uiEdgeType]] ++;
+          }
+          m_iUpBuff1[endX-1] = xSign(pRec[endX-1 + stride] - pRec[endX]);
+
+          pRec += stride;
+          pOrg += stride;
+        }
+      }
+    }
+  }
+}
+
+
+/** get SAO statistics
+ * \param  *psQTPart,  iYCbCr
+ */
+Void TEncSampleAdaptiveOffset::getSaoStats(SAOQTPart *psQTPart, Int iYCbCr)
+{
+  Int iLevelIdx, iPartIdx, iTypeIdx, iClassIdx;
+  Int i;
+  Int iNumTotalType = MAX_NUM_SAO_TYPE;
+  Int LcuIdxX;
+  Int LcuIdxY;
+  Int iAddr;
+  Int iFrameWidthInCU = m_pcPic->getFrameWidthInCU();
+  Int iDownPartIdx;
+  Int iPartStart;
+  Int iPartEnd;
+  SAOQTPart*  pOnePart; 
+
+  if (m_uiMaxSplitLevel == 0)
+  {
+    iPartIdx = 0;
+    pOnePart = &(psQTPart[iPartIdx]);
+    for (LcuIdxY = pOnePart->StartCUY; LcuIdxY<= pOnePart->EndCUY; LcuIdxY++)
+    {
+      for (LcuIdxX = pOnePart->StartCUX; LcuIdxX<= pOnePart->EndCUX; LcuIdxX++)
+      {
+        iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX;
+        calcSaoStatsCu(iAddr, iPartIdx, iYCbCr);
+      }
+    }
+  }
+  else
+  {
+    for(iPartIdx=m_aiNumCulPartsLevel[m_uiMaxSplitLevel-1]; iPartIdx<m_aiNumCulPartsLevel[m_uiMaxSplitLevel]; iPartIdx++)
+    {
+      pOnePart = &(psQTPart[iPartIdx]);
+      for (LcuIdxY = pOnePart->StartCUY; LcuIdxY<= pOnePart->EndCUY; LcuIdxY++)
+      {
+        for (LcuIdxX = pOnePart->StartCUX; LcuIdxX<= pOnePart->EndCUX; LcuIdxX++)
+        {
+          iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX;
+          calcSaoStatsCu(iAddr, iPartIdx, iYCbCr);
+        }
+      }
+    }
+    for (iLevelIdx = m_uiMaxSplitLevel-1; iLevelIdx>=0; iLevelIdx-- )
+    {
+      iPartStart = (iLevelIdx > 0) ? m_aiNumCulPartsLevel[iLevelIdx-1] : 0;
+      iPartEnd   = m_aiNumCulPartsLevel[iLevelIdx];
+
+      for(iPartIdx = iPartStart; iPartIdx < iPartEnd; iPartIdx++)
+      {
+        pOnePart = &(psQTPart[iPartIdx]);
+        for (i=0; i< NUM_DOWN_PART; i++)
+        {
+          iDownPartIdx = pOnePart->DownPartsIdx[i];
+          for (iTypeIdx=0; iTypeIdx<iNumTotalType; iTypeIdx++)
+          {
+            for (iClassIdx=0; iClassIdx< (iTypeIdx < SAO_BO ? m_iNumClass[iTypeIdx] : SAO_MAX_BO_CLASSES) +1; iClassIdx++)
+            {
+              m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx] += m_iOffsetOrg[iDownPartIdx][iTypeIdx][iClassIdx];
+              m_iCount [iPartIdx][iTypeIdx][iClassIdx]    += m_iCount [iDownPartIdx][iTypeIdx][iClassIdx];
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+/** reset offset statistics 
+ * \param 
+ */
+Void TEncSampleAdaptiveOffset::resetStats()
+{
+  for (Int i=0;i<m_iNumTotalParts;i++)
+  {
+    m_dCostPartBest[i] = MAX_DOUBLE;
+    m_iTypePartBest[i] = -1;
+    m_iDistOrg[i] = 0;
+    for (Int j=0;j<MAX_NUM_SAO_TYPE;j++)
+    {
+      m_iDist[i][j] = 0;
+      m_iRate[i][j] = 0;
+      m_dCost[i][j] = 0;
+      for (Int k=0;k<MAX_NUM_SAO_CLASS;k++)
+      {
+        m_iCount [i][j][k] = 0;
+        m_iOffset[i][j][k] = 0;
+        m_iOffsetOrg[i][j][k] = 0;
+      }  
+    }
+  }
+}
+
+#if SAO_CHROMA_LAMBDA 
+/** Sample adaptive offset process
+ * \param pcSaoParam
+ * \param dLambdaLuma
+ * \param dLambdaChroma
+ */
+#if SAO_ENCODING_CHOICE
+Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambdaLuma, Double dLambdaChroma, Int depth)
+#else
+Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambdaLuma, Double dLambdaChroma)
+#endif
+#else
+/** Sample adaptive offset process
+ * \param dLambda
+ */
+Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambda)
+#endif
+{
+    m_eSliceType          =  m_pcPic->getSlice(0)->getSliceType();
+    m_iPicNalReferenceIdc = (m_pcPic->getSlice(0)->isReferenced() ? 1 :0);
+
+#if SAO_CHROMA_LAMBDA 
+    m_dLambdaLuma    = dLambdaLuma;
+    m_dLambdaChroma  = dLambdaChroma;
+#else
+    m_dLambdaLuma    = dLambda;
+    m_dLambdaChroma  = dLambda;
+#endif
+
+    if(m_bUseNIF)
+    {
+        m_pcPic->getPicYuvRec()->copyToPic(m_pcYuvTmp);
+    }
+
+#if FULL_NBIT
+    m_uiSaoBitIncrease = g_uiBitDepth + (g_uiBitDepth-8) - min((Int)(g_uiBitDepth + (g_uiBitDepth-8)), 10);
+#else
+    m_uiSaoBitIncrease = g_uiBitDepth + g_uiBitIncrement - min((Int)(g_uiBitDepth + g_uiBitIncrement), 10);
+#endif
+
+#if FULL_NBIT
+    m_iOffsetTh = 1 << ( min((Int)(g_uiBitDepth + (g_uiBitDepth-8)-5),5) );
+#else
+    m_iOffsetTh = 1 << ( min((Int)(g_uiBitDepth + g_uiBitIncrement-5),5) );
+#endif
+
+    resetSAOParam(pcSaoParam);
+    if( !m_saoLcuBasedOptimization || !m_saoLcuBoundary )
+    {
+        resetStats();
+    }
+    Double dCostFinal = 0;
+    if ( m_saoLcuBasedOptimization)
+    {
+#if SAO_ENCODING_CHOICE
+        rdoSaoUnitAll(pcSaoParam, dLambdaLuma, dLambdaChroma, depth);
+#else
+        rdoSaoUnitAll(pcSaoParam, dLambdaLuma, dLambdaChroma);
+#endif
+    }
+    else
+    {
+        pcSaoParam->bSaoFlag[0] = 1;
+        pcSaoParam->bSaoFlag[1] = 0;
+        dCostFinal = 0;
+        Double lambdaRdo =  dLambdaLuma;
+        resetStats();
+        getSaoStats(pcSaoParam->psSaoPart[0], 0);
+        runQuadTreeDecision(pcSaoParam->psSaoPart[0], 0, dCostFinal, m_uiMaxSplitLevel, lambdaRdo, 0);
+        pcSaoParam->bSaoFlag[0] = dCostFinal < 0 ? 1:0;
+        if(pcSaoParam->bSaoFlag[0])
+        {
+            convertQT2SaoUnit(pcSaoParam, 0, 0);
+            assignSaoUnitSyntax(pcSaoParam->saoLcuParam[0],  pcSaoParam->psSaoPart[0], pcSaoParam->oneUnitFlag[0], 0);
+        }
+    }
+
+    if (pcSaoParam->bSaoFlag[0])
+    {
+        processSaoUnitAll( pcSaoParam->saoLcuParam[0], pcSaoParam->oneUnitFlag[0], 0);
+    }
+    if (pcSaoParam->bSaoFlag[1])
+    {
+        processSaoUnitAll( pcSaoParam->saoLcuParam[1], pcSaoParam->oneUnitFlag[1], 1);
+        processSaoUnitAll( pcSaoParam->saoLcuParam[2], pcSaoParam->oneUnitFlag[2], 2);
+    }
+}
+/** Check merge SAO unit
+* \param saoUnitCurr current SAO unit 
+* \param saoUnitCheck SAO unit tobe check
+* \param dir direction
+*/
+Void TEncSampleAdaptiveOffset::checkMerge(SaoLcuParam * saoUnitCurr, SaoLcuParam * saoUnitCheck, Int dir)
+{
+    Int i ;
+    Int countDiff = 0;
+    if (saoUnitCurr->partIdx != saoUnitCheck->partIdx)
+    {
+        if (saoUnitCurr->typeIdx !=-1)
+        {
+            if (saoUnitCurr->typeIdx == saoUnitCheck->typeIdx)
+            {
+                for (i=0;i<saoUnitCurr->length;i++)
+                {
+                    countDiff += (saoUnitCurr->offset[i] != saoUnitCheck->offset[i]);
+                }
+                countDiff += (saoUnitCurr->subTypeIdx != saoUnitCheck->subTypeIdx);
+                if (countDiff ==0)
+                {
+                    saoUnitCurr->partIdx = saoUnitCheck->partIdx;
+                    if (dir == 1)
+                    {
+                        saoUnitCurr->mergeUpFlag = 1;
+                        saoUnitCurr->mergeLeftFlag = 0;
+                    }
+                    else
+                    {
+                        saoUnitCurr->mergeUpFlag = 0;
+                        saoUnitCurr->mergeLeftFlag = 1;
+                    }
+                }
+            }
+        }
+        else
+        {
+            if (saoUnitCurr->typeIdx == saoUnitCheck->typeIdx)
+            {
+                saoUnitCurr->partIdx = saoUnitCheck->partIdx;
+                if (dir == 1)
+                {
+                    saoUnitCurr->mergeUpFlag = 1;
+                    saoUnitCurr->mergeLeftFlag = 0;
+                }
+                else
+                {
+                    saoUnitCurr->mergeUpFlag = 0;
+                    saoUnitCurr->mergeLeftFlag = 1;
+                }
+            }
+        }
+    }
+}
+/** Assign SAO unit syntax from picture-based algorithm
+* \param saoLcuParam SAO LCU parameters
+* \param saoPart SAO part
+* \param oneUnitFlag SAO one unit flag
+* \param iYCbCr color component Index
+*/
+Void TEncSampleAdaptiveOffset::assignSaoUnitSyntax(SaoLcuParam* saoLcuParam,  SAOQTPart* saoPart, Bool &oneUnitFlag, Int yCbCr)
+{
+    if (saoPart->bSplit == 0)
+    {
+        oneUnitFlag = 1;
+    }
+    else
+    {
+        Int i,j, addr, addrUp, addrLeft,  idx, idxUp, idxLeft,  idxCount;
+    
+        oneUnitFlag = 0;
+        
+        idxCount = -1;
+        saoLcuParam[0].mergeUpFlag = 0;
+        saoLcuParam[0].mergeLeftFlag = 0;
+        
+        for (j=0;j<m_iNumCuInHeight;j++)
+        {
+            for (i=0;i<m_iNumCuInWidth;i++)
+            {
+                addr     = i + j*m_iNumCuInWidth;
+                addrLeft = (addr%m_iNumCuInWidth == 0) ? -1 : addr - 1;
+                addrUp   = (addr<m_iNumCuInWidth)      ? -1 : addr - m_iNumCuInWidth;
+                idx      = saoLcuParam[addr].partIdxTmp;
+                idxLeft  = (addrLeft == -1) ? -1 : saoLcuParam[addrLeft].partIdxTmp;
+                idxUp    = (addrUp == -1)   ? -1 : saoLcuParam[addrUp].partIdxTmp;
+
+                if(idx!=idxLeft && idx!=idxUp)
+                {
+                    saoLcuParam[addr].mergeUpFlag   = 0; idxCount++;
+                    saoLcuParam[addr].mergeLeftFlag = 0;
+                    saoLcuParam[addr].partIdx = idxCount;
+                }
+                else if (idx==idxLeft)
+                {       
+                    saoLcuParam[addr].mergeUpFlag   = 1;
+                    saoLcuParam[addr].mergeLeftFlag = 1;
+                    saoLcuParam[addr].partIdx = saoLcuParam[addrLeft].partIdx;
+                }
+                else if (idx==idxUp)
+                {
+                    saoLcuParam[addr].mergeUpFlag   = 1;
+                    saoLcuParam[addr].mergeLeftFlag = 0;
+                    saoLcuParam[addr].partIdx = saoLcuParam[addrUp].partIdx;
+                }
+                if (addrUp != -1)
+                {
+                    checkMerge(&saoLcuParam[addr], &saoLcuParam[addrUp], 1);
+                }
+                if (addrLeft != -1)
+                {
+                    checkMerge(&saoLcuParam[addr], &saoLcuParam[addrLeft], 0);
+                }
+            }
+        }
+    }
+}
+/** rate distortion optimization of all SAO units
+* \param saoParam SAO parameters
+* \param lambda 
+* \param lambdaChroma
+*/
+#if SAO_ENCODING_CHOICE
+Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma, Int depth)
+#else
+Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma)
+#endif
+{
+    Int idxY;
+    Int idxX;
+    Int frameHeightInCU = saoParam->numCuInHeight;
+    Int frameWidthInCU  = saoParam->numCuInWidth;
+    Int j, k;
+    Int addr = 0;
+    Int addrUp = -1;
+    Int addrLeft = -1;
+    Int compIdx = 0;
+    SaoLcuParam mergeSaoParam[3][2];
+    Double compDistortion[3];
+
+    saoParam->bSaoFlag[0] = true;
+    saoParam->bSaoFlag[1] = true;
+    saoParam->oneUnitFlag[0] = false;
+    saoParam->oneUnitFlag[1] = false;
+    saoParam->oneUnitFlag[2] = false;
+
+#if SAO_ENCODING_CHOICE
+#if SAO_ENCODING_CHOICE_CHROMA
+    Int numNoSao[2];
+    numNoSao[0] = 0;// Luma 
+    numNoSao[1] = 0;// Chroma 
+    if( depth > 0 && m_depthSaoRate[0][depth-1] > SAO_ENCODING_RATE )
+    {
+        saoParam->bSaoFlag[0] = false;
+    }
+
+    if( depth > 0 && m_depthSaoRate[1][depth-1] > SAO_ENCODING_RATE_CHROMA )
+    {
+        saoParam->bSaoFlag[1] = false;
+    }
+#else
+    Int numNoSao = 0;
+
+    if( depth > 0 && m_depth0SaoRate > SAO_ENCODING_RATE )
+    {
+        saoParam->bSaoFlag[0] = false;
+        saoParam->bSaoFlag[1] = false;
+    }
+#endif
+#endif
+
+    for (idxY = 0; idxY< frameHeightInCU; idxY++)
+    {
+        for (idxX = 0; idxX< frameWidthInCU; idxX++)
+        {
+            addr     = idxX  + frameWidthInCU*idxY;
+            addrUp   = addr < frameWidthInCU ? -1:idxX   + frameWidthInCU*(idxY-1);
+            addrLeft = idxX == 0               ? -1:idxX-1 + frameWidthInCU*idxY;
+            Int allowMergeLeft = 1;
+            Int allowMergeUp   = 1;
+            UInt rate;
+            Double bestCost, mergeCost;
+
+            if (idxX!=0)
+            { 
+                // check tile id and slice id 
+                if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-1) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-1)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx()))
+                {
+                    allowMergeLeft = 0;
+                }
+            }
+            else
+            {
+                allowMergeLeft = 0;
+            }
+            if (idxY!=0)
+            {
+                if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-m_iNumCuInWidth) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-m_iNumCuInWidth)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx()))
+                {
+                    allowMergeUp = 0;
+                }
+            }
+            else
+            {
+                allowMergeUp = 0;
+            }
+
+            compDistortion[0] = 0; 
+            compDistortion[1] = 0; 
+            compDistortion[2] = 0;
+            m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
+
+            if (allowMergeLeft)
+            {
+                m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0); 
+            }
+            if (allowMergeUp)
+            {
+                m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0);
+            }
+
+            m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_TEMP_BEST] );
+
+            // reset stats Y, Cb, Cr
+            for ( compIdx=0;compIdx<3;compIdx++)
+            {
+                for ( j=0;j<MAX_NUM_SAO_TYPE;j++)
+                {
+                    for ( k=0;k< MAX_NUM_SAO_CLASS;k++)
+                    {
+                        m_iOffset   [compIdx][j][k] = 0;
+                        if( m_saoLcuBasedOptimization && m_saoLcuBoundary )
+                        {
+                            m_iCount    [compIdx][j][k] = m_count_PreDblk    [addr][compIdx][j][k];
+                            m_iOffsetOrg[compIdx][j][k] = m_offsetOrg_PreDblk[addr][compIdx][j][k];
+                        }
+                        else
+                        {
+                            m_iCount    [compIdx][j][k] = 0;
+                            m_iOffsetOrg[compIdx][j][k] = 0;
+                        }
+                    }  
+                }
+                saoParam->saoLcuParam[compIdx][addr].typeIdx       =  -1;
+                saoParam->saoLcuParam[compIdx][addr].mergeUpFlag   = 0;
+                saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag = 0;
+                saoParam->saoLcuParam[compIdx][addr].subTypeIdx    = 0;
+#if SAO_ENCODING_CHOICE
+                if( (compIdx ==0 && saoParam->bSaoFlag[0])|| (compIdx >0 && saoParam->bSaoFlag[1]) )
+#endif
+                {
+                    calcSaoStatsCu(addr, compIdx,  compIdx);
+                }
+            }
+            saoComponentParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, 0,  lambda, &mergeSaoParam[0][0], &compDistortion[0]);
+            sao2ChromaParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, lambdaChroma, &mergeSaoParam[1][0], &mergeSaoParam[2][0], &compDistortion[0]);
+            if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
+            {
+                // Cost of new SAO_params
+                m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
+                m_pcRDGoOnSbacCoder->resetBits();
+                if (allowMergeLeft)
+                {
+                    m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0); 
+                }
+                if (allowMergeUp)
+                {
+                    m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0);
+                }
+                for ( compIdx=0;compIdx<3;compIdx++)
+                {
+                    if( (compIdx ==0 && saoParam->bSaoFlag[0]) || (compIdx >0 && saoParam->bSaoFlag[1]))
+                    {
+                        m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
+                    }
+                }
+    
+                rate = m_pcEntropyCoder->getNumberOfWrittenBits();
+                bestCost = compDistortion[0] + (Double)rate;
+                m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+    
+                // Cost of Merge
+                for(Int mergeUp=0; mergeUp<2; ++mergeUp)
+                {
+                    if ( (allowMergeLeft && (mergeUp==0)) || (allowMergeUp && (mergeUp==1)) )
+                    {
+                        m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
+                        m_pcRDGoOnSbacCoder->resetBits();
+                        if (allowMergeLeft)
+                        {
+                            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(1-mergeUp); 
+                        }
+                        if ( allowMergeUp && (mergeUp==1) )
+                        {
+                            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(1); 
+                        }
+    
+                        rate = m_pcEntropyCoder->getNumberOfWrittenBits();
+                        mergeCost = compDistortion[mergeUp+1] + (Double)rate;
+                        if (mergeCost < bestCost)
+                        {
+                            bestCost = mergeCost;
+                            m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);              
+                            for ( compIdx=0;compIdx<3;compIdx++)
+                            {
+                                mergeSaoParam[compIdx][mergeUp].mergeLeftFlag = 1-mergeUp;
+                                mergeSaoParam[compIdx][mergeUp].mergeUpFlag = mergeUp;
+                                if( (compIdx==0 && saoParam->bSaoFlag[0]) || (compIdx>0 && saoParam->bSaoFlag[1]))
+                                {
+                                    copySaoUnit(&saoParam->saoLcuParam[compIdx][addr], &mergeSaoParam[compIdx][mergeUp] );             
+                                }
+                            }
+                        }
+                    }
+                }
+#if SAO_ENCODING_CHOICE
+#if SAO_ENCODING_CHOICE_CHROMA
+                if( saoParam->saoLcuParam[0][addr].typeIdx == -1)
+                {
+                    numNoSao[0]++;
+                }
+                if( saoParam->saoLcuParam[1][addr].typeIdx == -1)
+                {
+                    numNoSao[1]+=2;
+                }
+#else
+                for ( compIdx=0;compIdx<3;compIdx++)
+                {
+                    if( depth == 0 && saoParam->saoLcuParam[compIdx][addr].typeIdx == -1)
+                    {
+                        numNoSao++;
+                    }
+                }
+#endif
+#endif
+                m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+                m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
+            }
+        }
+    }
+#if SAO_ENCODING_CHOICE
+#if SAO_ENCODING_CHOICE_CHROMA
+#if SAO_ENCODING_CHOICE_CHROMA_BF
+    if( !saoParam->bSaoFlag[0]) 
+    {
+        m_depthSaoRate[0][depth] = 1.0;
+    }
+    else
+    {
+        m_depthSaoRate[0][depth] = numNoSao[0]/((Double) frameHeightInCU*frameWidthInCU);
+    }
+    if( !saoParam->bSaoFlag[1]) 
+    {
+        m_depthSaoRate[1][depth] = 1.0;
+    }
+    else 
+    {
+        m_depthSaoRate[1][depth] = numNoSao[1]/((Double) frameHeightInCU*frameWidthInCU*2);
+    }
+#else
+    m_depthSaoRate[0][depth] = numNoSao[0]/((Double) frameHeightInCU*frameWidthInCU);
+    m_depthSaoRate[1][depth] = numNoSao[1]/((Double) frameHeightInCU*frameWidthInCU*2);
+#endif
+#else
+    if( depth == 0)
+    {
+        // update SAO Rate
+        m_depth0SaoRate = numNoSao/((Double) frameHeightInCU*frameWidthInCU*3);
+    }
+#endif
+#endif
+}
+/** rate distortion optimization of SAO unit 
+* \param saoParam SAO parameters
+* \param addr address 
+* \param addrUp above address
+* \param addrLeft left address 
+* \param yCbCr color component index
+* \param lambda 
+*/
+inline Int64 TEncSampleAdaptiveOffset::estSaoTypeDist(Int compIdx, Int typeIdx, Int shift, Double lambda, Int *currentDistortionTableBo, Double *currentRdCostTableBo)
+{
+    Int64 estDist = 0;
+    Int classIdx;
+    for(classIdx=1; classIdx < ( (typeIdx < SAO_BO) ?  m_iNumClass[typeIdx]+1 : SAO_MAX_BO_CLASSES+1); classIdx++)
+    {
+        if( typeIdx == SAO_BO)
+        {
+            currentDistortionTableBo[classIdx-1] = 0;
+            currentRdCostTableBo[classIdx-1] = lambda;
+        }
+        if(m_iCount [compIdx][typeIdx][classIdx])
+        {
+#if FULL_NBIT
+            m_iOffset[compIdx][typeIdx][classIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[compIdx][typeIdx][classIdx]<<g_uiBitDepth-8)   / (Double)(m_iCount [compIdx][typeIdx][classIdx]<<m_uiSaoBitIncrease));
+#else
+            m_iOffset[compIdx][typeIdx][classIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[compIdx][typeIdx][classIdx]<<g_uiBitIncrement) / (Double)(m_iCount [compIdx][typeIdx][classIdx]<<m_uiSaoBitIncrease));
+#endif
+            m_iOffset[compIdx][typeIdx][classIdx] = Clip3(-m_iOffsetTh+1, m_iOffsetTh-1, (Int)m_iOffset[compIdx][typeIdx][classIdx]);
+            if (typeIdx < 4)
+            {
+                if ( m_iOffset[compIdx][typeIdx][classIdx]<0 && classIdx<3 )
+                {
+                    m_iOffset[compIdx][typeIdx][classIdx] = 0;
+                }
+                if ( m_iOffset[compIdx][typeIdx][classIdx]>0 && classIdx>=3)
+                {
+                    m_iOffset[compIdx][typeIdx][classIdx] = 0;
+                }
+            }
+            m_iOffset[compIdx][typeIdx][classIdx] = estIterOffset( typeIdx, classIdx, lambda, m_iOffset[compIdx][typeIdx][classIdx], m_iCount [compIdx][typeIdx][classIdx], m_iOffsetOrg[compIdx][typeIdx][classIdx], shift, m_uiSaoBitIncrease, currentDistortionTableBo, currentRdCostTableBo );
+        }
+        else
+        {
+            m_iOffsetOrg[compIdx][typeIdx][classIdx] = 0;
+            m_iOffset[compIdx][typeIdx][classIdx] = 0;
+        }
+        if( typeIdx != SAO_BO )
+        {
+            estDist   += estSaoDist( m_iCount [compIdx][typeIdx][classIdx], m_iOffset[compIdx][typeIdx][classIdx] << m_uiSaoBitIncrease, m_iOffsetOrg[compIdx][typeIdx][classIdx], shift);
+        }
+    }
+    return estDist;
+}
+
+inline Int64 TEncSampleAdaptiveOffset::estSaoDist(Int64 count, Int64 offset, Int64 offsetOrg, Int shift)
+{
+    return (( count*offset*offset-offsetOrg*offset*2 ) >> shift);
+}
+inline Int64 TEncSampleAdaptiveOffset::estIterOffset(Int typeIdx, Int classIdx, double lambda, Int64 offsetInput, Int64 count, Int64 offsetOrg, Int shift, Int bitIncrease, Int *currentDistortionTableBo, Double *currentRdCostTableBo )
+{
+    //Clean up, best_q_offset.
+    Int64 iterOffset, tempOffset;
+    Int64 tempDist, tempRate;
+    Double tempCost, tempMinCost;
+    Int64 offsetOutput = 0;
+    iterOffset = offsetInput;
+    // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 
+    tempMinCost = lambda; 
+    while (iterOffset != 0)
+    {
+        // Calculate the bits required for signalling the offset
+        tempRate = (typeIdx == SAO_BO) ? (abs((Int)iterOffset)+2) : (abs((Int)iterOffset)+1);
+        if (abs((Int)iterOffset)==m_iOffsetTh-1) 
+        {  
+            tempRate --;
+        }
+        // Do the dequntization before distorion calculation
+        tempOffset  = iterOffset << bitIncrease;
+        tempDist    = estSaoDist( count, tempOffset, offsetOrg, shift);
+        tempCost    = ((Double)tempDist + lambda * (Double) tempRate);
+        if(tempCost < tempMinCost)
+        {
+            tempMinCost = tempCost;
+            offsetOutput = iterOffset;
+            if(typeIdx == SAO_BO)
+            {
+                currentDistortionTableBo[classIdx-1] = (Int) tempDist;
+                currentRdCostTableBo[classIdx-1] = tempCost;
+            }
+        }
+        iterOffset = (iterOffset > 0) ? (iterOffset-1):(iterOffset+1);
+    }
+    return offsetOutput;
+}
+
+Void TEncSampleAdaptiveOffset::saoComponentParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda, SaoLcuParam *compSaoParam, Double *compDistortion)
+{
+    Int typeIdx;
+    Int64 estDist;
+    Int classIdx;
+
+    Int shift = g_uiBitIncrement << 1;
+
+    Int64 bestDist;
+
+    SaoLcuParam*  saoLcuParam = &(saoParam->saoLcuParam[yCbCr][addr]);
+    SaoLcuParam*  saoLcuParamNeighbor = NULL; 
+
+    resetSaoUnit(saoLcuParam);
+    resetSaoUnit(&compSaoParam[0]);
+    resetSaoUnit(&compSaoParam[1]);
+
+    Double dCostPartBest = MAX_DOUBLE;
+
+    Double  bestRDCostTableBo = MAX_DOUBLE;
+    Int     bestClassTableBo    = 0;
+    Int     currentDistortionTableBo[MAX_NUM_SAO_CLASS];
+    Double  currentRdCostTableBo[MAX_NUM_SAO_CLASS];
+
+    SaoLcuParam   saoLcuParamRdo;   
+    Double   estRate = 0;
+
+    resetSaoUnit(&saoLcuParamRdo);
+
+    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+    m_pcRDGoOnSbacCoder->resetBits();
+    m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo, yCbCr);
+    dCostPartBest = m_pcEntropyCoder->getNumberOfWrittenBits()*lambda ; 
+
+    copySaoUnit(saoLcuParam, &saoLcuParamRdo );
+
+    bestDist = 0;
+
+    for (typeIdx=0; typeIdx<MAX_NUM_SAO_TYPE; typeIdx++)
+    {
+        estDist = estSaoTypeDist(yCbCr, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo);
+        if( typeIdx == SAO_BO )
+        {
+            // Estimate Best Position
+            Double currentRDCost = 0.0;
+
+            for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++)
+            {
+                currentRDCost = 0.0;
+                for(UInt uj = i; uj < i+SAO_BO_LEN; uj++)
+                {
+                    currentRDCost += currentRdCostTableBo[uj];
+                }
+
+                if( currentRDCost < bestRDCostTableBo)
+                {
+                    bestRDCostTableBo = currentRDCost;
+                    bestClassTableBo  = i;
+                }
+            }
+
+            // Re code all Offsets
+            // Code Center
+            estDist = 0;
+            for(classIdx = bestClassTableBo; classIdx < bestClassTableBo+SAO_BO_LEN; classIdx++)
+            {
+                estDist += currentDistortionTableBo[classIdx];
+            }
+        }
+        resetSaoUnit(&saoLcuParamRdo);
+        saoLcuParamRdo.length = m_iNumClass[typeIdx];
+        saoLcuParamRdo.typeIdx = typeIdx;
+        saoLcuParamRdo.mergeLeftFlag = 0;
+        saoLcuParamRdo.mergeUpFlag   = 0;
+        saoLcuParamRdo.subTypeIdx = (typeIdx == SAO_BO) ? bestClassTableBo : 0;
+        for (classIdx = 0; classIdx < saoLcuParamRdo.length; classIdx++)
+        {
+            saoLcuParamRdo.offset[classIdx] = (Int)m_iOffset[yCbCr][typeIdx][classIdx+saoLcuParamRdo.subTypeIdx+1];
+        }
+        m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+        m_pcRDGoOnSbacCoder->resetBits();
+        m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo, yCbCr);
+
+        estRate = m_pcEntropyCoder->getNumberOfWrittenBits();
+        m_dCost[yCbCr][typeIdx] = (Double)((Double)estDist + lambda * (Double) estRate);
+
+        if(m_dCost[yCbCr][typeIdx] < dCostPartBest)
+        {
+            dCostPartBest = m_dCost[yCbCr][typeIdx];
+            copySaoUnit(saoLcuParam, &saoLcuParamRdo );
+            bestDist = estDist;       
+        }
+    }
+
+    compDistortion[0] += ((Double)bestDist/lambda);
+    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+    m_pcEntropyCoder->encodeSaoOffset(saoLcuParam, yCbCr);
+    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_TEMP_BEST] );
+
+    // merge left or merge up
+    for (Int idxNeighbor=0;idxNeighbor<2;idxNeighbor++) 
+    {
+        saoLcuParamNeighbor = NULL;
+        if (allowMergeLeft && addrLeft>=0 && idxNeighbor ==0)
+        {
+            saoLcuParamNeighbor = &(saoParam->saoLcuParam[yCbCr][addrLeft]);
+        }
+        else if (allowMergeUp && addrUp>=0 && idxNeighbor ==1)
+        {
+            saoLcuParamNeighbor = &(saoParam->saoLcuParam[yCbCr][addrUp]);
+        }
+        if (saoLcuParamNeighbor!=NULL)
+        {
+            estDist = 0;
+            typeIdx = saoLcuParamNeighbor->typeIdx;
+            if (typeIdx>=0) 
+            {
+                Int mergeBandPosition = (typeIdx == SAO_BO)?saoLcuParamNeighbor->subTypeIdx:0;
+                Int   merge_iOffset;
+                for(classIdx = 0; classIdx < m_iNumClass[typeIdx]; classIdx++)
+                {
+                    merge_iOffset = saoLcuParamNeighbor->offset[classIdx];
+                    estDist   += estSaoDist(m_iCount [yCbCr][typeIdx][classIdx+mergeBandPosition+1], merge_iOffset, m_iOffsetOrg[yCbCr][typeIdx][classIdx+mergeBandPosition+1],  shift);
+                }
+            }
+            else
+            {
+                estDist = 0;
+            }
+
+            copySaoUnit(&compSaoParam[idxNeighbor], saoLcuParamNeighbor );
+            compSaoParam[idxNeighbor].mergeUpFlag   = idxNeighbor;
+            compSaoParam[idxNeighbor].mergeLeftFlag = !idxNeighbor;
+
+            compDistortion[idxNeighbor+1] += ((Double)estDist/lambda);
+        } 
+    }
+}
+
+Void TEncSampleAdaptiveOffset::sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Double lambda, SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion)
+{
+    Int typeIdx;
+
+    Int64 estDist[2];
+    Int classIdx;
+    Int shift = g_uiBitIncrement << 1;
+    Int64 bestDist = 0;
+
+    SaoLcuParam*  saoLcuParam[2] = {&(saoParam->saoLcuParam[1][addr]), &(saoParam->saoLcuParam[2][addr])};
+    SaoLcuParam*  saoLcuParamNeighbor[2] = {NULL, NULL}; 
+    SaoLcuParam*  saoMergeParam[2][2];
+    saoMergeParam[0][0] = &crSaoParam[0];
+    saoMergeParam[0][1] = &crSaoParam[1]; 
+    saoMergeParam[1][0] = &cbSaoParam[0];
+    saoMergeParam[1][1] = &cbSaoParam[1];
+
+    resetSaoUnit(saoLcuParam[0]);
+    resetSaoUnit(saoLcuParam[1]);
+    resetSaoUnit(saoMergeParam[0][0]);
+    resetSaoUnit(saoMergeParam[0][1]);
+    resetSaoUnit(saoMergeParam[1][0]);
+    resetSaoUnit(saoMergeParam[1][1]);
+
+    Double costPartBest = MAX_DOUBLE;
+
+    Double  bestRDCostTableBo;
+    Int     bestClassTableBo[2]    = {0, 0};
+    Int     currentDistortionTableBo[MAX_NUM_SAO_CLASS];
+    Double  currentRdCostTableBo[MAX_NUM_SAO_CLASS];
+
+    SaoLcuParam   saoLcuParamRdo[2];   
+    Double   estRate = 0;
+
+    resetSaoUnit(&saoLcuParamRdo[0]);
+    resetSaoUnit(&saoLcuParamRdo[1]);
+
+    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+    m_pcRDGoOnSbacCoder->resetBits();
+    m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[0], 1);
+    m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[1], 2);
+
+    costPartBest = m_pcEntropyCoder->getNumberOfWrittenBits()*lambda ; 
+    copySaoUnit(saoLcuParam[0], &saoLcuParamRdo[0] );
+    copySaoUnit(saoLcuParam[1], &saoLcuParamRdo[1] );
+
+    for (typeIdx=0; typeIdx<MAX_NUM_SAO_TYPE; typeIdx++)
+    {
+        if( typeIdx == SAO_BO )
+        {
+            // Estimate Best Position
+            for(Int compIdx = 0; compIdx < 2; compIdx++)
+            {
+                Double currentRDCost = 0.0;
+                bestRDCostTableBo = MAX_DOUBLE;
+                estDist[compIdx] = estSaoTypeDist(compIdx+1, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo);
+
+                for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++)
+                {
+                    currentRDCost = 0.0;
+                    for(UInt uj = i; uj < i+SAO_BO_LEN; uj++)
+                    {
+                        currentRDCost += currentRdCostTableBo[uj];
+                    }
+
+                    if( currentRDCost < bestRDCostTableBo)
+                    {
+                        bestRDCostTableBo = currentRDCost;
+                        bestClassTableBo[compIdx]  = i;
+                    }
+                }
+
+                // Re code all Offsets
+                // Code Center
+                estDist[compIdx] = 0;
+                for(classIdx = bestClassTableBo[compIdx]; classIdx < bestClassTableBo[compIdx]+SAO_BO_LEN; classIdx++)
+                {
+                    estDist[compIdx] += currentDistortionTableBo[classIdx];
+                }
+            }
+        }
+        else
+        {
+            estDist[0] = estSaoTypeDist(1, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo);
+            estDist[1] = estSaoTypeDist(2, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo);
+        }
+
+        m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+        m_pcRDGoOnSbacCoder->resetBits();
+
+        for(Int compIdx = 0; compIdx < 2; compIdx++)
+        {
+            resetSaoUnit(&saoLcuParamRdo[compIdx]);
+            saoLcuParamRdo[compIdx].length = m_iNumClass[typeIdx];
+            saoLcuParamRdo[compIdx].typeIdx = typeIdx;
+            saoLcuParamRdo[compIdx].mergeLeftFlag = 0;
+            saoLcuParamRdo[compIdx].mergeUpFlag   = 0;
+            saoLcuParamRdo[compIdx].subTypeIdx = (typeIdx == SAO_BO) ? bestClassTableBo[compIdx] : 0;
+            for (classIdx = 0; classIdx < saoLcuParamRdo[compIdx].length; classIdx++)
+            {
+                saoLcuParamRdo[compIdx].offset[classIdx] = (Int)m_iOffset[compIdx+1][typeIdx][classIdx+saoLcuParamRdo[compIdx].subTypeIdx+1];
+            }
+            m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[compIdx], compIdx+1);
+        }
+        estRate = m_pcEntropyCoder->getNumberOfWrittenBits();
+        m_dCost[1][typeIdx] = (Double)((Double)(estDist[0] + estDist[1])  + lambda * (Double) estRate);
+
+        if(m_dCost[1][typeIdx] < costPartBest)
+        {
+            costPartBest = m_dCost[1][typeIdx];
+            copySaoUnit(saoLcuParam[0], &saoLcuParamRdo[0] );
+            copySaoUnit(saoLcuParam[1], &saoLcuParamRdo[1] );
+            bestDist = (estDist[0]+estDist[1]);       
+        }
+    }
+
+    distortion[0] += ((Double)bestDist/lambda);
+    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
+    m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[0], 1);
+    m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[1], 2);
+    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_TEMP_BEST] );
+
+    // merge left or merge up
+
+    for (Int idxNeighbor=0;idxNeighbor<2;idxNeighbor++) 
+    {
+        for(Int compIdx = 0; compIdx < 2; compIdx++)
+        {
+            saoLcuParamNeighbor[compIdx] = NULL;
+            if (allowMergeLeft && addrLeft>=0 && idxNeighbor ==0)
+            {
+                saoLcuParamNeighbor[compIdx] = &(saoParam->saoLcuParam[compIdx+1][addrLeft]);
+            }
+            else if (allowMergeUp && addrUp>=0 && idxNeighbor ==1)
+            {
+                saoLcuParamNeighbor[compIdx] = &(saoParam->saoLcuParam[compIdx+1][addrUp]);
+            }
+            if (saoLcuParamNeighbor[compIdx]!=NULL)
+            {
+                estDist[compIdx] = 0;
+                typeIdx = saoLcuParamNeighbor[compIdx]->typeIdx;
+                if (typeIdx>=0) 
+                {
+                    Int mergeBandPosition = (typeIdx == SAO_BO)?saoLcuParamNeighbor[compIdx]->subTypeIdx:0;
+                    Int   merge_iOffset;
+                    for(classIdx = 0; classIdx < m_iNumClass[typeIdx]; classIdx++)
+                    {
+                        merge_iOffset = saoLcuParamNeighbor[compIdx]->offset[classIdx];
+                        estDist[compIdx]   += estSaoDist(m_iCount [compIdx+1][typeIdx][classIdx+mergeBandPosition+1], merge_iOffset, m_iOffsetOrg[compIdx+1][typeIdx][classIdx+mergeBandPosition+1],  shift);
+                    }
+                }
+                else
+                {
+                    estDist[compIdx] = 0;
+                }
+
+                copySaoUnit(saoMergeParam[compIdx][idxNeighbor], saoLcuParamNeighbor[compIdx] );
+                saoMergeParam[compIdx][idxNeighbor]->mergeUpFlag   = idxNeighbor;
+                saoMergeParam[compIdx][idxNeighbor]->mergeLeftFlag = !idxNeighbor;
+                distortion[idxNeighbor+1] += ((Double)estDist[compIdx]/lambda);
+            }
+        } 
+    } 
+}
+#else
+TEncSampleAdaptiveOffset::TEncSampleAdaptiveOffset()
+{
+  m_pcEntropyCoder = NULL;
+  m_pppcRDSbacCoder = NULL;
+  m_pcRDGoOnSbacCoder = NULL;
+  m_pppcBinCoderCABAC = NULL;            
+  m_iCount = NULL;     
+  m_iOffset = NULL;      
+  m_iOffsetOrg = NULL;  
+  m_iRate = NULL;       
+  m_iDist = NULL;        
+  m_dCost = NULL;        
+  m_dCostPartBest = NULL; 
+  m_iDistOrg = NULL;      
+  m_iTypePartBest = NULL; 
+}
+TEncSampleAdaptiveOffset::~TEncSampleAdaptiveOffset()
+{
+
+}
+// ====================================================================================================================
+// Constants
+// ====================================================================================================================
+
+
+// ====================================================================================================================
+// Tables
+// ====================================================================================================================
+
+inline Double xRoundIbdi2(Double x)
+{
+#if FULL_NBIT
+  Int bitDepthMinus8 = g_uiBitDepth - 8;
+  return ((x)>0) ? (Int)(((Int)(x)+(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)) : ((Int)(((Int)(x)-(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)));
+#else
+  return ((x)>0) ? (Int)(((Int)(x)+(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)) : ((Int)(((Int)(x)-(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)));
+#endif
+}
+
+/** rounding with IBDI
+ * \param  x
+ */
+inline Double xRoundIbdi(Double x)
+{
+#if FULL_NBIT
+  return (g_uiBitDepth > 8 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ;
+#else
+  return (g_uiBitIncrement >0 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ;
+#endif
+}
+
+
+
+/** process SAO for one partition
+ * \param  *psQTPart, iPartIdx, dLambda
+ */
+Void TEncSampleAdaptiveOffset::rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda)
+{
+  Int iTypeIdx;
+  Int iNumTotalType = MAX_NUM_SAO_TYPE;
+  SAOQTPart*  pOnePart = &(psQTPart[iPartIdx]);
+
+  Int64 iEstDist;
+  Int64 iOffsetOrg;
+  Int64 iOffset;
+  Int64 iCount;
+  Int iClassIdx;
+  Int uiShift = g_uiBitIncrement << 1;
+  UInt uiDepth = pOnePart->PartLevel;
+
+  m_iDistOrg [iPartIdx] =  0;
+
+  Double  bestRDCostTableBo = MAX_DOUBLE;
+  Int     bestClassTableBo    = 0;
+  Int     currentDistortionTableBo[MAX_NUM_SAO_CLASS];
+  Double  currentRdCostTableBo[MAX_NUM_SAO_CLASS];
+
+#if HHI_INTERVIEW_SKIP
+  Int iFrameWidthInCU = m_pcPic->getFrameWidthInCU();
+  Int LcuIdxX = psQTPart->StartCUX;
+  Int LcuIdxY = psQTPart->StartCUY;
+  Int iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX;
+  TComDataCU *pcCU = m_pcPic->getCU(iAddr);
+  Bool bRenderable = pcCU->getRenderable(0) ;
+
+#endif
+  for (iTypeIdx=-1; iTypeIdx<iNumTotalType; iTypeIdx++)
+  {
+    if( m_bUseSBACRD )
+    {
+      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
+      m_pcRDGoOnSbacCoder->resetBits();
+    }
+    else
+    {
+      m_pcEntropyCoder->resetEntropy();
+      m_pcEntropyCoder->resetBits();
+    }
+
+    iEstDist = 0;
+
+    m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoTypeIdx(iTypeIdx+1);
+
+    if (iTypeIdx>=0)
+    {
+
+      for(iClassIdx=1; iClassIdx < ( (iTypeIdx < SAO_BO) ?  m_iNumClass[iTypeIdx]+1 : SAO_MAX_BO_CLASSES+1); iClassIdx++)
+      {
+        if( iTypeIdx == SAO_BO)
+        {
+          currentDistortionTableBo[iClassIdx-1] = 0;
+          currentRdCostTableBo[iClassIdx-1] = dLambda;
+        }
+#if HHI_INTERVIEW_SKIP
+        if(m_iCount [iPartIdx][iTypeIdx][iClassIdx] && !bRenderable)
+#else
+        if(m_iCount [iPartIdx][iTypeIdx][iClassIdx])
+#endif
+        {
+#if FULL_NBIT
+          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitDepth-8) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease));
+#else
+          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitIncrement) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease));
+#endif
+          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = Clip3(-m_iOffsetTh, m_iOffsetTh-1, (Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
+
+          if (iTypeIdx < 4)
+          {
+            if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]<0 && iClassIdx<3 )
+            {
+              m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
+            }
+            if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]>0 && iClassIdx>=3)
+            {
+              m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
+            }
+          }
+          {
+            //Clean up, best_q_offset.
+            Int64 iIterOffset, iTempOffset;
+            Int64 iTempDist, iTempRate;
+            Double dTempCost, dTempMinCost;
+            UInt uiLength, uiTemp;
+
+            iIterOffset = m_iOffset[iPartIdx][iTypeIdx][iClassIdx];
+            m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
+            dTempMinCost = dLambda; // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 
+
+            while (iIterOffset != 0)
+            {
+              // Calculate the bits required for signalling the offset
+              uiLength = 1;
+              uiTemp = (UInt)((iIterOffset <= 0) ? ( (-iIterOffset<<1) + 1 ) : (iIterOffset<<1));
+              while( 1 != uiTemp )
+              {
+                uiTemp >>= 1;
+                uiLength += 2;
+              }
+              iTempRate = (uiLength >> 1) + ((uiLength+1) >> 1);
+
+              // Do the dequntization before distorion calculation
+              iTempOffset    =  iIterOffset << m_uiSaoBitIncrease;
+              iTempDist  = (( m_iCount [iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*iTempOffset-m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*2 ) >> uiShift);
+
+              dTempCost = ((Double)iTempDist + dLambda * (Double) iTempRate);
+              if(dTempCost < dTempMinCost)
+              {
+                dTempMinCost = dTempCost;
+                m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = iIterOffset;
+                if(iTypeIdx == SAO_BO)
+                {
+                  currentDistortionTableBo[iClassIdx-1] = (Int) iTempDist;
+                  currentRdCostTableBo[iClassIdx-1] = dTempCost;
+                }
+              }
+              iIterOffset = (iIterOffset > 0) ? (iIterOffset-1):(iIterOffset+1);
+            }
+
+          }
+        }
+        else
+        {
+          m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx] = 0;
+          m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0;
+        }
+        if( iTypeIdx != SAO_BO )
+        {
+          iCount     =  m_iCount [iPartIdx][iTypeIdx][iClassIdx];
+          iOffset    =  m_iOffset[iPartIdx][iTypeIdx][iClassIdx] << m_uiSaoBitIncrease;
+          iOffsetOrg =  m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx];
+          iEstDist   += (( iCount*iOffset*iOffset-iOffsetOrg*iOffset*2 ) >> uiShift);
+          if (iTypeIdx < 4)
+          {
+            if (iClassIdx<3)
+            {
+              m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
+            }
+            else
+            {
+              m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)-m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
+            }
+          }
+          else
+          {
+            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]);
+          }
+        }
+      }
+
+      if( iTypeIdx == SAO_BO )
+      {
+        // Estimate Best Position
+        Double currentRDCost = 0.0;
+
+        for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++)
+        {
+          currentRDCost = 0.0;
+          for(UInt uj = i; uj < i+SAO_BO_LEN; uj++)
+          {
+            currentRDCost += currentRdCostTableBo[uj];
+          }
+
+          if( currentRDCost < bestRDCostTableBo)
+          {
+            bestRDCostTableBo = currentRDCost;
+            bestClassTableBo  = i;
+          }
+        }
+
+        // Re code all Offsets
+        // Code Center
+        m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUflc( (UInt) (bestClassTableBo) );
+
+        for(iClassIdx = bestClassTableBo; iClassIdx < bestClassTableBo+SAO_BO_LEN; iClassIdx++)
+        {
+          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx+1]);
+          iEstDist += currentDistortionTableBo[iClassIdx];
+        }
+      }
+
+      m_iDist[iPartIdx][iTypeIdx] = iEstDist;
+      m_iRate[iPartIdx][iTypeIdx] = m_pcEntropyCoder->getNumberOfWrittenBits();
+
+      m_dCost[iPartIdx][iTypeIdx] = (Double)((Double)m_iDist[iPartIdx][iTypeIdx] + dLambda * (Double) m_iRate[iPartIdx][iTypeIdx]);
+
+      if(m_dCost[iPartIdx][iTypeIdx] < m_dCostPartBest[iPartIdx])
+      {
+        m_iDistOrg [iPartIdx] = 0;
+        m_dCostPartBest[iPartIdx] = m_dCost[iPartIdx][iTypeIdx];
+        m_iTypePartBest[iPartIdx] = iTypeIdx;
+        if( m_bUseSBACRD )
+          m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] );
+      }
+    }
+    else
+    {
+      if(m_iDistOrg[iPartIdx] < m_dCostPartBest[iPartIdx] )
+      {
+        m_dCostPartBest[iPartIdx] = (Double) m_iDistOrg[iPartIdx] + m_pcEntropyCoder->getNumberOfWrittenBits()*dLambda ; 
+        m_iTypePartBest[iPartIdx] = -1;
+        if( m_bUseSBACRD )
+          m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] );
+      }
+    }
+  }
+
+  pOnePart->bProcessed = true;
+  pOnePart->bSplit     = false;
+  pOnePart->iMinDist   =        m_iTypePartBest[iPartIdx] >= 0 ? m_iDist[iPartIdx][m_iTypePartBest[iPartIdx]] : m_iDistOrg[iPartIdx];
+  pOnePart->iMinRate   = (Int) (m_iTypePartBest[iPartIdx] >= 0 ? m_iRate[iPartIdx][m_iTypePartBest[iPartIdx]] : 0);
+  pOnePart->dMinCost   = pOnePart->iMinDist + dLambda * pOnePart->iMinRate;
+  pOnePart->iBestType  = m_iTypePartBest[iPartIdx];
+  if (pOnePart->iBestType != -1)
+  {
+    //     pOnePart->bEnableFlag =  1;
+    pOnePart->iLength = m_iNumClass[pOnePart->iBestType];
+    Int minIndex = 0;
+    if( pOnePart->iBestType == SAO_BO )
+    {
+      pOnePart->bandPosition = bestClassTableBo;
+      minIndex = pOnePart->bandPosition;
+    }
+    for (Int i=0; i< pOnePart->iLength ; i++)
+    {
+      pOnePart->iOffset[i] = (Int) m_iOffset[iPartIdx][pOnePart->iBestType][minIndex+i+1];
+    }
+
+  }
+  else
+  {
+    //     pOnePart->bEnableFlag = 0;
+    pOnePart->iLength     = 0;
+  }
+}
+
+/** Run partition tree disable
+ */
+Void TEncSampleAdaptiveOffset::disablePartTree(SAOQTPart *psQTPart, Int iPartIdx)
+{
+  SAOQTPart*  pOnePart= &(psQTPart[iPartIdx]);
+  pOnePart->bSplit      = false;
+  pOnePart->iLength     =  0;
+  pOnePart->iBestType   = -1;
+
+  if (pOnePart->PartLevel < m_uiMaxSplitLevel)
+  {
+    for (Int i=0; i<NUM_DOWN_PART; i++)
+    {
+      disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]);
+    }
+  }
+}
+
+/** Run quadtree decision function
+ * \param  iPartIdx, pcPicOrg, pcPicDec, pcPicRest, &dCostFinal
+ */
+Void TEncSampleAdaptiveOffset::runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda)
+{
+  SAOQTPart*  pOnePart = &(psQTPart[iPartIdx]);
+
+  UInt uiDepth = pOnePart->PartLevel;
+  UInt uhNextDepth = uiDepth+1;
+
+  if (iPartIdx == 0)
+  {
+    dCostFinal = 0;
+  }
+
+  //SAO for this part
+  if(!pOnePart->bProcessed)
+  {
+    rdoSaoOnePart (psQTPart, iPartIdx, dLambda);
+  }
+
+  //SAO for sub 4 parts
+  if (pOnePart->PartLevel < iMaxLevel)
+  {
+    Double      dCostNotSplit = dLambda + pOnePart->dMinCost;
+    Double      dCostSplit    = dLambda;
+
+    for (Int i=0; i< NUM_DOWN_PART ;i++)
+    {
+      if( m_bUseSBACRD )  
+      {
+        if ( 0 == i) //initialize RD with previous depth buffer
+        {
+          m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
+        }
+        else
+        {
+          m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
+        }
+      }  
+      runQuadTreeDecision(psQTPart, pOnePart->DownPartsIdx[i], dCostFinal, iMaxLevel, dLambda);
+      dCostSplit += dCostFinal;
+      if( m_bUseSBACRD )
+      {
+        m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_TEMP_BEST]);
+      }
+    }
+
+    if(dCostSplit < dCostNotSplit)
+    {
+      dCostFinal = dCostSplit;
+      pOnePart->bSplit      = true;
+      pOnePart->iLength     =  0;
+      pOnePart->iBestType   = -1;
+      if( m_bUseSBACRD )
+      {
+        m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
+      }
+    }
+    else
+    {
+      dCostFinal = dCostNotSplit;
+      pOnePart->bSplit = false;
+      for (Int i=0; i<NUM_DOWN_PART; i++)
+      {
+        disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]);
+      }
+      if( m_bUseSBACRD )
+      {
+        m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
+      }
+    }
+  }
+  else
+  {
+    dCostFinal = pOnePart->dMinCost;
+  }
+}
+
+/** delete allocated memory of TEncSampleAdaptiveOffset class.
+ */
+Void TEncSampleAdaptiveOffset::destroyEncBuffer()
+{
+  for (Int i=0;i<m_iNumTotalParts;i++)
+  {
+    for (Int j=0;j<MAX_NUM_SAO_TYPE;j++)
+    {
+      if (m_iCount [i][j])
+      {
+        delete [] m_iCount [i][j]; 
+      }
+      if (m_iOffset[i][j])
+      {
+        delete [] m_iOffset[i][j]; 
+      }
+      if (m_iOffsetOrg[i][j])
+      {
+        delete [] m_iOffsetOrg[i][j]; 
+      }
+    }
+    if (m_iRate[i])
+    {
+      delete [] m_iRate[i];
+    }
+    if (m_iDist[i])
+    {
+      delete [] m_iDist[i]; 
+    }
+    if (m_dCost[i])
+    {
+      delete [] m_dCost[i]; 
+    }
+    if (m_iCount [i])
+    {
+      delete [] m_iCount [i]; 
+    }
+    if (m_iOffset[i])
+    {
+      delete [] m_iOffset[i]; 
+    }
+    if (m_iOffsetOrg[i])
+    {
+      delete [] m_iOffsetOrg[i]; 
+    }
+
+  }
+  if (m_iDistOrg)
+  {
+    delete [] m_iDistOrg ; m_iDistOrg = NULL;
+  }
+  if (m_dCostPartBest)
+  {
+    delete [] m_dCostPartBest ; m_dCostPartBest = NULL;
+  }
+  if (m_iTypePartBest)
+  {
+    delete [] m_iTypePartBest ; m_iTypePartBest = NULL;
+  }
+  if (m_iRate)
+  {
+    delete [] m_iRate ; m_iRate = NULL;
+  }
+  if (m_iDist)
+  {
+    delete [] m_iDist ; m_iDist = NULL;
+  }
+  if (m_dCost)
+  {
+    delete [] m_dCost ; m_dCost = NULL;
+  }
+  if (m_iCount)
+  {
+    delete [] m_iCount  ; m_iCount = NULL;
+  }
+  if (m_iOffset)
+  {
+    delete [] m_iOffset ; m_iOffset = NULL;
+  }
+  if (m_iOffsetOrg)
+  {
+    delete [] m_iOffsetOrg ; m_iOffsetOrg = NULL;
+  }
+
+  Int iMaxDepth = 4;
+  Int iDepth;
+  for ( iDepth = 0; iDepth < iMaxDepth+1; iDepth++ )
+  {
+    for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
+    {
+      delete m_pppcRDSbacCoder[iDepth][iCIIdx];
+      delete m_pppcBinCoderCABAC[iDepth][iCIIdx];
+    }
+  }
+
+  for ( iDepth = 0; iDepth < iMaxDepth+1; iDepth++ )
+  {
+    delete [] m_pppcRDSbacCoder[iDepth];
+    delete [] m_pppcBinCoderCABAC[iDepth];
+  }
+
+  delete [] m_pppcRDSbacCoder;
+  delete [] m_pppcBinCoderCABAC;
+}
+
+/** create Encoder Buffer for SAO
+ * \param 
+ */
+Void TEncSampleAdaptiveOffset::createEncBuffer()
+{
+  m_iDistOrg = new Int64 [m_iNumTotalParts]; 
+  m_dCostPartBest = new Double [m_iNumTotalParts]; 
+  m_iTypePartBest = new Int [m_iNumTotalParts]; 
+
+  m_iRate = new Int64* [m_iNumTotalParts];
+  m_iDist = new Int64* [m_iNumTotalParts];
+  m_dCost = new Double*[m_iNumTotalParts];
+
+  m_iCount  = new Int64 **[m_iNumTotalParts];
+  m_iOffset = new Int64 **[m_iNumTotalParts];
+  m_iOffsetOrg = new Int64 **[m_iNumTotalParts];
+
+  for (Int i=0;i<m_iNumTotalParts;i++)
+  {
+    m_iRate[i] = new Int64  [MAX_NUM_SAO_TYPE];
+    m_iDist[i] = new Int64  [MAX_NUM_SAO_TYPE]; 
+    m_dCost[i] = new Double [MAX_NUM_SAO_TYPE]; 
+
+    m_iCount [i] = new Int64 *[MAX_NUM_SAO_TYPE]; 
+    m_iOffset[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 
+    m_iOffsetOrg[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 
+
+    for (Int j=0;j<MAX_NUM_SAO_TYPE;j++)
+    {
+      m_iCount [i][j]   = new Int64 [MAX_NUM_SAO_CLASS]; 
+      m_iOffset[i][j]   = new Int64 [MAX_NUM_SAO_CLASS]; 
+      m_iOffsetOrg[i][j]= new Int64 [MAX_NUM_SAO_CLASS]; 
+    }
+  }
+
+  Int iMaxDepth = 4;
+  m_pppcRDSbacCoder = new TEncSbac** [iMaxDepth+1];
+#if FAST_BIT_EST
+  m_pppcBinCoderCABAC = new TEncBinCABACCounter** [iMaxDepth+1];
+#else
+  m_pppcBinCoderCABAC = new TEncBinCABAC** [iMaxDepth+1];
+#endif
+
+  for ( Int iDepth = 0; iDepth < iMaxDepth+1; iDepth++ )
+  {
+    m_pppcRDSbacCoder[iDepth] = new TEncSbac* [CI_NUM];
+#if FAST_BIT_EST
+    m_pppcBinCoderCABAC[iDepth] = new TEncBinCABACCounter* [CI_NUM];
+#else
+    m_pppcBinCoderCABAC[iDepth] = new TEncBinCABAC* [CI_NUM];
+#endif
+    for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
+    {
+      m_pppcRDSbacCoder[iDepth][iCIIdx] = new TEncSbac;
+#if FAST_BIT_EST
+      m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABACCounter;
+#else
+      m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABAC;
+#endif
+      m_pppcRDSbacCoder   [iDepth][iCIIdx]->init( m_pppcBinCoderCABAC [iDepth][iCIIdx] );
+    }
+  }
+}
+
+/** Start SAO encoder
+ * \param pcPic, pcEntropyCoder, pppcRDSbacCoder, pcRDGoOnSbacCoder 
+ */
+Void TEncSampleAdaptiveOffset::startSaoEnc( TComPic* pcPic, TEncEntropy* pcEntropyCoder, TEncSbac*** pppcRDSbacCoder, TEncSbac* pcRDGoOnSbacCoder)
+{
+  if( pcRDGoOnSbacCoder )
+    m_bUseSBACRD = true;
+  else
+    m_bUseSBACRD = false;
+
+  m_pcPic = pcPic;
+  m_pcEntropyCoder = pcEntropyCoder;
+
+  m_pcRDGoOnSbacCoder = pcRDGoOnSbacCoder;
+  m_pcEntropyCoder->resetEntropy();
+  m_pcEntropyCoder->resetBits();
+
+  if( m_bUseSBACRD )
+  {
+    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_NEXT_BEST]);
+    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_NEXT_BEST]);
+  }
+}
+
+/** End SAO encoder
+ */
+Void TEncSampleAdaptiveOffset::endSaoEnc()
+{
+  m_pcPic = NULL;
+  m_pcEntropyCoder = NULL;
+}
+
+inline int xSign(int x)
+{
+  return ((x >> 31) | ((int)( (((unsigned int) -x)) >> 31)));
+}
+
+/** Calculate SAO statistics for non-cross-slice or non-cross-tile processing
+ * \param  pRecStart to-be-filtered block buffer pointer
+ * \param  pOrgStart original block buffer pointer
+ * \param  stride picture buffer stride
+ * \param  ppStat statistics buffer
+ * \param  ppCount counter buffer
+ * \param  width block width
+ * \param  height block height
+ * \param  pbBorderAvail availabilities of block border pixels
+ */
+Void TEncSampleAdaptiveOffset::calcSaoStatsBlock( Pel* pRecStart, Pel* pOrgStart, Int stride, Int64** ppStats, Int64** ppCount, UInt width, UInt height, Bool* pbBorderAvail)
+{
+  Int64 *stats, *count;
+  Int classIdx, posShift, startX, endX, startY, endY, signLeft,signRight,signDown,signDown1;
+  Pel *pOrg, *pRec;
+  UInt edgeType;
+  Int x, y;
+
+  //--------- Band offset-----------//
+  stats = ppStats[SAO_BO];
+  count = ppCount[SAO_BO];
+  pOrg   = pOrgStart;
+  pRec   = pRecStart;
+  for (y=0; y< height; y++)
+  {
+    for (x=0; x< width; x++)
+    {
+      classIdx = m_lumaTableBo[pRec[x]];
+      if (classIdx)
+      {
+        stats[classIdx] += (pOrg[x] - pRec[x]); 
+        count[classIdx] ++;
+      }
+    }
+    pOrg += stride;
+    pRec += stride;
+  }
+  //---------- Edge offset 0--------------//
+  stats = ppStats[SAO_EO_0];
+  count = ppCount[SAO_EO_0];
+  pOrg   = pOrgStart;
+  pRec   = pRecStart;
+
+
+  startX = (pbBorderAvail[SGU_L]) ? 0 : 1;
+  endX   = (pbBorderAvail[SGU_R]) ? width : (width -1);
+  for (y=0; y< height; y++)
+  {
+    signLeft = xSign(pRec[startX] - pRec[startX-1]);
+    for (x=startX; x< endX; x++)
+    {
+      signRight =  xSign(pRec[x] - pRec[x+1]); 
+      edgeType =  signRight + signLeft + 2;
+      signLeft  = -signRight;
+
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+    }
+    pRec  += stride;
+    pOrg += stride;
+  }
+
+  //---------- Edge offset 1--------------//
+  stats = ppStats[SAO_EO_1];
+  count = ppCount[SAO_EO_1];
+  pOrg   = pOrgStart;
+  pRec   = pRecStart;
+
+  startY = (pbBorderAvail[SGU_T]) ? 0 : 1;
+  endY   = (pbBorderAvail[SGU_B]) ? height : height-1;
+  if (!pbBorderAvail[SGU_T])
+  {
+    pRec  += stride;
+    pOrg  += stride;
+  }
+
+  for (x=0; x< width; x++)
+  {
+    m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride]);
+  }
+  for (y=startY; y<endY; y++)
+  {
+    for (x=0; x< width; x++)
+    {
+      signDown     =  xSign(pRec[x] - pRec[x+stride]); 
+      edgeType    =  signDown + m_iUpBuff1[x] + 2;
+      m_iUpBuff1[x] = -signDown;
+
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+    }
+    pOrg += stride;
+    pRec += stride;
+  }
+  //---------- Edge offset 2--------------//
+  stats = ppStats[SAO_EO_2];
+  count = ppCount[SAO_EO_2];
+  pOrg   = pOrgStart;
+  pRec   = pRecStart;
+
+  posShift= stride + 1;
+
+  startX = (pbBorderAvail[SGU_L]) ? 0 : 1 ;
+  endX   = (pbBorderAvail[SGU_R]) ? width : (width-1);
+
+  //prepare 2nd line upper sign
+  pRec += stride;
+  for (x=startX; x< endX+1; x++)
+  {
+    m_iUpBuff1[x] = xSign(pRec[x] - pRec[x- posShift]);
+  }
+
+  //1st line
+  pRec -= stride;
+  if(pbBorderAvail[SGU_TL])
+  {
+    x= 0;
+    edgeType      =  xSign(pRec[x] - pRec[x- posShift]) - m_iUpBuff1[x+1] + 2;
+    stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+    count[m_auiEoTable[edgeType]] ++;
+  }
+  if(pbBorderAvail[SGU_T])
+  {
+    for(x= 1; x< endX; x++)
+    {
+      edgeType      =  xSign(pRec[x] - pRec[x- posShift]) - m_iUpBuff1[x+1] + 2;
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+    }
+  }
+  pRec   += stride;
+  pOrg   += stride;
+
+  //middle lines
+  for (y= 1; y< height-1; y++)
+  {
+    for (x=startX; x<endX; x++)
+    {
+      signDown1      =  xSign(pRec[x] - pRec[x+ posShift]) ;
+      edgeType      =  signDown1 + m_iUpBuff1[x] + 2;
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+
+      m_iUpBufft[x+1] = -signDown1; 
+    }
+    m_iUpBufft[startX] = xSign(pRec[stride+startX] - pRec[startX-1]);
+
+    ipSwap     = m_iUpBuff1;
+    m_iUpBuff1 = m_iUpBufft;
+    m_iUpBufft = ipSwap;
+
+    pRec  += stride;
+    pOrg  += stride;
+  }
+
+  //last line
+  if(pbBorderAvail[SGU_B])
+  {
+    for(x= startX; x< width-1; x++)
+    {
+      edgeType =  xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2;
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+    }
+  }
+  if(pbBorderAvail[SGU_BR])
+  {
+    x= width -1;
+    edgeType =  xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2;
+    stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+    count[m_auiEoTable[edgeType]] ++;
+  }
+
+  //---------- Edge offset 3--------------//
+
+  stats = ppStats[SAO_EO_3];
+  count = ppCount[SAO_EO_3];
+  pOrg   = pOrgStart;
+  pRec   = pRecStart;
+
+  posShift     = stride - 1;
+  startX = (pbBorderAvail[SGU_L]) ? 0 : 1;
+  endX   = (pbBorderAvail[SGU_R]) ? width : (width -1);
+
+  //prepare 2nd line upper sign
+  pRec += stride;
+  for (x=startX-1; x< endX; x++)
+  {
+    m_iUpBuff1[x] = xSign(pRec[x] - pRec[x- posShift]);
+  }
+
+
+  //first line
+  pRec -= stride;
+  if(pbBorderAvail[SGU_T])
+  {
+    for(x= startX; x< width -1; x++)
+    {
+      edgeType = xSign(pRec[x] - pRec[x- posShift]) -m_iUpBuff1[x-1] + 2;
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+    }
+  }
+  if(pbBorderAvail[SGU_TR])
+  {
+    x= width-1;
+    edgeType = xSign(pRec[x] - pRec[x- posShift]) -m_iUpBuff1[x-1] + 2;
+    stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+    count[m_auiEoTable[edgeType]] ++;
+  }
+  pRec  += stride;
+  pOrg  += stride;
+
+  //middle lines
+  for (y= 1; y< height-1; y++)
+  {
+    for(x= startX; x< endX; x++)
+    {
+      signDown1      =  xSign(pRec[x] - pRec[x+ posShift]) ;
+      edgeType      =  signDown1 + m_iUpBuff1[x] + 2;
+
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+      m_iUpBuff1[x-1] = -signDown1; 
+
+    }
+    m_iUpBuff1[endX-1] = xSign(pRec[endX-1 + stride] - pRec[endX]);
+
+    pRec  += stride;
+    pOrg  += stride;
+  }
+
+  //last line
+  if(pbBorderAvail[SGU_BL])
+  {
+    x= 0;
+    edgeType = xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2;
+    stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+    count[m_auiEoTable[edgeType]] ++;
+
+  }
+  if(pbBorderAvail[SGU_B])
+  {
+    for(x= 1; x< endX; x++)
+    {
+      edgeType = xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2;
+      stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]);
+      count[m_auiEoTable[edgeType]] ++;
+    }
+  }
+}
+
+/** Calculate SAO statistics for current LCU
+ * \param  iAddr,  iPartIdx,  iYCbCr
+ */
+Void TEncSampleAdaptiveOffset::calcSaoStatsCu(Int iAddr, Int iPartIdx, Int iYCbCr)
+{
+  if(!m_bUseNIF)
+  {
+    calcSaoStatsCuOrg( iAddr, iPartIdx, iYCbCr);
+  }
+  else
+  {
+    Int64** ppStats = m_iOffsetOrg[iPartIdx];
+    Int64** ppCount = m_iCount    [iPartIdx];
+
+    //parameters
+    Int  isChroma = (iYCbCr != 0)? 1:0;
+    Int  stride   = (iYCbCr != 0)?(m_pcPic->getCStride()):(m_pcPic->getStride());
+    Pel* pPicOrg = getPicYuvAddr (m_pcPic->getPicYuvOrg(), iYCbCr);
+    Pel* pPicRec  = getPicYuvAddr(m_pcYuvTmp, iYCbCr);
+
+    std::vector<NDBFBlockInfo>& vFilterBlocks = *(m_pcPic->getCU(iAddr)->getNDBFilterBlocks());
+
+    //variables
+    UInt  xPos, yPos, width, height;
+    Bool* pbBorderAvail;
+    UInt  posOffset;
+
+    for(Int i=0; i< vFilterBlocks.size(); i++)
+    {
+      xPos        = vFilterBlocks[i].posX   >> isChroma;
+      yPos        = vFilterBlocks[i].posY   >> isChroma;
+      width       = vFilterBlocks[i].width  >> isChroma;
+      height      = vFilterBlocks[i].height >> isChroma;
+      pbBorderAvail = vFilterBlocks[i].isBorderAvailable;
+
+      posOffset = (yPos* stride) + xPos;
+
+#if HHI_INTERVIEW_SKIP
+      if( !m_pcPic->getCU(iAddr)->getRenderable(0 ))
+      {
+      calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail);
+      }
+#else
+      calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail);
+#endif
+    }
+  }
+
+}
+
+/** Calculate SAO statistics for current LCU without non-crossing slice
+ * \param  iAddr,  iPartIdx,  iYCbCr
+ */
+Void TEncSampleAdaptiveOffset::calcSaoStatsCuOrg(Int iAddr, Int iPartIdx, Int iYCbCr)
+{
+  Int x,y;
+  TComDataCU *pTmpCu = m_pcPic->getCU(iAddr);
+  TComSPS *pTmpSPS =  m_pcPic->getSlice(0)->getSPS();
+
+  Pel* pOrg;
+  Pel* pRec;
+  Int iStride;
+  Int iLcuWidth  = pTmpSPS->getMaxCUHeight();
+  Int iLcuHeight = pTmpSPS->getMaxCUWidth();
+  UInt uiLPelX   = pTmpCu->getCUPelX();
+  UInt uiTPelY   = pTmpCu->getCUPelY();
+  UInt uiRPelX;
+  UInt uiBPelY;
+  Int64* iStats;
+  Int64* iCount;
+  Int iClassIdx;
+  Int iPicWidthTmp;
+  Int iPicHeightTmp;
+  Int iStartX;
+  Int iStartY;
+  Int iEndX;
+  Int iEndY;
+
+  Int iIsChroma = (iYCbCr!=0)? 1:0;
+  Int numSkipLine = iIsChroma? 2:4;
   if (m_saoInterleavingFlag == 0)
   {
@@ -1974,4 +4473,5 @@
 
 }
+#endif
 
 
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h	(revision 427)
@@ -71,4 +71,8 @@
   Int64  ***m_iOffset;     //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS]; 
   Int64  ***m_iOffsetOrg;  //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE]; 
+#if LGE_SAO_MIGRATION_D0091
+  Int64  ****m_count_PreDblk;      //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS]; 
+  Int64  ****m_offsetOrg_PreDblk;  //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS]; 
+#endif
   Int64  **m_iRate;        //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE]; 
   Int64  **m_iDist;        //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE]; 
@@ -79,4 +83,11 @@
   Int     m_iOffsetTh;
   Bool    m_bUseSBACRD;
+#if SAO_ENCODING_CHOICE
+#if SAO_ENCODING_CHOICE_CHROMA
+  Double  m_depthSaoRate[2][4];
+#else
+  Double  m_depth0SaoRate;
+#endif
+#endif
 
 public:
@@ -88,10 +99,21 @@
   Void resetStats();
 #if SAO_CHROMA_LAMBDA
+#if SAO_ENCODING_CHOICE
+  Void SAOProcess(SAOParam *pcSaoParam, Double dLambda, Double dLambdaChroma, Int depth);
+#else
   Void SAOProcess(SAOParam *pcSaoParam, Double dLambda, Double dLambdaChroma);
+#endif
 #else
   Void SAOProcess(SAOParam *pcSaoParam, Double dLambda);
 #endif
+
+#if LGE_SAO_MIGRATION_D0091
+  Void runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda, Int yCbCr);
+  Void rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda, Int yCbCr);
+#else
   Void runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda);
   Void rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda);
+#endif
+  
   Void disablePartTree(SAOQTPart *psQTPart, Int iPartIdx);
   Void getSaoStats(SAOQTPart *psQTPart, Int iYCbCr);
@@ -99,10 +121,25 @@
   Void calcSaoStatsBlock( Pel* pRecStart, Pel* pOrgStart, Int stride, Int64** ppStats, Int64** ppCount, UInt width, UInt height, Bool* pbBorderAvail);
   Void calcSaoStatsCuOrg(Int iAddr, Int iPartIdx, Int iYCbCr);
+#if LGE_SAO_MIGRATION_D0091
+  Void calcSaoStatsCu_BeforeDblk( TComPic* pcPic );
+#endif
   Void destroyEncBuffer();
   Void createEncBuffer();
   Void assignSaoUnitSyntax(SaoLcuParam* saoLcuParam,  SAOQTPart* saoPart, Bool &oneUnitFlag, Int yCbCr);
   Void checkMerge(SaoLcuParam * lcuParamCurr,SaoLcuParam * lcuParamCheck, Int dir);
+#if SAO_ENCODING_CHOICE
+  Void rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma, Int depth);
+#else
   Void rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma);
+#endif
+#if LGE_SAO_MIGRATION_D0091
+  Void saoComponentParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda, SaoLcuParam *compSaoParam, Double *distortion);
+  Void sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Double lambda, SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion);
+  inline Int64 estSaoDist(Int64 count, Int64 offset, Int64 offsetOrg, Int shift);
+  inline Int64 estIterOffset(Int typeIdx, Int classIdx, double lambda, Int64 offsetInput, Int64 count, Int64 offsetOrg, Int shift, Int bitIncrease, Int *currentDistortionTableBo, Double *currentRdCostTableBo );
+  inline Int64 estSaoTypeDist(Int compIdx, Int typeIdx, Int shift, Double lambda, Int *currentDistortionTableBo, Double *currentRdCostTableBo);
+#else
   Void rdoSaoUnit(SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda);
+#endif
   Void setMaxNumOffsetsPerPic(Int iVal) {m_maxNumOffsetsPerPic = iVal; }
   Int  getMaxNumOffsetsPerPic() {return m_maxNumOffsetsPerPic; }
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSbac.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 427)
@@ -99,4 +99,8 @@
 , m_cALFSvlcSCModel           ( 1,             1,               NUM_ALF_SVLC_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cCUAMPSCModel             ( 1,             1,               NUM_CU_AMP_CTX                , m_contextModels + m_numContextModels, m_numContextModels)
+#if LGE_SAO_MIGRATION_D0091
+, m_cSaoMergeSCModel          ( 1,             1,               NUM_SAO_MERGE_FLAG_CTX        , m_contextModels + m_numContextModels, m_numContextModels)
+, m_cSaoTypeIdxSCModel        ( 1,             1,               NUM_SAO_TYPE_IDX_CTX          , m_contextModels + m_numContextModels, m_numContextModels)
+#else
 , m_cSaoFlagSCModel           ( 1,             1,               NUM_SAO_FLAG_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cSaoUvlcSCModel           ( 1,             1,               NUM_SAO_UVLC_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
@@ -105,4 +109,5 @@
 , m_cSaoMergeUpSCModel        ( 1,             1,               NUM_SAO_MERGE_UP_FLAG_CTX     , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cSaoTypeIdxSCModel        ( 1,             1,               NUM_SAO_TYPE_IDX_CTX          , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
 , m_cDmmFlagSCModel           ( 1,             1,               NUM_DMM_FLAG_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
@@ -186,4 +191,8 @@
   m_cALFSvlcSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_ALF_SVLC );
   m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
+#if LGE_SAO_MIGRATION_D0091
+  m_cSaoMergeSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG );
+  m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
+#else
   m_cSaoFlagSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_SAO_FLAG );
   m_cSaoUvlcSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_SAO_UVLC );
@@ -192,4 +201,5 @@
   m_cSaoMergeUpSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_UP_FLAG );
   m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
+#endif
 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
   m_cDmmFlagSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_DMM_FLAG );
@@ -272,4 +282,8 @@
       curCost += m_cALFSvlcSCModel.calcCost           ( curSliceType, qp, (UChar*)INIT_ALF_SVLC );
       curCost += m_cCUTransSubdivFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
+#if LGE_SAO_MIGRATION_D0091
+      curCost += m_cSaoMergeSCModel.calcCost          ( curSliceType, qp, (UChar*)INIT_SAO_MERGE_FLAG );
+      curCost += m_cSaoTypeIdxSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_SAO_TYPE_IDX );
+#else
       curCost += m_cSaoFlagSCModel.calcCost           ( curSliceType, qp, (UChar*)INIT_SAO_FLAG );
       curCost += m_cSaoUvlcSCModel.calcCost           ( curSliceType, qp, (UChar*)INIT_SAO_UVLC );
@@ -278,4 +292,5 @@
       curCost += m_cSaoMergeUpSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_SAO_MERGE_UP_FLAG );
       curCost += m_cSaoTypeIdxSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_SAO_TYPE_IDX );
+#endif
 
       if (curCost < bestCost)
@@ -342,4 +357,8 @@
   m_cALFSvlcSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_ALF_SVLC );
   m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
+#if LGE_SAO_MIGRATION_D0091
+  m_cSaoMergeSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG );
+  m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
+#else
   m_cSaoFlagSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_SAO_FLAG );
   m_cSaoUvlcSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_SAO_UVLC );
@@ -348,4 +367,5 @@
   m_cSaoMergeUpSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_UP_FLAG );
   m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
+#endif
 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
   m_cDmmFlagSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_DMM_FLAG );
@@ -1913,5 +1933,77 @@
   }
 }
-
+#if LGE_SAO_MIGRATION_D0091
+Void TEncSbac::codeSAOSign( UInt code )
+{
+  m_pcBinIf->encodeBinEP( code );
+}
+
+Void TEncSbac::codeSaoMaxUvlc    ( UInt code, UInt maxSymbol )
+{
+  if (maxSymbol == 0)
+  {
+    return;
+  }
+
+  Int i;
+  Bool bCodeLast = ( maxSymbol > code );
+
+  if ( code == 0 )
+  {
+    m_pcBinIf->encodeBinEP( 0 );
+  }
+  else
+  {
+    m_pcBinIf->encodeBinEP( 1 );
+    for ( i=0; i<code-1; i++ )
+    {
+      m_pcBinIf->encodeBinEP( 1 );
+    }
+    if( bCodeLast )
+    {
+      m_pcBinIf->encodeBinEP( 0 );
+    }
+  }
+}
+
+/** Code SAO EO class or BO band position 
+ * \param uiLength
+ * \param uiCode
+ */
+Void TEncSbac::codeSaoUflc       ( UInt uiLength, UInt uiCode )
+{
+   m_pcBinIf->encodeBinsEP ( uiCode, uiLength );
+}
+/** Code SAO merge flags
+ * \param uiCode
+ * \param uiCompIdx
+ */
+Void TEncSbac::codeSaoMerge       ( UInt uiCode )
+{
+  if (uiCode == 0)
+  {
+    m_pcBinIf->encodeBin(0,  m_cSaoMergeSCModel.get( 0, 0, 0 ));
+  }
+  else
+  {
+    m_pcBinIf->encodeBin(1,  m_cSaoMergeSCModel.get( 0, 0, 0 ));
+  }
+}
+/** Code SAO type index 
+ * \param uiCode
+ */
+Void TEncSbac::codeSaoTypeIdx       ( UInt uiCode)
+{
+  if (uiCode == 0)
+  {
+    m_pcBinIf->encodeBin( 0, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) );
+  }
+  else
+  {
+    m_pcBinIf->encodeBin( 1, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) );
+    m_pcBinIf->encodeBinEP( uiCode <= 4 ? 1 : 0 ); //determine edge or band
+  }
+}
+#else
 Void TEncSbac::codeSaoFlag       ( UInt uiCode )
 {
@@ -2029,4 +2121,5 @@
   }
 }
+#endif
 /*!
  ****************************************************************************
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSbac.h
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSbac.h	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSbac.h	(revision 427)
@@ -126,4 +126,11 @@
   Void codeAlfCtrlFlag       ( UInt uiSymbol );
   Void  codeApsExtensionFlag () { assert (0); return; };
+#if LGE_SAO_MIGRATION_D0091
+  Void  codeSaoMaxUvlc    ( UInt code, UInt maxSymbol );
+  Void  codeSaoMerge      ( UInt  uiCode );
+  Void  codeSaoTypeIdx    ( UInt  uiCode);
+  Void  codeSaoUflc       ( UInt uiLength, UInt  uiCode );
+  Void  codeSAOSign       ( UInt  uiCode);  //<! code SAO offset sign
+#else
   Void  codeSaoFlag       ( UInt uiCode );
   Void  codeSaoUvlc       ( UInt uiCode );
@@ -134,4 +141,5 @@
   Void  codeSaoTypeIdx    ( UInt  uiCode);
   Void  codeSaoUflc       ( UInt  uiCode);
+#endif
   Void  codeScalingList      ( TComScalingList* scalingList     ){ assert (0);  return;};
   
@@ -298,4 +306,8 @@
   ContextModel3DBuffer m_cALFSvlcSCModel;
   ContextModel3DBuffer m_cCUAMPSCModel;
+#if LGE_SAO_MIGRATION_D0091
+  ContextModel3DBuffer m_cSaoMergeSCModel;
+  ContextModel3DBuffer m_cSaoTypeIdxSCModel;
+#else
   ContextModel3DBuffer m_cSaoFlagSCModel;
   ContextModel3DBuffer m_cSaoUvlcSCModel;
@@ -304,4 +316,5 @@
   ContextModel3DBuffer m_cSaoMergeUpSCModel;
   ContextModel3DBuffer m_cSaoTypeIdxSCModel;
+#endif
 
 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 427)
@@ -206,5 +206,9 @@
   
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
+  const Int iNumAMVPCands = AMVP_MAX_NUM_CANDS;
+#else
   const Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + 1;
+#endif
   for( Int iNum = 0; iNum < iNumAMVPCands+1; iNum++)
     for( Int iIdx = 0; iIdx < iNumAMVPCands; iIdx++)
@@ -2998,6 +3002,19 @@
       pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
 #if MERL_VSP_C0152
+#if MTK_D0156
+      if( !pcCU->getSlice()->getSPS()->getUseVSPCompensation() )
+      {
+          pcCU->setVSPIndexSubParts( 0, uiAbsPartIdx, iPUIdx, pcCU->getDepth( uiAbsPartIdx ) );
+      }
+      else
+#endif
       {
         Int iVSPIdx = 0;
+#if LGE_VSP_INHERIT_D0092
+        if (iVSPIndexTrue[uiMergeCand] == 1)
+        {
+            iVSPIdx = 1;
+        }
+#else
         Int numVSPIdx;
         numVSPIdx = 3;
@@ -3010,7 +3027,15 @@
             }
         }
+#endif
         pcCU->setVSPIndexSubParts( iVSPIdx, uiAbsPartIdx, iPUIdx, pcCU->getDepth( uiAbsPartIdx ) );
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
         pcCU->setVSPDirSubParts( iVSPDirTrue[iVSPIdx-1], uiAbsPartIdx, iPUIdx, pcCU->getDepth( uiAbsPartIdx ) );
+#endif
+#if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092
+       if(iVSPIdx != 0)
+       {
+        Int iIVCIdx = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==pcCU->getSlice()->getPOC() ? 0: pcCU->getSlice()->getNewRefIdx(REF_PIC_LIST_0);
+        cMvFieldNeighbours[ 2*uiMergeIndex].setRefIdx(iIVCIdx);
+      }
 #endif
       }
@@ -3125,5 +3150,9 @@
 
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
+  Int iNumAMVPCands = AMVP_MAX_NUM_CANDS;
+#else
   Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
+#endif
 #endif
 
@@ -3676,5 +3705,13 @@
       UInt uiMRGIndex = 0;
 #if MERL_VSP_C0152
+#if LGE_VSP_INHERIT_D0092
+      Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM];
+      for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++)
+      {
+          iVSPIndexTrue[i] = 0;
+      }
+#else
       Int iVSPIndexTrue[3] = {-1, -1, -1};
+#endif
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
       Int iVSPDirTrue[3]   = {-1, -1, -1};
@@ -3728,6 +3765,20 @@
         pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
 #if MERL_VSP_C0152
+
+#if MTK_D0156
+        if( !pcCU->getSlice()->getSPS()->getUseVSPCompensation() )
+        {
+            pcCU->setVSPIndexSubParts( 0, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+        }
+        else
+#endif
         {
           Int iVSPIdx = 0;
+#if LGE_VSP_INHERIT_D0092
+          if (iVSPIndexTrue[uiMRGIndex] == 1)
+          {
+              iVSPIdx = 1;
+          }
+#else
           Int numVSPIdx;
           numVSPIdx = 3;
@@ -3740,7 +3791,15 @@
               }
           }
+#endif
           pcCU->setVSPIndexSubParts( iVSPIdx, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
 #if MERL_VSP_NBDV_RefVId_Fix_D0166
           pcCU->setVSPDirSubParts( iVSPDirTrue[iVSPIdx-1], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+#endif
+#if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092
+         if(iVSPIdx != 0)
+         {
+           Int iIVCIdx = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==pcCU->getSlice()->getPOC() ? 0: pcCU->getSlice()->getNewRefIdx(REF_PIC_LIST_0);
+           cMRGMvField[ 0].setRefIdx(iIVCIdx);
+         }
 #endif
         }
@@ -3830,5 +3889,9 @@
     {
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
+      Int iNumAMVPCands = AMVP_MAX_NUM_CANDS;
+#else
       Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
+#endif
 #if ZERO_MVD_EST
       (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, iNumAMVPCands, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
@@ -3865,5 +3928,9 @@
       UInt uiTmpCost;
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
+      Int iNumAMVPCands = AMVP_MAX_NUM_CANDS;
+#else
       Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
+#endif
 #if ZERO_MVD_EST
       uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, iNumAMVPCands, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
@@ -3998,5 +4065,9 @@
   
 #if H3D_IVMP
+#if SEC_TWO_CANDIDATES_FOR_AMVP_D0122
+  Int iNumAMVPCands = AMVP_MAX_NUM_CANDS;
+#else
   Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
+#endif
 #endif
   
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 427)
@@ -787,4 +787,10 @@
   {
     pcSlice ->xSetApplyIC();
+#if SHARP_ILLUCOMP_PARSE_D0060
+    if (pcSlice->getApplyIC())
+    {
+      pcSlice->setIcSkipParseFlag(rpcPic->getCurrSlice()->getPOC() % m_pcCfg->getIntraPeriod() != 0);
+    }
+#endif
   }
 #endif
@@ -1218,4 +1224,72 @@
     TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );    
 
+#if LGE_SAO_MIGRATION_D0091
+    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
+    {
+        SAOParam *saoParam =  pcSlice->getAPS()->getSaoParam();
+        Int iNumCuInWidth     = saoParam->numCuInWidth;
+        Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
+        Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
+        Int rx = uiCUAddr % iNumCuInWidth;
+        Int ry = uiCUAddr / iNumCuInWidth;
+        Int allowMergeLeft = 1;
+        Int allowMergeUp   = 1;
+
+        if (rx!=0)
+        {
+            if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
+            {
+                allowMergeLeft = 0;
+            }
+        }
+        if (ry!=0)
+        {
+            if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
+            {
+                allowMergeUp = 0;
+            }
+        }
+
+        Int addr = pcCU->getAddr();
+        allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
+        allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
+
+        if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
+        {
+            Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
+            Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
+
+            if (allowMergeLeft)
+            {
+                m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
+            }
+            else
+            {
+                mergeLeft = 0;
+            }
+            if(mergeLeft == 0)
+            {
+                if (allowMergeUp)
+                {
+                    m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
+                }
+                else
+                {
+                    mergeUp = 0;
+                }
+                if(mergeUp == 0)
+                {
+                    for (Int compIdx=0;compIdx<3;compIdx++)
+                    {
+                        if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
+                        {
+                            m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
+                        }
+                    }
+                }
+            }
+        }
+    }
+#else
     if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
     {
@@ -1227,4 +1301,5 @@
       m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
     }
+#endif
 #if ENC_DEC_TRACE
     g_bJustDoIt = g_bEncDecTraceEnable;
Index: /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncTop.cpp	(revision 426)
+++ /branches/HTM-6.2-dev0/source/Lib/TLibEncoder/TEncTop.cpp	(revision 427)
@@ -103,5 +103,10 @@
   if (m_bUseSAO)
   {
+#if LGE_SAO_MIGRATION_D0091
+    m_cEncSAO.setSaoLcuBoundary(getSaoLcuBoundary());
+    m_cEncSAO.setSaoLcuBasedOptimization(getSaoLcuBasedOptimization());
+#else
     m_cEncSAO.setSaoInterleavingFlag(getSaoInterleavingFlag());
+#endif
     m_cEncSAO.setMaxNumOffsetsPerPic(getMaxNumOffsetsPerPic());
     m_cEncSAO.create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
@@ -708,4 +713,12 @@
 #if HHI_MPI
   m_cSPS.setUseMVI( m_bUseMVI );
+#endif
+
+
+#if MTK_D0156
+#if MERL_VSP_COMPENSATION_C0152
+  m_cSPS.setUseVSPCompensation           ( m_bUseVSPCompensation );
+#endif
+  m_cSPS.setUseDVPRefine                 ( m_bUseDVPRefine       );
 #endif
 
