va: vpp: Update the colorimetry and HDR fields when fixup src caps.
authorHe Junyan <junyan.he@intel.com>
Wed, 20 Apr 2022 05:18:34 +0000 (13:18 +0800)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 22 Apr 2022 06:53:37 +0000 (06:53 +0000)
When we fixup src caps, the current way of handling the HDR fields is not
correct.
1. We trim the HDR fields only when the input caps is not a subset of the
fixup src caps. But in fact, the input caps with HDR fields such as the
"mastering-display-info" can possibly be the subset of the fixup src caps,
if they have all same other fields.
2. We always copy the colorimetry from input caps to src caps if it is
absent. But when hdr-tone-mapping is enabled, the HDR->SDR conversion makes
the colorimetry change. We should use downstream's setting, or just use the
default colorimetry of SDR.

We changes to:
1. If hdr-tone-mapping is enabled, we trim all HDR fields and add a correct
colorimetry.
2. Copy colorimetry from input if it is still absent.
3. Consider the subset replacement.

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

subprojects/gst-plugins-bad/sys/va/gstvavpp.c

index 55d5012..bf0c54f 100644 (file)
@@ -1800,13 +1800,28 @@ copy_misc_fields_from_input (GstCaps * in_caps, GstCaps * out_caps)
   }
 }
 
-static inline void
-remove_hdr_fields (GstCaps * caps)
+static void
+update_hdr_fields (GstVaVpp * self, GstCaps * result)
 {
-  GstStructure *s = gst_caps_get_structure (caps, 0);
+  GstStructure *s = gst_caps_get_structure (result, 0);
+  GstVideoInfo out_info;
+  gboolean have_colorimetry;
 
   gst_structure_remove_fields (s, "mastering-display-info",
       "content-light-level", "hdr-format", NULL);
+
+  have_colorimetry = gst_structure_has_field (s, "colorimetry");
+  if (!have_colorimetry) {
+    if (gst_video_info_from_caps (&out_info, result)) {
+      gchar *colorimetry_str =
+          gst_video_colorimetry_to_string (&out_info.colorimetry);
+      gst_caps_set_simple (result, "colorimetry", G_TYPE_STRING,
+          colorimetry_str, NULL);
+      g_free (colorimetry_str);
+    } else {
+      GST_WARNING_OBJECT (self, "Failed to convert src pad caps to video info");
+    }
+  }
 }
 
 static GstCaps *
@@ -1836,14 +1851,14 @@ gst_va_vpp_fixate_caps (GstBaseTransform * trans, GstPadDirection direction,
   result = gst_caps_fixate (result);
 
   if (direction == GST_PAD_SINK) {
-    if (gst_caps_is_subset (caps, result)) {
+    if (self->hdr_mapping)
+      update_hdr_fields (self, result);
+
+    /* Try and preserve input colorimetry / chroma information */
+    transfer_colorimetry_from_input (self, caps, result);
+
+    if (gst_caps_is_subset (caps, result))
       gst_caps_replace (&result, caps);
-    } else {
-      /* Try and preserve input colorimetry / chroma information */
-      transfer_colorimetry_from_input (self, caps, result);
-      if (self->hdr_mapping)
-        remove_hdr_fields (result);
-    }
   }
 
   GST_DEBUG_OBJECT (self, "fixated othercaps to %" GST_PTR_FORMAT, result);