Index: branches/HTM-6.2-dev2-MERL/source/App/TAppDecoder/TAppDecTop.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/App/TAppDecoder/TAppDecTop.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/App/TAppDecoder/TAppDecTop.cpp	(revision 412)
@@ -735,5 +735,10 @@
 
 #if MERL_VSP_C0152
-Void TAppDecTop::setBWVSPLUT(TComSlice* pcSlice,  Int iCodedViewIdx,  Int iCurPoc)
+Void TAppDecTop::setBWVSPLUT(
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    Int iNeighborViewId,
+#endif
+    TComSlice* pcSlice,  Int iCodedViewIdx,  Int iCurPoc)
+
 {
   //first view does not have VSP 
@@ -742,8 +747,14 @@
   AOT( iCodedViewIdx <= 0);
   //AOT( iCodedViewIdx >= m_iNumberOfViews );
+#if !MERL_VSP_NBDV_RefVId_Fix_D0166
   Int iNeighborViewId = 0;
+#endif
   //  Int* piShiftLUT = bRenderFromLeft ? m_cCamParsCollector.getBaseViewShiftLUTI()[iCodedViewIdx][iNeighborViewId][0] : m_cCamParsCollector.getBaseViewShiftLUTI()[iNeighborViewId][iCodedViewIdx][0];
   Int* piShiftLUT = m_cCamParsCollector.getBaseViewShiftLUTI()[iNeighborViewId][iCodedViewIdx][0];
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  pcSlice->setBWVSPLUTParam(piShiftLUT, 2-LOG2_DISP_PREC_LUT, iNeighborViewId );
+#else
   pcSlice->setBWVSPLUTParam(piShiftLUT, 2-LOG2_DISP_PREC_LUT );
+#endif
 }
 #endif
Index: branches/HTM-6.2-dev2-MERL/source/App/TAppDecoder/TAppDecTop.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/App/TAppDecoder/TAppDecTop.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/App/TAppDecoder/TAppDecTop.h	(revision 412)
@@ -113,5 +113,9 @@
 
 #if MERL_VSP_C0152
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Void  setBWVSPLUT( Int iNeighborViewId, TComSlice* pcSlice, Int iCodedViewIdx, Int iCurPoc );
+#else
   Void  setBWVSPLUT( TComSlice* pcSlice, Int iCodedViewIdx, Int iCurPoc   );
+#endif
 #endif
 
Index: branches/HTM-6.2-dev2-MERL/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/App/TAppEncoder/TAppEncTop.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/App/TAppEncoder/TAppEncTop.cpp	(revision 412)
@@ -1097,6 +1097,17 @@
           pEncSlice->setRefPicBaseTxt(pcBaseTxtPic);
           pEncSlice->setRefPicBaseDepth(pcBaseDepthPic);
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+          for (Int refViewId=0; refViewId < iViewIdx; refViewId++ )
+          {
+            pEncSlice->setListDepthPic(m_acTEncDepthTopList[refViewId]->getListPic(), refViewId ); // The list will store only the depth pictures
+            setBWVSPLUT(refViewId, iViewIdx, gopId, false);
+          } 
+#endif
         }
+#if !MERL_VSP_NBDV_RefVId_Fix_D0166
         setBWVSPLUT( iViewIdx, gopId, false);
+#endif
+#endif
+
 #if MERL_VSP_C0152_BugFix_ForNoDepthCase
         }
@@ -1113,5 +1124,4 @@
 #endif
 
-#endif
         // call encoding function for one frame
         m_acTEncTopList[iViewIdx]->encode( eos[iViewIdx], pcPicYuvOrg, *m_picYuvRec[iViewIdx], outputAccessUnits, iNumEncoded, gopId );
@@ -1128,6 +1138,15 @@
           TEncSlice* pcSlice = (TEncSlice*) m_acTEncDepthTopList[iViewIdx]->getSliceEncoder();
           pcSlice->setRefPicBaseDepth(pcBaseDepthPic);
+#if  MERL_VSP_NBDV_RefVId_Fix_D0166
+          for (Int refViewId=0; refViewId < iViewIdx; refViewId++ )
+          {
+            pcSlice->setListDepthPic(m_acTEncDepthTopList[refViewId]->getListPic(), refViewId ); // The list will store only the depth pictures
+            setBWVSPLUT( refViewId, iViewIdx, gopId, true);
+          } 
+#endif
         }
+#if !MERL_VSP_NBDV_RefVId_Fix_D0166
         setBWVSPLUT( iViewIdx, gopId, true);
+#endif
 #endif
 
@@ -1646,5 +1665,10 @@
 
 #if MERL_VSP_C0152
-Void TAppEncTop::setBWVSPLUT(Int iCodedViewIdx, Int gopId, Bool isDepth)
+
+Void TAppEncTop::setBWVSPLUT(
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        Int iNeighborViewId,
+#endif
+        Int iCodedViewIdx, Int gopId, Bool isDepth)
 {
   //first view does not have VSP 
@@ -1653,6 +1677,7 @@
   AOT( iCodedViewIdx <= 0);
   AOT( iCodedViewIdx >= m_iNumberOfViews );
-
+#if !MERL_VSP_NBDV_RefVId_Fix_D0166
   Int iNeighborViewId = 0;
+#endif
   //setting look-up table
   Int* piShiftLUT = m_cCameraData.getBaseViewShiftLUTI()[iNeighborViewId][iCodedViewIdx][0];
@@ -1661,10 +1686,18 @@
   {
     TEncSlice* pcEncSlice = (TEncSlice*) m_acTEncDepthTopList[iCodedViewIdx]->getSliceEncoder();
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    pcEncSlice->setBWVSPLUTParam(  piShiftLUT, LOG2_DISP_PREC_LUT, iNeighborViewId );
+#else
     pcEncSlice->setBWVSPLUTParam(  piShiftLUT, LOG2_DISP_PREC_LUT );
+#endif
   }
   else
   {
     TEncSlice* pcEncSlice = (TEncSlice*) m_acTEncTopList[iCodedViewIdx]->getSliceEncoder();
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    pcEncSlice->setBWVSPLUTParam(  piShiftLUT, LOG2_DISP_PREC_LUT, iNeighborViewId );
+#else
     pcEncSlice->setBWVSPLUTParam(  piShiftLUT, LOG2_DISP_PREC_LUT );
+#endif
   }
 
Index: branches/HTM-6.2-dev2-MERL/source/App/TAppEncoder/TAppEncTop.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/App/TAppEncoder/TAppEncTop.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/App/TAppEncoder/TAppEncTop.h	(revision 412)
@@ -167,5 +167,9 @@
 
 #if MERL_VSP_C0152
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Void setBWVSPLUT( Int refViewIdx, Int iCodedViewIdx, Int gopId, Bool isDepth);
+#else
   Void setBWVSPLUT( Int iCodedViewIdx, Int gopId, Bool isDepth);
+#endif
 #endif
 };// END CLASS DEFINITION TAppEncTop
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComDataCU.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComDataCU.cpp	(revision 412)
@@ -55,5 +55,9 @@
 #define CHECK_ADD_YET(pcCURef,uiIdx,vspIdx) && !( (pcCURef)->getVSPIndex(uiIdx) == vspIdx && bVspMvZeroDone[vspIdx-1] )
 
-inline Void TComDataCU::xInheritVspMode( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo )
+inline Void TComDataCU::xInheritVspMode( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    , Int*     iVSPDirTrue
+#endif
+    )
 {
   Int vspIdx = (Int) pcCURef->getVSPIndex(uiIdx);
@@ -69,4 +73,39 @@
     if (vspIdx < 4)
     {
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      if(pDInfo->iN > 0 )
+      { // using derived disparity and store corresponding used reference list and ref idx
+        iVSPDirTrue[idx] = pDInfo->m_aListIdx[0];
+        assert(pDInfo->m_aRefIdx[0] < 0);
+#if MTK_VSP_USING_NBDV_D0105
+        pcMvFieldNeighbours[iCount<<1].setMvField( pDInfo->m_acMvCandNoRef[0], pDInfo->m_aRefIdx[0] );
+#else
+        pcMvFieldNeighbours[iCount<<1].setMvField( pDInfo->m_acMvCand[0], pDInfo->m_aRefIdx[0] );
+#endif
+        if ( pcCURef->getSlice()->isInterB() )
+        {
+#if MTK_VSP_USING_NBDV_D0105
+          pcMvFieldNeighbours[(iCount<<1)+1].setMvField( pDInfo->m_acMvCandNoRef[0], pDInfo->m_aRefIdx[0] );
+#else
+          pcMvFieldNeighbours[(iCount<<1)+1].setMvField( pDInfo->m_acMvCand[0], pDInfo->m_aRefIdx[0] );
+#endif
+        }
+      }
+      else
+      { // using the original neighboring block vsp reference list
+        TComMv cMvPred = pcCURef->getCUMvField(REF_PIC_LIST_0)->getMv(uiIdx);
+        Int    refId   = pcCURef->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiIdx);
+
+        assert(refId < 0);
+        iVSPDirTrue[idx] = pcCURef->getVSPDir(uiIdx);
+        pcMvFieldNeighbours[iCount<<1].setMvField( cMvPred, refId );
+        if ( pcCURef->getSlice()->isInterB() )
+        {
+          pcMvFieldNeighbours[(iCount<<1)+1].setMvField( cMvPred, refId );
+        }
+      }
+
+#else // !MERL_VSP_NBDV_RefVId_Fix_D0166
+
 #if MTK_VSP_USING_NBDV_D0105
       pcMvFieldNeighbours[ iCount<<1].setMvField ( pDInfo->m_acMvCandNoRef[0],  NOT_VALID );
@@ -82,4 +121,5 @@
 #endif
       }
+#endif
     }
   }
@@ -87,5 +127,9 @@
 
 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 )
+                                          UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                                        , Int*  iVspDirTrue
+#endif
+                                          )
 {
 #if MTK_LGE_VSP_DEPTH_OFF_D0105_D0139
@@ -99,5 +143,5 @@
   TComPic* pRefPicBaseDepth = NULL;
   pRefPicBaseDepth = getSlice()->getRefPicBaseDepth();
-  if(ucVspMergePos == VSP_MERGE_POS && pRefPicBaseDepth) //VSP can be used only when depth is used as input
+  if(ucVspMergePos == VSP_MERGE_POS && pRefPicBaseDepth) // VSP can be used only when depth is used as input
 #else
   if( ucVspMergePos == VSP_MERGE_POS )
@@ -120,4 +164,24 @@
           if (vspIdx < 4) // spatial
           {
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+            assert(pDInfo->m_aRefIdx[0] < 0);
+            iVspDirTrue[idx] = pDInfo->m_aListIdx[0];
+
+#if MTK_VSP_USING_NBDV_D0105
+            pcMvFieldNeighbours[iCount<<1].setMvField(pDInfo->m_acMvCandNoRef[0], pDInfo->m_aRefIdx[0] );
+#else
+            pcMvFieldNeighbours[iCount<<1].setMvField(pDInfo->m_acMvCand[0], pDInfo->m_aRefIdx[0] );
+#endif
+            if ( getSlice()->isInterB() )
+            {
+#if MTK_VSP_USING_NBDV_D0105
+              pcMvFieldNeighbours[(iCount<<1)+1].setMvField( pDInfo->m_acMvCandNoRef[0], pDInfo->m_aRefIdx[0] );
+#else
+              pcMvFieldNeighbours[(iCount<<1)+1].setMvField( pDInfo->m_acMvCand[0], pDInfo->m_aRefIdx[0] );
+#endif
+            }
+
+#else
+
 #if MTK_VSP_USING_NBDV_D0105
             pcMvFieldNeighbours[iCount<<1].setMvField(pDInfo->m_acMvCandNoRef[0], NOT_VALID );
@@ -133,4 +197,5 @@
 #endif
             }
+#endif
           }
           iVSPIndexTrue[idx] = iCount;
@@ -178,4 +243,7 @@
 #if MERL_VSP_C0152
   m_piVSPIndex         = NULL;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  m_piVSPDir           = NULL;
+#endif
 #endif
   m_puhLumaIntraDir    = NULL;
@@ -323,4 +391,7 @@
 #if MERL_VSP_C0152
     m_piVSPIndex         = (Char*  )xMalloc(Char,   uiNumPartition);
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    m_piVSPDir           = (Char*  )xMalloc(Char,   uiNumPartition);
+#endif
 #endif
 #if H3D_IVRP
@@ -483,4 +554,7 @@
 #if MERL_VSP_C0152
     if ( m_piVSPIndex         ) { xFree(m_piVSPIndex);          m_piVSPIndex        = NULL; }
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    if ( m_piVSPDir           ) { xFree(m_piVSPDir  );          m_piVSPDir          = NULL; }
+#endif
 #endif
     if ( m_puhMergeIndex      ) { xFree(m_puhMergeIndex);       m_puhMergeIndex     = NULL; }
@@ -688,4 +762,7 @@
 #if MERL_VSP_C0152
     m_piVSPIndex[ui] = pcFrom->m_piVSPIndex[ui];
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    m_piVSPDir  [ui] = pcFrom->m_piVSPDir  [ui];
+#endif
 #endif
     m_puhLumaIntraDir[ui]=pcFrom->m_puhLumaIntraDir[ui];
@@ -731,4 +808,7 @@
 #if MERL_VSP_C0152
     memset( m_piVSPIndex        + firstElement, 0,                        numElements * sizeof( *m_piVSPIndex ) );
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    memset( m_piVSPDir          + firstElement, 0,                        numElements * sizeof( *m_piVSPDir   ) );
+#endif
 #endif
     memset( m_puhLumaIntraDir   + firstElement, 2,                        numElements * sizeof( *m_puhLumaIntraDir ) );
@@ -908,4 +988,7 @@
 #if MERL_VSP_C0152
       m_piVSPIndex[ui] = 0;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      m_piVSPDir  [ui] = 0;
+#endif
 #endif
 #if H3D_IVRP
@@ -1022,4 +1105,7 @@
 #if MERL_VSP_C0152
   memset( m_piVSPIndex,         0, iSizeInChar );
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  memset( m_piVSPDir  ,         0, iSizeInChar );
+#endif
 #endif
 #if H3D_IVRP
@@ -1113,4 +1199,7 @@
 #if MERL_VSP_C0152
       m_piVSPIndex[ui]=pcCU->m_piVSPIndex[uiPartOffset+ui];
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      m_piVSPDir  [ui]=pcCU->m_piVSPDir  [uiPartOffset+ui];
+#endif
 #endif
       m_puhLumaIntraDir[ui]=pcCU->m_puhLumaIntraDir[uiPartOffset+ui];
@@ -1266,4 +1355,7 @@
 #if MERL_VSP_C0152
   m_piVSPIndex          = pcCU->getVSPIndex()         + uiPart;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  m_piVSPDir            = pcCU->getVSPDir  ()         + uiPart;
+#endif
 #endif
 #if H3D_IVRP
@@ -1437,4 +1529,7 @@
 #if MERL_VSP_C0152
   m_piVSPIndex         = pcCU->getVSPIndex()              + uiAbsPartIdx;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  m_piVSPDir           = pcCU->getVSPDir  ()              + uiAbsPartIdx;
+#endif
 #endif
 #if H3D_IVRP
@@ -1499,4 +1594,7 @@
 #if MERL_VSP_C0152
   memcpy( m_piVSPIndex          + uiOffset, pcCU->getVSPIndex(),          iSizeInChar );
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  memcpy( m_piVSPDir            + uiOffset, pcCU->getVSPDir  (),          iSizeInChar );
+#endif
 #endif
 #if H3D_IVRP
@@ -1648,4 +1746,7 @@
 #if MERL_VSP_C0152
   memcpy( rpcCU->getVSPIndex()          + m_uiAbsIdxInLCU, m_piVSPIndex,         iSizeInChar );
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  memcpy( rpcCU->getVSPDir  ()           + m_uiAbsIdxInLCU, m_piVSPDir  ,         iSizeInChar );
+#endif
 #endif
 #if H3D_IVRP
@@ -1781,5 +1882,8 @@
   memcpy( rpcCU->getMergeIndex()        + uiPartOffset, m_puhMergeIndex,       iSizeInUchar );
 #if MERL_VSP_C0152
-  memcpy( rpcCU->getVSPIndex()          + uiPartOffset, m_piVSPIndex,         iSizeInChar );
+  memcpy( rpcCU->getVSPIndex()          + uiPartOffset, m_piVSPIndex,          iSizeInChar );
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  memcpy( rpcCU->getVSPDir  ()           + uiPartOffset, m_piVSPDir  ,         iSizeInChar );
+#endif
 #endif
 #if H3D_IVRP
@@ -3079,5 +3183,13 @@
   setSubPart<Char>( iVSPIdx, m_piVSPIndex, uiAbsPartIdx, uiDepth, uiPartIdx );
 }
-#endif
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+Void TComDataCU::setVSPDirSubParts ( Char iVSPDir, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
+{
+  setSubPart<Char>( iVSPDir, m_piVSPDir, uiAbsPartIdx, uiDepth, uiPartIdx );
+}
+#endif
+
+#endif // MERL_VSP_C0152
 
 #if H3D_IVRP
@@ -3661,5 +3773,9 @@
  */
 #if MERL_VSP_C0152
-Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int* iVSPIndexTrue, Int mrgCandIdx )
+Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int* iVSPIndexTrue
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        , Int* iVSPDirTrue
+#endif
+        , Int mrgCandIdx )
 #else
 Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx )
@@ -3724,4 +3840,9 @@
 #if H3D_NBDV
   DisInfo cDisInfo;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  cDisInfo.bDV = false; // default setting
+  cDisInfo.iN  = 0;
+#endif
+
 #if !QC_CU_NBDV_D0181
   cDisInfo.iN = 0;
@@ -3741,4 +3862,10 @@
       cDisInfo.m_acMvCandNoRef[0] = getDvInfo(uiAbsPartIdx).m_acMvCandNoRef[0];
 #endif
+#if MERL_VSP_C0152
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      cDisInfo.m_aListIdx[0] = getDvInfo(uiAbsPartIdx).m_aListIdx[0];
+      cDisInfo.m_aRefIdx[0] = getDvInfo(uiAbsPartIdx).m_aRefIdx[0];
+#endif
+#endif
     }
 #else
@@ -3750,4 +3877,5 @@
 #endif
   }
+  
 #if FCO_DVP_REFINE_C0132_C0170
   if(getPic()->getDepthCoded() )
@@ -3782,4 +3910,22 @@
 #endif
   }
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166 && !MTK_LGE_VSP_DEPTH_OFF_D0105_D0139
+  if (bNoPdmMerge && cDisInfo.bDV == false) 
+  { // purely for default setting
+    cDisInfo.iN = 1;
+    cDisInfo.m_acMvCand[0].setHor(0);
+    cDisInfo.m_acMvCand[0].setVer(0);
+    cDisInfo.m_acMvCandNoRef[0].setHor(0);
+    cDisInfo.m_acMvCandNoRef[0].setVer(0);
+    cDisInfo.m_aVIdxCan[0] = 0;
+
+    RefPicList eRefPicList = REF_PIC_LIST_0 ;
+    Int refFrmIdx = 0;
+    getRefListAndRefFrmIdx(0, eRefPicList, refFrmIdx);
+    cDisInfo.m_aListIdx[0] = eRefPicList;
+    cDisInfo.m_aRefIdx [0] = -1-refFrmIdx;
+   }
+#endif
 
 #if MTK_DEPTH_MERGE_TEXTURE_CANDIDATE_C0137
@@ -3850,5 +3996,9 @@
 #if MERL_VSP_C0152
 #if !MTK_LGE_VSP_DEPTH_OFF_D0105_D0139
-      xInheritVspMode( pcTextureCU, uiPartIdxCenter, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo ) ;
+      xInheritVspMode( pcTextureCU, uiPartIdxCenter, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+         , iVSPDirTrue
+#endif
+        ) ;
 #endif
 #endif
@@ -3923,10 +4073,15 @@
   }  
   
-#endif //  H3D_IVMP 
+#endif //  H3D_IVMP
 
 #if MERL_VSP_COMPENSATION_C0152
   //===== vsp 0 ===== 
   if( iCount < 4 + extraMergeCand )
-    if ( !xAddVspMergeCand(0, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) )
+    if ( !xAddVspMergeCand(0, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+            , iVSPDirTrue
+#endif
+            )
+       )
       return;
 #endif
@@ -3996,5 +4151,9 @@
 #endif
 #if MERL_VSP_C0152
-        xInheritVspMode( pcCULeft, uiLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo ) ;
+        xInheritVspMode( pcCULeft, uiLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+         , iVSPDirTrue
+#endif
+                );
 #endif
         if ( mrgCandIdx == iCount )
@@ -4069,5 +4228,9 @@
 #endif
 #if MERL_VSP_C0152
-     xInheritVspMode( pcCUAbove, uiAbovePartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo ) ;
+     xInheritVspMode( pcCUAbove, uiAbovePartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+       , iVSPDirTrue
+#endif
+             ) ;
 #endif
     if ( mrgCandIdx == iCount )
@@ -4118,5 +4281,9 @@
 #endif
 #if MERL_VSP_C0152
-    xInheritVspMode( pcCUAboveRight, uiAboveRightPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo ) ;
+    xInheritVspMode( pcCUAboveRight, uiAboveRightPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+       , iVSPDirTrue
+#endif
+            ) ;
 #endif
     if ( mrgCandIdx == iCount )
@@ -4176,5 +4343,4 @@
 #endif // H3D_IVMP 
 
-
   //left bottom
   UInt uiLeftBottomPartIdx = 0;
@@ -4214,5 +4380,9 @@
 #endif
 #if MERL_VSP_C0152
-     xInheritVspMode( pcCULeftBottom, uiLeftBottomPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo ) ;
+     xInheritVspMode( pcCULeftBottom, uiLeftBottomPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+       , iVSPDirTrue
+#endif
+             ) ;
 #endif
     if ( mrgCandIdx == iCount )
@@ -4222,6 +4392,5 @@
     iCount ++;
   }
- 
-  
+
   // above left
 #if H3D_IVMP
@@ -4269,5 +4438,9 @@
 #endif
 #if MERL_VSP_C0152
-     xInheritVspMode( pcCUAboveLeft, uiAboveLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo ) ;
+     xInheritVspMode( pcCUAboveLeft, uiAboveLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+       , iVSPDirTrue
+#endif
+             ) ;
 #endif
       if ( mrgCandIdx == iCount )
@@ -4282,5 +4455,9 @@
   //===== vsp 5 =====
   if( iCount < 4 + extraMergeCand )
-    if ( !xAddVspMergeCand(5, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) )
+    if ( !xAddVspMergeCand(5, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+         , iVSPDirTrue
+#endif
+            ) )
       return;
 #endif
@@ -5150,5 +5327,10 @@
   return iDisp;
 }
-Void TComDataCU::estimateDVFromDM(UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred, Bool bSimpleDvpRefine)
+
+Void TComDataCU::estimateDVFromDM(
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+          Int refViewIdx,
+#endif
+          UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred, Bool bSimpleDvpRefine)
 {
   if (picDepth)
@@ -5164,5 +5346,9 @@
     Int  iShiftPrec;
 
-    getSlice()->getBWVSPLUTParam(aiShiftLUT, iShiftPrec);
+    getSlice()->getBWVSPLUTParam(aiShiftLUT, iShiftPrec
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+            , refViewIdx
+#endif
+            );
 
     Pel iDisp = getMcpFromDM( pcBaseViewDepthPicYuv, cMvPred, iBlkX, iBlkY, iWidth, iHeight, aiShiftLUT, iShiftPrec, bSimpleDvpRefine );
@@ -5193,11 +5379,32 @@
           clipMv(cMvPred);
 
-          TComPic* picDepth = getSlice()->getRefPicBaseDepth();
+          TComPic* picDepth = NULL;
+#if MERL_VSP_C0152
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+          Int refPOC = getSlice()->getRefPic(eRefPicList, refId)->getPOC();
+          picDepth = getSlice()->getDepthRefPic(refViewIdx, refPOC);
+          assert(refPOC == getSlice()->getPOC());
+          assert(picDepth != NULL);
+#else
+          picDepth = getSlice()->getRefPicBaseDepth();
+#endif
+#endif
+
 #if QC_CU_NBDV_D0181 && MERL_VSP_C0152
           pNbDvInfo->m_acMvCandNoRef[pNbDvInfo->iN] = cMvPred;
 #endif
           if (picDepth && bDepthRefine)
-            estimateDVFromDM(uiPartIdx, picDepth, uiPartAddr, &cMvPred, true);
-
+            estimateDVFromDM(
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                    refViewIdx,
+#endif
+                    uiPartIdx, picDepth, uiPartAddr, &cMvPred, true);
+
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+          pNbDvInfo->m_aListIdx[ pNbDvInfo->iN ] = eRefPicList;
+          pNbDvInfo->m_aRefIdx [ pNbDvInfo->iN ] = -1-refId;
+          assert(pNbDvInfo->m_aRefIdx [ pNbDvInfo->iN ] < 0);
+#endif
           pNbDvInfo->m_acMvCand[ pNbDvInfo->iN   ] = cMvPred;
           pNbDvInfo->m_aVIdxCan[ pNbDvInfo->iN++ ] = refViewIdx;
@@ -5217,15 +5424,44 @@
       else if (pcTmpCU->getVSPIndex(uiIdx) != 0) // is VSP
       { 
-        TComPic* picDepth = pcTmpCU->getSlice()->getRefPicBaseDepth();
+        TComPic* picDepth = NULL;
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        RefPicList privateRefPicList = (RefPicList) pcTmpCU->getVSPDir( uiIdx );
+        assert(privateRefPicList == REF_PIC_LIST_0 || privateRefPicList == REF_PIC_LIST_1);
+        Int  refIdx = -1-pcTmpCU->getCUMvField( privateRefPicList )->getRefIdx( uiIdx ); // a trick when storing refIdx for temporal BVSP
+        assert(refIdx >= 0);
+        Int  refViewIdx = getSlice()->getRefViewId(privateRefPicList, refIdx);
+        Int  refPOC = getSlice()->getRefPOC(privateRefPicList, refIdx);
+
+        picDepth = getSlice()->getDepthRefPic(refViewIdx, refPOC);
+        assert(refPOC == getSlice()->getPOC());
+        assert(picDepth != NULL);
+#else
+        picDepth = pcTmpCU->getSlice()->getRefPicBaseDepth();
+#endif
+
 #if QC_CU_NBDV_D0181 && MERL_VSP_C0152
         pNbDvInfo->m_acMvCandNoRef[pNbDvInfo->iN] = cMvPred;
 #endif
         if (picDepth && bDepthRefine)
-          estimateDVFromDM(uiPartIdx, picDepth, uiPartAddr, &cMvPred);
+          estimateDVFromDM(
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                  refViewIdx,
+#endif
+                  uiPartIdx, picDepth, uiPartAddr, &cMvPred);
 
         cMvPred.setVer(0);
 
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        pNbDvInfo->m_aRefIdx [ pNbDvInfo->iN ] = -1-refIdx;
+        pNbDvInfo->m_aListIdx[ pNbDvInfo->iN ] = privateRefPicList;
+        pNbDvInfo->m_acMvCand[ pNbDvInfo->iN ] = cMvPred;
+        pNbDvInfo->m_aVIdxCan[ pNbDvInfo->iN ] = refViewIdx;
+        assert(pNbDvInfo->m_aRefIdx [ pNbDvInfo->iN ] < 0);
+        pNbDvInfo->iN++;
+#else
         pNbDvInfo->m_acMvCand[ pNbDvInfo->iN]   = cMvPred;
         pNbDvInfo->m_aVIdxCan[ pNbDvInfo->iN++] = 0; // refViewIdx;
+#endif
         return true;
       }
@@ -5281,4 +5517,31 @@
   }
 }
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+Bool TComDataCU::getRefListAndRefFrmIdx(Int targetRefViewIdx, RefPicList& eRefPicList, Int& refFrmIdx)
+{
+  Bool isFound  = false;
+  RefPicList privateRefPicList = REF_PIC_LIST_0 ;
+
+  refFrmIdx = 0;
+  for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1) && isFound == false; iList++)
+  {
+    privateRefPicList = RefPicList(iList);
+    for (Int refIdx = 0; refIdx < getSlice()->getNumRefIdx(privateRefPicList); refIdx++)
+    {
+      Int refViewIdx  = getSlice()->getRefViewId( privateRefPicList, refIdx);
+      if ( refViewIdx == targetRefViewIdx)
+      {
+        refFrmIdx = refIdx;
+        eRefPicList = privateRefPicList;
+        isFound = true;
+        break;
+      }
+    }
+  }
+
+  return isFound;
+}
+#endif
 
 #if QC_CU_NBDV_D0181
@@ -5381,12 +5644,32 @@
           {
             clipMv(cColMv);
-            TComPic* picDepth = getSlice()->getRefPicBaseDepth();
+            TComPic* picDepth = NULL;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+            Int currPoc = getSlice()->getPOC();
+            picDepth = getSlice()->getDepthRefPic(iTargetViewIdx, currPoc);
+            assert(picDepth!=NULL);
+#else
+            picDepth = getSlice()->getRefPicBaseDepth();
+#endif
 #if QC_CU_NBDV_D0181 && MERL_VSP_C0152
             pDInfo->m_acMvCandNoRef[pDInfo->iN] = cColMv;
 #endif
             if (picDepth && bDepthRefine)
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+              estimateDVFromDM(iTargetViewIdx, uiPartIdx, picDepth, uiPartAddr, &cColMv, true);
+#else
               estimateDVFromDM(uiPartIdx, picDepth, uiPartAddr, &cColMv, true);
-
-            pDInfo->m_acMvCand[ pDInfo->iN] = cColMv;
+#endif
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+            Int refFrmIdx = 0;
+            RefPicList privateRefPicList = REF_PIC_LIST_0;
+            getRefListAndRefFrmIdx(iTargetViewIdx, privateRefPicList, refFrmIdx);
+            
+            pDInfo->m_aListIdx[ pDInfo->iN ]  = privateRefPicList;
+            pDInfo->m_aRefIdx [ pDInfo->iN ]  = -1-refFrmIdx;
+            assert(pDInfo->m_aRefIdx [ pDInfo->iN ] < 0);
+#endif
+            pDInfo->m_acMvCand[ pDInfo->iN ]  = cColMv;
             pDInfo->m_aVIdxCan[ pDInfo->iN++] = iTargetViewIdx;
 #if QC_CU_NBDV_D0181
@@ -5536,12 +5819,34 @@
           clipMv( cDispVec );
 
-          TComPic* picDepth = getSlice()->getRefPicBaseDepth();
+          TComPic* picDepth = NULL;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+          Int refPOC = getSlice()->getPOC();
+          picDepth = getSlice()->getDepthRefPic(0, refPOC);
+          assert(picDepth!=NULL);
+#else
+          picDepth = getSlice()->getRefPicBaseDepth();
+#endif
+
 #if QC_CU_NBDV_D0181 && MERL_VSP_C0152
           pDInfo->m_acMvCandNoRef[pDInfo->iN] = cDispVec;
 #endif
           if (picDepth && bDepthRefine)
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+            estimateDVFromDM(0, uiPartIdx, picDepth, uiPartAddr, &cDispVec, true); // from base view
+#else
             estimateDVFromDM(uiPartIdx, picDepth, uiPartAddr, &cDispVec, true);
-
-          pDInfo->m_acMvCand[ pDInfo->iN]   = cDispVec;
+#endif
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166 //if DVMCP is used, do a local reference frame list and idx search
+          Int refFrmIdx = 0;
+          RefPicList privateRefPicList = REF_PIC_LIST_0 ;
+          getRefListAndRefFrmIdx(0, privateRefPicList, refFrmIdx); // find the reference picture from base view
+
+          pDInfo->m_aListIdx[ pDInfo->iN ]  = privateRefPicList;
+          pDInfo->m_aRefIdx [ pDInfo->iN ]  = -1-refFrmIdx;
+          assert(pDInfo->m_aRefIdx [ pDInfo->iN ] < 0);
+#endif
+
+          pDInfo->m_acMvCand[ pDInfo->iN ]  = cDispVec;
           pDInfo->m_aVIdxCan[ pDInfo->iN++] = 0;
 #if !QC_CU_NBDV_D0181
@@ -5560,13 +5865,40 @@
     TComMv defaultDV(0, 0);
 
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    Int refPOC = getSlice()->getPOC();
+    picDepth = getSlice()->getDepthRefPic(0, refPOC);
+    assert(picDepth!=NULL);
+#else
     picDepth = getSlice()->getRefPicBaseDepth();
+#endif
+
+#if QC_CU_NBDV_D0181 && MERL_VSP_C0152 // TODO: CHECK if the macro is right
+    pDInfo->m_acMvCandNoRef[pDInfo->iN] = defaultDV;
+#endif
 
     if (picDepth && bDepthRefine)
     {
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      estimateDVFromDM(0, uiPartIdx, picDepth, uiPartAddr, &defaultDV, true); // from base view
+#else
       estimateDVFromDM(uiPartIdx, picDepth, uiPartAddr, &defaultDV, true);
-    }
-
+#endif
+    }
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    Int refFrmIdx = 0;
+    RefPicList privateRefPicList = REF_PIC_LIST_0 ;
+    getRefListAndRefFrmIdx(0, privateRefPicList, refFrmIdx); // find the reference picture from base view
+
+    pDInfo->m_aListIdx[ pDInfo->iN ]  = privateRefPicList;
+    pDInfo->m_aRefIdx [ pDInfo->iN ]  = -1-refFrmIdx;
+    assert(pDInfo->m_aRefIdx [ pDInfo->iN ] < 0);
+
+#endif
     pDInfo->m_acMvCand[pDInfo->iN] = defaultDV;
     pDInfo->m_aVIdxCan[pDInfo->iN] = 0;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166  // Bug fix for Samsung code.
+    pDInfo->iN++;
+#endif
   }
 #endif
@@ -7354,4 +7686,7 @@
 #if MERL_VSP_C0152 && MTK_UNCONSTRAINED_MVI_B0083
   memcpy( m_piVSPIndex + uiAbsPartIdxDst,  pcCU->getVSPIndex() + uiAbsPartIdxSrc, sizeof( m_piVSPIndex[0] ) * uiNumPartition );
+#endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  memcpy( m_piVSPDir   + uiAbsPartIdxDst,  pcCU->getVSPDir  () + uiAbsPartIdxSrc, sizeof( m_piVSPDir  [0] ) * uiNumPartition );
 #endif
 
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComDataCU.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComDataCU.h	(revision 412)
@@ -195,4 +195,7 @@
                                       ///< value 0: non-VSP, value 1: VSP
 #endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Char*         m_piVSPDir;           ///< 0: LIST0; 1: LIST1
+#endif
 #if AMP_MRG
   Bool          m_bIsMergeAMP;
@@ -280,6 +283,14 @@
 #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 Void   xInheritVspMode       ( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo ) ;
+                                        UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDisInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                                      , Int*   iVspDirTrue = NULL
+#endif
+                                        );
+  inline Void   xInheritVspMode       ( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    ,Int *iVSPDirTrue
+#endif
+    ) ;
 #endif
   Void          deriveRightBottomIdx        ( PartSize eCUMode, UInt uiPartIdx, UInt& ruiPartIdxRB );
@@ -477,4 +488,11 @@
   Void          setVSPIndex        ( UInt uiIdx, Int n )     { m_piVSPIndex[uiIdx] = n;    }
   Void          setVSPIndexSubParts( Char bVSPIndex, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth );
+#endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Char*         getVSPDir          ()                        { return m_piVSPDir;                           }
+  Char          getVSPDir          ( UInt uiIdx )            { return m_piVSPDir[uiIdx];                  }
+  Void          setVSPDir          ( UInt uiIdx, Int n )     { m_piVSPDir[uiIdx] = n;  }
+  Void          setVSPDirSubParts  ( Char bVSPDir, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth );
+  Bool          getRefListAndRefFrmIdx(Int targetRefViewIdx, RefPicList& eRefPicList, Int& refFrmIdx);
 #endif
 
@@ -576,5 +594,9 @@
 #if MERL_VSP_C0152
   Pel           getMcpFromDM(TComPicYuv* pcBaseViewDepthPicYuv, TComMv* mv, Int iBlkX, Int iBlkY, Int iWidth, Int iHeight, Int* aiShiftLUT, Int iShiftPrec, Bool bSimpleDvpRefine = false);
-  Void          estimateDVFromDM(UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred, Bool bSimpleDvpRefine = false);
+  Void          estimateDVFromDM(
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                Int refViewIdx,
+#endif
+                UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred, Bool bSimpleDvpRefine = false);
 #endif
   Bool          getIViewOrgDepthMvPred( UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMv );
@@ -682,5 +704,9 @@
   Bool          hasEqualMotion              ( UInt uiAbsPartIdx, TComDataCU* pcCandCU, UInt uiCandAbsPartIdx );
 #if MERL_VSP_C0152
-  Void          getInterMergeCandidates     ( UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int* uiVSPIndexTrue, Int mrgCandIdx = -1 );
+  Void          getInterMergeCandidates     ( UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int* uiVSPIndexTrue, 
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                Int* iVSPDir,
+#endif
+                Int mrgCandIdx = -1 );
 #else
   Void          getInterMergeCandidates     ( UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx = -1 );
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComMotionInfo.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComMotionInfo.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComMotionInfo.h	(revision 412)
@@ -71,4 +71,8 @@
 #endif
   Int    iN;                                ///< number of motion vector predictor candidates
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Int    m_aListIdx[ DIS_CANS ];            ///< array of reference list of derived NBDV
+  Int    m_aRefIdx [ DIS_CANS ];            ///< array of reference frame index corresponding to either RefList0/1
+#endif
 } DisInfo;
 
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComPrediction.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComPrediction.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComPrediction.cpp	(revision 412)
@@ -789,4 +789,124 @@
 
 #if MERL_VSP_C0152
+// Function to perform VSP block compensation 
+Void  TComPrediction::xPredInterVSPBlk(TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, TComMv cMv, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi )
+{
+  TComPic*    pRefPicBaseTxt        = NULL;
+  TComPicYuv* pcBaseViewTxtPicYuv   = NULL;
+  TComPicYuv* pcBaseViewDepthPicYuv = NULL;
+  Int iBlkX = 0;
+  Int iBlkY = 0;
+  Int* pShiftLUT;
+  Int  iShiftPrec;
+
+#if !MERL_VSP_NBDV_RefVId_Fix_D0166
+  pRefPicBaseTxt        = pcCU->getSlice()->getRefPicBaseTxt();
+  pcBaseViewTxtPicYuv   = pRefPicBaseTxt->getPicYuvRec();
+  TComPic* pRefPicBaseDepth = pcCU->getSlice()->getRefPicBaseDepth();
+  pcBaseViewDepthPicYuv     = pRefPicBaseDepth->getPicYuvRec();
+
+  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 ] ];
+  pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec);
+  xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred );
+  xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred );
+
+#else // MERL_VSP_NBDV_RefVId_Fix_D0166
+
+  //recover VSP reference frame according to negative refIdx number
+  RefPicList privateRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
+  assert(privateRefPicList == REF_PIC_LIST_0 || privateRefPicList == REF_PIC_LIST_1);
+
+  // Step 1: get depth reference
+  Int  refIdx = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr ); // texture ref index, a trick when storing refIdx
+  Int  viewId = pcCU->getSlice()->getRefViewId(privateRefPicList, refIdx);  // texture view id
+  Int  refPoc = pcCU->getSlice()->getRefPOC(privateRefPicList, refIdx);     // texture POC
+  TComPic* pRefPicBaseDepth = pcCU->getSlice()->getDepthRefPic(viewId, refPoc);
+
+  pcBaseViewDepthPicYuv = pRefPicBaseDepth->getPicYuvRec();
+  assert(refPoc == pcCU->getSlice()->getPOC());
+  assert(pRefPicBaseDepth != NULL);
+  assert(pcBaseViewDepthPicYuv != NULL);
+
+  iBlkX = ( pcCU->getAddr() % pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
+  iBlkY = ( pcCU->getAddr() / pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
+#if MERL_Bi_VSP_D0166
+  // Step 2: get texture reference
+  pRefPicBaseTxt = xGetVspRefTxt( pcCU, uiPartAddr, eRefPicList);
+  pcBaseViewTxtPicYuv = pRefPicBaseTxt->getPicYuvRec();
+  assert(pcBaseViewTxtPicYuv != NULL);
+
+  //initialize the LUT according to the reference view idx
+  pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec, pRefPicBaseTxt->getViewId());
+
+  // Step 3: Do compensation
+  xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred, bi );
+  xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred, bi );
+#else
+  // Step 2: get texture reference
+  pRefPicBaseTxt = pcCU->getSlice()->getRefPic(privateRefPicList, refIdx);
+  pcBaseViewTxtPicYuv = pRefPicBaseTxt->getPicYuvRec();
+  assert(pcBaseViewTxtPicYuv != NULL);
+
+  //initialize the LUT according to the reference view idx
+  pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec, pRefPicBaseTxt->getViewId());
+
+  // Step 3: Do compensation
+  xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred );
+  xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred );
+#endif
+
+#endif
+}
+
+
+
+#if MERL_Bi_VSP_D0166
+TComPic*  TComPrediction::xGetVspRefTxt(TComDataCU* pcCU, UInt uiPartAddr, RefPicList eRefPicList)
+{
+  RefPicList  privateRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
+  Int         refIdx = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr ); // texture ref index, a trick when storing refIdx
+  Int         viewId = pcCU->getSlice()->getRefViewId(privateRefPicList, refIdx);  // texture view id
+  TComPic*    refPic = NULL;
+
+  assert(privateRefPicList == REF_PIC_LIST_0 || privateRefPicList == REF_PIC_LIST_1);
+
+  if (privateRefPicList == eRefPicList)
+  {
+    Int  refIdxt = -1-pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
+    assert(refIdxt>= 0);
+    refPic = pcCU->getSlice()->getRefPic(eRefPicList, refIdxt);
+  }
+  else
+  {
+    // Find the other interview reference in order to do VSP
+    RefPicList otherRefPicList = privateRefPicList == REF_PIC_LIST_0 ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
+    Bool IsFound = false;
+    for (Int irefIdx = 0; irefIdx <pcCU->getSlice()->getNumRefIdx(otherRefPicList); irefIdx ++ )
+    {
+      Int refViewIdx  = pcCU->getSlice()->getRefViewId( otherRefPicList, irefIdx);
+      if ( (refViewIdx != pcCU->getSlice()->getViewId()) && (refViewIdx != viewId ) )
+      {
+        refPic = pcCU->getSlice()->getRefPic(otherRefPicList, irefIdx);
+        IsFound = true;
+        break;
+      }
+    }
+
+    if (IsFound == false)
+    {
+      Int  refIdxtxt = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr );
+      assert(refIdxtxt >= 0);
+      refPic = pcCU->getSlice()->getRefPic(privateRefPicList, refIdxtxt);
+    }
+    assert(IsFound);
+  }
+  assert(refPic != NULL);
+  return refPic;
+}
+#endif
+#endif
+
+#if MERL_VSP_C0152
 Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bPrdDepthMap, UInt uiSubSampExpX, UInt uiSubSampExpY, Bool bi )
 #else
@@ -829,5 +949,9 @@
 #endif
 #if QC_ARP_D0177
-  if( pcCU->getSlice()->getSPS()->isDepth() == false
+  if(
+#if MERL_VSP_C0152       
+       vspIdx == 0 &&   // TODO: Maybe logically redundant, but easier to read
+#endif
+       pcCU->getSlice()->getSPS()->isDepth() == false
     && pcCU->getSlice()->getSPS()->getViewId() > 0
     && pcCU->getSlice()->getSPS()->getUseAdvRP() > 0
@@ -847,21 +971,6 @@
 #if MERL_VSP_C0152
     if (vspIdx != 0)
-    { // depth, vsp
-      // get depth estimator here
-      TComPic* pRefPicBaseDepth = pcCU->getSlice()->getRefPicBaseDepth();
-      TComPicYuv* pcBaseViewDepthPicYuv = NULL;
-      if (vspIdx < 4) // spatial
-      {
-        pcBaseViewDepthPicYuv = pRefPicBaseDepth->getPicYuvRec();
-      }
-      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 ] ];
-      Int* pShiftLUT;
-      Int iShiftPrec;
-      pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec);
-      //using disparity to find the depth block of the base view as the depth block estimator of the current block
-      //using depth block estimator and base view texture to get Backward warping
-      xPredInterLumaBlkFromDM  ( pcBaseViewDepthPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,     pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
-      xPredInterChromaBlkFromDM( pcBaseViewDepthPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1,  pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
+    { // depth, vsp compensation 
+      xPredInterVSPBlk(pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, cMv, eRefPicList, rpcYuvPred, bi );
     }
     else
@@ -886,28 +995,11 @@
 #endif// MERL_VSP_C0152 //else
   }
-  else
+  else  // texture
   {
 #endif
 #if MERL_VSP_C0152
     if ( vspIdx != 0 )
-    { // texture, vsp
-      TComPic*    pRefPicBaseTxt        = pcCU->getSlice()->getRefPicBaseTxt();
-      TComPicYuv* pcBaseViewTxtPicYuv   = pRefPicBaseTxt->getPicYuvRec();
-      TComPicYuv* pcBaseViewDepthPicYuv = NULL;
-      if (vspIdx < 4) // spatial
-      {
-        TComPic* pRefPicBaseDepth = pcCU->getSlice()->getRefPicBaseDepth();
-        pcBaseViewDepthPicYuv     = pRefPicBaseDepth->getPicYuvRec();
-      }
-      Int iBlkX = ( pcCU->getAddr() % pRefPicBaseTxt->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
-      Int iBlkY = ( pcCU->getAddr() / pRefPicBaseTxt->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
-      Int* pShiftLUT;
-      Int iShiftPrec;
-      pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec);
-
-      //using disparity to find the depth block of the base view as the depth block estimator of the current block
-      //using depth block estimator and base view texture to get Backward warping
-      xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
-      xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
+    { // texture, vsp compensation
+      xPredInterVSPBlk(pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, cMv, eRefPicList, rpcYuvPred, bi );
     }
     else//texture not VSP
@@ -1072,4 +1164,65 @@
   Int      iRefIdx[2] = {-1, -1};
 
+#if MERL_Bi_VSP_D0166
+  Bool biDecision = 0;
+  Int  predDirVSP = 0;
+  if (pcCU->getVSPIndex(uiPartAddr) != 0) // is VSP
+  {
+    Int Bi_VSP_Avail = 0;
+    //test whether VSP is Bi or Uni
+    //Step1. Get derived DV view id
+    RefPicList privateRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
+    RefPicList otherRefPicList = privateRefPicList == REF_PIC_LIST_0 ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
+    assert(privateRefPicList == REF_PIC_LIST_0 || privateRefPicList == REF_PIC_LIST_1);
+    Int  refIdx = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr );
+    assert(refIdx >= 0);
+    Int  viewId = pcCU->getSlice()->getRefViewId(privateRefPicList, refIdx);
+    Int  refPoc = pcCU->getSlice()->getRefPOC(privateRefPicList, refIdx);
+
+    assert(refPoc == pcCU->getSlice()->getPOC());
+//    if(refPoc != pcCU->getSlice()->getPOC() )
+//    {
+//      printf("refPOC= %d, and current POC=%d\n", refPoc, pcCU->getSlice()->getPOC() );
+//    }
+    //Step 2. Get initial prediction direction value according to reference picture list availability
+    Int iInterDir = ((pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 0 && pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 0) ? 3 :
+      (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 0 ? 1 : 2)); 
+    //Step 3.  Check the availability of Bi VSP by checking the interview reference availability in the other reference list 
+    if(iInterDir==3)
+    {
+      for (Int irefIdx = 0; irefIdx <pcCU->getSlice()->getNumRefIdx(otherRefPicList); irefIdx ++ )
+      {
+        Int refViewIdx  = pcCU->getSlice()->getRefViewId( otherRefPicList, irefIdx);
+        if ( (refViewIdx != pcCU->getSlice()->getViewId()) && (refViewIdx != viewId ) )
+        {
+          Bi_VSP_Avail = 1;
+          break;
+        }
+      }
+    }
+    //Step 4. Update the Bi VSP prediction direction
+    if ( iInterDir == 3 && Bi_VSP_Avail == 1)
+    {
+      biDecision   = 1;
+      predDirVSP = 3;
+    }
+    else
+    {
+      biDecision = 0;
+      if ( privateRefPicList == REF_PIC_LIST_0 )
+        predDirVSP = 1;
+      else
+        predDirVSP = 2;
+    }
+  }
+  else 
+  {//not VSP
+    if( ( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 ) )
+      biDecision = 1;
+    else
+      biDecision = 0;
+  }
+#endif
+
   for ( Int iRefList = 0; iRefList < 2; iRefList++ )
   {
@@ -1087,8 +1240,19 @@
     else
     {
+
+#if !MERL_Bi_VSP_D0166 //both lists should go
       if ( iRefList== REF_PIC_LIST_1 && iRefIdx[iRefList] < 0 ) // iRefIdx[iRefList] ==NOT_VALID
       {
         continue;
       }
+#else
+      //Reference list loop termination
+      RefPicList privateVSPRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
+      if( (pcCU->getVSPIndex(uiPartAddr)!=0) &&  iRefList != privateVSPRefPicList && !biDecision  ) 
+      {//when VSP mode, if it is uni prediction, the other reference list should skip
+        continue;
+      }
+#endif
+
     }
 #else
@@ -1102,5 +1266,10 @@
 
     pcMbYuv = &m_acYuvPred[iRefList];
+
+#if MERL_Bi_VSP_D0166
+    if(biDecision==1)
+#else
     if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
+#endif
     {
 #if MERL_VSP_C0152
@@ -1142,8 +1311,10 @@
   {
 #if MERL_VSP_C0152
+#if !MERL_Bi_VSP_D0166
     if(pcCU->getVSPIndex(uiPartAddr))
       m_acYuvPred[0].copyPartToPartYuv( rpcYuvPred, uiPartAddr, iWidth, iHeight );
     else
 #endif
+#endif
     xWeightedPredictionBi( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
   }
@@ -1153,8 +1324,10 @@
   {
 #if MERL_VSP_C0152
+#if !MERL_Bi_VSP_D0166
     if(pcCU->getVSPIndex(uiPartAddr))
       m_acYuvPred[0].copyPartToPartYuv( rpcYuvPred, uiPartAddr, iWidth, iHeight );
     else
 #endif
+#endif
       xWeightedPredictionUni( pcCU, &m_acYuvPred[0], uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, rpcYuvPred, iPartIdx ); 
   }
@@ -1169,9 +1342,15 @@
     {
 #if MERL_VSP_C0152
+#if !MERL_Bi_VSP_D0166
       if(pcCU->getVSPIndex(uiPartAddr))
         m_acYuvPred[0].copyPartToPartYuv( rpcYuvPred, uiPartAddr, iWidth, iHeight );
       else
-#endif
+        xWeightedAverage( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
+#else
+      xWeightedAverage( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred, predDirVSP );
+#endif
+#else
       xWeightedAverage( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
+#endif
     }
   }
@@ -1507,6 +1686,9 @@
 //
 // Output: dstPic, PU predictor 64x64
-Void TComPrediction::xPredInterLumaBlkFromDM( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv* mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, Int vspIdx
-                                            , TComYuv *&dstPic )
+Void TComPrediction::xPredInterLumaBlkFromDM( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv* mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, TComYuv *&dstPic
+#if MERL_Bi_VSP_D0166
+                                            , Bool bi
+#endif          
+                                            )
 {
   Int widthLuma;
@@ -1730,5 +1912,10 @@
 
       assert( ref[refOffset] >= 0 && ref[refOffset]<= 255 );
+#if MERL_Bi_VSP_D0166
+      m_if.filterHorLuma( &ref[refOffset], refStride, &dst[xTxt], dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, !bi );
+#else
       m_if.filterHorLuma( &ref[refOffset], refStride, &dst[xTxt], dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, true );
+#endif
+
     }
     ref   += refStride*nTxtPerDepthY;
@@ -1738,9 +1925,13 @@
     yDepth++;
 #endif
-  }
-}
-
-Void TComPrediction::xPredInterChromaBlkFromDM ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv*mv, UInt partAddr, Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, Int vspIdx
-                                               , TComYuv *&dstPic )
+
+  }
+}
+
+Void TComPrediction::xPredInterChromaBlkFromDM ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv*mv, UInt partAddr, Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, TComYuv *&dstPic
+#if MERL_Bi_VSP_D0166
+                                               , Bool bi
+#endif
+                                               )
 {
   Int refStride = refPic->getCStride();
@@ -1808,20 +1999,4 @@
   Int depStrideBlock = depStride * nDepthPerTxtY;
 
-  if (isDepth)
-  {
-     // DT: Since the call for this function is redundant, ..
-     for (Int y = 0; y < size_y; y++)
-     {
-       for (Int x = 0; x < size_x; x++)
-       {
-         dstCb[x] = 128;
-         dstCr[x] = 128;
-       }
-       dstCb += dstStride;
-       dstCr += dstStride;
-     }
-     return;
-  }
-  
   if ( widthChroma > widthDepth ) // We assume
   {
@@ -2014,6 +2189,12 @@
         assert( refCb[refOffset] >= 0 && refCb[refOffset]<= 255 );
         assert( refCr[refOffset] >= 0 && refCr[refOffset]<= 255 );
+#if MERL_Bi_VSP_D0166
+        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);
+#else
         m_if.filterHorChroma(&refCb[refOffset], refStride, &dstCb[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, true);
         m_if.filterHorChroma(&refCr[refOffset], refStride, &dstCr[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, true);
+#endif
+
       }
       refCb += refStrideBlock;
@@ -2024,4 +2205,5 @@
     }
   }
+
 }
 
@@ -2031,4 +2213,5 @@
 Void TComPrediction::xWeightedAveragePdm( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst, UInt uiSubSampExpX, UInt uiSubSampExpY )
 {
+
   if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
   {
@@ -2050,18 +2233,46 @@
 #endif
 
-Void TComPrediction::xWeightedAverage( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst )
-{
+Void TComPrediction::xWeightedAverage( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst 
+#if MERL_Bi_VSP_D0166
+                                 , Int predDirVSP
+#endif
+  )
+{
+#if MERL_Bi_VSP_D0166
+  Bool isVSP = 0;
+  if (pcCU->getVSPIndex(uiPartIdx)!=0)//is VSP
+  {
+    isVSP = 1;
+  }
+
+  if(( !isVSP && iRefIdx0 >= 0 && iRefIdx1 >= 0 ) || ( isVSP && predDirVSP == 3 ))
+#else
   if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
+#endif
   {
     rpcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight );
   }
+#if MERL_Bi_VSP_D0166
+  else if ( ( !isVSP && iRefIdx0 >= 0 && iRefIdx1 <  0 ) || ( isVSP && predDirVSP == 1))
+#else
   else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
+#endif
   {
     pcYuvSrc0->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
   }
+#if MERL_Bi_VSP_D0166
+  else if (( !isVSP && iRefIdx0 <  0 && iRefIdx1 >= 0 ) || ( isVSP && predDirVSP == 2))
+#else
   else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
+#endif
   {
     pcYuvSrc1->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
   }
+#if MERL_Bi_VSP_D0166
+  else
+  {//for debug test only
+    assert(0);
+  }
+#endif
 }
 
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComPrediction.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComPrediction.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComPrediction.h	(revision 412)
@@ -115,9 +115,4 @@
       );
 
-#if MERL_VSP_C0152
-  Void xPredInterUniBWVSP         ( TComDataCU* pcCU,                          UInt uiPartAddr, UInt uiAbsPartIdx,               Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bPrdDepthMap, UInt uiSubSampExpX, UInt uiSubSampExpY, Bool bi=false );
-  Void xPredInterBiBWVSP          ( TComDataCU* pcCU,                          UInt uiPartAddr, UInt uiAbsPartIdx,               Int iWidth, Int iHeight, UInt uiSubSampExpX, UInt uiSubSampExpY, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bPrdDepthMap );
-#endif
-
 #if DEPTH_MAP_GENERATION
   Void xWeightedAveragePdm      ( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst, UInt uiSubSampExpX, UInt uiSubSampExpY );
@@ -151,11 +146,24 @@
     );
 #endif
+
+#if MERL_Bi_VSP_D0166
+  Void xWeightedAverage         ( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst,  Int predDir);
+#else
   Void xWeightedAverage         ( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst );
-
-#if MERL_VSP_C0152
-  Void xPredInterLumaBlkFromDM    ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv *mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, Int vspIdx
-                                  , TComYuv *&dstPic );
-  Void xPredInterChromaBlkFromDM  ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv *mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, Int vspIdx
-                                  , TComYuv *&dstPic );
+#endif
+#if MERL_VSP_C0152
+  Void xPredInterVSPBlk(TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, TComMv cMv, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi );
+#if MERL_Bi_VSP_D0166
+  TComPic*  xGetVspRefTxt(TComDataCU* pcCU, UInt uiPartAddr, RefPicList eRefPicList);
+  Void xPredInterLumaBlkFromDM    ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv *mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, 
+    TComYuv *&dstPic, Bool bi);
+  Void xPredInterChromaBlkFromDM  ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv *mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth,
+    TComYuv *&dstPic, Bool bi);
+#else
+  Void xPredInterLumaBlkFromDM    ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv *mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, 
+                                  TComYuv *&dstPic );
+  Void xPredInterChromaBlkFromDM  ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv *mv, UInt partAddr,Int posX, Int posY, Int size_x, Int size_y, Bool isDepth, 
+                                  TComYuv *&dstPic );
+#endif
 #endif
   Void xGetLLSPrediction ( TComPattern* pcPattern, Int* pSrc0, Int iSrcStride, Pel* pDst0, Int iDstStride, UInt uiWidth, UInt uiHeight, UInt uiExt0 );
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComSlice.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComSlice.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComSlice.cpp	(revision 412)
@@ -119,4 +119,8 @@
 #endif
 {
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  for(Int iNumCount = 0; iNumCount < MAX_VIEW_NUM; iNumCount++)
+    m_pcListDepthPic[iNumCount] =NULL;
+#endif
   m_aiNumRefIdx[0] = m_aiNumRefIdx[1] = m_aiNumRefIdx[2] = 0;
 
@@ -1386,4 +1390,31 @@
 }
 #endif
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+TComPic* TComSlice::getDepthRefPic(Int viewId, Int poc)
+{
+  TComPic* pPic = NULL;
+
+  if (m_pcListDepthPic[viewId] == NULL)
+    return NULL;
+
+  for( TComList<TComPic*>::iterator it = m_pcListDepthPic[viewId]->begin(); it != m_pcListDepthPic[viewId]->end(); it++ )
+  {
+    TComPic* currPic = *it;
+    TComSlice* currSlice = currPic->getCurrSlice();
+    Bool isDepth = currSlice->getIsDepth();
+    //assert(isDepth);
+    if( isDepth && currPic->getPOC() == poc && currPic->getViewId() == viewId ) // (*it)->getSPS()->isDepth()
+    {
+      pPic = *it;
+      break;
+    }
+  }
+
+  return pPic;
+}
+#endif
+
+
 #if QC_ARP_D0177
 Void TComSlice::setARPStepNum()                                  
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComSlice.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComSlice.h	(revision 412)
@@ -1119,4 +1119,7 @@
   Bool        m_bApplyIC;
 #endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  TComList<TComPic*>*  m_pcListDepthPic[MAX_VIEW_NUM]; // For encoder, the list may also include texture pictures. Three views with ViewIdx = 0, 1, 2
+#endif
 #if QC_ARP_D0177
   TComList<TComPic*> * m_pBaseViewRefPicList[MAX_VIEW_NUM];
@@ -1131,5 +1134,9 @@
   TComPic*     m_apcRefPicBaseTxt;
   TComPic*     m_apcRefPicBaseDepth;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Int*         m_aiShiftLUT[2]; // For reference views
+#else
   Int*         m_aiShiftLUT;
+#endif
   Int          m_iShiftPrec;
 #endif
@@ -1439,7 +1446,18 @@
   TComPic*     getRefPicBaseDepth        ()                        { return  m_apcRefPicBaseDepth; }
   Void         setRefPicBaseDepth        ( TComPic* RefPic)        { m_apcRefPicBaseDepth = RefPic; }
-
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Void setBWVSPLUTParam( Int *pShiftLUT, Int iLoG2LUTPrec, Int iNeighborViewId) { m_aiShiftLUT[iNeighborViewId] = pShiftLUT; m_iShiftPrec = iLoG2LUTPrec; }
+  Void getBWVSPLUTParam( Int*&pShiftLUT, Int&iLoG2LUTPrec, Int iNeighborViewId) { pShiftLUT = m_aiShiftLUT[iNeighborViewId]; iLoG2LUTPrec = m_iShiftPrec; }
+#else
   Void setBWVSPLUTParam( Int *pShiftLUT, Int iLoG2LUTPrec) { m_aiShiftLUT = pShiftLUT; m_iShiftPrec = iLoG2LUTPrec; }
   Void getBWVSPLUTParam( Int*&pShiftLUT, Int&iLoG2LUTPrec) { pShiftLUT = m_aiShiftLUT; iLoG2LUTPrec = m_iShiftPrec; }
+#endif
+#endif
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Void setListDepthPic( TComList<TComPic*>* pListDepthPic, Int viewId) { m_pcListDepthPic[viewId] = pListDepthPic; }
+  TComList<TComPic*>* getListDepthPic(Int viewId) { return m_pcListDepthPic[viewId]; }
+  TComPic*            getDepthRefPic(Int viewId, Int poc);
+  TComPic*            getDepthRefPic(Int refIdx);
 #endif
 
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TypeDef.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TypeDef.h	(revision 412)
@@ -182,44 +182,40 @@
 
 ///// ***** VSP *********
-#define MERL_VSP_C0152                    1 // JCT3V-C0152: 1: enable VSP-related tools; 0: disable VSP-related tools
-                                            // LGE_SIMP_DVP_REFINE_C0112            
-                                            // MERL_MTK_VSP_DVP_REFINE_C0152_C0131
+#define MERL_VSP_C0152                       1 // JCT3V-C0152: 1: enable VSP-related tools; 0: disable VSP-related tools
+                                               // LGE_SIMP_DVP_REFINE_C0112
+                                               // MERL_MTK_VSP_DVP_REFINE_C0152_C0131
 #if MERL_VSP_C0152
-#define MERL_VSP_C0152_BugFix_ForNoDepthCase     1// MERL bugfix for test condition of no depth
-/*
- * Two macros are used to configure combinations of JCT3V-C0152 and JCT3V-C0131
- * 
- *   a) (full) A full JCT3V-C0152 implementation, including JCT3V-C0131 
- *      #define MERL_VSP_COMPENSATION_C0152          1
- *      #define MERL_MTK_VSP_DVP_REFINE_C0152_C0131  1
- * 
- *   b) (mvp2off) For partial JCT3V-C0152 excluding overlaps from JCT3V-C0131
- *      #define MERL_VSP_COMPENSATION_C0152          1
- *      #define MERL_MTK_VSP_DVP_REFINE_C0152_C0131  0
- * 
- *   c) (nocand) For JCT3V-C0131 only
- *      #define MERL_VSP_COMPENSATION_C0152          0
- *      #define MERL_MTK_VSP_DVP_REFINE_C0152_C0131  1
- */
-
-#define MERL_VSP_COMPENSATION_C0152          1 // JCT3V-C0152: 1: add VSP merge candidate to merging candidate list; 0: not to add   (nocand).
-
-
-#define MERL_VSP_BLOCKSIZE_C0152             1 // JCT3V-C0152: VSP block size, supported values: 1, 2 and 4.
+
+#define MERL_VSP_C0152_BugFix_ForNoDepthCase 1 // MERL bugfix for test condition of no depth
+#define MERL_VSP_COMPENSATION_C0152          1 // JCT3V-C0152: 1: add VSP merge candidate to merging candidate list; 0: not to add (nocand).
+
+#define MERL_VSP_BLOCKSIZE_C0152             4 // JCT3V-C0152: VSP block size, supported values: 1, 2 and 4.
 #if MERL_VSP_BLOCKSIZE_C0152 == 1
-#define MERL_CVSP_D0165                      1 // JCT3V-D0165: 1:enable CVSP; 0: disable CVSP.
+#define MERL_CVSP_D0165                      1 // JCT3V-D0165: 1: enable CVSP; 0: disable CVSP.
+#else
+#define MERL_CVSP_D0165                      0 // JCT3V-D0165: 1: enable CVSP; 0: disable CVSP.
 #endif
 
 #define VSP_MERGE_POS                        5 // JCT3V-C0152: fixed position of VSP candidate in merge list, supported values: 5.
-                                               //MTK_DVPREFINE_BVSP_BUG_FIX               1
+                                               // MTK_DVPREFINE_BVSP_BUG_FIX               1
 #define MTK_DEPTH_TO_DISP_D0138              1 // JCT3V-D0138: Use max among four corners for DoNBDV and BVSP
+
+#define MTK_LGE_VSP_DEPTH_OFF_D0105_D0139    1 // JCT3V-D0105/JCT3V-D0139: disable VSP for depth map
+#define MTK_VSP_USING_NBDV_D0105             1 // JCT3V-D0105: use NBDV instead of DoNBDV for BVSP
+
+#define MERL_VSP_NBDV_RefVId_Fix_D0166       1 // JCT3V-D0166: 1: fix the NBDV with ref view selectioin; 0: always use base view with refViewIdx=0
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+#define MERL_Bi_VSP_D0166                    0 // JCT3V-D0166: 1: add supporting for Bi-VSP, the code under the macro can also handle uni-direction VSP
+#endif
 
 #else // !MERL_VSP_C0152
 #define MERL_VSP_COMPENSATION_C0152          0 // JCT3V-C0152: 1: add VSP merge candidate to merging candidate list; 0: not to add
 #define MERL_VSP_BLOCKSIZE_C0152             4 // JCT3V-C0152: VSP block size, supported values: 1, 2 and 4.
-#endif
-
-#define MTK_LGE_VSP_DEPTH_OFF_D0105_D0139             1  // JCT3V-D0105/JCT3V-D0139: disable VSP for depth map
-#define MTK_VSP_USING_NBDV_D0105                      1  // JCT3V-D0105: use NBDV instead of DoNBDV for BVSP
+#define MERL_VSP_C0152_BugFix_ForNoDepthCase 0 // MERL bugfix for test condition of no depth
+define MERL_CVSP_D0165                       0 // JCT3V-D0165: 1: enable CVSP; 0: disable CVSP.
+#define MERL_VSP_NBDV_RefVId_Fix_D0166       0 // JCT3V-D0166: 1: fix the NBDV with ref view selectioin; 0: always use base view with refViewIdx=0
+#define MERL_Bi_VSP_D0166                    0 // JCT3V-D0166: 1: add supporting for Bi-VSP, the code under the macro can also handle uni-direction VSP
+#define MTK_VSP_USING_NBDV_D0105             0
+#endif
 
 ///// ***** DERIVED PARAMETERS *********
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecCu.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecCu.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecCu.cpp	(revision 412)
@@ -393,6 +393,10 @@
         const UChar uhNewDepth = max<UInt>( uiDepth, pcTextureCU->getDepth( uiAbsPartIdx + ui ) );
 #if MERL_VSP_C0152
-        Int vspIdx = pcTextureCU->getVSPIndex( uiAbsPartIdx + ui);
-        pcCU->setVSPIndex( uiAbsPartIdx + ui, vspIdx);
+        Int vspIdx = pcTextureCU->getVSPIndex( uiAbsPartIdx + ui );
+        pcCU->setVSPIndex( uiAbsPartIdx + ui, vspIdx );
+#endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        Int vspDir = pcTextureCU->getVSPDir( uiAbsPartIdx + ui );
+        pcCU->setVSPDir( uiAbsPartIdx + ui, vspDir );
 #endif
         pcCU->setPredictionMode( uiAbsPartIdx + ui, MODE_SKIP );
@@ -412,5 +416,10 @@
 #if MERL_VSP_C0152
     Int iVSPIndexTrue[3] = {-1, -1, -1};
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    Int iVSPDirTrue[3]   = {-1, -1, -1};
+    m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, iVSPDirTrue, uiMergeIndex );
+#else
     m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, uiMergeIndex );
+#endif
     {
       Int iVSPIdx = 0;
@@ -425,5 +434,8 @@
           }
       }
-      pcCU->setVSPIndexSubParts( iVSPIdx, uiAbsPartIdx, 0, uiDepth );  //Initialize the VSP, may change later in get InterMergeCandidates()
+      pcCU->setVSPIndexSubParts( iVSPIdx, uiAbsPartIdx, 0, uiDepth );  // Initialize
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      pcCU->setVSPDirSubParts( iVSPDirTrue[iVSPIdx-1], uiAbsPartIdx, 0, uiDepth );
+#endif
     }
 #else
@@ -530,4 +542,13 @@
         Int vspIdx = pcTextureCU->getVSPIndex( uiAbsPartIdx + ui);
         pcCU->setVSPIndex( uiAbsPartIdx + ui, vspIdx);
+#endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        if (pcCU->getSlice()->getIsDepth()) {
+          pcCU->setVSPDir( uiAbsPartIdx + ui, 0);
+        }
+        else {
+          Int vspDir = pcTextureCU->getVSPDir( uiAbsPartIdx + ui);
+          pcCU->setVSPDir( uiAbsPartIdx + ui, vspDir);
+        }
 #endif
         pcCU->setPredictionMode( uiAbsPartIdx + ui, MODE_INTER );
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecEntropy.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 412)
@@ -321,6 +321,10 @@
 #if MERL_VSP_C0152
       Int iVSPIndexTrue[3] = {-1, -1, -1};
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      Int iVSPDirTrue[3]   = {-1, -1, -1};
+      pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, iVSPDirTrue, uiMergeIndex );
+#else
       pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, uiMergeIndex );
-
+#endif
 #if HHI_MPI
       if(pcCU->getTextureModeDepth( uiSubPartIdx ) == uiDepth)//MPI is used
@@ -330,6 +334,10 @@
         for( UInt ui = 0; ui < uiCurrPartNumb; ui++ )
         {
-          Int vspIdx = pcTextureCU->getVSPIndex( uiAbsPartIdx + ui);
+          Int vspIdx = pcTextureCU->getVSPIndex( uiAbsPartIdx + ui );
           pcCU->setVSPIndex( uiAbsPartIdx + ui, vspIdx);
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+          Int vspDir = pcTextureCU->getVSPDir( uiAbsPartIdx + ui );
+          pcCU->setVSPDir( uiAbsPartIdx + ui, vspDir);
+#endif
         }
       }
@@ -348,5 +356,8 @@
             }
         }
-        pcCU->setVSPIndexSubParts( iVSPIdx, uiSubPartIdx, uiPartIdx, uiDepth );  //Initialize the VSP, may change later in get InterMergeCandidates()
+        pcCU->setVSPIndexSubParts( iVSPIdx, uiSubPartIdx, uiPartIdx, uiDepth );               // Initialize
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        pcCU->setVSPDirSubParts( iVSPDirTrue[iVSPIdx-1], uiSubPartIdx, uiPartIdx, uiDepth );  // Initialize
+#endif
       }
 
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecTop.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecTop.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibDecoder/TDecTop.cpp	(revision 412)
@@ -1222,5 +1222,20 @@
      pcSlice->setRefPicBaseDepth(pcBaseDepthPic);
   }
+#if !MERL_VSP_NBDV_RefVId_Fix_D0166
   getTAppDecTop()->setBWVSPLUT( pcSlice, pcSlice->getViewId(),  pcSlice->getPOC() ); // get the LUT for backward warping
+#else
+  if (pcSlice->getViewId() != 0)
+  {
+    Bool isDepth = true;
+    for(Int refviewId = 0; refviewId < (pcSlice->getViewId()); refviewId++)
+    {
+      if (m_tAppDecTop->getTDecTop( refviewId, isDepth ))
+      {
+        pcSlice->setListDepthPic(m_tAppDecTop->getTDecTop( refviewId, isDepth )->getListPic(), refviewId); // The list will store only the depth pictures
+      }
+      getTAppDecTop()->setBWVSPLUT( refviewId, pcSlice, pcSlice->getViewId(),  pcSlice->getPOC() ); // get the LUT for backward warping
+    }
+  }
+#endif
 #endif
 
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncCu.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncCu.cpp	(revision 412)
@@ -623,4 +623,5 @@
           rpcTempCU->setPartSizeSubParts( ePartTemp, 0, uiDepth );
         }
+
         if(DvInfo.bDV==false)
         {
@@ -1714,5 +1715,5 @@
   UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
   UInt uiBPelY   = uiTPelY + (g_uiMaxCUHeight>>uiDepth) - 1;
-  
+
   if( getCheckBurstIPCMFlag() )
   {
@@ -1826,4 +1827,5 @@
   {
     m_pcEntropyCoder->encodeMergeIndex( pcCU, uiAbsPartIdx, 0 );
+
 #if LGE_ILLUCOMP_B0045
     m_pcEntropyCoder->encodeICFlag  ( pcCU, uiAbsPartIdx
@@ -1844,7 +1846,7 @@
 #endif
   m_pcEntropyCoder->encodePredMode( pcCU, uiAbsPartIdx );
-  
+
   m_pcEntropyCoder->encodePartSize( pcCU, uiAbsPartIdx, uiDepth );
-  
+
   if (pcCU->isIntra( uiAbsPartIdx ) && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N )
   {
@@ -1861,4 +1863,5 @@
   // prediction Info ( Intra : direction mode, Inter : Mv, reference idx )
   m_pcEntropyCoder->encodePredInfo( pcCU, uiAbsPartIdx );
+
 #if LGE_ILLUCOMP_B0045
     m_pcEntropyCoder->encodeICFlag  ( pcCU, uiAbsPartIdx
@@ -1934,5 +1937,10 @@
 #if MERL_VSP_C0152
   Int iVSPIndexTrue[3] = {-1, -1, -1};
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Int iVSPDirTrue[3]   = {-1, -1, -1};
+  rpcTempCU->getInterMergeCandidates( 0, 0, uhDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, iVSPDirTrue );
+#else
   rpcTempCU->getInterMergeCandidates( 0, 0, uhDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue );
+#endif
 #else
   rpcTempCU->getInterMergeCandidates( 0, 0, uhDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
@@ -2003,4 +2011,7 @@
             }
             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
           }
 #endif
@@ -2938,6 +2949,10 @@
       assert( rpcTempCU->getPredictionMode( ui ) != MODE_NONE );
 #if MERL_VSP_C0152
-      Int vspIdx = pcTextureCU->getVSPIndex( rpcTempCU->getZorderIdxInCU() + ui);
+      Int vspIdx = pcTextureCU->getVSPIndex( rpcTempCU->getZorderIdxInCU() + ui );
       rpcTempCU->setVSPIndex( ui , vspIdx);
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      Int vspDir = pcTextureCU->getVSPDir  ( rpcTempCU->getZorderIdxInCU() + ui );
+      rpcTempCU->setVSPDir( ui, vspDir);
+#endif
 #endif
     }
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 412)
@@ -2921,4 +2921,7 @@
                                  , Int* iVSPIndexTrue
 #endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                                 , Int* iVSPDirTrue
+#endif
                                  )
 {
@@ -2962,11 +2965,21 @@
   }
 #else
+
 #if MERL_VSP_C0152
-  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue );
+  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue 
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                               , iVSPDirTrue
+#endif
+  );
+
 #else
-  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
-#endif
-#endif
-
+  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                               , iVSPDirTrue
+#endif
+  );
+#endif
+
+#endif
 
 #if H3D_IVMP
@@ -2998,4 +3011,7 @@
         }
         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
       }
 #endif
@@ -3138,4 +3154,7 @@
     //reset the VSP flag to be 0
     pcCU->setVSPIndexSubParts( 0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr) );
+#endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+    pcCU->setVSPDirSubParts( 0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr) );
 #endif
 #if AMP_MRG
@@ -3377,5 +3396,5 @@
         iNumIter = 1;
       }
-      
+
       for ( Int iIter = 0; iIter < iNumIter; iIter++ )
       {
@@ -3658,4 +3677,7 @@
 #if MERL_VSP_C0152
       Int iVSPIndexTrue[3] = {-1, -1, -1};
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+      Int iVSPDirTrue[3]   = {-1, -1, -1};
+#endif
 #endif
       UInt uiMEInterDir = 0;
@@ -3688,5 +3710,5 @@
 
 
-xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost
+      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost
 #if CU_BASED_MRG_CAND_LIST
                  , cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand,
@@ -3694,4 +3716,7 @@
 #if MERL_VSP_C0152
                  , iVSPIndexTrue
+#endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                 , iVSPDirTrue
 #endif
         );
@@ -3716,4 +3741,7 @@
           }
           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
         }
 #endif
@@ -3738,5 +3766,8 @@
         pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
 #if MERL_VSP_C0152
-        pcCU->setVSPIndexSubParts ( 0 ,           uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+        pcCU->setVSPIndexSubParts ( 0,            uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+#endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+        pcCU->setVSPDirSubParts   ( 0,            uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
 #endif
         {
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSearch.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSearch.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSearch.h	(revision 412)
@@ -511,4 +511,7 @@
                                   , Int* iVSPIndexTrue
 #endif
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+                                  , Int* iVSPDirTrue
+#endif
                                    );
   // -------------------------------------------------------------------------------------------------------------------
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 412)
@@ -60,4 +60,8 @@
   m_pcBufferLowLatSbacCoders    = NULL;
   m_pcBufferLowLatBinCoderCABACs  = NULL;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  for(Int iNumCount = 0; iNumCount < MAX_VIEW_NUM; iNumCount++)
+    m_pcListDepthPic[iNumCount] =NULL;
+#endif
 #if FCO_DVP_REFINE_C0132_C0170
   m_pPicBaseTxt = NULL;
@@ -148,4 +152,9 @@
   m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
   m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
+
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  for(Int iNumCount = 0; iNumCount < MAX_VIEW_NUM; iNumCount++)
+    m_pcListDepthPic[iNumCount] =NULL;
+#endif
 }
 
@@ -819,7 +828,17 @@
 #if MERL_VSP_C0152
   // Send Depth/Texture pointers to slice level
+#if !MERL_VSP_NBDV_RefVId_Fix_D0166
   pcSlice->setBWVSPLUTParam(m_aiShiftLUT, m_iShiftPrec);
+#endif
   pcSlice->setRefPicBaseTxt(m_pPicBaseTxt);
   pcSlice->setRefPicBaseDepth(m_pPicBaseDepth);
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  for (Int refviewId=0; refviewId < pcSlice->getViewId(); refviewId++)
+  {
+    assert( m_pcListDepthPic[refviewId] );
+    pcSlice->setListDepthPic(m_pcListDepthPic[refviewId], refviewId);
+    pcSlice->setBWVSPLUTParam(m_aiShiftLUT[refviewId], m_iShiftPrec, refviewId);
+  }
+#endif
 #endif
 
Index: branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSlice.h
===================================================================
--- branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSlice.h	(revision 402)
+++ branches/HTM-6.2-dev2-MERL/source/Lib/TLibEncoder/TEncSlice.h	(revision 412)
@@ -106,8 +106,14 @@
   TComPic* m_pPicBaseTxt;
   TComPic* m_pPicBaseDepth;
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Int*     m_aiShiftLUT[2]; ///< For reference views from LIST0 and LIST1
+#else
   Int*     m_aiShiftLUT;
+#endif
   Int      m_iShiftPrec;
 #endif
-
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  TComList<TComPic*>*  m_pcListDepthPic[MAX_VIEW_NUM]; ///< For three views in total, indexed as viewId = 0, 1, 2
+#endif
 public:
   TEncSlice();
@@ -143,10 +149,22 @@
 
 #if MERL_VSP_C0152
-   Void     setBWVSPLUTParam    ( Int *pShiftLUT, Int iLoG2LUTPrec ) { m_aiShiftLUT = pShiftLUT; m_iShiftPrec = 2-iLoG2LUTPrec; }
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+  Void     setBWVSPLUTParam  ( Int *pShiftLUT, Int iLoG2LUTPrec, Int iNeighborViewId ) { m_aiShiftLUT[iNeighborViewId] = pShiftLUT; m_iShiftPrec = 2-iLoG2LUTPrec; }
+#else
+  Void     setBWVSPLUTParam    ( Int *pShiftLUT, Int iLoG2LUTPrec ) { m_aiShiftLUT = pShiftLUT; m_iShiftPrec = 2-iLoG2LUTPrec; }
+#endif
    Void     setRefPicBaseTxt    ( TComPic*pPicTxt   ) { m_pPicBaseTxt = pPicTxt;    }
    Void     setRefPicBaseDepth  ( TComPic*pPicDepth ) { m_pPicBaseDepth = pPicDepth;}
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+   Void     getBWVSPLUTParam  ( Int*& pShiftLUT, Int& iShiftPrec, Int iNeighborViewId ) { pShiftLUT = m_aiShiftLUT[iNeighborViewId]; iShiftPrec = m_iShiftPrec; }
+#else
    Void     getBWVSPLUTParam    ( Int*& pShiftLUT, Int& iShiftPrec ) { pShiftLUT = m_aiShiftLUT; iShiftPrec = m_iShiftPrec; }
+#endif
    TComPic* getRefPicBaseTxt    () { return m_pPicBaseTxt;   }
    TComPic* getRefPicBaseDepth  () { return m_pPicBaseDepth; }
+#if MERL_VSP_NBDV_RefVId_Fix_D0166
+   Void     setListDepthPic     ( TComList<TComPic*>* pListDepthPic, Int viewId ) { m_pcListDepthPic[viewId] = pListDepthPic; }
+   TComList<TComPic*>* getListDepthPic(Int viewId)  { return m_pcListDepthPic[viewId]; }
+#endif
 #endif
 };
