* a toplevel bin */
#define BIN_IS_TOPLEVEL(bin) ((GST_OBJECT_PARENT (bin) == NULL) || bin->priv->asynchandling)
-#define GST_BIN_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BIN, GstBinPrivate))
-
struct _GstBinPrivate
{
gboolean asynchandling;
}
#define gst_bin_parent_class parent_class
-G_DEFINE_TYPE_WITH_CODE (GstBin, gst_bin, GST_TYPE_ELEMENT, _do_init);
+G_DEFINE_TYPE_WITH_CODE (GstBin, gst_bin, GST_TYPE_ELEMENT,
+ G_ADD_PRIVATE (GstBin)
+ _do_init);
static GObject *
gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
- g_type_class_add_private (klass, sizeof (GstBinPrivate));
-
gobject_class->set_property = gst_bin_set_property;
gobject_class->get_property = gst_bin_get_property;
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin,
NULL);
- bin->priv = GST_BIN_GET_PRIVATE (bin);
+ bin->priv = gst_bin_get_instance_private (bin);
bin->priv->asynchandling = DEFAULT_ASYNC_HANDLING;
bin->priv->structure_cookie = 0;
bin->priv->message_forward = DEFAULT_MESSAGE_FORWARD;
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);
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 */
static void
bin_do_eos (GstBin * bin)
{
- guint32 seqnum = 0;
+ guint32 seqnum = GST_SEQNUM_INVALID;
gboolean eos;
GST_OBJECT_LOCK (bin);
GST_OBJECT_UNLOCK (bin);
tmessage = gst_message_new_eos (GST_OBJECT_CAST (bin));
- gst_message_set_seqnum (tmessage, seqnum);
+ if (seqnum != GST_SEQNUM_INVALID)
+ gst_message_set_seqnum (tmessage, seqnum);
GST_DEBUG_OBJECT (bin,
"all sinks posted EOS, posting seqnum #%" G_GUINT32_FORMAT, seqnum);
gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
static void
bin_do_stream_start (GstBin * bin)
{
- guint32 seqnum = 0;
+ guint32 seqnum = GST_SEQNUM_INVALID;
gboolean stream_start;
gboolean have_group_id = FALSE;
guint group_id = 0;
GST_OBJECT_UNLOCK (bin);
tmessage = gst_message_new_stream_start (GST_OBJECT_CAST (bin));
- gst_message_set_seqnum (tmessage, seqnum);
+ if (seqnum != GST_SEQNUM_INVALID)
+ gst_message_set_seqnum (tmessage, seqnum);
if (have_group_id)
gst_message_set_group_id (tmessage, group_id);
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);
}