GstElement *sink;
GstCaps *caps;
gulong pad_added_signal_id, no_more_pads_signal_id;
+ gboolean all_pads;
} DelayedLink;
typedef struct {
{
DelayedLink *link = data;
- GST_ELEMENT_WARNING(src, PARSE, DELAYED_LINK,
- (_("Delayed linking failed.")),
- ("failed delayed linking " PRETTY_PAD_NAME_FMT " to " PRETTY_PAD_NAME_FMT,
- PRETTY_PAD_NAME_ARGS (src, link->src_pad),
- PRETTY_PAD_NAME_ARGS (link->sink, link->sink_pad)));
+ /* Don't warn for all-pads links, as we expect those to
+ * still be active at no-more-pads */
+ if (!link->all_pads) {
+ GST_ELEMENT_WARNING(src, PARSE, DELAYED_LINK,
+ (_("Delayed linking failed.")),
+ ("failed delayed linking " PRETTY_PAD_NAME_FMT " to " PRETTY_PAD_NAME_FMT,
+ PRETTY_PAD_NAME_ARGS (src, link->src_pad),
+ PRETTY_PAD_NAME_ARGS (link->sink, 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 */
}
DelayedLink *link = data;
GST_CAT_INFO (GST_CAT_PIPELINE,
- "trying delayed linking " PRETTY_PAD_NAME_FMT " to " PRETTY_PAD_NAME_FMT,
+ "trying delayed linking %s " PRETTY_PAD_NAME_FMT " to " PRETTY_PAD_NAME_FMT,
+ link->all_pads ? "all pads" : "one pad",
PRETTY_PAD_NAME_ARGS (src, link->src_pad),
PRETTY_PAD_NAME_ARGS (link->sink, link->sink_pad));
/* do this here, we don't want to get any problems later on when
* unlocking states */
GST_CAT_DEBUG (GST_CAT_PIPELINE,
- "delayed linking " PRETTY_PAD_NAME_FMT " to " PRETTY_PAD_NAME_FMT " worked",
+ "delayed linking %s " PRETTY_PAD_NAME_FMT " to " PRETTY_PAD_NAME_FMT " worked",
+ link->all_pads ? "all pads" : "one pad",
PRETTY_PAD_NAME_ARGS (src, link->src_pad),
PRETTY_PAD_NAME_ARGS (link->sink, link->sink_pad));
g_signal_handler_disconnect (src, link->no_more_pads_signal_id);
/* releases 'link' */
- g_signal_handler_disconnect (src, link->pad_added_signal_id);
+ if (!link->all_pads)
+ g_signal_handler_disconnect (src, link->pad_added_signal_id);
}
}
static gboolean
gst_parse_perform_delayed_link (GstElement *src, const gchar *src_pad,
GstElement *sink, const gchar *sink_pad,
- GstCaps *caps)
+ GstCaps *caps, gboolean all_pads)
{
GList *templs = gst_element_class_get_pad_template_list (
GST_ELEMENT_GET_CLASS (src));
{
DelayedLink *data = g_slice_new (DelayedLink);
+ data->all_pads = all_pads;
+
/* TODO: maybe we should check if src_pad matches this template's names */
GST_CAT_DEBUG (GST_CAT_PIPELINE,
g_slist_length (srcs), g_slist_length (sinks), link->caps);
if (!srcs || !sinks) {
- if (gst_element_link_pads_filtered (src,
+ gboolean found_one = gst_element_link_pads_filtered (src,
+ srcs ? (const gchar *) srcs->data : NULL, sink,
+ sinks ? (const gchar *) sinks->data : NULL, link->caps);
+
+ if (found_one) {
+ if (!link->all_pads)
+ goto success; /* Linked one, and not an all-pads link = we're done */
+
+ /* Try and link more available pads */
+ while (gst_element_link_pads_filtered (src,
srcs ? (const gchar *) srcs->data : NULL, sink,
- sinks ? (const gchar *) sinks->data : NULL, link->caps)) {
+ sinks ? (const gchar *) sinks->data : NULL, link->caps));
+ }
+
+ /* We either didn't find any static pads, or this is a all-pads link,
+ * in which case watch for future pads and link those. Not a failure
+ * in the all-pads case if there's no sometimes pads to watch */
+ if (gst_parse_perform_delayed_link (src,
+ srcs ? (const gchar *) srcs->data : NULL,
+ sink, sinks ? (const gchar *) sinks->data : NULL, link->caps,
+ link->all_pads) || link->all_pads) {
goto success;
} else {
- if (gst_parse_perform_delayed_link (src,
- srcs ? (const gchar *) srcs->data : NULL,
- sink, sinks ? (const gchar *) sinks->data : NULL, link->caps)) {
- goto success;
- } else {
- goto error;
- }
+ goto error;
}
}
if (g_slist_length (link->src.pads) != g_slist_length (link->sink.pads)) {
} else {
if (gst_parse_perform_delayed_link (src, src_pad,
sink, sink_pad,
- link->caps)) {
+ link->caps, link->all_pads)) {
continue;
} else {
goto error;
%left <ss> REF PADREF BINREF
%token <ss> ASSIGNMENT
%token <ss> LINK
+%token <ss> LINK_ALL
%type <ss> binopener
%type <gg> graph
%left '(' ')'
%left ','
%right '.'
-%left '!' '='
+%left '!' '=' ':'
%lex-param { void *scanner }
%parse-param { void *scanner }
$$ = $4;
$$->last.pads = g_slist_concat ($$->last.pads, $5);
}
-
;
link: LINK { $$ = gst_parse_link_new ();
- $$->src.element = NULL;
- $$->sink.element = NULL;
- $$->src.name = NULL;
- $$->sink.name = NULL;
- $$->src.pads = NULL;
- $$->sink.pads = NULL;
- $$->caps = NULL;
+ $$->all_pads = FALSE;
+ if ($1) {
+ $$->caps = gst_caps_from_string ($1);
+ if ($$->caps == NULL)
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("could not parse caps \"%s\""), $1);
+ gst_parse_strfree ($1);
+ }
+ }
+ | LINK_ALL { $$ = gst_parse_link_new ();
+ $$->all_pads = TRUE;
if ($1) {
$$->caps = gst_caps_from_string ($1);
if ($$->caps == NULL)