tee: Check for the removed pad flag also in the slow pushing path
[platform/upstream/gstreamer.git] / gst / gstbin.c
index 96a0c9d..17190fd 100644 (file)
@@ -1122,11 +1122,15 @@ gst_bin_do_deep_add_remove (GstBin * bin, gint sig_id, const gchar * sig_name,
       while ((e = g_queue_pop_head (&elements))) {
         GstObject *parent = gst_object_get_parent (GST_OBJECT_CAST (e));
 
-        GST_LOG_OBJECT (bin, "calling %s for element %" GST_PTR_FORMAT
-            " in bin %" GST_PTR_FORMAT, sig_name, e, parent);
-        g_signal_emit (bin, sig_id, 0, parent, e);
-        gst_object_unref (parent);
-        g_object_unref (e);
+        /* an element could have removed some of its internal elements
+         * meanwhile, so protect against that */
+        if (parent) {
+          GST_LOG_OBJECT (bin, "calling %s for element %" GST_PTR_FORMAT
+              " in bin %" GST_PTR_FORMAT, sig_name, e, parent);
+          g_signal_emit (bin, sig_id, 0, parent, e);
+          gst_object_unref (parent);
+          g_object_unref (e);
+        }
       }
     }
     gst_iterator_free (it);
@@ -1301,12 +1305,14 @@ no_state_recalc:
     s = (GstStructure *) gst_message_get_structure (msg);
     gst_structure_get (s, "bin.old.context", GST_TYPE_CONTEXT, &context, NULL);
     gst_structure_remove_field (s, "bin.old.context");
-    gst_element_post_message (GST_ELEMENT_CAST (bin), msg);
+    /* Keep the msg around while we still need access to the context_type */
+    gst_element_post_message (GST_ELEMENT_CAST (bin), gst_message_ref (msg));
 
     /* lock to avoid losing a potential write */
     GST_OBJECT_LOCK (bin);
     replacement =
         gst_element_get_context_unlocked (GST_ELEMENT_CAST (bin), context_type);
+    gst_message_unref (msg);
 
     if (replacement) {
       /* we got the context set from GstElement::set_context */
@@ -4007,24 +4013,32 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
       GList *l, *contexts;
 
       gst_message_parse_context_type (message, &context_type);
-      GST_OBJECT_LOCK (bin);
-      contexts = GST_ELEMENT_CAST (bin)->contexts;
-      GST_LOG_OBJECT (bin, "got need-context message type: %s", context_type);
-      for (l = contexts; l; l = l->next) {
-        GstContext *tmp = l->data;
-        const gchar *tmp_type = gst_context_get_context_type (tmp);
-
-        if (strcmp (context_type, tmp_type) == 0) {
-          gst_element_set_context (GST_ELEMENT (src), l->data);
-          break;
+
+      if (src) {
+        GST_OBJECT_LOCK (bin);
+        contexts = GST_ELEMENT_CAST (bin)->contexts;
+        GST_LOG_OBJECT (bin, "got need-context message type: %s", context_type);
+        for (l = contexts; l; l = l->next) {
+          GstContext *tmp = l->data;
+          const gchar *tmp_type = gst_context_get_context_type (tmp);
+
+          if (strcmp (context_type, tmp_type) == 0) {
+            gst_element_set_context (GST_ELEMENT (src), l->data);
+            break;
+          }
         }
-      }
-      GST_OBJECT_UNLOCK (bin);
+        GST_OBJECT_UNLOCK (bin);
 
-      /* Forward if we couldn't answer the message */
-      if (l == NULL) {
-        goto forward;
+        /* Forward if we couldn't answer the message */
+        if (l == NULL) {
+          goto forward;
+        } else {
+          gst_message_unref (message);
+        }
       } else {
+        g_warning
+            ("Got need-context message in bin '%s' without source element, dropping",
+            GST_ELEMENT_NAME (bin));
         gst_message_unref (message);
       }