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);
if (G_UNLIKELY (bclass->remove_element == NULL))
goto no_function;
- /* We need to take the state lock here to ensure that we're
- * not currently just before setting the state of this child
- * element. Otherwise it can happen that we removed the element
- * here and e.g. set it to NULL state, and shortly afterwards
- * have another thread set it to a higher state again as part of
- * a state change for the whole bin.
- *
- * When adding an element to the bin this is not needed as we
- * require callers to always ensure after adding to the bin that
- * the new element is set to the correct state.
- */
- GST_STATE_LOCK (bin);
-
GST_CAT_DEBUG (GST_CAT_PARENTAGE, "removing element %s from bin %s",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
result = bclass->remove_element (bin, element);
GST_TRACER_BIN_REMOVE_POST (bin, result);
- GST_STATE_UNLOCK (bin);
-
return result;
/* ERROR handling */
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);
}