video-color: Add primaries and colorimetry compare functions
authorSeungha Yang <seungha@centricular.com>
Sat, 16 Jul 2022 14:36:22 +0000 (23:36 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 18 Jul 2022 08:56:45 +0000 (08:56 +0000)
SMPTE 170M and 240M use the same RGB and white point coordinates
and therefore both primaries can be considered functionally
equivalent.
Also, some transfer functions have different name but equal
gamma functions. Adding another colorimetry compare function
to deal with thoes cases at once

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2765>

subprojects/gst-plugins-base/gst-libs/gst/video/video-color.c
subprojects/gst-plugins-base/gst-libs/gst/video/video-color.h
subprojects/gst-plugins-base/tests/check/libs/video.c

index 7075a73..90fa380 100644 (file)
@@ -269,6 +269,38 @@ gst_video_colorimetry_is_equal (const GstVideoColorimetry * cinfo,
   return CI_IS_EQUAL (cinfo, other);
 }
 
+/**
+ * gst_video_colorimetry_is_equivalent:
+ * @cinfo: a #GstVideoColorimetry
+ * @bitdepth: bitdepth of a format associated with @cinfo
+ * @other: another #GstVideoColorimetry
+ * @other_bitdepth: bitdepth of a format associated with @other
+ *
+ * Compare the 2 colorimetry sets for functionally equality
+ *
+ * Returns: %TRUE if @cinfo and @other are equivalent.
+ *
+ * Since: 1.22
+ */
+gboolean
+gst_video_colorimetry_is_equivalent (const GstVideoColorimetry * cinfo,
+    guint bitdepth, const GstVideoColorimetry * other, guint other_bitdepth)
+{
+  g_return_val_if_fail (cinfo != NULL, FALSE);
+  g_return_val_if_fail (other != NULL, FALSE);
+
+  if (cinfo->range != other->range || cinfo->matrix != other->matrix)
+    return FALSE;
+
+  if (!gst_video_color_primaries_is_equivalent (cinfo->primaries,
+          other->primaries)) {
+    return FALSE;
+  }
+
+  return gst_video_transfer_function_is_equivalent (cinfo->transfer, bitdepth,
+      other->transfer, other_bitdepth);
+}
+
 #define WP_C    0.31006, 0.31616
 #define WP_D65  0.31271, 0.32902
 #define WP_CENTRE (1/3), (1/3)
@@ -320,6 +352,35 @@ gst_video_color_primaries_get_info (GstVideoColorPrimaries primaries)
 }
 
 /**
+ * gst_video_color_primaries_is_equivalent:
+ * @primaries: a #GstVideoColorPrimaries
+ * @other: another #GstVideoColorPrimaries
+ *
+ * Checks whether @primaries and @other are functionally equivalent
+ *
+ * Returns: TRUE if @primaries and @other can be considered equivalent.
+ *
+ * Since: 1.22
+ */
+gboolean
+gst_video_color_primaries_is_equivalent (GstVideoColorPrimaries primaries,
+    GstVideoColorPrimaries other)
+{
+  if (primaries == other)
+    return TRUE;
+
+  /* smpte-170m and 240m use the same reference RGB primaries and white point */
+  if ((primaries == GST_VIDEO_COLOR_PRIMARIES_SMPTE170M ||
+          primaries == GST_VIDEO_COLOR_PRIMARIES_SMPTE240M) &&
+      (other == GST_VIDEO_COLOR_PRIMARIES_SMPTE170M ||
+          other == GST_VIDEO_COLOR_PRIMARIES_SMPTE240M)) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
  * gst_video_color_matrix_get_Kr_Kb:
  * @matrix: a #GstVideoColorMatrix
  * @Kr: (out): result red channel coefficient
index c6ff3c8..ccdf64c 100644 (file)
@@ -222,6 +222,10 @@ GST_VIDEO_API
 const GstVideoColorPrimariesInfo *
                 gst_video_color_primaries_get_info     (GstVideoColorPrimaries primaries);
 
+GST_VIDEO_API
+gboolean gst_video_color_primaries_is_equivalent       (GstVideoColorPrimaries primaries,
+                                                        GstVideoColorPrimaries other);
+
 /**
  * GstVideoColorimetry:
  * @range: the color range. This is the valid range for the samples.
@@ -262,6 +266,12 @@ gchar *      gst_video_colorimetry_to_string   (const GstVideoColorimetry *cinfo
 GST_VIDEO_API
 gboolean     gst_video_colorimetry_is_equal    (const GstVideoColorimetry *cinfo, const GstVideoColorimetry *other);
 
+GST_VIDEO_API
+gboolean     gst_video_colorimetry_is_equivalent (const GstVideoColorimetry *cinfo,
+                                                  guint bitdepth,
+                                                  const GstVideoColorimetry *other,
+                                                  guint other_bitdepth);
+
 /* compute offset and scale */
 
 GST_VIDEO_API
index f17322d..5792364 100644 (file)
@@ -4071,6 +4071,41 @@ GST_START_TEST (test_auto_video_frame_unmap)
 
 GST_END_TEST;
 
+static gboolean
+is_equal_primaries_coord (const GstVideoColorPrimariesInfo * a,
+    const GstVideoColorPrimariesInfo * b)
+{
+  return (a->Wx == b->Wx && a->Wy == b->Wy && a->Rx == b->Rx && a->Ry == a->Ry
+      && a->Gx == b->Gx && a->Gy == b->Gy && a->Bx == b->Bx && a->By == b->By);
+}
+
+GST_START_TEST (test_video_color_primaries_equivalent)
+{
+  guint i, j;
+
+  for (i = 0; i <= GST_VIDEO_COLOR_PRIMARIES_EBU3213; i++) {
+    for (j = 0; j <= GST_VIDEO_COLOR_PRIMARIES_EBU3213; j++) {
+      GstVideoColorPrimaries primaries = (GstVideoColorPrimaries) i;
+      GstVideoColorPrimaries other = (GstVideoColorPrimaries) j;
+      const GstVideoColorPrimariesInfo *primaries_info =
+          gst_video_color_primaries_get_info (primaries);
+      const GstVideoColorPrimariesInfo *other_info =
+          gst_video_color_primaries_get_info (other);
+      gboolean equal =
+          gst_video_color_primaries_is_equivalent (primaries, other);
+      gboolean same_coord = is_equal_primaries_coord (primaries_info,
+          other_info);
+
+      if (equal)
+        fail_unless (same_coord);
+      else
+        fail_if (same_coord);
+    }
+  }
+}
+
+GST_END_TEST;
+
 static Suite *
 video_suite (void)
 {
@@ -4127,6 +4162,7 @@ video_suite (void)
   tcase_add_test (tc_chain, test_video_make_raw_caps);
   tcase_add_test (tc_chain, test_video_extrapolate_stride);
   tcase_add_test (tc_chain, test_auto_video_frame_unmap);
+  tcase_add_test (tc_chain, test_video_color_primaries_equivalent);
 
   return s;
 }