Index: trunk/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 55)
+++ trunk/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 125)
@@ -4,5 +4,5 @@
  * granted under this license.  
  *
- * Copyright (c) 2010-2012, ITU/ISO/IEC
+ * Copyright (c) 2010-2013, ITU/ISO/IEC
  * All rights reserved.
  *
@@ -89,14 +89,12 @@
   m_bRefreshPending     = 0;
   m_pocCRA            = 0;
-#if LTRP_IN_SPS
   m_numLongTermRefPicSPS = 0;
   ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
   ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
-#endif
-#if BUFFERING_PERIOD_AND_TIMING_SEI
   m_cpbRemovalDelay   = 0;
   m_lastBPSEI         = 0;
-#endif
-
+#if L0045_NON_NESTED_SEI_RESTRICTIONS
+  xResetNonNestedSEIPresentFlags();
+#endif
 #if SVC_UPSAMPLING
   m_pcPredSearch        = NULL;
@@ -110,19 +108,19 @@
 
 /** Create list to contain pointers to LCU start addresses of slice.
- * \param iWidth, iHeight are picture width, height. iMaxCUWidth, iMaxCUHeight are LCU width, height.
  */
 #if SVC_EXTENSION
-Void  TEncGOP::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UInt layerId )
-#else
-Void  TEncGOP::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight )
-#endif
+Void  TEncGOP::create( UInt layerId )
 {
   m_bLongtermTestPictureHasBeenCoded = 0;
   m_bLongtermTestPictureHasBeenCoded2 = 0;
-
-#if SVC_EXTENSION
   m_layerId = layerId;
-#endif
 }
+#else
+Void  TEncGOP::create()
+{
+  m_bLongtermTestPictureHasBeenCoded = 0;
+  m_bLongtermTestPictureHasBeenCoded2 = 0;
+}
+#endif
 
 Void  TEncGOP::destroy()
@@ -135,10 +133,5 @@
   m_pcCfg                = pcTEncTop;
   m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
-  m_pcListPic            = pcTEncTop->getListPic();
-
-#if SVC_EXTENSION
-  m_ppcTEncTop           = pcTEncTop->getLayerEnc();
-#endif
-  
+  m_pcListPic            = pcTEncTop->getListPic();  
   m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
   m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
@@ -148,19 +141,114 @@
   m_pcBitCounter         = pcTEncTop->getBitCounter();
   
-#if !REMOVE_ALF
-  // Adaptive Loop filter
-  m_pcAdaptiveLoopFilter = pcTEncTop->getAdaptiveLoopFilter();
-#endif
   //--Adaptive Loop filter
   m_pcSAO                = pcTEncTop->getSAO();
   m_pcRateCtrl           = pcTEncTop->getRateCtrl();
-#if BUFFERING_PERIOD_AND_TIMING_SEI
   m_lastBPSEI          = 0;
   m_totalCoded         = 0;
-#endif
-
+
+#if SVC_EXTENSION
+  m_ppcTEncTop           = pcTEncTop->getLayerEnc();
+#endif
 #if SVC_UPSAMPLING
   m_pcPredSearch         = pcTEncTop->getPredSearch();                       ///< encoder search class
 #endif
+}
+
+SEIActiveParameterSets* TEncGOP::xCreateSEIActiveParameterSets (TComSPS *sps)
+{
+  SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets(); 
+  seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId(); 
+#if L0047_APS_FLAGS
+  seiActiveParameterSets->m_fullRandomAccessFlag = false;
+  seiActiveParameterSets->m_noParamSetUpdateFlag = false;
+#endif
+  seiActiveParameterSets->numSpsIdsMinus1 = 0;
+  seiActiveParameterSets->activeSeqParamSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); 
+  seiActiveParameterSets->activeSeqParamSetId[0] = sps->getSPSId();
+  return seiActiveParameterSets;
+}
+
+SEIFramePacking* TEncGOP::xCreateSEIFramePacking()
+{
+  SEIFramePacking *seiFramePacking = new SEIFramePacking();
+  seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId();
+  seiFramePacking->m_arrangementCancelFlag = 0;
+  seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType();
+#if L0444_FPA_TYPE
+  assert((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) );
+#endif
+  seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx();
+  seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation();
+  seiFramePacking->m_spatialFlippingFlag = 0;
+  seiFramePacking->m_frame0FlippedFlag = 0;
+  seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2);
+  seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && m_iNumPicCoded&1);
+  seiFramePacking->m_frame0SelfContainedFlag = 0;
+  seiFramePacking->m_frame1SelfContainedFlag = 0;
+  seiFramePacking->m_frame0GridPositionX = 0;
+  seiFramePacking->m_frame0GridPositionY = 0;
+  seiFramePacking->m_frame1GridPositionX = 0;
+  seiFramePacking->m_frame1GridPositionY = 0;
+  seiFramePacking->m_arrangementReservedByte = 0;
+#if L0045_PERSISTENCE_FLAGS
+  seiFramePacking->m_arrangementPersistenceFlag = true;
+#else
+  seiFramePacking->m_arrangementRepetetionPeriod = 1;
+#endif
+  seiFramePacking->m_upsampledAspectRatio = 0;
+  return seiFramePacking;
+}
+
+SEIDisplayOrientation* TEncGOP::xCreateSEIDisplayOrientation()
+{
+  SEIDisplayOrientation *seiDisplayOrientation = new SEIDisplayOrientation();
+  seiDisplayOrientation->cancelFlag = false;
+  seiDisplayOrientation->horFlip = false;
+  seiDisplayOrientation->verFlip = false;
+  seiDisplayOrientation->anticlockwiseRotation = m_pcCfg->getDisplayOrientationSEIAngle();
+  return seiDisplayOrientation;
+}
+
+Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps)
+{
+  OutputNALUnit nalu(NAL_UNIT_SEI);
+
+  if(m_pcCfg->getActiveParameterSetsSEIEnabled())
+  {
+    SEIActiveParameterSets *sei = xCreateSEIActiveParameterSets (sps);
+
+    //nalu = NALUnit(NAL_UNIT_SEI); 
+    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
+    writeRBSPTrailingBits(nalu.m_Bitstream);
+    accessUnit.push_back(new NALUnitEBSP(nalu));
+    delete sei;
+#if L0045_NON_NESTED_SEI_RESTRICTIONS
+    m_activeParameterSetSEIPresentInAU = true;
+#endif
+  }
+
+  if(m_pcCfg->getFramePackingArrangementSEIEnabled())
+  {
+    SEIFramePacking *sei = xCreateSEIFramePacking ();
+
+    nalu = NALUnit(NAL_UNIT_SEI);
+    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
+    writeRBSPTrailingBits(nalu.m_Bitstream);
+    accessUnit.push_back(new NALUnitEBSP(nalu));
+    delete sei;
+  }
+  if (m_pcCfg->getDisplayOrientationSEIAngle())
+  {
+    SEIDisplayOrientation *sei = xCreateSEIDisplayOrientation();
+
+    nalu = NALUnit(NAL_UNIT_SEI); 
+    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
+    writeRBSPTrailingBits(nalu.m_Bitstream);
+    accessUnit.push_back(new NALUnitEBSP(nalu));
+    delete sei;
+  }
 }
 
@@ -187,9 +275,11 @@
 
   m_iNumPicCoded = 0;
-#if BUFFERING_PERIOD_AND_TIMING_SEI
   SEIPictureTiming pictureTimingSEI;
+#if L0044_DU_DPB_OUTPUT_DELAY_HRD
+  Int picSptDpbOutputDuDelay = 0;
+#endif
   UInt *accumBitsDU = NULL;
   UInt *accumNalsDU = NULL;
-#endif
+  SEIDecodingUnitInfo decodingUnitInfoSEI;
 #if SVC_EXTENSION
   for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
@@ -246,28 +336,24 @@
 
     /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
-    UInt uiPOCCurr = iPOCLast -iNumPicRcvd+ m_pcCfg->getGOPEntry(iGOPid).m_POC;
+    Int pocCurr = iPOCLast -iNumPicRcvd+ m_pcCfg->getGOPEntry(iGOPid).m_POC;
     Int iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
     if(iPOCLast == 0)
     {
-      uiPOCCurr=0;
+      pocCurr=0;
       iTimeOffset = 1;
     }
-    if(uiPOCCurr>=m_pcCfg->getFrameToBeEncoded())
+    if(pocCurr>=m_pcCfg->getFramesToBeEncoded())
     {
       continue;
     }
 
-#if SUPPORT_FOR_RAP_N_LP
-    if( getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR || getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
-#else
-    if(getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR)
-#endif
-    {
-      m_iLastIDR = uiPOCCurr;
+    if( getNalUnitType(pocCurr) == NAL_UNIT_CODED_SLICE_IDR || getNalUnitType(pocCurr) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
+    {
+      m_iLastIDR = pocCurr;
     }        
     // start a new access unit: create an entry in the list of output access units
     accessUnitsInGOP.push_back(AccessUnit());
     AccessUnit& accessUnit = accessUnitsInGOP.back();
-    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, uiPOCCurr );
+    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr );
 
     //  Slice data initialization
@@ -277,23 +363,14 @@
     pcPic->setCurrSliceIdx(0);
 #if SVC_EXTENSION
-      pcPic->setLayerId( m_layerId );
-#endif
-
-#if !REMOVE_APS
-    std::vector<TComAPS>& vAPS = m_pcEncTop->getAPS();
-#endif
-    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, uiPOCCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS() );
+    pcPic->setLayerId( m_layerId );
+#endif
+
+    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS() );
     pcSlice->setLastIDR(m_iLastIDR);
     pcSlice->setSliceIdx(0);
     //set default slice level flag to the same as SPS level flag
-#if MOVE_LOOP_FILTER_SLICES_FLAG
     pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
-#else
-    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getSPS()->getLFCrossSliceBoundaryFlag()  );
-#endif
     pcSlice->setScalingList ( m_pcEncTop->getScalingList()  );
-#if TS_FLAT_QUANTIZATION_MATRIX
     pcSlice->getScalingList()->setUseTransformSkip(m_pcEncTop->getPPS()->getUseTransformSkip());
-#endif
     if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF)
     {
@@ -333,10 +410,24 @@
       pcSlice->setSliceType(P_SLICE);
     }
-
     // Set the nal unit type
-    pcSlice->setNalUnitType(getNalUnitType(uiPOCCurr));
+    pcSlice->setNalUnitType(getNalUnitType(pocCurr));
+#if IDR_ALIGNMENT
+    if (m_layerId > 0)
+    {
+      TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId-1]->getListPic();
+      pcSlice->setBaseColPic (*cListPic, m_layerId );
+    }
+#endif
 #if REF_IDX_FRAMEWORK
-    if( m_layerId > 0 && (uiPOCCurr % m_pcCfg->getIntraPeriod() == 0) )
-    {
+
+    if( m_layerId > 0 && (pocCurr % m_pcCfg->getIntraPeriod() == 0) )
+    {
+#if IDR_ALIGNMENT
+      if( pcSlice->getBaseColPic()->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR )
+      {
+        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_IDR);
+      }
+      else
+#endif
       pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA);
     }
@@ -351,5 +442,4 @@
     }
 #endif
-#if TEMPORAL_LAYER_NON_REFERENCE
     if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_TRAIL_R)
     {
@@ -359,9 +449,8 @@
       }
     }
-#endif
 
     // Do decoding refresh marking if any 
     pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
-    m_pcEncTop->selectReferencePictureSet(pcSlice, uiPOCCurr, iGOPid,rcListPic);
+    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
     pcSlice->getRPS()->setNumberOfLongtermPictures(0);
 
@@ -374,7 +463,6 @@
     if(pcSlice->getTLayer() > 0)
     {
-      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic, pcSlice->getRPS()) || pcSlice->getSPS()->getTemporalIdNestingFlag())
-      {
-#if TEMPORAL_LAYER_NON_REFERENCE
+      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag())
+      {
         if(pcSlice->getTemporalLayerNonReferenceFlag())
         {
@@ -385,57 +473,47 @@
           pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TLA);
         }
-#else
-        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TLA);
-#endif
-      }
-#if STSA
-      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic, pcSlice->getRPS()))
-      {
-          Bool isSTSA=true;
-          for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
-          {
-              Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
-              if(lTid==pcSlice->getTLayer()) 
+      }
+      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
+      {
+        Bool isSTSA=true;
+        for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
+        {
+          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
+          if(lTid==pcSlice->getTLayer()) 
+          {
+            TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
+            for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
+            {
+              if(nRPS->getUsed(jj)) 
               {
-                  TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
-                  for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
-                  {
-                      if(nRPS->getUsed(jj)) {
-                          Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
-                          Int kk=0;
-                          for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
-                          {
-                              if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
-                                  break;
-                          }
-                          Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
-                          if(tTid >= pcSlice->getTLayer())
-                          {
-                              isSTSA=false;
-                              break;
-                          }
-                          
-                      }
-                  }
+                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
+                Int kk=0;
+                for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
+                {
+                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
+                    break;
+                }
+                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
+                if(tTid >= pcSlice->getTLayer())
+                {
+                  isSTSA=false;
+                  break;
+                }
               }
-          }
-          if(isSTSA==true)
-          {    
-#if TEMPORAL_LAYER_NON_REFERENCE
-            if(pcSlice->getTemporalLayerNonReferenceFlag())
-            {
-              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
             }
-            else
-            {
-              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
-            }
-#else
+          }
+        }
+        if(isSTSA==true)
+        {    
+          if(pcSlice->getTemporalLayerNonReferenceFlag())
+          {
+            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
+          }
+          else
+          {
             pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
-#endif
-          }
-      }
-#endif
-
+          }
+        }
+      }
     }
     arrangeLongtermPicturesInRPS(pcSlice, rcListPic);
@@ -446,4 +524,20 @@
     pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
 
+#if REF_LIST_BUGFIX
+    if(m_layerId > 0)
+    {
+      if( pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
+      {
+        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getNumILRRefIdx());
+        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getNumILRRefIdx());
+      }
+      else
+      {
+        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getNumRefIdx(REF_PIC_LIST_0)+pcSlice->getNumILRRefIdx());
+        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getNumRefIdx(REF_PIC_LIST_1)+pcSlice->getNumILRRefIdx());
+      }
+    }
+#endif
+
 #if ADAPTIVE_QP_SELECTION
     pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
@@ -451,20 +545,22 @@
 
 #if SVC_EXTENSION      
-      if(m_layerId > 0)
-      {
-        TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId-1]->getListPic();
-        pcSlice->setBaseColPic (*cListPic, m_layerId );
+    if(m_layerId > 0)
+    {
+#if !IDR_ALIGNMENT
+      TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId-1]->getListPic();
+      pcSlice->setBaseColPic (*cListPic, m_layerId );
+#endif
 #if SVC_UPSAMPLING
-        if ( pcPic->isSpatialEnhLayer())
-        {    
-          m_pcPredSearch->upsampleBasePic( pcPic->getFullPelBaseRec(), pcSlice->getBaseColPic()->getPicYuvRec(), pcPic->getPicYuvRec() );
-        }
-        else
-        {
+      if ( pcPic->isSpatialEnhLayer())
+      {    
+        m_pcPredSearch->upsampleBasePic( pcPic->getFullPelBaseRec(), pcSlice->getBaseColPic()->getPicYuvRec(), pcPic->getPicYuvRec() );
+      }
+      else
+      {
         pcPic->setFullPelBaseRec( pcSlice->getBaseColPic()->getPicYuvRec() );
-        }
-        pcSlice->setFullPelBaseRec ( pcPic->getFullPelBaseRec() );
-#endif
-      }
+      }
+      pcSlice->setFullPelBaseRec ( pcPic->getFullPelBaseRec() );
+#endif
+    }
 #endif 
 
@@ -477,5 +573,12 @@
 
     //  Set reference list
+#if REF_LIST_BUGFIX
+    if(m_layerId ==  0)
+    {
+      pcSlice->setRefPicList( rcListPic);
+    }
+#else
     pcSlice->setRefPicList ( rcListPic );
+#endif
 #if REF_IDX_FRAMEWORK
     if(m_layerId > 0)
@@ -484,40 +587,51 @@
 
 #if REF_IDX_MFM
-      pcSlice->setRefPOCListILP(m_pcEncTop->getIlpList(), pcSlice->getBaseColPic());
-#endif
+      if( pcSlice->getSPS()->getMFMEnabledFlag() )
+      {
+        pcSlice->setRefPOCListILP(m_pcEncTop->getIlpList(), pcSlice->getBaseColPic());
+      }
+#endif
+#if REF_LIST_BUGFIX
+      pcSlice->setRefPicListModificationSvc();
+      pcSlice->setRefPicListSvc( rcListPic, m_pcEncTop->getIlpList() );
+#else
       pcSlice->addRefPicList ( m_pcEncTop->getIlpList(), 1);
+#endif
 
 #if REF_IDX_MFM
-      Bool found         = false;
-      UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
-      UInt ColRefIdx     = pcSlice->getColRefIdx();
-      for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
-      { 
-        if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->getIsILR() ) 
-        { 
-          ColRefIdx = colIdx; 
-          found = true;
-          break; 
-        }
-      }
-
-      if( found == false )
-      {
-        ColFromL0Flag = 1 - ColFromL0Flag;
+      if( pcSlice->getSPS()->getMFMEnabledFlag() )
+      {
+        Bool found         = false;
+        UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
+        UInt ColRefIdx     = pcSlice->getColRefIdx();
         for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
         { 
-          if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->getIsILR() ) 
+          if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->isILR() ) 
           { 
             ColRefIdx = colIdx; 
-            found = true; 
+            found = true;
             break; 
-          } 
-        }
-      }
-
-      if(found == true)
-      {
-        pcSlice->setColFromL0Flag(ColFromL0Flag);
-        pcSlice->setColRefIdx(ColRefIdx);
+          }
+        }
+
+        if( found == false )
+        {
+          ColFromL0Flag = 1 - ColFromL0Flag;
+          for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
+          { 
+            if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->isILR() ) 
+            { 
+              ColRefIdx = colIdx; 
+              found = true; 
+              break; 
+            } 
+          }
+        }
+
+        if(found == true)
+        {
+          pcSlice->setColFromL0Flag(ColFromL0Flag);
+          pcSlice->setColRefIdx(ColRefIdx);
+        }
       }
 #endif
@@ -581,5 +695,5 @@
       {
         pcSlice->setNoBackPredFlag( true );
-        int i;
+        Int i;
         for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
         {
@@ -635,5 +749,5 @@
       {
         bGPBcheck=true;
-        int i;
+        Int i;
         for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
         {
@@ -655,4 +769,63 @@
     }
     pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
+
+#if RATE_CONTROL_LAMBDA_DOMAIN
+    Int sliceQP              = pcSlice->getSliceQp();
+    Double lambda            = 0.0;
+    Int actualHeadBits       = 0;
+    Int actualTotalBits      = 0;
+    Int estimatedBits        = 0;
+    Int tmpBitsBeforeWriting = 0;
+    if ( m_pcCfg->getUseRateCtrl() )
+    {
+      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
+      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
+      {
+        frameLevel = 0;
+      }
+      m_pcRateCtrl->initRCPic( frameLevel );
+      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
+
+      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
+      {
+        sliceQP              = m_pcCfg->getInitialQP();
+        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
+        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
+        Double dQPFactor     = 0.57*dLambda_scale;
+        Int    SHIFT_QP      = 12;
+        Int    bitdepth_luma_qp_scale = 0;
+        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
+        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
+      }
+      else if ( frameLevel == 0 )   // intra case, but use the model
+      {
+        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
+        {
+          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
+          bits = m_pcRateCtrl->getRCSeq()->getRefineBitsForIntra( bits );
+          if ( bits < 200 )
+          {
+            bits = 200;
+          }
+          m_pcRateCtrl->getRCPic()->setTargetBits( bits );
+        }
+
+        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
+        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture );
+        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
+      }
+      else    // normal case
+      {
+        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
+        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture );
+        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
+      }
+
+      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP );
+      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
+
+      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
+    }
+#endif
 
     UInt uiNumSlices = 1;
@@ -760,20 +933,19 @@
     pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];
 
-    UInt uiStartCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
-    UInt uiStartCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
-    pcSlice->setSliceCurStartCUAddr( uiStartCUAddrSlice ); // Setting "start CU addr" for current slice
+    UInt startCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
+    UInt startCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
+    pcSlice->setSliceCurStartCUAddr( startCUAddrSlice ); // Setting "start CU addr" for current slice
     m_storedStartCUAddrForEncodingSlice.clear();
 
-    UInt uiStartCUAddrDependentSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
-    UInt uiStartCUAddrDependentSlice    = 0; // used to keep track of current Dependent slice's starting CU addr.
-    pcSlice->setDependentSliceCurStartCUAddr( uiStartCUAddrDependentSlice ); // Setting "start CU addr" for current Dependent slice
-
-    m_storedStartCUAddrForEncodingDependentSlice.clear();
-    UInt uiNextCUAddr = 0;
-    m_storedStartCUAddrForEncodingSlice.push_back (uiNextCUAddr);
-    uiStartCUAddrSliceIdx++;
-    m_storedStartCUAddrForEncodingDependentSlice.push_back(uiNextCUAddr);
-    uiStartCUAddrDependentSliceIdx++;
-
+    UInt startCUAddrSliceSegmentIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
+    UInt startCUAddrSliceSegment    = 0; // used to keep track of current Dependent slice's starting CU addr.
+    pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); // Setting "start CU addr" for current Dependent slice
+
+    m_storedStartCUAddrForEncodingSliceSegment.clear();
+    UInt nextCUAddr = 0;
+    m_storedStartCUAddrForEncodingSlice.push_back (nextCUAddr);
+    startCUAddrSliceIdx++;
+    m_storedStartCUAddrForEncodingSliceSegment.push_back(nextCUAddr);
+    startCUAddrSliceSegmentIdx++;
 #if AVC_BASE
     if( m_layerId == 0 )
@@ -787,63 +959,62 @@
 #endif
 
-    while(uiNextCUAddr<uiRealEndAddress) // determine slice boundaries
+    while(nextCUAddr<uiRealEndAddress) // determine slice boundaries
     {
       pcSlice->setNextSlice       ( false );
-      pcSlice->setNextDependentSlice( false );
-      assert(pcPic->getNumAllocatedSlice() == uiStartCUAddrSliceIdx);
+      pcSlice->setNextSliceSegment( false );
+      assert(pcPic->getNumAllocatedSlice() == startCUAddrSliceIdx);
       m_pcSliceEncoder->precompressSlice( pcPic );
       m_pcSliceEncoder->compressSlice   ( pcPic );
 
-      Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextDependentSlice());
-      if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE))
-      {
-        uiStartCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
+      Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextSliceSegment());
+      if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU))
+      {
+        startCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
         // Reconstruction slice
-        m_storedStartCUAddrForEncodingSlice.push_back(uiStartCUAddrSlice);
-        uiStartCUAddrSliceIdx++;
+        m_storedStartCUAddrForEncodingSlice.push_back(startCUAddrSlice);
+        startCUAddrSliceIdx++;
         // Dependent slice
-        if (uiStartCUAddrDependentSliceIdx>0 && m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx-1] != uiStartCUAddrSlice)
-        {
-          m_storedStartCUAddrForEncodingDependentSlice.push_back(uiStartCUAddrSlice);
-          uiStartCUAddrDependentSliceIdx++;
-        }
-
-        if (uiStartCUAddrSlice < uiRealEndAddress)
+        if (startCUAddrSliceSegmentIdx>0 && m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx-1] != startCUAddrSlice)
+        {
+          m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSlice);
+          startCUAddrSliceSegmentIdx++;
+        }
+
+        if (startCUAddrSlice < uiRealEndAddress)
         {
           pcPic->allocateNewSlice();          
-          pcPic->setCurrSliceIdx                  ( uiStartCUAddrSliceIdx-1 );
-          m_pcSliceEncoder->setSliceIdx           ( uiStartCUAddrSliceIdx-1 );
-          pcSlice = pcPic->getSlice               ( uiStartCUAddrSliceIdx-1 );
+          pcPic->setCurrSliceIdx                  ( startCUAddrSliceIdx-1 );
+          m_pcSliceEncoder->setSliceIdx           ( startCUAddrSliceIdx-1 );
+          pcSlice = pcPic->getSlice               ( startCUAddrSliceIdx-1 );
           pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
-          pcSlice->setSliceIdx                    ( uiStartCUAddrSliceIdx-1 );
-          pcSlice->setSliceCurStartCUAddr         ( uiStartCUAddrSlice      );
-          pcSlice->setDependentSliceCurStartCUAddr  ( uiStartCUAddrSlice      );
+          pcSlice->setSliceIdx                    ( startCUAddrSliceIdx-1 );
+          pcSlice->setSliceCurStartCUAddr         ( startCUAddrSlice      );
+          pcSlice->setSliceSegmentCurStartCUAddr  ( startCUAddrSlice      );
           pcSlice->setSliceBits(0);
           uiNumSlices ++;
         }
       }
-      else if (pcSlice->isNextDependentSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE))
-      {
-        uiStartCUAddrDependentSlice                                                     = pcSlice->getDependentSliceCurEndCUAddr();
-        m_storedStartCUAddrForEncodingDependentSlice.push_back(uiStartCUAddrDependentSlice);
-        uiStartCUAddrDependentSliceIdx++;
-        pcSlice->setDependentSliceCurStartCUAddr( uiStartCUAddrDependentSlice );
+      else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU))
+      {
+        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
+        m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment);
+        startCUAddrSliceSegmentIdx++;
+        pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment );
       }
       else
       {
-        uiStartCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
-        uiStartCUAddrDependentSlice                                                     = pcSlice->getDependentSliceCurEndCUAddr();
+        startCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
+        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
       }        
 
-      uiNextCUAddr = (uiStartCUAddrSlice > uiStartCUAddrDependentSlice) ? uiStartCUAddrSlice : uiStartCUAddrDependentSlice;
+      nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment;
     }
     m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
-    uiStartCUAddrSliceIdx++;
-    m_storedStartCUAddrForEncodingDependentSlice.push_back(pcSlice->getSliceCurEndCUAddr());
-    uiStartCUAddrDependentSliceIdx++;
+    startCUAddrSliceIdx++;
+    m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr());
+    startCUAddrSliceSegmentIdx++;
 
     pcSlice = pcPic->getSlice(0);
 
-#if SAO_LCU_BOUNDARY
     // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
     if( m_pcCfg->getSaoLcuBasedOptimization() && m_pcCfg->getSaoLcuBoundary() )
@@ -852,21 +1023,13 @@
       m_pcSAO->calcSaoStatsCu_BeforeDblk( pcPic );
     }
-#endif
 
     //-- Loop filter
     Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
-    m_pcLoopFilter->setCfg(pcSlice->getPPS()->getDeblockingFilterControlPresentFlag(), pcSlice->getDeblockingFilterDisable(), pcSlice->getDeblockingFilterBetaOffsetDiv2(), pcSlice->getDeblockingFilterTcOffsetDiv2(), bLFCrossTileBoundary);
+    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
     m_pcLoopFilter->loopFilterPic( pcPic );
 
     pcSlice = pcPic->getSlice(0);
-#if REMOVE_ALF
     if(pcSlice->getSPS()->getUseSAO())
-#else
-    if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
-#endif
-    {
-#if !REMOVE_FGS
-      Int sliceGranularity = pcSlice->getPPS()->getSliceGranularity();
-#endif
+    {
       std::vector<Bool> LFCrossSliceBoundaryFlag;
       for(Int s=0; s< uiNumSlices; s++)
@@ -875,9 +1038,5 @@
       }
       m_storedStartCUAddrForEncodingSlice.resize(uiNumSlices+1);
-#if REMOVE_FGS
       pcPic->createNonDBFilterInfo(m_storedStartCUAddrForEncodingSlice, 0, &LFCrossSliceBoundaryFlag ,pcPic->getPicSym()->getNumTiles() ,bLFCrossTileBoundary);
-#else
-      pcPic->createNonDBFilterInfo(m_storedStartCUAddrForEncodingSlice, sliceGranularity, &LFCrossSliceBoundaryFlag ,pcPic->getPicSym()->getNumTiles() ,bLFCrossTileBoundary);
-#endif
     }
 
@@ -887,15 +1046,7 @@
     if(pcSlice->getSPS()->getUseSAO())
     {
-      m_pcSAO->createPicSaoInfo(pcPic, uiNumSlices);
-    }
-
-#if !REMOVE_ALF
-    pcSlice = pcPic->getSlice(0);
-
-    if(pcSlice->getSPS()->getUseALF())
-    {
-      m_pcAdaptiveLoopFilter->createPicAlfInfo(pcPic, uiNumSlices);
-    }
-#endif
+      m_pcSAO->createPicSaoInfo(pcPic);
+    }
+
     /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
     // Set entropy coder
@@ -906,15 +1057,13 @@
     {
 #if SVC_EXTENSION
-#if REMOVE_NAL_REF_FLAG
       OutputNALUnit nalu(NAL_UNIT_VPS, 0, m_layerId);
+#if AVC_BASE
+      if( m_layerId == 1 )
 #else
-      OutputNALUnit nalu(NAL_UNIT_VPS, true, 0, m_layerId);
-#endif
+      if( m_layerId == 0 )
+#endif
+      {
 #else
-#if REMOVE_NAL_REF_FLAG
       OutputNALUnit nalu(NAL_UNIT_VPS);
-#else
-      OutputNALUnit nalu(NAL_UNIT_VPS, true);
-#endif
 #endif
       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
@@ -922,20 +1071,17 @@
       writeRBSPTrailingBits(nalu.m_Bitstream);
       accessUnit.push_back(new NALUnitEBSP(nalu));
-
+#if RATE_CONTROL_LAMBDA_DOMAIN
+      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
+#endif
 #if SVC_EXTENSION
-#if REMOVE_NAL_REF_FLAG
+      }
+#endif
+
+#if SVC_EXTENSION
       nalu = NALUnit(NAL_UNIT_SPS, 0, m_layerId);
 #else
-      nalu = NALUnit(NAL_UNIT_SPS, true, 0, m_layerId);
-#endif
-#else
-#if REMOVE_NAL_REF_FLAG
       nalu = NALUnit(NAL_UNIT_SPS);
-#else
-      nalu = NALUnit(NAL_UNIT_SPS, true);
-#endif
 #endif
       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
-#if LTRP_IN_SPS
       if (m_bSeqFirst)
       {
@@ -947,7 +1093,5 @@
         }
       }
-#endif
-#if BUFFERING_PERIOD_AND_TIMING_SEI
-      if( m_pcCfg->getPictureTimingSEIEnabled() )
+      if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
       {
         UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
@@ -957,28 +1101,22 @@
           numDU ++;
         }
-        pcSlice->getSPS()->getVuiParameters()->setNumDU( numDU );
+        pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
         pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
       }
-      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() )
+      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
       {
         pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
       }
-#endif
       m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
       writeRBSPTrailingBits(nalu.m_Bitstream);
       accessUnit.push_back(new NALUnitEBSP(nalu));
+#if RATE_CONTROL_LAMBDA_DOMAIN
+      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
+#endif
 
 #if SVC_EXTENSION
-#if REMOVE_NAL_REF_FLAG
       nalu = NALUnit(NAL_UNIT_PPS, 0, m_layerId);
 #else
-      nalu = NALUnit(NAL_UNIT_PPS, true, 0, m_layerId);
-#endif
-#else
-#if REMOVE_NAL_REF_FLAG
       nalu = NALUnit(NAL_UNIT_PPS);
-#else
-      nalu = NALUnit(NAL_UNIT_PPS, true);
-#endif
 #endif
       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
@@ -986,38 +1124,23 @@
       writeRBSPTrailingBits(nalu.m_Bitstream);
       accessUnit.push_back(new NALUnitEBSP(nalu));
-
-#if ACTIVE_PARAMETER_SETS_SEI_MESSAGE  
-      if(m_pcCfg->getActiveParameterSetsSEIEnabled())
-      {
-        SEIActiveParameterSets sei_active_parameter_sets; 
-        sei_active_parameter_sets.activeVPSId = m_pcCfg->getVPS()->getVPSId(); 
-        sei_active_parameter_sets.activeSPSIdPresentFlag = m_pcCfg->getActiveParameterSetsSEIEnabled()==2 ? 1 : 0;
-        if(sei_active_parameter_sets.activeSPSIdPresentFlag) 
-        {
-          sei_active_parameter_sets.activeSeqParamSetId = pcSlice->getSPS()->getSPSId(); 
-        }
-        sei_active_parameter_sets.activeParamSetSEIExtensionFlag = 0;
-
-        nalu = NALUnit(NAL_UNIT_SEI); 
-        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
-        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_active_parameter_sets); 
-        writeRBSPTrailingBits(nalu.m_Bitstream);
-        accessUnit.push_back(new NALUnitEBSP(nalu));
-      }
-#endif 
+#if RATE_CONTROL_LAMBDA_DOMAIN
+      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
+#endif
+
+      xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());
 
       m_bSeqFirst = false;
     }
 
-#if BUFFERING_PERIOD_AND_TIMING_SEI
-    if( ( m_pcCfg->getPictureTimingSEIEnabled() ) &&
-        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
-        ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) )
-    {
-      if( pcSlice->getSPS()->getVuiParameters()->getSubPicCpbParamsPresentFlag() )
-      {
-        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getNumDU();
+    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
+        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
+        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
+       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
+    {
+      if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
+      {
+        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
         pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
-        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = 0;
+        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;
 
         if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
@@ -1038,10 +1161,20 @@
         }
       }
-      pictureTimingSEI.m_auCpbRemovalDelay = m_totalCoded - m_lastBPSEI;
+      pictureTimingSEI.m_auCpbRemovalDelay = std::max<Int>(1, m_totalCoded - m_lastBPSEI); // Syntax element signalled as minus, hence the .
       pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(0) + pcSlice->getPOC() - m_totalCoded;
-    }
+#if L0044_DU_DPB_OUTPUT_DELAY_HRD
+      Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
+      pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
+      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
+      {
+        picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
+      }
+#endif
+    }
+
     if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
         ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
-        ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) )
+        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
+       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
     {
       OutputNALUnit nalu(NAL_UNIT_SEI);
@@ -1057,9 +1190,13 @@
       sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
 
-      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimeScale();
+#if L0043_TIMING_INFO
+      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
+#else
+      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTimeScale();
+#endif
 
       UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
       uiInitialCpbRemovalDelay -= uiTmp;
-      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getTickDivisorMinus2() + 2 );
+      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
       sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
       sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
@@ -1067,10 +1204,31 @@
       sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
 
-      sei_buffering_period.m_altCpbParamsPresentFlag              = 0;
-      sei_buffering_period.m_sps                                  = pcSlice->getSPS();
-
-      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period );
+      sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
+#if L0328_SPLICING
+      //for the concatenation, it can be set to one during splicing.
+      sei_buffering_period.m_concatenationFlag = 0;
+      //since the temporal layer HRD is not ready, we assumed it is fixed
+      sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
+#endif
+#if L0044_CPB_DPB_DELAY_OFFSET
+      sei_buffering_period.m_cpbDelayOffset = 0;
+      sei_buffering_period.m_dpbDelayOffset = 0;
+#endif
+
+      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
       writeRBSPTrailingBits(nalu.m_Bitstream);
+#if L0045_NON_NESTED_SEI_RESTRICTIONS
+      UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
+      UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
+      AccessUnit::iterator it;
+      for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
+      {
+        it++;
+      }
+      accessUnit.insert(it, new NALUnitEBSP(nalu));
+      m_bufferingPeriodSEIPresentInAU = true;
+#else
       accessUnit.push_back(new NALUnitEBSP(nalu));
+#endif
 
       m_lastBPSEI = m_totalCoded;
@@ -1078,9 +1236,21 @@
     }
     m_cpbRemovalDelay ++;
-#endif
-#if RECOVERY_POINT_SEI
     if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
     {
-      // Recovery point SEI
+      if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
+      {
+        // Gradual decoding refresh SEI 
+        OutputNALUnit nalu(NAL_UNIT_SEI);
+        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
+        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+
+        SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
+        seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"
+
+        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
+        writeRBSPTrailingBits(nalu.m_Bitstream);
+        accessUnit.push_back(new NALUnitEBSP(nalu));
+      }
+    // Recovery point SEI
       OutputNALUnit nalu(NAL_UNIT_SEI);
       m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
@@ -1092,32 +1262,23 @@
       sei_recovery_point.m_brokenLinkFlag    = false;
 
-      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point );
+      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
       writeRBSPTrailingBits(nalu.m_Bitstream);
       accessUnit.push_back(new NALUnitEBSP(nalu));
     }
-#endif
+
     /* use the main bitstream buffer for storing the marshalled picture */
     m_pcEntropyCoder->setBitstream(NULL);
 
-    uiStartCUAddrSliceIdx = 0;
-    uiStartCUAddrSlice    = 0; 
-
-    uiStartCUAddrDependentSliceIdx = 0;
-    uiStartCUAddrDependentSlice    = 0; 
-    uiNextCUAddr                 = 0;
-    pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
-
-#if REMOVE_ALF
+    startCUAddrSliceIdx = 0;
+    startCUAddrSlice    = 0; 
+
+    startCUAddrSliceSegmentIdx = 0;
+    startCUAddrSliceSegment    = 0; 
+    nextCUAddr                 = 0;
+    pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
+
     Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
-#else
-    Int processingState = (pcSlice->getSPS()->getUseALF() || pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
-#endif
-#if !REMOVE_APS
-    static Int iCurrAPSIdx = 0;
-    Int iCodedAPSIdx = 0;
-    TComSlice* pcSliceForAPS = NULL;
-#endif
-    bool skippedSlice=false;
-    while (uiNextCUAddr < uiRealEndAddress) // Iterate over all slices
+    Bool skippedSlice=false;
+    while (nextCUAddr < uiRealEndAddress) // Iterate over all slices
     {
       switch(processingState)
@@ -1126,36 +1287,36 @@
         {
           pcSlice->setNextSlice       ( false );
-          pcSlice->setNextDependentSlice( false );
-          if (uiNextCUAddr == m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx])
-          {
-            pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
-            if(uiStartCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
+          pcSlice->setNextSliceSegment( false );
+          if (nextCUAddr == m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx])
+          {
+            pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
+            if(startCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
             {
-              pcSlice->checkColRefIdx(uiStartCUAddrSliceIdx, pcPic);
+              pcSlice->checkColRefIdx(startCUAddrSliceIdx, pcPic);
             }
-            pcPic->setCurrSliceIdx(uiStartCUAddrSliceIdx);
-            m_pcSliceEncoder->setSliceIdx(uiStartCUAddrSliceIdx);
-            assert(uiStartCUAddrSliceIdx == pcSlice->getSliceIdx());
+            pcPic->setCurrSliceIdx(startCUAddrSliceIdx);
+            m_pcSliceEncoder->setSliceIdx(startCUAddrSliceIdx);
+            assert(startCUAddrSliceIdx == pcSlice->getSliceIdx());
             // Reconstruction slice
-            pcSlice->setSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
-            pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx+1 ] );
+            pcSlice->setSliceCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
+            pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] );
             // Dependent slice
-            pcSlice->setDependentSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
-            pcSlice->setDependentSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx+1 ] );
+            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
+            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
 
             pcSlice->setNextSlice       ( true );
 
-            uiStartCUAddrSliceIdx++;
-            uiStartCUAddrDependentSliceIdx++;
+            startCUAddrSliceIdx++;
+            startCUAddrSliceSegmentIdx++;
           } 
-          else if (uiNextCUAddr == m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx])
+          else if (nextCUAddr == m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx])
           {
             // Dependent slice
-            pcSlice->setDependentSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
-            pcSlice->setDependentSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx+1 ] );
-
-            pcSlice->setNextDependentSlice( true );
-
-            uiStartCUAddrDependentSliceIdx++;
+            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
+            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
+
+            pcSlice->setNextSliceSegment( true );
+
+            startCUAddrSliceSegmentIdx++;
           }
 
@@ -1166,6 +1327,6 @@
           m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
 
-          uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurEndCUAddr()-1) % pcPic->getNumPartInCU();
-          uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurEndCUAddr()-1) / pcPic->getNumPartInCU();
+          uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU();
+          uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU();
           uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
           uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
@@ -1184,10 +1345,11 @@
             uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
           }
-          UInt uiEndAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
-          if(uiEndAddress<=pcSlice->getDependentSliceCurStartCUAddr()) {
-            UInt uiBoundingAddrSlice, uiBoundingAddrDependentSlice;
-            uiBoundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx];          
-            uiBoundingAddrDependentSlice = m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx];          
-            uiNextCUAddr               = min(uiBoundingAddrSlice, uiBoundingAddrDependentSlice);
+          UInt endAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
+          if(endAddress<=pcSlice->getSliceSegmentCurStartCUAddr()) 
+          {
+            UInt boundingAddrSlice, boundingAddrSliceSegment;
+            boundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];          
+            boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];          
+            nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
             if(pcSlice->isNextSlice())
             {
@@ -1199,5 +1361,5 @@
           {
             pcSlice->setNextSlice       ( true );
-            pcSlice->setNextDependentSlice( false );
+            pcSlice->setNextSliceSegment( false );
           }
           skippedSlice=false;
@@ -1212,27 +1374,25 @@
           /* start slice NALunit */
 #if SVC_EXTENSION
-#if REMOVE_NAL_REF_FLAG
           OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId );
 #else
-          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->isReferenced(), pcSlice->getTLayer(), m_layerId );
-#endif
-#else
-#if REMOVE_NAL_REF_FLAG
           OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
-#else
-          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->isReferenced(), pcSlice->getTLayer() );
-#endif
-#endif
-          Bool bDependentSlice = (!pcSlice->isNextSlice());
-          if (!bDependentSlice)
+#endif
+          Bool sliceSegment = (!pcSlice->isNextSlice());
+          if (!sliceSegment)
           {
             uiOneBitstreamPerSliceLength = 0; // start of a new slice
           }
           m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+#if RATE_CONTROL_LAMBDA_DOMAIN
+          tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
+#endif
           m_pcEntropyCoder->encodeSliceHeader(pcSlice);
+#if RATE_CONTROL_LAMBDA_DOMAIN
+          actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
+#endif
 
           // is it needed?
           {
-            if (!bDependentSlice)
+            if (!sliceSegment)
             {
               pcBitstreamRedirect->writeAlignOne();
@@ -1267,5 +1427,5 @@
             m_pcEntropyCoder->resetEntropy    ();
             // File writing
-            if (!bDependentSlice)
+            if (!sliceSegment)
             {
               m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
@@ -1284,5 +1444,5 @@
 
           pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
-          if (!bDependentSlice)
+          if (!sliceSegment)
           {
             pcSlice->setTileLocationCount ( 0 );
@@ -1313,32 +1473,17 @@
               m_pcEntropyCoder->encodeSliceFinish();
 
-#if BYTE_ALIGNMENT  
               pcSubstreamsOut[ui].writeByteAlignment();   // Byte-alignment in slice_data() at end of sub-stream
-#else
-              //!KS: The following writes trailing_bits. Should use proper function call to writeRBSPTrailingBits()
-              pcSubstreamsOut[ui].write( 1, 1 ); // stop bit.
-              pcSubstreamsOut[ui].writeAlignZero();
-#endif
               // Byte alignment is necessary between tiles when tiles are independent.
               uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
 
+              Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0);
+              if (bNextSubstreamInNewTile)
               {
-                Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)
-                  && ((ui+1)%uiNumSubstreamsPerTile == 0);
-                if (bNextSubstreamInNewTile)
-                {
-                  // byte align.
-                  while (uiTotalCodedSize&0x7)
-                  {
-                    pcSubstreamsOut[ui].write(0, 1);
-                    uiTotalCodedSize++;
-                  }
-                }
-                Bool bRecordOffsetNext = bNextSubstreamInNewTile;
-                if (bRecordOffsetNext)
-                  pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
+                pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
               }
               if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
+              {
                 puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits();
+              }
             }
 
@@ -1350,29 +1495,10 @@
             // Substreams...
             TComOutputBitstream *pcOut = pcBitstreamRedirect;
-#if !BYTE_ALIGNMENT
-            // xWriteTileLocation will perform byte-alignment...
-            {
-              if (bDependentSlice)
-              {
-                // In these cases, padding is necessary here.
-                pcOut = &nalu.m_Bitstream;
-                pcOut->writeAlignOne();
-              }
-            }
-#endif
           Int offs = 0;
           Int nss = pcSlice->getPPS()->getNumSubstreams();
-#if TILES_WPP_ENTROPYSLICES_FLAGS
           if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
-#else
-          if (pcSlice->getPPS()->getTilesOrEntropyCodingSyncIdc() == 2)
-#endif
           {
             // 1st line present for WPP.
-#if DEPENDENT_SLICES
-            offs = pcSlice->getDependentSliceCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
-#else
-            offs = pcSlice->getSliceCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
-#endif
+            offs = pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
             nss  = pcSlice->getNumEntryPointOffsets()+1;
           }
@@ -1383,8 +1509,8 @@
           }
 
-          UInt uiBoundingAddrSlice, uiBoundingAddrDependentSlice;
-          uiBoundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx];          
-          uiBoundingAddrDependentSlice = m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx];          
-          uiNextCUAddr               = min(uiBoundingAddrSlice, uiBoundingAddrDependentSlice);
+          UInt boundingAddrSlice, boundingAddrSliceSegment;
+          boundingAddrSlice        = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];          
+          boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];          
+          nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
           // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
           // If current NALU is the last NALU of slice and a NALU was buffered, then (a) Write current NALU (b) Update an write buffered NALU at approproate location in NALU list.
@@ -1392,4 +1518,7 @@
           xWriteTileLocationToSliceHeader(nalu, pcBitstreamRedirect, pcSlice);
           accessUnit.push_back(new NALUnitEBSP(nalu));
+#if RATE_CONTROL_LAMBDA_DOMAIN
+          actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
+#endif
           bNALUAlignedWrittenToList = true; 
           uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
@@ -1404,23 +1533,24 @@
           }
 
-#if BUFFERING_PERIOD_AND_TIMING_SEI
-          if( ( m_pcCfg->getPictureTimingSEIEnabled() ) &&
-              ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
-              ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) &&
-              ( pcSlice->getSPS()->getVuiParameters()->getSubPicCpbParamsPresentFlag() ) )
-          {
+          if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
+              ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
+              ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
+             || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
+              ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
+          {
+              UInt numNalus = 0;
             UInt numRBSPBytes = 0;
             for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
             {
               UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
-              if ((*it)->m_nalUnitType != NAL_UNIT_SEI)
+              if ((*it)->m_nalUnitType != NAL_UNIT_SEI && (*it)->m_nalUnitType != NAL_UNIT_SEI_SUFFIX)
               {
                 numRBSPBytes += numRBSPBytes_nal;
+                numNalus ++;
               }
             }
             accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
-            accumNalsDU[ pcSlice->getSliceIdx() ] = (UInt)accessUnit.size();
-          }
-#endif
+            accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus;   // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency
+          }
           processingState = ENCODE_SLICE;
           }
@@ -1428,8 +1558,4 @@
         case EXECUTE_INLOOPFILTER:
           {
-#if !REMOVE_APS
-            TComAPS cAPS;
-            allocAPS(&cAPS, pcSlice->getSPS());
-#endif
             // set entropy coder for RD
             m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
@@ -1439,9 +1565,5 @@
               m_pcEntropyCoder->setBitstream( m_pcBitCounter );
               m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcEncTop->getRDGoOnSbacCoder());
-#if REMOVE_APS
               SAOParam& cSaoParam = *pcSlice->getPic()->getPicSym()->getSaoParam();
-#else
-              SAOParam& cSaoParam = *(cAPS.getSaoParam());
-#endif
 
 #if SAO_CHROMA_LAMBDA
@@ -1452,91 +1574,21 @@
 #endif
 #else
-#if ALF_CHROMA_LAMBDA
-              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma());
-#else
               m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambda());
 #endif
-#endif
               m_pcSAO->endSaoEnc();
-#if !REMOVE_ALF
-              m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
-#else
               m_pcSAO->PCMLFDisableProcess(pcPic);
-#endif
             }
 #if SAO_RDO
             m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
 #endif
-            // adaptive loop filter
-#if !REMOVE_ALF
-            if ( pcSlice->getSPS()->getUseALF())
-            {
-#if ALF_CHROMA_LAMBDA 
-              m_pcAdaptiveLoopFilter->ALFProcess(cAPS.getAlfParam(), pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma() );
-#else
-#if SAO_CHROMA_LAMBDA
-              m_pcAdaptiveLoopFilter->ALFProcess(cAPS.getAlfParam(), pcPic->getSlice(0)->getLambdaLuma());
-#else
-              m_pcAdaptiveLoopFilter->ALFProcess(cAPS.getAlfParam(), pcPic->getSlice(0)->getLambda());
-#endif
-#endif
-              m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
-            }
-#endif
-#if !REMOVE_APS
-            iCodedAPSIdx = iCurrAPSIdx;
-            pcSliceForAPS = pcSlice;
-
-            assignNewAPS(cAPS, iCodedAPSIdx, vAPS, pcSliceForAPS);
-            iCurrAPSIdx = (iCurrAPSIdx +1)%MAX_NUM_SUPPORTED_APS;
-#endif
-            processingState = ENCODE_APS;
-
-            //set APS link to the slices
+            processingState = ENCODE_SLICE;
+
             for(Int s=0; s< uiNumSlices; s++)
             {
-#if !REMOVE_ALF
-              if (pcSlice->getSPS()->getUseALF())
-              {
-                for(Int compIdx =0; compIdx< 3; compIdx++)
-                {
-                  pcPic->getSlice(s)->setAlfEnabledFlag( cAPS.getAlfEnabled(compIdx), compIdx);
-                }
-              }
-#endif
               if (pcSlice->getSPS()->getUseSAO())
               {
-#if REMOVE_APS
                 pcPic->getSlice(s)->setSaoEnabledFlag((pcSlice->getPic()->getPicSym()->getSaoParam()->bSaoFlag[0]==1)?true:false);
-#else
-                pcPic->getSlice(s)->setSaoEnabledFlag((cAPS.getSaoParam()->bSaoFlag[0]==1)?true:false);
-#endif
               }
-#if !REMOVE_APS
-              pcPic->getSlice(s)->setAPS(&(vAPS[iCodedAPSIdx]));
-              pcPic->getSlice(s)->setAPSId(iCodedAPSIdx);
-#endif
             }
-
-            /* The destructor of cAPS that is about to be called will free
-             * the resource held by cAPS, which will cause problems since it
-             * has been aliased elsewhere.
-             *   Hint: never ever write an assignment operator that copies
-             *         pointers without the use of smart pointers.
-             * The following will clear the saved state before the destructor.
-             */
-#if !REMOVE_APS
-            cAPS = TComAPS();
-#endif
-          }
-          break;
-        case ENCODE_APS:
-          {
-#if !REMOVE_APS
-            OutputNALUnit nalu(NAL_UNIT_APS, true);
-            encodeAPS(&(vAPS[iCodedAPSIdx]), nalu.m_Bitstream, pcSliceForAPS);
-            accessUnit.push_back(new NALUnitEBSP(nalu));
-#endif
-            processingState = ENCODE_SLICE;
           }
           break;
@@ -1550,9 +1602,5 @@
       } // end iteration over slices
 
-#if REMOVE_ALF
       if(pcSlice->getSPS()->getUseSAO())
-#else
-      if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
-#endif
       {
         if(pcSlice->getSPS()->getUseSAO())
@@ -1560,10 +1608,4 @@
           m_pcSAO->destroyPicSaoInfo();
         }
-#if !REMOVE_ALF
-        if(pcSlice->getSPS()->getUseALF())
-        {
-          m_pcAdaptiveLoopFilter->destroyPicAlfInfo();
-        }
-#endif
         pcPic->destroyNonDBFilterInfo();
       }
@@ -1572,7 +1614,7 @@
       
       //-- For time output for each slice
-      Double dEncTime = (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
-
-      const char* digestStr = NULL;
+      Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
+
+      const Char* digestStr = NULL;
       if (m_pcCfg->getDecodedPictureHashSEIEnabled())
       {
@@ -1598,20 +1640,36 @@
         }
 #if SVC_EXTENSION
-#if REMOVE_NAL_REF_FLAG
-        OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer(), m_layerId);
+        OutputNALUnit nalu(NAL_UNIT_SEI_SUFFIX, pcSlice->getTLayer(), m_layerId);
 #else
-        OutputNALUnit nalu(NAL_UNIT_SEI, false, pcSlice->getTLayer(), m_layerId);
-#endif
-#else
-#if REMOVE_NAL_REF_FLAG
-        OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer());
-#else
-        OutputNALUnit nalu(NAL_UNIT_SEI, false, pcSlice->getTLayer());
-#endif
+        OutputNALUnit nalu(NAL_UNIT_SEI_SUFFIX, pcSlice->getTLayer());
 #endif
 
         /* write the SEI messages */
         m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
-        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest);
+        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
+        writeRBSPTrailingBits(nalu.m_Bitstream);
+
+        accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
+      }
+      if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
+      {
+        SEITemporalLevel0Index sei_temporal_level0_index;
+        if (pcSlice->getRapPicFlag())
+        {
+          m_tl0Idx = 0;
+          m_rapIdx = (m_rapIdx + 1) & 0xFF;
+        }
+        else
+        {
+          m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
+        }
+        sei_temporal_level0_index.tl0Idx = m_tl0Idx;
+        sei_temporal_level0_index.rapIdx = m_rapIdx;
+
+        OutputNALUnit nalu(NAL_UNIT_SEI); 
+
+        /* write the SEI messages */
+        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
+        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());
         writeRBSPTrailingBits(nalu.m_Bitstream);
 
@@ -1638,53 +1696,199 @@
         }
       }
+#if RATE_CONTROL_LAMBDA_DOMAIN
+      if ( m_pcCfg->getUseRateCtrl() )
+      {
+        Double effectivePercentage = m_pcRateCtrl->getRCPic()->getEffectivePercentage();
+        Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
+        Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
+        if ( avgLambda < 0.0 )
+        {
+          avgLambda = lambda;
+        }
+        m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, effectivePercentage );
+        m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
+
+        m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
+        if ( pcSlice->getSliceType() != I_SLICE )
+        {
+          m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
+        }
+        else    // for intra picture, the estimated bits are used to update the current status in the GOP
+        {
+          m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
+        }
+      }
+#else
       if(m_pcCfg->getUseRateCtrl())
       {
-        unsigned  frameBits = m_vRVM_RP[m_vRVM_RP.size()-1];
+        UInt  frameBits = m_vRVM_RP[m_vRVM_RP.size()-1];
         m_pcRateCtrl->updataRCFrameStatus((Int)frameBits, pcSlice->getSliceType());
       }
-#if BUFFERING_PERIOD_AND_TIMING_SEI
-      if( ( m_pcCfg->getPictureTimingSEIEnabled() ) &&
-          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
-          ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) )
-      {
-        OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer());
+#endif
+      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
+          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
+          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
+         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
+      {
         TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
-
-        if( vui->getSubPicCpbParamsPresentFlag() )
+        TComHRD *hrd = vui->getHrdParameters();
+
+        if( hrd->getSubPicCpbParamsPresentFlag() )
         {
           Int i;
           UInt64 ui64Tmp;
-          UInt uiTmp, uiPrev, uiCurr;
-
-          uiPrev = 0;
-          for( i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
-          {
-            pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
-            ui64Tmp = ( ( ( accumBitsDU[ pictureTimingSEI.m_numDecodingUnitsMinus1 ] - accumBitsDU[ i ] ) * ( vui->getTimeScale() / vui->getNumUnitsInTick() ) * ( vui->getTickDivisorMinus2() + 2 ) ) 
-                        / ( m_pcCfg->getTargetBitrate() << 10 ) );
-
-            uiTmp = (UInt)ui64Tmp;
-            if( uiTmp >= ( vui->getTickDivisorMinus2() + 2 ) )      uiCurr = 0;
-            else                                                     uiCurr = ( vui->getTickDivisorMinus2() + 2 ) - uiTmp;
-
-            if( i == pictureTimingSEI.m_numDecodingUnitsMinus1 ) uiCurr = vui->getTickDivisorMinus2() + 2;
-            if( uiCurr <= uiPrev )                                   uiCurr = uiPrev + 1;
-
-            pictureTimingSEI.m_duCpbRemovalDelayMinus1[ i ]              = (uiCurr - uiPrev) - 1;
-            uiPrev = uiCurr;
-          }
-        }
-        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
-        pictureTimingSEI.m_sps = pcSlice->getSPS();
-        m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI);
-        writeRBSPTrailingBits(nalu.m_Bitstream);
-
-        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
-        accessUnit.insert(it, new NALUnitEBSP(nalu));
-      }
-#endif
-#if FIXED_ROUNDING_FRAME_MEMORY
-      /* TODO: this should happen after copyToPic(pcPicYuvRecOut) */
-      pcPic->getPicYuvRec()->xFixedRoundingPic();
+          UInt uiPrev = 0;
+          UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
+          UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
+          UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
+
+          for( i = 0; i < numDU; i ++ )
+          {
+            pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
+          }
+
+          if( numDU == 1 )
+          {
+            pCRD[ 0 ] = 0; /* don't care */
+          }
+          else
+          {
+            pCRD[ numDU - 1 ] = 0;/* by definition */
+            UInt tmp = 0;
+            UInt accum = 0;
+
+            for( i = ( numDU - 2 ); i >= 0; i -- )
+            {
+#if L0043_TIMING_INFO
+              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
+#else
+              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( hrd->getTimeScale() / hrd->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
+#endif
+              if( (UInt)ui64Tmp > maxDiff )
+              {
+                tmp ++;
+              }
+            }
+            uiPrev = 0;
+
+            UInt flag = 0;
+            for( i = ( numDU - 2 ); i >= 0; i -- )
+            {
+              flag = 0;
+#if L0043_TIMING_INFO
+              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
+#else
+              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( hrd->getTimeScale() / hrd->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
+#endif
+
+              if( (UInt)ui64Tmp > maxDiff )
+              {
+                if(uiPrev >= maxDiff - tmp)
+                {
+                  ui64Tmp = uiPrev + 1;
+                  flag = 1;
+                }
+                else                            ui64Tmp = maxDiff - tmp + 1;
+              }
+              pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
+              if( (Int)pCRD[ i ] < 0 )
+              {
+                pCRD[ i ] = 0;
+              }
+              else if (tmp > 0 && flag == 1) 
+              {
+                tmp --;
+              }
+              accum += pCRD[ i ] + 1;
+              uiPrev = accum;
+            }
+          }
+        }
+        if( m_pcCfg->getPictureTimingSEIEnabled() )
+        {
+          OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer());
+          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
+          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
+          writeRBSPTrailingBits(nalu.m_Bitstream);
+#if L0045_NON_NESTED_SEI_RESTRICTIONS
+          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
+          UInt offsetPosition = m_activeParameterSetSEIPresentInAU 
+                                    + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
+          AccessUnit::iterator it;
+          for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
+          {
+            it++;
+          }
+          accessUnit.insert(it, new NALUnitEBSP(nalu));
+          m_pictureTimingSEIPresentInAU = true;
+#else
+          AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
+          accessUnit.insert(it, new NALUnitEBSP(nalu));
+#endif
+        }
+        if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
+        {             
+          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
+          for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
+          {
+            OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer());
+
+            SEIDecodingUnitInfo tempSEI;
+            tempSEI.m_decodingUnitIdx = i;
+            tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
+#if L0044_DU_DPB_OUTPUT_DELAY_HRD
+            tempSEI.m_dpbOutputDuDelayPresentFlag = false;
+            tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
+#endif
+
+            AccessUnit::iterator it;
+            // Insert the first one in the right location, before the first slice
+            if(i == 0)
+            {
+              // Insert before the first slice. 
+              m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
+              writeRBSPTrailingBits(nalu.m_Bitstream);
+
+#if L0045_NON_NESTED_SEI_RESTRICTIONS
+              UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
+              UInt offsetPosition = m_activeParameterSetSEIPresentInAU 
+                                    + m_bufferingPeriodSEIPresentInAU 
+                                    + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
+              for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
+              {
+                it++;
+              }
+              accessUnit.insert(it, new NALUnitEBSP(nalu));
+#else
+              it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
+              accessUnit.insert(it, new NALUnitEBSP(nalu)); 
+#endif
+            }
+            else
+            {
+              Int ctr;
+              // For the second decoding unit onwards we know how many NALUs are present
+              for (ctr = 0, it = accessUnit.begin(); it != accessUnit.end(); it++)
+              {            
+                if(ctr == accumNalsDU[ i - 1 ])
+                {
+                  // Insert before the first slice. 
+                  m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
+                  writeRBSPTrailingBits(nalu.m_Bitstream);
+
+                  accessUnit.insert(it, new NALUnitEBSP(nalu));
+                  break;
+                }
+                if ((*it)->m_nalUnitType != NAL_UNIT_SEI && (*it)->m_nalUnitType != NAL_UNIT_SEI_SUFFIX)
+                {
+                  ctr++;
+                }
+              }
+            }            
+          }
+        }
+      }
+#if L0045_NON_NESTED_SEI_RESTRICTIONS
+      xResetNonNestedSEIPresentFlags();
 #endif
       pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
@@ -1693,7 +1897,5 @@
       m_bFirst = false;
       m_iNumPicCoded++;
-#if BUFFERING_PERIOD_AND_TIMING_SEI
       m_totalCoded ++;
-#endif
       /* logging: insert a newline at end of picture period */
       printf("\n");
@@ -1702,14 +1904,14 @@
       delete[] pcSubstreamsOut;
   }
+#if !RATE_CONTROL_LAMBDA_DOMAIN
   if(m_pcCfg->getUseRateCtrl())
   {
     m_pcRateCtrl->updateRCGOPStatus();
   }
+#endif
   delete pcBitstreamRedirect;
 
-#if BUFFERING_PERIOD_AND_TIMING_SEI
   if( accumBitsDU != NULL) delete accumBitsDU;
   if( accumNalsDU != NULL) delete accumNalsDU;
-#endif
 
 #if SVC_EXTENSION
@@ -1719,88 +1921,4 @@
 #endif
 }
-
-#if !REMOVE_APS
-/** Memory allocation for APS
-  * \param [out] pAPS APS pointer
-  * \param [in] pSPS SPS pointer
-  */
-Void TEncGOP::allocAPS (TComAPS* pAPS, TComSPS* pSPS)
-{
-  if(pSPS->getUseSAO())
-  {
-    pAPS->createSaoParam();
-    m_pcSAO->allocSaoParam(pAPS->getSaoParam());
-  }
-#if !REMOVE_ALF
-  pAPS->createAlfParam();
-#endif
-}
-
-/** Memory deallocation for APS
-  * \param [out] pAPS APS pointer
-  * \param [in] pSPS SPS pointer
-  */
-Void TEncGOP::freeAPS (TComAPS* pAPS, TComSPS* pSPS)
-{
-  if(pSPS->getUseSAO())
-  {
-    if(pAPS->getSaoParam() != NULL)
-    {
-      m_pcSAO->freeSaoParam(pAPS->getSaoParam());
-      pAPS->destroySaoParam();
-
-    }
-  }
-#if !REMOVE_ALF
-  pAPS->destroyAlfParam();
-#endif
-}
-
-/** Assign APS object into APS container according to APS ID
-  * \param [in] cAPS APS object
-  * \param [in] apsID APS ID
-  * \param [in,out] vAPS APS container
-  * \param [in] pcSlice pointer to slice
-  */
-Void TEncGOP::assignNewAPS(TComAPS& cAPS, Int apsID, std::vector<TComAPS>& vAPS, TComSlice* pcSlice)
-{
-
-  cAPS.setAPSID(apsID);
-
-  //assign new APS into APS container
-  Int apsBufSize= (Int)vAPS.size();
-
-  if(apsID >= apsBufSize)
-  {
-    vAPS.resize(apsID +1);
-  }
-
-  freeAPS(&(vAPS[apsID]), pcSlice->getSPS());
-  vAPS[apsID] = cAPS;
-}
-
-/** encode APS syntax elements
-  * \param [in] pcAPS APS pointer
-  * \param [in, out] APSbs bitstream
-  * \param [in] pointer to slice (just used for entropy coder initialization)
-  */
-Void TEncGOP::encodeAPS(TComAPS* pcAPS, TComOutputBitstream& APSbs, TComSlice* pcSlice)
-{
-  m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice);
-  m_pcEntropyCoder->resetEntropy      ();
-  m_pcEntropyCoder->setBitstream(&APSbs);
-
-  m_pcEntropyCoder->encodeAPSInitInfo(pcAPS);
-#if !REMOVE_ALF
-  for(Int compIdx=0; compIdx < 3; compIdx++)
-  {
-    m_pcEntropyCoder->encodeAlfParam( (pcAPS->getAlfParam())[compIdx]);
-  }
-#endif
-  m_pcEntropyCoder->encodeApsExtensionFlag();
-  //neither SAO and ALF is enabled
-  writeRBSPTrailingBits(APSbs);
-}
-#endif
 
 #if !SVC_EXTENSION
@@ -1846,5 +1964,5 @@
   TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
   Bool bCalcDist = false;
-  m_pcLoopFilter->setCfg(pcSlice->getPPS()->getDeblockingFilterControlPresentFlag(), pcSlice->getDeblockingFilterDisable(), m_pcCfg->getLoopFilterBetaOffset(), m_pcCfg->getLoopFilterTcOffset(), m_pcCfg->getLFCrossTileBoundaryFlag());
+  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
   m_pcLoopFilter->loopFilterPic( pcPic );
   
@@ -1853,9 +1971,5 @@
   m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
   pcSlice = pcPic->getSlice(0);
-#if REMOVE_ALF
   if(pcSlice->getSPS()->getUseSAO())
-#else
-  if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
-#endif
   {
     std::vector<Bool> LFCrossSliceBoundaryFlag(1, true);
@@ -1866,38 +1980,5 @@
   }
   
-#if !REMOVE_ALF
-  // Adaptive Loop filter
-  if( pcSlice->getSPS()->getUseALF() )
-  {
-    m_pcAdaptiveLoopFilter->createPicAlfInfo(pcPic);
-
-    ALFParam* alfPicParam[3];
-    for(Int compIdx=0; compIdx < 3; compIdx++)
-    {
-      alfPicParam[compIdx] = new ALFParam(compIdx);
-    }
-
-#if ALF_CHROMA_LAMBDA 
-    m_pcAdaptiveLoopFilter->ALFProcess(alfPicParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma() );
-#else
-#if SAO_CHROMA_LAMBDA
-    m_pcAdaptiveLoopFilter->ALFProcess(alfPicParam, pcPic->getSlice(0)->getLambdaLuma());
-#else
-    m_pcAdaptiveLoopFilter->ALFProcess(alfPicParam, pcPic->getSlice(0)->getLambda());
-#endif
-#endif
-    for(Int compIdx=0; compIdx < 3; compIdx++)
-    {
-      delete alfPicParam[compIdx]; alfPicParam[compIdx] = NULL;
-    }
-    m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
-    m_pcAdaptiveLoopFilter->destroyPicAlfInfo();
-  }
-#endif
-#if REMOVE_ALF
   if( pcSlice->getSPS()->getUseSAO())
-#else
-  if( pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
-#endif
   {
     pcPic->destroyNonDBFilterInfo();
@@ -1931,5 +2012,5 @@
 }
 
-Void TEncGOP::xGetBuffer( TComList<TComPic*>&       rcListPic,
+Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
                          TComList<TComPicYuv*>&    rcListPicYuvRecOut,
                          Int                       iNumPicRcvd,
@@ -1937,5 +2018,5 @@
                          TComPic*&                 rpcPic,
                          TComPicYuv*&              rpcPicYuvRecOut,
-                         UInt                      uiPOCCurr )
+                         Int                       pocCurr )
 {
   Int i;
@@ -1955,5 +2036,5 @@
     rpcPic = *(iterPic);
     rpcPic->setCurrSliceIdx(0);
-    if (rpcPic->getPOC() == (Int)uiPOCCurr)
+    if (rpcPic->getPOC() == pocCurr)
     {
       break;
@@ -1962,5 +2043,5 @@
   }
   
-  assert (rpcPic->getPOC() == (Int)uiPOCCurr);
+  assert (rpcPic->getPOC() == pocCurr);
   
   return;
@@ -1972,10 +2053,5 @@
   Pel*  pSrc0   = pcPic0 ->getLumaAddr();
   Pel*  pSrc1   = pcPic1 ->getLumaAddr();
-#if IBDI_DISTORTION
-  Int  iShift = g_uiBitIncrement;
-  Int  iOffset = 1<<(g_uiBitIncrement-1);
-#else
-  UInt  uiShift = g_uiBitIncrement<<1;
-#endif
+  UInt  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthY-8);
   Int   iTemp;
   
@@ -1990,9 +2066,5 @@
     for( x = 0; x < iWidth; x++ )
     {
-#if IBDI_DISTORTION
-      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
-#else
       iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
-#endif
     }
     pSrc0 += iStride;
@@ -2000,4 +2072,5 @@
   }
   
+  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
   iHeight >>= 1;
   iWidth  >>= 1;
@@ -2011,9 +2084,5 @@
     for( x = 0; x < iWidth; x++ )
     {
-#if IBDI_DISTORTION
-      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
-#else
       iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
-#endif
     }
     pSrc0 += iStride;
@@ -2028,9 +2097,5 @@
     for( x = 0; x < iWidth; x++ )
     {
-#if IBDI_DISTORTION
-      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
-#else
       iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
-#endif
     }
     pSrc0 += iStride;
@@ -2042,9 +2107,8 @@
 
 #if VERBOSE_RATE
-static const char* nalUnitTypeToString(NalUnitType type)
+static const Char* nalUnitTypeToString(NalUnitType type)
 {
   switch (type)
   {
-#if NAL_UNIT_TYPES_J1003_D7
     case NAL_UNIT_CODED_SLICE_TRAIL_R: return "TRAIL_R";
     case NAL_UNIT_CODED_SLICE_TRAIL_N: return "TRAIL_N";
@@ -2061,18 +2125,7 @@
     case NAL_UNIT_CODED_SLICE_DLP: return "DLP";
     case NAL_UNIT_CODED_SLICE_TFD: return "TFD";
-#else
-    case NAL_UNIT_CODED_SLICE: return "SLICE";
-    case NAL_UNIT_CODED_SLICE_TFD: return "TFD";
-    case NAL_UNIT_CODED_SLICE_TLA: return "TLA";
-    case NAL_UNIT_CODED_SLICE_CRA: return "CRA";
-    case NAL_UNIT_CODED_SLICE_CRANT: return "CRANT";
-    case NAL_UNIT_CODED_SLICE_BLA: return "BLA";
-    case NAL_UNIT_CODED_SLICE_BLANT: return "BLANT";
-    case NAL_UNIT_CODED_SLICE_IDR: return "IDR";
-#endif
     case NAL_UNIT_VPS: return "VPS";
     case NAL_UNIT_SPS: return "SPS";
     case NAL_UNIT_PPS: return "PPS";
-#if NAL_UNIT_TYPES_J1003_D7
     case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
     case NAL_UNIT_EOS: return "EOS";
@@ -2080,10 +2133,4 @@
     case NAL_UNIT_FILLER_DATA: return "FILLER";
     case NAL_UNIT_SEI: return "SEI";
-#else
-    case NAL_UNIT_APS: return "APS";
-    case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
-    case NAL_UNIT_FILLER_DATA: return "FILLER";
-    case NAL_UNIT_SEI: return "SEI";
-#endif
     default: return "UNK";
   }
@@ -2157,7 +2204,8 @@
   }
   
-  unsigned int maxval = 255 * (1<<(g_uiBitDepth + g_uiBitIncrement -8));
-  Double fRefValueY = (double) maxval * maxval * iSize;
-  Double fRefValueC = fRefValueY / 4.0;
+  Int maxvalY = 255 << (g_bitDepthY-8);
+  Int maxvalC = 255 << (g_bitDepthC-8);
+  Double fRefValueY = (Double) maxvalY * maxvalY * iSize;
+  Double fRefValueC = (Double) maxvalC * maxvalC * iSize / 4.0;
   dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
   dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
@@ -2168,16 +2216,18 @@
    *  - SEI NAL units
    */
-  unsigned numRBSPBytes = 0;
+  UInt numRBSPBytes = 0;
   for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
   {
-    unsigned numRBSPBytes_nal = unsigned((*it)->m_nalUnitData.str().size());
+    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
 #if VERBOSE_RATE
     printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
 #endif
-    if ((*it)->m_nalUnitType != NAL_UNIT_SEI)
+    if ((*it)->m_nalUnitType != NAL_UNIT_SEI && (*it)->m_nalUnitType != NAL_UNIT_SEI_SUFFIX)
+    {
       numRBSPBytes += numRBSPBytes_nal;
-  }
-
-  unsigned uibits = numRBSPBytes * 8;
+    }
+  }
+
+  UInt uibits = numRBSPBytes * 8;
   m_vRVM_RP.push_back( uibits );
 
@@ -2271,15 +2321,15 @@
 
 /** Function for deciding the nal_unit_type.
- * \param uiPOCCurr POC of the current picture
- * \returns the nal_unit type of the picture
+ * \param pocCurr POC of the current picture
+ * \returns the nal unit type of the picture
  * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
  */
-NalUnitType TEncGOP::getNalUnitType(UInt uiPOCCurr)
+NalUnitType TEncGOP::getNalUnitType(Int pocCurr)
 {
-  if (uiPOCCurr == 0)
+  if (pocCurr == 0)
   {
     return NAL_UNIT_CODED_SLICE_IDR;
   }
-  if (uiPOCCurr % m_pcCfg->getIntraPeriod() == 0)
+  if (pocCurr % m_pcCfg->getIntraPeriod() == 0)
   {
     if (m_pcCfg->getDecodingRefreshType() == 1)
@@ -2294,5 +2344,5 @@
   if(m_pocCRA>0)
   {
-    if(uiPOCCurr<m_pocCRA)
+    if(pocCurr<m_pocCRA)
     {
       // All leading pictures are being marked as TFD pictures here since current encoder uses all 
@@ -2304,9 +2354,5 @@
     }
   }
-#if NAL_UNIT_TYPES_J1003_D7
   return NAL_UNIT_CODED_SLICE_TRAIL_R;
-#else
-  return NAL_UNIT_CODED_SLICE;
-#endif
 }
 
@@ -2315,5 +2361,5 @@
   Double dRVM = 0;
   
-  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFrameToBeEncoded() > RVM_VCEGAM10_M * 2 )
+  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
   {
     // calculate RVM only for lowdelay configurations
@@ -2340,5 +2386,5 @@
     dBavg /= ( N - 2 * RVM_VCEGAM10_M );
     
-    double dSigamB = 0;
+    Double dSigamB = 0;
     for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
     {
@@ -2348,5 +2394,5 @@
     dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
     
-    double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
+    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
     
     dRVM = dSigamB / dRavg * f;
@@ -2363,9 +2409,5 @@
 {
   // Byte-align
-#if BYTE_ALIGNMENT
   rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
-#else
-  rNalu.m_Bitstream.writeAlignOne();
-#endif
 
   // Perform bitstream concatenation
@@ -2411,7 +2453,9 @@
   // and assign values for pocLSBLT and MSB present flag
   Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
+  Int longtermPicsMSB[MAX_NUM_REF_PICS];
   Bool mSBPresentFlag[MAX_NUM_REF_PICS];
   ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
   ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
+  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
   ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
   ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
@@ -2426,52 +2470,24 @@
     longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
     indices[ctr]      = i; 
+    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
   }
   Int numLongPics = rps->getNumberOfLongtermPictures();
   assert(ctr == numLongPics);
 
-  // Arrange LTR pictures in decreasing order of LSB
+  // Arrange pictures in decreasing order of MSB; 
   for(i = 0; i < numLongPics; i++)
   {
     for(Int j = 0; j < numLongPics - 1; j++)
     {
-      if(longtermPicsLSB[j] < longtermPicsLSB[j+1])
+      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
       {
         std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
         std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
+        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
         std::swap(indices[j]        , indices[j+1]        );
       }
     }
   }
-  // Now for those pictures that have the same LSB, arrange them 
-  // in increasing MSB cycle, or equivalently decreasing MSB
-  for(i = 0; i < numLongPics;)    // i incremented using j
-  {
-    Int j = i + 1;
-    Int pocLSB = longtermPicsLSB[i];
-    for(; j < numLongPics; j++)
-    {
-      if(pocLSB != longtermPicsLSB[j])
-      {
-        break;
-      }
-    }
-    // Last index upto which lsb equals pocLSB is j - 1 
-    // Now sort based on the MSB values
-    Int sta, end;
-    for(sta = i; sta < j; sta++)
-    {
-      for(end = i; end < j - 1; end++)
-      {
-      // longtermPicsMSB = longtermPicsPoc - longtermPicsLSB
-        if(longtermPicsPoc[end] - longtermPicsLSB[end] < longtermPicsPoc[end+1] - longtermPicsLSB[end+1])
-        {
-          std::swap(longtermPicsPoc[end], longtermPicsPoc[end+1]);
-          std::swap(longtermPicsLSB[end], longtermPicsLSB[end+1]);
-          std::swap(indices[end]        , indices[end+1]        );
-        }
-      }
-    }
-    i = j;
-  }
+
   for(i = 0; i < numLongPics; i++)
   {
@@ -2484,9 +2500,5 @@
       pcPic = *iterPic;
       if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
-#if REFERENCE_PICTURE_DEFN
                                       (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
-#else
-                                      (pcPic->getSlice(0)->getNalRefFlag())     &&    // Reference picture
-#endif
                                         (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
       {
@@ -2522,4 +2534,35 @@
     assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
   }
+  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
+  {
+    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
+    {
+      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we 
+      // don't have to check the MSB present flag values for this constraint.
+      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
+    }
+  }
 }
+
+#if L0045_NON_NESTED_SEI_RESTRICTIONS
+/** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
+ * \param accessUnit Access Unit of the current picture
+ * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
+ */
+Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
+{
+  // Find the location of the first SEI message
+  AccessUnit::iterator it;
+  Int seiStartPos = 0;
+  for(it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
+  {
+     if ((*it)->isSei() || (*it)->isVcl())
+     {
+       break;
+     }               
+  }
+  assert(it != accessUnit.end());
+  return seiStartPos;
+}
+#endif
 //! \}
