Merge commit '0eaa25cbf5c0e4bf86545fb67c181a0ecd2f19c7' into 0.11
[platform/upstream/gstreamer.git] / tools / gst-launch.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *               2000 Wim Taymans <wtay@chello.be>
4  *               2004 Thomas Vander Stichele <thomas@apestaart.org>
5  *
6  * gst-launch.c: tool to launch GStreamer pipelines from the command line
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 /* FIXME: hack alert */
29 #ifdef HAVE_WIN32
30 #define DISABLE_FAULT_HANDLER
31 #endif
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <signal.h>
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 #ifndef DISABLE_FAULT_HANDLER
40 #include <sys/wait.h>
41 #endif
42 #include <locale.h>             /* for LC_ALL */
43 #include "tools.h"
44
45 /* FIXME: This is just a temporary hack.  We should have a better
46  * check for siginfo handling. */
47 #ifdef SA_SIGINFO
48 #define USE_SIGINFO
49 #endif
50
51 extern volatile gboolean glib_on_error_halt;
52
53 #ifndef DISABLE_FAULT_HANDLER
54 static void fault_restore (void);
55 static void fault_spin (void);
56 static void sigint_restore (void);
57 static gboolean caught_intr = FALSE;
58 #endif
59
60 /* event_loop return codes */
61 typedef enum _EventLoopResult
62 {
63   ELR_NO_ERROR = 0,
64   ELR_ERROR,
65   ELR_INTERRUPT
66 } EventLoopResult;
67
68 static GstElement *pipeline;
69 static EventLoopResult caught_error = ELR_NO_ERROR;
70 static gboolean quiet = FALSE;
71 static gboolean tags = FALSE;
72 static gboolean messages = FALSE;
73 static gboolean is_live = FALSE;
74 static gboolean waiting_eos = FALSE;
75
76 /* convenience macro so we don't have to litter the code with if(!quiet) */
77 #define PRINT if(!quiet)g_print
78
79 #ifndef DISABLE_FAULT_HANDLER
80 #ifndef USE_SIGINFO
81 static void
82 fault_handler_sighandler (int signum)
83 {
84   fault_restore ();
85
86   /* printf is used instead of g_print(), since it's less likely to
87    * deadlock */
88   switch (signum) {
89     case SIGSEGV:
90       fprintf (stderr, "Caught SIGSEGV\n");
91       break;
92     case SIGQUIT:
93       if (!quiet)
94         printf ("Caught SIGQUIT\n");
95       break;
96     default:
97       fprintf (stderr, "signo:  %d\n", signum);
98       break;
99   }
100
101   fault_spin ();
102 }
103
104 #else /* USE_SIGINFO */
105
106 static void
107 fault_handler_sigaction (int signum, siginfo_t * si, void *misc)
108 {
109   fault_restore ();
110
111   /* printf is used instead of g_print(), since it's less likely to
112    * deadlock */
113   switch (si->si_signo) {
114     case SIGSEGV:
115       fprintf (stderr, "Caught SIGSEGV accessing address %p\n", si->si_addr);
116       break;
117     case SIGQUIT:
118       if (!quiet)
119         printf ("Caught SIGQUIT\n");
120       break;
121     default:
122       fprintf (stderr, "signo:  %d\n", si->si_signo);
123       fprintf (stderr, "errno:  %d\n", si->si_errno);
124       fprintf (stderr, "code:   %d\n", si->si_code);
125       break;
126   }
127
128   fault_spin ();
129 }
130 #endif /* USE_SIGINFO */
131
132 static void
133 fault_spin (void)
134 {
135   int spinning = TRUE;
136
137   glib_on_error_halt = FALSE;
138   g_on_error_stack_trace ("gst-launch");
139
140   wait (NULL);
141
142   /* FIXME how do we know if we were run by libtool? */
143   fprintf (stderr,
144       "Spinning.  Please run 'gdb gst-launch %d' to continue debugging, "
145       "Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ());
146   while (spinning)
147     g_usleep (1000000);
148 }
149
150 static void
151 fault_restore (void)
152 {
153   struct sigaction action;
154
155   memset (&action, 0, sizeof (action));
156   action.sa_handler = SIG_DFL;
157
158   sigaction (SIGSEGV, &action, NULL);
159   sigaction (SIGQUIT, &action, NULL);
160 }
161
162 static void
163 fault_setup (void)
164 {
165   struct sigaction action;
166
167   memset (&action, 0, sizeof (action));
168 #ifdef USE_SIGINFO
169   action.sa_sigaction = fault_handler_sigaction;
170   action.sa_flags = SA_SIGINFO;
171 #else
172   action.sa_handler = fault_handler_sighandler;
173 #endif
174
175   sigaction (SIGSEGV, &action, NULL);
176   sigaction (SIGQUIT, &action, NULL);
177 }
178 #endif /* DISABLE_FAULT_HANDLER */
179
180 static void
181 print_error_message (GstMessage * msg)
182 {
183   GError *err = NULL;
184   gchar *name, *debug = NULL;
185
186   name = gst_object_get_path_string (msg->src);
187   gst_message_parse_error (msg, &err, &debug);
188
189   g_printerr (_("ERROR: from element %s: %s\n"), name, err->message);
190   if (debug != NULL)
191     g_printerr (_("Additional debug info:\n%s\n"), debug);
192
193   g_error_free (err);
194   g_free (debug);
195   g_free (name);
196 }
197
198 static void
199 print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
200 {
201   gint i, count;
202
203   count = gst_tag_list_get_tag_size (list, tag);
204
205   for (i = 0; i < count; i++) {
206     gchar *str;
207
208     if (gst_tag_get_type (tag) == G_TYPE_STRING) {
209       if (!gst_tag_list_get_string_index (list, tag, i, &str))
210         g_assert_not_reached ();
211     } else if (gst_tag_get_type (tag) == GST_TYPE_BUFFER) {
212       GstBuffer *img;
213
214       img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i));
215       if (img) {
216         gchar *caps_str;
217
218         caps_str = GST_BUFFER_CAPS (img) ?
219             gst_caps_to_string (GST_BUFFER_CAPS (img)) : g_strdup ("unknown");
220         str = g_strdup_printf ("buffer of %u bytes, type: %s",
221             GST_BUFFER_SIZE (img), caps_str);
222         g_free (caps_str);
223       } else {
224         str = g_strdup ("NULL buffer");
225       }
226     } else {
227       str =
228           g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
229     }
230
231     if (i == 0) {
232       PRINT ("%16s: %s\n", gst_tag_get_nick (tag), str);
233     } else {
234       PRINT ("%16s: %s\n", "", str);
235     }
236
237     g_free (str);
238   }
239 }
240
241 #ifndef DISABLE_FAULT_HANDLER
242 /* we only use sighandler here because the registers are not important */
243 static void
244 sigint_handler_sighandler (int signum)
245 {
246   PRINT ("Caught interrupt -- ");
247
248   /* If we were waiting for an EOS, we still want to catch
249    * the next signal to shutdown properly (and the following one
250    * will quit the program). */
251   if (waiting_eos) {
252     waiting_eos = FALSE;
253   } else {
254     sigint_restore ();
255   }
256   /* we set a flag that is checked by the mainloop, we cannot do much in the
257    * interrupt handler (no mutex or other blocking stuff) */
258   caught_intr = TRUE;
259 }
260
261 /* is called every 250 milliseconds (4 times a second), the interrupt handler
262  * will set a flag for us. We react to this by posting a message. */
263 static gboolean
264 check_intr (GstElement * pipeline)
265 {
266   if (!caught_intr) {
267     return TRUE;
268   } else {
269     caught_intr = FALSE;
270     PRINT ("handling interrupt.\n");
271
272     /* post an application specific message */
273     gst_element_post_message (GST_ELEMENT (pipeline),
274         gst_message_new_application (GST_OBJECT (pipeline),
275             gst_structure_new ("GstLaunchInterrupt",
276                 "message", G_TYPE_STRING, "Pipeline interrupted", NULL)));
277
278     /* remove timeout handler */
279     return FALSE;
280   }
281 }
282
283 static void
284 sigint_setup (void)
285 {
286   struct sigaction action;
287
288   memset (&action, 0, sizeof (action));
289   action.sa_handler = sigint_handler_sighandler;
290
291   sigaction (SIGINT, &action, NULL);
292 }
293
294 static void
295 sigint_restore (void)
296 {
297   struct sigaction action;
298
299   memset (&action, 0, sizeof (action));
300   action.sa_handler = SIG_DFL;
301
302   sigaction (SIGINT, &action, NULL);
303 }
304
305 /* FIXME 0.11: remove SIGUSR handling (also from man page) */
306 static void
307 play_handler (int signum)
308 {
309   switch (signum) {
310     case SIGUSR1:
311       PRINT ("Caught SIGUSR1 - Play request.\n");
312       gst_element_set_state (pipeline, GST_STATE_PLAYING);
313       break;
314     case SIGUSR2:
315       PRINT ("Caught SIGUSR2 - Stop request.\n");
316       gst_element_set_state (pipeline, GST_STATE_NULL);
317       break;
318   }
319 }
320
321 static void
322 play_signal_setup (void)
323 {
324   struct sigaction action;
325
326   memset (&action, 0, sizeof (action));
327   action.sa_handler = play_handler;
328   sigaction (SIGUSR1, &action, NULL);
329   sigaction (SIGUSR2, &action, NULL);
330 }
331 #endif /* DISABLE_FAULT_HANDLER */
332
333 /* returns ELR_ERROR if there was an error
334  * or ELR_INTERRUPT if we caught a keyboard interrupt
335  * or ELR_NO_ERROR otherwise. */
336 static EventLoopResult
337 event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
338 {
339 #ifndef DISABLE_FAULT_HANDLER
340   gulong timeout_id;
341 #endif
342   GstBus *bus;
343   GstMessage *message = NULL;
344   EventLoopResult res = ELR_NO_ERROR;
345   gboolean buffering = FALSE;
346
347   bus = gst_element_get_bus (GST_ELEMENT (pipeline));
348
349 #ifndef DISABLE_FAULT_HANDLER
350   timeout_id = g_timeout_add (250, (GSourceFunc) check_intr, pipeline);
351 #endif
352
353   while (TRUE) {
354     message = gst_bus_poll (bus, GST_MESSAGE_ANY, blocking ? -1 : 0);
355
356     /* if the poll timed out, only when !blocking */
357     if (message == NULL)
358       goto exit;
359
360     /* check if we need to dump messages to the console */
361     if (messages) {
362       GstObject *src_obj;
363       const GstStructure *s;
364       guint32 seqnum;
365
366       seqnum = gst_message_get_seqnum (message);
367
368       s = gst_message_get_structure (message);
369
370       src_obj = GST_MESSAGE_SRC (message);
371
372       if (GST_IS_ELEMENT (src_obj)) {
373         PRINT (_("Got message #%u from element \"%s\" (%s): "),
374             (guint) seqnum, GST_ELEMENT_NAME (src_obj),
375             GST_MESSAGE_TYPE_NAME (message));
376       } else if (GST_IS_PAD (src_obj)) {
377         PRINT (_("Got message #%u from pad \"%s:%s\" (%s): "),
378             (guint) seqnum, GST_DEBUG_PAD_NAME (src_obj),
379             GST_MESSAGE_TYPE_NAME (message));
380       } else if (GST_IS_OBJECT (src_obj)) {
381         PRINT (_("Got message #%u from object \"%s\" (%s): "),
382             (guint) seqnum, GST_OBJECT_NAME (src_obj),
383             GST_MESSAGE_TYPE_NAME (message));
384       } else {
385         PRINT (_("Got message #%u (%s): "), (guint) seqnum,
386             GST_MESSAGE_TYPE_NAME (message));
387       }
388
389       if (s) {
390         gchar *sstr;
391
392         sstr = gst_structure_to_string (s);
393         PRINT ("%s\n", sstr);
394         g_free (sstr);
395       } else {
396         PRINT ("no message details\n");
397       }
398     }
399
400     switch (GST_MESSAGE_TYPE (message)) {
401       case GST_MESSAGE_NEW_CLOCK:
402       {
403         GstClock *clock;
404
405         gst_message_parse_new_clock (message, &clock);
406
407         PRINT ("New clock: %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
408         break;
409       }
410       case GST_MESSAGE_CLOCK_LOST:
411         PRINT ("Clock lost, selecting a new one\n");
412         gst_element_set_state (pipeline, GST_STATE_PAUSED);
413         gst_element_set_state (pipeline, GST_STATE_PLAYING);
414         break;
415       case GST_MESSAGE_EOS:{
416         waiting_eos = FALSE;
417         PRINT (_("Got EOS from element \"%s\".\n"),
418             GST_MESSAGE_SRC_NAME (message));
419         goto exit;
420       }
421       case GST_MESSAGE_TAG:
422         if (tags) {
423           GstTagList *tags;
424
425           if (GST_IS_ELEMENT (GST_MESSAGE_SRC (message))) {
426             PRINT (_("FOUND TAG      : found by element \"%s\".\n"),
427                 GST_MESSAGE_SRC_NAME (message));
428           } else if (GST_IS_PAD (GST_MESSAGE_SRC (message))) {
429             PRINT (_("FOUND TAG      : found by pad \"%s:%s\".\n"),
430                 GST_DEBUG_PAD_NAME (GST_MESSAGE_SRC (message)));
431           } else if (GST_IS_OBJECT (GST_MESSAGE_SRC (message))) {
432             PRINT (_("FOUND TAG      : found by object \"%s\".\n"),
433                 GST_MESSAGE_SRC_NAME (message));
434           } else {
435             PRINT (_("FOUND TAG\n"));
436           }
437
438           gst_message_parse_tag (message, &tags);
439           gst_tag_list_foreach (tags, print_tag, NULL);
440           gst_tag_list_free (tags);
441         }
442         break;
443       case GST_MESSAGE_INFO:{
444         GError *gerror;
445         gchar *debug;
446         gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));
447
448         gst_message_parse_info (message, &gerror, &debug);
449         if (debug) {
450           PRINT (_("INFO:\n%s\n"), debug);
451         }
452         g_error_free (gerror);
453         g_free (debug);
454         g_free (name);
455         break;
456       }
457       case GST_MESSAGE_WARNING:{
458         GError *gerror;
459         gchar *debug;
460         gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));
461
462         /* dump graph on warning */
463         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
464             GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.warning");
465
466         gst_message_parse_warning (message, &gerror, &debug);
467         PRINT (_("WARNING: from element %s: %s\n"), name, gerror->message);
468         if (debug) {
469           PRINT (_("Additional debug info:\n%s\n"), debug);
470         }
471         g_error_free (gerror);
472         g_free (debug);
473         g_free (name);
474         break;
475       }
476       case GST_MESSAGE_ERROR:{
477         /* dump graph on error */
478         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
479             GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.error");
480
481         print_error_message (message);
482
483         /* we have an error */
484         res = ELR_ERROR;
485         goto exit;
486       }
487       case GST_MESSAGE_STATE_CHANGED:{
488         GstState old, new, pending;
489
490         /* we only care about pipeline state change messages */
491         if (GST_MESSAGE_SRC (message) != GST_OBJECT_CAST (pipeline))
492           break;
493
494         /* ignore when we are buffering since then we mess with the states
495          * ourselves. */
496         if (buffering) {
497           PRINT (_("Prerolled, waiting for buffering to finish...\n"));
498           break;
499         }
500
501         gst_message_parse_state_changed (message, &old, &new, &pending);
502
503         /* if we reached the final target state, exit */
504         if (target_state == GST_STATE_PAUSED && new == target_state)
505           goto exit;
506
507         /* else not an interesting message */
508         break;
509       }
510       case GST_MESSAGE_BUFFERING:{
511         gint percent;
512
513         gst_message_parse_buffering (message, &percent);
514         PRINT ("%s %d%%  \r", _("buffering..."), percent);
515
516         /* no state management needed for live pipelines */
517         if (is_live)
518           break;
519
520         if (percent == 100) {
521           /* a 100% message means buffering is done */
522           buffering = FALSE;
523           /* if the desired state is playing, go back */
524           if (target_state == GST_STATE_PLAYING) {
525             PRINT (_("Done buffering, setting pipeline to PLAYING ...\n"));
526             gst_element_set_state (pipeline, GST_STATE_PLAYING);
527           } else
528             goto exit;
529         } else {
530           /* buffering busy */
531           if (buffering == FALSE && target_state == GST_STATE_PLAYING) {
532             /* we were not buffering but PLAYING, PAUSE  the pipeline. */
533             PRINT (_("Buffering, setting pipeline to PAUSED ...\n"));
534             gst_element_set_state (pipeline, GST_STATE_PAUSED);
535           }
536           buffering = TRUE;
537         }
538         break;
539       }
540       case GST_MESSAGE_LATENCY:
541       {
542         PRINT (_("Redistribute latency...\n"));
543         gst_bin_recalculate_latency (GST_BIN (pipeline));
544         break;
545       }
546       case GST_MESSAGE_REQUEST_STATE:
547       {
548         GstState state;
549         gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));
550
551         gst_message_parse_request_state (message, &state);
552
553         PRINT (_("Setting state to %s as requested by %s...\n"),
554             gst_element_state_get_name (state), name);
555
556         gst_element_set_state (pipeline, state);
557
558         g_free (name);
559         break;
560       }
561       case GST_MESSAGE_APPLICATION:{
562         const GstStructure *s;
563
564         s = gst_message_get_structure (message);
565
566         if (gst_structure_has_name (s, "GstLaunchInterrupt")) {
567           /* this application message is posted when we caught an interrupt and
568            * we need to stop the pipeline. */
569           PRINT (_("Interrupt: Stopping pipeline ...\n"));
570           res = ELR_INTERRUPT;
571           goto exit;
572         }
573       }
574       default:
575         /* just be quiet by default */
576         break;
577     }
578     if (message)
579       gst_message_unref (message);
580   }
581   g_assert_not_reached ();
582
583 exit:
584   {
585     if (message)
586       gst_message_unref (message);
587     gst_object_unref (bus);
588 #ifndef DISABLE_FAULT_HANDLER
589     g_source_remove (timeout_id);
590 #endif
591     return res;
592   }
593 }
594
595 static GstBusSyncReply
596 bus_sync_handler (GstBus * bus, GstMessage * message, gpointer data)
597 {
598   GstElement *pipeline = (GstElement *) data;
599
600   switch (GST_MESSAGE_TYPE (message)) {
601     case GST_MESSAGE_STATE_CHANGED:
602       /* we only care about pipeline state change messages */
603       if (GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (pipeline)) {
604         GstState old, new, pending;
605         gchar *state_transition_name;
606
607         gst_message_parse_state_changed (message, &old, &new, &pending);
608
609         state_transition_name = g_strdup_printf ("%s_%s",
610             gst_element_state_get_name (old), gst_element_state_get_name (new));
611
612         /* dump graph for (some) pipeline state changes */
613         {
614           gchar *dump_name = g_strconcat ("gst-launch.", state_transition_name,
615               NULL);
616           GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
617               GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
618           g_free (dump_name);
619         }
620
621         /* place a marker into e.g. strace logs */
622         {
623           gchar *access_name = g_strconcat (g_get_tmp_dir (), G_DIR_SEPARATOR_S,
624               "gst-launch", G_DIR_SEPARATOR_S, state_transition_name, NULL);
625           g_file_test (access_name, G_FILE_TEST_EXISTS);
626           g_free (access_name);
627         }
628
629         g_free (state_transition_name);
630       }
631     default:
632       break;
633   }
634   return GST_BUS_PASS;
635 }
636
637 int
638 main (int argc, char *argv[])
639 {
640   /* options */
641   gboolean verbose = FALSE;
642   gboolean no_fault = FALSE;
643   gboolean no_sigusr_handler = FALSE;
644   gboolean trace = FALSE;
645   gboolean eos_on_shutdown = FALSE;
646   gchar *savefile = NULL;
647   gchar *exclude_args = NULL;
648 #ifndef GST_DISABLE_OPTION_PARSING
649   GOptionEntry options[] = {
650     {"tags", 't', 0, G_OPTION_ARG_NONE, &tags,
651         N_("Output tags (also known as metadata)"), NULL},
652     {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
653         N_("Output status information and property notifications"), NULL},
654     {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet,
655         N_("Do not print any progress information"), NULL},
656     {"messages", 'm', 0, G_OPTION_ARG_NONE, &messages,
657         N_("Output messages"), NULL},
658     {"exclude", 'X', 0, G_OPTION_ARG_NONE, &exclude_args,
659         N_("Do not output status information of TYPE"), N_("TYPE1,TYPE2,...")},
660     {"no-fault", 'f', 0, G_OPTION_ARG_NONE, &no_fault,
661         N_("Do not install a fault handler"), NULL},
662     {"no-sigusr-handler", '\0', 0, G_OPTION_ARG_NONE, &no_sigusr_handler,
663         N_("Do not install signal handlers for SIGUSR1 and SIGUSR2"), NULL},
664     {"trace", 'T', 0, G_OPTION_ARG_NONE, &trace,
665         N_("Print alloc trace (if enabled at compile time)"), NULL},
666     {"eos-on-shutdown", 'e', 0, G_OPTION_ARG_NONE, &eos_on_shutdown,
667         N_("Force EOS on sources before shutting the pipeline down"), NULL},
668     GST_TOOLS_GOPTION_VERSION,
669     {NULL}
670   };
671   GOptionContext *ctx;
672   GError *err = NULL;
673 #endif
674   gchar **argvn;
675   GError *error = NULL;
676   gint res = 0;
677
678   free (malloc (8));            /* -lefence */
679
680 #ifdef ENABLE_NLS
681   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
682   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
683   textdomain (GETTEXT_PACKAGE);
684 #endif
685
686   g_thread_init (NULL);
687
688   gst_tools_set_prgname ("gst-launch");
689
690 #ifndef GST_DISABLE_OPTION_PARSING
691   ctx = g_option_context_new ("PIPELINE-DESCRIPTION");
692   g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
693   g_option_context_add_group (ctx, gst_init_get_option_group ());
694   if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
695     if (err)
696       g_printerr ("Error initializing: %s\n", GST_STR_NULL (err->message));
697     else
698       g_printerr ("Error initializing: Unknown error!\n");
699     exit (1);
700   }
701   g_option_context_free (ctx);
702 #else
703   gst_init (&argc, &argv);
704 #endif
705
706   gst_tools_print_version ("gst-launch");
707
708 #ifndef DISABLE_FAULT_HANDLER
709   if (!no_fault)
710     fault_setup ();
711
712   sigint_setup ();
713
714   if (!no_sigusr_handler)
715     play_signal_setup ();
716 #endif
717
718   if (trace) {
719     if (!gst_alloc_trace_available ()) {
720       g_warning ("Trace not available (recompile with trace enabled).");
721     }
722     gst_alloc_trace_set_flags_all (GST_ALLOC_TRACE_LIVE |
723         GST_ALLOC_TRACE_MEM_LIVE);
724     gst_alloc_trace_print_live ();
725   }
726
727   /* make a null-terminated version of argv */
728   argvn = g_new0 (char *, argc);
729   memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1));
730   {
731     pipeline =
732         (GstElement *) gst_parse_launchv ((const gchar **) argvn, &error);
733   }
734   g_free (argvn);
735
736   if (!pipeline) {
737     if (error) {
738       g_printerr (_("ERROR: pipeline could not be constructed: %s.\n"),
739           GST_STR_NULL (error->message));
740       g_error_free (error);
741     } else {
742       g_printerr (_("ERROR: pipeline could not be constructed.\n"));
743     }
744     return 1;
745   } else if (error) {
746     g_printerr (_("WARNING: erroneous pipeline: %s\n"),
747         GST_STR_NULL (error->message));
748     g_error_free (error);
749     return 1;
750   }
751
752   if (verbose) {
753     gchar **exclude_list =
754         exclude_args ? g_strsplit (exclude_args, ",", 0) : NULL;
755     g_signal_connect (pipeline, "deep-notify",
756         G_CALLBACK (gst_object_default_deep_notify), exclude_list);
757   }
758
759   if (!savefile) {
760     GstState state, pending;
761     GstStateChangeReturn ret;
762     GstBus *bus;
763
764     /* If the top-level object is not a pipeline, place it in a pipeline. */
765     if (!GST_IS_PIPELINE (pipeline)) {
766       GstElement *real_pipeline = gst_element_factory_make ("pipeline", NULL);
767
768       if (real_pipeline == NULL) {
769         g_printerr (_("ERROR: the 'pipeline' element wasn't found.\n"));
770         return 1;
771       }
772       gst_bin_add (GST_BIN (real_pipeline), pipeline);
773       pipeline = real_pipeline;
774     }
775
776     bus = gst_element_get_bus (pipeline);
777     gst_bus_set_sync_handler (bus, bus_sync_handler, (gpointer) pipeline);
778     gst_object_unref (bus);
779
780     PRINT (_("Setting pipeline to PAUSED ...\n"));
781     ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
782
783     switch (ret) {
784       case GST_STATE_CHANGE_FAILURE:
785         g_printerr (_("ERROR: Pipeline doesn't want to pause.\n"));
786         res = -1;
787         event_loop (pipeline, FALSE, GST_STATE_VOID_PENDING);
788         goto end;
789       case GST_STATE_CHANGE_NO_PREROLL:
790         PRINT (_("Pipeline is live and does not need PREROLL ...\n"));
791         is_live = TRUE;
792         break;
793       case GST_STATE_CHANGE_ASYNC:
794         PRINT (_("Pipeline is PREROLLING ...\n"));
795         caught_error = event_loop (pipeline, TRUE, GST_STATE_PAUSED);
796         if (caught_error) {
797           g_printerr (_("ERROR: pipeline doesn't want to preroll.\n"));
798           goto end;
799         }
800         state = GST_STATE_PAUSED;
801         /* fallthrough */
802       case GST_STATE_CHANGE_SUCCESS:
803         PRINT (_("Pipeline is PREROLLED ...\n"));
804         break;
805     }
806
807     caught_error = event_loop (pipeline, FALSE, GST_STATE_PLAYING);
808
809     if (caught_error) {
810       g_printerr (_("ERROR: pipeline doesn't want to preroll.\n"));
811     } else {
812       GstClockTime tfthen, tfnow;
813       GstClockTimeDiff diff;
814
815       PRINT (_("Setting pipeline to PLAYING ...\n"));
816
817       if (gst_element_set_state (pipeline,
818               GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
819         GstMessage *err_msg;
820         GstBus *bus;
821
822         g_printerr (_("ERROR: pipeline doesn't want to play.\n"));
823         bus = gst_element_get_bus (pipeline);
824         if ((err_msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0))) {
825           print_error_message (err_msg);
826           gst_message_unref (err_msg);
827         }
828         gst_object_unref (bus);
829         res = -1;
830         goto end;
831       }
832
833       tfthen = gst_util_get_timestamp ();
834       caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING);
835       if (eos_on_shutdown && caught_error == ELR_INTERRUPT) {
836         PRINT (_("EOS on shutdown enabled -- Forcing EOS on the pipeline\n"));
837         waiting_eos = TRUE;
838         gst_element_send_event (pipeline, gst_event_new_eos ());
839         PRINT (_("Waiting for EOS...\n"));
840         caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING);
841
842         if (caught_error == ELR_NO_ERROR) {
843           /* we got EOS */
844           PRINT (_("EOS received - stopping pipeline...\n"));
845         } else if (caught_error == ELR_ERROR) {
846           PRINT (_("An error happened while waiting for EOS\n"));
847         }
848       }
849       tfnow = gst_util_get_timestamp ();
850
851       diff = GST_CLOCK_DIFF (tfthen, tfnow);
852
853       PRINT (_("Execution ended after %" G_GUINT64_FORMAT " ns.\n"), diff);
854     }
855
856     PRINT (_("Setting pipeline to PAUSED ...\n"));
857     gst_element_set_state (pipeline, GST_STATE_PAUSED);
858     if (caught_error == ELR_NO_ERROR)
859       gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
860
861     /* iterate mainloop to process pending stuff */
862     while (g_main_context_iteration (NULL, FALSE));
863
864     PRINT (_("Setting pipeline to READY ...\n"));
865     gst_element_set_state (pipeline, GST_STATE_READY);
866     gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
867
868   end:
869     PRINT (_("Setting pipeline to NULL ...\n"));
870     gst_element_set_state (pipeline, GST_STATE_NULL);
871     gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
872   }
873
874   PRINT (_("Freeing pipeline ...\n"));
875   gst_object_unref (pipeline);
876
877   gst_deinit ();
878   if (trace)
879     gst_alloc_trace_print_live ();
880
881   return res;
882 }