From: Sebastian Dröge Date: Sun, 9 Jun 2013 15:20:22 +0000 (+0200) Subject: gst-launch: Improve GstContext handling X-Git-Tag: 1.1.2~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b7ad14984be321aba76c4c3a7c6dc3972f74a1c9;p=platform%2Fupstream%2Fgstreamer.git gst-launch: Improve GstContext handling https://bugzilla.gnome.org/show_bug.cgi?id=700967 --- diff --git a/tools/gst-launch.c b/tools/gst-launch.c index 7d88dbd..d43a30e 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 ();