diff --git a/cfg/layers.cfg b/cfg/layers.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..f083583f89767ae10f384c6dab19ebcc4dc2e28a
--- /dev/null
+++ b/cfg/layers.cfg
@@ -0,0 +1,19 @@
+#======== Layers ===============
+MaxLayers                     : 2
+MaxSublayers                  : 1
+AllLayersSameNumSublayersFlag : 0
+AllIndependentLayersFlag      : 0
+#======== OLSs ===============
+EachLayerIsAnOlsFlag          : 0
+OlsModeIdc                    : 2
+NumOutputLayerSets            : 2
+OlsOutputLayer1               : 1 0
+#======== Layer-0 ===============
+LayerId0                      : 0
+#======== Layer-1 ===============
+LayerId1                      : 1
+NumRefLayers1                 : 1
+RefLayerIdx1                  : 0
+
+
+
diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index f30cf26d0b4c2cc9d661e629e1d365b605a065cb..afc037028aca334dc91cba04bb633de3fef8bd0d 100755
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -1788,7 +1788,18 @@ be encoded or decoded using one or more cores.
 
 \end{OptionTableNoShorthand}
 
+%%
+%% Slice/Sub-Picture coding parameters
+%%
+\begin{OptionTableNoShorthand}{Slice and Sub-Picture coding parameters}{tab:subpicture-coding}
 
+\Option{EnableSubPicPartitioning} &
+%\ShortOption{\None} &
+\Default{1} &
+Enable Sub Picture partitioning (0: single slice per sub-picture, 1: multiple slices per sub-picture can be used).
+\\
+
+\end{OptionTableNoShorthand}
 
 %%
 %% In-loop filtering parameters
diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index c76e14ab78af6c738c9556e3c545a5bf89432d84..a0717b2fe9e77803b1e679c515b620e0e9f6c1bb 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -116,6 +116,10 @@ uint32_t DecApp::decode()
 #endif
   bool loopFiltered = false;
 
+#if JVET_P1019_OUTPUT_LAYER_SET
+  bool bPicSkipped = false;
+#endif
+
   while (!!bitstreamFile)
   {
 #if JVET_P1006_PICTURE_HEADER
@@ -150,14 +154,48 @@ uint32_t DecApp::decode()
             (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
              nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP))
         {
+#if JVET_N0278_FIXES
+          xFlushOutput(pcListPic, nalu.m_nuhLayerId);
+#else
           xFlushOutput(pcListPic);
+#endif
         }
 
         // parse NAL unit syntax if within target decoding layer
+#if JVET_P1019_OUTPUT_LAYER_SET
+        if ((m_iMaxTemporalLayer < 0 || nalu.m_temporalId <= m_iMaxTemporalLayer) && isNaluWithinTargetDecLayerIdSet(&nalu))
+#else
         if ((m_iMaxTemporalLayer < 0 || nalu.m_temporalId <= m_iMaxTemporalLayer) && isNaluWithinTargetDecLayerIdSet(&nalu) && isNaluTheTargetLayer(&nalu))
+#endif
         {
+#if JVET_P1019_OUTPUT_LAYER_SET
+          if (bPicSkipped)
+          {
+            if ((nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_TRAIL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_RADL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR))
+            {
+              if (m_cDecLib.isSliceNaluFirstInAU(true, nalu))
+              {
+                m_cDecLib.resetAccessUnitNals();
+                m_cDecLib.resetAccessUnitApsNals();
+              }
+              bPicSkipped = false;
+            }
+          }
+#endif
           m_cDecLib.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
+#if JVET_P1019_OUTPUT_LAYER_SET
+          if (nalu.m_nalUnitType == NAL_UNIT_VPS)
+          {
+            deriveOutputLayerSet();
+          }
+#endif
         }
+#if JVET_P1019_OUTPUT_LAYER_SET
+        else
+        {
+          bPicSkipped = true;
+        }
+#endif
       }
     }
 #else 
@@ -212,7 +250,11 @@ uint32_t DecApp::decode()
 #endif
       }
 
+#if JVET_P1019_OUTPUT_LAYER_SET
+      if ((m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu))
+#else
       if ((m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu) || !isNaluTheTargetLayer(&nalu))
+#endif
       {
         bNewPicture = false;
       }
@@ -248,7 +290,11 @@ uint32_t DecApp::decode()
 #endif
 
 
-    if( ( bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) && !m_cDecLib.getFirstSliceInSequence() )
+#if JVET_P1019_OUTPUT_LAYER_SET
+    if ((bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) && !m_cDecLib.getFirstSliceInSequence() && !bPicSkipped)
+#else
+    if ((bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) && !m_cDecLib.getFirstSliceInSequence())
+#endif
     {
       if (!loopFiltered || bitstreamFile)
       {
@@ -297,7 +343,11 @@ uint32_t DecApp::decode()
 
 #if JVET_N0278_FIXES
         std::string reconFileName = m_reconFileName;
-        if( m_reconFileName.compare( "/dev/null" ) && (m_cDecLib.getVPS() != nullptr) && (m_cDecLib.getVPS()->getMaxLayers() > 1)  && (m_iTargetLayer == -1) )
+#if JVET_P1019_OUTPUT_LAYER_SET
+        if (m_reconFileName.compare("/dev/null") && (m_cDecLib.getVPS() != nullptr) && (m_cDecLib.getVPS()->getMaxLayers() > 1) && (isNaluWithinTargetOutputLayerIdSet(&nalu)))
+#else
+        if (m_reconFileName.compare("/dev/null") && (m_cDecLib.getVPS() != nullptr) && (m_cDecLib.getVPS()->getMaxLayers() > 1) && (m_iTargetLayer == -1))
+#endif
         {
           size_t pos = reconFileName.find_last_of('.');
           if (pos != string::npos)
@@ -309,7 +359,10 @@ uint32_t DecApp::decode()
             reconFileName.append( std::to_string( nalu.m_nuhLayerId ) );
           }
         }
-        m_cVideoIOYuvReconFile[nalu.m_nuhLayerId].open( reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
+#if JVET_P1019_OUTPUT_LAYER_SET
+        if(((m_cDecLib.getVPS() != nullptr) && (m_cDecLib.getVPS()->getMaxLayers() > 1) && (isNaluWithinTargetOutputLayerIdSet(&nalu))) || (m_cDecLib.getVPS() == nullptr))
+#endif
+        m_cVideoIOYuvReconFile[nalu.m_nuhLayerId].open(reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon); // write mode
 #else
         m_cVideoIOYuvReconFile.open( m_reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
         openedReconFile = true;
@@ -369,6 +422,173 @@ uint32_t DecApp::decode()
   return nRet;
 }
 
+#if JVET_P1019_OUTPUT_LAYER_SET
+bool DecApp::deriveOutputLayerSet()
+{
+  int vps_max_layers_minus1 = m_cDecLib.getVPS()->getMaxLayers() - 1;
+  int TotalNumOlss = 0;
+  int each_layer_is_an_ols_flag = m_cDecLib.getVPS()->getEachLayerIsAnOlsFlag();
+  int ols_mode_idc = m_cDecLib.getVPS()->getOlsModeIdc();
+  int num_output_layer_sets_minus1 = m_cDecLib.getVPS()->getNumOutputLayerSets() - 1;
+  int i = 0, j = 0, k = 0, r = 0;
+  int*  NumOutputLayersInOls;
+  int*  NumLayersInOls;
+  int** OutputLayerIdInOls;
+  int** OutputLayerIdx;
+  int** layerIncludedInOlsFlag;
+  int** LayerIdInOls;
+  int** dependencyFlag;
+  int** RefLayerIdx;
+  int*  NumRefLayers;
+
+  if (vps_max_layers_minus1 == 0)
+    TotalNumOlss = 1;
+  else if (each_layer_is_an_ols_flag || ols_mode_idc == 0 || ols_mode_idc == 1)
+    TotalNumOlss = vps_max_layers_minus1 + 1;
+  else if (ols_mode_idc == 2)
+    TotalNumOlss = num_output_layer_sets_minus1 + 1;
+
+  NumOutputLayersInOls = new int[m_cDecLib.getVPS()->getNumOutputLayerSets()];
+  NumLayersInOls = new int[m_cDecLib.getVPS()->getNumOutputLayerSets()];
+  OutputLayerIdInOls = new int*[TotalNumOlss];
+  OutputLayerIdx = new int*[TotalNumOlss];
+  layerIncludedInOlsFlag = new int*[TotalNumOlss];
+  LayerIdInOls = new int*[TotalNumOlss];
+
+  for (i = 0; i < TotalNumOlss; i++)
+  {
+    OutputLayerIdInOls[i] = new int[vps_max_layers_minus1 + 1];
+    OutputLayerIdx[i] = new int[vps_max_layers_minus1 + 1];
+    layerIncludedInOlsFlag[i] = new int[vps_max_layers_minus1 + 1];
+    LayerIdInOls[i] = new int[vps_max_layers_minus1 + 1];
+  }
+
+  dependencyFlag = new int*[vps_max_layers_minus1 + 1];
+  RefLayerIdx = new int*[vps_max_layers_minus1 + 1];
+  NumRefLayers = new int[vps_max_layers_minus1 + 1];
+
+  for (i = 0; i <= vps_max_layers_minus1; i++)
+  {
+    dependencyFlag[i] = new int[vps_max_layers_minus1 + 1];
+    RefLayerIdx[i] = new int[vps_max_layers_minus1 + 1];
+  }
+
+  for (i = 0; i <= vps_max_layers_minus1; i++) {
+    for (j = 0; j <= vps_max_layers_minus1; j++) {
+      dependencyFlag[i][j] = m_cDecLib.getVPS()->getDirectRefLayerFlag(i, j);
+      for (k = 0; k < i; k++)
+        if (m_cDecLib.getVPS()->getDirectRefLayerFlag(i, k) && dependencyFlag[k][j])
+          dependencyFlag[i][j] = 1;
+    }
+  }
+  for (i = 0; i <= vps_max_layers_minus1; i++)
+  {
+    for (j = 0, r = 0; j <= vps_max_layers_minus1; j++)
+    {
+      if (dependencyFlag[i][j])
+        RefLayerIdx[i][r++] = j;
+    }
+    NumRefLayers[i] = r;
+  }
+
+  NumOutputLayersInOls[0] = 1;
+  OutputLayerIdInOls[0][0] = m_cDecLib.getVPS()->getLayerId(0);
+  for (i = 1; i < TotalNumOlss; i++)
+  {
+    if (each_layer_is_an_ols_flag || ols_mode_idc == 0)
+    {
+      NumOutputLayersInOls[i] = 1;
+      OutputLayerIdInOls[i][0] = m_cDecLib.getVPS()->getLayerId(i);
+    }
+    else if (ols_mode_idc == 1) {
+      NumOutputLayersInOls[i] = i + 1;
+      for (j = 0; j < NumOutputLayersInOls[i]; j++)
+        OutputLayerIdInOls[i][j] = m_cDecLib.getVPS()->getLayerId(j);
+    }
+    else if (ols_mode_idc == 2) {
+      for (j = 0; j <= vps_max_layers_minus1; j++)
+      {
+        layerIncludedInOlsFlag[i][j] = 0;
+      }
+      for (k = 0, j = 0; k <= vps_max_layers_minus1; k++)
+      {
+        if (m_cDecLib.getVPS()->getOlsOutputLayerFlag(i, k))
+        {
+          layerIncludedInOlsFlag[i][k] = 1;
+          OutputLayerIdx[i][j] = k;
+          OutputLayerIdInOls[i][j++] = m_cDecLib.getVPS()->getLayerId(k);
+        }
+      }
+      NumOutputLayersInOls[i] = j;
+      for (j = 0; j < NumOutputLayersInOls[i]; j++)
+      {
+        int idx = OutputLayerIdx[i][j];
+        for (k = 0; k < NumRefLayers[idx]; k++)
+          layerIncludedInOlsFlag[i][RefLayerIdx[idx][k]] = 1;
+      }
+    }
+  }
+
+  m_targetOutputLayerIdSet.clear();
+  for (i = 0; i < NumOutputLayersInOls[m_iTargetOLS]; i++)
+    m_targetOutputLayerIdSet.push_back(OutputLayerIdInOls[m_iTargetOLS][i]);
+
+  NumLayersInOls[0] = 1;
+  LayerIdInOls[0][0] = m_cDecLib.getVPS()->getLayerId(0);
+  for (i = 1; i < TotalNumOlss; i++)
+  {
+    if (each_layer_is_an_ols_flag)
+    {
+      NumLayersInOls[i] = 1;
+      LayerIdInOls[i][0] = m_cDecLib.getVPS()->getLayerId(i);
+    }
+    else if (ols_mode_idc == 0 || ols_mode_idc == 1)
+    {
+      NumLayersInOls[i] = i + 1;
+      for (j = 0; j < NumLayersInOls[i]; j++)
+        LayerIdInOls[i][j] = m_cDecLib.getVPS()->getLayerId(j);
+    }
+    else if (ols_mode_idc == 2)
+    {
+      for (k = 0, j = 0; k <= vps_max_layers_minus1; k++)
+        if (layerIncludedInOlsFlag[i][k])
+          LayerIdInOls[i][j++] = m_cDecLib.getVPS()->getLayerId(k);
+      NumLayersInOls[i] = j;
+    }
+  }
+
+  m_targetDecLayerIdSet.clear();
+  for (i = 0; i < NumLayersInOls[m_iTargetOLS]; i++)
+    m_targetDecLayerIdSet.push_back(LayerIdInOls[m_iTargetOLS][i]);
+
+  delete[] NumOutputLayersInOls;
+  delete[] NumLayersInOls;
+  delete[] NumRefLayers;
+
+  for (i = 0; i < TotalNumOlss; i++)
+  {
+    delete[] OutputLayerIdInOls[i];
+    delete[] OutputLayerIdx[i];
+    delete[] layerIncludedInOlsFlag[i];
+    delete[] LayerIdInOls[i];
+  }
+  delete[] OutputLayerIdInOls;
+  delete[] OutputLayerIdx;
+  delete[] layerIncludedInOlsFlag;
+  delete[] LayerIdInOls;
+
+  for (i = 0; i <= vps_max_layers_minus1; i++)
+  {
+    delete[] dependencyFlag[i];
+    delete[] RefLayerIdx[i];
+  }
+  delete[] dependencyFlag;
+  delete[] RefLayerIdx;
+
+  return true;
+}
+#endif
+
 #if JVET_P1006_PICTURE_HEADER
 /**
  - lookahead through next NAL units to determine if current NAL unit is the first NAL unit in a new picture
@@ -593,7 +813,9 @@ void DecApp::xCreateDecLib()
   );
   m_cDecLib.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
 
+#if !JVET_P1019_OUTPUT_LAYER_SET
   m_cDecLib.setTargetDecLayer(m_iTargetLayer);
+#endif
 
   if (!m_outputDecodedSEIMessagesFilename.empty())
   {
@@ -1014,6 +1236,26 @@ bool DecApp::isNaluWithinTargetDecLayerIdSet( InputNALUnit* nalu )
   return false;
 }
 
+#if JVET_P1019_OUTPUT_LAYER_SET
+/** \param nalu Input nalu to check whether its LayerId is within targetOutputLayerIdSet
+ */
+bool DecApp::isNaluWithinTargetOutputLayerIdSet(InputNALUnit* nalu)
+{
+  if (m_targetOutputLayerIdSet.size() == 0) // By default, the set is empty, meaning all LayerIds are allowed
+  {
+    return true;
+  }
+  for (std::vector<int>::iterator it = m_targetOutputLayerIdSet.begin(); it != m_targetOutputLayerIdSet.end(); it++)
+  {
+    if (nalu->m_nuhLayerId == (*it))
+    {
+      return true;
+    }
+  }
+  return false;
+}
+
+#else
 /** \param nalu Input nalu to check whether its LayerId is the specified target layer
 */
 bool DecApp::isNaluTheTargetLayer(InputNALUnit* nalu)
@@ -1023,5 +1265,6 @@ bool DecApp::isNaluTheTargetLayer(InputNALUnit* nalu)
 
   return false;
 }
+#endif
 
 //! \}
diff --git a/source/App/DecoderApp/DecApp.h b/source/App/DecoderApp/DecApp.h
index 9abfb29193e429e5c8c07e3281d77e503f601fe8..1ff24433c87f189d6bf425f9ce3f538b3b7652a4 100644
--- a/source/App/DecoderApp/DecApp.h
+++ b/source/App/DecoderApp/DecApp.h
@@ -90,7 +90,12 @@ private:
   void  xFlushOutput      ( PicList* pcListPic ); ///< flush all remaining decoded pictures to file
 #endif
   bool  isNaluWithinTargetDecLayerIdSet ( InputNALUnit* nalu ); ///< check whether given Nalu is within targetDecLayerIdSet
+#if JVET_P1019_OUTPUT_LAYER_SET
+  bool  isNaluWithinTargetOutputLayerIdSet(InputNALUnit* nalu); ///< check whether given Nalu is within targetOutputLayerIdSet
+  bool  deriveOutputLayerSet(); ///< derive OLS and layer sets
+#else
   bool  isNaluTheTargetLayer(InputNALUnit* nalu); ///< check whether given Nalu is within targetDecLayerIdSet
+#endif
 #if JVET_P1006_PICTURE_HEADER
   bool  isNewPicture(ifstream *bitstreamFile, class InputByteStream *bytestream);  ///< check if next NAL unit will be the first NAL unit from a new picture
   bool  isNewAccessUnit(bool newPicture, ifstream *bitstreamFile, class InputByteStream *bytestream);  ///< check if next NAL unit will be the first NAL unit from a new access unit
diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp
index 42584a5fa8e63453d3faa2af06d5f409b6e893fd..7e5f3892c262df8bf2af220271b92b9132328376 100644
--- a/source/App/DecoderApp/DecAppCfg.cpp
+++ b/source/App/DecoderApp/DecAppCfg.cpp
@@ -87,7 +87,11 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
   ("OutputBitDepthC,d",         m_outputBitDepth[CHANNEL_TYPE_CHROMA], 0,          "bit depth of YUV output chroma component (default: use luma output bit-depth)")
   ("OutputColourSpaceConvert",  outputColourSpaceConvert,              string(""), "Colour space conversion to apply to input 444 video. Permitted values are (empty string=UNCHANGED) " + getListOfColourSpaceConverts(false))
   ("MaxTemporalLayer,t",        m_iMaxTemporalLayer,                   -1,         "Maximum Temporal Layer to be decoded. -1 to decode all layers")
-  ("TargetLayer,p",             m_iTargetLayer,                        -1,         "Target bitstream Layer to be decoded.")
+#if JVET_P1019_OUTPUT_LAYER_SET
+  ("TargetOutputLayerSet,p",    m_iTargetOLS,                          -1,         "Target output layer set.")
+#else
+  ("TargetLayer,p", m_iTargetLayer, -1, "Target bitstream Layer to be decoded.")
+#endif
   ("SEIDecodedPictureHash,-dph",m_decodedPictureHashSEIEnabled,        1,          "Control handling of decoded picture hash SEI messages\n"
                                                                                    "\t1: check hash in SEI messages if available in the bitstream\n"
                                                                                    "\t0: ignore SEI message")
@@ -224,7 +228,11 @@ DecAppCfg::DecAppCfg()
 , m_iSkipFrame(0)
 // m_outputBitDepth array initialised below
 , m_outputColourSpaceConvert(IPCOLOURSPACE_UNCHANGED)
+#if JVET_P1019_OUTPUT_LAYER_SET
+, m_iTargetOLS(0)
+#else
 , m_iTargetLayer(0)
+#endif
 , m_iMaxTemporalLayer(-1)
 , m_decodedPictureHashSEIEnabled(0)
 , m_decodedNoDisplaySEIEnabled(false)
diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h
index 774d15dac52c133a4aff18b9dd49d67530bcd47f..692a1d04a0056299d38dc72bc58c04f892da38d8 100644
--- a/source/App/DecoderApp/DecAppCfg.h
+++ b/source/App/DecoderApp/DecAppCfg.h
@@ -61,8 +61,12 @@ protected:
   int           m_iSkipFrame;                           ///< counter for frames prior to the random access point to skip
   int           m_outputBitDepth[MAX_NUM_CHANNEL_TYPE]; ///< bit depth used for writing output
   InputColourSpaceConversion m_outputColourSpaceConvert;
+#if JVET_P1019_OUTPUT_LAYER_SET
+  int           m_iTargetOLS;                         ///< target output layer set
+  std::vector<int> m_targetOutputLayerIdSet;          ///< set of LayerIds to be outputted           
+#else
   int           m_iTargetLayer;                       ///< target stream layer to be decoded
-
+#endif
   int           m_iMaxTemporalLayer;                  ///< maximum temporal layer to be decoded
   int           m_decodedPictureHashSEIEnabled;       ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
   bool          m_decodedNoDisplaySEIEnabled;         ///< Enable(true)/disable(false) writing only pictures that get displayed based on the no display SEI message
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 43c82d21140547e62b038fc6ebfdd79e487f65e4..a535145b7150c22aa7c40c4111b42ff28185ded0 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -93,14 +93,110 @@ void EncApp::xInitLibCfg()
   VPS vps;
 
 #if JVET_N0278_FIXES
-  vps.setMaxLayers                                               ( m_maxLayers );
+  vps.setMaxLayers( m_maxLayers );
+
+#if JVET_O1159_SCALABILITY
+  if (vps.getMaxLayers() > 1)
+  {
+    vps.setVPSId(1);  //JVET_P0205 vps_video_parameter_set_id shall be greater than 0 for multi-layer coding
+  }
+  else
+  {
+    vps.setVPSId(0);
+    vps.setEachLayerIsAnOlsFlag(1); // If vps_max_layers_minus1 is equal to 0,
+                                    // the value of each_layer_is_an_ols_flag is inferred to be equal to 1.
+                                    // Otherwise, when vps_all_independent_layers_flag is equal to 0,
+                                    // the value of each_layer_is_an_ols_flag is inferred to be equal to 0.
+  }
+  vps.setMaxSubLayers(m_maxSublayers);
+  if (vps.getMaxLayers() > 1 && vps.getMaxSubLayers() > 1)
+  {
+    vps.setAllLayersSameNumSublayersFlag(m_allLayersSameNumSublayersFlag);
+  }
+  if (vps.getMaxLayers() > 1)
+  {
+    vps.setAllIndependentLayersFlag(m_allIndependentLayersFlag);
+    if (!vps.getAllIndependentLayersFlag())
+    {
+      vps.setEachLayerIsAnOlsFlag(0);
+    }
+  }
+
+  for (int i = 0; i < vps.getMaxLayers(); i++)
+  {
+    vps.setGeneralLayerIdx( m_layerId[i], i );
+    vps.setLayerId(i, m_layerId[i]);
+
+    if (i > 0 && !vps.getAllIndependentLayersFlag())
+    {
+      vps.setIndependentLayerFlag( i, m_numRefLayers[i] ? false : true );
+
+      if (!vps.getIndependentLayerFlag(i))
+      {
+        for (int j = 0, k = 0; j < i; j++)
+        {
+          if (m_refLayerIdxStr[i].find(to_string(j)) != std::string::npos)
+          {
+            vps.setDirectRefLayerFlag(i, j, true);
+            vps.setInterLayerRefIdc( i, j, k );
+            vps.setDirectRefLayerIdx(i, k++, j);
+          }
+          else
+          {
+            vps.setDirectRefLayerFlag(i, j, false);
+          }
+        }
+      }
+    }
+  }
+
+
+  if (vps.getMaxLayers() > 1)
+  {
+    if (vps.getAllIndependentLayersFlag())
+    {
+      vps.setEachLayerIsAnOlsFlag(m_eachLayerIsAnOlsFlag);
+      if (vps.getEachLayerIsAnOlsFlag() == 0)
+      {
+        vps.setOlsModeIdc(2); // When vps_all_independent_layers_flag is equal to 1 and each_layer_is_an_ols_flag is equal to 0, the value of ols_mode_idc is inferred to be equal to 2
+      }
+    }
+    if (!vps.getEachLayerIsAnOlsFlag())
+    {
+      if (!vps.getAllIndependentLayersFlag())
+      {
+        vps.setOlsModeIdc(m_olsModeIdc);
+      }
+      if (vps.getOlsModeIdc() == 2)
+      {
+        vps.setNumOutputLayerSets(m_numOutputLayerSets);
+        for (int i = 1; i < vps.getNumOutputLayerSets(); i++)
+        {
+          for (int j = 0; j < vps.getMaxLayers(); j++)
+          {
+            if (m_olsOutputLayerStr[i].find(to_string(j)) != std::string::npos)
+            {
+              vps.setOlsOutputLayerFlag(i, j, 1);
+            }
+            else
+            {
+              vps.setOlsOutputLayerFlag(i, j, 0);
+            }
+          }
+        }
+      }
+    }
+  }
+#endif
 #else
   vps.setMaxLayers                                               ( 1 );
 #endif
+#if !JVET_O1159_SCALABILITY
   for(int i = 0; i < MAX_TLAYER; i++)
   {
     vps.setVPSIncludedLayerId                                    ( 0, i );
   }
+#endif
   vps.setVPSExtensionFlag                                        ( false );
   m_cEncLib.setVPS(&vps);
   m_cEncLib.setProfile                                           ( m_profile);
@@ -483,6 +579,11 @@ void EncApp::xInitLibCfg()
   }
   m_cEncLib.setLFCrossSliceBoundaryFlag                          ( m_bLFCrossSliceBoundaryFlag );
 #endif
+
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  //====== Sub-picture and Slices ========
+  m_cEncLib.setSingleSlicePerSubPicFlagFlag                      ( m_singleSlicePerSubPicFlag );
+#endif
   m_cEncLib.setUseSAO                                            ( m_bUseSAO );
   m_cEncLib.setTestSAODisableAtPictureLevel                      ( m_bTestSAODisableAtPictureLevel );
   m_cEncLib.setSaoEncodingRate                                   ( m_saoEncodingRate );
@@ -843,6 +944,9 @@ void EncApp::xInitLibCfg()
 #if JVET_O0549_ENCODER_ONLY_FILTER
   m_cEncLib.setGopBasedTemporalFilterEnabled(m_gopBasedTemporalFilterEnabled);
 #endif
+#if JVET_O1159_SCALABILITY
+  m_cEncLib.setNumRefLayers                                       ( m_numRefLayers );
+#endif
 }
 
 #if JVET_N0278_FIXES
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 530dd088b543ff463a0a64891762e9fed418c88a..3c90bde664c6c0580953828033fdf571063a7ead 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1331,6 +1331,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
                                                                                                                "\t3: max number of tiles per slice")
   ("LFCrossSliceBoundaryFlag",                        m_bLFCrossSliceBoundaryFlag,                       true)
 
+#endif
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  ("EnableSubPicPartitioning",                        m_subPicPartitionFlag,                             true, "Enable Sub-Picture partitioning (0: single slice per sub-picture, 1: multiple slices per sub-picture can be used)")
 #endif
   ("FastUDIUseMPMEnabled",                            m_bFastUDIUseMPMEnabled,                           true, "If enabled, adapt intra direction search, accounting for MPM")
   ("FastMEForGenBLowDelayEnabled",                    m_bFastMEForGenBLowDelayEnabled,                   true, "If enabled use a fast ME for generalised B Low Delay slices")
@@ -1696,6 +1699,21 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ( "UpscaledOutput",                                 m_upscaledOutput,                             0, "Output upscaled (2), decoded but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR" )
 #if JVET_N0278_FIXES
   ( "MaxLayers",                                      m_maxLayers,                                  1, "Max number of layers" )
+#if JVET_O1159_SCALABILITY
+
+  ;
+  opts.addOptions()
+  ( "MaxSublayers",                                   m_maxSublayers,                               1, "Max number of Sublayers")
+  ( "AllLayersSameNumSublayersFlag",                  m_allLayersSameNumSublayersFlag,           true, "All layers same num sublayersflag")
+  ( "AllIndependentLayersFlag",                       m_allIndependentLayersFlag,                true, "All layers are independent layer")
+  ( "LayerId%d",                                      m_layerId,                    0, MAX_VPS_LAYERS, "Max number of Sublayers")
+  ( "NumRefLayers%d",                                 m_numRefLayers,               0, MAX_VPS_LAYERS, "Number of direct reference layer index of i-th layer")
+  ( "RefLayerIdx%d",                                  m_refLayerIdxStr,    string(""), MAX_VPS_LAYERS, "Reference layer index(es)")
+  ( "EachLayerIsAnOlsFlag",                           m_eachLayerIsAnOlsFlag,                    true, "Each layer is an OLS layer flag")
+  ( "OlsModeIdc",                                     m_olsModeIdc,                                 0, "Output layer set mode")
+  ( "NumOutputLayerSets",                             m_numOutputLayerSets,                         1, "Number of output layer sets")
+  ( "OlsOutputLayer%d",                               m_olsOutputLayerStr, string(""), MAX_VPS_LAYERS, "Output layer index of i-th OLS")
+#endif
 #endif
     ;
 
@@ -1979,7 +1997,16 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   {
     m_subProfile[i] = cfg_SubProfile.values[i];
   }
-
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  if (m_subPicPartitionFlag)
+  {
+    m_singleSlicePerSubPicFlag = false;
+  }
+  else
+  {
+    m_singleSlicePerSubPicFlag = true;
+  }
+#endif
 #if !JVET_P1004_REMOVE_BRICKS
   if (m_tileUniformSpacingFlag)
   {
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 7988628f531d5ca8228404560219ffd28e994a9b..132fcb6640e7c4caeddcba5a31c5f42892aeb3e9 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -475,6 +475,10 @@ protected:
   int       m_uniformTileRowHeightMinus1;
   std::vector<int> m_tileColumnWidth;
   std::vector<int> m_tileRowHeight;
+#endif
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  bool      m_subPicPartitionFlag;
+  bool      m_singleSlicePerSubPicFlag;
 #endif
   bool      m_entropyCodingSyncEnabledFlag;
 
@@ -797,6 +801,20 @@ protected:
 
 #if JVET_N0278_FIXES
   int         m_maxLayers;
+
+#if JVET_O1159_SCALABILITY
+  int         m_layerId[MAX_VPS_LAYERS];
+  int         m_layerIdx;
+  int         m_maxSublayers;
+  bool        m_allLayersSameNumSublayersFlag;
+  bool        m_allIndependentLayersFlag;
+  int         m_numRefLayers[MAX_VPS_LAYERS];
+  std::string m_refLayerIdxStr[MAX_VPS_LAYERS];
+  bool        m_eachLayerIsAnOlsFlag;
+  int         m_olsModeIdc;
+  int         m_numOutputLayerSets;
+  std::string m_olsOutputLayerStr[MAX_VPS_LAYERS];
+#endif
 #endif
 
 #if EXTENSION_360_VIDEO
diff --git a/source/App/StreamMergeApp/StreamMergeApp.cpp b/source/App/StreamMergeApp/StreamMergeApp.cpp
index 4df1bad911969fda2a25d623bdeba36e4b3bf43a..7232956f0e82240fb7a432db098a146847842c07 100644
--- a/source/App/StreamMergeApp/StreamMergeApp.cpp
+++ b/source/App/StreamMergeApp/StreamMergeApp.cpp
@@ -279,9 +279,10 @@ uint32_t StreamMergeApp::mergeStreams()
 
   //set VPS which will be replicated for all layers but with differnt nul_layer_id
   vps.setMaxLayers(m_numInputStreams);
+#if !JVET_O1159_SCALABILITY
   for (int i = 0; i < m_numInputStreams; i++)
     vps.setVPSIncludedLayerId(i < 63 ? i : i + 1, i); //value 63 is reserved
-
+#endif
   vps.setVPSExtensionFlag(false);
 
   //Loop all input bitstreams to interleave their NALUs
diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index 0d09788b030a6117cade9d6288d73f0e7b031976..b18a1540b9fbbc1a3b86fc4645376ab77e3ed163 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -173,8 +173,15 @@ static const int MAX_NESTING_NUM_OPS =                           1024;
 static const int MAX_NESTING_NUM_LAYER =                           64;
 
 static const int MAX_VPS_NUM_HRD_PARAMETERS =                       1;
+#if JVET_O1159_SCALABILITY
+static const int MAX_VPS_LAYERS =                                  64;
+static const int MAX_VPS_SUBLAYERS =                                7;
+static const int MAX_NUM_REF_LAYERS =                               7;
+static const int MAX_NUM_OLSS =                                   256;
+static const int MAX_VPS_OLS_MODE_IDC =                             2;
+#else
 static const int MAX_VPS_LAYERS =                                 256;
-
+#endif
 static const int MAXIMUM_INTRA_FILTERED_WIDTH =                    16;
 static const int MAXIMUM_INTRA_FILTERED_HEIGHT =                   16;
 
diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index ce55a63dfb9a7ab6c45587d85c562916353f5000..3359acfcb199cbf5a50545c9b7a1b6c24dbb3a0b 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -315,7 +315,7 @@ void InterPrediction::xSubPuMC( PredictionUnit& pu, PelUnitBuf& predBuf, const R
   int  fstStep = (!verMC ? puHeight : puWidth);
   int  secStep = (!verMC ? puWidth : puHeight);
 
-#if JVET_P0590_SCALING_WINDOW
+#if JVET_P0590_SCALING_WINDOW || JVET_O1159_SCALABILITY
   bool scaled = pu.cu->slice->getScalingRatio( REF_PIC_LIST_0, 0 ) != SCALE_1X || ( pu.cs->slice->getSliceType() == B_SLICE ? pu.cu->slice->getScalingRatio( REF_PIC_LIST_1, 0 ) != SCALE_1X : false );
 #else
   pu.refIdx[0] = 0; pu.refIdx[1] = pu.cs->slice->getSliceType() == B_SLICE ? 0 : -1;
@@ -1942,7 +1942,7 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
       }
     }
 
-#if JVET_P0590_SCALING_WINDOW
+#if JVET_P0590_SCALING_WINDOW || JVET_O1159_SCALABILITY
     bioApplied = ( ( refIdx0 < 0 ? true : pu.cu->slice->getScalingRatio( REF_PIC_LIST_0, refIdx0 ) == SCALE_1X ) && ( refIdx1 < 0 ? true : pu.cu->slice->getScalingRatio( REF_PIC_LIST_1, refIdx1 ) == SCALE_1X ) ) ? bioApplied : false;
 #else
     bioApplied = PU::isRefPicSameSize( pu ) ? bioApplied : false;
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index 41d7de20e10b20c854550ddf8d249a22144fc96b..06c75687b3d12704ab7b0f2e9fa2f35d0c87041f 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -688,7 +688,11 @@ const CPelUnitBuf Picture::getRecoBuf(const UnitArea &unit, bool wrap)     const
 const CPelUnitBuf Picture::getRecoBuf(bool wrap)                           const { return M_BUFS(scheduler.getSplitPicId(), wrap ? PIC_RECON_WRAP : PIC_RECONSTRUCTION); }
 
 #if JVET_P1006_PICTURE_HEADER
+#if JVET_O1159_SCALABILITY
+void Picture::finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHeader *picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps )
+#else
 void Picture::finalInit( const SPS& sps, const PPS& pps, PicHeader* picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps )
+#endif
 #else
 void Picture::finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS* lmcsAps, APS* scalingListAps )
 #endif
@@ -724,6 +728,9 @@ void Picture::finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS* lmc
     cs->create(chromaFormatIDC, Area(0, 0, iWidth, iHeight), true, (bool)sps.getPLTMode());
   }
 
+#if JVET_O1159_SCALABILITY
+  cs->vps = vps;
+#endif
   cs->picture = this;
   cs->slice   = nullptr;  // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
   cs->pps     = &pps;
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index a257ea5803b6ab04f423eb754c73513a4656447b..4505f3b7a67a5e9a91467a175f00f49ee6b13a38 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -219,7 +219,11 @@ struct Picture : public UnitArea
 
   void extendPicBorder();
 #if JVET_P1006_PICTURE_HEADER
+#if JVET_O1159_SCALABILITY
+  void finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHeader *picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps );
+#else
   void finalInit( const SPS& sps, const PPS& pps, PicHeader *picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps );
+#endif
 #else
   void finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS* lmcsAps, APS* scalingListAps );
 #endif
diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp
index c0ac199862a7bebdb34658b00bf8feb0430805a1..85959f02e67df5fe79cc1f29fc0261480346ba39 100644
--- a/source/Lib/CommonLib/SEI.cpp
+++ b/source/Lib/CommonLib/SEI.cpp
@@ -113,7 +113,11 @@ void SEIBufferingPeriod::copyTo (SEIBufferingPeriod& target) const
   ::memcpy(target.m_initialCpbRemovalDelay, m_initialCpbRemovalDelay, sizeof(m_initialCpbRemovalDelay));
   ::memcpy(target.m_initialCpbRemovalOffset, m_initialCpbRemovalOffset, sizeof(m_initialCpbRemovalOffset));
   ::memcpy(target.m_cpbRemovalDelayDelta, m_cpbRemovalDelayDelta, sizeof(m_cpbRemovalDelayDelta));
+#if !JVET_P0446_BP_CPB_CNT_FIX
   ::memcpy(target.m_bpCpbCnt, m_bpCpbCnt, sizeof(m_bpCpbCnt));
+#else
+  target.m_bpCpbCnt = m_bpCpbCnt;
+#endif
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI
   target.m_bpDecodingUnitHrdParamsPresentFlag = m_bpDecodingUnitHrdParamsPresentFlag;
   target.m_decodingUnitCpbParamsInPicTimingSeiFlag = m_decodingUnitCpbParamsInPicTimingSeiFlag;
@@ -121,6 +125,13 @@ void SEIBufferingPeriod::copyTo (SEIBufferingPeriod& target) const
 #if JVET_P0181
   target.m_sublayerInitialCpbRemovalDelayPresentFlag = m_sublayerInitialCpbRemovalDelayPresentFlag;
 #endif
+#if JVET_P0446_CONCATENATION
+  target.m_concatenationFlag = m_concatenationFlag;
+  target.m_maxInitialRemovalDelayForConcatenation = m_maxInitialRemovalDelayForConcatenation;
+#endif
+#if JVET_P0446_ALT_CPB
+  target.m_altCpbParamsPresentFlag = m_altCpbParamsPresentFlag;
+#endif
 }
 
 void SEIPictureTiming::copyTo (SEIPictureTiming& target) const
@@ -147,6 +158,13 @@ void SEIPictureTiming::copyTo (SEIPictureTiming& target) const
 
   target.m_numNalusInDuMinus1 = m_numNalusInDuMinus1;
   target.m_duCpbRemovalDelayMinus1 = m_duCpbRemovalDelayMinus1;
+#if JVET_P0446_ALT_CPB
+  target.m_cpbAltTimingInfoPresentFlag = m_cpbAltTimingInfoPresentFlag;
+  target.m_cpbAltInitialCpbRemovalDelayDelta = m_cpbAltInitialCpbRemovalDelayDelta;
+  target.m_cpbAltInitialCpbRemovalOffsetDelta = m_cpbAltInitialCpbRemovalOffsetDelta;
+  target.m_cpbDelayOffset = m_cpbDelayOffset;
+  target.m_dpbDelayOffset = m_dpbDelayOffset;
+#endif
 }
 
 // Static member
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index 331abd94bcac82da0bb869fef2e9bcaae3309996..6bb76936944967ac366652eef1edc90a4c5dc9dc 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -321,6 +321,9 @@ public:
   , m_initialCpbRemovalDelayLength (0)
   , m_cpbRemovalDelayLength (0)
   , m_dpbOutputDelayLength (0)
+#if JVET_P0446_BP_CPB_CNT_FIX
+  , m_bpCpbCnt(0)
+#endif
   , m_duCpbRemovalDelayIncrementLength (0)
   , m_dpbOutputDelayDuLength (0)
   , m_cpbRemovalDelayDeltasPresentFlag (false)
@@ -332,12 +335,22 @@ public:
 #endif
 #if JVET_P0181
     , m_sublayerInitialCpbRemovalDelayPresentFlag(false)
+#endif
+#if JVET_P0446_CONCATENATION
+    , m_additionalConcatenationInfoPresentFlag (false)
+    , m_maxInitialRemovalDelayForConcatenation (0)
+#endif
+#if JVET_P0446_ALT_CPB
+    , m_altCpbParamsPresentFlag (false)
+    , m_useAltCpbParamsFlag (false)
 #endif
   {
     ::memset(m_initialCpbRemovalDelay, 0, sizeof(m_initialCpbRemovalDelay));
     ::memset(m_initialCpbRemovalOffset, 0, sizeof(m_initialCpbRemovalOffset));
     ::memset(m_cpbRemovalDelayDelta, 0, sizeof(m_cpbRemovalDelayDelta));
+#if !JVET_P0446_BP_CPB_CNT_FIX
     ::memset(m_bpCpbCnt, 0, sizeof(m_bpCpbCnt));
+#endif
   }
   virtual ~SEIBufferingPeriod() {}
 
@@ -350,7 +363,11 @@ public:
   uint32_t m_initialCpbRemovalDelayLength;
   uint32_t m_cpbRemovalDelayLength;
   uint32_t m_dpbOutputDelayLength;
+#if !JVET_P0446_BP_CPB_CNT_FIX
   int      m_bpCpbCnt[MAX_TLAYER];
+#else
+  int      m_bpCpbCnt;
+#endif
   uint32_t m_duCpbRemovalDelayIncrementLength;
   uint32_t m_dpbOutputDelayDuLength;
   uint32_t m_initialCpbRemovalDelay         [MAX_TLAYER][MAX_CPB_CNT][2];
@@ -368,6 +385,14 @@ public:
 #if JVET_P0181
   bool m_sublayerInitialCpbRemovalDelayPresentFlag;
 #endif
+#if JVET_P0446_CONCATENATION
+  bool     m_additionalConcatenationInfoPresentFlag;
+  uint32_t m_maxInitialRemovalDelayForConcatenation;
+#endif
+#if JVET_P0446_ALT_CPB
+  bool     m_altCpbParamsPresentFlag;
+  bool     m_useAltCpbParamsFlag;
+#endif
 };
 
 class SEIPictureTiming : public SEI
@@ -382,6 +407,11 @@ public:
   , m_picDpbOutputDuDelay (0)
   , m_numDecodingUnitsMinus1 (0)
   , m_duCommonCpbRemovalDelayFlag (false)
+#if JVET_P0446_ALT_CPB
+  , m_cpbAltTimingInfoPresentFlag (false)
+  , m_cpbDelayOffset (0)
+  , m_dpbDelayOffset (0)
+#endif
   {
     ::memset(m_ptSubLayerDelaysPresentFlag, 0, sizeof(m_ptSubLayerDelaysPresentFlag));
     ::memset(m_duCommonCpbRemovalDelayMinus1, 0, sizeof(m_duCommonCpbRemovalDelayMinus1));
@@ -397,6 +427,11 @@ public:
   , m_numDecodingUnitsMinus1 (0)
   , m_duCommonCpbRemovalDelayFlag (false)
   , m_duCommonCpbRemovalDelayMinus1 (0)
+#if JVET_P0446_ALT_CPB
+    , m_cpbAltTimingInfoPresentFlag (false)
+    , m_cpbDelayOffset (0)
+    , m_dpbDelayOffset (0)
+#endif
   {
     ::memset(m_subLayerDelaysPresentFlag, 0, sizeof(m_subLayerDelaysPresentFlag));
     ::memset(m_cpbRemovalDelayDeltaEnabledFlag, 0, sizeof(m_cpbRemovalDelayDeltaEnabledFlag));
@@ -435,6 +470,13 @@ public:
   std::vector<uint32_t> m_numNalusInDuMinus1;
   std::vector<uint32_t> m_duCpbRemovalDelayMinus1;
 #endif
+#if JVET_P0446_ALT_CPB
+  bool     m_cpbAltTimingInfoPresentFlag;
+  std::vector<uint32_t> m_cpbAltInitialCpbRemovalDelayDelta;
+  std::vector<uint32_t> m_cpbAltInitialCpbRemovalOffsetDelta;
+  uint32_t m_cpbDelayOffset;
+  uint32_t m_dpbDelayOffset;
+#endif
 };
 
 class SEIDecodingUnitInfo : public SEI
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index b29dde17b0a1383cf880af3e7cc83ee278407d3f..7dccc3b23c4f745371add4ce66ff41721c28fa30 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -497,8 +497,24 @@ void Slice::constructRefPicList(PicList& rcListPic)
   uint32_t numOfActiveRef = 0;
   //construct L0
   numOfActiveRef = getNumRefIdx(REF_PIC_LIST_0);
+#if JVET_O1159_SCALABILITY
+  int layerIdx = m_pcPic->cs->vps == nullptr ? 0 : m_pcPic->cs->vps->getGeneralLayerIdx( m_pcPic->layerId );
+#endif
+
   for (int ii = 0; ii < numOfActiveRef; ii++)
   {
+#if JVET_O1159_SCALABILITY
+    if( m_pRPL0->isInterLayerRefPic( ii ) )
+    {
+      CHECK( m_pRPL0->getInterLayerRefPicIdx( ii ) == NOT_VALID, "Wrong ILRP index" );
+
+      int refLayerIdx = m_pcPic->cs->vps->getDirectRefLayerIdx( layerIdx, m_pRPL0->getInterLayerRefPicIdx( ii ) );
+
+      pcRefPic = xGetRefPic( rcListPic, getPOC(), refLayerIdx );
+      pcRefPic->longTerm = true;
+    }
+    else
+#endif
     if (!m_pRPL0->isRefPicLongterm(ii))
     {
 #if JVET_N0278_FIXES
@@ -530,6 +546,18 @@ void Slice::constructRefPicList(PicList& rcListPic)
   numOfActiveRef = getNumRefIdx(REF_PIC_LIST_1);
   for (int ii = 0; ii < numOfActiveRef; ii++)
   {
+#if JVET_O1159_SCALABILITY
+    if( m_pRPL1->isInterLayerRefPic( ii ) )
+    {
+      CHECK( m_pRPL1->getInterLayerRefPicIdx( ii ) == NOT_VALID, "Wrong ILRP index" );
+
+      int refLayerIdx = m_pcPic->cs->vps->getDirectRefLayerIdx( layerIdx, m_pRPL1->getInterLayerRefPicIdx( ii ) );
+
+      pcRefPic = xGetRefPic( rcListPic, getPOC(), refLayerIdx );
+      pcRefPic->longTerm = true;
+    }
+    else
+#endif
     if (!m_pRPL1->isRefPicLongterm(ii))
     {
 #if JVET_N0278_FIXES
@@ -623,7 +651,11 @@ void Slice::checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureLi
       {
         CHECK(getPOC() - pRPL1->getRefPicIdentifier(i) < pocCRA, "Invalid state");
       }
+#if JVET_O1159_SCALABILITY
+      else if( !pRPL1->isInterLayerRefPic( i ) )
+#else
       else
+#endif
       {
 #if JVET_N0278_FIXES
         CHECK( xGetLongTermRefPic( rcListPic, pRPL1->getRefPicIdentifier( i ), pRPL1->getDeltaPocMSBPresentFlag( i ), m_pcPic->layerId )->getPOC() < pocCRA, "Invalid state" );
@@ -1148,7 +1180,11 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic) const
 
 
 //Function for applying picture marking based on the Reference Picture List
+#if JVET_O1159_SCALABILITY
+void Slice::applyReferencePictureListBasedMarking( PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1, const int layerId ) const
+#else
 void Slice::applyReferencePictureListBasedMarking(PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1) const
+#endif
 {
   int i, isReference;
   checkLeadingPictureRestrictions(rcListPic);
@@ -1167,8 +1203,26 @@ void Slice::applyReferencePictureListBasedMarking(PicList& rcListPic, const Refe
     isReference = 0;
     // loop through all pictures in the Reference Picture Set
     // to see if the picture should be kept as reference picture
-    for (i = 0; isNeedToCheck && !isReference && i<pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures(); i++)
+#if JVET_O1159_SCALABILITY
+    for( i = 0; isNeedToCheck && !isReference && i < pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(); i++ )
+    {
+      if( pRPL0->isInterLayerRefPic( i ) )
+      {
+        // Diagonal inter-layer prediction is not allowed
+        CHECK( pRPL0->getRefPicIdentifier( i ), "ILRP identifier should be 0" );
+
+        if( pcPic->poc == m_iPOC )
+        {
+          isReference = 1;
+          pcPic->longTerm = true;
+        }
+      }
+      else if (pcPic->layerId == layerId)
+      {
+#else
+    for (i = 0; isNeedToCheck && !isReference && i < pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures(); i++)
     {
+#endif
       if (!(pRPL0->isRefPicLongterm(i)))
       {
         if (pcPic->poc == this->getPOC() - pRPL0->getRefPicIdentifier(i))
@@ -1187,9 +1241,31 @@ void Slice::applyReferencePictureListBasedMarking(PicList& rcListPic, const Refe
           pcPic->longTerm = true;
         }
       }
+#if JVET_O1159_SCALABILITY
+      }
+#endif
     }
+
+#if JVET_O1159_SCALABILITY
+    for( i = 0; isNeedToCheck && !isReference && i < pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures(); i++ )
+    {
+      if( pRPL1->isInterLayerRefPic( i ) )
+      {
+        // Diagonal inter-layer prediction is not allowed
+        CHECK( pRPL1->getRefPicIdentifier( i ), "ILRP identifier should be 0" );
+
+        if( pcPic->poc == m_iPOC )
+        {
+          isReference = 1;
+          pcPic->longTerm = true;
+        }
+      }
+      else if( pcPic->layerId == layerId )
+      {
+#else
     for (i = 0; isNeedToCheck && !isReference && i<pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures(); i++)
     {
+#endif
       if (!(pRPL1->isRefPicLongterm(i)))
       {
         if (pcPic->poc == this->getPOC() - pRPL1->getRefPicIdentifier(i))
@@ -1208,10 +1284,17 @@ void Slice::applyReferencePictureListBasedMarking(PicList& rcListPic, const Refe
           pcPic->longTerm = true;
         }
       }
+#if JVET_O1159_SCALABILITY
+      }
+#endif
     }
     // mark the picture as "unused for reference" if it is not in
     // the Reference Picture List
+#if JVET_O1159_SCALABILITY
+    if( pcPic->layerId == layerId && pcPic->poc != m_iPOC && isReference == 0 )
+#else
     if (pcPic->poc != this->getPOC() && isReference == 0)
+#endif
     {
       pcPic->referenced = false;
       pcPic->longTerm = false;
@@ -1234,12 +1317,23 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
 
   if (this->isIDRorBLA()) return 0; //Assume that all pic in the DPB will be flushed anyway so no need to check.
 
+#if JVET_O1159_SCALABILITY
+  int numberOfPictures = pRPL->getNumberOfLongtermPictures() + pRPL->getNumberOfShorttermPictures() + pRPL->getNumberOfInterLayerPictures();
+#else
   int numberOfPictures = pRPL->getNumberOfLongtermPictures() + pRPL->getNumberOfShorttermPictures();
+#endif
   //Check long term ref pics
   for (int ii = 0; pRPL->getNumberOfLongtermPictures() > 0 && ii < numberOfPictures; ii++)
   {
+#if JVET_O1159_SCALABILITY
+    if( !pRPL->isRefPicLongterm( ii ) || pRPL->isInterLayerRefPic( ii ) )
+    {
+      continue;
+    }
+#else
     if (!pRPL->isRefPicLongterm(ii))
       continue;
+#endif
 
     notPresentPoc = pRPL->getRefPicIdentifier(ii);
     isAvailable = 0;
@@ -1326,12 +1420,23 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
 
   if (this->isIDRorBLA()) return 0; //Assume that all pic in the DPB will be flushed anyway so no need to check.
 
+#if JVET_O1159_SCALABILITY
+  int numberOfPictures = pRPL->getNumberOfLongtermPictures() + pRPL->getNumberOfShorttermPictures() + pRPL->getNumberOfInterLayerPictures();
+#else
   int numberOfPictures = pRPL->getNumberOfLongtermPictures() + pRPL->getNumberOfShorttermPictures();
+#endif
   //Check long term ref pics
   for (int ii = 0; pRPL->getNumberOfLongtermPictures() > 0 && ii < numberOfPictures; ii++)
   {
+#if JVET_O1159_SCALABILITY
+    if( !pRPL->isRefPicLongterm( ii ) || pRPL->isInterLayerRefPic( ii ) )
+    {
+      continue;
+    }
+#else
     if (!pRPL->isRefPicLongterm(ii))
       continue;
+#endif
 
     notPresentPoc = pRPL->getRefPicIdentifier(ii);
     isAvailable = 0;
@@ -1413,8 +1518,24 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
 
 bool Slice::isPOCInRefPicList(const ReferencePictureList *rpl, int poc )
 {
+#if JVET_O1159_SCALABILITY
+  for( int i = 0; i < rpl->getNumberOfLongtermPictures() + rpl->getNumberOfShorttermPictures() + rpl->getNumberOfInterLayerPictures(); i++ )
+  {
+    if( rpl->isInterLayerRefPic( i ) )
+    {
+      // Diagonal inter-layer prediction is not allowed
+      CHECK( rpl->getRefPicIdentifier( i ), "ILRP identifier should be 0" );
+
+      if( poc == m_iPOC )
+      {
+        return true;
+      }
+    }
+    else
+#else
   for (int i = 0; i < rpl->getNumberOfLongtermPictures() + rpl->getNumberOfShorttermPictures(); i++)
   {
+#endif
     if (rpl->isRefPicLongterm(i))
     {
       if (poc == rpl->getRefPicIdentifier(i))
@@ -1504,6 +1625,7 @@ void Slice::checkConformanceForDRAP( uint32_t temporalId )
   }
 }
 
+#if !JVET_O1159_SCALABILITY
 void Slice::createExplicitReferencePictureSetFromReference(PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1)
 {
   Picture* rpcPic;
@@ -1678,6 +1800,7 @@ void Slice::createExplicitReferencePictureSetFromReference(PicList& rcListPic, c
   this->setRPL1idx(-1);
   this->setRPL1(pLocalRPL1);
 }
+#endif
 
 //! get AC and DC values for weighted pred
 void  Slice::getWpAcDcParam(const WPACDCParam *&wp) const
@@ -1795,12 +1918,43 @@ unsigned Slice::getMinPictureDistance() const
 VPS::VPS()
   : m_VPSId(0)
   , m_uiMaxLayers(1)
-  , m_vpsExtensionFlag()
+#if JVET_P0185
+  , m_vpsMaxSubLayers(1)
+#endif
+#if JVET_O1159_SCALABILITY
+  , m_vpsAllLayersSameNumSubLayersFlag (true)
+  , m_vpsAllIndependentLayersFlag(true)
+  , m_vpsEachLayerIsAnOlsFlag (1)
+  , m_vpsOlsModeIdc (0)
+  , m_vpsNumOutputLayerSets (1)
+#endif
+, m_vpsExtensionFlag()
 {
+#if JVET_O1159_SCALABILITY
+  for (int i = 0; i < MAX_VPS_LAYERS; i++)
+  {
+    m_vpsLayerId[i] = 0;
+    m_vpsIndependentLayerFlag[i] = 1;
+    for (int j = 0; j < MAX_VPS_LAYERS; j++)
+    {
+      m_vpsDirectRefLayerFlag[i][j] = 0;
+      m_directRefLayerIdx[i][j] = MAX_VPS_LAYERS;
+      m_interLayerRefIdx[i][i] = NOT_VALID;
+    }
+  }
+  for (int i = 0; i < MAX_NUM_OLSS; i++)
+  {
+    for (int j = 0; j < MAX_VPS_LAYERS; j++)
+    {
+      m_vpsOlsOutputLayerFlag[i][j] = 0;
+    }
+  }
+#else
   for (int i = 0; i < MAX_VPS_LAYERS; i++)
   {
     m_vpsIncludedLayerId[i] = 0;
   }
+#endif
 }
 
 VPS::~VPS()
@@ -1886,11 +2040,17 @@ PicHeader::PicHeader()
   m_localRPL0.setNumberOfShorttermPictures(0);
   m_localRPL0.setNumberOfLongtermPictures(0);
   m_localRPL0.setLtrpInSliceHeaderFlag(0);
+#if JVET_O1159_SCALABILITY
+  m_localRPL0.setNumberOfInterLayerPictures( 0 );
+#endif
 
   m_localRPL1.setNumberOfActivePictures(0);
   m_localRPL1.setNumberOfShorttermPictures(0);
   m_localRPL1.setNumberOfLongtermPictures(0);
   m_localRPL1.setLtrpInSliceHeaderFlag(0);
+#if JVET_O1159_SCALABILITY
+  m_localRPL1.setNumberOfInterLayerPictures( 0 );
+#endif
 
   m_alfApsId.resize(0);
 }
@@ -2344,6 +2504,9 @@ PPS::PPS()
 , m_numTileCols                      (1)
 , m_numTileRows                      (1)
 , m_rectSliceFlag                    (1)  
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  , m_singleSlicePerSubPicFlag       (0)
+#endif
 , m_numSlicesInPic                   (1)
 , m_tileIdxDeltaPresentFlag          (0)
 , m_loopFilterAcrossTilesEnabledFlag (1)
@@ -2418,6 +2581,9 @@ PPS::PPS()
   m_tileRowBd.clear();
   m_ctuToTileCol.clear();
   m_ctuToTileRow.clear();
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  m_ctuToSubPicIdx.clear();
+#endif
   m_rectSlices.clear();
   m_sliceMap.clear();
 #endif
@@ -2432,6 +2598,9 @@ PPS::~PPS()
   m_tileRowBd.clear();
   m_ctuToTileCol.clear();
   m_ctuToTileRow.clear();
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  m_ctuToSubPicIdx.clear();
+#endif
   m_rectSlices.clear();
   m_sliceMap.clear();
 
@@ -2456,6 +2625,9 @@ void PPS::resetTileSliceInfo()
   m_tileRowBd.clear();
   m_ctuToTileCol.clear();
   m_ctuToTileRow.clear();
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  m_ctuToSubPicIdx.clear();
+#endif
   m_rectSlices.clear();
   m_sliceMap.clear();
 }
@@ -2565,7 +2737,24 @@ void PPS::initRectSliceMap()
   // allocate new memory for slice list
   CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
   m_sliceMap.resize( m_numSlicesInPic );
-
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  if ((getNumSubPics() > 0) && getSingleSlicePerSubPicFlag())
+  {
+    for (uint32_t i = 0; i <= getNumSubPics() - 1; i++)
+    {
+      m_sliceMap[i].initSliceMap();
+    }
+    uint32_t picSizeInCtu = getPicWidthInCtu() * getPicHeightInCtu();
+    uint32_t sliceIdx;
+    for (uint32_t i = 0; i < picSizeInCtu; i++)
+    {
+      sliceIdx = getCtuToSubPicIdx(i);
+      m_sliceMap[sliceIdx].pushToCtuAddrInSlice(i);
+    }
+  }
+  else
+  {
+#endif
   // generate CTU maps for all rectangular slices in picture
   for( uint32_t i = 0; i < m_numSlicesInPic; i++ )
   {
@@ -2620,7 +2809,9 @@ void PPS::initRectSliceMap()
                                       ctuY, getTileRowBd( tileY + 1 ), m_picWidthInCtu);
     } 
   }
-
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  }
+#endif
   // check for valid rectangular slice map
   checkSliceMap();
 }
@@ -2693,29 +2884,49 @@ APS::~APS()
 {
 }
 
-
+#if JVET_O1159_SCALABILITY
+ReferencePictureList::ReferencePictureList( const bool interLayerPicPresentFlag )
+#else
 ReferencePictureList::ReferencePictureList()
+#endif
   : m_numberOfShorttermPictures(0)
   , m_numberOfLongtermPictures(0)
   , m_numberOfActivePictures(MAX_INT)
   , m_ltrp_in_slice_header_flag(0)
+#if JVET_O1159_SCALABILITY
+  , m_interLayerPresentFlag( interLayerPicPresentFlag )
+  , m_numberOfInterLayerPictures( 0 )
+#endif
 {
   ::memset(m_isLongtermRefPic, 0, sizeof(m_isLongtermRefPic));
   ::memset(m_refPicIdentifier, 0, sizeof(m_refPicIdentifier));
   ::memset(m_POC, 0, sizeof(m_POC));
+#if JVET_O1159_SCALABILITY
+  ::memset( m_isInterLayerRefPic, 0, sizeof( m_isInterLayerRefPic ) );
+  ::memset( m_interLayerRefPicIdx, 0, sizeof( m_interLayerRefPicIdx ) );
+#endif
 }
 
 ReferencePictureList::~ReferencePictureList()
 {
 }
 
+#if JVET_O1159_SCALABILITY
+void ReferencePictureList::setRefPicIdentifier( int idx, int identifier, bool isLongterm, bool isInterLayerRefPic, int interLayerIdx )
+#else
 void ReferencePictureList::setRefPicIdentifier(int idx, int identifier, bool isLongterm)
+#endif
 {
   m_refPicIdentifier[idx] = identifier;
   m_isLongtermRefPic[idx] = isLongterm;
 
   m_deltaPocMSBPresentFlag[idx] = false;
   m_deltaPOCMSBCycleLT[idx] = 0;
+
+#if JVET_O1159_SCALABILITY
+  m_isInterLayerRefPic[idx] = isInterLayerRefPic;
+  m_interLayerRefPicIdx[idx] = interLayerIdx;
+#endif
 }
 
 int ReferencePictureList::getRefPicIdentifier(int idx) const
@@ -3500,9 +3711,16 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
         }
         else
         {
+#if JVET_P0185
+          m_vpsMap.clear();
+          m_vpsMap.allocatePS(0);
+          m_activeVPSId = 0;
+          m_vpsMap.setActive(0);
+#else
           //No actual VPS
           m_activeVPSId = -1;
           m_vpsMap.clear();
+#endif
         }
 #endif
 
@@ -3562,6 +3780,14 @@ void ParameterSetMap<SPS>::setID(SPS* parameterSet, const int psId)
   parameterSet->setSPSId(psId);
 }
 
+#if JVET_P0185
+template <>
+void ParameterSetMap<VPS>::setID(VPS* parameterSet, const int psId)
+{
+  parameterSet->setVPSId(psId);
+}
+#endif
+
 ProfileTierLevel::ProfileTierLevel()
   : m_tierFlag        (Level::MAIN)
   , m_profileIdc      (Profile::NONE)
@@ -3764,7 +3990,11 @@ void Slice::scaleRefPicList( Picture *scaledRefPic[ ], APS** apss, APS* lmcsAps,
             scaledRefPic[j]->referenced = true;
 
 #if JVET_P1006_PICTURE_HEADER
-            scaledRefPic[ j ]->finalInit( *sps, *pps, picHeader, apss, lmcsAps, scalingListAps );
+#if JVET_O1159_SCALABILITY
+            scaledRefPic[j]->finalInit( m_pcPic->cs->vps, *sps, *pps, picHeader, apss, lmcsAps, scalingListAps );
+#else
+            scaledRefPic[j]->finalInit( *sps, *pps, picHeader, apss, lmcsAps, scalingListAps );
+#endif
 #else
             scaledRefPic[ j ]->finalInit( *sps, *pps, apss, lmcsAps, scalingListAps );
 #endif
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 76ba94a57a03215bc2ed51e952a163e51f1d639f..a6f28708edc9c4f03c6707923a9c6bc5bb29df06 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -84,12 +84,26 @@ private:
   bool  m_deltaPocMSBPresentFlag[MAX_NUM_REF_PICS];
   int   m_deltaPOCMSBCycleLT[MAX_NUM_REF_PICS];
   bool  m_ltrp_in_slice_header_flag;
+#if JVET_O1159_SCALABILITY
+  bool  m_interLayerPresentFlag;
+  bool  m_isInterLayerRefPic[MAX_NUM_REF_PICS];
+  int   m_interLayerRefPicIdx[MAX_NUM_REF_PICS];
+  int   m_numberOfInterLayerPictures;
+#endif
 
 public:
+#if JVET_O1159_SCALABILITY
+  ReferencePictureList( const bool interLayerPicPresentFlag = false );
+#else
   ReferencePictureList();
+#endif
   virtual ~ReferencePictureList();
 
+#if JVET_O1159_SCALABILITY
+  void    setRefPicIdentifier( int idx, int identifier, bool isLongterm, bool isInterLayerRefPic, int interLayerIdx );
+#else
   void    setRefPicIdentifier(int idx, int identifier, bool isLongterm);
+#endif
   int     getRefPicIdentifier(int idx) const;
   bool    isRefPicLongterm(int idx) const;
 
@@ -102,7 +116,14 @@ public:
   void    setLtrpInSliceHeaderFlag(bool flag) { m_ltrp_in_slice_header_flag = flag; }
   bool    getLtrpInSliceHeaderFlag() const { return m_ltrp_in_slice_header_flag; }
 
+#if JVET_O1159_SCALABILITY
+  void    setNumberOfInterLayerPictures( const int numberOfIlrp ) { m_numberOfInterLayerPictures = numberOfIlrp; }
+  int     getNumberOfInterLayerPictures() const { return m_numberOfInterLayerPictures; }
+
+  int     getNumRefEntries() const { return m_numberOfShorttermPictures + m_numberOfLongtermPictures + m_numberOfInterLayerPictures; }
+#else
   int     getNumRefEntries() const { return m_numberOfShorttermPictures + m_numberOfLongtermPictures; }
+#endif
 
   void    setPOC(int idx, int POC);
   int     getPOC(int idx) const;
@@ -116,6 +137,14 @@ public:
   void    setDeltaPocMSBPresentFlag(int i, bool x) { m_deltaPocMSBPresentFlag[i] = x; }
 
   void    printRefPicInfo() const;
+
+#if JVET_O1159_SCALABILITY
+  bool      getInterLayerPresentFlag()                   const { return m_interLayerPresentFlag; }
+  void      setInterLayerPresentFlag( bool b )                 { m_interLayerPresentFlag = b; }
+  bool      isInterLayerRefPic( int idx )                const { return m_isInterLayerRefPic[idx]; }
+  int       getInterLayerRefPicIdx( int idx )            const { return m_interLayerRefPicIdx[idx]; }
+  void      setInterLayerRefPicIdx( int idx, int layerIdc )    { m_interLayerRefPicIdx[idx] = layerIdc; }
+#endif
 };
 
 /// Reference Picture List set class
@@ -452,7 +481,11 @@ class ProfileTierLevel
 
   ConstraintInfo    m_constraintInfo;
   bool              m_subLayerLevelPresentFlag[MAX_TLAYER - 1];
+#if JVET_P0217_PTL_SYNTAX_CLEANUP
+  Level::Name       m_subLayerLevelIdc[MAX_TLAYER];
+#else
   Level::Name       m_subLayerLevelIdc[MAX_TLAYER - 1];
+#endif
 
 public:
                 ProfileTierLevel();
@@ -655,6 +688,9 @@ public:
   uint32_t               getNumCtuInSlice() const             { return m_numCtuInSlice;   }
   std::vector<uint32_t>  getCtuAddrList( ) const              { return m_ctuAddrInSlice;  }
   uint32_t               getCtuAddrInSlice( int idx ) const   { CHECK(idx >= m_ctuAddrInSlice.size(), "CTU index exceeds number of CTUs in slice."); return m_ctuAddrInSlice[idx]; }
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  void                   pushToCtuAddrInSlice( uint32_t u )   { m_ctuAddrInSlice.push_back(u); m_numCtuInSlice++;}
+#endif
 
   void  initSliceMap() 
   {
@@ -747,7 +783,27 @@ private:
   int                   m_VPSId;
   uint32_t              m_uiMaxLayers;
 
+#if JVET_P0185
+  uint32_t              m_vpsMaxSubLayers;
+#endif
+#if JVET_O1159_SCALABILITY
+  uint32_t              m_vpsLayerId[MAX_VPS_LAYERS];
+  bool                  m_vpsAllLayersSameNumSubLayersFlag;
+  bool                  m_vpsAllIndependentLayersFlag;
+  bool                  m_vpsIndependentLayerFlag[MAX_VPS_LAYERS];
+  bool                  m_vpsDirectRefLayerFlag[MAX_VPS_LAYERS][MAX_VPS_LAYERS];
+  bool                  m_vpsEachLayerIsAnOlsFlag;
+  uint32_t              m_vpsOlsModeIdc;
+  uint32_t              m_vpsNumOutputLayerSets;
+  bool                  m_vpsOlsOutputLayerFlag[MAX_NUM_OLSS][MAX_VPS_LAYERS];
+  uint32_t              m_directRefLayerIdx[MAX_VPS_LAYERS][MAX_VPS_LAYERS];
+  uint32_t              m_generalLayerIdx[MAX_VPS_LAYERS];
+
+  // stores index ( ilrp_idx within 0 .. NumDirectRefLayers ) of the dependent reference layers 
+  uint32_t              m_interLayerRefIdx[MAX_VPS_LAYERS][MAX_VPS_LAYERS];
+#else
   uint32_t              m_vpsIncludedLayerId[MAX_VPS_LAYERS];
+#endif
   bool                  m_vpsExtensionFlag;
 
 public:
@@ -761,11 +817,54 @@ public:
   uint32_t          getMaxLayers() const                                 { return m_uiMaxLayers;                                            }
   void              setMaxLayers(uint32_t l)                             { m_uiMaxLayers = l;                                               }
 
+#if JVET_P0185
+  uint32_t          getMaxSubLayers() const                              { return m_vpsMaxSubLayers;                                        }
+  void              setMaxSubLayers(uint32_t value)                      { m_vpsMaxSubLayers = value;                                       }
+#endif
+#if JVET_O1159_SCALABILITY
+  bool              getAllLayersSameNumSublayersFlag() const { return m_vpsAllLayersSameNumSubLayersFlag; }
+  void              setAllLayersSameNumSublayersFlag(bool t) { m_vpsAllLayersSameNumSubLayersFlag = t; }
+
+  uint32_t          getLayerId(uint32_t layerIdx) const { return m_vpsLayerId[layerIdx]; }
+  void              setLayerId(uint32_t layerIdx, uint32_t layerId) { m_vpsLayerId[layerIdx] = layerId; }
+
+  bool              getAllIndependentLayersFlag() const { return m_vpsAllIndependentLayersFlag; }
+  void              setAllIndependentLayersFlag(bool t) { m_vpsAllIndependentLayersFlag = t; }
+
+  bool              getIndependentLayerFlag(uint32_t layerIdx) const { return m_vpsIndependentLayerFlag[layerIdx]; }
+  void              setIndependentLayerFlag(uint32_t layerIdx, bool t) { m_vpsIndependentLayerFlag[layerIdx] = t; }
+
+  bool              getDirectRefLayerFlag(uint32_t layerIdx, uint32_t refLayerIdx) const { return m_vpsDirectRefLayerFlag[layerIdx][refLayerIdx]; }
+  void              setDirectRefLayerFlag(uint32_t layerIdx, uint32_t refLayerIdx, bool t) { m_vpsDirectRefLayerFlag[layerIdx][refLayerIdx] = t; }
+
+  uint32_t          getDirectRefLayerIdx( uint32_t layerIdx, uint32_t refLayerIdc ) const { return m_directRefLayerIdx[layerIdx][refLayerIdc]; }
+  void              setDirectRefLayerIdx( uint32_t layerIdx, uint32_t refLayerIdc, uint32_t refLayerIdx ) { m_directRefLayerIdx[layerIdx][refLayerIdc] = refLayerIdx; }
+
+  uint32_t          getInterLayerRefIdc( uint32_t layerIdx, uint32_t refLayerIdx ) const { return m_interLayerRefIdx[layerIdx][refLayerIdx]; }
+  void              setInterLayerRefIdc( uint32_t layerIdx, uint32_t refLayerIdx, uint32_t refLayerIdc ) { m_interLayerRefIdx[layerIdx][refLayerIdx] = refLayerIdc; }
+
+  uint32_t          getGeneralLayerIdx(uint32_t layerId) const { return m_generalLayerIdx[layerId]; }
+  void              setGeneralLayerIdx(uint32_t layerId, uint32_t layerIdc) { m_generalLayerIdx[layerId] = layerIdc; }
+
+  bool              getEachLayerIsAnOlsFlag() const { return m_vpsEachLayerIsAnOlsFlag; }
+  void              setEachLayerIsAnOlsFlag(bool t) { m_vpsEachLayerIsAnOlsFlag = t; }
+
+  uint32_t          getOlsModeIdc() const { return m_vpsOlsModeIdc; }
+  void              setOlsModeIdc(uint32_t t) { m_vpsOlsModeIdc = t; }
+
+  uint32_t          getNumOutputLayerSets() const { return m_vpsNumOutputLayerSets; }
+  void              setNumOutputLayerSets(uint8_t t) { m_vpsNumOutputLayerSets = t; }
+
+  bool              getOlsOutputLayerFlag(uint32_t ols, uint32_t layer) const { return m_vpsOlsOutputLayerFlag[ols][layer]; }
+  void              setOlsOutputLayerFlag(uint32_t ols, uint32_t layer, bool t) { m_vpsOlsOutputLayerFlag[ols][layer] = t; }
+#else
+  void              setVPSIncludedLayerId(uint32_t v, uint32_t layer) { m_vpsIncludedLayerId[layer] = v; }
+  uint32_t          getVPSIncludedLayerId(uint32_t layer) const { return m_vpsIncludedLayerId[layer]; }
+>>>>>>> BD/VVCSoftware_VTM-JVET-O1159_JVET-P1019
+#endif
+
   bool              getVPSExtensionFlag() const                          { return m_vpsExtensionFlag;                                 }
   void              setVPSExtensionFlag(bool t)                          { m_vpsExtensionFlag = t;                                    }
-
-  void              setVPSIncludedLayerId(uint32_t v, uint32_t Layer)        { m_vpsIncludedLayerId[Layer] = v;                                    }
-  uint32_t          getVPSIncludedLayerId(uint32_t Layer) const              { return m_vpsIncludedLayerId[Layer];                                 }
 };
 
 class Window
@@ -1140,6 +1239,9 @@ private:
 #if JVET_P0590_SCALING_WINDOW
   bool              m_rprEnabledFlag;
 #endif
+#if JVET_O1159_SCALABILITY
+  bool              m_interLayerPresentFlag;
+#endif
 
 public:
 
@@ -1480,9 +1582,14 @@ public:
   bool      getSubLayerParametersPresentFlag()                            const     { return m_SubLayerCbpParametersPresentFlag;  }
 
 #if JVET_P0590_SCALING_WINDOW
-  bool      getRprEnabledFlag()                                           const    { return m_rprEnabledFlag; }
-  void      setRprEnabledFlag( bool flag )                                         { m_rprEnabledFlag = flag; }
+  bool      getRprEnabledFlag()                                           const     { return m_rprEnabledFlag; }
+  void      setRprEnabledFlag( bool flag )                                          { m_rprEnabledFlag = flag; }
+#endif
+#if JVET_O1159_SCALABILITY
+  bool      getInterLayerPresentFlag()                                        const { return m_interLayerPresentFlag; }
+  void      setInterLayerPresentFlag( bool b )                                      { m_interLayerPresentFlag = b; }
 #endif
+
 };
 
 
@@ -1580,6 +1687,10 @@ private:
   std::vector<uint32_t> m_ctuToTileCol;                 //!< mapping between CTU horizontal address and tile column index
   std::vector<uint32_t> m_ctuToTileRow;                 //!< mapping between CTU vertical address and tile row index
   bool             m_rectSliceFlag;                     //!< rectangular slice flag  
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  bool             m_singleSlicePerSubPicFlag;          //!< single slice per sub-picture flag
+  std::vector<uint32_t> m_ctuToSubPicIdx;               //!< mapping between CTU and Sub-picture index
+#endif
   uint32_t         m_numSlicesInPic;                    //!< number of rectangular slices in the picture (raster-scan slice specified at slice level)
   bool             m_tileIdxDeltaPresentFlag;           //!< tile index delta present flag
   std::vector<RectSlice> m_rectSlices;                  //!< list of rectangular slice signalling parameters
@@ -1817,6 +1928,11 @@ public:
   uint32_t               getTileIdx( const Position& pos ) const                          { return getTileIdx( pos.x / m_ctuSize, pos.y / m_ctuSize );                                                                      }
   void                   setRectSliceFlag( bool b )                                       { m_rectSliceFlag = b;                                                                                                            }
   bool                   getRectSliceFlag( ) const                                        { return  m_rectSliceFlag;                                                                                                        }
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  void                   setSingleSlicePerSubPicFlag( bool b )                            { m_singleSlicePerSubPicFlag = b;                                                                                                 }
+  bool                   getSingleSlicePerSubPicFlag( ) const                             { return  m_singleSlicePerSubPicFlag;                                                                                             }
+  uint32_t               getCtuToSubPicIdx( int idx ) const                               { CHECK( idx >= m_ctuToSubPicIdx.size(), "CTU address index exceeds valid range" ); return  m_ctuToSubPicIdx[idx];                }
+#endif
   void                   setNumSlicesInPic( uint32_t u )                                  { CHECK( u > MAX_SLICES, "Number of slices in picture exceeds valid range" ); m_numSlicesInPic = u;                               }
   uint32_t               getNumSlicesInPic( ) const                                       { return  m_numSlicesInPic;                                                                                                       }
   void                   setTileIdxDeltaPresentFlag( bool b )                             { m_tileIdxDeltaPresentFlag = b;                                                                                                  }
@@ -2711,11 +2827,18 @@ public:
 
   void                        checkLeadingPictureRestrictions( PicList& rcListPic )                                         const;
   int                         checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePictureList* pRPL, int rplIdx, bool printErrors, int* refPicIndex) const;
+#if JVET_O1159_SCALABILITY
+  void                        applyReferencePictureListBasedMarking( PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1, const int layerId )  const;
+#else
   void                        applyReferencePictureListBasedMarking( PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1 )  const;
+#endif
   bool                        isTemporalLayerSwitchingPoint( PicList& rcListPic )                                           const;
   bool                        isStepwiseTemporalLayerSwitchingPointCandidate( PicList& rcListPic )                          const;
   int                         checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePictureList *pRPL, int rplIdx, bool printErrors)                const;
+#if !JVET_O1159_SCALABILITY
+  // this is encoder only function
   void                        createExplicitReferencePictureSetFromReference(PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1);
+#endif
 #if !JVET_P1006_PICTURE_HEADER
   void                        setMaxNumMergeCand(uint32_t val )                          { m_maxNumMergeCand = val;                                      }
   uint32_t                    getMaxNumMergeCand() const                             { return m_maxNumMergeCand;                                     }
@@ -3067,6 +3190,10 @@ public:
                  ParameterSetManager();
   virtual        ~ParameterSetManager();
 
+#if JVET_O1159_SCALABILITY
+  void           storeVPS(VPS *vps, const std::vector<uint8_t> &naluData)    { m_vpsMap.storePS(vps->getVPSId(), vps, &naluData); }
+  VPS*           getVPS( int vpsId )                                         { return m_vpsMap.getPS( vpsId ); };
+#endif
 
   void           storeDPS(DPS *dps, const std::vector<uint8_t> &naluData)    { m_dpsMap.storePS( dps->getDecodingParameterSetId(), dps, &naluData); };
   //! get pointer to existing video parameter set
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 8fdbc670fd03e510024ed4dcb3ec7009a4230976..02a62ebbd226d94bc0a3e9e2d5f02fe8d24eae57 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -52,8 +52,12 @@
 
 #define FIELD_CODING_FIX                                  1 // Fix field coding 
 
+#define JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG           1 // JVET-P1024: single_slice_per_subpic_flag in the PPS
+
 #define JVET_P1038_ALF_PAD_RASTER_SLICE                   1 // JVET-P1038, handle ALF padding in raster scan slice
 
+#define JVET_P1019_OUTPUT_LAYER_SET                       1 // JVET-P1019: Signaling of output layer set (OLS) and its output process
+
 #define JVET_P0257_SCALING_LISTS_SPEEDUP_DEC              1 // JVET-P0257: Decoder speed-up for handling scaling matrices
 
 #define JVET_P2001_REMOVE_TRANSQUANT_BYPASS               1 // JVET-P2001: Remove transquant bypass - not supported in JVET-P2001 draft text
@@ -149,6 +153,8 @@
 
 #define JVET_N0278_FIXES                                  1 // Working draft 5 independent layers
 
+#define JVET_O1159_SCALABILITY                            1 // JVET-O1159: Scalability
+
 #define JVET_P0325_CHANGE_MERGE_CANDIDATE_ORDER           1 // JVET-P0325: reorder the spatial merge candidates
 
 #define JVET_P0984_SEI_SUBPIC_LEVEL                       1 // JVET-P0984: Subpicture level information SEI
@@ -255,6 +261,13 @@
 
 #define JVET_P0478_PTL_DPS                                1 // JVET-P0478: allow multiple PTL in DPS
 
+#define JVET_P0446_CONCATENATION                          1 // concatenation info in BP SEI
+#define JVET_P0446_ALT_CPB                                1 // alternative CPB parameters
+#define JVET_P0446_BP_CPB_CNT_FIX                         1 // bp_cpb_cnt is not an array according to the spec text
+#if JVET_P0446_ALT_CPB && !JVET_P0446_BP_CPB_CNT_FIX
+#error JVET_P0446_BP_CPB_CNT_FIX must be enabled for JVET_P0446_ALT_CPB
+#endif
+
 #define JVET_M0497_MATRIX_MULT                            0 // 0: Fast method; 1: Matrix multiplication
 
 #define JVET_P0181                                        1 // JVET-P0181 : Modifications to HRD information signalling
@@ -270,13 +283,15 @@
 
 #define JVET_P0171_SUBPICTURE_LAYOUT                      1  //JVET-P0171: subpicture layout
 
+#define JVET_P0185                                        1 // Infer vps_max_layers_minus1 to be equal to 0 when not present and also signal vps_max_sub_layers_minus1 
+
 #define HEVC_SEI                                          0 // SEI messages that are defined in HEVC, but not in VVC
 
 typedef std::pair<int, bool> TrMode;
 typedef std::pair<int, int>  TrCost;
 
 // clang-format off
-#define REUSE_CU_RESULTS                                  1
+#define REUSE_CU_RESULTS                                  1 
 #if REUSE_CU_RESULTS
 #define REUSE_CU_RESULTS_WITH_MULTIPLE_TUS                1
 #endif
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index b94a99e8303f2110e882e62b7894d702d7184a8b..906dde81f140f6db78da2f6c953d8d05c7d6ff1c 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -1404,7 +1404,7 @@ bool PU::checkDMVRCondition(const PredictionUnit& pu)
       && ((pu.lheight() * pu.lwidth()) >= 128)
       && (pu.cu->BcwIdx == BCW_DEFAULT)
       && ((!wp0[COMPONENT_Y].bPresentFlag) && (!wp1[COMPONENT_Y].bPresentFlag))
-#if JVET_P0590_SCALING_WINDOW
+#if JVET_P0590_SCALING_WINDOW || JVET_O1159_SCALABILITY
       && ( refIdx0 < 0 ? true : pu.cu->slice->getScalingRatio( REF_PIC_LIST_0, refIdx0 ) == SCALE_1X ) && ( refIdx1 < 0 ? true : pu.cu->slice->getScalingRatio( REF_PIC_LIST_1, refIdx1 ) == SCALE_1X )
 #else
       && PU::isRefPicSameSize( pu )
@@ -4080,7 +4080,7 @@ bool allowLfnstWithMip(const Size& block)
   return false;
 }
 
-#if !JVET_P0590_SCALING_WINDOW
+#if !JVET_P0590_SCALING_WINDOW && !JVET_O1159_SCALABILITY
 bool PU::isRefPicSameSize( const PredictionUnit& pu )
 {
   bool samePicSize = true;
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index 756377f247639ea5cc6ea1ce6dc4b0b44a289717..35fe75ca62d41a60ad1f28860cf541c52a5560f1 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -196,7 +196,7 @@ namespace PU
   bool getDerivedBV(PredictionUnit &pu, const Mv& currentMv, Mv& derivedMv);
   bool checkDMVRCondition(const PredictionUnit& pu);
 
-#if !JVET_P0590_SCALING_WINDOW
+#if !JVET_P0590_SCALING_WINDOW && !JVET_O1159_SCALABILITY
   bool isRefPicSameSize( const PredictionUnit& pu );
 #endif
 }
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 006550aeedd2b457ad4f078a6c7a6ef79ee1d30c..7d9e41875f4903781003fcc39c2ec270bd7df661 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -443,10 +443,11 @@ DecLib::~DecLib()
     m_prefixSEINALUs.pop_front();
   }
 
-#if JVET_N0278_FIXES
+#if JVET_N0278_FIXES && !JVET_O1159_SCALABILITY
   if( m_vps != nullptr )
   {
     delete m_vps;
+    m_vps = nullptr;
   }
 #endif
 }
@@ -698,6 +699,15 @@ void DecLib::finishPicture(int& poc, PicList*& rpcListPic, MsgLevel msgl )
         else
           msg( msgl, "%d ", pcSlice->getRefPOC( RefPicList( iRefList ), iRefIndex ) );
       }
+
+#if JVET_O1159_SCALABILITY
+      if( pcSlice->getRefPOC( RefPicList( iRefList ), iRefIndex ) == pcSlice->getPOC() )
+      {
+        msg( msgl, ".%d", pcSlice->getRefPic( RefPicList( iRefList ), iRefIndex )->layerId );
+      }   
+#endif
+
+      msg( msgl, " " );
     }
     msg( msgl, "] ");
   }
@@ -1054,6 +1064,10 @@ void DecLib::xActivateParameterSets()
     const SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());             // this is a temporary SPS object. Do not store this value
     CHECK(sps == 0, "No SPS present");
 
+#if JVET_O1159_SCALABILITY
+    const VPS *vps = sps->getVPSId() ? m_parameterSetManager.getVPS( sps->getVPSId() ) : nullptr;
+#endif
+
     if (NULL == pps->pcv)
     {
 #if JVET_P1006_PICTURE_HEADER
@@ -1106,9 +1120,17 @@ void DecLib::xActivateParameterSets()
     m_pcPic = xGetNewPicBuffer (*sps, *pps, m_apcSlicePilot->getTLayer());
 #endif
 
+#if JVET_O1159_SCALABILITY
+    m_apcSlicePilot->applyReferencePictureListBasedMarking( m_cListPic, m_apcSlicePilot->getRPL0(), m_apcSlicePilot->getRPL1(), layerId );
+#else
     m_apcSlicePilot->applyReferencePictureListBasedMarking(m_cListPic, m_apcSlicePilot->getRPL0(), m_apcSlicePilot->getRPL1());
+#endif
 #if JVET_P1006_PICTURE_HEADER
+#if JVET_O1159_SCALABILITY
+    m_pcPic->finalInit( vps, *sps, *pps, &m_picHeader, apss, lmcsAPS, scalinglistAPS );
+#else
     m_pcPic->finalInit( *sps, *pps, &m_picHeader, apss, lmcsAPS, scalinglistAPS );
+#endif
 #else
     m_pcPic->finalInit( *sps, *pps, apss, lmcsAPS, scalinglistAPS );
 #endif
@@ -1138,6 +1160,9 @@ void DecLib::xActivateParameterSets()
     m_pcPic->cs->slice = pSlice;
     m_pcPic->cs->sps   = sps;
     m_pcPic->cs->pps   = pps;
+#if JVET_O1159_SCALABILITY
+    m_pcPic->cs->vps = vps;
+#endif
 
     memcpy(m_pcPic->cs->alfApss, apss, sizeof(m_pcPic->cs->alfApss));
     m_pcPic->cs->lmcsAps = lmcsAPS;
@@ -1959,15 +1984,22 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
 void DecLib::xDecodeVPS( InputNALUnit& nalu )
 {
 #if JVET_N0278_FIXES
+#if JVET_O1159_SCALABILITY
+  m_vps = new VPS();
+#else
   if( m_vps == nullptr )
   {
     m_vps = new VPS();
   }
+#endif
   m_HLSReader.setBitstream( &nalu.getBitstream() );
 
   CHECK( nalu.m_temporalId, "The value of TemporalId of VPS NAL units shall be equal to 0" );
 
   m_HLSReader.parseVPS( m_vps );
+#if JVET_O1159_SCALABILITY
+  m_parameterSetManager.storeVPS( m_vps, nalu.getBitstream().getFifo());
+#endif
 #else
   VPS* vps = new VPS();
   m_HLSReader.setBitstream( &nalu.getBitstream() );
@@ -2032,11 +2064,13 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
 {
   bool ret;
   // ignore all NAL units of layers > 0
+#if !JVET_P1019_OUTPUT_LAYER_SET
   if (getTargetDecLayer() >= 0 && nalu.m_nuhLayerId != getTargetDecLayer()) //TBC: ignore bitstreams whose nuh_layer_id is not the target layer id
   {
     msg( WARNING, "Warning: found NAL unit with nuh_layer_id equal to %d. Ignoring.\n", nalu.m_nuhLayerId);
     return false;
   }
+#endif
 
   m_accessUnitNals.push_back( std::pair<NalUnitType, int>( nalu.m_nalUnitType, nalu.m_temporalId ) );
 
diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h
index bf4c3f3ef97250efd0d407bc7df4c74fb5332110..113d421847faa0a5c0dfeeddbad53a0d6818b8dd 100644
--- a/source/Lib/DecoderLib/DecLib.h
+++ b/source/Lib/DecoderLib/DecLib.h
@@ -85,7 +85,9 @@ private:
 
   SEIMessages             m_SEIs; ///< List of SEI messages that have been received before the first slice and between slices, excluding prefix SEIs...
 
+#if !JVET_P1019_OUTPUT_LAYER_SET
   int                     m_iTargetLayer;                       ///< target stream layer to be decoded
+#endif
 
   // functional classes
   IntraPrediction         m_cIntraPred;
@@ -173,8 +175,10 @@ public:
   void  checkNalUnitConstraints( uint32_t naluType );
 #endif
 
-  void  setTargetDecLayer (int val) { m_iTargetLayer = val; }
-  int   getTargetDecLayer()         { return m_iTargetLayer; }
+#if !JVET_P1019_OUTPUT_LAYER_SET
+  void  setTargetDecLayer(int val) { m_iTargetLayer = val; }
+  int   getTargetDecLayer() { return m_iTargetLayer; }
+#endif
 
   bool  getNoOutputPriorPicsFlag () const   { return m_isNoOutputPriorPics; }
   void  setNoOutputPriorPicsFlag (bool val) { m_isNoOutputPriorPics = val; }
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index ef4b1348e166eb1af96b31b88bac028ce45de77e..f8e813497a727385b1d7f68451adcdca12ae0ae1 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -670,6 +670,9 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
   sei_read_code( pDecodedMessageOutputStream, 5, code, "initial_cpb_removal_delay_length_minus1" );     sei.m_initialCpbRemovalDelayLength = code + 1;
   sei_read_code( pDecodedMessageOutputStream, 5, code, "cpb_removal_delay_length_minus1" );             sei.m_cpbRemovalDelayLength        = code + 1;
   sei_read_code( pDecodedMessageOutputStream, 5, code, "dpb_output_delay_length_minus1" );              sei.m_dpbOutputDelayLength         = code + 1;
+#if JVET_P0446_ALT_CPB
+  sei_read_flag( pDecodedMessageOutputStream, code, "alt_cpb_params_present_flag");                     sei.m_altCpbParamsPresentFlag      = code;
+#endif
   sei_read_flag( pDecodedMessageOutputStream, code, "bp_decoding_unit_hrd_params_present_flag" );       sei.m_bpDecodingUnitHrdParamsPresentFlag = code;
   if( sei.m_bpDecodingUnitHrdParamsPresentFlag )
   {
@@ -700,6 +703,16 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
 
   sei_read_flag( pDecodedMessageOutputStream, code, "concatenation_flag");
   sei.m_concatenationFlag = code;
+#if JVET_P0446_CONCATENATION
+  sei_read_flag ( pDecodedMessageOutputStream, code, "additional_concatenation_info_present_flag");
+  sei.m_additionalConcatenationInfoPresentFlag = code;
+  if (sei.m_additionalConcatenationInfoPresentFlag)
+  {
+    sei_read_code( pDecodedMessageOutputStream, sei.m_initialCpbRemovalDelayLength, code, "max_initial_removal_delay_for_concatenation" );
+    sei.m_maxInitialRemovalDelayForConcatenation = code;
+  }
+#endif
+
   sei_read_code( pDecodedMessageOutputStream, ( sei.m_cpbRemovalDelayLength ), code, "au_cpb_removal_delay_delta_minus1" );
   sei.m_auCpbRemovalDelayDelta = code + 1;
   sei_read_flag( pDecodedMessageOutputStream, code, "cpb_removal_delay_deltas_present_flag" );               sei.m_cpbRemovalDelayDeltasPresentFlag = code;
@@ -713,6 +726,9 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
     }
   }
   sei_read_code( pDecodedMessageOutputStream, 3, code, "bp_max_sub_layers_minus1" );     sei.m_bpMaxSubLayers = code + 1;
+#if JVET_P0446_BP_CPB_CNT_FIX
+  sei_read_uvlc( pDecodedMessageOutputStream, code, "bp_cpb_cnt_minus1" ); sei.m_bpCpbCnt = code + 1;
+#endif
 #if JVET_P0181
   sei_read_flag(pDecodedMessageOutputStream, code, "sublayer_initial_cpb_removal_delay_present_flag");
   sei.m_sublayerInitialCpbRemovalDelayPresentFlag = code;
@@ -721,13 +737,19 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
   for (i = 0; i < sei.m_bpMaxSubLayers; i++)
 #endif
   {
+#if !JVET_P0446_BP_CPB_CNT_FIX
     sei_read_uvlc( pDecodedMessageOutputStream, code, "bp_cpb_cnt_minus1[i]" ); sei.m_bpCpbCnt[i] = code + 1;
+#endif
     for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
     {
       if( ( ( nalOrVcl == 0 ) && ( sei.m_bpNalCpbParamsPresentFlag ) ) ||
          ( ( nalOrVcl == 1 ) && ( sei.m_bpVclCpbParamsPresentFlag ) ) )
       {
+#if JVET_P0446_BP_CPB_CNT_FIX
+        for( int j = 0; j < ( sei.m_bpCpbCnt ); j ++ )
+#else
         for( int j = 0; j < ( sei.m_bpCpbCnt[i] ); j ++ )
+#endif
         {
           sei_read_code( pDecodedMessageOutputStream, sei.m_initialCpbRemovalDelayLength, code, nalOrVcl ? "vcl_initial_cpb_removal_delay[i][j]" : "nal_initial_cpb_removal_delay[i][j]" );
           sei.m_initialCpbRemovalDelay[i][j][nalOrVcl] = code;
@@ -737,6 +759,13 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
       }
     }
   }
+#if JVET_P0446_ALT_CPB
+  if (sei.m_altCpbParamsPresentFlag)
+  {
+    sei_read_flag(pDecodedMessageOutputStream, code, "use_alt_cpb_params_flag"); sei.m_useAltCpbParamsFlag = code;
+  }
+#endif
+
 }
 
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI 
@@ -755,6 +784,33 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI 
   sei_read_code( pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, symbol, "cpb_removal_delay_minus1[bp_max_sub_layers_minus1]" );
   sei.m_auCpbRemovalDelay[bp.m_bpMaxSubLayers - 1] = symbol + 1;
+
+#if JVET_P0446_ALT_CPB
+  if( bp.m_altCpbParamsPresentFlag ) 
+  {
+    sei_read_flag( pDecodedMessageOutputStream, symbol, "cpb_alt_timing_info_present_flag" ); sei.m_cpbAltTimingInfoPresentFlag = symbol;
+    if( sei.m_cpbAltTimingInfoPresentFlag ) 
+    {
+      sei.m_cpbAltInitialCpbRemovalDelayDelta.resize(bp.m_bpCpbCnt);
+      sei.m_cpbAltInitialCpbRemovalOffsetDelta.resize(bp.m_bpCpbCnt);
+      for( int i = 0; i < bp.m_bpCpbCnt; i++ ) 
+      {
+        sei_read_code( pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, symbol, "cpb_alt_initial_cpb_removal_delay_delta[ i ]" );
+        sei.m_cpbAltInitialCpbRemovalDelayDelta[i]= symbol;
+        sei_read_code( pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, symbol, "cpb_alt_initial_cpb_removal_offset_delta[ i ]" );
+        sei.m_cpbAltInitialCpbRemovalOffsetDelta[i]= symbol;
+      }
+      sei_read_code( pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, sei.m_cpbDelayOffset, "cpb_delay_offset" );
+      sei_read_code( pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, sei.m_dpbDelayOffset, "dpb_delay_offset" );
+    }
+  }
+  else
+  {
+    sei.m_cpbAltTimingInfoPresentFlag = false;
+    sei.m_cpbDelayOffset = sei.m_dpbDelayOffset = 0;
+  }
+#endif
+
   for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ )
   {
     sei_read_flag( pDecodedMessageOutputStream,    symbol, "pt_sub_layer_delays_present_flag[i]" );    sei.m_ptSubLayerDelaysPresentFlag[i] = (symbol == 1);
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 563799eb0bf378d8f422f973d3999262ecc53fc8..237656a419f4d09f15cdd4e18fb036b083ad0e62 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -300,14 +300,27 @@ void HLSyntaxReader::copyRefPicList(SPS* sps, ReferencePictureList* source_rpl,
 {
   dest_rp->setNumberOfShorttermPictures(source_rpl->getNumberOfShorttermPictures());
 
-  if (sps->getLongTermRefsPresent())
-    dest_rp->setNumberOfLongtermPictures(dest_rp->getNumberOfLongtermPictures());
+#if JVET_O1159_SCALABILITY
+  dest_rp->setNumberOfInterLayerPictures( sps->getInterLayerPresentFlag() ? dest_rp->getNumberOfInterLayerPictures() : 0 );
+#endif
+
+  if( sps->getLongTermRefsPresent() )
+  {
+    dest_rp->setNumberOfLongtermPictures( dest_rp->getNumberOfLongtermPictures() );
+  }
   else
     dest_rp->setNumberOfLongtermPictures(0);
 
   uint32_t numRefPic = dest_rp->getNumberOfShorttermPictures() + dest_rp->getNumberOfLongtermPictures();
-  for (int ii = 0; ii < numRefPic; ii++)
-    dest_rp->setRefPicIdentifier(ii, source_rpl->getRefPicIdentifier(ii), source_rpl->isRefPicLongterm(ii));
+
+  for( int ii = 0; ii < numRefPic; ii++ )
+  {
+#if JVET_O1159_SCALABILITY
+    dest_rp->setRefPicIdentifier( ii, source_rpl->getRefPicIdentifier( ii ), source_rpl->isRefPicLongterm( ii ), source_rpl->isInterLayerRefPic( ii ), source_rpl->getInterLayerRefPicIdx( ii ) );
+#else
+    dest_rp->setRefPicIdentifier( ii, source_rpl->getRefPicIdentifier( ii ), source_rpl->isRefPicLongterm( ii ) );
+#endif
+  }
 }
 
 void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl)
@@ -317,6 +330,9 @@ void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl)
   uint32_t numRefPic = code;
   uint32_t numStrp = 0;
   uint32_t numLtrp = 0;
+#if JVET_O1159_SCALABILITY
+  uint32_t numIlrp = 0;
+#endif
 
   if (sps->getLongTermRefsPresent())
   {
@@ -329,8 +345,30 @@ void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl)
   int deltaValue = 0;
   bool firstSTRP = true;
 
+#if JVET_O1159_SCALABILITY
+  rpl->setInterLayerPresentFlag( sps->getInterLayerPresentFlag() );
+#endif
+
   for (int ii = 0; ii < numRefPic; ii++)
   {
+#if JVET_O1159_SCALABILITY
+    uint32_t isInterLayerRefPic = 0;
+
+    if( rpl->getInterLayerPresentFlag() )
+    {
+      READ_FLAG( isInterLayerRefPic, "inter_layer_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]" );
+
+      if( isInterLayerRefPic )
+      {
+        READ_UVLC( code, "ilrp_idx[ listIdx ][ rplsIdx ][ i ]" );
+        rpl->setRefPicIdentifier( ii, 0, true, true, code );
+        numIlrp++;
+      }
+    }
+
+    if( !isInterLayerRefPic )
+    {
+#endif
     isLongTerm = false;
     if (sps->getLongTermRefsPresent())
     {
@@ -363,19 +401,34 @@ void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl)
         deltaValue = prevDelta + readValue;
         prevDelta = deltaValue;
       }
+
+#if JVET_O1159_SCALABILITY
+      rpl->setRefPicIdentifier( ii, deltaValue, isLongTerm, false, 0 );
+#else
       rpl->setRefPicIdentifier(ii, deltaValue, isLongTerm);
+#endif
       numStrp++;
     }
     else
     {
       if (!rpl->getLtrpInSliceHeaderFlag())
         READ_CODE(sps->getBitsForPOC(), code, "poc_lsb_lt[listIdx][rplsIdx][j]");
+#if JVET_O1159_SCALABILITY
+      rpl->setRefPicIdentifier( ii, deltaValue, isLongTerm, false, 0 );
+#else
       rpl->setRefPicIdentifier(ii, code, isLongTerm);
+#endif 
       numLtrp++;
     }
+#if JVET_O1159_SCALABILITY
+    }
+#endif
   }
   rpl->setNumberOfShorttermPictures(numStrp);
   rpl->setNumberOfLongtermPictures(numLtrp);
+#if JVET_O1159_SCALABILITY
+  rpl->setNumberOfInterLayerPictures( numIlrp );
+#endif
 }
 
 void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetManager )
@@ -481,7 +534,15 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
      
     // rectangular slice signalling
     READ_CODE(1, uiCode, "rect_slice_flag");                          pcPPS->setRectSliceFlag( uiCode == 1 );
-    if( pcPPS->getRectSliceFlag() ) 
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+    if (pcPPS->getRectSliceFlag()) 
+    {
+      READ_FLAG(uiCode, "single_slice_per_subpic_flag");            pcPPS->setSingleSlicePerSubPicFlag(uiCode == 1);
+    }
+    if (pcPPS->getRectSliceFlag() & !(pcPPS->getSingleSlicePerSubPicFlag()))
+#else
+    if (pcPPS->getRectSliceFlag())
+#endif
     {
       int32_t tileIdx = 0;
 
@@ -1578,6 +1639,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   }
 
   READ_FLAG(uiCode, "long_term_ref_pics_flag");          pcSPS->setLongTermRefsPresent(uiCode);
+#if JVET_O1159_SCALABILITY
+  READ_FLAG( uiCode, "inter_layer_ref_pics_present_flag" );  pcSPS->setInterLayerPresentFlag( uiCode );
+#endif 
 #if JVET_P2001_SYNTAX_ORDER_MISMATCHES
   READ_FLAG( uiCode, "sps_idr_rpl_present_flag" );       pcSPS->setIDRRefParamListPresent( (bool) uiCode );
 #endif
@@ -2147,13 +2211,92 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
   READ_CODE(4, uiCode, "vps_video_parameter_set_id");         pcVPS->setVPSId(uiCode);
 #endif
 
+#if JVET_O1159_SCALABILITY
+  READ_CODE(6, uiCode, "vps_max_layers_minus1");              pcVPS->setMaxLayers(uiCode + 1);    CHECK(uiCode + 1 > MAX_VPS_LAYERS, "Invalid code");
+  if (pcVPS->getMaxLayers() - 1 == 0)
+  {
+    pcVPS->setEachLayerIsAnOlsFlag(1);
+  }
+  READ_CODE(3, uiCode, "vps_max_sublayers_minus1");           pcVPS->setMaxSubLayers(uiCode + 1); CHECK(uiCode + 1 > MAX_VPS_SUBLAYERS, "Invalid code");
+  if( pcVPS->getMaxLayers() > 1 && pcVPS->getMaxSubLayers() > 1)
+  {
+    READ_FLAG(uiCode, "vps_all_layers_same_num_sublayers_flag"); pcVPS->setAllLayersSameNumSublayersFlag(uiCode);
+  }
+  else
+  {
+    pcVPS->setAllLayersSameNumSublayersFlag(1);
+  }
+  if( pcVPS->getMaxLayers() > 1 )
+  {
+    READ_FLAG(uiCode, "vps_all_independent_layers_flag");  pcVPS->setAllIndependentLayersFlag(uiCode);
+    if (pcVPS->getAllIndependentLayersFlag() == 0)
+    {
+      pcVPS->setEachLayerIsAnOlsFlag(0);
+    }
+  }
+  for (uint32_t i = 0; i < pcVPS->getMaxLayers(); i++)
+  {
+    READ_CODE(6, uiCode, "vps_layer_id");                     pcVPS->setLayerId(i, uiCode);
+    pcVPS->setGeneralLayerIdx(uiCode, i);
+
+    if (i > 0 && !pcVPS->getAllIndependentLayersFlag())
+    {
+      READ_FLAG(uiCode, "vps_independent_layer_flag");     pcVPS->setIndependentLayerFlag(i, uiCode);
+      if (!pcVPS->getIndependentLayerFlag(i))
+      {
+        for (int j = 0, k = 0; j < i; j++)
+        {
+          READ_FLAG(uiCode, "vps_direct_dependency_flag"); pcVPS->setDirectRefLayerFlag(i, j, uiCode);
+          if( uiCode )
+          {
+            pcVPS->setInterLayerRefIdc( i, j, k );
+            pcVPS->setDirectRefLayerIdx( i, k++, j );
+          }
+        }
+      }
+    }
+  }
+
+  if (pcVPS->getMaxLayers() > 1)
+  {
+    if (pcVPS->getAllIndependentLayersFlag())
+    {
+      READ_FLAG(uiCode, "vps_each_layer_is_an_ols_flag");  pcVPS->setEachLayerIsAnOlsFlag(uiCode);
+      if (pcVPS->getEachLayerIsAnOlsFlag() == 0)
+      {
+        pcVPS->setOlsModeIdc(2);
+      }
+    }
+    if (!pcVPS->getEachLayerIsAnOlsFlag())
+    {
+      if (!pcVPS->getAllIndependentLayersFlag())
+      {
+        READ_CODE(2, uiCode, "vps_ols_mode_idc");             pcVPS->setOlsModeIdc(uiCode); CHECK(uiCode > MAX_VPS_OLS_MODE_IDC, "Invalid code");
+      }
+      if (pcVPS->getOlsModeIdc() == 2)
+      {
+        READ_CODE(8, uiCode, "num_output_layer_sets_minus1");   pcVPS->setNumOutputLayerSets(uiCode + 1);
+        for (uint32_t i = 1; i <= pcVPS->getNumOutputLayerSets() - 1; i++)
+        {
+          for (uint32_t j = 0; j < pcVPS->getMaxLayers(); j++)
+          {
+            READ_FLAG(uiCode, "vps_ols_output_layer_flag");        pcVPS->setOlsOutputLayerFlag(i, j, uiCode);
+          }
+        }
+      }
+    }
+  }
+#else
   READ_CODE(8, uiCode, "vps_max_layers_minus1");              pcVPS->setMaxLayers(uiCode + 1);    CHECK(uiCode + 1 > MAX_VPS_LAYERS, "Invalid code");
+#if JVET_P0185
+  READ_CODE(3, uiCode, "vps_max_sub_layers_minus1");          pcVPS->setMaxSubLayers(uiCode + 1);
+#endif
   for (uint32_t i = 0; i <= pcVPS->getMaxLayers() - 1; i++)
   {
     READ_CODE(7, uiCode, "vps_included_layer_id");          pcVPS->setVPSIncludedLayerId(uiCode, i);
     READ_FLAG(uiCode, "vps_reserved_zero_1bit");
   }
-
+#endif
   READ_FLAG(uiCode, "vps_extension_flag");
   if (uiCode)
   {
@@ -2390,7 +2533,11 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
             if (picHeader->getRPL( listIdx )->getLtrpInSliceHeaderFlag())
             {
               READ_CODE(sps->getBitsForPOC(), uiCode, "pic_poc_lsb_lt[i][j]");
+#if JVET_O1159_SCALABILITY
+              picHeader->getLocalRPL( listIdx )->setRefPicIdentifier( i, uiCode, true, false, 0 );
+#else
               picHeader->getLocalRPL( listIdx )->setRefPicIdentifier(i, uiCode, true);
+#endif
             }
             READ_FLAG(uiCode, "pic_delta_poc_msb_present_flag[i][j]");
             picHeader->getLocalRPL( listIdx )->setDeltaPocMSBPresentFlag(i, uiCode ? true : false);
@@ -3236,7 +3383,11 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
             if (pcSlice->getRPL0()->getLtrpInSliceHeaderFlag())
             {
               READ_CODE(sps->getBitsForPOC(), uiCode, "slice_poc_lsb_lt[i][j]");
+#if JVET_O1159_SCALABILITY
+              pcSlice->getLocalRPL0()->setRefPicIdentifier( i, uiCode, true, false, 0 );
+#else
               pcSlice->getLocalRPL0()->setRefPicIdentifier(i, uiCode, true);
+#endif
             }
             READ_FLAG(uiCode, "delta_poc_msb_present_flag[i][j]");
             pcSlice->getLocalRPL0()->setDeltaPocMSBPresentFlag(i, uiCode ? true : false);
@@ -3321,7 +3472,11 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
             if (pcSlice->getRPL1()->getLtrpInSliceHeaderFlag())
             {
               READ_CODE(sps->getBitsForPOC(), uiCode, "slice_poc_lsb_lt[i][j]");
+#if JVET_O1159_SCALABILITY
+              pcSlice->getLocalRPL0()->setRefPicIdentifier( i, uiCode, true, false, 0 );
+#else
               pcSlice->getLocalRPL1()->setRefPicIdentifier(i, uiCode, true);
+#endif
             }
             READ_FLAG(uiCode, "delta_poc_msb_present_flag[i][j]");
             pcSlice->getLocalRPL1()->setDeltaPocMSBPresentFlag(i, uiCode ? true : false);
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
index 445ff7e8bed8aa33e7c0b229cbc9f9d3e16f1d21..187e73f16ef13b6686daa624241378c2f3e87325 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
@@ -649,7 +649,11 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
                                       )
 {
 #if JVET_N0278_FIXES
+#if JVET_O1159_SCALABILITY
+  int layerIdx = cs.vps == nullptr ? 0 : cs.vps->getGeneralLayerIdx( cs.slice->getPic()->layerId );
+#else
   int layerIdx = cs.slice->getPic()->layerId; //VS: layerId should be converted to layerIdx
+#endif
 
    // IRAP AU is assumed
   if( !layerIdx && ( cs.slice->getPendingRasInit() || cs.slice->isIDRorBLA() ) )
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 9c89c5b391f8584b46097df24465af2e398d852f..6d555f0086fcccb6b3c7cdeeac726c7b5abe8246 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -522,7 +522,10 @@ protected:
   std::vector<int> m_tileColumnWidth;
   std::vector<int> m_tileRowHeight;
 #endif
-
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  //====== Sub-picture and Slices ========
+  bool      m_singleSlicePerSubPicFlag;
+#endif
   bool      m_entropyCodingSyncEnabledFlag;
 
 #if !JVET_P1004_REMOVE_BRICKS
@@ -850,6 +853,9 @@ protected:
   bool        m_rprEnabled;
   int         m_switchPocPeriod;
   int         m_upscaledOutput;
+#if JVET_O1159_SCALABILITY
+  int         m_numRefLayers[MAX_VPS_LAYERS];
+#endif
 
 public:
   EncCfg()
@@ -1498,7 +1504,11 @@ public:
   void      setLFCrossSliceBoundaryFlag     ( bool   bValue  )       { m_bLFCrossSliceBoundaryFlag = bValue; }
   bool      getLFCrossSliceBoundaryFlag     ()                       { return m_bLFCrossSliceBoundaryFlag;   }
 #endif
-
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+  //====== Sub-picture and Slices ========
+  void      setSingleSlicePerSubPicFlagFlag( bool b )                { m_singleSlicePerSubPicFlag = b;    }
+  bool      getSingleSlicePerSubPicFlagFlag( )                       { return m_singleSlicePerSubPicFlag;    }
+#endif
   void      setUseSAO                  (bool bVal)                   { m_bUseSAO = bVal; }
   bool      getUseSAO                  ()                            { return m_bUseSAO; }
   void  setTestSAODisableAtPictureLevel (bool bVal)                  { m_bTestSAODisableAtPictureLevel = bVal; }
@@ -2153,6 +2163,11 @@ public:
   void        setSwitchPocPeriod( int p )                            { m_switchPocPeriod = p;}
   void        setUpscaledOutput( int b )                             { m_upscaledOutput = b; }
   int         getUpscaledOutput()                              const { return m_upscaledOutput; }
+
+#if JVET_O1159_SCALABILITY
+  void        setNumRefLayers( int* numRefLayers )                   { std::memcpy( m_numRefLayers, numRefLayers, sizeof( m_numRefLayers ) ); }
+  int         getNumRefLayers( int layerIdx )                  const { return m_numRefLayers[layerIdx];  }
+#endif
 };
 
 //! \}
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index a9b93ae60b55e9f43c688fe53b991a616b4355d7..a631486e03c1cf98bfadbc8dd6b3c4b74029659d 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -332,11 +332,17 @@ int EncGOP::xWriteDPS (AccessUnit &accessUnit, const DPS *dps)
   }
 }
 
-
+#if JVET_O1159_SCALABILITY
+int EncGOP::xWriteSPS( AccessUnit &accessUnit, const SPS *sps, const int layerId )
+#else
 int EncGOP::xWriteSPS (AccessUnit &accessUnit, const SPS *sps)
+#endif
 {
   OutputNALUnit nalu(NAL_UNIT_SPS);
   m_HLSWriter->setBitstream( &nalu.m_Bitstream );
+#if JVET_O1159_SCALABILITY
+  nalu.m_nuhLayerId = layerId;
+#endif
   CHECK( nalu.m_temporalId, "The value of TemporalId of SPS NAL units shall be equal to 0" );
   m_HLSWriter->codeSPS( sps );
   accessUnit.push_back(new NALUnitEBSP(nalu));
@@ -396,7 +402,11 @@ int EncGOP::xWriteParameterSets( AccessUnit &accessUnit, Slice *slice, const boo
     if( m_pcEncLib->SPSNeedsWriting( slice->getSPS()->getSPSId() ) ) // Note this assumes that all changes to the SPS are made at the EncLib level prior to picture creation (EncLib::xGetNewPicBuffer).
     {
       CHECK( !( bSeqFirst ), "Unspecified error" ); // Implementations that use more than 1 SPS need to be aware of activation issues.
+#if JVET_O1159_SCALABILITY
+      actualTotalBits += xWriteSPS( accessUnit, slice->getSPS(), m_pcEncLib->getLayerId() );
+#else
       actualTotalBits += xWriteSPS( accessUnit, slice->getSPS() );
+#endif
     }
   }
 
@@ -441,6 +451,9 @@ int EncGOP::xWritePicHeader( AccessUnit &accessUnit, PicHeader *picHeader )
   OutputNALUnit nalu(NAL_UNIT_PH);
   m_HLSWriter->setBitstream( &nalu.m_Bitstream );
   nalu.m_temporalId = accessUnit.temporalId;
+#if JVET_P1019_OUTPUT_LAYER_SET
+  nalu.m_nuhLayerId = m_pcEncLib->getLayerId();
+#endif
   m_HLSWriter->codePictureHeader( picHeader );
   accessUnit.push_back(new NALUnitEBSP(nalu));
   return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
@@ -460,7 +473,11 @@ void EncGOP::xWriteAccessUnitDelimiter (AccessUnit &accessUnit, Slice *slice)
   }
   else
   {
+#if JVET_O1159_SCALABILITY
+    nalu.m_nuhLayerId = slice->getVPS()->getLayerId(0);
+#else
     nalu.m_nuhLayerId = slice->getVPS()->getVPSIncludedLayerId(0);
+#endif
   }
   CHECK( nalu.m_temporalId != accessUnit.temporalId, "TemporalId shall be equal to the TemporalId of the AU containing the NAL unit" );
 #else
@@ -2086,7 +2103,11 @@ void EncGOP::xPicInitLMCS(Picture *pic, Slice *slice)
     if (m_pcReshaper->getSliceReshaperInfo().getSliceReshapeModelPresentFlag())
     {
 #if JVET_N0278_FIXES
+#if JVET_O1159_SCALABILITY
+      int apsId = std::min<int>( 3, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) );
+#else
       int apsId = std::min<int>( 3, m_pcEncLib->getLayerId() ); //VS: layerId should be converted to laeyrIdx
+#endif
 #else
       int apsId = 0;
 #endif
@@ -2134,7 +2155,11 @@ void EncGOP::xPicInitLMCS(Picture *pic, Slice *slice)
 #endif
     {
 #if JVET_N0278_FIXES
+#if JVET_O1159_SCALABILITY
+      int apsId = std::min<int>( 3, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) );
+#else
       int apsId = std::min<int>( 3, m_pcEncLib->getLayerId() ); //VS: layerId should be converted to laeyrIdx
+#endif
 #else
       int apsId = 0;
 #endif
@@ -2434,12 +2459,24 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     }
 
     if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 ||
-        (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) ))
+        (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) )
+#if JVET_O1159_SCALABILITY
+      || ( !pcSlice->isIRAP() && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers( pcSlice->getPic()->cs->vps->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) ) )
+#endif
+      )
     {
+#if JVET_O1159_SCALABILITY
+      xCreateExplicitReferencePictureSetFromReference( pcSlice, rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1() );
+#else
       pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1());
+#endif
     }
 
+#if JVET_O1159_SCALABILITY
+    pcSlice->applyReferencePictureListBasedMarking( rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1(), pcSlice->getPic()->layerId );
+#else
     pcSlice->applyReferencePictureListBasedMarking(rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1());
+#endif
 
     if(pcSlice->getTLayer() > 0
       && !(pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL     // Check if not a leading picture
@@ -2449,6 +2486,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     if (pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
       {
         bool isSTSA=true;
+
+#if JVET_O1159_SCALABILITY
+        if( !m_pcEncLib->getVPS()->getAllIndependentLayersFlag() && m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) )
+        {
+          isSTSA = false;
+        }
+#endif
+
         for(int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
         {
           int lTid = m_pcCfg->getRPLEntry(0, ii).m_temporalId;
@@ -2993,7 +3038,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 #endif
 
 #if JVET_N0278_FIXES
+#if JVET_O1159_SCALABILITY
+      int apsId = std::min<int>( 7, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) );
+#else
       int apsId = std::min<int>( 7, m_pcEncLib->getLayerId() ); //VS: layerId should be converted to laeyrIdx
+#endif
 #else
       int apsId = 0;
 #endif
@@ -3106,7 +3155,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 #endif
 
 #if JVET_N0278_FIXES
+#if JVET_O1159_SCALABILITY
+        int apsId = std::min<int>( 3, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) );
+#else
         int apsId = std::min<int>( 3, m_pcEncLib->getLayerId() ); //VS: layerId should be converted to laeyrIdx
+#endif
 #else
         int apsId = 0;
 #endif
@@ -3313,7 +3366,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       }
 
 #if JVET_N0278_FIXES
+#if JVET_O1159_SCALABILITY
+      int layerIdx = m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() );
+#else
       int layerIdx = m_pcEncLib->getLayerId(); //VS: convert layerId to layerIdx after VPS is implemented
+#endif
 
       // it is assumed that layerIdx equal to 0 is always present
       actualTotalBits += xWriteParameterSets( accessUnit, pcSlice, writePS && !layerIdx );
@@ -4689,6 +4746,15 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
           else
             msg( NOTICE, "%d ", pcSlice->getRefPOC( RefPicList( iRefList ), iRefIndex ) );
         }
+
+#if JVET_O1159_SCALABILITY
+        if( pcSlice->getRefPOC( RefPicList( iRefList ), iRefIndex ) == pcSlice->getPOC() )
+        {
+          msg( NOTICE, ".%d", pcSlice->getRefPic( RefPicList( iRefList ), iRefIndex )->layerId );
+        }
+#endif
+
+        msg( NOTICE, " " );
       }
       msg( NOTICE, "]" );
     }
@@ -5493,4 +5559,275 @@ void EncGOP::applyDeblockingFilterParameterSelection( Picture* pcPic, const uint
   }
 }
 #endif
+
+#if JVET_O1159_SCALABILITY
+void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicList& rcListPic, const ReferencePictureList *rpl0, const ReferencePictureList *rpl1 )
+{
+  Picture* rpcPic;
+  int pocCycle = 0;
+
+  Picture* pic = slice->getPic();
+  const VPS* vps = slice->getPic()->cs->vps;
+  int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx( pic->layerId );
+
+  ReferencePictureList* pLocalRPL0 = slice->getLocalRPL0();
+  *pLocalRPL0 = ReferencePictureList( slice->getSPS()->getInterLayerPresentFlag() );
+
+  uint32_t numOfSTRPL0 = 0;
+  uint32_t numOfLTRPL0 = 0;
+  uint32_t numOfILRPL0 = 0;
+  uint32_t numOfRefPic = rpl0->getNumberOfShorttermPictures() + rpl0->getNumberOfLongtermPictures();
+  uint32_t refPicIdxL0 = 0;
+
+  for( int ii = 0; ii < numOfRefPic; ii++ )
+  {
+    // loop through all pictures in the reference picture buffer
+    PicList::iterator iterPic = rcListPic.begin();
+    bool isAvailable = false;
+
+    pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() );
+    while( iterPic != rcListPic.end() )
+    {
+      rpcPic = *( iterPic++ );
+
+      if( rpcPic->layerId == pic->layerId )
+      {
+        if( !rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
+        {
+          isAvailable = true;
+          break;
+        }
+        else if( rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
+        {
+          isAvailable = true;
+          break;
+        }
+      }
+    }
+
+    if( isAvailable )
+    {
+      pLocalRPL0->setRefPicIdentifier( refPicIdxL0, rpl0->getRefPicIdentifier( ii ), rpl0->isRefPicLongterm( ii ), false, NOT_VALID );
+      refPicIdxL0++;
+      numOfSTRPL0 = numOfSTRPL0 + ( ( rpl0->isRefPicLongterm( ii ) ) ? 0 : 1 );
+      numOfLTRPL0 += ( rpl0->isRefPicLongterm( ii ) && !rpl0->isInterLayerRefPic( ii ) ) ? 1 : 0;
+      isAvailable = false;
+    }
+  }
+
+  // inter-layer reference pictures are added to the end of the reference picture list
+  if( layerIdx && vps && !vps->getAllIndependentLayersFlag() )
+  {
+    numOfRefPic = rpl0->getNumberOfInterLayerPictures() ? rpl0->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx );
+
+    for( int ii = 0; ii < numOfRefPic; ii++ )
+    {
+      // loop through all pictures in the reference picture buffer
+      PicList::iterator iterPic = rcListPic.begin();
+
+      while( iterPic != rcListPic.end() )
+      {
+        rpcPic = *( iterPic++ );
+        int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
+
+        if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) )
+        {          
+          pLocalRPL0->setRefPicIdentifier( refPicIdxL0, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
+          refPicIdxL0++;
+          numOfILRPL0++;
+          break;
+        }
+      }
+    }
+  }
+
+  if( slice->getEnableDRAPSEI() )
+  {
+    pLocalRPL0->setNumberOfShorttermPictures( numOfSTRPL0 );
+    pLocalRPL0->setNumberOfLongtermPictures( numOfLTRPL0 );
+    pLocalRPL0->setNumberOfInterLayerPictures( numOfILRPL0 );
+
+    if( !slice->isIRAP() && !slice->isPOCInRefPicList( pLocalRPL0, slice->getAssociatedIRAPPOC() ) )
+    {
+      if( slice->getUseLTforDRAP() && !slice->isPOCInRefPicList( rpl1, slice->getAssociatedIRAPPOC() ) )
+      {
+        // Adding associated IRAP as longterm picture
+        pLocalRPL0->setRefPicIdentifier( refPicIdxL0, slice->getAssociatedIRAPPOC(), true, false, 0 );
+        refPicIdxL0++;
+        numOfLTRPL0++;
+      }
+      else
+      {
+        // Adding associated IRAP as shortterm picture
+        pLocalRPL0->setRefPicIdentifier( refPicIdxL0, slice->getPOC() - slice->getAssociatedIRAPPOC(), false, false, 0 );
+        refPicIdxL0++;
+        numOfSTRPL0++;
+      }
+    }
+  }
+
+  ReferencePictureList* pLocalRPL1 = slice->getLocalRPL1();
+  *pLocalRPL1 = ReferencePictureList( slice->getSPS()->getInterLayerPresentFlag() );
+
+  uint32_t numOfSTRPL1 = 0;
+  uint32_t numOfLTRPL1 = 0;
+  uint32_t numOfILRPL1 = 0;
+  numOfRefPic = rpl1->getNumberOfShorttermPictures() + rpl1->getNumberOfLongtermPictures();
+  uint32_t refPicIdxL1 = 0;
+
+  for( int ii = 0; ii < numOfRefPic; ii++ )
+  {
+    // loop through all pictures in the reference picture buffer
+    PicList::iterator iterPic = rcListPic.begin();
+    bool isAvailable = false;
+    pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() );
+    while( iterPic != rcListPic.end() )
+    {
+      rpcPic = *( iterPic++ );
+
+      if( rpcPic->layerId == pic->layerId )
+      {
+        if( !rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
+        {
+          isAvailable = true;
+          break;
+        }
+        else if( rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
+        {
+          isAvailable = true;
+          break;
+        }
+      }      
+    }
+
+    if( isAvailable )
+    {
+      pLocalRPL1->setRefPicIdentifier( refPicIdxL1, rpl1->getRefPicIdentifier( ii ), rpl1->isRefPicLongterm( ii ), false, NOT_VALID );
+      refPicIdxL1++;
+      numOfSTRPL1 = numOfSTRPL1 + ( ( rpl1->isRefPicLongterm( ii ) ) ? 0 : 1 );
+      numOfLTRPL1 += ( rpl1->isRefPicLongterm( ii ) && !rpl1->isInterLayerRefPic( ii ) ) ? 1 : 0;
+      isAvailable = false;
+    }
+  }
+
+  
+  // inter-layer reference pictures are added to the end of the reference picture list
+  if( layerIdx && vps && !vps->getAllIndependentLayersFlag() )
+  {
+    numOfRefPic = rpl1->getNumberOfInterLayerPictures() ? rpl1->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx );
+
+    for( int ii = 0; ii < numOfRefPic; ii++ )
+    {
+      // loop through all pictures in the reference picture buffer
+      PicList::iterator iterPic = rcListPic.begin();
+
+      while( iterPic != rcListPic.end() )
+      {
+        rpcPic = *( iterPic++ );
+        int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
+
+        if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) )
+        {
+          pLocalRPL1->setRefPicIdentifier( refPicIdxL1, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
+          refPicIdxL1++;
+          numOfILRPL1++;
+          break;
+        }
+      }
+    }
+  }
+
+  //Copy from L1 if we have less than active ref pic
+  int numOfNeedToFill = rpl0->getNumberOfActivePictures() - (numOfLTRPL0 + numOfSTRPL0);
+  bool isDisallowMixedRefPic = ( slice->getSPS()->getAllActiveRplEntriesHasSameSignFlag() ) ? true : false;
+  int originalL0StrpNum = numOfSTRPL0;
+  int originalL0LtrpNum = numOfLTRPL0;
+  int originalL0IlrpNum = numOfILRPL0;
+
+  for( int ii = 0; numOfNeedToFill > 0 && ii < ( pLocalRPL1->getNumberOfLongtermPictures() + pLocalRPL1->getNumberOfShorttermPictures() + pLocalRPL1->getNumberOfInterLayerPictures() ); ii++ )
+  {
+    if( ii <= ( numOfLTRPL1 + numOfSTRPL1 + numOfILRPL1 - 1 ) )
+    {
+      //Make sure this copy is not already in L0
+      bool canIncludeThis = true;
+      for( int jj = 0; jj < refPicIdxL0; jj++ )
+      {
+        if( ( pLocalRPL1->getRefPicIdentifier( ii ) == pLocalRPL0->getRefPicIdentifier( jj ) ) && ( pLocalRPL1->isRefPicLongterm( ii ) == pLocalRPL0->isRefPicLongterm( jj ) ) && pLocalRPL1->getInterLayerRefPicIdx( ii ) == pLocalRPL0->getInterLayerRefPicIdx( jj ) )
+        {
+          canIncludeThis = false;
+        }
+
+        bool sameSign = ( pLocalRPL1->getRefPicIdentifier( ii ) > 0 ) == ( pLocalRPL0->getRefPicIdentifier( 0 ) > 0 );
+
+        if( isDisallowMixedRefPic && canIncludeThis && !pLocalRPL1->isRefPicLongterm( ii ) && !sameSign )
+        {
+          canIncludeThis = false;
+        }
+      }
+      if( canIncludeThis )
+      {
+        pLocalRPL0->setRefPicIdentifier( refPicIdxL0, pLocalRPL1->getRefPicIdentifier( ii ), pLocalRPL1->isRefPicLongterm( ii ), pLocalRPL1->isInterLayerRefPic( ii ), pLocalRPL1->getInterLayerRefPicIdx( ii ) );
+        refPicIdxL0++;
+        numOfSTRPL0 = numOfSTRPL0 + ( ( pLocalRPL1->isRefPicLongterm( ii ) ) ? 0 : 1 );
+        numOfLTRPL0 += ( pLocalRPL1->isRefPicLongterm( ii ) && !pLocalRPL1->isInterLayerRefPic( ii ) ) ? 1 : 0;
+        numOfILRPL0 += pLocalRPL1->isInterLayerRefPic( ii ) ? 1 : 0;
+        numOfNeedToFill--;
+      }
+    }
+  }
+  pLocalRPL0->setNumberOfLongtermPictures( numOfLTRPL0 );
+  pLocalRPL0->setNumberOfShorttermPictures( numOfSTRPL0 );
+  pLocalRPL0->setNumberOfInterLayerPictures( numOfILRPL0 );
+  int numPics = numOfLTRPL0 + numOfSTRPL0;
+
+  pLocalRPL0->setNumberOfActivePictures( ( numPics < rpl0->getNumberOfActivePictures() ? numPics : rpl0->getNumberOfActivePictures() ) + numOfILRPL0 );
+  pLocalRPL0->setLtrpInSliceHeaderFlag( rpl0->getLtrpInSliceHeaderFlag() );
+  slice->setRPL0idx( -1 );
+  slice->setRPL0( pLocalRPL0 );
+
+  //Copy from L0 if we have less than active ref pic
+  numOfNeedToFill = pLocalRPL0->getNumberOfActivePictures() - ( numOfLTRPL1 + numOfSTRPL1 );
+
+  for( int ii = 0; numOfNeedToFill > 0 && ii < ( pLocalRPL0->getNumberOfLongtermPictures() + pLocalRPL0->getNumberOfShorttermPictures() + pLocalRPL0->getNumberOfInterLayerPictures() ); ii++ )
+  {
+    if( ii <= ( originalL0StrpNum + originalL0LtrpNum + originalL0IlrpNum - 1 ) )
+    {
+      //Make sure this copy is not already in L0
+      bool canIncludeThis = true;
+      for( int jj = 0; jj < refPicIdxL1; jj++ )
+      {
+        if( ( pLocalRPL0->getRefPicIdentifier( ii ) == pLocalRPL1->getRefPicIdentifier( jj ) ) && ( pLocalRPL0->isRefPicLongterm( ii ) == pLocalRPL1->isRefPicLongterm( jj ) ) && pLocalRPL0->getInterLayerRefPicIdx( ii ) == pLocalRPL1->getInterLayerRefPicIdx( jj ) )
+        {
+          canIncludeThis = false;
+        }
+
+        bool sameSign = ( pLocalRPL0->getRefPicIdentifier( ii ) > 0 ) == ( pLocalRPL1->getRefPicIdentifier( 0 ) > 0 );
+
+        if( isDisallowMixedRefPic && canIncludeThis && !pLocalRPL0->isRefPicLongterm( ii ) && !sameSign )
+        {
+          canIncludeThis = false;
+        }
+      }
+      if( canIncludeThis )
+      {
+        pLocalRPL1->setRefPicIdentifier( refPicIdxL1, pLocalRPL0->getRefPicIdentifier( ii ), pLocalRPL0->isRefPicLongterm( ii ), pLocalRPL0->isInterLayerRefPic( ii ), pLocalRPL0->getInterLayerRefPicIdx( ii ) );
+        refPicIdxL1++;
+        numOfSTRPL1 = numOfSTRPL1 + ( ( pLocalRPL0->isRefPicLongterm( ii ) ) ? 0 : 1 );
+        numOfLTRPL1 += ( pLocalRPL0->isRefPicLongterm( ii ) && !pLocalRPL0->isInterLayerRefPic( ii ) ) ? 1 : 0;
+        numOfLTRPL1 += pLocalRPL0->isInterLayerRefPic( ii ) ? 1 : 0;
+        numOfNeedToFill--;
+      }
+    }
+  }
+  pLocalRPL1->setNumberOfLongtermPictures( numOfLTRPL1 );
+  pLocalRPL1->setNumberOfShorttermPictures( numOfSTRPL1 );
+  pLocalRPL1->setNumberOfInterLayerPictures( numOfILRPL1 );
+  numPics = numOfLTRPL1 + numOfSTRPL1;
+
+  pLocalRPL1->setNumberOfActivePictures( ( isDisallowMixedRefPic ? numPics : ( numPics < rpl1->getNumberOfActivePictures() ? numPics : rpl1->getNumberOfActivePictures() ) ) + numOfILRPL1 );
+  pLocalRPL1->setLtrpInSliceHeaderFlag( rpl1->getLtrpInSliceHeaderFlag() );
+  slice->setRPL1idx( -1 );
+  slice->setRPL1( pLocalRPL1 );
+}
+#endif
 //! \}
diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h
index 018e8273a1efa821ea4f8c009c9053c23a71b6ee..ea48063b958a0038fd91661184c6a106c2413cf0 100644
--- a/source/Lib/EncoderLib/EncGOP.h
+++ b/source/Lib/EncoderLib/EncGOP.h
@@ -330,7 +330,11 @@ protected:
 
   int xWriteVPS (AccessUnit &accessUnit, const VPS *vps);
   int xWriteDPS (AccessUnit &accessUnit, const DPS *dps);
+#if JVET_O1159_SCALABILITY
+  int xWriteSPS( AccessUnit &accessUnit, const SPS *sps, const int layerId = 0 );
+#else
   int xWriteSPS (AccessUnit &accessUnit, const SPS *sps);
+#endif
   int xWritePPS( AccessUnit &accessUnit, const PPS *pps, const SPS *sps, const int layerId = 0 );
 #if JVET_P0588_SUFFIX_APS
   int xWriteAPS( AccessUnit &accessUnit, APS *aps, const int layerId, const bool isPrefixNUT );
@@ -346,6 +350,9 @@ protected:
 #if W0038_DB_OPT
   void applyDeblockingFilterParameterSelection( Picture* pcPic, const uint32_t numSlices, const int gopID );
 #endif
+#if JVET_O1159_SCALABILITY
+  void xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicList& rcListPic, const ReferencePictureList *rpl0, const ReferencePictureList *rpl1 );
+#endif
 };// END CLASS DEFINITION EncGOP
 
 //! \}
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 8bdfaaf10a2b1c0ad35d7fbf43040d08d364c054..dd965fa4a7d316e28bf5c97875da03a04b629245 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -243,8 +243,16 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
   aps0.setAPSType( SCALING_LIST_APS );
 
   // initialize SPS
+#if JVET_O1159_SCALABILITY
+  xInitSPS( sps0, m_cVPS );
+#else
   xInitSPS(sps0);
+#endif
+#if JVET_P0185
+  xInitVPS(m_cVPS, sps0);
+#else
   xInitVPS(m_cVPS);
+#endif
 
   int dpsId = getDecodingParameterSetEnabled() ? 1 : 0;
   xInitDPS(m_dps, sps0, dpsId);
@@ -465,7 +473,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
 #endif
     picBg->getRecoBuf().fill(0);
 #if JVET_P1006_PICTURE_HEADER
+#if JVET_O1159_SCALABILITY
+    picBg->finalInit( &m_cVPS, sps0, pps0, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     picBg->finalInit( sps0, pps0, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
 #else
     picBg->finalInit( sps0, pps0, m_apss, m_lmcsAPS, m_scalinglistAPS );
 #endif
@@ -625,7 +637,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
 
     picCurr->M_BUFS( 0, PIC_ORIGINAL ).copyFrom( m_cGOPEncoder.getPicBg()->getRecoBuf() );
 #if JVET_P1006_PICTURE_HEADER
+#if JVET_O1159_SCALABILITY
+    picCurr->finalInit( &m_cVPS, *sps, *pps, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     picCurr->finalInit( *sps, *pps, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
 #else
     picCurr->finalInit( *sps, *pps, m_apss, m_lmcsAPS, m_scalinglistAPS );
 #endif
@@ -758,8 +774,12 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
       pcPicCurr->M_BUFS( 0, PIC_ORIGINAL ).swap( *pcPicYuvOrg );
       pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL ).swap( *cPicYuvTrueOrg );
     }
-#if JVET_P1006_PICTURE_HEADER    
+#if JVET_P1006_PICTURE_HEADER
+#if JVET_O1159_SCALABILITY
+    pcPicCurr->finalInit( &m_cVPS, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     pcPicCurr->finalInit( *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
 #else
     pcPicCurr->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS );
 #endif
@@ -1105,7 +1125,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicY
         const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
         const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );
 #if JVET_P1006_PICTURE_HEADER
+#if JVET_O1159_SCALABILITY
+        pcField->finalInit( &m_cVPS, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
         pcField->finalInit( *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
 #else
         pcField->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS );
 #endif
@@ -1392,18 +1416,26 @@ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Pict
   m_iNumPicRcvd++;
 }
 
-
-void EncLib::xInitVPS(VPS &vps)
+#if JVET_P0185
+void EncLib::xInitVPS(VPS& vps, const SPS& sps)
+#else
+void EncLib::xInitVPS(VPS& vps)
+#endif
 {
   // The SPS must have already been set up.
   // set the VPS profile information.
 #if !JVET_N0278_FIXES  
   vps.setMaxLayers(1);
 #endif
+#if !JVET_O1159_SCALABILITY
   for (uint32_t i = 0; i < vps.getMaxLayers(); i++)
   {
     vps.setVPSIncludedLayerId(0, i);
   }
+#endif
+#if JVET_P0185
+  vps.setMaxSubLayers(sps.getMaxTLayers());
+#endif
 }
 
 void EncLib::xInitDPS(DPS &dps, const SPS &sps, const int dpsId)
@@ -1422,8 +1454,11 @@ void EncLib::xInitDPS(DPS &dps, const SPS &sps, const int dpsId)
 #endif
 }
 
-
+#if JVET_O1159_SCALABILITY
+void EncLib::xInitSPS( SPS& sps, VPS& vps )
+#else
 void EncLib::xInitSPS(SPS &sps)
+#endif
 {
   ProfileTierLevel* profileTierLevel = sps.getProfileTierLevel();
   ConstraintInfo* cinfo = profileTierLevel->getConstraintInfo();
@@ -1482,7 +1517,9 @@ void EncLib::xInitSPS(SPS &sps)
   /* XXX: should Main be marked as compatible with still picture? */
   /* XXX: may be a good idea to refactor the above into a function
    * that chooses the actual compatibility based upon options */
-
+#if JVET_O1159_SCALABILITY
+  sps.setVPSId(m_cVPS.getVPSId());
+#endif
   sps.setMaxPicWidthInLumaSamples( m_iSourceWidth );
   sps.setMaxPicHeightInLumaSamples( m_iSourceHeight );
   sps.setMaxCUWidth             ( m_maxCUWidth        );
@@ -1736,7 +1773,10 @@ void EncLib::xInitSPS(SPS &sps)
   }
 #endif
 
-#if JVET_P0590_SCALING_WINDOW
+#if JVET_O1159_SCALABILITY
+  sps.setInterLayerPresentFlag( vps.getMaxLayers() > 1 && !vps.getAllIndependentLayersFlag() );
+  sps.setRprEnabledFlag( m_rprEnabled || sps.getInterLayerPresentFlag() );
+#elif JVET_P0590_SCALING_WINDOW
   sps.setRprEnabledFlag( m_rprEnabled );
 #endif
 }
@@ -2225,10 +2265,19 @@ void EncLib::xInitRPL(SPS &sps, bool isFieldCoding)
       rpl->setNumberOfLongtermPictures(0);   //Hardcoded as 0 for now. need to update this when implementing LTRP
       rpl->setNumberOfActivePictures(ge.m_numRefPicsActive);
       rpl->setLtrpInSliceHeaderFlag(ge.m_ltrp_in_slice_header_flag);
+#if JVET_O1159_SCALABILITY
+      rpl->setInterLayerPresentFlag( sps.getInterLayerPresentFlag() );
+      // inter-layer reference picture is not signaled in SPS RPL, SPS is shared currently
+      rpl->setNumberOfInterLayerPictures( 0 );
+#endif
 
       for (int k = 0; k < ge.m_numRefPics; k++)
       {
+#if JVET_O1159_SCALABILITY
+        rpl->setRefPicIdentifier( k, ge.m_deltaRefPics[k], 0, false, 0 );
+#else
         rpl->setRefPicIdentifier(k, ge.m_deltaRefPics[k], 0);
+#endif
       }
     }
   }
diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h
index 6bfa2db54c2fe68715839c8cdd789762f21b8e68..a7eebb41cbbd5da2d32e87344c51bebd2e3714ea 100644
--- a/source/Lib/EncoderLib/EncLib.h
+++ b/source/Lib/EncoderLib/EncLib.h
@@ -178,9 +178,17 @@ public:
 
 protected:
   void  xGetNewPicBuffer  ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Picture*& rpcPic, int ppsId ); ///< get picture buffer which will be processed. If ppsId<0, then the ppsMap will be queried for the first match.
-  void  xInitVPS          (VPS &vps); ///< initialize VPS from encoder options
+#if JVET_P0185
+  void  xInitVPS(VPS& vps, const SPS& sps); ///< initialize VPS from encoder options
+#else
+  void  xInitVPS(VPS& vps); ///< initialize VPS from encoder options
+#endif
   void  xInitDPS          (DPS &dps, const SPS &sps, const int dpsId); ///< initialize DPS from encoder options
+#if JVET_O1159_SCALABILITY
+  void  xInitSPS          ( SPS& sps, VPS& vps );       ///< initialize SPS from encoder options
+#else
   void  xInitSPS          (SPS &sps);                 ///< initialize SPS from encoder options
+#endif
   void  xInitPPS          (PPS &pps, const SPS &sps); ///< initialize PPS from encoder options
 #if JVET_P1006_PICTURE_HEADER
   void  xInitPicHeader    (PicHeader &picHeader, const SPS &sps, const PPS &pps); ///< initialize Picture Header from encoder options
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index d4dd73a9293d915d30c8e5734fb446a0b62850ce..c629f0fc5b2dfac47354413341ffbd6ceb4bda9f 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -1991,7 +1991,6 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
   else
   {
     CHECK( encTestmode.type != ETM_POST_DONT_SPLIT, "Unknown mode" );
-
     if ((cuECtx.get<double>(BEST_NO_IMV_COST) == (MAX_DOUBLE * .5) || cuECtx.get<bool>(IS_REUSING_CU)) && !slice.isIntra())
     {
       unsigned idx1, idx2, idx3, idx4;
@@ -2001,7 +2000,6 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
         m_pcInterSearch->insertUniMvCands(partitioner.currArea().Y(), g_reusedUniMVs[idx1][idx2][idx3][idx4]);
       }
     }
-
     if( !bestCS || ( bestCS && isModeSplit( bestMode ) ) )
     {
       return false;
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index d89acc46eee5180fbde18800991b982cc5146882..973f83e18808d5d2fb96c40b4e51bb9a01e8ed06 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -211,10 +211,17 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI,
   bufferingPeriodSEI->m_bpNalCpbParamsPresentFlag = true;
   bufferingPeriodSEI->m_bpVclCpbParamsPresentFlag = true;
   bufferingPeriodSEI->m_bpMaxSubLayers = m_pcCfg->getMaxTempLayer() ;
+#if JVET_P0446_BP_CPB_CNT_FIX
+  bufferingPeriodSEI->m_bpCpbCnt = 1;
+#endif
   for(int i=0; i < bufferingPeriodSEI->m_bpMaxSubLayers; i++)
   {
+#if !JVET_P0446_BP_CPB_CNT_FIX
     bufferingPeriodSEI->m_bpCpbCnt[i] = 1;
     for(int j=0; j < bufferingPeriodSEI->m_bpCpbCnt[i]; j++)
+#else
+    for(int j=0; j < bufferingPeriodSEI->m_bpCpbCnt; j++)
+#endif
     {
       bufferingPeriodSEI->m_initialCpbRemovalDelay[j][i][0] = uiInitialCpbRemovalDelay;
       bufferingPeriodSEI->m_initialCpbRemovalDelay[j][i][1] = uiInitialCpbRemovalDelay;
@@ -222,6 +229,13 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI,
       bufferingPeriodSEI->m_initialCpbRemovalOffset[j][i][1] = uiInitialCpbRemovalDelay;
     }
   }
+#if JVET_P0446_CONCATENATION
+  // We don't set concatenation_flag here. max_initial_removal_delay_for_concatenation depends on the usage scenario.
+  // The parameters could be added to config file, but as long as the initialisation of generic buffering parameters is
+  // not controllable, it does not seem to make sense to provide settings for these.
+  bufferingPeriodSEI->m_concatenationFlag = false;
+  bufferingPeriodSEI->m_maxInitialRemovalDelayForConcatenation = uiInitialCpbRemovalDelay;
+#endif
 
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI
 #if JVET_P1004_REMOVE_BRICKS
@@ -312,6 +326,15 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI,
         break;
     }
   }
+#if JVET_P0446_ALT_CPB
+  // A commercial encoder should track the buffer state for all layers and sub-layers
+  // to ensure CPB conformance. Such tracking is required for calculating alternative
+  // CPB parameters.
+  // Unfortunately VTM does not have such tracking. Thus we cannot encode alternative 
+  // CPB parameters here.
+  bufferingPeriodSEI->m_altCpbParamsPresentFlag = false;
+  bufferingPeriodSEI->m_useAltCpbParamsFlag = false;
+#endif
 }
 
 #if JVET_P0462_SEI360
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index bfc46b817cb366f42d14f727f5e6d85fc1c854ea..5a300a5dd8435d093a383d5ae08ba785489d1de5 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -387,6 +387,9 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
   WRITE_CODE( sei.m_cpbRemovalDelayLength - 1,        5, "cpb_removal_delay_length_minus1" );
   CHECK (sei.m_dpbOutputDelayLength < 1, "sei.m_dpbOutputDelayLength must be > 0");
   WRITE_CODE( sei.m_dpbOutputDelayLength - 1,         5, "dpb_output_delay_length_minus1" );
+#if JVET_P0446_ALT_CPB
+  WRITE_FLAG(sei.m_altCpbParamsPresentFlag, "alt_cpb_params_present_flag");
+#endif
   WRITE_FLAG( sei.m_bpDecodingUnitHrdParamsPresentFlag, "bp_decoding_unit_hrd_params_present_flag"  );
   if( sei.m_bpDecodingUnitHrdParamsPresentFlag )
   {
@@ -416,6 +419,13 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
 #endif
 
   WRITE_FLAG( sei.m_concatenationFlag, "concatenation_flag");
+#if JVET_P0446_CONCATENATION
+  WRITE_FLAG( sei.m_additionalConcatenationInfoPresentFlag, "additional_concatenation_info_present_flag");
+  if (sei.m_additionalConcatenationInfoPresentFlag)
+  {
+    WRITE_CODE( sei.m_maxInitialRemovalDelayForConcatenation, sei.m_initialCpbRemovalDelayLength, "max_initial_removal_delay_for_concatenation" );
+  }
+#endif
 
   CHECK (sei.m_auCpbRemovalDelayDelta < 1, "sei.m_auCpbRemovalDelayDelta must be > 0");
   WRITE_CODE( sei.m_auCpbRemovalDelayDelta - 1, sei.m_cpbRemovalDelayLength, "au_cpb_removal_delay_delta_minus1" );
@@ -432,6 +442,10 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
     CHECK (sei.m_bpMaxSubLayers < 1, "bp_max_sub_layers_minus1 must be > 0");
     WRITE_CODE( sei.m_bpMaxSubLayers - 1,        3, "bp_max_sub_layers_minus1" );
   }
+#if JVET_P0446_BP_CPB_CNT_FIX
+  CHECK (sei.m_bpCpbCnt < 1, "sei.m_bpCpbCnt must be > 0");
+  WRITE_UVLC( sei.m_bpCpbCnt - 1, "bp_cpb_cnt_minus1");
+#endif
 #if JVET_P0181
   WRITE_FLAG(sei.m_sublayerInitialCpbRemovalDelayPresentFlag, "sublayer_initial_cpb_removal_delay_present_flag");
   for (int i = (sei.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : sei.m_bpMaxSubLayers - 1); i < sei.m_bpMaxSubLayers; i++)
@@ -439,14 +453,20 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
   for (int i = 0; i < sei.m_bpMaxSubLayers; i++)
 #endif
   {
+#if !JVET_P0446_BP_CPB_CNT_FIX
     CHECK (sei.m_bpCpbCnt[i] < 1, "sei.m_bpCpbCnt[i] must be > 0");
     WRITE_UVLC( sei.m_bpCpbCnt[i] - 1, "bp_cpb_cnt_minus1[i]");
+#endif
     for( int nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
     {
       if( ( ( nalOrVcl == 0 ) && ( sei.m_bpNalCpbParamsPresentFlag ) ) ||
          ( ( nalOrVcl == 1 ) && ( sei.m_bpVclCpbParamsPresentFlag ) ) )
       {
+#if !JVET_P0446_BP_CPB_CNT_FIX
         for( int j = 0; j < sei.m_bpCpbCnt[i]; j ++ )
+#else
+        for( int j = 0; j < sei.m_bpCpbCnt; j ++ )
+#endif
         {
           WRITE_CODE( sei.m_initialCpbRemovalDelay[j][i][nalOrVcl],  sei.m_initialCpbRemovalDelayLength,           "initial_cpb_removal_delay[j][i][nalOrVcl]" );
           WRITE_CODE( sei.m_initialCpbRemovalOffset[j][i][nalOrVcl], sei.m_initialCpbRemovalDelayLength,           "initial_cpb_removal_delay_offset[j][i][nalOrVcl]" );
@@ -454,6 +474,13 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
       }
     }
   }
+#if JVET_P0446_ALT_CPB
+  if (sei.m_altCpbParamsPresentFlag)
+  {
+    WRITE_FLAG(sei.m_useAltCpbParamsFlag, "use_alt_cpb_params_flag");
+  }
+#endif
+
 }
 
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI 
@@ -465,6 +492,22 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *s
   
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI 
   WRITE_CODE( sei.m_auCpbRemovalDelay[bp.m_bpMaxSubLayers - 1] - 1, bp.m_cpbRemovalDelayLength,               "cpb_removal_delay_minus1[bp_max_sub_layers_minus1]" );
+#if JVET_P0446_ALT_CPB
+  if( bp.m_altCpbParamsPresentFlag ) 
+  {
+    WRITE_FLAG( sei.m_cpbAltTimingInfoPresentFlag, "cpb_alt_timing_info_present_flag" );
+    if( sei.m_cpbAltTimingInfoPresentFlag ) 
+    {
+      for( int i = 0; i < bp.m_bpCpbCnt; i++ ) 
+      {
+        WRITE_CODE( sei.m_cpbAltInitialCpbRemovalDelayDelta[i], bp.m_initialCpbRemovalDelayLength, "cpb_alt_initial_cpb_removal_delay_delta[ i ]" );
+        WRITE_CODE( sei.m_cpbAltInitialCpbRemovalOffsetDelta[i], bp.m_initialCpbRemovalDelayLength, "cpb_alt_initial_cpb_removal_offset_delta[ i ]" );
+      }
+      WRITE_CODE( sei.m_cpbDelayOffset, bp.m_initialCpbRemovalDelayLength, "cpb_delay_offset" );
+      WRITE_CODE( sei.m_dpbDelayOffset, bp.m_initialCpbRemovalDelayLength, "dpb_delay_offset" );
+    }
+  }
+#endif
   for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ )
   {
     WRITE_FLAG( sei.m_ptSubLayerDelaysPresentFlag[i], "pt_sub_layer_delays_present_flag[i]" );
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 2b8341f36dd56ab4a60fa22650e354110b12e663..128572dec6bba59dbb1350506ce15c50eff55640 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -185,8 +185,14 @@ void AUDWriter::codeAUD(OutputBitstream& bs, const int pictureType)
 
 void HLSWriter::xCodeRefPicList( const ReferencePictureList* rpl, bool isLongTermPresent, uint32_t ltLsbBitsCount, const bool isForbiddenZeroDeltaPoc )
 {
+#if JVET_O1159_SCALABILITY
+  uint32_t numRefPic = rpl->getNumberOfShorttermPictures() + rpl->getNumberOfLongtermPictures() + rpl->getNumberOfInterLayerPictures();
+  WRITE_UVLC( numRefPic, "num_ref_entries[ listIdx ][ rplsIdx ]" );
+#else
   WRITE_UVLC(rpl->getNumberOfShorttermPictures() + rpl->getNumberOfLongtermPictures(), "num_ref_entries[ listIdx ][ rplsIdx ]");
   uint32_t numRefPic = rpl->getNumberOfShorttermPictures() + rpl->getNumberOfLongtermPictures();
+#endif
+
   if (isLongTermPresent)
   {
     WRITE_FLAG(rpl->getLtrpInSliceHeaderFlag(), "ltrp_in_slice_header_flag[ listIdx ][ rplsIdx ]");
@@ -196,8 +202,26 @@ void HLSWriter::xCodeRefPicList( const ReferencePictureList* rpl, bool isLongTer
   bool firstSTRP = true;
   for (int ii = 0; ii < numRefPic; ii++)
   {
-    if (isLongTermPresent)
-      WRITE_FLAG(!rpl->isRefPicLongterm(ii), "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]");
+#if JVET_O1159_SCALABILITY
+    if( rpl->getInterLayerPresentFlag() )
+    {
+      WRITE_FLAG( rpl->isInterLayerRefPic( ii ), "inter_layer_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]" );
+
+      if( rpl->isInterLayerRefPic( ii ) )
+      {
+        CHECK( rpl->getInterLayerRefPicIdx( ii ) < 0, "Wrong inter-layer reference index" );
+        WRITE_UVLC( rpl->getInterLayerRefPicIdx( ii ), "ilrp_idx[ listIdx ][ rplsIdx ][ i ]" );
+      }
+    }
+
+    if( !rpl->isInterLayerRefPic( ii ) )
+    {
+#endif
+    if( isLongTermPresent )
+    {
+      WRITE_FLAG( !rpl->isRefPicLongterm( ii ), "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]" );
+    }
+
     if (!rpl->isRefPicLongterm(ii))
     {
       if (firstSTRP)
@@ -225,6 +249,9 @@ void HLSWriter::xCodeRefPicList( const ReferencePictureList* rpl, bool isLongTer
     {
       WRITE_CODE(rpl->getRefPicIdentifier(ii), ltLsbBitsCount, "poc_lsb_lt[listIdx][rplsIdx][i]");
     }
+#if JVET_O1159_SCALABILITY
+    }
+#endif
   }
 }
 
@@ -307,7 +334,15 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
      
     // rectangular slice signalling
     WRITE_FLAG( pcPPS->getRectSliceFlag( ) ? 1 : 0, "rect_slice_flag");
-    if( pcPPS->getRectSliceFlag() ) 
+#if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
+    if (pcPPS->getRectSliceFlag())
+    {
+      WRITE_FLAG(pcPPS->getSingleSlicePerSubPicFlag( ) ? 1 : 0, "single_slice_per_subpic_flag");
+    }
+    if (pcPPS->getRectSliceFlag() & !(pcPPS->getSingleSlicePerSubPicFlag()))
+#else
+    if (pcPPS->getRectSliceFlag())
+#endif 
     {      
       WRITE_UVLC( pcPPS->getNumSlicesInPic( ) - 1, "num_slices_in_pic_minus1" );
       WRITE_FLAG( pcPPS->getTileIdxDeltaPresentFlag( ) ? 1 : 0, "tile_idx_delta_present_flag");
@@ -1001,6 +1036,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   }
   CHECK( pcSPS->getMaxCUWidth() != pcSPS->getMaxCUHeight(),                          "Rectangular CTUs not supported" );
   WRITE_FLAG(pcSPS->getLongTermRefsPresent() ? 1 : 0, "long_term_ref_pics_flag");
+#if JVET_O1159_SCALABILITY
+  WRITE_FLAG( pcSPS->getInterLayerPresentFlag() ? 1 : 0, "inter_layer_ref_pics_present_flag" );
+#endif 
 #if JVET_P2001_SYNTAX_ORDER_MISMATCHES
   WRITE_FLAG(pcSPS->getIDRRefParamListPresent() ? 1 : 0, "sps_idr_rpl_present_flag" );
 #endif
@@ -1445,13 +1483,68 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
   xTraceVPSHeader();
 #endif
   WRITE_CODE(pcVPS->getVPSId(), 4, "vps_video_parameter_set_id");
+#if JVET_O1159_SCALABILITY
+  WRITE_CODE(pcVPS->getMaxLayers() - 1, 6, "vps_max_layers_minus1");
+  WRITE_CODE(pcVPS->getMaxSubLayers() - 1, 3, "vps_max_sublayers_minus1");
+  if (pcVPS->getMaxLayers() > 1 && pcVPS->getMaxSubLayers() > 1) 
+  {
+    WRITE_FLAG(pcVPS->getAllLayersSameNumSublayersFlag(), "vps_all_layers_same_num_sublayers_flag");
+  }
+  if (pcVPS->getMaxLayers() > 1)
+  {
+    WRITE_FLAG(pcVPS->getAllIndependentLayersFlag(), "vps_all_independent_layers_flag");
+  }
+  for (uint32_t i = 0; i < pcVPS->getMaxLayers(); i++)
+  {
+    WRITE_CODE(pcVPS->getLayerId(i), 6, "vps_layer_id");
+    if (i > 0 && !pcVPS->getAllIndependentLayersFlag())
+    {
+      WRITE_FLAG(pcVPS->getIndependentLayerFlag(i), "vps_independent_layer_flag");
+      if (!pcVPS->getIndependentLayerFlag(i))
+      {
+        for (int j = 0; j < i; j++)
+        {
+          WRITE_FLAG(pcVPS->getDirectRefLayerFlag(i, j), "vps_direct_dependency_flag");
+        }
+      }
+    }
+  }
+  if( pcVPS->getMaxLayers() > 1 )
+  {
+    if (pcVPS->getAllIndependentLayersFlag()) 
+    {
+      WRITE_FLAG(pcVPS->getEachLayerIsAnOlsFlag(), "vps_each_layer_is_an_ols_flag");
+    }
+    if (!pcVPS->getEachLayerIsAnOlsFlag()) 
+    {
+      if (!pcVPS->getAllIndependentLayersFlag()) {
+        WRITE_CODE(pcVPS->getOlsModeIdc(), 2, "vps_ols_mode_idc");
+      }
+      if (pcVPS->getOlsModeIdc() == 2)
+      {
+        WRITE_CODE(pcVPS->getNumOutputLayerSets() - 1, 8, "vps_num_output_layer_sets_minus1");
+        for (uint32_t i = 1; i < pcVPS->getNumOutputLayerSets(); i++)
+        {
+          for (uint32_t j = 0; j < pcVPS->getMaxLayers(); j++)
+          {
+            WRITE_FLAG(pcVPS->getOlsOutputLayerFlag(i, j), "vps_ols_output_layer_flag");
+          }
+        }
+      }
+    }
+  }
+#else
   WRITE_CODE(pcVPS->getMaxLayers() - 1, 8, "vps_max_layers_minus1");
+#if JVET_P0185
+  CHECK(pcVPS->getMaxSubLayers() < 1 || pcVPS->getMaxSubLayers() > 7, "vps_max_sub_layers_minus1 must be in range 0..6");
+  WRITE_CODE(pcVPS->getMaxSubLayers() - 1, 3, "vps_max_sub_layers_minus1");
+#endif
   for (uint32_t i = 0; i <= pcVPS->getMaxLayers() - 1; i++)
   {
     WRITE_CODE(pcVPS->getVPSIncludedLayerId(i), 7, "vps_included_layer_id");
     WRITE_FLAG(0, "vps_reserved_zero_1bit");
   }
-
+#endif
   WRITE_FLAG(0, "vps_extension_flag");
 
   //future extensions here..
diff --git a/source/Lib/Utilities/program_options_lite.h b/source/Lib/Utilities/program_options_lite.h
index 23aa1803f25d985545e945edfe782e36ebf15323..8375a2aa77ef03ffc8d4a2119811ce654a3da501 100644
--- a/source/Lib/Utilities/program_options_lite.h
+++ b/source/Lib/Utilities/program_options_lite.h
@@ -232,7 +232,63 @@ namespace df
         parent.addOption(new Option<T>(name, storage, default_val, desc));
         return *this;
       }
+#if 1 //JVET_O1159_SCALABILITY
+      template<typename T>
+      OptionSpecific&
+        operator()(const std::string& name, T* storage, T default_val, unsigned uiMaxNum, const std::string& desc = "")
+      {
+        std::string cNameBuffer;
+        std::string cDescriptionBuffer;
+
+        for (unsigned int uiK = 0; uiK < uiMaxNum; uiK++)
+        {
+          // it needs to be reset when extra digit is added, e.g. number 10 and above
+          cNameBuffer.resize(name.size() + 10);
+          cDescriptionBuffer.resize(desc.size() + 10);
+
+          // isn't there are sprintf function for string??
+          sprintf((char*)cNameBuffer.c_str(), name.c_str(), uiK, uiK);
+          sprintf((char*)cDescriptionBuffer.c_str(), desc.c_str(), uiK, uiK);
+
+          size_t pos = cNameBuffer.find_first_of('\0');
+          if (pos != std::string::npos)
+          {
+            cNameBuffer.resize(pos);
+          }
+
+          parent.addOption(new Option<T>(cNameBuffer, (storage[uiK]), default_val, cDescriptionBuffer));
+        }
+
+        return *this;
+      }
 
+      template<typename T>
+      OptionSpecific&
+        operator()(const std::string& name, T** storage, T default_val, unsigned uiMaxNum, const std::string& desc = "")
+      {
+        std::string cNameBuffer;
+        std::string cDescriptionBuffer;
+
+        for (unsigned int uiK = 0; uiK < uiMaxNum; uiK++)
+        {
+          // it needs to be reset when extra digit is added, e.g. number 10 and above
+          cNameBuffer.resize(name.size() + 10);
+          cDescriptionBuffer.resize(desc.size() + 10);
+
+          // isn't there are sprintf function for string??
+          sprintf((char*)cNameBuffer.c_str(), name.c_str(), uiK, uiK);
+          sprintf((char*)cDescriptionBuffer.c_str(), desc.c_str(), uiK, uiK);
+
+          size_t pos = cNameBuffer.find_first_of('\0');
+          if (pos != std::string::npos)
+            cNameBuffer.resize(pos);
+
+          parent.addOption(new Option<T>(cNameBuffer, *(storage[uiK]), default_val, cDescriptionBuffer));
+        }
+
+        return *this;
+      }
+#endif
       /**
        * Add option described by name to the parent Options list,
        *   with desc as an optional help description