Index: branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 910)
+++ 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 910)
+++ 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 910)
+++ 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
