Index: trunk/source/App/TAppDecoder/TAppDecTop.cpp
===================================================================
--- trunk/source/App/TAppDecoder/TAppDecTop.cpp	(revision 597)
+++ trunk/source/App/TAppDecoder/TAppDecTop.cpp	(revision 644)
@@ -41,9 +41,8 @@
 #include <fcntl.h>
 #include <assert.h>
-
+#include <iostream>
 #include "TAppDecTop.h"
 #include "TLibDecoder/AnnexBread.h"
 #include "TLibDecoder/NALread.h"
-
 //! \ingroup TAppDecoder
 //! \{
@@ -255,4 +254,44 @@
         openedReconFile[curLayerId] = true;
       }
+#if ALIGNED_BUMPING
+      Bool outputPicturesFlag = true;  
+#if NO_OUTPUT_OF_PRIOR_PICS
+      if( m_acTDecTop[nalu.m_layerId].getNoOutputOfPriorPicsFlags() )
+      {
+        outputPicturesFlag = false;
+      }
+#endif
+
+      if (nalu.m_nalUnitType == NAL_UNIT_EOS) // End of sequence
+      {
+        flushAllPictures( nalu.m_layerId, outputPicturesFlag );       
+      }
+      if( bNewPicture ) // New picture, slice header parsed but picture not decoded
+      {
+#if NO_OUTPUT_OF_PRIOR_PICS
+        if( 
+#else
+        if ( bNewPOC &&
+#endif
+           (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
+            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
+            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP
+            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL
+            || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) )
+        {
+          flushAllPictures( nalu.m_layerId, outputPicturesFlag );
+        }
+        else
+        {
+          this->checkOutputBeforeDecoding( nalu.m_layerId );
+        }
+      }
+
+      /* The following code has to be executed when the last DU of the picture is decoded
+         TODO: Need code to identify end of decoding a picture
+      {
+        this->checkOutputAfterDecoding( );
+      } */
+#else
       if ( bNewPicture && bNewPOC &&
            (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
@@ -273,10 +312,15 @@
         xWriteOutput( pcListPic, curLayerId, nalu.m_temporalId );
       }
-    }
-  }
+#endif
+    }
+  }
+#if ALIGNED_BUMPING
+   flushAllPictures( true );   
+#else
   for(UInt layer = 0; layer <= m_tgtLayerId; layer++)
   {
     xFlushOutput( m_acTDecTop[layer].getListPic(), layer );
   }
+#endif
   // delete buffers
 #if AVC_BASE
@@ -987,4 +1031,403 @@
   return false;
 }
-
+#if ALIGNED_BUMPING
+// Function outputs a picture, and marks it as not needed for output.
+Void TAppDecTop::xOutputAndMarkPic( TComPic *pic, const Char *reconFile, const Int layerIdx, Int &pocLastDisplay, DpbStatus &dpbStatus )
+{
+  if ( reconFile )
+  {
+    const Window &conf = pic->getConformanceWindow();
+    const Window &defDisp = m_respectDefDispWindow ? pic->getDefDisplayWindow() : Window();
+    Int xScal =  1, yScal = 1;
+#if REPN_FORMAT_IN_VPS
+    UInt chromaFormatIdc = pic->getSlice(0)->getChromaFormatIdc();
+    xScal = TComSPS::getWinUnitX( chromaFormatIdc );
+    yScal = TComSPS::getWinUnitY( chromaFormatIdc );
+#endif
+    m_acTVideoIOYuvReconFile[layerIdx].write( pic->getPicYuvRec(),
+      conf.getWindowLeftOffset()  * xScal + defDisp.getWindowLeftOffset(),
+      conf.getWindowRightOffset() * xScal + defDisp.getWindowRightOffset(),
+      conf.getWindowTopOffset()   * yScal + defDisp.getWindowTopOffset(),
+      conf.getWindowBottomOffset()* yScal + defDisp.getWindowBottomOffset() );
+  }
+  // update POC of display order
+  pocLastDisplay = pic->getPOC();
+
+  // Mark as not needed for output
+  pic->setOutputMark(false);
+
+  // "erase" non-referenced picture in the reference picture list after display
+  if ( !pic->getSlice(0)->isReferenced() && pic->getReconMark() == true )
+  {
+    pic->setReconMark(false);
+
+    // mark it should be extended later
+    pic->getPicYuvRec()->setBorderExtension( false );
+
+    dpbStatus.m_numPicsInLayer[layerIdx]--;
+  }
+}
+
+Void TAppDecTop::flushAllPictures(Int layerId, Bool outputPictures)
+{
+  // First "empty" all pictures that are not used for reference and not needed for output
+  emptyUnusedPicturesNotNeededForOutput();
+
+  if( outputPictures )  // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
+  {
+    std::vector<Int>  listOfPocs;
+    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
+    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
+    DpbStatus dpbStatus;
+
+    // Find the status of the DPB
+    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
+
+    if( listOfPocs.size() )
+    {
+      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
+      {
+        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
+      }
+    }
+  }
+
+  // Now remove all pictures from the layer DPB?
+  markAllPicturesAsErased(layerId);
+}
+Void TAppDecTop::flushAllPictures(Bool outputPictures)
+{
+  // First "empty" all pictures that are not used for reference and not needed for output
+  emptyUnusedPicturesNotNeededForOutput();
+
+  if( outputPictures )  // All pictures in the DPB are to be output
+  {
+    std::vector<Int>  listOfPocs;
+    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
+    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
+    DpbStatus dpbStatus;
+
+    // Find the status of the DPB
+    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
+
+    while( dpbStatus.m_numAUsNotDisplayed )
+    {
+      bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
+    }
+  }
+
+  // Now remove all pictures from the DPB?
+  markAllPicturesAsErased();
+}
+
+Void TAppDecTop::markAllPicturesAsErased()
+{
+  for(Int i = 0; i < MAX_LAYERS; i++)
+  {
+    m_acTDecTop[i].getListPic()->clear();
+  }
+}
+
+Void TAppDecTop::markAllPicturesAsErased(Int layerIdx)
+{
+  m_acTDecTop[layerIdx].getListPic()->clear();
+}
+
+Void TAppDecTop::checkOutputBeforeDecoding(Int layerIdx)
+{
+    
+  std::vector<Int>  listOfPocs;
+  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
+  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
+  DpbStatus dpbStatus;
+
+  // First "empty" all pictures that are not used for reference and not needed for output
+  emptyUnusedPicturesNotNeededForOutput();
+
+  // Find the status of the DPB
+  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
+
+  // If not picture to be output, return
+  if( listOfPocs.size() == 0 )
+  {
+    return;
+  }
+
+  // Find DPB-information from the VPS
+  DpbStatus maxDpbLimit;
+  Int targetLsIdx, subDpbIdx;
+  TComVPS *vps = findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
+  if( getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 )
+  {
+    targetLsIdx = 0;
+    subDpbIdx   = 0; 
+  }
+  else
+  {
+    targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
+    subDpbIdx   = vps->getSubDpbAssigned( targetLsIdx, layerIdx );
+  }
+  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
+  while( ifInvokeBumpingBeforeDecoding(dpbStatus, maxDpbLimit, layerIdx, subDpbIdx) )
+  {
+    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
+  }  
+}
+
+Void TAppDecTop::checkOutputAfterDecoding()
+{    
+  std::vector<Int>  listOfPocs;
+  std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
+  std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
+  DpbStatus dpbStatus;
+
+  // First "empty" all pictures that are not used for reference and not needed for output
+  emptyUnusedPicturesNotNeededForOutput();
+
+  // Find the status of the DPB
+  xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
+
+  // If not picture to be output, return
+  if( listOfPocs.size() == 0 )
+  {
+    return;
+  }
+
+  // Find DPB-information from the VPS
+  DpbStatus maxDpbLimit;
+  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
+
+  // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
+  while( ifInvokeBumpingAfterDecoding(dpbStatus, maxDpbLimit) )
+  {
+    bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
+  }  
+}
+
+Void TAppDecTop::bumpingProcess(std::vector<Int> &listOfPocs, std::vector<Int> *listOfPocsInEachLayer, std::vector<Int> *listOfPocsPositionInEachLayer, DpbStatus &dpbStatus)
+{
+  // Choose the smallest POC value
+  Int pocValue = *(listOfPocs.begin());
+  std::vector<int>::iterator it;
+  TComList<TComPic*>::iterator iterPic;
+  for( Int layerIdx = 0; layerIdx < dpbStatus.m_numLayers; layerIdx++)
+  {
+    // Check if picture with pocValue is present.
+    it = find( listOfPocsInEachLayer[layerIdx].begin(), listOfPocsInEachLayer[layerIdx].end(), pocValue );
+    if( it != listOfPocsInEachLayer[layerIdx].end() )  // picture found.
+    {
+      Int picPosition = std::distance( listOfPocsInEachLayer[layerIdx].begin(), it );
+      Int j;
+      for(j = 0, iterPic = m_acTDecTop[layerIdx].getListPic()->begin(); j < listOfPocsPositionInEachLayer[layerIdx][picPosition]; j++) // Picture to be output
+      {
+        iterPic++;
+      }
+      TComPic *pic = *iterPic;
+
+      xOutputAndMarkPic( pic, m_pchReconFile[layerIdx], layerIdx, m_aiPOCLastDisplay[layerIdx], dpbStatus );
+
+      listOfPocsInEachLayer[layerIdx].erase( it );
+      listOfPocsPositionInEachLayer[layerIdx].erase( listOfPocsPositionInEachLayer[layerIdx].begin() + picPosition );
+    }
+  }
+  // Update sub-DPB status
+  for( Int subDpbIdx = 0; subDpbIdx < dpbStatus.m_numSubDpbs; subDpbIdx++)
+  {
+    dpbStatus.m_numPicsInSubDpb[subDpbIdx]--;
+  }
+  dpbStatus.m_numAUsNotDisplayed--;    
+
+  // Remove the picture from the listOfPocs
+  listOfPocs.erase( listOfPocs.begin() );
+}
+
+TComVPS *TAppDecTop::findDpbParametersFromVps(std::vector<Int> const &listOfPocs, std::vector<Int> const *listOfPocsInEachLayer, std::vector<Int> const *listOfPocsPositionInEachLayer, DpbStatus &maxDpbLimit)
+{
+  Int targetOutputLsIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx();
+  TComVPS *vps = NULL;
+
+  if( targetOutputLsIdx == 0 )   // Only base layer is output
+  {
+    TComSPS *sps = NULL;
+    assert( listOfPocsInEachLayer[0].size() != 0 );
+    TComList<TComPic*>::iterator iterPic;
+    Int j;
+    for(j = 0, iterPic = m_acTDecTop[0].getListPic()->begin(); j < listOfPocsPositionInEachLayer[0][0]; j++) // Picture to be output
+    {
+      iterPic++;
+    }
+    TComPic *pic = *iterPic;
+    sps = pic->getSlice(0)->getSPS();   assert( sps->getLayerId() == 0 );
+    vps = pic->getSlice(0)->getVPS();
+    Int highestTId = sps->getMaxTLayers() - 1;
+
+    maxDpbLimit.m_numAUsNotDisplayed = sps->getNumReorderPics( highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
+    maxDpbLimit.m_maxLatencyIncrease = sps->getMaxLatencyIncrease( highestTId ) > 0;
+    if( maxDpbLimit.m_maxLatencyIncrease )
+    {
+      maxDpbLimit.m_maxLatencyPictures = sps->getMaxLatencyIncrease( highestTId ) + sps->getNumReorderPics( highestTId ) - 1;
+    }
+    maxDpbLimit.m_numPicsInLayer[0] = sps->getMaxDecPicBuffering( highestTId );
+    maxDpbLimit.m_numPicsInSubDpb[0] = sps->getMaxDecPicBuffering( highestTId );
+  }
+  else
+  {
+    // -------------------------------------
+    // Find the VPS used for the pictures
+    // -------------------------------------
+    for(Int i = 0; i < MAX_LAYERS; i++)
+    {
+      if( m_acTDecTop[i].getListPic()->empty() )
+      {
+        assert( listOfPocsInEachLayer[i].size() == 0 );
+        continue;
+      }
+      std::vector<Int>::const_iterator it;
+      it = find( listOfPocsInEachLayer[i].begin(), listOfPocsInEachLayer[i].end(), listOfPocs[0] );
+      TComList<TComPic*>::iterator iterPic;
+      if( it != listOfPocsInEachLayer[i].end() )
+      {
+        Int picPosition = std::distance( listOfPocsInEachLayer[i].begin(), it );
+        Int j;
+        for(j = 0, iterPic = m_acTDecTop[i].getListPic()->begin(); j < listOfPocsPositionInEachLayer[i][picPosition]; j++) // Picture to be output
+        {
+          iterPic++;
+        }
+        TComPic *pic = *iterPic;
+        vps = pic->getSlice(0)->getVPS();
+        break;
+      }
+    }
+
+    Int targetLsIdx       = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
+    Int highestTId = vps->getMaxTLayers() - 1;
+
+    maxDpbLimit.m_numAUsNotDisplayed = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ); // m_numAUsNotDisplayed is only variable name - stores reorderpics
+    maxDpbLimit.m_maxLatencyIncrease  = vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) > 0;
+    if( maxDpbLimit.m_maxLatencyIncrease )
+    {
+      maxDpbLimit.m_maxLatencyPictures = vps->getMaxVpsNumReorderPics( targetOutputLsIdx, highestTId ) + vps->getMaxVpsLatencyIncreasePlus1(targetOutputLsIdx, highestTId ) - 1;
+    }
+    for(Int i = 0; i < vps->getNumLayersInIdList( targetLsIdx ); i++)
+    {
+      maxDpbLimit.m_numPicsInLayer[i] = vps->getMaxVpsLayerDecPicBuffMinus1( targetOutputLsIdx, i, highestTId ) + 1;
+      maxDpbLimit.m_numPicsInSubDpb[vps->getSubDpbAssigned( targetLsIdx, i )] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, vps->getSubDpbAssigned( targetLsIdx, i ), highestTId) + 1;
+    }
+    // -------------------------------------
+  }
+  return vps;
+}
+Void TAppDecTop::emptyUnusedPicturesNotNeededForOutput()
+{
+  for(Int layerIdx = 0; layerIdx < MAX_LAYERS; layerIdx++)
+  {
+    TComList <TComPic*> *pcListPic = m_acTDecTop[layerIdx].getListPic();
+    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
+    while ( iterPic != pcListPic->end() )
+    {
+      TComPic *pic = *iterPic;
+      if( !pic->getSlice(0)->isReferenced() && !pic->getOutputMark() )
+      {
+        // Emtpy the picture buffer
+        pic->setReconMark( false );
+      }
+      iterPic++;
+    }
+  }
+}
+
+Bool TAppDecTop::ifInvokeBumpingBeforeDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit, const Int layerIdx, const Int subDpbIdx )
+{
+  Bool retVal = false;
+  // Number of reorder picutres
+  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
+
+  // Number of pictures in each sub-DPB
+  retVal |= ( dpbStatus.m_numPicsInSubDpb[subDpbIdx] >= dpbLimit.m_numPicsInSubDpb[subDpbIdx] );
+  
+  // Number of pictures in each layer
+  retVal |= ( dpbStatus.m_numPicsInLayer[layerIdx] >= dpbLimit.m_numPicsInLayer[layerIdx]);
+
+  return retVal;
+}
+
+Bool TAppDecTop::ifInvokeBumpingAfterDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit )
+{
+  Bool retVal = false;
+
+  // Number of reorder picutres
+  retVal |= ( dpbStatus.m_numAUsNotDisplayed > dpbLimit.m_numAUsNotDisplayed );
+
+  return retVal;
+}
+
+Void TAppDecTop::xFindDPBStatus( std::vector<Int> &listOfPocs
+                            , std::vector<Int> *listOfPocsInEachLayer
+                            , std::vector<Int> *listOfPocsPositionInEachLayer
+                            , DpbStatus &dpbStatus
+                            )
+{
+  TComVPS *vps = NULL;
+  dpbStatus.init();
+  for( Int i = 0; i < MAX_LAYERS; i++ )
+  {
+    if( m_acTDecTop[i].getListPic()->empty() )
+    {
+      continue;
+    }
+    
+    // To check # AUs that have at least one picture not output,
+    // For each layer, populate listOfPOcs if not already present
+    TComList<TComPic*>::iterator iterPic = m_acTDecTop[i].getListPic()->begin();
+    Int picPositionInList = 0;
+    while (iterPic != m_acTDecTop[i].getListPic()->end())
+    {
+      TComPic* pic = *(iterPic);
+      if( pic->getReconMark() )
+      {
+        if( vps == NULL )
+        {
+          vps = pic->getSlice(0)->getVPS();
+        }
+
+        std::vector<Int>::iterator it;
+        if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
+        {
+          it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
+          if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
+          {
+            listOfPocs.push_back( pic->getPOC() );
+          }
+          listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
+          listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
+        }
+        if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
+        {
+          dpbStatus.m_numPicsInLayer[i]++;  // Count pictures that are "used for reference" or "needed for output"
+        }
+      }
+      iterPic++;
+      picPositionInList++;
+    }
+  }
+
+  assert( vps != NULL );    // No picture in any DPB?
+  std::sort( listOfPocs.begin(), listOfPocs.end() );    // Sort in increasing order of POC
+  Int targetLsIdx = vps->getOutputLayerSetIdx( getCommonDecoderParams()->getTargetOutputLayerSetIdx() );
+  // Update status
+  dpbStatus.m_numAUsNotDisplayed = listOfPocs.size();   // Number of AUs not displayed
+  dpbStatus.m_numLayers = vps->getNumLayersInIdList( targetLsIdx );
+  dpbStatus.m_numSubDpbs = vps->getNumSubDpbs( vps->getOutputLayerSetIdx(
+                                                      this->getCommonDecoderParams()->getTargetOutputLayerSetIdx() ) );
+
+  for(Int i = 0; i < dpbStatus.m_numLayers; i++)
+  {
+    dpbStatus.m_numPicsNotDisplayedInLayer[i] = listOfPocsInEachLayer[i].size();
+    dpbStatus.m_numPicsInSubDpb[vps->getSubDpbAssigned(targetLsIdx,i)] += dpbStatus.m_numPicsInLayer[i];
+  }
+  assert( dpbStatus.m_numAUsNotDisplayed != -1 );
+
+
+}  
+#endif
 //! \}
Index: trunk/source/App/TAppDecoder/TAppDecTop.h
===================================================================
--- trunk/source/App/TAppDecoder/TAppDecTop.h	(revision 597)
+++ trunk/source/App/TAppDecoder/TAppDecTop.h	(revision 644)
@@ -55,5 +55,7 @@
 // Class definition
 // ====================================================================================================================
-
+#if ALIGNED_BUMPING
+struct DpbStatus;
+#endif
 /// decoder application class
 class TAppDecTop : public TAppDecCfg
@@ -98,6 +100,58 @@
 #endif
   Bool  isNaluWithinTargetDecLayerIdSet ( InputNALUnit* nalu ); ///< check whether given Nalu is within targetDecLayerIdSet
+#if ALIGNED_BUMPING
+  Void checkOutputBeforeDecoding(Int layerIdx);
+  Void checkOutputAfterDecoding();
+  Void flushAllPictures(Bool outputPictures); 
+  Void flushAllPictures(Int layerId, Bool outputPictures);
+
+  Void xOutputAndMarkPic( TComPic *pic, const Char *reconFile, const Int layerID, Int &pocLastDisplay, DpbStatus &dpbStatus);
+  Void xFindDPBStatus( std::vector<Int> &listOfPocs
+                            , std::vector<Int> *listOfPocsInEachLayer
+                            , std::vector<Int> *listOfPocsPositionInEachLayer
+                            , DpbStatus &dpbStatus
+                            );
+
+  Bool ifInvokeBumpingBeforeDecoding( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit, const Int layerIdx, const Int subDpbIdx );
+  Bool ifInvokeBumpingAfterDecoding ( const DpbStatus &dpbStatus, const DpbStatus &dpbLimit );
+  Void bumpingProcess(std::vector<Int> &listOfPocs, std::vector<Int> *listOfPocsInEachLayer, std::vector<Int> *listOfPocsPositionInEachLayer, DpbStatus &dpbStatus);
+  Void emptyUnusedPicturesNotNeededForOutput();
+  Void markAllPicturesAsErased();
+  Void markAllPicturesAsErased(Int layerIdx);
+  TComVPS* findDpbParametersFromVps(std::vector<Int> const &listOfPocs, std::vector<Int> const *listOfPocsInEachLayer, std::vector<Int> const *listOfPocsPositionInEachLayer, DpbStatus &maxDpbLimit);
+#endif
 };
 
+#if ALIGNED_BUMPING
+struct DpbStatus
+{
+  // Number of AUs and pictures
+  Int m_numAUsNotDisplayed;
+  Int m_numPicsNotDisplayedInLayer[MAX_LAYERS];
+  Int m_numPicsInLayer[MAX_LAYERS];   // Pictures marked as used_for_reference or needed for output in the layer
+  Int m_numPicsInSubDpb[MAX_LAYERS];  // Pictures marked as used_for_reference or needed for output in the sub-DPB
+  Bool m_maxLatencyIncrease;
+  Int m_maxLatencyPictures;
+  
+  Int m_numSubDpbs;
+  Int m_numLayers;
+
+  DpbStatus()
+  {
+    init();
+  }
+  Void init()
+  {
+    m_numAUsNotDisplayed = 0;
+    m_maxLatencyIncrease  = false;
+    m_maxLatencyPictures  = 0;
+    ::memset( m_numPicsInLayer,  0, sizeof(m_numPicsInLayer)  );
+    ::memset( m_numPicsInSubDpb, 0, sizeof(m_numPicsInSubDpb) );
+    ::memset(m_numPicsNotDisplayedInLayer, 0, sizeof(m_numPicsNotDisplayedInLayer) );
+    m_numSubDpbs = -1;
+    m_numLayers = -1;
+  }
+};
+#endif
 //! \}
 
Index: trunk/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 597)
+++ trunk/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 644)
@@ -385,4 +385,7 @@
   string    cfg_scaledRefLayerBottomOffset [MAX_LAYERS];
   Int*      cfg_numScaledRefLayerOffsets[MAX_LAYERS];
+#if P0312_VERT_PHASE_ADJ
+  string    cfg_vertPhasePositionEnableFlag[MAX_LAYERS];
+#endif
 
 #if O0098_SCALED_REF_LAYER_ID
@@ -393,4 +396,8 @@
   string*    cfg_scaledRefLayerRightOffsetPtr  [MAX_LAYERS];
   string*    cfg_scaledRefLayerBottomOffsetPtr [MAX_LAYERS];
+#if P0312_VERT_PHASE_ADJ
+  string*    cfg_vertPhasePositionEnableFlagPtr[MAX_LAYERS];
+#endif
+
 #if RC_SHVC_HARMONIZATION
   Bool*   cfg_RCEnableRateControl  [MAX_LAYERS];
@@ -451,10 +458,13 @@
     {
 #if O0098_SCALED_REF_LAYER_ID
-      cfg_scaledRefLayerIdPtr          [layer] = &cfg_scaledRefLayerId[layer]          ;
-#endif
-      cfg_scaledRefLayerLeftOffsetPtr  [layer] = &cfg_scaledRefLayerLeftOffset[layer]  ;
-      cfg_scaledRefLayerTopOffsetPtr   [layer] = &cfg_scaledRefLayerTopOffset[layer]   ;
-      cfg_scaledRefLayerRightOffsetPtr [layer] = &cfg_scaledRefLayerRightOffset[layer] ;
+      cfg_scaledRefLayerIdPtr          [layer] = &cfg_scaledRefLayerId[layer];
+#endif
+      cfg_scaledRefLayerLeftOffsetPtr  [layer] = &cfg_scaledRefLayerLeftOffset[layer];
+      cfg_scaledRefLayerTopOffsetPtr   [layer] = &cfg_scaledRefLayerTopOffset[layer];
+      cfg_scaledRefLayerRightOffsetPtr [layer] = &cfg_scaledRefLayerRightOffset[layer];
       cfg_scaledRefLayerBottomOffsetPtr[layer] = &cfg_scaledRefLayerBottomOffset[layer];
+#if P0312_VERT_PHASE_ADJ
+      cfg_vertPhasePositionEnableFlagPtr[layer] = &cfg_vertPhasePositionEnableFlag[layer];
+#endif
     }
 #if RC_SHVC_HARMONIZATION
@@ -569,5 +579,8 @@
                                                                  " bottom-right luma sample of the EL picture, in units of two luma samples")
   ("ScaledRefLayerBottomOffset%d", cfg_scaledRefLayerBottomOffsetPtr,string(""), MAX_LAYERS, "Vertical offset of bottom-right luma sample of scaled base layer picture with respect to"
-                                                                 " bottom-right luma sample of the EL picture, in units of two luma samples")
+  " bottom-right luma sample of the EL picture, in units of two luma samples")
+#if P0312_VERT_PHASE_ADJ
+  ("VertPhasePositionEnableFlag%d", cfg_vertPhasePositionEnableFlagPtr,string(""), MAX_LAYERS, "VertPhasePositionEnableFlag for layer %d")
+#endif
 #if O0194_DIFFERENT_BITDEPTH_EL_BL
   ("InputBitDepth%d",       cfg_InputBitDepthY,    8, MAX_LAYERS, "Bit-depth of input file for layer %d")
@@ -588,4 +601,7 @@
 #if N0147_IRAP_ALIGN_FLAG
   ("CrossLayerIrapAlignFlag", m_crossLayerIrapAlignFlag, true, "align IRAP across layers" )  
+#endif
+#if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
+  ("CrossLayerAlignedIdrOnlyFlag", m_crossLayerAlignedIdrOnlyFlag, true, "only idr for IRAP across layers" )  
 #endif
 #if O0194_WEIGHTED_PREDICTION_CGS
@@ -714,5 +730,4 @@
   ("LambdaModifier5,-LM5", m_adLambdaModifier[ 5 ], ( Double )1.0, "Lambda modifier for temporal layer 5")
   ("LambdaModifier6,-LM6", m_adLambdaModifier[ 6 ], ( Double )1.0, "Lambda modifier for temporal layer 6")
-  ("LambdaModifier7,-LM7", m_adLambdaModifier[ 7 ], ( Double )1.0, "Lambda modifier for temporal layer 7")
 #endif
 
@@ -1070,9 +1085,16 @@
       assert( strcmp(cfg_scaledRefLayerId[layer].c_str(),  ""));
 #endif
+#if P0312_VERT_PHASE_ADJ
       assert( strcmp(cfg_scaledRefLayerLeftOffset[layer].c_str(),  "") ||
               strcmp(cfg_scaledRefLayerRightOffset[layer].c_str(), "") ||
               strcmp(cfg_scaledRefLayerTopOffset[layer].c_str(),   "") ||
-              strcmp(cfg_scaledRefLayerBottomOffset[layer].c_str(),"")
-            ); 
+              strcmp(cfg_scaledRefLayerBottomOffset[layer].c_str(),"") ||
+              strcmp(cfg_vertPhasePositionEnableFlag[layer].c_str(),"") ); 
+#else
+      assert( strcmp(cfg_scaledRefLayerLeftOffset[layer].c_str(),  "") ||
+              strcmp(cfg_scaledRefLayerRightOffset[layer].c_str(), "") ||
+              strcmp(cfg_scaledRefLayerTopOffset[layer].c_str(),   "") ||
+              strcmp(cfg_scaledRefLayerBottomOffset[layer].c_str(),"") ); 
+#endif
     }
 
@@ -1150,4 +1172,19 @@
       }
     }
+#if P0312_VERT_PHASE_ADJ
+   // VertPhasePositionEnableFlag //
+    if(strcmp(cfg_vertPhasePositionEnableFlag[layer].c_str(),  ""))
+    {
+      cfgStringToArray( &tempArray, cfg_vertPhasePositionEnableFlag[layer], m_acLayerCfg[layer].m_numScaledRefLayerOffsets, "VertPhasePositionEnableFlag");
+      if(tempArray)
+      {
+        for(Int i = 0; i < m_acLayerCfg[layer].m_numScaledRefLayerOffsets; i++)
+        {
+          m_acLayerCfg[layer].m_vertPhasePositionEnableFlag[i] = tempArray[i];
+        }
+        delete [] tempArray; tempArray = NULL;
+      }
+    }
+#endif
   }
 #if VPS_EXTN_DIRECT_REF_LAYERS
@@ -2342,4 +2379,7 @@
   printf("Cross layer IRAP alignment    : %d\n", m_crossLayerIrapAlignFlag );
 #endif
+#if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
+  printf("IDR only for IRAP             : %d\n", m_crossLayerAlignedIdrOnlyFlag );
+#endif
 #if O0194_WEIGHTED_PREDICTION_CGS
   printf("InterLayerWeightedPred        : %d\n", m_useInterLayerWeightedPred );
Index: trunk/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncCfg.h	(revision 597)
+++ trunk/source/App/TAppEncoder/TAppEncCfg.h	(revision 644)
@@ -384,4 +384,7 @@
   Bool      m_crossLayerIrapAlignFlag;
 #endif
+#if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
+  Bool      m_crossLayerAlignedIdrOnlyFlag;
+#endif
 #if O0149_CROSS_LAYER_BLA_FLAG
   Bool      m_crossLayerBLAFlag;
Index: trunk/source/App/TAppEncoder/TAppEncLayerCfg.cpp
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncLayerCfg.cpp	(revision 597)
+++ trunk/source/App/TAppEncoder/TAppEncLayerCfg.cpp	(revision 644)
@@ -60,4 +60,7 @@
   ::memset(m_scaledRefLayerRightOffset,  0, sizeof(m_scaledRefLayerRightOffset));
   ::memset(m_scaledRefLayerBottomOffset, 0, sizeof(m_scaledRefLayerBottomOffset));
+#if P0312_VERT_PHASE_ADJ 
+  ::memset(m_vertPhasePositionEnableFlag, 0, sizeof(m_vertPhasePositionEnableFlag));
+#endif
 }
 
Index: trunk/source/App/TAppEncoder/TAppEncLayerCfg.h
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncLayerCfg.h	(revision 597)
+++ trunk/source/App/TAppEncoder/TAppEncLayerCfg.h	(revision 644)
@@ -97,4 +97,8 @@
   Int       m_scaledRefLayerRightOffset [MAX_LAYERS];
   Int       m_scaledRefLayerBottomOffset[MAX_LAYERS];
+#if P0312_VERT_PHASE_ADJ 
+  Bool      m_vertPhasePositionEnableFlag[MAX_LAYERS];
+#endif
+
 #if O0194_DIFFERENT_BITDEPTH_EL_BL
   Int       m_inputBitDepthY;                               ///< bit-depth of input file (luma component)
Index: trunk/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncTop.cpp	(revision 597)
+++ trunk/source/App/TAppEncoder/TAppEncTop.cpp	(revision 644)
@@ -570,6 +570,12 @@
         m_acTEncTop[layer].setScaledRefLayerId(i, m_acLayerCfg[layer].m_scaledRefLayerId[i]);
 #endif
+#if P0312_VERT_PHASE_ADJ
+        m_acTEncTop[layer].setVertPhasePositionEnableFlag( i, m_acLayerCfg[layer].m_vertPhasePositionEnableFlag[i] );
+        m_acTEncTop[layer].getScaledRefLayerWindow(i).setWindow( 2*m_acLayerCfg[layer].m_scaledRefLayerLeftOffset[i], 2*m_acLayerCfg[layer].m_scaledRefLayerRightOffset[i],
+                                                  2*m_acLayerCfg[layer].m_scaledRefLayerTopOffset[i], 2*m_acLayerCfg[layer].m_scaledRefLayerBottomOffset[i], m_acLayerCfg[layer].m_vertPhasePositionEnableFlag[i] );
+#else
         m_acTEncTop[layer].getScaledRefLayerWindow(i).setWindow( 2*m_acLayerCfg[layer].m_scaledRefLayerLeftOffset[i], 2*m_acLayerCfg[layer].m_scaledRefLayerRightOffset[i],
                                                   2*m_acLayerCfg[layer].m_scaledRefLayerTopOffset[i], 2*m_acLayerCfg[layer].m_scaledRefLayerBottomOffset[i]);
+#endif
       }
     }
@@ -956,4 +962,8 @@
 #endif
     m_acTEncTop[layer].init(isFieldCoding);
+#if P0182_VPS_VUI_PS_FLAG
+    m_acTEncTop[layer].getVPS()->setSPSId(layer, m_acTEncTop[layer].getSPS()->getSPSId());
+    m_acTEncTop[layer].getVPS()->setPPSId(layer, m_acTEncTop[layer].getPPS()->getPPSId());
+#endif
   }
 #if VPS_RENAME
@@ -1193,5 +1203,5 @@
         // at the encoder, modify below
         Int oldValue = vps->getMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j );
-        oldValue += vps->getMaxVpsLayerDecPicBuffMinus1( i, k, j );
+        oldValue += vps->getMaxVpsLayerDecPicBuffMinus1( i, k, j ) + 1;
         vps->setMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j, oldValue );
 #else
@@ -1200,4 +1210,12 @@
         maxNumReorderPics       = std::max( maxNumReorderPics, m_acTEncTop[layerId].getNumReorderPics(j));
       }
+#if RESOLUTION_BASED_DPB
+      for(Int k = 0; k < vps->getNumSubDpbs(i); k++)
+      {
+        // Decrement m_maxVpsDecPicBufferingMinus1
+        Int oldValue = vps->getMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j );
+        vps->setMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j, oldValue - 1 );
+      }
+#endif
       vps->setMaxVpsNumReorderPics(i, j, maxNumReorderPics);
       vps->determineSubDpbInfoFlags();
@@ -1286,4 +1304,7 @@
     vps->setCrossLayerPictureTypeAlignFlag( m_crossLayerPictureTypeAlignFlag );
 #endif
+#if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
+    vps->setCrossLayerAlignedIdrOnlyFlag( m_crossLayerAlignedIdrOnlyFlag );
+#endif
 #if N0147_IRAP_ALIGN_FLAG
     vps->setCrossLayerIrapAlignFlag( m_crossLayerIrapAlignFlag );
@@ -1327,6 +1348,85 @@
 #endif
 
+#if P0300_ALT_OUTPUT_LAYER_FLAG
+  for (Int k = 0; k < MAX_VPS_LAYER_SETS_PLUS1; k++)
+  {
+    vps->setAltOuputLayerFlag( k, m_altOutputLayerFlag );
+  }
+#else
 #if O0153_ALT_OUTPUT_LAYER_FLAG
   vps->setAltOuputLayerFlag( m_altOutputLayerFlag );
+#endif
+#endif
+
+#if P0312_VERT_PHASE_ADJ
+  Bool vpsVuiVertPhaseInUseFlag = false;
+  for( UInt layerId = 1; layerId < m_numLayers; layerId++ )
+  {
+    for( i = 0; i < m_acLayerCfg[layerId].m_numScaledRefLayerOffsets; i++ )
+    {
+      if( m_acTEncTop[layerId].getVertPhasePositionEnableFlag(i) )
+      {
+        vpsVuiVertPhaseInUseFlag = true;
+        break;
+      }
+    }
+  }
+  vps->setVpsVuiVertPhaseInUseFlag( vpsVuiVertPhaseInUseFlag );
+#endif
+
+#if O0164_MULTI_LAYER_HRD
+  vps->setVpsVuiBspHrdPresentFlag(false);
+  TEncTop *pcCfg = &m_acTEncTop[0];
+  if( pcCfg->getBufferingPeriodSEIEnabled() )
+  {
+    vps->setVpsVuiBspHrdPresentFlag(true);
+    vps->setVpsNumBspHrdParametersMinus1(vps->getNumLayerSets() - 2); 
+    vps->createBspHrdParamBuffer(vps->getVpsNumBspHrdParametersMinus1() + 1);
+    for ( i = 0; i <= vps->getVpsNumBspHrdParametersMinus1(); i++ )
+    {
+      vps->setBspCprmsPresentFlag(i, true);
+
+      UInt layerId = i + 1;
+      TEncTop *pcCfgLayer = &m_acTEncTop[layerId];
+
+      Int iPicWidth         = pcCfgLayer->getSourceWidth();
+      Int iPicHeight        = pcCfgLayer->getSourceHeight();
+      UInt uiWidthInCU       = ( iPicWidth %m_uiMaxCUWidth  ) ? iPicWidth /m_uiMaxCUWidth  + 1 : iPicWidth /m_uiMaxCUWidth;
+      UInt uiHeightInCU      = ( iPicHeight%m_uiMaxCUHeight ) ? iPicHeight/m_uiMaxCUHeight + 1 : iPicHeight/m_uiMaxCUHeight;
+      UInt uiNumCUsInFrame   = uiWidthInCU * uiHeightInCU;
+
+      UInt maxCU = pcCfgLayer->getSliceArgument() >> ( m_uiMaxCUDepth << 1);
+      UInt numDU = ( pcCfgLayer->getSliceMode() == 1 ) ? ( uiNumCUsInFrame / maxCU ) : ( 0 );
+      if( uiNumCUsInFrame % maxCU != 0 || numDU == 0 )
+      {
+        numDU ++;
+      }
+      vps->getBspHrd(i)->setNumDU( numDU );
+      vps->setBspHrdParameters( i, pcCfgLayer->getFrameRate(), numDU, pcCfgLayer->getTargetBitrate(), ( pcCfgLayer->getIntraPeriod() > 0 ) );
+    }
+    for(UInt h = 1; h <= (vps->getNumLayerSets()-1); h++)
+    {
+      vps->setNumBitstreamPartitions(h, 1);
+      for( i = 0; i < vps->getNumBitstreamPartitions(h); i++ )
+      {
+        for( UInt j = 0; j <= (vps->getMaxLayers()-1); j++ )
+        {
+          if (vps->getLayerIdIncludedFlag(h, j) && h == j)
+          {
+            vps->setLayerInBspFlag(h, i, j, true);
+          }
+        }
+      }
+      vps->setNumBspSchedCombinations(h, 1);
+      for( i = 0; i < vps->getNumBspSchedCombinations(h); i++ )
+      {
+        for( UInt j = 0; j < vps->getNumBitstreamPartitions(h); j++ )
+        {
+          vps->setBspCombHrdIdx(h, i, j, 0);
+          vps->setBspCombSchedIdx(h, i, j, 0);
+        }
+      }
+    }
+  }
 #endif
 
