Index: branches/HTM-9.3-dev1-Qualcomm/cfg/3D-HEVC/baseCfg_2view+depth.cfg
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/cfg/3D-HEVC/baseCfg_2view+depth.cfg	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/cfg/3D-HEVC/baseCfg_2view+depth.cfg	(revision 779)
@@ -202,5 +202,5 @@
 IvMvScaling                         : 1                # Interview motion vector scaling
 SubPULog2Size                       : 3                # Log2 of sub-PU size for IvMvPred (2...6)
-
+SubPUMPILog2Size                    : 3	            # Log2 of sub-PU size for MPI (3...6)
 
 #========== depth coding tools ==========
Index: branches/HTM-9.3-dev1-Qualcomm/cfg/3D-HEVC/baseCfg_3view+depth.cfg
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/cfg/3D-HEVC/baseCfg_3view+depth.cfg	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/cfg/3D-HEVC/baseCfg_3view+depth.cfg	(revision 779)
@@ -232,5 +232,5 @@
 IvMvScaling                         : 1                # Interview motion vector scaling
 SubPULog2Size                       : 3				   # Log2 of sub-PU size for IvMvPred (2...6)
-
+SubPUMPILog2Size                    : 3	            # Log2 of sub-PU size for MPI (3...6)
 
 #========== depth coding tools ==========
Index: branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 779)
@@ -513,5 +513,7 @@
   ("SubPULog2Size", m_iSubPULog2Size, (Int)3, "Sub-PU size index: 2^n")
 #endif
-
+#if QC_SPIVMP_MPI_G0119
+  ("SubPUMPILog2Size", m_iSubPUMPILog2Size, (Int)3, "Sub-PU MPI size index: 2^n")
+#endif
 #if H_3D_IC
   ("IlluCompEnable",           m_abUseIC, true, "Enable illumination compensation")
@@ -1516,4 +1518,9 @@
   xConfirmPara( m_iSubPULog2Size > 6,                                        "SubPULog2Size must be 6 or smaller.");
   xConfirmPara( (1<<m_iSubPULog2Size) > m_uiMaxCUWidth,                      "SubPULog2Size must be log2(maxCUSize) or smaller.");
+#endif
+#if QC_SPIVMP_MPI_G0119
+  xConfirmPara( m_iSubPUMPILog2Size < 3,                                        "SubPUMPILog2Size must be 3 or greater.");
+  xConfirmPara( m_iSubPUMPILog2Size > 6,                                        "SubPUMPILog2Size must be 6 or smaller.");
+  xConfirmPara( ( 1 << m_iSubPUMPILog2Size ) > m_uiMaxCUWidth,                  "SubPUMPILog2Size must be log2(maxCUSize) or smaller.");
 #endif
 #if ADAPTIVE_QP_SELECTION
@@ -2474,4 +2481,7 @@
 #endif
 #endif
+#if QC_SPIVMP_MPI_G0119
+  printf(" SubPUMPILog2Size:%d  " , m_iSubPUMPILog2Size  );
+#endif
 #if H_3D_ARP
   printf(" ARP:%d  ", m_uiUseAdvResPred  );
Index: branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncCfg.h	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncCfg.h	(revision 779)
@@ -130,4 +130,7 @@
   Int                    m_iSubPULog2Size;                    
 #endif
+#endif
+#if QC_SPIVMP_MPI_G0119
+  Int                    m_iSubPUMPILog2Size;                    
 #endif
 #if H_3D_ARP                                                  /// < flag and number of weighting factors in ARP
Index: branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncTop.cpp	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/App/TAppEncoder/TAppEncTop.cpp	(revision 779)
@@ -184,4 +184,7 @@
 #if H_3D_SPIVMP
     m_cTEncTop.setSubPULog2Size                 (( isDepth || 0==layerIdInVps ) ? 0 : m_iSubPULog2Size   );
+#endif
+#if QC_SPIVMP_MPI_G0119
+    m_cTEncTop.setSubPUMPILog2Size              ( !isDepth ? 0 : m_iSubPUMPILog2Size   );
 #endif
 #if H_3D_IC
@@ -1911,4 +1914,7 @@
 #endif
   }  
+#if QC_SPIVMP_MPI_G0119
+  vps.setSubPUMPILog2Size( m_iSubPUMPILog2Size );
+#endif
 #if H_3D
   vps.setIvMvScalingFlag( m_ivMvScalingFlag );   
Index: branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TComDataCU.cpp	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TComDataCU.cpp	(revision 779)
@@ -4075,4 +4075,112 @@
   if( bMPIFlag)
   {
+#if QC_SPIVMP_MPI_G0119
+    tmpMV[0].setMvField( cZeroMv, NOT_VALID );
+    tmpMV[1].setMvField( cZeroMv, NOT_VALID );
+    tmpDir        =  0;
+
+    TComPic * pcTexPic = m_pcSlice->getTexturePic();
+#if H_3D_FCO
+    if (pcTexturePic->getReconMark())
+    {
+#endif    
+      TComPicYuv*   pcTexRec = pcTexPic->getPicYuvRec  ();
+      UInt          uiPartAddr;
+      Int           iWidth, iHeight;
+      Int           iCurrPosX, iCurrPosY;
+
+      this->getPartIndexAndSize( uiPUIdx, uiPartAddr, iWidth, iHeight );
+      pcTexRec->getTopLeftSamplePos( this->getAddr(), this->getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
+
+      Int iPUWidth, iPUHeight, iNumPart, iNumPartLine;
+      this->getSPPara(iWidth, iHeight, iNumPart, iNumPartLine, iPUWidth, iPUHeight);
+
+      for (Int i=0; i<iNumPart; i++)
+      {
+        puhInterDirSP[i] = 0;
+        pcMvFieldSP[2*i].getMv().set(0, 0);
+        pcMvFieldSP[2*i+1].getMv().set(0, 0);
+        pcMvFieldSP[2*i].setRefIdx(-1);
+        pcMvFieldSP[2*i+1].setRefIdx(-1);
+      }
+
+      Int         iTexCUAddr;
+      Int         iTexAbsPartIdx;
+      TComDataCU* pcTexCU;
+      Int iPartition = 0;
+      Int iInterDirSaved = 0;
+      TComMvField cMvFieldSaved[2];
+
+      Int iOffsetX = iPUWidth/2;;
+      Int iOffsetY = iPUHeight/2;
+
+      Int         iTexPosX, iTexPosY;
+      const TComMv cMvRounding( 1 << ( 2 - 1 ), 1 << ( 2 - 1 ) );
+      for (Int i=iCurrPosY; i < iCurrPosY + iHeight; i += iPUHeight)
+      {
+        for (Int j = iCurrPosX; j < iCurrPosX + iWidth; j += iPUWidth)
+        {
+          iTexPosX     = j + iOffsetX;
+          iTexPosY     = i + iOffsetY; 
+          pcTexRec->getCUAddrAndPartIdx( iTexPosX, iTexPosY, iTexCUAddr, iTexAbsPartIdx );
+          pcTexCU  = pcTexPic->getCU( iTexCUAddr );
+
+          if( pcTexCU && !pcTexCU->isIntra(iTexAbsPartIdx) )
+          {
+            for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )
+            {
+              RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
+              TComMvField cTexMvField;
+              pcTexCU->getMvField( pcTexCU, iTexAbsPartIdx, eCurrRefPicList, cTexMvField );
+              Int iValidDepRef = getPic()->isTextRefValid( eCurrRefPicList, cTexMvField.getRefIdx() );
+              if( (cTexMvField.getRefIdx()>=0) && ( iValidDepRef >= 0 ) )
+              {
+                TComMv cMv = cTexMvField.getMv() + cMvRounding;
+                cMv >>=2;
+                this->clipMv( cMv );
+                pcMvFieldSP[2*iPartition + uiCurrRefListId].setMvField(cMv, iValidDepRef);
+              }
+            }
+          }
+          puhInterDirSP[iPartition] = (pcMvFieldSP[2*iPartition].getRefIdx()!=-1 ? 1: 0) + (pcMvFieldSP[2*iPartition+1].getRefIdx()!=-1 ? 2: 0);
+          if (puhInterDirSP[iPartition] == 0)
+          {
+            if (iInterDirSaved != 0)
+            {
+              puhInterDirSP[iPartition] = iInterDirSaved;
+              pcMvFieldSP[2*iPartition] = cMvFieldSaved[0];
+              pcMvFieldSP[2*iPartition + 1] = cMvFieldSaved[1];
+            }
+          }
+          else
+          {
+            if (iInterDirSaved ==0)
+            {
+              pbSPIVMPFlag[iCount] = true;
+              tmpDir = puhInterDirSP[iPartition];
+              tmpMV[0] = pcMvFieldSP[2*iPartition];
+              tmpMV[1] = pcMvFieldSP[2*iPartition+1];
+
+              if (iPartition != 0)
+              {
+                for (Int iPart = iPartition-1; iPart >= 0; iPart--)
+                {
+                  puhInterDirSP[iPart] = puhInterDirSP[iPartition];
+                  pcMvFieldSP[2*iPart] = pcMvFieldSP[2*iPartition];
+                  pcMvFieldSP[2*iPart + 1] = pcMvFieldSP[2*iPartition + 1];
+                }
+              }
+            }
+            iInterDirSaved = puhInterDirSP[iPartition];
+            cMvFieldSaved[0] = pcMvFieldSP[2*iPartition];
+            cMvFieldSaved[1] = pcMvFieldSP[2*iPartition + 1];
+          }
+          iPartition ++;
+        }
+      }
+#if H_3D_FCO
+    }
+#endif
+#else
     UInt uiPartIdxCenter;
     xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );    
@@ -4131,5 +4239,5 @@
         tmpDir += ((tmpMV[1].getRefIdx()>=0)?2:0);
       }
-
+#endif
       if( tmpDir != 0 )
       {
@@ -4190,5 +4298,8 @@
           }
         }
-
+#if QC_SPIVMP_MPI_G0119
+        pcMvFieldNeighbours[iCount<<1].setMvField(tmpMV[0].getMv(), tmpMV[0].getRefIdx());
+        pcMvFieldNeighbours[(iCount<<1)+1].setMvField(tmpMV[1].getMv(), tmpMV[1].getRefIdx());
+#else
         if( (tmpMV[0].getRefIdx()>=0) && ( tRef[0] >= 0 ) )
         {
@@ -4202,4 +4313,5 @@
           }
         }
+#endif
         puhInterDirNeighbours[iCount] = tmpDir;
 
@@ -4210,5 +4322,7 @@
         iCount ++;
       }
-    }
+#if !QC_SPIVMP_MPI_G0119
+    }
+#endif
   }
 
@@ -4339,4 +4453,7 @@
     if (bIvMC)
     {
+#if QC_SPIVMP_MPI_G0119
+      if(!m_pcSlice->getIsDepth())
+#endif
       pbSPIVMPFlag[iCount] = true;
       if( ( ivCandDir[0] & 1 ) == 1 )
@@ -6945,4 +7062,10 @@
 {
   Int iSubPUSize = 1<<getSlice()->getVPS()->getSubPULog2Size(getSlice()->getLayerId());
+#if QC_SPIVMP_MPI_G0119
+  if( getSlice()->getIsDepth() )
+  {
+    iSubPUSize = 1 << getSlice()->getVPS()->getSubPUMPILog2Size();
+  }
+#endif
   iNumSPInOneLine = iPUWidth/iSubPUSize;
   iNumSPInOneLine = iNumSPInOneLine < 1 ? 1: iNumSPInOneLine;
@@ -7038,5 +7161,8 @@
   //////////sub-PU IvMC///////////
   ////////////////////////////////
-  
+#if QC_SPIVMP_MPI_G0119
+  if(!m_pcSlice->getIsDepth())
+  {
+#endif  
   Int iNumSPInOneLine, iNumSP, iSPWidth, iSPHeight;
   getSPPara(iWidth, iHeight, iNumSP, iNumSPInOneLine, iSPWidth, iSPHeight);
@@ -7158,4 +7284,7 @@
   iCurrPosX  += ( iWidth  >> 1 );
   iCurrPosY  += ( iHeight >> 1 );
+#if QC_SPIVMP_MPI_G0119
+ }
+#endif
 #endif
 
@@ -7165,5 +7294,14 @@
 
 #if H_3D_SPIVMP
+#if QC_SPIVMP_MPI_G0119
+ if(m_pcSlice->getIsDepth())
+ {
+   iCurrPosX  += ( iWidth  >> 1 );
+   iCurrPosY  += ( iHeight >> 1 );
+ }
+ for(Int iLoopCan = ( 1 - m_pcSlice->getIsDepth() ); iLoopCan < 2; iLoopCan ++) 
+#else
   for(Int iLoopCan = 1; iLoopCan < 2; iLoopCan ++) 
+#endif
 #else
   for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
@@ -7173,5 +7311,5 @@
     // iLoopCan == 1 --> IvMCShift 
 
-#if !H_3D_SPIVMP
+#if !H_3D_SPIVMP || QC_SPIVMP_MPI_G0119
     Int         iBaseCUAddr;
     Int         iBaseAbsPartIdx;
@@ -7181,5 +7319,5 @@
     Int offsetH = (iLoopCan == 0) ? 0 : ( ((iHeight/2)*4) + 4 );
 
-#if H_3D_SPIVMP
+#if H_3D_SPIVMP && !QC_SPIVMP_MPI_G0119
     iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + offsetW + 2 ) >> 2 ) );
     iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + offsetH + 2 ) >> 2 ) ); 
@@ -7190,5 +7328,5 @@
     pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY , iBaseCUAddr, iBaseAbsPartIdx );
 
-#if H_3D_SPIVMP
+#if H_3D_SPIVMP && !QC_SPIVMP_MPI_G0119
     pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
 #else
@@ -7248,5 +7386,9 @@
   }
 #if H_3D_SPIVMP
+#if QC_SPIVMP_MPI_G0119
+  for(Int iLoopCan = ( 1 - m_pcSlice->getIsDepth() ); iLoopCan < 2; iLoopCan ++) 
+#else
   for(Int iLoopCan = 1; iLoopCan < 2; iLoopCan ++)
+#endif
 #else
   for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
Index: branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TComSlice.h	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TComSlice.h	(revision 779)
@@ -783,4 +783,7 @@
 #endif
 #endif
+#if QC_SPIVMP_MPI_G0119
+  Int         m_iSubPUMPILog2Size;
+#endif
 #if H_3D_VSP
   Bool        m_viewSynthesisPredFlag    [ MAX_NUM_LAYERS ];
@@ -1057,4 +1060,8 @@
   Void    setSubPULog2Size(Int layerIdInVps, Int u)    { m_iSubPULog2Size[layerIdInVps] = u;}
 #endif
+#endif
+#if QC_SPIVMP_MPI_G0119
+  Int     getSubPUMPILog2Size( )           { return m_iSubPUMPILog2Size; }
+  Void    setSubPUMPILog2Size( Int u )     { m_iSubPUMPILog2Size = u;    }
 #endif
 #if H_3D_VSP
Index: branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TypeDef.h	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibCommon/TypeDef.h	(revision 779)
@@ -224,4 +224,8 @@
 #if H_3D_ARP
 #define H_3D_ARP_WFNR                     3
+#endif
+
+#if H_3D_SPIVMP
+#define QC_SPIVMP_MPI_G0119               1 // Sub-PU level MPI merge candidate
 #endif
 
Index: branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 779)
@@ -1762,5 +1762,7 @@
     }
   }
-
+#if QC_SPIVMP_MPI_G0119
+  READ_UVLC (uiCode, "log2_sub_PU_MPI_size_minus3");              pcVPS->setSubPUMPILog2Size( uiCode + 3 ); 
+#endif
   READ_FLAG( uiCode, "iv_mv_scaling_flag");                       pcVPS->setIvMvScalingFlag( uiCode == 1 ? true : false ); 
 }
Index: branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 779)
@@ -1555,4 +1555,7 @@
     }
   }
+#if QC_SPIVMP_MPI_G0119
+  WRITE_UVLC( pcVPS->getSubPUMPILog2Size( ) - 3, "log2_sub_PU_MPI_size_minus3");
+#endif
 #if H_3D_TMVP
   WRITE_FLAG( pcVPS->getIvMvScalingFlag( ) ? 1 : 0 ,          "iv_mv_scaling_flag" );
Index: branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibEncoder/TEncCfg.h	(revision 776)
+++ branches/HTM-9.3-dev1-Qualcomm/source/Lib/TLibEncoder/TEncCfg.h	(revision 779)
@@ -411,4 +411,7 @@
   Int      m_iSubPULog2Size;
 #endif
+#if QC_SPIVMP_MPI_G0119
+  Int      m_iSubPUMPILog2Size;
+#endif
 #if H_3D_IC
   Bool      m_bUseIC;
@@ -515,5 +518,8 @@
   Void       setSubPULog2Size                   (Int u)              { m_iSubPULog2Size = u; }     
 #endif
-
+#if QC_SPIVMP_MPI_G0119
+  Int        getSubPUMPILog2Size            ()               { return m_iSubPUMPILog2Size;}
+  Void       setSubPUMPILog2Size            (Int u)          { m_iSubPUMPILog2Size = u;   }     
+#endif
 #if H_3D_IC
   Void       setUseIC                       ( Bool bVal )    { m_bUseIC = bVal; }
