From cf2dc2f94cac070ad6704b766129cd6e4316b069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alicia=20Boya=20Garc=C3=ADa?= Date: Wed, 5 Feb 2025 18:53:33 +0100 Subject: [PATCH] gstreamer: parse: Fix log in gst_parse_perform_link Suppose you're trying to debug why this pipeline doesn't work: ``` $ GST_DEBUG=GST_PIPELINE:DEBUG gst-launch-1.0 \ videotestsrc num-buffers=10 ! x264enc name=enc ! mux.sink_0 \ mpegtsmux name=mux ! fakesink ``` You will encounter this line in the logs: > gst_parse_perform_link: linking some pad of GstX264Enc named enc to > pad mux of GstMpegTsMux named mux (0/1) with caps "(NULL)" It would seem that the element name is being read as a pad name as well, and that made me wonder if the parsing was not working. However, it was just a bug in the code printing that log. This patch fixes that bug. Note that it is possible to specify more than one pad name for each side of the link. For instance, the following is a valid pipeline that will remux the video and audio of an MP4 file into MKV: ``` $ GST_DEBUG=GST_PIPELINE:DEBUG gst-launch \ filesrc location=input.mp4 ! qtdemux name=demux \ multiqueue name=mq \ matroskamux name=mux ! filesink location=output.mkv \ demux.video_0,audio_0 ! mq.sink_0,sink_1 \ mq.src_0,src_1 ! mux.video_0,audio_0 ``` The new logging accomodates this by using a new utility function to join strings of pad name lists instead of `PRETTY_PAD_NAME_FMT` (which only supports one pad name). For example: > linking pads {video_0, audio_0} of GstQTDemux named demux to pads > {sink_0, sink_1} of GstMultiQueue named mq with caps "(NULL)" Part-of: --- subprojects/gstreamer/gst/parse/grammar.y.in | 33 +++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/subprojects/gstreamer/gst/parse/grammar.y.in b/subprojects/gstreamer/gst/parse/grammar.y.in index fbc36f19de..e9e34f3ce9 100644 --- a/subprojects/gstreamer/gst/parse/grammar.y.in +++ b/subprojects/gstreamer/gst/parse/grammar.y.in @@ -905,7 +905,7 @@ static void gst_parse_free_delayed_link (DelayedLink *link) #define PRETTY_PAD_NAME_FMT "%s %s of %s named %s" #define PRETTY_PAD_NAME_ARGS(elem, pad_name) \ - (pad_name ? "pad " : "some"), (pad_name ? pad_name : "pad"), \ + (pad_name ? "pad" : "some"), (pad_name ? pad_name : "pad"), \ G_OBJECT_TYPE_NAME(elem), GST_STR_NULL (GST_ELEMENT_NAME (elem)) static void gst_parse_no_more_pads (GstElement *src, gpointer data) @@ -1042,6 +1042,23 @@ gst_parse_element_can_do_caps (GstElement * e, GstPadDirection dir, return can_do; } +static gchar* +format_pad_names(const GSList* list) +{ + if (!list) + return g_strdup ("(any)"); + GString* str = g_string_new (NULL); + gboolean is_first = TRUE; + while (list) { + if (!is_first) + g_string_append (str, ", "); + g_string_append (str, (const gchar *) list->data); + list = list->next; + is_first = FALSE; + } + return g_string_free (str, FALSE); +} + /* * performs a link and frees the struct. src and sink elements must be given * return values 0 - link performed @@ -1058,11 +1075,17 @@ gst_parse_perform_link (link_t *link, graph_t *graph) g_assert (GST_IS_ELEMENT (src)); g_assert (GST_IS_ELEMENT (sink)); +#ifndef GST_DISABLE_GST_DEBUG + gchar* srcpad_names = format_pad_names (srcs); + gchar* sinkpad_names = format_pad_names (sinks); GST_CAT_INFO (GST_CAT_PIPELINE, - "linking " PRETTY_PAD_NAME_FMT " to " PRETTY_PAD_NAME_FMT " (%u/%u) with caps \"%" GST_PTR_FORMAT "\"", - PRETTY_PAD_NAME_ARGS (src, link->src.name), - PRETTY_PAD_NAME_ARGS (sink, link->sink.name), - g_slist_length (srcs), g_slist_length (sinks), link->caps); + "linking pads {%s} of %s named %s to pads {%s} of %s named %s with caps \"%" GST_PTR_FORMAT "\"", + srcpad_names, G_OBJECT_TYPE_NAME (src), GST_STR_NULL (GST_ELEMENT_NAME (src)), + sinkpad_names, G_OBJECT_TYPE_NAME (sink), GST_STR_NULL (GST_ELEMENT_NAME (sink)), + link->caps); + g_free (srcpad_names); + g_free (sinkpad_names); +#endif if (!srcs || !sinks) { gboolean found_one = gst_element_link_pads_filtered (src,