Index: branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 774)
+++ branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 776)
@@ -87,4 +87,9 @@
     fprintf( g_hTrace, "=========== Tone Mapping Info SEI message ===========\n");
     break;
+#if P0050_KNEE_FUNCTION_SEI
+  case SEI::KNEE_FUNCTION_INFO:
+    fprintf( g_hTrace, "=========== Knee Function Information SEI message ===========\n");
+    break;
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   case SEI::COLOR_MAPPING_INFO:
@@ -177,4 +182,9 @@
     xWriteSEIToneMappingInfo(*static_cast<const SEIToneMappingInfo*>(&sei));
     break;
+#if P0050_KNEE_FUNCTION_SEI
+  case SEI::KNEE_FUNCTION_INFO:
+    xWriteSEIKneeFunctionInfo(*static_cast<const SEIKneeFunctionInfo*>(&sei));
+    break;
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   case SEI::COLOR_MAPPING_INFO:
@@ -575,5 +585,27 @@
   xWriteByteAlign();
 }
-
+#if P0050_KNEE_FUNCTION_SEI
+Void SEIWriter::xWriteSEIKneeFunctionInfo(const SEIKneeFunctionInfo &sei)
+{
+  WRITE_UVLC( sei.m_kneeId, "knee_function_id" );
+  WRITE_FLAG( sei.m_kneeCancelFlag, "knee_function_cancel_flag" ); 
+  if ( !sei.m_kneeCancelFlag )
+  {
+    WRITE_FLAG( sei.m_kneePersistenceFlag, "knee_function_persistence_flag" );
+    WRITE_FLAG( sei.m_kneeMappingFlag, "mapping_flag" );
+    WRITE_CODE( (UInt)sei.m_kneeInputDrange , 32,  "input_d_range" );
+    WRITE_CODE( (UInt)sei.m_kneeInputDispLuminance, 32,  "input_disp_luminance" );
+    WRITE_CODE( (UInt)sei.m_kneeOutputDrange, 32,  "output_d_range" );
+    WRITE_CODE( (UInt)sei.m_kneeOutputDispLuminance, 32,  "output_disp_luminance" );
+    WRITE_UVLC( sei.m_kneeNumKneePointsMinus1, "num_knee_points_minus1" );
+    for(Int i = 0; i <= sei.m_kneeNumKneePointsMinus1; i++ )
+    {
+      WRITE_CODE( (UInt)sei.m_kneeInputKneePoint[i], 10,"input_knee_point" );
+      WRITE_CODE( (UInt)sei.m_kneeOutputKneePoint[i], 10, "output_knee_point" );
+    }
+  }
+  xWriteByteAlign();
+}
+#endif
 #if Q0074_SEI_COLOR_MAPPING
 Void SEIWriter::xWriteSEIColorMappingInfo(const SEIColorMappingInfo& sei)
Index: branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 774)
+++ branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 776)
@@ -72,4 +72,7 @@
   Void xWriteSEIGradualDecodingRefreshInfo(const SEIGradualDecodingRefreshInfo &sei);
   Void xWriteSEIToneMappingInfo(const SEIToneMappingInfo& sei);
+#if P0050_KNEE_FUNCTION_SEI
+  Void xWriteSEIKneeFunctionInfo(const SEIKneeFunctionInfo &sei);
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   Void xWriteSEIColorMappingInfo(const SEIColorMappingInfo& sei);
Index: branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 774)
+++ branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 776)
@@ -248,4 +248,18 @@
   Int*      m_codedPivotValue;
   Int*      m_targetPivotValue;
+#if P0050_KNEE_FUNCTION_SEI
+  Bool      m_kneeSEIEnabled;
+  Int       m_kneeSEIId;
+  Bool      m_kneeSEICancelFlag;
+  Bool      m_kneeSEIPersistenceFlag;
+  Bool      m_kneeSEIMappingFlag;
+  Int       m_kneeSEIInputDrange;
+  Int       m_kneeSEIInputDispLuminance;
+  Int       m_kneeSEIOutputDrange;
+  Int       m_kneeSEIOutputDispLuminance;
+  Int       m_kneeSEINumKneePointsMinus1;
+  Int*      m_kneeSEIInputKneePoint;
+  Int*      m_kneeSEIOutputKneePoint;
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   Char*     m_seiColorMappingFile;
@@ -668,4 +682,30 @@
   Void  setTMISEIExtendedWhiteLevelLumaCodeValue(Int b)      {  m_extendedWhiteLevelLumaCodeValue =b;  }
   Int   getTMISEIExtendedWhiteLevelLumaCodeValue()           {  return m_extendedWhiteLevelLumaCodeValue;  }
+#if P0050_KNEE_FUNCTION_SEI
+  Void  setKneeSEIEnabled(Int b)                             { m_kneeSEIEnabled = b; }
+  Bool  getKneeSEIEnabled()                                  { return m_kneeSEIEnabled; }
+  Void  setKneeSEIId(Int b)                                  { m_kneeSEIId = b; }
+  Int   getKneeSEIId()                                       { return m_kneeSEIId; }
+  Void  setKneeSEICancelFlag(Bool b)                         { m_kneeSEICancelFlag=b; }
+  Bool  getKneeSEICancelFlag()                               { return m_kneeSEICancelFlag; }
+  Void  setKneeSEIPersistenceFlag(Bool b)                    { m_kneeSEIPersistenceFlag = b; }
+  Bool  getKneeSEIPersistenceFlag()                          { return m_kneeSEIPersistenceFlag; }
+  Void  setKneeSEIMappingFlag(Bool b)                        { m_kneeSEIMappingFlag = b; }
+  Bool  getKneeSEIMappingFlag()                              { return m_kneeSEIMappingFlag; }
+  Void  setKneeSEIInputDrange(Int b)                         { m_kneeSEIInputDrange = b; }
+  Int   getKneeSEIInputDrange()                              { return m_kneeSEIInputDrange; }
+  Void  setKneeSEIInputDispLuminance(Int b)                  { m_kneeSEIInputDispLuminance = b; }
+  Int   getKneeSEIInputDispLuminance()                       { return m_kneeSEIInputDispLuminance; }
+  Void  setKneeSEIOutputDrange(Int b)                        { m_kneeSEIOutputDrange = b; }
+  Int   getKneeSEIOutputDrange()                             { return m_kneeSEIOutputDrange; }
+  Void  setKneeSEIOutputDispLuminance(Int b)                 { m_kneeSEIOutputDispLuminance = b; }
+  Int   getKneeSEIOutputDispLuminance()                      { return m_kneeSEIOutputDispLuminance; }
+  Void  setKneeSEINumKneePointsMinus1(Int b)                 { m_kneeSEINumKneePointsMinus1 = b; }
+  Int   getKneeSEINumKneePointsMinus1()                      { return m_kneeSEINumKneePointsMinus1; }
+  Void  setKneeSEIInputKneePoint(Int *p)                     { m_kneeSEIInputKneePoint = p; }
+  Int*  getKneeSEIInputKneePoint()                           { return m_kneeSEIInputKneePoint; }
+  Void  setKneeSEIOutputKneePoint(Int *p)                    { m_kneeSEIOutputKneePoint = p; }
+  Int*  getKneeSEIOutputKneePoint()                          { return m_kneeSEIOutputKneePoint; }
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   Void  setColorMappingInfoSEIFile( Char* nameFile )         {  m_seiColorMappingFile = nameFile; }
Index: branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 774)
+++ branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 776)
@@ -325,4 +325,37 @@
 }
 
+#if P0050_KNEE_FUNCTION_SEI
+SEIKneeFunctionInfo* TEncGOP::xCreateSEIKneeFunctionInfo()
+{
+  SEIKneeFunctionInfo *seiKneeFunctionInfo = new SEIKneeFunctionInfo();
+  seiKneeFunctionInfo->m_kneeId = m_pcCfg->getKneeSEIId();
+  seiKneeFunctionInfo->m_kneeCancelFlag = m_pcCfg->getKneeSEICancelFlag();
+  if ( !seiKneeFunctionInfo->m_kneeCancelFlag )
+  {
+    seiKneeFunctionInfo->m_kneePersistenceFlag = m_pcCfg->getKneeSEIPersistenceFlag();
+    seiKneeFunctionInfo->m_kneeMappingFlag = m_pcCfg->getKneeSEIMappingFlag();
+    seiKneeFunctionInfo->m_kneeInputDrange = m_pcCfg->getKneeSEIInputDrange();
+    seiKneeFunctionInfo->m_kneeInputDispLuminance = m_pcCfg->getKneeSEIInputDispLuminance();
+    seiKneeFunctionInfo->m_kneeOutputDrange = m_pcCfg->getKneeSEIOutputDrange();
+    seiKneeFunctionInfo->m_kneeOutputDispLuminance = m_pcCfg->getKneeSEIOutputDispLuminance();
+
+    seiKneeFunctionInfo->m_kneeNumKneePointsMinus1 = m_pcCfg->getKneeSEINumKneePointsMinus1();
+    Int* piInputKneePoint  = m_pcCfg->getKneeSEIInputKneePoint();
+    Int* piOutputKneePoint = m_pcCfg->getKneeSEIOutputKneePoint();
+    if(piInputKneePoint&&piOutputKneePoint)
+    {
+      seiKneeFunctionInfo->m_kneeInputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
+      seiKneeFunctionInfo->m_kneeOutputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
+      for(Int i=0; i<=seiKneeFunctionInfo->m_kneeNumKneePointsMinus1; i++)
+      {
+        seiKneeFunctionInfo->m_kneeInputKneePoint[i] = piInputKneePoint[i];
+        seiKneeFunctionInfo->m_kneeOutputKneePoint[i] = piOutputKneePoint[i];
+       }
+    }
+  }
+  return seiKneeFunctionInfo;
+}
+#endif
+
 #if Q0074_SEI_COLOR_MAPPING
 SEIColorMappingInfo*  TEncGOP::xCreateSEIColorMappingInfo( Char* file )
@@ -475,4 +508,21 @@
     delete sei;
   }
+#if P0050_KNEE_FUNCTION_SEI
+  if(m_pcCfg->getKneeSEIEnabled())
+  {
+    SEIKneeFunctionInfo *sei = xCreateSEIKneeFunctionInfo();
+
+    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
+    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 Q0074_SEI_COLOR_MAPPING
   if(m_pcCfg->getColorMappingInfoSEIFile())
Index: branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 774)
+++ branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 776)
@@ -207,4 +207,7 @@
 
   SEIToneMappingInfo*     xCreateSEIToneMappingInfo();
+#if P0050_KNEE_FUNCTION_SEI
+  SEIKneeFunctionInfo*    xCreateSEIKneeFunctionInfo();
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   SEIColorMappingInfo*    xCreateSEIColorMappingInfo( Char* file );
