Index: branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecCu.cpp
===================================================================
--- branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecCu.cpp	(revision 222)
+++ branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecCu.cpp	(revision 231)
@@ -361,7 +361,12 @@
 
       UInt uiCurrPartNumb = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
+
       for( UInt ui = 0; ui < uiCurrPartNumb; ui++ )
       {
         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);
+#endif
         pcCU->setPredictionMode( uiAbsPartIdx + ui, MODE_SKIP );
         pcCU->setPartitionSize( uiAbsPartIdx + ui, SIZE_2Nx2N );
@@ -376,5 +381,24 @@
 #if SIMP_MRG_PRUN      
     UInt uiMergeIndex = pcCU->getMergeIndex(uiAbsPartIdx);
+#if MERL_VSP_C0152
+    Int iVSPIndexTrue[3] = {-1, -1, -1};
+    m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, uiMergeIndex );
+    {
+      Int iVSPIdx = 0;
+      Int numVspIdx;
+      numVspIdx = 3;
+      for (Int i = 0; i < numVspIdx; i++)
+      {
+        if (iVSPIndexTrue[i] == uiMergeIndex)
+          {
+            iVSPIdx = i+1;
+            break;
+          }
+      }
+      pcCU->setVSPIndexSubParts( iVSPIdx, uiAbsPartIdx, 0, uiDepth );  //Initialize the VSP, may change later in get InterMergeCandidates()
+    }
+#else
     m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex );
+#endif
 #else
     m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
@@ -467,7 +491,12 @@
 
       UInt uiCurrPartNumb = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
+
       for( UInt ui = 0; ui < uiCurrPartNumb; ui++ )
       {
         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);
+#endif
         pcCU->setPredictionMode( uiAbsPartIdx + ui, MODE_INTER );
         pcCU->setPartitionSize( uiAbsPartIdx + ui, SIZE_2Nx2N );
@@ -658,6 +687,9 @@
   
   // inter prediction
+#if MERL_VSP_C0152
+  m_pcPrediction->motionCompensationBWVSP( pcCU, m_ppcYuvReco[uiDepth], uiAbsPartIdx );
+#else
   m_pcPrediction->motionCompensation( pcCU, m_ppcYuvReco[uiDepth] );
-  
+#endif
 #if HHI_MPI
   if( pcCU->getTextureModeDepth( 0 ) != -1 )
@@ -1047,5 +1079,5 @@
   // reconstruct residual based on mask + DC residuals
   Pel apDCResiValues[2];
-  Pel apDCRecoValues[2];
+  //Pel apDCRecoValues[2];
   for( UInt ui = 0; ui < uiNumSegments; ui++ )
   {
@@ -1054,5 +1086,5 @@
     Pel   pRecoValue  = GetIdx2DepthValue( pPredIdx + pResiIdx );
     
-    apDCRecoValues[ui]  = pRecoValue;
+    //apDCRecoValues[ui]  = pRecoValue;
     apDCResiValues[ui]  = pRecoValue - apDCPredValues[ui];
   }
Index: branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecCu.h
===================================================================
--- branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecCu.h	(revision 222)
+++ branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecCu.h	(revision 231)
@@ -65,5 +65,5 @@
 #endif
   TComDataCU**        m_ppcCU;            ///< CU data array
-  
+
   // access channel
   TComTrQuant*        m_pcTrQuant;
@@ -85,5 +85,5 @@
   /// destroy internal buffers
   Void  destroy                 ();
-  
+
   /// decode CU information
   Void  decodeCU                ( TComDataCU* pcCU, UInt& ruiIsLast );
Index: branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecEntropy.cpp
===================================================================
--- branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 222)
+++ branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 231)
@@ -337,5 +337,37 @@
 #if SIMP_MRG_PRUN       
       UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx);
+#if MERL_VSP_C0152
+      Int iVSPIndexTrue[3] = {-1, -1, -1};
+      pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, uiMergeIndex );
+
+      if(pcCU->getTextureModeDepth( uiSubPartIdx ) == uiDepth)//MPI is used
+      {
+        TComDataCU *pcTextureCU = pcCU->getSlice()->getTexturePic()->getCU( pcCU->getAddr() );
+        UInt uiCurrPartNumb = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
+        for( UInt ui = 0; ui < uiCurrPartNumb; ui++ )
+        {
+          Int vspIdx = pcTextureCU->getVSPIndex( uiAbsPartIdx + ui);
+          pcCU->setVSPIndex( uiAbsPartIdx + ui, vspIdx);
+        }
+      }
+      else // MPI not used
+      {
+        Int iVSPIdx = 0;
+        Int numVspIdx;
+        numVspIdx = 3;
+        for (Int i = 0; i < numVspIdx; i++)
+        {
+          if (iVSPIndexTrue[i] == uiMergeIndex)
+            {
+              iVSPIdx = i+1;
+              break;
+            }
+        }
+        pcCU->setVSPIndexSubParts( iVSPIdx, uiSubPartIdx, uiPartIdx, uiDepth );  //Initialize the VSP, may change later in get InterMergeCandidates()
+      }
+
+#else
       pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex );
+#endif
 #else      
       pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
Index: branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecGop.cpp
===================================================================
--- branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecGop.cpp	(revision 222)
+++ branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecGop.cpp	(revision 231)
@@ -511,4 +511,5 @@
     m_vAlfCUCtrlSlices.clear();
   }
+  fflush(stdout);
 }
 
Index: branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecTop.cpp
===================================================================
--- branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecTop.cpp	(revision 222)
+++ branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecTop.cpp	(revision 231)
@@ -59,4 +59,10 @@
     m_aaiCodedScale       [ uiId ] = new Int [ MAX_VIEW_NUM ];
   }
+
+#if MERL_VSP_C0152
+  xCreateLUTs( (UInt)MAX_VIEW_NUM, (UInt)MAX_VIEW_NUM, m_adBaseViewShiftLUT, m_aiBaseViewShiftLUT );
+  m_iLog2Precision   = LOG2_DISP_PREC_LUT;
+  m_uiBitDepthForLUT = 8; // fixed
+#endif
 }
 
@@ -72,4 +78,9 @@
   delete [] m_aiViewOrderIndex;
   delete [] m_aiViewReceived;
+
+#if MERL_VSP_C0152
+  xDeleteArray( m_adBaseViewShiftLUT, MAX_VIEW_NUM, MAX_VIEW_NUM, 2 );
+  xDeleteArray( m_aiBaseViewShiftLUT, MAX_VIEW_NUM, MAX_VIEW_NUM, 2 );
+#endif
 }
 
@@ -85,4 +96,80 @@
   m_uiMaxViewId             = 0;
 }
+
+#if MERL_VSP_C0152
+Void
+CamParsCollector::xCreateLUTs( UInt uiNumberSourceViews, UInt uiNumberTargetViews, Double****& radLUT, Int****& raiLUT)
+{
+  //AOF( m_uiBitDepthForLUT == 8 );
+  //AOF(radLUT == NULL && raiLUT == NULL );
+
+  uiNumberSourceViews = Max( 1, uiNumberSourceViews );
+  uiNumberTargetViews = Max( 1, uiNumberTargetViews );
+
+  radLUT         = new Double***[ uiNumberSourceViews ];
+  raiLUT         = new Int   ***[ uiNumberSourceViews ];
+
+  for( UInt uiSourceView = 0; uiSourceView < uiNumberSourceViews; uiSourceView++ )
+  {
+    radLUT        [ uiSourceView ] = new Double**[ uiNumberTargetViews ];
+    raiLUT        [ uiSourceView ] = new Int   **[ uiNumberTargetViews ];
+
+    for( UInt uiTargetView = 0; uiTargetView < uiNumberTargetViews; uiTargetView++ )
+    {
+      radLUT        [ uiSourceView ][ uiTargetView ]      = new Double*[ 2 ];
+      radLUT        [ uiSourceView ][ uiTargetView ][ 0 ] = new Double [ 257 ];
+      radLUT        [ uiSourceView ][ uiTargetView ][ 1 ] = new Double [ 257 ];
+
+      raiLUT        [ uiSourceView ][ uiTargetView ]      = new Int*   [ 2 ];
+      raiLUT        [ uiSourceView ][ uiTargetView ][ 0 ] = new Int    [ 257 ];
+      raiLUT        [ uiSourceView ][ uiTargetView ][ 1 ] = new Int    [ 257 ];
+    }
+  }
+}
+
+Void 
+  CamParsCollector::xInitLUTs( UInt uiSourceView, UInt uiTargetView, Int iScale, Int iOffset, Double****& radLUT, Int****& raiLUT)
+{
+  Int     iLog2DivLuma   = m_uiBitDepthForLUT + m_uiCamParsCodedPrecision + 1 - m_iLog2Precision;   AOF( iLog2DivLuma > 0 );
+  Int     iLog2DivChroma = iLog2DivLuma + 1;
+
+  iOffset <<= m_uiBitDepthForLUT;
+
+  Double dScale  = (Double) iScale  / (( Double ) ( 1 << iLog2DivLuma ));
+  Double dOffset = (Double) iOffset / (( Double ) ( 1 << iLog2DivLuma ));
+
+  // offsets including rounding offsets
+  Int64 iOffsetLuma   = iOffset + ( ( 1 << iLog2DivLuma   ) >> 1 );
+  Int64 iOffsetChroma = iOffset + ( ( 1 << iLog2DivChroma ) >> 1 );
+
+
+  for( UInt uiDepthValue = 0; uiDepthValue < 256; uiDepthValue++ )
+  {
+
+    // real-valued look-up tables
+    Double  dShiftLuma      = ( (Double)uiDepthValue * dScale + dOffset ) * Double( 1 << m_iLog2Precision );
+    Double  dShiftChroma    = dShiftLuma / 2;
+    radLUT[ uiSourceView ][ uiTargetView ][ 0 ][ uiDepthValue ] = dShiftLuma;
+    radLUT[ uiSourceView ][ uiTargetView ][ 1 ][ uiDepthValue ] = dShiftChroma;
+
+    // integer-valued look-up tables
+    Int64   iTempScale      = (Int64)uiDepthValue * iScale;
+    Int64   iShiftLuma      = ( iTempScale + iOffsetLuma   ) >> iLog2DivLuma;
+    Int64   iShiftChroma    = ( iTempScale + iOffsetChroma ) >> iLog2DivChroma;
+    raiLUT[ uiSourceView ][ uiTargetView ][ 0 ][ uiDepthValue ] = (Int)iShiftLuma;
+    raiLUT[ uiSourceView ][ uiTargetView ][ 1 ][ uiDepthValue ] = (Int)iShiftChroma;
+
+    // maximum deviation
+    //dMaxDispDev     = Max( dMaxDispDev,    fabs( Double( (Int) iTestScale   ) - dShiftLuma * Double( 1 << iLog2DivLuma ) ) / Double( 1 << iLog2DivLuma ) );
+    //dMaxRndDispDvL  = Max( dMaxRndDispDvL, fabs( Double( (Int) iShiftLuma   ) - dShiftLuma   ) );
+    //dMaxRndDispDvC  = Max( dMaxRndDispDvC, fabs( Double( (Int) iShiftChroma ) - dShiftChroma ) );
+  }
+
+  radLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 256 ] = radLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 255 ];
+  radLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 256 ] = radLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 255 ];
+  raiLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 256 ] = raiLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 255 ];
+  raiLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 256 ] = raiLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 255 ];
+}
+#endif // end MERL_VSP_C0152
 
 Void
@@ -167,4 +254,8 @@
         m_aaiCodedScale [ uiViewId ][ uiBaseId ]  = pcSlice->getInvCodedScale () [ uiBaseId ];
         m_aaiCodedOffset[ uiViewId ][ uiBaseId ]  = pcSlice->getInvCodedOffset() [ uiBaseId ];
+#if MERL_VSP_C0152
+        xInitLUTs( uiBaseId, uiViewId, m_aaiCodedScale[ uiBaseId ][ uiViewId ], m_aaiCodedOffset[ uiBaseId ][ uiViewId ], m_adBaseViewShiftLUT, m_aiBaseViewShiftLUT);
+        xInitLUTs( uiViewId, uiBaseId, m_aaiCodedScale[ uiViewId ][ uiBaseId ], m_aaiCodedOffset[ uiViewId ][ uiBaseId ], m_adBaseViewShiftLUT, m_aiBaseViewShiftLUT);
+#endif
       }
       else
@@ -174,4 +265,8 @@
         m_aaiCodedScale [ uiViewId ][ uiBaseId ]  = pcSlice->getSPS()->getInvCodedScale () [ uiBaseId ];
         m_aaiCodedOffset[ uiViewId ][ uiBaseId ]  = pcSlice->getSPS()->getInvCodedOffset() [ uiBaseId ];
+#if MERL_VSP_C0152
+        xInitLUTs( uiBaseId, uiViewId, m_aaiCodedScale[ uiBaseId ][ uiViewId ], m_aaiCodedOffset[ uiBaseId ][ uiViewId ], m_adBaseViewShiftLUT, m_aiBaseViewShiftLUT );
+        xInitLUTs( uiViewId, uiBaseId, m_aaiCodedScale[ uiViewId ][ uiBaseId ], m_aaiCodedOffset[ uiViewId ][ uiBaseId ], m_adBaseViewShiftLUT, m_aiBaseViewShiftLUT );
+#endif
       }
     }
@@ -188,4 +283,8 @@
         m_aaiCodedScale [ uiViewId ][ uiBaseId ]  = pcSlice->getInvCodedScale () [ uiBaseId ];
         m_aaiCodedOffset[ uiViewId ][ uiBaseId ]  = pcSlice->getInvCodedOffset() [ uiBaseId ];
+#if MERL_VSP_C0152
+        xInitLUTs( uiBaseId, uiViewId, m_aaiCodedScale[ uiBaseId ][ uiViewId ], m_aaiCodedOffset[ uiBaseId ][ uiViewId ], m_adBaseViewShiftLUT, m_aiBaseViewShiftLUT );
+        xInitLUTs( uiViewId, uiBaseId, m_aaiCodedScale[ uiViewId ][ uiBaseId ], m_aaiCodedOffset[ uiViewId ][ uiBaseId ], m_adBaseViewShiftLUT, m_aiBaseViewShiftLUT );
+#endif
       }
     }
@@ -258,5 +357,5 @@
 #endif
 #if ENC_DEC_TRACE
-  g_hTrace = fopen( "TraceDec.txt", "wb" );
+  if(!g_hTrace) g_hTrace = fopen( "TraceDec.txt", "wb" );
   g_bJustDoIt = g_bEncDecTraceDisable;
   g_nSymbolCounter = 0;
@@ -277,5 +376,6 @@
 {
 #if ENC_DEC_TRACE
-  fclose( g_hTrace );
+  if(g_hTrace) fclose( g_hTrace );
+  g_hTrace=NULL;
 #endif
 }
@@ -304,4 +404,5 @@
   m_cResidualGenerator.destroy();
 #endif
+
 }
 
@@ -1109,4 +1210,19 @@
     initWedgeLists();
   }
+#endif
+
+#if MERL_VSP_C0152 // set BW LUT 
+  if( m_pcCamParsCollector ) // Initialize the LUT elements 
+  {
+    m_pcCamParsCollector->setSlice( pcSlice );
+  }
+  if( pcSlice->getViewId() !=0 )
+  {
+    TComPic* pcBaseTxtPic = m_tAppDecTop->getPicFromView(  0, pcSlice->getPOC(), false );  // get base view reconstructed texture
+    TComPic* pcBaseDepthPic = m_tAppDecTop->getPicFromView(  0, pcSlice->getPOC(), true ); // get base view reconstructed depth
+     pcSlice->setRefPicBaseTxt(pcBaseTxtPic);
+     pcSlice->setRefPicBaseDepth(pcBaseDepthPic);
+  }
+  getTAppDecTop()->setBWVSPLUT( pcSlice, pcSlice->getViewId(),  pcSlice->getPOC() ); // get the LUT for backward warping
 #endif
 
Index: branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecTop.h
===================================================================
--- branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecTop.h	(revision 222)
+++ branches/HTM-5.1-dev3-MERL/source/Lib/TLibDecoder/TDecTop.h	(revision 231)
@@ -77,4 +77,7 @@
   Bool  isInitialized() const { return m_bInitialized; }
 
+#if MERL_VSP_C0152
+  Int**** getBaseViewShiftLUTI()  { return m_aiBaseViewShiftLUT;   }
+#endif
 private:
   Bool  xIsComplete ();
@@ -97,5 +100,79 @@
   Int     m_iLastPOC;
   UInt    m_uiMaxViewId;
+
+#if MERL_VSP_C0152
+  UInt    m_uiBitDepthForLUT;
+  UInt    m_iLog2Precision;
+  UInt    m_uiInputBitDepth;
+  // look-up tables
+  Double****   m_adBaseViewShiftLUT;       ///< Disparity LUT
+  Int****      m_aiBaseViewShiftLUT;       ///< Disparity LUT
+  Void xCreateLUTs( UInt uiNumberSourceViews, UInt uiNumberTargetViews, Double****& radLUT, Int****& raiLUT);
+  Void xInitLUTs( UInt uiSourceView, UInt uiTargetView, Int iScale, Int iOffset, Double****& radLUT, Int****& raiLUT);
+  template<class T> Void  xDeleteArray  ( T*& rpt, UInt uiSize1, UInt uiSize2, UInt uiSize3 );
+  template<class T> Void  xDeleteArray  ( T*& rpt, UInt uiSize1, UInt uiSize2 );
+  template<class T> Void  xDeleteArray  ( T*& rpt, UInt uiSize );
+#endif
+
 };
+
+#if MERL_VSP_C0152
+template <class T>
+Void CamParsCollector::xDeleteArray( T*& rpt, UInt uiSize1, UInt uiSize2, UInt uiSize3 )
+{
+  if( rpt )
+  {
+    for( UInt uiK = 0; uiK < uiSize1; uiK++ )
+    {
+      for( UInt uiL = 0; uiL < uiSize2; uiL++ )
+      {
+        for( UInt uiM = 0; uiM < uiSize3; uiM++ )
+        {
+          delete[] rpt[ uiK ][ uiL ][ uiM ];
+        }
+        delete[] rpt[ uiK ][ uiL ];
+      }
+      delete[] rpt[ uiK ];
+    }
+    delete[] rpt;
+  }
+  rpt = NULL;
+};
+
+
+template <class T>
+Void CamParsCollector::xDeleteArray( T*& rpt, UInt uiSize1, UInt uiSize2 )
+{
+  if( rpt )
+  {
+    for( UInt uiK = 0; uiK < uiSize1; uiK++ )
+    {
+      for( UInt uiL = 0; uiL < uiSize2; uiL++ )
+      {
+        delete[] rpt[ uiK ][ uiL ];
+      }
+      delete[] rpt[ uiK ];
+    }
+    delete[] rpt;
+  }
+  rpt = NULL;
+};
+
+
+template <class T>
+Void CamParsCollector::xDeleteArray( T*& rpt, UInt uiSize )
+{
+  if( rpt )
+  {
+    for( UInt uiK = 0; uiK < uiSize; uiK++ )
+    {
+      delete[] rpt[ uiK ];
+    }
+    delete[] rpt;
+  }
+  rpt = NULL;
+};
+
+#endif
 
 /// decoder class
@@ -206,4 +283,5 @@
   ParameterSetManagerDecoder* xGetParaSetDec ()        {return  &m_parameterSetManagerDecoder;}
 #endif
+
 protected:
   Void  xGetNewPicBuffer  (TComSlice* pcSlice, TComPic*& rpcPic);
