diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2013-06-09 17:20:22 +0200 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2013-06-09 17:20:22 +0200 |
commit | b7ad14984be321aba76c4c3a7c6dc3972f74a1c9 (patch) | |
tree | a5110c7df54f4380a0dc0bf8d933883a96084612 /tools | |
parent | 002a9ac8fe49b85e942d677f4fa4d8dd3b247c3b (diff) | |
download | gstreamer-b7ad14984be321aba76c4c3a7c6dc3972f74a1c9.tar.gz |
gst-launch: Improve GstContext handling
https://bugzilla.gnome.org/show_bug.cgi?id=700967
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gst-launch.c | 82 |
1 files changed, 61 insertions, 21 deletions
diff --git a/tools/gst-launch.c b/tools/gst-launch.c index 7d88dbd5ff..d43a30ebf5 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -63,6 +63,9 @@ static gboolean messages = FALSE; 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 @@ -805,34 +808,26 @@ event_loop (GstElement * pipeline, gboolean blocking, gboolean do_progress, 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: @@ -892,6 +887,50 @@ bus_sync_handler (GstBus * bus, GstMessage * message, gpointer data) 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; } @@ -1170,6 +1209,7 @@ main (int argc, char *argv[]) PRINT (_("Freeing pipeline ...\n")); gst_object_unref (pipeline); + gst_context_replace (&context, NULL); gst_deinit (); |