Index: trunk/source/App/TAppDecoder/TAppDecCfg.cpp
===================================================================
--- trunk/source/App/TAppDecoder/TAppDecCfg.cpp	(revision 713)
+++ trunk/source/App/TAppDecoder/TAppDecCfg.cpp	(revision 815)
@@ -146,4 +146,5 @@
   m_tgtLayerId = nLayerNum - 1;
   assert( m_tgtLayerId >= 0 );
+  assert( m_tgtLayerId < MAX_LAYERS );
 #if O0137_MAX_LAYERID
   assert( m_tgtLayerId < MAX_NUM_LAYER_IDS );
Index: trunk/source/App/TAppDecoder/TAppDecTop.cpp
===================================================================
--- trunk/source/App/TAppDecoder/TAppDecTop.cpp	(revision 713)
+++ trunk/source/App/TAppDecoder/TAppDecTop.cpp	(revision 815)
@@ -191,5 +191,4 @@
     InputNALUnit nalu;
     byteStreamNALUnit(bytestream, nalUnit, stats);
-
     // call actual decoding function
     Bool bNewPicture = false;
@@ -215,5 +214,9 @@
       {
         bNewPicture = m_acTDecTop[nalu.m_layerId].decode(nalu, m_iSkipFrame, m_aiPOCLastDisplay[nalu.m_layerId], curLayerId, bNewPOC);
+#if POC_RESET_IDC_DECODER
+        if ( (bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 3) || (m_acTDecTop[nalu.m_layerId].getParseIdc() == 0) )
+#else
         if (bNewPicture)
+#endif
         {
           bitstreamFile.clear();
@@ -225,8 +228,22 @@
           bytestream.reset();
         }
-      }
-    }
-
+#if POC_RESET_IDC_DECODER
+        else if(m_acTDecTop[nalu.m_layerId].getParseIdc() == 1) 
+        {
+          bitstreamFile.clear();
+          // This is before third parse of the NAL unit, and 
+          // location points to correct beginning of the NALU
+          bitstreamFile.seekg(location);
+          bytestream.reset();
+        }
+#endif
+      }
+    }
+
+#if POC_RESET_IDC_DECODER
+    if ((bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 3) || (m_acTDecTop[nalu.m_layerId].getParseIdc() == 0) || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS)
+#else
     if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS)
+#endif
     {
 #if O0194_DIFFERENT_BITDEPTH_EL_BL
@@ -245,4 +262,11 @@
     }
 
+#if POC_RESET_IDC_DECODER
+    if( bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() == 0 )
+    {
+      outputAllPictures( nalu.m_layerId, true );
+    }
+#endif
+
     if( pcListPic )
     {
@@ -269,5 +293,11 @@
         flushAllPictures( nalu.m_layerId, outputPicturesFlag );       
       }
+
+#if POC_RESET_IDC_DECODER
+      if( bNewPicture && m_acTDecTop[nalu.m_layerId].getParseIdc() != 0 )
+      // New picture, slice header parsed but picture not decoded
+#else
       if( bNewPicture ) // New picture, slice header parsed but picture not decoded
+#endif
       {
 #if NO_OUTPUT_OF_PRIOR_PICS
@@ -1235,5 +1265,9 @@
 
     // Find the status of the DPB
+#if POC_RESET_IDC_DECODER
+    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, false);
+#else
     xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus);
+#endif
 
     while( dpbStatus.m_numAUsNotDisplayed )
@@ -1282,6 +1316,8 @@
   // Find DPB-information from the VPS
   DpbStatus maxDpbLimit;
+#if RESOLUTION_BASED_DPB
   Int targetLsIdx, subDpbIdx;
   TComVPS *vps = findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
+
   if( getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 )
   {
@@ -1294,4 +1330,8 @@
     subDpbIdx   = vps->getSubDpbAssigned( targetLsIdx, layerIdx );
   }
+#else
+  Int subDpbIdx = getCommonDecoderParams()->getTargetOutputLayerSetIdx() == 0 ? 0 : layerIdx;
+  findDpbParametersFromVps(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, maxDpbLimit);
+#endif
   // Assume that listOfPocs is sorted in increasing order - if not have to sort it.
   while( ifInvokeBumpingBeforeDecoding(dpbStatus, maxDpbLimit, layerIdx, subDpbIdx) )
@@ -1437,6 +1477,10 @@
     for(Int i = 0; i < vps->getNumLayersInIdList( targetLsIdx ); i++)
     {
+#if RESOUTION_BASED_DPB
       maxDpbLimit.m_numPicsInLayer[i] = vps->getMaxVpsLayerDecPicBuffMinus1( targetOutputLsIdx, i, highestTId ) + 1;
       maxDpbLimit.m_numPicsInSubDpb[vps->getSubDpbAssigned( targetLsIdx, i )] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, vps->getSubDpbAssigned( targetLsIdx, i ), highestTId) + 1;
+#else
+      maxDpbLimit.m_numPicsInSubDpb[i] = vps->getMaxVpsDecPicBufferingMinus1( targetOutputLsIdx, i, highestTId) + 1;
+#endif
     }
     // -------------------------------------
@@ -1472,6 +1516,8 @@
   retVal |= ( dpbStatus.m_numPicsInSubDpb[subDpbIdx] >= dpbLimit.m_numPicsInSubDpb[subDpbIdx] );
   
+#if RESOLUTION_BASED_DPB
   // Number of pictures in each layer
   retVal |= ( dpbStatus.m_numPicsInLayer[layerIdx] >= dpbLimit.m_numPicsInLayer[layerIdx]);
+#endif
 
   return retVal;
@@ -1492,4 +1538,7 @@
                             , std::vector<Int> *listOfPocsPositionInEachLayer
                             , DpbStatus &dpbStatus
+#if POC_RESET_IDC_DECODER
+                            , Bool notOutputCurrAu
+#endif
                             )
 {
@@ -1516,20 +1565,26 @@
           vps = pic->getSlice(0)->getVPS();
         }
-
-        std::vector<Int>::iterator it;
-        if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
-        {
-          it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
-          if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
+#if POC_RESET_IDC_DECODER
+        if( !(pic->isCurrAu() && notOutputCurrAu ) )
+        {
+#endif
+          std::vector<Int>::iterator it;
+          if( pic->getOutputMark() ) // && pic->getPOC() > m_aiPOCLastDisplay[i])
           {
-            listOfPocs.push_back( pic->getPOC() );
+            it = find( listOfPocs.begin(), listOfPocs.end(), pic->getPOC() ); // Check if already included
+            if( it == listOfPocs.end() )  // New POC value - i.e. new AU - add to the list
+            {
+              listOfPocs.push_back( pic->getPOC() );
+            }
+            listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
+            listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
           }
-          listOfPocsInEachLayer         [i].push_back( pic->getPOC()    );    // POC to be output in each layer
-          listOfPocsPositionInEachLayer [i].push_back( picPositionInList  );  // For ease of access
-        }
-        if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
-        {
-          dpbStatus.m_numPicsInLayer[i]++;  // Count pictures that are "used for reference" or "needed for output"
-        }
+          if( pic->getSlice(0)->isReferenced() || pic->getOutputMark() )
+          {
+            dpbStatus.m_numPicsInLayer[i]++;  // Count pictures that are "used for reference" or "needed for output"
+          }
+#if POC_RESET_IDC_DECODER
+        }
+#endif
       }
       iterPic++;
@@ -1550,10 +1605,35 @@
   {
     dpbStatus.m_numPicsNotDisplayedInLayer[i] = listOfPocsInEachLayer[i].size();
+#if RESOLUTION_BASED_DPB
     dpbStatus.m_numPicsInSubDpb[vps->getSubDpbAssigned(targetLsIdx,i)] += dpbStatus.m_numPicsInLayer[i];
+#else
+    dpbStatus.m_numPicsInSubDpb[i] += dpbStatus.m_numPicsInLayer[i];
+#endif
   }
   assert( dpbStatus.m_numAUsNotDisplayed != -1 );
-
-
 }  
+
+#if POC_RESET_IDC_DECODER
+Void TAppDecTop::outputAllPictures(Int layerId, Bool notOutputCurrPic)
+{
+  { // All pictures in the DPB in that layer are to be output; this means other pictures would also be output
+    std::vector<Int>  listOfPocs;
+    std::vector<Int>  listOfPocsInEachLayer[MAX_LAYERS];
+    std::vector<Int>  listOfPocsPositionInEachLayer[MAX_LAYERS];
+    DpbStatus dpbStatus;
+
+    // Find the status of the DPB
+    xFindDPBStatus(listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus, notOutputCurrPic);
+
+    if( listOfPocs.size() )
+    {
+      while( listOfPocsInEachLayer[layerId].size() )    // As long as there picture in the layer to be output
+      {
+        bumpingProcess( listOfPocs, listOfPocsInEachLayer, listOfPocsPositionInEachLayer, dpbStatus );
+      }
+    }
+  }
+}
+#endif
 #endif
 //! \}
Index: trunk/source/App/TAppDecoder/TAppDecTop.h
===================================================================
--- trunk/source/App/TAppDecoder/TAppDecTop.h	(revision 713)
+++ trunk/source/App/TAppDecoder/TAppDecTop.h	(revision 815)
@@ -107,8 +107,14 @@
 
   Void xOutputAndMarkPic( TComPic *pic, const Char *reconFile, const Int layerID, Int &pocLastDisplay, DpbStatus &dpbStatus);
+#if POC_RESET_IDC_DECODER
+  Void outputAllPictures(Int layerId, Bool notOutputCurrAu);
+#endif
   Void xFindDPBStatus( std::vector<Int> &listOfPocs
                             , std::vector<Int> *listOfPocsInEachLayer
                             , std::vector<Int> *listOfPocsPositionInEachLayer
                             , DpbStatus &dpbStatus
+#if POC_RESET_IDC_DECODER
+                            , Bool notOutputCurrAu = true
+#endif
                             );
 
Index: trunk/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 713)
+++ trunk/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 815)
@@ -69,7 +69,5 @@
 , m_avcBaseLayerFlag(0)
 #endif
-#if N0120_MAX_TID_REF_CFG
 , m_maxTidRefPresentFlag(1)
-#endif 
 , m_pColumnWidth()
 , m_pRowHeight()
@@ -420,7 +418,5 @@
   Int*    cfg_OutputBitDepthC   [MAX_LAYERS];
 #endif
-#if N0120_MAX_TID_REF_CFG
   Int*    cfg_maxTidIlRefPicsPlus1[MAX_LAYERS]; 
-#endif 
   for(UInt layer = 0; layer < MAX_LAYERS; layer++)
   {
@@ -491,11 +487,24 @@
   cfg_OutputBitDepthC  [layer] = &m_acLayerCfg[layer].m_outputBitDepthC;
 #endif
-#if N0120_MAX_TID_REF_CFG
-    cfg_maxTidIlRefPicsPlus1[layer] = &m_acLayerCfg[layer].m_maxTidIlRefPicsPlus1; 
-#endif 
+  cfg_maxTidIlRefPicsPlus1[layer] = &m_acLayerCfg[layer].m_maxTidIlRefPicsPlus1; 
 #if AUXILIARY_PICTURES
     cfg_auxId[layer]                = &m_acLayerCfg[layer].m_auxId; 
 #endif
   }
+#if Q0078_ADD_LAYER_SETS
+  Int* cfg_numLayerInIdList[MAX_VPS_LAYER_SETS_PLUS1];
+  string cfg_layerSetLayerIdList[MAX_VPS_LAYER_SETS_PLUS1];
+  string* cfg_layerSetLayerIdListPtr[MAX_VPS_LAYER_SETS_PLUS1];
+  Int* cfg_numHighestLayerIdx[MAX_VPS_LAYER_SETS_PLUS1];
+  string cfg_highestLayerIdx[MAX_VPS_LAYER_SETS_PLUS1];
+  string* cfg_highestLayerIdxPtr[MAX_VPS_LAYER_SETS_PLUS1];
+  for (UInt i = 0; i < MAX_VPS_LAYER_SETS_PLUS1; i++)
+  {
+    cfg_numLayerInIdList[i] = &m_numLayerInIdList[i];
+    cfg_layerSetLayerIdListPtr[i] = &cfg_layerSetLayerIdList[i];
+    cfg_highestLayerIdxPtr[i] = &cfg_highestLayerIdx[i];
+    cfg_numHighestLayerIdx[i] = &m_numHighestLayerIdx[i];
+  }
+#endif
 #if AVC_BASE
   string  cfg_BLInputFile;
@@ -519,4 +528,8 @@
   string cfg_codedPivotValue;
   string cfg_targetPivotValue;
+#if P0050_KNEE_FUNCTION_SEI
+  string cfg_kneeSEIInputKneePointValue;
+  string cfg_kneeSEIOutputKneePointValue;
+#endif
   po::Options opts;
   opts.addOptions()
@@ -548,4 +561,12 @@
 #endif
   ("NumLayers",               m_numLayers, 1, "Number of layers to code")
+#if Q0078_ADD_LAYER_SETS
+  ("NumLayerSets",            m_numLayerSets, 0, "Number of layer sets")
+  ("NumLayerInIdList%d",      cfg_numLayerInIdList, 0, MAX_VPS_LAYER_ID_PLUS1, "Number of layers in the set")
+  ("LayerSetLayerIdList%d",   cfg_layerSetLayerIdListPtr, string(""), MAX_VPS_LAYER_ID_PLUS1, "Layer IDs for the set")
+  ("NumAddLayerSets",         m_numAddLayerSets, 0, "Number of additional layer sets")
+  ("NumHighestLayerIdx%d",    cfg_numHighestLayerIdx, 0, MAX_VPS_LAYER_ID_PLUS1, "Number of highest layer idx")
+  ("HighestLayerIdx%d",       cfg_highestLayerIdxPtr, string(""), MAX_VPS_LAYER_ID_PLUS1, "Highest layer idx for an additional layer set")
+#endif
 #if AUXILIARY_PICTURES
   ("InputChromaFormat%d",     cfg_tmpInputChromaFormat,  420, MAX_LAYERS, "InputChromaFormatIDC for layer %d")
@@ -554,13 +575,8 @@
 #endif
   ("ConformanceMode%d",       cfg_conformanceMode,0, MAX_LAYERS, "Window conformance mode (0: no cropping, 1:automatic padding, 2: padding, 3:cropping")
-#if SCALABILITY_MASK_E0104
   ("ScalabilityMask1",        m_scalabilityMask[1], 0, "scalability_mask[1] (multiview)")
   ("ScalabilityMask2",        m_scalabilityMask[2], 1, "scalability_mask[2] (scalable)" )
 #if AUXILIARY_PICTURES
   ("ScalabilityMask3",        m_scalabilityMask[3], 0, "scalability_mask[3] (auxiliary pictures)" )
-#endif
-#else
-  ("ScalabilityMask0",        m_scalabilityMask[0], 0, "scalability_mask[0] (multiview)")
-  ("ScalabilityMask1",        m_scalabilityMask[1], 1, "scalability_mask[1] (scalable)" )
 #endif
   ("BitstreamFile,b",         cfg_BitstreamFile, string(""), "Bitstream output file name")
@@ -598,14 +614,10 @@
   ("OutputBitDepthC%d",     cfg_OutputBitDepthC,   0, MAX_LAYERS, "As per OutputBitDepth but for chroma component. (default:InternalBitDepthC)")
 #endif
-#if N0120_MAX_TID_REF_CFG
   ("MaxTidRefPresentFlag", m_maxTidRefPresentFlag, true, "max_tid_ref_present_flag (0: not present, 1: present(default)) " )
   ("MaxTidIlRefPicsPlus1%d", cfg_maxTidIlRefPicsPlus1, 1, MAX_LAYERS, "allowed maximum temporal_id for inter-layer prediction")
-#endif
 #if O0223_PICTURE_TYPES_ALIGN_FLAG
   ("CrossLayerPictureTypeAlignFlag", m_crossLayerPictureTypeAlignFlag, true, "align picture type across layers" )  
 #endif
-#if N0147_IRAP_ALIGN_FLAG
   ("CrossLayerIrapAlignFlag", m_crossLayerIrapAlignFlag, true, "align IRAP across layers" )  
-#endif
 #if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
   ("CrossLayerAlignedIdrOnlyFlag", m_crossLayerAlignedIdrOnlyFlag, true, "only idr for IRAP across layers" )  
@@ -953,4 +965,21 @@
   ("SEISOPDescription",              m_SOPDescriptionSEIEnabled,              0, "Control generation of SOP description SEI messages")
   ("SEIScalableNesting",             m_scalableNestingSEIEnabled,              0, "Control generation of scalable nesting SEI messages")
+#if P0050_KNEE_FUNCTION_SEI
+  ("SEIKneeFunctionInfo",                 m_kneeSEIEnabled,               false, "Control generation of Knee function SEI messages")
+  ("SEIKneeFunctionId",                   m_kneeSEIId,                        0, "Specifies Id of Knee function SEI message for a given session")
+  ("SEIKneeFunctionCancelFlag",           m_kneeSEICancelFlag,            false, "Indicates that Knee function SEI message cancels the persistance or follows")
+  ("SEIKneeFunctionPersistenceFlag",      m_kneeSEIPersistenceFlag,        true, "Specifies the persistence of the Knee function SEI message")
+  ("SEIKneeFunctionMappingFlag",          m_kneeSEIMappingFlag,           false, "Specifies the mapping mode of the Knee function SEI message")
+  ("SEIKneeFunctionInputDrange",          m_kneeSEIInputDrange,            1000, "Specifies the peak luminance level for the input picture of Knee function SEI messages")
+  ("SEIKneeFunctionInputDispLuminance",   m_kneeSEIInputDispLuminance,      100, "Specifies the expected display brightness for the input picture of Knee function SEI messages")
+  ("SEIKneeFunctionOutputDrange",         m_kneeSEIOutputDrange,           4000, "Specifies the peak luminance level for the output picture of Knee function SEI messages")
+  ("SEIKneeFunctionOutputDispLuminance",  m_kneeSEIOutputDispLuminance,     800, "Specifies the expected display brightness for the output picture of Knee function SEI messages")
+  ("SEIKneeFunctionNumKneePointsMinus1",  m_kneeSEINumKneePointsMinus1,       2, "Specifies the number of knee points - 1")
+  ("SEIKneeFunctionInputKneePointValue",  cfg_kneeSEIInputKneePointValue,     string("600 800 900"), "Array of input knee point")
+  ("SEIKneeFunctionOutputKneePointValue", cfg_kneeSEIOutputKneePointValue,    string("100 250 450"), "Array of output knee point")
+#endif
+#if Q0189_TMVP_CONSTRAINTS
+  ("SEITemporalMotionVectorPredictionConstraints",             m_TMVPConstraintsSEIEnabled,              0, "Control generation of TMVP constrants SEI message")
+#endif
 #if M0040_ADAPTIVE_RESOLUTION_CHANGE
   ("AdaptiveResolutionChange",     m_adaptiveResolutionChange, 0, "Adaptive resolution change frame number. Should coincide with EL RAP picture. (0: disable)")
@@ -976,4 +1005,7 @@
   ("CGSLUTBit",     m_nCGSLUTBit , 12, "bit depth of CGS LUT")
 #endif
+#if Q0108_TSA_STSA
+  ("InheritCodingStruct%d",m_inheritCodingStruct, 0, MAX_LAYERS, "Predicts the GOP structure of one layer for another layer")
+#endif
   ;
   
@@ -983,6 +1015,39 @@
     opts.addOptions()(cOSS.str(), m_GOPList[i-1], GOPEntry());
   }
+
+#if Q0108_TSA_STSA
+  for (Int i=1; i<MAX_LAYERS; i++)
+  {
+    for(Int j=1; j<MAX_GOP+1; j++)
+    { 
+      std::ostringstream cOSS;
+      cOSS<<"Layer"<<i<<"Frame"<<j;
+      opts.addOptions()(cOSS.str(), m_EhGOPList[i][j-1], GOPEntry());
+    }
+  }
+#endif 
+
   po::setDefaults(opts);
   const list<const Char*>& argv_unhandled = po::scanArgv(opts, argc, (const Char**) argv);
+
+#if Q0108_TSA_STSA
+  for (Int i=1; i<MAX_LAYERS; i++)
+  {
+    if(m_inheritCodingStruct[i] == 0)
+    {
+      for(Int j=1; j<MAX_GOP+1; j++)
+      { 
+        m_EhGOPList[i][j-1] = m_GOPList[j-1];
+      }
+    }
+    else if( m_inheritCodingStruct[i] > 0)
+    {
+      for(Int j=1; j<MAX_GOP+1; j++)
+      {
+        m_EhGOPList[i][j-1] = m_EhGOPList[m_inheritCodingStruct[i]][j-1];
+      }
+    }
+  }
+#endif 
 
   if(m_isField)
@@ -1309,4 +1374,46 @@
     {
       m_acLayerCfg[layer].m_predLayerIds = NULL;
+    }
+  }
+#endif
+#if Q0078_ADD_LAYER_SETS
+  for (Int layerSet = 0; layerSet < m_numLayerSets; layerSet++)
+  {
+    if (m_numLayerInIdList[layerSet] > 0)
+    {
+      Char* layerSetLayerIdListDup = cfg_layerSetLayerIdList[layerSet].empty() ? NULL : strdup(cfg_layerSetLayerIdList[layerSet].c_str());
+      Int  i = 0;
+      char *layerId = strtok(layerSetLayerIdListDup, " ,-");
+      while (layerId != NULL)
+      {
+        if (i >= m_numLayerInIdList[layerSet])
+        {
+          printf("NumLayerInIdList%d: The number of layers in the set is larger than the allowed number of layers.\n", layerSet);
+          exit(EXIT_FAILURE);
+        }
+        m_layerSetLayerIdList[layerSet][i] = atoi(layerId);
+        layerId = strtok(NULL, " ,-");
+        i++;
+      }
+    }
+  }
+  for (Int addLayerSet = 0; addLayerSet < m_numAddLayerSets; addLayerSet++)
+  {
+    if (m_numHighestLayerIdx[addLayerSet] > 0)
+    {
+      Char* highestLayrIdxListDup = cfg_highestLayerIdx[addLayerSet].empty() ? NULL : strdup(cfg_highestLayerIdx[addLayerSet].c_str());
+      Int  i = 0;
+      char *layerIdx = strtok(highestLayrIdxListDup, " ,-");
+      while (layerIdx != NULL)
+      {
+        if (i >= m_numLayerInIdList[addLayerSet])
+        {
+          printf("NumLayerInIdList%d: The number of layer idx's in the highest layer idx list is larger than the allowed number of idx's.\n", addLayerSet);
+          exit(EXIT_FAILURE);
+        }
+        m_highestLayerIdx[addLayerSet][i] = atoi(layerIdx);
+        layerIdx = strtok(NULL, " ,-");
+        i++;
+      }
     }
   }
@@ -1495,4 +1602,30 @@
     }
   }
+#if P0050_KNEE_FUNCTION_SEI
+  if( m_kneeSEIEnabled && !m_kneeSEICancelFlag )
+  {
+    Char* pcInputKneePointValue  = cfg_kneeSEIInputKneePointValue.empty()  ? NULL : strdup(cfg_kneeSEIInputKneePointValue.c_str());
+    Char* pcOutputKneePointValue = cfg_kneeSEIOutputKneePointValue.empty() ? NULL : strdup(cfg_kneeSEIOutputKneePointValue.c_str());
+    assert ( m_kneeSEINumKneePointsMinus1 >= 0 && m_kneeSEINumKneePointsMinus1 < 999 );
+    m_kneeSEIInputKneePoint = new Int[m_kneeSEINumKneePointsMinus1+1];
+    m_kneeSEIOutputKneePoint = new Int[m_kneeSEINumKneePointsMinus1+1];
+    char *InputVal = strtok(pcInputKneePointValue, " .,");
+    Int i=0;
+    while( InputVal && i<(m_kneeSEINumKneePointsMinus1+1) )
+    {
+      m_kneeSEIInputKneePoint[i] = (UInt) atoi( InputVal );
+      InputVal = strtok(NULL, " .,");
+      i++;
+    }
+    char *OutputVal = strtok(pcOutputKneePointValue, " .,");
+    i=0;
+    while( OutputVal && i<(m_kneeSEINumKneePointsMinus1+1) )
+    {
+      m_kneeSEIOutputKneePoint[i] = (UInt) atoi( OutputVal );
+      OutputVal = strtok(NULL, " .,");
+      i++;
+    }
+  }
+#endif
 
 #if N0383_IL_CONSTRAINED_TILE_SETS_SEI
@@ -1742,8 +1875,41 @@
    * This permits the ability to omit a GOP structure specification */
 #if SVC_EXTENSION
+#if Q0108_TSA_STSA
+  if( m_acLayerCfg[0].m_iIntraPeriod == 1 && m_GOPList[0].m_POC == -1 )
+  {
+    m_GOPList[0] = GOPEntry();
+    m_GOPList[0].m_QPFactor = 1;
+    m_GOPList[0].m_betaOffsetDiv2 = 0;
+    m_GOPList[0].m_tcOffsetDiv2 = 0;
+    m_GOPList[0].m_POC = 1;
+    m_GOPList[0].m_numRefPicsActive = 4;
+  }
+
   for(UInt layer = 0; layer < MAX_LAYERS; layer++)
   {
+    if (m_acLayerCfg[layer].m_iIntraPeriod == 1 && m_EhGOPList[layer][0].m_POC == -1) {
+      m_EhGOPList[layer][0] = GOPEntry();
+      m_EhGOPList[layer][0].m_QPFactor = 1;
+      m_EhGOPList[layer][0].m_betaOffsetDiv2 = 0;
+      m_EhGOPList[layer][0].m_tcOffsetDiv2 = 0;
+      m_EhGOPList[layer][0].m_POC = 1;
+      m_EhGOPList[layer][0].m_numRefPicsActive = 4;
+    }
+  }
+#else
+  for(UInt layer = 0; layer < MAX_LAYERS; layer++)
+  {
     Int m_iIntraPeriod = m_acLayerCfg[layer].m_iIntraPeriod;
-#endif
+    if (m_iIntraPeriod == 1 && m_GOPList[0].m_POC == -1) {
+      m_GOPList[0] = GOPEntry();
+      m_GOPList[0].m_QPFactor = 1;
+      m_GOPList[0].m_betaOffsetDiv2 = 0;
+      m_GOPList[0].m_tcOffsetDiv2 = 0;
+      m_GOPList[0].m_POC = 1;
+      m_GOPList[0].m_numRefPicsActive = 4;
+    }
+  }
+#endif
+#else
   if (m_iIntraPeriod == 1 && m_GOPList[0].m_POC == -1) {
     m_GOPList[0] = GOPEntry();
@@ -1754,8 +1920,5 @@
     m_GOPList[0].m_numRefPicsActive = 4;
   }
-#if SVC_EXTENSION
-  }
-#endif
-  
+#endif
 
   Bool verifiedGOP=false;
@@ -1790,5 +1953,4 @@
   xConfirmPara( m_numLayers > MAX_LAYERS , "Number of layers in config file is greater than MAX_LAYERS" );
   m_numLayers = m_numLayers > MAX_LAYERS ? MAX_LAYERS : m_numLayers;
-
   
   // it can be updated after AVC BL support will be added to the WD
@@ -1827,5 +1989,9 @@
 #endif
 
-  m_extraRPSs=0;
+#if !Q0108_TSA_STSA
+   m_extraRPSs = 0;                                      
+#else
+  memset( m_extraRPSs, 0, sizeof( m_extraRPSs ) );
+#endif
   //start looping through frames in coding order until we can verify that the GOP structure is correct.
   while(!verifiedGOP&&!errorGOP) 
@@ -1893,5 +2059,9 @@
       {
         //create a new GOPEntry for this frame containing all the reference pictures that were available (POC > 0)
+#if !Q0108_TSA_STSA
         m_GOPList[m_iGOPSize+m_extraRPSs]=m_GOPList[curGOP];
+#else
+        m_GOPList[m_iGOPSize+m_extraRPSs[0]]=m_GOPList[curGOP];
+#endif
         Int newRefs=0;
         for(Int i = 0; i< m_GOPList[curGOP].m_numRefPics; i++) 
@@ -1900,6 +2070,11 @@
           if(absPOC>=0)
           {
+#if !Q0108_TSA_STSA
             m_GOPList[m_iGOPSize+m_extraRPSs].m_referencePics[newRefs]=m_GOPList[curGOP].m_referencePics[i];
             m_GOPList[m_iGOPSize+m_extraRPSs].m_usedByCurrPic[newRefs]=m_GOPList[curGOP].m_usedByCurrPic[i];
+#else
+            m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_referencePics[newRefs]=m_GOPList[curGOP].m_referencePics[i];
+            m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_usedByCurrPic[newRefs]=m_GOPList[curGOP].m_usedByCurrPic[i];
+#endif
             newRefs++;
           }
@@ -1924,5 +2099,9 @@
             for(Int i=0; i<newRefs; i++) 
             {
+#if !Q0108_TSA_STSA
               if(m_GOPList[m_iGOPSize+m_extraRPSs].m_referencePics[i]==offPOC-curPOC)
+#else
+              if(m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_referencePics[i]==offPOC-curPOC)
+#endif
               {
                 newRef=false;
@@ -1939,5 +2118,9 @@
               for(Int j=0; j<newRefs; j++)
               {
+#if !Q0108_TSA_STSA
                 if(m_GOPList[m_iGOPSize+m_extraRPSs].m_referencePics[j]<offPOC-curPOC||m_GOPList[m_iGOPSize+m_extraRPSs].m_referencePics[j]>0)
+#else
+                if(m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_referencePics[j]<offPOC-curPOC||m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_referencePics[j]>0)
+#endif
                 {
                   insertPoint = j;
@@ -1949,8 +2132,16 @@
               for(Int j=insertPoint; j<newRefs+1; j++)
               {
+#if !Q0108_TSA_STSA
                 Int newPrev = m_GOPList[m_iGOPSize+m_extraRPSs].m_referencePics[j];
                 Int newUsed = m_GOPList[m_iGOPSize+m_extraRPSs].m_usedByCurrPic[j];
                 m_GOPList[m_iGOPSize+m_extraRPSs].m_referencePics[j]=prev;
                 m_GOPList[m_iGOPSize+m_extraRPSs].m_usedByCurrPic[j]=prevUsed;
+#else
+                Int newPrev = m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_referencePics[j];
+                Int newUsed = m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_usedByCurrPic[j];
+                m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_referencePics[j]=prev;
+                m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_usedByCurrPic[j]=prevUsed;
+#endif
+
                 prevUsed=newUsed;
                 prev=newPrev;
@@ -1964,14 +2155,32 @@
           }
         }
+#if !Q0108_TSA_STSA
         m_GOPList[m_iGOPSize+m_extraRPSs].m_numRefPics=newRefs;
         m_GOPList[m_iGOPSize+m_extraRPSs].m_POC = curPOC;
+#else
+        m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_numRefPics=newRefs;
+        m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_POC = curPOC;
+#endif
+#if !Q0108_TSA_STSA
         if (m_extraRPSs == 0)
-        {
+#else
+        if (m_extraRPSs[0] == 0)
+#endif
+        {
+#if !Q0108_TSA_STSA
           m_GOPList[m_iGOPSize+m_extraRPSs].m_interRPSPrediction = 0;
           m_GOPList[m_iGOPSize+m_extraRPSs].m_numRefIdc = 0;
+#else
+          m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_interRPSPrediction = 0;
+          m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_numRefIdc = 0;
+#endif
         }
         else
         {
+#if !Q0108_TSA_STSA
           Int rIdx =  m_iGOPSize + m_extraRPSs - 1;
+#else
+          Int rIdx =  m_iGOPSize + m_extraRPSs[0] - 1;
+#endif
           Int refPOC = m_GOPList[rIdx].m_POC;
           Int refPics = m_GOPList[rIdx].m_numRefPics;
@@ -1982,4 +2191,5 @@
             Int absPOCref = refPOC+deltaPOC;
             Int refIdc = 0;
+#if !Q0108_TSA_STSA
             for (Int j = 0; j < m_GOPList[m_iGOPSize+m_extraRPSs].m_numRefPics; j++)
             {
@@ -2006,4 +2216,31 @@
         m_extraRPSs++;
       }
+#else
+            for (Int j = 0; j < m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_numRefPics; j++)
+            {
+              if ( (absPOCref - curPOC) == m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_referencePics[j])
+              {
+                if (m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_usedByCurrPic[j])
+                {
+                  refIdc = 1;
+                }
+                else
+                {
+                  refIdc = 2;
+                }
+              }
+            }
+            m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_refIdc[newIdc]=refIdc;
+            newIdc++;
+          }
+          m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_interRPSPrediction = 1;  
+          m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_numRefIdc = newIdc;
+          m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_deltaRPS = refPOC - m_GOPList[m_iGOPSize+m_extraRPSs[0]].m_POC; 
+        }
+        curGOP=m_iGOPSize+m_extraRPSs[0];
+        m_extraRPSs[0]++;
+      }
+#endif
+
       numRefs=0;
       for(Int i = 0; i< m_GOPList[curGOP].m_numRefPics; i++) 
@@ -2022,4 +2259,245 @@
   }
   xConfirmPara(errorGOP,"Invalid GOP structure given");
+
+#if SVC_EXTENSION && Q0108_TSA_STSA
+  for ( Int layerId = 1; layerId < m_numLayers; layerId++ )
+  {
+    verifiedGOP=false;
+    errorGOP=false;
+    checkGOP=1;
+    numRefs = m_isField ? 2 : 1;
+    refList[0]=0;
+
+    if(m_isField)
+    {
+      refList[1] = 1;
+    }
+
+    memset( isOK, 0, sizeof( isOK ) );
+    numOK=0;
+
+    for(Int i=0; i<m_iGOPSize; i++)
+    {
+      if(m_EhGOPList[layerId][i].m_POC==m_iGOPSize)
+      {
+        xConfirmPara( m_EhGOPList[layerId][i].m_temporalId!=0 , "The last frame in each GOP must have temporal ID = 0 " );
+      }
+    }
+
+    xConfirmPara( m_numLayers > MAX_LAYERS , "Number of layers in config file is greater than MAX_LAYERS" );
+    m_numLayers = m_numLayers > MAX_LAYERS ? MAX_LAYERS : m_numLayers;
+
+    // verify layer configuration parameters
+    for(UInt layer=0; layer<m_numLayers; layer++)
+    {
+      Int m_iIntraPeriod = m_acLayerCfg[layer].m_iIntraPeriod;
+      if ( (m_iIntraPeriod != 1) && !m_loopFilterOffsetInPPS && m_DeblockingFilterControlPresent && (!m_bLoopFilterDisable) )
+      {
+        for(Int i=0; i<m_iGOPSize; i++)
+        {
+          xConfirmPara( (m_EhGOPList[layerId][i].m_betaOffsetDiv2 + m_loopFilterBetaOffsetDiv2) < -6 || (m_EhGOPList[layerId][i].m_betaOffsetDiv2 + m_loopFilterBetaOffsetDiv2) > 6, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-6 to 6)" );
+          xConfirmPara( (m_EhGOPList[layerId][i].m_tcOffsetDiv2 + m_loopFilterTcOffsetDiv2) < -6 || (m_EhGOPList[layerId][i].m_tcOffsetDiv2 + m_loopFilterTcOffsetDiv2) > 6, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-6 to 6)" );
+        }
+      }
+    }
+
+    //start looping through frames in coding order until we can verify that the GOP structure is correct.
+    while(!verifiedGOP&&!errorGOP) 
+    {
+      Int curGOP = (checkGOP-1)%m_iGOPSize;
+      Int curPOC = ((checkGOP-1)/m_iGOPSize)*m_iGOPSize + m_EhGOPList[layerId][curGOP].m_POC;    
+      if(m_EhGOPList[layerId][curGOP].m_POC<0) 
+      {
+        printf("\nError: found fewer Reference Picture Sets than GOPSize\n");
+        errorGOP=true;
+      }
+      else 
+      {
+        //check that all reference pictures are available, or have a POC < 0 meaning they might be available in the next GOP.
+        Bool beforeI = false;
+        for(Int i = 0; i< m_EhGOPList[layerId][curGOP].m_numRefPics; i++) 
+        {
+          Int absPOC = curPOC+m_EhGOPList[layerId][curGOP].m_referencePics[i];
+          if(absPOC < 0)
+          {
+            beforeI=true;
+          }
+          else 
+          {
+            Bool found=false;
+            for(Int j=0; j<numRefs; j++) 
+            {
+              if(refList[j]==absPOC) 
+              {
+                found=true;
+                for(Int k=0; k<m_iGOPSize; k++)
+                {
+                  if(absPOC%m_iGOPSize == m_EhGOPList[layerId][k].m_POC%m_iGOPSize)
+                  {
+                    if(m_EhGOPList[layerId][k].m_temporalId==m_EhGOPList[layerId][curGOP].m_temporalId)
+                    {
+                      m_EhGOPList[layerId][k].m_refPic = true;
+                    }
+                    m_EhGOPList[layerId][curGOP].m_usedByCurrPic[i]=m_EhGOPList[layerId][k].m_temporalId<=m_EhGOPList[layerId][curGOP].m_temporalId;
+                  }
+                }
+              }
+            }
+            if(!found)
+            {
+              printf("\nError: ref pic %d is not available for GOP frame %d\n",m_EhGOPList[layerId][curGOP].m_referencePics[i],curGOP+1);
+              errorGOP=true;
+            }
+          }
+        }
+        if(!beforeI&&!errorGOP)
+        {
+          //all ref frames were present
+          if(!isOK[curGOP]) 
+          {
+            numOK++;
+            isOK[curGOP]=true;
+            if(numOK==m_iGOPSize)
+            {
+              verifiedGOP=true;
+            }
+          }
+        }
+        else 
+        {
+          //create a new GOPEntry for this frame containing all the reference pictures that were available (POC > 0)
+
+          m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]]=m_EhGOPList[layerId][curGOP];
+          Int newRefs=0;
+          for(Int i = 0; i< m_EhGOPList[layerId][curGOP].m_numRefPics; i++) 
+          {
+            Int absPOC = curPOC+m_EhGOPList[layerId][curGOP].m_referencePics[i];
+            if(absPOC>=0)
+            {
+              m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_referencePics[newRefs]=m_EhGOPList[layerId][curGOP].m_referencePics[i];
+              m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_usedByCurrPic[newRefs]=m_EhGOPList[layerId][curGOP].m_usedByCurrPic[i];
+              newRefs++;
+            }
+          }
+          Int numPrefRefs = m_EhGOPList[layerId][curGOP].m_numRefPicsActive;
+
+          for(Int offset = -1; offset>-checkGOP; offset--)
+          {
+            //step backwards in coding order and include any extra available pictures we might find useful to replace the ones with POC < 0.
+            Int offGOP = (checkGOP-1+offset)%m_iGOPSize;
+            Int offPOC = ((checkGOP-1+offset)/m_iGOPSize)*m_iGOPSize + m_EhGOPList[layerId][offGOP].m_POC;
+            if(offPOC>=0&&m_EhGOPList[layerId][offGOP].m_temporalId<=m_EhGOPList[layerId][curGOP].m_temporalId)
+            {
+              Bool newRef=false;
+              for(Int i=0; i<numRefs; i++)
+              {
+                if(refList[i]==offPOC)
+                {
+                  newRef=true;
+                }
+              }
+              for(Int i=0; i<newRefs; i++) 
+              {
+                if(m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_referencePics[i]==offPOC-curPOC)
+                {
+                  newRef=false;
+                }
+              }
+              if(newRef) 
+              {
+                Int insertPoint=newRefs;
+                //this picture can be added, find appropriate place in list and insert it.
+                if(m_EhGOPList[layerId][offGOP].m_temporalId==m_EhGOPList[layerId][curGOP].m_temporalId)
+                {
+                  m_EhGOPList[layerId][offGOP].m_refPic = true;
+                }
+                for(Int j=0; j<newRefs; j++)
+                {
+                  if(m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_referencePics[j]<offPOC-curPOC||m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_referencePics[j]>0)
+                  {
+                    insertPoint = j;
+                    break;
+                  }
+                }
+                Int prev = offPOC-curPOC;
+                Int prevUsed = m_EhGOPList[layerId][offGOP].m_temporalId<=m_EhGOPList[layerId][curGOP].m_temporalId;
+                for(Int j=insertPoint; j<newRefs+1; j++)
+                {
+                  Int newPrev = m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_referencePics[j];
+                  Int newUsed = m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_usedByCurrPic[j];
+                  m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_referencePics[j]=prev;
+                  m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_usedByCurrPic[j]=prevUsed;
+                  prevUsed=newUsed;
+                  prev=newPrev;
+                }
+                newRefs++;
+              }
+            }
+            if(newRefs>=numPrefRefs)
+            {
+              break;
+            }
+          }
+          m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_numRefPics=newRefs;
+          m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_POC = curPOC;
+          if (m_extraRPSs[layerId] == 0)
+          {
+            m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_interRPSPrediction = 0;
+            m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_numRefIdc = 0;
+          }
+          else
+          {
+            Int rIdx =  m_iGOPSize + m_extraRPSs[layerId] - 1;
+            Int refPOC = m_EhGOPList[layerId][rIdx].m_POC;
+            Int refPics = m_EhGOPList[layerId][rIdx].m_numRefPics;
+            Int newIdc=0;
+            for(Int i = 0; i<= refPics; i++) 
+            {
+              Int deltaPOC = ((i != refPics)? m_EhGOPList[layerId][rIdx].m_referencePics[i] : 0);  // check if the reference abs POC is >= 0
+              Int absPOCref = refPOC+deltaPOC;
+              Int refIdc = 0;
+              for (Int j = 0; j < m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_numRefPics; j++)
+              {
+                if ( (absPOCref - curPOC) == m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_referencePics[j])
+                {
+                  if (m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_usedByCurrPic[j])
+                  {
+                    refIdc = 1;
+                  }
+                  else
+                  {
+                    refIdc = 2;
+                  }
+                }
+              }
+              m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_refIdc[newIdc]=refIdc;
+              newIdc++;
+            }
+            m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_interRPSPrediction = 1;  
+            m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_numRefIdc = newIdc;
+            m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_deltaRPS = refPOC - m_EhGOPList[layerId][m_iGOPSize+m_extraRPSs[layerId]].m_POC; 
+          }
+          curGOP=m_iGOPSize+m_extraRPSs[layerId];
+          m_extraRPSs[layerId]++;
+        }
+        numRefs=0;
+        for(Int i = 0; i< m_EhGOPList[layerId][curGOP].m_numRefPics; i++) 
+        {
+          Int absPOC = curPOC+m_EhGOPList[layerId][curGOP].m_referencePics[i];
+          if(absPOC >= 0) 
+          {
+            refList[numRefs]=absPOC;
+            numRefs++;
+          }
+        }
+        refList[numRefs]=curPOC;
+        numRefs++;
+      }
+      checkGOP++;
+    }
+    xConfirmPara(errorGOP,"Invalid GOP structure given");
+  }
+#endif 
+
   m_maxTempLayer = 1;
   for(Int i=0; i<m_iGOPSize; i++) 
@@ -2031,4 +2509,20 @@
     xConfirmPara(m_GOPList[i].m_sliceType!='B'&&m_GOPList[i].m_sliceType!='P'&&m_GOPList[i].m_sliceType!='I', "Slice type must be equal to B or P or I");
   }
+
+#if Q0108_TSA_STSA
+  for ( Int layerId = 1; layerId < m_numLayers; layerId++)
+  {
+    m_EhMaxTempLayer[layerId] = 1;
+    for(Int i=0; i<m_iGOPSize; i++) 
+    {
+      if(m_EhGOPList[layerId][i].m_temporalId >= m_EhMaxTempLayer[layerId] )
+      {
+        m_EhMaxTempLayer[layerId] = m_EhGOPList[layerId][i].m_temporalId;
+      }
+      xConfirmPara(m_GOPList[i].m_sliceType!='B'&&m_GOPList[i].m_sliceType!='P'&&m_GOPList[i].m_sliceType!='I', "Slice type must be equal to B or P or I");
+    }
+  }
+#endif
+
   for(Int i=0; i<MAX_TLAYER; i++)
   {
@@ -2195,4 +2689,18 @@
     xConfirmPara( m_extendedWhiteLevelLumaCodeValue < m_nominalWhiteLevelLumaCodeValue, "SEIToneMapExtendedWhiteLevelLumaCodeValue shall be greater than or equal to SEIToneMapNominalWhiteLevelLumaCodeValue");
   }
+#if P0050_KNEE_FUNCTION_SEI
+  if (m_kneeSEIEnabled && !m_kneeSEICancelFlag)
+  {
+    xConfirmPara( m_kneeSEINumKneePointsMinus1 < 0 || m_kneeSEINumKneePointsMinus1 > 998, "SEIKneeFunctionNumKneePointsMinus1 must be in the range of 0 to 998");
+    for ( UInt i=0; i<=m_kneeSEINumKneePointsMinus1; i++ ){
+      xConfirmPara( m_kneeSEIInputKneePoint[i] < 1 || m_kneeSEIInputKneePoint[i] > 999, "SEIKneeFunctionInputKneePointValue must be in the range of 1 to 999");
+      xConfirmPara( m_kneeSEIOutputKneePoint[i] < 0 || m_kneeSEIOutputKneePoint[i] > 1000, "SEIKneeFunctionInputKneePointValue must be in the range of 0 to 1000");
+      if ( i > 0 )
+      {
+        xConfirmPara( m_kneeSEIInputKneePoint[i-1] >= m_kneeSEIInputKneePoint[i],  "The i-th SEIKneeFunctionInputKneePointValue must be greather than the (i-1)-th value");
+      }
+    }
+  }
+#endif
 
 #if RC_SHVC_HARMONIZATION
@@ -2234,4 +2742,6 @@
     xConfirmPara(m_framePackingSEIType < 3 || m_framePackingSEIType > 5 , "SEIFramePackingType must be in rage 3 to 5");
   }
+
+#if SVC_EXTENSION
 #if VPS_EXTN_DIRECT_REF_LAYERS
   xConfirmPara( (m_acLayerCfg[0].m_numSamplePredRefLayers != 0) && (m_acLayerCfg[0].m_numSamplePredRefLayers != -1), "Layer 0 cannot have any reference layers" );
@@ -2304,10 +2814,8 @@
   }
 #endif
-#if N0120_MAX_TID_REF_CFG
   for (UInt layer=0; layer < MAX_LAYERS-1; layer++)
   {
     xConfirmPara(m_acLayerCfg[layer].m_maxTidIlRefPicsPlus1 < 0 || m_acLayerCfg[layer].m_maxTidIlRefPicsPlus1 > 7, "MaxTidIlRefPicsPlus1 must be in range 0 to 7");
   }
-#endif 
 #if AUXILIARY_PICTURES
   for (UInt layer=0; layer < MAX_LAYERS-1; layer++)
@@ -2320,4 +2828,5 @@
   xConfirmPara( m_nCGSFlag < 0 || m_nCGSFlag > 1 , "0<=CGS<=1" );
 #endif
+#endif //SVC_EXTENSION
 #undef xConfirmPara
   if (check_failed)
@@ -2397,16 +2906,11 @@
 #if SVC_EXTENSION  
   printf("Total number of layers        : %d\n", m_numLayers       );
-#if SCALABILITY_MASK_E0104
-  printf("Multiview                     : %d\n", m_scalabilityMask[1] );
-  printf("Scalable                      : %d\n", m_scalabilityMask[2] );
+  printf("Multiview                     : %d\n", m_scalabilityMask[VIEW_ORDER_INDEX] );
+  printf("Scalable                      : %d\n", m_scalabilityMask[SCALABILITY_ID] );
 #if AVC_BASE
   printf("Base layer                    : %s\n", m_avcBaseLayerFlag ? "AVC" : "HEVC");
 #endif
 #if AUXILIARY_PICTURES
-  printf("Auxiliary pictures            : %d\n", m_scalabilityMask[3] );
-#endif
-#else
-  printf("Multiview                     : %d\n", m_scalabilityMask[0] );
-  printf("Scalable                      : %d\n", m_scalabilityMask[1] );
+  printf("Auxiliary pictures            : %d\n", m_scalabilityMask[AUX_ID] );
 #endif
 #if M0040_ADAPTIVE_RESOLUTION_CHANGE
@@ -2419,7 +2923,5 @@
   printf("Align picture type            : %d\n", m_crossLayerPictureTypeAlignFlag );
 #endif
-#if N0147_IRAP_ALIGN_FLAG
   printf("Cross layer IRAP alignment    : %d\n", m_crossLayerIrapAlignFlag );
-#endif
 #if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
   printf("IDR only for IRAP             : %d\n", m_crossLayerAlignedIdrOnlyFlag );
Index: trunk/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncCfg.h	(revision 713)
+++ trunk/source/App/TAppEncoder/TAppEncCfg.h	(revision 815)
@@ -73,7 +73,13 @@
   Char*     m_BLSyntaxFile;                                   ///< input syntax file
 #endif
-#if N0120_MAX_TID_REF_CFG
   Bool      m_maxTidRefPresentFlag; 
-#endif 
+#if Q0078_ADD_LAYER_SETS
+  Int       m_numLayerSets;
+  Int       m_numLayerInIdList[MAX_VPS_LAYER_SETS_PLUS1];
+  Int       m_layerSetLayerIdList[MAX_VPS_LAYER_SETS_PLUS1][MAX_VPS_LAYER_ID_PLUS1];
+  Int       m_numAddLayerSets;
+  Int       m_numHighestLayerIdx[MAX_VPS_LAYER_SETS_PLUS1];
+  Int       m_highestLayerIdx[MAX_VPS_LAYER_SETS_PLUS1][MAX_VPS_LAYER_ID_PLUS1];
+#endif
 #else
   Char*     m_pchInputFile;                                   ///< source file name
@@ -119,6 +125,17 @@
   Int       m_iDecodingRefreshType;                           ///< random access type
   Int       m_iGOPSize;                                       ///< GOP size of hierarchical structure
+
+#if !Q0108_TSA_STSA
   Int       m_extraRPSs;                                      ///< extra RPSs added to handle CRA
+#else
+  Int       m_extraRPSs[MAX_LAYERS];                          ///< extra RPSs added to handle CRA
+#endif
+
   GOPEntry  m_GOPList[MAX_GOP];                               ///< the coding structure entries from the config file
+#if Q0108_TSA_STSA
+  GOPEntry  m_EhGOPList[MAX_LAYERS][MAX_GOP];                 ///< the enhancement layer coding structure entries from the config file
+  Int       m_inheritCodingStruct[MAX_LAYERS];
+#endif
+
   Int       m_numReorderPics[MAX_TLAYER];                     ///< total number of reorder pictures
   Int       m_maxDecPicBuffering[MAX_TLAYER];                 ///< total number of pictures in the decoded picture buffer
@@ -148,4 +165,7 @@
   
   Int       m_maxTempLayer;                                  ///< Max temporal layer
+#if Q0108_TSA_STSA
+  Int       m_EhMaxTempLayer[MAX_LAYERS];                    ///< Max temporal layer
+#endif
 
 #if !LAYER_CTB
@@ -285,4 +305,7 @@
   Int       m_SOPDescriptionSEIEnabled;
   Int       m_scalableNestingSEIEnabled;
+#if Q0189_TMVP_CONSTRAINTS
+  Int       m_TMVPConstraintsSEIEnabled;
+#endif
   // weighted prediction
   Bool      m_useWeightedPred;                    ///< Use of weighted prediction in P slices
@@ -363,4 +386,5 @@
   Void  xPrintParameter ();                                   ///< print configuration values
   Void  xPrintUsage     ();                                   ///< print usage
+#if SVC_EXTENSION
 #if M0040_ADAPTIVE_RESOLUTION_CHANGE
   Int       m_adaptiveResolutionChange;                       ///< Indicate adaptive resolution change frame
@@ -386,6 +410,18 @@
   Bool      m_crossLayerPictureTypeAlignFlag;
 #endif
-#if N0147_IRAP_ALIGN_FLAG
   Bool      m_crossLayerIrapAlignFlag;
+#if P0050_KNEE_FUNCTION_SEI
+  Bool      m_kneeSEIEnabled;
+  Int       m_kneeSEIId;
+  Bool      m_kneeSEICancelFlag;
+  Bool      m_kneeSEIPersistenceFlag;
+  Bool      m_kneeSEIMappingFlag;
+  Int       m_kneeSEIInputDrange;
+  Int       m_kneeSEIInputDispLuminance;
+  Int       m_kneeSEIOutputDrange;
+  Int       m_kneeSEIOutputDispLuminance;
+  Int       m_kneeSEINumKneePointsMinus1;
+  Int*      m_kneeSEIInputKneePoint;
+  Int*      m_kneeSEIOutputKneePoint;
 #endif
 #if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
@@ -404,4 +440,5 @@
   Int  m_nCGSLUTBit;
 #endif
+#endif //SVC_EXTENSION
 public:
   TAppEncCfg();
Index: trunk/source/App/TAppEncoder/TAppEncLayerCfg.h
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncLayerCfg.h	(revision 713)
+++ trunk/source/App/TAppEncoder/TAppEncLayerCfg.h	(revision 815)
@@ -83,7 +83,5 @@
 #endif
 
-#if N0120_MAX_TID_REF_CFG
   Int       m_maxTidIlRefPicsPlus1;
-#endif 
   Int       m_iWaveFrontSubstreams; //< If iWaveFrontSynchro, this is the number of substreams per frame (dependent tiles) or per tile (independent tiles).
 
@@ -181,7 +179,5 @@
   Void    setSourceHeight(Int x)      { m_iSourceHeight = x;    }
 #endif
-#if N0120_MAX_TID_REF_CFG
   Int     getMaxTidIlRefPicsPlus1()   { return m_maxTidIlRefPicsPlus1; }
-#endif 
 #if LAYER_CTB
   UInt    getMaxCUWidth()             {return m_uiMaxCUWidth;      }
Index: trunk/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- trunk/source/App/TAppEncoder/TAppEncTop.cpp	(revision 713)
+++ trunk/source/App/TAppEncoder/TAppEncTop.cpp	(revision 815)
@@ -82,7 +82,4 @@
     vps->setTemporalNestingFlag(true);
   }
-#if !VPS_RENAME
-  vps.setMaxLayers                        ( 1 );
-#endif
   for(Int i = 0; i < MAX_TLAYER; i++)
   {
@@ -190,4 +187,6 @@
   delete [] mapIdxToLayer;
 #endif
+
+  assert( m_numLayers <= MAX_LAYERS );
 
   for(UInt layer=0; layer<m_numLayers; layer++)
@@ -241,7 +240,15 @@
     m_acTEncTop[layer].setDecodingRefreshType          ( m_iDecodingRefreshType );
     m_acTEncTop[layer].setGOPSize                      ( m_iGOPSize );
+#if Q0108_TSA_STSA
+    m_acTEncTop[layer].setGopList                      ( layer ? m_EhGOPList[layer] : m_GOPList );
+#else
     m_acTEncTop[layer].setGopList                      ( m_GOPList );
-
+#endif
+
+#if !Q0108_TSA_STSA
     m_acTEncTop[layer].setExtraRPSs                    ( m_extraRPSs );
+#else
+    m_acTEncTop[layer].setExtraRPSs                    ( m_extraRPSs[layer] );
+#endif
     for(Int i = 0; i < MAX_TLAYER; i++)
     {
@@ -256,13 +263,23 @@
 
     m_acTEncTop[layer].setPad                          ( m_acLayerCfg[layer].getPad() );
-
+#if !Q0108_TSA_STSA
     m_acTEncTop[layer].setMaxTempLayer                 ( m_maxTempLayer );
+#else
+    if (layer== 0)
+    {
+      m_acTEncTop[layer].setMaxTempLayer                 ( m_maxTempLayer );
+    }
+    else
+    {
+      m_acTEncTop[layer].setMaxTempLayer                 ( m_EhMaxTempLayer[layer] );
+    }
+#endif
     m_acTEncTop[layer].setUseAMP( m_enableAMP );
-#if N0120_MAX_TID_REF_CFG
-    if (layer<m_numLayers-1)
+
+    if( layer < m_numLayers - 1 )
     {
        m_acTEncTop[layer].setMaxTidIlRefPicsPlus1 ( m_acLayerCfg[layer].getMaxTidIlRefPicsPlus1());
     }
-#endif
+
 #if VPS_EXTN_DIRECT_REF_LAYERS
     if(layer)
@@ -306,4 +323,7 @@
       }
       Int numDirectRefLayers = 0;
+
+      assert( layer < MAX_LAYERS );
+
       for (Int i = 0; i < layer; i++)
       {
@@ -480,4 +500,18 @@
     m_acTEncTop[layer].setTMISEINominalWhiteLevelLumaCodeValue      ( m_nominalWhiteLevelLumaCodeValue );
     m_acTEncTop[layer].setTMISEIExtendedWhiteLevelLumaCodeValue     ( m_extendedWhiteLevelLumaCodeValue );
+#if P0050_KNEE_FUNCTION_SEI
+    m_acTEncTop[layer].setKneeSEIEnabled                            ( m_kneeSEIEnabled );
+    m_acTEncTop[layer].setKneeSEIId                                 ( m_kneeSEIId );
+    m_acTEncTop[layer].setKneeSEICancelFlag                         ( m_kneeSEICancelFlag );
+    m_acTEncTop[layer].setKneeSEIPersistenceFlag                    ( m_kneeSEIPersistenceFlag );
+    m_acTEncTop[layer].setKneeSEIMappingFlag                        ( m_kneeSEIMappingFlag );
+    m_acTEncTop[layer].setKneeSEIInputDrange                        ( m_kneeSEIInputDrange );
+    m_acTEncTop[layer].setKneeSEIInputDispLuminance                 ( m_kneeSEIInputDispLuminance );
+    m_acTEncTop[layer].setKneeSEIOutputDrange                       ( m_kneeSEIOutputDrange );
+    m_acTEncTop[layer].setKneeSEIOutputDispLuminance                ( m_kneeSEIOutputDispLuminance );
+    m_acTEncTop[layer].setKneeSEINumKneePointsMinus1                ( m_kneeSEINumKneePointsMinus1 );
+    m_acTEncTop[layer].setKneeSEIInputKneePoint                     ( m_kneeSEIInputKneePoint );
+    m_acTEncTop[layer].setKneeSEIOutputKneePoint                    ( m_kneeSEIOutputKneePoint );
+#endif
 #if Q0074_SEI_COLOR_MAPPING
     m_acTEncTop[layer].setColorMappingInfoSEIFile                   ( m_acLayerCfg[layer].m_cSeiColorMappingFile.empty() ? NULL : const_cast<Char *>(m_acLayerCfg[layer].m_cSeiColorMappingFile.c_str()) );
@@ -497,4 +531,7 @@
     m_acTEncTop[layer].setSOPDescriptionSEIEnabled( m_SOPDescriptionSEIEnabled );
     m_acTEncTop[layer].setScalableNestingSEIEnabled( m_scalableNestingSEIEnabled );
+#if Q0189_TMVP_CONSTRAINTS
+    m_acTEncTop[layer].setTMVPConstraintsSEIEnabled( m_TMVPConstraintsSEIEnabled);           
+#endif
 #if N0383_IL_CONSTRAINED_TILE_SETS_SEI
     m_acTEncTop[layer].setInterLayerConstrainedTileSetsSEIEnabled( m_interLayerConstrainedTileSetsSEIEnabled );
@@ -614,4 +651,7 @@
     m_acTEncTop[layer].setCGSLUTBit( m_nCGSLUTBit );
 #endif
+#if Q0078_ADD_LAYER_SETS
+    m_acTEncTop[layer].setNumAddLayerSets( m_numAddLayerSets );
+#endif
   }
 }
@@ -799,4 +839,18 @@
   m_cTEncTop.setTMISEINominalWhiteLevelLumaCodeValue      ( m_nominalWhiteLevelLumaCodeValue );
   m_cTEncTop.setTMISEIExtendedWhiteLevelLumaCodeValue     ( m_extendedWhiteLevelLumaCodeValue );
+#if P0050_KNEE_FUNCTION_SEI
+  m_cTEncTop.setKneeSEIEnabled              ( m_kneeSEIEnabled );
+  m_cTEncTop.setKneeSEIId                   ( m_kneeSEIId );
+  m_cTEncTop.setKneeSEICancelFlag           ( m_kneeSEICancelFlag );
+  m_cTEncTop.setKneeSEIPersistenceFlag      ( m_kneeSEIPersistenceFlag );
+  m_cTEncTop.setKneeSEIMappingFlag          ( m_kneeSEIMappingFlag );
+  m_cTEncTop.setKneeSEIInputDrange          ( m_kneeSEIInputDrange );
+  m_cTEncTop.setKneeSEIInputDispLuminance   ( m_kneeSEIInputDispLuminance );
+  m_cTEncTop.setKneeSEIOutputDrange         ( m_kneeSEIOutputDrange );
+  m_cTEncTop.setKneeSEIOutputDispLuminance  ( m_kneeSEIOutputDispLuminance );
+  m_cTEncTop.setKneeSEINumKneePointsMinus1  ( m_kneeSEINumKneePointsMinus1 );
+  m_cTEncTop.setKneeSEIInputKneePoint       ( m_kneeSEIInputKneePoint );
+  m_cTEncTop.setKneeSEIOutputKneePoint      ( m_kneeSEIOutputKneePoint );
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   m_cTEncTop.setColorMappingInfoSEIFile                   ( m_pchSEIColorMappingFile );
@@ -994,7 +1048,5 @@
 #endif
   }
-#if VPS_RENAME
   m_acTEncTop[0].getVPS()->setMaxLayers( m_numLayers );
-#endif
 #if VPS_EXTN_OP_LAYER_SETS
   TComVPS* vps = m_acTEncTop[0].getVPS();
@@ -1003,27 +1055,79 @@
   vps->setVpsExtensionFlag( m_numLayers > 1 ? true : false );
 
-  vps->setNumLayerSets(m_numLayers);
-  for(Int setId = 1; setId < vps->getNumLayerSets(); setId++)
-  {
-    for(Int layerId = 0; layerId <= vps->getMaxLayerId(); layerId++)
-    {
+#if Q0078_ADD_LAYER_SETS
+  if (m_numLayerSets > 0)
+  {
+    vps->setNumLayerSets(m_numLayerSets+1);
+    for (Int setId = 1; setId < vps->getNumLayerSets(); setId++)
+    {
+      for (Int layerId = 0; layerId <= vps->getMaxLayerId(); layerId++)
+      {
+        vps->setLayerIdIncludedFlag(false, setId, layerId);
+      }
+    }
+    for (Int setId = 1; setId < vps->getNumLayerSets(); setId++)
+    {
+      for (Int i = 0; i < m_numLayerInIdList[setId-1]; i++)
+      {
+        Int layerId = m_layerSetLayerIdList[setId-1][i];
+
 #if O0194_DIFFERENT_BITDEPTH_EL_BL
-      //4
-      g_bitDepthY = m_acLayerCfg[layerId].m_internalBitDepthY;
-      g_bitDepthC = m_acLayerCfg[layerId].m_internalBitDepthC;
-
-      g_uiPCMBitDepthLuma = m_bPCMInputBitDepthFlag ? m_acLayerCfg[layerId].m_inputBitDepthY : m_acLayerCfg[layerId].m_internalBitDepthY;
-      g_uiPCMBitDepthChroma = m_bPCMInputBitDepthFlag ? m_acLayerCfg[layerId].m_inputBitDepthC : m_acLayerCfg[layerId].m_internalBitDepthC;
-#endif
-      if( layerId <= setId )
-      {
+        //4
+        g_bitDepthY = m_acLayerCfg[layerId].m_internalBitDepthY;
+        g_bitDepthC = m_acLayerCfg[layerId].m_internalBitDepthC;
+
+        g_uiPCMBitDepthLuma = m_bPCMInputBitDepthFlag ? m_acLayerCfg[layerId].m_inputBitDepthY : m_acLayerCfg[layerId].m_internalBitDepthY;
+        g_uiPCMBitDepthChroma = m_bPCMInputBitDepthFlag ? m_acLayerCfg[layerId].m_inputBitDepthC : m_acLayerCfg[layerId].m_internalBitDepthC;
+#endif
+
         vps->setLayerIdIncludedFlag(true, setId, layerId);
       }
-      else
-      {
-        vps->setLayerIdIncludedFlag(false, setId, layerId);
-      }
-    }
-  }
+    }
+  }
+  else
+  {
+    // Default layer sets
+#endif
+    vps->setNumLayerSets(m_numLayers);
+    for (Int setId = 1; setId < vps->getNumLayerSets(); setId++)
+    {
+      for (Int layerId = 0; layerId <= vps->getMaxLayerId(); layerId++)
+      {
+#if O0194_DIFFERENT_BITDEPTH_EL_BL
+        //4
+        g_bitDepthY = m_acLayerCfg[layerId].m_internalBitDepthY;
+        g_bitDepthC = m_acLayerCfg[layerId].m_internalBitDepthC;
+
+        g_uiPCMBitDepthLuma = m_bPCMInputBitDepthFlag ? m_acLayerCfg[layerId].m_inputBitDepthY : m_acLayerCfg[layerId].m_internalBitDepthY;
+        g_uiPCMBitDepthChroma = m_bPCMInputBitDepthFlag ? m_acLayerCfg[layerId].m_inputBitDepthC : m_acLayerCfg[layerId].m_internalBitDepthC;
+#endif
+        if (layerId <= setId)
+        {
+          vps->setLayerIdIncludedFlag(true, setId, layerId);
+        }
+        else
+        {
+          vps->setLayerIdIncludedFlag(false, setId, layerId);
+        }
+      }
+    }
+#if Q0078_ADD_LAYER_SETS
+  }
+#endif
+#if Q0078_ADD_LAYER_SETS
+  vps->setVpsNumLayerSetsMinus1(vps->getNumLayerSets() - 1);
+  vps->setNumAddLayerSets(m_numAddLayerSets);
+  vps->setNumLayerSets(vps->getNumLayerSets() + vps->getNumAddLayerSets());
+  if (m_numAddLayerSets > 0)
+  {
+    for (Int setId = 0; setId < m_numAddLayerSets; setId++)
+    {
+      for (Int j = 0; j < m_numHighestLayerIdx[setId]; j++)
+      {
+        vps->setHighestLayerIdxPlus1(setId, j + 1, m_highestLayerIdx[setId][j] + 1);
+      }
+    }
+  }
+#endif
 #if VPS_EXTN_MASK_AND_DIM_INFO
   UInt i = 0, dimIdLen = 0;
@@ -1097,4 +1201,5 @@
 #if VPS_TSLAYERS
     vps->setMaxTSLayersPresentFlag(true);
+
     for( i = 0; i < vps->getMaxLayers(); i++ )
     {
@@ -1102,15 +1207,9 @@
     }
 #endif
-#if N0120_MAX_TID_REF_PRESENT_FLAG
-#if N0120_MAX_TID_REF_CFG
   vps->setMaxTidRefPresentFlag(m_maxTidRefPresentFlag);
-#else
-  vps->setMaxTidRefPresentFlag(true);
-#endif
   if (vps->getMaxTidRefPresentFlag())
   {
     for( i = 0; i < vps->getMaxLayers() - 1; i++ )
     {
-#if N0120_MAX_TID_REF_CFG
 #if O0225_MAX_TID_FOR_REF_LAYERS
       for( Int j = i+1; j < vps->getMaxLayers(); j++)
@@ -1121,23 +1220,13 @@
       vps->setMaxTidIlRefPicsPlus1(i, m_acTEncTop[i].getMaxTidIlRefPicsPlus1());
 #endif 
-#else
+    }
+  }
+  else
+  {
+    for( i = 0; i < vps->getMaxLayers() - 1; i++ )
+    {
 #if O0225_MAX_TID_FOR_REF_LAYERS
       for( Int j = i+1; j < vps->getMaxLayers(); j++)
       {
-        vps->setMaxTidIlRefPicsPlus1(i, j, vps->getMaxTLayers()+1);
-      }
-#else
-      vps->setMaxTidIlRefPicsPlus1(i, vps->getMaxTLayers()+1);
-#endif
-#endif
-    }
-  }
-  else
-  {
-    for( i = 0; i < vps->getMaxLayers() - 1; i++ )
-    {
-#if O0225_MAX_TID_FOR_REF_LAYERS
-      for( Int j = i+1; j < vps->getMaxLayers(); j++)
-      {
         vps->setMaxTidIlRefPicsPlus1(i, j, 7);
       }
@@ -1147,12 +1236,5 @@
     }
   }
-#endif
-#if ILP_SSH_SIG
-#if ILP_SSH_SIG_FIX
     vps->setIlpSshSignalingEnabledFlag(false);
-#else
-    vps->setIlpSshSignalingEnabledFlag(true);
-#endif
-#endif
 #if VPS_EXTN_PROFILE_INFO
   vps->getPTLForExtnPtr()->resize(vps->getNumLayerSets());
@@ -1162,105 +1244,4 @@
     // Note - may need to be changed for other layer structures.
     *(vps->getPTLForExtn(setId)) = *(m_acTEncTop[setId].getSPS()->getPTL());
-  }
-#endif
-  // Target output layer
-  vps->setNumOutputLayerSets(vps->getNumLayerSets());
-  vps->setNumProfileTierLevel(vps->getNumLayerSets());
-#if P0295_DEFAULT_OUT_LAYER_IDC
-  vps->setDefaultTargetOutputLayerIdc(1);
-#else
-#if O0109_DEFAULT_ONE_OUT_LAYER_IDC
-  vps->setDefaultOneTargetOutputLayerIdc(1);
-#else
-  vps->setDefaultOneTargetOutputLayerFlag(true);
-#endif
-#endif
-  for(i = 1; i < vps->getNumLayerSets(); i++)
-  {
-    vps->setProfileLevelTierIdx(i, i);
-    vps->setOutputLayerSetIdx(i, i);
-  }  
-#endif
- #if VPS_DPB_SIZE_TABLE
-  // The Layer ID List variables can be derived here.  
-#if DERIVE_LAYER_ID_LIST_VARIABLES
-  vps->deriveLayerIdListVariables();
-#endif
-#if RESOLUTION_BASED_DPB
-  vps->assignSubDpbIndices();
-#else
-  vps->deriveNumberOfSubDpbs();
-#endif
-
-  // derive OutputLayerFlag[i][j] 
-  if( vps->getDefaultTargetOutputLayerIdc() == 1 )
-  {
-    // default_target_output_layer_idc equal to 1 specifies that only the layer with the highest value of nuh_layer_id such that nuh_layer_id equal to nuhLayerIdA and 
-    // AuxId[ nuhLayerIdA ] equal to 0 in each of the output layer sets with index in the range of 1 to vps_num_layer_sets_minus1, inclusive, is an output layer of its output layer set.
-
-    // Include the highest layer as output layer for each layer set
-    for(Int lsIdx = 1; lsIdx < vps->getNumLayerSets(); lsIdx++)
-    {
-      for( UInt layer = 0; layer < vps->getNumLayersInIdList(lsIdx); layer++ )
-      {
-        if( vps->getLayerIdIncludedFlag(lsIdx, layer) )      
-        {        
-          vps->setOutputLayerFlag( lsIdx, layer, layer == vps->getNumLayersInIdList(lsIdx) - 1 );
-        }
-      }
-    }
-  }
-  else
-  {
-    // cases when default_target_output_layer_idc is not equal to 1
-    assert(!"default_target_output_layer_idc not equal to 1 is not yet supported");
-  }
-
-  // Initialize dpb_size_table() for all ouput layer sets in the VPS extension
-  for(i = 1; i < vps->getNumOutputLayerSets(); i++)
-  {
-#if CHANGE_NUMSUBDPB_IDX
-    Int layerSetIdxForOutputLayerSet = vps->getOutputLayerSetIdx( i );
-#endif
-    Int layerSetId = vps->getOutputLayerSetIdx(i);
-
-    for(Int j = 0; j < vps->getMaxTLayers(); j++)
-    {
-
-      Int maxNumReorderPics = -1;
-#if CHANGE_NUMSUBDPB_IDX
-#if RESOLUTION_BASED_DPB
-      for(Int k = 0; k < vps->getNumLayersInIdList(layerSetIdxForOutputLayerSet); k++)
-#else
-      for(Int k = 0; k < vps->getNumSubDpbs(layerSetIdxForOutputLayerSet); k++)
-#endif
-#else
-      for(Int k = 0; k < vps->getNumSubDpbs(i); k++)
-#endif
-      {
-        Int layerId = vps->getLayerSetLayerIdList(layerSetId, k); // k-th layer in the output layer set
-#if RESOLUTION_BASED_DPB
-        vps->setMaxVpsLayerDecPicBuffMinus1( i, k, j, m_acTEncTop[layerId].getMaxDecPicBuffering(j) - 1 );
-        // Add sub-DPB sizes of layers belonging to a sub-DPB. If a different sub-DPB size is calculated
-        // at the encoder, modify below
-        Int oldValue = vps->getMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j );
-        oldValue += vps->getMaxVpsLayerDecPicBuffMinus1( i, k, j ) + 1;
-        vps->setMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j, oldValue );
-#else
-        vps->setMaxVpsDecPicBufferingMinus1( i, k, j,  m_acTEncTop[layerId].getMaxDecPicBuffering(j) - 1 );
-#endif
-        maxNumReorderPics       = std::max( maxNumReorderPics, m_acTEncTop[layerId].getNumReorderPics(j));
-      }
-#if RESOLUTION_BASED_DPB
-      for(Int k = 0; k < vps->getNumSubDpbs(i); k++)
-      {
-        // Decrement m_maxVpsDecPicBufferingMinus1
-        Int oldValue = vps->getMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j );
-        vps->setMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j, oldValue - 1 );
-      }
-#endif
-      vps->setMaxVpsNumReorderPics(i, j, maxNumReorderPics);
-      vps->determineSubDpbInfoFlags();
-    }
   }
 #endif
@@ -1271,32 +1252,32 @@
   Bool isDefaultDirectDependencyTypeSet = false;
 #endif
-  for(UInt layerCtr = 1;layerCtr <= vps->getMaxLayers() - 1; layerCtr++)
-  {
-    vps->setNumDirectRefLayers( layerCtr, m_acTEncTop[layerCtr].getNumDirectRefLayers() );
-    maxDirectRefLayers = max<UInt>( maxDirectRefLayers, vps->getNumDirectRefLayers( layerCtr ) );
-
-    for(i = 0; i < vps->getNumDirectRefLayers(layerCtr); i++)
-    {
-      vps->setRefLayerId( layerCtr, i, m_acTEncTop[layerCtr].getRefLayerId(i) );
+  for (UInt layerCtr = 1; layerCtr <= vps->getMaxLayers() - 1; layerCtr++)
+  {
+    vps->setNumDirectRefLayers(layerCtr, m_acTEncTop[layerCtr].getNumDirectRefLayers());
+    maxDirectRefLayers = max<UInt>(maxDirectRefLayers, vps->getNumDirectRefLayers(layerCtr));
+
+    for (i = 0; i < vps->getNumDirectRefLayers(layerCtr); i++)
+    {
+      vps->setRefLayerId(layerCtr, i, m_acTEncTop[layerCtr].getRefLayerId(i));
     }
     // Set direct dependency flag
     // Initialize flag to 0
-    for(Int refLayerCtr = 0; refLayerCtr < layerCtr; refLayerCtr++)
-    {
-      vps->setDirectDependencyFlag( layerCtr, refLayerCtr, false );
-    }
-    for(i = 0; i < vps->getNumDirectRefLayers(layerCtr); i++)
-    {
-      vps->setDirectDependencyFlag( layerCtr, vps->getLayerIdInVps(m_acTEncTop[layerCtr].getRefLayerId(i)), true);
+    for (Int refLayerCtr = 0; refLayerCtr < layerCtr; refLayerCtr++)
+    {
+      vps->setDirectDependencyFlag(layerCtr, refLayerCtr, false);
+    }
+    for (i = 0; i < vps->getNumDirectRefLayers(layerCtr); i++)
+    {
+      vps->setDirectDependencyFlag(layerCtr, vps->getLayerIdInVps(m_acTEncTop[layerCtr].getRefLayerId(i)), true);
     }
     // prediction indications
     vps->setDirectDepTypeLen(2); // sample and motion types are encoded
-    for(Int refLayerCtr = 0; refLayerCtr < layerCtr; refLayerCtr++)
-    {
-      if (vps->getDirectDependencyFlag( layerCtr, refLayerCtr))
+    for (Int refLayerCtr = 0; refLayerCtr < layerCtr; refLayerCtr++)
+    {
+      if (vps->getDirectDependencyFlag(layerCtr, refLayerCtr))
       {
         assert(m_acTEncTop[layerCtr].getSamplePredEnabledFlag(refLayerCtr) || m_acTEncTop[layerCtr].getMotionPredEnabledFlag(refLayerCtr));
-        vps->setDirectDependencyType( layerCtr, refLayerCtr, ((m_acTEncTop[layerCtr].getSamplePredEnabledFlag(refLayerCtr) ? 1 : 0) |
-                                                              (m_acTEncTop[layerCtr].getMotionPredEnabledFlag(refLayerCtr) ? 2 : 0)) - 1);
+        vps->setDirectDependencyType(layerCtr, refLayerCtr, ((m_acTEncTop[layerCtr].getSamplePredEnabledFlag(refLayerCtr) ? 1 : 0) |
+          (m_acTEncTop[layerCtr].getMotionPredEnabledFlag(refLayerCtr) ? 2 : 0)) - 1);
 #if O0096_DEFAULT_DEPENDENCY_TYPE
         if (!isDefaultDirectDependencyTypeSet)
@@ -1314,5 +1295,5 @@
       else
       {
-        vps->setDirectDependencyType( layerCtr, refLayerCtr, 0 );
+        vps->setDirectDependencyType(layerCtr, refLayerCtr, 0);
       }
     }
@@ -1320,16 +1301,122 @@
 
 #if O0092_0094_DEPENDENCY_CONSTRAINT
-  for(UInt layerCtr = 1;layerCtr <= vps->getMaxLayers() - 1; layerCtr++)
-  {
-    vps->setNumRefLayers(vps->getLayerIdInNuh(layerCtr));   // identify the number of direct and indirect reference layers of current layer and set recursiveRefLayersFlags
-  }
-  if(vps->getMaxLayers() > MAX_REF_LAYERS)
-  {
-    for(UInt layerCtr = 1; layerCtr <= vps->getMaxLayers() - 1; layerCtr++)
-    {
-      assert( vps->getNumRefLayers(vps->getLayerIdInNuh(layerCtr)) <= MAX_REF_LAYERS);
-    }
-  }
-#endif
+  vps->setNumRefLayers();
+
+  if (vps->getMaxLayers() > MAX_REF_LAYERS)
+  {
+    for (UInt layerCtr = 1; layerCtr <= vps->getMaxLayers() - 1; layerCtr++)
+    {
+      assert(vps->getNumRefLayers(vps->getLayerIdInNuh(layerCtr)) <= MAX_REF_LAYERS);
+    }
+  }
+#endif
+#if Q0078_ADD_LAYER_SETS
+  vps->setPredictedLayerIds();
+  vps->setTreePartitionLayerIdList();
+  vps->setLayerIdIncludedFlagsForAddLayerSets();
+#endif
+#endif
+  // Target output layer
+  vps->setNumOutputLayerSets(vps->getNumLayerSets());
+  vps->setNumProfileTierLevel(vps->getNumLayerSets());
+#if P0295_DEFAULT_OUT_LAYER_IDC
+  vps->setDefaultTargetOutputLayerIdc(1);
+#else
+#if O0109_DEFAULT_ONE_OUT_LAYER_IDC
+  vps->setDefaultOneTargetOutputLayerIdc(1);
+#else
+  vps->setDefaultOneTargetOutputLayerFlag(true);
+#endif
+#endif
+  for(i = 1; i < vps->getNumLayerSets(); i++)
+  {
+    vps->setProfileLevelTierIdx(i, i);
+    vps->setOutputLayerSetIdx(i, i);
+  }  
+#endif
+ #if VPS_DPB_SIZE_TABLE
+  // The Layer ID List variables can be derived here.  
+#if DERIVE_LAYER_ID_LIST_VARIABLES
+  vps->deriveLayerIdListVariables();
+#endif
+#if RESOLUTION_BASED_DPB
+  vps->assignSubDpbIndices();
+#else
+  vps->deriveNumberOfSubDpbs();
+#endif
+
+  // derive OutputLayerFlag[i][j] 
+  if( vps->getDefaultTargetOutputLayerIdc() == 1 )
+  {
+    // default_output_layer_idc equal to 1 specifies that only the layer with the highest value of nuh_layer_id such that nuh_layer_id equal to nuhLayerIdA and 
+    // AuxId[ nuhLayerIdA ] equal to 0 in each of the output layer sets with index in the range of 1 to vps_num_layer_sets_minus1, inclusive, is an output layer of its output layer set.
+
+    // Include the highest layer as output layer for each layer set
+    for(Int lsIdx = 1; lsIdx < vps->getNumLayerSets(); lsIdx++)
+    {
+      for( UInt layer = 0; layer < vps->getNumLayersInIdList(lsIdx); layer++ )
+      {
+#if !Q0078_ADD_LAYER_SETS  // the following condition is incorrect and is not needed anyway
+        if( vps->getLayerIdIncludedFlag(lsIdx, layer) )      
+#endif
+        {        
+          vps->setOutputLayerFlag( lsIdx, layer, layer == vps->getNumLayersInIdList(lsIdx) - 1 );
+        }
+      }
+    }
+  }
+  else
+  {
+    // cases when default_output_layer_idc is not equal to 1
+    assert(!"default_output_layer_idc not equal to 1 is not yet supported");
+  }
+
+  // Initialize dpb_size_table() for all ouput layer sets in the VPS extension
+  for(i = 1; i < vps->getNumOutputLayerSets(); i++)
+  {
+#if CHANGE_NUMSUBDPB_IDX
+    Int layerSetIdxForOutputLayerSet = vps->getOutputLayerSetIdx( i );
+#endif
+    Int layerSetId = vps->getOutputLayerSetIdx(i);
+
+    for(Int j = 0; j < vps->getMaxTLayers(); j++)
+    {
+
+      Int maxNumReorderPics = -1;
+#if CHANGE_NUMSUBDPB_IDX
+#if RESOLUTION_BASED_DPB
+      for(Int k = 0; k < vps->getNumLayersInIdList(layerSetIdxForOutputLayerSet); k++)
+#else
+      for(Int k = 0; k < vps->getNumSubDpbs(layerSetIdxForOutputLayerSet); k++)
+#endif
+#else
+      for(Int k = 0; k < vps->getNumSubDpbs(i); k++)
+#endif
+      {
+        Int layerId = vps->getLayerSetLayerIdList(layerSetId, k); // k-th layer in the output layer set
+#if RESOLUTION_BASED_DPB
+        vps->setMaxVpsLayerDecPicBuffMinus1( i, k, j, m_acTEncTop[layerId].getMaxDecPicBuffering(j) - 1 );
+        // Add sub-DPB sizes of layers belonging to a sub-DPB. If a different sub-DPB size is calculated
+        // at the encoder, modify below
+        Int oldValue = vps->getMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j );
+        oldValue += vps->getMaxVpsLayerDecPicBuffMinus1( i, k, j ) + 1;
+        vps->setMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j, oldValue );
+#else
+        vps->setMaxVpsDecPicBufferingMinus1( i, k, j,  m_acTEncTop[layerId].getMaxDecPicBuffering(j) - 1 );
+#endif
+        maxNumReorderPics       = std::max( maxNumReorderPics, m_acTEncTop[layerId].getNumReorderPics(j));
+      }
+#if RESOLUTION_BASED_DPB
+      for(Int k = 0; k < vps->getNumSubDpbs(i); k++)
+      {
+        // Decrement m_maxVpsDecPicBufferingMinus1
+        Int oldValue = vps->getMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j );
+        vps->setMaxVpsDecPicBufferingMinus1( i, vps->getSubDpbAssigned( layerSetIdxForOutputLayerSet, k ), j, oldValue - 1 );
+      }
+#endif
+      vps->setMaxVpsNumReorderPics(i, j, maxNumReorderPics);
+      vps->determineSubDpbInfoFlags();
+    }
+  }
 #endif
     vps->setMaxOneActiveRefLayerFlag(maxDirectRefLayers > 1 ? false : true);
@@ -1339,5 +1426,9 @@
       if( vps->getNumDirectRefLayers( vps->getLayerIdInNuh(i) ) == 0  )
       {
+#if Q0078_ADD_LAYER_SETS
+        vps->setPocLsbNotPresentFlag(i, true); // make independedent layers base-layer compliant
+#else
         vps->setPocLsbNotPresentFlag(i, false);
+#endif
       }
     }
@@ -1349,5 +1440,4 @@
     vps->setCrossLayerAlignedIdrOnlyFlag( m_crossLayerAlignedIdrOnlyFlag );
 #endif
-#if N0147_IRAP_ALIGN_FLAG
     vps->setCrossLayerIrapAlignFlag( m_crossLayerIrapAlignFlag );
     for(UInt layerCtr = 1;layerCtr <= vps->getMaxLayers() - 1; layerCtr++)
@@ -1365,5 +1455,4 @@
       }
     }
-#endif
 #if M0040_ADAPTIVE_RESOLUTION_CHANGE
   vps->setSingleLayerForNonIrapFlag(m_adaptiveResolutionChange > 0 ? true : false);
@@ -1418,5 +1507,9 @@
   {
     vps->setVpsVuiBspHrdPresentFlag(true);
+#if Q0078_ADD_LAYER_SETS
+    vps->setVpsNumBspHrdParametersMinus1(vps->getVpsNumLayerSetsMinus1() - 1); 
+#else
     vps->setVpsNumBspHrdParametersMinus1(vps->getNumLayerSets() - 2); 
+#endif
     vps->createBspHrdParamBuffer(vps->getVpsNumBspHrdParametersMinus1() + 1);
     for ( i = 0; i <= vps->getVpsNumBspHrdParametersMinus1(); i++ )
@@ -1451,5 +1544,9 @@
       vps->setBspHrdParameters( i, pcCfgLayer->getFrameRate(), numDU, pcCfgLayer->getTargetBitrate(), ( pcCfgLayer->getIntraPeriod() > 0 ) );
     }
+#if Q0078_ADD_LAYER_SETS
+    for (UInt h = 1; h <= vps->getVpsNumLayerSetsMinus1(); h++)
+#else
     for(UInt h = 1; h <= (vps->getNumLayerSets()-1); h++)
+#endif
     {
       vps->setNumBitstreamPartitions(h, 1);
@@ -1532,5 +1629,5 @@
     if( m_isField )
     {
-#if SVC_UPSAMPLING
+#if SVC_EXTENSION
 #if LAYER_CTB
 #if AUXILIARY_PICTURES
@@ -1552,5 +1649,5 @@
     else
     {
-#if SVC_UPSAMPLING
+#if SVC_EXTENSION
 #if LAYER_CTB
 #if AUXILIARY_PICTURES
@@ -1991,5 +2088,4 @@
     rpcPicYuvRec = new TComPicYuv;
 
-#if SVC_UPSAMPLING
 #if LAYER_CTB
 #if AUXILIARY_PICTURES
@@ -2005,7 +2101,4 @@
 #endif
 #endif
-#else
-    rpcPicYuvRec->create( m_acLayerCfg[layer].getSourceWidth(), m_acLayerCfg[layer].getSourceHeight(), m_uiMaxCUWidth, m_uiMaxCUHeight, m_uiMaxCUDepth );
-#endif
 
   }
@@ -2032,4 +2125,10 @@
 Void TAppEncTop::xWriteRecon(UInt layer, Int iNumEncoded)
 {
+#if REPN_FORMAT_IN_VPS
+  ChromaFormat chromaFormatIdc = m_acLayerCfg[layer].getChromaFormatIDC();
+  Int xScal = TComSPS::getWinUnitX( chromaFormatIdc );
+  Int yScal = TComSPS::getWinUnitY( chromaFormatIdc );
+#endif
+
   if (m_isField)
   {
@@ -2054,5 +2153,10 @@
 #endif
       {
+#if REPN_FORMAT_IN_VPS
+        m_acTVideoIOYuvReconFile[layer].write( pcPicYuvRecTop, pcPicYuvRecBottom, m_acLayerCfg[layer].getConfLeft() * xScal, m_acLayerCfg[layer].getConfRight() * xScal, 
+          m_acLayerCfg[layer].getConfTop() * yScal, m_acLayerCfg[layer].getConfBottom() * yScal, m_isTopFieldFirst );
+#else
         m_acTVideoIOYuvReconFile[layer].write( pcPicYuvRecTop, pcPicYuvRecBottom, m_acLayerCfg[layer].getConfLeft(), m_acLayerCfg[layer].getConfRight(), m_acLayerCfg[layer].getConfTop(), m_acLayerCfg[layer].getConfBottom(), m_isTopFieldFirst );
+#endif
       }
     }
@@ -2078,6 +2182,11 @@
 #endif
       {
+#if REPN_FORMAT_IN_VPS
+        m_acTVideoIOYuvReconFile[layer].write( pcPicYuvRec, m_acLayerCfg[layer].getConfLeft() * xScal, m_acLayerCfg[layer].getConfRight() * xScal,
+          m_acLayerCfg[layer].getConfTop() * yScal, m_acLayerCfg[layer].getConfBottom() * yScal );
+#else
         m_acTVideoIOYuvReconFile[layer].write( pcPicYuvRec, m_acLayerCfg[layer].getConfLeft(), m_acLayerCfg[layer].getConfRight(),
           m_acLayerCfg[layer].getConfTop(), m_acLayerCfg[layer].getConfBottom() );
+#endif
       }
     }
Index: trunk/source/App/utils/BLRewrite/BLRewrite.c
===================================================================
--- trunk/source/App/utils/BLRewrite/BLRewrite.c	(revision 815)
+++ trunk/source/App/utils/BLRewrite/BLRewrite.c	(revision 815)
@@ -0,0 +1,274 @@
+/* The copyright in this software is being made available under the BSD
+* License, included below. This software may be subject to other third party
+* and contributor rights, including patent rights, and no such rights are
+* granted under this license.
+*
+* Copyright (c) 2010-2014, ITU/ISO/IEC
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+*  * Redistributions of source code must retain the above copyright notice,
+*    this list of conditions and the following disclaimer.
+*  * Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+*    be used to endorse or promote products derived from this software without
+*    specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+enum NalUnitType
+{
+  NAL_UNIT_CODED_SLICE_TRAIL_N = 0,   // 0
+  NAL_UNIT_CODED_SLICE_TRAIL_R,   // 1
+
+  NAL_UNIT_CODED_SLICE_TSA_N,     // 2
+  NAL_UNIT_CODED_SLICE_TSA_R,       // 3
+
+  NAL_UNIT_CODED_SLICE_STSA_N,    // 4
+  NAL_UNIT_CODED_SLICE_STSA_R,    // 5
+
+  NAL_UNIT_CODED_SLICE_RADL_N,    // 6
+  NAL_UNIT_CODED_SLICE_RADL_R,      // 7
+
+  NAL_UNIT_CODED_SLICE_RASL_N,    // 8
+  NAL_UNIT_CODED_SLICE_RASL_R,      // 9
+
+  NAL_UNIT_RESERVED_VCL_N10,
+  NAL_UNIT_RESERVED_VCL_R11,
+  NAL_UNIT_RESERVED_VCL_N12,
+  NAL_UNIT_RESERVED_VCL_R13,
+  NAL_UNIT_RESERVED_VCL_N14,
+  NAL_UNIT_RESERVED_VCL_R15,
+
+  NAL_UNIT_CODED_SLICE_BLA_W_LP,    // 16
+  NAL_UNIT_CODED_SLICE_BLA_W_RADL,  // 17
+  NAL_UNIT_CODED_SLICE_BLA_N_LP,  // 18
+  NAL_UNIT_CODED_SLICE_IDR_W_RADL,  // 19
+  NAL_UNIT_CODED_SLICE_IDR_N_LP,  // 20
+  NAL_UNIT_CODED_SLICE_CRA,       // 21
+  NAL_UNIT_RESERVED_IRAP_VCL22,
+  NAL_UNIT_RESERVED_IRAP_VCL23,
+
+  NAL_UNIT_RESERVED_VCL24,
+  NAL_UNIT_RESERVED_VCL25,
+  NAL_UNIT_RESERVED_VCL26,
+  NAL_UNIT_RESERVED_VCL27,
+  NAL_UNIT_RESERVED_VCL28,
+  NAL_UNIT_RESERVED_VCL29,
+  NAL_UNIT_RESERVED_VCL30,
+  NAL_UNIT_RESERVED_VCL31,
+
+  NAL_UNIT_VPS,                   // 32
+  NAL_UNIT_SPS,                   // 33
+  NAL_UNIT_PPS,                   // 34
+  NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35
+  NAL_UNIT_EOS,                   // 36
+  NAL_UNIT_EOB,                   // 37
+  NAL_UNIT_FILLER_DATA,           // 38
+  NAL_UNIT_PREFIX_SEI,              // 39
+  NAL_UNIT_SUFFIX_SEI,              // 40
+  NAL_UNIT_RESERVED_NVCL41,
+  NAL_UNIT_RESERVED_NVCL42,
+  NAL_UNIT_RESERVED_NVCL43,
+  NAL_UNIT_RESERVED_NVCL44,
+  NAL_UNIT_RESERVED_NVCL45,
+  NAL_UNIT_RESERVED_NVCL46,
+  NAL_UNIT_RESERVED_NVCL47,
+  NAL_UNIT_UNSPECIFIED_48,
+  NAL_UNIT_UNSPECIFIED_49,
+  NAL_UNIT_UNSPECIFIED_50,
+  NAL_UNIT_UNSPECIFIED_51,
+  NAL_UNIT_UNSPECIFIED_52,
+  NAL_UNIT_UNSPECIFIED_53,
+  NAL_UNIT_UNSPECIFIED_54,
+  NAL_UNIT_UNSPECIFIED_55,
+  NAL_UNIT_UNSPECIFIED_56,
+  NAL_UNIT_UNSPECIFIED_57,
+  NAL_UNIT_UNSPECIFIED_58,
+  NAL_UNIT_UNSPECIFIED_59,
+  NAL_UNIT_UNSPECIFIED_60,
+  NAL_UNIT_UNSPECIFIED_61,
+  NAL_UNIT_UNSPECIFIED_62,
+  NAL_UNIT_UNSPECIFIED_63,
+  NAL_UNIT_INVALID,
+};
+
+typedef struct NalUnitHeader_s
+{
+  int nalUnitType;
+  int nuhLayerId;
+  int nuhTemporalIdPlus1;
+} NalUnitHeader;
+
+
+int findStartCodePrefix(FILE *inFile, int *numStartCodeZeros)
+{
+  int numZeros = 0;
+  int currByte;
+  
+  while (1)
+  {
+    currByte = fgetc(inFile);
+    if (currByte == EOF)
+    {
+      return 0;
+    }
+
+    if (currByte == 0x01 && numZeros > 1)
+    {
+      *numStartCodeZeros = numZeros;
+      return 1;
+    }
+    else if (currByte == 0)
+    {
+      numZeros++;
+    }
+    else
+    {
+      numZeros = 0;
+    }
+  }
+}
+
+int parseNalUnitHeader(FILE *inFile, NalUnitHeader *nalu)
+{
+  int byte0, byte1;
+
+  byte0 = fgetc(inFile);
+  byte1 = fgetc(inFile);
+
+  if (byte0 == EOF || byte1 == EOF)
+  {
+    return 0;
+  }
+
+  nalu->nalUnitType = (byte0 >> 1) & 0x3f;
+  nalu->nuhLayerId  = (((byte0 << 8) | byte1) >> 3) & 0x3f;
+  nalu->nuhTemporalIdPlus1 = byte1 & 0x07;
+
+  return 1;
+}
+
+void writeStartCodePrefixAndNUH(FILE *outFile, int numStartCodeZeros, NalUnitHeader *nalu)
+{
+  int byte0, byte1;
+  int i;
+
+  /* Start code prefix */
+  if (numStartCodeZeros > 3)
+  {
+    numStartCodeZeros = 3;
+  }
+  for (i = 0; i < numStartCodeZeros; i++)
+  {
+    fputc(0, outFile);
+  }
+  fputc(0x01, outFile);
+
+  /* NAL unit header */
+  byte0 = ((nalu->nalUnitType << 6) | nalu->nuhLayerId) >> 5;
+  byte1 = ((nalu->nuhLayerId << 3) | nalu->nuhTemporalIdPlus1) & 0xff;
+  fputc(byte0, outFile);
+  fputc(byte1, outFile);
+}
+
+int main(int argc, char **argv)
+{
+  FILE *inFile;
+  FILE *outFile;
+  int assignedBaseLayerId;
+  NalUnitHeader nalu;
+  int numStartCodeZeros;
+  int isSpsPpsEosEob;
+
+  if (argc < 3)
+  {
+    printf("Usage: Splicer <infile> <outfile> <assigned base layer ID>\n", argv[0]);
+  }
+
+  inFile = fopen(argv[1], "rb");
+  if (inFile == NULL)
+  {
+    fprintf(stderr, "Cannot open input file %s\n", argv[1]);
+    exit(1);
+  }
+
+  outFile = fopen(argv[2], "wb");
+  if (outFile == NULL)
+  {
+    fprintf(stderr, "Cannot open output file %s\n", argv[2]);
+    exit(1);
+  }
+
+  assignedBaseLayerId = atoi(argv[3]);
+
+  while (1)
+  {
+    if (!findStartCodePrefix(inFile, &numStartCodeZeros))
+    {
+      break;
+    }
+    if (!parseNalUnitHeader(inFile, &nalu))
+    {
+      break;
+    }
+
+    printf("NAL unit type: %i,  NUH layer ID: %i,  NUH Temporal ID: %i\n", nalu.nalUnitType, nalu.nuhLayerId, nalu.nuhTemporalIdPlus1 - 1);
+
+    isSpsPpsEosEob = (nalu.nalUnitType == NAL_UNIT_SPS || nalu.nalUnitType == NAL_UNIT_PPS || nalu.nalUnitType == NAL_UNIT_EOS || nalu.nalUnitType == NAL_UNIT_EOB);
+
+    if ((isSpsPpsEosEob && nalu.nuhLayerId == 0) || (!isSpsPpsEosEob && nalu.nuhLayerId == assignedBaseLayerId))
+    {
+      /* Write current NAL unit to output bitstream */
+
+      long naluBytesStartPos;
+      long numNaluBytes;
+      long i;
+
+      nalu.nuhLayerId = 0;
+      writeStartCodePrefixAndNUH(outFile, numStartCodeZeros, &nalu);
+
+      naluBytesStartPos = ftell(inFile);
+      /* Find beginning of the next NAL unit to calculate length of the current unit */
+      if (findStartCodePrefix(inFile, &numStartCodeZeros))
+      {
+        numNaluBytes = ftell(inFile) - naluBytesStartPos - numStartCodeZeros - 1;
+      }
+      else
+      {
+        numNaluBytes = ftell(inFile) - naluBytesStartPos;
+      }
+      fseek(inFile, naluBytesStartPos, SEEK_SET);
+
+      for (i = 0; i < numNaluBytes; i++)
+      {
+        fputc(fgetc(inFile), outFile);
+      }
+    }
+  }
+
+  fclose(inFile);
+  fclose(outFile);
+
+
+  return 0;
+}
Index: trunk/source/App/utils/BLRewrite/ReadMe.txt
===================================================================
--- trunk/source/App/utils/BLRewrite/ReadMe.txt	(revision 815)
+++ trunk/source/App/utils/BLRewrite/ReadMe.txt	(revision 815)
@@ -0,0 +1,17 @@
+
+This is a simple tool that extracts an independent non-base layer from a multi-layer bitstream, converts it to a base-layer bistream and writes it to a file. The tool is invoked as follows. 
+
+  BLRewrite <infile> <outfile> <layer ID of the extracted layer>
+
+The tool is based on the contribution JCTVC-Q0078 / JCTVC-R0042. Sub-bitstream extraction process done by the tool can be summarized as follows.
+
+- NAL units with nal_unit_type not equal to SPS_NUT, PPS_NUT, EOS_NUT and EOB_NUT and with nuh_layer_id not equal to the assignedBaseLayerId are removed from outBitstream.
+- NAL units with nal_unit_type equal to SPS_NUT, PPS_NUT, EOS_NUT or EOB_NUT with nuh_layer_id not equal to 0 are removed from outBitstream.
+- For each NAL unit, the following applies:
+   When nuh_layer_id is equal to assignedBaseLayerId, nuh_layer_id is set equal to 0.
+
+The resulting bitstream can be decoded with an HEVC/H.265 v1 compliant decoder as long as the extracted independent layer conform with v1 specification text. The tool removes VPS from the output bitstream so an HEVC/H.265 decoder should not expect it to be present.
+
+
+
+
