Index: trunk/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- trunk/source/Lib/TLibCommon/TComDataCU.cpp	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComDataCU.cpp	(revision 28)
@@ -2143,4 +2143,43 @@
 #endif
 
+#if REF_IDX_ME_ZEROMV
+Bool TComDataCU::xCheckZeroMVILRMerge(UChar uhInterDir, TComMvField& cMvFieldL0, TComMvField& cMvFieldL1)
+{
+	Bool checkZeroMVILR = true;
+
+	if(uhInterDir&0x1)  //list0
+	{
+		Int refIdxL0 = cMvFieldL0.getRefIdx();
+		if(getSlice()->getRefPic(REF_PIC_LIST_0, refIdxL0)->getIsILR())
+			checkZeroMVILR &= (cMvFieldL0.getHor() == 0 && cMvFieldL0.getVer() == 0);
+	}
+	if(uhInterDir&0x2)  //list1
+	{
+		Int refIdxL1  = cMvFieldL1.getRefIdx();
+		if(getSlice()->getRefPic(REF_PIC_LIST_1, refIdxL1)->getIsILR())
+			checkZeroMVILR &= (cMvFieldL1.getHor() == 0 && cMvFieldL1.getVer() == 0);
+	}
+
+	return checkZeroMVILR;
+}
+
+Bool TComDataCU::xCheckZeroMVILRMvdL1Zero(Int iRefList, Int iRefIdx, Int MvpIdx)
+{
+	RefPicList eRefPicList = iRefList > 0? REF_PIC_LIST_1: REF_PIC_LIST_0;
+	assert(eRefPicList == REF_PIC_LIST_1);
+
+	Bool checkZeroMVILR = true;
+
+	if(getSlice()->getRefPic(eRefPicList, iRefIdx)->getIsILR())
+	{
+		AMVPInfo* pcAMVPInfo = getCUMvField(eRefPicList)->getAMVPInfo();
+		TComMv    cMv        = pcAMVPInfo->m_acMvCand[MvpIdx];
+		checkZeroMVILR &= (cMv.getHor() == 0 && cMv.getVer() == 0);
+	}
+
+	return checkZeroMVILR;
+}
+#endif
+
 UInt TComDataCU::getCtxSkipFlag( UInt uiAbsPartIdx )
 {
Index: trunk/source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- trunk/source/Lib/TLibCommon/TComDataCU.h	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComDataCU.h	(revision 28)
@@ -562,5 +562,10 @@
   UInt          getCtxIntraBLFlag               ( UInt   uiAbsPartIdx                                 );
 #endif  
-  
+
+#if REF_IDX_ME_ZEROMV
+  Bool xCheckZeroMVILRMerge(UChar uhInterDir, TComMvField& cMvFieldL0, TComMvField& cMvFieldL1);
+  Bool xCheckZeroMVILRMvdL1Zero(Int iRefList, Int iRefIdx, Int MvpIdx);
+#endif
+
   UInt          getSliceStartCU         ( UInt pos )                  { return m_uiSliceStartCU[pos-m_uiAbsIdxInLCU];                                                                                          }
   UInt          getDependentSliceStartCU  ( UInt pos )                  { return m_uiDependentSliceStartCU[pos-m_uiAbsIdxInLCU];                                                                                   }
@@ -591,4 +596,6 @@
 #endif
 };
+
+
 
 namespace RasterAddress
Index: trunk/source/Lib/TLibCommon/TComMotionInfo.h
===================================================================
--- trunk/source/Lib/TLibCommon/TComMotionInfo.h	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComMotionInfo.h	(revision 28)
@@ -158,4 +158,20 @@
   Void compress(Char* pePredMode, Int scale); 
 #endif
+
+#if REF_IDX_MFM
+  Void    setMvField( TComMvField const  & mvField, Int iIdx)
+  {
+    m_pcMv[iIdx]      = mvField.getMv();
+    m_piRefIdx[iIdx]  = mvField.getRefIdx();
+    return;
+  }
+
+  Void    setMvField( TComMv  cMv,  Int iRefIdx, Int iIdx)
+  {
+    m_pcMv[iIdx]      = cMv;
+    m_piRefIdx[iIdx]  = iRefIdx;
+    return;
+  }
+#endif
 };
 
Index: trunk/source/Lib/TLibCommon/TComPic.cpp
===================================================================
--- trunk/source/Lib/TLibCommon/TComPic.cpp	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComPic.cpp	(revision 28)
@@ -68,7 +68,8 @@
 , m_bSpatialEnhLayer( false )
 , m_pcFullPelBaseRec( NULL )
-#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE
+#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE || REF_IDX_MFM
 , m_bIsILR                                (false)
 #endif
+
 #endif
 {
@@ -554,5 +555,125 @@
     upsampledRowWidthCroma);
 }
+
+#if REF_IDX_MFM
+Void TComPic::deriveUnitIdxBase( UInt uiUpsamplePelX, UInt uiUpsamplePelY, UInt ratio, UInt& uiBaseCUAddr, UInt& uiBaseAbsPartIdx )
+{
+  //pixel in the base layer
+
+  UInt uiPelX       = (uiUpsamplePelX<<1)/ratio;
+  UInt uiPelY       = (uiUpsamplePelY<<1)/ratio;
+  UInt uiBaseWidth  = getPicYuvRec()->getWidth();
+  UInt uiBaseHeight = getPicYuvRec()->getHeight();
+
+  UInt uiWidthInCU       = ( uiBaseWidth % g_uiMaxCUWidth  ) ? uiBaseWidth /g_uiMaxCUWidth  + 1 : uiBaseWidth /g_uiMaxCUWidth;
+  UInt uiHeightInCU      = ( uiBaseHeight% g_uiMaxCUHeight ) ? uiBaseHeight/ g_uiMaxCUHeight + 1 : uiBaseHeight/ g_uiMaxCUHeight;
+
+  uiPelX     = (UInt)Clip3<UInt>(0, uiWidthInCU * g_uiMaxCUWidth - 1, uiPelX);
+  uiPelY     = (UInt)Clip3<UInt>(0, uiHeightInCU * g_uiMaxCUHeight - 1, uiPelY);
+  
+  uiBaseCUAddr = uiPelY / g_uiMaxCUHeight * uiWidthInCU + uiPelX / g_uiMaxCUWidth;
+
+  UInt uiWidthMinPU = g_uiMaxCUWidth / (1<<g_uiMaxCUDepth);
+  UInt uiHeightMinPU = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
+  
+  UInt uiAbsPelX = uiPelX - (uiPelX / g_uiMaxCUWidth) * g_uiMaxCUWidth;
+  UInt uiAbsPelY = uiPelY - (uiPelY / g_uiMaxCUHeight) * g_uiMaxCUHeight;
+
+  UInt RasterIdx = uiAbsPelY / uiHeightMinPU * (g_uiMaxCUWidth/uiWidthMinPU) + uiAbsPelX / uiWidthMinPU;
+  uiBaseAbsPartIdx = g_auiRasterToZscan[RasterIdx];
+
+  return;
+}
+
+
+
+
+Void TComPic::copyUpsampledMvField(TComPic* pcPicBase)
+{
+
+
+
+	Int iBWidth   = pcPicBase->getPicYuvRec()->getWidth () - pcPicBase->getPicYuvRec()->getPicCropLeftOffset() - pcPicBase->getPicYuvRec()->getPicCropRightOffset();
+	Int iBHeight  = pcPicBase->getPicYuvRec()->getHeight() - pcPicBase->getPicYuvRec()->getPicCropTopOffset() - pcPicBase->getPicYuvRec()->getPicCropBottomOffset();
+
+	Int iEWidth   = getPicYuvRec()->getWidth() -  getPicYuvRec()->getPicCropLeftOffset() - getPicYuvRec()->getPicCropRightOffset();
+	Int iEHeight  = getPicYuvRec()->getHeight() - getPicYuvRec()->getPicCropTopOffset() -  getPicYuvRec()->getPicCropBottomOffset();
+
+
+	UInt upSampleRatio = 0;
+	if(iEWidth == iBWidth && iEHeight == iBHeight)
+	{
+		upSampleRatio = 2;
+	}
+	else if(2*iEWidth == 3*iBWidth && 2*iEHeight == 3*iBHeight)
+	{
+		upSampleRatio = 3;
+	}
+	else if(iEWidth == 2*iBWidth && iEHeight == 2*iBHeight)
+	{
+		upSampleRatio = 4;
+	}
+	else
+	{
+		assert(0);
+	}
+
+	for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCUsInFrame(); cuIdx++)  //each LCU
+	{
+		UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
+
+		TComDataCU*             pcCUDes = getCU(cuIdx);
+
+		UInt uiWidthMinPU      = g_uiMaxCUWidth/(1<<g_uiMaxCUDepth);
+		UInt uiHeightMinPU     = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
+		Int unitNum = max (1, (Int)((16/uiWidthMinPU)*(16/uiHeightMinPU)) ); 
+
+		for(UInt uiAbsPartIdx = 0; uiAbsPartIdx < uiNumPartitions; uiAbsPartIdx+=unitNum )  //each 16x16 unit
+		{
+			//pixel position of each unit in up-sampled layer
+			UInt	uiPelX = pcCUDes->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
+			UInt	uiPelY = pcCUDes->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
+			UInt uiBaseCUAddr, uiBaseAbsPartIdx;
+     		pcPicBase->deriveUnitIdxBase(uiPelX + 8, uiPelY + 8, upSampleRatio, uiBaseCUAddr, uiBaseAbsPartIdx);
+			if( (pcPicBase->getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_NONE) && (pcPicBase->getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_INTRA) )  //base layer unit not skip and invalid mode
+			{
+				for(UInt list = 0; list < 2; list++)  //each list
+				{ 
+					TComMv cMv = pcPicBase->getCU(uiBaseCUAddr)->getCUMvField((RefPicList)list)->getMv(uiBaseAbsPartIdx);
+					Int refIdx = pcPicBase->getCU(uiBaseCUAddr)->getCUMvField((RefPicList)list)->getRefIdx(uiBaseAbsPartIdx);
+
+					Int Hor =  ((Int)upSampleRatio * cMv.getHor())/2 ;
+					Int Ver =  ((Int)upSampleRatio * cMv.getVer())/2 ;
+
+					TComMv cScaledMv(Hor, Ver);
+					TComMvField sMvField;
+					sMvField.setMvField(cScaledMv, refIdx);
+
+					pcCUDes->getCUMvField((RefPicList)list)->setMvField(sMvField, uiAbsPartIdx);
+					pcCUDes->setPredictionMode(uiAbsPartIdx, MODE_INTER);
+				}
+			}
+
+			else
+			{
+				TComMvField zeroMvField;  //zero MV and invalid reference index
+				pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, uiAbsPartIdx);
+				pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, uiAbsPartIdx);
+				pcCUDes->setPredictionMode(uiAbsPartIdx, MODE_INTRA);
+			}
+
+			for(UInt i = 1; i < unitNum; i++ )  
+			{
+				pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(pcCUDes->getCUMvField(REF_PIC_LIST_0)->getMv(uiAbsPartIdx), pcCUDes->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
+				pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(pcCUDes->getCUMvField(REF_PIC_LIST_1)->getMv(uiAbsPartIdx), pcCUDes->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
+				pcCUDes->setPredictionMode(uiAbsPartIdx+i, pcCUDes->getPredictionMode(uiAbsPartIdx))  ;
+			}
+		}
+			memset( pcCUDes->getPartitionSize(), SIZE_2Nx2N, sizeof(char)*uiNumPartitions);
+	}
+}
 #endif
 
+#endif
+
 //! \}
Index: trunk/source/Lib/TLibCommon/TComPic.h
===================================================================
--- trunk/source/Lib/TLibCommon/TComPic.h	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComPic.h	(revision 28)
@@ -88,5 +88,5 @@
   Bool                  m_bSpatialEnhLayer;       // whether current layer is a spatial enhancement layer,
   TComPicYuv*           m_pcFullPelBaseRec;    // upsampled base layer recontruction for difference domain inter prediction
-#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE
+#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE || REF_IDX_MFM
   Bool                  m_bIsILR;                 //  Is ILR picture
 #endif
@@ -118,7 +118,12 @@
   TComPicYuv*   getFullPelBaseRec   ()  { return  m_pcFullPelBaseRec;  }
 #endif
-#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE
+#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE || REF_IDX_MFM
   Void          setIsILR( Bool bIsILR)      {m_bIsILR = bIsILR;}
   Bool          getIsILR()                  {return m_bIsILR;}
+#endif
+
+#if REF_IDX_MFM
+  Void          copyUpsampledMvField  (  TComPic* pcPicBase );
+  Void          deriveUnitIdxBase     (  UInt uiUpsamplePelX, UInt uiUpsamplePelY, UInt ratio, UInt& uiBaseCUAddr, UInt& uiBaseAbsPartIdx );
 #endif
 
Index: trunk/source/Lib/TLibCommon/TComPicYuv.h
===================================================================
--- trunk/source/Lib/TLibCommon/TComPicYuv.h	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComPicYuv.h	(revision 28)
@@ -129,4 +129,7 @@
 #endif
 
+#if JCTVC_L0178
+  Void   setWidth   ( Int iPicWidth )     { m_iPicWidth = iPicWidth; }
+#endif
   Int   getStride   ()     { return (m_iPicWidth     ) + (m_iLumaMarginX  <<1); }
   Int   getCStride  ()     { return (m_iPicWidth >> 1) + (m_iChromaMarginX<<1); }
Index: trunk/source/Lib/TLibCommon/TComSlice.cpp
===================================================================
--- trunk/source/Lib/TLibCommon/TComSlice.cpp	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComSlice.cpp	(revision 28)
@@ -519,4 +519,11 @@
   if(getSPS()->getLayerId() && m_eSliceType != I_SLICE)
   {
+#if REF_IDX_MFM
+    assert(iRefPicNum == 1);
+    if( getPOC() != 0 )
+    { 
+      pIlpPicList[0]->copyUpsampledMvField(getBaseColPic());
+    }
+#endif
     //add to list 0;
     Int iOffset;
@@ -546,4 +553,49 @@
   }
 }
+
+#if REF_IDX_MFM
+Void TComSlice::setRefPOCListILP( TComPic** ilpPic, TComPic *pcRefPicBL )
+{
+  //set reference picture POC of each ILP reference 
+  Int thePoc = ilpPic[0]->getPOC(); 
+  assert(thePoc >= 0); 
+  assert(thePoc == pcRefPicBL->getPOC());
+
+  //initialize reference POC of ILP 
+  for(Int refIdx = 0; refIdx < MAX_NUM_REF; refIdx++) 
+  { 
+    ilpPic[0]->getSlice(0)->setRefPOC(0, REF_PIC_LIST_0, refIdx); 
+    ilpPic[0]->getSlice(0)->setRefPOC(0, REF_PIC_LIST_1, refIdx); 
+
+    ilpPic[0]->getSlice(0)->setRefPic(NULL, REF_PIC_LIST_0, refIdx); 
+    ilpPic[0]->getSlice(0)->setRefPic(NULL, REF_PIC_LIST_1, refIdx); 
+  }
+
+  //set reference POC of ILP 
+  ilpPic[0]->getSlice(0)->setNumRefIdx(REF_PIC_LIST_0, pcRefPicBL->getSlice(0)->getNumRefIdx(REF_PIC_LIST_0));
+  assert(ilpPic[0]->getSlice(0)->getNumRefIdx(REF_PIC_LIST_0) <= MAX_NUM_REF); 
+  ilpPic[0]->getSlice(0)->setNumRefIdx(REF_PIC_LIST_1, pcRefPicBL->getSlice(0)->getNumRefIdx(REF_PIC_LIST_1));
+  assert(ilpPic[0]->getSlice(0)->getNumRefIdx(REF_PIC_LIST_1) <= MAX_NUM_REF);
+
+  for(Int refIdx = 0; refIdx < pcRefPicBL->getSlice(0)->getNumRefIdx(REF_PIC_LIST_0); refIdx++) 
+  {
+	  ilpPic[0]->getSlice(0)->setRefPOC(pcRefPicBL->getSlice(0)->getRefPOC(REF_PIC_LIST_0, refIdx), REF_PIC_LIST_0, refIdx); 
+  }
+  for(Int refIdx = 0; refIdx < pcRefPicBL->getSlice(0)->getNumRefIdx(REF_PIC_LIST_1); refIdx++) 
+  {
+	  ilpPic[0]->getSlice(0)->setRefPOC(pcRefPicBL->getSlice(0)->getRefPOC(REF_PIC_LIST_1, refIdx), REF_PIC_LIST_1, refIdx);
+  }
+  for(Int refIdx = 0; refIdx < pcRefPicBL->getSlice(0)->getNumRefIdx(REF_PIC_LIST_0); refIdx++) 
+  {
+	  ilpPic[0]->getSlice(0)->setRefPic(pcRefPicBL->getSlice(0)->getRefPic(REF_PIC_LIST_0, refIdx), REF_PIC_LIST_0, refIdx); 
+  }
+  for(Int refIdx = 0; refIdx < pcRefPicBL->getSlice(0)->getNumRefIdx(REF_PIC_LIST_1); refIdx++) 
+  {
+	  ilpPic[0]->getSlice(0)->setRefPic(pcRefPicBL->getSlice(0)->getRefPic(REF_PIC_LIST_1, refIdx), REF_PIC_LIST_1, refIdx); 
+  }
+  return;
+}
+#endif
+
 #endif
 
Index: trunk/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- trunk/source/Lib/TLibCommon/TComSlice.h	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComSlice.h	(revision 28)
@@ -649,4 +649,7 @@
   UInt m_layerId;
 #endif
+#if REF_IDX_MFM
+  Bool m_bMFMEnabledFlag;
+#endif
 public:
   TComSPS();
@@ -837,4 +840,8 @@
   UInt     getLayerId() { return m_layerId; }
 #endif
+#if REF_IDX_MFM
+  Void     setMFMEnabledFlag(Bool flag) {m_bMFMEnabledFlag = flag;}
+  Bool     getMFMEnabledFlag()          {return m_bMFMEnabledFlag;}
+#endif
 };
 
@@ -1448,4 +1455,9 @@
   TComPicYuv* getFullPelBaseRec   ()  { return  m_pcFullPelBaseRec;  }
 #endif
+
+#if REF_IDX_MFM
+  Void      setRefPOCListILP(TComPic** ilpPic, TComPic *pcRefPicBL);
+#endif
+
   Void      setRefPicList       ( TComList<TComPic*>& rcListPic );
   Void      setRefPOCList       ();
Index: trunk/source/Lib/TLibCommon/TComUpsampleFilter.cpp
===================================================================
--- trunk/source/Lib/TLibCommon/TComUpsampleFilter.cpp	(revision 21)
+++ trunk/source/Lib/TLibCommon/TComUpsampleFilter.cpp	(revision 28)
@@ -143,5 +143,53 @@
   Int iEHeight  = pcUsPic->getHeight() - pcUsPic->getPicCropTopOffset() - pcUsPic->getPicCropBottomOffset();
   Int iEStride  = pcUsPic->getStride();
-
+  
+  Pel* piTempBufY = pcTempPic->getLumaAddr();
+  Pel* piSrcBufY  = pcBasePic->getLumaAddr();
+  Pel* piDstBufY  = pcUsPic->getLumaAddr();
+  
+  Pel* piSrcY;
+  Pel* piDstY;
+  
+  Pel* piTempBufU = pcTempPic->getCbAddr();
+  Pel* piSrcBufU  = pcBasePic->getCbAddr();
+  Pel* piDstBufU  = pcUsPic->getCbAddr();
+  
+  Pel* piTempBufV = pcTempPic->getCrAddr();
+  Pel* piSrcBufV  = pcBasePic->getCrAddr();
+  Pel* piDstBufV  = pcUsPic->getCrAddr();
+  
+  Pel* piSrcU;
+  Pel* piDstU;
+  Pel* piSrcV;
+  Pel* piDstV;
+  
+#if JCTVC_L0178
+  Pel *tempBufRight = NULL, *tempBufBottom = NULL;
+  Int tempBufSizeRight = 0, tempBufSizeBottom = 0;
+  
+  if ( pcBasePic->getPicCropRightOffset() )
+  {
+    tempBufSizeRight = pcBasePic->getPicCropRightOffset() * pcBasePic->getHeight();
+  }
+  
+  if( pcBasePic->getPicCropBottomOffset() )
+  {
+    tempBufSizeBottom = pcBasePic->getPicCropBottomOffset() * pcBasePic->getWidth ();
+  }
+  
+  if( tempBufSizeRight )
+  {
+    tempBufRight = (Pel *) xMalloc(Pel, tempBufSizeRight + (tempBufSizeRight>>1) );
+    assert( tempBufRight );
+  }
+  
+  if( tempBufSizeBottom )
+  {
+    tempBufBottom = (Pel *) xMalloc(Pel, tempBufSizeBottom + (tempBufSizeBottom>>1) );
+    assert( tempBufBottom );
+  }
+ 
+#endif
+  
 #if PHASE_DERIVATION_IN_INTEGER
   Int iRefPos16 = 0;
@@ -179,14 +227,80 @@
 #endif
 
-  Pel* piTempBufY = pcTempPic->getLumaAddr();
-  Pel* piSrcBufY  = pcBasePic->getLumaAddr();
-  Pel* piDstBufY  = pcUsPic->getLumaAddr();
-
-  Pel* piSrcY;
-  Pel* piDstY;
+
 
   assert ( iEWidth == 2*iBWidth || 2*iEWidth == 3*iBWidth );
   assert ( iEHeight == 2*iBHeight || 2*iEHeight == 3*iBHeight );
 
+#if JCTVC_L0178
+  // save the cropped region to copy back to the base picture since the base picture might be used as a reference picture
+  if( tempBufSizeRight )
+  {
+    piSrcY = piSrcBufY + iBWidth;
+    piDstY = tempBufRight;
+    for( i = 0; i < pcBasePic->getHeight(); i++ )
+    {
+      memcpy(piDstY, piSrcY, sizeof(Pel) * pcBasePic->getPicCropRightOffset());
+      piSrcY += iBStride;
+      piDstY += pcBasePic->getPicCropRightOffset();
+    }
+    
+    if(pcBasePic->getPicCropRightOffset()>>1)
+    {
+      Int iBStrideChroma = (iBStride>>1);
+      piSrcU = piSrcBufU + (iBWidth>>1);
+      piDstU = tempBufRight + pcBasePic->getPicCropRightOffset() * pcBasePic->getHeight();
+      piSrcV = piSrcBufV + (iBWidth>>1);
+      piDstV = piDstU + (pcBasePic->getPicCropRightOffset()>>1) * (pcBasePic->getHeight()>>1);
+    
+      for( i = 0; i < pcBasePic->getHeight()>>1; i++ )
+      {
+        memcpy(piDstU, piSrcU, sizeof(Pel) * (pcBasePic->getPicCropRightOffset()>>1));
+        piSrcU += iBStrideChroma;
+        piDstU += (pcBasePic->getPicCropRightOffset()>>1);
+        
+        memcpy(piDstV, piSrcV, sizeof(Pel) * (pcBasePic->getPicCropRightOffset()>>1));
+        piSrcV += iBStrideChroma;
+        piDstV += (pcBasePic->getPicCropRightOffset()>>1);
+      }
+    }
+    
+    pcBasePic->setWidth(iBWidth);
+  }
+  
+  if( tempBufSizeBottom )
+  {
+    piSrcY = piSrcBufY + iBHeight * iBStride;
+    piDstY = tempBufBottom;
+    for( i = 0; i < pcBasePic->getPicCropBottomOffset(); i++ )
+    {
+      memcpy(piDstY, piSrcY, sizeof(Pel) * pcBasePic->getWidth());
+      piSrcY += iBStride;
+      piDstY += pcBasePic->getWidth();
+    }
+    
+    if(pcBasePic->getPicCropBottomOffset()>>1)
+    {
+      Int iBStrideChroma = (iBStride>>1);
+      piSrcU = piSrcBufU + (iBHeight>>1) * iBStrideChroma;
+      piDstU = tempBufBottom + pcBasePic->getPicCropBottomOffset() * pcBasePic->getWidth();
+      piSrcV = piSrcBufV + (iBHeight>>1) * iBStrideChroma;
+      piDstV = piDstU + (pcBasePic->getPicCropBottomOffset()>>1) * (pcBasePic->getWidth()>>1);
+      
+      for( i = 0; i < pcBasePic->getPicCropBottomOffset()>>1; i++ )
+      {
+        memcpy(piDstU, piSrcU, sizeof(Pel) * (pcBasePic->getWidth()>>1));
+        piSrcU += iBStrideChroma;
+        piDstU += (pcBasePic->getWidth()>>1);
+        
+        memcpy(piDstV, piSrcV, sizeof(Pel) * (pcBasePic->getWidth()>>1));
+        piSrcV += iBStrideChroma;
+        piDstV += (pcBasePic->getWidth()>>1);
+      }
+    }
+
+    pcBasePic->setHeight(iBHeight);
+  }
+#endif
+  
   pcBasePic->setBorderExtension(false);
   pcBasePic->extendPicBorder   (); // extend the border.
@@ -278,16 +392,4 @@
 
   //========== UV component upsampling ===========
-  Pel* piTempBufU = pcTempPic->getCbAddr();
-  Pel* piSrcBufU  = pcBasePic->getCbAddr();
-  Pel* piDstBufU  = pcUsPic->getCbAddr();
-
-  Pel* piTempBufV = pcTempPic->getCrAddr();
-  Pel* piSrcBufV  = pcBasePic->getCrAddr();
-  Pel* piDstBufV  = pcUsPic->getCrAddr();
-
-  Pel* piSrcU;
-  Pel* piDstU;
-  Pel* piSrcV;
-  Pel* piDstV;
 
   iEWidth  >>= 1;
@@ -405,4 +507,97 @@
   pcTempPic->setBorderExtension(false);
   pcBasePic->setBorderExtension(false);
+  
+#if JCTVC_L0178
+  // copy back the saved cropped region
+  if( tempBufSizeRight )
+  {
+    // put the correct width back
+    pcBasePic->setWidth(pcBasePic->getWidth()+pcBasePic->getPicCropRightOffset());
+  }
+  if( tempBufSizeBottom )
+  {
+    pcBasePic->setHeight(pcBasePic->getHeight()+pcBasePic->getPicCropBottomOffset());
+  }
+  
+  iBWidth   = pcBasePic->getWidth () - pcBasePic->getPicCropLeftOffset() - pcBasePic->getPicCropRightOffset();
+  iBHeight  = pcBasePic->getHeight() - pcBasePic->getPicCropTopOffset() - pcBasePic->getPicCropBottomOffset();
+  
+  iBStride  = pcBasePic->getStride();
+  
+  if( tempBufSizeRight )
+  {
+    piSrcY = tempBufRight;
+    piDstY = piSrcBufY + iBWidth;
+    
+    for( i = 0; i < pcBasePic->getHeight(); i++ )
+    {
+      memcpy(piDstY, piSrcY, sizeof(Pel) * pcBasePic->getPicCropRightOffset());
+      piSrcY += pcBasePic->getPicCropRightOffset();
+      piDstY += iBStride;
+    }
+    
+    if(pcBasePic->getPicCropRightOffset()>>1)
+    {
+      Int iBStrideChroma = (iBStride>>1);
+      piSrcU = tempBufRight + pcBasePic->getPicCropRightOffset() * pcBasePic->getHeight();
+      piDstU = piSrcBufU + (iBWidth>>1);
+      piSrcV = piSrcU + (pcBasePic->getPicCropRightOffset()>>1) * (pcBasePic->getHeight()>>1);
+      piDstV = piSrcBufV + (iBWidth>>1);
+
+      for( i = 0; i < pcBasePic->getHeight()>>1; i++ )
+      {
+        memcpy(piDstU, piSrcU, sizeof(Pel) * (pcBasePic->getPicCropRightOffset()>>1));
+        piSrcU += (pcBasePic->getPicCropRightOffset()>>1);
+        piDstU += iBStrideChroma;
+        
+        memcpy(piDstV, piSrcV, sizeof(Pel) * (pcBasePic->getPicCropRightOffset()>>1));
+        piSrcV += (pcBasePic->getPicCropRightOffset()>>1);
+        piDstV += iBStrideChroma;
+      }
+    }
+  }
+  
+  if( tempBufSizeBottom )
+  {
+    piDstY = piSrcBufY + iBHeight * iBStride;
+    piSrcY = tempBufBottom;
+    for( i = 0; i < pcBasePic->getPicCropBottomOffset(); i++ )
+    {
+      memcpy(piDstY, piSrcY, sizeof(Pel) * pcBasePic->getWidth());
+      piDstY += iBStride;
+      piSrcY += pcBasePic->getWidth();
+    }
+    
+    if(pcBasePic->getPicCropBottomOffset()>>1)
+    {
+      Int iBStrideChroma = (iBStride>>1);
+      piSrcU = tempBufBottom + pcBasePic->getPicCropBottomOffset() * pcBasePic->getWidth();
+      piDstU = piSrcBufU + (iBHeight>>1) * iBStrideChroma;
+      piSrcV = piSrcU + (pcBasePic->getPicCropBottomOffset()>>1) * (pcBasePic->getWidth()>>1);
+      piDstV = piSrcBufV + (iBHeight>>1) * iBStrideChroma;
+            
+      for( i = 0; i < pcBasePic->getPicCropBottomOffset()>>1; i++ )
+      {
+        memcpy(piDstU, piSrcU, sizeof(Pel) * (pcBasePic->getWidth()>>1));
+        piSrcU += (pcBasePic->getWidth()>>1);
+        piDstU += iBStrideChroma;
+        
+        memcpy(piDstV, piSrcV, sizeof(Pel) * (pcBasePic->getWidth()>>1));
+        piSrcV += (pcBasePic->getWidth()>>1);
+        piDstV += iBStrideChroma;
+      }
+    }
+  
+  }
+
+  if( tempBufSizeRight )
+  {
+    xFree( tempBufRight );
+  }
+  if( tempBufSizeBottom )
+  {
+    xFree( tempBufBottom );
+  }
+#endif
 }
 #endif //SVC_EXTENSION
Index: trunk/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- trunk/source/Lib/TLibCommon/TypeDef.h	(revision 21)
+++ trunk/source/Lib/TLibCommon/TypeDef.h	(revision 28)
@@ -60,4 +60,5 @@
 #define REF_IDX_ME_ZEROMV                1      ///< L0051: use zero motion for inter-layer reference picture (without fractional ME)
 #define ENCODER_FAST_MODE                1      ///< L0174: enable encoder fast mode. TestMethod 1 is enabled by setting to 1 and TestMethod 2 is enable by setting to 2. By default it is set to 1.
+#define REF_IDX_MFM                      1      ///< L0336: motion vector mapping of inter-layer reference picture
 #else
 #define INTRA_BL                         1      ///< inter-layer texture prediction
@@ -72,4 +73,8 @@
 #define SVC_BL_CAND_INTRA                0      ///< Intra Base Mode Prediction hook as an example 
 #endif
+#endif
+
+#if SVC_UPSAMPLING
+#define JCTVC_L0178                      1      ///< implementation of JCTVC-L0178 (code only supports right and bottom croppping offsets)
 #endif
 
Index: trunk/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- trunk/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 21)
+++ trunk/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 28)
@@ -844,4 +844,12 @@
 #endif
   READ_FLAG( uiCode, "sps_temporal_mvp_enable_flag" );            pcSPS->setTMVPFlagsPresent(uiCode);
+#if REF_IDX_MFM
+  if(pcSPS->getLayerId() > 0)
+  {
+	  READ_FLAG( uiCode, "sps_enh_mfm_enable_flag" );
+	  pcSPS->setMFMEnabledFlag( uiCode ? true : false );
+	  assert(pcSPS->getMFMEnabledFlag()); 
+  }
+#endif
 #if SUPPORT_FOR_VUI
   READ_FLAG( uiCode, "vui_parameters_present_flag" );             pcSPS->setVuiParametersPresentFlag(uiCode);
Index: trunk/source/Lib/TLibDecoder/TDecGop.cpp
===================================================================
--- trunk/source/Lib/TLibDecoder/TDecGop.cpp	(revision 21)
+++ trunk/source/Lib/TLibDecoder/TDecGop.cpp	(revision 28)
@@ -287,4 +287,6 @@
 
   rpcPic->compressMotion(); 
+
+
   Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
   if (!pcSlice->isReferenced()) c += 32;
Index: trunk/source/Lib/TLibDecoder/TDecTop.cpp
===================================================================
--- trunk/source/Lib/TLibDecoder/TDecTop.cpp	(revision 21)
+++ trunk/source/Lib/TLibDecoder/TDecTop.cpp	(revision 28)
@@ -164,5 +164,5 @@
         m_cIlpPic[j]->create(pcSPS->getPicWidthInLumaSamples(), pcSPS->getPicHeightInLumaSamples(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, true);
 #endif
-#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV
+#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || REF_IDX_MFM
         m_cIlpPic[j]->setIsILR(true);
 #endif
@@ -270,4 +270,6 @@
     rpcPic->getPicSym()->allocSaoParam(&m_cSAO);
 #endif
+
+
     m_cListPic.pushBack( rpcPic );
     
@@ -316,4 +318,6 @@
   rpcPic->getPicSym()->allocSaoParam(&m_cSAO);
 #endif
+
+
 }
 
@@ -768,4 +772,8 @@
     {
       setILRPic(pcPic);
+#if REF_IDX_MFM
+      pcSlice->setRefPOCListILP(m_ppcTDecTop[m_layerId]->m_cIlpPic, pcSlice->getBaseColPic());
+#endif
+
       pcSlice->addRefPicList ( m_cIlpPic, 
                                1, 
@@ -880,4 +888,8 @@
   m_cEntropyDecoder.decodeSPS( sps );
   m_parameterSetManagerDecoder.storePrefetchedSPS(sps);
+#if REF_IDX_MFM
+  m_pcSPS = sps;
+  setMFMEnabledFlag(sps->getMFMEnabledFlag());
+#endif
 #if !REMOVE_ALF
   m_cAdaptiveLoopFilter.create( sps->getPicWidthInLumaSamples(), sps->getPicHeightInLumaSamples(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
Index: trunk/source/Lib/TLibDecoder/TDecTop.h
===================================================================
--- trunk/source/Lib/TLibDecoder/TDecTop.h	(revision 21)
+++ trunk/source/Lib/TLibDecoder/TDecTop.h	(revision 28)
@@ -80,4 +80,10 @@
   ParameterSetManagerDecoder m_parameterSetManagerDecoder;  // storage for parameter sets 
 #endif
+
+#if REF_IDX_MFM
+  TComSPS*               m_pcSPS;
+  Bool                   m_bMFMEnabledFlag;
+#endif
+
   TComSlice*              m_apcSlicePilot;
   
@@ -170,4 +176,10 @@
   Void      setILRPic(TComPic *pcPic);
 #endif
+#if REF_IDX_MFM
+  TComSPS*  getSPS()                       {return m_pcSPS;}
+  Void      setMFMEnabledFlag(Bool flag)   {m_bMFMEnabledFlag = flag;}
+  Bool      getMFMEnabledFlag()            {return m_bMFMEnabledFlag;}
+#endif
+
 protected:
   Void  xGetNewPicBuffer  (TComSlice* pcSlice, TComPic*& rpcPic);
Index: trunk/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 21)
+++ trunk/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 28)
@@ -600,4 +600,11 @@
 #endif
   WRITE_FLAG( pcSPS->getTMVPFlagsPresent()  ? 1 : 0,           "sps_temporal_mvp_enable_flag" );
+#if REF_IDX_MFM
+  if( pcSPS->getLayerId() > 0 )
+  {
+	  assert(pcSPS->getMFMEnabledFlag());
+	  WRITE_FLAG( pcSPS->getMFMEnabledFlag() ? 1 : 0,          "sps_enh_mfm_enable_flag" );
+  }
+#endif
 #if SUPPORT_FOR_VUI
   WRITE_FLAG( pcSPS->getVuiParametersPresentFlag(),             "vui_parameters_present_flag" );
Index: trunk/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncCu.cpp	(revision 21)
+++ trunk/source/Lib/TLibEncoder/TEncCu.cpp	(revision 28)
@@ -1351,4 +1351,9 @@
     for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
     {
+#if REF_IDX_ME_ZEROMV
+		Bool bZeroMVILR = rpcTempCU->xCheckZeroMVILRMerge(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]);
+		if(bZeroMVILR)
+		{
+#endif
         if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))
         {
@@ -1402,4 +1407,7 @@
     }
     }
+#if REF_IDX_ME_ZEROMV 
+	}
+#endif
    }
 
Index: trunk/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 21)
+++ trunk/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 28)
@@ -465,4 +465,9 @@
 #endif 
 
+#if REF_IDX_FRAMEWORK
+    if (pcSlice->getSliceType() == B_SLICE) 
+      pcSlice->setColFromL0Flag(1-uiColDir);
+#endif
+
     //  Set reference list
     pcSlice->setRefPicList ( rcListPic );
@@ -471,5 +476,44 @@
     {
       m_pcEncTop->setILRPic(pcPic);
+
+#if REF_IDX_MFM
+      pcSlice->setRefPOCListILP(m_pcEncTop->getIlpList(), pcSlice->getBaseColPic());
+#endif
       pcSlice->addRefPicList ( m_pcEncTop->getIlpList(), 1);
+
+#if REF_IDX_MFM
+      Bool found         = false;
+      UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
+      UInt ColRefIdx     = pcSlice->getColRefIdx();
+      for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
+      { 
+        if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->getIsILR() ) 
+        { 
+          ColRefIdx = colIdx; 
+          found = true;
+          break; 
+        }
+      }
+
+      if( found == false )
+      {
+        ColFromL0Flag = 1 - ColFromL0Flag;
+        for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
+        { 
+          if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->getIsILR() ) 
+          { 
+            ColRefIdx = colIdx; 
+            found = true; 
+            break; 
+          } 
+        }
+      }
+
+      if(found == true)
+      {
+        pcSlice->setColFromL0Flag(ColFromL0Flag);
+        pcSlice->setColRefIdx(ColRefIdx);
+      }
+#endif
     }
 #endif
@@ -495,5 +539,7 @@
     if (pcSlice->getSliceType() == B_SLICE)
     {
+#if !REF_IDX_FRAMEWORK
       pcSlice->setColFromL0Flag(1-uiColDir);
+#endif
       Bool bLowDelay = true;
       Int  iCurrPOC  = pcSlice->getPOC();
Index: trunk/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 21)
+++ trunk/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 28)
@@ -3211,4 +3211,9 @@
   for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
   {
+#if REF_IDX_ME_ZEROMV
+	  Bool bZeroMVILR = pcCU->xCheckZeroMVILRMerge(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]);
+	  if(bZeroMVILR)
+	  {
+#endif
       UInt uiCostCand = MAX_UINT;
       UInt uiBitsCand = 0;
@@ -3234,4 +3239,7 @@
         uiMergeIndex = uiMergeCand;
       }
+#if REF_IDX_ME_ZEROMV
+	  }
+#endif
     }
 }
@@ -3420,7 +3428,15 @@
         if(pcCU->getSlice()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
         {
+#if REF_IDX_ME_ZEROMV 
+		  Bool bZeroMVILR = pcCU->xCheckZeroMVILRMvdL1Zero(iRefList, iRefIdxTemp, aaiMvpIdx[iRefList][iRefIdxTemp]);
+		  if(bZeroMVILR)
+		  {
+#endif
           bestBiPDist = biPDistTemp;
           bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
           bestBiPRefIdxL1 = iRefIdxTemp;
+#if REF_IDX_ME_ZEROMV
+		  }
+#endif
         }
 
@@ -3560,5 +3576,9 @@
     }
     //  Bi-directional prediction
+#if REF_IDX_ME_ZEROMV
+	if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) && !(pcCU->getSlice()->getMvdL1ZeroFlag() && bestBiPDist == MAX_INT) )
+#else
     if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
+#endif
     {
       
Index: trunk/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncTop.cpp	(revision 21)
+++ trunk/source/Lib/TLibEncoder/TEncTop.cpp	(revision 28)
@@ -85,4 +85,7 @@
   memset(m_cIlpPic, 0, sizeof(m_cIlpPic));
 #endif
+#if REF_IDX_MFM
+  m_bMFMEnabledFlag = false;
+#endif
 }
 
@@ -394,5 +397,5 @@
         m_cIlpPic[j]->create(m_iSourceWidth, m_iSourceHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, true);
 #endif
-#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE
+#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE || REF_IDX_MFM
         m_cIlpPic[j]->setIsILR(true);
 #endif
@@ -599,4 +602,5 @@
   // mark it should be extended
   rpcPic->getPicYuvRec()->setBorderExtension(false);
+
 }
 
@@ -605,4 +609,7 @@
 #if SVC_EXTENSION
   m_cSPS.setLayerId(m_layerId);
+#endif
+#if REF_IDX_MFM
+  m_cSPS.setMFMEnabledFlag(m_bMFMEnabledFlag);
 #endif
 
Index: trunk/source/Lib/TLibEncoder/TEncTop.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncTop.h	(revision 21)
+++ trunk/source/Lib/TLibEncoder/TEncTop.h	(revision 28)
@@ -140,4 +140,7 @@
   TComPic*                m_cIlpPic[MAX_NUM_REF];                    ///<  Inter layer Prediction picture =  upsampled picture 
 #endif
+#if REF_IDX_MFM
+  Bool                    m_bMFMEnabledFlag;
+#endif
 protected:
   Void  xGetNewPicBuffer  ( TComPic*& rpcPic );           ///< get picture buffer which will be processed
@@ -228,4 +231,8 @@
   Void setILRPic(TComPic *pcPic);
 #endif
+#if REF_IDX_MFM
+  Void setMFMEnabledFlag       (Bool flag)   {m_bMFMEnabledFlag = flag;}
+  Bool getMFMEnabledFlag()                   {return m_bMFMEnabledFlag;}    
+#endif
 
 };
