Index: branches/SHM-1.0-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/SHM-1.0-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 25)
@@ -98,4 +98,10 @@
     m_acTEncTop[layer].setFrameToBeEncoded             ( m_iFrameToBeEncoded );
 
+#if REF_IDX_MFM
+	if(layer == 0)
+		m_acTEncTop[layer].setMFMEnabledFlag(false);
+	else
+		m_acTEncTop[layer].setMFMEnabledFlag(true);
+#endif
     // set layer ID 
     m_acTEncTop[layer].setLayerId ( layer ); 
Index: branches/SHM-1.0-dev/source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibCommon/TComDataCU.h	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibCommon/TComDataCU.h	(revision 25)
@@ -597,4 +597,43 @@
 };
 
+#if REF_IDX_MFM
+class TComUpsampledMvFieldCU
+{
+  TComCUMvField m_acCUMvField[2];  //array of motion vector field
+  UInt          m_uiCUAddr;
+  UInt          m_uiCUPelX;
+  UInt          m_uiCUPelY;
+
+public:
+  Void          createMvField(Int CUAddr, Int uiWidthInCU, UInt uiNumPartitions) 
+  { 
+    m_uiCUAddr      = CUAddr;
+    m_uiCUPelX      = (CUAddr % uiWidthInCU) * g_uiMaxCUWidth;
+    m_uiCUPelY      = (CUAddr / uiWidthInCU) * g_uiMaxCUWidth;
+
+    m_acCUMvField[0].create( uiNumPartitions ); 
+		m_acCUMvField[1].create( uiNumPartitions );
+    return; 
+  }
+
+  Void          initMvField() 
+  { 
+    m_acCUMvField[0].clearMvField(); 
+    m_acCUMvField[1].clearMvField(); 
+    return; 
+  }
+  Void          destroy() 
+  { 
+    m_acCUMvField[0].destroy(); 
+    m_acCUMvField[1].destroy(); 
+    return; 
+  }
+  TComCUMvField* getCUMvField         ( RefPicList e )          { return  &m_acCUMvField[e]; }
+  UInt           getAddr              ()                        { return  m_uiCUAddr;}
+  UInt           getCUPelX            ()                        { return  m_uiCUPelX; }
+  UInt           getCUPelY            ()                        { return  m_uiCUPelY; }
+};
+#endif
+
 namespace RasterAddress
 {
Index: branches/SHM-1.0-dev/source/Lib/TLibCommon/TComMotionInfo.h
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibCommon/TComMotionInfo.h	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibCommon/TComMotionInfo.h	(revision 25)
@@ -158,4 +158,21 @@
   Void compress(Char* pePredMode, Int scale); 
 #endif
+
+#if REF_IDX_MFM
+  UInt    getNumPartition()    { return m_uiNumPartition; }        
+  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: branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPic.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPic.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPic.cpp	(revision 25)
@@ -68,6 +68,12 @@
 , 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
+#if REF_IDX_MFM
+, m_bIsUpsampledMvField                   (false) 
+, m_apcTComUpsampledMvFieldCU             (NULL)
+, m_peUpsampledPredMode                   (NULL)
+, m_iNumCUInUpsampledPic                  (-1)
 #endif
 #endif
@@ -554,5 +560,161 @@
     upsampledRowWidthCroma);
 }
+
+#if REF_IDX_MFM
+Void TComPic::createUpSampledMvField(Int upSampledHeight, Int upSampledWidth, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth )
+{
+	UInt uiNumPartitions   = 1<<(uiMaxDepth<<1);
+	UInt uiWidthInCU       = ( upSampledWidth % uiMaxWidth  ) ? upSampledWidth /uiMaxWidth  + 1 : upSampledWidth /uiMaxWidth;
+  UInt uiHeightInCU      = ( upSampledHeight% uiMaxHeight ) ? upSampledHeight/uiMaxHeight + 1 : upSampledHeight/uiMaxHeight;
+	UInt uiNumCUsInFrame   = uiWidthInCU * uiHeightInCU;
+	m_iNumCUInUpsampledPic = uiNumCUsInFrame;
+
+	m_apcTComUpsampledMvFieldCU     = new TComUpsampledMvFieldCU*[uiNumCUsInFrame];
+	m_peUpsampledPredMode           = new char*[uiNumCUsInFrame];
+
+	for (Int i = 0; i < uiNumCUsInFrame; i++ )
+	{
+		m_apcTComUpsampledMvFieldCU[i] = new TComUpsampledMvFieldCU;
+		m_apcTComUpsampledMvFieldCU[i]->createMvField(i, uiWidthInCU, uiNumPartitions);  //create Mv field
+		m_apcTComUpsampledMvFieldCU[i]->initMvField();                                   //initialize Mv field
+
+	  m_peUpsampledPredMode[i]     = new char[uiNumPartitions];
+	}
+
+	return;
+}
+
+Void TComPic::deriveUnitIdxBase(UInt uiUpsamplePelX, UInt uiUpsamplePelY, float ratio, UInt& uiBaseCUAddr, UInt& uiBaseAbsPartIdx)
+{
+  //pixel in the base layer
+  UInt uiPelX       = (UInt)((float)uiUpsamplePelX/ratio);
+  UInt uiPelY       = (UInt)((float)uiUpsamplePelY/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;
+}
+
+
+//MV field up-sampling
+Void TComPic::doTheUpSampleMvField(UInt upSampleRatio)
+{
+  UInt uiWidthMinPU      = g_uiMaxCUWidth/(1<<g_uiMaxCUDepth);
+  UInt uiHeightMinPU     = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
+  UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
+  UInt uiPelX, uiPelY;
+  UInt uiBaseCUAddr, uiBaseAbsPartIdx;
+  float ratio = 0;
+
+  //????????????????????????????
+  if(upSampleRatio == 0)       //ONE_TO_ONE
+    ratio = 1.0;
+  else if(upSampleRatio == 1)  //ONE_TO_TWO
+    ratio = 2.0;
+  else if(upSampleRatio == 2)  //TWO_TO_THREE
+    ratio = 1.5;
+
+  for(UInt uiCUAddr = 0; uiCUAddr < m_iNumCUInUpsampledPic; uiCUAddr++)  //each LCU
+  {
+    TComUpsampledMvFieldCU*& pcMvFieldCU = getUpsampledMvFieldCU(uiCUAddr);
+    pcMvFieldCU->initMvField();                                          //MV field initialization
+
+    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
+      uiPelX = pcMvFieldCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
+      uiPelY = pcMvFieldCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
+
+      //????????????????????????????
+      deriveUnitIdxBase(uiPelX + 8, uiPelY + 8, ratio, uiBaseCUAddr, uiBaseAbsPartIdx);
+      if( (getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_NONE) && (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 = getCU(uiBaseCUAddr)->getCUMvField((RefPicList)list)->getMv(uiBaseAbsPartIdx);
+          Int refIdx = getCU(uiBaseCUAddr)->getCUMvField((RefPicList)list)->getRefIdx(uiBaseAbsPartIdx);
+        //????????????????????????????
+        Int Hor = (Short) (ratio * cMv.getHor());
+        Int Ver = (Short) (ratio * cMv.getVer());
+
+        TComMv cScaledMv(Hor, Ver);
+        TComMvField sMvField;
+        sMvField.setMvField(cScaledMv, refIdx);
+
+        pcMvFieldCU->getCUMvField((RefPicList)list)->setMvField(sMvField, uiAbsPartIdx);
+        m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx] = MODE_INTER;
+        }
+      }
+      else
+      {
+        TComMvField zeroMvField;  //zero MV and invalid reference index
+        pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, uiAbsPartIdx);
+        pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, uiAbsPartIdx);
+
+    	  m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx]     = MODE_INTRA;
+      }
+
+      //MV compression
+      for(UInt i = 1; i < unitNum; i++ )  
+      {
+        pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->setMvField(pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->getMv(uiAbsPartIdx), pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
+        pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->setMvField(pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->getMv(uiAbsPartIdx), pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
+    	  m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx+i]     = m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx];
+      }
+
+    }  //ending for(UInt uiAbsPartIdx = 0; uiAbsPartIdx < uiNumPartitions; uiAbsPartIdx++) 
+  }  //ending for(UInt uiCUAddr = 0; uiCUAddr < m_iNumCUInUpsampledPic; uiCUAddr++)
+  return;
+}
+
+Void TComPic::copyUpsampledMvField(TComPic* pcPicBase)
+{
+  assert( getPicSym()->getNumberOfCUsInFrame() == pcPicBase->getNumCUInUpsampledPic() );
+
+  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCUsInFrame(); cuIdx++)  //each LCU
+  {
+    UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
+
+    TComDataCU*             pcCUDes = getCU(cuIdx);
+    TComUpsampledMvFieldCU* pcMvFieldCU = pcPicBase->getUpsampledMvFieldCU(cuIdx);
+    for(UInt list = 0; list < 2; list++)  //each reference list
+    {
+      TComCUMvField* pcCUMvFieldDes = pcCUDes->getCUMvField((RefPicList)list);
+      TComCUMvField* pcCUMvFieldOrg = pcMvFieldCU->getCUMvField((RefPicList)list);
+
+      assert(pcCUMvFieldDes->getNumPartition() == pcCUMvFieldOrg->getNumPartition());
+      assert(pcCUMvFieldDes->getNumPartition() == uiNumPartitions);
+
+      pcCUMvFieldDes->clearMvField();
+      pcCUMvFieldDes->copyFrom(pcCUMvFieldOrg, pcCUMvFieldDes->getNumPartition(), 0);      
+    }
+
+    char* pPredModeSrc = pcPicBase->getUpsampledPreModeCU(cuIdx);
+    char* pPredModeDst = pcCUDes->getPredictionMode();
+    memcpy(pPredModeDst, pPredModeSrc, sizeof(char)*uiNumPartitions);
+    memset( pcCUDes->getPartitionSize(), SIZE_2Nx2N, sizeof(char)*uiNumPartitions);
+  }
+}
 #endif
 
+#endif
+
 //! \}
Index: branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPic.h
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPic.h	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPic.h	(revision 25)
@@ -88,6 +88,12 @@
   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
+#if REF_IDX_MFM
+  Bool                          m_bIsUpsampledMvField;
+  TComUpsampledMvFieldCU**      m_apcTComUpsampledMvFieldCU;
+  Char**                        m_peUpsampledPredMode;
+  Int                           m_iNumCUInUpsampledPic;
 #endif
 #endif
@@ -118,7 +124,28 @@
   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
+  Bool          IsUpsampledMvField()                         { return m_bIsUpsampledMvField; }
+  Void          setUpsampledMvField(Bool isUpsampledMvField) { m_bIsUpsampledMvField = isUpsampledMvField; }
+  Bool          upsampledMvFieldIsNull()      
+                {
+                  if (m_apcTComUpsampledMvFieldCU == NULL) 
+                    return true; 
+                  else 
+                    return false; 
+                }
+  Void          createUpSampledMvField(  Int upSampledHeight, Int upSampledWidth, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth );
+  Void          doTheUpSampleMvField  (  UInt upSampleRatio );
+  Void          copyUpsampledMvField  (  TComPic* pcPicBase );
+  Void deriveUnitIdxBase(UInt uiUpsamplePelX, UInt uiUpsamplePelY, float ratio, UInt& uiBaseCUAddr, UInt& uiBaseAbsPartIdx);
+
+  Int           getNumCUInUpsampledPic()       { return m_iNumCUInUpsampledPic; }
+  TComUpsampledMvFieldCU*&  getUpsampledMvFieldCU( UInt uiCUAddr )  { return m_apcTComUpsampledMvFieldCU[uiCUAddr]; }
+  char*  getUpsampledPreModeCU( UInt uiCUAddr )  { return m_peUpsampledPredMode[uiCUAddr]; }
+
+
 #endif
 
Index: branches/SHM-1.0-dev/source/Lib/TLibCommon/TComSlice.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibCommon/TComSlice.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibCommon/TComSlice.cpp	(revision 25)
@@ -519,4 +519,12 @@
   if(getSPS()->getLayerId() && m_eSliceType != I_SLICE)
   {
+#if REF_IDX_MFM
+    assert(iRefPicNum == 1);
+    if(getPOC() != 0)
+    { 
+      assert(getBaseColPic()->IsUpsampledMvField() == true); 
+      pIlpPicList[0]->copyUpsampledMvField(getBaseColPic());
+    }
+#endif
     //add to list 0;
     Int iOffset;
@@ -546,4 +554,44 @@
   }
 }
+
+#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: branches/SHM-1.0-dev/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibCommon/TComSlice.h	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibCommon/TComSlice.h	(revision 25)
@@ -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: branches/SHM-1.0-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibCommon/TypeDef.h	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibCommon/TypeDef.h	(revision 25)
@@ -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
Index: branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 25)
@@ -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: branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecGop.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecGop.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecGop.cpp	(revision 25)
@@ -287,4 +287,39 @@
 
   rpcPic->compressMotion(); 
+
+#if REF_IDX_MFM
+  if( rpcPic->getLayerId() == 0 && rpcPic->upsampledMvFieldIsNull() ) 
+  { 
+    TComSPS *spsEL = m_ppcTDecTop[1]->getSPS();
+
+    rpcPic->createUpSampledMvField(spsEL->getPicHeightInLumaSamples(), spsEL->getPicWidthInLumaSamples(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);  //create up-sampled mv field 
+  }
+
+  if( rpcPic->getLayerId() == 0 && rpcPic->IsUpsampledMvField() == false ) 
+  { 
+    TComSPS *spsBL = m_ppcTDecTop[0]->getSPS();
+    TComSPS *spsEL = m_ppcTDecTop[1]->getSPS();
+
+    Int iBWidth  = spsBL->getPicWidthInLumaSamples() - spsBL->getPicCropLeftOffset() - spsBL->getPicCropRightOffset(); 
+    Int iBHeight = spsBL->getPicHeightInLumaSamples() - spsBL->getPicCropTopOffset() - spsBL->getPicCropBottomOffset();
+
+    Int iEWidth  = spsEL->getPicWidthInLumaSamples() - spsEL->getPicCropLeftOffset() - spsEL->getPicCropRightOffset(); 
+    Int iEHeight = spsEL->getPicHeightInLumaSamples() - spsEL->getPicCropTopOffset() - spsEL->getPicCropBottomOffset();
+
+    UInt upSampleRatio; 
+    if(iEWidth == iBWidth && iEHeight == iBHeight) 
+      upSampleRatio = 0; 
+    else if(iEWidth == 2*iBWidth && iEHeight == 2*iBHeight) 
+      upSampleRatio = 1; 
+    else if(2*iEWidth == 3*iBWidth && 2*iEHeight == 3*iBHeight) 
+      upSampleRatio = 2; 
+    else 
+      assert(0);
+
+    rpcPic->doTheUpSampleMvField(upSampleRatio); 
+    rpcPic->setUpsampledMvField(true);
+  }
+#endif
+
   Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
   if (!pcSlice->isReferenced()) c += 32;
Index: branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecTop.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 25)
@@ -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,8 @@
     rpcPic->getPicSym()->allocSaoParam(&m_cSAO);
 #endif
+
+#if REF_IDX_MFM
+    rpcPic->setUpsampledMvField(false);
+#endif
     m_cListPic.pushBack( rpcPic );
     
@@ -315,4 +319,8 @@
 #if REMOVE_APS
   rpcPic->getPicSym()->allocSaoParam(&m_cSAO);
+#endif
+
+#if REF_IDX_MFM
+  rpcPic->setUpsampledMvField(false);
 #endif
 }
@@ -768,4 +776,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 +892,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: branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecTop.h
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecTop.h	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibDecoder/TDecTop.h	(revision 25)
@@ -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: branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 25)
@@ -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: branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 25)
@@ -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();
@@ -1515,4 +1561,34 @@
 
       pcPic->compressMotion(); 
+#if REF_IDX_MFM
+      if( m_layerId == 0 && pcPic->upsampledMvFieldIsNull() )
+      {
+        Int     iEHeight     = m_ppcTEncTop[m_layerId+1]->getSourceHeight();
+        Int     iEWidth      = m_ppcTEncTop[m_layerId+1]->getSourceWidth();
+        pcPic->createUpSampledMvField(iEHeight, iEWidth, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);  //create up-sampled mv field
+      }
+
+    	if( m_layerId == 0 && pcPic->IsUpsampledMvField() == false )
+      {
+        Int iBWidth  = m_ppcTEncTop[m_layerId]->getSourceWidth() - m_ppcTEncTop[m_layerId]->getCropLeft() - m_ppcTEncTop[m_layerId]->getCropRight();
+        Int iBHeight = m_ppcTEncTop[m_layerId]->getSourceHeight() - m_ppcTEncTop[m_layerId]->getCropTop() - m_ppcTEncTop[m_layerId]->getCropBottom();
+
+        Int iEWidth  = m_ppcTEncTop[m_layerId+1]->getSourceWidth() - m_ppcTEncTop[m_layerId+1]->getCropLeft() - m_ppcTEncTop[m_layerId+1]->getCropRight();
+        Int iEHeight = m_ppcTEncTop[m_layerId+1]->getSourceHeight() - m_ppcTEncTop[m_layerId+1]->getCropTop() - m_ppcTEncTop[m_layerId+1]->getCropBottom();
+
+        UInt upSampleRatio;
+        if(iEWidth == iBWidth && iEHeight == iBHeight)
+          upSampleRatio = 0;
+        else if(iEWidth == 2*iBWidth && iEHeight == 2*iBHeight)
+          upSampleRatio = 1;
+        else if(2*iEWidth == 3*iBWidth && 2*iEHeight == 3*iBHeight)
+          upSampleRatio = 2;
+        else
+          assert(0);
+
+        pcPic->doTheUpSampleMvField(upSampleRatio);
+        pcPic->setUpsampledMvField(true);
+      }
+#endif
       
       //-- For time output for each slice
Index: branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 25)
@@ -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,7 @@
   // mark it should be extended
   rpcPic->getPicYuvRec()->setBorderExtension(false);
+#if REF_IDX_MFM
+  rpcPic->setUpsampledMvField(false);
+#endif
 }
 
@@ -605,4 +611,7 @@
 #if SVC_EXTENSION
   m_cSPS.setLayerId(m_layerId);
+#endif
+#if REF_IDX_MFM
+  m_cSPS.setMFMEnabledFlag(m_bMFMEnabledFlag);
 #endif
 
Index: branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncTop.h
===================================================================
--- branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncTop.h	(revision 24)
+++ branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncTop.h	(revision 25)
@@ -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
 
 };
