Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComDataCU.cpp	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComDataCU.cpp	(revision 510)
@@ -116,4 +116,8 @@
 #endif
 
+#if H_3D_VSP
+  m_piVSPFlag            = NULL;
+#endif
+
 #if H_3D_ARP
   m_puhARPW              = NULL;
@@ -157,4 +161,7 @@
     m_pbMergeFlag        = (Bool*  )xMalloc(Bool,   uiNumPartition);
     m_puhMergeIndex      = (UChar* )xMalloc(UChar,  uiNumPartition);
+#if H_3D_VSP
+    m_piVSPFlag          = (Char*  )xMalloc(Char,   uiNumPartition);
+#endif
     m_puhLumaIntraDir    = (UChar* )xMalloc(UChar,  uiNumPartition);
     m_puhChromaIntraDir  = (UChar* )xMalloc(UChar,  uiNumPartition);
@@ -276,4 +283,7 @@
     if ( m_pbMergeFlag        ) { xFree(m_pbMergeFlag);         m_pbMergeFlag       = NULL; }
     if ( m_puhMergeIndex      ) { xFree(m_puhMergeIndex);       m_puhMergeIndex     = NULL; }
+#if H_3D_VSP
+    if ( m_piVSPFlag          ) { xFree(m_piVSPFlag);           m_piVSPFlag         = NULL; }
+#endif
     if ( m_puhLumaIntraDir    ) { xFree(m_puhLumaIntraDir);     m_puhLumaIntraDir   = NULL; }
     if ( m_puhChromaIntraDir  ) { xFree(m_puhChromaIntraDir);   m_puhChromaIntraDir = NULL; }
@@ -442,4 +452,7 @@
     m_pbMergeFlag[ui]=pcFrom->m_pbMergeFlag[ui];
     m_puhMergeIndex[ui]=pcFrom->m_puhMergeIndex[ui];
+#if H_3D_VSP
+    m_piVSPFlag[ui] = pcFrom->m_piVSPFlag[ui];
+#endif
     m_puhLumaIntraDir[ui]=pcFrom->m_puhLumaIntraDir[ui];
     m_puhChromaIntraDir[ui]=pcFrom->m_puhChromaIntraDir[ui];
@@ -475,4 +488,7 @@
     memset( m_pbMergeFlag       + firstElement, false,                    numElements * sizeof( *m_pbMergeFlag ) );
     memset( m_puhMergeIndex     + firstElement, 0,                        numElements * sizeof( *m_puhMergeIndex ) );
+#if H_3D_VSP
+    memset( m_piVSPFlag         + firstElement, 0,                        numElements * sizeof( *m_piVSPFlag ) );
+#endif
     memset( m_puhLumaIntraDir   + firstElement, DC_IDX,                   numElements * sizeof( *m_puhLumaIntraDir ) );
     memset( m_puhChromaIntraDir + firstElement, 0,                        numElements * sizeof( *m_puhChromaIntraDir ) );
@@ -617,4 +633,7 @@
       m_pbMergeFlag[ui] = 0;
       m_puhMergeIndex[ui] = 0;
+#if H_3D_VSP
+      m_piVSPFlag[ui] = 0;
+#endif
       m_puhLumaIntraDir[ui] = DC_IDX;
       m_puhChromaIntraDir[ui] = 0;
@@ -688,4 +707,7 @@
   memset( m_pbMergeFlag,        0, iSizeInBool  );
   memset( m_puhMergeIndex,      0, iSizeInUchar );
+#if H_3D_VSP
+  memset( m_piVSPFlag,          0, sizeof( Char  ) * m_uiNumPartition );
+#endif
   memset( m_puhLumaIntraDir,    DC_IDX, iSizeInUchar );
   memset( m_puhChromaIntraDir,  0, iSizeInUchar );
@@ -744,4 +766,7 @@
       m_pbMergeFlag[ui]=pcCU->m_pbMergeFlag[uiPartOffset+ui];
       m_puhMergeIndex[ui]=pcCU->m_puhMergeIndex[uiPartOffset+ui];
+#if H_3D_VSP
+      m_piVSPFlag[ui]=pcCU->m_piVSPFlag[uiPartOffset+ui];
+#endif
       m_puhLumaIntraDir[ui]=pcCU->m_puhLumaIntraDir[uiPartOffset+ui];
       m_puhChromaIntraDir[ui]=pcCU->m_puhChromaIntraDir[uiPartOffset+ui];
@@ -866,4 +891,7 @@
   m_pbMergeFlag         = pcCU->getMergeFlag()        + uiPart;
   m_puhMergeIndex       = pcCU->getMergeIndex()       + uiPart;
+#if H_3D_VSP
+  m_piVSPFlag           = pcCU->getVSPFlag()          + uiPart;
+#endif
 
 #if H_3D_ARP
@@ -986,4 +1014,7 @@
   m_pbMergeFlag        = pcCU->getMergeFlag()             + uiAbsPartIdx;
   m_puhMergeIndex      = pcCU->getMergeIndex()            + uiAbsPartIdx;
+#if H_3D_VSP
+  m_piVSPFlag          = pcCU->getVSPFlag()               + uiAbsPartIdx;
+#endif
 
   m_apiMVPIdx[eRefPicList] = pcCU->getMVPIdx(eRefPicList) + uiAbsPartIdx;
@@ -1030,4 +1061,7 @@
   memcpy( m_pbMergeFlag         + uiOffset, pcCU->getMergeFlag(),         iSizeInBool  );
   memcpy( m_puhMergeIndex       + uiOffset, pcCU->getMergeIndex(),        iSizeInUchar );
+#if H_3D_VSP
+  memcpy( m_piVSPFlag           + uiOffset, pcCU->getVSPFlag(),           sizeof( Char ) * uiNumPartition );
+#endif
   memcpy( m_puhLumaIntraDir     + uiOffset, pcCU->getLumaIntraDir(),      iSizeInUchar );
   memcpy( m_puhChromaIntraDir   + uiOffset, pcCU->getChromaIntraDir(),    iSizeInUchar );
@@ -1120,4 +1154,7 @@
   memcpy( rpcCU->getMergeFlag()         + m_uiAbsIdxInLCU, m_pbMergeFlag,         iSizeInBool  );
   memcpy( rpcCU->getMergeIndex()        + m_uiAbsIdxInLCU, m_puhMergeIndex,       iSizeInUchar );
+#if H_3D_VSP
+  memcpy( rpcCU->getVSPFlag()           + m_uiAbsIdxInLCU, m_piVSPFlag,           sizeof( Char ) * m_uiNumPartition );
+#endif
   memcpy( rpcCU->getLumaIntraDir()      + m_uiAbsIdxInLCU, m_puhLumaIntraDir,     iSizeInUchar );
   memcpy( rpcCU->getChromaIntraDir()    + m_uiAbsIdxInLCU, m_puhChromaIntraDir,   iSizeInUchar );
@@ -1199,4 +1236,7 @@
   memcpy( rpcCU->getMergeFlag()         + uiPartOffset, m_pbMergeFlag,         iSizeInBool  );
   memcpy( rpcCU->getMergeIndex()        + uiPartOffset, m_puhMergeIndex,       iSizeInUchar );
+#if H_3D_VSP
+  memcpy( rpcCU->getVSPFlag()           + uiPartOffset, m_piVSPFlag,           sizeof(Char) * uiQNumPart );
+#endif
   memcpy( rpcCU->getLumaIntraDir()      + uiPartOffset, m_puhLumaIntraDir,     iSizeInUchar );
   memcpy( rpcCU->getChromaIntraDir()    + uiPartOffset, m_puhChromaIntraDir,   iSizeInUchar );
@@ -2143,4 +2183,11 @@
   setSubPart<UChar>( uiMergeIndex, m_puhMergeIndex, uiAbsPartIdx, uiDepth, uiPartIdx );
 }
+
+#if H_3D_VSP
+Void TComDataCU::setVSPFlagSubParts( Char iVSPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
+{
+  setSubPart<Char>( iVSPFlag, m_piVSPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
+}
+#endif
 
 Void TComDataCU::setChromIntraDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiDepth )
@@ -2572,4 +2619,120 @@
 }
 
+#if H_3D_VSP
+
+/** Add a VSP merging candidate
+ * \Inputs
+ * \param uiPUIdx: PU index within a CU
+ * \param ucVspMergePos: Specify the VSP merge candidate position
+ * \param mrgCandIdx: Target merge candidate index. At encoder, it is set equal to -1, such that the whole merge candidate list will be constructed.
+ * \param pDinfo: The "disparity information" derived from neighboring blocks. Type 1 MV.
+ * \param uiCount: The next position to add VSP merge candidate
+ *
+ * \Outputs
+ * \param uiCount: The next position to add merge candidate. Will be updated if VSP is successfully added
+ * \param abCandIsInter: abCandIsInter[iCount] tells that VSP candidate is an Inter candidate, if VSP is successfully added
+ * \param pcMvFieldNeighbours:   Return the "disparity vector". Type 1 MV. To be used to fetch a depth block. A "global" variable
+ * \param puhInterDirNeighbours: Tells the VSP prediction direction. TODO: The value does NOT matter for VSP, as the direction will be determined based on availability later
+ *                                Having it as output is mainly for coding beauty
+ * \param vspFlag: vspFlag[iCount] will be set (equal to 1), if VSP is successfully added. To be used to indicate the actual position of the VSP candidate
+ *
+ * \Return
+ *   true:  if the VSP candidate is added at the target position
+ *   false: otherwise
+ */
+inline Bool TComDataCU::xAddVspCand( UChar ucVspMergePos, Int mrgCandIdx, DisInfo* pDInfo, Int& iCount,
+                                     Bool* abCandIsInter, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int* vspFlag )
+{
+  if( !m_pcSlice->getVPS()->getViewSynthesisPredFlag( m_pcSlice->getLayerIdInVps() ) ) // Not to add the candidate if VSP is turned off
+    return false;
+  if( m_pcSlice->getIsDepth() ) // VSP is turned off for depth layers
+    return false;
+
+  Int refViewIdx = pDInfo->m_aVIdxCan;
+  TComPic* picDepth = NULL;
+  //assert(getSlice()->getRefPic(eRefPicList, refId)->getPOC() == getSlice()->getPOC());
+  picDepth = getSlice()->getIvPic( true, refViewIdx );
+
+  /*
+  // Code if simply re-writing
+  if(ucVspMergePos == H_3D_VSPPOSITION && picDepth != NULL && 0 != m_pcSlice->getViewIndex() ) // VSP can be used only when depth is used as input
+  {
+    abCandIsInter[iCount] = true;
+    puhInterDirNeighbours[iCount] = 1;
+    vspFlag[iCount] = 1;
+    vspDirTrue[iCount] = 0; // TODO: Check if this is really useful!!!!
+
+    Int iRefIdxList0 = getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC() == getSlice()->getPOC() ? 0 :
+                      (getSlice()->getAlterRefIdx(REF_PIC_LIST_0) == -1 ? NOT_VALID : getSlice()->getAlterRefIdx(REF_PIC_LIST_0));
+    pcMvFieldNeighbours[iCount<<1].setMvField( pDInfo->m_acDoNBDV, iRefIdxList0 );
+    if (getSlice()->isInterB())
+    {
+      puhInterDirNeighbours[iCount] = xGetVspDirection(uiPUIdx);
+      Int iRefIdxList1 = getSlice()->getRefPic(REF_PIC_LIST_1, 0)->getPOC() == getSlice()->getPOC() ? 0 :
+                        (getSlice()->getAlterRefIdx(REF_PIC_LIST_1) == -1 ? NOT_VALID : getSlice()->getAlterRefIdx(REF_PIC_LIST_1));
+      pcMvFieldNeighbours[(iCount<<1)+1].setMvField( pDInfo->m_acDoNBDV, iRefIdxList1 );
+    }
+
+    if ( mrgCandIdx == iCount )
+      return true;
+
+    iCount++;
+  }
+  */
+  if(ucVspMergePos == H_3D_VSP_POSITION && picDepth != NULL && 0 != m_pcSlice->getViewIndex() ) // VSP can be used only when depth is used as input
+  {
+    abCandIsInter[iCount] = true;
+    puhInterDirNeighbours[iCount] = 0;
+    vspFlag[iCount] = 1;
+
+    Bool refViewAvailFlag = false;
+    UChar predFlag[2] = {0, 0};
+    Int  iRefListIdX = 0;
+    Int  iRefListIdY = 0;
+
+    for( iRefListIdX = 0; iRefListIdX < 2 && !refViewAvailFlag; iRefListIdX++ )
+    {
+      RefPicList eRefPicList = RefPicList( iRefListIdX );
+      for (Int i = 0; i < m_pcSlice->getNumRefIdx(eRefPicList) && !refViewAvailFlag; i++)
+      {
+        Int viewIdxRefInList = m_pcSlice->getRefPic(eRefPicList, i)->getViewIndex();
+        if (refViewIdx == viewIdxRefInList)
+        {
+          refViewAvailFlag = true;
+          predFlag[iRefListIdX] = 1;
+          iRefListIdY = 1 - iRefListIdX;
+          pcMvFieldNeighbours[(iCount<<1)+iRefListIdX].setMvField( pDInfo->m_acDoNBDV, i );
+        }
+      }
+    }
+
+    if (m_pcSlice->isInterB() && refViewAvailFlag)
+    {
+      RefPicList eRefPicList = RefPicList( iRefListIdY );
+      refViewAvailFlag = false;
+      for (Int i = 0; i < m_pcSlice->getNumRefIdx(eRefPicList) && !refViewAvailFlag; i++)
+      {
+        Int viewIdxRefInList = m_pcSlice->getRefPic(eRefPicList, i)->getViewIndex();
+        if (refViewIdx != viewIdxRefInList)
+        {
+          refViewAvailFlag = true;
+          predFlag[iRefListIdY] = 1;
+          pcMvFieldNeighbours[(iCount<<1)+iRefListIdY].setMvField( pDInfo->m_acDoNBDV, i );
+        }
+      }
+    }
+
+    puhInterDirNeighbours[iCount] = (predFlag[0] | (predFlag[1] << 1));
+
+    if ( mrgCandIdx == iCount )
+      return true;
+
+    iCount++;
+  }
+
+  return false;
+}
+#endif
+
 /** Constructs a list of merging candidates
  * \param uiAbsPartIdx
@@ -2580,5 +2743,11 @@
  * \param numValidMergeCand
  */
-Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx )
+Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours
+#if H_3D_VSP
+      , Int* vspFlag
+#endif
+      , Int& numValidMergeCand
+      , Int mrgCandIdx
+)
 {
   UInt uiAbsPartAddr = m_uiAbsIdxInLCU + uiAbsPartIdx;
@@ -2830,4 +2999,8 @@
       pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
 #endif
+#if H_3D_VSP
+      if (pcCULeft->getVSPFlag(uiLeftPartIdx) == 1)
+        vspFlag[iCount] = 1;
+#endif
       if ( mrgCandIdx == iCount )
       {
@@ -2894,4 +3067,8 @@
       pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
 #endif
+#if H_3D_VSP
+      if (pcCUAbove->getVSPFlag(uiAbovePartIdx) == 1)
+        vspFlag[iCount] = 1;
+#endif
       if ( mrgCandIdx == iCount )
       {
@@ -2936,4 +3113,8 @@
     pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
 #endif
+#if H_3D_VSP
+    if (pcCUAboveRight->getVSPFlag(uiAboveRightPartIdx) == 1)
+      vspFlag[iCount] = 1;
+#endif
     if ( mrgCandIdx == iCount )
     {
@@ -3003,4 +3184,12 @@
 #endif
 
+#if H_3D_VSP
+  if ( xAddVspCand( 3, mrgCandIdx, &cDisInfo, iCount, abCandIsInter, pcMvFieldNeighbours, puhInterDirNeighbours, vspFlag ) )
+    return;
+  // early termination
+  if (iCount == getSlice()->getMaxNumMergeCand())
+    return;
+#endif
+
   //left bottom
   UInt uiLeftBottomPartIdx = 0;
@@ -3025,4 +3214,8 @@
     pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
 #endif
+#if H_3D_VSP
+    if (pcCULeftBottom->getVSPFlag(uiLeftBottomPartIdx) == 1)
+      vspFlag[iCount] = 1;
+#endif
     if ( mrgCandIdx == iCount )
     {
@@ -3060,4 +3253,8 @@
       pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
       pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
+#endif
+#if H_3D_VSP
+      if (pcCUAboveLeft->getVSPFlag(uiAboveLeftPartIdx) == 1)
+        vspFlag[iCount] = 1;
 #endif
       if ( mrgCandIdx == iCount )
@@ -3192,5 +3389,16 @@
     {
       Int i = uiPriorityList0[idx]; Int j = uiPriorityList1[idx];
+#if H_3D_VSP
+      Bool bValid = true;
+      if ( vspFlag[i] == 1 || vspFlag[j] == 1 )
+        bValid = false;
+      if( !m_pcSlice->getVPS()->getViewSynthesisPredFlag( m_pcSlice->getLayerIdInVps() ) )
+        assert(bValid == true);
+#endif
+#if H_3D_VSP
+      if (abCandIsInter[i] && abCandIsInter[j] && (puhInterDirNeighbours[i]&0x1) && (puhInterDirNeighbours[j]&0x2) && bValid)
+#else
       if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
+#endif
       {
         abCandIsInter[uiArrayAddr] = true;
@@ -4515,6 +4723,5 @@
             estimateDVFromDM(iTargetViewIdx, uiPartIdx, picDepth, uiPartAddr, &cColMv );
 
-          //Notes from MTK: Please uncomment the following parts while integrating VSP
-#if H_3D_VSP
+#if 0 // H_3D_VSP
           Int refFrmIdx = 0;
           RefPicList privateRefPicList = REF_PIC_LIST_0;
@@ -4635,5 +4842,5 @@
           pDInfo->m_acDoNBDV = cDispVec;
           
-#if H_3D_VSP
+#if 0 // H_3D_VSP
           Int refFrmIdx = 0;
           RefPicList privateRefPicList = REF_PIC_LIST_0 ;
@@ -4666,5 +4873,5 @@
   pDInfo->m_acDoNBDV = defaultDV;
 
-#if H_3D_VSP
+#if 0 // H_3D_VSP
   Int refFrmIdx = 0;
   RefPicList privateRefPicList = REF_PIC_LIST_0 ;
@@ -4684,5 +4891,4 @@
   Int iPictureWidth  = pcBaseViewDepthPicYuv->getWidth();
   Int iPictureHeight = pcBaseViewDepthPicYuv->getHeight();
-  
 
   Int depthStartPosX = Clip3(0,   iPictureWidth - iBlkWidth,  iBlkX + ((mv->getHor()+2)>>2));
@@ -4749,7 +4955,7 @@
           pNbDvInfo->m_aVIdxCan = refViewIdx;
 #if H_3D_NBDV_REF
-          TComPic* picDepth = NULL;          
+          TComPic* picDepth = NULL;
           assert(getSlice()->getRefPic(eRefPicList, refId)->getPOC() == getSlice()->getPOC());          
-          picDepth   = getSlice()->getIvPic (true, refViewIdx );          
+          picDepth   = getSlice()->getIvPic (true, refViewIdx );
           assert(picDepth != NULL);
 
@@ -4760,5 +4966,10 @@
             estimateDVFromDM(refViewIdx, uiPartIdx, picDepth, uiPartAddr, &cMvPred );
 
-          
+#if 0 // H_3D_VSP
+          pNbDvInfo->m_aListIdx[ pNbDvInfo->iN ] = eRefPicList;
+          pNbDvInfo->m_aRefIdx [ pNbDvInfo->iN ] = -1-refId;
+          assert(pNbDvInfo->m_aRefIdx [ pNbDvInfo->iN ] < 0);
+#endif
+
           pNbDvInfo->m_acDoNBDV = cMvPred;
 #endif
@@ -4769,5 +4980,5 @@
           assert( uiMvpDvPos < IDV_CANDS );
           paIDVInfo->m_acMvCand[iList][ uiMvpDvPos ] = TComMv( cMvPred.getIDVHor(), cMvPred.getIDVVer() );
-          //Notes from QC: DvMCP is implemented in a way that doesnt carry the reference view identifier as NBDV. It only works for CTC and needs to be fixed to be aligned with other part of the NBDV design.
+          //Notes from QC: DvMCP is implemented in a way that doesn�t carry the reference view identifier as NBDV. It only works for CTC and needs to be fixed to be aligned with other part of the NBDV design.
           paIDVInfo->m_aVIdxCan[iList][ uiMvpDvPos ] = 0; 
           paIDVInfo->m_bAvailab[iList][ uiMvpDvPos ] = true;
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComDataCU.h	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComDataCU.h	(revision 510)
@@ -194,4 +194,8 @@
   DisInfo*      m_pDvInfo;
 #endif
+#if H_3D_VSP
+  Char*         m_piVSPFlag;          ///< array of VSP flags to indicate whehter a block uses VSP or not
+                                      ///< 0: non-VSP; 1: VSP
+#endif
 #if H_3D_ARP
   UChar*        m_puhARPW;
@@ -221,4 +225,8 @@
   Bool          xAddMVPCand           ( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir );
   Bool          xAddMVPCandOrder      ( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir );
+#if H_3D_VSP
+  Bool          xAddVspCand( UChar ucVspMergePos, Int mrgCandIdx, DisInfo* pDInfo, Int& iCount,
+                             Bool* abCandIsInter, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int* vspIdxTrue );
+#endif
 
   Void          deriveRightBottomIdx        ( UInt uiPartIdx, UInt& ruiPartIdxRB );
@@ -549,5 +557,16 @@
   
   Bool          hasEqualMotion              ( UInt uiAbsPartIdx, TComDataCU* pcCandCU, UInt uiCandAbsPartIdx );
-  Void          getInterMergeCandidates       ( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx = -1 );
+  Void          getInterMergeCandidates     ( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours
+#if H_3D_VSP
+                                            , Int* vspFlag
+#endif
+                                            , Int& numValidMergeCand
+                                            , Int mrgCandIdx = -1 );
+#if H_3D_VSP
+  Char*         getVSPFlag        ()                        { return m_piVSPFlag;        }
+  Char          getVSPFlag        ( UInt uiIdx )            { return m_piVSPFlag[uiIdx]; }
+  Void          setVSPFlag        ( UInt uiIdx, Int n )     { m_piVSPFlag[uiIdx] = n;    }
+  Void          setVSPFlagSubParts( Char iVSPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth );
+#endif
   Void          deriveLeftRightTopIdxGeneral  ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT );
   Void          deriveLeftBottomIdxGeneral    ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLB );
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComPrediction.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComPrediction.cpp	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComPrediction.cpp	(revision 510)
@@ -51,9 +51,18 @@
 {
   m_piYuvExt = NULL;
+#if H_3D_VSP
+  m_pDepthBlock = (Int*) malloc(MAX_NUM_SPU_W*MAX_NUM_SPU_W*sizeof(Int));
+  if (m_pDepthBlock == NULL)
+      printf("ERROR: UKTGHU, No memory allocated.\n");
+#endif
 }
 
 TComPrediction::~TComPrediction()
 {
-  
+#if H_3D_VSP
+  if (m_pDepthBlock != NULL)
+      free(m_pDepthBlock);
+#endif
+
   delete[] m_piYuvExt;
 
@@ -428,34 +437,51 @@
   Int         iHeight;
   UInt        uiPartAddr;
+#if H_3D_VSP
+  UInt        uiAbsPartIdx = pcCU->getZorderIdxInCU();
+#endif
 
   if ( iPartIdx >= 0 )
   {
     pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
-    if ( eRefPicList != REF_PIC_LIST_X )
-    {
-      if( pcCU->getSlice()->getPPS()->getUseWP())
-      {
-        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
+#if H_3D_VSP
+    if ( 0 == pcCU->getVSPFlag(uiPartAddr) )
+    {
+#endif
+      if ( eRefPicList != REF_PIC_LIST_X )
+      {
+        if( pcCU->getSlice()->getPPS()->getUseWP())
+        {
+          xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
+        }
+        else
+        {
+          xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
+        }
+        if ( pcCU->getSlice()->getPPS()->getUseWP() )
+        {
+          xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
+        }
       }
       else
       {
-        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
-      }
-      if ( pcCU->getSlice()->getPPS()->getUseWP() )
-      {
-        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
-      }
+        if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
+        {
+          xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
+        }
+        else
+        {
+          xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
+        }
+      }
+#if H_3D_VSP
     }
     else
     {
       if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
-      {
-        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
-      }
+        xPredInterUniVSP( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
       else
-      {
-        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
-      }
-    }
+        xPredInterBiVSP ( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, pcYuvPred );
+    }
+#endif
     return;
   }
@@ -465,30 +491,44 @@
     pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
 
-    if ( eRefPicList != REF_PIC_LIST_X )
-    {
-      if( pcCU->getSlice()->getPPS()->getUseWP())
-      {
-        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
+#if H_3D_VSP
+    if ( 0 == pcCU->getVSPFlag(uiPartAddr) )
+    {
+#endif
+      if ( eRefPicList != REF_PIC_LIST_X )
+      {
+        if( pcCU->getSlice()->getPPS()->getUseWP())
+        {
+          xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
+        }
+        else
+        {
+          xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
+        }
+        if ( pcCU->getSlice()->getPPS()->getUseWP() )
+        {
+          xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
+        }
       }
       else
       {
-        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
-      }
-      if ( pcCU->getSlice()->getPPS()->getUseWP() )
-      {
-        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
-      }
+        if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
+        {
+          xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
+        }
+        else
+        {
+          xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
+        }
+      }
+#if H_3D_VSP
     }
     else
     {
       if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
-      {
-        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
-      }
+        xPredInterUniVSP( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
       else
-      {
-        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
-      }
-    }
+        xPredInterBiVSP ( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, pcYuvPred );
+    }
+#endif
   }
   return;
@@ -531,4 +571,35 @@
 #endif
 }
+
+#if H_3D_VSP
+Void TComPrediction::xPredInterUniVSP( TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi )
+{
+  // Step 1: get depth reference
+  Int depthRefViewIdx = pcCU->getDvInfo(uiPartAddr).m_aVIdxCan;
+  TComPic* pRefPicBaseDepth = pcCU->getSlice()->getIvPic (true, depthRefViewIdx );
+  assert(pRefPicBaseDepth != NULL);
+  TComPicYuv* pcBaseViewDepthPicYuv = pRefPicBaseDepth->getPicYuvRec();
+  assert(pcBaseViewDepthPicYuv != NULL);
+
+  // Step 2: get texture reference
+  Int iRefIdx = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
+  assert(iRefIdx >= 0);
+  TComPic* pRefPicBaseTxt = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx );
+  TComPicYuv* pcBaseViewTxtPicYuv = pRefPicBaseTxt->getPicYuvRec();
+  assert(pcBaseViewTxtPicYuv != NULL);
+
+  // Step 3: initialize the LUT according to the reference viewIdx
+  Int txtRefViewIdx = pRefPicBaseTxt->getViewIndex();
+  Int* pShiftLUT    = pcCU->getSlice()->getDepthToDisparityB( txtRefViewIdx );
+
+  // Step 4: Do compensation
+  TComMv cMv  = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
+  pcCU->clipMv(cMv);
+  Int iBlkX = ( pcCU->getAddr() % pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
+  Int iBlkY = ( pcCU->getAddr() / pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
+  xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getIsDepth(), rpcYuvPred, bi );
+  xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getIsDepth(), rpcYuvPred, bi );
+}
+#endif
 
 #if H_3D_ARP
@@ -674,4 +745,33 @@
   }
 }
+
+#if H_3D_VSP
+
+Void TComPrediction::xPredInterBiVSP( TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvPred )
+{
+  TComYuv* pcMbYuv;
+  Int      iRefIdx[2] = {-1, -1};
+
+  for ( Int iRefList = 0; iRefList < 2; iRefList++ )
+  {
+    RefPicList eRefPicList = RefPicList(iRefList);
+    iRefIdx[iRefList] = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
+
+    if ( iRefIdx[iRefList] < 0 )
+      continue;
+
+    assert( iRefIdx[iRefList] < pcCU->getSlice()->getNumRefIdx(eRefPicList) );
+
+    pcMbYuv = &m_acYuvPred[iRefList];
+    if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
+      xPredInterUniVSP ( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, eRefPicList, pcMbYuv, true );
+    else
+      xPredInterUniVSP ( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, eRefPicList, pcMbYuv );
+  }
+
+  xWeightedAverage( &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
+}
+
+#endif
 
 /**
@@ -1283,3 +1383,485 @@
 }
 #endif
+
+#if H_3D_VSP
+// Input:
+// refPic: Ref picture. Full picture, with padding
+// posX, posY:     PU position, texture
+// sizeX, sizeY: PU size
+// partAddr: z-order index
+// mv: disparity vector. derived from neighboring blocks
+//
+// Output: dstPic, PU predictor 64x64
+Void TComPrediction::xPredInterLumaBlkFromDM( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, TComMv* mv, UInt partAddr,Int posX, Int posY
+                                            , Int sizeX, Int sizeY, Bool isDepth, TComYuv *&dstPic, Bool bi )
+{
+  Int widthLuma;
+  Int heightLuma;
+
+  if (isDepth)
+  {
+    widthLuma   =  pPicBaseDepth->getWidth();
+    heightLuma  =  pPicBaseDepth->getHeight();
+  }
+  else
+  {
+    widthLuma   =  refPic->getWidth();
+    heightLuma  =  refPic->getHeight();
+  }
+
+#if H_3D_VSP_BLOCKSIZE != 1
+  Int widthDepth  = pPicBaseDepth->getWidth();
+  Int heightDepth = pPicBaseDepth->getHeight();
+#endif
+
+#if H_3D_VSP_CONSTRAINED
+  Int widthDepth  = pPicBaseDepth->getWidth();
+  Int heightDepth = pPicBaseDepth->getHeight();
+#endif
+
+  Int nTxtPerDepthX = widthLuma  / ( pPicBaseDepth->getWidth() );  // texture pixel # per depth pixel
+  Int nTxtPerDepthY = heightLuma / ( pPicBaseDepth->getHeight() );
+
+  Int refStride = refPic->getStride();
+  Int dstStride = dstPic->getStride();
+  Int depStride =  pPicBaseDepth->getStride();
+  Int depthPosX = Clip3(0,   widthLuma - sizeX,  (posX/nTxtPerDepthX) + ((mv->getHor()+2)>>2));
+  Int depthPosY = Clip3(0,   heightLuma- sizeY,  (posY/nTxtPerDepthY) + ((mv->getVer()+2)>>2));
+  Pel *ref    = refPic->getLumaAddr() + posX + posY * refStride;
+  Pel *dst    = dstPic->getLumaAddr(partAddr);
+  Pel *depth  = pPicBaseDepth->getLumaAddr() + depthPosX + depthPosY * depStride;
+
+#if H_3D_VSP_BLOCKSIZE != 1
+#if H_3D_VSP_BLOCKSIZE == 2
+  Int  dW = sizeX>>1;
+  Int  dH = sizeY>>1;
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+  Int  dW = sizeX>>2;
+  Int  dH = sizeY>>2;
+#endif
+  {
+    Pel* depthi = depth;
+    for (Int j = 0; j < dH; j++)
+    {
+      for (Int i = 0; i < dW; i++)
+      {
+        Pel* depthTmp;
+#if H_3D_VSP_BLOCKSIZE == 2
+        if (depthPosX + (i<<1) < widthDepth)
+          depthTmp = depthi + (i << 1);
+        else
+          depthTmp = depthi + (widthDepth - depthPosX - 1);
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+        if (depthPosX + (i<<2) < widthDepth)
+          depthTmp = depthi + (i << 2);
+        else
+          depthTmp = depthi + (widthDepth - depthPosX - 1);
+#endif
+        Int maxV = 0;
+        for (Int blockj = 0; blockj < H_3D_VSP_BLOCKSIZE; blockj+=(H_3D_VSP_BLOCKSIZE-1))
+        {
+          Int iX = 0;
+          for (Int blocki = 0; blocki < H_3D_VSP_BLOCKSIZE; blocki+=(H_3D_VSP_BLOCKSIZE-1))
+          {
+            if (maxV < depthTmp[iX])
+              maxV = depthTmp[iX];
+#if H_3D_VSP_BLOCKSIZE == 2
+            if (depthPosX + (i<<1) + blocki < widthDepth - 1)
+#else // H_3D_VSP_BLOCKSIZE == 4
+            if (depthPosX + (i<<2) + blocki < widthDepth - 1)
+#endif
+              iX = (H_3D_VSP_BLOCKSIZE-1);
+          }
+#if H_3D_VSP_BLOCKSIZE == 2
+          if (depthPosY + (j<<1) + blockj < heightDepth - 1)
+#else // H_3D_VSP_BLOCKSIZE == 4
+          if (depthPosY + (j<<2) + blockj < heightDepth - 1)
+#endif
+            depthTmp += depStride * (H_3D_VSP_BLOCKSIZE-1);
+        }
+        m_pDepthBlock[i+j*dW] = maxV;
+      } // end of i < dW
+#if H_3D_VSP_BLOCKSIZE == 2
+      if (depthPosY + ((j+1)<<1) < heightDepth)
+        depthi += (depStride << 1);
+      else
+        depthi  = depth + (heightDepth-depthPosY-1)*depStride;
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+      if (depthPosY + ((j+1)<<2) < heightDepth) // heightDepth-1
+        depthi += (depStride << 2);
+      else
+        depthi  = depth + (heightDepth-depthPosY-1)*depStride; // the last line
+#endif
+    }
+  }
+#endif // H_3D_VSP_BLOCKSIZE != 1
+
+#if H_3D_VSP_BLOCKSIZE == 1
+#if H_3D_VSP_CONSTRAINED
+  //get LUT based horizontal reference range
+  Int range = xGetConstrainedSize(sizeX, sizeY);
+
+  // The minimum depth value
+  Int minRelativePos = MAX_INT;
+  Int maxRelativePos = MIN_INT;
+
+  Pel* depthTemp, *depthInitial=depth;
+  for (Int yTxt =0; yTxt<sizeY; yTxt++)
+  {
+    for (Int xTxt =0; xTxt<sizeX; xTxt++)
+    {
+      if (depthPosX+xTxt < widthDepth)
+        depthTemp = depthInitial + xTxt;
+      else
+        depthTemp = depthInitial + (widthDepth - depthPosX - 1);
+
+      Int disparity = pShiftLUT[ *depthTemp ]; // << iShiftPrec;
+      Int disparityInt = disparity >> 2;
+
+      if( disparity <= 0)
+      {
+        if (minRelativePos > disparityInt+xTxt)
+            minRelativePos = disparityInt+xTxt;
+      }
+      else
+      {
+        if (maxRelativePos < disparityInt+xTxt)
+            maxRelativePos = disparityInt+xTxt;
+      }
+    }
+    if (depthPosY+yTxt < heightDepth)
+      depthInitial = depthInitial + depStride;
+  }
+
+  Int disparity_tmp = pShiftLUT[ *depth ]; // << iShiftPrec;
+  if (disparity_tmp <= 0)
+    maxRelativePos = minRelativePos + range -1 ;
+  else
+    minRelativePos = maxRelativePos - range +1 ;
+#endif
+#endif // H_3D_VSP_BLOCKSIZE == 1
+
+#if H_3D_VSP_BLOCKSIZE != 1
+  Int yDepth = 0;
+#endif
+  for ( Int yTxt = 0; yTxt < sizeY; yTxt += nTxtPerDepthY )
+  {
+    for ( Int xTxt = 0, xDepth = 0; xTxt < sizeX; xTxt += nTxtPerDepthX, xDepth++ )
+    {
+      Pel repDepth = 0; // to store the depth value used for warping
+#if H_3D_VSP_BLOCKSIZE == 1
+      repDepth = depth[xDepth];
+#endif
+#if H_3D_VSP_BLOCKSIZE == 2
+      repDepth = m_pDepthBlock[(xTxt>>1) + (yTxt>>1)*dW];
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+      repDepth = m_pDepthBlock[(xTxt>>2) + (yTxt>>2)*dW];
+#endif
+
+      assert( repDepth >= 0 && repDepth <= 255 );
+      Int disparity = pShiftLUT[ repDepth ]; // remove << iShiftPrec ??
+      Int refOffset = xTxt + (disparity >> 2);
+      Int xFrac = disparity & 0x3;
+#if H_3D_VSP_CONSTRAINED
+      if(refOffset<minRelativePos || refOffset>maxRelativePos)
+        xFrac = 0;
+      refOffset = Clip3(minRelativePos, maxRelativePos, refOffset);
+#endif
+      Int absX  = posX + refOffset;
+
+      if (xFrac == 0)
+        absX = Clip3(0, widthLuma-1, absX);
+      else
+        absX = Clip3(4, widthLuma-5, absX);
+
+      refOffset = absX - posX;
+
+      assert( ref[refOffset] >= 0 && ref[refOffset]<= 255 );
+      m_if.filterHorLuma( &ref[refOffset], refStride, &dst[xTxt], dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, !bi );
+
+    }
+    ref   += refStride*nTxtPerDepthY;
+    dst   += dstStride*nTxtPerDepthY;
+    depth += depStride;
+#if H_3D_VSP_BLOCKSIZE != 1
+    yDepth++;
+#endif
+
+  }
+}
+
+Void TComPrediction::xPredInterChromaBlkFromDM ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, TComMv*mv, UInt partAddr, Int posX, Int posY
+                                               , Int sizeX, Int sizeY, Bool isDepth, TComYuv *&dstPic, Bool bi)
+{
+  Int refStride = refPic->getCStride();
+  Int dstStride = dstPic->getCStride();
+  Int depStride = pPicBaseDepth->getStride();
+
+  Int widthChroma, heightChroma;
+  if( isDepth)
+  {
+     widthChroma   = pPicBaseDepth->getWidth()>>1;
+     heightChroma  = pPicBaseDepth->getHeight()>>1;
+  }
+  else
+  {
+     widthChroma   = refPic->getWidth()>>1;
+     heightChroma  = refPic->getHeight()>>1;
+  }
+
+  // Below is only for Texture chroma component
+
+  Int widthDepth  = pPicBaseDepth->getWidth();
+  Int heightDepth = pPicBaseDepth->getHeight();
+
+  Int nTxtPerDepthX, nTxtPerDepthY;  // Number of texture samples per one depth sample
+  Int nDepthPerTxtX, nDepthPerTxtY;  // Number of depth samples per one texture sample
+
+  Int depthPosX;  // Starting position in depth image
+  Int depthPosY;
+
+  if ( widthChroma > widthDepth )
+  {
+    nTxtPerDepthX = widthChroma / widthDepth;
+    nDepthPerTxtX = 1;
+    depthPosX = posX / nTxtPerDepthX + ((mv->getHor()+2)>>2);
+  }
+  else
+  {
+    nTxtPerDepthX = 1;
+    nDepthPerTxtX = widthDepth / widthChroma;
+    depthPosX = posX * nDepthPerTxtX + ((mv->getHor()+2)>>2);
+  }
+  depthPosX = Clip3(0, widthDepth - (sizeX<<1), depthPosX);
+  if ( heightChroma > heightDepth )
+  {
+    nTxtPerDepthY = heightChroma / heightDepth;
+    nDepthPerTxtY = 1;
+    depthPosY = posY / nTxtPerDepthY + ((mv->getVer()+2)>>2);
+  }
+  else
+  {
+    nTxtPerDepthY = 1;
+    nDepthPerTxtY = heightDepth / heightChroma;
+    depthPosY = posY * nDepthPerTxtY + ((mv->getVer()+2)>>2);
+  }
+  depthPosY = Clip3(0, heightDepth - (sizeY<<1), depthPosY);
+
+  Pel *refCb  = refPic->getCbAddr() + posX + posY * refStride;
+  Pel *refCr  = refPic->getCrAddr() + posX + posY * refStride;
+  Pel *dstCb  = dstPic->getCbAddr(partAddr);
+  Pel *dstCr  = dstPic->getCrAddr(partAddr);
+  Pel *depth  = pPicBaseDepth->getLumaAddr() + depthPosX + depthPosY * depStride;  // move the pointer to the current depth pixel position
+
+  Int refStrideBlock = refStride * nTxtPerDepthY;
+  Int dstStrideBlock = dstStride * nTxtPerDepthY;
+  Int depStrideBlock = depStride * nDepthPerTxtY;
+
+  if ( widthChroma > widthDepth ) // We assume
+  {
+    assert( heightChroma > heightDepth );
+    printf("This branch should never been reached.\n");
+    exit(0);
+  }
+  else
+  {
+#if H_3D_VSP_BLOCKSIZE == 1
+  Int  dW = sizeX;
+  Int  dH = sizeY;
+  Int  sW = 2; // search window size
+  Int  sH = 2;
+#endif
+#if H_3D_VSP_BLOCKSIZE == 2
+  Int  dW = sizeX;
+  Int  dH = sizeY;
+  Int  sW = 2; // search window size
+  Int  sH = 2;
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+  Int  dW = sizeX>>1;
+  Int  dH = sizeY>>1;
+  Int  sW = 4; // search window size
+  Int  sH = 4;
+#endif
+
+  {
+    Pel* depthi = depth;
+    for (Int j = 0; j < dH; j++)
+    {
+      for (Int i = 0; i < dW; i++)
+      {
+        Pel* depthTmp;
+#if H_3D_VSP_BLOCKSIZE == 1
+        depthTmp = depthi + (i << 1);
+#endif
+#if H_3D_VSP_BLOCKSIZE == 2
+        if (depthPosX + (i<<1) < widthDepth)
+          depthTmp = depthi + (i << 1);
+        else
+          depthTmp = depthi + (widthDepth - depthPosX - 1);
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+        if (depthPosX + (i<<2) < widthDepth)
+          depthTmp = depthi + (i << 2);
+        else
+          depthTmp = depthi + (widthDepth - depthPosX - 1);
+#endif
+        Int maxV = 0;
+        for (Int blockj = 0; blockj < sH; blockj+=(sH-1))
+        {
+          Int iX = 0;
+          for (Int blocki = 0; blocki < sW; blocki+=(sW-1))
+          {
+            if (maxV < depthTmp[iX])
+              maxV = depthTmp[iX];
+            if (depthPosX + i*sW + blocki < widthDepth - 1)
+                iX = (sW-1);
+          }
+          if (depthPosY + j*sH + blockj < heightDepth - 1)
+                depthTmp += depStride * (sH-1);
+        }
+        m_pDepthBlock[i+j*dW] = maxV;
+      } // end of i < dW
+#if H_3D_VSP_BLOCKSIZE == 1
+      if (depthPosY + ((j+1)<<1) < heightDepth)
+        depthi += (depStride << 1);
+      else
+        depthi  = depth + (heightDepth-1)*depStride;
+#endif
+#if H_3D_VSP_BLOCKSIZE == 2
+      if (depthPosY + ((j+1)<<1) < heightDepth)
+        depthi += (depStride << 1);
+      else
+        depthi  = depth + (heightDepth-depthPosY-1)*depStride;
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+      if (depthPosY + ((j+1)<<2) < heightDepth) // heightDepth-1
+        depthi += (depStride << 2);
+      else
+        depthi  = depth + (heightDepth-depthPosY-1)*depStride; // the last line
+#endif
+    }
+  }
+
+
+#if H_3D_VSP_BLOCKSIZE == 1
+#if H_3D_VSP_CONSTRAINED
+  //get LUT based horizontal reference range
+  Int range = xGetConstrainedSize(sizeX, sizeY, false);
+
+  // The minimum depth value
+  Int minRelativePos = MAX_INT;
+  Int maxRelativePos = MIN_INT;
+
+  Int depthTmp;
+  for (Int yTxt=0; yTxt<sizeY; yTxt++)
+  {
+    for (Int xTxt=0; xTxt<sizeX; xTxt++)
+    {
+      depthTmp = m_pDepthBlock[xTxt+yTxt*dW];
+      Int disparity = pShiftLUT[ depthTmp ]; // << iShiftPrec;
+      Int disparityInt = disparity >> 3;//in chroma resolution
+
+      if (disparityInt < 0)
+      {
+        if (minRelativePos > disparityInt+xTxt)
+            minRelativePos = disparityInt+xTxt;
+      }
+      else
+      {
+        if (maxRelativePos < disparityInt+xTxt)
+            maxRelativePos = disparityInt+xTxt;
+      }
+    }
+  }
+
+  depthTmp = m_pDepthBlock[0];
+  Int disparity_tmp = pShiftLUT[ depthTmp ]; // << iShiftPrec;
+  if ( disparity_tmp < 0 )
+    maxRelativePos = minRelativePos + range - 1;
+  else
+    minRelativePos = maxRelativePos - range + 1;
+
+#endif // H_3D_VSP_CONSTRAINED
+#endif // H_3D_VSP_BLOCKSIZE == 1
+
+    // (sizeX, sizeY) is Chroma block size
+    for ( Int yTxt = 0, yDepth = 0; yTxt < sizeY; yTxt += nTxtPerDepthY, yDepth += nDepthPerTxtY )
+    {
+      for ( Int xTxt = 0, xDepth = 0; xTxt < sizeX; xTxt += nTxtPerDepthX, xDepth += nDepthPerTxtX )
+      {
+        Pel repDepth = 0; // to store the depth value used for warping
+#if H_3D_VSP_BLOCKSIZE == 1
+        repDepth = m_pDepthBlock[(xTxt) + (yTxt)*dW];
+#endif
+#if H_3D_VSP_BLOCKSIZE == 2
+        repDepth = m_pDepthBlock[(xTxt) + (yTxt)*dW];
+#endif
+#if H_3D_VSP_BLOCKSIZE == 4
+        repDepth = m_pDepthBlock[(xTxt>>1) + (yTxt>>1)*dW];
+#endif
+
+      // calculate the offset in the reference picture
+        Int disparity = pShiftLUT[ repDepth ]; // Remove << iShiftPrec;
+        Int refOffset = xTxt + (disparity >> 3); // in integer pixel in chroma image
+        Int xFrac = disparity & 0x7;
+#if H_3D_VSP_CONSTRAINED
+        if(refOffset < minRelativePos || refOffset > maxRelativePos)
+          xFrac = 0;
+        refOffset = Clip3(minRelativePos, maxRelativePos, refOffset);
+#endif
+        Int absX  = posX + refOffset;
+
+        if (xFrac == 0)
+          absX = Clip3(0, widthChroma-1, absX);
+        else
+          absX = Clip3(4, widthChroma-5, absX);
+
+        refOffset = absX - posX;
+
+        assert( refCb[refOffset] >= 0 && refCb[refOffset]<= 255 );
+        assert( refCr[refOffset] >= 0 && refCr[refOffset]<= 255 );
+        m_if.filterHorChroma(&refCb[refOffset], refStride, &dstCb[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, !bi);
+        m_if.filterHorChroma(&refCr[refOffset], refStride, &dstCr[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, !bi);
+      }
+      refCb += refStrideBlock;
+      refCr += refStrideBlock;
+      dstCb += dstStrideBlock;
+      dstCr += dstStrideBlock;
+      depth += depStrideBlock;
+    }
+  }
+
+}
+
+#if H_3D_VSP_CONSTRAINED
+
+Int TComPrediction::xGetConstrainedSize(Int nPbW, Int nPbH, Bool bLuma)
+{
+  Int iSize = 0;
+  if (bLuma)
+  {
+    Int iArea = (nPbW+7) * (nPbH+7);
+    Int iAlpha = iArea / nPbH - nPbW - 7;
+    iSize = iAlpha + nPbW;
+  }
+  else // chroma
+  {
+    Int iArea = (nPbW+2) * (nPbH+2);
+    Int iAlpha = iArea / nPbH - nPbW - 4;
+    iSize = iAlpha + nPbW;
+  }
+  return iSize;
+}
+
+#endif
+
+
+#endif
+
+
 //! \}
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComPrediction.h
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComPrediction.h	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComPrediction.h	(revision 510)
@@ -78,4 +78,12 @@
   UInt   m_uiaShift[ 63 ];       // Table for multiplication to substitue of division operation
 #endif
+
+#if H_3D_VSP
+  Int*   m_pDepthBlock; ///< Local variable, to store a depth block, just to prevent allocate memory every time
+#if H_3D_VSP_CONSTRAINED
+  Int  xGetConstrainedSize(Int nPbW, Int nPbH, Bool bLuma = true);
+#endif
+#endif
+
   Void xPredIntraAng            (Int bitDepth, Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, UInt width, UInt height, UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable, Bool bFilter );
   Void xPredIntraPlanar         ( Int* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height );
@@ -83,9 +91,14 @@
   // motion compensation functions
 #if H_3D_ARP
-  Void xPredInterUniARP         ( TComDataCU* pcCU,                          UInt uiPartAddr,               Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi=false, TComMvField * pNewMvFiled = NULL );
+  Void xPredInterUniARP         ( TComDataCU* pcCU,                          UInt uiPartAddr,                    Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi=false, TComMvField * pNewMvFiled = NULL );
 #endif
-  Void xPredInterUni            ( TComDataCU* pcCU,                          UInt uiPartAddr,               Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi=false          );
-  Void xPredInterBi             ( TComDataCU* pcCU,                          UInt uiPartAddr,               Int iWidth, Int iHeight,                         TComYuv*& rpcYuvPred );
-  Void xPredInterLumaBlk  ( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi 
+  Void xPredInterUni            ( TComDataCU* pcCU,                          UInt uiPartAddr,                    Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi=false          );
+  Void xPredInterBi             ( TComDataCU* pcCU,                          UInt uiPartAddr,                    Int iWidth, Int iHeight,                         TComYuv*& rpcYuvPred );
+#if H_3D_VSP
+  Void xPredInterUniVSP         ( TComDataCU* pcCU,                          UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi=false          );
+  Void xPredInterBiVSP          ( TComDataCU* pcCU,                          UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight,                         TComYuv*& rpcYuvPred );
+#endif
+
+  Void xPredInterLumaBlk  ( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
 #if H_3D_ARP
     , Bool filterType = false
@@ -95,5 +108,6 @@
 #endif
     );
-  Void xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi 
+  Void xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
+
 #if H_3D_ARP
     , Bool filterType = false
@@ -103,4 +117,14 @@
 #endif
     );
+
+#if H_3D_VSP
+  Void xPredInterLumaBlkFromDM  ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, TComMv* mv, UInt partAddr,Int posX, Int posY, Int sizeX, Int sizeY, Bool isDepth
+                                , TComYuv *&dstPic
+                                , Bool bi );
+  Void xPredInterChromaBlkFromDM( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, TComMv*mv, UInt partAddr, Int posX, Int posY, Int sizeX, Int sizeY, Bool isDepth
+                                , TComYuv *&dstPic
+                                , Bool bi );
+#endif
+
   Void xWeightedAverage         ( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst );
   
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComSlice.h	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComSlice.h	(revision 510)
@@ -532,5 +532,5 @@
 #endif
 #if H_3D_VSP
-  Bool        m_viewSynthesisPredFlag    [ MAX_NUM_LAYERS ]; 
+  Bool        m_viewSynthesisPredFlag    [ MAX_NUM_LAYERS ];
 #endif
 #if H_3D_NBDV_REF
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TypeDef.h	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TypeDef.h	(revision 510)
@@ -96,6 +96,25 @@
                                               // MTK_D0156
                                               // MERL_VSP_NBDV_RefVId_Fix_D0166
-#endif
-#define H_3D_VSP                          0   // Depth oriented neighboring block disparity derivation
+                                              // MERL_C0152
+#endif
+#define H_3D_VSP                          1   // View syntheis prediction, C0152, D0166, D0092, 
+                                              // MTK_D0105, LG_D0139: No VSP for depth
+                                              // MTK_D0156,
+                                              // MERL_C0152: Basic VSP
+                                              // QC_D0191: Clean up
+                                              // LG_D0092: Multiple VSP candidate allowed
+                                              // MTK_D0105: No VSP for depth. Single depth fetching for DoNBDV and VSP
+                                              //
+                                              //
+
+#if H_3D_VSP
+#define H_3D_VSP_POSITION                 3   // The only supported position
+#define H_3D_VSP_BLOCKSIZE                1   // Supported values: 1, 2, and 4
+#if H_3D_VSP_BLOCKSIZE == 1
+#define H_3D_VSP_CONSTRAINED              1   // Constrained VSP @ 1x1
+#else
+#define H_3D_VSP_CONSTRAINED              0
+#endif
+#endif
 
 #define H_3D_IV_MERGE                     1   // Inter-view motion merge candidate
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibDecoder/TDecCu.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibDecoder/TDecCu.cpp	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibDecoder/TDecCu.cpp	(revision 510)
@@ -347,5 +347,15 @@
     m_pcEntropyDecoder->decodeMergeIndex( pcCU, 0, uiAbsPartIdx, uiDepth );
     UInt uiMergeIndex = pcCU->getMergeIndex(uiAbsPartIdx);
+
+#if H_3D_VSP
+    Int vspFlag[MRG_MAX_NUM_CANDS_MEM];
+    memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM);
+
+    m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, vspFlag, numValidMergeCand, uiMergeIndex );
+    pcCU->setVSPFlagSubParts( vspFlag[uiMergeIndex], uiAbsPartIdx, 0, uiDepth );
+#else
     m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex );
+#endif
+
     pcCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeIndex], uiAbsPartIdx, 0, uiDepth );
 
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibDecoder/TDecEntropy.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 510)
@@ -225,5 +225,12 @@
         if ( !isMerged )
         {
+#if H_3D_VSP
+          Int vspFlag[MRG_MAX_NUM_CANDS_MEM];
+          memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM);
+          pcSubCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, vspFlag, numValidMergeCand );
+          pcCU->setVSPFlagSubParts( vspFlag[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth );
+#else
           pcSubCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
+#endif
           isMerged = true;
         }
@@ -232,6 +239,13 @@
       else
       {
-        uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx);
+        uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); // Redundant line
+#if H_3D_VSP
+        Int vspFlag[MRG_MAX_NUM_CANDS_MEM];
+        memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM);
+        pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours, uhInterDirNeighbours, vspFlag, numValidMergeCand, uiMergeIndex );
+        pcCU->setVSPFlagSubParts( vspFlag[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth );
+#else
         pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex );
+#endif
       }
       pcCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth );
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncCu.cpp	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncCu.cpp	(revision 510)
@@ -1354,5 +1354,12 @@
   rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
   rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );
+
+#if H_3D_VSP
+  Int vspFlag[MRG_MAX_NUM_CANDS_MEM];
+  memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM);
+  rpcTempCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, vspFlag, numValidMergeCand );
+#else
   rpcTempCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
+#endif
 
 #if H_3D_IV_MERGE
@@ -1419,4 +1426,7 @@
           rpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth ); // interprets depth relative to LCU level
           rpcTempCU->setMergeIndexSubParts( uiMergeCand, 0, 0, uhDepth ); // interprets depth relative to LCU level
+#if H_3D_VSP
+          rpcTempCU->setVSPFlagSubParts( vspFlag[uiMergeCand], 0, 0, uhDepth );
+#endif
           rpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth ); // interprets depth relative to LCU level
           rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 510)
@@ -821,4 +821,12 @@
     }
 
+    // A bug fix provided by Gerhard to deal with IBP configuration. NEED futher study
+#if H_MV
+    if( pcSlice->getIdrPicFlag() )
+    {
+      pcSlice->setEnableTMVPFlag(0);
+    }
+#endif
+
 #if H_3D_VSO
   // Should be moved to TEncTop !!! 
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 510)
@@ -3171,5 +3171,10 @@
  * \returns Void
  */
-Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost, TComMvField* cMvFieldNeighbours, UChar* uhInterDirNeighbours, Int& numValidMergeCand )
+Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost, TComMvField* cMvFieldNeighbours, UChar* uhInterDirNeighbours
+#if H_3D_VSP
+                                 , Int* vspFlag
+#endif
+                                 , Int& numValidMergeCand
+                                 )
 {
   UInt uiAbsPartIdx = 0;
@@ -3185,5 +3190,10 @@
     if ( iPUIdx == 0 )
     {
-      pcCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
+      pcCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours
+#if H_3D_VSP
+                                   , vspFlag
+#endif
+                                   , numValidMergeCand
+                                   );
     }
     pcCU->setPartSizeSubParts( partSize, 0, uiDepth );
@@ -3191,5 +3201,10 @@
   else
   {
-    pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
+    pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours
+#if H_3D_VSP
+                                 , vspFlag
+#endif
+                                 , numValidMergeCand
+                                 );
   }
   xRestrictBipredMergeCand( pcCU, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
@@ -3206,4 +3221,8 @@
       pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
       pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
+
+#if H_3D_VSP
+      pcCU->setVSPFlagSubParts( vspFlag[uiMergeCand], uiAbsPartIdx, iPUIdx, pcCU->getDepth( uiAbsPartIdx ) );
+#endif
 
       xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
@@ -3362,4 +3381,8 @@
     
     pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
+
+#if H_3D_VSP
+    pcCU->setVSPFlagSubParts( 0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr) );
+#endif
     
 #if AMP_MRG
@@ -3965,5 +3988,15 @@
       // find Merge result
       UInt uiMRGCost = MAX_UINT;
-      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand);
+#if H_3D_VSP
+      Int vspFlag[MRG_MAX_NUM_CANDS_MEM];
+      memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM);
+#endif
+
+      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours
+#if H_3D_VSP
+                      , vspFlag
+#endif
+                      , numValidMergeCand
+                      );
       if ( uiMRGCost < uiMECost )
       {
@@ -3971,4 +4004,7 @@
         pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
         pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+#if H_3D_VSP
+        pcCU->setVSPFlagSubParts( vspFlag[uiMRGIndex], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+#endif
         pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
         {
@@ -3990,4 +4026,7 @@
         pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
         pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+#if H_3D_VSP
+        pcCU->setVSPFlagSubParts ( 0,             uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+#endif
         {
           pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
Index: branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSearch.h
===================================================================
--- branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSearch.h	(revision 508)
+++ branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSearch.h	(revision 510)
@@ -380,6 +380,9 @@
                                     UInt&           ruiCost
                                   , TComMvField* cMvFieldNeighbours,  
-                                    UChar* uhInterDirNeighbours,
-                                    Int& numValidMergeCand
+                                    UChar* uhInterDirNeighbours
+#if H_3D_VSP
+                                  , Int* vspFlag
+#endif
+                                  , Int& numValidMergeCand
                                    );
 
