Index: branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 816)
@@ -521,4 +521,7 @@
 #if H_3D_INTER_SDC
   ("InterSDC",                 m_bDepthInterSDCFlag,        true, "Enable depth inter SDC")
+#endif
+#if H_3D_DBBP
+  ("DBBP",                     m_bUseDBBP,   true, "Enable depth-based block partitioning" )
 #endif
 #if H_3D_IV_MERGE
@@ -2492,5 +2495,5 @@
 #endif
 #if H_3D_IC
-  printf( "IlluCompEnable: %d ", m_abUseIC);
+  printf( "IlluCompEnable:%d ", m_abUseIC);
 #endif
 #if H_3D_NBDV_REF
@@ -2509,8 +2512,11 @@
 #endif
 #if H_3D_INTER_SDC
-  printf( "interSDC: %d ", m_bDepthInterSDCFlag ? 1 : 0 );
+  printf( "interSDC:%d ", m_bDepthInterSDCFlag ? 1 : 0 );
+#endif
+#if H_3D_DBBP
+  printf("DBBP:%d ", m_bUseDBBP ? 1 : 0);
 #endif
 #if H_3D_IV_MERGE
-  printf( "MPI: %d ", m_bMPIFlag ? 1 : 0 );
+  printf( "MPI:%d ", m_bMPIFlag ? 1 : 0 );
 #endif
   printf("\n\n");  
Index: branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncCfg.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncCfg.h	(revision 816)
@@ -492,4 +492,7 @@
   Bool m_bDepthInterSDCFlag;                                ///< flag for inter SDC of depth map coding
 #endif
+#if H_3D_DBBP
+  Bool      m_bUseDBBP;                                     ///< flag for depth-based block partitioning
+#endif
 #if H_3D_IV_MERGE
   Bool m_bMPIFlag;                                           ///< flag for MPI of depth map coding
Index: branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncTop.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/App/TAppEncoder/TAppEncTop.cpp	(revision 816)
@@ -204,4 +204,7 @@
 #if H_3D_INTER_SDC
     m_cTEncTop.setInterSDCEnable               ( isDepth ? m_bDepthInterSDCFlag    : false );
+#endif
+#if H_3D_DBBP
+    m_cTEncTop.setUseDBBP                      ( vps.getViewIndex( layerId ) == 0 || isDepth ? false : m_bUseDBBP );
 #endif
 #if H_3D_IV_MERGE
@@ -1912,5 +1915,8 @@
 #if H_3D_VSP
     vps.setViewSynthesisPredFlag( layer, !isLayerZero && !isDepth && m_viewSynthesisPredFlag );         
-#endif      
+#endif
+#if H_3D_DBBP
+    vps.setUseDBBP              ( layer, !isLayerZero && !isDepth && m_bUseDBBP );
+#endif
 #if H_3D_INTER_SDC
     vps.setInterSDCFlag( layer, !isLayerZero && isDepth && m_bDepthInterSDCFlag );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/ContextTables.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/ContextTables.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/ContextTables.h	(revision 816)
@@ -125,4 +125,8 @@
 #define NUM_INTER_SDC_RESIDUAL_CTX    1      ///< number of context models for abs of inter SDC residual
 #endif
+
+#if H_3D_DBBP
+#define DBBP_NUM_FLAG_CTX                 1
+#endif
 // ====================================================================================================================
 // Tables
@@ -459,4 +463,12 @@
 //! \}
 
-
-#endif
+#if H_3D_DBBP
+static const UChar INIT_DBBP_FLAG[3][DBBP_NUM_FLAG_CTX] =
+{
+  { CNU },
+  { CNU },
+  { CNU },
+};
+#endif
+
+#endif
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComDataCU.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComDataCU.cpp	(revision 816)
@@ -153,4 +153,7 @@
   m_pucInterSDCMask       = NULL;
 #endif
+#if H_3D_DBBP
+  m_pbDBBPFlag         = NULL;
+#endif
 
 #if MTK_DDD_G0063
@@ -288,4 +291,7 @@
     }
 #endif
+#if H_3D_DBBP
+    m_pbDBBPFlag         = (Bool*  )xMalloc(Bool,   uiNumPartition);
+#endif
   }
   else
@@ -425,4 +431,7 @@
       if ( m_apSegmentInterDCOffset[i] ) { xFree( m_apSegmentInterDCOffset[i] ); m_apSegmentInterDCOffset[i] = NULL; }
   }
+#endif
+#if H_3D_DBBP
+    if ( m_pbDBBPFlag         ) { xFree(m_pbDBBPFlag);          m_pbDBBPFlag        = NULL; }
 #endif
   }
@@ -577,4 +586,7 @@
 #if H_3D_INTER_SDC
     m_pbInterSDCFlag[ui] = pcFrom->m_pbInterSDCFlag[ui];
+#endif
+#if H_3D_DBBP
+    m_pbDBBPFlag[ui] = pcFrom->m_pbDBBPFlag[ui];
 #endif
   }
@@ -653,4 +665,7 @@
       memset( m_apSegmentInterDCOffset[i] + firstElement,     0,         numElements * sizeof( *m_apSegmentInterDCOffset[i] ) );
     }
+#endif
+#if H_3D_DBBP
+    memset( m_pbDBBPFlag        + firstElement, false,                    numElements * sizeof( *m_pbDBBPFlag ) );
 #endif
   }
@@ -832,4 +847,7 @@
       }
 #endif
+#if H_3D_DBBP
+      m_pbDBBPFlag[ui] = false;
+#endif
     }
   }
@@ -950,4 +968,7 @@
     memset( m_apSegmentInterDCOffset[i], 0, sizeof( Int ) * m_uiNumPartition );
   }
+#endif
+#if H_3D_DBBP
+  memset( m_pbDBBPFlag,         0, iSizeInBool  );
 #endif
 
@@ -1034,4 +1055,7 @@
       }
 #endif
+#if H_3D_DBBP
+      m_pbDBBPFlag[ui]=pcCU->m_pbDBBPFlag[uiPartOffset+ui];
+#endif
     }
   }
@@ -1195,4 +1219,7 @@
   }
 #endif
+#if H_3D_DBBP
+  m_pbDBBPFlag              = pcCU->getDBBPFlag()         + uiPart;
+#endif
   m_puhDepth=pcCU->getDepth()                     + uiPart;
   m_puhWidth=pcCU->getWidth()                     + uiPart;
@@ -1311,4 +1338,8 @@
   m_pucDisparityDerivedDepth         = pcCU->getDDDepth()              + uiAbsPartIdx;
   m_pbUseDDD                         = pcCU->getUseDDD()              + uiAbsPartIdx;
+#endif
+    
+#if H_3D_DBBP
+  m_pbDBBPFlag       = pcCU->getDBBPFlag()              + uiAbsPartIdx;
 #endif
 
@@ -1400,4 +1431,7 @@
   }
 #endif
+#if H_3D_DBBP
+  memcpy( m_pbDBBPFlag          + uiOffset, pcCU->getDBBPFlag(),          iSizeInBool  );
+#endif
 
   memcpy( m_puhDepth  + uiOffset, pcCU->getDepth(),  iSizeInUchar );
@@ -1527,4 +1561,8 @@
   }
 #endif
+#if H_3D_DBBP
+  memcpy( rpcCU->getDBBPFlag()          + m_uiAbsIdxInLCU, m_pbDBBPFlag,          iSizeInBool  );
+#endif
+  
   memcpy( rpcCU->getDepth()  + m_uiAbsIdxInLCU, m_puhDepth,  iSizeInUchar );
   memcpy( rpcCU->getWidth()  + m_uiAbsIdxInLCU, m_puhWidth,  iSizeInUchar );
@@ -1640,4 +1678,8 @@
   }
 #endif
+#if H_3D_DBBP
+  memcpy( rpcCU->getDBBPFlag()          + uiPartOffset, m_pbDBBPFlag,          iSizeInBool  );
+#endif
+  
   memcpy( rpcCU->getDepth()  + uiPartOffset, m_puhDepth,  iSizeInUchar );
   memcpy( rpcCU->getWidth()  + uiPartOffset, m_puhWidth,  iSizeInUchar );
@@ -2378,4 +2420,79 @@
 
   return uiCtx;
+}
+#endif
+
+#if H_3D_DBBP
+Pel* TComDataCU::getVirtualDepthBlock(UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt& uiDepthStride)
+{
+  // get coded and reconstructed depth view
+  TComPicYuv* depthPicYuv = NULL;
+  Pel* pDepthPels = NULL;
+  
+  // DBBP is a texture coding tool
+  if( getSlice()->getIsDepth() )
+    return NULL;
+  
+#if H_3D_FCO
+  TComPic* depthPic = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
+  
+  if( depthPic && depthPic->getPicYuvRec() != NULL && depthPic->getIsDepth() )  // depth first
+  {
+    depthPicYuv = depthPic->getPicYuvRec();
+    depthPicYuv->extendPicBorder();
+    
+    // get collocated depth block for current CU
+    uiDepthStride = depthPicYuv->getStride();
+    pDepthPels    = depthPicYuv->getLumaAddr( getAddr(), uiAbsPartIdx );
+  }
+  else  // texture first
+#else
+  {
+    DisInfo DvInfo = getDvInfo(uiAbsPartIdx);
+    
+    TComPic* baseDepthPic = getSlice()->getIvPic (true, DvInfo.m_aVIdxCan);
+    
+    if( baseDepthPic == NULL || baseDepthPic->getPicYuvRec() == NULL )
+      return NULL;
+    
+    depthPicYuv   = baseDepthPic->getPicYuvRec();
+    depthPicYuv->extendPicBorder();
+    uiDepthStride = depthPicYuv->getStride();
+    
+    Int iBlkX = ( getAddr() % baseDepthPic->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ getZorderIdxInCU()+uiAbsPartIdx ] ];
+    Int iBlkY = ( getAddr() / baseDepthPic->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ getZorderIdxInCU()+uiAbsPartIdx ] ];
+    
+    Int iPictureWidth  = depthPicYuv->getWidth();
+    Int iPictureHeight = depthPicYuv->getHeight();
+    
+    Int iWidth  = uiWidth;
+    Int iHeight = uiHeight;
+    
+    Bool depthRefineFlag = false;
+#if H_3D_NBDV_REF
+    depthRefineFlag = m_pcSlice->getVPS()->getDepthRefinementFlag( m_pcSlice->getLayerIdInVps() );
+#endif // H_3D_NBDV_REF
+    
+    TComMv cDv = depthRefineFlag ? DvInfo.m_acDoNBDV : DvInfo.m_acNBDV;
+    
+    Int depthPosX = Clip3(0,   iPictureWidth - iWidth,  iBlkX + ((cDv.getHor()+2)>>2));
+    Int depthPosY = Clip3(0,   iPictureHeight- iHeight, iBlkY + ((cDv.getVer()+2)>>2));
+    
+    pDepthPels = depthPicYuv->getLumaAddr() + depthPosX + depthPosY * uiDepthStride;
+  }
+#endif
+  
+  AOF( depthPicYuv != NULL );
+  AOF( pDepthPels != NULL );
+  AOF( uiDepthStride != 0 );
+  
+  return pDepthPels;
+}
+#endif
+
+#if H_3D_DBBP
+Void TComDataCU::setDBBPFlagSubParts ( Bool bDBBPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
+{
+  setSubPart( bDBBPFlag, m_pbDBBPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
 }
 #endif
@@ -4030,4 +4147,7 @@
 #if H_3D_ARP
   Bool bARPFlag = getARPW(uiAbsPartIdx)>0 ? true : false;
+#endif
+#if H_3D_DBBP
+  Bool bDBBPFlag = getDBBPFlag(uiAbsPartIdx);
 #endif
 
@@ -4696,4 +4816,7 @@
       pbSPIVMPFlag[iCount] = true;
 #endif
+#if H_3D_DBBP
+      pbSPIVMPFlag[iCount] &= !bDBBPFlag;
+#endif
       if( ( ivCandDir[0] & 1 ) == 1 )
       {
@@ -5809,4 +5932,9 @@
   Int height = 0;
   UInt partAddr;
+  
+#if H_3D_DBBP
+  if( getDBBPFlag(0) )
+    return true;
+#endif
 
   getPartIndexAndSize( puIdx, partAddr, width, height );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComDataCU.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComDataCU.h	(revision 816)
@@ -97,4 +97,21 @@
 };
 
+#if H_3D_DBBP
+typedef struct _DBBPTmpData
+{
+  TComMv      acMvd[2][2];          // for two segments and two lists
+  TComMvField acMvField[2][2];      // for two segments and two lists
+  Int         aiMvpNum[2][2];       // for two segments and two lists
+  Int         aiMvpIdx[2][2];       // for two segments and two lists
+  UChar       auhInterDir[2];       // for two segments
+  Bool        abMergeFlag[2];       // for two segments
+  UChar       auhMergeIndex[2];     // for two segments
+  Char        ahVSPFlag[2];         // for two segments
+  DisInfo     acDvInfo[2];          // for two segments
+  
+  PartSize    eVirtualPartSize;
+  UInt        uiVirtualPartIndex;
+} DBBPTmpData;
+#endif
 
 // ====================================================================================================================
@@ -223,4 +240,8 @@
   UChar*        m_pucInterSDCMask;
 #endif
+#if H_3D_DBBP
+  Bool*         m_pbDBBPFlag;        ///< array of DBBP flags
+  DBBPTmpData   m_sDBBPTmpData;
+#endif
 #if H_3D
   Bool          m_bAvailableFlagA1;    ///< A1 available flag
@@ -362,4 +383,8 @@
   Void          setCUTransquantBypassSubParts( Bool flag, UInt uiAbsPartIdx, UInt uiDepth );
   
+#if H_3D_DBBP
+  Pel*          getVirtualDepthBlock(UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt& uiDepthStride);
+#endif
+  
   Bool*        getSkipFlag            ()                        { return m_skipFlag;          }
   Bool         getSkipFlag            (UInt idx)                { return m_skipFlag[idx];     }
@@ -373,4 +398,12 @@
   Void          setPredictionMode     ( UInt uiIdx, PredMode uh){ m_pePredMode[uiIdx] = uh;   }
   Void          setPredModeSubParts   ( PredMode eMode, UInt uiAbsPartIdx, UInt uiDepth );
+  
+#if H_3D_DBBP
+  Bool*         getDBBPFlag           ()                        { return m_pbDBBPFlag;               }
+  Bool          getDBBPFlag           ( UInt uiIdx )            { return m_pbDBBPFlag[uiIdx];        }
+  Void          setDBBPFlag           ( UInt uiIdx, Bool b )    { m_pbDBBPFlag[uiIdx] = b;           }
+  Void          setDBBPFlagSubParts   ( Bool bDBBPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth );
+  DBBPTmpData*  getDBBPTmpData        () { return &m_sDBBPTmpData; }
+#endif
   
   UChar*        getWidth              ()                        { return m_puhWidth;          }
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComPrediction.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComPrediction.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComPrediction.cpp	(revision 816)
@@ -601,4 +601,275 @@
 #endif
 
+#if H_3D_DBBP
+PartSize TComPrediction::getPartitionSizeFromDepth(Pel* pDepthPels, UInt uiDepthStride, UInt uiSize)
+{
+  // find virtual partitioning for this CU based on depth block
+  // segmentation of texture block --> mask IDs
+  Pel*  pDepthBlockStart      = pDepthPels;
+  
+  // first compute average of depth block for thresholding
+  Int iSumDepth = 0;
+  Int iSubSample = 4;
+  for (Int y=0; y<uiSize; y+=iSubSample)
+  {
+    for (Int x=0; x<uiSize; x+=iSubSample)
+    {
+      Int depthPel = pDepthPels[x];
+      
+      iSumDepth += depthPel;
+    }
+    
+    // next row
+    pDepthPels += uiDepthStride*iSubSample;
+  }
+  
+  Int iSizeInBits = g_aucConvertToBit[uiSize] - g_aucConvertToBit[iSubSample];  // respect sub-sampling factor
+  Int iMean = iSumDepth >> iSizeInBits*2;       // iMean /= (uiWidth*uiHeight);
+  AOF( iMean == iSumDepth/((uiSize/iSubSample)*(uiSize/iSubSample) ) );
+  AOF( iMean >= 0 && iMean < 256);
+  
+  // start again for segmentation
+  pDepthPels = pDepthBlockStart;
+  
+  // start mapping process
+  Bool bAMPAvail = uiSize > 8;
+  Int matchedPartSum[6][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}; // counter for each part size and boolean option
+  PartSize virtualPartSizes[6] = { SIZE_Nx2N, SIZE_2NxN, SIZE_2NxnU, SIZE_2NxnD, SIZE_nLx2N, SIZE_nRx2N };
+  
+  UInt uiHalfSize = uiSize>>1;
+  UInt uiQuarterSize = uiSize>>2;
+  
+  for (Int y=0; y<uiSize; y+=iSubSample)
+  {
+    for (Int x=0; x<uiSize; x+=iSubSample)
+    {
+      Int depthPel = pDepthPels[x];
+      
+      // decide which segment this pixel belongs to
+      Int ucSegment = (Int)(depthPel>iMean);
+      AOF( ucSegment == 0 || ucSegment == 1 );
+      
+      // Matched Filter to find optimal (conventional) partitioning
+      
+      // SIZE_Nx2N
+      if(x<uiHalfSize)  // left
+        matchedPartSum[0][ucSegment]++;
+      else  // right
+        matchedPartSum[0][1-ucSegment]++;
+      
+      // SIZE_2NxN
+      if(y<uiHalfSize)  // top
+        matchedPartSum[1][ucSegment]++;
+      else  // bottom
+        matchedPartSum[1][1-ucSegment]++;
+      
+      if( bAMPAvail )
+      {
+        // SIZE_2NxnU
+        if(y<uiQuarterSize)  // top (1/4)
+          matchedPartSum[2][ucSegment]++;
+        else  // bottom (3/4)
+          matchedPartSum[2][1-ucSegment]++;
+        
+        // SIZE_2NxnD
+        if(y<(uiQuarterSize*3))  // top (3/4)
+          matchedPartSum[3][ucSegment]++;
+        else  // bottom (1/4)
+          matchedPartSum[3][1-ucSegment]++;
+        
+        // SIZE_nLx2N
+        if(x<uiQuarterSize)  // left (1/4)
+          matchedPartSum[4][ucSegment]++;
+        else  // right (3/4)
+          matchedPartSum[4][1-ucSegment]++;
+        
+        // SIZE_nRx2N
+        if(x<(uiQuarterSize*3))  // left (3/4)
+          matchedPartSum[5][ucSegment]++;
+        else  // right (1/4)
+          matchedPartSum[5][1-ucSegment]++;
+      }
+    }
+    
+    // next row
+    pDepthPels += uiDepthStride*iSubSample;
+  }
+  
+  PartSize matchedPartSize = SIZE_NONE;
+  
+  Int iMaxMatchSum = 0;
+  for(Int p=0; p<6; p++)  // loop over partition sizes
+  {
+    for( Int b=0; b<=1; b++ ) // loop over boolean options
+    {
+      if(matchedPartSum[p][b] > iMaxMatchSum)
+      {
+        iMaxMatchSum = matchedPartSum[p][b];
+        matchedPartSize = virtualPartSizes[p];
+      }
+    }
+  }
+  
+  AOF( matchedPartSize != SIZE_NONE );
+  
+  return matchedPartSize;
+}
+
+Bool TComPrediction::getSegmentMaskFromDepth( Pel* pDepthPels, UInt uiDepthStride, UInt uiWidth, UInt uiHeight, Bool* pMask )
+{
+  AOF( uiWidth == uiHeight );
+  
+  // segmentation of texture block --> mask IDs
+  Pel*  pDepthBlockStart      = pDepthPels;
+  
+  // first compute average of depth block for thresholding
+  Int iSumDepth = 0;
+  Int uiMinDepth = MAX_INT;
+  Int uiMaxDepth = 0;
+  for (Int y=0; y<uiHeight; y++)
+  {
+    for (Int x=0; x<uiWidth; x++)
+    {
+      Int depthPel = pDepthPels[x];
+      iSumDepth += depthPel;
+      
+      if( depthPel > uiMaxDepth )
+        uiMaxDepth = depthPel;
+      if( depthPel < uiMinDepth )
+        uiMinDepth = depthPel;
+    }
+    
+    // next row
+    pDepthPels += uiDepthStride;
+  }
+  
+  // don't generate mask for blocks with small depth range (encoder decision)
+  if( uiMaxDepth - uiMinDepth < 10 )
+    return false;
+  
+  Int iSizeInBits = g_aucConvertToBit[uiWidth]+2;
+  Int iMean = iSumDepth >> iSizeInBits*2;       // iMean /= (uiWidth*uiHeight);
+  AOF( iMean == iSumDepth/(uiWidth*uiHeight) );
+  AOF( iMean >= 0 && iMean < 256);
+  
+  // start again for segmentation
+  pDepthPels = pDepthBlockStart;
+  
+  Bool bInvertMask = pDepthPels[0]>iMean; // top-left segment needs to be mapped to partIdx 0
+  
+  // generate mask
+  UInt uiSumPix[2] = {0,0};
+  for (Int y=0; y<uiHeight; y++)
+  {
+    for (Int x=0; x<uiHeight; x++)
+    {
+      Int depthPel = pDepthPels[x];
+      
+      // decide which segment this pixel belongs to
+      Int ucSegment = (Int)(depthPel>iMean);
+      AOF( ucSegment == 0 || ucSegment == 1 );
+      
+      if( bInvertMask )
+        ucSegment = 1-ucSegment;
+      
+      // count pixels for each segment
+      uiSumPix[ucSegment]++;
+      
+      // set mask value
+      pMask[x] = (Bool)ucSegment;
+    }
+    
+    // next row
+    pDepthPels += uiDepthStride;
+    pMask += MAX_CU_SIZE;
+  }
+  
+  // don't generate valid mask for tiny segments (encoder decision)
+  // each segment needs to cover at least 1/8th of block
+  UInt uiMinPixPerSegment = (uiWidth*uiHeight) >> 3;
+  if( !( uiSumPix[0] > uiMinPixPerSegment && uiSumPix[1] > uiMinPixPerSegment ) )
+    return false;
+  
+  // all good
+  return true;
+}
+
+Void TComPrediction::combineSegmentsWithMask( TComYuv* pInYuv[2], TComYuv* pOutYuv, Bool* pMask, UInt uiWidth, UInt uiHeight, UInt uiPartAddr )
+{
+  Pel*  piSrc[2]    = {pInYuv[0]->getLumaAddr(uiPartAddr), pInYuv[1]->getLumaAddr(uiPartAddr)};
+  UInt  uiSrcStride = pInYuv[0]->getStride();
+  Pel*  piDst       = pOutYuv->getLumaAddr(uiPartAddr);
+  UInt  uiDstStride = pOutYuv->getStride();
+  
+  UInt  uiMaskStride= MAX_CU_SIZE;
+  
+  // backup pointer
+  Bool* pMaskStart = pMask;
+  
+  // combine luma first
+  for (Int y=0; y<uiHeight; y++)
+  {
+    for (Int x=0; x<uiWidth; x++)
+    {
+      UChar ucSegment = (UChar)pMask[x];
+      AOF( ucSegment < 2 );
+      
+      // filtering
+      Bool t = (y==0)?pMaskStart[(y+1)*uiMaskStride+x]:pMaskStart[(y-1)*uiMaskStride+x];
+      Bool l = (x==0)?pMaskStart[y*uiMaskStride+x+1]:pMaskStart[y*uiMaskStride+x-1];
+      Bool b = (y==uiHeight-1)?pMaskStart[(y-1)*uiMaskStride+x]:pMaskStart[(y+1)*uiMaskStride+x];
+      Bool r = (x==uiWidth-1)?pMaskStart[y*uiMaskStride+x-1]:pMaskStart[y*uiMaskStride+x+1];
+      
+      Bool bBlend = !((t&&l&&b&&r) || (!t&&!l&&!b&&!r));
+      piDst[x] = bBlend?((piSrc[0][x]+piSrc[1][x]+1)>>1):piSrc[ucSegment][x];
+    }
+    
+    piSrc[0]  += uiSrcStride;
+    piSrc[1]  += uiSrcStride;
+    piDst     += uiDstStride;
+    pMask     += uiMaskStride;
+  }
+  
+  // now combine chroma
+  Pel*  piSrcU[2]       = { pInYuv[0]->getCbAddr(uiPartAddr), pInYuv[1]->getCbAddr(uiPartAddr) };
+  Pel*  piSrcV[2]       = { pInYuv[0]->getCrAddr(uiPartAddr), pInYuv[1]->getCrAddr(uiPartAddr) };
+  UInt  uiSrcStrideC    = pInYuv[0]->getCStride();
+  Pel*  piDstU          = pOutYuv->getCbAddr(uiPartAddr);
+  Pel*  piDstV          = pOutYuv->getCrAddr(uiPartAddr);
+  UInt  uiDstStrideC    = pOutYuv->getCStride();
+  UInt  uiWidthC        = uiWidth >> 1;
+  UInt  uiHeightC       = uiHeight >> 1;
+  pMask = pMaskStart;
+  
+  for (Int y=0; y<uiHeightC; y++)
+  {
+    for (Int x=0; x<uiWidthC; x++)
+    {
+      UChar ucSegment = (UChar)pMask[x*2];
+      AOF( ucSegment < 2 );
+      
+      // filtering
+      Bool t = (y==0)?pMaskStart[(y+1)*2*uiMaskStride+x*2]:pMaskStart[(y-1)*2*uiMaskStride+x*2];
+      Bool l = (x==0)?pMaskStart[y*2*uiMaskStride+(x+1)*2]:pMaskStart[y*2*uiMaskStride+(x-1)*2];
+      Bool b = (y==uiHeightC-1)?pMaskStart[(y-1)*2*uiMaskStride+x*2]:pMaskStart[(y+1)*2*uiMaskStride+x*2];
+      Bool r = (x==uiWidthC-1)?pMaskStart[y*2*uiMaskStride+(x-1)*2]:pMaskStart[y*2*uiMaskStride+(x+1)*2];
+      
+      Bool bBlend = !((t&&l&&b&&r) || (!t&&!l&&!b&&!r));
+      
+      piDstU[x] = bBlend?((piSrcU[0][x]+piSrcU[1][x]+1)>>1):piSrcU[ucSegment][x];
+      piDstV[x] = bBlend?((piSrcV[0][x]+piSrcV[1][x]+1)>>1):piSrcV[ucSegment][x];
+    }
+    
+    piSrcU[0]   += uiSrcStrideC;
+    piSrcU[1]   += uiSrcStrideC;
+    piSrcV[0]   += uiSrcStrideC;
+    piSrcV[1]   += uiSrcStrideC;
+    piDstU      += uiDstStrideC;
+    piDstV      += uiDstStrideC;
+    pMask       += 2*uiMaskStride;
+  }
+}
+#endif
+
 Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
 {
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComPrediction.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComPrediction.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComPrediction.h	(revision 816)
@@ -179,4 +179,10 @@
 #endif
 #endif
+  
+#if H_3D_DBBP
+  PartSize      getPartitionSizeFromDepth(Pel* pDepthPels, UInt uiDepthStride, UInt uiSize);
+  Bool          getSegmentMaskFromDepth( Pel* pDepthPels, UInt uiDepthStride, UInt uiWidth, UInt uiHeight, Bool* pMask );
+  Void          combineSegmentsWithMask( TComYuv* pInYuv[2], TComYuv* pOutYuv, Bool* pMask, UInt uiWidth, UInt uiHeight, UInt uiPartAddr = 0 );
+#endif
 
   Pel  predIntraGetPredValDC      ( Int* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight, Bool bAbove, Bool bLeft );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRdCost.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRdCost.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRdCost.cpp	(revision 816)
@@ -326,4 +326,20 @@
   rcDistParam.DistFunc = m_afpDistortFunc[eDFunc + g_aucConvertToBit[ rcDistParam.iCols ] + 1 ];
   
+#if H_3D_DBBP
+  if( g_bTestVirtualParts )
+  {
+    if( eDFunc >= DF_SSE && eDFunc <= DF_SSE16N )
+      rcDistParam.DistFunc = TComRdCost::xGetMaskedSSE;
+    else if( eDFunc >= DF_SAD && eDFunc <= DF_SADS16N )
+      rcDistParam.DistFunc = TComRdCost::xGetMaskedSAD;
+    else if( eDFunc >= DF_HADS && eDFunc <= DF_HADS16N )
+      rcDistParam.DistFunc = TComRdCost::xGetMaskedHADs;
+    else if( eDFunc >= DF_VSD && eDFunc <= DF_VSD16N )
+      rcDistParam.DistFunc = TComRdCost::xGetMaskedVSD;
+    else if( eDFunc >= DF_SAD12 && eDFunc <= DF_SADS48 )
+      rcDistParam.DistFunc = TComRdCost::xGetMaskedSAD;
+  }
+#endif
+  
   // initialize
   rcDistParam.iSubShift  = 0;
@@ -357,4 +373,11 @@
   {
     rcDistParam.DistFunc = m_afpDistortFunc[45 ];
+  }
+#endif
+  
+#if H_3D_DBBP
+  if( g_bTestVirtualParts )
+  {
+    rcDistParam.DistFunc = TComRdCost::xGetMaskedSAD;
   }
 #endif
@@ -411,4 +434,14 @@
     rcDistParam.DistFunc = m_afpDistortFunc[DF_HADS + g_aucConvertToBit[ rcDistParam.iCols ] + 1 ];
   }
+  
+#if H_3D_DBBP
+  if( g_bTestVirtualParts )
+  {
+    if( !bHADME )
+      rcDistParam.DistFunc = TComRdCost::xGetMaskedSAD;
+    else
+      rcDistParam.DistFunc = TComRdCost::xGetMaskedHADs;
+  }
+#endif
   
   // initialize
@@ -433,4 +466,15 @@
   rcDP.bitDepth   = bitDepth;
   rcDP.DistFunc   = m_afpDistortFunc[ ( bHadamard ? DF_HADS : DF_SADS ) + g_aucConvertToBit[ iWidth ] + 1 ];
+  
+#if H_3D_DBBP
+  if( g_bTestVirtualParts )
+  {
+    if( !bHadamard )
+      rcDP.DistFunc = TComRdCost::xGetMaskedSAD;
+    else
+      rcDP.DistFunc = TComRdCost::xGetMaskedHADs;
+  }
+#endif
+  
 #if NS_HAD
   rcDP.bUseNSHAD  = bUseNSHAD;
@@ -631,4 +675,215 @@
 // Distortion functions
 // ====================================================================================================================
+
+#if H_3D_DBBP
+// --------------------------------------------------------------------------------------------------------------------
+// Masked distortion functions
+// --------------------------------------------------------------------------------------------------------------------
+
+UInt TComRdCost::xGetMaskedSSE( DistParam* pcDtParam )
+{
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iCols   = pcDtParam->iCols;
+  Int  iStrideOrg = pcDtParam->iStrideOrg;
+  Int  iStrideCur = pcDtParam->iStrideCur;
+  
+  UInt uiSum = 0;
+  
+  UInt uiShift = DISTORTION_PRECISION_ADJUSTMENT((pcDtParam->bitDepth-8) << 1);
+  
+  Int iTemp;
+  
+  for( ; iRows != 0; iRows-- )
+  {
+    for (Int n = 0; n < iCols; n++ )
+    {
+      if( piOrg[n] != DBBP_INVALID_SHORT )
+      {
+        iTemp = piOrg[n  ] - piCur[n  ];
+        uiSum += ( iTemp * iTemp ) >> uiShift;
+      }
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+  
+  return ( uiSum );
+}
+
+UInt TComRdCost::xGetMaskedSAD( DistParam* pcDtParam )
+{
+  
+  AOF(!pcDtParam->bApplyWeight);
+#if H_3D_IC
+  AOF(!pcDtParam->bUseIC);
+#endif
+  
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iCols   = pcDtParam->iCols;
+  Int  iStrideCur = pcDtParam->iStrideCur;
+  Int  iStrideOrg = pcDtParam->iStrideOrg;
+  
+  UInt uiSum = 0;
+  
+  for( ; iRows != 0; iRows-- )
+  {
+    for (Int n = 0; n < iCols; n++ )
+    {
+      if( piOrg[n] != DBBP_INVALID_SHORT )
+        uiSum += abs( piOrg[n] - piCur[n] );
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+  
+  return uiSum >> DISTORTION_PRECISION_ADJUSTMENT(pcDtParam->bitDepth-8);
+}
+
+UInt TComRdCost::xGetMaskedHADs( DistParam* pcDtParam )
+{
+  AOF(!pcDtParam->bApplyWeight);
+#if H_3D_IC
+  AOF(!pcDtParam->bUseIC);
+#endif
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iCols   = pcDtParam->iCols;
+  Int  iStrideCur = pcDtParam->iStrideCur;
+  Int  iStrideOrg = pcDtParam->iStrideOrg;
+  Int  iStep  = pcDtParam->iStep;
+  
+  Int  x, y;
+  
+  UInt uiSum = 0;
+  
+#if NS_HAD
+  if( ( ( iRows % 8 == 0) && (iCols % 8 == 0) && ( iRows == iCols ) ) || ( ( iRows % 8 == 0 ) && (iCols % 8 == 0) && !pcDtParam->bUseNSHAD ) )
+#else
+    if( ( iRows % 8 == 0) && (iCols % 8 == 0) )
+#endif
+    {
+      Int  iOffsetOrg = iStrideOrg<<3;
+      Int  iOffsetCur = iStrideCur<<3;
+      for ( y=0; y<iRows; y+= 8 )
+      {
+        for ( x=0; x<iCols; x+= 8 )
+        {
+          if( piOrg[x] != DBBP_INVALID_SHORT )
+            uiSum += xCalcHADs8x8( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+        }
+        piOrg += iOffsetOrg;
+        piCur += iOffsetCur;
+      }
+    }
+#if NS_HAD
+    else if ( ( iCols > 8 ) && ( iCols > iRows ) && pcDtParam->bUseNSHAD )
+    {
+      Int  iOffsetOrg = iStrideOrg<<2;
+      Int  iOffsetCur = iStrideCur<<2;
+      for ( y=0; y<iRows; y+= 4 )
+      {
+        for ( x=0; x<iCols; x+= 16 )
+        {
+          if( piOrg[x] != DBBP_INVALID_SHORT )
+            uiSum += xCalcHADs16x4( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+        }
+        piOrg += iOffsetOrg;
+        piCur += iOffsetCur;
+      }
+    }
+    else if ( ( iRows > 8 ) && ( iCols < iRows ) && pcDtParam->bUseNSHAD )
+    {
+      Int  iOffsetOrg = iStrideOrg<<4;
+      Int  iOffsetCur = iStrideCur<<4;
+      for ( y=0; y<iRows; y+= 16 )
+      {
+        for ( x=0; x<iCols; x+= 4 )
+        {
+          if( piOrg[x] != DBBP_INVALID_SHORT )
+            uiSum += xCalcHADs4x16( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+        }
+        piOrg += iOffsetOrg;
+        piCur += iOffsetCur;
+      }
+    }
+#endif
+    else if( ( iRows % 4 == 0) && (iCols % 4 == 0) )
+    {
+      Int  iOffsetOrg = iStrideOrg<<2;
+      Int  iOffsetCur = iStrideCur<<2;
+      
+      for ( y=0; y<iRows; y+= 4 )
+      {
+        for ( x=0; x<iCols; x+= 4 )
+        {
+          if( piOrg[x] != DBBP_INVALID_SHORT )
+            uiSum += xCalcHADs4x4( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+        }
+        piOrg += iOffsetOrg;
+        piCur += iOffsetCur;
+      }
+    }
+    else if( ( iRows % 2 == 0) && (iCols % 2 == 0) )
+    {
+      Int  iOffsetOrg = iStrideOrg<<1;
+      Int  iOffsetCur = iStrideCur<<1;
+      for ( y=0; y<iRows; y+=2 )
+      {
+        for ( x=0; x<iCols; x+=2 )
+        {
+          if( piOrg[x] != DBBP_INVALID_SHORT )
+            uiSum += xCalcHADs2x2( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+        }
+        piOrg += iOffsetOrg;
+        piCur += iOffsetCur;
+      }
+    }
+    else
+    {
+      assert(false);
+    }
+  
+  return uiSum >> DISTORTION_PRECISION_ADJUSTMENT(pcDtParam->bitDepth-8);
+}
+
+UInt TComRdCost::xGetMaskedVSD( DistParam* pcDtParam )
+{
+  Pel* piOrg    = pcDtParam->pOrg;
+  Pel* piCur    = pcDtParam->pCur;
+  Pel* piVirRec = pcDtParam->pVirRec;
+  Pel* piVirOrg = pcDtParam->pVirOrg;
+  Int  iRows    = pcDtParam->iRows;
+  Int  iCols    = pcDtParam->iCols;
+  Int  iStrideOrg = pcDtParam->iStrideOrg;
+  Int  iStrideCur = pcDtParam->iStrideCur;
+  Int  iStrideVir = pcDtParam->iStrideVir;
+  
+  UInt uiSum = 0;
+  UInt uiShift = DISTORTION_PRECISION_ADJUSTMENT(pcDtParam->bitDepth-8)<<1;
+  
+  Int dDM;
+  
+  for ( Int y = 0 ; y < iRows ; y++ )
+  {
+    for (Int x = 0; x < iCols; x++ )
+    {
+      if( piOrg[x] != DBBP_INVALID_SHORT )
+      {
+        dDM = (Int) ( piOrg[x  ] - piCur[x  ] );
+        uiSum += getVSDEstimate( dDM, piOrg, iStrideOrg, piVirRec, piVirOrg, iStrideVir, x, y ) >> uiShift;
+      }
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+  
+  return ( uiSum );
+}
+#endif
 
 // --------------------------------------------------------------------------------------------------------------------
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRdCost.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRdCost.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRdCost.h	(revision 816)
@@ -334,4 +334,11 @@
 #endif
   
+#if H_3D_DBBP
+  static UInt xGetMaskedSSE     ( DistParam* pcDtParam );
+  static UInt xGetMaskedSAD     ( DistParam* pcDtParam );
+  static UInt xGetMaskedHADs    ( DistParam* pcDtParam );
+  static UInt xGetMaskedVSD     ( DistParam* pcDtParam );
+#endif
+  
 public:
 #if WEIGHTED_CHROMA_DISTORTION
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRom.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRom.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRom.cpp	(revision 816)
@@ -106,4 +106,8 @@
 // ====================================================================================================================
 
+#if H_3D_DBBP
+Bool g_bTestVirtualParts;
+#endif
+
 UInt g_uiMaxCUWidth  = MAX_CU_SIZE;
 UInt g_uiMaxCUHeight = MAX_CU_SIZE;
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRom.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRom.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComRom.h	(revision 816)
@@ -72,4 +72,8 @@
 // ====================================================================================================================
 
+#if H_3D_DBBP
+extern       Bool   g_bTestVirtualParts;
+#endif
+
 // flexible conversion from relative to absolute index
 extern       UInt   g_auiZscanToRaster[ MAX_NUM_SPU_W*MAX_NUM_SPU_W ];
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComSlice.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComSlice.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComSlice.cpp	(revision 816)
@@ -1827,4 +1827,7 @@
 #if H_3D_INTER_SDC
     m_bInterSDCFlag        [ i ] = false;
+#endif
+#if H_3D_DBBP
+    m_dbbpFlag             [ i ] = false;
 #endif
 #if H_3D_IV_MERGE
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComSlice.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TComSlice.h	(revision 816)
@@ -805,4 +805,7 @@
   Bool        m_bInterSDCFlag[MAX_NUM_LAYERS   ];
 #endif
+#if H_3D_DBBP
+  Bool        m_dbbpFlag[MAX_NUM_LAYERS];
+#endif
 #if H_3D_IV_MERGE
   Bool        m_bMPIFlag[MAX_NUM_LAYERS   ];
@@ -955,5 +958,5 @@
   Bool    inferOutputLayerFlag( Int layerSetIdx, Int i )                   { return ( getDefaultOneTargetOutputLayerIdc( ) == 0 || ( ( getDefaultOneTargetOutputLayerIdc( ) == 1 ) && ( i == m_layerSetLayerIdList[layerSetIdx].size() - 1  ) ));  }
 
-  Void    setProfileLevelTierIdx( Int outLayerSetIdx, Int val )            { m_profileLevelTierIdx[ outLayerSetIdx  = val ]; }
+  Void    setProfileLevelTierIdx( Int outLayerSetIdx, Int val )            { m_profileLevelTierIdx[ outLayerSetIdx ] = val; }
   Int     getProfileLevelTierIdx( Int outLayerSetIdx )                     { return m_profileLevelTierIdx[ outLayerSetIdx ]; } 
   Void    setAltOutputLayerFlag( Bool flag )                               { m_altOutputLayerFlag = flag; } 
@@ -1081,4 +1084,8 @@
   Bool    getInterSDCFlag      ( Int layerIdInVps )           { return m_bInterSDCFlag[layerIdInVps]; }
   Void    setInterSDCFlag      ( Int layerIdInVps, Bool bval ){ m_bInterSDCFlag[layerIdInVps] = bval; }
+#endif
+#if H_3D_DBBP
+  Bool getUseDBBP              ( Int layerIdInVps )         { return m_dbbpFlag[layerIdInVps]; }
+  Void setUseDBBP              ( Int layerIdInVps, Bool bval ){ m_dbbpFlag[layerIdInVps] = bval; }
 #endif
 #if H_3D_IV_MERGE
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TypeDef.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibCommon/TypeDef.h	(revision 816)
@@ -179,4 +179,7 @@
 #define H_3D_FCO                          0   // Flexible coding order for 3D
 
+#define H_3D_DBBP                         1   // DBBP: Depth-based Block Partitioning and Merging
+
+
 
 
@@ -269,4 +272,10 @@
 #define IC_CONST_SHIFT                    5
 #define IC_SHIFT_DIFF                     12
+#endif
+
+///// ***** DEPTH-BASED BLOCK PARTITIONING *********
+#if H_3D_DBBP
+#define DBBP_INVALID_SHORT                (-4)
+#define RWTH_DBBP_PACK_MODE               SIZE_2NxN
 #endif
 
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 816)
@@ -1714,4 +1714,7 @@
         READ_FLAG( uiCode, "view_synthesis_pred_flag[i]"); pcVPS->setViewSynthesisPredFlag( i, uiCode == 1 ? true : false );
 #endif
+#if H_3D_DBBP
+          READ_FLAG( uiCode, "use_dbbp_flag[i]" ); pcVPS->setUseDBBP( i, uiCode == 1 ? true : false );
+#endif
       }
       else
@@ -2794,4 +2797,10 @@
 }
 #endif
+#if H_3D_DBBP
+  Void TDecCavlc::parseDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
+  {
+    assert(0);
+  }
+#endif
 // ====================================================================================================================
 // Protected member functions
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCAVLC.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 816)
@@ -127,4 +127,7 @@
   Void  parseInterSDCResidualData ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPart );
 #endif
+#if H_3D_DBBP
+  Void  parseDBBPFlag       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#endif
   Void parseSplitFlag       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
   Void parsePartSize        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCu.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCu.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCu.cpp	(revision 816)
@@ -50,4 +50,7 @@
   m_ppcYuvReco = NULL;
   m_ppcCU      = NULL;
+#if H_3D_DBBP
+  m_ppcYuvRecoDBBP = NULL;
+#endif
 }
 
@@ -75,4 +78,7 @@
   m_ppcYuvReco = new TComYuv*[m_uiMaxDepth-1];
   m_ppcCU      = new TComDataCU*[m_uiMaxDepth-1];
+#if H_3D_DBBP
+  m_ppcYuvRecoDBBP = new TComYuv*[m_uiMaxDepth-1];
+#endif
   
   UInt uiNumPartitions;
@@ -86,4 +92,7 @@
     m_ppcYuvReco[ui] = new TComYuv;    m_ppcYuvReco[ui]->create( uiWidth, uiHeight );
     m_ppcCU     [ui] = new TComDataCU; m_ppcCU     [ui]->create( uiNumPartitions, uiWidth, uiHeight, true, uiMaxWidth >> (m_uiMaxDepth - 1) );
+#if H_3D_DBBP
+    m_ppcYuvRecoDBBP[ui] = new TComYuv;    m_ppcYuvRecoDBBP[ui]->create( uiWidth, uiHeight );
+#endif
   }
   
@@ -106,4 +115,7 @@
     m_ppcYuvReco[ui]->destroy(); delete m_ppcYuvReco[ui]; m_ppcYuvReco[ui] = NULL;
     m_ppcCU     [ui]->destroy(); delete m_ppcCU     [ui]; m_ppcCU     [ui] = NULL;
+#if H_3D_DBBP
+    m_ppcYuvRecoDBBP[ui]->destroy(); delete m_ppcYuvRecoDBBP[ui]; m_ppcYuvRecoDBBP[ui] = NULL;
+#endif
   }
   
@@ -111,4 +123,7 @@
   delete [] m_ppcYuvReco; m_ppcYuvReco = NULL;
   delete [] m_ppcCU     ; m_ppcCU      = NULL;
+#if H_3D_DBBP
+  delete [] m_ppcYuvRecoDBBP; m_ppcYuvRecoDBBP = NULL;
+#endif
 }
 
@@ -618,4 +633,12 @@
   {
     case MODE_INTER:
+#if H_3D_DBBP
+      if( m_ppcCU[uiDepth]->getDBBPFlag(0) )
+      {
+        xReconInterDBBP( m_ppcCU[uiDepth], uiAbsPartIdx, uiDepth );
+      }
+      else
+      {
+#endif
 #if H_3D_INTER_SDC
       if( m_ppcCU[uiDepth]->getInterSDCFlag( 0 ) )
@@ -628,4 +651,7 @@
       xReconInter( m_ppcCU[uiDepth], uiDepth );
 #if H_3D_INTER_SDC
+      }
+#endif
+#if H_3D_DBBP
       }
 #endif
@@ -717,4 +743,137 @@
     pRecCb += uiStrideC;
     pRecCr += uiStrideC;
+  }
+}
+#endif
+
+#if H_3D_DBBP
+Void TDecCu::xReconInterDBBP( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
+{
+  AOF(!pcCU->getSlice()->getIsDepth());
+  AOF(!pcCU->getSlice()->isIntra());
+  PartSize ePartSize = pcCU->getPartitionSize( 0 );
+  AOF( uiAbsPartIdx == pcCU->getZorderIdxInCU() );
+  
+  // get collocated depth block
+  UInt uiDepthStride = 0;
+  Pel* pDepthPels = pcCU->getVirtualDepthBlock(0, pcCU->getWidth(0), pcCU->getHeight(0), uiDepthStride);
+  AOF( pDepthPels != NULL );
+  AOF( uiDepthStride != 0 );
+  
+  // compute mask by segmenting depth block
+  AOF( pcCU->getWidth(0) == m_ppcYuvReco[uiDepth]->getWidth() );
+  Bool pMask[MAX_CU_SIZE*MAX_CU_SIZE];
+  Bool bValidMask = m_pcPrediction->getSegmentMaskFromDepth(pDepthPels, uiDepthStride, pcCU->getWidth(0), pcCU->getHeight(0), pMask);
+  AOF(bValidMask);
+  
+  DBBPTmpData* pDBBPTmpData = pcCU->getDBBPTmpData();
+  TComYuv* apSegPredYuv[2] = { m_ppcYuvReco[uiDepth], m_ppcYuvRecoDBBP[uiDepth] };
+  
+  // first, extract the two sets of motion parameters
+  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4;
+  for( UInt uiSegment = 0; uiSegment < 2; uiSegment++ )
+  {
+    UInt uiPartAddr = uiSegment*uiPUOffset;
+    
+    pDBBPTmpData->auhInterDir[uiSegment] = pcCU->getInterDir(uiPartAddr);
+    
+    for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+    {
+      RefPicList eRefList = (RefPicList)uiRefListIdx;
+      pcCU->getMvField(pcCU, uiPartAddr, eRefList, pDBBPTmpData->acMvField[uiSegment][eRefList]);
+    }
+    
+    pDBBPTmpData->ahVSPFlag[uiSegment] = pcCU->getVSPFlag( uiPartAddr );
+    pDBBPTmpData->acDvInfo[uiSegment] = pcCU->getDvInfo( uiPartAddr );
+  }
+  
+  // do motion compensation for each segment as 2Nx2N
+  pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
+  pcCU->setPredModeSubParts( MODE_INTER, 0, uiDepth );
+  for( UInt uiSegment = 0; uiSegment < 2; uiSegment++ )
+  {
+    pcCU->setInterDirSubParts( pDBBPTmpData->auhInterDir[uiSegment], 0, 0, uiDepth );
+    
+    pcCU->setVSPFlagSubParts( pDBBPTmpData->ahVSPFlag[uiSegment], 0, 0, uiDepth );
+    pcCU->setDvInfoSubParts( pDBBPTmpData->acDvInfo[uiSegment], 0, 0, uiDepth );
+    
+    for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+    {
+      RefPicList eRefList = (RefPicList)uiRefListIdx;
+#if NTT_STORE_SPDV_VSP_G0148
+      if( pcCU->getVSPFlag( 0 ) != 0 )
+      {
+        if ( pcCU->getInterDir(0) & (1<<uiRefListIdx) )
+        {
+          UInt dummy;
+          Int vspSize;
+          Int width, height;
+          pcCU->getPartIndexAndSize( 0, dummy, width, height, 0, pcCU->getTotalNumPart()==256 );
+          AOF( dummy == 0 );
+          AOF( width == height );
+          pcCU->setMvFieldPUForVSP( pcCU, 0, width, height, eRefList, pDBBPTmpData->acMvField[uiSegment][eRefList].getRefIdx(), vspSize );
+          pcCU->setVSPFlag( 0, vspSize );
+        }
+      }
+      else
+#endif
+      pcCU->getCUMvField( eRefList )->setAllMvField( pDBBPTmpData->acMvField[uiSegment][eRefList], SIZE_2Nx2N, 0, 0 );
+    }
+    
+    // inter prediction
+    m_pcPrediction->motionCompensation( pcCU, apSegPredYuv[uiSegment] );
+  }
+  
+  // restore motion information in both segments again
+  pcCU->setPartSizeSubParts( ePartSize,  0, uiDepth );
+  pcCU->setPredModeSubParts( MODE_INTER, 0, uiDepth );
+  for( UInt uiSegment = 0; uiSegment < 2; uiSegment++ )
+  {
+    UInt uiPartAddr = uiSegment*uiPUOffset;
+    
+    pcCU->setDBBPFlagSubParts(true, uiPartAddr, uiSegment, uiDepth);
+    
+    pcCU->setVSPFlagSubParts( pDBBPTmpData->ahVSPFlag[uiSegment], uiPartAddr, uiSegment, uiDepth );
+    pcCU->setDvInfoSubParts( pDBBPTmpData->acDvInfo[uiSegment], uiPartAddr, uiSegment, uiDepth );
+    
+    pcCU->setInterDirSubParts(pDBBPTmpData->auhInterDir[uiSegment], uiPartAddr, uiSegment, uiDepth); // interprets depth relative to LCU level
+    
+    for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+    {
+      RefPicList eRefList = (RefPicList)uiRefListIdx;
+#if NTT_STORE_SPDV_VSP_G0148
+      if( pcCU->getVSPFlag( uiPartAddr ) != 0 )
+      {
+        if ( pcCU->getInterDir(uiPartAddr) & (1<<uiRefListIdx) )
+        {
+          UInt dummy;
+          Int vspSize;
+          Int width, height;
+          pcCU->getPartIndexAndSize( uiSegment, dummy, width, height, 0, pcCU->getTotalNumPart()==256 );
+          AOF( dummy == uiPartAddr );
+          pcCU->setMvFieldPUForVSP( pcCU, uiPartAddr, width, height, RefPicList( uiRefListIdx ), pcCU->getMVPIdx(eRefList, uiPartAddr), vspSize );
+          pcCU->setVSPFlag( uiPartAddr, vspSize );
+        }
+      }
+      else
+#endif
+      pcCU->getCUMvField( eRefList )->setAllMvField( pDBBPTmpData->acMvField[uiSegment][eRefList], ePartSize, uiPartAddr, 0, uiSegment ); // interprets depth relative to rpcTempCU level
+    }
+  }
+  
+  // reconstruct final prediction signal by combining both segments
+  m_pcPrediction->combineSegmentsWithMask(apSegPredYuv, m_ppcYuvReco[uiDepth], pMask, pcCU->getWidth(0), pcCU->getHeight(0));
+  
+  // inter recon
+  xDecodeInterTexture( pcCU, 0, uiDepth );
+  
+  // clip for only non-zero cbp case
+  if  ( ( pcCU->getCbf( 0, TEXT_LUMA ) ) || ( pcCU->getCbf( 0, TEXT_CHROMA_U ) ) || ( pcCU->getCbf(0, TEXT_CHROMA_V ) ) )
+  {
+    m_ppcYuvReco[uiDepth]->addClip( m_ppcYuvReco[uiDepth], m_ppcYuvResi[uiDepth], 0, pcCU->getWidth( 0 ) );
+  }
+  else
+  {
+    m_ppcYuvReco[uiDepth]->copyPartToPartYuv( m_ppcYuvReco[uiDepth],0, pcCU->getWidth( 0 ),pcCU->getHeight( 0 ));
   }
 }
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCu.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCu.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecCu.h	(revision 816)
@@ -63,4 +63,8 @@
   TComDataCU**        m_ppcCU;            ///< CU data array
   
+#if H_3D_DBBP
+  TComYuv**           m_ppcYuvRecoDBBP;
+#endif
+  
   // access channel
   TComTrQuant*        m_pcTrQuant;
@@ -98,4 +102,8 @@
   Void xReconInter              ( TComDataCU* pcCU, UInt uiDepth );
   
+#if H_3D_DBBP
+  Void xReconInterDBBP          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#endif
+  
   Void  xReconIntraQT           ( TComDataCU* pcCU, UInt uiDepth );
   Void  xIntraRecLumaBlk        ( TComDataCU* pcCU, UInt uiTrDepth, UInt uiAbsPartIdx, TComYuv* pcRecoYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecEntropy.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 816)
@@ -137,4 +137,32 @@
 {
   m_pcEntropyDecoderIf->parsePartSize( pcCU, uiAbsPartIdx, uiDepth );
+  
+#if H_3D_DBBP
+  if( pcCU->getSlice()->getVPS()->getUseDBBP(pcCU->getSlice()->getLayerIdInVps()) && pcCU->getPartitionSize(uiAbsPartIdx) == RWTH_DBBP_PACK_MODE )
+  {
+    decodeDBBPFlag(pcCU, uiAbsPartIdx, uiDepth);
+    
+    if( pcCU->getDBBPFlag(uiAbsPartIdx) )
+    {
+      AOF( pcCU->getPartitionSize(uiAbsPartIdx) == RWTH_DBBP_PACK_MODE );
+      
+      // get collocated depth block
+      UInt uiDepthStride = 0;
+      Pel* pDepthPels = NULL;
+      pDepthPels = pcCU->getVirtualDepthBlock(uiAbsPartIdx, pcCU->getWidth(uiAbsPartIdx), pcCU->getHeight(uiAbsPartIdx), uiDepthStride);
+      
+      AOF( pDepthPels != NULL );
+      AOF( uiDepthStride != 0 );
+      
+      // derive true partitioning for this CU based on depth
+      // (needs to be done in parsing process as motion vector predictors are also derived during parsing)
+      PartSize eVirtualPartSize = m_pcPrediction->getPartitionSizeFromDepth(pDepthPels, uiDepthStride, pcCU->getWidth(uiAbsPartIdx));
+      AOF( eVirtualPartSize != SIZE_NONE );
+      
+      pcCU->setPartSizeSubParts(eVirtualPartSize, uiAbsPartIdx, uiDepth);
+      AOF( pcCU->getPartitionSize(uiAbsPartIdx) == eVirtualPartSize );
+    }
+  }
+#endif
 }
 
@@ -247,5 +275,9 @@
       decodeARPW  ( pcCU, uiAbsPartIdx, uiDepth );
 #endif
+#if H_3D_DBBP
+      if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && ePartSize != SIZE_2Nx2N && pcSubCU->getWidth( 0 ) <= 8 && pcCU->getDBBPFlag(uiAbsPartIdx) == false )
+#else
       if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && ePartSize != SIZE_2Nx2N && pcSubCU->getWidth( 0 ) <= 8 ) 
+#endif
       {
         pcSubCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
@@ -830,3 +862,10 @@
 #endif
 
+#if H_3D_DBBP
+Void TDecEntropy::decodeDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
+{
+  m_pcEntropyDecoderIf->parseDBBPFlag( pcCU, uiAbsPartIdx, uiDepth );
+}
+#endif
+
 //! \}
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecEntropy.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecEntropy.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecEntropy.h	(revision 816)
@@ -99,4 +99,7 @@
   virtual Void parseInterSDCResidualData ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPart ) = 0;
 #endif
+#if H_3D_DBBP
+  virtual Void parseDBBPFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
+#endif
   virtual Void parsePartSize      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
   virtual Void parsePredMode      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
@@ -182,4 +185,7 @@
   Void decodeInterSDCResidualData ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 #endif
+#if H_3D_DBBP
+  Void decodeDBBPFlag          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#endif
   Void decodeIPCMInfo          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecSbac.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecSbac.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecSbac.cpp	(revision 816)
@@ -100,4 +100,7 @@
 , m_cInterSDCResidualSignFlagSCModel ( 1,             1,  NUM_INTER_SDC_SIGN_FLAG_CTX      , m_contextModels + m_numContextModels, m_numContextModels)
 #endif
+#if H_3D_DBBP
+, m_cDBBPFlagSCModel             ( 1,             1,                 DBBP_NUM_FLAG_CTX           , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 {
   assert( m_numContextModels <= MAX_NUM_CTX_MOD );
@@ -182,4 +185,7 @@
   m_cInterSDCResidualSCModel.initBuffer   ( sliceType, qp, (UChar*)INIT_INTER_SDC_RESIDUAL );
   m_cInterSDCResidualSignFlagSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_INTER_SDC_SIGN_FLAG );
+#endif
+#if H_3D_DBBP
+  m_cDBBPFlagSCModel.initBuffer              ( sliceType, qp, (UChar*)INIT_DBBP_FLAG );
 #endif
   m_uiLastDQpNonZero  = 0;
@@ -251,4 +257,7 @@
   m_cInterSDCResidualSCModel.initBuffer   ( eSliceType, iQp, (UChar*)INIT_INTER_SDC_RESIDUAL );
   m_cInterSDCResidualSignFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_INTER_SDC_SIGN_FLAG );
+#endif
+#if H_3D_DBBP
+  m_cDBBPFlagSCModel.initBuffer              ( eSliceType, iQp, (UChar*)INIT_DBBP_FLAG );
 #endif
   m_pcTDecBinIf->start();
@@ -2132,3 +2141,30 @@
 #endif
 
+#if H_3D_DBBP
+Void TDecSbac::parseDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
+{
+  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
+  AOF( pcCU->getSlice()->getVPS()->getUseDBBP(pcCU->getSlice()->getLayerIdInVps()) );
+  AOF( !pcCU->getSlice()->getIsDepth() );
+  AOF( ePartSize == RWTH_DBBP_PACK_MODE );
+  
+  UInt uiSymbol = 0;
+  
+  m_pcTDecBinIf->decodeBin( uiSymbol, m_cDBBPFlagSCModel.get( 0, 0, 0 ) );
+  
+  DTRACE_CABAC_VL( g_nSymbolCounter++ );
+  DTRACE_CABAC_T( "\tDBBPFlag" );
+  DTRACE_CABAC_T( "\tuiCtxDBBP: ");
+  DTRACE_CABAC_V( uiCtxDBBPFlag );
+  DTRACE_CABAC_T( "\tuiSymbol: ");
+  DTRACE_CABAC_V( uiSymbol );
+  DTRACE_CABAC_T( "\n");
+  
+  if( uiSymbol )
+  {
+    pcCU->setDBBPFlagSubParts(true, uiAbsPartIdx, 0, uiDepth);
+  }
+}
+#endif
+
 //! \}
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecSbac.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecSbac.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibDecoder/TDecSbac.h	(revision 816)
@@ -115,4 +115,7 @@
   Void  parseInterSDCResidualData ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPart );
 #endif
+#if H_3D_DBBP
+  Void parseDBBPFlag        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#endif
 private:
   TComInputBitstream* m_pcBitstream;
@@ -224,4 +227,7 @@
   ContextModel3DBuffer m_cInterSDCResidualSignFlagSCModel;
 #endif
+#if H_3D_DBBP
+  ContextModel3DBuffer m_cDBBPFlagSCModel;
+#endif
 };
 
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 816)
@@ -1516,4 +1516,7 @@
         WRITE_FLAG( pcVPS->getViewSynthesisPredFlag( i ) ? 1 : 0 , "view_synthesis_pred_flag[i]");
 #endif
+#if H_3D_DBBP
+        WRITE_FLAG( pcVPS->getUseDBBP( i ) ? 1 : 0, "use_dbbp_flag[i]" );
+#endif
       }          
       else
@@ -2534,3 +2537,10 @@
 }
 #endif
+    
+#if H_3D_DBBP
+Void TEncCavlc::codeDBBPFlag    ( TComDataCU* pcCU, UInt uiAbsPartIdx )
+{
+  assert(0);
+}
+#endif
 //! \}
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCavlc.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCavlc.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCavlc.h	(revision 816)
@@ -141,4 +141,7 @@
   Void codeInterSDCResidualData  ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiSegment );
 #endif
+#if H_3D_DBBP
+  Void codeDBBPFlag       ( TComDataCU* pcCU, UInt uiAbsPartIdx );
+#endif
 
   Void codeInterModeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiEncMode );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCfg.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCfg.h	(revision 816)
@@ -420,4 +420,7 @@
   bool      m_bInterSDC;
 #endif
+#if H_3D_DBBP
+  Bool      m_bUseDBBP;
+#endif
   //====== Depth Intra Modes ======
 #if H_3D_DIM
@@ -529,4 +532,8 @@
   Void       setInterSDCEnable              ( Bool bVal )    { m_bInterSDC = bVal; }
   Bool       getInterSDCEnable              ()               { return m_bInterSDC; }
+#endif
+#if H_3D_DBBP
+  Void       setUseDBBP                     ( Bool  b )      { m_bUseDBBP   = b; }
+  Bool       getUseDBBP()                                    { return m_bUseDBBP;     }
 #endif
   //======== Transform =============
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCu.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCu.cpp	(revision 816)
@@ -76,4 +76,7 @@
   m_ppcRecoYuvTemp = new TComYuv*[m_uhTotalDepth-1];
   m_ppcOrigYuv     = new TComYuv*[m_uhTotalDepth-1];
+#if H_3D_DBBP
+  m_ppcOrigYuvDBBP = new TComYuv*[m_uhTotalDepth-1];
+#endif
   
   UInt uiNumPartitions;
@@ -100,4 +103,7 @@
     
     m_ppcOrigYuv    [i] = new TComYuv; m_ppcOrigYuv    [i]->create(uiWidth, uiHeight);
+#if H_3D_DBBP
+    m_ppcOrigYuvDBBP[i] = new TComYuv; m_ppcOrigYuvDBBP[i]->create(uiWidth, uiHeight);
+#endif
   }
   
@@ -180,4 +186,10 @@
       m_ppcOrigYuv[i]->destroy();     delete m_ppcOrigYuv[i];     m_ppcOrigYuv[i] = NULL;
     }
+#if H_3D_DBBP
+    if(m_ppcOrigYuvDBBP[i])
+    {
+      m_ppcOrigYuvDBBP[i]->destroy(); delete m_ppcOrigYuvDBBP[i]; m_ppcOrigYuvDBBP[i] = NULL;
+    }
+#endif
   }
   if(m_ppcBestCU)
@@ -234,4 +246,11 @@
     m_ppcOrigYuv = NULL;
   }
+#if H_3D_DBBP
+  if(m_ppcOrigYuvDBBP)
+  {
+    delete [] m_ppcOrigYuvDBBP;
+    m_ppcOrigYuvDBBP = NULL;
+  }
+#endif
 }
 
@@ -654,4 +673,16 @@
             rpcTempCU->setDvInfoSubParts(DvInfo, 0, uiDepth);
 #endif
+          
+#if H_3D_DBBP
+          if( m_pcEncCfg->getUseDBBP() )
+          {
+            xCheckRDCostInterDBBP( rpcBestCU, rpcTempCU, false );
+            rpcTempCU->initEstData( uiDepth, iQP );
+#if H_3D_VSP
+            rpcTempCU->setDvInfoSubParts(DvInfo, 0, uiDepth);
+#endif
+          }
+#endif
+          
             if(m_pcEncCfg->getUseCbfFastMode())
             {
@@ -2310,4 +2341,207 @@
 }
 
+#if H_3D_DBBP
+Void TEncCu::xInvalidateOriginalSegments( TComYuv* pOrigYuv, TComYuv* pOrigYuvTemp, Bool* pMask, UInt uiValidSegment )
+{
+  UInt  uiWidth     = pOrigYuv->getWidth ( );
+  UInt  uiHeight    = pOrigYuv->getHeight( );
+  Pel*  piSrc       = pOrigYuv->getLumaAddr( );
+  UInt  uiSrcStride = pOrigYuv->getStride();
+  Pel*  piDst       = pOrigYuvTemp->getLumaAddr( );
+  UInt  uiDstStride = pOrigYuvTemp->getStride();
+  
+  UInt  uiMaskStride= MAX_CU_SIZE;
+  
+  AOF( uiWidth == uiHeight );
+  
+  // backup pointer
+  Bool* pMaskStart = pMask;
+  
+  for (Int y=0; y<uiHeight; y++)
+  {
+    for (Int x=0; x<uiWidth; x++)
+    {
+      UChar ucSegment = (UChar)pMask[x];
+      assert( ucSegment < 2 );
+      
+      piDst[x] = (ucSegment==uiValidSegment)?piSrc[x]:DBBP_INVALID_SHORT;
+    }
+    
+    piSrc  += uiSrcStride;
+    piDst  += uiDstStride;
+    pMask  += uiMaskStride;
+  }
+  
+  // now invalidate chroma
+  Pel*  piSrcU       = pOrigYuv->getCbAddr();
+  Pel*  piSrcV       = pOrigYuv->getCrAddr();
+  UInt  uiSrcStrideC = pOrigYuv->getCStride();
+  Pel*  piDstU       = pOrigYuvTemp->getCbAddr( );
+  Pel*  piDstV       = pOrigYuvTemp->getCrAddr( );
+  UInt  uiDstStrideC = pOrigYuvTemp->getCStride();
+  pMask = pMaskStart;
+  
+  for (Int y=0; y<uiHeight/2; y++)
+  {
+    for (Int x=0; x<uiWidth/2; x++)
+    {
+      UChar ucSegment = (UChar)pMask[x*2];
+      assert( ucSegment < 2 );
+      
+      piDstU[x] = (ucSegment==uiValidSegment)?piSrcU[x]:DBBP_INVALID_SHORT;
+      piDstV[x] = (ucSegment==uiValidSegment)?piSrcV[x]:DBBP_INVALID_SHORT;
+    }
+    
+    piSrcU  += uiSrcStrideC;
+    piSrcV  += uiSrcStrideC;
+    piDstU  += uiDstStrideC;
+    piDstV  += uiDstStrideC;
+    pMask   += 2*uiMaskStride;
+  }
+}
+
+Void TEncCu::xCheckRDCostInterDBBP( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool bUseMRG )
+{
+  AOF( !rpcTempCU->getSlice()->getIsDepth() );
+  
+  
+  UChar uhDepth = rpcTempCU->getDepth( 0 );
+  
+#if H_3D_VSO
+  if( m_pcRdCost->getUseRenModel() )
+  {
+    UInt  uiWidth     = m_ppcOrigYuv[uhDepth]->getWidth ( );
+    UInt  uiHeight    = m_ppcOrigYuv[uhDepth]->getHeight( );
+    Pel*  piSrc       = m_ppcOrigYuv[uhDepth]->getLumaAddr( );
+    UInt  uiSrcStride = m_ppcOrigYuv[uhDepth]->getStride();
+    m_pcRdCost->setRenModelData( rpcTempCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
+  }
+#endif
+  
+  UInt uiWidth  = rpcTempCU->getWidth(0);
+  UInt uiHeight = rpcTempCU->getHeight(0);
+  AOF( uiWidth == uiHeight );
+  
+  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N,  0, uhDepth );
+  
+  // get coded and reconstructed depth view
+  UInt uiDepthStride = 0;
+  Pel* pDepthPels = rpcTempCU->getVirtualDepthBlock(0, uiWidth, uiHeight, uiDepthStride);
+  AOF( pDepthPels != NULL );
+  AOF( uiDepthStride != 0 );
+  
+  // derive partitioning from depth
+  PartSize eVirtualPartSize = m_pcPredSearch->getPartitionSizeFromDepth(pDepthPels, uiDepthStride, uiWidth);
+  
+  // derive segmentation mask from depth
+  Bool pMask[MAX_CU_SIZE*MAX_CU_SIZE];
+  Bool bValidMask = m_pcPredSearch->getSegmentMaskFromDepth(pDepthPels, uiDepthStride, uiWidth, uiHeight, pMask);
+  
+  if( !bValidMask )
+    return;
+  
+  // find optimal motion/disparity vector for each segment
+  DisInfo originalDvInfo = rpcTempCU->getDvInfo(0);
+  DBBPTmpData* pDBBPTmpData = rpcTempCU->getDBBPTmpData();
+  TComYuv* apPredYuv[2] = { m_ppcRecoYuvTemp[uhDepth], m_ppcPredYuvTemp[uhDepth] };
+  
+  // find optimal motion vector fields for both segments (as 2Nx2N)
+  rpcTempCU->setDepthSubParts( uhDepth, 0 );
+  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N,  0, uhDepth );
+  rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth );
+  for( UInt uiSegment = 0; uiSegment < 2; uiSegment++ )
+  {
+    rpcTempCU->setDBBPFlagSubParts(true, 0, 0, uhDepth);
+    rpcTempCU->setDvInfoSubParts(originalDvInfo, 0, uhDepth);
+    
+    // invalidate all other segments in original YUV
+    xInvalidateOriginalSegments(m_ppcOrigYuv[uhDepth], m_ppcOrigYuvDBBP[uhDepth], pMask, uiSegment);
+    
+    // do motion estimation for this segment
+    g_bTestVirtualParts = true;
+    rpcTempCU->getDBBPTmpData()->eVirtualPartSize = eVirtualPartSize;
+    rpcTempCU->getDBBPTmpData()->uiVirtualPartIndex = uiSegment;
+    m_pcPredSearch->predInterSearch( rpcTempCU, m_ppcOrigYuvDBBP[uhDepth], apPredYuv[uiSegment], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], false, false, bUseMRG );
+    g_bTestVirtualParts = false;
+    
+    // extract motion parameters of full block for this segment
+    pDBBPTmpData->auhInterDir[uiSegment] = rpcTempCU->getInterDir(0);
+    
+    pDBBPTmpData->abMergeFlag[uiSegment] = rpcTempCU->getMergeFlag(0);
+    pDBBPTmpData->auhMergeIndex[uiSegment] = rpcTempCU->getMergeIndex(0);
+    
+    pDBBPTmpData->ahVSPFlag[uiSegment] = rpcTempCU->getVSPFlag(0);
+    pDBBPTmpData->acDvInfo[uiSegment] = rpcTempCU->getDvInfo(0);
+    
+    for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+    {
+      RefPicList eRefList = (RefPicList)uiRefListIdx;
+      
+      pDBBPTmpData->acMvd[uiSegment][eRefList] = rpcTempCU->getCUMvField(eRefList)->getMvd(0);
+      pDBBPTmpData->aiMvpNum[uiSegment][eRefList] = rpcTempCU->getMVPNum(eRefList, 0);
+      pDBBPTmpData->aiMvpIdx[uiSegment][eRefList] = rpcTempCU->getMVPIdx(eRefList, 0);
+      
+      rpcTempCU->getMvField(rpcTempCU, 0, eRefList, pDBBPTmpData->acMvField[uiSegment][eRefList]);
+    }
+  }
+  
+  rpcTempCU->setDepthSubParts( uhDepth, 0 );
+  rpcTempCU->setPartSizeSubParts  ( eVirtualPartSize,  0, uhDepth );
+  rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );
+  
+  UInt uiPUOffset = ( g_auiPUOffset[UInt( eVirtualPartSize )] << ( ( rpcTempCU->getSlice()->getSPS()->getMaxCUDepth() - uhDepth ) << 1 ) ) >> 4;
+  for( UInt uiSegment = 0; uiSegment < 2; uiSegment++ )
+  {
+    UInt uiPartAddr = uiSegment*uiPUOffset;
+    
+    rpcTempCU->setDBBPFlagSubParts(true, uiPartAddr, uiSegment, uhDepth);
+    
+    // now set stored information from 2Nx2N motion search to each partition
+    rpcTempCU->setInterDirSubParts(pDBBPTmpData->auhInterDir[uiSegment], uiPartAddr, uiSegment, uhDepth); // interprets depth relative to LCU level
+    
+    rpcTempCU->setMergeFlagSubParts(pDBBPTmpData->abMergeFlag[uiSegment], uiPartAddr, uiSegment, uhDepth);
+    rpcTempCU->setMergeIndexSubParts(pDBBPTmpData->auhMergeIndex[uiSegment], uiPartAddr, uiSegment, uhDepth);
+    
+    rpcTempCU->setVSPFlagSubParts(pDBBPTmpData->ahVSPFlag[uiSegment], uiPartAddr, uiSegment, uhDepth);
+    rpcTempCU->setDvInfoSubParts(pDBBPTmpData->acDvInfo[uiSegment], uiPartAddr, uiSegment, uhDepth);
+    
+    for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+    {
+      RefPicList eRefList = (RefPicList)uiRefListIdx;
+      
+      rpcTempCU->getCUMvField( eRefList )->setAllMvd(pDBBPTmpData->acMvd[uiSegment][eRefList], eVirtualPartSize, uiPartAddr, 0, uiSegment);
+      rpcTempCU->setMVPNum(eRefList, uiPartAddr, pDBBPTmpData->aiMvpNum[uiSegment][eRefList]);
+      rpcTempCU->setMVPIdx(eRefList, uiPartAddr, pDBBPTmpData->aiMvpIdx[uiSegment][eRefList]);
+      
+#if NTT_STORE_SPDV_VSP_G0148
+      if( rpcTempCU->getVSPFlag( uiPartAddr ) != 0 )
+      {
+        if ( rpcTempCU->getInterDir(uiPartAddr) & (1<<uiRefListIdx) )
+        {
+          UInt dummy;
+          Int vspSize;
+          Int width, height;
+          rpcTempCU->getPartIndexAndSize( uiSegment, dummy, width, height, uiPartAddr, rpcTempCU->getTotalNumPart()==256 );
+          AOF( dummy == uiPartAddr );
+          rpcTempCU->setMvFieldPUForVSP( rpcTempCU, uiPartAddr, width, height, eRefList, pDBBPTmpData->acMvField[uiSegment][eRefList].getRefIdx(), vspSize );
+          rpcTempCU->setVSPFlag( uiPartAddr, vspSize );
+        }
+      }
+      else
+#endif
+      rpcTempCU->getCUMvField( eRefList )->setAllMvField( pDBBPTmpData->acMvField[uiSegment][eRefList], eVirtualPartSize, uiPartAddr, 0, uiSegment ); // interprets depth relative to rpcTempCU level
+    }
+  }
+  
+  // reconstruct final prediction signal by combining both segments
+  m_pcPredSearch->combineSegmentsWithMask(apPredYuv, m_ppcPredYuvTemp[uhDepth], pMask, uiWidth, uiHeight);
+  
+  m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false );
+  
+  xCheckDQP( rpcTempCU );
+  xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
+}
+#endif
+
 Void TEncCu::xCheckRDCostIntra( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize eSize )
 {
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCu.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCu.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncCu.h	(revision 816)
@@ -82,4 +82,8 @@
   TComYuv**               m_ppcOrigYuv;     ///< Original Yuv for each depth
   
+#if H_3D_DBBP
+  TComYuv**               m_ppcOrigYuvDBBP;
+#endif
+  
   //  Data : encoder control
   Bool                    m_bEncodeDQP;
@@ -168,4 +172,8 @@
   Void  xCheckRDCostInter   ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize  );
 #endif
+#if H_3D_DBBP
+  Void  xInvalidateOriginalSegments( TComYuv* pOrigYuv, TComYuv* pOrigYuvTemp, Bool* pMask, UInt uiValidSegment );
+  Void  xCheckRDCostInterDBBP( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool bUseMRG = false );
+#endif
   Void  xCheckRDCostIntra   ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize  );
   Void  xCheckDQP           ( TComDataCU*  pcCU );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncEntropy.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 816)
@@ -240,5 +240,29 @@
     uiAbsPartIdx = 0;
   }
+  
+#if H_3D_DBBP
+  PartSize eVirtualPartSize = pcCU->getPartitionSize(uiAbsPartIdx);
+  if( pcCU->getDBBPFlag(uiAbsPartIdx) )
+  {
+    // temporarily change partition size for DBBP blocks
+    pcCU->setPartSizeSubParts(RWTH_DBBP_PACK_MODE, uiAbsPartIdx, uiDepth);
+  }
+#endif
+  
   m_pcEntropyCoderIf->codePartSize( pcCU, uiAbsPartIdx, uiDepth );
+  
+#if H_3D_DBBP
+  if( pcCU->getSlice()->getVPS()->getUseDBBP(pcCU->getSlice()->getLayerIdInVps()) && pcCU->getPartitionSize(uiAbsPartIdx) == RWTH_DBBP_PACK_MODE )
+  {
+    encodeDBBPFlag(pcCU, uiAbsPartIdx, bRD);
+    
+    if( pcCU->getDBBPFlag(uiAbsPartIdx) )
+    {
+      AOF( pcCU->getPartitionSize(uiAbsPartIdx) == RWTH_DBBP_PACK_MODE );
+      // restore virtual partition size for DBBP blocks
+      pcCU->setPartSizeSubParts(eVirtualPartSize, uiAbsPartIdx, uiDepth);
+    }
+  }
+#endif
 }
 
@@ -873,3 +897,14 @@
 #endif
 
+#if H_3D_DBBP
+Void TEncEntropy::encodeDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
+{
+  if( bRD )
+  {
+    uiAbsPartIdx = 0;
+  }
+  m_pcEntropyCoderIf->codeDBBPFlag( pcCU, uiAbsPartIdx );
+}
+#endif
+
 //! \}
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncEntropy.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncEntropy.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncEntropy.h	(revision 816)
@@ -97,4 +97,7 @@
   virtual Void codeInterSDCFlag  ( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
   virtual Void codeInterSDCResidualData ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiSegment ) = 0;
+#endif
+#if H_3D_DBBP
+  virtual Void codeDBBPFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
 #endif
   virtual Void codeSplitFlag     ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
@@ -189,4 +192,7 @@
   Void encodeInterSDCResidualData( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD );
 #endif
+#if H_3D_DBBP
+  Void encodeDBBPFlag     ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
+#endif
   Void encodePredMode          ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
   Void encodePartSize          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD = false );
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSbac.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 816)
@@ -106,4 +106,7 @@
 , m_cInterSDCResidualSignFlagSCModel ( 1,             1,  NUM_INTER_SDC_SIGN_FLAG_CTX      , m_contextModels + m_numContextModels, m_numContextModels)
 #endif
+#if H_3D_DBBP
+, m_cDBBPFlagSCModel             ( 1,             1,                 DBBP_NUM_FLAG_CTX           , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 {
   assert( m_numContextModels <= MAX_NUM_CTX_MOD );
@@ -181,4 +184,7 @@
   m_cInterSDCResidualSignFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_INTER_SDC_SIGN_FLAG );
 #endif
+#if H_3D_DBBP
+  m_cDBBPFlagSCModel.initBuffer              ( eSliceType, iQp, (UChar*)INIT_DBBP_FLAG );
+#endif
   // new structure
   m_uiLastQp = iQp;
@@ -222,4 +228,7 @@
       curCost += m_cInterSDCResidualSCModel.calcCost  ( curSliceType, qp, (UChar*)INIT_INTER_SDC_RESIDUAL );
       curCost += m_cInterSDCResidualSignFlagSCModel.calcCost( curSliceType, qp, (UChar*)INIT_INTER_SDC_SIGN_FLAG );
+#endif
+#if H_3D_DBBP
+      curCost += m_cDBBPFlagSCModel.calcCost          ( curSliceType, qp, (UChar*)INIT_DBBP_FLAG );
 #endif
       curCost += m_cCUPartSizeSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_PART_SIZE );
@@ -330,4 +339,7 @@
   m_cInterSDCResidualSignFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_INTER_SDC_SIGN_FLAG );
 #endif
+#if H_3D_DBBP
+  m_cDBBPFlagSCModel.initBuffer              ( eSliceType, iQp, (UChar*)INIT_DBBP_FLAG );
+#endif
   m_pcBinIf->start();
 }
@@ -1228,4 +1240,11 @@
     m_pcBinIf->encodeBin( uiInterDir == 2 ? 1 : 0, *( pCtx + uiCtx ) );
   }
+#if H_3D_DBBP
+  else
+  {
+    // only uni-prediction is allowed for DBBP
+    AOF( uiInterDir == 0 || uiInterDir == 1 );
+  }
+#endif
   if (uiInterDir < 2)
   {
@@ -2158,3 +2177,17 @@
 }
 #endif
+
+#if H_3D_DBBP
+Void TEncSbac::codeDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
+{
+  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
+  AOF( ePartSize == RWTH_DBBP_PACK_MODE );
+  AOF( pcCU->getSlice()->getVPS()->getUseDBBP(pcCU->getSlice()->getLayerIdInVps()) );
+  AOF( !pcCU->getSlice()->getIsDepth() );
+  
+  UInt uiSymbol = pcCU->getDBBPFlag( uiAbsPartIdx ) ? 1 : 0;
+  m_pcBinIf->encodeBin( uiSymbol, m_cDBBPFlagSCModel.get( 0, 0, 0 ) );
+}
+#endif
+
 //! \}
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSbac.h
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSbac.h	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSbac.h	(revision 816)
@@ -157,4 +157,7 @@
   Void codeInterSDCResidualData  ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiSegment );
 #endif
+#if H_3D_DBBP
+  Void codeDBBPFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx );
+#endif
   Void codeSplitFlag     ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
   Void codeMVPIdx        ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList );
@@ -260,4 +263,7 @@
   ContextModel3DBuffer m_cInterSDCResidualSignFlagSCModel;
 #endif
+#if H_3D_DBBP
+  ContextModel3DBuffer m_cDBBPFlagSCModel;
+#endif
 };
 
Index: branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 815)
+++ branches/HTM-9.3-dev1-RWTH/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 816)
@@ -3583,6 +3583,61 @@
   pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
   UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
+  
+#if H_3D_DBBP
+  DBBPTmpData* pDBBPTmpData = pcCU->getDBBPTmpData();
+  if( pcCU->getDBBPFlag(0) )
+  {
+    AOF( uiAbsPartIdx == 0 );
+    AOF( iPUIdx == 0 );
+    AOF( pcCU->getPartitionSize(0) == SIZE_2Nx2N );
+    AOF( pDBBPTmpData->eVirtualPartSize != SIZE_NONE );
+    
+    // temporary change of partition size for candidate derivation
+    pcCU->setPartSizeSubParts( pDBBPTmpData->eVirtualPartSize, 0, pcCU->getDepth(0));
+    iPUIdx = pcCU->getDBBPTmpData()->uiVirtualPartIndex;
+    
+    // if this is handling the second segment, make sure that motion info of first segment is available
+    if( iPUIdx == 1 )
+    {
+      pcCU->setInterDirSubParts(pDBBPTmpData->auhInterDir[0], 0, 0, pcCU->getDepth(0)); // interprets depth relative to LCU level
+      
+      pcCU->setVSPFlagSubParts(pDBBPTmpData->ahVSPFlag[0], 0, 0, pcCU->getDepth(0));
+      pcCU->setDvInfoSubParts(pDBBPTmpData->acDvInfo[0], 0, 0, pcCU->getDepth(0));
+      
+      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+      {
+        RefPicList eRefList = (RefPicList)uiRefListIdx;
+        
+#if NTT_STORE_SPDV_VSP_G0148
+        if( pcCU->getVSPFlag( 0 ) != 0 )
+        {
+          if ( pcCU->getInterDir(0) & (1<<uiRefListIdx) )
+          {
+            UInt dummy;
+            Int vspSize;
+            Int width, height;
+            pcCU->getPartIndexAndSize( 0, dummy, width, height, 0, pcCU->getTotalNumPart()==256 );
+            AOF( dummy == 0 );
+            pcCU->setMvFieldPUForVSP( pcCU, 0, width, height, eRefList, pDBBPTmpData->acMvField[0][eRefList].getRefIdx(), vspSize );
+            pcCU->setVSPFlag( 0, vspSize );
+          }
+        }
+        else
+#endif
+        pcCU->getCUMvField( eRefList )->setAllMvField( pDBBPTmpData->acMvField[0][eRefList], pDBBPTmpData->eVirtualPartSize, 0, 0, 0 ); // interprets depth relative to rpcTempCU level
+      }
+    }
+    
+    // update these values to virtual partition size
+    pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
+  }
+#endif
+  
   PartSize partSize = pcCU->getPartitionSize( 0 );
+#if H_3D_DBBP
+  if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && partSize != SIZE_2Nx2N && pcCU->getWidth( 0 ) <= 8 && pcCU->getDBBPFlag(0) == false )
+#else
   if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && partSize != SIZE_2Nx2N && pcCU->getWidth( 0 ) <= 8 )
+#endif
   {
     pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
@@ -3634,4 +3689,19 @@
 #endif
 
+#if H_3D_DBBP
+  if( pcCU->getDBBPFlag(0) )
+  {
+    // reset to 2Nx2N for actual motion search
+    iPUIdx = 0;
+    AOF( pcCU->getPartitionSize(0) == pDBBPTmpData->eVirtualPartSize );
+    pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, pcCU->getDepth(0));
+    
+    // restore values for 2Nx2N partition size
+    pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
+    
+    AOF( uiAbsPartIdx == 0 );
+    AOF( iWidth == iHeight );
+  }
+#endif
 
   ruiCost = MAX_UINT;
@@ -4346,5 +4416,10 @@
 #endif
 
+#if H_3D_DBBP
+    // test merge mode for DBBP (2Nx2N)
+    if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N || pcCU->getDBBPFlag(0) )
+#else
     if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
+#endif
     {
       UInt uiMRGInterDir = 0;     
@@ -4564,5 +4639,50 @@
   if (!bFilled)
   {
+#if H_3D_DBBP
+    DBBPTmpData* pDBBPTmpData = pcCU->getDBBPTmpData();
+    if( pcCU->getDBBPFlag(0) )
+    {
+      AOF( uiPartAddr == 0 );
+      AOF( uiPartIdx == 0 );
+      AOF( pcCU->getPartitionSize(0) == SIZE_2Nx2N );
+      AOF( pDBBPTmpData->eVirtualPartSize != SIZE_NONE );
+      AOF( iRoiWidth == iRoiHeight );
+      
+      // temporary change of partition size for candidate derivation
+      pcCU->setPartSizeSubParts( pDBBPTmpData->eVirtualPartSize, 0, pcCU->getDepth(0));
+      uiPartIdx = pcCU->getDBBPTmpData()->uiVirtualPartIndex;
+      
+      // if this is handling the second segment, make sure that motion info of first segment is set to first segment
+      if( uiPartIdx == 1 )
+      {
+        pcCU->setInterDirSubParts(pDBBPTmpData->auhInterDir[0], 0, 0, pcCU->getDepth(0)); // interprets depth relative to LCU level
+        
+        for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+        {
+          RefPicList eRefList = (RefPicList)uiRefListIdx;
+          pcCU->getCUMvField( eRefList )->setAllMvField( pDBBPTmpData->acMvField[0][eRefList], pDBBPTmpData->eVirtualPartSize, 0, 0, 0 ); // interprets depth relative to rpcTempCU level
+        }
+      }
+      
+      // update these values to virtual partition size
+      pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
+    }
+#endif
+    
     pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
+    
+#if H_3D_DBBP
+    if( pcCU->getDBBPFlag(0) )
+    {
+      // reset to 2Nx2N for motion search
+      uiPartIdx = 0;
+      AOF( pcCU->getPartitionSize(0) == pDBBPTmpData->eVirtualPartSize );
+      pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, pcCU->getDepth(0));
+      
+      // restore values for 2Nx2N partition size
+      pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
+      AOF(uiPartAddr==0);
+    }
+#endif
   }
   
