Adds flag for eos on shutdown in gst-launch. Fixes #575814.

This commit is contained in:
Thiago Santos 2009-03-26 13:08:01 -03:00
parent 4446f9972d
commit 5fa36d9f3d

View file

@ -54,10 +54,19 @@ static void fault_restore (void);
static void fault_spin (void); static void fault_spin (void);
static void sigint_restore (void); static void sigint_restore (void);
static gboolean caught_intr = FALSE; static gboolean caught_intr = FALSE;
static gboolean waiting_eos = FALSE;
#endif #endif
/* event_loop return codes */
typedef enum _EventLoopResult
{
ELR_NO_ERROR = 0,
ELR_ERROR,
ELR_INTERRUPT
} EventLoopResult;
static GstElement *pipeline; static GstElement *pipeline;
static gboolean caught_error = FALSE; static EventLoopResult caught_error = ELR_NO_ERROR;
static gboolean quiet = FALSE; static gboolean quiet = FALSE;
static gboolean tags = FALSE; static gboolean tags = FALSE;
static gboolean messages = FALSE; static gboolean messages = FALSE;
@ -287,8 +296,14 @@ sigint_handler_sighandler (int signum)
{ {
g_print ("Caught interrupt -- "); g_print ("Caught interrupt -- ");
sigint_restore (); /* If we were waiting for an EOS, we still want to catch
* the next signal to shutdown properly (and the following one
* will quit the program). */
if (waiting_eos) {
waiting_eos = FALSE;
} else {
sigint_restore ();
}
/* we set a flag that is checked by the mainloop, we cannot do much in the /* we set a flag that is checked by the mainloop, we cannot do much in the
* interrupt handler (no mutex or other blocking stuff) */ * interrupt handler (no mutex or other blocking stuff) */
caught_intr = TRUE; caught_intr = TRUE;
@ -365,13 +380,15 @@ play_signal_setup (void)
} }
#endif /* DISABLE_FAULT_HANDLER */ #endif /* DISABLE_FAULT_HANDLER */
/* returns TRUE if there was an error or we caught a keyboard interrupt. */ /* returns ELR_ERROR if there was an error
static gboolean * or ELR_INTERRUPT if we caught a keyboard interrupt
* or ELR_NO_ERROR otherwise. */
static EventLoopResult
event_loop (GstElement * pipeline, gboolean blocking, GstState target_state) event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
{ {
GstBus *bus; GstBus *bus;
GstMessage *message = NULL; GstMessage *message = NULL;
gboolean res = FALSE; EventLoopResult res = ELR_NO_ERROR;
gboolean buffering = FALSE; gboolean buffering = FALSE;
bus = gst_element_get_bus (GST_ELEMENT (pipeline)); bus = gst_element_get_bus (GST_ELEMENT (pipeline));
@ -483,7 +500,7 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
g_error_free (gerror); g_error_free (gerror);
g_free (debug); g_free (debug);
/* we have an error */ /* we have an error */
res = TRUE; res = ELR_ERROR;
goto exit; goto exit;
} }
case GST_MESSAGE_STATE_CHANGED:{ case GST_MESSAGE_STATE_CHANGED:{
@ -579,8 +596,7 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
/* this application message is posted when we caught an interrupt and /* this application message is posted when we caught an interrupt and
* we need to stop the pipeline. */ * we need to stop the pipeline. */
PRINT (_("Interrupt: Stopping pipeline ...\n")); PRINT (_("Interrupt: Stopping pipeline ...\n"));
/* return TRUE when we caught an interrupt */ res = ELR_INTERRUPT;
res = TRUE;
goto exit; goto exit;
} }
} }
@ -609,6 +625,7 @@ main (int argc, char *argv[])
gboolean verbose = FALSE; gboolean verbose = FALSE;
gboolean no_fault = FALSE; gboolean no_fault = FALSE;
gboolean trace = FALSE; gboolean trace = FALSE;
gboolean eos_on_shutdown = FALSE;
gchar *savefile = NULL; gchar *savefile = NULL;
gchar *exclude_args = NULL; gchar *exclude_args = NULL;
GOptionEntry options[] = { GOptionEntry options[] = {
@ -630,6 +647,8 @@ main (int argc, char *argv[])
N_("Do not install a fault handler"), NULL}, N_("Do not install a fault handler"), NULL},
{"trace", 'T', 0, G_OPTION_ARG_NONE, &trace, {"trace", 'T', 0, G_OPTION_ARG_NONE, &trace,
N_("Print alloc trace (if enabled at compile time)"), NULL}, N_("Print alloc trace (if enabled at compile time)"), NULL},
{"eos-on-shutdown", 'e', 0, G_OPTION_ARG_NONE, &eos_on_shutdown,
N_("Force EOS on sources before shutting the pipeline down"), NULL},
GST_TOOLS_GOPTION_VERSION, GST_TOOLS_GOPTION_VERSION,
{NULL} {NULL}
}; };
@ -799,6 +818,20 @@ main (int argc, char *argv[])
tfthen = gst_util_get_timestamp (); tfthen = gst_util_get_timestamp ();
caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING); caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING);
if (eos_on_shutdown && caught_error == ELR_INTERRUPT) {
PRINT (_("EOS on shutdown enabled -- Forcing EOS on the pipeline\n"));
waiting_eos = TRUE;
gst_element_send_event (pipeline, gst_event_new_eos ());
PRINT (_("Waiting for EOS...\n"));
caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING);
if (caught_error == ELR_NO_ERROR) {
/* we got EOS */
PRINT (_("EOS received - stopping pipeline...\n"));
} else if (caught_error == ELR_ERROR) {
PRINT (_("An error happened while waiting for EOS\n"));
}
}
tfnow = gst_util_get_timestamp (); tfnow = gst_util_get_timestamp ();
diff = GST_CLOCK_DIFF (tfthen, tfnow); diff = GST_CLOCK_DIFF (tfthen, tfnow);
@ -811,7 +844,7 @@ main (int argc, char *argv[])
PRINT (_("Setting pipeline to PAUSED ...\n")); PRINT (_("Setting pipeline to PAUSED ...\n"));
gst_element_set_state (pipeline, GST_STATE_PAUSED); gst_element_set_state (pipeline, GST_STATE_PAUSED);
if (!caught_error) if (caught_error == ELR_NO_ERROR)
gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE); gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
PRINT (_("Setting pipeline to READY ...\n")); PRINT (_("Setting pipeline to READY ...\n"));
gst_element_set_state (pipeline, GST_STATE_READY); gst_element_set_state (pipeline, GST_STATE_READY);