Allow elements to post EOS in the state change function.

Original commit message from CVS:
* 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.
This commit is contained in:
Wim Taymans 2005-06-25 17:51:12 +00:00
parent f4f2cadeb5
commit 4e9438da9f
3 changed files with 53 additions and 22 deletions

View file

@ -1,3 +1,13 @@
2005-06-25 Wim Taymans <wim@fluendo.com>
* 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 <wim@fluendo.com>
* gst/elements/gsttee.c: (gst_tee_chain), (gst_tee_loop),

View file

@ -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);

View file

@ -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 {