Index: source/Lib/TLibCommon/ContextTables.h
===================================================================
--- source/Lib/TLibCommon/ContextTables.h	(revision 548)
+++ source/Lib/TLibCommon/ContextTables.h	(working copy)
@@ -45,6 +45,10 @@
 // ====================================================================================================================
 // Constants
 // ====================================================================================================================
+#if WIDE_ANGLE_INTRA
+#define NUM_WIDE_ANGLE_CTX            1       ///< number of context models for the new mode
+#endif
+
 #if VCEG_AZ07_BAC_ADAPT_WDOW || VCEG_AZ07_INIT_PREVFRAME
 #define MAX_NUM_CTX_MOD             384       ///< number of context models for last coefficient position
 #else
@@ -285,6 +289,16 @@
 // Tables
 // ====================================================================================================================
 
+#if WIDE_ANGLE_INTRA
+static const UChar
+INIT_WIDE_ANGLE_MODE[NUMBER_OF_SLICE_TYPES][NUM_WIDE_ANGLE_CTX] =
+{
+  { 154 },
+  { 154 },
+  { 154 },
+};
+#endif
+
 // initial probability for cu_transquant_bypass flag
 static const UChar
 INIT_CU_TRANSQUANT_BYPASS_FLAG[NUMBER_OF_SLICE_TYPES][NUM_CU_TRANSQUANT_BYPASS_FLAG_CTX] =
Index: source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- source/Lib/TLibCommon/TComDataCU.cpp	(revision 548)
+++ source/Lib/TLibCommon/TComDataCU.cpp	(working copy)
@@ -62,6 +62,10 @@
 #endif
 
   m_skipFlag           = NULL;
+#if WIDE_ANGLE_INTRA
+  for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+    m_wideAngleMode[i] = NULL;
+#endif
 
 #if VCEG_AZ05_INTRA_MPI
   m_MPIIdx             = NULL;
@@ -242,6 +246,10 @@
 
     m_ChromaQpAdj        = new UChar[ uiNumPartition ];
     m_skipFlag           = new Bool[ uiNumPartition ];
+#if WIDE_ANGLE_INTRA
+    for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+      m_wideAngleMode[i] = (Char* )xMalloc(Char,  uiNumPartition);
+#endif
 #if VCEG_AZ05_INTRA_MPI
     m_MPIIdx             = new Char[ uiNumPartition ];
 #endif
@@ -467,6 +475,15 @@
       delete[] m_skipFlag;
       m_skipFlag = NULL;
     }
+
+#if WIDE_ANGLE_INTRA
+    for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+    {
+      xFree(m_wideAngleMode[i]);
+      m_wideAngleMode[i] = NULL;
+    }
+#endif
+
 #if VCEG_AZ05_INTRA_MPI
     if ( m_MPIIdx ) 
     { 
@@ -818,6 +835,10 @@
   m_uiNumPartition     = pcPic->getNumPartitionsInCtu();
 
   memset( m_skipFlag          , false,                      m_uiNumPartition * sizeof( *m_skipFlag ) );
+#if WIDE_ANGLE_INTRA
+  for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+    memset( m_wideAngleMode[i], 0, m_uiNumPartition * sizeof( *m_wideAngleMode[i] ) );
+#endif
 #if VCEG_AZ05_INTRA_MPI
   memset( m_MPIIdx            , 0,                      m_uiNumPartition * sizeof( *m_MPIIdx ) );
 #endif
@@ -1085,6 +1106,11 @@
 #endif
     }
     m_skipFlag[ui]      = false;
+#if WIDE_ANGLE_INTRA
+    for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+      m_wideAngleMode[i][ui] = 0;
+#endif
+
 #if VCEG_AZ05_INTRA_MPI
     m_MPIIdx[ui]        = 0;
 #endif
@@ -1312,6 +1338,10 @@
     }
     memset(m_puhInterDir + uiZorderDst, 0, uiCurrPartNumb );
     memset(m_skipFlag + uiZorderDst, false, uiCurrPartNumb );
+#if WIDE_ANGLE_INTRA
+    for( UInt ch = 0; ch < MAX_NUM_CHANNEL_TYPE; ch++ )
+      memset(m_wideAngleMode[ch] + uiZorderDst, 0, uiCurrPartNumb );
+#endif
     memset(m_pePredMode + uiZorderDst, NUMBER_OF_PREDICTION_MODES, uiCurrPartNumb );
     memset(m_CUTransquantBypass + uiZorderDst, 0, uiCurrPartNumb );
 
@@ -1511,6 +1541,10 @@
   for (UInt ui = 0; ui < m_uiNumPartition; ui++)
   {
     m_skipFlag[ui]   = false;
+#if WIDE_ANGLE_INTRA
+    for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+      m_wideAngleMode[i][ui] = 0;
+#endif
 #if VCEG_AZ05_INTRA_MPI
     m_MPIIdx[ui]     = 0;
 #endif
@@ -1636,6 +1670,10 @@
   m_uiCUPelY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
 
   m_skipFlag           =pcCU->getSkipFlag()          + uiPart;
+#if WIDE_ANGLE_INTRA
+  for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+    m_wideAngleMode[i] = pcCU->getWideAngleMode (ChannelType(i)) + uiPart;
+#endif
 
 #if VCEG_AZ05_INTRA_MPI
   m_MPIIdx             = pcCU->getMPIIdx()           + uiPart;
@@ -1804,6 +1842,10 @@
   }
 
   m_skipFlag           = pcCU->getSkipFlag ()             + uiAbsPartIdx;
+#if WIDE_ANGLE_INTRA
+  for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+    m_wideAngleMode[i] = pcCU->getWideAngleMode (ChannelType(i)) + uiAbsPartIdx;
+#endif
 #if VCEG_AZ05_INTRA_MPI
   m_MPIIdx             = pcCU->getMPIIdx ()               + uiAbsPartIdx;
 #endif
@@ -1894,6 +1936,10 @@
 
     Int sizeInChar = sizeof(Char)* uiNumPartition;
     memcpy(m_skipFlag + uiOffset, pcCU->getSkipFlag(), sizeof(*m_skipFlag)   * uiNumPartition);
+#if WIDE_ANGLE_INTRA
+  for( UInt i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
+    memcpy(m_wideAngleMode[i] + uiOffset, pcCU->getWideAngleMode(ChannelType(i)),  sizeof( *m_wideAngleMode[i] )  * uiNumPartition );
+#endif
 #if VCEG_AZ05_INTRA_MPI
     memcpy(m_MPIIdx + uiOffset, pcCU->getMPIIdx(), sizeof(*m_MPIIdx)   * uiNumPartition);
 #endif
@@ -2088,6 +2134,10 @@
     uiZorderDst = g_auiRasterToZscan[uiRaster] - m_absZIdxInCtu;
 
     memcpy(m_skipFlag + uiZorderDst, pcCU->getSkipFlag()+uiZorderSrc, uiCurrPartNumb );
+#if WIDE_ANGLE_INTRA
+    for (UInt ch=0; ch<numValidChan; ch++)
+      memcpy(m_wideAngleMode[ch] + uiZorderDst, pcCU->getWideAngleMode(ChannelType(ch))+uiZorderSrc, uiCurrPartNumb );
+#endif
 #if VCEG_AZ05_INTRA_MPI
     memcpy( m_MPIIdx     + uiZorderDst, pcCU->getMPIIdx()+uiZorderSrc, uiCurrPartNumb );
 #endif
@@ -2206,6 +2256,10 @@
 
   Int sizeInChar  = sizeof( Char ) * uiNumPartition;
   memcpy( m_skipFlag   + uiOffset, pcCU->getSkipFlag(),       sizeof( *m_skipFlag )   * uiNumPartition );
+#if WIDE_ANGLE_INTRA
+  for (UInt ch=0; ch<numValidChan; ch++)
+    memcpy( m_wideAngleMode[ch] + uiOffset, pcCU->getWideAngleMode(ChannelType(ch)), sizeof( *m_wideAngleMode[ch] ) * uiNumPartition );
+#endif
 #if VCEG_AZ05_INTRA_MPI
   memcpy( m_MPIIdx     + uiOffset, pcCU->getMPIIdx(),         sizeof( *m_MPIIdx )   * uiNumPartition );
 #endif
@@ -2385,6 +2439,10 @@
       memcpy( pCtu->isLumaIntraFilterHidden() + uiZorderDst, m_pbFiltFlagHidden + uiZorderSrc, uiCurrPartNumb );
 #endif
       memcpy( pCtu->getSkipFlag() + uiZorderDst, m_skipFlag + uiZorderSrc, uiCurrPartNumb );
+#if WIDE_ANGLE_INTRA
+      for (UInt ch=0; ch<numValidChan; ch++)
+        memcpy( pCtu->getWideAngleMode(ChannelType(ch)) + uiZorderDst, m_wideAngleMode[ch] + uiZorderSrc, uiCurrPartNumb );
+#endif
 #if VCEG_AZ05_INTRA_MPI
       memcpy( pCtu->getMPIIdx()   + uiZorderDst, m_MPIIdx + uiZorderSrc, uiCurrPartNumb );
 #endif
@@ -2497,7 +2555,11 @@
       uiZorderSrc = g_auiRasterToZscan[uiRaster] - m_absZIdxInCtu;
       uiZorderDst = g_auiRasterToZscan[uiRaster];
 
+#if WIDE_ANGLE_INTRA
       for (UInt ch=1; ch<numValidChan; ch++)
+        memcpy( pCtu->getWideAngleMode(ChannelType(ch)) + uiZorderDst, m_wideAngleMode[ch] + uiZorderSrc, uiCurrPartNumb );
+#endif
+      for (UInt ch=1; ch<numValidChan; ch++)
       {
         memcpy( pCtu->getIntraDir(ChannelType(ch)) + uiZorderDst, m_puhIntraDir[ch] + uiZorderSrc, uiCurrPartNumb);
       }
@@ -2556,6 +2618,11 @@
   memcpy( pCtu->isLumaIntraFilterHidden() + m_absZIdxInCtu, m_pbFiltFlagHidden, sizeof( *m_pbFiltFlagHidden ) * m_uiNumPartition );
 #endif
   memcpy( pCtu->getSkipFlag() + m_absZIdxInCtu, m_skipFlag, sizeof( *m_skipFlag ) * m_uiNumPartition );
+#if WIDE_ANGLE_INTRA
+  for (UInt ch=0; ch<numValidChan; ch++)
+    memcpy( pCtu->getWideAngleMode(ChannelType(ch))  + m_absZIdxInCtu, m_wideAngleMode[ch],  sizeof( *m_wideAngleMode[ch] )  * m_uiNumPartition );
+#endif
+
 #if VCEG_AZ05_INTRA_MPI
   memcpy( pCtu->getMPIIdx()   + m_absZIdxInCtu, m_MPIIdx, sizeof( *m_MPIIdx ) * m_uiNumPartition );
 #endif
@@ -4300,6 +4367,21 @@
 
   if( !getMergeFlag( uiAbsPartIdx ) )
   {
+#if ER_MV_PBL
+    ListPredDir predDir = DIR_NONE;
+    if (   getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx) >= 0
+        && getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx) >= 0 )
+    {
+      AMVPInfo cAMVPInfoL1;
+      fillMvpCand( uiPartIdx, uiAbsPartIdx, REF_PIC_LIST_1, getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx), &cAMVPInfoL1
+#if VCEG_AZ07_FRUC_MERGE
+                   , pPred
+#endif
+                 );
+      predDir = (cAMVPInfoL1.isScaled[0] == HIGH_PRIO || cAMVPInfoL1.isScaled[1] == HIGH_PRIO) ? DIR_L1toL0 : DIR_L0toL1;
+    }
+#endif
+
     for( RefPicList eRefPicList = REF_PIC_LIST_0 ; eRefPicList <= REF_PIC_LIST_1 ; eRefPicList = ( RefPicList )( ( Int )eRefPicList + 1 ) )
     {
       TComCUMvField * pMVField = getCUMvField( eRefPicList );
@@ -4315,6 +4397,76 @@
 #endif
           );
 
+#if ER_MV_PBL
+        if ( predDir == DIR_L1toL0 && eRefPicList == REF_PIC_LIST_0 && getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx) >= 0 && getSlice()->getMvdL1ZeroFlag() == false )
+        {
+          TComMv cMvL1  = getCUMvField(REF_PIC_LIST_1)->getMv(uiAbsPartIdx);
+          Int    iRefL1 = getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx);
+
+          if (bResetMV)
+          {
+#if JVET_E0076_MULTI_PEL_MVD
+            xRoundMV( cMvL1, uiAbsPartIdx );
+#else
+            xRoundMV( cMvL1 );
+#endif
+          }
+
+          Bool hasScaled = false;
+          Int  firstHasScaledIdx = -1;
+
+          for (Int iMvpIdx = 0; iMvpIdx < pcAMVPInfo->iN; iMvpIdx++)
+          {
+            if (pcAMVPInfo->isScaled[iMvpIdx] == LOW_PRIO)
+            {
+              hasScaled = true;
+              firstHasScaledIdx = iMvpIdx;
+              break;
+            }
+          }
+
+          TComMv cMvPredFromL1;
+          Bool   hasMvPredFromL1 = false;
+          //hasMvPredFromL1 = xAddList1Cand(cMvL1, cMvPredFromL1, pMVField->getRefIdx(uiAbsPartIdx), iRefL1, uiAbsPartIdx);
+          hasMvPredFromL1 = xAddListXCand( cMvL1, cMvPredFromL1, 1, iRefL1, pMVField->getRefIdx(uiAbsPartIdx), uiAbsPartIdx );
+
+          if (hasScaled && hasMvPredFromL1)
+          {
+            pcAMVPInfo->m_acMvCand[firstHasScaledIdx] = cMvPredFromL1;
+          }
+        }
+
+        if (predDir == DIR_L0toL1 && eRefPicList == REF_PIC_LIST_1 && getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx) >= 0 && getSlice()->getMvdL1ZeroFlag() == false)
+        {
+          TComMv cMvL0 = getCUMvField(REF_PIC_LIST_0)->getMv(uiAbsPartIdx);
+          Int    iRefL0 = getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx);
+
+          Bool hasScaled = false;
+          Int  firstHasScaledIdx = -1;
+
+          for (Int iMvpIdx = 0; iMvpIdx < pcAMVPInfo->iN; iMvpIdx++)
+          {
+            if (pcAMVPInfo->isScaled[iMvpIdx] == LOW_PRIO)
+            {
+              hasScaled = true;
+              firstHasScaledIdx = iMvpIdx;
+              break;
+            }
+          }
+
+          TComMv cMvPredFromL0;
+          Bool   hasMvPredFromL0 = false;
+          //hasMvPredFromL0 = xAddList0Cand(cMvL0, cMvPredFromL0, iRefL0, pMVField->getRefIdx(uiAbsPartIdx), uiAbsPartIdx);
+          hasMvPredFromL0 = xAddListXCand( cMvL0, cMvPredFromL0, 0, iRefL0, pMVField->getRefIdx(uiAbsPartIdx), uiAbsPartIdx );
+
+
+          if (hasScaled && hasMvPredFromL0)
+          {
+            pcAMVPInfo->m_acMvCand[firstHasScaledIdx] = cMvPredFromL0;
+          }
+        }
+#endif
+
         mvPred = pcAMVPInfo->m_acMvCand[getMVPIdx(eRefPicList , uiAbsPartIdx)];
 
         if( bResetMV )
@@ -4980,6 +5132,73 @@
 #endif
 }
 
+#if WIDE_ANGLE_INTRA
+
+#if VCEG_AZ07_INTRA_65ANG_MODES
+#define WIDE_ANGLE_INTRA_MODE_RANGE 10
+#else
+#define WIDE_ANGLE_INTRA_MODE_RANGE 5
+#endif
+     
+Bool TComDataCU::hasWideAngleModeAvailable( UInt uiAbsPartIdx, Int predMode )
+{
+  const Int horMinMode = 2 + 1;                                       // Bottom-left-diagonal + 1
+  const Int horMaxMode = 2 + WIDE_ANGLE_INTRA_MODE_RANGE;
+  const Int verMinMode = VDIA_IDX - WIDE_ANGLE_INTRA_MODE_RANGE;
+  const Int verMaxMode = VDIA_IDX - 1;                                // Top-right-diagonal - 1
+
+  Int width  = getWidth (uiAbsPartIdx);
+  Int height = getHeight(uiAbsPartIdx);
+
+  if ( width > height )
+    return  ( predMode >= horMinMode ) && ( predMode <= horMaxMode );
+  else if ( height > width )
+    return  ( predMode >= verMinMode ) && ( predMode <= verMaxMode );
+  else
+    return false;
+}
+
+Int TComDataCU::deriveChromaWideAngleMode( UInt uiAbsPartIdx, Int predMode )
+{
+#if JVET_C0024_QTBT
+  UInt uiIntraModeLuma = getSlice()->isIntra() ? getPic()->getCtu(getCtuRsAddr())->getIntraDir(CHANNEL_TYPE_LUMA, getZorderIdxInCtu()+uiAbsPartIdx) : getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx );
+  UInt uiIntraMode     = predMode == DM_CHROMA_IDX ? uiIntraModeLuma : predMode; // Get real prediction mode if direct mode is indicated (in the case of JVET_E0062_MULTI_DMS this is set already)
+  Int wideAngleMode    = getSlice()->isIntra() ? hasWideAngleModeAvailable ( uiAbsPartIdx, uiIntraMode ) && getWidth(uiAbsPartIdx) != getHeight(uiAbsPartIdx) : uiIntraMode == uiIntraModeLuma ? getWideAngleMode ( CHANNEL_TYPE_LUMA, uiAbsPartIdx ) : 0;
+#else
+  UInt uiIntraModeLuma = getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx );
+  UInt uiIntraMode     = predMode == DM_CHROMA_IDX ? uiIntraModeLuma : predMode; // Get real prediction mode if direct mode is indicated (in the case of JVET_E0062_MULTI_DMS this is set already)
+  Int wideAngleMode    = uiIntraMode == uiIntraModeLuma ? getWideAngleMode ( CHANNEL_TYPE_LUMA, uiAbsPartIdx ) : 0;
+#endif
+  
+  return wideAngleMode;
+}
+
+Bool TComDataCU::hasWideAngleChromaFlag( UInt uiAbsPartIdx, Int predMode )
+{
+#if JVET_C0024_QTBT
+  if ( getSlice()->isIntra() )
+  {
+    UInt uiIntraModeLuma = getPic()->getCtu(getCtuRsAddr())->getIntraDir(CHANNEL_TYPE_LUMA, getZorderIdxInCtu()+uiAbsPartIdx);
+    UInt uiIntraMode     = predMode == DM_CHROMA_IDX ? uiIntraModeLuma : predMode; // Get real prediction mode if direct mode is indicated (in the case of JVET_E0062_MULTI_DMS this is set already)
+    
+    return hasWideAngleModeAvailable( uiAbsPartIdx, uiIntraMode );
+  }
+#endif
+
+  return false;
+}
+     
+Void TComDataCU::setWideAngleModeSubParts( ChannelType channelType, Char mode, UInt absPartIdx, UInt depth )
+{
+#if JVET_C0024_QTBT
+  setSubPart<Char>( mode, m_wideAngleMode[channelType], absPartIdx, getWidth(absPartIdx), getHeight(absPartIdx) );
+#else
+  assert( sizeof( *m_wideAngleMode[channelType]) == 1 );
+  memset( m_wideAngleMode[channelType] + absPartIdx, mode, m_pcPic->getNumPartitionsInCtu() >> ( 2 * depth ) );
+#endif
+}
+#endif
+
 #if VCEG_AZ05_INTRA_MPI
 Void TComDataCU::setMPIIdxSubParts( Char MPIIdx, UInt absPartIdx, UInt depth  )
 {
@@ -6422,6 +6641,200 @@
 
 #endif
 
+#if ER_MV_LB
+
+template< Bool DO_TOP, Bool DO_LEFT>
+Void TComDataCU::lookBack( UInt uiPartIdxRT, UInt uiPartIdxLB, std::vector<PropMvPack>& mvPacks)
+{
+  mvPacks.clear();
+
+#if ER_LB_USE_RANGE_LIMIT
+  Int  mileage  = 0;
+  Int  ctuSize  = getPic()->getPicSym()->getMinCUWidth() * getPic()->getPicSym()->getNumPartInCtuWidth();
+  Int  milLimit = ER_RANGE_CTU_RATIO * ctuSize;
+#endif
+
+  // Get TOP CU
+  if ( DO_TOP )
+  {
+    UInt        uiCurPartIdx    = 0;
+    UInt        uiCurPartIdxRT  = 0;
+    TComDataCU* pcCUCur         = getPUAbove(uiCurPartIdx, uiPartIdxRT);
+    TComDataCU* pcCUAbove       = pcCUCur;
+
+    Bool        bLookBackVer    = pcCUCur;
+    Bool        bFoundCandVer   = false;
+    PropMvPack  mvPackCandVer;
+
+#if ER_LB_USE_RANGE_LIMIT
+    mileage  = 0;
+#endif
+
+    while ( bLookBackVer && !bFoundCandVer )
+    {
+      UInt uiHeightInSubblk = pcCUCur->getHeight(uiCurPartIdx) / pcCUCur->getPic()->getPicSym()->getMinCUHeight();
+
+#if ER_LB_USE_RANGE_LIMIT
+      {
+        mileage += pcCUCur->getHeight(uiCurPartIdx);
+        if (mileage > milLimit) break;
+      }
+#endif
+      uiCurPartIdxRT = g_auiRasterToZscan[g_auiZscanToRaster[uiCurPartIdx] - (uiHeightInSubblk - 1) * pcCUCur->getPic()->getPicSym()->getNumPartInCtuWidth()];
+      pcCUAbove = pcCUCur->getPUAbove(uiCurPartIdx, uiCurPartIdxRT);
+
+      if (pcCUAbove && pcCUAbove->isInter(uiCurPartIdx))
+      {
+        PropMvPack pack;
+        pack.mvDir = pcCUAbove->getInterDir(uiCurPartIdx);
+        pack.mvField[REF_PIC_LIST_0].setMvField( pcCUAbove->getCUMvField(REF_PIC_LIST_0)->getMv(uiCurPartIdx),
+                                                 pcCUAbove->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiCurPartIdx) );
+
+        pack.mvField[REF_PIC_LIST_1].setMvField( pcCUAbove->getCUMvField(REF_PIC_LIST_1)->getMv(uiCurPartIdx),
+                                                 pcCUAbove->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiCurPartIdx) );
+#if VCEG_AZ06_IC
+        pack.ICFlag = false;
+#endif
+
+        bFoundCandVer = true;
+        mvPacks.push_back(pack);
+      }
+
+      pcCUCur = pcCUAbove;
+      bLookBackVer = pcCUCur;
+    }
+  }
+
+  // Get LEFT CU
+  if ( DO_LEFT )
+  {
+    UInt        uiCurPartIdx   = 0;
+    UInt        uiCurPartIdxLB = 0;
+    TComDataCU* pcCUCur        = getPULeft(uiCurPartIdx, uiPartIdxLB);
+    TComDataCU* pcCULeft       = pcCUCur;
+
+    Bool        bLookBackHor   = pcCUCur;
+    Bool        bFoundCandHor  = false;
+    PropMvPack  mvPackCandHor;
+
+#if ER_LB_USE_RANGE_LIMIT
+    mileage = 0;
+#endif
+
+    while (bLookBackHor && !bFoundCandHor)
+    {
+      UInt uiWidthInSubblk = pcCUCur->getWidth(uiCurPartIdx) / pcCUCur->getPic()->getPicSym()->getMinCUHeight();
+
+#if ER_LB_USE_RANGE_LIMIT
+      {
+        mileage += pcCUCur->getWidth(uiCurPartIdx);
+        if ( mileage > milLimit ) break;
+      }
+#endif
+
+      uiCurPartIdxLB = g_auiRasterToZscan[g_auiZscanToRaster[uiCurPartIdx] - (uiWidthInSubblk - 1)];
+      pcCULeft = pcCUCur->getPULeft(uiCurPartIdx, uiCurPartIdxLB);
+
+      if (pcCULeft && pcCULeft->isInter(uiCurPartIdx))
+      {
+        PropMvPack pack;
+        pack.mvDir = pcCULeft->getInterDir(uiCurPartIdx);
+        pack.mvField[REF_PIC_LIST_0].setMvField( pcCULeft->getCUMvField(REF_PIC_LIST_0)->getMv(uiCurPartIdx),
+                                                 pcCULeft->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiCurPartIdx) );
+
+        pack.mvField[REF_PIC_LIST_1].setMvField( pcCULeft->getCUMvField(REF_PIC_LIST_1)->getMv(uiCurPartIdx),
+                                                 pcCULeft->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiCurPartIdx) );
+
+#if VCEG_AZ06_IC
+        pack.ICFlag = false;
+#endif
+
+        Bool bAllowed = true;
+        for (std::vector<PropMvPack>::iterator it = mvPacks.begin(); it != mvPacks.end(); it++)
+        {
+          if (equalPackCheck(*it, pack))
+          {
+            bAllowed = false; break;
+          }
+        }
+
+        if (bAllowed)
+        {
+          bFoundCandHor = true;
+          mvPacks.push_back(pack);
+        }
+      }
+
+      pcCUCur = pcCULeft;
+      bLookBackHor = pcCUCur;
+    }
+  }
+}
+
+Bool  TComDataCU::isOKwithList( PropMvPack&    mvPack,
+                                TComMvField*   pcMFieldNeighbours,
+                                UChar*         puhInterDirNeighbours,
+                                Int            numValidMergeCand
+#if VCEG_AZ06_IC
+                               ,Bool*         pbICFlag
+#endif
+#if COM16_C806_VCEG_AZ10_SUB_PU_TMVP
+                               ,UChar*        peMergeTypeNeighbors
+#endif
+                               )
+{
+  for (Int other = 0; other < numValidMergeCand; other++)
+  {
+#if COM16_C806_VCEG_AZ10_SUB_PU_TMVP
+    if ( peMergeTypeNeighbors[other] != MGR_TYPE_DEFAULT_N )
+      continue;
+#endif
+
+    {
+      PropMvPack otherPack;
+#if VCEG_AZ06_IC
+      otherPack.ICFlag = pbICFlag[other];
+      otherPack.mvDir  = puhInterDirNeighbours[other];
+
+      otherPack.mvField[REF_PIC_LIST_0].setMvField( pcMFieldNeighbours[ other << 1     ].getMv(), pcMFieldNeighbours[ other << 1     ].getRefIdx() );
+      otherPack.mvField[REF_PIC_LIST_1].setMvField( pcMFieldNeighbours[(other << 1) + 1].getMv(), pcMFieldNeighbours[(other << 1) + 1].getRefIdx() );
+#endif
+      if (equalPackCheck (mvPack, otherPack))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+Bool  TComDataCU::equalPackCheck ( PropMvPack& pack0,
+                                   PropMvPack& pack1 )
+{
+  if ( pack0.mvDir != pack1.mvDir)
+    return false;
+
+#if VCEG_AZ06_IC
+ //  if (pack0.ICFlag != pack1.ICFlag)
+ //    return false;
+#endif
+
+  for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
+  {
+    if ( pack0.mvDir & (1 << uiRefListIdx) )
+    {
+      if ( pack0.mvField[uiRefListIdx].getMv()     != pack1.mvField[uiRefListIdx].getMv() ||
+           pack0.mvField[uiRefListIdx].getRefIdx() != pack1.mvField[uiRefListIdx].getRefIdx() )
+      {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+#endif
+
 //! Construct a list of merging candidates
 Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand
 #if VCEG_AZ06_IC
@@ -6468,6 +6881,10 @@
 
   Int iCount = 0;
 
+#if ER_NO_ADD_IF_MANY_SPATIAL
+  Int iSpatialCount = 0;
+#endif
+
   UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
 #if JVET_C0024_QTBT
   assert(uiPUIdx==0);
@@ -6532,6 +6949,9 @@
       return;
     }
     iCount ++;
+#if ER_NO_ADD_IF_MANY_SPATIAL
+    iSpatialCount++;
+#endif
   }
 
   // early termination
@@ -6573,6 +6993,9 @@
       return;
     }
     iCount ++;
+#if ER_NO_ADD_IF_MANY_SPATIAL
+    iSpatialCount++;
+#endif
   }
   // early termination
   if (iCount == getSlice()->getMaxNumMergeCand())
@@ -6621,6 +7044,9 @@
       return;
     }
     iCount ++;
+#if ER_NO_ADD_IF_MANY_SPATIAL
+    iSpatialCount++;
+#endif
   }
   // early termination
   if (iCount == getSlice()->getMaxNumMergeCand())
@@ -6669,6 +7095,9 @@
     {
       return;
     }
+#if ER_NO_ADD_IF_MANY_SPATIAL
+    iSpatialCount++;
+#endif
     iCount ++;
   }
   // early termination
@@ -6836,6 +7265,9 @@
       {
         return;
       }
+#if ER_NO_ADD_IF_MANY_SPATIAL
+      iSpatialCount++;
+#endif
       iCount ++;
     }
   }
@@ -6845,6 +7277,51 @@
     return;
   }
 
+#if ER_MV_LB
+  std::vector < PropMvPack > mvPacks;
+
+  lookBack < true, true > ( uiPartIdxRT, uiPartIdxLB, mvPacks );
+
+#if ER_NO_ADD_IF_MANY_SPATIAL
+  for (std::vector<PropMvPack>::iterator it = mvPacks.begin(); it != mvPacks.end() && iSpatialCount < ER_SPATIAL_LIMIT; it++)
+#else
+  for (std::vector<PropMvPack>::iterator it = mvPacks.begin(); it != mvPacks.end(); it++)
+#endif
+  {
+    if ( isOKwithList( *it, pcMvFieldNeighbours, puhInterDirNeighbours, iCount
+#if VCEG_AZ06_IC
+                       , pbICFlag
+#endif
+#if COM16_C806_VCEG_AZ10_SUB_PU_TMVP
+                       , peMergeTypeNeighbors
+#endif
+                      ) )
+    {
+      puhInterDirNeighbours[iCount] = it->mvDir;
+      pcMvFieldNeighbours[iCount << 1].setMvField(it->mvField[REF_PIC_LIST_0].getMv(), it->mvField[REF_PIC_LIST_0].getRefIdx());
+      if (getSlice()->isInterB())
+        pcMvFieldNeighbours[(iCount << 1) + 1].setMvField(it->mvField[REF_PIC_LIST_1].getMv(), it->mvField[REF_PIC_LIST_1].getRefIdx());
+
+      if (mrgCandIdx == iCount)
+      {
+        return;
+      }
+
+      iCount++;
+
+      // early termination
+      if (iCount == getSlice()->getMaxNumMergeCand())
+      {
+        return;
+      }
+    }
+
+    Int numOfInterest = (it - mvPacks.begin()) + 1;
+    if (numOfInterest >= ER_NB_LIMIT) break;
+
+  }
+#endif
+
   if ( getSlice()->getEnableTMVPFlag() )
   {
     //>> MTK colocated-RightBottom
@@ -7758,6 +8235,9 @@
     }
     if ( ctuRsAddr >= 0 && xGetColMVP( eRefPicList, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx_Col ) )
     {
+#if ER_MV_PBL
+      pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
       pInfo->m_acMvCand[pInfo->iN++] = cColMv;
     }
     else
@@ -7766,6 +8246,9 @@
       xDeriveCenterIdx( uiPartIdx, uiPartIdxCenter );
       if (xGetColMVP( eRefPicList, getCtuRsAddr(), uiPartIdxCenter,  cColMv, iRefIdx_Col ))
       {
+#if ER_MV_PBL
+        pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
         pInfo->m_acMvCand[pInfo->iN++] = cColMv;
       }
     }
@@ -7791,11 +8274,17 @@
       {
         for( Int n = min( pInfo->iN , AMVP_MAX_NUM_CANDS - 1 ) ; n > 0 ; n-- )
         {
+#if ER_MV_PBL
+          pInfo->isScaled[n] = pInfo->isScaled[n - 1];
+#endif
           pInfo->m_acMvCand[n] = pInfo->m_acMvCand[n-1];
         }
         pInfo->m_acMvCand[0] = rMV;
         pInfo->iN = min( pInfo->iN + 1 , AMVP_MAX_NUM_CANDS );
       }
+#if ER_MV_PBL
+      pInfo->isScaled[0] = HIGH_PRIO;
+#endif
     }
   }
 #endif
@@ -7808,6 +8297,9 @@
   while (pInfo->iN < AMVP_MAX_NUM_CANDS)
   {
     pInfo->m_acMvCand[pInfo->iN].set(0,0);
+#if ER_MV_PBL
+    pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
     pInfo->iN++;
   }
   
@@ -8005,6 +8497,126 @@
 // Protected member functions
 // ====================================================================================================================
 
+#if ER_MV_PBL
+// add lx candidate to current list ly
+Bool TComDataCU::xAddListXCand(TComMv cMvLx, TComMv& cMvPredLy, Int Lx, Int iRefIdxLx, Int iRefIdxLy, UInt uPartIdx)
+{
+  if (iRefIdxLx < 0 || iRefIdxLy < 0)
+  {
+    assert(0);
+    return false;
+  }
+
+  RefPicList listX = RefPicList(Lx);
+  RefPicList listY = RefPicList(1 - Lx);
+  Int  iCurrRefPOC = m_pcSlice->getRefPic(listY, iRefIdxLy)->getPOC();
+  Int  iNeibRefPOC = m_pcSlice->getRefPic(listX, iRefIdxLx)->getPOC();
+
+#if VCEG_AZ07_IMV
+  Bool bIsIMV = getiMVFlag(uPartIdx) && getSlice()->getSPS()->getIMV();
+#endif
+
+  if (iNeibRefPOC == iCurrRefPOC)
+  {
+    cMvPredLy = cMvLx;
+#if VCEG_AZ07_IMV
+    if (bIsIMV)
+    {
+#if JVET_E0076_MULTI_PEL_MVD
+      xRoundMV(cMvPredLy, uPartIdx);
+#else
+      xRoundMV(cMvPredLy);
+#endif
+    }
+#endif
+    return true;
+  }
+
+  Int iCurrPOC = m_pcSlice->getPOC();
+  Int iNeibPOC = iCurrPOC;
+
+  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(listY, iRefIdxLy)->getIsLongTerm();
+  Bool bIsNeibRefLongTerm = m_pcSlice->getRefPic(listX, iRefIdxLx)->getIsLongTerm();
+
+  TComMv cMvPred = cMvLx;
+  TComMv rcMv;
+
+  if (bIsCurrRefLongTerm == bIsNeibRefLongTerm)
+  {
+    if (bIsCurrRefLongTerm || bIsNeibRefLongTerm)
+    {
+      cMvPredLy = cMvPred;
+    }
+    else
+    {
+      Int iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC);
+      if (iScale == 4096)
+      {
+        cMvPredLy = cMvPred;
+      }
+      else
+      {
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+        cMvPredLy = cMvPred.scaleMv(iScale);
+        cMvPredLy.roundMV2SignalPrecision();
+#else
+        cMvPredLy = cMvPred.scaleMv(iScale);
+#endif
+      }
+    }
+#if VCEG_AZ07_IMV
+    if (bIsIMV)
+    {
+#if JVET_E0076_MULTI_PEL_MVD
+      xRoundMV(cMvPredLy, uPartIdx);
+#else
+      xRoundMV(cMvPredLy);
+#endif
+    }
+#endif
+    return true;
+  }
+  else
+  {
+    assert(0);
+    return false;
+  }
+}
+
+Void TComDataCU::xGetFreeSlot ( AMVPInfo* pAmvpInfo,
+                                Bool&     bHasSlot,
+                                Int&      iSlotIdx )
+{
+  for (Int iMvpIdx = 0; iMvpIdx < pAmvpInfo->iN; iMvpIdx++)
+  {
+    if ( pAmvpInfo->isScaled[iMvpIdx] == LOW_PRIO )
+    {
+      bHasSlot = true;
+      iSlotIdx = iMvpIdx;
+      return;
+    }
+  }
+
+  bHasSlot = false;
+  iSlotIdx = -1;
+  return;
+}
+
+
+Bool TComDataCU::xHasHighPrio( AMVPInfo* pAmvpInfo )
+{
+  for (Int iMvpIdx = 0; iMvpIdx < pAmvpInfo->iN; iMvpIdx++)
+  {
+    if (pAmvpInfo->isScaled[iMvpIdx] == HIGH_PRIO)
+    {
+      return true;
+    }
+  }
+  return false;
+}
+
+#endif
+
 Bool TComDataCU::xAddMVPCand( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir
 #if COM16_C1016_AFFINE
   , bool bAffine
@@ -8067,6 +8679,9 @@
       }
       if ( i == pInfo->iN )
       {
+#if ER_MV_PBL
+        pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
         pInfo->m_acMvCand[pInfo->iN++] = cMvPred;
         return true;
       }
@@ -8073,10 +8688,16 @@
     }
     else
     {
+#if ER_MV_PBL
+      pInfo->isScaled[pInfo->iN] = HIGH_PRIO;
+#endif
       pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
       return true;
     }
 #else
+#if ER_MV_PBL
+    pInfo->isScaled[pInfo->iN] = HIGH_PRIO;
+#endif
     pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
     return true;
 #endif
@@ -8116,6 +8737,9 @@
         }
         if ( i == pInfo->iN )
         {
+#if ER_MV_PBL
+          pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
           pInfo->m_acMvCand[pInfo->iN++] = cMvPred;
           return true;
         }
@@ -8122,10 +8746,16 @@
       }
       else
       {
+#if ER_MV_PBL
+        pInfo->isScaled[pInfo->iN] = HIGH_PRIO;
+#endif
         pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
         return true;
       }
 #else
+#if ER_MV_PBL
+      pInfo->isScaled[pInfo->iN] = HIGH_PRIO;
+#endif
       pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
       return true;
 #endif
@@ -8244,6 +8874,9 @@
         }
         if ( i == pInfo->iN )
         {
+#if ER_MV_PBL
+          pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
           pInfo->m_acMvCand[pInfo->iN++] = rcMv;
           return true;
         }
@@ -8250,10 +8883,16 @@
       }
       else
       {
+#if ER_MV_PBL
+        pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
         pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
         return true;
       }
 #else
+#if ER_MV_PBL
+      pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
       pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
       return true;
 #endif
@@ -8298,6 +8937,9 @@
         }
         if ( i == pInfo->iN )
         {
+#if ER_MV_PBL
+          pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
           pInfo->m_acMvCand[pInfo->iN++] = rcMv;
           return true;
         }
@@ -8304,10 +8946,16 @@
       }
       else
       {
+#if ER_MV_PBL
+        pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
         pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
         return true;
       }
 #else
+#if ER_MV_PBL
+      pInfo->isScaled[pInfo->iN] = LOW_PRIO;
+#endif
       pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
       return true;
 #endif
@@ -8622,7 +9270,11 @@
 
 #if COM16_C806_OBMC
 // Function for fetching neighboring motions.
-Bool TComDataCU::getNeigMotion( UInt uiAbsPartIdx, TComMvField cNeigMvField[2], Int &irNeigPredDir, Int iDir, TComMvField cCurMvField[2], Int &iCurrDir, UInt uiZeroIdx, Bool &bTobeStored )
+Bool TComDataCU::getNeigMotion( UInt uiAbsPartIdx, TComMvField cNeigMvField[2], Int &irNeigPredDir, Int iDir, TComMvField cCurMvField[2], Int &iCurrDir, UInt uiZeroIdx, Bool &bTobeStored
+#if OBMC_SKIP
+  , Bool bImplicit
+#endif
+)
 {
   TComDataCU* pcTmpCU = NULL;
   UInt uiIdx;
@@ -8650,6 +9302,12 @@
     return false;
   }
 
+
+#if OBMC_LIC_SKIP
+  if ((pcTmpCU->getICFlag(uiIdx) != getICFlag(uiAbsPartIdx)) && bImplicit)
+    return false;
+#endif
+
   irNeigPredDir = pcTmpCU->getInterDir( uiIdx );
   if(irNeigPredDir)
   { 
Index: source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- source/Lib/TLibCommon/TComDataCU.h	(revision 548)
+++ source/Lib/TLibCommon/TComDataCU.h	(working copy)
@@ -68,6 +68,16 @@
 // Class definition
 // ====================================================================================================================
 
+struct PropMvPack
+{
+  TComMvField mvField[2];
+  UChar       mvDir;
+  UChar       mvPrio;
+#if VCEG_AZ06_IC
+  Bool        ICFlag;
+#endif
+};
+
 /// CU data structure class
 class TComDataCU
 {
@@ -122,6 +132,9 @@
   // -------------------------------------------------------------------------------------------------------------------
 
   Bool*          m_skipFlag;           ///< array of skip flags
+#if WIDE_ANGLE_INTRA
+  Char*          m_wideAngleMode[MAX_NUM_CHANNEL_TYPE]; ///< Wide angle intra mode indicator
+#endif
 #if VCEG_AZ05_INTRA_MPI
   Char*          m_MPIIdx;             ///< array of MPIIdxs
 #endif
@@ -387,6 +400,16 @@
   Void          setSkipFlag           ( UInt idx, Bool skip)     { m_skipFlag[idx] = skip;   }
   Void          setSkipFlagSubParts   ( Bool skip, UInt absPartIdx, UInt depth );
 
+#if WIDE_ANGLE_INTRA
+  Char*         getWideAngleMode        ( ChannelType channelType )                         { return m_wideAngleMode[channelType];          }
+  Char          getWideAngleMode        ( ChannelType channelType, UInt idx)                { return m_wideAngleMode[channelType][idx];     }
+  Void          setWideAngleMode        ( ChannelType channelType, UInt idx, Char mode)     { m_wideAngleMode[channelType][idx] = mode;     }
+  Void          setWideAngleModeSubParts( ChannelType channelType, Char mode, UInt absPartIdx, UInt depth );
+  Bool          hasWideAngleModeAvailable( UInt uiAbsPartIdx, Int predMode );
+  Bool          hasWideAngleChromaFlag   ( UInt uiAbsPartIdx, Int predMode );
+  Int           deriveChromaWideAngleMode( UInt uiAbsPartIdx, Int predMode );
+#endif
+
 #if VCEG_AZ05_INTRA_MPI
   Char*         getMPIIdx               ()                        { return m_MPIIdx;          }
   Char          getMPIIdx               ( UInt idx)               { return m_MPIIdx[idx];     }
@@ -627,8 +650,13 @@
   Void          setOBMCFlag          ( UInt idx, Bool OBMC )   { m_OBMCFlag[idx] = OBMC;     }
   Void          setOBMCFlagSubParts  ( Bool OBMC, UInt absPartIdx, UInt depth );
   Bool          isOBMCFlagCoded      ( UInt uiAbsPartIdx );
-  Bool          getNeigMotion( UInt uiAbsPartIdx, TComMvField cNeigMvField[2], Int &irNeigPredDir, Int iDir, TComMvField cCurMvField[2], Int &iCurrDir, UInt uiZeroIdx, Bool &bTobeStored);
+  Bool          getNeigMotion( UInt uiAbsPartIdx, TComMvField cNeigMvField[2], Int &irNeigPredDir, Int iDir, TComMvField cCurMvField[2], Int &iCurrDir, UInt uiZeroIdx, Bool &bTobeStored
+#if OBMC_SKIP
+    , Bool bImplicit
 #endif
+  );
+#endif
+
 #if VCEG_AZ06_IC
   Bool*         getICFlag            ()                        { return m_pbICFlag;               }
   Bool          getICFlag            ( UInt uiIdx )            { return m_pbICFlag[uiIdx];        }
@@ -760,6 +788,23 @@
   // member functions for motion vector
   // -------------------------------------------------------------------------------------------------------------------
 
+#if ER_MV_PBL
+
+  Bool          xAddListXCand         ( TComMv  cMvLx,
+                                        TComMv& cMvPredLy,
+                                        Int     lx,
+                                        Int     iRefIdxLx,
+                                        Int     iRefIdxLy,
+                                        UInt    uPartIdx );
+
+  Void          xGetFreeSlot          ( AMVPInfo* pAmvpInfo,
+                                        Bool&     bHasSlot,
+                                        Int&      iSlotIdx );
+
+  Bool          xHasHighPrio          ( AMVPInfo* pAmvpInfo );
+
+#endif
+
   Void          getMvField            ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, TComMvField& rcMvField );
 
   Void          fillMvpCand           ( UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, AMVPInfo* pInfo 
@@ -848,7 +893,31 @@
   , TComDataCU*     pDecCurrCU = NULL
 #endif
     , Int mrgCandIdx = -1 );
+
+#if ER_MV_LB
+
+  template< Bool DO_TOP, Bool DO_LEFT >
+  Void lookBack ( UInt uiPartIdxRT, UInt uiPartIdxLB, std::vector<PropMvPack>& mvPacks );
+
+  Bool         isOKwithList ( PropMvPack&    mvPack,
+                              TComMvField*   pcMFieldNeighbours,
+                              UChar*         puhInterDirNeighbours,
+                              Int            numValidMergeCand
+#if VCEG_AZ06_IC
+                             ,Bool*          pbICFlag
+#endif
 #if COM16_C806_VCEG_AZ10_SUB_PU_TMVP
+                             ,UChar*         peMergeTypeNeighbors
+#endif
+                            );
+
+  Bool        equalPackCheck ( PropMvPack& pack0,
+                               PropMvPack& pack1 );
+
+#endif
+
+
+#if COM16_C806_VCEG_AZ10_SUB_PU_TMVP
   
   Void          getSPPara(Int iPUWidth, Int iPUHeight, Int& iNumSP, Int& iNumSPInOneLine, Int& iSPWidth, Int& iSPHeight);
   Void          getSPAbsPartIdx(UInt uiBaseAbsPartIdx, Int iWidth, Int iHeight, Int iPartIdx, Int iNumPartLine, UInt& ruiPartAddr );
Index: source/Lib/TLibCommon/TComLoopFilter.cpp
===================================================================
--- source/Lib/TLibCommon/TComLoopFilter.cpp	(revision 548)
+++ source/Lib/TLibCommon/TComLoopFilter.cpp	(working copy)
@@ -45,7 +45,6 @@
 #endif
 //! \ingroup TLibCommon
 //! \{
-
 // ====================================================================================================================
 // Constants
 // ====================================================================================================================
@@ -79,6 +78,10 @@
 {
   for( Int edgeDir = 0; edgeDir < NUM_EDGE_DIR; edgeDir++ )
   {
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    m_aapucBS_chroma       [edgeDir] = NULL;
+    m_aapbEdgeFilter_chroma[edgeDir] = NULL;
+#endif
     m_aapucBS       [edgeDir] = NULL;
     m_aapbEdgeFilter[edgeDir] = NULL;
   }
@@ -88,6 +91,37 @@
 {
 }
 
+#if DEBLOCKING_SUBBLOCKS
+/**
+ * \brief Get sub-block size for further refinement
+ *
+ * \param pcCU            Pointer to current CU
+ * \param uiAbsPartIdx    Address of block within CU
+ * \param nBlkWidth       Width of the block
+ * \param nBlkHeight      Height of the block
+ */
+Int xFrucGetSubBlkSize( TComDataCU * pcCU , UInt uiAbsPartIdx , Int nBlkWidth , Int nBlkHeight )
+{
+#if JVET_C0024_QTBT
+  Int avgLength = 1<<(((g_aucConvertToBit[pcCU->getWidth( uiAbsPartIdx )] + g_aucConvertToBit[pcCU->getHeight( uiAbsPartIdx )] + 1)>>1) + MIN_CU_LOG2);
+  Int nRefineBlkSize = max( avgLength >> pcCU->getSlice()->getSPS()->getFRUCSmallBlkRefineDepth() , FRUC_MERGE_REFINE_MINBLKSIZE );
+#else
+  Int nRefineBlkSize = max( pcCU->getWidth( uiAbsPartIdx ) >> pcCU->getSlice()->getSPS()->getFRUCSmallBlkRefineDepth() , FRUC_MERGE_REFINE_MINBLKSIZE );
+#endif
+  while( true )
+  {
+    Int nMask = nRefineBlkSize - 1;
+    if( nRefineBlkSize > min( nBlkWidth , nBlkHeight ) || ( nBlkWidth & nMask ) || ( nBlkHeight & nMask ) )
+      nRefineBlkSize >>= 1;
+    else
+      break;
+  }
+  assert( nRefineBlkSize >= FRUC_MERGE_REFINE_MINBLKSIZE );
+  return( nRefineBlkSize );
+}
+#endif
+
+
 // ====================================================================================================================
 // Public member functions
 // ====================================================================================================================
@@ -102,6 +136,10 @@
   m_uiNumPartitions = 1 << ( uiMaxCUDepth<<1 );
   for( Int edgeDir = 0; edgeDir < NUM_EDGE_DIR; edgeDir++ )
   {
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    m_aapucBS_chroma       [edgeDir] = new UChar[m_uiNumPartitions];
+    m_aapbEdgeFilter_chroma[edgeDir] = new Bool [m_uiNumPartitions];
+#endif
     m_aapucBS       [edgeDir] = new UChar[m_uiNumPartitions];
     m_aapbEdgeFilter[edgeDir] = new Bool [m_uiNumPartitions];
   }
@@ -111,6 +149,19 @@
 {
   for( Int edgeDir = 0; edgeDir < NUM_EDGE_DIR; edgeDir++ )
   {
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    if (m_aapucBS_chroma[edgeDir] != NULL)
+    {
+      delete [] m_aapucBS_chroma[edgeDir];
+      m_aapucBS_chroma[edgeDir] = NULL;
+    }
+
+    if (m_aapbEdgeFilter_chroma[edgeDir])
+    {
+      delete [] m_aapbEdgeFilter_chroma[edgeDir];
+      m_aapbEdgeFilter_chroma[edgeDir] = NULL;
+    }
+#endif
     if (m_aapucBS[edgeDir] != NULL)
     {
       delete [] m_aapucBS[edgeDir];
@@ -137,6 +188,10 @@
   {
     TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
 
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    ::memset( m_aapucBS_chroma       [EDGE_VER], 0, sizeof( UChar ) * m_uiNumPartitions );
+    ::memset( m_aapbEdgeFilter_chroma[EDGE_VER], 0, sizeof( Bool  ) * m_uiNumPartitions );
+#endif
     ::memset( m_aapucBS       [EDGE_VER], 0, sizeof( UChar ) * m_uiNumPartitions );
     ::memset( m_aapbEdgeFilter[EDGE_VER], 0, sizeof( Bool  ) * m_uiNumPartitions );
 
@@ -147,9 +202,10 @@
     xDeblockCU( pCtu, 0, 0, uiCTUSize, uiCTUSize,EDGE_VER );
     if (pCtu->getSlice()->isIntra())
     {
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES==0
       ::memset( m_aapucBS       [EDGE_VER], 0, sizeof( UChar ) * m_uiNumPartitions );
       ::memset( m_aapbEdgeFilter[EDGE_VER], 0, sizeof( Bool  ) * m_uiNumPartitions );
-
+#endif
       pCtu->getSlice()->setTextType(CHANNEL_TYPE_CHROMA);
       xDeblockCU( pCtu, 0, 0, uiCTUSize, uiCTUSize, EDGE_VER );
     }
@@ -163,6 +219,10 @@
   {
     TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
 
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    ::memset( m_aapucBS_chroma       [EDGE_HOR], 0, sizeof( UChar ) * m_uiNumPartitions );
+    ::memset( m_aapbEdgeFilter_chroma[EDGE_HOR], 0, sizeof( Bool  ) * m_uiNumPartitions );
+#endif
     ::memset( m_aapucBS       [EDGE_HOR], 0, sizeof( UChar ) * m_uiNumPartitions );
     ::memset( m_aapbEdgeFilter[EDGE_HOR], 0, sizeof( Bool  ) * m_uiNumPartitions );
 
@@ -173,9 +233,10 @@
     xDeblockCU( pCtu, 0, 0, uiCTUSize, uiCTUSize, EDGE_HOR );
     if (pCtu->getSlice()->isIntra())
     {
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES==0
       ::memset( m_aapucBS       [EDGE_HOR], 0, sizeof( UChar ) * m_uiNumPartitions );
       ::memset( m_aapbEdgeFilter[EDGE_HOR], 0, sizeof( Bool  ) * m_uiNumPartitions );
-
+#endif
       pCtu->getSlice()->setTextType(CHANNEL_TYPE_CHROMA);
       xDeblockCU( pCtu, 0, 0, uiCTUSize, uiCTUSize, EDGE_HOR );
     }
@@ -276,7 +337,9 @@
   xSetEdgefilterTU   ( tuRecurse );
   xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx );
 #endif
-
+#if DEBLOCKING_IMPROVEMENTS
+  Bool isInnerInterBoundary = false;
+#endif
 #if JVET_C0024_QTBT
  // const UInt uiPelsInPart = sps.getCTUSize() >> sps.getMaxTotalCUDepth();
   for (UInt j=0; j<(edgeDir==EDGE_VER ? uiHeight: 1); j+=uiMinCUH)
@@ -302,10 +365,28 @@
     }
 
 #endif
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    if(pcCU->getSlice()->isIntra() && !isLuma(pcCU->getTextType()))
+    {
+      if ( m_aapbEdgeFilter_chroma[edgeDir][uiPartIdx] && uiBSCheck )
+      {
+        xGetBoundaryStrengthSingle ( pcCU, edgeDir, uiPartIdx );
+      }
+    }
+    else
+    {
+      if ( m_aapbEdgeFilter[edgeDir][uiPartIdx] && uiBSCheck )
+      {
+        xGetBoundaryStrengthSingle ( pcCU, edgeDir, uiPartIdx );
+      }
+    }
+
+#else
     if ( m_aapbEdgeFilter[edgeDir][uiPartIdx] && uiBSCheck )
     {
       xGetBoundaryStrengthSingle ( pcCU, edgeDir, uiPartIdx );
     }
+#endif
 #if JVET_C0024_QTBT
     }
   }
@@ -323,6 +404,63 @@
   const Bool bAlwaysDoChroma=chFmt==CHROMA_444;
 #endif
 
+#if DEBLOCKING_IMPROVEMENTS
+  UChar maxFiltLengthP[MAX_CU_SIZE/4];
+  UChar maxFiltLengthQ[MAX_CU_SIZE/4];
+  ::memset(maxFiltLengthP,7,sizeof(UChar)*MAX_CU_SIZE/4);
+  ::memset(maxFiltLengthQ,7,sizeof(UChar)*MAX_CU_SIZE/4);
+#endif
+#if DEBLOCKING_SUBBLOCKS
+  Bool isFRUC = pcCU->getFRUCMgrMode(uiAbsZorderIdx)!=0;
+  Bool isMVsub = pcCU->getMergeFlag(uiAbsZorderIdx) && (pcCU->getMergeType(uiAbsZorderIdx)!=MGR_TYPE_DEFAULT_N);
+  Bool isAffine = pcCU->getAffineFlag(uiAbsZorderIdx);
+  Int theSize = 4;
+  if(isFRUC || isMVsub || isAffine)
+  {
+    if(isFRUC)
+    {
+      theSize = max(4,xFrucGetSubBlkSize(pcCU, uiAbsZorderIdx,pcCU->getWidth(uiAbsZorderIdx),pcCU->getHeight(uiAbsZorderIdx)));
+    }
+    else
+    {
+      theSize = 4;
+    }
+    // determine bs
+    if((edgeDir==EDGE_VER) && (theSize< pcCU->getWidth(uiAbsZorderIdx)))
+    {
+      UInt newZorderIdx;
+      UInt filteredWidth = theSize;
+      while(filteredWidth < pcCU->getWidth(uiAbsZorderIdx))
+      {
+        newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + (filteredWidth/pcCU->getPic()->getMinCUWidth() )];
+        for (Int nr=0;nr<pcCU->getHeight(uiAbsZorderIdx)/pcCU->getPic()->getMinCUHeight();nr++)
+        {
+          newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + nr*pcCU->getPic()->getNumPartInCtuWidth() + (filteredWidth/pcCU->getPic()->getMinCUWidth() )];
+          xGetBoundaryStrengthSingleSubBlock ( pcCU, edgeDir, newZorderIdx);
+        }
+        filteredWidth +=theSize;
+      }
+    }
+
+    if((edgeDir==EDGE_HOR) && (theSize< pcCU->getHeight(uiAbsZorderIdx)))
+    {
+      UInt newZorderIdx;
+      UInt filteredHeight = theSize;
+
+      while(filteredHeight < pcCU->getHeight(uiAbsZorderIdx))
+      {
+        newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + ( filteredHeight/pcCU->getPic()->getMinCUHeight() )*pcCU->getPic()->getNumPartInCtuWidth()];
+        for (Int nr=0;nr<pcCU->getWidth(uiAbsZorderIdx)/pcCU->getPic()->getMinCUWidth();nr++)
+        {
+          newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + nr + ( filteredHeight/pcCU->getPic()->getMinCUHeight() )*pcCU->getPic()->getNumPartInCtuWidth()];
+          xGetBoundaryStrengthSingleSubBlock ( pcCU, edgeDir, newZorderIdx);
+        }
+        filteredHeight +=theSize;
+      }
+    }
+
+  }
+#endif
   for ( Int iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
   {
 #if JVET_C0024_QTBT
@@ -329,7 +467,52 @@
     if (isLuma(pcCU->getTextType()))
     {
 #endif
+#if DEBLOCKING_IMPROVEMENTS
+      UInt firstBlockPos; UInt lastBlockPos;
+      if(edgeDir == EDGE_HOR)
+      {
+        firstBlockPos = pcCU->getCUPelY()+g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
+        lastBlockPos = firstBlockPos + pcCU->getHeight(uiAbsZorderIdx) - 1;
+      }
+      else
+      {
+        firstBlockPos = pcCU->getCUPelX()+g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
+        lastBlockPos = firstBlockPos + pcCU->getWidth(uiAbsZorderIdx) - 1;
+      }
+#if DEBLOCKING_SUBBLOCKS
+      // deblock subblock edges
+      if(isFRUC || isMVsub || isAffine)
+      {
+        isInnerInterBoundary = true;
+        if((edgeDir==EDGE_VER) && (theSize< pcCU->getWidth(uiAbsZorderIdx)))
+        {
+          UInt newZorderIdx;
+          UInt filteredWidth = 4;
+          while((filteredWidth < ((Int)pcCU->getWidth(uiAbsZorderIdx))))
+          {
+            newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + (filteredWidth/pcCU->getPic()->getMinCUWidth() )];
+            xEdgeFilterLuma     ( pcCU, newZorderIdx, uiDepth, edgeDir, iEdge, isInnerInterBoundary, firstBlockPos, lastBlockPos );
+            filteredWidth += 4;
+          }
+        }
+        if((edgeDir==EDGE_HOR) && (theSize< pcCU->getHeight(uiAbsZorderIdx)))
+        {
+          UInt newZorderIdx;
+          UInt filteredHeight = 4;
+          while((filteredHeight < ((Int)pcCU->getHeight(uiAbsZorderIdx))))
+          {
+            newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + ( filteredHeight/pcCU->getPic()->getMinCUHeight() )*pcCU->getPic()->getNumPartInCtuWidth()];
+            xEdgeFilterLuma     ( pcCU, newZorderIdx, uiDepth, edgeDir, iEdge, isInnerInterBoundary, firstBlockPos, lastBlockPos );
+            filteredHeight += 4;
+          }
+        }
+      }
+#endif
+      isInnerInterBoundary = false;
+      xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge, isInnerInterBoundary, firstBlockPos, lastBlockPos );
+#else
     xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge );
+#endif
 #if JVET_C0024_QTBT
     }
     if ((isChroma(pcCU->getTextType()) || !pcCU->getSlice()->isIntra()) && pcPic->getChromaFormat()!=CHROMA_400)
@@ -342,7 +525,50 @@
        )
 #endif
     {
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+      bool useLumaBs = false;
+      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge, pcCU->getWidth(uiAbsZorderIdx), pcCU->getHeight(uiAbsZorderIdx), useLumaBs );
+      if( pcCU->getSlice()->isIntra() && (pcCU->getIntraDir(CHANNEL_TYPE_CHROMA, uiAbsZorderIdx) > 66) && (pcCU->getIntraDir(CHANNEL_TYPE_CHROMA, uiAbsZorderIdx) < 73) && (pcCU->getWidth(uiAbsZorderIdx)>8) && (pcCU->getHeight(uiAbsZorderIdx)>8))
+      {
+        // filter chroma block edge with collocated luma edge
+        useLumaBs = true;
+        UInt newZorderIdx;
+        UInt newWidth = pcCU->getWidth(uiAbsZorderIdx);
+        UInt newHeight = pcCU->getHeight(uiAbsZorderIdx);
+        if(edgeDir==1) // horisontal
+        {
+          if(newHeight > 16)
+          {
+            //newHeight = newHeight >> 1;
+            newHeight = 16;
+            UInt filteredHeight = 16;
+            while(filteredHeight < pcCU->getHeight(uiAbsZorderIdx))
+            {
+              newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + ( filteredHeight/pcCU->getPic()->getMinCUHeight() )*pcCU->getPic()->getNumPartInCtuWidth()];
+              xEdgeFilterChroma   ( pcCU, newZorderIdx, uiDepth, edgeDir, iEdge, newWidth,newHeight,useLumaBs);
+              filteredHeight +=16;
+            }
+          }
+        }
+        if(edgeDir==0) // vertical
+        {
+          if(newWidth > 16)
+          {
+            newWidth = 16;
+            UInt filteredWidth = 16;
+            while(filteredWidth < pcCU->getWidth(uiAbsZorderIdx))
+            {
+              newZorderIdx = g_auiRasterToZscan[ g_auiZscanToRaster[uiAbsZorderIdx] + (filteredWidth/pcCU->getPic()->getMinCUWidth() )];
+              xEdgeFilterChroma   ( pcCU, newZorderIdx, uiDepth, edgeDir, iEdge, newWidth,newHeight,useLumaBs);
+              filteredWidth +=16;
+            }
+          }
+        }
+
+      }
+#else
       xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge );
+#endif
     }
 #if JVET_C0024_QTBT
     }
@@ -375,11 +601,47 @@
   for( UInt ui = 0; ui < uiNumElem; ui++ )
   {
     const UInt uiBsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdgeIdx, ui, rect );
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    if(pcCU->getSlice()->isIntra())
+    {
+      if(isLuma(pcCU->getTextType()))
+      {
+        m_aapbEdgeFilter[edgeDir][uiBsIdx] = bValue;
+      }
+      else
+      {
+        m_aapbEdgeFilter_chroma[edgeDir][uiBsIdx] = bValue;
+      }
+    }
+    else
+    {
+      m_aapbEdgeFilter[edgeDir][uiBsIdx] = bValue;
+    }
+#else
     m_aapbEdgeFilter[edgeDir][uiBsIdx] = bValue;
+#endif
     if (iEdgeIdx == 0)
     {
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    if(pcCU->getSlice()->isIntra())
+    {
+      if(isLuma(pcCU->getTextType()))
+      {
+        m_aapucBS[edgeDir][uiBsIdx] = bValue;
+      }
+      else
+      {
+        m_aapucBS_chroma[edgeDir][uiBsIdx] = bValue;
+      }
+    }
+    else
+    {
       m_aapucBS[edgeDir][uiBsIdx] = bValue;
     }
+#else
+      m_aapucBS[edgeDir][uiBsIdx] = bValue;
+#endif
+    }
   }
 }
 
@@ -590,6 +852,165 @@
   }
 }
 
+#if DEBLOCKING_SUBBLOCKS
+Bool TComLoopFilter::xGetBoundaryStrengthSingleSubBlock( TComDataCU* pCtu, DeblockEdgeDir edgeDir, UInt uiAbsPartIdx4x4BlockWithinCtu )
+{
+  TComSlice * const pcSlice = pCtu->getSlice();
+
+  const Bool lfCrossSliceBoundaryFlag=pCtu->getSlice()->getLFCrossSliceBoundaryFlag();
+
+  const UInt uiPartQ = uiAbsPartIdx4x4BlockWithinCtu;
+  TComDataCU* const pcCUQ = pCtu;
+
+  UInt uiPartP;
+  TComDataCU* pcCUP;
+  UInt uiBs = 0;
+
+  //-- Calculate Block Index
+  if (edgeDir == EDGE_VER)
+  {
+    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ, !lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
+  }
+  else  // (edgeDir == EDGE_HOR)
+  {
+    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pCtu->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
+  }
+
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+      Int nThreshold = 4 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+#endif
+      if (pcSlice->isInterB() || pcCUP->getSlice()->isInterB())
+      {
+        Int iRefIdx;
+        TComPic *piRefP0, *piRefP1, *piRefQ0, *piRefQ1;
+        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
+        piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
+        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
+        piRefP1 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_1, iRefIdx);
+        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
+        piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
+        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
+        piRefQ1 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
+
+        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
+        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
+        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
+        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
+
+        if (piRefP0 == NULL)
+        {
+          pcMvP0.setZero();
+        }
+        if (piRefP1 == NULL)
+        {
+          pcMvP1.setZero();
+        }
+        if (piRefQ0 == NULL)
+        {
+          pcMvQ0.setZero();
+        }
+        if (piRefQ1 == NULL)
+        {
+          pcMvQ1.setZero();
+        }
+
+        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
+        {
+          if ( piRefP0 != piRefP1 )   // Different L0 & L1
+          {
+            if ( piRefP0 == piRefQ0 )
+            {
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+              uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= nThreshold) ||
+                       (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= nThreshold) ||
+                       (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= nThreshold) ||
+                       (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= nThreshold)) ? 1 : 0;
+#else
+              uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
+                       (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
+                       (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
+                       (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
+#endif
+            }
+            else
+            {
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+              uiBs  = ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= nThreshold) ||
+                       (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= nThreshold) ||
+                       (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= nThreshold) ||
+                       (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= nThreshold)) ? 1 : 0;
+#else
+              uiBs  = ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
+                       (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
+                       (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
+                       (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
+#endif
+            }
+          }
+          else    // Same L0 & L1
+          {
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+            uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= nThreshold) ||
+                     (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= nThreshold) ||
+                     (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= nThreshold) ||
+                     (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= nThreshold)) &&
+                    ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= nThreshold) ||
+                     (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= nThreshold) ||
+                     (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= nThreshold) ||
+                     (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= nThreshold)) ? 1 : 0;
+#else
+            uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
+                     (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
+                     (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
+                     (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) &&
+                    ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
+                     (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
+                     (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
+                     (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
+#endif
+          }
+        }
+        else // for all different Ref_Idx
+        {
+          uiBs = 1;
+        }
+      }
+      else  // pcSlice->isInterP()
+      {
+        Int iRefIdx;
+        TComPic *piRefP0, *piRefQ0;
+        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
+        piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
+        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
+        piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
+        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
+        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
+
+        if (piRefP0 == NULL)
+        {
+          pcMvP0.setZero();
+        }
+        if (piRefQ0 == NULL)
+        {
+          pcMvQ0.setZero();
+        }
+
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+        uiBs  = ((piRefP0 != piRefQ0) ||
+                 (abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= nThreshold) ||
+                 (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= nThreshold)) ? 1 : 0;
+#else
+        uiBs  = ((piRefP0 != piRefQ0) ||
+                 (abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
+                 (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4)) ? 1 : 0;
+#endif
+      }
+      m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] = uiBs;
+      return uiBs;
+}
+#endif
+
+
 Void TComLoopFilter::xGetBoundaryStrengthSingle ( TComDataCU* pCtu, DeblockEdgeDir edgeDir, UInt uiAbsPartIdx4x4BlockWithinCtu )
 {
   TComSlice * const pcSlice = pCtu->getSlice();
@@ -618,7 +1039,6 @@
   {
     uiBs = 2;
   }
-
   //-- Set BS for not Intra MB : BS = 2 or 1 or 0
 #if JVET_C0024_QTBT
   if ( isLuma(pCtu->getTextType()) && (!pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ)) )
@@ -769,12 +1189,33 @@
       }
     }   // enf of "if( one of BCBP == 0 )"
   }   // enf of "if( not Intra )"
-
-  m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] = uiBs;
+#if DEBLOCKING_LIC
+  if ( (pcCUP->getICFlag(uiPartP) || pcCUQ->getICFlag(uiPartQ)) )
+  {
+    uiBs = 3;  // this can distinguish it from intra and inter mv diff and coeffs
+  }
+#endif
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+  if(pCtu->getSlice()->isIntra() && !isLuma(pCtu->getTextType()))
+  {
+      m_aapucBS_chroma[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] = uiBs;
+  }
+  else
+  {
+      m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] = uiBs;
+  }
+#else
+    m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] = uiBs;
+#endif
 }
 
 
+#if DEBLOCKING_IMPROVEMENTS
+//Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge, UChar* maxFiltLengthP, UChar* maxFiltLengthQ, Bool isInnerInterBoundary, UInt firstBlockPos, UInt lastBlockPos )
+Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge, Bool isInnerInterBoundary, UInt firstBlockPos, UInt lastBlockPos )
+#else
 Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge  )
+#endif
 {
         TComPicYuv *pcPicYuvRec                   = pcCU->getPic()->getPicYuvRec();
         Pel        *piSrc                         = pcPicYuvRec->getAddr(COMPONENT_Y, pcCU->getCtuRsAddr(), uiAbsZorderIdx );
@@ -845,15 +1286,51 @@
   }
 
   const Int iBitdepthScale = 1 << (bitDepthLuma-8);
+#if DEBLOCKING_IMPROVEMENTS
+  Int maxLengthP = 7; // number of pixels to modify at most
+  Int maxLengthQ = 7; // number of pixels to modify at most
+  Int doFilteringList[MAX_CU_SIZE/4];
+  Bool swList[MAX_CU_SIZE/4];
+  Int iTcList[MAX_CU_SIZE/4];
+  Bool bFilterPList[MAX_CU_SIZE/4];
+  Bool bFilterQList[MAX_CU_SIZE/4];
+  Bool bPartPNoFilterList[MAX_CU_SIZE/4];
+  Bool bPartQNoFilterList[MAX_CU_SIZE/4];
+  ::memset(doFilteringList,0,sizeof(Int)*MAX_CU_SIZE/4);
+  ::memset(iTcList,0,sizeof(Int)*MAX_CU_SIZE/4);
+  ::memset(swList,0,sizeof(Bool)*MAX_CU_SIZE/4);
+  ::memset(bFilterPList,0,sizeof(Bool)*MAX_CU_SIZE/4);
+  ::memset(bFilterQList,0,sizeof(Bool)*MAX_CU_SIZE/4);
+  ::memset(bPartPNoFilterList,0,sizeof(Bool)*MAX_CU_SIZE/4);
+  ::memset(bPartQNoFilterList,0,sizeof(Bool)*MAX_CU_SIZE/4);
 
+  // selected number of samples to filter, for side P and side Q
+  UChar superStrongList[MAX_CU_SIZE/4];
+  ::memset(superStrongList,0,sizeof(UChar)*MAX_CU_SIZE/4);
+
+  // temporary storage of super strong decisions
+  Bool sswList[3][MAX_CU_SIZE/4];
+  ::memset(sswList[0],0,sizeof(Bool)*MAX_CU_SIZE/4);
+  ::memset(sswList[1],0,sizeof(Bool)*MAX_CU_SIZE/4);
+  ::memset(sswList[2],0,sizeof(Bool)*MAX_CU_SIZE/4);
+
+  // first store decisions for block boundary
   for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
   {
     uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdge, iIdx);
     uiBs = m_aapucBS[edgeDir][uiBsAbsIdx];
+#if DEBLOCKING_LIC
+    if(uiBs==3)
+    {
+      uiBs = 1;
+    }
+#endif
+
     if ( uiBs )
     {
       iQP_Q = pcCU->getQP( uiBsAbsIdx );
       uiPartQIdx = uiBsAbsIdx;
+
       // Derive neighboring PU index
       if (edgeDir == EDGE_VER)
       {
@@ -870,6 +1347,381 @@
       Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, Int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs-1) + (tcOffsetDiv2 << 1)));
       Int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1));
 
+      iTcList[iIdx] =  sm_tcTable[iIndexTC]*iBitdepthScale;
+      Int iBeta = sm_betaTable[iIndexB]*iBitdepthScale;
+      Int iSideThreshold = (iBeta+(iBeta>>1))>>3;
+
+#if JVET_C0024_DF_MODIFY
+      UInt  uiBlocksInPart = 1;
+#else
+      UInt  uiBlocksInPart = uiPelsInPart / 4 ? uiPelsInPart / 4 : 1;
+#endif
+
+      for (UInt iBlkIdx = 0; iBlkIdx<uiBlocksInPart; iBlkIdx ++)
+      {
+        Int dp0 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
+        Int dq0 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
+#if JVET_C0024_DF_MODIFY
+        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+uiPelsInPart-1), iOffset);
+        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+uiPelsInPart-1), iOffset);
+#else
+        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
+        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
+#endif
+        Int d0 = dp0 + dq0;
+        Int d3 = dp3 + dq3;
+
+        Int dp = dp0 + dp3;
+        Int dq = dq0 + dq3;
+
+        Int d =  d0 + d3;
+
+        bPartPNoFilterList[iIdx] = bPartPNoFilter;
+        bPartQNoFilterList[iIdx] = bPartQNoFilter;
+        if (bPCMFilter || ppsTransquantBypassEnableFlag)
+        {
+          // Check if each of PUs is I_PCM with LF disabling
+          bPartPNoFilterList[iIdx] = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));
+          bPartQNoFilterList[iIdx] = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));
+
+          // check if each of PUs is lossless coded
+          bPartPNoFilterList[iIdx] = bPartPNoFilterList[iIdx] || (pcCUP->isLosslessCoded(uiPartPIdx) );
+          bPartQNoFilterList[iIdx] = bPartQNoFilterList[iIdx] || (pcCUQ->isLosslessCoded(uiPartQIdx) );
+        }
+
+        if (d < iBeta)
+        {
+          doFilteringList[iIdx] = true;
+#if DEBLOCKING_SUBBLOCKS && DEBLOCKING_SUPERSTRONG
+          maxLengthP = 7; // number of pixels to modify at most
+          maxLengthQ = 7; // number of pixels to modify at most
+          if(isInnerInterBoundary)
+          {
+            // check distance to nearest block boundary or sub-block boundary with bs>0
+            // this halfs the number of line code for this part..., joint code for vertical and horisontal boundaries..
+            UInt startPos;
+            Int offsetRaster;
+            if(edgeDir == EDGE_HOR)
+            {
+              startPos = pcCU->getCUPelY()+g_auiRasterToPelY[ g_auiZscanToRaster[uiBsAbsIdx]];
+              offsetRaster = pcCU->getPic()->getNumPartInCtuWidth();
+            }
+            else
+            {
+              startPos = pcCU->getCUPelX()+g_auiRasterToPelX[ g_auiZscanToRaster[uiBsAbsIdx] ];
+              offsetRaster = 1;
+            }
+            // check P side
+            if(startPos > (firstBlockPos + 4))
+            {
+              // check previous sub-block 4 samples away from current sub block boundary
+              UInt newZorderIdx = g_auiRasterToZscan[ (Int)g_auiZscanToRaster[uiBsAbsIdx] - offsetRaster];
+              Bool aBs1 = m_aapucBS[edgeDir][newZorderIdx]>0;
+              if(aBs1)
+              {
+                // first neighbour sub-block boundary 4 samples away
+                maxLengthP = 1;
+              }
+              else
+              {
+                if(startPos> (firstBlockPos + 8))
+                {
+                  // check next sub-block 8 samples away from current sub block boundary
+                  newZorderIdx = g_auiRasterToZscan[ (Int)g_auiZscanToRaster[uiBsAbsIdx] - 2*offsetRaster];
+                  aBs1 = m_aapucBS[edgeDir][newZorderIdx]>0;
+                  if(aBs1)
+                  {
+                    // first neighbour sub-block boundary 8 samples away
+                    maxLengthP = 3;
+                  }
+                  else
+                  {
+                    if(startPos> (firstBlockPos + 12))
+                    {
+                      // check next sub-block 12 samples away from current sub block boundary
+                      newZorderIdx = g_auiRasterToZscan[ (Int)g_auiZscanToRaster[uiBsAbsIdx] - 3*offsetRaster];
+                      aBs1 = m_aapucBS[edgeDir][newZorderIdx]>0;
+                      if(aBs1)
+                      {
+                        // first neighbour sub-block boundary 12 samples away
+                        maxLengthP = 5;
+                      }
+                      else
+                      {
+                        // first neighbour sub-block boundary at least 16 samples away
+                        maxLengthP = 7;
+                      }
+                    }
+                  }
+                }
+                else
+                {
+                  maxLengthP = 3;
+                }
+              }
+            }
+            else
+            {
+              // first sub-block boundary in block
+              maxLengthP = 1;
+            }
+          
+            // check Q side
+            if(startPos < (lastBlockPos - 4))
+            {
+              // check next sub-block 4 samples away from current sub block boundary
+              UInt newZorderIdx = g_auiRasterToZscan[ (Int)g_auiZscanToRaster[uiBsAbsIdx] + offsetRaster];
+              Bool aBs1 = m_aapucBS[edgeDir][newZorderIdx]>0;
+              if(aBs1)
+              {
+                // first neighbour sub-block boundary 4 samples away
+                maxLengthQ = 1;
+              }
+              else
+              {
+                if((Int)startPos < ((Int)lastBlockPos - 8))
+                {
+                  // check next sub-block 8 samples away from current sub block boundary
+                  newZorderIdx = g_auiRasterToZscan[ (Int)g_auiZscanToRaster[uiBsAbsIdx] + 2*offsetRaster];
+                  aBs1 = m_aapucBS[edgeDir][newZorderIdx]>0;
+                  if(aBs1)
+                  {
+                    // first neighbour sub-block boundary 8 samples away
+                    maxLengthQ = 3;
+                  }
+                  else
+                  {
+                    if((Int)startPos < ((Int)lastBlockPos - 12))
+                    {
+                      // check next sub-block 12 samples away from current sub block boundary
+                      newZorderIdx = g_auiRasterToZscan[ (Int)g_auiZscanToRaster[uiBsAbsIdx] + 3*offsetRaster];
+                      aBs1 = m_aapucBS[edgeDir][newZorderIdx]>0;
+                      if(aBs1)
+                      {
+                        // first neighbour sub-block boundary 12 samples away
+                        maxLengthQ = 5;
+                      }
+                      else
+                      {
+                        // first neighbour sub-block boundary at least 16 samples away
+                        maxLengthQ = 7;
+                      }
+                    }
+                  }
+                }
+                else
+                {
+                  maxLengthQ = 3;
+                }
+              }
+            }
+            else
+            {
+              // last sub-block boundary in block
+              maxLengthQ = 1;
+            }
+          }
+#endif
+          //  make sure we do not filter with overlap between blocks
+#if DEBLOCKING_NOOVERLAP_BLOCKS
+          if(!isInnerInterBoundary)
+          {
+            if(edgeDir == EDGE_HOR)
+            {
+              maxLengthP = (pcCUP->getHeight(uiPartPIdx) >> 1) - 1;
+              maxLengthQ = (pcCU->getHeight(uiPartQIdx) >> 1) - 1;
+            }
+            else
+            {
+              maxLengthP = (pcCUP->getWidth(uiPartPIdx) >> 1) - 1;
+              maxLengthQ = (pcCU->getWidth(uiPartQIdx)  >> 1) - 1;
+            }
+          }
+#endif
+          if((maxLengthP>1) || isInnerInterBoundary)
+          {
+            bFilterPList[iIdx] = (dp < iSideThreshold);
+          }
+          else
+          {
+            bFilterPList[iIdx] = false;
+          }
+          if((maxLengthQ>1) || isInnerInterBoundary)
+          {
+            bFilterQList[iIdx] = (dq < iSideThreshold);
+          }
+          else
+          {
+            bFilterQList[iIdx] = false;
+          }
+
+          if(((maxLengthP >2)&&(maxLengthQ>2))  || isInnerInterBoundary)
+          {
+          swList[iIdx] =  xUseStrongFiltering( iOffset, 2*d0, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0))
+#if JVET_C0024_DF_MODIFY
+          && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+uiPelsInPart-1));
+#else
+          && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3));
+#endif
+          }
+          else
+          {
+            swList[iIdx] =  false;
+          }
+
+#if DEBLOCKING_SUPERSTRONG
+#if DEBLOCKING_SUBBLOCKS
+          UChar maxSuperStrongFilterLength = min(maxLengthP,maxLengthQ);
+#else
+          UChar maxSuperStrongFilterLength = 7;
+#endif
+
+          // 3 pix super strong
+          if((maxSuperStrongFilterLength>=3) && ((pcCU->getHeight(uiAbsZorderIdx) >= 8) && (pcCU->getWidth(uiAbsZorderIdx) >= 8) && (pcCUP->getHeight(uiPartPIdx) >= 8) && (pcCUP->getWidth(uiPartPIdx) >= 8)))
+          {
+            sswList[0][iIdx] = swList[iIdx] && xUseSuperStrongFiltering( iOffset, 2*d0, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0),3)
+  #if JVET_C0024_DF_MODIFY
+            && xUseSuperStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+uiPelsInPart-1),3);
+  #else
+            && xUseSuperStrongFiltering( iOffset, 2*d3, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3),3);
+  #endif
+          }
+          else
+          {
+            sswList[0][iIdx] = false;
+          }
+
+          // 5 pix super strong
+          if((maxSuperStrongFilterLength>=5) && ((pcCU->getHeight(uiAbsZorderIdx) >= 16) && (pcCU->getWidth(uiAbsZorderIdx) >= 16) && (pcCUP->getHeight(uiPartPIdx) >= 16) && (pcCUP->getWidth(uiPartPIdx) >= 16)))
+          {
+            sswList[1][iIdx] = swList[iIdx] && xUseSuperStrongFiltering( iOffset, 2*d0, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0),5)
+  #if JVET_C0024_DF_MODIFY
+            && xUseSuperStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+uiPelsInPart-1),5);
+  #else
+            && xUseSuperStrongFiltering( iOffset, 2*d3, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3),5);
+  #endif
+          }
+          else
+          {
+            sswList[1][iIdx] = false;
+          }
+
+          // 7 pix super strong
+          if((maxSuperStrongFilterLength>=7) && ((pcCU->getHeight(uiAbsZorderIdx) >= 32) && (pcCU->getWidth(uiAbsZorderIdx) >= 32) && (pcCUP->getHeight(uiPartPIdx) >= 32) && (pcCUP->getWidth(uiPartPIdx) >= 32)))
+          {
+            sswList[2][iIdx] = swList[iIdx] && xUseSuperStrongFiltering( iOffset, 2*d0, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0),7)
+  #if JVET_C0024_DF_MODIFY
+            && xUseSuperStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+uiPelsInPart-1),7);
+  #else
+            && xUseSuperStrongFiltering( iOffset, 2*d3, iBeta, iTcList[iIdx], piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3),7);
+  #endif
+          }
+          else
+          {
+            sswList[2][iIdx] = false;
+          }
+
+          superStrongList[iIdx] = 0;
+
+          if (((iIdx+1) % 4)==0)
+          {
+            Bool superStrong =  sswList[2][iIdx] && sswList[2][iIdx-1] && sswList[2][iIdx-2] && sswList[2][iIdx-3];
+            if(superStrong)
+            {
+              superStrongList[iIdx] = superStrongList[iIdx-1] = superStrongList[iIdx-2] = superStrongList[iIdx-3] = 7;
+            }
+            else
+            {
+              superStrong =  sswList[1][iIdx] && sswList[1][iIdx-1] && sswList[1][iIdx-2] && sswList[1][iIdx-3];
+              if(superStrong)
+              {
+                superStrongList[iIdx] = superStrongList[iIdx-1] = superStrongList[iIdx-2] = superStrongList[iIdx-3] = 5;
+              }
+              else
+              {
+                superStrong =  sswList[0][iIdx] && sswList[0][iIdx-1] && sswList[0][iIdx-2] && sswList[0][iIdx-3];
+                if(superStrong)
+                {
+                  superStrongList[iIdx] = superStrongList[iIdx-1] = superStrongList[iIdx-2] = superStrongList[iIdx-3] = 3;
+                }
+                else
+                {
+                  superStrongList[iIdx] = superStrongList[iIdx-1] = superStrongList[iIdx-2] = superStrongList[iIdx-3] = 0;
+                }
+              }
+            }
+          }
+#else
+          superStrongList[iIdx] = 0;
+#endif
+        }
+        else
+        {
+          doFilteringList[iIdx] = false;
+        }
+      }
+    }
+    else
+    {
+      doFilteringList[iIdx] = false;
+    }
+  }
+
+  // then filter according to stored decisions
+  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
+  {
+
+#if JVET_C0024_DF_MODIFY
+      UInt  uiBlocksInPart = 1;
+#else
+      UInt  uiBlocksInPart = uiPelsInPart / 4 ? uiPelsInPart / 4 : 1;
+#endif
+      for (UInt iBlkIdx = 0; iBlkIdx<uiBlocksInPart; iBlkIdx ++)
+      {
+        if (doFilteringList[iIdx] )
+        {
+
+          Int iThrCut = iTcList[iIdx]*10; // can be determined in filter loop
+#if JVET_C0024_DF_MODIFY
+          for ( Int i = 0; i < uiPelsInPart; i++)
+#else
+          for ( Int i = 0; i < DEBLOCK_SMALLEST_BLOCK/2; i++)
+#endif
+          {
+#if DEBLOCKING_SUPERSTRONG
+            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+i), iOffset, iTcList[iIdx], swList[iIdx], bPartPNoFilterList[iIdx], bPartQNoFilterList[iIdx], iThrCut, bFilterPList[iIdx], bFilterQList[iIdx], bitDepthLuma, superStrongList[iIdx]);
+#else
+            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+i), iOffset, iTcList[iIdx], swList[iIdx], bPartPNoFilterList[iIdx], bPartQNoFilterList[iIdx], iThrCut, bFilterPList[iIdx], bFilterQList[iIdx], bitDepthLuma);
+#endif
+          }
+        }
+      }
+  }
+
+#else
+  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
+  {
+    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdge, iIdx);
+    uiBs = m_aapucBS[edgeDir][uiBsAbsIdx];
+    if ( uiBs )
+    {
+      iQP_Q = pcCU->getQP( uiBsAbsIdx );
+      uiPartQIdx = uiBsAbsIdx;
+      // Derive neighboring PU index
+      if (edgeDir == EDGE_VER)
+      {
+        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
+      }
+      else  // (iDir == EDGE_HOR)
+      {
+        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, false, !m_bLFCrossTileBoundary);
+      }
+      iQP_P = pcCUP->getQP(uiPartPIdx);
+      iQP = (iQP_P + iQP_Q + 1) >> 1;
+
+      Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, Int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs-1) + (tcOffsetDiv2 << 1)));
+      Int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1));
+
       Int iTc =  sm_tcTable[iIndexTC]*iBitdepthScale;
       Int iBeta = sm_betaTable[iIndexB]*iBitdepthScale;
       Int iSideThreshold = (iBeta+(iBeta>>1))>>3;
@@ -934,10 +1786,15 @@
       }
     }
   }
+#endif
 }
 
 
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge, const UInt width, const UInt height, const bool useLumaBs)
+#else
 Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge )
+#endif
 {
         TComPicYuv *pcPicYuvRec    = pcCU->getPic()->getPicYuvRec();
         Int         iStride        = pcPicYuvRec->getStride(COMPONENT_Cb);
@@ -988,8 +1845,18 @@
 
 #if JVET_C0024_QTBT
   UInt uiNumParts;
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
   if (edgeDir == EDGE_VER)
   {
+    uiNumParts = height / pcCU->getPic()->getMinCUHeight();
+  }
+  else
+  {
+    uiNumParts = width / pcCU->getPic()->getMinCUWidth();
+  }
+#else
+  if (edgeDir == EDGE_VER)
+  {
     uiNumParts = pcCU->getHeight(uiAbsZorderIdx) / pcCU->getPic()->getMinCUHeight();
   }
   else
@@ -996,6 +1863,7 @@
   {
     uiNumParts = pcCU->getWidth(uiAbsZorderIdx) / pcCU->getPic()->getMinCUWidth();
   }
+#endif
 #else
   UInt  uiNumParts = pcCU->getPic()->getNumPartInCtuWidth()>>uiDepth;
 #endif
@@ -1028,10 +1896,39 @@
   for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
   {
     uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdge, iIdx);
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+    if(pcCU->getSlice()->isIntra())
+    {
+      if(useLumaBs)
+      {
+        ucBs = m_aapucBS[edgeDir][uiBsAbsIdx];
+      }
+      else
+      {
+        ucBs = m_aapucBS_chroma[edgeDir][uiBsAbsIdx];
+      }
+    }
+    else
+    {
+      ucBs = m_aapucBS[edgeDir][uiBsAbsIdx];
+    }
+#else
     ucBs = m_aapucBS[edgeDir][uiBsAbsIdx];
-
+#endif
     if ( ucBs > 1)
     {
+#if DEBLOCKING_LIC
+    if(ucBs == 3)
+    {
+      ucBs = 2;
+    }
+#endif
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+      if(useLumaBs)
+      {
+        ucBs = 1;
+      }
+#endif
       iQP_Q = pcCU->getQP( uiBsAbsIdx );
       UInt  uiPartQIdx = uiBsAbsIdx;
       // Derive neighboring PU index
@@ -1112,7 +2009,11 @@
  \param bFilterSecondQ  decision weak filter/no filter for partQ
  \param bitDepthLuma    luma bit depth
 */
+#if DEBLOCKING_SUPERSTRONG
+__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int tc, Bool sw, Bool bPartPNoFilter, Bool bPartQNoFilter, Int iThrCut, Bool bFilterSecondP, Bool bFilterSecondQ, const Int bitDepthLuma, Int superStrong)
+#else
 __inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int tc, Bool sw, Bool bPartPNoFilter, Bool bPartQNoFilter, Int iThrCut, Bool bFilterSecondP, Bool bFilterSecondQ, const Int bitDepthLuma)
+#endif
 {
   Int delta;
 
@@ -1127,6 +2028,93 @@
 
   if (sw)
   {
+#if DEBLOCKING_SUPERSTRONG
+    if((superStrong > 0))
+    {
+      Pel n15  = piSrc[ iOffset*7];
+      Pel n14  = piSrc[ iOffset*6];
+      Pel n13  = piSrc[ iOffset*5];
+      Pel n12  = piSrc[ iOffset*4];
+      Pel n11  = piSrc[ iOffset*3];
+      Pel n10  = piSrc[ iOffset*2];
+      Pel n9  = piSrc[ iOffset];
+      Pel n8  = piSrc[0];
+      Pel n7  = piSrc[-iOffset];
+      Pel n6  = piSrc[-iOffset*2];
+      Pel n5  = piSrc[-iOffset*3];
+      Pel n4  = piSrc[-iOffset*4];
+      Pel n3  = piSrc[-iOffset*5];
+      Pel n2  = piSrc[-iOffset*6];
+      Pel n1  = piSrc[-iOffset*7];
+      Pel n0  = piSrc[-iOffset*8];
+
+      Pel dbCoeffs7[7]={59, 50, 41,32,23,14,5};
+      Pel dbCoeffs5[7]={58, 45, 32,19,6,0,0};
+      Pel dbCoeffs3[7]={53, 32, 11,0,0,0,0};
+      Pel refP;
+      Pel refQ;
+      Pel refMiddle;
+      Pel src;
+
+      Int numPixToFilter = superStrong;
+      Pel *dbCoeffs;
+      switch(numPixToFilter)
+      {
+      case 3:{
+        refMiddle = (2*(n5+n10)+3*(n6+n7+n8+n9)+8) >> 4;
+        dbCoeffs = dbCoeffs3;
+        refP = (n4+n5+1) >> 1;
+        refQ = (n11+n10+1) >> 1;
+        break;
+             }
+      case 5:{
+        refMiddle = (n3+n4+2*(n5+n6+n7+n8+n9+n10)+n11+n12+8) >> 4;
+        dbCoeffs = dbCoeffs5;
+        refP = (n2+n3+1) >> 1;
+        refQ = (n13+n12+1) >> 1;
+        break;
+             }
+      case 7:{
+        refMiddle = (n1+n2+n3+n4+n5+n6+2*(n7+n8)+n9+n10+n11+n12+n13+n14+8) >> 4;
+        dbCoeffs = dbCoeffs7;
+        refP = (n0+n1+1) >> 1;
+        refQ = (n15+n14+1) >> 1;
+        break;
+             }
+      default:{
+        refMiddle = (2*(n5+n10)+3*(n6+n7+n8+n9)+8) >> 4;
+        dbCoeffs = dbCoeffs3;
+        refP = (n4+n5+1) >> 1;
+        refQ = (n11+n10+1) >> 1;
+        break;
+              }
+      }
+
+      // P side
+      for(Int thePos=0; thePos<numPixToFilter; thePos++)
+      {
+        src = piSrc[-iOffset*(thePos+1)];
+        piSrc[-iOffset*(thePos+1)] = Clip3(src-tc,src+tc,((refMiddle*dbCoeffs[thePos]+refP*(64-dbCoeffs[thePos]) + 32) >> 6));
+      }
+
+      // Q side
+      for(Int thePos=0; thePos<numPixToFilter; thePos++)
+      {
+        src = piSrc[iOffset*(thePos)];
+        piSrc[iOffset*(thePos)] = Clip3(src-tc,src+tc,((refMiddle*dbCoeffs[thePos]+refQ*(64-dbCoeffs[thePos]) + 32) >> 6));
+      }
+
+    }
+    else
+    {
+      piSrc[-iOffset]   = Clip3(m3-2*tc, m3+2*tc, ((m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3));
+      piSrc[0]          = Clip3(m4-2*tc, m4+2*tc, ((m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3));
+      piSrc[-iOffset*2] = Clip3(m2-2*tc, m2+2*tc, ((m1 + m2 + m3 + m4 + 2)>>2));
+      piSrc[ iOffset]   = Clip3(m5-2*tc, m5+2*tc, ((m3 + m4 + m5 + m6 + 2)>>2));
+      piSrc[-iOffset*3] = Clip3(m1-2*tc, m1+2*tc, ((2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3));
+      piSrc[ iOffset*2] = Clip3(m6-2*tc, m6+2*tc, ((m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3));
+    }
+#else
     piSrc[-iOffset]   = Clip3(m3-2*tc, m3+2*tc, ((m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3));
     piSrc[0]          = Clip3(m4-2*tc, m4+2*tc, ((m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3));
     piSrc[-iOffset*2] = Clip3(m2-2*tc, m2+2*tc, ((m1 + m2 + m3 + m4 + 2)>>2));
@@ -1133,6 +2121,7 @@
     piSrc[ iOffset]   = Clip3(m5-2*tc, m5+2*tc, ((m3 + m4 + m5 + m6 + 2)>>2));
     piSrc[-iOffset*3] = Clip3(m1-2*tc, m1+2*tc, ((2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3));
     piSrc[ iOffset*2] = Clip3(m6-2*tc, m6+2*tc, ((m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3));
+#endif
   }
   else
   {
@@ -1171,7 +2160,6 @@
       }
     }
   }
-
   if(bPartPNoFilter)
   {
     piSrc[-iOffset] = m3;
@@ -1258,4 +2246,65 @@
 {
   return abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
 }
+
+#if DEBLOCKING_IMPROVEMENTS
+__inline Bool TComLoopFilter::xUseSuperStrongFiltering( Int offset, Int d, Int beta, Int tc, Pel* piSrc, Int type)
+{
+  Pel n8  = piSrc[0];
+  Pel n7  = piSrc[-offset];
+  switch(type)
+  {
+  case 3: {
+    // p3 p2 p1 p0 | q0 q1 q2 q3
+    // n4 n5 n6 n7   n8 n9 n10 n11
+    Pel n11  = piSrc[ offset*3];
+    Pel n10  = piSrc[ offset*2];
+    Pel n9  = piSrc[ offset];
+    Pel n6  = piSrc[-offset*2];
+    Pel n5  = piSrc[-offset*3];
+    Pel n4  = piSrc[-offset*4];
+    Int d_strong1 = abs(n11-n9-n10+n8) + abs(n7-n5-n6+n4);
+    return ( ((d_strong1 < ((3*beta)>>5))));
+    break;
+          }
+  case 5: {
+    Pel n13  = piSrc[ offset*5];
+    Pel n12  = piSrc[ offset*4];
+    Pel n3  = piSrc[-offset*5];
+    Pel n2  = piSrc[-offset*6];
+    Int d_strong1 = abs(n12-n8) + abs(n7-n3);
+    Int d_strong2 = abs(n13-n8) + abs(n7-n2);
+    return ( (d_strong1 < (beta>>3)) && (d_strong2 < (beta>>3)));
+    break;
+          }
+  case 7: {
+    Pel n15  = piSrc[ offset*7];
+    Pel n14  = piSrc[ offset*6];
+    Pel n13  = piSrc[ offset*5];
+    Pel n12  = piSrc[ offset*4];
+    Pel n11  = piSrc[ offset*3];
+    Pel n10  = piSrc[ offset*2];
+    Pel n5  = piSrc[-offset*3];
+    Pel n4  = piSrc[-offset*4];
+    Pel n3  = piSrc[-offset*5];
+    Pel n2  = piSrc[-offset*6];
+    Pel n1  = piSrc[-offset*7];
+    Pel n0  = piSrc[-offset*8];
+    Int d_strong1 = abs(n12-2*n10+n8) + abs(n7-2*n5+n3);
+    Int d_strong3 = abs(n14-2*n11+n8) + abs(n7-2*n4+n1);
+    Int d_strong2 = abs(n13-n11-n10+n8) + abs(n7-n5-n4+n2);
+    Int d_strong4 = abs(n15-n12-n11+n8) + abs(n7-n4-n3+n0);
+    return ( (d_strong1 < ((3*beta)>>5)) && (d_strong2 < ((3*beta)>>5)) && (d_strong3 < ((3*beta)>>5)) && (d_strong4 < ((3*beta)>>5)));
+    break;
+          }
+
+  default: {
+    return false;
+    break;
+           }
+  }
+
+}
+#endif
+
 //! \}
Index: source/Lib/TLibCommon/TComLoopFilter.h
===================================================================
--- source/Lib/TLibCommon/TComLoopFilter.h	(revision 548)
+++ source/Lib/TLibCommon/TComLoopFilter.h	(working copy)
@@ -60,6 +60,10 @@
 private:
 
   UInt      m_uiNumPartitions;
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+  UChar*    m_aapucBS_chroma[NUM_EDGE_DIR];         ///< Bs for [Ver/Hor][Y/U/V][Blk_Idx]
+  Bool*     m_aapbEdgeFilter_chroma[NUM_EDGE_DIR];
+#endif
   UChar*    m_aapucBS[NUM_EDGE_DIR];         ///< Bs for [Ver/Hor][Y/U/V][Blk_Idx]
   Bool*     m_aapbEdgeFilter[NUM_EDGE_DIR];
   LFCUParam m_stLFCUParam;                   ///< status structure
@@ -83,6 +87,10 @@
   Void xSetEdgefilterTU           ( TComTU &rTu );
   Void xSetEdgefilterPU           ( TComDataCU* pcCU, UInt uiAbsZorderIdx );
 #endif
+
+#if DEBLOCKING_SUBBLOCKS 
+  Bool xGetBoundaryStrengthSingleSubBlock ( TComDataCU* pCtu, DeblockEdgeDir edgeDir, UInt uiPartIdx);
+#endif
   Void xGetBoundaryStrengthSingle ( TComDataCU* pCtu, DeblockEdgeDir edgeDir, UInt uiPartIdx );
   UInt xCalcBsIdx                 ( TComDataCU* pcCU, UInt absZIdxInCtu, DeblockEdgeDir edgeDir, Int iEdgeIdx, Int iBaseUnitIdx, const struct TComRectangle *rect=NULL )
   {
@@ -116,10 +124,21 @@
                                const TComRectangle *rect = 0
                                );
 
+#if DEBLOCKING_IMPROVEMENTS
+  Void xEdgeFilterLuma            ( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge, Bool isInnerInterBoundary, UInt firstBlockPos, UInt lastBlockPos );
+#else
   Void xEdgeFilterLuma            ( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge );
+#endif
+#if DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES
+  Void xEdgeFilterChroma          ( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge, const UInt width, const UInt height, const bool useLumaBs);
+#else
   Void xEdgeFilterChroma          ( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge );
-
+#endif
+#if DEBLOCKING_SUPERSTRONG
+  __inline Void xPelFilterLuma( Pel* piSrc, Int iOffset, Int tc, Bool sw, Bool bPartPNoFilter, Bool bPartQNoFilter, Int iThrCut, Bool bFilterSecondP, Bool bFilterSecondQ, const Int bitDepthLuma, Int superStrong);
+#else
   __inline Void xPelFilterLuma( Pel* piSrc, Int iOffset, Int tc, Bool sw, Bool bPartPNoFilter, Bool bPartQNoFilter, Int iThrCut, Bool bFilterSecondP, Bool bFilterSecondQ, const Int bitDepthLuma);
+#endif
     __inline Void xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc, Bool bPartPNoFilter, Bool bPartQNoFilter, const Int bitDepthChroma
 #if JVET_D0033_ADAPTIVE_CLIPPING
                                     , ComponentID compID
@@ -134,6 +153,11 @@
   static const UChar sm_tcTable[54];
   static const UChar sm_betaTable[52];
 
+#if DEBLOCKING_IMPROVEMENTS
+  __inline Bool xUseSuperStrongFiltering( Int offset, Int d, Int beta, Int tc, Pel* piSrc, Int type);
+#else
+  __inline Bool xUseSuperStrongFiltering( Int offset, Int d, Int beta, Int tc, Pel* piSrc, Int type);
+#endif
 public:
   TComLoopFilter();
   virtual ~TComLoopFilter();
Index: source/Lib/TLibCommon/TComMotionInfo.h
===================================================================
--- source/Lib/TLibCommon/TComMotionInfo.h	(revision 548)
+++ source/Lib/TLibCommon/TComMotionInfo.h	(working copy)
@@ -59,6 +59,9 @@
 {
   TComMv m_acMvCand[ AMVP_MAX_NUM_CANDS_MEM ];  ///< array of motion vector predictor candidates
   Int    iN;                                ///< number of motion vector predictor candidates
+#if ER_MV_PBL
+  PredMvPrio isScaled[AMVP_MAX_NUM_CANDS_MEM];
+#endif
 } AMVPInfo;
 
 #if COM16_C1016_AFFINE
Index: source/Lib/TLibCommon/TComPrediction.cpp
===================================================================
--- source/Lib/TLibCommon/TComPrediction.cpp	(revision 548)
+++ source/Lib/TLibCommon/TComPrediction.cpp	(working copy)
@@ -111,6 +111,25 @@
   }
 };
 
+#if QP_SPACT_TH
+
+const Int TComPrediction::m_spatialThres[MAX_QP + 1] =
+{
+  32, 32, 32, 32, 32,
+  32, 32, 32, 32, 32,
+  32, 32, 32, 32, 32, // QP <= 14
+  32, 32, 16, 16, 16, // QP 15 16 17 18 19
+  16, 14, 14, 12, 10, // QP 20 21 22 23 24
+   8,  8,  6,  6,  4, // QP 25 26 27 28 29
+   4,  4,  4,  2,  2, // QP 30 31 32 33 34
+   2,  2,  2,  1,  1, // QP 35 36 37 38 39
+   1,  0,  0,  0,  0, // QP 40 41 42 43 44
+   0,  0,  0,  0,  0, // QP 45 46 47 48 49
+   0,  0              // QP 50 51
+};
+
+#endif
+
 // ====================================================================================================================
 // Constructor / destructor / initialize
 // ====================================================================================================================
@@ -528,6 +547,9 @@
 #if COM16_C983_RSAF_PREVENT_OVERSMOOTHING
                                           , Bool enableRSAF
 #endif
+#if WIDE_ANGLE_INTRA
+                                          , Int wideAngleMode
+#endif
                                           )
 {
   Int width=Int(uiWidth);
@@ -555,11 +577,19 @@
   }
   else // Do angular predictions
   {
+#if WIDE_ANGLE_INTRA
 #if VCEG_AZ07_INTRA_65ANG_MODES
+    Bool             bIsModeVer         = (dirMode >= DIA_IDX);
+#else
+    Bool             bIsModeVer         = (dirMode >= 18);
+#endif
+#else
+#if VCEG_AZ07_INTRA_65ANG_MODES
     const Bool       bIsModeVer         = (dirMode >= DIA_IDX);
 #else
     const Bool       bIsModeVer         = (dirMode >= 18);
 #endif
+#endif
     const Int        intraPredAngleMode = (bIsModeVer) ? (Int)dirMode - VER_IDX :  -((Int)dirMode - HOR_IDX);
     const Int        absAngMode         = abs(intraPredAngleMode);
     const Int        signAng            = intraPredAngleMode < 0 ? -1 : 1;
@@ -577,6 +607,18 @@
     Int absAng                      = angTable[absAngMode];
     Int intraPredAngle              = signAng * absAng;
 
+#if WIDE_ANGLE_INTRA
+    Int minRefInd                   = 0;
+    Int maxRefInd                   = width + height;
+    
+    if ( wideAngleMode )
+    {
+      bIsModeVer     = !bIsModeVer;        // Flip to using other border
+      absAng         = (32*invAngle) >> 8; // Calculate the new angle using the inverse of the original
+      intraPredAngle = absAng;             // Only applied to positive angles
+    }
+#endif
+
     Pel* refMain;
     Pel* refSide;
 
@@ -621,6 +663,11 @@
         invAngleSum += invAngle;
         refMain[k] = refSide[invAngleSum>>8];
       }
+
+#if WIDE_ANGLE_INTRA
+      minRefInd = ((refMainOffsetPreScale+1)*intraPredAngle>>5 ) + 1;
+      maxRefInd = bIsModeVer ? width : height;
+#endif
     }
     else
     {
@@ -679,7 +726,7 @@
     else
     {
       Pel *pDsty=pDst;
-
+      
       for (Int y=0, deltaPos=intraPredAngle; y<height; y++, deltaPos+=intraPredAngle, pDsty+=dstStride)
       {
         const Int deltaInt   = deltaPos >> 5;
@@ -705,13 +752,20 @@
             for (x=0;x<width;x++)
             {
               refMainIndex = x+deltaInt+1;
-
+              
+#if WIDE_ANGLE_INTRA
+              p[0] = refMainIndex-1 < minRefInd ? refMain[minRefInd] : refMainIndex-1 > maxRefInd ? refMain[maxRefInd] : refMain[refMainIndex-1];
+              p[1] = refMainIndex   > maxRefInd ? refMain[maxRefInd] : refMain[refMainIndex];
+              p[2] = refMainIndex+1 > maxRefInd ? refMain[maxRefInd] : refMain[refMainIndex+1];
+              p[3] = refMainIndex+2 > maxRefInd ? refMain[maxRefInd] : refMain[refMainIndex+2];
+#else
               p[1] = refMain[refMainIndex];
               p[2] = refMain[refMainIndex+1];
 
               p[0] = x==0 ? p[1] : refMain[refMainIndex-1];
               p[3] = x==(width-1) ? p[2] : refMain[refMainIndex+2];
-
+#endif
+              
               pDst[y*dstStride+x] =  (Pel)( ( f[0]*p[0] + f[1]*p[1] + f[2]*p[2] + f[3]*p[3] + 128 ) >> 8 );
 
 #if COM16_C983_RSAF_PREVENT_OVERSMOOTHING
@@ -731,6 +785,15 @@
           else
           {
 #endif
+#if WIDE_ANGLE_INTRA
+          for (Int x=0;x<width;x++)
+          {
+            Int refMainInd0 = x+deltaInt+1 > maxRefInd ? maxRefInd : x+deltaInt+1;
+            Int refMainInd1 = x+deltaInt+2 > maxRefInd ? maxRefInd : x+deltaInt+2;
+            
+            pDsty[x] = (Pel) ( ((32-deltaFract)*refMain[refMainInd0] + deltaFract*refMain[refMainInd1] + 16) >> 5 );
+          }
+#else
           const Pel *pRM=refMain+deltaInt+1;
           Int lastRefMainPel=*pRM++;
           for (Int x=0;x<width;pRM++,x++)
@@ -739,6 +802,7 @@
             pDsty[x+0] = (Pel) ( ((32-deltaFract)*lastRefMainPel + deltaFract*thisRefMainPel +16) >> 5 );
             lastRefMainPel=thisRefMainPel;
           }
+#endif
 #if VCEG_AZ07_INTRA_4TAP_FILTER
           }
 #endif
@@ -748,7 +812,11 @@
           // Just copy the integer samples
           for (Int x=0;x<width; x++)
           {
+#if WIDE_ANGLE_INTRA
+            pDsty[x] = x+deltaInt+1 > maxRefInd ? refMain[maxRefInd] : refMain[x+deltaInt+1];
+#else
             pDsty[x] = refMain[x+deltaInt+1];
+#endif
           }
         }
       }
@@ -817,6 +885,10 @@
   const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
 #endif
 
+#if WIDE_ANGLE_INTRA
+  Int wideAngleMode = rTu.getCU()->getWideAngleMode ( channelType, rTu.GetAbsPartIdxTU() );
+#endif
+
   if ( bUseLosslessDPCM )
   {
     const Pel *ptrSrc = getPredictorPtr( compID, false );
@@ -931,6 +1003,10 @@
 #else
 #if VCEG_AZ07_INTRA_65ANG_MODES
       Int   iSelMode = (uiDirMode > 1 ? 18 + ((Int(uiDirMode) - 34)>>1) : uiDirMode);
+#if WIDE_ANGLE_INTRA
+      if ( wideAngleMode )
+        iSelMode = uiDirMode < DIA_IDX ? 34 : 2;
+#endif
 #if JVET_C0024_QTBT
       const Int *pdpcParam[2] = { g_pdpc_pred_param[blkSizeGroup[0]][iSelMode], g_pdpc_pred_param[blkSizeGroup[1]][iSelMode] };
       const Int *pPdpcPar = pdpcParam[iWidth < iHeight];
@@ -1014,6 +1090,12 @@
 #if VCEG_AZ07_INTRA_4TAP_FILTER
           , enable4TapFilter
 #endif
+#if WIDE_ANGLE_INTRA
+#if COM16_C983_RSAF_PREVENT_OVERSMOOTHING
+          , wideAngleMode ? true : false
+#endif
+          , wideAngleMode
+#endif
           );
       }
 
@@ -1036,13 +1118,172 @@
       }
 
 #if JVET_C0024_QTBT
+#if MBF_PLANAR==0
       Int scale = g_aucConvertToBit[iWidth] + MIN_CU_LOG2 + g_aucConvertToBit[iHeight] + MIN_CU_LOG2 < 10 ? 0: 1;
+#endif
 #else
+#if MBF_PLANAR==0
       Int scale = (iBlkSize < 32 ? 0 : 1);
 #endif
+#endif
 #if !JVET_D0033_ADAPTIVE_CLIPPING
       Int bitDepth = rTu.getCU()->getSlice()->getSPS()->getBitDepth(channelType);
 #endif
+
+#if MBF_PLANAR
+    // do filtering of top left part, topright and left bottom
+    Int numSamps;
+    Int ParShift = 8; //normalization factor
+    Int ParScale = 1 << ParShift;
+    Int ParOffset = 1 << (ParShift - 1);
+
+    Int f4_a[4] = {32, 58, 88, 118};
+    Int f4_b[4] = {32, 64, 96, 128};
+
+    Int f2_a[2] = {64, 118};
+    Int f2_b[2] = {64, 128};
+
+    Int *theFilter1;
+    Int *theFilter2;
+    Int tmpFilter[7];
+
+    numSamps = 4;
+    theFilter1 = f4_a;
+    theFilter2 = f4_b;
+    if(iWidth<8  || iHeight<8)
+    {
+      numSamps = 2;
+      theFilter1 = f2_a;
+      theFilter2 = f2_b;
+    }
+
+    for (Int nr=0; nr<numSamps;nr++)
+    {
+      tmpFilter[nr] = theFilter1[nr];
+    }
+
+#if JVET_C0024_QTBT
+      for (Int row = 0; row < min(numSamps,iHeight); row++)
+#else
+      for (Int row = 0; row < min(numSamps,iBlkSize); row++)
+#endif
+      {
+        Int pos          = row * uiStride;
+        Int Coeff_Top    = theFilter1[numSamps-row-1];
+#if JVET_C0024_QTBT
+        for (Int col = 0; col < min(numSamps,iWidth); col++, pos++)
+#else
+        for (Int col = 0; col < min(numSamps,iBlkSize); col++, pos++)
+#endif
+        {
+          Int Coeff_Left    = tmpFilter[numSamps-col-1];
+
+          Int TmpCoeff_Top = Coeff_Top;
+          Int Coeff_Cur     = ParScale - Coeff_Left - TmpCoeff_Top;
+
+          Int sampleVal = (Coeff_Left* piRefVector[-row - 1] + TmpCoeff_Top * piRefVector[col + 1]  + Coeff_Cur * pDst[pos] + ParOffset) >> ParShift;
+#if JVET_D0033_ADAPTIVE_CLIPPING
+          pDst[pos] = ClipA(sampleVal,compID);
+#else
+          pDst[pos] = Clip3(0, ((1 << bitDepth) - 1), sampleVal);
+#endif
+        }
+      }
+
+      // filter top right region
+      if(iWidth > numSamps)
+      {
+        Int posOffset = numSamps;
+
+#if JVET_C0024_QTBT
+      for (Int row = 0; row < min(numSamps,iHeight); row++)
+#else
+      for (Int row = 0; row < min(numSamps,iBlkSize); row++)
+#endif
+      {
+        Int pos          = row * uiStride + posOffset;
+
+        Int Coeff_Top    = theFilter2[numSamps-row-1];
+
+  #if JVET_C0024_QTBT
+          for (Int col = numSamps; col < iWidth; col++, pos++)
+  #else
+          for (Int col = numSamps; col < iBlkSize; col++, pos++)
+  #endif
+          {
+
+            Int Coeff_Cur     = ParScale - Coeff_Top;
+
+            Int sampleVal = (Coeff_Top * piRefVector[col + 1]  + Coeff_Cur * pDst[pos] + ParOffset) >> ParShift;
+  #if JVET_D0033_ADAPTIVE_CLIPPING
+            pDst[pos] = ClipA(sampleVal,compID);
+  #else
+            pDst[pos] = Clip3(0, ((1 << bitDepth) - 1), sampleVal);
+  #endif
+          }
+        }
+
+      }
+      // filter bottom left region
+      if(iHeight > numSamps)
+      {
+  #if JVET_C0024_QTBT
+        for (Int row = numSamps; row < iHeight; row++)
+  #else
+        for (Int row = numSamps; row < iBlkSize; row++)
+  #endif
+        {
+          Int pos          = row * uiStride;
+  #if JVET_C0024_QTBT
+          for (Int col = 0; col < min(numSamps,iWidth); col++, pos++)
+  #else
+          for (Int col = 0; col < min(numSamps,iBlkSize); col++, pos++)
+  #endif
+          {
+            Int Coeff_Left    = theFilter2[numSamps-col-1];
+            Int Coeff_Cur     = ParScale - Coeff_Left;
+
+            Int sampleVal = (Coeff_Left* piRefVector[-row - 1] + Coeff_Cur * pDst[pos] + ParOffset) >> ParShift;
+  #if JVET_D0033_ADAPTIVE_CLIPPING
+            pDst[pos] = ClipA(sampleVal,compID);
+  #else
+            pDst[pos] = Clip3(0, ((1 << bitDepth) - 1), sampleVal);
+  #endif
+          }
+        }
+      }
+
+      if(iWidth > numSamps && iHeight > numSamps)
+      {
+        Int posOffset = numSamps;
+  #if JVET_C0024_QTBT
+        for (Int row = numSamps; row < iHeight; row++)
+  #else
+        for (Int row = numSamps; row < iBlkSize; row++)
+  #endif
+        {
+          Int pos          = row * uiStride + posOffset;
+  #if JVET_C0024_QTBT
+          for (Int col = numSamps; col < iWidth; col++, pos++)
+  #else
+          for (Int col = numSamps; col < iBlkSize; col++, pos++)
+  #endif
+          {
+            Int sampleVal = pDst[pos];
+#if JVET_D0033_ADAPTIVE_CLIPPING
+            pDst[pos] = ClipA(sampleVal,compID);
+  #else
+            pDst[pos] = Clip3(0, ((1 << bitDepth) - 1), sampleVal);
+  #endif
+          }
+        }
+
+      }
+
+      return; //terminate the prediction process
+    }
+
+#else
       Int ParShift = 6; //normalization factor
       Int ParScale = 1 << ParShift;
       Int ParOffset = 1 << (ParShift - 1);
@@ -1089,6 +1330,7 @@
       }
       return; //terminate the prediction process
     }
+#endif
 #else
     const Pel *ptrSrc = getPredictorPtr( compID, bUseFilteredPredSamples );
 #endif
@@ -1104,7 +1346,6 @@
 #elif COM16_C1046_PDPC_RSAF_HARMONIZATION
     const Pel *ptrSrc = getPredictorPtr(compID, bUseFilteredPredSamples);
 #endif
-
 #if VCEG_AZ05_INTRA_MPI
     TComDataCU *const pcCU = rTu.getCU();
     const UInt              uiAbsPartIdx = rTu.GetAbsPartIdxTU();
@@ -1160,6 +1401,9 @@
 #if COM16_C983_RSAF_PREVENT_OVERSMOOTHING
         , pcCU->getSlice()->getSPS()->getUseRSAF()
 #endif
+#if WIDE_ANGLE_INTRA
+        , wideAngleMode
+#endif
         );
 
 #if VCEG_AZ05_INTRA_MPI
@@ -1172,7 +1416,12 @@
       if ( uiDirMode == DC_IDX )
 #endif
       {
+#if MBF_DC
+        Bool strongFilter = pcCU->getROTIdx( CHANNEL_TYPE_LUMA, uiAbsPartIdx ) > 0;
+        xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, channelType, strongFilter );
+#else
         xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, channelType );
+#endif
       }
 #if VCEG_AZ07_INTRA_BOUNDARY_FILTER
 #if JVET_C0024_QTBT
@@ -1181,6 +1430,14 @@
       else if( enableBoundaryFilter && isLuma(compID) )
 #endif
       {
+#if WIDE_ANGLE_INTRA
+        if ( wideAngleMode )
+        {
+          xIntraPredFilteringModeInvDGL( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode );
+        }
+        else
+#endif
+          
 #if VCEG_AZ07_INTRA_65ANG_MODES
         if( uiDirMode == VDIA_IDX )
 #else
@@ -1550,7 +1807,11 @@
     for (UInt comp=COMPONENT_Y; comp<pcYuvPred->getNumberValidComponents(); comp++)
     {
       const ComponentID compID=ComponentID(comp);
-      xPredAffineBlk( compID, pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, acMv, iWidth, iHeight, pcYuvPred, bi, pcCU->getSlice()->getSPS()->getBitDepth(toChannelType(compID)) );
+      xPredAffineBlk( compID, pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, acMv, iWidth, iHeight, pcYuvPred, bi, pcCU->getSlice()->getSPS()->getBitDepth(toChannelType(compID))
+#if BORDER_FLEX_AFFINE
+                    , true
+#endif
+                     );
     }
 
     return;
@@ -2210,11 +2471,114 @@
 }
 #endif
 
+#if MVD_SDH
+Void TComPrediction::xPredLumaBlk( TComDataCU * cu, TComPicYuv *refPic, UInt partAddr, TComMv mv, Int width, Int height, TComYuv *dstPic, const Int bitDepth
+#if VCEG_AZ06_IC
+                                  , Bool bLICflag
+#endif
+                                 )
+{
+  // This function performs MC ( IC) for Luma
+
+  cu->clipMv(mv);
+
+  Int nFilterIdx = 0;
+
+  Int     refStride = refPic->getStride(COMPONENT_Y);
+  Int     dstStride = dstPic->getStride(COMPONENT_Y);
+  Int     shiftHor  = 2;
+  Int     shiftVer  = 2;
+
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+  shiftHor += VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+  shiftVer += VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+#endif
+
+  Int     refOffset = (mv.getHor() >> shiftHor) + (mv.getVer() >> shiftVer) * refStride;
+  Pel*    ref = refPic->getAddr(COMPONENT_Y, cu->getCtuRsAddr(), cu->getZorderIdxInCtu() + partAddr) + refOffset;
+  Pel*    dst = dstPic->getAddr(COMPONENT_Y, partAddr);
+
+  Int     xFrac = mv.getHor() & ((1 << shiftHor) - 1);
+  Int     yFrac = mv.getVer() & ((1 << shiftVer) - 1);
+  UInt    cxWidth = width;
+  UInt    cxHeight = height;
+
+  const ChromaFormat chFmt = cu->getPic()->getChromaFormat();
+
+  if (yFrac == 0)
+  {
+    m_if.filterHor(COMPONENT_Y, ref, refStride, dst, dstStride, cxWidth, cxHeight, xFrac, true, chFmt, bitDepth
+      , nFilterIdx
+    );
+  }
+  else if (xFrac == 0)
+  {
+    m_if.filterVer(COMPONENT_Y, ref, refStride, dst, dstStride, cxWidth, cxHeight, yFrac, true, true, chFmt, bitDepth
+      , nFilterIdx
+    );
+  }
+  else
+  {
+    Int   tmpStride = m_filteredBlockTmp[0].getStride(COMPONENT_Y);
+    Pel*  tmp = m_filteredBlockTmp[0].getAddr(COMPONENT_Y);
+
+    Int vFilterSize = NTAPS_LUMA;
+
+    m_if.filterHor(COMPONENT_Y, ref - ((vFilterSize >> 1) - 1) * refStride, refStride, tmp, tmpStride, cxWidth, cxHeight + vFilterSize - 1, xFrac, false, chFmt, bitDepth
+      , nFilterIdx
+    );
+
+    m_if.filterVer(COMPONENT_Y, tmp + ((vFilterSize >> 1) - 1)*tmpStride, tmpStride, dst, dstStride, cxWidth, cxHeight, yFrac, false, true, chFmt, bitDepth
+      , nFilterIdx
+    );
+  }
+
+
+#if VCEG_AZ06_IC
+  if ( bLICflag )
+  {
+    Int a, b, i, j;
+    const Int iShift = m_ICConstShift;
+    xGetLLSICPrediction(cu, &mv, refPic, a, b, COMPONENT_Y, bitDepth);
+
+    dst = dstPic->getAddr(COMPONENT_Y, partAddr);
+
+    for (i = 0; i < cxHeight; i++)
+    {
+      for (j = 0; j < cxWidth; j++)
+      {
+#if JVET_D0033_ADAPTIVE_CLIPPING
+        dst[j] = ClipA(((a*dst[j]) >> iShift) + b, COMPONENT_Y);
+#else
+        dst[j] = Clip3(0, (1 << bitDepth) - 1, ((a*dst[j]) >> iShift) + b);
+#endif
+      }
+      dst += dstStride;
+    }
+  }
+#endif
+
+}
+#endif
+
 #if JVET_G0082
 
 __inline Void TComPrediction::calcBlkGradient(Int sx, Int sy, Int64 *arraysGx2, Int64 *arraysGxGy, Int64 *arraysGxdI, Int64 *arraysGy2, Int64 *arraysGydI,
   Int64 &sGx2, Int64 &sGy2, Int64 &sGxGy, Int64 &sGxdI, Int64 &sGydI, Int iWidth, Int iHeight)
 {
+#if 1
+  static const UInt weightTbl[8][8] = {
+    { 1, 2, 3, 4, 4, 3, 2, 1,     },
+    { 2, 4, 6, 8, 8, 6, 4, 2,     },
+    { 3, 6, 9, 12, 12, 9, 6, 3,   },
+    { 4, 8, 12, 16, 16, 12, 8, 4, },
+    { 4, 8, 12, 16, 16, 12, 8, 4, },
+    { 3, 6, 9, 12, 12, 9, 6, 3,   },
+    { 2, 4, 6, 8, 8, 6, 4, 2,     },
+    { 1, 2, 3, 4, 4, 3, 2, 1      }
+    };
+#else
+  // Original JEM 7.0 code causing warnings on Linux/g++
   static const UInt weightTbl[8][8] = { 1, 2, 3, 4, 4, 3, 2, 1,
     2, 4, 6, 8, 8, 6, 4, 2,
     3, 6, 9, 12, 12, 9, 6, 3,
@@ -2223,7 +2587,7 @@
     3, 6, 9, 12, 12, 9, 6, 3,
     2, 4, 6, 8, 8, 6, 4, 2,
     1, 2, 3, 4, 4, 3, 2, 1 };
-
+#endif
   Int64 *pGx2 = arraysGx2;
   Int64 *pGy2 = arraysGy2;
   Int64 *pGxGy = arraysGxGy;
@@ -3757,8 +4121,163 @@
  *
  * This function performs filtering left and top edges of the prediction samples for DC mode (intra coding).
  */
+#if MBF_DC
+Void TComPrediction::xDCPredFiltering( const Pel* pSrc, Int iSrcStride, Pel* pDst, Int iDstStride, Int iWidth, Int iHeight, ChannelType channelType, Bool strongFilter )
+#else
 Void TComPrediction::xDCPredFiltering( const Pel* pSrc, Int iSrcStride, Pel* pDst, Int iDstStride, Int iWidth, Int iHeight, ChannelType channelType )
+#endif
 {
+#if MBF_DC
+  if (isLuma(channelType))
+  {
+    Int x, y, nrFilterCoeff;
+    Int filterCoeff15[15] = {8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120};
+    Int weightCoeff15[15] = {1, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8};
+    Int filterCoeff7[7] = {2, 24, 46, 64, 82, 104, 126};
+    Int filterCoeff7_[7] = {16, 32, 48, 64, 80, 96, 112};
+    Int weightCoeff7[7] = {5, 7, 8, 10, 13, 16, 17};
+    Int weightCoeff_weak_7[7] = { 2, 2, 2, 2, 2, 2, 1};
+    Int filterCoeff4[4] = {5, 43, 87, 123};
+    Int filterCoeff4_[4] = {25, 51, 77, 103};
+    Int weightCoeff4[4] = {13, 20, 23, 29};
+    Int filterCoeff2[2] = {14, 114};
+    Int filterCoeff2_[2] = {43, 85};
+    Int weightCoeff2[2] = {58, 70};
+    Int filterCoeff1[1] = {64};
+    Int filterCoeff1_[1] = {64};
+    Int weightCoeff1[1] = {0};
+
+    Int* filterCoeffPtr;
+    Int* filterCoeffPtr_;
+    Int* weightCoeffPtr;
+
+    switch (min(iWidth, iHeight))
+    {
+    case 128:
+    case 64:
+    case 32:
+      if (!strongFilter)
+      {
+        nrFilterCoeff = 7;
+        filterCoeffPtr = filterCoeff7;
+        filterCoeffPtr_ = filterCoeff7_;
+        weightCoeffPtr = weightCoeff_weak_7;
+      }
+      else
+      {
+        nrFilterCoeff = 15;
+        filterCoeffPtr = filterCoeff15;
+        filterCoeffPtr_ = filterCoeff15;
+        weightCoeffPtr = weightCoeff15;
+      }
+      break;
+    case 16:
+      if (!strongFilter)
+      {
+        nrFilterCoeff = 7;
+        filterCoeffPtr = filterCoeff7;
+        filterCoeffPtr_ = filterCoeff7_;
+        weightCoeffPtr = weightCoeff_weak_7;
+      }
+      else
+      {
+        nrFilterCoeff = 7;
+        filterCoeffPtr = filterCoeff7;
+        filterCoeffPtr_ = filterCoeff7_;
+        weightCoeffPtr = weightCoeff7;
+      }
+      break;
+    case 8:
+      if (!strongFilter)
+      {
+        nrFilterCoeff = 1;
+        filterCoeffPtr = filterCoeff1;
+        filterCoeffPtr_ = filterCoeff1_;
+        weightCoeffPtr = weightCoeff1;
+      }
+      else
+      {
+        nrFilterCoeff = 4;
+        filterCoeffPtr = filterCoeff4;
+        filterCoeffPtr_ = filterCoeff4_;
+        weightCoeffPtr = weightCoeff4;
+      }
+      break;
+    case 4:
+      if (!strongFilter)
+      {
+        nrFilterCoeff = 1;
+        filterCoeffPtr = filterCoeff1;
+        filterCoeffPtr_ = filterCoeff1_;
+        weightCoeffPtr = weightCoeff1;
+      }
+      else
+      {
+        nrFilterCoeff = 2;
+        filterCoeffPtr = filterCoeff2;
+        filterCoeffPtr_ = filterCoeff2_;
+        weightCoeffPtr = weightCoeff2;
+      }
+      break;
+    default:
+      assert(0);
+    }
+    // filter TOP LEFT region
+    for (y = 0; y < nrFilterCoeff; y++)
+    {
+      Int refSampleLeft = pSrc[y*iSrcStride - 1];
+      for (x = 0; x < nrFilterCoeff; x++)
+      {
+        Int refSampleTop = pSrc[x - iSrcStride];
+        Int filterCoeffLeft = filterCoeffPtr[nrFilterCoeff - 1 - x] + y * weightCoeffPtr[nrFilterCoeff - 1 - x];
+        Int filterCoeffTop = filterCoeffPtr[nrFilterCoeff - 1 - y] + x * weightCoeffPtr[nrFilterCoeff - 1 - y];
+        Int filterCoeffDst = 256 - filterCoeffLeft - filterCoeffTop;
+        Int dstT = refSampleTop * filterCoeffTop;
+        Int dstL = refSampleLeft * filterCoeffLeft;
+        Int dstD = pDst[y * iDstStride + x] * filterCoeffDst;
+        pDst[y*iDstStride + x] = (Pel)((dstT + dstL + dstD + 128) >> 8);
+      }
+    }
+    // filter LEFT region
+    for (y = nrFilterCoeff; y < iHeight; y++)
+    {
+      Int refSample = pSrc[y*iSrcStride - 1];
+      for (x = 0; x < nrFilterCoeff; x++)
+      {
+        Int filterCoeffLeft = filterCoeffPtr_[nrFilterCoeff - 1 - x];
+        if (strongFilter)
+        {
+          Int filterCoeffDst = 128 - filterCoeffLeft;
+          pDst[y*iDstStride + x] = (Pel)((refSample * filterCoeffLeft + pDst[y * iDstStride + x] * filterCoeffDst + 64) >> 7);
+        }
+        else
+        {
+          Int filterCoeffDst = 256 - filterCoeffLeft;
+          pDst[y*iDstStride + x] = (Pel)((refSample * filterCoeffLeft + pDst[y * iDstStride + x] * filterCoeffDst + 128) >> 8);
+        }
+      }
+    }
+    // filter TOP region
+    for (x = nrFilterCoeff; x < iWidth; x++)
+    {
+      Int refSample = pSrc[x - iSrcStride];
+      for (y = 0; y < nrFilterCoeff; y++)
+      {
+        Int filterCoeffTop = filterCoeffPtr_[nrFilterCoeff - 1 - y];
+        if (strongFilter)
+        {
+          Int filterCoeffDst = 128 - filterCoeffTop;
+          pDst[y*iDstStride + x] = (Pel)((refSample * filterCoeffTop + pDst[y * iDstStride + x] * filterCoeffDst + 64) >> 7);
+        }
+        else
+        {
+          Int filterCoeffDst = 256 - filterCoeffTop;
+          pDst[y*iDstStride + x] = (Pel)((refSample * filterCoeffTop + pDst[y * iDstStride + x] * filterCoeffDst + 128) >> 8);
+        }
+      }
+    }
+  }
+#else
   Int x, y, iDstStride2, iSrcStride2;
 
   if (isLuma(channelType) && (iWidth <= MAXIMUM_INTRA_FILTERED_WIDTH) && (iHeight <= MAXIMUM_INTRA_FILTERED_HEIGHT))
@@ -3780,6 +4299,7 @@
   }
 
   return;
+#endif
 }
 
 #if VCEG_AZ07_INTRA_BOUNDARY_FILTER
@@ -3829,6 +4349,41 @@
   return;
 }
 
+#if WIDE_ANGLE_INTRA
+Void TComPrediction::xIntraPredFilteringModeInvDGL( const Pel* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight, UInt uiMode )
+{
+  Pel* pDst = rpDst;
+  
+#if VCEG_AZ07_INTRA_65ANG_MODES
+  Bool bHorz = (uiMode > DIA_IDX);
+#else
+  Bool bHorz = (uiMode > 18);
+#endif
+  
+  const Int offset[2] = {  0, 1 };
+  const Int filter[3] = { 12, 1, 3 };
+  
+  if(bHorz) // Effective prediction took place from the left border - filter top border
+  {
+    for ( Int x = 0; x < iWidth; x++ )
+    {
+      pDst[x] = ( filter[0] * pDst[x]
+                + filter[1] * pSrc[x - iSrcStride + offset[0]]
+                + filter[2] * pSrc[x - iSrcStride + offset[1]] + 8) >> 4;
+    }
+  }
+  else
+  {
+    for ( Int y = 0; y < iHeight; y++ )
+    {
+      pDst[y * iDstStride] = ( filter[0] * pDst[y * iDstStride]
+                             + filter[1] * pSrc[(y + offset[0] ) * iSrcStride -1 ]
+                             + filter[2] * pSrc[(y + offset[1] ) * iSrcStride -1 ] + 8) >> 4;
+    }
+  }
+}
+#endif
+
 Void TComPrediction::xIntraPredFilteringModeDGL( const Pel* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight, UInt uiMode )
 {
   Pel* pDst = rpDst;
@@ -4006,6 +4561,11 @@
     return;
   }
   
+#if BORDER_FLEX_AFFINE_OBMC_OFF_FOR_AFFINE
+  if ( pcCU->getAffineFlag( uiAbsPartIdx ) )
+    return;
+#endif
+  
 #if JVET_C0024_QTBT
   PartSize ePartSize = SIZE_2Nx2N;
 #else
@@ -4079,6 +4639,7 @@
     bSubMotion = true;
   }
 #endif
+  
 #if !JVET_C0024_QTBT
   Bool bVerticalPU  = ( ePartSize == SIZE_2NxN || ePartSize == SIZE_2NxnU || ePartSize == SIZE_2NxnD );
   Bool bHorizonalPU = ( ePartSize == SIZE_Nx2N || ePartSize == SIZE_nLx2N || ePartSize == SIZE_nRx2N );
@@ -4145,6 +4706,35 @@
 
   Bool bCurrMotStored = false, bDiffMot[4]= { false, false, false, false };
 #endif
+
+#if OBMC_SKIP
+
+  Bool bImplicit = !pcCU->isOBMCFlagCoded(uiAbsPartIdx);
+  Int  iSpaAct = 0;
+
+  Bool b1stRndSkip = false;
+
+  if (bImplicit)
+  {
+
+    iSpaAct = xGetBlkSACT( pcYuvPred->getAddr(COMPONENT_Y,
+                           uiAbsPartIdx),
+                           pcYuvPred->getStride(COMPONENT_Y), uiWidth, uiHeight );
+
+
+    const Int i1stRndTH = xGetSpaTH(pcCU, uiAbsPartIdx);
+
+    b1stRndSkip = (iSpaAct < i1stRndTH);
+  }
+
+
+  if (b1stRndSkip)
+    return;
+
+#endif
+
+
+
   TComMvField cCurMvField[2], cNeigMvField[2];
 
   Int maxDir = bNormal2Nx2N ? 2 : 4;
@@ -4241,7 +4831,11 @@
         bSubBlockOBMCSimp |= ( bOBMCSimp || pcCU->getAffineFlag( uiSubPartIdx ) );
 #endif
 #if JVET_C0024_QTBT
+#if OBMC_SKIP
+        if (pcCU->getNeigMotion(uiSubPartIdx, cNeigMvField, iNeigPredDir, iDir, cCurMvField, iCurPredDir, uiZeroIdx, bCurrMotStored, bImplicit))
+#else
         if( pcCU->getNeigMotion( uiSubPartIdx, cNeigMvField, iNeigPredDir, iDir, cCurMvField, iCurPredDir, uiZeroIdx, bCurrMotStored ) )
+#endif
 #else
         if( ( bCurSubBkFetched && bDiffMot[iDir] ) || pcCU->getNeigMotion( uiSubPartIdx, cNeigMvField, iNeigPredDir, iDir, cCurMvField, iCurPredDir, uiZeroIdx, bCurrMotStored ) )
 #endif
@@ -5214,6 +5808,55 @@
   return( bAvailable );
 }
 
+
+#if OBMC_SKIP
+UInt TComPrediction::xGetBlkSACT( Pel * pSrc,
+                                  UInt  stride,
+                                  UInt  width,
+                                  UInt  height )
+{
+  if (width <= 2 || height <= 2) return 0;
+
+  // Do not care samples around block boundary
+
+  UInt   uiSum = 0;
+  Double dbAvg = 0;
+  Pel   *pAddr = pSrc;
+  UInt   count = 0;
+
+  // Adjust pAddr to point at second row
+  pAddr += stride;
+
+  for (Int y1 = 1; y1 < (height - 1); y1++)
+  {
+    for (Int x1 = 1; x1 < (width - 1); x1++)
+    {
+      Pel * pC   = pAddr + x1;
+      Int  lap2D = ((*pC) << 2) - *(pC - 1) - *(pC + 1) - *(pC - stride) - *(pC + stride);
+      uiSum += std::abs(lap2D);
+      count++;
+    }
+    pAddr += stride;
+  }
+
+  dbAvg = (Double)uiSum / count;
+  return (UInt)dbAvg;
+}
+
+UInt TComPrediction::xGetSpaTH(TComDataCU * pCU, UInt uiAbsPartIdx)
+{
+#if QP_SPACT_TH
+  UInt uiTh   = m_spatialThres[ Clip3(0, MAX_QP, (Int)pCU->getSlice()->getSliceQp()) ]; 
+       uiTh <<= ( pCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8 );
+#else
+  UInt uiTh = (SPACT_SKIP_TH) << (pCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
+#endif
+
+  return uiTh;
+}
+#endif
+
+
 /**
  * \brief Refine Mv for each sub-block of the block based on bilateral matching or template matching
  *
@@ -7410,6 +8053,226 @@
 }
 
 
+#if BORDER_FLEX_AFFINE
+
+#define REMAP_FILTER_NUM_SUBPELS  64 // Allowed values: 64 or 16
+
+#if REMAP_FILTER_NUM_SUBPELS == 64
+
+#define REMAP_FILTER_SUBPEL_SHIFT  6
+#define REMAP_FILTER_OFFSET      128
+#define REMAP_FILTER_SHIFT         8
+
+#elif REMAP_FILTER_NUM_SUBPELS == 16
+
+#define REMAP_FILTER_SUBPEL_SHIFT  4
+#define REMAP_FILTER_OFFSET       32
+#define REMAP_FILTER_SHIFT         6
+
+#else
+error...
+#endif
+
+#define REMAP_FILTER_LEN           8
+#define REMAP_NUM_POS              4
+#define REMAP_PADDING              4
+
+#define REMAP_MAX_DEVIATION_PERP  (REMAP_FILTER_NUM_SUBPELS/2 - 1)
+#define REMAP_MAX_DEVIATION_LAT   (REMAP_FILTER_NUM_SUBPELS   - 1)
+
+#if REMAP_FILTER_NUM_SUBPELS == 16
+// JEM motion comp filter
+Short affineFlexingFilter[REMAP_FILTER_NUM_SUBPELS][REMAP_FILTER_LEN] =
+{
+  {  0, 0,   0, 64,  0,   0,  0,  0 },
+  {  0, 1,  -3, 63,  4,  -2,  1,  0 },
+  { -1, 2,  -5, 62,  8,  -3,  1,  0 },
+  { -1, 3,  -8, 60, 13,  -4,  1,  0 },
+  { -1, 4, -10, 58, 17,  -5,  1,  0 },
+  { -1, 4, -11, 52, 26,  -8,  3, -1 },
+  { -1, 3,  -9, 47, 31, -10,  4, -1 },
+  { -1, 4, -11, 45, 34, -10,  4, -1 },
+  { -1, 4, -11, 40, 40, -11,  4, -1 },
+  { -1, 4, -10, 34, 45, -11,  4, -1 },
+  { -1, 4, -10, 31, 47,  -9,  3, -1 },
+  { -1, 3,  -8, 26, 52, -11,  4, -1 },
+  {  0, 1,  -5, 17, 58, -10,  4, -1 },
+  {  0, 1,  -4, 13, 60,  -8,  3, -1 },
+  {  0, 1,  -3,  8, 62,  -5,  2, -1 },
+  {  0, 1,  -2,  4, 63,  -3,  1,  0 }
+};
+#else
+// "Original" KTA affine filter for 1/64 pels
+Short affineFlexingFilter[REMAP_FILTER_NUM_SUBPELS][REMAP_FILTER_LEN] =
+{
+  {   0,  0,   0, 256,   0,   0,  0,  0},
+  {   0,  1,  -3, 256,   4,  -2,  0,  0},
+  {   0,  2,  -7, 255,   8,  -3,  1,  0},
+  {  -1,  3, -10, 255,  12,  -4,  1,  0},
+  {  -1,  4, -13, 254,  16,  -5,  2, -1},
+  {  -1,  5, -16, 253,  20,  -7,  2,  0},
+  {  -1,  6, -18, 251,  25,  -9,  3, -1},
+  {  -2,  7, -21, 250,  29, -10,  4, -1},
+  {  -2,  8, -23, 248,  34, -12,  4, -1},
+  {  -2,  8, -25, 246,  38, -13,  5, -1},
+  {  -2,  9, -27, 244,  43, -15,  5, -1},
+  {  -2, 10, -30, 242,  48, -16,  6, -2},
+  {  -2, 10, -31, 239,  52, -17,  5,  0},
+  {  -2, 10, -32, 237,  57, -18,  6, -2},
+  {  -2, 11, -34, 234,  63, -21,  7, -2},
+  {  -2, 11, -35, 231,  68, -21,  6, -2},
+  {  -3, 13, -38, 228,  74, -24,  9, -3},
+  {  -2, 12, -38, 224,  78, -24,  7, -1},
+  {  -3, 14, -40, 221,  84, -27, 10, -3},
+  {  -2, 12, -39, 217,  88, -27,  8, -1},
+  {  -3, 13, -40, 213,  94, -28,  9, -2},
+  {  -3, 15, -43, 210, 100, -31, 11, -3},
+  {  -3, 13, -41, 205, 104, -30,  9, -1},
+  {  -3, 12, -41, 201, 110, -31,  9, -1},
+  {  -3, 15, -43, 197, 116, -35, 12, -3},
+  {  -3, 14, -43, 192, 121, -35, 12, -2},
+  {  -2, 13, -42, 187, 126, -35, 10, -1},
+  {  -3, 14, -43, 183, 132, -37, 12, -2},
+  {  -2, 13, -42, 178, 137, -38, 12, -2},
+  {  -3, 14, -42, 173, 143, -39, 12, -2},
+  {  -3, 15, -43, 169, 148, -41, 14, -3},
+  {  -3, 13, -41, 163, 153, -40, 13, -2},
+  {  -3, 13, -40, 158, 158, -40, 13, -3},
+  {  -2, 13, -40, 153, 163, -41, 13, -3},
+  {  -3, 14, -41, 148, 169, -43, 15, -3},
+  {  -2, 12, -39, 143, 173, -42, 14, -3},
+  {  -2, 12, -38, 137, 178, -42, 13, -2},
+  {  -2, 12, -37, 132, 183, -43, 14, -3},
+  {  -1, 10, -35, 126, 187, -42, 13, -2},
+  {  -2, 12, -35, 121, 192, -43, 14, -3},
+  {  -3, 12, -35, 116, 197, -43, 15, -3},
+  {  -1,  9, -31, 110, 201, -41, 12, -3},
+  {  -1,  9, -30, 104, 205, -41, 13, -3},
+  {  -3, 11, -31, 100, 210, -43, 15, -3},
+  {  -2,  9, -28,  94, 213, -40, 13, -3},
+  {  -1,  8, -27,  88, 217, -39, 12, -2},
+  {  -3, 10, -27,  84, 221, -40, 14, -3},
+  {  -1,  7, -24,  78, 224, -38, 12, -2},
+  {  -3,  9, -24,  74, 228, -38, 13, -3},
+  {  -2,  6, -21,  68, 231, -35, 11, -2},
+  {  -2,  7, -21,  63, 234, -34, 11, -2},
+  {  -2,  6, -18,  57, 237, -32, 10, -2},
+  {   0,  5, -17,  52, 239, -31, 10, -2},
+  {  -2,  6, -16,  48, 242, -30, 10, -2},
+  {  -1,  5, -15,  43, 244, -27,  9, -2},
+  {  -1,  5, -13,  38, 246, -25,  8, -2},
+  {  -1,  4, -12,  34, 248, -23,  8, -2},
+  {  -1,  4, -10,  29, 250, -21,  7, -2},
+  {  -1,  3,  -9,  25, 251, -18,  6, -1},
+  {   0,  2,  -7,  20, 253, -16,  5, -1},
+  {  -1,  2,  -5,  16, 254, -13,  4, -1},
+  {   0,  1,  -4,  12, 255, -10,  3, -1},
+  {   0,  1,  -3,   8, 255,  -7,  2,  0},
+  {   0,  0,  -2,   4, 256,  -3,  1,  0}
+};
+#endif
+
+// Calculate position offsets for each line in a sub-PU based on the motion vector difference between sub-PUs
+Void TComPrediction::xAffineFlexGetOffsets( Int blkPosDiff, Int* posDiff )
+{
+  Int rounding = blkPosDiff >= 0 ? 1 : -1;
+
+  posDiff[3] = (blkPosDiff + rounding)  / 3; // Subpel difference for the bottom/right edge samples (a look-up table of REMAP_FILTER_NUM_SUBPELS values)
+  posDiff[2] = (blkPosDiff + 4       ) >> 3; // Subpel difference for the samples one pel away from the bottom/right edge samples
+  posDiff[1] = -posDiff[2];                  // Subpel difference for the samples one pel away from the top/left edge samples
+  posDiff[0] = -posDiff[3];                  // Subpel difference for the top/left edge samples
+}
+
+Void TComPrediction::xAffineFlexFilter ( Int *input, Pel *filter, Pel &output, Bool clip, ComponentID compID, Int maxPel )
+{
+  Int outPel = REMAP_FILTER_OFFSET;
+  
+  for ( Int i = 0; i < REMAP_FILTER_LEN; i++ )
+    outPel += input[i] * (Int)filter[i];
+  
+  outPel >>= REMAP_FILTER_SHIFT;
+  
+  if ( clip )
+#if JVET_D0033_ADAPTIVE_CLIPPING
+    output = ClipA(outPel, compID);
+#else
+    output = outPel < 0 ? 0 : outPel > maxPel ? maxPel : outPel;
+#endif
+  else
+    output = outPel;
+}
+
+// Perform either lateral or perpendicular flexing in either horizontal or vertical direction for a whole PU
+Void TComPrediction::xAffineFlexPU( Pel *pels, Bool lateral, Bool horFilter, Int width, Int height, Int blkStride, Int blkPosDiff, Int clip, Int bitDepth, ComponentID compID )
+{
+  static Int inputBuf  [MAX_CU_SIZE + 2*REMAP_PADDING ]; // With room to pad the input
+  Pel       *filters   [REMAP_NUM_POS];
+  Int        intOffsets[REMAP_NUM_POS];
+  Int        posDiffs  [REMAP_NUM_POS];
+  Int        maxDiff   = lateral ? REMAP_MAX_DEVIATION_LAT : REMAP_MAX_DEVIATION_PERP;
+  
+  xAffineFlexGetOffsets( blkPosDiff, posDiffs );
+  
+  if ( abs(posDiffs[0]) == 0 || abs(posDiffs[0]) > maxDiff )
+    return;
+
+  Int numLines    = horFilter ? height    : width;   // Lines refer here to full lines scanned within a block and
+  Int numPels     = horFilter ? width     : height;  // pels to samples to be filtered in the line direction
+  Int strideLines = horFilter ? blkStride : 1;
+  Int stridePels  = horFilter ? 1         : blkStride;
+  Int *input      = inputBuf + REMAP_PADDING;
+  Int maxPel      = (1 << bitDepth) - 1;
+  
+  // Set up filters for different line positions
+  for ( Int i = 0; i < REMAP_NUM_POS; i++ ) {
+    intOffsets[i]  = posDiffs[i] < 0 ? -REMAP_FILTER_LEN/2 : -REMAP_FILTER_LEN/2 + 1;       // Where the filtering actually starts
+    filters[i]     = affineFlexingFilter[ posDiffs[i] & (REMAP_FILTER_NUM_SUBPELS - 1) ];
+  }
+  
+  for ( Int line = 0; line < numLines; line++ )
+  {
+    Int lineStartPos = line * strideLines;
+    
+    // Collect the input "line" and pad both ends
+    for ( Int i = 0; i < numPels; i++ )
+      input[i] = pels[lineStartPos + i * stridePels];
+    
+    for ( Int i = 1; i <= REMAP_PADDING; i++ )
+      input[-i] = input[0];
+
+    for ( Int i = 0; i < REMAP_PADDING; i++ )
+      input[numPels + i] = input[numPels - 1];
+    
+    // Process the input line
+    if ( lateral )
+    {
+      if ( posDiffs[ line % REMAP_NUM_POS ] != 0 )
+      {
+        Pel *filter = filters   [ line % REMAP_NUM_POS ];
+        Int  offset = intOffsets[ line % REMAP_NUM_POS ];
+        
+        for ( Int i = 0; i < numPels; i++ )
+          xAffineFlexFilter ( input + i + offset, filter, pels[lineStartPos + i * stridePels], clip, compID, maxPel );
+      }
+    }
+    else // Perpendicular
+    {
+      for ( Int i = 0; i < numPels ; i++ )
+      {
+        if ( posDiffs[ i % REMAP_NUM_POS ] != 0 )
+        {
+          Pel *filter = filters   [ i % REMAP_NUM_POS ];
+          Int  offset = intOffsets[ i % REMAP_NUM_POS ];
+          
+          xAffineFlexFilter ( input + i + offset, filter, pels[lineStartPos + i * stridePels], clip, compID, maxPel );
+        }
+      }
+    }
+  }
+}
+#endif // BORDER_FLEX_AFFINE
+
+
 /**
  * \brief Generate motion-compensated block
  *
@@ -7424,7 +8287,11 @@
  * \param bi         Flag indicating whether bipred is used
  * \param  bitDepth  Bit depth
  */
-Void TComPrediction::xPredAffineBlk(const ComponentID compID, TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv acMv[3], Int width, Int height, TComYuv *dstPic, Bool bi, const Int bitDepth )
+Void TComPrediction::xPredAffineBlk(const ComponentID compID, TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv acMv[3], Int width, Int height, TComYuv *dstPic, Bool bi, const Int bitDepth
+#if BORDER_FLEX_AFFINE
+                                  , Bool finalRecon
+#endif
+                                    )
 {
 #if COM16_C1016_AFFINE
   if ( acMv[0] == acMv[1] )
@@ -7623,6 +8490,36 @@
     iMvScaleHor = iMvYHor;
     iMvScaleVer = iMvYVer;
   }
+  
+#if BORDER_FLEX_AFFINE
+  if ( compID == COMPONENT_Y && finalRecon && blockWidth == AFFINE_MIN_BLOCK_SIZE && blockHeight == AFFINE_MIN_BLOCK_SIZE )
+  {
+    Int  flexShift      = shift - (REMAP_FILTER_SUBPEL_SHIFT - 4); // Less shifting if there is more accuracy for the flexing filter
+    Int  amountZooming  = abs(iDMvHorX);
+    Int  amountRotating = abs(iDMvHorY);
+    Bool doLateral      = amountRotating >= amountZooming;
+    
+    dst = dstPic->getAddr( compID, partAddr );
+    
+    // Lateral resampling
+    if ( doLateral )
+    {
+      Int deltaX = (iDMvVerX * blockHeight) >> flexShift; // Difference in x component when stepping in vertical direction
+      Int deltaY = (iDMvHorY * blockWidth)  >> flexShift; // Difference in y component when stepping in horizontal direction
+      
+      xAffineFlexPU( dst, true,  true, cxWidth, cxHeight, dstStride, deltaX, !bi, bitDepth, compID ); // Horizontal filter
+      xAffineFlexPU( dst, true, false, cxWidth, cxHeight, dstStride, deltaY, !bi, bitDepth, compID ); // Vertical filter
+    }
+    else // Perpendicular resampling
+    {
+      Int deltaX = (iDMvHorX * blockWidth)  >> flexShift; // Difference in x component when stepping in horizontal direction
+      Int deltaY = (iDMvVerY * blockHeight) >> flexShift; // Difference in y component when stepping in vertical direction
+      
+      xAffineFlexPU( dst, false, false, cxWidth, cxHeight, dstStride, deltaY, !bi, bitDepth, compID ); // Vertical filter
+      xAffineFlexPU( dst, false,  true, cxWidth, cxHeight, dstStride, deltaX, !bi, bitDepth, compID ); // Horizontal filter
+    }
+  }
+#endif // BORDER_FLEX_AFFINE
 }
 
 Void TComPrediction::getMvPredAffineAMVP( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, TComMv acMvPred[3] )
Index: source/Lib/TLibCommon/TComPrediction.h
===================================================================
--- source/Lib/TLibCommon/TComPrediction.h	(revision 548)
+++ source/Lib/TLibCommon/TComPrediction.h	(working copy)
@@ -94,6 +94,10 @@
   UInt*  m_puiSPAddr;
 #endif
 
+#if QP_SPACT_TH
+  static const Int m_spatialThres[MAX_QP + 1];
+#endif
+
 protected:
 #if VCEG_AZ05_BIO  
   Pel*   m_pGradX0;
@@ -165,8 +169,15 @@
 #if COM16_C983_RSAF_PREVENT_OVERSMOOTHING
     , Bool enableRSAF = false 
 #endif
+#if WIDE_ANGLE_INTRA
+    , Int wideAngleMode = 0
+#endif
     );
   Void xPredIntraPlanar         ( const Pel* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height );
+  
+#if WIDE_ANGLE_INTRA
+  Void xIntraPredFilteringModeInvDGL( const Pel* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight, UInt uiMode );
+#endif
 
 #if VCEG_AZ07_FRUC_MERGE
   TComRdCost              m_cFRUCRDCost;
@@ -242,6 +253,17 @@
     , Bool bICFlag      = false
 #endif
     );
+
+
+#if MVD_SDH
+  Void xPredLumaBlk( TComDataCU * cu, TComPicYuv *refPic, UInt partAddr, TComMv mv, Int width, Int height, TComYuv *dstPic, const Int bitDepth
+#if VCEG_AZ06_IC
+                    , Bool bLICflag = false
+#endif
+                    );
+#endif
+
+
 #if JVET_E0052_DMVR
   Void xBIPMVRefine(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, Int iWidth, Int iHeight, TComYuv* pOrgYuv, TComYuv* pDstYuv, UInt uiMaxSearchRounds, UInt nSearchStepShift, UInt& uiMinCost);
   UInt xDirectMCCost(Int iBitDepth, Pel* pRef, UInt uiRefStride, Pel* pOrg, UInt uiOrgStride, Int iWidth, Int iHeight);
@@ -270,8 +292,11 @@
 #if COM16_C1046_PDPC_INTRA
   Void xReferenceFilter  (Int iBlkSize, Int iOrigWeight, Int iFilterOrder, Int * piRefVector, Int * piLowPassRef);
 #endif
+#if MBF_DC
+  Void xDCPredFiltering( const Pel* pSrc, Int iSrcStride, Pel* pDst, Int iDstStride, Int iWidth, Int iHeight, ChannelType channelType, Bool strongFilter );
+#else
   Void xDCPredFiltering( const Pel* pSrc, Int iSrcStride, Pel* pDst, Int iDstStride, Int iWidth, Int iHeight, ChannelType channelType );
-
+#endif
 #if VCEG_AZ05_INTRA_MPI
   Void xMPIredFiltering(Pel* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight, Int idxMPI);
 #endif
@@ -297,6 +322,12 @@
 #endif
     );
 #endif
+
+#if OBMC_SKIP
+  UInt xGetSpaTH(TComDataCU * pCU, UInt uiAbsPartIdx);
+  UInt xGetBlkSACT(Pel * pSrc, UInt stride, UInt width, UInt height);
+#endif
+
 #if VCEG_AZ07_FRUC_MERGE
   Bool xFrucFindBlkMv( TComDataCU * pCU , UInt uiPUIdx );
   Bool xFrucFindBlkMv4Pred( TComDataCU * pCU , UInt uiPUIdx , RefPicList eTargetRefPicList , Int nTargetRefIdx
@@ -430,10 +461,20 @@
 
 #if COM16_C1016_AFFINE
   Bool xCheckIdenticalAffineMotion ( TComDataCU* pcCU, UInt PartAddr, Int iWidth, Int iHeight );
-  Void xPredAffineBlk              ( const ComponentID compID, TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv acMv[3], Int width, Int height, TComYuv *dstPic, Bool bi, const Int bitDepth );
+  Void xPredAffineBlk              ( const ComponentID compID, TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv acMv[3], Int width, Int height, TComYuv *dstPic, Bool bi, const Int bitDepth
+#if BORDER_FLEX_AFFINE
+                                    , Bool finalRecon = false
+#endif
+                                    );
 
   Void getMvPredAffineAMVP         ( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, TComMv acMvPred[3] );
 #endif
+  
+#if BORDER_FLEX_AFFINE
+  Void xAffineFlexGetOffsets       ( Int blkPosDiff, Int* posDiff );
+  Void xAffineFlexFilter           ( Int *input, Pel *filter, Pel &output, Bool clip, ComponentID compID, Int maxPel );
+  Void xAffineFlexPU               ( Pel *pels, Bool lateral, Bool horFilter, Int width, Int height, Int blkStride, Int blkPosDiff, Int clip, Int bitDepth, ComponentID compID );
+#endif
 
   Pel  predIntraGetPredValDC      ( const Pel* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight);
 
Index: source/Lib/TLibCommon/TypeDef.h
===================================================================
--- source/Lib/TLibCommon/TypeDef.h	(revision 548)
+++ source/Lib/TLibCommon/TypeDef.h	(working copy)
@@ -44,6 +44,110 @@
 
 #include <vector>
 
+/***************************/
+// Deblocking improvements
+/***************************/
+#define DEBLOCKING_IMPROVEMENTS                           1
+#if DEBLOCKING_IMPROVEMENTS
+#define DEBLOCKING_CHROMA_BASED_ON_LUMA_BOUNDARIES        1 // deblock internal boundaries of chroma blocks due to prediction from luma
+#define DEBLOCKING_LIC                                    1 // deblock if LIC is used in one of the blocks
+#define DEBLOCKING_SUPERSTRONG                            1 // deblock using longer deblocking filters
+#define DEBLOCKING_SUBBLOCKS                              1 // deblock sub-block boundaries for sub-block prediction modes, no overlap across block boundaries
+#define DEBLOCKING_NOOVERLAP_BLOCKS                       1 // deblock with no overlap in filtering between block boundaries
+#endif
+
+/***************************/
+// Multiple boundary filtering
+/***************************/
+#define MBF_PLANAR                                        1 // smoothens boundaries of planar mode
+#define MBF_DC                                            1 // smoothens boundaries of DC mode
+
+/***************************/
+// Wide angle intra prediction
+/***************************/
+#define WIDE_ANGLE_INTRA                                  1
+
+/***************************/
+// Affine flexing
+/***************************/
+#define BORDER_FLEX_AFFINE                                1
+
+#if BORDER_FLEX_AFFINE
+#define BORDER_FLEX_AFFINE_OBMC_OFF_FOR_AFFINE            1
+#else
+#define BORDER_FLEX_AFFINE_OBMC_OFF_FOR_AFFINE            0
+#endif
+
+/***************************/
+// Motion PBL Tool
+/***************************/
+#define ER_MV_PBL                                         1
+
+#if ER_MV_PBL
+// Tunings
+#define PBL_PREREMOVE_HIGHFREQ                            1
+#endif
+
+/***************************/
+// Motion Look Back Tool
+/***************************/
+#define ER_MV_LB                                          1
+
+#if ER_MV_LB
+
+// Tunings
+#define ER_NB_LIMIT                                       2 ///< specify the number of old candidates to be added
+#define ER_LB_USE_RANGE_LIMIT                             1 ///< specify whether to use range for look back
+#define ER_NO_ADD_IF_MANY_SPATIAL                         1
+
+
+#if ER_LB_USE_RANGE_LIMIT
+#define ER_RANGE_CTU_RATIO                               (1)
+#endif
+
+#if ER_NO_ADD_IF_MANY_SPATIAL
+#define ER_SPATIAL_LIMIT                                 (4)
+#endif
+
+#endif
+
+/***************************/
+// OBMC restriction tool
+/***************************/
+
+#define OBMC_SKIP                                         1
+
+#if OBMC_SKIP
+
+#define QP_SPACT_TH                                       1
+
+#if !QP_SPACT_TH
+#define SPACT_SKIP_TH                                     4 // Fixed threshold instead of QP dependent threshold
+#endif
+
+#define OBMC_LIC_SKIP                                     1
+
+#endif
+
+/***************************/
+// MVD SDH tool
+/***************************/
+
+#define MVD_SDH                                          1
+
+#if MVD_SDH
+
+#define SR_RANGE                                        (1)
+#define USE_MVP_IDX                                      0
+
+#if PBL_PREREMOVE_HIGHFREQ
+#define SHARE_PREREMOVE                                  1
+#else
+#define SHARE_PREREMOVE                                  0
+#endif
+
+#endif
+
 //! \ingroup TLibCommon
 //! \{
 ///////////////////////////////////////////////////////////
@@ -328,6 +432,7 @@
 // KTA tools section end
 ///////////////////////////////////////////////////////////
 
+
 // ====================================================================================================================
 // Debugging
 // ====================================================================================================================
@@ -572,6 +677,22 @@
   NUMBER_OF_RDPCM_SIGNALLING_MODES = 2
 };
 
+#if ER_MV_PBL
+enum ListPredDir
+{
+  DIR_L0toL1 = 0,
+  DIR_L1toL0 = 1,
+  DIR_NONE   = 2
+};
+enum PredMvPrio
+{
+  LOW_PRIO    = 0,
+  MEDIUM_PRIO = 1,
+  HIGH_PRIO   = 2,
+  UNKOWN_PRIO = 3
+};
+#endif
+
 /// supported slice type
 enum SliceType
 {
Index: source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 548)
+++ source/Lib/TLibDecoder/TDecCAVLC.cpp	(working copy)
@@ -1879,6 +1879,13 @@
   }
 }
 
+#if WIDE_ANGLE_INTRA
+Void TDecCavlc::parseWideAngleIntraFlag( TComDataCU* /*pcCU*/, UInt /*uiAbsPartIdx*/, UInt /*uiDepth*/, ChannelType /*channel*/ )
+{
+  assert(0);
+}
+#endif
+
 Void TDecCavlc::parseSkipFlag( TComDataCU* /*pcCU*/, UInt /*uiAbsPartIdx*/, UInt /*uiDepth*/ )
 {
   assert(0);
@@ -1971,7 +1978,11 @@
 {
   assert(0);
 }
-Void TDecCavlc::parseMvd( TComDataCU* /*pcCU*/, UInt /*uiAbsPartIdx*/, UInt /*uiPartIdx*/, UInt /*uiDepth*/, RefPicList /*eRefList*/ )
+Void TDecCavlc::parseMvd( TComDataCU* /*pcCU*/, UInt /*uiAbsPartIdx*/, UInt /*uiPartIdx*/, UInt /*uiDepth*/, RefPicList /*eRefList*/
+#if MVD_SDH
+                        , UInt
+#endif
+)
 {
   assert(0);
 }
@@ -2573,4 +2584,4 @@
   assert(0);
 }
 #endif
-//! \}
\ No newline at end of file
+//! \}
Index: source/Lib/TLibDecoder/TDecCAVLC.h
===================================================================
--- source/Lib/TLibDecoder/TDecCAVLC.h	(revision 548)
+++ source/Lib/TLibDecoder/TDecCAVLC.h	(working copy)
@@ -86,6 +86,9 @@
   Void parseMVPIdx          ( Int& riMVPIdx );
 
   Void parseSkipFlag        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#if WIDE_ANGLE_INTRA
+  Void parseWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, ChannelType channel );
+#endif
 #if COM16_C806_OBMC
   Void  parseOBMCFlag       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 #endif
@@ -127,7 +130,13 @@
 
   Void parseInterDir        ( TComDataCU* pcCU, UInt& ruiInterDir, UInt uiAbsPartIdx );
   Void parseRefFrmIdx       ( TComDataCU* pcCU, Int& riRefFrmIdx, RefPicList eRefList );
+
+#if MVD_SDH
+  Void parseMvd             ( TComDataCU* pcCU, UInt uiAbsPartAddr, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList, UInt mode );
+#else
   Void parseMvd             ( TComDataCU* pcCU, UInt uiAbsPartAddr,UInt uiPartIdx,    UInt uiDepth, RefPicList eRefList );
+#endif
+
   Void parseCrossComponentPrediction( class TComTU &rTu, ComponentID compID );
 
   Void parseDeltaQP         ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
@@ -202,4 +211,4 @@
 
 //! \}
 
-#endif // !defined(AFX_TDECCAVLC_H__9732DD64_59B0_4A41_B29E_1A5B18821EAD__INCLUDED_)
\ No newline at end of file
+#endif // !defined(AFX_TDECCAVLC_H__9732DD64_59B0_4A41_B29E_1A5B18821EAD__INCLUDED_)
Index: source/Lib/TLibDecoder/TDecCu.cpp
===================================================================
--- source/Lib/TLibDecoder/TDecCu.cpp	(revision 548)
+++ source/Lib/TLibDecoder/TDecCu.cpp	(working copy)
@@ -2033,6 +2033,18 @@
   }
 }
 
+#if ER_MV_PBL
+Void  TDecCu::xCopyAMVPInfo( AMVPInfo* pSrc, AMVPInfo* pDst )
+{
+  pDst->iN = pSrc->iN;
+  for (Int i = 0; i < pSrc->iN; i++)
+  {
+    pDst->isScaled[i]   = pSrc->isScaled[i];
+    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
+  }
+}
+#endif
+
 #if VCEG_AZ07_FRUC_MERGE || JVET_C0024_QTBT
 Void TDecCu::xDeriveCUMV( TComDataCU * pcCU , UInt uiAbsPartIdx , UInt uiDepth )
 {
@@ -2197,6 +2209,118 @@
     }
     else
     {
+#if ER_MV_PBL
+      Bool toolEnabled = false;
+      if (pcSubCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiSubPartIdx - uiAbsPartIdx) >= 0
+        && pcSubCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiSubPartIdx - uiAbsPartIdx) >= 0
+        && pcCU->getSlice()->getMvdL1ZeroFlag() == false
+#if COM16_C1016_AFFINE
+        && !pcCU->isAffine(uiSubPartIdx)
+#endif
+        )
+      {
+        toolEnabled = true;
+      }
+
+      if (toolEnabled)
+      {
+        AMVPInfo   cAMVPInfoL1;
+        pcSubCU->fillMvpCand( uiPartIdx, uiSubPartIdx - uiAbsPartIdx, REF_PIC_LIST_1, pcSubCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiSubPartIdx - uiAbsPartIdx), &cAMVPInfoL1
+#if VCEG_AZ07_FRUC_MERGE
+                              , m_pcPrediction
+#endif
+                             );
+
+        ListPredDir predDir = (cAMVPInfoL1.isScaled[0] == HIGH_PRIO || cAMVPInfoL1.isScaled[1] == HIGH_PRIO) ? DIR_L1toL0 : DIR_L0toL1;
+
+        for (UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++)
+        {
+          UInt refListIdx = (predDir == DIR_L0toL1) ? uiRefListIdx : (1 - uiRefListIdx);
+
+          RefPicList eRefList = RefPicList(refListIdx);
+
+          if (pcCU->getSlice()->getNumRefIdx(eRefList) > 0 && (pcCU->getInterDir(uiSubPartIdx) & (1 << refListIdx)))
+          {
+            Short iMvdHor = pcCU->getCUMvField(eRefList)->getMvd(uiSubPartIdx).getHor();
+            Short iMvdVer = pcCU->getCUMvField(eRefList)->getMvd(uiSubPartIdx).getVer();
+#if VCEG_AZ07_IMV
+            if (pcCU->getiMVFlag(uiSubPartIdx))
+            {
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+              iMvdHor <<= VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+              iMvdVer <<= VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+#else
+              iMvdHor <<= 2;
+              iMvdVer <<= 2;
+#endif
+
+#if  JVET_E0076_MULTI_PEL_MVD
+              if (pcCU->getiMVFlag(uiSubPartIdx) == 2)
+              {
+                iMvdHor <<= MULTI_PEL_MVD_BITS;
+                iMvdVer <<= MULTI_PEL_MVD_BITS;
+              }
+#endif
+
+            }
+#endif
+            TComMv cMv(iMvdHor, iMvdVer);
+
+            pcCU->getCUMvField(RefPicList(refListIdx))->setAllMvd(cMv, ePartSize, uiSubPartIdx, uiDepth, uiPartIdx);
+
+            AMVPInfo* pAMVPInfo = pcSubCU->getCUMvField(eRefList)->getAMVPInfo();
+
+            if ( eRefList == REF_PIC_LIST_1 )
+              xCopyAMVPInfo ( &cAMVPInfoL1, pAMVPInfo );
+            else
+            {
+              pcSubCU->fillMvpCand( uiPartIdx, uiSubPartIdx - uiAbsPartIdx, eRefList, pcSubCU->getCUMvField(eRefList)->getRefIdx(uiSubPartIdx - uiAbsPartIdx), pAMVPInfo
+#if VCEG_AZ07_FRUC_MERGE
+                                   , m_pcPrediction
+#endif
+                                   );
+            }
+
+
+            {
+              Bool hasScaled         = false;
+              Int  firstHasScaledIdx = -1;
+
+              if (predDir == DIR_L1toL0 && eRefList == REF_PIC_LIST_0)
+              {
+                pcSubCU->xGetFreeSlot( pAMVPInfo, hasScaled, firstHasScaledIdx );
+                TComMv cMvL1 = pcSubCU->getCUMvField(REF_PIC_LIST_1)->getMv(uiSubPartIdx - uiAbsPartIdx);
+                TComMv cMvPredFromL1;
+                Bool hasMvPredFromL1 = pcSubCU->xAddListXCand( cMvL1, cMvPredFromL1, 1, pcSubCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiSubPartIdx - uiAbsPartIdx),
+                                                                                        pcSubCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiSubPartIdx - uiAbsPartIdx), uiSubPartIdx - uiAbsPartIdx );
+                if (hasScaled && hasMvPredFromL1)
+                {
+                  pAMVPInfo->m_acMvCand[firstHasScaledIdx] = cMvPredFromL1;
+                }
+              }
+
+              if ((predDir == DIR_L0toL1) && eRefList == REF_PIC_LIST_1)
+              {
+                pcSubCU->xGetFreeSlot( pAMVPInfo, hasScaled, firstHasScaledIdx );
+                TComMv cMvL0 = pcSubCU->getCUMvField(REF_PIC_LIST_0)->getMv(uiSubPartIdx - uiAbsPartIdx);
+                TComMv cMvPredFromL0;
+                Bool hasMvPredFromL0 = pcSubCU->xAddListXCand( cMvL0, cMvPredFromL0, 0, pcSubCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx(uiSubPartIdx - uiAbsPartIdx),
+                                                                                        pcSubCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx(uiSubPartIdx - uiAbsPartIdx), uiSubPartIdx - uiAbsPartIdx );
+                if (hasScaled && hasMvPredFromL0)
+                {
+                  pAMVPInfo->m_acMvCand[firstHasScaledIdx] = cMvPredFromL0;
+                }
+              }
+            }
+
+            m_pcPrediction->getMvPredAMVP(pcSubCU, uiPartIdx, uiSubPartIdx - uiAbsPartIdx, RefPicList(refListIdx), cMv);
+            cMv += TComMv(iMvdHor, iMvdVer);
+            pcSubCU->getCUMvField(RefPicList(refListIdx))->setAllMv(cMv, ePartSize, uiSubPartIdx - uiAbsPartIdx, 0, uiPartIdx);
+          }
+        }
+      }
+      else
+#endif
       for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
       {
         RefPicList eRefList = RefPicList( uiRefListIdx );
Index: source/Lib/TLibDecoder/TDecCu.h
===================================================================
--- source/Lib/TLibDecoder/TDecCu.h	(revision 548)
+++ source/Lib/TLibDecoder/TDecCu.h	(working copy)
@@ -122,6 +122,10 @@
 
 protected:
 
+#if ER_MV_PBL
+  Void  xCopyAMVPInfo( AMVPInfo* pSrc, AMVPInfo* pDst );
+#endif
+
 #if JVET_C0024_QTBT
   Void xDecodeCU                ( TComDataCU* const pcCU, const UInt uiAbsPartIdx, const UInt uiDepth, const UInt uiWidth, const UInt uiHeight, Bool &isLastCtuOfSliceSegment, UInt uiSplitConstrain=0);
 #else
Index: source/Lib/TLibDecoder/TDecEntropy.cpp
===================================================================
--- source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 548)
+++ source/Lib/TLibDecoder/TDecEntropy.cpp	(working copy)
@@ -64,6 +64,13 @@
   m_pcEntropyDecoderIf->parseSkipFlag( pcCU, uiAbsPartIdx, uiDepth );
 }
 
+#if WIDE_ANGLE_INTRA
+Void TDecEntropy::decodeWideAngleIntraFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, ChannelType channel )
+{
+  m_pcEntropyDecoderIf->parseWideAngleIntraFlag( pcCU, uiAbsPartIdx, uiDepth, channel );
+}
+#endif
+
 #if VCEG_AZ07_IMV
 Void TDecEntropy::decodeiMVFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
 {
@@ -468,12 +475,19 @@
         if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
         {
           decodeRefFrmIdxPU( pcCU,    uiSubPartIdx,              uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) );
+#if MVD_SDH
+          decodeMvdPU      ( pcCU,    uiSubPartIdx,              uiDepth, uiPartIdx, RefPicList( uiRefListIdx ), 0 );
+#else
           decodeMvdPU      ( pcCU,    uiSubPartIdx,              uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) );
+#endif
 #if VCEG_AZ07_IMV
           bNonZeroMvd |= ( pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMvd( uiSubPartIdx ).getHor() != 0 );
           bNonZeroMvd |= ( pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMvd( uiSubPartIdx ).getVer() != 0 );
 #endif
+
+#if !MVD_SDH
           decodeMVPIdxPU   ( pcSubCU, uiSubPartIdx-uiAbsPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) );
+#endif
 #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
           if (bDebugPredEnabled)
           {
@@ -636,6 +650,27 @@
   }
 #endif
 #endif
+
+#if MVD_SDH
+  for (UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset)
+  {
+    if (!pcCU->getMergeFlag(uiSubPartIdx))
+    {
+      for (UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++)
+      {
+        if (pcCU->getSlice()->getNumRefIdx(RefPicList(uiRefListIdx)) > 0)
+        {
+          decodeMVPIdxPU(pcSubCU, uiSubPartIdx - uiAbsPartIdx, uiDepth, uiPartIdx, RefPicList(uiRefListIdx));
+
+          decodeMvdPU(pcCU, uiSubPartIdx, uiDepth, uiPartIdx, RefPicList(uiRefListIdx), 1);
+
+          deriveMvPU(pcSubCU, uiSubPartIdx - uiAbsPartIdx, uiPartIdx, RefPicList(uiRefListIdx));
+        }
+      }
+    }
+  }
+#endif
+
   return;
 }
 
@@ -696,7 +731,11 @@
  * \param eRefList
  * \returns Void
  */
-Void TDecEntropy::decodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList )
+Void TDecEntropy::decodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList
+#if MVD_SDH
+                              , UInt mode
+#endif
+)
 {
   if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
   {
@@ -703,11 +742,18 @@
 #if COM16_C1016_AFFINE
     if ( pcCU->isAffine(uiAbsPartIdx) )
     {
+#if MVD_SDH
+      if (mode == 0)
+#endif
       m_pcEntropyDecoderIf->parseAffineMvd( pcCU, uiAbsPartIdx, uiPartIdx, uiDepth, eRefList );
     }
     else
 #endif
+#if MVD_SDH
+      m_pcEntropyDecoderIf->parseMvd(pcCU, uiAbsPartIdx, uiPartIdx, uiDepth, eRefList, mode);
+#else
     m_pcEntropyDecoderIf->parseMvd( pcCU, uiAbsPartIdx, uiPartIdx, uiDepth, eRefList );
+#endif
   }
 }
 
@@ -715,15 +761,19 @@
 {
   Int iMVPIdx = -1;
 
+#if !MVD_SDH
   TComMv cZeroMv( 0, 0 );
   TComMv cMv     = cZeroMv;
   Int    iRefIdx = -1;
+#endif
 
   TComCUMvField* pcSubCUMvField = pcSubCU->getCUMvField( eRefList );
   AMVPInfo* pAMVPInfo = pcSubCUMvField->getAMVPInfo();
 
+#if !MVD_SDH
   iRefIdx = pcSubCUMvField->getRefIdx(uiPartAddr);
   cMv = cZeroMv;
+#endif
 
 #if COM16_C1016_AFFINE && !VCEG_AZ07_FRUC_MERGE
   if ( pcSubCU->isAffine(uiPartAddr) )
@@ -774,7 +824,7 @@
   {
     m_pcEntropyDecoderIf->parseMVPIdx( iMVPIdx );
   }
-#if VCEG_AZ07_FRUC_MERGE
+#if VCEG_AZ07_FRUC_MERGE || ER_MV_PBL
   pAMVPInfo->iN = 2;
 #else
   pcSubCU->fillMvpCand(uiPartIdx, uiPartAddr, eRefList, iRefIdx, pAMVPInfo);
@@ -781,6 +831,7 @@
 #endif
   pcSubCU->setMVPNumSubParts(pAMVPInfo->iN, eRefList, uiPartAddr, uiPartIdx, uiDepth);
   pcSubCU->setMVPIdxSubParts( iMVPIdx, eRefList, uiPartAddr, uiPartIdx, uiDepth );
+#if !MVD_SDH
   if ( iRefIdx >= 0 )
   {
     m_pcPrediction->getMvPredAMVP( pcSubCU, uiPartIdx, uiPartAddr, eRefList, cMv);
@@ -793,9 +844,47 @@
   PartSize ePartSize = pcSubCU->getPartitionSize( uiPartAddr );
   pcSubCU->getCUMvField( eRefList )->setAllMv(cMv, ePartSize, uiPartAddr, 0, uiPartIdx);
 #endif
+#endif
 }
 
+#if MVD_SDH
+Void TDecEntropy::deriveMvPU(TComDataCU* pcSubCU, UInt uiPartAddr, UInt uiPartIdx, RefPicList eRefList)
+{
+  // As syntax order changed when MVD SDH is enabled,
+  // thus this function is called after MVD sign is parsed
+
+  // syntax order:
+  // MVD magnitudes
+  // IMV flag
+  // MVP index
+  // MVD signs
+
+  TComMv cZeroMv(0, 0);
+  TComMv cMv = cZeroMv;
+  Int    iRefIdx = -1;
+
+  TComCUMvField* pcSubCUMvField = pcSubCU->getCUMvField(eRefList);
+  iRefIdx = pcSubCUMvField->getRefIdx(uiPartAddr);
+
+
+  if (iRefIdx >= 0)
+  {
+    m_pcPrediction->getMvPredAMVP(pcSubCU, uiPartIdx, uiPartAddr, eRefList, cMv);
+    cMv += pcSubCUMvField->getMvd(uiPartAddr);
+  }
+
 #if JVET_C0024_QTBT
+  pcSubCU->getCUMvField(eRefList)->setAllMv(cMv, SIZE_2Nx2N, uiPartAddr, 0, uiPartIdx);
+#else
+  PartSize ePartSize = pcSubCU->getPartitionSize(uiPartAddr);
+  pcSubCU->getCUMvField(eRefList)->setAllMv(cMv, ePartSize, uiPartAddr, 0, uiPartIdx);
+#endif
+
+
+}
+#endif
+
+#if JVET_C0024_QTBT
 Void TDecEntropy::xDecodeTransform        ( Bool& bCodeDQP, Bool& isChromaQpAdjCoded, TComTU &rTu, ComponentID compID)
 {
   TComDataCU *pcCU=rTu.getCU();
@@ -1872,4 +1961,4 @@
 }
 #endif
 
-//! \}
\ No newline at end of file
+//! \}
Index: source/Lib/TLibDecoder/TDecEntropy.h
===================================================================
--- source/Lib/TLibDecoder/TDecEntropy.h	(revision 548)
+++ source/Lib/TLibDecoder/TDecEntropy.h	(working copy)
@@ -89,6 +89,9 @@
 
 public:
   virtual Void parseSkipFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
+#if WIDE_ANGLE_INTRA
+  virtual Void parseWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, ChannelType channel ) = 0;
+#endif
 #if COM16_C806_OBMC
   virtual Void parseOBMCFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
 #endif
@@ -130,7 +133,11 @@
 
   virtual Void parseInterDir      ( TComDataCU* pcCU, UInt& ruiInterDir, UInt uiAbsPartIdx ) = 0;
   virtual Void parseRefFrmIdx     ( TComDataCU* pcCU, Int& riRefFrmIdx, RefPicList eRefList ) = 0;
+#if MVD_SDH
+  virtual Void parseMvd           ( TComDataCU* pcCU, UInt uiAbsPartAddr, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList, UInt mode ) = 0;
+#else
   virtual Void parseMvd           ( TComDataCU* pcCU, UInt uiAbsPartAddr, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList ) = 0;
+#endif
   virtual Void parseCrossComponentPrediction ( class TComTU &rTu, ComponentID compID ) = 0;
 
   virtual Void parseTransformSubdivFlag( UInt& ruiSubdivFlag, UInt uiLog2TransformBlockSize ) = 0;
@@ -225,9 +232,17 @@
   Void decodePUWise       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, TComDataCU* pcSubCU );
   Void decodeInterDirPU   ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx );
   Void decodeRefFrmIdxPU  ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList );
+#if MVD_SDH
+  Void decodeMvdPU        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList, UInt mode );
+#else
   Void decodeMvdPU        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList );
+#endif
   Void decodeMVPIdxPU     ( TComDataCU* pcSubCU, UInt uiPartAddr, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList );
 
+#if MVD_SDH
+  Void deriveMvPU         ( TComDataCU* pcSubCU, UInt uiPartAddr, UInt uiPartIdx, RefPicList eRefList );
+#endif
+
   Void    setEntropyDecoder           ( TDecEntropyIf* p );
   Void    setBitstream                ( TComInputBitstream* p ) { m_pcEntropyDecoderIf->setBitstream(p);                    }
 #if VCEG_AZ07_BAC_ADAPT_WDOW || VCEG_AZ07_INIT_PREVFRAME
@@ -259,6 +274,10 @@
 #endif
   Void decodeSplitFlag         ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
   Void decodeSkipFlag          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#if WIDE_ANGLE_INTRA
+  Void decodeWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, ChannelType channel );
+#endif
+
 #if VCEG_AZ05_INTRA_MPI
   Void decodeMPIIdx            ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 #endif
@@ -351,4 +370,4 @@
 
 //! \}
 
-#endif // __TDECENTROPY__
\ No newline at end of file
+#endif // __TDECENTROPY__
Index: source/Lib/TLibDecoder/TDecSbac.cpp
===================================================================
--- source/Lib/TLibDecoder/TDecSbac.cpp	(revision 548)
+++ source/Lib/TLibDecoder/TDecSbac.cpp	(working copy)
@@ -68,6 +68,9 @@
 , m_cBTSplitFlagSCModel                      ( 1,             1,                      NUM_BTSPLIT_MODE_CTX                 , m_contextModels + m_numContextModels, m_numContextModels )
 #endif
 , m_cCUSkipFlagSCModel                       ( 1,             1,                      NUM_SKIP_FLAG_CTX                    , m_contextModels + m_numContextModels, m_numContextModels)
+#if WIDE_ANGLE_INTRA
+, m_cCUWideAngleModeSCModel                  ( 1,             1,                      NUM_WIDE_ANGLE_CTX                   , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 #if VCEG_AZ05_INTRA_MPI
 , m_cMPIIdxSCModel                           ( 1,             1,                      NUM_MPI_CTX                          , m_contextModels + m_numContextModels, m_numContextModels)
 #endif
@@ -193,6 +196,9 @@
   m_cBTSplitFlagSCModel.initBuffer                ( sliceType, qp, (UChar*)INIT_BTSPLIT_MODE );
 #endif
   m_cCUSkipFlagSCModel.initBuffer                 ( sliceType, qp, (UChar*)INIT_SKIP_FLAG );
+#if WIDE_ANGLE_INTRA
+  m_cCUWideAngleModeSCModel.initBuffer            ( sliceType, qp, (UChar*)INIT_WIDE_ANGLE_MODE );
+#endif
 #if VCEG_AZ05_INTRA_MPI
   m_cMPIIdxSCModel.initBuffer                     ( sliceType, qp, (UChar*)INIT_MPIIdx_FLAG );
 #endif
@@ -565,6 +571,23 @@
   pcCU->setCUTransquantBypassSubParts(uiSymbol ? true : false, uiAbsPartIdx, uiDepth);
 }
 
+#if WIDE_ANGLE_INTRA
+Void TDecSbac::parseWideAngleIntraFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, ChannelType channel )
+{
+  UInt uiSymbol = 0;
+
+#if 1
+  UInt uiCtxNewMode = 0;
+
+  m_pcTDecBinIf->decodeBin( uiSymbol, m_cCUWideAngleModeSCModel.get( 0, 0, uiCtxNewMode ) RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__SKIP_FLAG) );
+#else
+  m_pcTDecBinIf->decodeBinEP( uiSymbol RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__SKIP_FLAG) );
+#endif
+
+  pcCU->setWideAngleModeSubParts( channel, uiSymbol, uiAbsPartIdx, uiDepth );
+}
+#endif
+
 /** parse skip flag
  * \param pcCU
  * \param uiAbsPartIdx
@@ -655,6 +678,11 @@
 #if COM16_C806_OBMC
 Void TDecSbac::parseOBMCFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
 {
+#if BORDER_FLEX_AFFINE_OBMC_OFF_FOR_AFFINE
+  if ( pcCU->getAffineFlag( uiAbsPartIdx ) )
+    return;
+#endif
+  
   pcCU->setOBMCFlagSubParts( true, uiAbsPartIdx, uiDepth );
 
   if ( !pcCU->getSlice()->getSPS()->getOBMC() || !pcCU->isOBMCFlagCoded( uiAbsPartIdx ) )
@@ -1469,6 +1497,11 @@
 #endif
     }
     pcCU->setIntraDirSubParts(CHANNEL_TYPE_LUMA, (UChar)intraPredMode, absPartIdx+partOffset*j, depth );
+
+#if WIDE_ANGLE_INTRA
+    if ( pcCU->hasWideAngleModeAvailable( absPartIdx+partOffset*j, intraPredMode ) )
+      parseWideAngleIntraFlag(pcCU, absPartIdx+partOffset*j, depth, CHANNEL_TYPE_LUMA);
+#endif
   }
 }
 
@@ -1589,6 +1622,13 @@
   }
 #endif
   pcCU->setIntraDirSubParts( CHANNEL_TYPE_CHROMA, uiSymbol, uiAbsPartIdx, uiDepth );
+ 
+#if WIDE_ANGLE_INTRA
+  if ( pcCU->hasWideAngleChromaFlag( uiAbsPartIdx, pcCU->getIntraDir( CHANNEL_TYPE_CHROMA, uiAbsPartIdx ) ) )
+    parseWideAngleIntraFlag(pcCU, uiAbsPartIdx, uiDepth, CHANNEL_TYPE_CHROMA );
+  else
+    pcCU->setWideAngleModeSubParts( CHANNEL_TYPE_CHROMA, pcCU->deriveChromaWideAngleMode( uiAbsPartIdx, uiSymbol ), uiAbsPartIdx, uiDepth );
+#endif
 }
 #else
 Void TDecSbac::parseIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
@@ -1648,6 +1688,13 @@
 #endif
   }
   pcCU->setIntraDirSubParts( CHANNEL_TYPE_CHROMA, uiSymbol, uiAbsPartIdx, uiDepth );
+
+#if WIDE_ANGLE_INTRA
+  if ( pcCU->hasWideAngleChromaFlag( uiAbsPartIdx, pcCU->getIntraDir( CHANNEL_TYPE_CHROMA, uiAbsPartIdx ) ) )
+    parseWideAngleIntraFlag(pcCU, uiAbsPartIdx, uiDepth, CHANNEL_TYPE_CHROMA );
+  else
+    pcCU->setWideAngleModeSubParts( CHANNEL_TYPE_CHROMA, pcCU->deriveChromaWideAngleMode( uiAbsPartIdx, uiSymbol ), uiAbsPartIdx, uiDepth );
+#endif
 }
 #endif
 
@@ -1724,7 +1771,11 @@
   return;
 }
 
+#if MVD_SDH
+Void TDecSbac::parseMvd(TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList, UInt mode)
+#else
 Void TDecSbac::parseMvd( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList )
+#endif
 {
   UInt uiSymbol;
   UInt uiHorAbs;
@@ -1740,6 +1791,96 @@
   }
   else
   {
+#if MVD_SDH
+    assert(mode == 0 || mode == 1);
+
+    if (mode == 0)
+    {
+      m_pcTDecBinIf->decodeBin(uiHorAbs, *pCtx RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD));
+      m_pcTDecBinIf->decodeBin(uiVerAbs, *pCtx RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD));
+
+      const Bool bHorAbsGr0 = uiHorAbs != 0;
+      const Bool bVerAbsGr0 = uiVerAbs != 0;
+      pCtx++;
+
+      if (bHorAbsGr0)
+      {
+        m_pcTDecBinIf->decodeBin(uiSymbol, *pCtx RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD));
+        uiHorAbs += uiSymbol;
+      }
+
+      if (bVerAbsGr0)
+      {
+        m_pcTDecBinIf->decodeBin(uiSymbol, *pCtx RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD));
+        uiVerAbs += uiSymbol;
+      }
+
+      if (bHorAbsGr0)
+      {
+        if (2 == uiHorAbs)
+        {
+          xReadEpExGolomb(uiSymbol, 1 RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD_EP));
+          uiHorAbs += uiSymbol;
+        }
+      }
+
+      if (bVerAbsGr0)
+      {
+        if (2 == uiVerAbs)
+        {
+          xReadEpExGolomb(uiSymbol, 1 RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD_EP));
+          uiVerAbs += uiSymbol;
+        }
+      }
+
+    }
+    else
+    {
+      // parse sign information
+      // Restore the absolute mvd value
+      TComMv cParsedMvd = pcCU->getCUMvField(eRefList)->getMvd(uiAbsPartIdx);
+
+      uiHorAbs = cParsedMvd.getHor();
+      uiVerAbs = cParsedMvd.getVer();
+
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+      uiHorAbs >>= VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+      uiVerAbs >>= VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+#endif
+
+      assert(uiHorAbs >= 0 && uiVerAbs >= 0);
+
+      if (uiHorAbs != 0)
+      {
+        if ( pcCU->getiMVFlag(uiAbsPartIdx) )
+        {
+          m_pcTDecBinIf->decodeBinEP(uiHorSign RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD_EP));
+        }
+        else
+        {
+          // Derive the sign from parsed info
+          Int iSum = uiHorAbs + uiVerAbs;
+#if USE_MVP_IDX
+          iSum += pcCU->getMVPIdx(eRefList, uiAbsPartIdx);
+#else
+          iSum += ((pcCU->getWidth(uiAbsPartIdx) + pcCU->getHeight(uiAbsPartIdx)) >> 1);
+          iSum += pcCU->getCUMvField(eRefList)->getRefIdx(uiAbsPartIdx);
+#endif
+
+          uiHorSign = (iSum & 0x1);
+        }
+      }
+
+      if (uiVerAbs != 0)
+      {
+        m_pcTDecBinIf->decodeBinEP(uiVerSign RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD_EP));
+      }
+
+
+    }
+
+#else
+
     m_pcTDecBinIf->decodeBin( uiHorAbs, *pCtx RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD) );
     m_pcTDecBinIf->decodeBin( uiVerAbs, *pCtx RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD) );
 
@@ -1781,6 +1922,8 @@
       m_pcTDecBinIf->decodeBinEP( uiVerSign RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(STATS__CABAC_BITS__MVD_EP) );
     }
 
+#endif
+
   }
 
 #if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
@@ -2929,7 +3072,7 @@
     {
       if( uiNumSig > g_iEmtSigNumThr )
       {
-        parseEmtTuIdx( pcCU, uiAbsPartIdx, rTu.GetTransformDepthTotal() ); 
+        parseEmtTuIdx( pcCU, uiAbsPartIdx, rTu.GetTransformDepthTotal() );
       }
       else
       {
@@ -3722,4 +3865,4 @@
 }
 #endif
 
-//! \}
\ No newline at end of file
+//! \}
Index: source/Lib/TLibDecoder/TDecSbac.h
===================================================================
--- source/Lib/TLibDecoder/TDecSbac.h	(revision 548)
+++ source/Lib/TLibDecoder/TDecSbac.h	(working copy)
@@ -126,6 +126,9 @@
 public:
 
   Void parseSkipFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#if WIDE_ANGLE_INTRA
+  Void parseWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, ChannelType channel );
+#endif
 #if VCEG_AZ07_IMV
   Void parseiMVFlag       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 #endif
@@ -167,7 +170,11 @@
 
   Void parseInterDir      ( TComDataCU* pcCU, UInt& ruiInterDir, UInt uiAbsPartIdx );
   Void parseRefFrmIdx     ( TComDataCU* pcCU, Int& riRefFrmIdx, RefPicList eRefList );
+#if MVD_SDH
+  Void parseMvd           ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList, UInt mode );
+#else
   Void parseMvd           ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList );
+#endif
   Void parseCrossComponentPrediction ( class TComTU &rTu, ComponentID compID );
 
   Void parseTransformSubdivFlag( UInt& ruiSubdivFlag, UInt uiLog2TransformBlockSize );
@@ -242,6 +249,9 @@
   ContextModel3DBuffer m_cBTSplitFlagSCModel;
 #endif
   ContextModel3DBuffer m_cCUSkipFlagSCModel;
+#if WIDE_ANGLE_INTRA
+  ContextModel3DBuffer m_cCUWideAngleModeSCModel;
+#endif
 #if VCEG_AZ05_INTRA_MPI
   ContextModel3DBuffer m_cMPIIdxSCModel;
 #endif
Index: source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 548)
+++ source/Lib/TLibEncoder/TEncCavlc.cpp	(working copy)
@@ -1433,6 +1433,13 @@
   assert(0);
 }
 
+#if WIDE_ANGLE_INTRA
+Void TEncCavlc::codeWideAngleIntraFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, ChannelType channel )
+{
+  assert(0);
+}
+#endif
+
 Void TEncCavlc::codeSkipFlag( TComDataCU* /*pcCU*/, UInt /*uiAbsPartIdx*/ )
 {
   assert(0);
@@ -1543,8 +1550,11 @@
 {
   assert(0);
 }
-
+#if MVD_SDH
+Void TEncCavlc::codeMvd(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList, UInt uiMode)
+#else
 Void TEncCavlc::codeMvd( TComDataCU* /*pcCU*/, UInt /*uiAbsPartIdx*/, RefPicList /*eRefList*/ )
+#endif
 {
   assert(0);
 }
@@ -1967,4 +1977,4 @@
 }
 #endif
 
-//! \}
\ No newline at end of file
+//! \}
Index: source/Lib/TLibEncoder/TEncCavlc.h
===================================================================
--- source/Lib/TLibEncoder/TEncCavlc.h	(revision 548)
+++ source/Lib/TLibEncoder/TEncCavlc.h	(working copy)
@@ -103,6 +103,9 @@
   Void codeSAOBlkParam(SAOBlkParam& /*saoBlkParam*/, const BitDepths& /*bitDepths*/, Bool* /*sliceEnabled*/, Bool /*leftMergeAvail*/, Bool /*aboveMergeAvail*/, Bool /*onlyEstMergeInfo*/ = false){printf("only supported in CABAC"); assert(0); exit(-1);}
   Void codeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void codeSkipFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx );
+#if WIDE_ANGLE_INTRA
+  Void codeWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, ChannelType channel );
+#endif
 #if VCEG_AZ05_INTRA_MPI
   Void codeMPIIdx        ( TComDataCU* pcCU, UInt uiAbsPartIdx );
 #endif
@@ -156,7 +159,11 @@
   Void codeIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void codeInterDir      ( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void codeRefFrmIdx     ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList );
+#if MVD_SDH
+  Void codeMvd(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList, UInt uiMode = 4);
+#else
   Void codeMvd           ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList );
+#endif
   Void codeCrossComponentPrediction( TComTU &rTu, ComponentID compID );
 
   Void codeDeltaQP       ( TComDataCU* pcCU, UInt uiAbsPartIdx );
Index: source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- source/Lib/TLibEncoder/TEncCu.cpp	(revision 548)
+++ source/Lib/TLibEncoder/TEncCu.cpp	(working copy)
@@ -2342,6 +2342,9 @@
 #if JVET_D0077_SAVE_LOAD_ENC_INFO
       if( saveLoadTag == SAVE_ENC_INFO )
       {
+#if WIDE_ANGLE_INTRA
+        m_pcPredSearch->setSaveLoadNewMode(uiWidthIdx, uiHeightIdx, rpcBestCU->getWideAngleMode(CHANNEL_TYPE_LUMA, 0));
+#endif
 #if COM16_C806_EMT
         m_pcPredSearch->setSaveLoadEmtFlag(uiWidthIdx, uiHeightIdx, rpcBestCU->getEmtCuFlag(0));
         m_pcPredSearch->setSaveLoadEmtIdx(uiWidthIdx, uiHeightIdx, rpcBestCU->getEmtTuIdx(0));
@@ -4879,6 +4882,18 @@
 #endif
 #endif
 
+#if MBF_DC
+  if( isLuma(rpcTempCU->getTextType()) && ucNsstIdx && !iNonZeroCoeffNonTs && rpcTempCU->getIntraDir(rpcTempCU->getTextType(), 0 ) == DC_IDX)
+  {
+    rpcTempCU->getTotalCost() = MAX_DOUBLE;
+
+    rpcTempCU->setROTIdxSubParts( rpcTempCU->getTextType(), 0, 0, uiDepth );
+    if( !rpcTempCU->getSlice()->isIntra() )
+    {
+      rpcTempCU->setROTIdxSubParts( CHANNEL_TYPE_CHROMA, 0, 0, uiDepth );
+    }
+  }
+#endif
 #if !JVET_C0024_DELTA_QP_FIX
   xCheckDQP( rpcTempCU );
 #endif
@@ -5110,6 +5125,9 @@
   pDst->iN = pSrc->iN;
   for (Int i = 0; i < pSrc->iN; i++)
   {
+#if ER_MV_PBL
+    pDst->isScaled[i] = pSrc->isScaled[i];
+#endif
     pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
   }
 }
@@ -5400,4 +5418,4 @@
   }
 }
 #endif
-//! \}
\ No newline at end of file
+//! \}
Index: source/Lib/TLibEncoder/TEncEntropy.cpp
===================================================================
--- source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 548)
+++ source/Lib/TLibEncoder/TEncEntropy.cpp	(working copy)
@@ -114,6 +114,16 @@
   return;
 }
 
+#if WIDE_ANGLE_INTRA
+Void TEncEntropy::encodeWideAngleIntraFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, ChannelType channel, Bool bRD )
+{
+  if( bRD )
+    uiAbsPartIdx = 0;
+
+  m_pcEntropyCoderIf->codeWideAngleIntraFlag( pcCU, uiAbsPartIdx, channel );
+}
+#endif
+
 Void TEncEntropy::encodeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
 {
   if ( pcCU->getSlice()->isIntra() )
@@ -790,13 +800,22 @@
         if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
         {
           encodeRefFrmIdxPU ( pcCU, uiAbsPartIdx, RefPicList( uiRefListIdx ) );
+
+#if MVD_SDH
+          encodeMvdPU       ( pcCU, uiAbsPartIdx, RefPicList(uiRefListIdx), 0 );
+#else
           encodeMvdPU       ( pcCU, uiAbsPartIdx, RefPicList( uiRefListIdx ) );
+#endif
 
 #if VCEG_AZ07_IMV
           bNonZeroMvd |= ( pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMvd( uiAbsPartIdx ).getHor() != 0 );
           bNonZeroMvd |= ( pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMvd( uiAbsPartIdx ).getVer() != 0 );
 #endif
+
+#if !MVD_SDH
           encodeMVPIdxPU    ( pcCU, uiAbsPartIdx, RefPicList( uiRefListIdx ) );
+#endif
+
 #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
           if (bDebugPred)
           {
@@ -821,6 +840,21 @@
     assert( pcCU->getiMVFlag( uiAbsPartIdx ) == 0 );
   }
 #endif
+
+#if MVD_SDH
+    if (pcCU->getMergeFlag(uiAbsPartIdx) == false)
+    {
+      for (UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++)
+      {
+        if (pcCU->getSlice()->getNumRefIdx(RefPicList(uiRefListIdx)) > 0)
+        {
+          encodeMVPIdxPU( pcCU, uiAbsPartIdx, RefPicList(uiRefListIdx) );
+          encodeMvdPU( pcCU, uiAbsPartIdx, RefPicList(uiRefListIdx), 1 );
+        }
+      }
+    }
+#endif
+
   return;
 }
 #endif
@@ -898,13 +932,22 @@
         if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
         {
           encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
+
+#if MVD_SDH
+          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList(uiRefListIdx), 0 );
+#else
           encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
+#endif
 
 #if VCEG_AZ07_IMV
           bNonZeroMvd |= ( pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMvd( uiSubPartIdx ).getHor() != 0 );
           bNonZeroMvd |= ( pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMvd( uiSubPartIdx ).getVer() != 0 );
 #endif
+
+#if !MVD_SDH
           encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
+#endif
+
 #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
           if (bDebugPred)
           {
@@ -930,6 +973,25 @@
     assert( pcCU->getiMVFlag( uiAbsPartIdx ) == 0 );
   }
 #endif
+
+
+#if MVD_SDH
+  for (UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset)
+  {
+    if (pcCU->getMergeFlag(uiSubPartIdx) == false)
+    {
+      for (UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++)
+      {
+        if (pcCU->getSlice()->getNumRefIdx(RefPicList(uiRefListIdx)) > 0)
+        {
+          encodeMVPIdxPU(pcCU, uiSubPartIdx, RefPicList(uiRefListIdx));
+          encodeMvdPU(pcCU, uiSubPartIdx, RefPicList(uiRefListIdx), 1);
+        }
+      }
+    }
+  }
+#endif
+
   return;
 }
 
@@ -964,7 +1026,11 @@
 }
 
 //! encode motion vector difference for a PU block
+#if MVD_SDH
+Void TEncEntropy::encodeMvdPU(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList, UInt uiMode)
+#else
 Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
+#endif
 {
   assert( pcCU->isInter( uiAbsPartIdx ) );
 
@@ -971,7 +1037,11 @@
 #if COM16_C1016_AFFINE
   if ( pcCU->isAffine(uiAbsPartIdx) )
   {
+#if MVD_SDH
+    if (pcCU->getInterDir(uiAbsPartIdx) & (1 << eRefList) && uiMode == 0)
+#else
     if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
+#endif
     {
       // derive LT, RT
       UInt uiPartIdxLT, uiPartIdxRT, uiAbsIndexInLCU;
@@ -987,7 +1057,11 @@
 
   if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
   {
+#if MVD_SDH
+    m_pcEntropyCoderIf->codeMvd(pcCU, uiAbsPartIdx, eRefList, uiMode);
+#else
     m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
+#endif
   }
   return;
 }
Index: source/Lib/TLibEncoder/TEncEntropy.h
===================================================================
--- source/Lib/TLibEncoder/TEncEntropy.h	(revision 548)
+++ source/Lib/TLibEncoder/TEncEntropy.h	(working copy)
@@ -101,6 +101,10 @@
 public:
   virtual Void codeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
   virtual Void codeSkipFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
+#if WIDE_ANGLE_INTRA
+  virtual Void codeWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, ChannelType channel ) = 0;
+#endif
+
 #if VCEG_AZ05_INTRA_MPI
   virtual Void codeMPIIdx        (TComDataCU* pcCU, UInt uiAbsPartIdx)   = 0;
 #endif
@@ -151,7 +155,13 @@
   virtual Void codeIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
   virtual Void codeInterDir      ( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
   virtual Void codeRefFrmIdx     ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )      = 0;
+
+#if MVD_SDH
+  virtual Void codeMvd           ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList, UInt uiMode = 4 ) = 0;
+#else
   virtual Void codeMvd           ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )      = 0;
+#endif
+
   virtual Void codeCrossComponentPrediction( TComTU &rTu, ComponentID compID ) = 0;
 
   virtual Void codeDeltaQP       ( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
@@ -262,6 +272,10 @@
 #endif
   Void encodeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
   Void encodeSkipFlag          ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
+#if WIDE_ANGLE_INTRA
+  Void encodeWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, ChannelType channel, Bool bRD = false );
+#endif
+
 #if COM16_C806_OBMC
   Void encodeOBMCFlag          ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
 #endif
@@ -277,7 +291,11 @@
   Void encodePUWise       ( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void encodeInterDirPU   ( TComDataCU* pcSubCU, UInt uiAbsPartIdx  );
   Void encodeRefFrmIdxPU  ( TComDataCU* pcSubCU, UInt uiAbsPartIdx, RefPicList eRefList );
+#if MVD_SDH
+  Void encodeMvdPU        ( TComDataCU* pcSubCU, UInt uiAbsPartIdx, RefPicList eRefList, UInt uiMode );
+#else
   Void encodeMvdPU        ( TComDataCU* pcSubCU, UInt uiAbsPartIdx, RefPicList eRefList );
+#endif
   Void encodeMVPIdxPU     ( TComDataCU* pcSubCU, UInt uiAbsPartIdx, RefPicList eRefList );
   Void encodeMergeFlag    ( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void encodeMergeIndex   ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
Index: source/Lib/TLibEncoder/TEncSbac.cpp
===================================================================
--- source/Lib/TLibEncoder/TEncSbac.cpp	(revision 548)
+++ source/Lib/TLibEncoder/TEncSbac.cpp	(working copy)
@@ -67,6 +67,9 @@
 , m_cBTSplitFlagSCModel                ( 1,             1,                      NUM_BTSPLIT_MODE_CTX                 , m_contextModels + m_numContextModels, m_numContextModels )
 #endif
 , m_cCUSkipFlagSCModel                 ( 1,             1,                      NUM_SKIP_FLAG_CTX                    , m_contextModels + m_numContextModels, m_numContextModels)
+#if WIDE_ANGLE_INTRA
+, m_cCUWideAngleModeSCModel            ( 1,             1,                      NUM_WIDE_ANGLE_CTX                   , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 #if VCEG_AZ05_INTRA_MPI
 , m_cMPIIdxSCModel                     ( 1,             1,                      NUM_MPI_CTX                          , m_contextModels + m_numContextModels, m_numContextModels)
 #endif
@@ -170,6 +173,9 @@
   m_cBTSplitFlagSCModel.initBuffer                ( eSliceType, iQp, (UChar*)INIT_BTSPLIT_MODE );
 #endif
   m_cCUSkipFlagSCModel.initBuffer                 ( eSliceType, iQp, (UChar*)INIT_SKIP_FLAG );
+#if WIDE_ANGLE_INTRA
+  m_cCUWideAngleModeSCModel.initBuffer            ( eSliceType, iQp, (UChar*)INIT_WIDE_ANGLE_MODE );
+#endif
 #if VCEG_AZ05_INTRA_MPI
   m_cMPIIdxSCModel.initBuffer                     ( eSliceType, iQp, (UChar*)INIT_MPIIdx_FLAG );
 #endif 
@@ -280,6 +286,9 @@
       curCost += m_cBTSplitFlagSCModel.calcCost                ( curSliceType, qp, (UChar*)INIT_BTSPLIT_MODE );
 #endif
       curCost += m_cCUSkipFlagSCModel.calcCost                 ( curSliceType, qp, (UChar*)INIT_SKIP_FLAG );
+#if WIDE_ANGLE_INTRA
+      curCost += m_cCUWideAngleModeSCModel.calcCost            ( curSliceType, qp, (UChar*)INIT_WIDE_ANGLE_MODE );
+#endif
 #if VCEG_AZ05_INTRA_MPI
       curCost += m_cMPIIdxSCModel.calcCost                     ( curSliceType, qp, (UChar*)INIT_MPIIdx_FLAG );
 #endif
@@ -592,6 +601,9 @@
   if (isLuma(chType))
   {
     this->m_cCUIntraPredSCModel      .copyFrom( &pSrc->m_cCUIntraPredSCModel       );
+#if WIDE_ANGLE_INTRA
+    this->m_cCUWideAngleModeSCModel  .copyFrom( &pSrc->m_cCUWideAngleModeSCModel   );
+#endif
   }
   else
   {
@@ -733,6 +745,21 @@
   m_pcBinIf->encodeBin( uiSymbol, m_CUTransquantBypassFlagSCModel.get( 0, 0, 0 ) );
 }
 
+#if WIDE_ANGLE_INTRA
+Void TEncSbac::codeWideAngleIntraFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, ChannelType channel )
+{
+  UInt uiSymbol = pcCU->getWideAngleMode ( channel, uiAbsPartIdx ) ? 1 : 0;
+
+#if 1
+  UInt uiCtxNewMode = 0;
+
+  m_pcBinIf->encodeBin( uiSymbol, m_cCUWideAngleModeSCModel.get( 0, 0, uiCtxNewMode ) );
+#else
+  m_pcBinIf->encodeBinEP( uiSymbol );
+#endif
+}
+#endif
+
 /** code skip flag
  * \param pcCU
  * \param uiAbsPartIdx
@@ -756,6 +783,11 @@
 #if COM16_C806_OBMC
 Void TEncSbac::codeOBMCFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
 {
+#if BORDER_FLEX_AFFINE_OBMC_OFF_FOR_AFFINE
+  if ( pcCU->getAffineFlag( uiAbsPartIdx ) )
+    return;
+#endif
+  
   UInt uiSymbol = pcCU->getOBMCFlag( uiAbsPartIdx ) ? 1 : 0;
 
   m_pcBinIf->encodeBin( uiSymbol, m_cCUOBMCFlagSCModel.get( 0, 0, 0 ) );
@@ -1377,6 +1409,11 @@
       m_pcBinIf->encodeBinsEP( dir[j], 5 );
 #endif
     }
+
+#if WIDE_ANGLE_INTRA
+    if ( pcCU->hasWideAngleModeAvailable( absPartIdx+partOffset*j, pcCU->getIntraDir( CHANNEL_TYPE_LUMA, absPartIdx+partOffset*j ) ) )
+      codeWideAngleIntraFlag(pcCU, absPartIdx+partOffset*j, CHANNEL_TYPE_LUMA);
+#endif
   }
   return;
 }
@@ -1568,6 +1605,12 @@
     m_pcBinIf->encodeBinsEP( uiIntraDirChroma, 2 );
   }
 #endif
+  
+#if WIDE_ANGLE_INTRA
+  if ( pcCU->hasWideAngleChromaFlag( uiAbsPartIdx, pcCU->getIntraDir( CHANNEL_TYPE_CHROMA, uiAbsPartIdx ) ) )
+    codeWideAngleIntraFlag(pcCU, uiAbsPartIdx, CHANNEL_TYPE_CHROMA);
+#endif
+
   return;
 }
 
@@ -1637,7 +1680,11 @@
   return;
 }
 
+#if MVD_SDH
+Void TEncSbac::codeMvd(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList, UInt uiMode)
+#else
 Void TEncSbac::codeMvd( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
+#endif
 {
   if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefList == REF_PIC_LIST_1 && pcCU->getInterDir(uiAbsPartIdx)==3)
   {
@@ -1678,46 +1725,152 @@
 #endif
 #endif
 
-  m_pcBinIf->encodeBin( iHor != 0 ? 1 : 0, *pCtx );
-  m_pcBinIf->encodeBin( iVer != 0 ? 1 : 0, *pCtx );
+#if MVD_SDH
+    switch (uiMode)
+    {
+    case 0:
+    {
+      // encode the magnitude information
 
-  const Bool bHorAbsGr0 = iHor != 0;
-  const Bool bVerAbsGr0 = iVer != 0;
-  const UInt uiHorAbs   = 0 > iHor ? -iHor : iHor;
-  const UInt uiVerAbs   = 0 > iVer ? -iVer : iVer;
+      m_pcBinIf->encodeBin(iHor != 0 ? 1 : 0, *pCtx);
+      m_pcBinIf->encodeBin(iVer != 0 ? 1 : 0, *pCtx);
 
-  pCtx++;
+      const Bool bHorAbsGr0 = iHor != 0;
+      const Bool bVerAbsGr0 = iVer != 0;
+      const UInt uiHorAbs = 0 > iHor ? -iHor : iHor;
+      const UInt uiVerAbs = 0 > iVer ? -iVer : iVer;
 
-  if( bHorAbsGr0 )
-  {
-    m_pcBinIf->encodeBin( uiHorAbs > 1 ? 1 : 0, *pCtx );
-  }
+      pCtx++;
 
-  if( bVerAbsGr0 )
-  {
-    m_pcBinIf->encodeBin( uiVerAbs > 1 ? 1 : 0, *pCtx );
-  }
+      if (bHorAbsGr0)
+      {
+        m_pcBinIf->encodeBin(uiHorAbs > 1 ? 1 : 0, *pCtx);
+      }
 
-  if( bHorAbsGr0 )
-  {
-    if( uiHorAbs > 1 )
+      if (bVerAbsGr0)
+      {
+        m_pcBinIf->encodeBin(uiVerAbs > 1 ? 1 : 0, *pCtx);
+      }
+
+      if (bHorAbsGr0)
+      {
+        if (uiHorAbs > 1)
+        {
+          xWriteEpExGolomb(uiHorAbs - 2, 1);
+        }
+      }
+
+      if (bVerAbsGr0)
+      {
+        if (uiVerAbs > 1)
+        {
+          xWriteEpExGolomb(uiVerAbs - 2, 1);
+        }
+      }
+
+    }
+    break;
+    case 1:
     {
-      xWriteEpExGolomb( uiHorAbs-2, 1 );
+      // encode sign information
+
+      const Bool bHorAbsGr0 = iHor != 0;
+      const Bool bVerAbsGr0 = iVer != 0;
+
+      if (bHorAbsGr0)
+      {
+        {
+#if VCEG_AZ07_IMV
+          if ( pcCU->getiMVFlag(uiAbsPartIdx) && pcCU->getSlice()->getSPS()->getIMV() )
+          {
+            m_pcBinIf->encodeBinEP(0 > iHor ? 1 : 0);
+          }
+          else
+#endif
+          {
+            Int sign = iHor >= 0 ? 0 : 1;
+
+            Int  iSum = std::abs(iHor) + std::abs(iVer);
+#if USE_MVP_IDX
+            iSum += pcCU->getMVPIdx(eRefList, uiAbsPartIdx);
+#else
+            iSum += (Int)((pcCU->getWidth(uiAbsPartIdx) + pcCU->getHeight(uiAbsPartIdx)) >> 1);
+            iSum += (Int)(pcCU->getCUMvField(eRefList)->getRefIdx(uiAbsPartIdx));
+#endif
+
+            if (sign != (iSum % 2))
+            {
+              //std::cout << " iSum = " << iSum << std::endl;
+              //std::cout << " Sign = " << sign << std::endl;
+              //std::cout << " iHor = " << iHor << std::endl;
+              //std::cout << " iVer = " << iVer << std::endl;
+              //std::cout << " iWidth = " << (Int)pcCU->getWidth(uiAbsPartIdx) << std::endl;
+              //std::cout << " iHeight = " << (Int)pcCU->getHeight(uiAbsPartIdx) << std::endl;
+              //std::cout << " CU_X = " << pcCU->getCUPelX() << std::endl;
+              //std::cout << " CU_Y = " << pcCU->getCUPelY() << std::endl;
+              //std::cout << " POC = " << pcCU->getSlice()->getPOC() << std::endl;
+
+              assert(0);
+            }
+          }
+        }
+      }
+
+      if (bVerAbsGr0)
+      {
+        m_pcBinIf->encodeBinEP(0 > iVer ? 1 : 0);
+      }
+
     }
+    break;
+    default:
+    {
+#endif
 
-    m_pcBinIf->encodeBinEP( 0 > iHor ? 1 : 0 );
-  }
+      m_pcBinIf->encodeBin(iHor != 0 ? 1 : 0, *pCtx);
+      m_pcBinIf->encodeBin(iVer != 0 ? 1 : 0, *pCtx);
 
-  if( bVerAbsGr0 )
-  {
-    if( uiVerAbs > 1 )
-    {
-      xWriteEpExGolomb( uiVerAbs-2, 1 );
+      const Bool bHorAbsGr0 = iHor != 0;
+      const Bool bVerAbsGr0 = iVer != 0;
+      const UInt uiHorAbs = 0 > iHor ? -iHor : iHor;
+      const UInt uiVerAbs = 0 > iVer ? -iVer : iVer;
+
+      pCtx++;
+
+      if (bHorAbsGr0)
+      {
+        m_pcBinIf->encodeBin(uiHorAbs > 1 ? 1 : 0, *pCtx);
+      }
+
+      if (bVerAbsGr0)
+      {
+        m_pcBinIf->encodeBin(uiVerAbs > 1 ? 1 : 0, *pCtx);
+      }
+
+      if (bHorAbsGr0)
+      {
+        if (uiHorAbs > 1)
+        {
+          xWriteEpExGolomb(uiHorAbs - 2, 1);
+        }
+
+        m_pcBinIf->encodeBinEP(0 > iHor ? 1 : 0);
+      }
+
+      if (bVerAbsGr0)
+      {
+        if (uiVerAbs > 1)
+        {
+          xWriteEpExGolomb(uiVerAbs - 2, 1);
+        }
+
+        m_pcBinIf->encodeBinEP(0 > iVer ? 1 : 0);
+      }
+#if MVD_SDH
     }
+    }
+#endif
 
-    m_pcBinIf->encodeBinEP( 0 > iVer ? 1 : 0 );
-  }
-
   return;
 }
 
@@ -2798,7 +2951,7 @@
     {
       if ( uiTuNumSig>g_iEmtSigNumThr )
       {
-        codeEmtTuIdx( pcCU, uiAbsPartIdx, rTu.GetTransformDepthTotal() ); 
+        codeEmtTuIdx( pcCU, uiAbsPartIdx, rTu.GetTransformDepthTotal() );
       }
       else
       {
@@ -3769,4 +3922,4 @@
 }
 #endif
 
-//! \}
\ No newline at end of file
+//! \}
Index: source/Lib/TLibEncoder/TEncSbac.h
===================================================================
--- source/Lib/TLibEncoder/TEncSbac.h	(revision 548)
+++ source/Lib/TLibEncoder/TEncSbac.h	(working copy)
@@ -137,6 +137,9 @@
 public:
   Void codeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void codeSkipFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx );
+#if WIDE_ANGLE_INTRA
+  Void codeWideAngleIntraFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, ChannelType channel );
+#endif
 #if VCEG_AZ05_INTRA_MPI
   Void codeMPIIdx        ( TComDataCU* pcCU, UInt uiAbsPartIdx );
 #endif
@@ -189,7 +192,12 @@
   Void codeIntraDirChroma      ( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void codeInterDir            ( TComDataCU* pcCU, UInt uiAbsPartIdx );
   Void codeRefFrmIdx           ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList );
+
+#if MVD_SDH
+  Void codeMvd                 ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList, UInt uiMode = 4 );
+#else
   Void codeMvd                 ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList );
+#endif
 
   Void codeCrossComponentPrediction( TComTU &rTu, ComponentID compID );
 
@@ -284,6 +292,9 @@
   ContextModel3DBuffer m_cBTSplitFlagSCModel;
 #endif
   ContextModel3DBuffer m_cCUSkipFlagSCModel;
+#if WIDE_ANGLE_INTRA
+  ContextModel3DBuffer m_cCUWideAngleModeSCModel;
+#endif
 #if VCEG_AZ05_INTRA_MPI
   ContextModel3DBuffer m_cMPIIdxSCModel;
 #endif
@@ -384,4 +395,4 @@
 
 //! \}
 
-#endif // !defined(AFX_TENCSBAC_H__DDA7CDC4_EDE3_4015_9D32_2156249C82AA__INCLUDED_)
\ No newline at end of file
+#endif // !defined(AFX_TENCSBAC_H__DDA7CDC4_EDE3_4015_9D32_2156249C82AA__INCLUDED_)
Index: source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- source/Lib/TLibEncoder/TEncSearch.cpp	(revision 548)
+++ source/Lib/TLibEncoder/TEncSearch.cpp	(working copy)
@@ -44,6 +44,9 @@
 #include <math.h>
 #include <limits>
 
+#if ER_MV_PBL
+#include <vector>
+#endif
 
 //! \ingroup TLibEncoder
 //! \{
@@ -348,6 +351,14 @@
       m_pLMMFPredSaved[k] = new Pel[MAX_CU_SIZE * MAX_CU_SIZE];
   }
 #endif
+
+#if PBL_PREREMOVE_HIGHFREQ
+  m_bPreRemoved = false;
+#endif
+
+#if MVD_SDH
+  m_cSearchPairs.clear();
+#endif
 }
 
 
@@ -621,6 +632,11 @@
   }
   delete[]m_pLMMFPredSaved;
 #endif
+
+#if MVD_SDH
+  m_cSearchPairs.clear();
+#endif
+
 }
 
 TEncSearch::~TEncSearch()
@@ -924,6 +940,29 @@
   }
 #endif
 
+#if PBL_PREREMOVE_HIGHFREQ
+  m_bPreRemoved = false;
+#endif
+
+#if MVD_SDH
+  m_cSearchPairs.clear();
+
+  Int precision  = 0;
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+      precision += VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+#endif
+
+  Int srcRange = std::max( (Int)1, (Int)SR_RANGE );
+
+  for (Int pairHor = -srcRange; pairHor <= srcRange; pairHor++)
+  {
+    for (Int pairVer = -srcRange; pairVer <= srcRange; pairVer++)
+    {
+      m_cSearchPairs.push_back( std::make_pair( pairHor << precision, pairVer << precision ) );
+    }
+  }
+#endif
+
   m_isInitialized = true;
 }
 
@@ -1576,6 +1615,12 @@
       continue;
     }
 #endif
+#if MVD_SDH
+    if (!pcPatternKey->getImvFlag() && ((i > 0 && iFrac == 1)))
+    {
+      continue;
+    }
+#endif
     TComMv cMvTest = pcMvRefine[i];
     cMvTest += baseRefMv;
 
@@ -1628,8 +1673,85 @@
   return uiDistBest;
 }
 
+#if ER_MV_PBL
+Distortion TEncSearch::xApplyWoAdjust ( TComYuv*    pcOrgYuv,
+                                        TComDataCU* pcCU,
+                                        UInt        uiAbsPartIdx,
+                                        TComMv      mvPred,
+                                        TComMv&     mvAdjusted,
+                                        Int         iRefListID,
+                                        Int         iRefIdx,
+                                        UInt&       iBits )
+{
+  Distortion  uiCost       = std::numeric_limits < Distortion > ::max();
+  RefPicList  eRefPicList  = RefPicList(iRefListID);
+  Int         iRoiWidth    = pcCU->getWidth(uiAbsPartIdx);
+  Int         iRoiHeight   = pcCU->getHeight(uiAbsPartIdx);
+  Double      fWeight      = 0.5;
 
+  TComPicYuv *pcPicYuvRef  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
+  TComYuv*    pcPicYuvPred = &m_acYuvPred[iRefListID];
 
+ 
+  TComYuv    *pcYuv      = &m_cYuvPredTemp;
+
+#if PBL_PREREMOVE_HIGHFREQ
+  if ( !m_bPreRemoved )
+#endif
+  {
+    TComYuv    *pcYuvOther = &m_acYuvPred[1 - iRefListID];
+    pcOrgYuv->copyPartToPartYuv( pcYuv, uiAbsPartIdx, iRoiWidth, iRoiHeight );
+    pcYuv->removeHighFreq( pcYuvOther, uiAbsPartIdx, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled() );
+  }
+
+  pcCU->clipMv ( mvAdjusted );
+
+#if VCEG_AZ06_IC
+  Bool bICFlag = pcCU->getICFlag( uiAbsPartIdx );
+#endif
+
+  xPredInterBlk( COMPONENT_Y, pcCU, pcPicYuvRef, uiAbsPartIdx, &mvAdjusted, iRoiWidth, iRoiHeight, pcPicYuvPred, false, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA)
+#if VCEG_AZ05_BIO
+                , false
+#endif
+#if VCEG_AZ07_FRUC_MERGE
+                , false
+#endif
+#if VCEG_AZ06_IC
+                , false
+#endif
+                );
+
+  // calc distortion
+  TComPattern   tmpPattern;
+  TComPattern*  pcPatternKey  = &tmpPattern;
+  pcPatternKey->m_pcCU        = pcCU;
+  pcPatternKey->m_uiPartAddr  = uiAbsPartIdx;
+  pcPatternKey->m_mvPred      = &mvPred;
+  iCostScale                  = 0;
+
+  uiCost = m_pcRdCost->getDistPart( pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA),
+                                    pcPicYuvPred->getAddr( COMPONENT_Y, uiAbsPartIdx ),
+                                    pcPicYuvPred->getStride( COMPONENT_Y ),
+                                    pcYuv->getAddr( COMPONENT_Y, uiAbsPartIdx ),
+                                    pcYuv->getStride( COMPONENT_Y ), pcCU->getWidth( uiAbsPartIdx ), pcCU->getHeight( uiAbsPartIdx ), COMPONENT_Y, DF_HADS
+#if WCG_LUMA_DQP_CM_SCALE
+                                    , 0, 0
+#endif
+#if VCEG_AZ06_IC
+                                    , bICFlag
+#endif
+                                  );
+
+  UInt       tmpMvdBits = xMvdBits( pcPatternKey, mvAdjusted.getHor(), mvAdjusted.getVer() );
+             iBits     += tmpMvdBits;
+
+  return (Distortion)( floor( fWeight * (Double)uiCost ) + (Double)m_pcRdCost->getCostSearch(iBits) );
+}
+
+#endif
+
+
 Void
 TEncSearch::xEncSubdivCbfQT(TComTU      &rTu,
                             Bool         bLuma,
@@ -5211,6 +5333,10 @@
 #endif
 #endif
 
+#if WIDE_ANGLE_INTRA
+  Int bestWideAngleMode = 0;
+#endif
+
   //===== loop over partitions =====
   TComTURecurse tuRecurseCU(pcCU, 0);
   TComTURecurse tuRecurseWithPU(tuRecurseCU, false, (uiInitTrDepth==0)?TComTU::DONT_SPLIT : TComTU::QUAD_SPLIT);
@@ -5341,11 +5467,22 @@
         }
         bSatdChecked[uiMode] = true;
 #endif        
+
         const Bool bUseFilter=TComPrediction::filteringIntraReferenceSamples(COMPONENT_Y, uiMode, puRect.width, puRect.height, chFmt, sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag()
 #if COM16_C983_RSAF_PREVENT_OVERSMOOTHING 
           , sps.getUseRSAF()
 #endif
                                                                             );
+#if WIDE_ANGLE_INTRA
+        Int wideAngleModeMax = pcCU->hasWideAngleModeAvailable ( uiPartOffset, uiMode ) ? 1 : 0;
+        
+        for( Int wideAngleMode = 0; wideAngleMode <= wideAngleModeMax; wideAngleMode++ )
+        {
+          UInt uiModeExt = uiMode + wideAngleMode*NUM_INTRA_MODE;
+          uiSad          = 0;
+          
+          pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_LUMA, wideAngleMode, uiPartOffset, uiDepth + uiInitTrDepth );
+#endif
 
         predIntraAng( COMPONENT_Y, uiMode, piOrg, uiStride, piPred, uiStride, tuRecurseWithPU, bUseFilter, TComPrediction::UseDPCMForFirstPassIntraEstimation(tuRecurseWithPU, uiMode) );
 
@@ -5367,6 +5504,10 @@
         std::cout << "1st pass mode " << uiMode << " SAD = " << uiSad << ", mode bits = " << iModeBits << ", cost = " << cost << "\n";
 #endif
 
+#if WIDE_ANGLE_INTRA
+        uiMode = uiModeExt;
+#endif
+
 #if JVET_C0024_FAST_MRG
 #if JVET_D0127_REDUNDANCY_REMOVAL
         CandNum += updateCandList(uiMode, cost, numModesForFullRD + 2, uiRdModeList, CandCostList);
@@ -5402,6 +5543,11 @@
         }
 #endif   
 #endif
+#if WIDE_ANGLE_INTRA
+        }
+
+        pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_LUMA, 0, uiPartOffset, uiDepth + uiInitTrDepth );
+#endif
       }
 #if JVET_D0127_REDUNDANCY_REMOVAL
       if (NSSTSaveFlag){
@@ -5493,6 +5639,10 @@
       for( Int modeIdx = 0; modeIdx < numModesForFullRD; modeIdx++ )
       {
         UInt uiParentMode = uiParentCandList[modeIdx];
+#if WIDE_ANGLE_INTRA
+        uiParentMode      = uiParentMode % NUM_INTRA_MODE;
+#endif
+
 #if JVET_E0077_ENHANCED_LM
         if (uiParentMode>2 && uiParentMode<(NUM_INTRA_MODE - NUM_INTRA_MODE_NON_ANG - 1))
 #else
@@ -5527,7 +5677,6 @@
                 , sps.getUseRSAF() 
 #endif
                                                                                   );
-
               predIntraAng( COMPONENT_Y, uiMode, piOrg, uiStride, piPred, uiStride, tuRecurseWithPU, bUseFilter, TComPrediction::UseDPCMForFirstPassIntraEstimation(tuRecurseWithPU, uiMode) );
 
 
@@ -5539,7 +5688,7 @@
 #if DEBUG_INTRA_SEARCH_COSTS
               std::cout << "1st pass mode for extended angular mode " << uiMode << " SAD = " << uiSad << ", mode bits = " << iModeBits << ", cost = " << cost << "\n";
 #endif
-              
+   
 #if JVET_C0024_FAST_MRG
               CandNum += updateCandList( uiMode, cost, numModesForFullRD, uiRdModeList, CandCostList );
 #else
@@ -5568,7 +5717,66 @@
         }
       }
 #endif
+        
+#if WIDE_ANGLE_INTRA && VCEG_AZ07_INTRA_65ANG_MODES
+      {
+        pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_LUMA, 1, uiPartOffset, uiDepth + uiInitTrDepth );
 
+        for( Int modeIdx = 3; modeIdx < numModesAvailable; modeIdx+= 2 )
+        {
+          UInt uiMode    = modeIdx;
+          UInt uiModeExt = uiMode + NUM_INTRA_MODE;
+          
+          if ( !pcCU->hasWideAngleModeAvailable ( uiPartOffset, uiMode ) )
+            continue;
+          
+          const Bool bUseFilter=TComPrediction::filteringIntraReferenceSamples(COMPONENT_Y, uiMode, puRect.width, puRect.height, chFmt, sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag()
+#if COM16_C983_RSAF_PREVENT_OVERSMOOTHING
+                                                                               , sps.getUseRSAF()
+#endif
+                                                                               );
+          
+          predIntraAng( COMPONENT_Y, uiMode, piOrg, uiStride, piPred, uiStride, tuRecurseWithPU, bUseFilter, TComPrediction::UseDPCMForFirstPassIntraEstimation(tuRecurseWithPU, uiMode) );
+          
+          // use hadamard transform here
+          Distortion uiSad = distParam.DistFunc(&distParam);
+          UInt   iModeBits = xModeBitsIntra( pcCU, uiMode, uiPartOffset, uiDepth, CHANNEL_TYPE_LUMA
+#if VCEG_AZ07_INTRA_65ANG_MODES
+                                            , uiPreds, iAboveLeftCase
+#endif
+                                            );
+
+          Double cost = (Double)uiSad + (Double)iModeBits * sqrtLambdaForFirstPass;
+          
+#if JVET_C0024_FAST_MRG
+          CandNum += updateCandList ( uiModeExt, cost, numModesForFullRD, uiRdModeList, CandCostList );
+#else
+          CandNum += xUpdateCandList( uiModeExt, cost, numModesForFullRD, uiRdModeList, CandCostList );
+#endif
+          
+#if JVET_C0024_PBINTRA_FAST
+          if (uiSad < CandHadList[0])
+          {
+            CandHadList[2] = CandHadList[1];
+            CandHadList[1] = CandHadList[0];
+            CandHadList[0] = uiSad;
+          }
+          else if (uiSad < CandHadList[1])
+          {
+            CandHadList[2] = CandHadList[1];
+            CandHadList[1] = uiSad;
+          }
+          else if (uiSad < CandHadList[2])
+          {
+            CandHadList[2] = uiSad;
+          }
+#endif
+        }
+        
+        pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_LUMA, 0, uiPartOffset, uiDepth + uiInitTrDepth );
+      }
+#endif
+        
       if (m_pcEncCfg->getFastUDIUseMPMEnabled())
       {
 #if !VCEG_AZ07_INTRA_65ANG_MODES
@@ -5600,7 +5808,6 @@
             }
           }
 #endif
-
           for( Int i=0; i < numModesForFullRD; i++)
           {
             mostProbableModeIncluded |= (mostProbableMode == uiRdModeList[i]);
@@ -5746,6 +5953,13 @@
       // set luma prediction mode
       UInt uiOrgMode = uiRdModeList[uiMode];
 
+#if WIDE_ANGLE_INTRA
+      Int wideAngleMode = uiOrgMode / NUM_INTRA_MODE;
+      uiOrgMode         = uiOrgMode % NUM_INTRA_MODE;
+      
+      pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_LUMA, wideAngleMode, uiPartOffset, uiDepth + uiInitTrDepth );
+#endif
+
 #if COM16_C983_RSAF 
       if (isRSAFEnabled)
 #if JVET_C0024_QTBT
@@ -5856,9 +6070,13 @@
         uiSecondBestMode  = uiBestPUMode;
         dSecondBestPUCost = dBestPUCost;
 #endif
+#if WIDE_ANGLE_INTRA
+        bestWideAngleMode = wideAngleMode;
+#endif
         uiBestPUMode  = uiOrgMode;
         uiBestPUDistY = uiPUDistY;
         dBestPUCost   = dPUCost;
+        
 #if COM16_C806_EMT
         if ( 1==ucEmtUsageFlag && m_pcEncCfg->getUseFastIntraEMT() )
         {
@@ -5948,7 +6166,10 @@
         uiOrgMode = DebugOptionList::ForceLumaMode.getInt();
       }
 #endif
-
+      
+#if WIDE_ANGLE_INTRA
+      pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_LUMA, bestWideAngleMode, uiPartOffset, uiDepth + uiInitTrDepth );
+#endif
       pcCU->setIntraDirSubParts ( CHANNEL_TYPE_LUMA, uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
       DEBUG_STRING_NEW(sModeTree)
 
@@ -6189,6 +6410,9 @@
 #endif
     //=== update PU data ====
     pcCU->setIntraDirSubParts     ( CHANNEL_TYPE_LUMA, uiBestPUMode, uiPartOffset, uiDepth + uiInitTrDepth );
+#if WIDE_ANGLE_INTRA
+    pcCU->setWideAngleModeSubParts( CHANNEL_TYPE_LUMA, bestWideAngleMode, uiPartOffset, uiDepth + uiInitTrDepth );
+#endif
   } while (tuRecurseWithPU.nextSection(tuRecurseCU));
 
 #if !JVET_C0024_QTBT
@@ -6272,6 +6496,9 @@
     UInt       uiBestMode  = 0;
     Distortion uiBestDist  = 0;
     Double     dBestCost   = MAX_DOUBLE;
+#if WIDE_ANGLE_INTRA
+    Int bestWideAngleMode  = 0;
+#endif
 
     //----- init mode list -----
     if (tuRecurseWithPU.ProcessChannelSection(CHANNEL_TYPE_CHROMA))
@@ -6522,6 +6749,18 @@
 #endif
           }
 #endif
+          
+#if WIDE_ANGLE_INTRA
+          Int wideAngleModeMin = 0;
+          Int wideAngleModeMax = 1;
+          
+          if ( !pcCU->hasWideAngleChromaFlag( uiPartOffset, uiModeList[uiMode] ) )
+            wideAngleModeMin = wideAngleModeMax = pcCU->deriveChromaWideAngleMode( uiPartOffset, uiModeList[uiMode] );
+          
+          for ( Int wideAngleMode = wideAngleModeMin; wideAngleMode <= wideAngleModeMax; wideAngleMode++ )
+          {
+            pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_CHROMA, wideAngleMode, uiPartOffset, uiDepthCU+uiInitTrDepth );
+#endif
 
           //----- restore context models -----
 #if JVET_C0024_QTBT
@@ -6561,6 +6800,9 @@
             dBestCost   = dCost;
             uiBestDist  = uiDist;
             uiBestMode  = uiModeList[uiMode];
+#if WIDE_ANGLE_INTRA
+            bestWideAngleMode = wideAngleMode;
+#endif
             xSetIntraResultChromaQT( pcRecoYuv, tuRecurseWithPU );
 #if JVET_C0024_QTBT            
             UInt uiRaster = g_auiZscanToRaster[pcCU->getZorderIdxInCtu()];
@@ -6588,6 +6830,9 @@
             }
 #endif
           }
+#if WIDE_ANGLE_INTRA
+          }
+#endif
         }
 
         DEBUG_STRING_APPEND(sDebug, sPU)
@@ -6648,6 +6893,9 @@
       }
 
       pcCU->setIntraDirSubParts( CHANNEL_TYPE_CHROMA, uiBestMode, uiPartOffset, uiDepthCU+uiInitTrDepth );
+#if WIDE_ANGLE_INTRA
+      pcCU->setWideAngleModeSubParts ( CHANNEL_TYPE_CHROMA, bestWideAngleMode, uiPartOffset, uiDepthCU+uiInitTrDepth );
+#endif
 
       pcCU->getTotalDistortion      () += uiBestDist;
     }
@@ -7101,6 +7349,10 @@
   Int          bestBiPMvpL1 = 0;
   Distortion   biPDistTemp = std::numeric_limits<Distortion>::max();
 
+#if PBL_PREREMOVE_HIGHFREQ
+  m_bPreRemoved = false;
+#endif
+
 #if !JVET_C0024_QTBT
   TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
   UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
@@ -7295,6 +7547,9 @@
 #if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
           , uiPartAddr
 #endif
+#if MVD_SDH
+          , pcOrgYuv, iPartIdx, iRefIdxTemp, false
+#endif
           );
 
         if ( iRefList == 0 )
@@ -7347,6 +7602,16 @@
       )
     {
 
+#if ER_MV_PBL
+
+      Bool bEnablePBL = pcCU->getSlice()->getMvdL1ZeroFlag() ? false : true;
+      Bool bHasL1Dist = false;
+
+      std::vector < Distortion > vDistL1;
+      std::vector < UInt >       vBitsL1;
+
+#endif
+
       cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
       iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
 
@@ -7430,6 +7695,14 @@
         {
           iRefList = 0;
         }
+
+#if ER_MV_PBL
+        if ( bEnablePBL && (iIter == iNumIter - 1) && (iRefList == 1) )
+        {
+          bHasL1Dist = true;
+        }
+#endif
+
         if ( iIter == 0 && !pcCU->getSlice()->getMvdL1ZeroFlag())
         {
           pcCU->getCUMvField(RefPicList(1-iRefList))->setAllMv( cMv[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
@@ -7484,11 +7757,23 @@
 #if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
             , uiPartAddr
 #endif
+#if MVD_SDH
+            , pcOrgYuv, iPartIdx, iRefIdxTemp, true
+#endif
             );
 
 #if JVET_E0076_MULTI_PEL_MVD
           assert ( cMvPredBi[iRefList][iRefIdxTemp] == aacAMVPInfo[iRefList][iRefIdxTemp].m_acMvCand[aaiMvpIdxBi[iRefList][iRefIdxTemp]] );
 #endif
+
+#if ER_MV_PBL
+          if ( bEnablePBL && bHasL1Dist )
+          {
+            vDistL1.push_back( uiCostTemp );
+            vBitsL1.push_back( uiBitsTemp );
+          }
+#endif
+
           if ( uiCostTemp < uiCostBi )
           {
             bChanged = true;
@@ -7525,6 +7810,9 @@
 #if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
               , uiPartAddr
 #endif
+#if MVD_SDH
+              , pcOrgYuv, iPartIdx, iRefIdxBi[0], true
+#endif
               );
             if(!pcCU->getSlice()->getMvdL1ZeroFlag())
             {
@@ -7533,6 +7821,9 @@
 #if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
                 , uiPartAddr
 #endif
+#if MVD_SDH
+                , pcOrgYuv, iPartIdx, iRefIdxBi[1], true
+#endif
                 );
             }
           }
@@ -7539,6 +7830,290 @@
           break;
         }
       } // for loop-iter
+
+#if ER_MV_PBL
+
+      Bool bPotential = false;
+
+      if ( bEnablePBL )
+      {
+        for ( Int iiList = 0; iiList < 2 && !bPotential; iiList++ )
+        {
+          RefPicList iiRefList = RefPicList( iiList );
+          Int        iiRefIdx  = pcCU->getSlice()->getNumRefIdx( iiRefList );
+
+          //assert(iiRefIdx > 0);
+
+          for (Int iiIdx = 0; iiIdx < iiRefIdx && !bPotential; iiIdx++)
+          {
+            for (Int iMvpIdx = 0; iMvpIdx < aacAMVPInfo[iiRefList][iiIdx].iN; iMvpIdx++)
+            {
+              if (aacAMVPInfo[iiRefList][ iiIdx ].isScaled[iMvpIdx] == LOW_PRIO)
+              {
+                bPotential = true; break;
+              }
+            }
+          }
+        }
+      }
+
+      {
+      if ( bEnablePBL && bPotential )
+      {
+        Bool   switchList     = false;
+        Int    m_iDefaultBiSr = m_bipredSearchRange;
+        UInt   refListTo      = 1;
+        UInt   refListFrom    = 0;
+        UInt   uiAddCostBi    = MAX_UINT;
+
+        // Initialize the FROM part
+        RefPicList eRefPicListTo   = RefPicList(refListTo);
+        RefPicList eRefPicListFrom = RefPicList(refListFrom);
+
+        pcCU->getCUMvField(eRefPicListFrom)->setAllMv(cMvBi[refListFrom], ePartSize, uiPartAddr, 0, iPartIdx);
+        pcCU->getCUMvField(eRefPicListFrom)->setAllRefIdx(iRefIdxBi[refListFrom], ePartSize, uiPartAddr, 0, iPartIdx);
+
+        TComYuv*  pcYuvPred = &m_acYuvPred[eRefPicListFrom];
+
+        if ( !bHasL1Dist )
+        {
+#if JVET_E0052_DMVR
+          motionCompensation(pcCU, pcYuvPred, true, eRefPicListFrom, iPartIdx);
+#else
+          motionCompensation(pcCU, pcYuvPred, eRefPicListFrom, iPartIdx);
+#endif
+        }
+
+#if PBL_PREREMOVE_HIGHFREQ
+        // Remove HIGH Frequency
+        {
+          assert ( m_bPreRemoved == false );
+          TComYuv    *pcYuvOther = &m_acYuvPred[ 1 - refListTo ];
+          TComYuv    *pcYuv      = &m_cYuvPredTemp;
+          pcOrgYuv->copyPartToPartYuv( pcYuv, iPartIdx, iRoiWidth, iRoiHeight );
+          pcYuv->removeHighFreq( pcYuvOther, iPartIdx, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled() );
+          m_bPreRemoved = true;
+        }
+#endif
+
+        {
+          // Search over the TO part
+          Int targetNumRefIdx = pcCU->getSlice()->getNumRefIdx(eRefPicListTo);
+
+          for (Int iRefIdxTemp = 0; iRefIdxTemp < targetNumRefIdx; iRefIdxTemp++)
+          {
+            uiBitsTemp = uiMbBits[2] + uiMotBits[refListFrom];
+            if (targetNumRefIdx > 1)
+            {
+#if JVET_D0123_ME_CTX_LUT_BITS
+              uiBitsTemp += xRefFrameIdxBits(pcCU, iRefIdxTemp, (UInt)targetNumRefIdx);
+#else
+              uiBitsTemp += iRefIdxTemp + 1;
+              if (iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList) - 1) uiBitsTemp--;
+#endif
+            }
+
+            Bool hasScaled         = false;
+            Int  firstHasScaledIdx = -1;
+
+            if ( !pcCU->xHasHighPrio (&aacAMVPInfo[refListTo][iRefIdxTemp]) )
+              pcCU->xGetFreeSlot( &aacAMVPInfo[refListTo][iRefIdxTemp], hasScaled, firstHasScaledIdx );
+
+            TComMv cMvPredFrom;
+            Bool   hasMvPredFrom = pcCU->xAddListXCand(cMvBi[refListFrom], cMvPredFrom, refListFrom, iRefIdxBi[refListFrom], iRefIdxTemp, uiPartAddr);
+            Bool   bUpdate       = false;
+
+            if (hasScaled && hasMvPredFrom)
+            {
+              aacAMVPInfo[refListTo][iRefIdxTemp].m_acMvCand[firstHasScaledIdx] = cMvPredFrom;
+              aacAMVPInfo[refListTo][iRefIdxTemp].isScaled[firstHasScaledIdx]   = UNKOWN_PRIO;
+              aaiMvpIdxBi[refListTo][iRefIdxTemp] = firstHasScaledIdx;
+              cMvPredBi[refListTo][iRefIdxTemp]   = cMvPredFrom;
+
+              m_bipredSearchRange = std::min(1, m_iDefaultBiSr);
+              bUpdate             = true;
+            }
+            else
+              m_bipredSearchRange = std::min(0, m_iDefaultBiSr);
+
+            if ( !bUpdate && bHasL1Dist )
+            {
+              xCopyAMVPInfo(&aacAMVPInfo[refListTo][iRefIdxTemp], pcCU->getCUMvField(eRefPicListTo)->getAMVPInfo());
+              uiCostTemp = vDistL1[iRefIdxTemp];
+              uiBitsTemp = vBitsL1[iRefIdxTemp];
+            }
+            else
+            {
+              uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[refListTo][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
+              {
+                if ( !bUpdate && !pcCU->getiMVFlag(uiPartAddr) )
+                  uiCostTemp = xApplyWoAdjust( pcOrgYuv, pcCU, iPartIdx, cMvPredBi[refListTo][iRefIdxTemp], cMvTemp[refListTo][iRefIdxTemp], refListTo, iRefIdxTemp, uiBitsTemp );
+                else
+                {
+                  // call ME
+#if JVET_E0076_MULTI_PEL_MVD
+                  xCopyAMVPInfo(&aacAMVPInfo[refListTo][iRefIdxTemp], pcCU->getCUMvField(eRefPicListTo)->getAMVPInfo());
+                  xMotionEstimation(pcCU, pcOrgYuv, iPartIdx, eRefPicListTo, &cMvPredBi[refListTo][iRefIdxTemp], iRefIdxTemp, cMvTemp[refListTo][iRefIdxTemp], aaiMvpIdxBi[refListTo][iRefIdxTemp], uiBitsTemp, uiCostTemp, true
+                  );
+#else
+                  xMotionEstimation(pcCU, pcOrgYuv, iPartIdx, eRefPicListTo, &cMvPredBi[refListTo][iRefIdxTemp], iRefIdxTemp, cMvTemp[refListTo][iRefIdxTemp], uiBitsTemp, uiCostTemp, true
+#if PBL_LIMIT_SR
+                    , l0NoUpdate
+#endif
+                  );
+#endif
+                }
+              }
+
+              xCopyAMVPInfo(&aacAMVPInfo[refListTo][iRefIdxTemp], pcCU->getCUMvField(eRefPicListTo)->getAMVPInfo());
+              assert(aacAMVPInfo[refListTo][iRefIdxTemp].m_acMvCand[aaiMvpIdxBi[refListTo][iRefIdxTemp]] == cMvPredBi[refListTo][iRefIdxTemp]);
+              xCheckBestMVP(pcCU, eRefPicListTo, cMvTemp[refListTo][iRefIdxTemp], cMvPredBi[refListTo][iRefIdxTemp], aaiMvpIdxBi[refListTo][iRefIdxTemp], uiBitsTemp, uiCostTemp
+#if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
+                , uiPartAddr
+#endif
+#if MVD_SDH
+                , pcOrgYuv, iPartIdx, iRefIdxTemp, true
+#endif
+              );
+            }
+
+            if (uiCostTemp < uiAddCostBi)
+            {
+              cMvBi[refListTo]     = cMvTemp[refListTo][iRefIdxTemp];
+              iRefIdxBi[refListTo] = iRefIdxTemp;
+
+              uiAddCostBi          = uiCostTemp;
+              uiMotBits[refListTo] = uiBitsTemp - uiMbBits[2] - uiMotBits[refListFrom];
+              uiBits[2]            = uiBitsTemp;
+            }
+          }
+
+          uiCostBi = uiAddCostBi;
+
+          if ( pcCU->xHasHighPrio (&aacAMVPInfo[refListTo][iRefIdxBi[refListTo]]) )
+          {
+            switchList = true;
+            assert(aacAMVPInfo[refListTo][iRefIdxBi[refListTo]].isScaled[0] != UNKOWN_PRIO && aacAMVPInfo[refListTo][iRefIdxBi[refListTo]].isScaled[1] != UNKOWN_PRIO);
+          }
+        }
+
+#if PBL_PREREMOVE_HIGHFREQ
+        m_bPreRemoved = false;
+#endif
+
+        if (switchList)
+        {
+          refListTo       = 1 - refListTo;
+          refListFrom     = 1 - refListFrom;
+          eRefPicListTo   = RefPicList( refListTo );
+          eRefPicListFrom = RefPicList( refListFrom );
+          uiAddCostBi     = MAX_UINT;
+
+
+          pcCU->getCUMvField(eRefPicListFrom)->setAllMv(cMvBi[refListFrom], ePartSize, uiPartAddr, 0, iPartIdx);
+          pcCU->getCUMvField(eRefPicListFrom)->setAllRefIdx(iRefIdxBi[refListFrom], ePartSize, uiPartAddr, 0, iPartIdx);
+          pcYuvPred = &m_acYuvPred[eRefPicListFrom];
+
+#if JVET_E0052_DMVR
+            motionCompensation(pcCU, pcYuvPred, true, eRefPicListFrom, iPartIdx);
+#else
+            motionCompensation(pcCU, pcYuvPred, eRefPicListFrom, iPartIdx);
+#endif
+
+#if PBL_PREREMOVE_HIGHFREQ
+            // Remove HIGH Frequency
+            {
+              TComYuv    *pcYuvOther = &m_acYuvPred[1 - refListTo];
+              TComYuv    *pcYuv      = &m_cYuvPredTemp;
+              pcOrgYuv->copyPartToPartYuv( pcYuv, iPartIdx, iRoiWidth, iRoiHeight );
+              pcYuv->removeHighFreq( pcYuvOther, iPartIdx, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled() );
+              m_bPreRemoved = true;
+            }
+#endif
+
+          iRefStart = 0;
+          iRefEnd = pcCU->getSlice()->getNumRefIdx(eRefPicListTo);
+
+          for (Int iRefIdxTemp = iRefStart; iRefIdxTemp < iRefEnd; iRefIdxTemp++)
+          {
+            uiBitsTemp = uiMbBits[2] + uiMotBits[refListFrom];
+            if (iRefEnd > 1)
+            {
+              uiBitsTemp += iRefIdxTemp + 1;
+              if (iRefIdxTemp == iRefEnd - 1) uiBitsTemp--;
+            }
+
+            Bool hasScaled = false;
+            Int  firstHasScaledIdx = -1;
+            pcCU->xGetFreeSlot( &aacAMVPInfo[refListTo][iRefIdxTemp], hasScaled, firstHasScaledIdx );
+
+            TComMv cMvPredFrom;
+            Bool   hasMvPredFrom = pcCU->xAddListXCand(cMvBi[refListFrom], cMvPredFrom, refListFrom, iRefIdxBi[refListFrom], iRefIdxTemp, uiPartAddr);
+            Bool   unKindSearch  = false;
+
+            if (hasScaled && hasMvPredFrom)
+            {
+              aacAMVPInfo[refListTo][iRefIdxTemp].m_acMvCand[firstHasScaledIdx] = cMvPredFrom;
+              aacAMVPInfo[refListTo][iRefIdxTemp].isScaled[firstHasScaledIdx]   = UNKOWN_PRIO;
+              aaiMvpIdxBi[refListTo][iRefIdxTemp] = firstHasScaledIdx;
+              cMvPredBi[refListTo][iRefIdxTemp]   = cMvPredFrom;
+              m_bipredSearchRange = std::min(1, m_iDefaultBiSr);
+            }
+            else
+            {
+              m_bipredSearchRange = std::min(0, m_iDefaultBiSr);
+              unKindSearch        = true;
+            }
+
+            uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[refListTo][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
+
+            if ( unKindSearch && !pcCU->getiMVFlag(uiPartAddr) )
+            {
+              uiCostTemp = xApplyWoAdjust(pcOrgYuv, pcCU, iPartIdx, cMvPredBi[refListTo][iRefIdxTemp], cMvTemp[refListTo][iRefIdxTemp], refListTo, iRefIdxTemp, uiBitsTemp);
+            }
+            else
+            {
+              // call ME
+#if JVET_E0076_MULTI_PEL_MVD
+              xCopyAMVPInfo(&aacAMVPInfo[refListTo][iRefIdxTemp], pcCU->getCUMvField(eRefPicListTo)->getAMVPInfo());
+              xMotionEstimation(pcCU, pcOrgYuv, iPartIdx, eRefPicListTo, &cMvPredBi[refListTo][iRefIdxTemp], iRefIdxTemp, cMvTemp[refListTo][iRefIdxTemp], aaiMvpIdxBi[refListTo][iRefIdxTemp], uiBitsTemp, uiCostTemp, true
+              );
+#else
+              xMotionEstimation(pcCU, pcOrgYuv, iPartIdx, eRefPicListTo, &cMvPredBi[refListTo][iRefIdxTemp], iRefIdxTemp, cMvTemp[refListTo][iRefIdxTemp], uiBitsTemp, uiCostTemp, true
+              );
+#endif
+            }
+
+            xCopyAMVPInfo(&aacAMVPInfo[refListTo][iRefIdxTemp], pcCU->getCUMvField(eRefPicListTo)->getAMVPInfo());
+            assert(aacAMVPInfo[refListTo][iRefIdxTemp].m_acMvCand[aaiMvpIdxBi[refListTo][iRefIdxTemp]] == cMvPredBi[refListTo][iRefIdxTemp]);
+              xCheckBestMVP(pcCU, eRefPicListTo, cMvTemp[refListTo][iRefIdxTemp], cMvPredBi[refListTo][iRefIdxTemp], aaiMvpIdxBi[refListTo][iRefIdxTemp], uiBitsTemp, uiCostTemp
+#if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
+                , uiPartAddr
+#endif
+#if MVD_SDH
+                , pcOrgYuv, iPartIdx, iRefIdxTemp, true
+#endif
+              );
+
+            if (uiCostTemp < uiAddCostBi)
+            {
+              cMvBi[refListTo]     = cMvTemp[refListTo][iRefIdxTemp];
+              iRefIdxBi[refListTo] = iRefIdxTemp;
+
+              uiAddCostBi          = uiCostTemp;
+              uiMotBits[refListTo] = uiBitsTemp - uiMbBits[2] - uiMotBits[refListFrom];
+              uiBits[2]            = uiBitsTemp;
+            }
+          }
+          uiCostBi = uiAddCostBi;
+        }
+
+        m_bipredSearchRange = m_iDefaultBiSr;
+
+      }
+      }
+#endif
+
     } // if (B_SLICE)
 #if COM16_C806_LARGE_CTU && !JVET_C0024_QTBT
     }
@@ -8381,6 +8956,9 @@
   pDst->iN = pSrc->iN;
   for (Int i = 0; i < pSrc->iN; i++)
   {
+#if ER_MV_PBL
+    pDst->isScaled[i] = pSrc->isScaled[i];
+#endif
     pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
   }
 }
@@ -8505,10 +9083,234 @@
 
 #endif
 
-Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, Distortion& ruiCost 
-#if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
+#if MVD_SDH
+
+Bool TEncSearch::isSdhFullfiled(TComDataCU * pcCU, Int iMvpIdx, Int iPartAddr, Int iRefIdx, TComMv& cMvd)
+{
+  Int  precision = 0;
+#if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+  precision += VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
+#endif
+
+  Int  iMvdX = (cMvd.getHor()) >> precision;
+  Int  iMvdY = (cMvd.getVer()) >> precision;
+  Int  iSignX = (iMvdX >= 0) ? 0 : 1;
+
+  Int  iSum = std::abs(iMvdX) + std::abs(iMvdY);
+#if USE_MVP_IDX
+  iSum += iMvpIdx;
+#else
+  iSum += (Int)((pcCU->getWidth(iPartAddr) + pcCU->getHeight(iPartAddr)) >> 1);
+  iSum += iRefIdx;
+#endif
+
+  if (iSignX == (iSum & 0x1))
+    return true;
+
+  return false;
+}
+
+Void TEncSearch::xSdhRefine( TComDataCU*  pcCU,
+                             RefPicList   eRefPicList,
+                             TComPattern* pcPatternKey,
+                             TComMv&      cMv,
+                             TComMv&      rcMvPred,
+                             Int&         riMVPIdx,
+                             UInt&        ruiBits,
+                             UInt&        ruiMvBits,
+                             UInt&        ruiCost,
+                             TComYuv*     pcOrgYuv,
+                             UInt         uiPartIdx,
+                             Int          iRefIdx,
+                             Bool         isBi )
+{
+  TComMv   mvUnderTest(cMv.getHor(), cMv.getVer());
+
+  Double   fWeight    = 1.0;
+
+  UInt     bestMvpIdx = riMVPIdx;
+  UInt     bestMvBits = 0;
+  TComMv   bestMv( cMv.getHor(), cMv.getVer() );
+
+  UInt     mvBits     = 0;
+  UInt     ruiErr     = std::numeric_limits<UInt>::max();
+  UInt     bestCost   = std::numeric_limits<UInt>::max();
+  UInt     currCost   = std::numeric_limits<UInt>::max();
+
+  UInt     uiPartAddr;
+  Int      iRoiWidth;
+  Int      iRoiHeight;
+
+  pcCU->getPartIndexAndSize(uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight);
+
+  // Get initial bits (without current MvpIdx MvD  bits)
+  UInt iInitBits   = ruiBits - ruiMvBits;
+
+  // Set up distortion parameters
+  DistParam cDistParam;
+  cDistParam.bApplyWeight = false;
+  cDistParam.bMRFlag      = false;
+
+  if (isBi)
+  {
+    fWeight = 0.5;
+
+    TComYuv* pcYuv = &m_cYuvPredTemp;
+
+#if SHARE_PREREMOVE
+    if (!m_bPreRemoved)
+#endif
+    {
+      TComYuv* pcYuvOther = &m_acYuvPred[1 - (Int)eRefPicList];
+      pcOrgYuv->copyPartToPartYuv(pcYuv, uiPartIdx, iRoiWidth, iRoiHeight);
+      pcYuv->removeHighFreq(pcYuvOther, uiPartIdx, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled());
+    }
+
+    m_pcRdCost->setDistParam( cDistParam,
+                              pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA),
+                              pcYuv->getAddr(COMPONENT_Y, uiPartAddr),
+                              pcYuv->getStride(COMPONENT_Y),
+                              m_tmpYuvPred.getAddr(COMPONENT_Y, uiPartAddr),
+                              m_tmpYuvPred.getStride(COMPONENT_Y),
+                              iRoiWidth, iRoiHeight, m_pcEncCfg->getUseHADME() && (pcCU->getCUTransquantBypass(uiPartIdx) == 0) );
+  }
+  else
+  {
+    m_pcRdCost->setDistParam( cDistParam,
+                              pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA),
+                              pcOrgYuv->getAddr(COMPONENT_Y, uiPartAddr),
+                              pcOrgYuv->getStride(COMPONENT_Y),
+                              m_tmpYuvPred.getAddr(COMPONENT_Y, uiPartAddr),
+                              m_tmpYuvPred.getStride(COMPONENT_Y),
+                              iRoiWidth, iRoiHeight, m_pcEncCfg->getUseHADME() && (pcCU->getCUTransquantBypass(uiPartIdx) == 0) );
+  }
+
+  // set up amvp list
+  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
+
+  Bool bPass = false;
+  std::vector< std::pair<int, int> >& cSearchPairs = m_cSearchPairs;
+
+  for (Int Iter = 0; Iter < cSearchPairs.size(); Iter++)
+  {
+    mvUnderTest.setHor( cMv.getHor() + cSearchPairs[Iter].first  );
+    mvUnderTest.setVer( cMv.getVer() + cSearchPairs[Iter].second );
+
+    TComMv cMvd0( mvUnderTest - pcAMVPInfo->m_acMvCand[0] );
+    TComMv cMvd1( mvUnderTest - pcAMVPInfo->m_acMvCand[1] );
+
+    Bool bMvp0pass = (cMvd0.getAbsHor() == 0) || isSdhFullfiled(pcCU, 0, uiPartAddr, iRefIdx, cMvd0);
+    Bool bMvp1pass = (cMvd1.getAbsHor() == 0) || isSdhFullfiled(pcCU, 1, uiPartAddr, iRefIdx, cMvd1);
+
+    if (!bMvp0pass && !bMvp1pass)
+      continue;
+    bPass = true;
+
+    xPredLumaBlk(pcCU, pcCU->getSlice()->getRefPic(eRefPicList, iRefIdx)->getPicYuvRec(), uiPartAddr, mvUnderTest, iRoiWidth, iRoiHeight, &m_tmpYuvPred, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA)
+#if VCEG_AZ06_IC
+                  , pcCU->getICFlag(uiPartAddr)
+#endif
+                  );
+
+    // calculate distortion
+    ruiErr = cDistParam.DistFunc(&cDistParam);
+
+    // cost base
+    currCost = ( (UInt)(floor)(fWeight * (Double)ruiErr) );
+
+    // calculate cost for Mvp0
+    if (bMvp0pass)
+    {
+      pcPatternKey->m_mvPred = &(pcAMVPInfo->m_acMvCand[0]);
+      mvBits = xMvdBits(pcPatternKey, mvUnderTest.getHor(), mvUnderTest.getVer()) + m_auiMVPIdxCost[0][AMVP_MAX_NUM_CANDS];
+
+      if (cMvd0.getAbsHor() != 0)
+        mvBits -= EPBIT;
+
+      UInt mvp0Cost = currCost + m_pcRdCost->getCostSearch(mvBits);
+
+      if (mvp0Cost < bestCost)
+      {
+        bestCost   = mvp0Cost;
+        bestMvpIdx = 0;
+        bestMvBits = mvBits;
+        bestMv     = mvUnderTest;
+      }
+    }
+
+    // calculate cost for Mvp1
+    if (bMvp1pass)
+    {
+      pcPatternKey->m_mvPred = &(pcAMVPInfo->m_acMvCand[1]);
+      mvBits = xMvdBits(pcPatternKey, mvUnderTest.getHor(), mvUnderTest.getVer()) + m_auiMVPIdxCost[1][AMVP_MAX_NUM_CANDS];
+
+      if (cMvd1.getAbsHor() != 0)
+        mvBits -= EPBIT;
+
+      UInt mvp1Cost = currCost + m_pcRdCost->getCostSearch(mvBits);
+
+      if (mvp1Cost < bestCost)
+      {
+        bestCost   = mvp1Cost;
+        bestMvpIdx = 1;
+        bestMvBits = mvBits;
+        bestMv     = mvUnderTest;
+      }
+    }
+  }
+
+  // This is a backup for unsuccessful sdh
+  if (!bPass)
+  {
+    // Force MV to be MVP0
+    mvUnderTest = pcAMVPInfo->m_acMvCand[0];
+    xPredInterBlk( COMPONENT_Y, pcCU, pcCU->getSlice()->getRefPic(eRefPicList, iRefIdx)->getPicYuvRec(), uiPartAddr, &mvUnderTest, iRoiWidth, iRoiHeight, &m_tmpYuvPred, false, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA), false, 0, pcCU->getICFlag(uiPartAddr) );
+    // Reassign to MVP0 to avoid changes because of clipping in xPredInterBlk()
+    mvUnderTest = pcAMVPInfo->m_acMvCand[0];
+
+    ruiErr      = cDistParam.DistFunc(&cDistParam);
+    currCost    = ((UInt)(floor)(fWeight * (Double)ruiErr));
+
+    pcPatternKey->m_mvPred = &(pcAMVPInfo->m_acMvCand[0]);
+
+    mvBits     = xMvdBits(pcPatternKey, mvUnderTest.getHor(), mvUnderTest.getVer()) + m_auiMVPIdxCost[0][AMVP_MAX_NUM_CANDS];
+    bestCost   = currCost + m_pcRdCost->getCostSearch(mvBits);
+    bestMvpIdx = 0;
+    bestMvBits = mvBits;
+    bestMv     = mvUnderTest;
+  }
+
+  Short bestMVx = bestMv.getHor();
+  Short bestMVy = bestMv.getVer();
+  cMv.set( bestMVx, bestMVy );
+
+  ruiBits   = iInitBits + bestMvBits;
+  ruiMvBits = bestMvBits;
+  ruiCost   = (Distortion)( ((Double)bestCost - (Double)m_pcRdCost->getCostSearch(bestMvBits)) + (Double)m_pcRdCost->getCostSearch(ruiBits));
+
+  rcMvPred  = pcAMVPInfo->m_acMvCand[bestMvpIdx];
+  riMVPIdx  = bestMvpIdx;
+}
+
+#endif
+
+
+Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList,
+#if MVD_SDH
+                                 TComMv&      cMv,
+#else
+                                 TComMv cMv,
+#endif
+                                 TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, Distortion& ruiCost
+#if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS || MVD_SDH
   , UInt uiPartAddr
 #endif
+#if MVD_SDH
+  , TComYuv*    pcOrgYuv
+  , UInt        uiPartIdx
+  , Int         iRefIdx
+  , Bool        isBi
+#endif
   )
 {
 
@@ -8531,7 +9333,9 @@
   m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(0) );
   m_pcRdCost->setCostScale ( 0    );
 
+#if !MVD_SDH
   Int iBestMVPIdx = riMVPIdx;
+#endif
 
   m_pcRdCost->setPredictor( rcMvPred );
 #if JVET_D0123_ME_CTX_LUT_BITS
@@ -8555,53 +9359,75 @@
     );
 #endif
   iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
-  Int iBestMvBits = iOrgMvBits;
 
-  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
+#if MVD_SDH
   {
-    if (iMVPIdx == riMVPIdx)
+    UInt iBestMvBits = iOrgMvBits;
+    xSdhRefine ( pcCU,
+                 eRefPicList,
+                 pcPatternKey,
+                 cMv,
+                 rcMvPred,
+                 riMVPIdx,
+                 ruiBits,
+                 iBestMvBits,
+                 ruiCost,
+                 pcOrgYuv,
+                 uiPartIdx,
+                 iRefIdx,
+                 isBi );
+  }
+#else
+
+    Int iBestMvBits = iOrgMvBits;
+
+    for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
     {
-      continue;
-    }
+      if (iMVPIdx == riMVPIdx)
+      {
+        continue;
+      }
 #if JVET_D0123_ME_CTX_LUT_BITS
-    pcPatternKey->m_mvPred = &pcAMVPInfo->m_acMvCand[iMVPIdx];
-    Int iMvBits = xMvdBits(pcPatternKey, cMv.getHor(), cMv.getVer());
+      pcPatternKey->m_mvPred = &pcAMVPInfo->m_acMvCand[iMVPIdx];
+      Int iMvBits = xMvdBits(pcPatternKey, cMv.getHor(), cMv.getVer());
 #else
-    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
+      m_pcRdCost->setPredictor(pcAMVPInfo->m_acMvCand[iMVPIdx]);
 
-    Int iMvBits = m_pcRdCost->getBits(
+      Int iMvBits = m_pcRdCost->getBits(
 #if VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
-      cMv.getHor() >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, cMv.getVer() >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
+        cMv.getHor() >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, cMv.getVer() >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE
 #else
-      cMv.getHor(), cMv.getVer()
+        cMv.getHor(), cMv.getVer()
 #endif
 #if VCEG_AZ07_IMV
-      , pcCU->getiMVFlag( uiPartAddr )
+        , pcCU->getiMVFlag(uiPartAddr)
 #endif
       );
 #endif
-    iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
+      iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
 
-    if (iMvBits < iBestMvBits)
-    {
-      iBestMvBits = iMvBits;
-      iBestMVPIdx = iMVPIdx;
+      if (iMvBits < iBestMvBits)
+      {
+        iBestMvBits = iMvBits;
+        iBestMVPIdx = iMVPIdx;
+      }
     }
-  }
 
-  if (iBestMVPIdx != riMVPIdx)  //if changed
-  {
-    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
+    if (iBestMVPIdx != riMVPIdx)  //if changed
+    {
+      rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
 
-    riMVPIdx = iBestMVPIdx;
-    UInt uiOrgBits = ruiBits;
-    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
+      riMVPIdx = iBestMVPIdx;
+      UInt uiOrgBits = ruiBits;
+      ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
 #if JVET_D0123_ME_CTX_LUT_BITS
-    ruiCost = (ruiCost - m_pcRdCost->getCostSearch( uiOrgBits ))  + m_pcRdCost->getCostSearch( ruiBits );
+      ruiCost = (ruiCost - m_pcRdCost->getCostSearch(uiOrgBits)) + m_pcRdCost->getCostSearch(ruiBits);
 #else
-    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
+      ruiCost = (ruiCost - m_pcRdCost->getCost(uiOrgBits)) + m_pcRdCost->getCost(ruiBits);
 #endif
-  }
+    }
+
+#endif
 }
 
 
@@ -8706,6 +9532,18 @@
 #endif
   if ( bBi )
   {
+
+#if PBL_PREREMOVE_HIGHFREQ
+    pcYuv = &m_cYuvPredTemp;
+
+    if (!m_bPreRemoved)
+    {
+      TComYuv*  pcYuvOther = &m_acYuvPred[1 - (Int)eRefPicList];
+      pcYuvOrg->copyPartToPartYuv(pcYuv, uiPartAddr, iRoiWidth, iRoiHeight);
+      pcYuv->removeHighFreq(pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled());
+    }
+
+#else
     TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
     pcYuv                = &m_cYuvPredTemp;
 
@@ -8712,6 +9550,7 @@
     pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
 
     pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled() );
+#endif
 
     fWeight = 0.5;
   }
@@ -8818,7 +9657,11 @@
 #if JVET_E0076_MULTI_PEL_MVD
   if (!intMvRefineNeeded (pcCU, iPartIdx))
   {
+#if MVD_SDH
+    xPatternSearchFracDIF( bIsLosslessCoded, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost, true );
+#else
     xPatternSearchFracDIF( bIsLosslessCoded, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
+#endif
   }
   else
   {
@@ -9434,6 +10277,9 @@
                                        TComMv&      rcMvHalf,
                                        TComMv&      rcMvQter,
                                        Distortion&  ruiCost
+#if MVD_SDH
+                                     , Bool        bSdhEnabled
+#endif
                                       )
 {
   //  Reference pattern initialization (integer scale)
@@ -9457,7 +10303,11 @@
   iCostScale = 0;
 #endif
 #if VCEG_AZ07_IMV
+#if MVD_SDH
+  if (pcPatternKey->getImvFlag() || bSdhEnabled)
+#else
   if( pcPatternKey->getImvFlag() )
+#endif
   {
     rcMvQter = TComMv( 0, 0 );
     return;
@@ -12825,4 +13675,4 @@
 }
 #endif
 
-//! \}
\ No newline at end of file
+//! \}
Index: source/Lib/TLibEncoder/TEncSearch.h
===================================================================
--- source/Lib/TLibEncoder/TEncSearch.h	(revision 548)
+++ source/Lib/TLibEncoder/TEncSearch.h	(working copy)
@@ -53,6 +53,11 @@
 #include "TLibCommon/TComBilateralFilter.h"
 #endif
 
+#if MVD_SDH
+#include <vector>
+#include <utility>
+#endif
+
 //! \ingroup TLibEncoder
 //! \{
 
@@ -162,6 +167,9 @@
 #if JVET_D0077_SAVE_LOAD_ENC_INFO
   UInt            m_SaveLoadPartIdx[MAX_CU_DEPTH-MIN_CU_LOG2+1][MAX_CU_DEPTH-MIN_CU_LOG2+1]; ///< partition index of the block for save/load encoder decision 
   UChar           m_SaveLoadTag[MAX_CU_DEPTH-MIN_CU_LOG2+1][MAX_CU_DEPTH-MIN_CU_LOG2+1];     ///< 0: not used, 1: save, 2: load
+#if WIDE_ANGLE_INTRA
+  UChar           m_SaveLoadNewMode[MAX_CU_DEPTH-MIN_CU_LOG2+1][MAX_CU_DEPTH-MIN_CU_LOG2+1]; 
+#endif
 #if COM16_C806_EMT
   UChar           m_SaveLoadEmtFlag[MAX_CU_DEPTH-MIN_CU_LOG2+1][MAX_CU_DEPTH-MIN_CU_LOG2+1]; 
   UChar           m_SaveLoadEmtIdx [MAX_CU_DEPTH-MIN_CU_LOG2+1][MAX_CU_DEPTH-MIN_CU_LOG2+1]; 
@@ -198,6 +206,14 @@
   Int             iCostScale;
 #endif
 
+#if PBL_PREREMOVE_HIGHFREQ
+  Bool m_bPreRemoved;
+#endif
+
+#if MVD_SDH
+  std::vector< std::pair<int, int> > m_cSearchPairs;
+#endif
+
 protected:
   // interface to option
   TEncCfg*        m_pcEncCfg;
@@ -274,6 +290,10 @@
 #if JVET_D0077_SAVE_LOAD_ENC_INFO
   UChar getSaveLoadTag( UInt uiPartIdx, UInt uiWIdx, UInt uiHIdx ) {  return uiPartIdx == m_SaveLoadPartIdx[uiWIdx][uiHIdx] ? m_SaveLoadTag[uiWIdx][uiHIdx] : SAVE_LOAD_INIT; };
   Void  setSaveLoadTag( UInt uiPartIdx, UInt uiWIdx, UInt uiHIdx, UChar c ) { m_SaveLoadPartIdx[uiWIdx][uiHIdx] = uiPartIdx; m_SaveLoadTag[uiWIdx][uiHIdx] = c; };
+#if WIDE_ANGLE_INTRA
+  Char  getSaveLoadNewMode( UInt uiWIdx, UInt uiHIdx ) {  return m_SaveLoadNewMode[uiWIdx][uiHIdx]; }; 
+  Void  setSaveLoadNewMode( UInt uiWIdx, UInt uiHIdx, Char c ) { m_SaveLoadNewMode[uiWIdx][uiHIdx] = c; };
+#endif
 #if COM16_C806_EMT
   UChar getSaveLoadEmtFlag( UInt uiWIdx, UInt uiHIdx ) {  return m_SaveLoadEmtFlag[uiWIdx][uiHIdx]; }; 
   Void  setSaveLoadEmtFlag( UInt uiWIdx, UInt uiHIdx, UChar c ) { m_SaveLoadEmtFlag[uiWIdx][uiHIdx] = c; };
@@ -325,6 +345,17 @@
                                   Int iFrac, TComMv& rcMvFrac, Bool bAllowUseOfHadamard
                                  );
 
+#if ER_MV_PBL
+  Distortion xApplyWoAdjust ( TComYuv*    pcOrgYuv,
+                              TComDataCU* pcCU,
+                              UInt        uiAbsPartIdx,
+                              TComMv      mvPred,
+                              TComMv&     mvAdjusted,
+                              Int         iRefListID,
+                              Int         iRefIdx,
+                              UInt&       iBits );
+#endif
+
   typedef struct
   {
     Pel*        piRefY;
@@ -573,16 +604,54 @@
 
   Void xCheckBestMVP              ( TComDataCU* pcCU,
                                     RefPicList  eRefPicList,
+#if MVD_SDH
+                                    TComMv&     cMv,
+#else
                                     TComMv      cMv,
+#endif
                                     TComMv&     rcMvPred,
                                     Int&        riMVPIdx,
                                     UInt&       ruiBits,
                                     Distortion& ruiCost 
-#if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS
+#if VCEG_AZ07_IMV || JVET_D0123_ME_CTX_LUT_BITS || MVD_SDH
                                     , UInt uiPartAddr
 #endif
+#if MVD_SDH
+                                   , TComYuv*    pcOrgYuv
+                                   , UInt        uiPartIdx
+                                   , Int         iRefIdx
+                                   , Bool        isBi
+#endif
                                     );
 
+#if MVD_SDH
+
+  Bool isMvdSdhOn ( TComDataCU* pcCU, Int iPartAddr ) {
+#if VCEG_AZ07_IMV
+                                                       return pcCU->getiMVFlag( iPartAddr )  ? false : true ;
+#else
+                                                       return true;
+#endif
+                                                      }
+
+  Bool isSdhFullfiled ( TComDataCU * pcCU, Int iMvpIdx, Int iPartAddr, Int iRefIdx, TComMv& cMvd );
+
+  Void xSdhRefine ( TComDataCU*  pcCU,
+                    RefPicList   eRefPicList,
+                    TComPattern* pcPatternKey,
+                    TComMv&      cMv,
+                    TComMv&      rcMvPred,
+                    Int&         riMVPIdx,
+                    UInt&        ruiBits,
+                    UInt&        ruiMvBits,
+                    UInt&        ruiCost,
+                    TComYuv*     pcOrgYuv,
+                    UInt         uiPartIdx,
+                    Int          iRefIdx,
+                    Bool         isBi );
+
+#endif
+
 #if JVET_E0076_MULTI_PEL_MVD
   Bool intMvRefineNeeded (TComDataCU* pcCU, Int iPartIdx) { return pcCU->getiMVFlag(iPartIdx) != 0 ? true : false; }
   Void intMvRefine ( TComDataCU* pcCU, RefPicList eRefPicList, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv& rcMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, Distortion& ruiCost, Double fWeight  );
@@ -745,6 +814,9 @@
                                     TComMv&      rcMvHalf,
                                     TComMv&      rcMvQter,
                                     Distortion&  ruiCost
+#if MVD_SDH
+                                   ,Bool         bSdhEnabled = false
+#endif
                                    );
 
   #if COM16_C1016_AFFINE
@@ -843,4 +915,4 @@
 
 //! \}
 
-#endif // __TENCSEARCH__
\ No newline at end of file
+#endif // __TENCSEARCH__
