*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-/* FIXME: hack alert */
-#ifdef HAVE_WIN32
-#define DISABLE_FAULT_HANDLER
-#endif
-
+#include <glib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifndef DISABLE_FAULT_HANDLER
+#ifdef G_OS_UNIX
+#include <glib-unix.h>
#include <sys/wait.h>
+#elif defined (G_OS_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
#endif
#include <locale.h> /* for LC_ALL */
#include "tools.h"
-/* FIXME: This is just a temporary hack. We should have a better
- * check for siginfo handling. */
-#ifdef SA_SIGINFO
-#define USE_SIGINFO
-#endif
-
extern volatile gboolean glib_on_error_halt;
-#ifndef DISABLE_FAULT_HANDLER
+#ifdef G_OS_UNIX
static void fault_restore (void);
static void fault_spin (void);
-static void sigint_restore (void);
-static gboolean caught_intr = FALSE;
#endif
/* event_loop return codes */
static gboolean messages = FALSE;
static gboolean is_live = FALSE;
static gboolean waiting_eos = FALSE;
+static gchar **exclude_args = NULL;
/* convenience macro so we don't have to litter the code with if(!quiet) */
#define PRINT if(!quiet)g_print
-#ifndef DISABLE_FAULT_HANDLER
-#ifndef USE_SIGINFO
+#ifdef G_OS_UNIX
static void
fault_handler_sighandler (int signum)
{
fault_spin ();
}
-#else /* USE_SIGINFO */
-
-static void
-fault_handler_sigaction (int signum, siginfo_t * si, void *misc)
-{
- fault_restore ();
-
- /* printf is used instead of g_print(), since it's less likely to
- * deadlock */
- switch (si->si_signo) {
- case SIGSEGV:
- fprintf (stderr, "Caught SIGSEGV accessing address %p\n", si->si_addr);
- break;
- case SIGQUIT:
- if (!quiet)
- printf ("Caught SIGQUIT\n");
- break;
- default:
- fprintf (stderr, "signo: %d\n", si->si_signo);
- fprintf (stderr, "errno: %d\n", si->si_errno);
- fprintf (stderr, "code: %d\n", si->si_code);
- break;
- }
-
- fault_spin ();
-}
-#endif /* USE_SIGINFO */
-
static void
fault_spin (void)
{
int spinning = TRUE;
glib_on_error_halt = FALSE;
- g_on_error_stack_trace ("gst-launch");
+ g_on_error_stack_trace ("gst-launch-" GST_API_VERSION);
wait (NULL);
/* FIXME how do we know if we were run by libtool? */
fprintf (stderr,
- "Spinning. Please run 'gdb gst-launch %d' to continue debugging, "
- "Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ());
+ "Spinning. Please run 'gdb gst-launch-" GST_API_VERSION " %d' to "
+ "continue debugging, Ctrl-C to quit, or Ctrl-\\ to dump core.\n",
+ (gint) getpid ());
while (spinning)
g_usleep (1000000);
}
struct sigaction action;
memset (&action, 0, sizeof (action));
-#ifdef USE_SIGINFO
- action.sa_sigaction = fault_handler_sigaction;
- action.sa_flags = SA_SIGINFO;
-#else
action.sa_handler = fault_handler_sighandler;
-#endif
sigaction (SIGSEGV, &action, NULL);
sigaction (SIGQUIT, &action, NULL);
}
-#endif /* DISABLE_FAULT_HANDLER */
+#endif /* G_OS_UNIX */
#if 0
typedef struct _GstIndexStats
if (debug != NULL)
g_printerr (_("Additional debug info:\n%s\n"), debug);
- g_error_free (err);
+ g_clear_error (&err);
g_free (debug);
g_free (name);
}
count = gst_tag_list_get_tag_size (list, tag);
for (i = 0; i < count; i++) {
- gchar *str;
+ gchar *str = NULL;
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
- if (!gst_tag_list_get_string_index (list, tag, i, &str))
+ if (!gst_tag_list_get_string_index (list, tag, i, &str)) {
+ g_warning ("Couldn't fetch string for %s tag", tag);
g_assert_not_reached ();
- } else if (gst_tag_get_type (tag) == GST_TYPE_BUFFER) {
- GstBuffer *img;
+ }
+ } else if (gst_tag_get_type (tag) == GST_TYPE_SAMPLE) {
+ GstSample *sample = NULL;
- img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i));
- if (img) {
- gchar *caps_str;
+ if (gst_tag_list_get_sample_index (list, tag, i, &sample)) {
+ GstBuffer *img = gst_sample_get_buffer (sample);
+ GstCaps *caps = gst_sample_get_caps (sample);
- caps_str = g_strdup ("unknown");
- str = g_strdup_printf ("buffer of %" G_GSIZE_FORMAT " bytes, type: %s",
- gst_buffer_get_size (img), caps_str);
- g_free (caps_str);
+ if (img) {
+ if (caps) {
+ gchar *caps_str;
+
+ caps_str = gst_caps_to_string (caps);
+ str = g_strdup_printf ("buffer of %" G_GSIZE_FORMAT " bytes, "
+ "type: %s", gst_buffer_get_size (img), caps_str);
+ g_free (caps_str);
+ } else {
+ str = g_strdup_printf ("buffer of %" G_GSIZE_FORMAT " bytes",
+ gst_buffer_get_size (img));
+ }
+ } else {
+ str = g_strdup ("NULL buffer");
+ }
} else {
- str = g_strdup ("NULL buffer");
+ g_warning ("Couldn't fetch sample for %s tag", tag);
+ g_assert_not_reached ();
}
+ gst_sample_unref (sample);
} else if (gst_tag_get_type (tag) == GST_TYPE_DATE_TIME) {
GstDateTime *dt = NULL;
gst_tag_list_get_date_time_index (list, tag, i, &dt);
- if (gst_date_time_get_hour (dt) < 0) {
- str = g_strdup_printf ("%02u-%02u-%04u", gst_date_time_get_day (dt),
- gst_date_time_get_month (dt), gst_date_time_get_year (dt));
+ if (!gst_date_time_has_time (dt)) {
+ str = gst_date_time_to_iso8601_string (dt);
} else {
gdouble tz_offset = gst_date_time_get_time_zone_offset (dt);
gchar tz_str[32];
g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
}
- if (i == 0) {
- PRINT ("%16s: %s\n", gst_tag_get_nick (tag), str);
- } else {
- PRINT ("%16s: %s\n", "", str);
+ if (str) {
+ PRINT ("%16s: %s\n", i == 0 ? gst_tag_get_nick (tag) : "", str);
+ g_free (str);
}
-
- g_free (str);
}
}
gchar *str;
gint depth = GPOINTER_TO_INT (user_data);
- gst_tag_list_copy_value (&val, tags, tag);
+ if (!gst_tag_list_copy_value (&val, tags, tag))
+ return;
if (G_VALUE_HOLDS_STRING (&val))
str = g_value_dup_string (&val);
GstTocEntry *entry = (GstTocEntry *) data;
const gchar spc[MAX_INDENT + 1] = " ";
guint indent = MIN (GPOINTER_TO_UINT (user_data), MAX_INDENT);
+ const GstTagList *tags;
+ GList *subentries;
gint64 start, stop;
- gst_toc_entry_get_start_stop (entry, &start, &stop);
+ gst_toc_entry_get_start_stop_times (entry, &start, &stop);
PRINT ("%s%s:", &spc[MAX_INDENT - indent],
- gst_toc_entry_type_get_nick (entry->type));
+ gst_toc_entry_type_get_nick (gst_toc_entry_get_entry_type (entry)));
if (GST_CLOCK_TIME_IS_VALID (start)) {
PRINT (" start: %" GST_TIME_FORMAT, GST_TIME_ARGS (start));
}
indent += 2;
/* print tags */
- gst_tag_list_foreach (entry->tags, print_tag_foreach,
- GUINT_TO_POINTER (indent));
+ tags = gst_toc_entry_get_tags (entry);
+ if (tags)
+ gst_tag_list_foreach (tags, print_tag_foreach, GUINT_TO_POINTER (indent));
/* loop over sub-toc entries */
- g_list_foreach (entry->subentries, print_toc_entry,
- GUINT_TO_POINTER (indent));
+ subentries = gst_toc_entry_get_sub_entries (entry);
+ g_list_foreach (subentries, print_toc_entry, GUINT_TO_POINTER (indent));
}
-#ifndef DISABLE_FAULT_HANDLER
-/* we only use sighandler here because the registers are not important */
-static void
-sigint_handler_sighandler (int signum)
-{
- PRINT ("Caught interrupt -- ");
-
- /* 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
- * interrupt handler (no mutex or other blocking stuff) */
- caught_intr = TRUE;
-}
+#ifdef G_OS_UNIX
+static guint signal_watch_hup_id;
+#endif
+#if defined(G_OS_UNIX) || defined(G_OS_WIN32)
+static guint signal_watch_intr_id;
+#if defined(G_OS_WIN32)
+static GstElement *intr_pipeline;
+#endif
+#endif
-/* is called every 250 milliseconds (4 times a second), the interrupt handler
- * will set a flag for us. We react to this by posting a message. */
+#if defined(G_OS_UNIX) || defined(G_OS_WIN32)
+/* As the interrupt handler is dispatched from GMainContext as a GSourceFunc
+ * handler, we can react to this by posting a message. */
static gboolean
-check_intr (GstElement * pipeline)
+intr_handler (gpointer user_data)
{
- if (!caught_intr) {
- return TRUE;
- } else {
- caught_intr = FALSE;
- PRINT ("handling interrupt.\n");
+ GstElement *pipeline = (GstElement *) user_data;
- /* post an application specific message */
- gst_element_post_message (GST_ELEMENT (pipeline),
- gst_message_new_application (GST_OBJECT (pipeline),
- gst_structure_new ("GstLaunchInterrupt",
- "message", G_TYPE_STRING, "Pipeline interrupted", NULL)));
+ PRINT ("handling interrupt.\n");
- /* remove timeout handler */
- return FALSE;
- }
+ /* post an application specific message */
+ gst_element_post_message (GST_ELEMENT (pipeline),
+ gst_message_new_application (GST_OBJECT (pipeline),
+ gst_structure_new ("GstLaunchInterrupt",
+ "message", G_TYPE_STRING, "Pipeline interrupted", NULL)));
+
+ /* remove signal handler */
+ signal_watch_intr_id = 0;
+ return G_SOURCE_REMOVE;
}
-static void
-sigint_setup (void)
+#ifdef G_OS_UNIX
+static gboolean
+hup_handler (gpointer user_data)
{
- struct sigaction action;
+ GstElement *pipeline = (GstElement *) user_data;
- memset (&action, 0, sizeof (action));
- action.sa_handler = sigint_handler_sighandler;
+ if (g_getenv ("GST_DEBUG_DUMP_DOT_DIR") != NULL) {
+ PRINT ("SIGHUP: dumping dot file snapshot ...\n");
+ } else {
+ PRINT ("SIGHUP: not dumping dot file snapshot, GST_DEBUG_DUMP_DOT_DIR "
+ "environment variable not set.\n");
+ }
+
+ /* dump graph on hup */
+ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
+ GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.snapshot");
- sigaction (SIGINT, &action, NULL);
+ return G_SOURCE_CONTINUE;
}
+#endif
-static void
-sigint_restore (void)
+#if defined(G_OS_WIN32) /* G_OS_UNIX */
+static BOOL WINAPI
+w32_intr_handler (DWORD dwCtrlType)
{
- struct sigaction action;
-
- memset (&action, 0, sizeof (action));
- action.sa_handler = SIG_DFL;
-
- sigaction (SIGINT, &action, NULL);
+ intr_handler ((gpointer) intr_pipeline);
+ intr_pipeline = NULL;
+ return TRUE;
}
-#endif /* DISABLE_FAULT_HANDLER */
+#endif /* G_OS_WIN32 */
+#endif /* G_OS_UNIX */
/* returns ELR_ERROR if there was an error
* 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, gboolean do_progress,
+ GstState target_state)
{
-#ifndef DISABLE_FAULT_HANDLER
- gulong timeout_id;
-#endif
GstBus *bus;
GstMessage *message = NULL;
EventLoopResult res = ELR_NO_ERROR;
- gboolean buffering = FALSE;
+ gboolean buffering = FALSE, in_progress = FALSE;
+ gboolean prerolled = target_state != GST_STATE_PAUSED;
bus = gst_element_get_bus (GST_ELEMENT (pipeline));
-#ifndef DISABLE_FAULT_HANDLER
- timeout_id = g_timeout_add (250, (GSourceFunc) check_intr, pipeline);
+#ifdef G_OS_UNIX
+ signal_watch_intr_id =
+ g_unix_signal_add (SIGINT, (GSourceFunc) intr_handler, pipeline);
+ signal_watch_hup_id =
+ g_unix_signal_add (SIGHUP, (GSourceFunc) hup_handler, pipeline);
+#elif defined(G_OS_WIN32)
+ intr_pipeline = NULL;
+ if (SetConsoleCtrlHandler (w32_intr_handler, TRUE))
+ intr_pipeline = pipeline;
#endif
while (TRUE) {
break;
case GST_MESSAGE_TOC:
if (toc) {
- GstToc *toc_msg;
+ GstToc *toc;
+ GList *entries;
gboolean updated;
if (GST_IS_ELEMENT (GST_MESSAGE_SRC (message))) {
PRINT (_("FOUND TOC\n"));
}
- gst_message_parse_toc (message, &toc_msg, &updated);
+ gst_message_parse_toc (message, &toc, &updated);
/* recursively loop over toc entries */
- g_list_foreach (toc_msg->entries, print_toc_entry,
- GUINT_TO_POINTER (0));
- gst_toc_unref (toc_msg);
+ entries = gst_toc_get_entries (toc);
+ g_list_foreach (entries, print_toc_entry, GUINT_TO_POINTER (0));
+ gst_toc_unref (toc);
}
break;
case GST_MESSAGE_INFO:{
if (debug) {
PRINT (_("INFO:\n%s\n"), debug);
}
- g_error_free (gerror);
+ g_clear_error (&gerror);
g_free (debug);
g_free (name);
break;
if (debug) {
PRINT (_("Additional debug info:\n%s\n"), debug);
}
- g_error_free (gerror);
+ g_clear_error (&gerror);
g_free (debug);
g_free (name);
break;
if (GST_MESSAGE_SRC (message) != GST_OBJECT_CAST (pipeline))
break;
- /* ignore when we are buffering since then we mess with the states
- * ourselves. */
- if (buffering) {
- PRINT (_("Prerolled, waiting for buffering to finish...\n"));
- break;
- }
-
gst_message_parse_state_changed (message, &old, &new, &pending);
/* if we reached the final target state, exit */
- if (target_state == GST_STATE_PAUSED && new == target_state)
+ if (target_state == GST_STATE_PAUSED && new == target_state) {
+ prerolled = TRUE;
+ /* ignore when we are buffering since then we mess with the states
+ * ourselves. */
+ if (buffering) {
+ PRINT (_("Prerolled, waiting for buffering to finish...\n"));
+ break;
+ }
+ if (in_progress) {
+ PRINT (_("Prerolled, waiting for progress to finish...\n"));
+ break;
+ }
goto exit;
-
+ }
/* else not an interesting message */
break;
}
if (target_state == GST_STATE_PLAYING) {
PRINT (_("Done buffering, setting pipeline to PLAYING ...\n"));
gst_element_set_state (pipeline, GST_STATE_PLAYING);
- } else
+ } else if (prerolled && !in_progress)
goto exit;
} else {
/* buffering busy */
- if (buffering == FALSE && target_state == GST_STATE_PLAYING) {
+ if (!buffering && target_state == GST_STATE_PLAYING) {
/* we were not buffering but PLAYING, PAUSE the pipeline. */
PRINT (_("Buffering, setting pipeline to PAUSED ...\n"));
gst_element_set_state (pipeline, GST_STATE_PAUSED);
}
break;
}
+ case GST_MESSAGE_PROGRESS:
+ {
+ GstProgressType type;
+ gchar *code, *text;
+
+ gst_message_parse_progress (message, &type, &code, &text);
+
+ switch (type) {
+ case GST_PROGRESS_TYPE_START:
+ case GST_PROGRESS_TYPE_CONTINUE:
+ if (do_progress) {
+ in_progress = TRUE;
+ blocking = TRUE;
+ }
+ break;
+ case GST_PROGRESS_TYPE_COMPLETE:
+ case GST_PROGRESS_TYPE_CANCELED:
+ case GST_PROGRESS_TYPE_ERROR:
+ in_progress = FALSE;
+ break;
+ default:
+ break;
+ }
+ PRINT (_("Progress: (%s) %s\n"), code, text);
+ g_free (code);
+ g_free (text);
+
+ if (do_progress && !in_progress && !buffering && prerolled)
+ goto exit;
+ break;
+ }
case GST_MESSAGE_ELEMENT:{
if (gst_is_missing_plugin_message (message)) {
const gchar *desc;
}
break;
}
+ case GST_MESSAGE_HAVE_CONTEXT:{
+ GstContext *context;
+ const gchar *context_type;
+ gchar *context_str;
+
+ gst_message_parse_have_context (message, &context);
+
+ context_type = gst_context_get_context_type (context);
+ context_str =
+ gst_structure_to_string (gst_context_get_structure (context));
+ PRINT (_("Got context from element '%s': %s=%s\n"),
+ GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)), context_type,
+ context_str);
+ g_free (context_str);
+ gst_context_unref (context);
+ break;
+ }
+ case GST_MESSAGE_PROPERTY_NOTIFY:{
+ const GValue *val;
+ const gchar *name;
+ GstObject *obj;
+ gchar *val_str = NULL;
+ gchar **ex_prop, *obj_name;
+
+ if (quiet)
+ break;
+
+ gst_message_parse_property_notify (message, &obj, &name, &val);
+
+ /* Let's not print anything for excluded properties... */
+ ex_prop = exclude_args;
+ while (ex_prop != NULL && *ex_prop != NULL) {
+ if (strcmp (name, *ex_prop) == 0)
+ break;
+ ex_prop++;
+ }
+ if (ex_prop != NULL && *ex_prop != NULL)
+ break;
+
+ obj_name = gst_object_get_path_string (GST_OBJECT (obj));
+ if (val != NULL) {
+ if (G_VALUE_HOLDS_STRING (val))
+ val_str = g_value_dup_string (val);
+ else if (G_VALUE_TYPE (val) == GST_TYPE_CAPS)
+ val_str = gst_caps_to_string (g_value_get_boxed (val));
+ else if (G_VALUE_TYPE (val) == GST_TYPE_TAG_LIST)
+ val_str = gst_tag_list_to_string (g_value_get_boxed (val));
+ else if (G_VALUE_TYPE (val) == GST_TYPE_STRUCTURE)
+ val_str = gst_structure_to_string (g_value_get_boxed (val));
+ else
+ val_str = gst_value_serialize (val);
+ } else {
+ val_str = g_strdup ("(no value)");
+ }
+
+ g_print ("%s: %s = %s\n", obj_name, name, val_str);
+ g_free (obj_name);
+ g_free (val_str);
+ break;
+ }
default:
/* just be quiet by default */
break;
if (message)
gst_message_unref (message);
gst_object_unref (bus);
-#ifndef DISABLE_FAULT_HANDLER
- g_source_remove (timeout_id);
+#ifdef G_OS_UNIX
+ if (signal_watch_intr_id > 0)
+ g_source_remove (signal_watch_intr_id);
+ if (signal_watch_hup_id > 0)
+ g_source_remove (signal_watch_hup_id);
+#elif defined(G_OS_WIN32)
+ intr_pipeline = NULL;
+ SetConsoleCtrlHandler (w32_intr_handler, FALSE);
#endif
return res;
}
g_free (state_transition_name);
}
+ break;
default:
break;
}
gboolean check_index = FALSE;
#endif
gchar *savefile = NULL;
- gchar *exclude_args = NULL;
#ifndef GST_DISABLE_OPTION_PARSING
GOptionEntry options[] = {
{"tags", 't', 0, G_OPTION_ARG_NONE, &tags,
N_("Do not print any progress information"), NULL},
{"messages", 'm', 0, G_OPTION_ARG_NONE, &messages,
N_("Output messages"), NULL},
- {"exclude", 'X', 0, G_OPTION_ARG_NONE, &exclude_args,
- N_("Do not output status information of TYPE"), N_("TYPE1,TYPE2,...")},
+ {"exclude", 'X', 0, G_OPTION_ARG_STRING_ARRAY, &exclude_args,
+ N_("Do not output status information for the specified property "
+ "if verbose output is enabled (can be used multiple times)"),
+ N_("PROPERTY-NAME")},
{"no-fault", 'f', 0, G_OPTION_ARG_NONE, &no_fault,
N_("Do not install a fault handler"), NULL},
{"eos-on-shutdown", 'e', 0, G_OPTION_ARG_NONE, &eos_on_shutdown,
#endif
gchar **argvn;
GError *error = NULL;
+ gulong deep_notify_id = 0;
gint res = 0;
free (malloc (8)); /* -lefence */
+ setlocale (LC_ALL, "");
+
#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
- gst_tools_set_prgname ("gst-launch");
+ g_set_prgname ("gst-launch-" GST_API_VERSION);
+ /* Ensure XInitThreads() is called if/when needed */
+ g_setenv ("GST_GL_XINITTHREADS", "1", TRUE);
#ifndef GST_DISABLE_OPTION_PARSING
ctx = g_option_context_new ("PIPELINE-DESCRIPTION");
g_printerr ("Error initializing: %s\n", GST_STR_NULL (err->message));
else
g_printerr ("Error initializing: Unknown error!\n");
+ g_clear_error (&err);
+ g_option_context_free (ctx);
exit (1);
}
g_option_context_free (ctx);
gst_init (&argc, &argv);
#endif
- gst_tools_print_version ("gst-launch");
+ gst_tools_print_version ();
-#ifndef DISABLE_FAULT_HANDLER
+#ifdef G_OS_UNIX
if (!no_fault)
fault_setup ();
-
- sigint_setup ();
#endif
/* make a null-terminated version of argv */
if (error) {
g_printerr (_("ERROR: pipeline could not be constructed: %s.\n"),
GST_STR_NULL (error->message));
- g_error_free (error);
+ g_clear_error (&error);
} else {
g_printerr (_("ERROR: pipeline could not be constructed.\n"));
}
} else if (error) {
g_printerr (_("WARNING: erroneous pipeline: %s\n"),
GST_STR_NULL (error->message));
- g_error_free (error);
+ g_clear_error (&error);
return 1;
}
- if (verbose) {
- gchar **exclude_list =
- exclude_args ? g_strsplit (exclude_args, ",", 0) : NULL;
- g_signal_connect (pipeline, "deep-notify",
- G_CALLBACK (gst_object_default_deep_notify), exclude_list);
- }
-
if (!savefile) {
GstState state, pending;
GstStateChangeReturn ret;
gst_bin_add (GST_BIN (real_pipeline), pipeline);
pipeline = real_pipeline;
}
+ if (verbose) {
+ deep_notify_id =
+ gst_element_add_property_deep_notify_watch (pipeline, NULL, TRUE);
+ }
#if 0
if (check_index) {
/* gst_index_new() creates a null-index, it does not store anything, but
case GST_STATE_CHANGE_FAILURE:
g_printerr (_("ERROR: Pipeline doesn't want to pause.\n"));
res = -1;
- event_loop (pipeline, FALSE, GST_STATE_VOID_PENDING);
+ event_loop (pipeline, FALSE, FALSE, GST_STATE_VOID_PENDING);
goto end;
case GST_STATE_CHANGE_NO_PREROLL:
PRINT (_("Pipeline is live and does not need PREROLL ...\n"));
break;
case GST_STATE_CHANGE_ASYNC:
PRINT (_("Pipeline is PREROLLING ...\n"));
- caught_error = event_loop (pipeline, TRUE, GST_STATE_PAUSED);
+ caught_error = event_loop (pipeline, TRUE, TRUE, GST_STATE_PAUSED);
if (caught_error) {
g_printerr (_("ERROR: pipeline doesn't want to preroll.\n"));
+ res = caught_error;
goto end;
}
state = GST_STATE_PAUSED;
break;
}
- caught_error = event_loop (pipeline, FALSE, GST_STATE_PLAYING);
+ caught_error = event_loop (pipeline, FALSE, TRUE, GST_STATE_PLAYING);
if (caught_error) {
g_printerr (_("ERROR: pipeline doesn't want to preroll.\n"));
+ res = caught_error;
} else {
GstClockTime tfthen, tfnow;
GstClockTimeDiff diff;
}
tfthen = gst_util_get_timestamp ();
- caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING);
+ caught_error = event_loop (pipeline, TRUE, FALSE, GST_STATE_PLAYING);
+ res = caught_error;
if (eos_on_shutdown && caught_error != ELR_NO_ERROR) {
gboolean ignore_errors;
PRINT (_("Waiting for EOS...\n"));
while (TRUE) {
- caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING);
+ caught_error = event_loop (pipeline, TRUE, FALSE, GST_STATE_PLAYING);
if (caught_error == ELR_NO_ERROR) {
/* we got EOS */
} else if (caught_error == ELR_INTERRUPT) {
PRINT (_
("Interrupt while waiting for EOS - stopping pipeline...\n"));
+ res = caught_error;
break;
} else if (caught_error == ELR_ERROR) {
if (!ignore_errors) {
PRINT (_("An error happened while waiting for EOS\n"));
+ res = caught_error;
break;
}
}
diff = GST_CLOCK_DIFF (tfthen, tfnow);
- PRINT (_("Execution ended after %" G_GUINT64_FORMAT " ns.\n"), diff);
+ PRINT (_("Execution ended after %" GST_TIME_FORMAT "\n"),
+ GST_TIME_ARGS (diff));
}
PRINT (_("Setting pipeline to PAUSED ...\n"));
/* iterate mainloop to process pending stuff */
while (g_main_context_iteration (NULL, FALSE));
+ /* No need to see all those pad caps going to NULL etc., it's just noise */
+ if (deep_notify_id != 0)
+ g_signal_handler_disconnect (pipeline, deep_notify_id);
+
PRINT (_("Setting pipeline to READY ...\n"));
gst_element_set_state (pipeline, GST_STATE_READY);
gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);