Index: branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecCfg.cpp
===================================================================
--- branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecCfg.cpp	(revision 367)
+++ branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecCfg.cpp	(revision 368)
@@ -42,4 +42,7 @@
 #include "TAppCommon/program_options_lite.h"
 
+#if H_MV
+#include <cassert>
+#endif
 #ifdef WIN32
 #define strdup _strdup
@@ -75,4 +78,7 @@
   ("OutputBitDepth,d", m_outputBitDepthY, 0, "bit depth of YUV output luma component (default: use 0 for native depth)")
   ("OutputBitDepthC,d", m_outputBitDepthC, 0, "bit depth of YUV output chroma component (default: use 0 for native depth)")
+#if H_MV
+  ("MaxLayerId,-ls", m_maxLayerId, MAX_NUM_LAYER_IDS-1, "Maximum LayerId to be decoded.")
+#endif
   ("MaxTemporalLayer,t", m_iMaxTemporalLayer, -1, "Maximum Temporal Layer to be decoded. -1 to decode all layers")
   ("SEIDecodedPictureHash", m_decodedPictureHashSEIEnabled, 1, "Control handling of decoded picture hash SEI messages\n"
@@ -151,7 +157,33 @@
     }
   }
+#if H_MV
+  else
+  {
+    for ( Int curLayerId = 0; curLayerId <= m_maxLayerId; curLayerId++ )
+    {
+      m_targetDecLayerIdSet.push_back( curLayerId );
+    }
+  }
+#endif
 
   return true;
 }
 
+#if H_MV
+Void TAppDecCfg::xAppendToFileNameEnd( Char* pchInputFileName, const Char* pchStringToAppend, Char*& rpchOutputFileName)
+{
+  size_t iInLength     = strlen(pchInputFileName);
+  size_t iAppendLength = strlen(pchStringToAppend); 
+
+  rpchOutputFileName = (Char*) malloc(iInLength+iAppendLength+1);                        
+  Char* pCDot = strrchr(pchInputFileName,'.');         
+  pCDot = pCDot ? pCDot : pchInputFileName + iInLength;        
+  size_t iCharsToDot = pCDot - pchInputFileName ; 
+  size_t iCharsToEnd = iInLength - iCharsToDot;         
+  strncpy(rpchOutputFileName                            ,  pchInputFileName            , iCharsToDot  );
+  strncpy(rpchOutputFileName+ iCharsToDot               ,  pchStringToAppend           , iAppendLength); 
+  strncpy(rpchOutputFileName+ iCharsToDot+iAppendLength ,  pchInputFileName+iCharsToDot, iCharsToEnd  );        
+  rpchOutputFileName[iInLength+iAppendLength] = '\0';          
+}
+#endif
 //! \}
Index: branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecCfg.h
===================================================================
--- branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecCfg.h	(revision 367)
+++ branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecCfg.h	(revision 368)
@@ -58,4 +58,8 @@
 protected:
   Char*         m_pchBitstreamFile;                   ///< input bitstream file name
+#if H_MV
+  Int           m_maxLayerId;                         ///< maximum nuh_layer_id decoded
+  std::vector<Char*> m_pchReconFiles;                 ///< array of output reconstruction file name create from output reconstruction file name
+#endif
   Char*         m_pchReconFile;                       ///< output reconstruction file name
   Int           m_iSkipFrame;                         ///< counter for frames prior to the random access point to skip
@@ -69,7 +73,14 @@
   Int           m_respectDefDispWindow;               ///< Only output content inside the default display window 
 
+#if H_MV
+  Void xAppendToFileNameEnd( Char* pchInputFileName, const Char* pchStringToAppend, Char*& rpchOutputFileName); ///< create filenames
+#endif
 public:
   TAppDecCfg()
   : m_pchBitstreamFile(NULL)
+#if H_MV
+  , m_maxLayerId(0)
+  , m_pchReconFiles(NULL) 
+#endif
   , m_pchReconFile(NULL)
   , m_iSkipFrame(0)
Index: branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecTop.cpp
===================================================================
--- branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecTop.cpp	(revision 367)
+++ branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecTop.cpp	(revision 368)
@@ -54,7 +54,14 @@
 
 TAppDecTop::TAppDecTop()
+#if !H_MV
 : m_iPOCLastDisplay(-MAX_INT)
+#else
+: m_numDecoders( 0 )
+#endif
 {
   ::memset (m_abDecFlag, 0, sizeof (m_abDecFlag));
+#if H_MV
+  for (Int i = 0; i < MAX_NUM_LAYER_IDS; i++) m_layerIdToDecIdx[i] = -1; 
+#endif
 }
 
@@ -70,4 +77,14 @@
     m_pchBitstreamFile = NULL;
   }
+#if H_MV
+  for (Int decIdx = 0; decIdx < m_numDecoders; decIdx++)
+  {
+    if (m_pchReconFiles[decIdx])
+    {
+      free (m_pchReconFiles[decIdx]);
+      m_pchReconFiles[decIdx] = NULL;
+    }
+  }
+#endif
   if (m_pchReconFile)
   {
@@ -92,4 +109,7 @@
 {
   Int                 poc;
+#if H_MV
+  poc = -1; 
+#endif
   TComList<TComPic*>* pcListPic = NULL;
 
@@ -106,8 +126,21 @@
   xCreateDecLib();
   xInitDecLib  ();
+#if !H_MV
   m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.
 
   // main decoder loop
   Bool recon_opened = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
+#else
+  Int  pocCurrPic        = -MAX_INT;     
+  Int  pocLastPic        = -MAX_INT;   
+  
+  Int  layerIdLastPic    = 0; 
+  Int  layerIdCurrPic    = 0; 
+
+  Int  decIdxLastPic     = 0; 
+  Int  decIdxCurrPic     = 0; 
+
+  Bool firstSlice        = true; 
+#endif
  
   while (!!bitstreamFile)
@@ -119,5 +152,7 @@
     streampos location = bitstreamFile.tellg();
     AnnexBStats stats = AnnexBStats();
+#if !H_MV
     Bool bPreviousPictureDecoded = false;
+#endif
 
     vector<uint8_t> nalUnit;
@@ -127,4 +162,9 @@
     // call actual decoding function
     Bool bNewPicture = false;
+#if H_MV
+    Bool newSliceDiffPoc   = false;
+    Bool newSliceDiffLayer = false;
+    Bool allLayersDecoded  = false;     
+#endif
     if (nalUnit.empty())
     {
@@ -139,4 +179,46 @@
     {
       read(nalu, nalUnit);
+#if H_MV      
+      Int decIdx     = xGetDecoderIdx( nalu.m_layerId , true );
+      
+      if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu) )
+      {
+        bNewPicture = false;
+      }
+      else
+      { 
+        newSliceDiffLayer = nalu.isSlice() && ( nalu.m_layerId != layerIdCurrPic ) && !firstSlice;
+        newSliceDiffPoc   = m_tDecTop[decIdx]->decode(nalu, m_iSkipFrame, m_pocLastDisplay[decIdx], newSliceDiffLayer );
+        // decode function only returns true when all of the following conditions are true
+        // - poc in particular layer changes
+        // - nalu does not belong to first slice in layer
+        // - nalu.isSlice() == true      
+
+        bNewPicture       = newSliceDiffLayer || newSliceDiffPoc; 
+
+        if ( nalu.isSlice() && firstSlice )
+        {
+          layerIdCurrPic = nalu.m_layerId; 
+          pocCurrPic     = m_tDecTop[decIdx]->getCurrPoc(); 
+          decIdxCurrPic  = decIdx; 
+          firstSlice     = false; 
+        }
+
+        if ( bNewPicture || !bitstreamFile )
+        { 
+          layerIdLastPic    = layerIdCurrPic;  
+          layerIdCurrPic    = nalu.m_layerId; 
+          
+          pocLastPic        = pocCurrPic; 
+          pocCurrPic        = m_tDecTop[decIdx]->getCurrPoc(); 
+          
+          decIdxLastPic     = decIdxCurrPic; 
+          decIdxCurrPic     = decIdx; 
+
+          allLayersDecoded = ( pocCurrPic != pocLastPic );
+        }
+
+        
+#else
       if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
       {
@@ -154,4 +236,5 @@
       {
         bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
+#endif
         if (bNewPicture)
         {
@@ -164,23 +247,52 @@
           bytestream.reset();
         }
+#if !H_MV
         bPreviousPictureDecoded = true; 
+#endif
       }
     }
     if (bNewPicture || !bitstreamFile)
     {
+#if H_MV
+      assert( decIdxLastPic != -1 ); 
+      m_tDecTop[decIdxLastPic]->endPicDecoding(poc, pcListPic, m_targetDecLayerIdSet );
+#else
       m_cTDecTop.executeLoopFilters(poc, pcListPic);
-    }
+#endif
+    }
+#if H_3D
+    if ( allLayersDecoded || !bitstreamFile )
+    {
+      for( Int dI = 0; dI < m_numDecoders; dI++ )
+      {
+        TComPic* picLastCoded = m_ivPicLists.getPic( m_tDecTop[dI]->getLayerId(), pocLastPic );
+        assert( picLastCoded != NULL );        
+        picLastCoded->compressMotion();         
+      }
+    }
+#endif
 
     if( pcListPic )
     {
+#if H_MV
+      if ( m_pchReconFiles[decIdxLastPic] && !m_reconOpen[decIdxLastPic] )
+#else
       if ( m_pchReconFile && !recon_opened )
+#endif
       {
         if (!m_outputBitDepthY) { m_outputBitDepthY = g_bitDepthY; }
         if (!m_outputBitDepthC) { m_outputBitDepthC = g_bitDepthC; }
 
+#if H_MV
+        m_tVideoIOYuvReconFile[decIdxLastPic]->open( m_pchReconFiles[decIdxLastPic], true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
+        m_reconOpen[decIdxLastPic] = true;
+      }
+      if ( bNewPicture && newSliceDiffPoc && 
+#else
         m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode
         recon_opened = true;
       }
       if ( bNewPicture && 
+#endif
            (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
             || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
@@ -189,9 +301,24 @@
             || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
       {
+#if H_MV
+        xFlushOutput( pcListPic, decIdxLastPic );
+#else
         xFlushOutput( pcListPic );
+#endif
       }
       // write reconstruction to file
       if(bNewPicture)
       {
+#if H_MV
+        xWriteOutput( pcListPic, decIdxLastPic, nalu.m_temporalId );
+      }
+    }
+  }
+
+  for(UInt decIdx = 0; decIdx < m_numDecoders; decIdx++)
+  {
+    xFlushOutput( m_tDecTop[decIdx]->getListPic(), decIdx );
+  }
+#else
         xWriteOutput( pcListPic, nalu.m_temporalId );
       }
@@ -202,4 +329,5 @@
   // delete buffers
   m_cTDecTop.deletePicBuffer();
+#endif
      
   // destroy internal classes
@@ -213,10 +341,37 @@
 Void TAppDecTop::xCreateDecLib()
 {
+#if H_MV
+  // initialize global variables
+  initROM();  
+#else
   // create decoder class
   m_cTDecTop.create();
+#endif
 }
 
 Void TAppDecTop::xDestroyDecLib()
 {
+#if H_MV
+  // destroy ROM
+  destroyROM();
+
+  for(Int decIdx = 0; decIdx < m_numDecoders ; decIdx++)
+  {
+    if( m_tVideoIOYuvReconFile[decIdx] )
+    {
+      m_tVideoIOYuvReconFile[decIdx]->close();
+      delete m_tVideoIOYuvReconFile[decIdx]; 
+      m_tVideoIOYuvReconFile[decIdx] = NULL ;
+    }
+
+    if( m_tDecTop[decIdx] )
+    {
+      m_tDecTop[decIdx]->deletePicBuffer();
+      m_tDecTop[decIdx]->destroy() ;
+    }
+    delete m_tDecTop[decIdx] ; 
+    m_tDecTop[decIdx] = NULL ;
+  }
+#else
   if ( m_pchReconFile )
   {
@@ -226,11 +381,14 @@
   // destroy decoder class
   m_cTDecTop.destroy();
+#endif
 }
 
 Void TAppDecTop::xInitDecLib()
 {
+#if !H_MV
   // initialize decoder class
   m_cTDecTop.init();
   m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
+#endif
 }
 
@@ -238,5 +396,9 @@
     \todo            DYN_REF_FREE should be revised
  */
+#if H_MV
+Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, Int decIdx, Int tId )
+#else
 Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
+#endif
 {
   TComList<TComPic*>::iterator iterPic   = pcListPic->begin();
@@ -246,5 +408,9 @@
   {
     TComPic* pcPic = *(iterPic);
+#if H_MV
+    if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx])
+#else
     if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
+#endif
     {
        not_displayed++;
@@ -258,13 +424,25 @@
     TComPic* pcPic = *(iterPic);
     
+#if H_MV
+    if ( pcPic->getOutputMark() && (not_displayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_pocLastDisplay[decIdx]))
+#else
     if ( pcPic->getOutputMark() && (not_displayed >  pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_iPOCLastDisplay))
+#endif
     {
       // write to file
        not_displayed--;
+#if H_MV
+      if ( m_pchReconFiles[decIdx] )
+#else
       if ( m_pchReconFile )
+#endif
       {
         const Window &conf = pcPic->getConformanceWindow();
         const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
+#if H_MV
+        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
+#else
         m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
+#endif
                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
@@ -274,5 +452,9 @@
       
       // update POC of display order
+#if H_MV
+      m_pocLastDisplay[decIdx] = pcPic->getPOC();
+#else
       m_iPOCLastDisplay = pcPic->getPOC();
+#endif
       
       // erase non-referenced picture in the reference picture list after display
@@ -302,5 +484,9 @@
     \todo            DYN_REF_FREE should be revised
  */
+#if H_MV
+Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int decIdx )
+#else
 Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
+#endif
 {
   if(!pcListPic)
@@ -319,9 +505,17 @@
     {
       // write to file
+#if H_MV
+      if ( m_pchReconFiles[decIdx] )
+#else
       if ( m_pchReconFile )
+#endif
       {
         const Window &conf = pcPic->getConformanceWindow();
         const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
+#if H_MV
+        m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
+#else
         m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
+#endif
                                        conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
                                        conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
@@ -331,5 +525,9 @@
       
       // update POC of display order
+#if H_MV
+      m_pocLastDisplay[decIdx] = pcPic->getPOC();
+#else
       m_iPOCLastDisplay = pcPic->getPOC();
+#endif
       
       // erase non-referenced picture in the reference picture list after display
@@ -351,4 +549,5 @@
       pcPic->setOutputMark(false);
     }
+#if !H_MV
 #if !DYN_REF_FREE
     if(pcPic)
@@ -359,8 +558,13 @@
     }
 #endif 
+#endif
     iterPic++;
   }
+#if H_MV
+  m_pocLastDisplay[decIdx] = -MAX_INT;
+#else
   pcListPic->clear();
   m_iPOCLastDisplay = -MAX_INT;
+#endif
 }
 
@@ -375,5 +579,9 @@
   for (std::vector<Int>::iterator it = m_targetDecLayerIdSet.begin(); it != m_targetDecLayerIdSet.end(); it++)
   {
+#if H_MV
+    if ( nalu->m_layerId == (*it) )
+#else
     if ( nalu->m_reservedZero6Bits == (*it) )
+#endif
     {
       return true;
Index: branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecTop.h
===================================================================
--- branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecTop.h	(revision 367)
+++ branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/TAppDecTop.h	(revision 368)
@@ -61,10 +61,23 @@
 private:
   // class interface
+#if H_MV
+  TDecTop*                        m_tDecTop             [ MAX_NUM_LAYERS ];    ///< decoder classes
+  TVideoIOYuv*                    m_tVideoIOYuvReconFile[ MAX_NUM_LAYERS ];    ///< reconstruction YUV class
+  Int                             m_layerIdToDecIdx     [ MAX_NUM_LAYER_IDS ]; ///< maping from layer id to decoder index
+  Int                             m_numDecoders;                               ///< number of decoder instances
+  TComPicLists                    m_ivPicLists;                                ///< picture buffers of decoder instances
+#else
   TDecTop                         m_cTDecTop;                     ///< decoder class
   TVideoIOYuv                     m_cTVideoIOYuvReconFile;        ///< reconstruction YUV class
+#endif
   
   // for output control
   Bool                            m_abDecFlag[ MAX_GOP ];         ///< decoded flag in one GOP
+#if H_MV
+  Int                             m_pocLastDisplay      [ MAX_NUM_LAYERS ]; ///< last POC in display order
+  Bool                            m_reconOpen           [ MAX_NUM_LAYERS ]; ///< reconstruction file opened
+#else
   Int                             m_iPOCLastDisplay;              ///< last POC in display order
+#endif
   
 public:
@@ -81,6 +94,61 @@
   Void  xInitDecLib       (); ///< initialize decoder class
   
+#if H_MV
+  Void  xWriteOutput      ( TComList<TComPic*>* pcListPic, Int layerId, Int tId ); ///< write YUV to file
+  Void  xFlushOutput      ( TComList<TComPic*>* pcListPic, Int layerId ); ///< flush all remaining decoded pictures to file
+  Int   xGetDecoderIdx    ( Int layerId, Bool createFlag = false )
+  { 
+    Int decIdx = -1; 
+    if ( m_layerIdToDecIdx[ layerId ] != -1 ) 
+    {      
+      decIdx = m_layerIdToDecIdx[ layerId ]; 
+    }
+    else
+    {      
+      assert ( createFlag ); 
+      assert( m_numDecoders < MAX_NUM_LAYERS ); 
+
+      decIdx = m_numDecoders; 
+      
+      // Init decoder
+      m_tDecTop[ decIdx ] =  new TDecTop;
+      m_tDecTop[ decIdx ]->create();
+      m_tDecTop[ decIdx ]->init( );
+      m_tDecTop[ decIdx ]->setLayerId( layerId );
+      m_tDecTop[ decIdx ]->setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
+      m_tDecTop[ decIdx ]->setIvPicLists( &m_ivPicLists ); 
+     
+      // append pic list of new decoder to PicLists 
+      assert( m_ivPicLists.size() == m_numDecoders );
+      m_ivPicLists.push_back( m_tDecTop[ decIdx ]->getListPic() );
+
+      // create recon file related stuff      
+      Char* pchTempFilename = NULL;
+      if ( m_pchReconFile )
+      {      
+        Char buffer[4];      
+        sprintf(buffer,"_%i", layerId );
+        assert ( m_pchReconFile ); 
+        xAppendToFileNameEnd( m_pchReconFile , buffer, pchTempFilename );
+        assert( m_pchReconFiles.size() == m_numDecoders );
+      }
+
+      m_pchReconFiles.push_back( pchTempFilename );   
+
+      m_tVideoIOYuvReconFile[ decIdx ] = new TVideoIOYuv;
+      m_reconOpen           [ decIdx ] = false;
+
+      // set others 
+      m_pocLastDisplay      [ decIdx ] = -MAX_INT;
+      m_layerIdToDecIdx     [ layerId ] = decIdx; 
+
+      m_numDecoders++; 
+    };
+    return decIdx; 
+  }
+#else
   Void  xWriteOutput      ( TComList<TComPic*>* pcListPic , UInt tId); ///< write YUV to file
   Void  xFlushOutput      ( TComList<TComPic*>* pcListPic ); ///< flush all remaining decoded pictures to file
+#endif
   Bool  isNaluWithinTargetDecLayerIdSet ( InputNALUnit* nalu ); ///< check whether given Nalu is within targetDecLayerIdSet
 };
Index: branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/decmain.cpp
===================================================================
--- branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/decmain.cpp	(revision 367)
+++ branches/HTM-DEV-0.1-dev/source/App/TAppDecoder/decmain.cpp	(revision 368)
@@ -56,5 +56,9 @@
   // print information
   fprintf( stdout, "\n" );
+#if H_MV
+  fprintf( stdout, "3D-HTM Software: Decoder Version [%s] based on HM Version [%s]", NV_VERSION, HM_VERSION );  
+#else
   fprintf( stdout, "HM software: Decoder Version [%s]", NV_VERSION );
+#endif
   fprintf( stdout, NVM_ONOS );
   fprintf( stdout, NVM_COMPILEDBY );
