parse-launch: warn when still waiting to plug sub-pipelines after no-more-pads

The parse-launch API automagically handles dynamic pads and performs delayed
linking as needed, without any feedback about whether the linking succeeded or
not however. If a delayed dynamic link can't be completed for whatever reason,
parse-launch will simply wait in case a suitable pad appears later. This may
never happen though, in which case the pipeline may just hang forever.

Try to improve this by connecting to the "no-more-pads" signal of any element
with dynamic pads and posting a warning message for the related outstanding
dynamic links when "no-more-pads" is emitted.

Fixes #760003
This commit is contained in:
Stefan Sauer 2016-01-02 19:42:17 +01:00
parent 7c992cfbe0
commit 46a851b279
2 changed files with 25 additions and 4 deletions

View file

@ -35,6 +35,8 @@ GQuark gst_parse_error_quark (void);
*/ */
#define GST_PARSE_ERROR gst_parse_error_quark () #define GST_PARSE_ERROR gst_parse_error_quark ()
/* FIXME 2.0: rename to GstParseLaunchError, this is not only related to
*parsing */
/** /**
* GstParseError: * GstParseError:
* @GST_PARSE_ERROR_SYNTAX: A syntax error occurred. * @GST_PARSE_ERROR_SYNTAX: A syntax error occurred.
@ -44,6 +46,7 @@ GQuark gst_parse_error_quark (void);
* @GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY: There was an error setting a property * @GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY: There was an error setting a property
* @GST_PARSE_ERROR_EMPTY_BIN: An empty bin was specified. * @GST_PARSE_ERROR_EMPTY_BIN: An empty bin was specified.
* @GST_PARSE_ERROR_EMPTY: An empty description was specified * @GST_PARSE_ERROR_EMPTY: An empty description was specified
* @GST_PARSE_ERROR_DELAYED_LINK: A delayed link did not get resolved.
* *
* The different parsing errors that can occur. * The different parsing errors that can occur.
*/ */
@ -55,7 +58,8 @@ typedef enum
GST_PARSE_ERROR_LINK, GST_PARSE_ERROR_LINK,
GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY, GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY,
GST_PARSE_ERROR_EMPTY_BIN, GST_PARSE_ERROR_EMPTY_BIN,
GST_PARSE_ERROR_EMPTY GST_PARSE_ERROR_EMPTY,
GST_PARSE_ERROR_DELAYED_LINK
} GstParseError; } GstParseError;
/** /**

View file

@ -232,7 +232,7 @@ typedef struct {
gchar *sink_pad; gchar *sink_pad;
GstElement *sink; GstElement *sink;
GstCaps *caps; GstCaps *caps;
gulong signal_id; gulong pad_added_signal_id, no_more_pads_signal_id;
} DelayedLink; } DelayedLink;
typedef struct { typedef struct {
@ -490,6 +490,19 @@ static void gst_parse_free_delayed_link (DelayedLink *link)
g_slice_free (DelayedLink, link); g_slice_free (DelayedLink, link);
} }
static void gst_parse_no_more_pads (GstElement *src, gpointer data)
{
DelayedLink *link = data;
GST_ELEMENT_WARNING(src, PARSE, DELAYED_LINK,
(_("Delayed linking failed.")),
("failed delayed linking %s:%s to %s:%s",
GST_STR_NULL (GST_ELEMENT_NAME (src)), GST_STR_NULL (link->src_pad),
GST_STR_NULL (GST_ELEMENT_NAME (link->sink)), GST_STR_NULL (link->sink_pad)));
/* we keep the handlers connected, so that in case an element still adds a pad
* despite no-more-pads, we will consider it for pending delayed links */
}
static void gst_parse_found_pad (GstElement *src, GstPad *pad, gpointer data) static void gst_parse_found_pad (GstElement *src, GstPad *pad, gpointer data)
{ {
DelayedLink *link = data; DelayedLink *link = data;
@ -505,7 +518,9 @@ static void gst_parse_found_pad (GstElement *src, GstPad *pad, gpointer data)
GST_CAT_DEBUG (GST_CAT_PIPELINE, "delayed linking %s:%s to %s:%s worked", GST_CAT_DEBUG (GST_CAT_PIPELINE, "delayed linking %s:%s to %s:%s worked",
GST_STR_NULL (GST_ELEMENT_NAME (src)), GST_STR_NULL (link->src_pad), GST_STR_NULL (GST_ELEMENT_NAME (src)), GST_STR_NULL (link->src_pad),
GST_STR_NULL (GST_ELEMENT_NAME (link->sink)), GST_STR_NULL (link->sink_pad)); GST_STR_NULL (GST_ELEMENT_NAME (link->sink)), GST_STR_NULL (link->sink_pad));
g_signal_handler_disconnect (src, link->signal_id); g_signal_handler_disconnect (src, link->no_more_pads_signal_id);
/* releases 'link' */
g_signal_handler_disconnect (src, link->pad_added_signal_id);
} }
} }
@ -539,9 +554,11 @@ gst_parse_perform_delayed_link (GstElement *src, const gchar *src_pad,
} else { } else {
data->caps = NULL; data->caps = NULL;
} }
data->signal_id = g_signal_connect_data (src, "pad-added", data->pad_added_signal_id = g_signal_connect_data (src, "pad-added",
G_CALLBACK (gst_parse_found_pad), data, G_CALLBACK (gst_parse_found_pad), data,
(GClosureNotify) gst_parse_free_delayed_link, (GConnectFlags) 0); (GClosureNotify) gst_parse_free_delayed_link, (GConnectFlags) 0);
data->no_more_pads_signal_id = g_signal_connect (src, "no-more-pads",
G_CALLBACK (gst_parse_no_more_pads), data);
return TRUE; return TRUE;
} }
} }