tee: First deactivate the pad and then remove it when releasing pads
[platform/upstream/gstreamer.git] / gst / parse / grammar.y
index d7b431e..1aa77ed 100644 (file)
@@ -406,7 +406,7 @@ static void gst_parse_element_set (gchar *value, GstElement *element, graph_t *g
   } 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, \
@@ -583,6 +583,52 @@ gst_parse_perform_delayed_link (GstElement *src, const gchar *src_pad,
   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
@@ -659,9 +705,40 @@ success:
   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;
 }
@@ -768,7 +845,7 @@ elementary:
 
 /*************************************************************
 * 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
@@ -995,7 +1072,7 @@ assignments:       /* NOP */                     { $$ = NULL; }
        |       ASSIGNMENT assignments        { $$ = g_slist_prepend ($2, $1); }
        ;
 
-binopener:     '('                           { $$ = gst_parse_strdup(_("bin")); }
+binopener:     '('                           { $$ = gst_parse_strdup("bin"); }
        |       BINREF                        { $$ = $1; }
        ;
 bin:   binopener assignments chainlist ')'   {
@@ -1069,7 +1146,6 @@ priv_gst_parse_launch (const gchar *str, GError **error, GstParseContext *ctx,
   graph_t g;
   gchar *dstr;
   GSList *walk;
-  GstBin *bin = NULL;
   GstElement *ret;
   yyscan_t scanner;
 
@@ -1132,6 +1208,7 @@ priv_gst_parse_launch (const gchar *str, GError **error, GstParseContext *ctx,
 
   /* 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
@@ -1149,8 +1226,6 @@ priv_gst_parse_launch (const gchar *str, GError **error, GstParseContext *ctx,
   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;