[x265] [PATCH] sei: add content light level info SEI

Steve Borho steve at borho.org
Sat May 2 21:04:00 CEST 2015


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1430593406 18000
#      Sat May 02 14:03:26 2015 -0500
# Node ID 8edb3ade2d62644f39b936e2322dcd831f568a0c
# Parent  a73024cfe8446a4a26c89518f84df1084516f264
sei: add content light level info SEI

diff -r a73024cfe844 -r 8edb3ade2d62 doc/reST/cli.rst
--- a/doc/reST/cli.rst	Sat May 02 11:11:04 2015 -0500
+++ b/doc/reST/cli.rst	Sat May 02 14:03:26 2015 -0500
@@ -1496,14 +1496,28 @@
 	string format is "G(%hu,%hu)B(%hu,%hu)R(%hu,%hu)WP(%hu,%hu)L(%u,%u)"
 	where %hu are unsigned 16bit integers and %u are unsigned 32bit
 	integers. The SEI includes X,Y display primaries for RGB channels,
-	white point X,Y and max,min luminance values.
+	white point X,Y and max,min luminance values. (HDR)
 
 	Example for P65D3 1000-nits:
 
 		G(13200,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)
 
 	Note that this string value will need to be escaped or quoted to
-	protect against shell expansion on many platforms
+	protect against shell expansion on many platforms. No default.
+
+.. option:: --max-cll <string>
+
+	Maximum content light level and maximum frame average light level as
+	required by the Consumer Electronics Association 861.3 specification.
+
+	Specified as a string which is parsed when the stream header SEI are
+	emitted. The string format is "%hu,%hu" where %hu are unsigned 16bit
+	integers. The first value is the max content light level (or 0 if no
+	maximum is indicated), the second value is the maximum picture
+	average light level (or 0). (HDR)
+
+	Note that this string value will need to be escaped or quoted to
+	protect against shell expansion on many platforms. No default.
 
 Bitstream options
 =================
diff -r a73024cfe844 -r 8edb3ade2d62 source/common/param.cpp
--- a/source/common/param.cpp	Sat May 02 11:11:04 2015 -0500
+++ b/source/common/param.cpp	Sat May 02 14:03:26 2015 -0500
@@ -852,6 +852,7 @@
     OPT("analysis-file") p->analysisFileName = strdup(value);
     OPT("qg-size") p->rc.qgSize = atoi(value);
     OPT("master-display") p->masteringDisplayColorVolume = strdup(value);
+    OPT("max-cll") p->contentLightLevelInfo = strdup(value);
     else
         return X265_PARAM_BAD_NAME;
 #undef OPT
diff -r a73024cfe844 -r 8edb3ade2d62 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Sat May 02 11:11:04 2015 -0500
+++ b/source/encoder/encoder.cpp	Sat May 02 14:03:26 2015 -0500
@@ -372,6 +372,7 @@
         free(m_param->csvfn);
         free(m_param->numaPools);
         free((void*)m_param->masteringDisplayColorVolume);
+        free((void*)m_param->contentLightLevelInfo);
 
         X265_FREE(m_param);
     }
@@ -1455,6 +1456,20 @@
             x265_log(m_param, X265_LOG_WARNING, "unable to parse mastering display color volume info\n");
     }
 
+    if (m_param->contentLightLevelInfo)
+    {
+        SEIContentLightLevel cllsei;
+        if (cllsei.parse(m_param->contentLightLevelInfo))
+        {
+            bs.resetBits();
+            cllsei.write(bs, m_sps);
+            bs.writeByteAlignment();
+            list.serialize(NAL_UNIT_PREFIX_SEI, bs);
+        }
+        else
+            x265_log(m_param, X265_LOG_WARNING, "unable to parse content light level info\n");
+    }
+
     if (m_param->bEmitInfoSEI)
     {
         char *opts = x265_param2string(m_param);
diff -r a73024cfe844 -r 8edb3ade2d62 source/encoder/sei.h
--- a/source/encoder/sei.h	Sat May 02 11:11:04 2015 -0500
+++ b/source/encoder/sei.h	Sat May 02 14:03:26 2015 -0500
@@ -72,6 +72,7 @@
         SCALABLE_NESTING                     = 133,
         REGION_REFRESH_INFO                  = 134,
         MASTERING_DISPLAY_INFO               = 137,
+        CONTENT_LIGHT_LEVEL_INFO             = 144,
     };
 
     virtual PayloadType payloadType() const = 0;
@@ -153,6 +154,32 @@
     }
 };
 
+class SEIContentLightLevel : public SEI
+{
+public:
+
+    uint16_t max_content_light_level;
+    uint16_t max_pic_average_light_level;
+
+    PayloadType payloadType() const { return CONTENT_LIGHT_LEVEL_INFO; }
+
+    bool parse(const char* value)
+    {
+        return sscanf(value, "%hu,%hu",
+                      &max_content_light_level, &max_pic_average_light_level) == 2;
+    }
+
+    void write(Bitstream& bs, const SPS&)
+    {
+        m_bitIf = &bs;
+
+        WRITE_CODE(CONTENT_LIGHT_LEVEL_INFO, 8, "payload_type");
+        WRITE_CODE(4, 8, "payload_size");
+        WRITE_CODE(max_content_light_level,     16, "max_content_light_level");
+        WRITE_CODE(max_pic_average_light_level, 16, "max_pic_average_light_level");
+    }
+};
+
 class SEIDecodedPictureHash : public SEI
 {
 public:
diff -r a73024cfe844 -r 8edb3ade2d62 source/x265.h
--- a/source/x265.h	Sat May 02 11:11:04 2015 -0500
+++ b/source/x265.h	Sat May 02 14:03:26 2015 -0500
@@ -1108,6 +1108,13 @@
      * max,min luminance values. */
     const char* masteringDisplayColorVolume;
 
+    /* Content light level info SEI, specified as a string which is parsed when
+     * the stream header SEI are emitted. The string format is "%hu,%hu" where
+     * %hu are unsigned 16bit integers. The first value is the max content light
+     * level (or 0 if no maximum is indicated), the second value is the maximum
+     * picture average light level (or 0). */
+    const char* contentLightLevelInfo;
+
 } x265_param;
 
 /* x265_param_alloc:
diff -r a73024cfe844 -r 8edb3ade2d62 source/x265cli.h
--- a/source/x265cli.h	Sat May 02 11:11:04 2015 -0500
+++ b/source/x265cli.h	Sat May 02 14:03:26 2015 -0500
@@ -184,6 +184,7 @@
     { "chromaloc",      required_argument, NULL, 0 },
     { "crop-rect",      required_argument, NULL, 0 },
     { "master-display", required_argument, NULL, 0 },
+    { "max-cll",        required_argument, NULL, 0 },
     { "no-dither",            no_argument, NULL, 0 },
     { "dither",               no_argument, NULL, 0 },
     { "no-repeat-headers",    no_argument, NULL, 0 },
@@ -392,8 +393,9 @@
     H1("   --colormatrix <string>        Specify color matrix setting from undef, bt709, fcc, bt470bg, smpte170m,\n");
     H1("                                 smpte240m, GBR, YCgCo, bt2020nc, bt2020c. Default undef\n");
     H1("   --chromaloc <integer>         Specify chroma sample location (0 to 5). Default of %d\n", param->vui.chromaSampleLocTypeTopField);
-    H0("   --master-display <string>     SMPTE ST 2086 master display color volume info\n");
+    H0("   --master-display <string>     SMPTE ST 2086 master display color volume info SEI (HDR)\n");
     H0("                                    format: G(x,y)B(x,y)R(x,y)WP(x,y)L(max,min)\n");
+    H0("   --max-cll <string>            Emit content light level info SEI as \"cll,fall\" (HDR)\n");
     H0("\nBitstream options:\n");
     H0("   --[no-]repeat-headers         Emit SPS and PPS headers at each keyframe. Default %s\n", OPT(param->bRepeatHeaders));
     H0("   --[no-]info                   Emit SEI identifying encoder and parameters. Default %s\n", OPT(param->bEmitInfoSEI));


More information about the x265-devel mailing list