Index: branches/SHM-dev/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComDataCU.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComDataCU.cpp	(revision 1574)
@@ -2959,11 +2959,25 @@
   // use coldir.
   const TComPic    * const pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());
+#if REDUCED_ENCODER_MEMORY
+  if (!pColPic->getPicSym()->hasDPBPerCtuData())
+  {
+    return false;
+  }
+  const TComPicSym::DPBPerCtuData * const pColDpbCtu = &(pColPic->getPicSym()->getDPBPerCtuData(ctuRsAddr));
+  const TComSlice * const pColSlice = pColDpbCtu->getSlice();
+  if(pColDpbCtu->getPartitionSize(partUnitIdx)==NUMBER_OF_PART_SIZES)
+#else
   const TComDataCU * const pColCtu = pColPic->getCtu( ctuRsAddr );
   if(pColCtu->getPic()==0 || pColCtu->getPartitionSize(partUnitIdx)==NUMBER_OF_PART_SIZES)
+#endif
   {
     return false;
   }
 
+#if REDUCED_ENCODER_MEMORY
+  if (!pColDpbCtu->isInter(absPartAddr))
+#else
   if (!pColCtu->isInter(absPartAddr))
+#endif
   {
     return false;
@@ -2971,10 +2985,18 @@
 
   RefPicList eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());
+#if REDUCED_ENCODER_MEMORY
+  Int iColRefIdx            = pColDpbCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
+#else
   Int iColRefIdx            = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
+#endif
 
   if (iColRefIdx < 0 )
   {
     eColRefPicList = RefPicList(1 - eColRefPicList);
+#if REDUCED_ENCODER_MEMORY
+    iColRefIdx = pColDpbCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
+#else
     iColRefIdx = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
+#endif
 
     if (iColRefIdx < 0 )
@@ -2985,5 +3007,9 @@
 
   const Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, refIdx)->getIsLongTerm();
+#if REDUCED_ENCODER_MEMORY
+  const Bool bIsColRefLongTerm  = pColSlice->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
+#else
   const Bool bIsColRefLongTerm  = pColCtu->getSlice()->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
+#endif
 
   if ( bIsCurrRefLongTerm != bIsColRefLongTerm )
@@ -2993,5 +3019,9 @@
 
   // Scale the vector.
+#if REDUCED_ENCODER_MEMORY
+  const TComMv &cColMv = pColDpbCtu->getCUMvField(eColRefPicList)->getMv(absPartAddr);
+#else
   const TComMv &cColMv = pColCtu->getCUMvField(eColRefPicList)->getMv(absPartAddr);
+#endif
   if ( bIsCurrRefLongTerm /*|| bIsColRefLongTerm*/ )
   {
@@ -3001,6 +3031,11 @@
   {
     const Int currPOC    = m_pcSlice->getPOC();
+#if REDUCED_ENCODER_MEMORY
+    const Int colPOC     = pColSlice->getPOC();
+    const Int colRefPOC  = pColSlice->getRefPOC(eColRefPicList, iColRefIdx);
+#else
     const Int colPOC     = pColCtu->getSlice()->getPOC();
     const Int colRefPOC  = pColCtu->getSlice()->getRefPOC(eColRefPicList, iColRefIdx);
+#endif
     const Int currRefPOC = m_pcSlice->getRefPic(eRefPicList, refIdx)->getPOC();
     const Int scale      = xGetDistScaleFactor(currPOC, currRefPOC, colPOC, colRefPOC);
@@ -3053,4 +3088,16 @@
 Void TComDataCU::compressMV()
 {
+#if REDUCED_ENCODER_MEMORY
+  const Int scaleFactor = std::max<Int>(1,4 * AMVP_DECIMATION_FACTOR / m_unitSize);
+  TComPicSym &picSym=*(getPic()->getPicSym());
+  TComPicSym::DPBPerCtuData &dpbForCtu=picSym.getDPBPerCtuData(getCtuRsAddr());
+
+  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
+  {
+    dpbForCtu.m_CUMvField[i].compress(dpbForCtu.m_pePredMode, m_pePredMode, scaleFactor,m_acCUMvField[i]);
+    memcpy(dpbForCtu.m_pePartSize, m_pePartSize, sizeof(*m_pePartSize)*m_uiNumPartition);
+    dpbForCtu.m_pSlice = getSlice();
+  }
+#else
   Int scaleFactor = 4 * AMVP_DECIMATION_FACTOR / m_unitSize;
   if (scaleFactor > 0)
@@ -3061,4 +3108,5 @@
     }
   }
+#endif
 }
 
Index: branches/SHM-dev/source/Lib/TLibCommon/TComMotionInfo.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComMotionInfo.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComMotionInfo.cpp	(revision 1574)
@@ -328,4 +328,28 @@
  * \param scale      Factor by which to subsample motion information
  */
+#if REDUCED_ENCODER_MEMORY
+Void TComCUMvField::compress(SChar *pePredMode, const SChar* pePredModeSource, const Int scale, const TComCUMvField &source)
+{
+  const Int numSubpartsWithIdenticalMotion = scale * scale;
+  assert( numSubpartsWithIdenticalMotion > 0 && numSubpartsWithIdenticalMotion <= m_uiNumPartition);
+  assert(source.m_uiNumPartition == m_uiNumPartition);
+
+  for ( Int partIdx = 0; partIdx < m_uiNumPartition; partIdx += numSubpartsWithIdenticalMotion )
+  {
+    TComMv cMv(0,0);
+    Int iRefIdx = 0;
+
+    cMv = source.m_pcMv[ partIdx ];
+    PredMode predMode = static_cast<PredMode>( pePredModeSource[ partIdx ] );
+    iRefIdx = source.m_piRefIdx[ partIdx ];
+    for ( Int i = 0; i < numSubpartsWithIdenticalMotion; i++ )
+    {
+      m_pcMv[ partIdx + i ] = cMv;
+      pePredMode[ partIdx + i ] = predMode;
+      m_piRefIdx[ partIdx + i ] = iRefIdx;
+    }
+  }
+}
+#else
 Void TComCUMvField::compress(SChar* pePredMode, Int scale)
 {
@@ -349,3 +373,4 @@
   }
 }
+#endif
 //! \}
Index: branches/SHM-dev/source/Lib/TLibCommon/TComMotionInfo.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComMotionInfo.h	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComMotionInfo.h	(revision 1574)
@@ -153,5 +153,9 @@
   }
 
+#if REDUCED_ENCODER_MEMORY
+  Void compress(SChar *pePredMode, const SChar* pePredModeSource, const Int scale, const TComCUMvField &source);
+#else
   Void compress(SChar* pePredMode, Int scale);
+#endif
 
 #if SVC_EXTENSION
Index: branches/SHM-dev/source/Lib/TLibCommon/TComPic.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComPic.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComPic.cpp	(revision 1574)
@@ -78,5 +78,9 @@
 }
 #if SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+Void TComPic::create( const TComSPS &sps, const TComPPS &pps, const Bool bCreateEncoderSourcePicYuv, const Bool bCreateForImmediateReconstruction, const UInt layerId )
+#else
 Void TComPic::create( const TComSPS &sps, const TComPPS &pps, const Bool bIsVirtual, const UInt layerId )
+#endif
 {
   destroy();
@@ -92,12 +96,24 @@
   m_layerId = layerId;
 
+#if REDUCED_ENCODER_MEMORY
+  m_picSym.create( sps, pps, uiMaxDepth, bCreateForImmediateReconstruction, layerId );
+  if (bCreateEncoderSourcePicYuv)
+#else
   m_picSym.create( sps, pps, uiMaxDepth, layerId );
 
   if (!bIsVirtual)
-  {
-    m_apcPicYuv[PIC_YUV_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
+#endif
+  {
+    m_apcPicYuv[PIC_YUV_ORG     ]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG     ]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
     m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
   }
+#if REDUCED_ENCODER_MEMORY
+  if (bCreateForImmediateReconstruction)
+  {
+#endif
   m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
+#if REDUCED_ENCODER_MEMORY
+  }
+#endif
 
   for( Int i = 0; i < MAX_LAYERS; i++ )
@@ -117,5 +133,9 @@
 }
 #else
+#if REDUCED_ENCODER_MEMORY
+Void TComPic::create( const TComSPS &sps, const TComPPS &pps, const Bool bCreateEncoderSourcePicYuv, const Bool bCreateForImmediateReconstruction )
+#else
 Void TComPic::create( const TComSPS &sps, const TComPPS &pps, const Bool bIsVirtual)
+#endif
 {
   destroy();
@@ -128,11 +148,23 @@
   const UInt         uiMaxDepth      = sps.getMaxTotalCUDepth();
 
+#if REDUCED_ENCODER_MEMORY
+  m_picSym.create( sps, pps, uiMaxDepth, bCreateForImmediateReconstruction );
+  if (bCreateEncoderSourcePicYuv)
+#else
   m_picSym.create( sps, pps, uiMaxDepth );
   if (!bIsVirtual)
+#endif
   {
     m_apcPicYuv[PIC_YUV_ORG    ]   = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG     ]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
     m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
   }
-  m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
+#if REDUCED_ENCODER_MEMORY
+  if (bCreateForImmediateReconstruction)
+  {
+#endif
+    m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
+#if REDUCED_ENCODER_MEMORY
+  }
+#endif
 
   // there are no SEI messages associated with this picture initially
@@ -142,4 +174,80 @@
   }
   m_bUsedByCurr = false;
+}
+#endif
+
+#if REDUCED_ENCODER_MEMORY
+Void TComPic::prepareForEncoderSourcePicYuv()
+{
+  const TComSPS &sps=m_picSym.getSPS();
+
+  const ChromaFormat chromaFormatIDC = sps.getChromaFormatIdc();
+  const Int          iWidth          = sps.getPicWidthInLumaSamples();
+  const Int          iHeight         = sps.getPicHeightInLumaSamples();
+  const UInt         uiMaxCuWidth    = sps.getMaxCUWidth();
+  const UInt         uiMaxCuHeight   = sps.getMaxCUHeight();
+  const UInt         uiMaxDepth      = sps.getMaxTotalCUDepth();
+
+  if (m_apcPicYuv[PIC_YUV_ORG    ]==NULL)
+  {
+    m_apcPicYuv[PIC_YUV_ORG    ]   = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG     ]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
+  }
+  if (m_apcPicYuv[PIC_YUV_TRUE_ORG    ]==NULL)
+  {
+    m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
+  }
+}
+
+Void TComPic::prepareForReconstruction()
+{
+  if (m_apcPicYuv[PIC_YUV_REC] == NULL)
+  {
+    const TComSPS &sps=m_picSym.getSPS();
+    const ChromaFormat chromaFormatIDC = sps.getChromaFormatIdc();
+    const Int          iWidth          = sps.getPicWidthInLumaSamples();
+    const Int          iHeight         = sps.getPicHeightInLumaSamples();
+    const UInt         uiMaxCuWidth    = sps.getMaxCUWidth();
+    const UInt         uiMaxCuHeight   = sps.getMaxCUHeight();
+    const UInt         uiMaxDepth      = sps.getMaxTotalCUDepth();
+
+    m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
+  }
+
+  // mark it should be extended
+  m_apcPicYuv[PIC_YUV_REC]->setBorderExtension(false);
+
+  m_picSym.prepareForReconstruction();
+}
+
+Void TComPic::releaseReconstructionIntermediateData()
+{
+  m_picSym.releaseReconstructionIntermediateData();
+}
+
+Void TComPic::releaseEncoderSourceImageData()
+{
+  if (m_apcPicYuv[PIC_YUV_ORG    ])
+  {
+    m_apcPicYuv[PIC_YUV_ORG]->destroy();
+    delete m_apcPicYuv[PIC_YUV_ORG];
+    m_apcPicYuv[PIC_YUV_ORG] = NULL;
+  }
+  if (m_apcPicYuv[PIC_YUV_TRUE_ORG    ])
+  {
+    m_apcPicYuv[PIC_YUV_TRUE_ORG]->destroy();
+    delete m_apcPicYuv[PIC_YUV_TRUE_ORG];
+    m_apcPicYuv[PIC_YUV_TRUE_ORG] = NULL;
+  }
+}
+
+Void TComPic::releaseAllReconstructionData()
+{
+  if (m_apcPicYuv[PIC_YUV_REC    ])
+  {
+    m_apcPicYuv[PIC_YUV_REC]->destroy();
+    delete m_apcPicYuv[PIC_YUV_REC];
+    m_apcPicYuv[PIC_YUV_REC] = NULL;
+  }
+  m_picSym.releaseAllReconstructionData();
 }
 #endif
Index: branches/SHM-dev/source/Lib/TLibCommon/TComPic.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComPic.h	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComPic.h	(revision 1574)
@@ -101,8 +101,21 @@
   virtual ~TComPic();
 
+#if REDUCED_ENCODER_MEMORY
+#if SVC_EXTENSION
+  Void          create( const TComSPS &sps, const TComPPS &pps, const Bool bCreateEncoderSourcePicYuv, const Bool bCreateForImmediateReconstruction, const UInt layerId );
+#else
+  Void          create( const TComSPS &sps, const TComPPS &pps, const Bool bCreateEncoderSourcePicYuv, const Bool bCreateForImmediateReconstruction );
+#endif
+  Void          prepareForEncoderSourcePicYuv();
+  Void          prepareForReconstruction();
+  Void          releaseReconstructionIntermediateData();
+  Void          releaseAllReconstructionData();
+  Void          releaseEncoderSourceImageData();
+#else
 #if SVC_EXTENSION
   Void          create( const TComSPS &sps, const TComPPS &pps, const Bool bIsVirtual /*= false*/, const UInt layerId );
 #else
   Void          create( const TComSPS &sps, const TComPPS &pps, const Bool bIsVirtual /*= false*/ );
+#endif
 #endif
 
Index: branches/SHM-dev/source/Lib/TLibCommon/TComPicSym.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComPicSym.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComPicSym.cpp	(revision 1574)
@@ -64,4 +64,7 @@
 ,m_puiTileIdxMap(NULL)
 ,m_ctuRsToTsAddrMap(NULL)
+#if REDUCED_ENCODER_MEMORY
+,m_dpbPerCtuData(NULL)
+#endif
 ,m_saoBlkParams(NULL)
 #if ADAPTIVE_QP_SELECTION
@@ -83,9 +86,18 @@
 }
 
+
 #if SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+Void TComPicSym::create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth, const Bool bAllocateCtuArray, const UInt layerId )
+#else
 Void TComPicSym::create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth, const UInt layerId )
-{
+#endif
+{
+#else
+#if REDUCED_ENCODER_MEMORY
+Void TComPicSym::create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth, const Bool bAllocateCtuArray )
 #else
 Void TComPicSym::create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth )
+#endif
 {
 #endif
@@ -95,5 +107,7 @@
   m_pps = pps;
 
+#if !REDUCED_ENCODER_MEMORY
   const ChromaFormat chromaFormatIDC = sps.getChromaFormatIdc();
+#endif
   const Int iPicWidth      = sps.getPicWidthInLumaSamples();
   const Int iPicHeight     = sps.getPicHeightInLumaSamples();
@@ -114,5 +128,9 @@
 
   m_numCtusInFrame     = m_frameWidthInCtus * m_frameHeightInCtus;
+#if REDUCED_ENCODER_MEMORY
+  m_pictureCtuArray    = NULL;
+#else
   m_pictureCtuArray    = new TComDataCU*[m_numCtusInFrame];
+#endif
 
   clearSliceBuffer();
@@ -126,8 +144,14 @@
   if (m_pParentARLBuffer == NULL)
   {
-     m_pParentARLBuffer = new TCoeff[uiMaxCuWidth*uiMaxCuHeight*MAX_NUM_COMPONENT];
-  }
-#endif
-
+    m_pParentARLBuffer = new TCoeff[uiMaxCuWidth*uiMaxCuHeight*MAX_NUM_COMPONENT];
+  }
+#endif
+
+#if REDUCED_ENCODER_MEMORY
+  if (bAllocateCtuArray)
+  {
+    prepareForReconstruction();
+  }
+#else
   for (UInt i=0; i<m_numCtusInFrame ; i++ )
   {
@@ -139,4 +163,5 @@
       );
   }
+#endif
 
   m_ctuTsToRsAddrMap = new UInt[m_numCtusInFrame+1];
@@ -164,8 +189,44 @@
 }
 
-Void TComPicSym::destroy()
-{
-  clearSliceBuffer();
-
+#if REDUCED_ENCODER_MEMORY
+Void TComPicSym::prepareForReconstruction()
+{
+  const ChromaFormat chromaFormatIDC = m_sps.getChromaFormatIdc();
+  const UInt uiMaxCuWidth  = m_sps.getMaxCUWidth();
+  const UInt uiMaxCuHeight = m_sps.getMaxCUHeight();
+  if (m_pictureCtuArray == NULL)
+  {
+    m_pictureCtuArray = new TComDataCU*[m_numCtusInFrame];
+
+    for (UInt i=0; i<m_numCtusInFrame ; i++ )
+    {
+      m_pictureCtuArray[i] = new TComDataCU;
+      m_pictureCtuArray[i]->create( chromaFormatIDC, m_numPartitionsInCtu, uiMaxCuWidth, uiMaxCuHeight, false, uiMaxCuWidth >> m_uhTotalDepth
+#if ADAPTIVE_QP_SELECTION
+        , m_pParentARLBuffer
+#endif
+        );
+    }
+  }
+  if (m_dpbPerCtuData == NULL)
+  {
+    m_dpbPerCtuData = new DPBPerCtuData[m_numCtusInFrame];
+    for(UInt i=0; i<m_numCtusInFrame; i++)
+    {
+      for(Int j=0; j<NUM_REF_PIC_LIST_01; j++)
+      {
+        m_dpbPerCtuData[i].m_CUMvField[j].create( m_numPartitionsInCtu );
+      }
+      m_dpbPerCtuData[i].m_pePredMode = new SChar[m_numPartitionsInCtu];
+      memset(m_dpbPerCtuData[i].m_pePredMode, m_numPartitionsInCtu, NUMBER_OF_PREDICTION_MODES);
+      m_dpbPerCtuData[i].m_pePartSize = new SChar[m_numPartitionsInCtu];
+      memset(m_dpbPerCtuData[i].m_pePartSize, m_numPartitionsInCtu, NUMBER_OF_PART_SIZES);
+      m_dpbPerCtuData[i].m_pSlice=NULL;
+    }
+  }
+}
+
+Void TComPicSym::releaseReconstructionIntermediateData()
+{
   if (m_pictureCtuArray)
   {
@@ -182,4 +243,49 @@
     m_pictureCtuArray = NULL;
   }
+}
+
+Void TComPicSym::releaseAllReconstructionData()
+{
+  releaseReconstructionIntermediateData();
+
+  if (m_dpbPerCtuData != NULL)
+  {
+    for(UInt i=0; i<m_numCtusInFrame; i++)
+    {
+      for(Int j=0; j<NUM_REF_PIC_LIST_01; j++)
+      {
+        m_dpbPerCtuData[i].m_CUMvField[j].destroy();
+      }
+      delete [] m_dpbPerCtuData[i].m_pePredMode;
+      delete [] m_dpbPerCtuData[i].m_pePartSize;
+    }
+    delete [] m_dpbPerCtuData;
+    m_dpbPerCtuData=NULL;
+  }
+}
+#endif
+
+Void TComPicSym::destroy()
+{
+  clearSliceBuffer();
+
+#if REDUCED_ENCODER_MEMORY
+  releaseAllReconstructionData();
+#else
+  if (m_pictureCtuArray)
+  {
+    for (Int i = 0; i < m_numCtusInFrame; i++)
+    {
+      if (m_pictureCtuArray[i])
+      {
+        m_pictureCtuArray[i]->destroy();
+        delete m_pictureCtuArray[i];
+        m_pictureCtuArray[i] = NULL;
+      }
+    }
+    delete [] m_pictureCtuArray;
+    m_pictureCtuArray = NULL;
+  }
+#endif
 
   delete [] m_ctuTsToRsAddrMap;
Index: branches/SHM-dev/source/Lib/TLibCommon/TComPicSym.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComPicSym.h	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComPicSym.h	(revision 1574)
@@ -106,4 +106,22 @@
   UInt*         m_ctuRsToTsAddrMap;    ///< for a given RS (Raster-Scan) address, returns the TS (Tile-Scan; coding order) address. cf CtbAddrRsToTs in specification.
 
+#if REDUCED_ENCODER_MEMORY
+public:
+  struct DPBPerCtuData
+  {
+    Bool isInter(const UInt absPartAddr)                const { return m_pePredMode[absPartAddr] == MODE_INTER; }
+    PartSize getPartitionSize( const UInt absPartAddr ) const { return static_cast<PartSize>( m_pePartSize[absPartAddr] ); }
+    const TComCUMvField* getCUMvField ( RefPicList e )  const { return &m_CUMvField[e];                  }
+    const TComSlice* getSlice()                         const { return m_pSlice; }
+
+    SChar        * m_pePredMode;
+    SChar        * m_pePartSize;
+    TComCUMvField  m_CUMvField[NUM_REF_PIC_LIST_01];
+    TComSlice    * m_pSlice;
+  };
+
+private:
+  DPBPerCtuData *m_dpbPerCtuData;
+#endif
   SAOBlkParam  *m_saoBlkParams;
 #if ADAPTIVE_QP_SELECTION
@@ -130,10 +148,23 @@
 public:
 #if SVC_EXTENSION
-  Void               create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth, const UInt layerId );
+#if REDUCED_ENCODER_MEMORY
+Void               create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth, const Bool bAllocateCtuArray , const UInt layerId );
+#else
+Void               create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth, const UInt layerId );
+#endif
 #if CGS_3D_ASYMLUT
   TComPPS*           getPPSToUpdate()                                      { return &m_pps; }
 #endif
 #else
-  Void               create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth );
+#if REDUCED_ENCODER_MEMORY
+Void               create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth, const Bool bAllocateCtuArray );
+#else
+Void               create  ( const TComSPS &sps, const TComPPS &pps, UInt uiMaxDepth );
+#endif
+#endif
+#if REDUCED_ENCODER_MEMORY  
+  Void               prepareForReconstruction();
+  Void               releaseReconstructionIntermediateData();
+  Void               releaseAllReconstructionData();
 #endif
   Void               destroy ();
@@ -153,4 +184,9 @@
   const TComSPS&     getSPS()                 const                        { return m_sps; }
   const TComPPS&     getPPS()                 const                        { return m_pps; }
+#if REDUCED_ENCODER_MEMORY
+  Bool                 hasDPBPerCtuData() const                            { return (m_dpbPerCtuData!=0); };
+  DPBPerCtuData&       getDPBPerCtuData(UInt ctuRsAddr)                    { return m_dpbPerCtuData[ctuRsAddr]; }
+  const DPBPerCtuData& getDPBPerCtuData(UInt ctuRsAddr) const              { return m_dpbPerCtuData[ctuRsAddr]; }
+#endif
 
   TComSlice *        swapSliceObject(TComSlice* p, UInt i)                 { p->setSPS(&m_sps); p->setPPS(&m_pps); TComSlice *pTmp=m_apSlices[i];m_apSlices[i] = p; pTmp->setSPS(0); pTmp->setPPS(0); return pTmp; }
Index: branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1574)
@@ -173,4 +173,5 @@
 #define W0062_RECALCULATE_QP_TO_ALIGN_WITH_LAMBDA         0 ///< This recalculates QP to align with the derived lambda (same relation as for all intra coding is used). Currently disabled by default.
 #define OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP            1 ///< Adds command line option to reset SAO parameters after each IRAP.
+#define REDUCED_ENCODER_MEMORY                            1 ///< When 1, the encoder will allocate TComPic memory when required and release it when no longer required.
 
 // ====================================================================================================================
Index: branches/SHM-dev/source/Lib/TLibDecoder/TDecTop.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 1574)
@@ -275,7 +275,15 @@
     }
 
+#if REDUCED_ENCODER_MEMORY
+    rpcPic->create ( sps, pps, false, true, m_layerId);
+#else
     rpcPic->create( sps, pps, true, m_layerId);
+#endif
 #else //SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+    rpcPic->create ( sps, pps, false, true);
+#else
     rpcPic->create ( sps, pps, true);
+#endif
 #endif //SVC_EXTENSION
     
@@ -323,8 +331,15 @@
     xSetRequireResamplingFlag( vps, sps, pps, rpcPic );
   }
-
+#if REDUCED_ENCODER_MEMORY
+  rpcPic->create ( sps, pps, false, true, m_layerId);
+#else
   rpcPic->create( sps, pps, true, m_layerId);
+#endif
 #else  //SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+  rpcPic->create ( sps, pps, false, true);
+#else
   rpcPic->create ( sps, pps, true);
+#endif
 #endif //SVC_EXTENSION
 }
@@ -522,5 +537,9 @@
         pBLPic->getPicSym()->inferSpsForNonHEVCBL(vps, sps->getMaxCUWidth(), sps->getMaxCUHeight());
 
+#if REDUCED_ENCODER_MEMORY
+        pBLPic->create( pBLPic->getPicSym()->getSPS(), *pps, true, true, refLayerId);
+#else
         pBLPic->create( pBLPic->getPicSym()->getSPS(), *pps, true, refLayerId);
+#endif
 
         // it is needed where the VPS is accessed through the slice
@@ -2278,5 +2297,9 @@
         m_cIlpPic[j] = new  TComPic;
 
+#if REDUCED_ENCODER_MEMORY
+        m_cIlpPic[j]->create(*sps, *pps, true, false, m_layerId);
+#else
         m_cIlpPic[j]->create(*sps, *pps, true, m_layerId);
+#endif
 
         for (Int i=0; i<m_cIlpPic[j]->getPicSym()->getNumberOfCtusInFrame(); i++)
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1574)
@@ -1460,4 +1460,8 @@
     xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField );
 
+#if REDUCED_ENCODER_MEMORY
+    pcPic->prepareForReconstruction();
+
+#endif
     //  Slice data initialization
     pcPic->clearSliceBuffer();
@@ -2853,4 +2857,13 @@
       iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
     }
+#if REDUCED_ENCODER_MEMORY
+
+    pcPic->releaseReconstructionIntermediateData();
+    if (!isField) // don't release the source data for field-coding because the fields are dealt with in pairs. // TODO: release source data for interlace simulations.
+    {
+      pcPic->releaseEncoderSourceImageData();
+    }
+
+#endif
   } // iGOPid-loop
 
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncPic.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncPic.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncPic.cpp	(revision 1574)
@@ -125,11 +125,23 @@
 #if SVC_EXTENSION
 // * \param vps reference to used VPS
+#if REDUCED_ENCODER_MEMORY
+Void TEncPic::create( const TComVPS& vps, const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth, const UInt layerId )
+{
+  TComPic::create( sps, pps, true, false, layerId );
+#else
 Void TEncPic::create( const TComVPS& vps, const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth, Bool bIsVirtual, const UInt layerId )
 {
   TComPic::create( sps, pps, bIsVirtual, layerId );
+#endif
+#else
+#if REDUCED_ENCODER_MEMORY
+Void TEncPic::create( const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth )
+{
+  TComPic::create( sps, pps, true, false );
 #else
 Void TEncPic::create( const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth, Bool bIsVirtual )
 {
   TComPic::create( sps, pps, bIsVirtual );
+#endif
 #endif
   const Int  iWidth      = sps.getPicWidthInLumaSamples();
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncPic.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncPic.h	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncPic.h	(revision 1574)
@@ -106,7 +106,15 @@
 
 #if SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+  Void          create( const TComVPS &vps, const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth, const UInt layerId );
+#else
   Void          create( const TComVPS &vps, const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth, Bool bIsVirtual /* = false*/, const UInt layerId );
+#endif
 #else  //SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+  Void          create( const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth );
+#else
   Void          create( const TComSPS &sps, const TComPPS &pps, UInt uiMaxAdaptiveQPDepth, Bool bIsVirtual /* = false*/ );
+#endif
 #endif //SVC_EXTENSION
 
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1573)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1574)
@@ -532,5 +532,7 @@
             
       pcField->getSlice(0)->setPOC( m_iPOCLast );        // superfluous?
+#if !REDUCED_ENCODER_MEMORY
       pcField->getPicYuvRec()->setBorderExtension(false);// where is this normally?
+#endif
 
       pcField->setTopField(isTopField);                  // interlaced requirement
@@ -630,5 +632,7 @@
 
       pcField->getSlice(0)->setPOC( m_iPOCLast );        // superfluous?
+#if !REDUCED_ENCODER_MEMORY
       pcField->getPicYuvRec()->setBorderExtension(false);// where is this normally?
+#endif
 
       pcField->setTopField(isTopField);                  // interlaced requirement
@@ -704,4 +708,8 @@
       }
     }
+#if REDUCED_ENCODER_MEMORY
+    rpcPic->releaseAllReconstructionData();
+    rpcPic->prepareForEncoderSourcePicYuv();
+#endif
   }
   else
@@ -748,8 +756,14 @@
         }
       }
-
-      pcEPic->create( m_cVPS, m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1, false, m_layerId);
+#if REDUCED_ENCODER_MEMORY
+#else
+      pcEPic->create( m_cVPS, m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1, m_layerId);
+#endif
 #else  //SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+      pcEPic->create( m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1);
+#else
       pcEPic->create( m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1, false);
+#endif
 #endif //SVC_EXTENSION
       rpcPic = pcEPic;
@@ -794,7 +808,15 @@
       }
 
+#if REDUCED_ENCODER_MEMORY
+      rpcPic->create( m_cSPS, m_cPPS, true, false, m_layerId );
+#else
       rpcPic->create( m_cSPS, m_cPPS, false, m_layerId );
+#endif
 #else  //SVC_EXTENSION
+#if REDUCED_ENCODER_MEMORY
+      rpcPic->create( m_cSPS, m_cPPS, true, false );
+#else
       rpcPic->create( m_cSPS, m_cPPS, false );
+#endif      
 #endif //SVC_EXTENSION
     }
@@ -808,6 +830,8 @@
 
   rpcPic->getSlice(0)->setPOC( m_iPOCLast );
+#if !REDUCED_ENCODER_MEMORY
   // mark it should be extended
   rpcPic->getPicYuvRec()->setBorderExtension(false);
+#endif
 }
 
@@ -1732,5 +1756,9 @@
       {
         m_cIlpPic[j] = new TComPic;
+#if REDUCED_ENCODER_MEMORY
+        m_cIlpPic[j]->create(m_cSPS, m_cPPS, true, false, m_layerId);
+#else
         m_cIlpPic[j]->create(m_cSPS, m_cPPS, true, m_layerId);
+#endif
         for (Int i=0; i<m_cIlpPic[j]->getPicSym()->getNumberOfCtusInFrame(); i++)
         {
