} else {
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), value);
if (pspec != NULL) {
- target = g_object_ref (element);
+ target = G_OBJECT (g_object_ref (element));
GST_CAT_LOG_OBJECT (GST_CAT_PIPELINE, target, "found %s property", value);
} else {
SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_PROPERTY, \
return FALSE;
}
+static gboolean
+gst_parse_element_can_do_caps (GstElement * e, GstPadDirection dir,
+ GstCaps * link_caps)
+{
+ gboolean can_do = FALSE, done = FALSE;
+ GstIterator *it;
+
+ it = (dir == GST_PAD_SRC) ? gst_element_iterate_src_pads (e) : gst_element_iterate_sink_pads (e);
+
+ while (!done && !can_do) {
+ GValue v = G_VALUE_INIT;
+ GstPad *pad;
+ GstCaps *caps;
+
+ switch (gst_iterator_next (it, &v)) {
+ case GST_ITERATOR_OK:
+ pad = g_value_get_object (&v);
+
+ caps = gst_pad_get_current_caps (pad);
+ if (caps == NULL)
+ caps = gst_pad_query_caps (pad, NULL);
+
+ can_do = gst_caps_can_intersect (caps, link_caps);
+
+ GST_TRACE ("can_do: %d for %" GST_PTR_FORMAT " and %" GST_PTR_FORMAT,
+ can_do, caps, link_caps);
+
+ gst_caps_unref (caps);
+
+ g_value_unset (&v);
+ break;
+ case GST_ITERATOR_DONE:
+ case GST_ITERATOR_ERROR:
+ done = TRUE;
+ break;
+ case GST_ITERATOR_RESYNC:
+ gst_iterator_resync (it);
+ break;
+ }
+ }
+
+ gst_iterator_free (it);
+
+ return can_do;
+}
+
/*
* performs a link and frees the struct. src and sink elements must be given
* return values 0 - link performed
return 0;
error:
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
- _("could not link %s to %s"), GST_ELEMENT_NAME (src),
- GST_ELEMENT_NAME (sink));
+ if (link->caps != NULL) {
+ gboolean src_can_do_caps, sink_can_do_caps;
+ gchar *caps_str = gst_caps_to_string (link->caps);
+
+ src_can_do_caps =
+ gst_parse_element_can_do_caps (src, GST_PAD_SRC, link->caps);
+ sink_can_do_caps =
+ gst_parse_element_can_do_caps (sink, GST_PAD_SINK, link->caps);
+
+ if (!src_can_do_caps && sink_can_do_caps) {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
+ _("could not link %s to %s, %s can't handle caps %s"),
+ GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (sink),
+ GST_ELEMENT_NAME (src), caps_str);
+ } else if (src_can_do_caps && !sink_can_do_caps) {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
+ _("could not link %s to %s, %s can't handle caps %s"),
+ GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (sink),
+ GST_ELEMENT_NAME (sink), caps_str);
+ } else if (!src_can_do_caps && !sink_can_do_caps) {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
+ _("could not link %s to %s, neither element can handle caps %s"),
+ GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (sink), caps_str);
+ } else {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
+ _("could not link %s to %s with caps %s"),
+ GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (sink), caps_str);
+ }
+ g_free (caps_str);
+ } else {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
+ _("could not link %s to %s"), GST_ELEMENT_NAME (src),
+ GST_ELEMENT_NAME (sink));
+ }
gst_parse_free_link (link);
return -1;
}
/*************************************************************
* Grammar explanation: (cont'd)
-* a _chain_ is a list of _elementary_s that have _link_s inbetween
+* a _chain_ is a list of _elementary_s that have _link_s in between
* which are represented through infix-notation.
*
* fakesrc ! sometransformation ! fakesink
| ASSIGNMENT assignments { $$ = g_slist_prepend ($2, $1); }
;
-binopener: '(' { $$ = gst_parse_strdup(_("bin")); }
+binopener: '(' { $$ = gst_parse_strdup("bin"); }
| BINREF { $$ = $1; }
;
bin: binopener assignments chainlist ')' {
graph_t g;
gchar *dstr;
GSList *walk;
- GstBin *bin = NULL;
GstElement *ret;
yyscan_t scanner;
/* put all elements in our bin if necessary */
if(g.chain->elements->next){
+ GstBin *bin;
if (flags & GST_PARSE_FLAG_PLACE_IN_BIN)
bin = GST_BIN (gst_element_factory_make ("bin", NULL));
else
ret = (GstElement *) g.chain->elements->data;
g_slist_free (g.chain->elements);
g.chain->elements=NULL;
- if (GST_IS_BIN (ret))
- bin = GST_BIN (ret);
gst_parse_free_chain (g.chain);
g.chain = NULL;