blob: f0a94123e8b7504c60fd221e61d97bb73be3882c [file] [log] [blame]
Wim Taymans7ccc2cf2000-08-28 20:20:55 +00001#include <string.h>
2#include <stdlib.h>
David Schleef96b9f9d2002-11-14 02:49:16 +00003#include <signal.h>
4#include <sys/wait.h>
Wim Taymans0e40bc52002-03-30 17:06:45 +00005#include <gst/gst.h>
Erik Walthinsen0ec40082000-01-30 10:44:33 +00006
Wim Taymans109f7a02001-12-24 12:30:09 +00007static guint64 iterations = 0;
8static guint64 sum = 0;
Wim Taymans7fc83d12002-09-12 20:11:12 +00009static guint64 min = G_MAXINT64;
Wim Taymans109f7a02001-12-24 12:30:09 +000010static guint64 max = 0;
Wim Taymans086de422002-05-08 20:40:48 +000011static GstClock *s_clock;
Wim Taymans109f7a02001-12-24 12:30:09 +000012
Wim Taymans3f1fe952001-07-23 00:57:06 +000013gboolean
14idle_func (gpointer data)
15{
Wim Taymans109f7a02001-12-24 12:30:09 +000016 gboolean busy;
Wim Taymans0e40bc52002-03-30 17:06:45 +000017 GTimeVal tfthen, tfnow;
18 GstClockTimeDiff diff;
Wim Taymans109f7a02001-12-24 12:30:09 +000019
Wim Taymans086de422002-05-08 20:40:48 +000020 if (s_clock) {
21 //g_print ("%lld\n", gst_clock_get_time (s_clock));
22 }
23
Wim Taymans0e40bc52002-03-30 17:06:45 +000024 g_get_current_time (&tfthen);
Wim Taymans109f7a02001-12-24 12:30:09 +000025 busy = gst_bin_iterate (GST_BIN (data));
26 iterations++;
Wim Taymans0e40bc52002-03-30 17:06:45 +000027 g_get_current_time (&tfnow);
Wim Taymans109f7a02001-12-24 12:30:09 +000028
Wim Taymans0e40bc52002-03-30 17:06:45 +000029 diff = GST_TIMEVAL_TO_TIME (tfnow) -
30 GST_TIMEVAL_TO_TIME (tfthen);
Wim Taymans109f7a02001-12-24 12:30:09 +000031
32 sum += diff;
33 min = MIN (min, diff);
34 max = MAX (max, diff);
35
36 if (!busy) {
Michael Meeksd0409922001-12-14 18:11:52 +000037 gst_main_quit ();
Wim Taymansd7ddba92002-06-03 20:59:02 +000038 g_print ("execution ended after %llu iterations (sum %llu ns, average %llu ns, min %llu ns, max %llu ns)\n",
Wim Taymans109f7a02001-12-24 12:30:09 +000039 iterations, sum, sum/iterations, min, max);
Erik Walthinsend574ab82001-10-17 10:21:27 +000040 }
Wim Taymans109f7a02001-12-24 12:30:09 +000041
42 return busy;
Wim Taymans3f1fe952001-07-23 00:57:06 +000043}
44
Andy Wingo57dc4b52002-01-14 07:18:43 +000045static GstElement*
Andy Wingof7aa64c2002-02-06 16:35:16 +000046xmllaunch_parse_cmdline (const gchar **argv)
Andy Wingo57dc4b52002-01-14 07:18:43 +000047{
Andy Wingoaa29faa2002-01-15 05:57:14 +000048 GstElement *pipeline = NULL, *e;
Andy Wingo57dc4b52002-01-14 07:18:43 +000049 GstXML *xml;
50 gboolean err;
Andy Wingoaa29faa2002-01-15 05:57:14 +000051 const gchar *arg;
52 gchar *element, *property, *value;
Andy Wingo57dc4b52002-01-14 07:18:43 +000053 GList *l;
Andy Wingoaa29faa2002-01-15 05:57:14 +000054 gint i = 0;
Andy Wingo57dc4b52002-01-14 07:18:43 +000055
Andy Wingoaa29faa2002-01-15 05:57:14 +000056 if (!(arg = argv[0])) {
Andy Wingof7aa64c2002-02-06 16:35:16 +000057 g_print ("usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n");
Andy Wingo57dc4b52002-01-14 07:18:43 +000058 exit (1);
59 }
60
61 xml = gst_xml_new ();
Andy Wingoaa29faa2002-01-15 05:57:14 +000062 err = gst_xml_parse_file(xml, arg, NULL);
Andy Wingo57dc4b52002-01-14 07:18:43 +000063
64 if (err != TRUE) {
Andy Wingoaa29faa2002-01-15 05:57:14 +000065 fprintf (stderr, "ERROR: parse of xml file '%s' failed\n", arg);
Andy Wingo57dc4b52002-01-14 07:18:43 +000066 exit (1);
67 }
68
69 l = gst_xml_get_topelements (xml);
Andy Wingoaa29faa2002-01-15 05:57:14 +000070 if (!l) {
71 fprintf (stderr, "ERROR: no toplevel pipeline element in file '%s'\n", arg);
72 exit (1);
73 }
74
75 if (l->next)
76 g_warning ("only one toplevel element is supported at this time");
77
78 pipeline = GST_ELEMENT (l->data);
79
80 while ((arg = argv[++i])) {
81 element = g_strdup (arg);
82 property = strchr (element, '.');
83 value = strchr (element, '=');
84
85 if (!(element < property && property < value)) {
86 fprintf (stderr, "ERROR: could not parse command line argument %d: %s", i, element);
87 g_free (element);
88 exit (1);
89 }
90
91 *property++ = '\0';
92 *value++ = '\0';
93
Andy Wingoaa29faa2002-01-15 05:57:14 +000094 e = gst_bin_get_by_name (GST_BIN (pipeline), element);
95 if (!e) {
96 g_warning ("element named '%s' not found", element);
97 } else {
98 gst_util_set_object_arg (G_OBJECT (e), property, value);
99 }
Andy Wingo703f2712002-01-15 05:58:45 +0000100 g_free (element);
Andy Wingoaa29faa2002-01-15 05:57:14 +0000101 }
102
Andy Wingo57dc4b52002-01-14 07:18:43 +0000103 if (!l)
104 return NULL;
105 else
106 return l->data;
107}
108
David Schleef96b9f9d2002-11-14 02:49:16 +0000109extern volatile gboolean glib_on_error_halt;
110void fault_restore(void);
111
112void fault_handler(int signum, siginfo_t *si, void *misc)
113{
114 int spinning = TRUE;
115
116 fault_restore();
117
118 if(si->si_signo == SIGSEGV){
119 g_print ("Caught SIGSEGV accessing address %p\n", si->si_addr);
120 }else if(si->si_signo == SIGQUIT){
121 g_print ("Caught SIGQUIT\n");
122 }else{
123 g_print ("signo: %d\n",si->si_signo);
124 g_print ("errno: %d\n",si->si_errno);
125 g_print ("code: %d\n",si->si_code);
126 }
127
128 glib_on_error_halt = FALSE;
129 g_on_error_stack_trace("gst-launch");
130
131 wait(NULL);
132
133#if 1
134 /* FIXME how do we know if we were run by libtool? */
135 g_print("Spinning. Please run 'gdb gst-launch %d' to continue debugging, "
136 "Ctrl-C to quit, or Ctrl-\\ to dump core.\n",
137 getpid());
138 while(spinning)usleep(1000000);
139#else
140 /* This spawns a gdb and attaches it to gst-launch. */
141 {
142 char str[40];
143 sprintf(str,"gdb -quiet gst-launch %d",getpid());
144 system(str);
145 }
146
147 _exit(0);
148#endif
149
150}
151
152void fault_restore(void)
153{
154 struct sigaction action;
155
156 memset(&action,0,sizeof(action));
157 action.sa_handler = SIG_DFL;
158
159 sigaction(SIGSEGV, &action, NULL);
160 sigaction(SIGQUIT, &action, NULL);
161}
162
163void fault_setup(void)
164{
165 struct sigaction action;
166
167 memset(&action,0,sizeof(action));
168 action.sa_sigaction = fault_handler;
169 action.sa_flags = SA_SIGINFO;
170
171 sigaction(SIGSEGV, &action, NULL);
172 sigaction(SIGQUIT, &action, NULL);
173}
174
Wim Taymans044c4612001-01-21 16:06:42 +0000175int
176main(int argc, char *argv[])
177{
Benjamin Otte5f832492002-04-16 14:45:53 +0000178 /* options */
Benjamin Otte1952e9d2002-02-24 17:08:07 +0000179 gboolean silent = FALSE;
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000180 gchar *savefile = NULL;
Benjamin Otte5f832492002-04-16 14:45:53 +0000181 gchar *exclude_args = NULL;
Benjamin Otte1952e9d2002-02-24 17:08:07 +0000182 struct poptOption options[] = {
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000183 {"silent", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &silent, 0,
184 "do not output status information", NULL},
Benjamin Otte5f832492002-04-16 14:45:53 +0000185 {"exclude", 'X', POPT_ARG_STRING|POPT_ARGFLAG_STRIP, &exclude_args, 0,
186 "do not output status information of TYPE", "TYPE1,TYPE2,..."},
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000187 {"output", 'o', POPT_ARG_STRING|POPT_ARGFLAG_STRIP, &savefile, 0,
188 "save xml representation of pipeline to FILE and exit", "FILE"},
Benjamin Otte1952e9d2002-02-24 17:08:07 +0000189 POPT_TABLEEND
190 };
191
Erik Walthinsen2671b852001-01-09 04:39:35 +0000192 GstElement *pipeline;
Andy Wingoaa29faa2002-01-15 05:57:14 +0000193 gchar **argvn;
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000194 GError *error = NULL;
Wim Taymans64761892002-11-20 21:29:29 +0000195 gint res = 0;
Erik Walthinsen2671b852001-01-09 04:39:35 +0000196
Wim Taymans6dc4fb72001-12-14 14:28:27 +0000197 free (malloc (8)); /* -lefence */
198
David Schleef96b9f9d2002-11-14 02:49:16 +0000199 fault_setup();
200
Benjamin Otte1952e9d2002-02-24 17:08:07 +0000201 gst_init_with_popt_table (&argc, &argv, options);
Andy Wingof38969f2002-01-14 04:09:56 +0000202
Andy Wingoaa29faa2002-01-15 05:57:14 +0000203 /* make a null-terminated version of argv */
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000204 argvn = g_new0 (char*, argc);
Andy Wingoaa29faa2002-01-15 05:57:14 +0000205 memcpy (argvn, argv+1, sizeof (char*) * (argc-1));
Andy Wingof38969f2002-01-14 04:09:56 +0000206 if (strstr (argv[0], "gst-xmllaunch")) {
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000207 pipeline = xmllaunch_parse_cmdline ((const gchar**)argvn);
Andy Wingof38969f2002-01-14 04:09:56 +0000208 } else {
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000209 pipeline = (GstElement*) gst_parse_launchv ((const gchar**)argvn, &error);
Wim Taymans86bdfc62001-05-20 20:06:09 +0000210 }
Wim Taymansd9e80e92002-09-17 21:32:26 +0000211 g_free (argvn);
Erik Walthinsen0ee56882000-12-31 10:46:16 +0000212
Andy Wingof38969f2002-01-14 04:09:56 +0000213 if (!pipeline) {
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000214 if (error)
215 fprintf(stderr, "ERROR: pipeline could not be constructed: %s\n", error->message);
216 else
217 fprintf(stderr, "ERROR: pipeline could not be constructed\n");
Erik Walthinsenb4dcb2f2001-06-02 18:26:25 +0000218 exit(1);
219 }
Andy Wingof38969f2002-01-14 04:09:56 +0000220
Benjamin Otte1952e9d2002-02-24 17:08:07 +0000221 if (!silent)
Benjamin Otte5f832492002-04-16 14:45:53 +0000222 {
Benjamin Otte8e5c2232002-04-17 00:18:04 +0000223 gchar **exclude_list = exclude_args ? g_strsplit (exclude_args, ",", 0) : NULL;
Wim Taymans7fc18002002-07-30 19:25:24 +0000224 g_signal_connect (pipeline, "deep_notify", G_CALLBACK (gst_element_default_deep_notify), exclude_list);
Benjamin Otte5f832492002-04-16 14:45:53 +0000225 }
Wim Taymans7fc18002002-07-30 19:25:24 +0000226 g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), NULL);
Benjamin Otte7e4e6442002-02-06 07:10:37 +0000227
Erik Walthinsend574ab82001-10-17 10:21:27 +0000228#ifndef GST_DISABLE_LOADSAVE
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000229 if (savefile) {
Andy Wingod262bea2002-01-11 15:49:47 +0000230 gst_xml_write_file (GST_ELEMENT (pipeline), fopen (savefile, "w"));
Richard Boulton216e8622001-06-19 10:34:15 +0000231 }
Erik Walthinsend574ab82001-10-17 10:21:27 +0000232#endif
Andy Wingof38969f2002-01-14 04:09:56 +0000233
Andy Wingo70cfc6c2002-04-07 23:32:16 +0000234 if (!savefile) {
Wim Taymansb02211c2001-12-22 21:26:56 +0000235 gst_buffer_print_stats();
Wim Taymans550446c2002-07-08 19:23:59 +0000236 gst_event_print_stats();
237
Richard Boulton216e8622001-06-19 10:34:15 +0000238 fprintf(stderr,"RUNNING pipeline\n");
Wim Taymansf7d73c92002-12-08 20:08:39 +0000239 if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_FAILURE) {
Wim Taymansd61cbc82001-12-12 18:31:25 +0000240 fprintf(stderr,"pipeline doesn't want to play\n");
Wim Taymans64761892002-11-20 21:29:29 +0000241 res = -1;
242 goto end;
Wim Taymansd61cbc82001-12-12 18:31:25 +0000243 }
Erik Walthinsen043f6232001-04-15 22:54:57 +0000244
Wim Taymans086de422002-05-08 20:40:48 +0000245 s_clock = gst_bin_get_clock (GST_BIN (pipeline));
246
Andy Wingocfb228b2002-03-30 19:31:14 +0000247 if (!GST_FLAG_IS_SET (GST_OBJECT (pipeline), GST_BIN_SELF_SCHEDULABLE)) {
Andy Wingoa43fade2002-03-18 04:41:37 +0000248 g_idle_add (idle_func, pipeline);
249 gst_main ();
250 } else {
Andy Wingocfb228b2002-03-30 19:31:14 +0000251 g_print ("waiting for the state change...\n");
252 gst_element_wait_state_change (pipeline);
Wim Taymans7fc18002002-07-30 19:25:24 +0000253 g_print ("got the state change...\n");
Andy Wingoa43fade2002-03-18 04:41:37 +0000254 }
Erik Walthinsene3184392001-01-04 10:47:39 +0000255
Richard Boulton216e8622001-06-19 10:34:15 +0000256 gst_element_set_state (pipeline, GST_STATE_NULL);
257 }
Wim Taymans64761892002-11-20 21:29:29 +0000258
259end:
260 gst_buffer_print_stats();
261 gst_event_print_stats();
262
Wim Taymans34f05212001-12-19 19:23:51 +0000263 gst_object_unref (GST_OBJECT (pipeline));
Wim Taymans7ccc2cf2000-08-28 20:20:55 +0000264
Wim Taymans64761892002-11-20 21:29:29 +0000265 return res;
Erik Walthinsen0ec40082000-01-30 10:44:33 +0000266}
David Schleef96b9f9d2002-11-14 02:49:16 +0000267