Index: /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 775)
+++ /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 776)
@@ -513,4 +513,8 @@
   string cfg_codedPivotValue;
   string cfg_targetPivotValue;
+#if P0050_KNEE_FUNCTION_SEI
+  string cfg_kneeSEIInputKneePointValue;
+  string cfg_kneeSEIOutputKneePointValue;
+#endif
   po::Options opts;
   opts.addOptions()
@@ -943,4 +947,19 @@
   ("SEISOPDescription",              m_SOPDescriptionSEIEnabled,              0, "Control generation of SOP description SEI messages")
   ("SEIScalableNesting",             m_scalableNestingSEIEnabled,              0, "Control generation of scalable nesting SEI messages")
+#if P0050_KNEE_FUNCTION_SEI
+  ("SEIKneeFunctionInfo",                 m_kneeSEIEnabled,               false, "Control generation of Knee function SEI messages")
+  ("SEIKneeFunctionId",                   m_kneeSEIId,                        0, "Specifies Id of Knee function SEI message for a given session")
+  ("SEIKneeFunctionCancelFlag",           m_kneeSEICancelFlag,            false, "Indicates that Knee function SEI message cancels the persistance or follows")
+  ("SEIKneeFunctionPersistenceFlag",      m_kneeSEIPersistenceFlag,        true, "Specifies the persistence of the Knee function SEI message")
+  ("SEIKneeFunctionMappingFlag",          m_kneeSEIMappingFlag,           false, "Specifies the mapping mode of the Knee function SEI message")
+  ("SEIKneeFunctionInputDrange",          m_kneeSEIInputDrange,            1000, "Specifies the peak luminance level for the input picture of Knee function SEI messages")
+  ("SEIKneeFunctionInputDispLuminance",   m_kneeSEIInputDispLuminance,      100, "Specifies the expected display brightness for the input picture of Knee function SEI messages")
+  ("SEIKneeFunctionOutputDrange",         m_kneeSEIOutputDrange,           4000, "Specifies the peak luminance level for the output picture of Knee function SEI messages")
+  ("SEIKneeFunctionOutputDispLuminance",  m_kneeSEIOutputDispLuminance,     800, "Specifies the expected display brightness for the output picture of Knee function SEI messages")
+  ("SEIKneeFunctionNumKneePointsMinus1",  m_kneeSEINumKneePointsMinus1,       2, "Specifies the number of knee points - 1")
+  ("SEIKneeFunctionInputKneePointValue",  cfg_kneeSEIInputKneePointValue,     string("600 800 900"), "Array of input knee point")
+  ("SEIKneeFunctionOutputKneePointValue", cfg_kneeSEIOutputKneePointValue,    string("100 250 450"), "Array of output knee point")
+#endif
+
 #if M0040_ADAPTIVE_RESOLUTION_CHANGE
   ("AdaptiveResolutionChange",     m_adaptiveResolutionChange, 0, "Adaptive resolution change frame number. Should coincide with EL RAP picture. (0: disable)")
@@ -1485,4 +1504,30 @@
     }
   }
+#if P0050_KNEE_FUNCTION_SEI
+  if( m_kneeSEIEnabled && !m_kneeSEICancelFlag )
+  {
+    Char* pcInputKneePointValue  = cfg_kneeSEIInputKneePointValue.empty()  ? NULL : strdup(cfg_kneeSEIInputKneePointValue.c_str());
+    Char* pcOutputKneePointValue = cfg_kneeSEIOutputKneePointValue.empty() ? NULL : strdup(cfg_kneeSEIOutputKneePointValue.c_str());
+    assert ( m_kneeSEINumKneePointsMinus1 >= 0 && m_kneeSEINumKneePointsMinus1 < 999 );
+    m_kneeSEIInputKneePoint = new Int[m_kneeSEINumKneePointsMinus1+1];
+    m_kneeSEIOutputKneePoint = new Int[m_kneeSEINumKneePointsMinus1+1];
+    char *InputVal = strtok(pcInputKneePointValue, " .,");
+    Int i=0;
+    while( InputVal && i<(m_kneeSEINumKneePointsMinus1+1) )
+    {
+      m_kneeSEIInputKneePoint[i] = (UInt) atoi( InputVal );
+      InputVal = strtok(NULL, " .,");
+      i++;
+    }
+    char *OutputVal = strtok(pcOutputKneePointValue, " .,");
+    i=0;
+    while( OutputVal && i<(m_kneeSEINumKneePointsMinus1+1) )
+    {
+      m_kneeSEIOutputKneePoint[i] = (UInt) atoi( OutputVal );
+      OutputVal = strtok(NULL, " .,");
+      i++;
+    }
+  }
+#endif
 
 #if N0383_IL_CONSTRAINED_TILE_SETS_SEI
@@ -2185,4 +2230,18 @@
     xConfirmPara( m_extendedWhiteLevelLumaCodeValue < m_nominalWhiteLevelLumaCodeValue, "SEIToneMapExtendedWhiteLevelLumaCodeValue shall be greater than or equal to SEIToneMapNominalWhiteLevelLumaCodeValue");
   }
+#if P0050_KNEE_FUNCTION_SEI
+  if (m_kneeSEIEnabled && !m_kneeSEICancelFlag)
+  {
+    xConfirmPara( m_kneeSEINumKneePointsMinus1 < 0 || m_kneeSEINumKneePointsMinus1 > 998, "SEIKneeFunctionNumKneePointsMinus1 must be in the range of 0 to 998");
+    for ( UInt i=0; i<=m_kneeSEINumKneePointsMinus1; i++ ){
+      xConfirmPara( m_kneeSEIInputKneePoint[i] < 1 || m_kneeSEIInputKneePoint[i] > 999, "SEIKneeFunctionInputKneePointValue must be in the range of 1 to 999");
+      xConfirmPara( m_kneeSEIOutputKneePoint[i] < 0 || m_kneeSEIOutputKneePoint[i] > 1000, "SEIKneeFunctionInputKneePointValue must be in the range of 0 to 1000");
+      if ( i > 0 )
+      {
+        xConfirmPara( m_kneeSEIInputKneePoint[i-1] >= m_kneeSEIInputKneePoint[i],  "The i-th SEIKneeFunctionInputKneePointValue must be greather than the (i-1)-th value");
+      }
+    }
+  }
+#endif
 
 #if RC_SHVC_HARMONIZATION
Index: /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 775)
+++ /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 776)
@@ -386,4 +386,18 @@
 #endif
   Bool      m_crossLayerIrapAlignFlag;
+#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 P0068_CROSS_LAYER_ALIGNED_IDR_ONLY_FOR_IRAP_FLAG
   Bool      m_crossLayerAlignedIdrOnlyFlag;
Index: /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 775)
+++ /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 776)
@@ -485,4 +485,18 @@
     m_acTEncTop[layer].setTMISEINominalWhiteLevelLumaCodeValue      ( m_nominalWhiteLevelLumaCodeValue );
     m_acTEncTop[layer].setTMISEIExtendedWhiteLevelLumaCodeValue     ( m_extendedWhiteLevelLumaCodeValue );
+#if P0050_KNEE_FUNCTION_SEI
+    m_acTEncTop[layer].setKneeSEIEnabled                            ( m_kneeSEIEnabled );
+    m_acTEncTop[layer].setKneeSEIId                                 ( m_kneeSEIId );
+    m_acTEncTop[layer].setKneeSEICancelFlag                         ( m_kneeSEICancelFlag );
+    m_acTEncTop[layer].setKneeSEIPersistenceFlag                    ( m_kneeSEIPersistenceFlag );
+    m_acTEncTop[layer].setKneeSEIMappingFlag                        ( m_kneeSEIMappingFlag );
+    m_acTEncTop[layer].setKneeSEIInputDrange                        ( m_kneeSEIInputDrange );
+    m_acTEncTop[layer].setKneeSEIInputDispLuminance                 ( m_kneeSEIInputDispLuminance );
+    m_acTEncTop[layer].setKneeSEIOutputDrange                       ( m_kneeSEIOutputDrange );
+    m_acTEncTop[layer].setKneeSEIOutputDispLuminance                ( m_kneeSEIOutputDispLuminance );
+    m_acTEncTop[layer].setKneeSEINumKneePointsMinus1                ( m_kneeSEINumKneePointsMinus1 );
+    m_acTEncTop[layer].setKneeSEIInputKneePoint                     ( m_kneeSEIInputKneePoint );
+    m_acTEncTop[layer].setKneeSEIOutputKneePoint                    ( m_kneeSEIOutputKneePoint );
+#endif
 #if Q0074_SEI_COLOR_MAPPING
     m_acTEncTop[layer].setColorMappingInfoSEIFile                   ( m_acLayerCfg[layer].m_cSeiColorMappingFile.empty() ? NULL : const_cast<Char *>(m_acLayerCfg[layer].m_cSeiColorMappingFile.c_str()) );
@@ -804,4 +818,18 @@
   m_cTEncTop.setTMISEINominalWhiteLevelLumaCodeValue      ( m_nominalWhiteLevelLumaCodeValue );
   m_cTEncTop.setTMISEIExtendedWhiteLevelLumaCodeValue     ( m_extendedWhiteLevelLumaCodeValue );
+#if P0050_KNEE_FUNCTION_SEI
+  m_cTEncTop.setKneeSEIEnabled              ( m_kneeSEIEnabled );
+  m_cTEncTop.setKneeSEIId                   ( m_kneeSEIId );
+  m_cTEncTop.setKneeSEICancelFlag           ( m_kneeSEICancelFlag );
+  m_cTEncTop.setKneeSEIPersistenceFlag      ( m_kneeSEIPersistenceFlag );
+  m_cTEncTop.setKneeSEIMappingFlag          ( m_kneeSEIMappingFlag );
+  m_cTEncTop.setKneeSEIInputDrange          ( m_kneeSEIInputDrange );
+  m_cTEncTop.setKneeSEIInputDispLuminance   ( m_kneeSEIInputDispLuminance );
+  m_cTEncTop.setKneeSEIOutputDrange         ( m_kneeSEIOutputDrange );
+  m_cTEncTop.setKneeSEIOutputDispLuminance  ( m_kneeSEIOutputDispLuminance );
+  m_cTEncTop.setKneeSEINumKneePointsMinus1  ( m_kneeSEINumKneePointsMinus1 );
+  m_cTEncTop.setKneeSEIInputKneePoint       ( m_kneeSEIInputKneePoint );
+  m_cTEncTop.setKneeSEIOutputKneePoint      ( m_kneeSEIOutputKneePoint );
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   m_cTEncTop.setColorMappingInfoSEIFile                   ( m_pchSEIColorMappingFile );
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/SEI.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/SEI.h	(revision 775)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/SEI.h	(revision 776)
@@ -66,4 +66,7 @@
     POST_FILTER_HINT                     = 22,
     TONE_MAPPING_INFO                    = 23,
+#if P0050_KNEE_FUNCTION_SEI
+    KNEE_FUNCTION_INFO                   = 24,
+#endif
     FRAME_PACKING                        = 45,
     DISPLAY_ORIENTATION                  = 47,
@@ -407,5 +410,25 @@
   Int    m_extendedWhiteLevelLumaCodeValue;
 };
-
+#if P0050_KNEE_FUNCTION_SEI
+class SEIKneeFunctionInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return KNEE_FUNCTION_INFO; }
+  SEIKneeFunctionInfo() {}
+  virtual ~SEIKneeFunctionInfo() {}
+
+  Int   m_kneeId;
+  Bool  m_kneeCancelFlag;
+  Bool  m_kneePersistenceFlag;
+  Bool  m_kneeMappingFlag;
+  Int   m_kneeInputDrange;
+  Int   m_kneeInputDispLuminance;
+  Int   m_kneeOutputDrange;
+  Int   m_kneeOutputDispLuminance;
+  Int   m_kneeNumKneePointsMinus1;
+  std::vector<Int> m_kneeInputKneePoint;
+  std::vector<Int> m_kneeOutputKneePoint;
+};
+#endif
 #if Q0074_SEI_COLOR_MAPPING
 class SEIColorMappingInfo : public SEI
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/TypeDef.h	(revision 775)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/TypeDef.h	(revision 776)
@@ -100,4 +100,5 @@
 #define Q0048_CGS_3D_ASYMLUT             1      ///< JCTVC-Q0048: Colour gamut scalability with look-up table
 #if Q0048_CGS_3D_ASYMLUT
+
 #define CGS_GCC_NO_VECTORIZATION         1
 #define O0194_WEIGHTED_PREDICTION_CGS    0
@@ -264,4 +265,7 @@
 #define LAYER_DECPICBUFF_PARAM           1      ///< JCTVC-Q0102 Proposal 2 infer value from layer DPB param
 #define HRD_BPB                         1      ///< JCTVC-Q0101 Bitstream Partition Buffering Proposals
+
+#define P0050_KNEE_FUNCTION_SEI          1      ///< JCTVC-P0050: Knee function SEI
+
 #if VIEW_ID_RELATED_SIGNALING
 /// scalability types
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/SEIread.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 775)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 776)
@@ -93,4 +93,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:
@@ -285,4 +290,10 @@
       xParseSEIToneMappingInfo((SEIToneMappingInfo&) *sei, payloadSize);
       break;
+#if P0050_KNEE_FUNCTION_SEI
+    case SEI::KNEE_FUNCTION_INFO:
+      sei = new SEIKneeFunctionInfo;
+      xParseSEIKneeFunctionInfo((SEIKneeFunctionInfo&) *sei, payloadSize);
+      break;
+#endif
 #if Q0074_SEI_COLOR_MAPPING
     case SEI::COLOR_MAPPING_INFO:
@@ -849,4 +860,31 @@
 }
 
+#if P0050_KNEE_FUNCTION_SEI
+Void SEIReader::xParseSEIKneeFunctionInfo(SEIKneeFunctionInfo& sei, UInt /*payloadSize*/){
+  Int i;
+  UInt val;
+  READ_UVLC( val, "knee_function_id" );                   sei.m_kneeId = val;
+  READ_FLAG( val, "knee_function_cancel_flag" );          sei.m_kneeCancelFlag = val;
+  if ( !sei.m_kneeCancelFlag )
+  {
+    READ_FLAG( val, "knee_function_persistence_flag" );   sei.m_kneePersistenceFlag = val;
+    READ_FLAG( val, "mapping_flag" );                     sei.m_kneeMappingFlag = val;
+    READ_CODE( 32, val, "input_d_range" );                sei.m_kneeInputDrange = val;
+    READ_CODE( 32, val, "input_disp_luminance" );         sei.m_kneeInputDispLuminance = val;
+    READ_CODE( 32, val, "output_d_range" );               sei.m_kneeOutputDrange = val;
+    READ_CODE( 32, val, "output_disp_luminance" );        sei.m_kneeOutputDispLuminance = val;
+    READ_UVLC( val, "num_knee_points_minus1" );           sei.m_kneeNumKneePointsMinus1 = val;
+    assert( sei.m_kneeNumKneePointsMinus1 > 0 );
+    sei.m_kneeInputKneePoint.resize(sei.m_kneeNumKneePointsMinus1+1);
+    sei.m_kneeOutputKneePoint.resize(sei.m_kneeNumKneePointsMinus1+1);
+    for(i = 0; i <= sei.m_kneeNumKneePointsMinus1; i++ )
+    {
+      READ_CODE( 10, val, "input_knee_point" );           sei.m_kneeInputKneePoint[i] = val;
+      READ_CODE( 10, val, "output_knee_point" );          sei.m_kneeOutputKneePoint[i] = val;
+    }
+  }
+}
+#endif
+
 #if Q0074_SEI_COLOR_MAPPING
 Void SEIReader::xParseSEIColorMappingInfo(SEIColorMappingInfo& sei, UInt /*payloadSize*/)
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/SEIread.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/SEIread.h	(revision 775)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/SEIread.h	(revision 776)
@@ -90,4 +90,7 @@
   Void xParseSEIGradualDecodingRefreshInfo (SEIGradualDecodingRefreshInfo &sei, UInt payloadSize);
   Void xParseSEIToneMappingInfo       (SEIToneMappingInfo& sei, UInt payloadSize);
+#if P0050_KNEE_FUNCTION_SEI
+  Void xParseSEIKneeFunctionInfo      (SEIKneeFunctionInfo& sei, UInt payloadSize);
+#endif
 #if Q0074_SEI_COLOR_MAPPING
   Void xParseSEIColorMappingInfo      (SEIColorMappingInfo& sei, UInt payloadSize);
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 775)
+++ /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 775)
+++ /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 775)
+++ /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 775)
+++ /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 775)
+++ /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 );
