Index: branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 861)
+++ branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 862)
@@ -737,4 +737,13 @@
   ("SEISOPDescription",              m_SOPDescriptionSEIEnabled,              0, "Control generation of SOP description SEI messages")
   ("SEIScalableNesting",             m_scalableNestingSEIEnabled,              0, "Control generation of scalable nesting SEI messages")
+#if H_MV_HLS_7_SEI_P0204_26
+  ("SubBitstreamPropSEIEnabled",              m_subBistreamPropSEIEnabled,    false                     ,"Enable signaling of sub-bitstream property SEI message")
+  ("SEISubBitstreamNumAdditionalSubStreams",  m_sbPropNumAdditionalSubStreams,0, "Number of substreams for which additional information is signalled")
+  ("SEISubBitstreamSubBitstreamMode",         m_sbPropSubBitstreamMode,       std::vector< Int  >(1,0)  ,"Specifies mode of generation of the i-th sub-bitstream (0 or 1)")
+  ("SEISubBitstreamOutputLayerSetIdxToVps",   m_sbPropOutputLayerSetIdxToVps, std::vector< Int  >(1,0)  ,"Specifies output layer set index of the i-th sub-bitstream ")
+  ("SEISubBitstreamHighestSublayerId",        m_sbPropHighestSublayerId,      std::vector< Int  >(1,0)  ,"Specifies highest TemporalId of the i-th sub-bitstream")
+  ("SEISubBitstreamAvgBitRate",               m_sbPropAvgBitRate,             std::vector< Int  >(1,0)  ,"Specifies average bit rate of the i-th sub-bitstream")
+  ("SEISubBitstreamMaxBitRate",               m_sbPropMaxBitRate,             std::vector< Int  >(1,0)  ,"Specifies maximum bit rate of the i-th sub-bitstream")
+#endif
 #if H_3D
   ("CameraParameterFile,cpf", m_pchCameraParameterFile,    (Char *) 0, "Camera Parameter File Name")
@@ -2244,4 +2253,23 @@
   }
 #endif
+#if H_MV_HLS_7_SEI_P0204_26
+  // Check input parameters for Sub-bitstream property SEI message
+  if( m_subBistreamPropSEIEnabled )
+  {
+    xConfirmPara( 
+      (this->m_sbPropNumAdditionalSubStreams != m_sbPropAvgBitRate.size() )
+      || (this->m_sbPropNumAdditionalSubStreams != m_sbPropHighestSublayerId.size() )
+      || (this->m_sbPropNumAdditionalSubStreams != m_sbPropMaxBitRate.size() )
+      || (this->m_sbPropNumAdditionalSubStreams != m_sbPropOutputLayerSetIdxToVps.size() )
+      || (this->m_sbPropNumAdditionalSubStreams != m_sbPropSubBitstreamMode.size()), "Some parameters of some sub-bitstream not defined");
+
+    for( Int i = 0; i < m_sbPropNumAdditionalSubStreams; i++ )
+    {
+      xConfirmPara( m_sbPropSubBitstreamMode[i] < 0 || m_sbPropSubBitstreamMode[i] > 1, "Mode value should be 0 or 1" );
+      xConfirmPara( m_sbPropHighestSublayerId[i] < 0 || m_sbPropHighestSublayerId[i] > MAX_TLAYER-1, "Maximum sub-layer ID out of range" );
+      xConfirmPara( m_sbPropOutputLayerSetIdxToVps[i] < 0 || m_sbPropOutputLayerSetIdxToVps[i] >= MAX_VPS_OUTPUTLAYER_SETS, "OutputLayerSetIdxToVps should be within allowed range" );
+    }
+  }
+#endif
 #undef xConfirmPara
   if (check_failed)
Index: branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncCfg.h	(revision 861)
+++ branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncCfg.h	(revision 862)
@@ -440,5 +440,13 @@
   Int       m_log2MaxMvLengthHorizontal;                      ///< Indicate the maximum absolute value of a decoded horizontal MV component in quarter-pel luma units
   Int       m_log2MaxMvLengthVertical;                        ///< Indicate the maximum absolute value of a decoded vertical MV component in quarter-pel luma units
-
+#if H_MV_HLS_7_SEI_P0204_26
+  Bool              m_subBistreamPropSEIEnabled;
+  Int               m_sbPropNumAdditionalSubStreams;
+  std::vector<Int>  m_sbPropSubBitstreamMode;
+  std::vector<Int>  m_sbPropOutputLayerSetIdxToVps;
+  std::vector<Int>  m_sbPropHighestSublayerId;
+  std::vector<Int>  m_sbPropAvgBitRate;
+  std::vector<Int>  m_sbPropMaxBitRate;
+#endif
 #if H_3D
   // Camera parameters
Index: branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncTop.cpp	(revision 861)
+++ branches/HTM-10.0-dev0/source/App/TAppEncoder/TAppEncTop.cpp	(revision 862)
@@ -429,4 +429,16 @@
   m_cTEncTop.setSOPDescriptionSEIEnabled( m_SOPDescriptionSEIEnabled );
   m_cTEncTop.setScalableNestingSEIEnabled( m_scalableNestingSEIEnabled );
+#if H_MV_HLS_7_SEI_P0204_26
+  m_cTEncTop.setSubBitstreamPropSEIEnabled( m_subBistreamPropSEIEnabled );
+  if( m_subBistreamPropSEIEnabled )
+  {
+    m_cTEncTop.setNumAdditionalSubStreams ( m_sbPropNumAdditionalSubStreams );
+    m_cTEncTop.setSubBitstreamMode        ( m_sbPropSubBitstreamMode );
+    m_cTEncTop.setOutputLayerSetIdxToVps  ( m_sbPropOutputLayerSetIdxToVps );
+    m_cTEncTop.setHighestSublayerId       ( m_sbPropHighestSublayerId );
+    m_cTEncTop.setAvgBitRate              ( m_sbPropAvgBitRate );
+    m_cTEncTop.setMaxBitRate              ( m_sbPropMaxBitRate );
+  }
+#endif
   m_cTEncTop.setUniformSpacingIdr          ( m_iUniformSpacingIdr );
   m_cTEncTop.setNumColumnsMinus1           ( m_iNumColumnsMinus1 );
Index: branches/HTM-10.0-dev0/source/Lib/TLibCommon/SEI.h
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibCommon/SEI.h	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibCommon/SEI.h	(revision 862)
@@ -72,4 +72,7 @@
     SCALABLE_NESTING                     = 133,
     REGION_REFRESH_INFO                  = 134,
+#if H_MV_HLS_7_SEI_P0204_26
+    SUB_BITSTREAM_PROPERTY               = 139,    // Final PayloadType to be defined after finalization
+#endif
   };
   
@@ -363,4 +366,23 @@
 };
 
+#if H_MV_HLS_7_SEI_P0204_26
+class SEISubBitstreamProperty : public SEI
+{
+public:
+  PayloadType payloadType() const { return SUB_BITSTREAM_PROPERTY; }
+
+  SEISubBitstreamProperty():   m_activeVpsId(-1), m_numAdditionalSubStreams(0) {}
+  virtual ~SEISubBitstreamProperty() {}
+
+  Int  m_activeVpsId;
+  Int  m_numAdditionalSubStreams;
+  std::vector<Int>  m_subBitstreamMode;
+  std::vector<Int>  m_outputLayerSetIdxToVps;
+  std::vector<Int>  m_highestSublayerId;
+  std::vector<Int>  m_avgBitRate;
+  std::vector<Int>  m_maxBitRate;
+};
+#endif
+
 typedef std::list<SEI*> SEIMessages;
 
Index: branches/HTM-10.0-dev0/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibCommon/TypeDef.h	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibCommon/TypeDef.h	(revision 862)
@@ -339,5 +339,5 @@
 // #define H_MV_HLS_7_POC_P0041_3            0 // (POC/P0041/POC reset) #3 It was remarked that we should require each non-IRAP picture that has discardable_flag equal to 1 to have NUT value indicating that it is a sub-layer non-reference picture. This was agreed. Decision: Adopt (with constraint for discardable_flag as described above) 
 // #define H_MV_HLS_7_POC_P0041_FIXES        0 // (POC/P0041/Fixes) For each non-IRAP picture that has discardable_flag equal to 1 to have NUT value indicating that it is a sub-layer non-reference picture. 
-// #define H_MV_HLS_7_SEI_P0204_26           0 // (SEI/P0204/sub-bitstream SEI) #26 Add sub-bitstream property SEI message. Decision: Adopt
+#define H_MV_HLS_7_SEI_P0204_26           1 // (SEI/P0204/sub-bitstream SEI) #26 Add sub-bitstream property SEI message. Decision: Adopt
 #define H_MV_HLS_7_MISC_P0130_20          1 // (MISC/P0130/discardable not in inter-layer RPS) #20 Add constraint restricting pictures marked as discardable from being present in the temporal or inter-layer RPS,
 
@@ -416,4 +416,7 @@
 #define MAX_NUM_BITSTREAM_PARTITIONS    100 ///< Maximum value is actually not specified 
 #define MAX_NUM_BSP_SCHED_COMBINATION   100 ///< Maximum value is actually not specified 
+#if H_MV_HLS_7_SEI_P0204_26
+#define MAX_SUB_STREAMS                 1024
+#endif
 #else
 #define MAX_NUM_LAYER_IDS                64
Index: branches/HTM-10.0-dev0/source/Lib/TLibDecoder/SEIread.cpp
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibDecoder/SEIread.cpp	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibDecoder/SEIread.cpp	(revision 862)
@@ -99,4 +99,9 @@
     fprintf( g_hTrace, "=========== Scalable Nesting SEI message ===========\n");
     break;
+#if H_MV_HLS_7_SEI_P0204_26
+  case SEI::SUB_BITSTREAM_PROPERTY:
+    fprintf( g_hTrace, "=========== Sub-bitstream property SEI message ===========\n");
+    break;
+#endif
   default:
     fprintf( g_hTrace, "=========== Unknown SEI message ===========\n");
@@ -240,4 +245,10 @@
       xParseSEIScalableNesting((SEIScalableNesting&) *sei, nalUnitType, payloadSize, sps);
       break;
+#if H_MV_HLS_7_SEI_P0204_26
+     case SEI::SUB_BITSTREAM_PROPERTY:
+       sei = new SEISubBitstreamProperty;
+       xParseSEISubBitstreamProperty((SEISubBitstreamProperty&) *sei);
+       break;
+#endif
     default:
       for (UInt i = 0; i < payloadSize; i++)
@@ -766,4 +777,31 @@
 
 }
+#if H_MV_HLS_7_SEI_P0204_26
+Void SEIReader::xParseSEISubBitstreamProperty(SEISubBitstreamProperty &sei)
+{
+  UInt uiCode;
+  READ_CODE( 4, uiCode, "active_vps_id" );                      sei.m_activeVpsId = uiCode;
+  READ_UVLC(    uiCode, "num_additional_sub_streams_minus1" );  sei.m_numAdditionalSubStreams = uiCode + 1;
+
+  xResizeSubBitstreamPropertySeiArrays(sei);
+  for( Int i = 0; i < sei.m_numAdditionalSubStreams; i++ )
+  {
+    READ_CODE(  2, uiCode, "sub_bitstream_mode[i]"           ); sei.m_subBitstreamMode[i] = uiCode;
+    READ_UVLC(     uiCode, "output_layer_set_idx_to_vps[i]"  ); sei.m_outputLayerSetIdxToVps[i] = uiCode;
+    READ_CODE(  3, uiCode, "highest_sub_layer_id[i]"         ); sei.m_highestSublayerId[i] = uiCode;
+    READ_CODE( 16, uiCode, "avg_bit_rate[i]"                 ); sei.m_avgBitRate[i] = uiCode;
+    READ_CODE( 16, uiCode, "max_bit_rate[i]"                 ); sei.m_maxBitRate[i] = uiCode;
+  }
+  xParseByteAlign();
+}
+Void SEIReader::xResizeSubBitstreamPropertySeiArrays(SEISubBitstreamProperty &sei)
+{
+  sei.m_subBitstreamMode.resize( sei.m_numAdditionalSubStreams );
+  sei.m_outputLayerSetIdxToVps.resize( sei.m_numAdditionalSubStreams );
+  sei.m_highestSublayerId.resize( sei.m_numAdditionalSubStreams );
+  sei.m_avgBitRate.resize( sei.m_numAdditionalSubStreams );
+  sei.m_maxBitRate.resize( sei.m_numAdditionalSubStreams );
+}
+#endif
 
 Void SEIReader::xParseByteAlign()
Index: branches/HTM-10.0-dev0/source/Lib/TLibDecoder/SEIread.h
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibDecoder/SEIread.h	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibDecoder/SEIread.h	(revision 862)
@@ -73,4 +73,8 @@
   Void xParseSEISOPDescription        (SEISOPDescription &sei, UInt payloadSize);
   Void xParseSEIScalableNesting       (SEIScalableNesting& sei, const NalUnitType nalUnitType, UInt payloadSize, TComSPS *sps);
+#if H_MV_HLS_7_SEI_P0204_26
+  Void  xParseSEISubBitstreamProperty   (SEISubBitstreamProperty &sei);
+  Void  xResizeSubBitstreamPropertySeiArrays(SEISubBitstreamProperty &sei);
+#endif
   Void xParseByteAlign();
 };
Index: branches/HTM-10.0-dev0/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 862)
@@ -93,4 +93,9 @@
     fprintf( g_hTrace, "=========== Scalable Nesting SEI message ===========\n");
     break;
+#if H_MV_HLS_7_SEI_P0204_26
+    case SEI::SUB_BITSTREAM_PROPERTY:
+    fprintf( g_hTrace, "=========== Sub-bitstream property SEI message ===========\n");
+    break;
+#endif
   default:
     fprintf( g_hTrace, "=========== Unknown SEI message ===========\n");
@@ -146,4 +151,9 @@
     xWriteSEIScalableNesting(bs, *static_cast<const SEIScalableNesting*>(&sei), sps);
     break;
+#if H_MV_HLS_7_SEI_P0204_26
+   case SEI::SUB_BITSTREAM_PROPERTY:
+   xWriteSEISubBitstreamProperty(*static_cast<const SEISubBitstreamProperty*>(&sei));
+   break;
+#endif
   default:
     assert(!"Unhandled SEI message");
@@ -579,4 +589,23 @@
 }
 
+#if H_MV_HLS_7_SEI_P0204_26
+Void SEIWriter::xWriteSEISubBitstreamProperty(const SEISubBitstreamProperty &sei)
+{
+  WRITE_CODE( sei.m_activeVpsId, 4, "active_vps_id" );
+  assert( sei.m_numAdditionalSubStreams >= 1 );
+  WRITE_UVLC( sei.m_numAdditionalSubStreams - 1, "num_additional_sub_streams_minus1" );
+
+  for( Int i = 0; i < sei.m_numAdditionalSubStreams; i++ )
+  {
+    WRITE_CODE( sei.m_subBitstreamMode[i],       2, "sub_bitstream_mode[i]"           );
+    WRITE_UVLC( sei.m_outputLayerSetIdxToVps[i],    "output_layer_set_idx_to_vps[i]"  );
+    WRITE_CODE( sei.m_highestSublayerId[i],      3, "highest_sub_layer_id[i]"         );
+    WRITE_CODE( sei.m_avgBitRate[i],            16, "avg_bit_rate[i]"                 );
+    WRITE_CODE( sei.m_maxBitRate[i],            16, "max_bit_rate[i]"                 );
+  }
+  xWriteByteAlign();
+}
+#endif
+
 Void SEIWriter::xWriteByteAlign()
 {
Index: branches/HTM-10.0-dev0/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibEncoder/SEIwrite.h	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibEncoder/SEIwrite.h	(revision 862)
@@ -66,4 +66,7 @@
   Void xWriteSEISOPDescription(const SEISOPDescription& sei);
   Void xWriteSEIScalableNesting(TComBitIf& bs, const SEIScalableNesting& sei, TComSPS *sps);
+#if H_MV_HLS_7_SEI_P0204_26
+  Void xWriteSEISubBitstreamProperty(const SEISubBitstreamProperty &sei);
+#endif
   Void xWriteByteAlign();
 };
Index: branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncCfg.h	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncCfg.h	(revision 862)
@@ -347,4 +347,13 @@
 
   Bool      m_useStrongIntraSmoothing;                        ///< enable the use of strong intra smoothing (bi_linear interpolation) for 32x32 blocks when reference samples are flat.
+#if H_MV_HLS_7_SEI_P0204_26
+  Bool              m_subBistreamPropSEIEnabled;
+  Int               m_numAdditionalSubStreams;
+  std::vector<Int>  m_subBitstreamMode;
+  std::vector<Int>  m_outputLayerSetIdxToVps;
+  std::vector<Int>  m_highestSublayerId;
+  std::vector<Int>  m_avgBitRate;
+  std::vector<Int>  m_maxBitRate;
+#endif
 
 #if H_MV
@@ -779,4 +788,33 @@
   Void  setScalableNestingSEIEnabled(Int b)                { m_scalableNestingSEIEnabled = b; }
   Int   getScalableNestingSEIEnabled()                     { return m_scalableNestingSEIEnabled; }
+
+#if H_MV_HLS_7_SEI_P0204_26
+  Bool   getSubBitstreamPropSEIEnabled()        { return m_subBistreamPropSEIEnabled;}
+  Void   setSubBitstreamPropSEIEnabled(Bool x)  { m_subBistreamPropSEIEnabled = x;}
+
+  Int    getNumAdditionalSubStreams()           { return m_numAdditionalSubStreams;}
+  Void   setNumAdditionalSubStreams(Int x)      { m_numAdditionalSubStreams = x;}
+
+  std::vector<Int> const &getSubBitstreamMode()  { return m_subBitstreamMode;}
+  Int   getSubBitstreamMode(Int idx)  { return m_subBitstreamMode[idx];}
+  Void  setSubBitstreamMode(std::vector<Int> &x)  { m_subBitstreamMode = x;}
+
+  std::vector<Int> const &getOutputLayerSetIdxToVps()  { return m_outputLayerSetIdxToVps;}
+  Int   getOutputLayerSetIdxToVps(Int idx)  { return m_outputLayerSetIdxToVps[idx];}
+  Void  setOutputLayerSetIdxToVps(std::vector<Int> &x)  { m_outputLayerSetIdxToVps = x;}
+
+  std::vector<Int> const &getHighestSublayerId()  { return m_highestSublayerId;}
+  Int   getHighestSublayerId(Int idx)  { return m_highestSublayerId[idx];}
+  Void  setHighestSublayerId(std::vector<Int> &x)  { m_highestSublayerId = x;}
+
+  std::vector<Int> const &getAvgBitRate()  { return m_avgBitRate;}
+  Int   getAvgBitRate(Int idx)  { return m_avgBitRate[idx];}
+  Void  setAvgBitRate(std::vector<Int> &x)  { m_avgBitRate = x;}
+
+  std::vector<Int> const &getMaxBitRate()  { return m_maxBitRate;}
+  Int   getMaxBitRate(Int idx)  { return m_maxBitRate[idx];}
+  Void  setMaxBitRate(std::vector<Int> &x)  { m_maxBitRate = x;}
+
+#endif
   Void      setUseWP               ( Bool b )    { m_useWeightedPred   = b;    }
   Void      setWPBiPred            ( Bool b )    { m_useWeightedBiPred = b;    }
Index: branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 862)
@@ -296,4 +296,23 @@
 }
 
+#if H_MV_HLS_7_SEI_P0204_26
+SEISubBitstreamProperty *TEncGOP::xCreateSEISubBitstreamProperty( TComSPS *sps)
+{
+  SEISubBitstreamProperty *seiSubBitstreamProperty = new SEISubBitstreamProperty();
+
+  seiSubBitstreamProperty->m_activeVpsId = sps->getVPSId();
+  /* These values can be determined by the encoder; for now we will use the input parameter */
+  TEncTop *encTop = this->m_pcEncTop;
+  seiSubBitstreamProperty->m_numAdditionalSubStreams = encTop->getNumAdditionalSubStreams();
+  seiSubBitstreamProperty->m_subBitstreamMode        = encTop->getSubBitstreamMode();
+  seiSubBitstreamProperty->m_outputLayerSetIdxToVps  = encTop->getOutputLayerSetIdxToVps();
+  seiSubBitstreamProperty->m_highestSublayerId       = encTop->getHighestSublayerId();
+  seiSubBitstreamProperty->m_avgBitRate              = encTop->getAvgBitRate();
+  seiSubBitstreamProperty->m_maxBitRate              = encTop->getMaxBitRate();
+
+  return seiSubBitstreamProperty;
+}
+#endif
+
 Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps)
 {
@@ -346,4 +365,17 @@
     delete sei;
   }
+#if H_MV_HLS_7_SEI_P0204_26
+  if( m_pcCfg->getSubBitstreamPropSEIEnabled() )
+  {
+    SEISubBitstreamProperty *sei = xCreateSEISubBitstreamProperty ( sps );
+
+    nalu = NALUnit(NAL_UNIT_PREFIX_SEI); 
+    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
+    writeRBSPTrailingBits(nalu.m_Bitstream);
+    accessUnit.push_back(new NALUnitEBSP(nalu));
+    delete sei;
+  }
+#endif
 }
 
Index: branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncGOP.h	(revision 861)
+++ branches/HTM-10.0-dev0/source/Lib/TLibEncoder/TEncGOP.h	(revision 862)
@@ -212,4 +212,7 @@
 
   SEIToneMappingInfo*     xCreateSEIToneMappingInfo();
+#if H_MV_HLS_7_SEI_P0204_26
+  SEISubBitstreamProperty *xCreateSEISubBitstreamProperty( TComSPS *sps);
+#endif
 
   Void xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps);
