From 1b851ae23f542542dbaa470c80886ae1d7ad6e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 1 Mar 2022 20:56:43 +0200 Subject: [PATCH] matroska-mux: Handle multiview-mode/flags caps fields correctly when checking caps equality 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: --- .../gst/matroska/matroska-mux.c | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c index b9063ce23e..bf172b44f4 100644 --- a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c +++ b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c @@ -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);