Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 911)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 912)
@@ -620,4 +620,19 @@
   string cfg_kneeSEIInputKneePointValue;
   string cfg_kneeSEIOutputKneePointValue;
+#endif
+#if Q0096_OVERLAY_SEI
+  const Int CFG_MAX_OVERLAYS = 3;
+  UInt   cfg_overlaySEIIdx[CFG_MAX_OVERLAYS];  
+  Bool   cfg_overlaySEILanguagePresentFlag[CFG_MAX_OVERLAYS];  
+  UInt   cfg_overlaySEIContentLayerId[CFG_MAX_OVERLAYS];
+  Bool   cfg_overlaySEILabelPresentFlag[CFG_MAX_OVERLAYS];
+  UInt   cfg_overlaySEILabelLayerId[CFG_MAX_OVERLAYS];
+  Bool   cfg_overlaySEIAlphaPresentFlag[CFG_MAX_OVERLAYS];
+  UInt   cfg_overlaySEIAlphaLayerId[CFG_MAX_OVERLAYS];
+  UInt   cfg_overlaySEINumElementsMinus1[CFG_MAX_OVERLAYS];
+  string cfg_overlaySEIElementLabelRanges[CFG_MAX_OVERLAYS];  
+  string cfg_overlaySEILanguage[CFG_MAX_OVERLAYS];  
+  string cfg_overlaySEIName[CFG_MAX_OVERLAYS];  
+  string cfg_overlaySEIElementNames[CFG_MAX_OVERLAYS];  
 #endif
 
@@ -1118,4 +1133,53 @@
   ("SEIKneeFunctionOutputKneePointValue", cfg_kneeSEIOutputKneePointValue,    string("100 250 450"), "Array of output knee point")
 #endif
+#if Q0096_OVERLAY_SEI
+  ("SEIOverlayInfo",                          m_overlaySEIEnabled,                      false, "Control generation of Selectable Overlays SEI messages")
+  ("SEIOverlayCancelFlag",                    m_overlayInfoCancelFlag,                   true, "Indicates that Selectable Overlay SEI message cancels the persistance or follows (default: 1)")
+  ("SEIOverlayContentAuxIdMinus128",          m_overlayContentAuxIdMinus128,          UInt(0), "Indicates the AuxId value of auxiliary pictures containing overlay content - 128")
+  ("SEIOverlayLabelAuxIdMinus128",            m_overlayLabelAuxIdMinus128,            UInt(1), "Indicates the AuxId value of auxiliary pictures containing label content - 128")
+  ("SEIOverlayAlphaAuxIdMinus128",            m_overlayAlphaAuxIdMinus128,            UInt(2), "Indicates the AuxId value of auxiliary pictures containing alpha content - 128")
+  ("SEIOverlayElementLabelValueLengthMinus8", m_overlayElementLabelValueLengthMinus8, UInt(0), "Indicates the number of bits used for coding min and max label values - 8")
+  ("SEIOverlayNumOverlaysMinus1",             m_numOverlaysMinus1,                    UInt(0), "Specifies the number of overlays described by this SEI message - 1")
+  ("SEIOverlayIdx0",                          cfg_overlaySEIIdx[0],                   UInt(0), "Indicates the index of overlay 0")
+  ("SEIOverlayIdx1",                          cfg_overlaySEIIdx[1],                   UInt(1), "Indicates the index of overlay 1")
+  ("SEIOverlayIdx2",                          cfg_overlaySEIIdx[2],                   UInt(2), "Indicates the index of overlay 2")
+  ("SEIOverlayLanguagePresentFlag0",          cfg_overlaySEILanguagePresentFlag[0],     false, "Indicates if the language for overlay 0 is specified")
+  ("SEIOverlayLanguagePresentFlag1",          cfg_overlaySEILanguagePresentFlag[1],     false, "Indicates if the language for overlay 1 is specified")
+  ("SEIOverlayLanguagePresentFlag2",          cfg_overlaySEILanguagePresentFlag[2],     false, "Indicates if the language for overlay 2 is specified")
+  ("SEIOverlayContentLayerId0",               cfg_overlaySEIContentLayerId[0],        UInt(0), "Indicates the nuh_layer_id value of the overlay content of overlay 0")  
+  ("SEIOverlayContentLayerId1",               cfg_overlaySEIContentLayerId[1],        UInt(0), "Indicates the nuh_layer_id value of the overlay content of overlay 1")  
+  ("SEIOverlayContentLayerId2",               cfg_overlaySEIContentLayerId[2],        UInt(0), "Indicates the nuh_layer_id value of the overlay content of overlay 2")  
+  ("SEIOverlayLabelPresentFlag0",             cfg_overlaySEILabelPresentFlag[0],        false, "Specifies if label content 0 is present")  
+  ("SEIOverlayLabelPresentFlag1",             cfg_overlaySEILabelPresentFlag[1],        false, "Specifies if label content 1 is present")  
+  ("SEIOverlayLabelPresentFlag2",             cfg_overlaySEILabelPresentFlag[2],        false, "Specifies if label content 2 is present")  
+  ("SEIOverlayLabelLayerId0",                 cfg_overlaySEILabelLayerId[0],          UInt(0), "Specifies the nuh_layer_id value of the label content of overlay 0")  
+  ("SEIOverlayLabelLayerId1",                 cfg_overlaySEILabelLayerId[1],          UInt(0), "Specifies the nuh_layer_id value of the label content of overlay 1")  
+  ("SEIOverlayLabelLayerId2",                 cfg_overlaySEILabelLayerId[2],          UInt(0), "Specifies the nuh_layer_id value of the label content of overlay 2")  
+  ("SEIOverlayAlphaPresentFlag0",             cfg_overlaySEIAlphaPresentFlag[0],        false, "Specifies if alpha content 0 is present")  
+  ("SEIOverlayAlphaPresentFlag1",             cfg_overlaySEIAlphaPresentFlag[1],        false, "Specifies if alpha content 1 is present")  
+  ("SEIOverlayAlphaPresentFlag2",             cfg_overlaySEIAlphaPresentFlag[2],        false, "Specifies if alpha content 2 is present")  
+  ("SEIOverlayAlphaLayerId0",                 cfg_overlaySEIAlphaLayerId[0],          UInt(0), "Specifies the nuh_layer_id value of the alpha content of overlay 0")  
+  ("SEIOverlayAlphaLayerId1",                 cfg_overlaySEIAlphaLayerId[1],          UInt(0), "Specifies the nuh_layer_id value of the alpha content of overlay 1")  
+  ("SEIOverlayAlphaLayerId2",                 cfg_overlaySEIAlphaLayerId[2],          UInt(0), "Specifies the nuh_layer_id value of the alpha content of overlay 2")  
+  ("SEIOverlayNumElementsMinus1_0",           cfg_overlaySEINumElementsMinus1[0],     UInt(0), "Specifies the number of overlay elements in overlay 0")  
+  ("SEIOverlayNumElementsMinus1_1",           cfg_overlaySEINumElementsMinus1[1],     UInt(0), "Specifies the number of overlay elements in overlay 1")  
+  ("SEIOverlayNumElementsMinus1_2",           cfg_overlaySEINumElementsMinus1[2],     UInt(0), "Specifies the number of overlay elements in overlay 2")  
+  ("SEIOverlayElementLabelRange0",            cfg_overlaySEIElementLabelRanges[0], string(""), "Array of minimum and maximum values in order min0, max0, min1, max1, etc.\n"""
+                                                                                               "indicating the range of sample values corresponding to overlay elements of overlay 0")    
+  ("SEIOverlayElementLabelRange1",            cfg_overlaySEIElementLabelRanges[1], string(""), "Array of minimum and maximum values in order min0, max0, min1, max1, etc.\n"""
+                                                                                               "indicating the range of sample values corresponding to overlay elements of overlay 1")    
+  ("SEIOverlayElementLabelRange2",            cfg_overlaySEIElementLabelRanges[2], string(""), "Array of minimum and maximum values in order min0, max0, min1, max1, etc.\n"""
+                                                                                               "indicating the range of sample values corresponding to overlay elements of overlay 2")  
+  ("SEIOverlayLanguage0",                     cfg_overlaySEILanguage[0],           string(""), "Indicates the language of overlay 0 by a language tag according to RFC 5646")
+  ("SEIOverlayLanguage1",                     cfg_overlaySEILanguage[1],           string(""), "Indicates the language of overlay 1 by a language tag according to RFC 5646")
+  ("SEIOverlayLanguage2",                     cfg_overlaySEILanguage[2],           string(""), "Indicates the language of overlay 2 by a language tag according to RFC 5646")
+  ("SEIOverlayName0",                         cfg_overlaySEIName[0],       string("Overlay0"), "Indicates the name of overlay 0")
+  ("SEIOverlayName1",                         cfg_overlaySEIName[1],       string("Overlay1"), "Indicates the name of overlay 1")
+  ("SEIOverlayName2",                         cfg_overlaySEIName[2],       string("Overlay2"), "Indicates the name of overlay 2")
+  ("SEIOverlayElementNames0",                 cfg_overlaySEIElementNames[0],       string(""), "Indicates the names of all overlay elements of overlay 0 in the format name1|name2|name3|...")                                                                                       
+  ("SEIOverlayElementNames1",                 cfg_overlaySEIElementNames[1],       string(""), "Indicates the names of all overlay elements of overlay 1 in the format name1|name2|name3|...")                                                                                       
+  ("SEIOverlayElementNames2",                 cfg_overlaySEIElementNames[2],       string(""), "Indicates the names of all overlay elements of overlay 2 in the format name1|name2|name3|...")                                                                                       
+  ("SEIOverlayPersistenceFlag",               m_overlayInfoPersistenceFlag,              true, "Indicates if the SEI message applies to the current picture only (0) or also to following pictures (1)")
+#endif
 #if Q0189_TMVP_CONSTRAINTS
   ("SEITemporalMotionVectorPredictionConstraints",             m_TMVPConstraintsSEIEnabled,              0, "Control generation of TMVP constrants SEI message")
@@ -2097,4 +2161,79 @@
       pcOutputKneePointValue = NULL;
     }
+  }
+#endif
+#if Q0096_OVERLAY_SEI
+  if( m_overlaySEIEnabled && !m_overlayInfoCancelFlag )
+  {
+    m_overlayIdx.resize                 ( m_numOverlaysMinus1+1 );  
+    m_overlayLanguagePresentFlag.resize ( m_numOverlaysMinus1+1 );
+    m_overlayContentLayerId.resize      ( m_numOverlaysMinus1+1 );
+    m_overlayLabelPresentFlag.resize    ( m_numOverlaysMinus1+1 );
+    m_overlayLabelLayerId.resize        ( m_numOverlaysMinus1+1 );
+    m_overlayAlphaPresentFlag.resize    ( m_numOverlaysMinus1+1 );
+    m_overlayAlphaLayerId.resize        ( m_numOverlaysMinus1+1 );
+    m_numOverlayElementsMinus1.resize   ( m_numOverlaysMinus1+1 );
+    m_overlayElementLabelMin.resize     ( m_numOverlaysMinus1+1 );
+    m_overlayElementLabelMax.resize     ( m_numOverlaysMinus1+1 );  
+    m_overlayLanguage.resize            ( m_numOverlaysMinus1+1 );     
+    m_overlayName.resize                ( m_numOverlaysMinus1+1 );     
+    m_overlayElementName.resize         ( m_numOverlaysMinus1+1 );     
+    for (Int i=0 ; i<=m_numOverlaysMinus1 ; i++)
+    {
+      m_overlayIdx[i]                  = cfg_overlaySEIIdx[i];
+      m_overlayLanguagePresentFlag[i]  = cfg_overlaySEILanguagePresentFlag[i];
+      m_overlayContentLayerId[i]       = cfg_overlaySEIContentLayerId[i];
+      m_overlayLabelPresentFlag[i]     = cfg_overlaySEILabelPresentFlag[i];
+      m_overlayLabelLayerId[i]         = cfg_overlaySEILabelLayerId[i];
+      m_overlayAlphaPresentFlag[i]     = cfg_overlaySEIAlphaPresentFlag[i];
+      m_overlayAlphaLayerId[i]         = cfg_overlaySEIAlphaLayerId[i];
+      m_numOverlayElementsMinus1[i]    = cfg_overlaySEINumElementsMinus1[i];
+      m_overlayLanguage[i]             = cfg_overlaySEILanguage[i];
+      m_overlayName[i]                 = cfg_overlaySEIName[i];
+      
+      //parse min and max values of label elements
+      istringstream ranges(cfg_overlaySEIElementLabelRanges[i]);
+      string range;          
+      UInt val;        
+      vector<UInt> vRanges;
+      while ( getline(ranges, range, ' ') ) 
+      {        
+        istringstream(range) >> val;        
+        vRanges.push_back(val);
+      }      
+      assert( vRanges.size()%2==0 );
+      assert( vRanges.size()==2*(m_numOverlayElementsMinus1[i]+1) );
+      m_overlayElementLabelMin[i].resize( m_numOverlayElementsMinus1[i]+1 );
+      m_overlayElementLabelMax[i].resize( m_numOverlayElementsMinus1[i]+1 );
+      for (Int j=0 ; j<=m_numOverlayElementsMinus1[i] ; j++)
+      {
+        m_overlayElementLabelMin[i][j] = vRanges[2*j];
+        m_overlayElementLabelMax[i][j] = vRanges[2*j+1];
+      }
+      
+      //parse overlay element names
+      istringstream elementNames(cfg_overlaySEIElementNames[i]);
+      string elementName;                
+      vector<string> vElementName;                
+      while ( getline(elementNames, elementName, '|') ) 
+      {        
+        vElementName.push_back(elementName);         
+      }      
+      if ( m_overlayLabelPresentFlag[i] )
+      {
+        m_overlayElementName[i].resize( m_numOverlayElementsMinus1[i]+1 );     
+        for (Int j=0 ; j<=m_numOverlayElementsMinus1[i] ; j++)
+        {
+          if (j < vElementName.size())
+          {
+            m_overlayElementName[i][j] = vElementName[j];
+          }
+          else
+          {
+            m_overlayElementName[i][j] = string("NoElementName");
+          }
+        }
+      }            
+    }        
   }
 #endif
@@ -3357,4 +3496,18 @@
   }
 #endif
+#if Q0096_OVERLAY_SEI
+  if( m_overlaySEIEnabled && !m_overlayInfoCancelFlag )
+  {
+    xConfirmPara( m_overlayContentAuxIdMinus128 < 0 || m_overlayContentAuxIdMinus128 > 31, "SEIOverlayContentAuxIdMinus128 must be in the range of 0 to 31");
+    xConfirmPara( m_overlayLabelAuxIdMinus128 < 0 || m_overlayLabelAuxIdMinus128 > 31, "SEIOverlayLabelAuxIdMinus128 must be in the range of 0 to 31");
+    xConfirmPara( m_overlayAlphaAuxIdMinus128 < 0 || m_overlayAlphaAuxIdMinus128 > 31, "SEIOverlayAlphaAuxIdMinus128 must be in the range of 0 to 31");
+    xConfirmPara( m_numOverlaysMinus1 < 0 || m_numOverlaysMinus1 > 15, "SEIOverlayNumOverlaysMinus1 must be in the range of 0 to 15");
+    for (Int i=0 ; i<=m_numOverlaysMinus1 ; i++ )
+    {
+      xConfirmPara( m_overlayIdx[i] < 0 || m_overlayIdx[i] > 255, "SEIOverlayIdx must be in the range of 0 to 255");
+      xConfirmPara( m_numOverlayElementsMinus1[i] < 0 || m_numOverlayElementsMinus1[i] > 255, "SEIOverlayNumElementsMinus1 must be in the range of 0 to 255");
+    }
+  }
+#endif
 #if Q0074_COLOUR_REMAPPING_SEI
 #if !SVC_EXTENSION
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 911)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 912)
@@ -451,4 +451,27 @@
   Int*      m_kneeSEIOutputKneePoint;
 #endif
+#if Q0096_OVERLAY_SEI
+  Bool                                m_overlaySEIEnabled;
+  Bool                                m_overlayInfoCancelFlag;
+  UInt                                m_overlayContentAuxIdMinus128;
+  UInt                                m_overlayLabelAuxIdMinus128;
+  UInt                                m_overlayAlphaAuxIdMinus128;
+  UInt                                m_overlayElementLabelValueLengthMinus8;
+  UInt                                m_numOverlaysMinus1;
+  std::vector<UInt>                   m_overlayIdx;  
+  std::vector<Bool>                   m_overlayLanguagePresentFlag;
+  std::vector<UInt>                   m_overlayContentLayerId;
+  std::vector<Bool>                   m_overlayLabelPresentFlag;
+  std::vector<UInt>                   m_overlayLabelLayerId;
+  std::vector<Bool>                   m_overlayAlphaPresentFlag;
+  std::vector<UInt>                   m_overlayAlphaLayerId;
+  std::vector<UInt>                   m_numOverlayElementsMinus1;
+  std::vector< std::vector<UInt> >    m_overlayElementLabelMin;
+  std::vector< std::vector<UInt> >    m_overlayElementLabelMax;
+  std::vector<string>                 m_overlayLanguage;  
+  std::vector<string>                 m_overlayName;  
+  std::vector< std::vector<string> >  m_overlayElementName;  
+  Bool                                m_overlayInfoPersistenceFlag;
+#endif
 #if P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
   Bool      m_crossLayerAlignedIdrOnlyFlag;
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 911)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 912)
@@ -549,4 +549,27 @@
     m_acTEncTop[layer].setKneeSEIInputKneePoint                     ( m_kneeSEIInputKneePoint );
     m_acTEncTop[layer].setKneeSEIOutputKneePoint                    ( m_kneeSEIOutputKneePoint );
+#endif
+#if Q0096_OVERLAY_SEI
+    m_acTEncTop[layer].setOverlaySEIEnabled                         ( m_overlaySEIEnabled );
+    m_acTEncTop[layer].setOverlaySEICancelFlag                      ( m_overlayInfoCancelFlag );
+    m_acTEncTop[layer].setOverlaySEIContentAuxIdMinus128            ( m_overlayContentAuxIdMinus128 );
+    m_acTEncTop[layer].setOverlaySEILabelAuxIdMinus128              ( m_overlayLabelAuxIdMinus128 );
+    m_acTEncTop[layer].setOverlaySEIAlphaAuxIdMinus128              ( m_overlayAlphaAuxIdMinus128 );
+    m_acTEncTop[layer].setOverlaySEIElementLabelValueLengthMinus8   ( m_overlayElementLabelValueLengthMinus8 );
+    m_acTEncTop[layer].setOverlaySEINumOverlaysMinus1               ( m_numOverlaysMinus1 );
+    m_acTEncTop[layer].setOverlaySEIIdx                             ( m_overlayIdx );
+    m_acTEncTop[layer].setOverlaySEILanguagePresentFlag             ( m_overlayLanguagePresentFlag );
+    m_acTEncTop[layer].setOverlaySEIContentLayerId                  ( m_overlayContentLayerId );
+    m_acTEncTop[layer].setOverlaySEILabelPresentFlag                ( m_overlayLabelPresentFlag );
+    m_acTEncTop[layer].setOverlaySEILabelLayerId                    ( m_overlayLabelLayerId );
+    m_acTEncTop[layer].setOverlaySEIAlphaPresentFlag                ( m_overlayAlphaPresentFlag );
+    m_acTEncTop[layer].setOverlaySEIAlphaLayerId                    ( m_overlayAlphaLayerId );
+    m_acTEncTop[layer].setOverlaySEINumElementsMinus1               ( m_numOverlayElementsMinus1 );
+    m_acTEncTop[layer].setOverlaySEIElementLabelMin                 ( m_overlayElementLabelMin );
+    m_acTEncTop[layer].setOverlaySEIElementLabelMax                 ( m_overlayElementLabelMax );
+    m_acTEncTop[layer].setOverlaySEILanguage                        ( m_overlayLanguage );
+    m_acTEncTop[layer].setOverlaySEIName                            ( m_overlayName );
+    m_acTEncTop[layer].setOverlaySEIElementName                     ( m_overlayElementName );
+    m_acTEncTop[layer].setOverlaySEIPersistenceFlag                 ( m_overlayInfoPersistenceFlag );
 #endif
 #if Q0074_COLOUR_REMAPPING_SEI
Index: /branches/SHM-dev/source/Lib/TLibCommon/SEI.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/SEI.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibCommon/SEI.h	(revision 912)
@@ -111,4 +111,7 @@
     FRAME_FIELD_INFO                     = 147,
 #endif
+#if Q0096_OVERLAY_SEI
+    OVERLAY_INFO                         = 166,    
+#endif
   };
   
@@ -699,3 +702,51 @@
 #endif
 
+#if Q0096_OVERLAY_SEI
+class SEIOverlayInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return OVERLAY_INFO; }
+  SEIOverlayInfo() 
+    :  m_numOverlaysMinus1(-1) 
+    {}
+
+  virtual ~SEIOverlayInfo() 
+  {
+    for (Int i=0 ; i<=m_numOverlaysMinus1 ; i++)
+    { 
+      delete [] m_overlayLanguage[i];          
+      delete [] m_overlayName[i];
+      for (Int j=0 ; j<=m_numOverlayElementsMinus1[i] ; j++)
+      {
+        delete [] m_overlayElementName[i][j];
+      }
+    }
+  }
+
+  Bool                                m_overlayInfoCancelFlag;
+  UInt                                m_overlayContentAuxIdMinus128;
+  UInt                                m_overlayLabelAuxIdMinus128;
+  UInt                                m_overlayAlphaAuxIdMinus128;
+  UInt                                m_overlayElementLabelValueLengthMinus8;
+  UInt                                m_numOverlaysMinus1;
+  std::vector<UInt>                   m_overlayIdx;
+  std::vector<Bool>                   m_languageOverlayPresentFlag;
+  std::vector<UInt>                   m_overlayContentLayerId;
+  std::vector<Bool>                   m_overlayLabelPresentFlag;
+  std::vector<UInt>                   m_overlayLabelLayerId;
+  std::vector<Bool>                   m_overlayAlphaPresentFlag;
+  std::vector<UInt>                   m_overlayAlphaLayerId;
+  std::vector<UInt>                   m_numOverlayElementsMinus1;
+  std::vector< std::vector<UInt> >    m_overlayElementLabelMin;
+  std::vector< std::vector<UInt> >    m_overlayElementLabelMax;
+  std::vector<UChar*>                 m_overlayLanguage;
+  std::vector<UInt>                   m_overlayLanguageLength;
+  std::vector<UChar*>                 m_overlayName;
+  std::vector<UInt>                   m_overlayNameLength;
+  std::vector< std::vector<UChar*> >  m_overlayElementName;
+  std::vector< std::vector<UInt> >    m_overlayElementNameLength;
+  Bool                                m_overlayInfoPersistenceFlag;
+};
+#endif
+
 //! \}
Index: /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 912)
@@ -320,4 +320,10 @@
 #define Q0247_FRAME_FIELD_INFO           1      ///< JCTVC-Q0247: field_frame_info SEI message
 #define R0247_SEI_ACTIVE                 1      ///< JCTVC-R0247: active parameter sets SEI message
+#define Q0096_OVERLAY_SEI                1      ///< JCTVC-Q0096, JCTVC-Q0045: selectable overlays SEI message
+#if Q0096_OVERLAY_SEI 
+# define MAX_OVERLAYS                    16
+# define MAX_OVERLAY_ELEMENTS            256
+# define MAX_OVERLAY_STRING_BYTES        256
+#endif
 
 #endif // SVC_EXTENSION
Index: /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 912)
@@ -146,4 +146,9 @@
     break;
 #endif
+#if Q0096_OVERLAY_SEI
+  case SEI::OVERLAY_INFO:
+    fprintf( g_hTrace, "=========== Overlay Information SEI message ===========\n");
+    break;
+#endif
 #endif //SVC_EXTENSION
   default:
@@ -412,4 +417,10 @@
      break;
 #endif
+#if Q0096_OVERLAY_SEI
+   case SEI::OVERLAY_INFO:
+     sei = new SEIOverlayInfo;
+     xParseSEIOverlayInfo((SEIOverlayInfo&) *sei, payloadSize);
+     break;
+#endif
 #endif //SVC_EXTENSION
       break;
@@ -1726,4 +1737,108 @@
 #endif
 
+#if Q0096_OVERLAY_SEI
+Void SEIReader::xParseSEIOverlayInfo(SEIOverlayInfo& sei, UInt /*payloadSize*/){
+  Int i, j;
+  UInt val;
+  READ_FLAG( val, "overlay_info_cancel_flag" );                 sei.m_overlayInfoCancelFlag = val;
+  if ( !sei.m_overlayInfoCancelFlag )
+  {
+    READ_UVLC( val, "overlay_content_aux_id_minus128" );            sei.m_overlayContentAuxIdMinus128 = val;
+    READ_UVLC( val, "overlay_label_aux_id_minus128" );              sei.m_overlayLabelAuxIdMinus128 = val;
+    READ_UVLC( val, "overlay_alpha_aux_id_minus128" );              sei.m_overlayAlphaAuxIdMinus128 = val;
+    READ_UVLC( val, "overlay_element_label_value_length_minus8" );  sei.m_overlayElementLabelValueLengthMinus8 = val;
+    READ_UVLC( val, "num_overlays_minus1" );                        sei.m_numOverlaysMinus1 = val;
+
+    assert( sei.m_numOverlaysMinus1 < MAX_OVERLAYS );
+    sei.m_overlayIdx.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_languageOverlayPresentFlag.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayContentLayerId.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayLabelPresentFlag.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayLabelLayerId.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayAlphaPresentFlag.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayAlphaLayerId.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_numOverlayElementsMinus1.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayElementLabelMin.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayElementLabelMax.resize( sei.m_numOverlaysMinus1+1 );
+    for ( i=0 ; i<=sei.m_numOverlaysMinus1 ; i++ )
+    {
+      READ_UVLC( val, "overlay_idx" );                      sei.m_overlayIdx[i] = val;
+      READ_FLAG( val, "language_overlay_present_flag" );    sei.m_languageOverlayPresentFlag[i] = val;
+      READ_CODE( 6, val, "overlay_content_layer_id");       sei.m_overlayContentLayerId[i] = val;
+      READ_FLAG( val, "overlay_label_present_flag" );       sei.m_overlayLabelPresentFlag[i] = val;
+      if ( sei.m_overlayLabelPresentFlag[i] )
+      {
+        READ_CODE( 6, val, "overlay_label_layer_id");     sei.m_overlayLabelLayerId[i] = val;
+      }
+      READ_FLAG( val, "overlay_alpha_present_flag" );       sei.m_overlayAlphaPresentFlag[i] = val;
+      if ( sei.m_overlayAlphaPresentFlag[i] )
+      {
+        READ_CODE( 6, val, "overlay_alpha_layer_id");     sei.m_overlayAlphaLayerId[i] = val;
+      }
+      if ( sei.m_overlayLabelPresentFlag[i] )
+      {
+        READ_UVLC( val, "num_overlay_elements_minus1");   sei.m_numOverlayElementsMinus1[i] = val;
+        assert( sei.m_numOverlayElementsMinus1[i] < MAX_OVERLAY_ELEMENTS );
+        sei.m_overlayElementLabelMin[i].resize( sei.m_numOverlayElementsMinus1[i]+1 );
+        sei.m_overlayElementLabelMax[i].resize( sei.m_numOverlayElementsMinus1[i]+1 );
+        for ( j=0 ; j<=sei.m_numOverlayElementsMinus1[i] ; j++ )
+        {
+          READ_CODE(sei.m_overlayElementLabelValueLengthMinus8 + 8, val, "overlay_element_label_min"); sei.m_overlayElementLabelMin[i][j] = val;
+          READ_CODE(sei.m_overlayElementLabelValueLengthMinus8 + 8, val, "overlay_element_label_max"); sei.m_overlayElementLabelMax[i][j] = val;
+        }      
+      }
+      else
+      {
+        sei.m_numOverlayElementsMinus1[i] = 0;
+      }
+    }
+
+    // byte alignment
+    while ( m_pcBitstream->getNumBitsRead() % 8 != 0 )
+    {
+      READ_FLAG( val, "overlay_zero_bit" );
+      assert( val==0 );
+    }
+
+    UChar* sval = new UChar[MAX_OVERLAY_STRING_BYTES];
+    UInt slen;    
+    sei.m_overlayLanguage.resize( sei.m_numOverlaysMinus1+1, NULL );
+    sei.m_overlayLanguageLength.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayName.resize( sei.m_numOverlaysMinus1+1, NULL );
+    sei.m_overlayNameLength.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayElementName.resize( sei.m_numOverlaysMinus1+1 );
+    sei.m_overlayElementNameLength.resize( sei.m_numOverlaysMinus1+1 );
+    for ( i=0 ; i<=sei.m_numOverlaysMinus1 ; i++ )
+    {
+      if ( sei.m_languageOverlayPresentFlag[i] )
+      {
+        READ_STRING( MAX_OVERLAY_STRING_BYTES, sval, slen, "overlay_language" );
+        sei.m_overlayLanguage[i] = new UChar[slen];
+        memcpy(sei.m_overlayLanguage[i], sval, slen);
+        sei.m_overlayLanguageLength[i] = slen;
+      }
+      READ_STRING( MAX_OVERLAY_STRING_BYTES, sval, slen, "overlay_name" );
+      sei.m_overlayName[i] = new UChar[slen];
+      memcpy(sei.m_overlayName[i], sval, slen);
+      sei.m_overlayNameLength[i] = slen;
+      if ( sei.m_overlayLabelPresentFlag[i] )
+      {
+        sei.m_overlayElementName[i].resize( sei.m_numOverlayElementsMinus1[i]+1, NULL );
+        sei.m_overlayElementNameLength[i].resize( sei.m_numOverlayElementsMinus1[i]+1 );
+        for ( j=0 ; j<=sei.m_numOverlayElementsMinus1[i] ; j++)
+        {
+          READ_STRING( MAX_OVERLAY_STRING_BYTES, sval, slen, "overlay_element_name" );
+          sei.m_overlayElementName[i][j] = new UChar[slen];
+          memcpy(sei.m_overlayElementName[i][j], sval, slen);
+          sei.m_overlayElementNameLength[i][j] = slen;
+        }
+      }
+    }
+    READ_FLAG( val, "overlay_info_persistence_flag" );        sei.m_overlayInfoPersistenceFlag = val;
+  }
+  xParseByteAlign();
+}
+#endif
+
 #endif //SVC_EXTENSION
 
Index: /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h	(revision 912)
@@ -146,4 +146,7 @@
   Void xParseSEIFrameFieldInfo    (SEIFrameFieldInfo& sei, UInt payloadSize);
 #endif
+#if Q0096_OVERLAY_SEI
+  Void xParseSEIOverlayInfo           (SEIOverlayInfo& sei, UInt payloadSize);
+#endif
   Void xParseByteAlign();
 };
Index: /branches/SHM-dev/source/Lib/TLibDecoder/SyntaxElementParser.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibDecoder/SyntaxElementParser.cpp	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibDecoder/SyntaxElementParser.cpp	(revision 912)
@@ -85,4 +85,14 @@
 }
 
+#if Q0096_OVERLAY_SEI
+Void  SyntaxElementParser::xReadStringTr        (UInt buSize, UChar *pValue, UInt& rLength, const Char *pSymbolName)
+{
+  xReadString(buSize, pValue, rLength);
+  fprintf( g_hTrace, "%8lld  ", g_nSymbolCounter++ );
+  fprintf( g_hTrace, "%-50s st(v=%d)  : %s\n", pSymbolName, rLength, pValue );
+  fflush ( g_hTrace );
+}
+#endif
+
 #endif
 
@@ -153,4 +163,24 @@
 }
 
+#if Q0096_OVERLAY_SEI
+Void  SyntaxElementParser::xReadString  (UInt bufSize, UChar *pVal, UInt& rLength)
+{
+  assert( m_pcBitstream->getNumBitsRead() % 8 == 0 ); //always start reading at a byte-aligned position
+  assert ( bufSize > 1 ); //last byte always used for null-termination
+  UInt val;
+  UInt i;
+  for (i=0 ; i<bufSize ; ++i ) 
+  {
+    m_pcBitstream->readByte( val );
+    pVal[i] = val;
+    if ( val == 0)
+    {
+      break;
+    }
+  }
+  rLength = i;
+  assert( pVal[rLength] == 0 );
+}
+#endif
 
 //! \}
Index: /branches/SHM-dev/source/Lib/TLibDecoder/SyntaxElementParser.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibDecoder/SyntaxElementParser.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibDecoder/SyntaxElementParser.h	(revision 912)
@@ -51,4 +51,7 @@
 #define READ_SVLC(        code, name)     xReadSvlcTr (         code, name )
 #define READ_FLAG(        code, name)     xReadFlagTr (         code, name )
+#if Q0096_OVERLAY_SEI
+#define READ_STRING(bufSize, code, length, name)   xReadStringTr ( bufSize, code, length, name )
+#endif
 
 #else
@@ -58,4 +61,7 @@
 #define READ_SVLC(        code, name)     xReadSvlc (         code )
 #define READ_FLAG(        code, name)     xReadFlag (         code )
+#if Q0096_OVERLAY_SEI
+#define READ_STRING(bufSize, code, length, name)   xReadString ( bufSize, code, length )
+#endif
 
 #endif
@@ -82,4 +88,7 @@
   Void  xReadSvlc    ( Int&   val );
   Void  xReadFlag    ( UInt&  val );
+#if Q0096_OVERLAY_SEI
+  Void  xReadString  (UInt bufSize, UChar *val, UInt& length);
+#endif
 #if ENC_DEC_TRACE
   Void  xReadCodeTr  (UInt  length, UInt& rValue, const Char *pSymbolName);
@@ -87,4 +96,7 @@
   Void  xReadSvlcTr  (               Int& rValue, const Char *pSymbolName);
   Void  xReadFlagTr  (              UInt& rValue, const Char *pSymbolName);
+#if Q0096_OVERLAY_SEI
+  Void  xReadStringTr(UInt bufSize, UChar *pValue, UInt& rLength, const Char *pSymbolName);
+#endif
 #endif
 public:
Index: /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 912)
@@ -140,4 +140,9 @@
     break;
 #endif
+#if Q0096_OVERLAY_SEI
+  case SEI::OVERLAY_INFO:
+    fprintf( g_hTrace, "=========== Overlay Information SEI message ===========\n");
+    break;
+#endif
 #endif //SVC_EXTENSION
   default:
@@ -285,4 +290,9 @@
    case SEI::FRAME_FIELD_INFO:
      xWriteSEIFrameFieldInfo(*static_cast<const SEIFrameFieldInfo*>(&sei));
+     break;
+#endif
+#if Q0096_OVERLAY_SEI
+   case SEI::OVERLAY_INFO:
+     xWriteSEIOverlayInfo(*static_cast<const SEIOverlayInfo*>(&sei));
      break;
 #endif
@@ -1330,4 +1340,72 @@
 #endif
 
+#if Q0096_OVERLAY_SEI
+Void SEIWriter::xWriteSEIOverlayInfo(const SEIOverlayInfo &sei)
+{
+  Int i,j;
+  WRITE_FLAG( sei.m_overlayInfoCancelFlag, "overlay_info_cancel_flag" );
+  if ( !sei.m_overlayInfoCancelFlag )
+  {
+    WRITE_UVLC( sei.m_overlayContentAuxIdMinus128, "overlay_content_aux_id_minus128" );
+    WRITE_UVLC( sei.m_overlayLabelAuxIdMinus128, "overlay_label_aux_id_minus128" );
+    WRITE_UVLC( sei.m_overlayAlphaAuxIdMinus128, "overlay_alpha_aux_id_minus128" );
+    WRITE_UVLC( sei.m_overlayElementLabelValueLengthMinus8, "overlay_element_label_value_length_minus8" );
+    assert( sei.m_numOverlaysMinus1 < MAX_OVERLAYS );
+    WRITE_UVLC( sei.m_numOverlaysMinus1, "num_overlays_minus1" );
+    for (i=0 ; i<=sei.m_numOverlaysMinus1 ; i++)
+    {
+      WRITE_UVLC( sei.m_overlayIdx[i], "overlay_idx" );
+      WRITE_FLAG( sei.m_languageOverlayPresentFlag[i], "language_overlay_present_flag" );
+      WRITE_CODE( sei.m_overlayContentLayerId[i], 6, "overlay_content_layer_id");
+      WRITE_FLAG( sei.m_overlayLabelPresentFlag[i], "overlay_label_present_flag" );
+      if ( sei.m_overlayLabelPresentFlag[i] )
+      {
+        WRITE_CODE(  sei.m_overlayLabelLayerId[i], 6, "overlay_label_layer_id");
+      }
+      WRITE_FLAG( sei.m_overlayAlphaPresentFlag[i], "overlay_alpha_present_flag" );
+      if ( sei.m_overlayAlphaPresentFlag[i] )
+      {
+        WRITE_CODE( sei.m_overlayAlphaLayerId[i], 6, "overlay_alpha_layer_id");
+      }
+      if ( sei.m_overlayLabelPresentFlag[i] )
+      {
+        assert( sei.m_numOverlayElementsMinus1[i] < MAX_OVERLAY_ELEMENTS );
+        WRITE_UVLC( sei.m_numOverlayElementsMinus1[i], "num_overlay_elements_minus1");
+        for ( j=0 ; j<=sei.m_numOverlayElementsMinus1[i] ; j++ )
+        {
+          WRITE_CODE(sei.m_overlayElementLabelMin[i][j], sei.m_overlayElementLabelValueLengthMinus8 + 8, "overlay_element_label_min");
+          WRITE_CODE(sei.m_overlayElementLabelMax[i][j], sei.m_overlayElementLabelValueLengthMinus8 + 8, "overlay_element_label_max"); 
+        }
+      }
+    }
+
+
+    // byte alignment
+    while ( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0 )
+    {
+      WRITE_FLAG( 0, "overlay_zero_bit" );
+    }
+
+    for ( i=0 ; i<=sei.m_numOverlaysMinus1 ; i++ )
+    {
+      if ( sei.m_languageOverlayPresentFlag[i] )
+      {
+        WRITE_STRING( sei.m_overlayLanguage[i], sei.m_overlayLanguageLength[i], "overlay_language" );    //WRITE_STRING adds zero-termination byte
+      }
+      WRITE_STRING( sei.m_overlayName[i], sei.m_overlayNameLength[i], "overlay_name" );
+      if ( sei.m_overlayLabelPresentFlag[i] )
+      {
+        for ( j=0 ; j<=sei.m_numOverlayElementsMinus1[i] ; j++)
+        {
+          WRITE_STRING( sei.m_overlayElementName[i][j], sei.m_overlayElementNameLength[i][j], "overlay_element_name" );
+        }
+      }
+    }
+    WRITE_FLAG( sei.m_overlayInfoPersistenceFlag, "overlay_info_persistence_flag" );
+  }
+  xWriteByteAlign();
+}
+#endif
+
 #endif //SVC_EXTENSION
 
Index: /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 912)
@@ -123,4 +123,7 @@
   Void xWriteSEIVPSRewriting(const SEIVPSRewriting &sei);
 #endif
+#if Q0096_OVERLAY_SEI
+  Void xWriteSEIOverlayInfo(const SEIOverlayInfo &sei);
+#endif
 #endif //SVC_EXTENSION
 };
Index: /branches/SHM-dev/source/Lib/TLibEncoder/SyntaxElementWriter.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/SyntaxElementWriter.cpp	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/SyntaxElementWriter.cpp	(revision 912)
@@ -91,4 +91,16 @@
 }
 
+#if Q0096_OVERLAY_SEI
+Void  SyntaxElementWriter::xWriteStringTr( UChar* value, UInt length, const Char *pSymbolName)
+{
+  xWriteString(value, length);
+  if( g_HLSTraceEnable )
+  {
+    fprintf( g_hTrace, "%8lld  ", g_nSymbolCounter++ );
+    fprintf( g_hTrace, "%-50s st(v=%d)  : %s\n", pSymbolName, length, value ); 
+  }
+}
+#endif
+
 #endif
 
@@ -130,3 +142,15 @@
 }
 
+#if Q0096_OVERLAY_SEI
+Void  SyntaxElementWriter::xWriteString( UChar* sCode, UInt uiLength)
+{
+  assert(m_pcBitIf->getNumberOfWrittenBits() % 8 == 0 );
+  for (Int i=0 ; i<uiLength; i++)
+  {
+    m_pcBitIf->write( sCode[i], 8 );
+  }
+  m_pcBitIf->write( 0, 8 ); //zero-termination byte
+}
+#endif
+
 //! \}
Index: /branches/SHM-dev/source/Lib/TLibEncoder/SyntaxElementWriter.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/SyntaxElementWriter.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/SyntaxElementWriter.h	(revision 912)
@@ -56,4 +56,7 @@
 #define WRITE_SVLC( value,         name)    xWriteSvlcTr ( value,         name )
 #define WRITE_FLAG( value,         name)    xWriteFlagTr ( value,         name )
+#if Q0096_OVERLAY_SEI
+#define WRITE_STRING( value, length, name)   xWriteStringTr( value, length, name )
+#endif
 
 #else
@@ -63,4 +66,7 @@
 #define WRITE_SVLC( value,         name)     xWriteSvlc ( value )
 #define WRITE_FLAG( value,         name)     xWriteFlag ( value )
+#if Q0096_OVERLAY_SEI
+#define WRITE_STRING( value, length, name)   xWriteString( value, length )
+#endif
 
 #endif
@@ -82,4 +88,7 @@
   Void  xWriteSvlc            ( Int  iCode   );
   Void  xWriteFlag            ( UInt uiCode );
+#if Q0096_OVERLAY_SEI
+  Void  xWriteString          ( UChar* sCode, UInt uiLength);
+#endif
 #if ENC_DEC_TRACE
   Void  xWriteCodeTr          ( UInt value, UInt  length, const Char *pSymbolName);
@@ -87,4 +96,7 @@
   Void  xWriteSvlcTr          ( Int  value,               const Char *pSymbolName);
   Void  xWriteFlagTr          ( UInt value,               const Char *pSymbolName);
+#if Q0096_OVERLAY_SEI
+  Void  xWriteStringTr        ( UChar* value, UInt length, const Char *pSymbolName);
+#endif
 #endif
 
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 912)
@@ -387,4 +387,27 @@
   Int*      m_kneeSEIInputKneePoint;
   Int*      m_kneeSEIOutputKneePoint;
+#endif
+#if Q0096_OVERLAY_SEI
+  Bool                                m_overlaySEIEnabled;
+  Bool                                m_overlayInfoCancelFlag;
+  UInt                                m_overlayContentAuxIdMinus128;
+  UInt                                m_overlayLabelAuxIdMinus128;
+  UInt                                m_overlayAlphaAuxIdMinus128;
+  UInt                                m_overlayElementLabelValueLengthMinus8;
+  UInt                                m_numOverlaysMinus1;
+  std::vector<UInt>                   m_overlayIdx;  
+  std::vector<Bool>                   m_overlayLanguagePresentFlag;
+  std::vector<UInt>                   m_overlayContentLayerId;
+  std::vector<Bool>                   m_overlayLabelPresentFlag;
+  std::vector<UInt>                   m_overlayLabelLayerId;
+  std::vector<Bool>                   m_overlayAlphaPresentFlag;
+  std::vector<UInt>                   m_overlayAlphaLayerId;
+  std::vector<UInt>                   m_numOverlayElementsMinus1;
+  std::vector< std::vector<UInt> >    m_overlayElementLabelMin;
+  std::vector< std::vector<UInt> >    m_overlayElementLabelMax;
+  std::vector<string>                 m_overlayLanguage;  
+  std::vector<string>                 m_overlayName;  
+  std::vector< std::vector<string> >  m_overlayElementName;  
+  Bool                                m_overlayInfoPersistenceFlag;
 #endif
 #if Q0189_TMVP_CONSTRAINTS
@@ -994,4 +1017,48 @@
   UInt  getIlcIdc(UInt b)                                  { return m_ilcIdc[b]; }
 #endif
+#if Q0096_OVERLAY_SEI  
+  Void                                setOverlaySEIEnabled(Int b)                                              { m_overlaySEIEnabled = b; }
+  Bool                                getOverlaySEIEnabled()                                                   { return m_overlaySEIEnabled; }
+  Void                                setOverlaySEICancelFlag(Int b)                                           { m_overlayInfoCancelFlag = b; } 
+  Bool                                getOverlaySEICancelFlag()                                                { return m_overlayInfoCancelFlag; } 
+  Void                                setOverlaySEIContentAuxIdMinus128(UInt b)                                { m_overlayContentAuxIdMinus128 = b; }     
+  UInt                                getOverlaySEIContentAuxIdMinus128()                                      { return m_overlayContentAuxIdMinus128; }     
+  Void                                setOverlaySEILabelAuxIdMinus128(UInt b)                                  { m_overlayLabelAuxIdMinus128 = b; }     
+  UInt                                getOverlaySEILabelAuxIdMinus128()                                        { return m_overlayLabelAuxIdMinus128; }  
+  Void                                setOverlaySEIAlphaAuxIdMinus128(UInt b)                                  { m_overlayAlphaAuxIdMinus128 = b; }     
+  UInt                                getOverlaySEIAlphaAuxIdMinus128()                                        { return m_overlayAlphaAuxIdMinus128; }  
+  Void                                setOverlaySEIElementLabelValueLengthMinus8(UInt b)                       { m_overlayElementLabelValueLengthMinus8 = b; }     
+  UInt                                getOverlaySEIElementLabelValueLengthMinus8()                             { return m_overlayElementLabelValueLengthMinus8; }  
+  Void                                setOverlaySEINumOverlaysMinus1(UInt b)                                   { m_numOverlaysMinus1 = b; }     
+  UInt                                getOverlaySEINumOverlaysMinus1()                                         { return m_numOverlaysMinus1; }     
+  Void                                setOverlaySEIIdx(const std::vector<UInt>& b)                             { m_overlayIdx = b; }      
+  std::vector<UInt>                   getOverlaySEIIdx()                                                       { return m_overlayIdx; }      
+  Void                                setOverlaySEILanguagePresentFlag(const std::vector<Bool>& b)             { m_overlayLanguagePresentFlag = b; }      
+  std::vector<Bool>                   getOverlaySEILanguagePresentFlag()                                       { return m_overlayLanguagePresentFlag; }   
+  Void                                setOverlaySEIContentLayerId(const std::vector<UInt>& b)                  { m_overlayContentLayerId = b; }      
+  std::vector<UInt>                   getOverlaySEIContentLayerId()                                            { return m_overlayContentLayerId; }      
+  Void                                setOverlaySEILabelPresentFlag(const std::vector<Bool>& b)                { m_overlayLabelPresentFlag = b; }      
+  std::vector<Bool>                   getOverlaySEILabelPresentFlag()                                          { return m_overlayLabelPresentFlag; } 
+  Void                                setOverlaySEILabelLayerId(const std::vector<UInt>& b)                    { m_overlayLabelLayerId = b; }      
+  std::vector<UInt>                   getOverlaySEILabelLayerId()                                              { return m_overlayLabelLayerId; }   
+  Void                                setOverlaySEIAlphaPresentFlag(const std::vector<Bool>& b)                { m_overlayAlphaPresentFlag = b; }      
+  std::vector<Bool>                   getOverlaySEIAlphaPresentFlag()                                          { return m_overlayAlphaPresentFlag; }     
+  Void                                setOverlaySEIAlphaLayerId(const std::vector<UInt>& b)                    { m_overlayAlphaLayerId = b; }      
+  std::vector<UInt>                   getOverlaySEIAlphaLayerId()                                              { return m_overlayAlphaLayerId; }   
+  Void                                setOverlaySEINumElementsMinus1(const std::vector<UInt>& b)               { m_numOverlayElementsMinus1 = b; }      
+  std::vector<UInt>                   getOverlaySEINumElementsMinus1()                                         { return m_numOverlayElementsMinus1; }     
+  Void                                setOverlaySEIElementLabelMin(const std::vector< std::vector<UInt> >& b)  { m_overlayElementLabelMin = b; }      
+  std::vector< std::vector<UInt> >    getOverlaySEIElementLabelMin()                                           { return m_overlayElementLabelMin; }   
+  Void                                setOverlaySEIElementLabelMax(const std::vector< std::vector<UInt> >& b)  { m_overlayElementLabelMax = b; }      
+  std::vector< std::vector<UInt> >    getOverlaySEIElementLabelMax()                                           { return m_overlayElementLabelMax; }              
+  Void                                setOverlaySEILanguage(const std::vector<string>& b)                      { m_overlayLanguage = b; }      
+  std::vector<string>                 getOverlaySEILanguage()                                                  { return m_overlayLanguage; }   
+  Void                                setOverlaySEIName(const std::vector<string>& b)                          { m_overlayName = b; }      
+  std::vector<string>                 getOverlaySEIName()                                                      { return m_overlayName; }   
+  Void                                setOverlaySEIElementName(const std::vector< std::vector<string> >& b)    { m_overlayElementName = b; }      
+  std::vector< std::vector<string> >  getOverlaySEIElementName()                                               { return m_overlayElementName; }   
+  Void                                setOverlaySEIPersistenceFlag(Int b)                                      { m_overlayInfoPersistenceFlag = b; } 
+  Bool                                getOverlaySEIPersistenceFlag()                                           { return m_overlayInfoPersistenceFlag; } 
+#endif
 #if Q0048_CGS_3D_ASYMLUT
   Void      setCGSFlag(Int n)             { m_nCGSFlag = n;    }
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 912)
@@ -382,4 +382,84 @@
 #endif
 
+#if Q0096_OVERLAY_SEI
+SEIOverlayInfo* TEncGOP::xCreateSEIOverlayInfo()
+{  
+  SEIOverlayInfo *sei = new SEIOverlayInfo();  
+  sei->m_overlayInfoCancelFlag = m_pcCfg->getOverlaySEICancelFlag();    
+  if ( !sei->m_overlayInfoCancelFlag )
+  {
+    sei->m_overlayContentAuxIdMinus128          = m_pcCfg->getOverlaySEIContentAuxIdMinus128(); 
+    sei->m_overlayLabelAuxIdMinus128            = m_pcCfg->getOverlaySEILabelAuxIdMinus128();  
+    sei->m_overlayAlphaAuxIdMinus128            = m_pcCfg->getOverlaySEIAlphaAuxIdMinus128(); 
+    sei->m_overlayElementLabelValueLengthMinus8 = m_pcCfg->getOverlaySEIElementLabelValueLengthMinus8(); 
+    sei->m_numOverlaysMinus1                    = m_pcCfg->getOverlaySEINumOverlaysMinus1();     
+    sei->m_overlayIdx                           = m_pcCfg->getOverlaySEIIdx();            
+    sei->m_languageOverlayPresentFlag           = m_pcCfg->getOverlaySEILanguagePresentFlag();
+    sei->m_overlayContentLayerId                = m_pcCfg->getOverlaySEIContentLayerId();   
+    sei->m_overlayLabelPresentFlag              = m_pcCfg->getOverlaySEILabelPresentFlag();   
+    sei->m_overlayLabelLayerId                  = m_pcCfg->getOverlaySEILabelLayerId();   
+    sei->m_overlayAlphaPresentFlag              = m_pcCfg->getOverlaySEIAlphaPresentFlag();   
+    sei->m_overlayAlphaLayerId                  = m_pcCfg->getOverlaySEIAlphaLayerId();   
+    sei->m_numOverlayElementsMinus1             = m_pcCfg->getOverlaySEINumElementsMinus1();
+    sei->m_overlayElementLabelMin               = m_pcCfg->getOverlaySEIElementLabelMin();
+    sei->m_overlayElementLabelMax               = m_pcCfg->getOverlaySEIElementLabelMax();    
+    sei->m_overlayLanguage.resize               ( sei->m_numOverlaysMinus1+1, NULL );
+    sei->m_overlayLanguageLength.resize         ( sei->m_numOverlaysMinus1+1 );
+    sei->m_overlayName.resize                   ( sei->m_numOverlaysMinus1+1, NULL );
+    sei->m_overlayNameLength.resize             ( sei->m_numOverlaysMinus1+1 );
+    sei->m_overlayElementName.resize            ( sei->m_numOverlaysMinus1+1 );
+    sei->m_overlayElementNameLength.resize      ( sei->m_numOverlaysMinus1+1 );  
+
+    Int i,j;
+    string strTmp;
+    Int nBytes;
+    assert( m_pcCfg->getOverlaySEILanguage().size()    == sei->m_numOverlaysMinus1+1 );
+    assert( m_pcCfg->getOverlaySEIName().size()        == sei->m_numOverlaysMinus1+1 );
+    assert( m_pcCfg->getOverlaySEIElementName().size() == sei->m_numOverlaysMinus1+1 );
+    
+    for ( i=0 ; i<=sei->m_numOverlaysMinus1; i++ )
+    {      
+      //language tag
+      if ( sei->m_languageOverlayPresentFlag[i] )
+      {                
+        strTmp = m_pcCfg->getOverlaySEILanguage()[i];
+        nBytes = m_pcCfg->getOverlaySEILanguage()[i].size();        
+        assert( nBytes>0 );
+        sei->m_overlayLanguage[i] = new UChar[nBytes];
+        memcpy(sei->m_overlayLanguage[i], strTmp.c_str(), nBytes);        
+        sei->m_overlayLanguageLength[i] = nBytes;        
+      }
+
+      //overlay name
+      strTmp = m_pcCfg->getOverlaySEIName()[i];
+      nBytes = m_pcCfg->getOverlaySEIName()[i].size();        
+      assert( nBytes>0 );
+      sei->m_overlayName[i] = new UChar[nBytes];      
+      memcpy(sei->m_overlayName[i], strTmp.c_str(), nBytes);        
+      sei->m_overlayNameLength[i] = nBytes;
+
+      //overlay element names
+      if ( sei->m_overlayLabelPresentFlag[i] )
+      {        
+        sei->m_overlayElementName[i].resize( sei->m_numOverlayElementsMinus1[i]+1, NULL );
+        sei->m_overlayElementNameLength[i].resize( sei->m_numOverlayElementsMinus1[i]+1 );
+        assert( m_pcCfg->getOverlaySEIElementName()[i].size() == sei->m_numOverlayElementsMinus1[i]+1 );        
+        for ( j=0 ; j<=sei->m_numOverlayElementsMinus1[i] ; j++)
+        {
+          strTmp = m_pcCfg->getOverlaySEIElementName()[i][j];
+          nBytes = m_pcCfg->getOverlaySEIElementName()[i][j].size();        
+          assert( nBytes>0 );
+          sei->m_overlayElementName[i][j] = new UChar[nBytes];
+          memcpy(sei->m_overlayElementName[i][j], strTmp.c_str(), nBytes);        
+          sei->m_overlayElementNameLength[i][j] = nBytes;
+        }
+      }
+    }
+  sei->m_overlayInfoPersistenceFlag = true;
+  }
+  return sei;
+}
+#endif
+
 #if Q0074_COLOUR_REMAPPING_SEI
 SEIColourRemappingInfo*  TEncGOP::xCreateSEIColourRemappingInfo()
@@ -574,4 +654,20 @@
 
     nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, m_pcCfg->getNumLayer()-1); // For highest layer
+    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+#if O0164_MULTI_LAYER_HRD
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
+#else
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
+#endif
+    writeRBSPTrailingBits(nalu.m_Bitstream);
+    accessUnit.push_back(new NALUnitEBSP(nalu));
+    delete sei;
+  }
+#endif
+
+#if Q0096_OVERLAY_SEI
+  if(m_pcCfg->getOverlaySEIEnabled())
+  {    
+    SEIOverlayInfo *sei = xCreateSEIOverlayInfo();       
     m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
 #if O0164_MULTI_LAYER_HRD
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 911)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 912)
@@ -259,4 +259,7 @@
 #endif
 #endif
+#if Q0096_OVERLAY_SEI
+  SEIOverlayInfo* xCreateSEIOverlayInfo();
+#endif
 #if Q0048_CGS_3D_ASYMLUT
   Void xDetermin3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS );
