Index: trunk/source/Lib/TLibCommon/TComPic.cpp
===================================================================
--- trunk/source/Lib/TLibCommon/TComPic.cpp	(revision 19)
+++ trunk/source/Lib/TLibCommon/TComPic.cpp	(revision 20)
@@ -68,5 +68,5 @@
 , m_bSpatialEnhLayer( false )
 , m_pcFullPelBaseRec( NULL )
-#if REF_IDX_ME_AROUND_ZEROMV
+#if REF_IDX_ME_AROUND_ZEROMV || ENCODER_FAST_MODE
 , m_bIsILR                                (false)
 #endif
Index: trunk/source/Lib/TLibCommon/TComPic.h
===================================================================
--- trunk/source/Lib/TLibCommon/TComPic.h	(revision 19)
+++ trunk/source/Lib/TLibCommon/TComPic.h	(revision 20)
@@ -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
+#if REF_IDX_ME_AROUND_ZEROMV || ENCODER_FAST_MODE
   Bool                  m_bIsILR;                 //  Is ILR picture
 #endif
@@ -118,5 +118,5 @@
   TComPicYuv*   getFullPelBaseRec   ()  { return  m_pcFullPelBaseRec;  }
 #endif
-#if REF_IDX_ME_AROUND_ZEROMV
+#if REF_IDX_ME_AROUND_ZEROMV || ENCODER_FAST_MODE
   Void          setIsILR( Bool bIsILR)      {m_bIsILR = bIsILR;}
   Bool          getIsILR()                  {return m_bIsILR;}
Index: trunk/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- trunk/source/Lib/TLibCommon/TypeDef.h	(revision 19)
+++ trunk/source/Lib/TLibCommon/TypeDef.h	(revision 20)
@@ -58,4 +58,5 @@
 #if REF_IDX_FRAMEWORK
 #define REF_IDX_ME_AROUND_ZEROMV         0      ///< added ME around zero MV for inter-layer reference picture
+#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.
 #else
 #define INTRA_BL                         1      ///< inter-layer texture prediction
Index: trunk/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncCu.cpp	(revision 19)
+++ trunk/source/Lib/TLibEncoder/TEncCu.cpp	(revision 20)
@@ -471,4 +471,15 @@
   if(!bSliceEnd && !bSliceStart && bInsidePicture )
   {
+#if (ENCODER_FAST_MODE)
+    bool testInter = true;
+    if (rpcBestCU->getLayerId() > 0)
+    {
+      if (rpcBestCU->getSlice()->getBaseColPic()->getSlice(0)->getSliceType() == I_SLICE)
+      {
+        testInter = false;
+      }
+
+    }
+#endif
     for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
     {
@@ -485,5 +496,9 @@
 
       // do inter modes, SKIP and 2Nx2N
+#if (ENCODER_FAST_MODE == 1)
+      if( rpcBestCU->getSlice()->getSliceType() != I_SLICE && testInter )
+#else
       if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
+#endif
       {
         // 2Nx2N
@@ -506,4 +521,8 @@
           }
         }
+#if (ENCODER_FAST_MODE == 2)
+        if (testInter)
+        {
+#endif
 
     if(!m_pcEncCfg->getUseEarlySkipDetection())
@@ -519,4 +538,7 @@
         }
     }
+#if (ENCODER_FAST_MODE == 2)
+    }
+#endif
 
       }
@@ -550,5 +572,9 @@
 
       // do inter modes, NxN, 2NxN, and Nx2N
+#if (ENCODER_FAST_MODE)
+      if( rpcBestCU->getSlice()->getSliceType() != I_SLICE && testInter )
+#else
       if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
+#endif
       {
         // 2Nx2N, NxN
@@ -709,8 +735,16 @@
       {
         // speedup for inter frames
+#if (ENCODER_FAST_MODE)
         if( rpcBestCU->getSlice()->getSliceType() == I_SLICE || 
+          !testInter ||
           rpcBestCU->getCbf( 0, TEXT_LUMA     ) != 0   ||
           rpcBestCU->getCbf( 0, TEXT_CHROMA_U ) != 0   ||
           rpcBestCU->getCbf( 0, TEXT_CHROMA_V ) != 0     ) // avoid very complex intra if it is unlikely
+#else
+         if( rpcBestCU->getSlice()->getSliceType() == I_SLICE || 
+          rpcBestCU->getCbf( 0, TEXT_LUMA     ) != 0   ||
+          rpcBestCU->getCbf( 0, TEXT_CHROMA_U ) != 0   ||
+          rpcBestCU->getCbf( 0, TEXT_CHROMA_V ) != 0     ) // avoid very complex intra if it is unlikely
+#endif 
         {
           xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_2Nx2N );
@@ -747,4 +781,13 @@
       }
 #endif
+
+#if (ENCODER_FAST_MODE)
+        if(pcPic->getLayerId() > 0)
+        { 
+          xCheckRDCostILRUni( rpcBestCU, rpcTempCU); 
+          rpcTempCU->initEstData( uiDepth, iQP );
+       }
+#endif
+
       if (isAddLowestQP && (iQP == lowestQP))
       {
@@ -1308,5 +1351,4 @@
     for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
     {
-      {
         if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))
         {
@@ -1361,5 +1403,4 @@
     }
    }
-  }
 
   if(uiNoResidual == 0 && m_pcEncCfg->getUseEarlySkipDetection())
@@ -1434,5 +1475,34 @@
   xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
 }
-
+#if (ENCODER_FAST_MODE)
+Void TEncCu::xCheckRDCostILRUni(TComDataCU *&rpcBestCU, TComDataCU *&rpcTempCU)
+{
+  UChar uhDepth = rpcTempCU->getDepth( 0 );
+
+  rpcTempCU->setDepthSubParts( uhDepth, 0 );
+
+#if SKIP_FLAG
+  rpcTempCU->setSkipFlagSubParts( false, 0, uhDepth );
+#endif
+
+  rpcTempCU->setPartSizeSubParts  ( SIZE_2Nx2N,  0, uhDepth );  //2Nx2N
+  rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );
+  rpcTempCU->setCUTransquantBypassSubParts  ( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );
+
+  Bool exitILR = m_pcPredSearch->predInterSearchILRUni( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
+
+  if(!exitILR)
+    return;
+
+  m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false );
+
+  rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
+
+  xCheckDQP( rpcTempCU );
+  xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
+
+  return;
+}
+#endif
 Void TEncCu::xCheckRDCostIntra( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize eSize )
 {
Index: trunk/source/Lib/TLibEncoder/TEncCu.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncCu.h	(revision 19)
+++ trunk/source/Lib/TLibEncoder/TEncCu.h	(revision 20)
@@ -150,4 +150,7 @@
   Void  xCheckRDCostIntraBL ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU  );
 #endif
+#if ENCODER_FAST_MODE
+  Void  xCheckRDCostILRUni  ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU );
+#endif
 
   Void  xCheckBestMode      ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU                      );
Index: trunk/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 19)
+++ trunk/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 20)
@@ -3211,5 +3211,4 @@
   for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
   {
-    {
       UInt uiCostCand = MAX_UINT;
       UInt uiBitsCand = 0;
@@ -3236,5 +3235,4 @@
       }
     }
-  }
 }
 
@@ -3360,4 +3358,8 @@
     UInt          uiBitsTempL0[MAX_NUM_REF];
 
+#if (ENCODER_FAST_MODE)
+    Bool          testILR;
+#endif
+
     xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
     
@@ -3381,6 +3383,25 @@
       RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
       
+#if (ENCODER_FAST_MODE)
+      if (pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1)
+      {
+        testILR = false;
+      }
+      else
+      {
+        testILR = true;
+      }
+#endif
+
       for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
       {
+#if (ENCODER_FAST_MODE)
+        TComPic* pcPic    = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxTemp );
+        if( !testILR && pcPic->getIsILR() && (ePartSize == SIZE_2Nx2N) ) 
+        {
+          continue;
+        }
+#endif
+
         uiBitsTemp = uiMbBits[iRefList];
         if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
@@ -3613,4 +3634,12 @@
         Bool bChanged = false;
         
+#if (ENCODER_FAST_MODE)
+        Bool     testIter = true;
+        TComPic* pcPic    = pcCU->getSlice()->getRefPic( RefPicList(1 - iRefList), iRefIdxBi[1 - iRefList] );
+        if(pcPic->getIsILR() && (ePartSize == SIZE_2Nx2N))
+          testIter = false;  //the fixed part is ILR, skip this iteration       
+        if(testIter)
+        {
+#endif
         iRefStart = 0;
         iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
@@ -3618,4 +3647,12 @@
         for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
         {
+#if (ENCODER_FAST_MODE)
+            Bool testRefIdx = true;
+            pcPic           = pcCU->getSlice()->getRefPic( RefPicList(iRefList) , iRefIdxTemp );
+            if(pcPic->getIsILR() && (ePartSize == SIZE_2Nx2N))
+              testRefIdx = false;  //the refined part is ILR, skip this reference pic           
+            if(testRefIdx)
+            {
+#endif
           uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
           if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
@@ -3658,5 +3695,11 @@
             }
           }
+#if (ENCODER_FAST_MODE)
+            }
+#endif
+          }
+#if (ENCODER_FAST_MODE)
         } // for loop-iRefIdxTemp
+#endif
         
         if ( !bChanged )
@@ -3942,4 +3985,137 @@
   return;
 }
+#if ENCODER_FAST_MODE
+Bool TEncSearch::predInterSearchILRUni( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv )
+{
+  rpcPredYuv->clear();
+  rpcRecoYuv->clear();
+
+  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
+
+  TComMv        cMv[2];
+  TComMv        cMvPred[2][33];
+  TComMv        cMvTemp[2][33];
+  TComMv        TempMv;
+
+  Int           iRefIdx[2]={0,0};
+
+  Int           aaiMvpIdx[2][33];
+  Int           aaiMvpNum[2][33];
+
+  UInt          uiMbBits[3] = {1, 1, 0};
+  UInt          uiLastMode = 0;
+
+  UInt          uiCost[2]   = { MAX_UINT, MAX_UINT };     //uni, rdCost
+  UInt          uiCostTemp;
+  UInt          biPDistTemp = MAX_INT;
+  UInt          uiBitsTemp;
+
+  PartSize      ePartSize = pcCU->getPartitionSize( 0 );  //2Nx2N
+  Int           iPartIdx  = 0;                            //one PU in CU
+  UInt          uiPartAddr;
+  Int           iRoiWidth, iRoiHeight;
+
+  xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
+  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
+
+  for( Int iRefList = 0; iRefList < iNumPredDir; iRefList++)  //list
+  {
+    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+
+    Int  iRefIdxTemp = -1;
+    Bool foundILR    = false;
+    for( Int refIdx = 0; refIdx < pcCU->getSlice()->getNumRefIdx(eRefPicList); refIdx++ )
+      if( pcCU->getSlice()->getRefPic(eRefPicList, refIdx)->getIsILR() )
+      {
+        iRefIdxTemp = refIdx;
+        foundILR    = true;
+        break;
+      }
+
+    if(!foundILR)  //no ILR in eRefPiclist
+      continue;  
+
+    uiBitsTemp = uiMbBits[iRefList];
+    if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 ) 
+    { 
+      uiBitsTemp += iRefIdxTemp+1; 
+      if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--; 
+    }
+
+    xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
+    aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
+    aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
+
+    uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
+
+    xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
+    xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
+
+    if( uiCostTemp < uiCost[iRefList] )
+    {
+      uiCost[iRefList] = uiCostTemp;
+
+      cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
+      iRefIdx[iRefList] = iRefIdxTemp;
+
+      pcCU->getCUMvField(eRefPicList)->setAllMv( cMv[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
+      pcCU->getCUMvField(eRefPicList)->setAllRefIdx( iRefIdx[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
+    }
+  }
+
+  if( uiCost[0] == MAX_UINT && uiCost[1] == MAX_UINT )  //no ILR in both list0 and list1
+    return false;
+
+  //  Clear Motion Field 
+  pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
+  pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
+  pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx ); 
+  pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx );
+
+  pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
+  pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
+  pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
+  pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
+
+  if( uiCost[0] <= uiCost[1] )  //list0 ILR
+  {
+    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv    ( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
+    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
+
+    TempMv = cMv[0] - cMvPred[0][iRefIdx[0]]; 
+    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
+
+    pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
+
+    pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
+    pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
+  }
+  else if( uiCost[1] < uiCost[0] )  //list1 ILR
+  {
+    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv    ( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
+    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
+
+    TempMv = cMv[1] - cMvPred[1][iRefIdx[1]]; 
+    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
+
+    pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
+
+    pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
+    pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
+  }
+  else
+    assert(0);
+
+  pcCU->setMergeFlagSubParts( false, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
+
+  motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
+
+  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
+
+  return true;
+}
+
+
+#endif
 
 // AMVP
Index: trunk/source/Lib/TLibEncoder/TEncSearch.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSearch.h	(revision 19)
+++ trunk/source/Lib/TLibEncoder/TEncSearch.h	(revision 20)
@@ -215,4 +215,14 @@
                                 );
   
+#if (ENCODER_FAST_MODE)
+  Bool predInterSearchILRUni    ( TComDataCU* pcCU,
+                                  TComYuv*    pcOrgYuv,
+                                  TComYuv*&   rpcPredYuv,
+                                  TComYuv*&   rpcResiYuv,
+                                  TComYuv*&   rpcRecoYuv
+                                );
+
+#endif
+  
   /// encode residual and compute rd-cost for inter mode
   Void encodeResAndCalcRdInterCU( TComDataCU* pcCU,
Index: trunk/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncTop.cpp	(revision 19)
+++ trunk/source/Lib/TLibEncoder/TEncTop.cpp	(revision 20)
@@ -394,5 +394,5 @@
         m_cIlpPic[j]->create(m_iSourceWidth, m_iSourceHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, true);
 #endif
-#if REF_IDX_ME_AROUND_ZEROMV
+#if REF_IDX_ME_AROUND_ZEROMV || ENCODER_FAST_MODE
         m_cIlpPic[j]->setIsILR(true);
 #endif
