matroska-mux: Handle multiview-mode/flags caps fields correctly when checking caps...
authorSebastian Dröge <sebastian@centricular.com>
Tue, 1 Mar 2022 18:56:43 +0000 (20:56 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 2 Mar 2022 10:27:47 +0000 (10:27 +0000)
Not having these fields is equivalent with them being mono/0 so consider
them like that. The generic caps functions are not aware of these
semantics and would consider the caps different, causing a negotiation
failure when caps are changing from caps with to caps without or the
other way around.

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

subprojects/gst-plugins-good/gst/matroska/matroska-mux.c

index b9063ce..bf172b4 100644 (file)
@@ -1018,13 +1018,32 @@ check_field (GQuark field_id, const GValue * value, gpointer user_data)
       return FALSE;
     else if (field_id == g_quark_from_static_string ("bit-depth-luma"))
       return FALSE;
+
+    /* Remove multiview-mode=mono and multiview-flags=0 fields as those are
+     * equivalent with not having the fields but are not considered equivalent
+     * by the generic caps functions.
+     */
+    if (field_id == g_quark_from_static_string ("multiview-mode")) {
+      const gchar *s = g_value_get_string (value);
+
+      if (g_strcmp0 (s, "mono") == 0)
+        return FALSE;
+    }
+
+    if (field_id == g_quark_from_static_string ("multiview-flags")) {
+      guint multiview_flags = gst_value_get_flagset_flags (value);
+
+      if (multiview_flags == 0)
+        return FALSE;
+    }
   }
 
   return TRUE;
 }
 
 static gboolean
-check_new_caps (GstCaps * old_caps, GstCaps * new_caps)
+check_new_caps (GstMatroskaTrackVideoContext * videocontext, GstCaps * old_caps,
+    GstCaps * new_caps)
 {
   GstStructure *old_s, *new_s;
   gboolean ret;
@@ -1076,9 +1095,17 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
 
   mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
 
+  /* find context */
+  collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
+  g_assert (collect_pad);
+  context = collect_pad->track;
+  g_assert (context);
+  g_assert (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO);
+  videocontext = (GstMatroskaTrackVideoContext *) context;
+
   if ((old_caps = gst_pad_get_current_caps (pad))) {
     if (mux->state >= GST_MATROSKA_MUX_STATE_HEADER
-        && !check_new_caps (old_caps, caps)) {
+        && !check_new_caps (videocontext, old_caps, caps)) {
       GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
           ("Caps changes are not supported by Matroska\nCurrent: `%"
               GST_PTR_FORMAT "`\nNew: `%" GST_PTR_FORMAT "`", old_caps, caps));
@@ -1093,14 +1120,6 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
     goto refuse_caps;
   }
 
-  /* find context */
-  collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
-  g_assert (collect_pad);
-  context = collect_pad->track;
-  g_assert (context);
-  g_assert (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO);
-  videocontext = (GstMatroskaTrackVideoContext *) context;
-
   /* gst -> matroska ID'ing */
   structure = gst_caps_get_structure (caps, 0);