Index: /branches/SHM-5.0-dev/source/Lib/TLibCommon/SEI.cpp
===================================================================
--- /branches/SHM-5.0-dev/source/Lib/TLibCommon/SEI.cpp	(revision 582)
+++ /branches/SHM-5.0-dev/source/Lib/TLibCommon/SEI.cpp	(revision 583)
@@ -41,4 +41,17 @@
 //Table D-7 Meaning of camera iso sensitivity indicator and exposure index rating indicator
 Int  Table_exp_indicator[32] = {0, 10, 12, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 8000, -1};
+
+#if SUB_BITSTREAM_PROPERTY_SEI
+SEISubBitstreamProperty::SEISubBitstreamProperty()
+{
+  m_activeVpsId             = -1;
+  m_numAdditionalSubStreams = 0;
+  ::memset(m_subBitstreamMode       , 0, sizeof(m_subBitstreamMode));
+  ::memset(m_outputLayerSetIdxToVps , 0, sizeof(m_outputLayerSetIdxToVps));
+  ::memset(m_highestSublayerId      , 0, sizeof(m_highestSublayerId));
+  ::memset(m_avgBitRate             , 0, sizeof(m_avgBitRate));
+  ::memset(m_maxBitRate             , 0, sizeof(m_maxBitRate));
+}
+#endif
 
 SEIMessages getSeisByType(SEIMessages &seiList, SEI::PayloadType seiType)
Index: /branches/SHM-5.0-dev/source/Lib/TLibCommon/SEI.h
===================================================================
--- /branches/SHM-5.0-dev/source/Lib/TLibCommon/SEI.h	(revision 582)
+++ /branches/SHM-5.0-dev/source/Lib/TLibCommon/SEI.h	(revision 583)
@@ -78,4 +78,7 @@
     INTER_LAYER_CONSTRAINED_TILE_SETS    = 138
 #endif
+#if SUB_BITSTREAM_PROPERTY_SEI
+   ,SUB_BITSTREAM_PROPERTY               = 139    // Final PayloadType to be defined after finalization
+#endif
   };
   
@@ -407,4 +410,22 @@
 #endif
 
+#if SUB_BITSTREAM_PROPERTY_SEI
+class SEISubBitstreamProperty : public SEI
+{
+public:
+  PayloadType payloadType() const { return SUB_BITSTREAM_PROPERTY; }
+
+  SEISubBitstreamProperty();
+  virtual ~SEISubBitstreamProperty() {}
+
+  Int  m_activeVpsId;
+  Int  m_numAdditionalSubStreams;
+  Int  m_subBitstreamMode       [MAX_SUB_STREAMS];
+  Int  m_outputLayerSetIdxToVps [MAX_SUB_STREAMS];
+  Int  m_highestSublayerId      [MAX_SUB_STREAMS];
+  Int  m_avgBitRate             [MAX_SUB_STREAMS];
+  Int  m_maxBitRate             [MAX_SUB_STREAMS];
+};
+#endif
 
 typedef std::list<SEI*> SEIMessages;
Index: /branches/SHM-5.0-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-5.0-dev/source/Lib/TLibCommon/TypeDef.h	(revision 582)
+++ /branches/SHM-5.0-dev/source/Lib/TLibCommon/TypeDef.h	(revision 583)
@@ -58,4 +58,5 @@
 #define CHANGE_NUMSUBDPB_IDX             1      ///< Change index of NumSubDpb from output layer set to layer set, to be more aligned with the Spec
 #define RESOLUTION_BASED_DPB             1      ///< JCTVC-P0192: Assign layers to sub-DPBs based on the rep_format() signaled in the VPS
+#define SUB_BITSTREAM_PROPERTY_SEI       1      ///< JCTVC-P0204: Sub-bitstream property SEI message
 #define O0109_O0199_FLAGS_TO_VUI         1      ///< JCTVC-O0109, O0199: move single_layer_for_non_irap_flag and higher_layer_flag to vps_vui
 #define O0109_VIEW_ID_LEN                1      ///< JCTVC-O0109: view_id_len_minus1 to view_id_len, and add constraint (1<<view_id_len) is greater than or equal to NumViews
@@ -250,4 +251,8 @@
 #define MAX_VPS_OP_SETS_PLUS1                     1024
 #define MAX_VPS_NUH_RESERVED_ZERO_LAYER_ID_PLUS1  1
+#endif
+
+#if SUB_BITSTREAM_PROPERTY_SEI
+#define MAX_SUB_STREAMS                           1024
 #endif
 
Index: /branches/SHM-5.0-dev/source/Lib/TLibDecoder/SEIread.cpp
===================================================================
--- /branches/SHM-5.0-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 582)
+++ /branches/SHM-5.0-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 583)
@@ -106,4 +106,9 @@
     break;
 #endif
+#if SUB_BITSTREAM_PROPERTY_SEI
+    case SEI::SUB_BITSTREAM_PROPERTY:
+      fprintf( g_hTrace, "=========== Sub-bitstream property SEI message ===========\n");
+      break;
+#endif
   case SEI::SCALABLE_NESTING:
     fprintf( g_hTrace, "=========== Scalable Nesting SEI message ===========\n");
@@ -276,4 +281,10 @@
       xParseSEIInterLayerConstrainedTileSets((SEIInterLayerConstrainedTileSets&) *sei, payloadSize);
       break;
+#endif
+#if SUB_BITSTREAM_PROPERTY_SEI
+   case SEI::SUB_BITSTREAM_PROPERTY:
+     sei = new SEISubBitstreamProperty;
+     xParseSEISubBitstreamProperty((SEISubBitstreamProperty&) *sei);
+     break;
 #endif
     case SEI::SCALABLE_NESTING:
@@ -829,5 +840,22 @@
 }
 #endif
-
+#if SUB_BITSTREAM_PROPERTY_SEI
+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;
+
+  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();
+}
+#endif
 #if LAYERS_NOT_PRESENT_SEI
 Void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, UInt payloadSize, TComVPS *vps, TComSPS *sps)
Index: /branches/SHM-5.0-dev/source/Lib/TLibDecoder/SEIread.h
===================================================================
--- /branches/SHM-5.0-dev/source/Lib/TLibDecoder/SEIread.h	(revision 582)
+++ /branches/SHM-5.0-dev/source/Lib/TLibDecoder/SEIread.h	(revision 583)
@@ -83,4 +83,7 @@
   Void xParseSEIInterLayerConstrainedTileSets (SEIInterLayerConstrainedTileSets &sei, UInt payloadSize);
 #endif
+#if SUB_BITSTREAM_PROPERTY_SEI
+Void   xParseSEISubBitstreamProperty   (SEISubBitstreamProperty &sei);
+#endif
 #if LAYERS_NOT_PRESENT_SEI
   Void xParseSEILayersNotPresent      (SEILayersNotPresent &sei, UInt payloadSize, TComVPS *vps);
Index: /branches/SHM-5.0-dev/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- /branches/SHM-5.0-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 582)
+++ /branches/SHM-5.0-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 583)
@@ -100,4 +100,9 @@
     break;
 #endif
+#if SUB_BITSTREAM_PROPERTY_SEI
+    case SEI::SUB_BITSTREAM_PROPERTY:
+      fprintf( g_hTrace, "=========== Sub-bitstream property SEI message ===========\n");
+      break;
+#endif
   case SEI::SCALABLE_NESTING:
     fprintf( g_hTrace, "=========== Scalable Nesting SEI message ===========\n");
@@ -162,4 +167,9 @@
     xWriteSEIInterLayerConstrainedTileSets(*static_cast<const SEIInterLayerConstrainedTileSets*>(&sei));
     break;
+#endif
+#if SUB_BITSTREAM_PROPERTY_SEI
+   case SEI::SUB_BITSTREAM_PROPERTY:
+     xWriteSEISubBitstreamProperty(*static_cast<const SEISubBitstreamProperty*>(&sei));
+     break;
 #endif
   case SEI::SCALABLE_NESTING:
@@ -606,5 +616,22 @@
 }
 #endif
-
+#if SUB_BITSTREAM_PROPERTY_SEI
+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::xWriteSEIScalableNesting(TComBitIf& bs, const SEIScalableNesting& sei, TComSPS *sps)
 {
Index: /branches/SHM-5.0-dev/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- /branches/SHM-5.0-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 582)
+++ /branches/SHM-5.0-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 583)
@@ -71,4 +71,7 @@
   Void xWriteSEIInterLayerConstrainedTileSets(const SEIInterLayerConstrainedTileSets& sei);
 #endif
+#if SUB_BITSTREAM_PROPERTY_SEI
+  Void xWriteSEISubBitstreamProperty(const SEISubBitstreamProperty &sei);
+#endif
   Void xWriteSEIScalableNesting(TComBitIf& bs, const SEIScalableNesting& sei, TComSPS *sps);
   Void xWriteByteAlign();
