static gboolean is_live = FALSE;
static gboolean waiting_eos = FALSE;
+G_LOCK_DEFINE_STATIC (context);
+static GstContext *context = NULL;
+
/* convenience macro so we don't have to litter the code with if(!quiet) */
#define PRINT if(!quiet)g_print
break;
}
case GST_MESSAGE_HAVE_CONTEXT:{
- GstContext *context1, *context2;
+ GstContext *context_new;
gchar *context_str;
- gst_message_parse_have_context (message, &context1);
+ gst_message_parse_have_context (message, &context_new);
context_str =
- gst_structure_to_string (gst_context_get_structure (context1));
+ gst_structure_to_string (gst_context_get_structure (context_new));
PRINT (_("Got context from element '%s': %s\n"),
GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)), context_str);
g_free (context_str);
-
- context2 = gst_element_get_context (pipeline);
- if (context2) {
- const GstStructure *s1;
- GstStructure *s2;
-
- /* Merge structures */
- context2 = gst_context_make_writable (context2);
- s1 = gst_context_get_structure (context1);
- s2 = gst_context_writable_structure (context2);
- gst_structure_foreach (s1, merge_structures, s2);
- gst_element_set_context (pipeline, context2);
- gst_context_unref (context2);
- } else {
- /* Copy over the context */
- gst_element_set_context (pipeline, context1);
- }
- gst_context_unref (context1);
+ gst_context_unref (context_new);
+
+ /* The contexts were merged in the sync handler already, here
+ * now just print them and propagate the merged context to the
+ * complete pipeline */
+ G_LOCK (context);
+ context_new = gst_context_ref (context_new);
+ G_UNLOCK (context);
+ gst_element_set_context (pipeline, context_new);
+ gst_context_unref (context_new);
break;
}
default:
g_free (state_transition_name);
}
+ case GST_MESSAGE_NEED_CONTEXT:{
+ G_LOCK (context);
+ /* We could filter something here, but instead we can also just pass the complete
+ * context knowledge we have to the element. If we have what it needs, it will be
+ * happy, otherwise we can't do anything else anyway */
+ if (context)
+ gst_element_set_context (GST_ELEMENT_CAST (GST_MESSAGE_SRC (message)),
+ context);
+ G_UNLOCK (context);
+
+ break;
+ }
+ case GST_MESSAGE_HAVE_CONTEXT:{
+ GstContext *context_new;
+
+ gst_message_parse_have_context (message, &context_new);
+
+ /* Merge the contexts here as soon as possible and not
+ * in the async bus handler, in case something asks for
+ * a specific context before the async bus handler is run.
+ *
+ * Don't set the context on the complete pipeline here as it
+ * might deadlock, but do that from the async bus handler
+ * instead.
+ */
+ G_LOCK (context);
+ if (context) {
+ const GstStructure *s1;
+ GstStructure *s2;
+
+ /* Merge structures */
+ context = gst_context_make_writable (context);
+ s1 = gst_context_get_structure (context_new);
+ s2 = gst_context_writable_structure (context);
+ gst_structure_foreach (s1, merge_structures, s2);
+ gst_context_unref (context);
+ } else {
+ /* Copy over the context */
+ gst_context_replace (&context, context_new);
+ }
+ gst_context_unref (context_new);
+ G_UNLOCK (context);
+ break;
+ }
default:
break;
}
PRINT (_("Freeing pipeline ...\n"));
gst_object_unref (pipeline);
+ gst_context_replace (&context, NULL);
gst_deinit ();