diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 49bdad2c4452833e4cdb41a90687df8355493f26..ad40955451cad60555deb02d34d6bc26e59b6de8 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -388,6 +388,32 @@ void EncApp::xInitLibCfg()
 #endif
   m_cEncLib.setRDpenalty                                         ( m_rdPenalty );
   m_cEncLib.setCTUSize                                           ( m_uiCTUSize );
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  m_cEncLib.setSubPicPresentFlag                                 ( m_subPicPresentFlag );
+  if(m_subPicPresentFlag){
+    m_cEncLib.setNumSubPics                                      ( m_numSubPics );
+    for (int i = 0; i < m_numSubPics; i++)
+    {
+      m_cEncLib.setSubPicCtuTopLeftX                             ( m_subPicCtuTopLeftX[i], i );
+      m_cEncLib.setSubPicCtuTopLeftY                             ( m_subPicCtuTopLeftY[i], i );
+      m_cEncLib.setSubPicWidth                                   ( m_subPicWidth[i], i );
+      m_cEncLib.setSubPicHeight                                  ( m_subPicHeight[i], i );
+      m_cEncLib.setSubPicTreatedAsPicFlag                        ( m_subPicTreatedAsPicFlag[i], i );
+      m_cEncLib.setLoopFilterAcrossSubpicEnabledFlag             ( m_loopFilterAcrossSubpicEnabledFlag[i], i );
+    }
+  }
+  m_cEncLib.setSubPicIdPresentFlag                               ( m_subPicIdPresentFlag );
+  if (m_subPicIdPresentFlag) {
+    m_cEncLib.setSubPicIdSignallingPresentFlag                   ( m_subPicIdSignallingPresentFlag );
+    if(m_subPicIdSignallingPresentFlag){
+      m_cEncLib.setSubPicIdLen                                   ( m_subPicIdLen );
+      for (int i = 0; i < m_numSubPics; i++)
+      {
+        m_cEncLib.setSubPicId                                    ( m_subPicId[i], i );
+      }
+    }
+  }
+#endif
   m_cEncLib.setUseSplitConsOverride                              ( m_SplitConsOverrideEnabledFlag );
   m_cEncLib.setMinQTSizes                                        ( m_uiMinQT );
   m_cEncLib.setMaxMTTHierarchyDepth                              ( m_uiMaxMTTHierarchyDepth, m_uiMaxMTTHierarchyDepthI, m_uiMaxMTTHierarchyDepthIChroma );
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 3c90bde664c6c0580953828033fdf571063a7ead..4d5fad73751798026a0fcbc04e07e1eb1a43e9bc 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -923,7 +923,15 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<unsigned> cfg_virtualBoundariesPosY       (0, std::numeric_limits<uint32_t>::max(), 0, 3);
 
   SMultiValueInput<uint8_t> cfg_SubProfile(0, std::numeric_limits<uint8_t>::max(), 0, std::numeric_limits<uint8_t>::max());
-
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  SMultiValueInput<uint32_t>  cfg_subPicCtuTopLeftX(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS);
+  SMultiValueInput<uint32_t>  cfg_subPicCtuTopLeftY(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS);
+  SMultiValueInput<uint32_t>  cfg_subPicWidth(1, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS);
+  SMultiValueInput<uint32_t>  cfg_subPicHeight(1, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS);
+  SMultiValueInput<uint32_t>  cfg_subPicTreatedAsPicFlag(0, 1, 0, MAX_NUM_SUB_PICS);
+  SMultiValueInput<uint32_t>  cfg_loopFilterAcrossSubpicEnabledFlag(0, 1, 0, MAX_NUM_SUB_PICS);
+  SMultiValueInput<uint32_t>  cfg_subPicId(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS);
+#endif
   int warnUnknowParameter = 0;
 
 #if ENABLE_TRACING
@@ -1044,6 +1052,20 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("NonPackedSource",                                 m_nonPackedConstraintFlag,                        false, "Indicate that source does not contain frame packing")
   ("FrameOnly",                                       m_frameOnlyConstraintFlag,                        false, "Indicate that the bitstream contains only frames")
   ("CTUSize",                                         m_uiCTUSize,                                       128u, "CTUSize (specifies the CTU size if QTBT is on) [default: 128]")
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  ("SubPicPresentFlag",                               m_subPicPresentFlag,                              false, "equal to 1 specifies that subpicture parameters are present in in the SPS RBSP syntax")
+  ("NumSubPics",                                      m_numSubPics,                                        0u, "specifies the number of subpictures")
+  ("SubPicCtuTopLeftX",                               cfg_subPicCtuTopLeftX,            cfg_subPicCtuTopLeftX, "specifies horizontal position of top left CTU of i-th subpicture in unit of CtbSizeY")
+  ("SubPicCtuTopLeftY",                               cfg_subPicCtuTopLeftY,            cfg_subPicCtuTopLeftY, "specifies vertical position of top left CTU of i-th subpicture in unit of CtbSizeY")
+  ("SubPicWidth",                                     cfg_subPicWidth,                        cfg_subPicWidth, "specifies the width of the i-th subpicture in units of CtbSizeY")
+  ("SubPicHeight",                                    cfg_subPicHeight,                      cfg_subPicHeight, "specifies the height of the i-th subpicture in units of CtbSizeY")
+  ("SubPicTreatedAsPicFlag",                          cfg_subPicTreatedAsPicFlag,  cfg_subPicTreatedAsPicFlag, "equal to 1 specifies that the i-th subpicture of each coded picture in the CLVS is treated as a picture in the decoding process excluding in-loop filtering operations")
+  ("LoopFilterAcrossSubpicEnabledFlag",               cfg_loopFilterAcrossSubpicEnabledFlag, cfg_loopFilterAcrossSubpicEnabledFlag, "equal to 1 specifies that in-loop filtering operations may be performed across the boundaries of the i-th subpicture in each coded picture in the CLVS")
+  ("SubPicIdPresentFlag",                             m_subPicIdPresentFlag,                            false, "equal to 1 specifies that subpicture ID mapping is present in the SPS")
+  ("SubPicIdSignallingPresentFlag",                   m_subPicIdSignallingPresentFlag,                  false, "equal to 1 specifies that subpicture ID mapping is signalled in the SPS")
+  ("SubPicIdLen",                                     m_subPicIdLen,                                       0u, "specifies the number of bits used to represent the syntax element sps_subpic_id[ i ]. ")
+  ("SubPicId",                                        cfg_subPicId,                              cfg_subPicId, "specifies that subpicture ID of the i-th subpicture")
+#endif
   ("EnablePartitionConstraintsOverride",              m_SplitConsOverrideEnabledFlag,                    true, "Enable partition constraints override")
   ("MinQTISlice",                                     m_uiMinQT[0],                                        8u, "MinQTISlice")
   ("MinQTLumaISlice",                                 m_uiMinQT[0],                                        8u, "MinQTLumaISlice")
@@ -1894,7 +1916,28 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     //number of fields to encode
     m_framesToBeEncoded *= 2;
   }
-
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  if ( m_subPicPresentFlag )
+  {
+    CHECK( m_numSubPics > 255 || m_numSubPics < 1, "Number of subpicture must be within 1 to 255" );
+    m_subPicCtuTopLeftX                 = cfg_subPicCtuTopLeftX.values;
+    m_subPicCtuTopLeftY                 = cfg_subPicCtuTopLeftY.values;
+    m_subPicWidth                       = cfg_subPicWidth.values;
+    m_subPicHeight                      = cfg_subPicHeight.values;
+    m_subPicTreatedAsPicFlag            = cfg_subPicTreatedAsPicFlag.values;
+    m_loopFilterAcrossSubpicEnabledFlag = cfg_loopFilterAcrossSubpicEnabledFlag.values;
+    m_subPicId                          = cfg_subPicId.values;
+    for(int i = 0; i < m_numSubPics; i++){
+      CHECK(m_subPicCtuTopLeftX[i] + m_subPicWidth[i] > (m_iSourceWidth + m_uiCTUSize - 1) / m_uiCTUSize, "subpicture must not exceed picture boundary");
+      CHECK(m_subPicCtuTopLeftY[i] + m_subPicHeight[i] > (m_iSourceHeight + m_uiCTUSize - 1) / m_uiCTUSize, "subpicture must not exceed picture boundary");
+    }
+    if (m_subPicIdPresentFlag) {
+      if (m_subPicIdSignallingPresentFlag) {
+        CHECK( m_subPicIdLen > 16, "sibpic ID length must not exceed 16 bits" );
+      }
+    }
+  }
+#endif
 #if JVET_P1004_REMOVE_BRICKS
   if( m_picPartitionFlag ) 
   {
@@ -4329,6 +4372,28 @@ void EncAppCfg::xPrintParameter()
     msg( DETAILS, "Profile                                : %s\n", profileToString(m_profile) );
   }
   msg( DETAILS, "CU size / depth / total-depth          : %d / %d / %d\n", m_uiMaxCUWidth, m_uiMaxCUDepth, m_uiMaxCodingDepth );
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  msg(DETAILS, "subpicture present flag                            : %d\n", m_subPicPresentFlag);
+  if (m_subPicPresentFlag) {
+    msg(DETAILS, "number of subpictures                            : %d\n", m_numSubPics);
+    for (int i = 0; i < m_numSubPics; i++) {
+      msg(DETAILS, "[%d]th subpictures location                           :[%d %d]\n", i, m_subPicCtuTopLeftX[i], m_subPicCtuTopLeftY[i]);
+      msg(DETAILS, "[%d]th subpictures size                           :[%d %d]\n", i, m_subPicWidth[i], m_subPicHeight[i]);
+      msg(DETAILS, "[%d]th subpictures treated as picture flag                           :%d\n", i, m_subPicTreatedAsPicFlag);
+      msg(DETAILS, "loop filter cross [%d]th subpictures enabled flag                           :%d\n", i, m_loopFilterAcrossSubpicEnabledFlag);
+
+    }
+  }
+  msg(DETAILS, "subpicture ID present flag                            : %d\n", m_subPicIdPresentFlag);
+  if (m_subPicIdPresentFlag) {
+    msg(DETAILS, "subpicture ID signalling present flag                            : %d\n", m_subPicIdSignallingPresentFlag);
+    for (int i = 0; i < m_numSubPics; i++) {
+      msg(DETAILS, "[%d]th subpictures ID length                           :%d\n", i, m_subPicIdLen);
+      msg(DETAILS, "[%d]th subpictures ID                          :%d\n", i, m_subPicId);
+
+    }
+  }
+#endif
   msg( DETAILS, "Max TB size                            : %d \n", 1 << m_log2MaxTbSize );
   msg( DETAILS, "Motion search range                    : %d\n", m_iSearchRange );
   msg( DETAILS, "Intra period                           : %d\n", m_iIntraPeriod );
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 132fcb6640e7c4caeddcba5a31c5f42892aeb3e9..8f227d1d99144dc5d1198b6f28ddc12c5c23233f 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -276,6 +276,20 @@ protected:
 
   // coding unit (CU) definition
   unsigned  m_uiCTUSize;
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  bool m_subPicPresentFlag;
+  unsigned m_numSubPics;
+  std::vector<uint32_t> m_subPicCtuTopLeftX;
+  std::vector<uint32_t> m_subPicCtuTopLeftY;
+  std::vector<uint32_t> m_subPicWidth;
+  std::vector<uint32_t> m_subPicHeight;
+  std::vector<uint32_t> m_subPicTreatedAsPicFlag;
+  std::vector<uint32_t> m_loopFilterAcrossSubpicEnabledFlag;
+  bool m_subPicIdPresentFlag;
+  bool m_subPicIdSignallingPresentFlag;
+  unsigned m_subPicIdLen;
+  std::vector<uint32_t> m_subPicId;
+#endif
   bool      m_SplitConsOverrideEnabledFlag;
   unsigned  m_uiMinQT[3]; // 0: I slice luma; 1: P/B slice; 2: I slice chroma
   unsigned  m_uiMaxMTTHierarchyDepth;
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 237656a419f4d09f15cdd4e18fb036b083ad0e62..28ee3fb204511db918bca3d11d7c8cfb5bb97a22 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -1528,13 +1528,13 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
     READ_CODE(8, uiCode, "sps_num_subpics_minus1"); pcSPS->setNumSubPics(uiCode + 1);
     for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++)
     {
-      READ_CODE(ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_ctu_top_left_x[ i ]");
+      READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_ctu_top_left_x[ i ]");
       pcSPS->setSubPicCtuTopLeftX(picIdx, uiCode);
-      READ_CODE(ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_ctu_top_left_y[ i ]");
+      READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_ctu_top_left_y[ i ]");
       pcSPS->setSubPicCtuTopLeftY(picIdx, uiCode);
-      READ_CODE(ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_width_minus1[ i ]");
+      READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_width_minus1[ i ]");
       pcSPS->setSubPicWidth(picIdx, uiCode + 1);
-      READ_CODE(ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_height_minus1[ i ]");
+      READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_height_minus1[ i ]");
       pcSPS->setSubPicHeight(picIdx, uiCode + 1);
       READ_FLAG(uiCode, "subpic_treated_as_pic_flag[ i ]");
       pcSPS->setSubPicTreatedAsPicFlag(picIdx, uiCode);
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index a73aabaad7e1a706bac77846dde4c536466df621..1fddc05e28a9b8538989f06706ebc786eee21a79 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -273,6 +273,20 @@ protected:
 
   int       m_maxTempLayer;                      ///< Max temporal layer
   unsigned  m_CTUSize;
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  bool                  m_subPicPresentFlag;
+  unsigned              m_numSubPics;
+  uint32_t              m_subPicCtuTopLeftX[MAX_NUM_SUB_PICS];
+  uint32_t              m_subPicCtuTopLeftY[MAX_NUM_SUB_PICS];
+  uint32_t              m_subPicWidth[MAX_NUM_SUB_PICS];
+  uint32_t              m_subPicHeight[MAX_NUM_SUB_PICS];
+  uint32_t              m_subPicTreatedAsPicFlag[MAX_NUM_SUB_PICS];
+  uint32_t              m_loopFilterAcrossSubpicEnabledFlag[MAX_NUM_SUB_PICS];
+  bool                  m_subPicIdPresentFlag;
+  bool                  m_subPicIdSignallingPresentFlag;
+  unsigned              m_subPicIdLen;
+  uint32_t              m_subPicId[MAX_NUM_SUB_PICS];
+#endif
   bool      m_useSplitConsOverride;
   unsigned  m_uiMinQT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma
   unsigned  m_uiMaxMTTHierarchyDepth;
@@ -1040,7 +1054,33 @@ public:
   bool      getUseSplitConsOverride         ()         const { return m_useSplitConsOverride; }
   void      setDualITree                    ( bool b )       { m_dualITree = b; }
   bool      getDualITree                    ()         const { return m_dualITree; }
-
+#if JVET_P0171_SUBPICTURE_LAYOUT
+  void      setSubPicPresentFlag                        (bool b)                    { m_subPicPresentFlag = b; }
+  void      setNumSubPics                               (uint32_t u)                { m_numSubPics = u; }
+  void      setSubPicCtuTopLeftX                        (uint32_t u, int i)         { m_subPicCtuTopLeftX[i] = u; }
+  void      setSubPicCtuTopLeftY                        (uint32_t u, int i)         { m_subPicCtuTopLeftY[i] = u; }
+  void      setSubPicWidth                              (uint32_t u, int i)         { m_subPicWidth[i] = u; }
+  void      setSubPicHeight                             (uint32_t u, int i)         { m_subPicHeight[i] = u; }
+  void      setSubPicTreatedAsPicFlag                   (bool b, int i)             { m_subPicTreatedAsPicFlag[i] = b; }
+  void      setLoopFilterAcrossSubpicEnabledFlag        (uint32_t u, int i)         { m_loopFilterAcrossSubpicEnabledFlag[i] = u; }
+  void      setSubPicIdPresentFlag                      (bool b)                    { m_subPicIdPresentFlag = b; }
+  void      setSubPicIdSignallingPresentFlag            (bool b)                    { m_subPicIdSignallingPresentFlag = b; }
+  void      setSubPicIdLen                              (uint32_t u)                { m_subPicIdLen = u; }
+  void      setSubPicId                                 (uint32_t b, int i)         { m_subPicId[i] = b; }
+
+  bool      getSubPicPresentFlag                        ()                          { return m_subPicPresentFlag; }
+  uint32_t  getNumSubPics                               ()                          { return m_numSubPics; }
+  uint32_t  getSubPicCtuTopLeftX                        (int i)                     { return m_subPicCtuTopLeftX[i]; }
+  uint32_t  getSubPicCtuTopLeftY                        (int i)                     { return m_subPicCtuTopLeftY[i]; }
+  uint32_t  getSubPicWidth                              (int i)                     { return m_subPicWidth[i]; }
+  uint32_t  getSubPicHeight                             (int i)                     { return m_subPicHeight[i]; }
+  bool      getSubPicTreatedAsPicFlag                   (int i)                     { return m_subPicTreatedAsPicFlag[i]; }
+  uint32_t  getLoopFilterAcrossSubpicEnabledFlag        (int i)                     { return m_loopFilterAcrossSubpicEnabledFlag[i]; }
+  bool      getSubPicIdPresentFlag                      ()                          { return m_subPicIdPresentFlag; }
+  bool      getSubPicIdSignallingPresentFlag            ()                          { return m_subPicIdSignallingPresentFlag; }
+  uint32_t  getSubPicIdLen                              ()                          { return m_subPicIdLen; }
+  uint32_t  getSubPicId                                 (int i)                     { return m_subPicId[i]; }
+#endif
   void      setLFNST                        ( bool b )       { m_LFNST = b; }
   bool      getLFNST()                                 const { return m_LFNST; }
   void      setUseFastLFNST                 ( bool b )       { m_useFastLFNST = b; }
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 53c734c219f9122192aea730515251e92bcffd54..eb203b40cce89649c7bc81f49a8584f01fd1841b 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1686,20 +1686,29 @@ void EncLib::xInitSPS(SPS &sps)
 
 #if JVET_P1006_PICTURE_HEADER
 #if JVET_P0171_SUBPICTURE_LAYOUT
-  for (int picIdx = 0; picIdx < MAX_NUM_SUB_PICS; picIdx++) {
-    sps.setSubPicCtuTopLeftX(picIdx, 0);
-    sps.setSubPicCtuTopLeftY(picIdx, 0);
-    sps.setSubPicWidth(picIdx, ((sps.getMaxPicWidthInLumaSamples() + sps.getCTUSize() - 1)  >> floorLog2(sps.getCTUSize())));
-    sps.setSubPicHeight(picIdx, ((sps.getMaxPicHeightInLumaSamples() + sps.getCTUSize() - 1)  >> floorLog2(sps.getCTUSize())));
-    sps.setSubPicTreatedAsPicFlag(picIdx, 0);
-    sps.setLoopFilterAcrossSubpicEnabledFlag(picIdx, 1);
-  }
-#endif
-  sps.setSubPicIdSignallingPresentFlag(false);
-  sps.setSubPicIdLen(16);
-  for(int picIdx=0; picIdx<MAX_NUM_SUB_PICS; picIdx++)
-  {
-    sps.setSubPicId(picIdx, picIdx);
+  sps.setSubPicPresentFlag(m_subPicPresentFlag);
+  if (m_subPicPresentFlag) {
+    sps.setNumSubPics(m_numSubPics);
+    for (int i = 0; i < m_numSubPics; i++) {
+      sps.setSubPicCtuTopLeftX(i, m_subPicCtuTopLeftX[i] );
+      sps.setSubPicCtuTopLeftY(i, m_subPicCtuTopLeftY[i]);
+      sps.setSubPicWidth(i, m_subPicWidth[i]);
+      sps.setSubPicHeight(i, m_subPicHeight[i]);
+      sps.setSubPicTreatedAsPicFlag(i, m_subPicTreatedAsPicFlag[i]);
+      sps.setLoopFilterAcrossSubpicEnabledFlag(i, m_loopFilterAcrossSubpicEnabledFlag[i]);
+    }
+  }
+#endif
+  sps.setSubPicIdPresentFlag(m_subPicIdPresentFlag);
+  if (m_subPicIdPresentFlag) {
+    sps.setSubPicIdSignallingPresentFlag(m_subPicIdSignallingPresentFlag);
+    if (m_subPicIdSignallingPresentFlag){
+      sps.setSubPicIdLen(m_subPicIdLen);
+      for (int i = 0; i < m_numSubPics; i++)
+  {
+        sps.setSubPicId(i, m_subPicId[i]);
+      }
+    }
   }
 
   sps.setLoopFilterAcrossVirtualBoundariesDisabledFlag( m_loopFilterAcrossVirtualBoundariesDisabledFlag );
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 128572dec6bba59dbb1350506ce15c50eff55640..93b1e95af4f70425a78ebb45af01e06036b12077 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -969,10 +969,10 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
     WRITE_CODE(pcSPS->getNumSubPics() - 1, 8, "sps_num_subpics_minus1");
     for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++)
     {
-      WRITE_CODE( pcSPS->getSubPicCtuTopLeftX(picIdx), ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples()  +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize()))), "subpic_ctu_top_left_x[ i ]"  );
-      WRITE_CODE( pcSPS->getSubPicCtuTopLeftY(picIdx), ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize()))), "subpic_ctu_top_left_y[ i ]"  );
-      WRITE_CODE( pcSPS->getSubPicWidth(picIdx) - 1,   ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples()  +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize()))), "subpic_width_minus1[ i ]"    );
-      WRITE_CODE( pcSPS->getSubPicHeight(picIdx) - 1,  ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize()))), "subpic_height_minus1[ i ]"   );
+      WRITE_CODE( pcSPS->getSubPicCtuTopLeftX(picIdx), std::max(1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples()  +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize())))), "subpic_ctu_top_left_x[ i ]"  );
+      WRITE_CODE( pcSPS->getSubPicCtuTopLeftY(picIdx), std::max(1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize())))), "subpic_ctu_top_left_y[ i ]"  );
+      WRITE_CODE( pcSPS->getSubPicWidth(picIdx) - 1,   std::max(1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples()  +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize())))), "subpic_width_minus1[ i ]"    );
+      WRITE_CODE( pcSPS->getSubPicHeight(picIdx) - 1,  std::max(1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() +  pcSPS->getCTUSize() - 1)  >> floorLog2( pcSPS->getCTUSize())))), "subpic_height_minus1[ i ]"   );
       WRITE_FLAG( pcSPS->getSubPicTreatedAsPicFlag(picIdx),  "subpic_treated_as_pic_flag[ i ]" );
       WRITE_FLAG( pcSPS->getLoopFilterAcrossSubpicEnabledFlag(picIdx),  "loop_filter_across_subpic_enabled_flag[ i ]" );
     }