qtmux: Always write colr atom with the colorimetry information
authorSebastian Dröge <sebastian@centricular.com>
Thu, 29 Sep 2016 18:56:18 +0000 (21:56 +0300)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 1 Nov 2016 18:41:22 +0000 (20:41 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=772181

gst/isomp4/atoms.c
gst/isomp4/atoms.h
gst/isomp4/fourcc.h
gst/isomp4/gstqtmux.c

index 1846d9b..eb32bf7 100644 (file)
@@ -3948,7 +3948,7 @@ build_fiel_extension (GstVideoInterlaceMode mode, GstVideoFieldOrder order)
 }
 
 AtomInfo *
-build_colr_extension (GstVideoColorimetry colorimetry)
+build_colr_extension (const GstVideoColorimetry * colorimetry, gboolean is_mp4)
 {
   AtomData *atom_data = atom_data_new (FOURCC_colr);
   guint8 *data;
@@ -3956,7 +3956,7 @@ build_colr_extension (GstVideoColorimetry colorimetry)
   guint16 transfer_function;
   guint16 matrix;
 
-  switch (colorimetry.primaries) {
+  switch (colorimetry->primaries) {
     case GST_VIDEO_COLOR_PRIMARIES_BT709:
       primaries = 1;
       break;
@@ -3967,13 +3967,16 @@ build_colr_extension (GstVideoColorimetry colorimetry)
     case GST_VIDEO_COLOR_PRIMARIES_SMPTE240M:
       primaries = 6;
       break;
+    case GST_VIDEO_COLOR_PRIMARIES_BT2020:
+      primaries = 9;
+      break;
     case GST_VIDEO_COLOR_PRIMARIES_UNKNOWN:
     default:
       primaries = 2;
       break;
   }
 
-  switch (colorimetry.transfer) {
+  switch (colorimetry->transfer) {
     case GST_VIDEO_TRANSFER_BT709:
       transfer_function = 1;
       break;
@@ -3986,7 +3989,7 @@ build_colr_extension (GstVideoColorimetry colorimetry)
       break;
   }
 
-  switch (colorimetry.matrix) {
+  switch (colorimetry->matrix) {
     case GST_VIDEO_COLOR_MATRIX_BT709:
       matrix = 1;
       break;
@@ -3996,22 +3999,33 @@ build_colr_extension (GstVideoColorimetry colorimetry)
     case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
       matrix = 7;
       break;
+    case GST_VIDEO_COLOR_MATRIX_BT2020:
+      matrix = 9;
+      break;
     case GST_VIDEO_COLOR_MATRIX_UNKNOWN:
     default:
       matrix = 2;
       break;
   }
 
-  atom_data_alloc_mem (atom_data, 10);
+  atom_data_alloc_mem (atom_data, 10 + (is_mp4 ? 1 : 0));
   data = atom_data->data;
 
   /* colour specification box */
-  GST_WRITE_UINT32_LE (data, FOURCC_nclc);
+  if (is_mp4)
+    GST_WRITE_UINT32_LE (data, FOURCC_nclx);
+  else
+    GST_WRITE_UINT32_LE (data, FOURCC_nclc);
 
   GST_WRITE_UINT16_BE (data + 4, primaries);
-  GST_WRITE_UINT16_BE (data + 6, transfer_function);    /* transfer function */
+  GST_WRITE_UINT16_BE (data + 6, transfer_function);
   GST_WRITE_UINT16_BE (data + 8, matrix);
 
+  if (is_mp4) {
+    GST_WRITE_UINT8 (data + 10,
+        colorimetry->range == GST_VIDEO_COLOR_RANGE_0_255 ? 0x80 : 0x00);
+  }
+
   return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
       atom_data_free);
 }
index d2e354a..f164ebf 100644 (file)
@@ -1044,7 +1044,7 @@ AtomInfo *   build_jp2h_extension        (gint width, gint height, const gchar *
 
 AtomInfo *   build_jp2x_extension        (const GstBuffer * prefix);
 AtomInfo *   build_fiel_extension        (GstVideoInterlaceMode mode, GstVideoFieldOrder order);
-AtomInfo *   build_colr_extension        (GstVideoColorimetry colorimetry);
+AtomInfo *   build_colr_extension        (const GstVideoColorimetry *colorimetry, gboolean is_mp4);
 AtomInfo *   build_ac3_extension         (guint8 fscod, guint8 bsid,
                                           guint8 bsmod, guint8 acmod,
                                           guint8 lfe_on, guint8 bitrate_code);
index d7d9e8d..076a5f2 100644 (file)
@@ -170,6 +170,7 @@ G_BEGIN_DECLS
 #define FOURCC_mp4v     GST_MAKE_FOURCC('m','p','4','v')
 #define FOURCC_name     GST_MAKE_FOURCC('n','a','m','e')
 #define FOURCC_nclc     GST_MAKE_FOURCC('n','c','l','c')
+#define FOURCC_nclx     GST_MAKE_FOURCC('n','c','l','x')
 #define FOURCC_opus     GST_MAKE_FOURCC('O','p','u','s')
 #define FOURCC_dops     GST_MAKE_FOURCC('d','O','p','s')
 #define FOURCC_pasp     GST_MAKE_FOURCC('p','a','s','p')
index 2005621..4a4187d 100644 (file)
@@ -4240,11 +4240,8 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps)
     entry.fourcc = fourcc;
   } else if (strcmp (mimetype, "video/x-prores") == 0) {
     const gchar *variant;
-    const gchar *colorimetry_str;
-    GstVideoColorimetry colorimetry;
 
     variant = gst_structure_get_string (structure, "variant");
-    colorimetry_str = gst_structure_get_string (structure, "colorimetry");
     if (!variant || !g_strcmp0 (variant, "standard"))
       entry.fourcc = FOURCC_apcn;
     else if (!g_strcmp0 (variant, "lt"))
@@ -4253,25 +4250,26 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps)
       entry.fourcc = FOURCC_apch;
     else if (!g_strcmp0 (variant, "proxy"))
       entry.fourcc = FOURCC_apco;
+  }
+
+  if (!entry.fourcc)
+    goto refuse_caps;
+
+  if (qtmux_klass->format == GST_QT_MUX_FORMAT_QT ||
+      qtmux_klass->format == GST_QT_MUX_FORMAT_MP4) {
+    const gchar *s;
+    GstVideoColorimetry colorimetry;
 
-    if (gst_video_colorimetry_from_string (&colorimetry, colorimetry_str)) {
-      ext_atom = build_colr_extension (colorimetry);
+    s = gst_structure_get_string (structure, "colorimetry");
+    if (s && gst_video_colorimetry_from_string (&colorimetry, s)) {
+      ext_atom =
+          build_colr_extension (&colorimetry,
+          qtmux_klass->format == GST_QT_MUX_FORMAT_MP4);
       if (ext_atom)
         ext_atom_list = g_list_append (ext_atom_list, ext_atom);
     }
-
-    if (colorimetry_str == NULL) {
-      /* TODO: Maybe implement better heuristics */
-      GST_WARNING_OBJECT (qtmux,
-          "Colorimetry information not found in caps. The resulting file's "
-          "color information might be wrong");
-      colorimetry_str = height < 720 ? "bt601" : "bt709";
-    }
   }
 
-  if (!entry.fourcc)
-    goto refuse_caps;
-
   if (qtmux_klass->format == GST_QT_MUX_FORMAT_QT
       || strcmp (mimetype, "image/x-j2c") == 0
       || strcmp (mimetype, "image/x-jpc") == 0) {