Index: branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 291)
+++ branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 292)
@@ -821,4 +821,7 @@
   ("SEIGradualDecodingRefreshInfo",  m_gradualDecodingRefreshInfoEnabled,      0, "Control generation of gradual decoding refresh information SEI message")
   ("SEIDecodingUnitInfo",             m_decodingUnitInfoSEIEnabled,                       0, "Control generation of decoding unit information SEI message.")
+#if M0043_LAYERS_PRESENT_SEI
+  ("SEILayersPresent",               m_layersPresentSEIEnabled,                0, "Control generation of layers present SEI message")
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   ("SEISOPDescription",              m_SOPDescriptionSEIEnabled,              0, "Control generation of SOP description SEI messages")
Index: branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 291)
+++ branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 292)
@@ -274,4 +274,7 @@
   Int       m_gradualDecodingRefreshInfoEnabled;
   Int       m_decodingUnitInfoSEIEnabled;
+#if M0043_LAYERS_PRESENT_SEI
+  Int       m_layersPresentSEIEnabled;
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   Int       m_SOPDescriptionSEIEnabled;
Index: branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 291)
+++ branches/SHM-2.1-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 292)
@@ -388,4 +388,7 @@
     m_acTEncTop[layer].setGradualDecodingRefreshInfoEnabled( m_gradualDecodingRefreshInfoEnabled );
     m_acTEncTop[layer].setDecodingUnitInfoSEIEnabled( m_decodingUnitInfoSEIEnabled );
+#if M0043_LAYERS_PRESENT_SEI
+    m_acTEncTop[layer].setLayersPresentSEIEnabled( m_layersPresentSEIEnabled );
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
     m_acTEncTop[layer].setSOPDescriptionSEIEnabled( m_SOPDescriptionSEIEnabled );
@@ -725,4 +728,7 @@
   m_cTEncTop.setGradualDecodingRefreshInfoEnabled( m_gradualDecodingRefreshInfoEnabled );
   m_cTEncTop.setDecodingUnitInfoSEIEnabled( m_decodingUnitInfoSEIEnabled );
+#if M0043_LAYERS_PRESENT_SEI
+  m_cTEncTop.setLayersPresentSEIEnabled( m_layersPresentSEIEnabled );
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   m_cTEncTop.setSOPDescriptionSEIEnabled( m_SOPDescriptionSEIEnabled );
Index: branches/SHM-2.1-dev/source/Lib/TLibCommon/SEI.h
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibCommon/SEI.h	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibCommon/SEI.h	(revision 292)
@@ -72,4 +72,7 @@
     SCALABLE_NESTING                     = 133,
     REGION_REFRESH_INFO                  = 134,
+#if M0043_LAYERS_PRESENT_SEI
+    LAYERS_PRESENT                       = 137,
+#endif
   };
   
@@ -354,4 +357,19 @@
   Bool m_gdrForegroundFlag;
 };
+
+#if M0043_LAYERS_PRESENT_SEI
+class SEILayersPresent : public SEI
+{
+public:
+  PayloadType payloadType() const { return LAYERS_PRESENT; }
+
+  SEILayersPresent() {}
+  virtual ~SEILayersPresent() {}
+
+  UInt m_activeVpsId;
+  UInt m_vpsMaxLayers;
+  Bool m_layerPresentFlag[MAX_LAYERS];
+};
+#endif
 
 #if L0208_SOP_DESCRIPTION_SEI
Index: branches/SHM-2.1-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibCommon/TypeDef.h	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibCommon/TypeDef.h	(revision 292)
@@ -135,4 +135,6 @@
 #define FIX1071 1 ///< Temporary fix for issue #1071
 
+
+#define M0043_LAYERS_PRESENT_SEI      0 ///< M0043: add layers present SEI
 #define L0208_SOP_DESCRIPTION_SEI     1 ///< L0208: add SOP descrioption SEI
 #define MAX_NUM_PICS_IN_SOP           1024
Index: branches/SHM-2.1-dev/source/Lib/TLibDecoder/SEIread.cpp
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 292)
@@ -95,4 +95,9 @@
     break;
 #endif
+#if M0043_LAYERS_PRESENT_SEI
+  case SEI::LAYERS_PRESENT:
+    fprintf( g_hTrace, "=========== Layers Present SEI message ===========\n");
+    break;
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   case SEI::SOP_DESCRIPTION:
@@ -115,5 +120,9 @@
  * unmarshal a single SEI message from bitstream bs
  */
+#if M0043_LAYERS_PRESENT_SEI
+void SEIReader::parseSEImessage(TComInputBitstream* bs, SEIMessages& seis, const NalUnitType nalUnitType, TComVPS *vps, TComSPS *sps)
+#else
 void SEIReader::parseSEImessage(TComInputBitstream* bs, SEIMessages& seis, const NalUnitType nalUnitType, TComSPS *sps)
+#endif
 {
   setBitstream(bs);
@@ -122,5 +131,9 @@
   do
   {
+#if M0043_LAYERS_PRESENT_SEI
+    xReadSEImessage(seis, nalUnitType, vps, sps);
+#else
     xReadSEImessage(seis, nalUnitType, sps);
+#endif
     /* SEI messages are an integer number of bytes, something has failed
     * in the parsing if bitstream not byte-aligned */
@@ -133,5 +146,9 @@
 }
 
+#if M0043_LAYERS_PRESENT_SEI
+Void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType, TComVPS *vps, TComSPS *sps)
+#else
 Void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType, TComSPS *sps)
+#endif
 {
 #if ENC_DEC_TRACE
@@ -240,4 +257,17 @@
       break;
 #endif
+#if M0043_LAYERS_PRESENT_SEI
+    case SEI::LAYERS_PRESENT:
+      if (!vps)
+      {
+        printf ("Warning: Found Layers present SEI message, but no active VPS is available. Ignoring.");
+      }
+      else
+      {
+        sei = new SEILayersPresent;
+        xParseSEILayersPresent((SEILayersPresent&) *sei, payloadSize, vps);
+      }
+      break;
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
     case SEI::SOP_DESCRIPTION:
@@ -249,5 +279,9 @@
     case SEI::SCALABLE_NESTING:
       sei = new SEIScalableNesting;
+#if M0043_LAYERS_PRESENT_SEI
+      xParseSEIScalableNesting((SEIScalableNesting&) *sei, nalUnitType, payloadSize, vps, sps);
+#else
       xParseSEIScalableNesting((SEIScalableNesting&) *sei, nalUnitType, payloadSize, sps);
+#endif
       break;
 #endif
@@ -751,4 +785,25 @@
 #endif
 
+#if M0043_LAYERS_PRESENT_SEI
+Void SEIReader::xParseSEILayersPresent(SEILayersPresent &sei, UInt payloadSize, TComVPS *vps)
+{
+  UInt uiCode;
+  UInt i = 0;
+
+  READ_UVLC( uiCode,           "lp_sei_active_vps_id" ); sei.m_activeVpsId = uiCode;
+  assert(vps->getVPSId() == sei.m_activeVpsId);
+  sei.m_vpsMaxLayers = vps->getMaxLayers();
+  for (; i < sei.m_vpsMaxLayers; i++)
+  {
+    READ_FLAG( uiCode,         "layer_present_flag"   ); sei.m_layerPresentFlag[i] = uiCode ? true : false;
+  }
+  for (; i < MAX_LAYERS; i++)
+  {
+    sei.m_layerPresentFlag[i] = false;
+  }
+  xParseByteAlign();
+}
+#endif
+
 #if L0208_SOP_DESCRIPTION_SEI
 Void SEIReader::xParseSEISOPDescription(SEISOPDescription &sei, UInt payloadSize)
@@ -777,6 +832,11 @@
 #endif
 
+
 #if K0180_SCALABLE_NESTING_SEI
+#if M0043_LAYERS_PRESENT_SEI
+Void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, UInt payloadSize, TComVPS *vps, TComSPS *sps)
+#else
 Void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, UInt payloadSize, TComSPS *sps)
+#endif
 {
   UInt uiCode;
@@ -820,5 +880,9 @@
   // read nested SEI messages
   do {
+#if M0043_LAYERS_PRESENT_SEI
+    xReadSEImessage(sei.m_nestedSEIs, nalUnitType, vps, sps);
+#else
     xReadSEImessage(sei.m_nestedSEIs, nalUnitType, sps);
+#endif
   } while (m_pcBitstream->getNumBitsLeft() > 8);
 
Index: branches/SHM-2.1-dev/source/Lib/TLibDecoder/SEIread.h
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibDecoder/SEIread.h	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibDecoder/SEIread.h	(revision 292)
@@ -56,7 +56,15 @@
   SEIReader() {};
   virtual ~SEIReader() {};
+#if M0043_LAYERS_PRESENT_SEI
+  Void parseSEImessage(TComInputBitstream* bs, SEIMessages& seis, const NalUnitType nalUnitType, TComVPS *vps, TComSPS *sps);
+#else
   Void parseSEImessage(TComInputBitstream* bs, SEIMessages& seis, const NalUnitType nalUnitType, TComSPS *sps);
+#endif
 protected:
+#if M0043_LAYERS_PRESENT_SEI
+  Void xReadSEImessage                (SEIMessages& seis, const NalUnitType nalUnitType, TComVPS *vps, TComSPS *sps);
+#else
   Void xReadSEImessage                (SEIMessages& seis, const NalUnitType nalUnitType, TComSPS *sps);
+#endif
   Void xParseSEIuserDataUnregistered  (SEIuserDataUnregistered &sei, UInt payloadSize);
   Void xParseSEIActiveParameterSets   (SEIActiveParameterSets  &sei, UInt payloadSize);
@@ -73,9 +81,16 @@
   Void xParseSEIToneMappingInfo       (SEIToneMappingInfo& sei, UInt payloadSize);
 #endif
+#if M0043_LAYERS_PRESENT_SEI
+  Void xParseSEILayersPresent         (SEILayersPresent &sei, UInt payloadSize, TComVPS *vps);
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   Void xParseSEISOPDescription        (SEISOPDescription &sei, UInt payloadSize);
 #endif
 #if K0180_SCALABLE_NESTING_SEI
+#if M0043_LAYERS_PRESENT_SEI
+  Void xParseSEIScalableNesting       (SEIScalableNesting& sei, const NalUnitType nalUnitType, UInt payloadSize, TComVPS *vps, TComSPS *sps);
+#else
   Void xParseSEIScalableNesting       (SEIScalableNesting& sei, const NalUnitType nalUnitType, UInt payloadSize, TComSPS *sps);
+#endif
 #endif
   Void xParseByteAlign();
Index: branches/SHM-2.1-dev/source/Lib/TLibDecoder/TDecTop.cpp
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 292)
@@ -1098,9 +1098,17 @@
   if(nalUnitType == NAL_UNIT_SUFFIX_SEI)
   {
+#if M0043_LAYERS_PRESENT_SEI
+    m_seiReader.parseSEImessage( bs, m_pcPic->getSEIs(), nalUnitType, m_parameterSetManagerDecoder[m_layerId].getActiveVPS(), m_parameterSetManagerDecoder[m_layerId].getActiveSPS() );
+#else
     m_seiReader.parseSEImessage( bs, m_pcPic->getSEIs(), nalUnitType, m_parameterSetManagerDecoder[m_layerId].getActiveSPS() );
+#endif
   }
   else
   {
+#if M0043_LAYERS_PRESENT_SEI
+    m_seiReader.parseSEImessage( bs, m_SEIs, nalUnitType, m_parameterSetManagerDecoder[m_layerId].getActiveVPS(), m_parameterSetManagerDecoder[m_layerId].getActiveSPS() );
+#else
     m_seiReader.parseSEImessage( bs, m_SEIs, nalUnitType, m_parameterSetManagerDecoder[m_layerId].getActiveSPS() );
+#endif
     SEIMessages activeParamSets = getSeisByType(m_SEIs, SEI::ACTIVE_PARAMETER_SETS);
     if (activeParamSets.size()>0)
@@ -1118,9 +1126,17 @@
   if(nalUnitType == NAL_UNIT_SUFFIX_SEI)
   {
+#if M0043_LAYERS_PRESENT_SEI
+    m_seiReader.parseSEImessage( bs, m_pcPic->getSEIs(), nalUnitType, m_parameterSetManagerDecoder.getActiveVPS(), m_parameterSetManagerDecoder.getActiveSPS() );
+#else
     m_seiReader.parseSEImessage( bs, m_pcPic->getSEIs(), nalUnitType, m_parameterSetManagerDecoder.getActiveSPS() );
+#endif
   }
   else
   {
+#if M0043_LAYERS_PRESENT_SEI
+    m_seiReader.parseSEImessage( bs, m_SEIs, nalUnitType, m_parameterSetManagerDecoder.getActiveVPS(), m_parameterSetManagerDecoder.getActiveSPS() );
+#else
     m_seiReader.parseSEImessage( bs, m_SEIs, nalUnitType, m_parameterSetManagerDecoder.getActiveSPS() );
+#endif
     SEIMessages activeParamSets = getSeisByType(m_SEIs, SEI::ACTIVE_PARAMETER_SETS);
     if (activeParamSets.size()>0)
Index: branches/SHM-2.1-dev/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 292)
@@ -89,4 +89,9 @@
     break;
 #endif
+#if M0043_LAYERS_PRESENT_SEI
+  case SEI::LAYERS_PRESENT:
+    fprintf( g_hTrace, "=========== Layers Present SEI message ===========\n");
+    break;
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   case SEI::SOP_DESCRIPTION:
@@ -150,4 +155,9 @@
   case SEI::TONE_MAPPING_INFO:
     xWriteSEIToneMappingInfo(*static_cast<const SEIToneMappingInfo*>(&sei));
+    break;
+#endif
+#if M0043_LAYERS_PRESENT_SEI
+  case SEI::LAYERS_PRESENT:
+    xWriteSEILayersPresent(*static_cast<const SEILayersPresent*>(&sei));
     break;
 #endif
@@ -591,4 +601,16 @@
 }
 
+#if M0043_LAYERS_PRESENT_SEI
+Void SEIWriter::xWriteSEILayersPresent(const SEILayersPresent& sei)
+{
+  WRITE_UVLC( sei.m_activeVpsId,           "lp_sei_active_vps_id" );
+  for (UInt i = 0; i < sei.m_vpsMaxLayers; i++)
+  {
+    WRITE_FLAG( sei.m_layerPresentFlag[i], "layer_present_flag"   );
+  }
+  xWriteByteAlign();
+}
+#endif
+
 #if L0208_SOP_DESCRIPTION_SEI
 Void SEIWriter::xWriteSEISOPDescription(const SEISOPDescription& sei)
Index: branches/SHM-2.1-dev/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 292)
@@ -70,4 +70,7 @@
   Void xWriteSEIToneMappingInfo(const SEIToneMappingInfo& sei);
 #endif
+#if M0043_LAYERS_PRESENT_SEI
+  Void xWriteSEILayersPresent(const SEILayersPresent& sei);
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   Void xWriteSEISOPDescription(const SEISOPDescription& sei);
Index: branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 292)
@@ -289,4 +289,7 @@
   Int       m_gradualDecodingRefreshInfoEnabled;
   Int       m_decodingUnitInfoSEIEnabled;
+#if M0043_LAYERS_PRESENT_SEI
+  Int       m_layersPresentSEIEnabled;
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   Int       m_SOPDescriptionSEIEnabled;
@@ -733,4 +736,8 @@
   Void  setDecodingUnitInfoSEIEnabled(Int b)                { m_decodingUnitInfoSEIEnabled = b;    }
   Int   getDecodingUnitInfoSEIEnabled()                     { return m_decodingUnitInfoSEIEnabled; }
+#if M0043_LAYERS_PRESENT_SEI
+  Void  setLayersPresentSEIEnabled(Int b)                { m_layersPresentSEIEnabled = b; }
+  Int   getLayersPresentSEIEnabled()                     { return m_layersPresentSEIEnabled; }
+#endif
 #if L0208_SOP_DESCRIPTION_SEI
   Void  setSOPDescriptionSEIEnabled(Int b)                { m_SOPDescriptionSEIEnabled = b; }
Index: branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 292)
@@ -173,4 +173,23 @@
 }
 
+#if M0043_LAYERS_PRESENT_SEI
+SEILayersPresent* TEncGOP::xCreateSEILayersPresent ()
+{
+  UInt i = 0;
+  SEILayersPresent *seiLayersPresent = new SEILayersPresent(); 
+  seiLayersPresent->m_activeVpsId = m_pcCfg->getVPS()->getVPSId(); 
+  seiLayersPresent->m_vpsMaxLayers = m_pcCfg->getVPS()->getMaxLayers();
+  for ( ; i < seiLayersPresent->m_vpsMaxLayers; i++)
+  {
+    seiLayersPresent->m_layerPresentFlag[i] = true; 
+  }
+  for ( ; i < MAX_LAYERS; i++)
+  {
+    seiLayersPresent->m_layerPresentFlag[i] = false; 
+  }
+  return seiLayersPresent;
+}
+#endif
+
 SEIFramePacking* TEncGOP::xCreateSEIFramePacking()
 {
@@ -319,4 +338,16 @@
 #endif
   }
+
+#if M0043_LAYERS_PRESENT_SEI
+  if(m_pcCfg->getLayersPresentSEIEnabled())
+  {
+    SEILayersPresent *sei = xCreateSEILayersPresent ();
+    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
 
   if(m_pcCfg->getFramePackingArrangementSEIEnabled())
Index: branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 291)
+++ branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 292)
@@ -180,4 +180,7 @@
 
   SEIActiveParameterSets* xCreateSEIActiveParameterSets (TComSPS *sps);
+#if M0043_LAYERS_PRESENT_SEI
+  SEILayersPresent*       xCreateSEILayersPresent ();
+#endif
   SEIFramePacking*        xCreateSEIFramePacking();
   SEIDisplayOrientation*  xCreateSEIDisplayOrientation();
