diff --git a/ChangeLog b/ChangeLog index 4dc79047c3..8e1c21e533 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-06-25 Wim Taymans + + * gst/gstpipeline.c: (is_eos), (pipeline_bus_handler), + (gst_pipeline_change_state): + * tools/gst-launch.c: (check_intr), (event_loop), (main): + Allow elements to post EOS in the state change function. + Fix up -launch, make it exit the poll loop when the + pipeline actually changed state. + Fix up warning parsing in -launch. + 2005-06-25 Wim Taymans * gst/elements/gsttee.c: (gst_tee_chain), (gst_tee_loop), diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index 6d7524d84c..30c9600d20 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -238,28 +238,17 @@ is_eos (GstPipeline * pipeline) { GstElement *element = GST_ELEMENT (data); GList *eosed; - GstElementState state, pending; - GstElementStateReturn complete; gchar *name; - complete = gst_element_get_state (element, &state, &pending, NULL); name = gst_element_get_name (element); - - if (complete == GST_STATE_ASYNC) { - GST_DEBUG ("element %s still performing state change", name); - result = FALSE; - done = TRUE; - goto done; - } else if (state != GST_STATE_PLAYING) { - GST_DEBUG ("element %s not playing %d %d", name, state, pending); - goto done; - } eosed = g_list_find (pipeline->eosed, element); if (!eosed) { + GST_DEBUG ("element %s did not post EOS yet", name); result = FALSE; done = TRUE; + } else { + GST_DEBUG ("element %s posted EOS", name); } - done: g_free (name); gst_object_unref (GST_OBJECT (element)); break; @@ -331,6 +320,7 @@ pipeline_bus_handler (GstBus * bus, GstMessage * message, GST_UNLOCK (bus); if (is_eos (pipeline)) { posteos = TRUE; + GST_DEBUG ("all sinks posted EOS"); } /* we drop all EOS messages */ result = GST_BUS_DROP; @@ -439,10 +429,12 @@ gst_pipeline_change_state (GstElement * element) break; } - /* we wait for async state changes ourselves. + /* we wait for async state changes ourselves when we are in an + * intermediate state. * FIXME this can block forever, better do this in a worker * thread or use a timeout? */ - if (result == GST_STATE_ASYNC) { + if (result == GST_STATE_ASYNC && + (GST_STATE_FINAL (pipeline) != GST_STATE_PENDING (pipeline))) { GTimeVal *timeval, timeout; GST_STATE_UNLOCK (pipeline); diff --git a/tools/gst-launch.c b/tools/gst-launch.c index 425d56a613..b2199f39ba 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -281,9 +281,21 @@ check_intr (GstElement * pipeline) if (!caught_intr) { return TRUE; } else { + GstBus *bus; + GstMessage *message; + caught_intr = FALSE; g_print ("Pausing pipeline.\n"); + + bus = gst_element_get_bus (GST_ELEMENT (pipeline)); + message = gst_message_new_warning (GST_OBJECT (pipeline), + NULL, "pipeline interrupted"); + gst_bus_post (bus, message); + gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_get_state (pipeline, NULL, NULL, NULL); + g_print ("Pipeline paused.\n"); + return FALSE; } @@ -361,6 +373,9 @@ event_loop (GstElement * pipeline, gboolean blocking) switch (revent) { case GST_MESSAGE_EOS: + g_print (_ + ("GOT EOS from element \"%s\".\n"), + GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)))); gst_message_unref (message); return FALSE; case GST_MESSAGE_TAG: @@ -375,7 +390,22 @@ event_loop (GstElement * pipeline, gboolean blocking) } gst_message_unref (message); break; - case GST_MESSAGE_WARNING: + case GST_MESSAGE_WARNING:{ + GError *gerror; + gchar *debug; + + gst_message_parse_warning (message, &gerror, &debug); + if (debug) { + g_print ("WARNING: Element \"%s\" warns: %s\n", + GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))), + debug); + } + gst_message_unref (message); + if (gerror) + g_error_free (gerror); + g_free (debug); + break; + } case GST_MESSAGE_ERROR:{ GError *gerror; gchar *debug; @@ -383,7 +413,8 @@ event_loop (GstElement * pipeline, gboolean blocking) gst_message_parse_error (message, &gerror, &debug); gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); gst_message_unref (message); - g_error_free (gerror); + if (gerror) + g_error_free (gerror); g_free (debug); return TRUE; } @@ -391,7 +422,8 @@ event_loop (GstElement * pipeline, gboolean blocking) GstElementState old, new; gst_message_parse_state_changed (message, &old, &new); - if (!(old == GST_STATE_PLAYING && new == GST_STATE_PAUSED)) { + if (!(old == GST_STATE_PLAYING && new == GST_STATE_PAUSED && + GST_MESSAGE_SRC (message) == GST_OBJECT (pipeline))) { gst_message_unref (message); break; } @@ -572,9 +604,6 @@ main (int argc, char *argv[]) caught_error = event_loop (pipeline, FALSE); - /* see if we got any messages */ - while (g_main_context_iteration (NULL, FALSE)); - if (caught_error) { fprintf (stderr, _("ERROR: pipeline doesn't want to preroll.\n")); } else {