[x265] [PATCH 1 of 2] api: add SMPTE ST 2086 mastering display color metadata

Steve Borho steve at borho.org
Mon Apr 13 18:49:49 CEST 2015


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1428950812 25200
#      Mon Apr 13 11:46:52 2015 -0700
# Node ID f371cc447c5947f59b57971a7574ad89ac2c7388
# Parent  4cccf22b00ee188a72c8dc3896d7dc1613d855ad
api: add SMPTE ST 2086 mastering display color metadata

This is setting a precedent for adding support for an SEI which is passed
directly from user arguments into the bitstream with no validations and minimal
overhead to the public API.

diff -r 4cccf22b00ee -r f371cc447c59 doc/reST/cli.rst
--- a/doc/reST/cli.rst	Fri Apr 10 18:15:38 2015 -0500
+++ b/doc/reST/cli.rst	Mon Apr 13 11:46:52 2015 -0700
@@ -1478,6 +1478,20 @@
 	specification for a description of these values. Default undefined
 	(not signaled)
 
+.. option:: --master-display <string>
+
+	SMPTE ST 2086 mastering display color volume SEI info, specified as
+	a string which is parsed when the stream header SEI are emitted. The
+	string format is "Y(%hu,%hu)U(%hu,%hu)V(%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 YUV channels,
+	white point X,Y and max,min luminance values.
+
+	Example: Y(10,12)U(5,13)V(5,13)WP(100,100)L(1000,100)
+
+	Note that this string value will need to be escaped or quoted to
+	protect against shell expansion on many platforms
+
 Bitstream options
 =================
 
diff -r 4cccf22b00ee -r f371cc447c59 source/CMakeLists.txt
--- a/source/CMakeLists.txt	Fri Apr 10 18:15:38 2015 -0500
+++ b/source/CMakeLists.txt	Mon Apr 13 11:46:52 2015 -0700
@@ -30,7 +30,7 @@
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
 
 # X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 55)
+set(X265_BUILD 56)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 4cccf22b00ee -r f371cc447c59 source/common/param.cpp
--- a/source/common/param.cpp	Fri Apr 10 18:15:38 2015 -0500
+++ b/source/common/param.cpp	Mon Apr 13 11:46:52 2015 -0700
@@ -851,6 +851,7 @@
     OPT("lambda-file") p->rc.lambdaFileName = strdup(value);
     OPT("analysis-file") p->analysisFileName = strdup(value);
     OPT("qg-size") p->rc.qgSize = atoi(value);
+    OPT("master-display") p->masteringDisplayColorVolume = strdup(value);
     else
         return X265_PARAM_BAD_NAME;
 #undef OPT
diff -r 4cccf22b00ee -r f371cc447c59 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Fri Apr 10 18:15:38 2015 -0500
+++ b/source/encoder/encoder.cpp	Mon Apr 13 11:46:52 2015 -0700
@@ -371,6 +371,7 @@
         free((void*)m_param->scalingLists);
         free(m_param->csvfn);
         free(m_param->numaPools);
+        free((void*)m_param->masteringDisplayColorVolume);
 
         X265_FREE(m_param);
     }
@@ -1440,6 +1441,20 @@
     bs.writeByteAlignment();
     list.serialize(NAL_UNIT_PPS, bs);
 
+    if (m_param->masteringDisplayColorVolume)
+    {
+        SEIMasteringDisplayColorVolume mdsei;
+        if (mdsei.parse(m_param->masteringDisplayColorVolume))
+        {
+            bs.resetBits();
+            mdsei.write(bs, m_sps);
+            bs.writeByteAlignment();
+            list.serialize(NAL_UNIT_PREFIX_SEI, bs);
+        }
+        else
+            x265_log(m_param, X265_LOG_WARNING, "unable to parse mastering display color volume info\n");
+    }
+
     if (m_param->bEmitInfoSEI)
     {
         char *opts = x265_param2string(m_param);
diff -r 4cccf22b00ee -r f371cc447c59 source/encoder/sei.h
--- a/source/encoder/sei.h	Fri Apr 10 18:15:38 2015 -0500
+++ b/source/encoder/sei.h	Mon Apr 13 11:46:52 2015 -0700
@@ -71,6 +71,7 @@
         DECODED_PICTURE_HASH                 = 132,
         SCALABLE_NESTING                     = 133,
         REGION_REFRESH_INFO                  = 134,
+        MASTERING_DISPLAY_INFO               = 137,
     };
 
     virtual PayloadType payloadType() const = 0;
@@ -111,6 +112,47 @@
     }
 };
 
+class SEIMasteringDisplayColorVolume : public SEI
+{
+public:
+
+    uint16_t displayPrimaryX[3];
+    uint16_t displayPrimaryY[3];
+    uint16_t whitePointX, whitePointY;
+    uint32_t maxDisplayMasteringLuminance;
+    uint32_t minDisplayMasteringLuminance;
+
+    PayloadType payloadType() const { return MASTERING_DISPLAY_INFO; }
+
+    bool parse(const char* value)
+    {
+        return sscanf(value, "Y(%hu,%hu)U(%hu,%hu)V(%hu,%hu)WP(%hu,%hu)L(%u,%u)",
+                      &displayPrimaryX[0], &displayPrimaryY[0],
+                      &displayPrimaryX[1], &displayPrimaryY[1],
+                      &displayPrimaryX[2], &displayPrimaryY[2],
+                      &whitePointX, &whitePointY,
+                      &maxDisplayMasteringLuminance, &minDisplayMasteringLuminance) == 10;
+    }
+
+    void write(Bitstream& bs, const SPS&)
+    {
+        m_bitIf = &bs;
+
+        WRITE_CODE(MASTERING_DISPLAY_INFO, 8, "payload_type");
+        WRITE_CODE(8 * 2 + 2 * 4, 8, "payload_size");
+
+        for (uint32_t i = 0; i < 3; i++)
+        {
+            WRITE_CODE(displayPrimaryX[i], 16, "display_primaries_x[ c ]");
+            WRITE_CODE(displayPrimaryY[i], 16, "display_primaries_y[ c ]");
+        }
+        WRITE_CODE(whitePointX, 16, "white_point_x");
+        WRITE_CODE(whitePointY, 16, "white_point_y");
+        WRITE_CODE(maxDisplayMasteringLuminance, 32, "max_display_mastering_luminance");
+        WRITE_CODE(minDisplayMasteringLuminance, 32, "min_display_mastering_luminance");
+    }
+};
+
 class SEIDecodedPictureHash : public SEI
 {
 public:
diff -r 4cccf22b00ee -r f371cc447c59 source/x265.h
--- a/source/x265.h	Fri Apr 10 18:15:38 2015 -0500
+++ b/source/x265.h	Mon Apr 13 11:46:52 2015 -0700
@@ -1099,6 +1099,15 @@
          * conformance cropping window to further crop the displayed window */
         int defDispWinBottomOffset;
     } vui;
+
+    /* SMPTE ST 2086 mastering display color volume SEI info, specified as a
+     * string which is parsed when the stream header SEI are emitted. The string
+     * format is "Y(%hu,%hu)U(%hu,%hu)V(%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 YUV channels, white point X,Y and
+     * max,min luminance values. */
+    const char* masteringDisplayColorVolume;
+
 } x265_param;
 
 /* x265_param_alloc:
diff -r 4cccf22b00ee -r f371cc447c59 source/x265cli.h
--- a/source/x265cli.h	Fri Apr 10 18:15:38 2015 -0500
+++ b/source/x265cli.h	Mon Apr 13 11:46:52 2015 -0700
@@ -183,6 +183,7 @@
     { "colormatrix",    required_argument, NULL, 0 },
     { "chromaloc",      required_argument, NULL, 0 },
     { "crop-rect",      required_argument, NULL, 0 },
+    { "master-display", required_argument, NULL, 0 },
     { "no-dither",            no_argument, NULL, 0 },
     { "dither",               no_argument, NULL, 0 },
     { "no-repeat-headers",    no_argument, NULL, 0 },
@@ -389,6 +390,8 @@
     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("                                    format: Y(x,y)U(x,y)V(x,y)WP(x,y)L(max,min)\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