Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1036)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1037)
@@ -1688,4 +1688,15 @@
   ("SEIMasteringDisplayWhitePoint",                   cfg_DisplayWhitePointCode,     cfg_DisplayWhitePointCode, "Mastering display white point CIE xy coordinates in normalised increments of 1/50000 (e.g. 0.333 = 16667)")
     
+#if P0123_ALPHA_CHANNEL_SEI
+  ("SEIAlphaChannelInfo",                     m_alphaSEIEnabled,                        false, "Enables transmission of information associated with alpha channel (default : 0)")
+  ("SEIAlphaCancelFlag",                      m_alphaCancelFlag,                         true, "Denotes that this SEI message cancels the persistence of any previously received alpha channel SEI message (default : 1)")
+  ("SEIAlphaUseIdc",                          m_alphaUseIdc,                                2, "Denotes the use of the received alpha channel in final picture composition (e.g. pre-multiplied alpha, default : 2)")
+  ("SEIAlphaBitDepthMinus8",                  m_alphaBitDepthMinus8,                        0, "Denotes the bit depth associated with the received alpha channel (default : 0)")
+  ("SEIAlphaTransparentValue",                m_alphaTransparentValue,                      0, "Denotes the sample value which is considered transparent for alpha blending purposes (default : 0)")
+  ("SEIAlphaOpaqueValue",                     m_alphaOpaqueValue,                         255, "Denotes the sample value which is considered opaque for alpha blending purposes (default : 255)")
+  ("SEIAlphaIncrementFlag",                   m_alphaIncrementFlag,                     false, "Denotes whether the sample values should be incremented by one for the purposes of alpha blending (default : 0)")
+  ("SEIAlphaClipFlag",                        m_alphaClipFlag,                          false, "Denotes whether clipping is applied to the sample values (default : 0)")
+  ("SEIAlphaClipType",                        m_alphaClipTypeFlag,                      false, "Denotes the type of clipping applied to the sample values (0 = binary, 1 = linear, default : 0)")
+#endif
 #if Q0096_OVERLAY_SEI
   ("SEIOverlayInfo",                          m_overlaySEIEnabled,                      false, "Control generation of Selectable Overlays SEI messages")
@@ -4473,4 +4484,11 @@
   }
 
+#if P0123_ALPHA_CHANNEL_SEI
+  if( m_alphaSEIEnabled && !m_alphaCancelFlag )
+  {
+    xConfirmPara(0 < m_alphaUseIdc || m_alphaUseIdc > 2, "SEIAlphaUseIdc greater than 2 is reserved for future use by ITU-T | ISO/IEC");
+    xConfirmPara(m_alphaBitDepthMinus8 < 0 || m_alphaBitDepthMinus8 > 7, "SEIAlphaBitDepthMinus8 shall be in the range 0 to 7 inclusive");
+  }
+#endif
 #if Q0096_OVERLAY_SEI
   if( m_overlaySEIEnabled && !m_overlayInfoCancelFlag )
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1036)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1037)
@@ -436,5 +436,15 @@
   Int       m_layersNotPresentSEIEnabled;
 #endif
-
+#if P0123_ALPHA_CHANNEL_SEI
+  Bool      m_alphaSEIEnabled;
+  Bool      m_alphaCancelFlag;
+  Int       m_alphaUseIdc;
+  Int       m_alphaBitDepthMinus8;
+  Int       m_alphaTransparentValue;
+  Int       m_alphaOpaqueValue;
+  Bool      m_alphaIncrementFlag;
+  Bool      m_alphaClipFlag;
+  Bool      m_alphaClipTypeFlag;
+#endif
 #if SVC_EXTENSION
 #if FAST_INTRA_SHVC
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1036)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1037)
@@ -612,4 +612,15 @@
     m_acTEncTop[layer].setKneeSEIOutputKneePoint                            ( m_kneeSEIOutputKneePoint );
     m_acTEncTop[layer].setMasteringDisplaySEI                               ( m_masteringDisplay );
+#if P0123_ALPHA_CHANNEL_SEI
+    m_acTEncTop[layer].setAlphaSEIEnabled                                   ( m_alphaSEIEnabled );
+    m_acTEncTop[layer].setAlphaCancelFlag                                   ( m_alphaCancelFlag );
+    m_acTEncTop[layer].setAlphaUseIdc                                       ( m_alphaUseIdc );
+    m_acTEncTop[layer].setAlphaBitDepthMinus8                               ( m_alphaBitDepthMinus8 );
+    m_acTEncTop[layer].setAlphaTransparentValue                             ( m_alphaTransparentValue );
+    m_acTEncTop[layer].setAlphaOpaqueValue                                  ( m_alphaOpaqueValue );
+    m_acTEncTop[layer].setAlphaIncrementFlag                                ( m_alphaIncrementFlag );
+    m_acTEncTop[layer].setAlphaClipFlag                                     ( m_alphaClipFlag );
+    m_acTEncTop[layer].setAlphaClipTypeFlag                                 ( m_alphaClipTypeFlag );
+#endif
 #if Q0096_OVERLAY_SEI
     m_acTEncTop[layer].setOverlaySEIEnabled                                 ( m_overlaySEIEnabled );
Index: /branches/SHM-dev/source/Lib/TLibCommon/SEI.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/SEI.cpp	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibCommon/SEI.cpp	(revision 1037)
@@ -162,4 +162,7 @@
     case SEI::OVERLAY_INFO:                         return "Overlay Information";
 #endif
+#if P0123_ALPHA_CHANNEL_SEI
+    case SEI::ALPHA_CHANNEL_INFO:                   return "Alpha Channel Information";
+#endif
 #endif
     default:                                        return "Unknown";
Index: /branches/SHM-dev/source/Lib/TLibCommon/SEI.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/SEI.h	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibCommon/SEI.h	(revision 1037)
@@ -121,5 +121,8 @@
 #endif
 #if Q0096_OVERLAY_SEI
-    OVERLAY_INFO                         = 153,    
+    OVERLAY_INFO                         = 153,
+#endif
+#if P0123_ALPHA_CHANNEL_SEI
+    ALPHA_CHANNEL_INFO                   = 165,
 #endif
   };
@@ -670,4 +673,22 @@
 #endif
 
+#if P0123_ALPHA_CHANNEL_SEI
+class SEIAlphaChannelInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return ALPHA_CHANNEL_INFO; }
+  SEIAlphaChannelInfo() {}
+  virtual ~SEIAlphaChannelInfo() {}
+  Bool m_alphaChannelCancelFlag;
+  UInt m_alphaChannelUseIdc;
+  UInt m_alphaChannelBitDepthMinus8;
+  UInt m_alphaTransparentValue;
+  UInt m_alphaOpaqueValue;
+  Bool m_alphaChannelIncrFlag;
+  Bool m_alphaChannelClipFlag;
+  Bool m_alphaChannelClipTypeFlag;
+};
+#endif
+
 #if Q0096_OVERLAY_SEI
 class SEIOverlayInfo : public SEI
Index: /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1037)
@@ -341,4 +341,5 @@
 # define MAX_OVERLAY_STRING_BYTES        256
 #endif
+#define P0123_ALPHA_CHANNEL_SEI          1      ///< JCTVC-P0123: SEI message for alpha channel information
 
 #endif // SVC_EXTENSION
Index: /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 1037)
@@ -383,4 +383,10 @@
      break;
 #endif
+#if P0123_ALPHA_CHANNEL_SEI
+   case SEI::ALPHA_CHANNEL_INFO:
+     sei = new SEIAlphaChannelInfo;
+     xParseSEIAlphaChannelInfo((SEIAlphaChannelInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
+     break;
+#endif
 #if Q0096_OVERLAY_SEI
    case SEI::OVERLAY_INFO:
@@ -390,17 +396,16 @@
 #endif
 #endif //SVC_EXTENSION
-      break;
-    default:
-      for (UInt i = 0; i < payloadSize; i++)
-      {
-        UInt seiByte;
-        sei_read_code (NULL, 8, seiByte, "unknown prefix SEI payload byte");
-      }
-      printf ("Unknown prefix SEI message (payloadType = %d) was found!\n", payloadType);
-      if (pDecodedMessageOutputStream)
-      {
-        (*pDecodedMessageOutputStream) << "Unknown prefix SEI message (payloadType = " << payloadType << ") was found!\n";
-      }
-      break;
+   default:
+     for (UInt i = 0; i < payloadSize; i++)
+     {
+       UInt seiByte;
+       sei_read_code (NULL, 8, seiByte, "unknown prefix SEI payload byte");
+     }
+     printf ("Unknown prefix SEI message (payloadType = %d) was found!\n", payloadType);
+     if (pDecodedMessageOutputStream)
+     {
+       (*pDecodedMessageOutputStream) << "Unknown prefix SEI message (payloadType = " << payloadType << ") was found!\n";
+     }
+     break;
     }
   }
@@ -1874,4 +1879,25 @@
 }
 
+#endif
+
+#if P0123_ALPHA_CHANNEL_SEI
+void SEIReader::xParseSEIAlphaChannelInfo(SEIAlphaChannelInfo &sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  UInt value;
+  sei_read_flag(pDecodedMessageOutputStream, value, "alpha_channel_cancel_flag"); sei.m_alphaChannelCancelFlag = value;
+  if(!sei.m_alphaChannelCancelFlag)
+  {
+    sei_read_code(pDecodedMessageOutputStream, 3, value, "alpha_channel_use_idc");          sei.m_alphaChannelUseIdc = value;
+    sei_read_code(pDecodedMessageOutputStream, 3, value, "alpha_channel_bit_depth_minus8"); sei.m_alphaChannelBitDepthMinus8 = value;
+    sei_read_code(pDecodedMessageOutputStream, sei.m_alphaChannelBitDepthMinus8 + 9, value, "alpha_transparent_value"); sei.m_alphaTransparentValue = value;
+    sei_read_code(pDecodedMessageOutputStream, sei.m_alphaChannelBitDepthMinus8 + 9, value, "alpha_opaque_value"); sei.m_alphaOpaqueValue = value;
+    sei_read_flag(pDecodedMessageOutputStream, value, "alpha_channel_incr_flag");        sei.m_alphaChannelIncrFlag = value;
+    sei_read_flag(pDecodedMessageOutputStream, value, "alpha_channel_clip_flag");        sei.m_alphaChannelClipFlag = value;
+    if(sei.m_alphaChannelClipFlag)
+    {
+      sei_read_flag(pDecodedMessageOutputStream, value, "alpha_channel_clip_type_flag"); sei.m_alphaChannelClipTypeFlag = value;
+    }
+  }  
+}
 #endif
 
Index: /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h	(revision 1037)
@@ -154,4 +154,7 @@
   Void xParseSEIFrameFieldInfo                (SEIFrameFieldInfo& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream);
 #endif
+#if P0123_ALPHA_CHANNEL_SEI
+  Void xParseSEIAlphaChannelInfo              (SEIAlphaChannelInfo& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream);
+#endif
 #if Q0096_OVERLAY_SEI
   Void xParseSEIOverlayInfo                   (SEIOverlayInfo& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream);
Index: /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 1037)
@@ -209,4 +209,9 @@
      break;
 #endif
+#if P0123_ALPHA_CHANNEL_SEI
+   case SEI::ALPHA_CHANNEL_INFO:
+     xWriteSEIAlphaChannelInfo(*static_cast<const SEIAlphaChannelInfo*>(&sei));
+     break;
+#endif
 #if Q0096_OVERLAY_SEI
    case SEI::OVERLAY_INFO:
@@ -1417,4 +1422,25 @@
 #endif
 
+#if P0123_ALPHA_CHANNEL_SEI
+Void SEIWriter::xWriteSEIAlphaChannelInfo(const SEIAlphaChannelInfo &sei)
+{
+  WRITE_FLAG(sei.m_alphaChannelCancelFlag, "alpha_channel_cancel_flag");
+  if(!sei.m_alphaChannelCancelFlag)
+  {
+    WRITE_CODE(sei.m_alphaChannelUseIdc, 3, "alpha_channel_use_idc");
+    WRITE_CODE(sei.m_alphaChannelBitDepthMinus8, 3, "alpha_channel_bit_depth_minus8");
+    WRITE_CODE(sei.m_alphaTransparentValue, sei.m_alphaChannelBitDepthMinus8 + 9, "alpha_transparent_value");
+    WRITE_CODE(sei.m_alphaOpaqueValue, sei.m_alphaChannelBitDepthMinus8 + 9, "alpha_opaque_value");
+    WRITE_FLAG(sei.m_alphaChannelIncrFlag, "alpha_channel_incr_flag");
+    WRITE_FLAG(sei.m_alphaChannelClipFlag, "alpha_channel_clip_flag");
+    if(sei.m_alphaChannelClipFlag)
+    {
+      WRITE_FLAG(sei.m_alphaChannelClipTypeFlag, "alpha_channel_clip_type_flag");
+    }
+  }
+  xWriteByteAlign();
+}
+#endif
+
 #if Q0096_OVERLAY_SEI
 Void SEIWriter::xWriteSEIOverlayInfo(const SEIOverlayInfo &sei)
Index: /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 1037)
@@ -131,4 +131,7 @@
   Void xWriteSEIVPSRewriting(const SEIVPSRewriting &sei);
 #endif
+#if P0123_ALPHA_CHANNEL_SEI
+  Void xWriteSEIAlphaChannelInfo(const SEIAlphaChannelInfo &sei);
+#endif
 #if Q0096_OVERLAY_SEI
   Void xWriteSEIOverlayInfo(const SEIOverlayInfo &sei);
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1037)
@@ -415,14 +415,25 @@
 #endif
 #if Q0048_CGS_3D_ASYMLUT
-  Int  m_nCGSFlag;
-  Int  m_nCGSMaxOctantDepth;
-  Int  m_nCGSMaxYPartNumLog2;
-  Int  m_nCGSLUTBit;
+  Int       m_nCGSFlag;
+  Int       m_nCGSMaxOctantDepth;
+  Int       m_nCGSMaxYPartNumLog2;
+  Int       m_nCGSLUTBit;
 #if R0151_CGS_3D_ASYMLUT_IMPROVE
-  Int  m_nCGSAdaptiveChroma;
+  Int       m_nCGSAdaptiveChroma;
 #endif
 #if R0179_ENC_OPT_3DLUT_SIZE
-  Int  m_nCGSLutSizeRDO;
-#endif
+  Int       m_nCGSLutSizeRDO;
+#endif
+#endif
+#if P0123_ALPHA_CHANNEL_SEI
+  Bool      m_alphaSEIEnabled;
+  Bool      m_alphaCancelFlag;
+  Int       m_alphaUseIdc;
+  Int       m_alphaBitDepthMinus8;
+  Int       m_alphaTransparentValue;
+  Int       m_alphaOpaqueValue;
+  Bool      m_alphaIncrementFlag;
+  Int       m_alphaClipFlag;
+  Int       m_alphaClipTypeFlag;
 #endif
 #if Q0096_OVERLAY_SEI
@@ -994,7 +1005,27 @@
 
 #if Q0189_TMVP_CONSTRAINTS
-  Void  setTMVPConstraintsSEIEnabled(Int b)                { m_TMVPConstraintsSEIEnabled = b; }
-  Int   getTMVPConstraintsSEIEnabled()                {  return m_TMVPConstraintsSEIEnabled; }
-
+  Void  setTMVPConstraintsSEIEnabled(Int b)                  { m_TMVPConstraintsSEIEnabled = b; }
+  Int   getTMVPConstraintsSEIEnabled()                       {  return m_TMVPConstraintsSEIEnabled; }
+
+#endif
+#if P0123_ALPHA_CHANNEL_SEI
+  Void  setAlphaSEIEnabled(Bool b)                           { m_alphaSEIEnabled       = b; }
+  Bool  getAlphaSEIEnabled()                                 { return m_alphaSEIEnabled; }
+  Void  setAlphaCancelFlag(Bool b)                           { m_alphaCancelFlag       = b; }
+  Bool  getAlphaCancelFlag()                                 { return m_alphaCancelFlag; }
+  Void  setAlphaUseIdc(Int idc)                              { m_alphaUseIdc           = idc; }
+  Int   getAlphaUseIdc()                                     { return m_alphaUseIdc; }
+  Void  setAlphaBitDepthMinus8(Int d)                        { m_alphaBitDepthMinus8   = d; }
+  Int   getAlphaBitDepthMinus8()                             { return m_alphaBitDepthMinus8; }
+  Void  setAlphaTransparentValue(Int v)                      { m_alphaTransparentValue = v; }
+  Int   getAlphaTransparentValue()                           { return m_alphaTransparentValue; }
+  Void  setAlphaOpaqueValue(Int v)                           { m_alphaOpaqueValue      = v; }
+  Int   getAlphaOpaqueValue()                                { return m_alphaOpaqueValue; }
+  Void  setAlphaIncrementFlag(Bool b)                        { m_alphaIncrementFlag    = b; }
+  Int   getAlphaIncrementFlag()                              { return m_alphaIncrementFlag; }
+  Void  setAlphaClipFlag(Bool b)                             { m_alphaClipFlag         = b; }
+  Bool  getAlphaClipFlag()                                   { return m_alphaClipFlag; }
+  Void  setAlphaClipTypeFlag(Bool b)                         { m_alphaClipTypeFlag     = b; }
+  Bool  getAlphaClipTypeFlag()                               { return m_alphaClipTypeFlag; }
 #endif
 #if Q0074_COLOUR_REMAPPING_SEI
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1037)
@@ -684,4 +684,20 @@
 #else
     m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
+#endif
+    writeRBSPTrailingBits(nalu.m_Bitstream);
+    accessUnit.push_back(new NALUnitEBSP(nalu));
+    delete sei;
+  }
+#endif
+
+#if P0123_ALPHA_CHANNEL_SEI
+  if( m_pcCfg->getAlphaSEIEnabled() && m_pcEncTop->getVPS()->getScalabilityId(m_layerId, AUX_ID) && m_pcEncTop->getVPS()->getDimensionId(m_layerId, m_pcEncTop->getVPS()->getNumScalabilityTypes() - 1) == AUX_ALPHA )
+  {
+    SEIAlphaChannelInfo *sei = xCreateSEIAlphaChannelInfo();
+    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);
@@ -4364,4 +4380,22 @@
 }
 
+#if P0123_ALPHA_CHANNEL_SEI
+SEIAlphaChannelInfo* TEncGOP::xCreateSEIAlphaChannelInfo()
+{
+  SEIAlphaChannelInfo *sei = new SEIAlphaChannelInfo();
+  sei->m_alphaChannelCancelFlag = m_pcCfg->getAlphaCancelFlag();
+  if(!sei->m_alphaChannelCancelFlag)
+  {
+    sei->m_alphaChannelUseIdc = m_pcCfg->getAlphaUseIdc();
+    sei->m_alphaChannelBitDepthMinus8 = m_pcCfg->getAlphaBitDepthMinus8();
+    sei->m_alphaTransparentValue = m_pcCfg->getAlphaTransparentValue();
+    sei->m_alphaOpaqueValue = m_pcCfg->getAlphaOpaqueValue();
+    sei->m_alphaChannelIncrFlag = m_pcCfg->getAlphaIncrementFlag();
+    sei->m_alphaChannelClipFlag = m_pcCfg->getAlphaClipFlag();
+    sei->m_alphaChannelClipTypeFlag = m_pcCfg->getAlphaClipTypeFlag();
+  }
+  return sei;
+}
+#endif
 #if Q0096_OVERLAY_SEI
 SEIOverlayInfo* TEncGOP::xCreateSEIOverlayInfo()
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1036)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1037)
@@ -262,4 +262,7 @@
 #endif
 #endif
+#if P0123_ALPHA_CHANNEL_SEI
+  SEIAlphaChannelInfo* xCreateSEIAlphaChannelInfo();
+#endif
 #if Q0096_OVERLAY_SEI
   SEIOverlayInfo* xCreateSEIOverlayInfo();
