Wim Taymans | 7ccc2cf | 2000-08-28 20:20:55 +0000 | [diff] [blame] | 1 | #include <string.h> |
| 2 | #include <stdlib.h> |
David Schleef | 96b9f9d | 2002-11-14 02:49:16 +0000 | [diff] [blame] | 3 | #include <signal.h> |
| 4 | #include <sys/wait.h> |
Wim Taymans | 0e40bc5 | 2002-03-30 17:06:45 +0000 | [diff] [blame] | 5 | #include <gst/gst.h> |
Erik Walthinsen | 0ec4008 | 2000-01-30 10:44:33 +0000 | [diff] [blame] | 6 | |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 7 | static guint64 iterations = 0; |
| 8 | static guint64 sum = 0; |
Wim Taymans | 7fc83d1 | 2002-09-12 20:11:12 +0000 | [diff] [blame] | 9 | static guint64 min = G_MAXINT64; |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 10 | static guint64 max = 0; |
Wim Taymans | 086de42 | 2002-05-08 20:40:48 +0000 | [diff] [blame] | 11 | static GstClock *s_clock; |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 12 | |
Wim Taymans | 3f1fe95 | 2001-07-23 00:57:06 +0000 | [diff] [blame] | 13 | gboolean |
| 14 | idle_func (gpointer data) |
| 15 | { |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 16 | gboolean busy; |
Wim Taymans | 0e40bc5 | 2002-03-30 17:06:45 +0000 | [diff] [blame] | 17 | GTimeVal tfthen, tfnow; |
| 18 | GstClockTimeDiff diff; |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 19 | |
Wim Taymans | 086de42 | 2002-05-08 20:40:48 +0000 | [diff] [blame] | 20 | if (s_clock) { |
| 21 | //g_print ("%lld\n", gst_clock_get_time (s_clock)); |
| 22 | } |
| 23 | |
Wim Taymans | 0e40bc5 | 2002-03-30 17:06:45 +0000 | [diff] [blame] | 24 | g_get_current_time (&tfthen); |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 25 | busy = gst_bin_iterate (GST_BIN (data)); |
| 26 | iterations++; |
Wim Taymans | 0e40bc5 | 2002-03-30 17:06:45 +0000 | [diff] [blame] | 27 | g_get_current_time (&tfnow); |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 28 | |
Wim Taymans | 0e40bc5 | 2002-03-30 17:06:45 +0000 | [diff] [blame] | 29 | diff = GST_TIMEVAL_TO_TIME (tfnow) - |
| 30 | GST_TIMEVAL_TO_TIME (tfthen); |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 31 | |
| 32 | sum += diff; |
| 33 | min = MIN (min, diff); |
| 34 | max = MAX (max, diff); |
| 35 | |
| 36 | if (!busy) { |
Michael Meeks | d040992 | 2001-12-14 18:11:52 +0000 | [diff] [blame] | 37 | gst_main_quit (); |
Wim Taymans | d7ddba9 | 2002-06-03 20:59:02 +0000 | [diff] [blame] | 38 | g_print ("execution ended after %llu iterations (sum %llu ns, average %llu ns, min %llu ns, max %llu ns)\n", |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 39 | iterations, sum, sum/iterations, min, max); |
Erik Walthinsen | d574ab8 | 2001-10-17 10:21:27 +0000 | [diff] [blame] | 40 | } |
Wim Taymans | 109f7a0 | 2001-12-24 12:30:09 +0000 | [diff] [blame] | 41 | |
| 42 | return busy; |
Wim Taymans | 3f1fe95 | 2001-07-23 00:57:06 +0000 | [diff] [blame] | 43 | } |
| 44 | |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 45 | static GstElement* |
Andy Wingo | f7aa64c | 2002-02-06 16:35:16 +0000 | [diff] [blame] | 46 | xmllaunch_parse_cmdline (const gchar **argv) |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 47 | { |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 48 | GstElement *pipeline = NULL, *e; |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 49 | GstXML *xml; |
| 50 | gboolean err; |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 51 | const gchar *arg; |
| 52 | gchar *element, *property, *value; |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 53 | GList *l; |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 54 | gint i = 0; |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 55 | |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 56 | if (!(arg = argv[0])) { |
Andy Wingo | f7aa64c | 2002-02-06 16:35:16 +0000 | [diff] [blame] | 57 | g_print ("usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"); |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 58 | exit (1); |
| 59 | } |
| 60 | |
| 61 | xml = gst_xml_new (); |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 62 | err = gst_xml_parse_file(xml, arg, NULL); |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 63 | |
| 64 | if (err != TRUE) { |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 65 | fprintf (stderr, "ERROR: parse of xml file '%s' failed\n", arg); |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 66 | exit (1); |
| 67 | } |
| 68 | |
| 69 | l = gst_xml_get_topelements (xml); |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 70 | 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 Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 94 | 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 Wingo | 703f271 | 2002-01-15 05:58:45 +0000 | [diff] [blame] | 100 | g_free (element); |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 101 | } |
| 102 | |
Andy Wingo | 57dc4b5 | 2002-01-14 07:18:43 +0000 | [diff] [blame] | 103 | if (!l) |
| 104 | return NULL; |
| 105 | else |
| 106 | return l->data; |
| 107 | } |
| 108 | |
David Schleef | 96b9f9d | 2002-11-14 02:49:16 +0000 | [diff] [blame] | 109 | extern volatile gboolean glib_on_error_halt; |
| 110 | void fault_restore(void); |
| 111 | |
| 112 | void 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 | |
| 152 | void 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 | |
| 163 | void 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 Taymans | 044c461 | 2001-01-21 16:06:42 +0000 | [diff] [blame] | 175 | int |
| 176 | main(int argc, char *argv[]) |
| 177 | { |
Benjamin Otte | 5f83249 | 2002-04-16 14:45:53 +0000 | [diff] [blame] | 178 | /* options */ |
Benjamin Otte | 1952e9d | 2002-02-24 17:08:07 +0000 | [diff] [blame] | 179 | gboolean silent = FALSE; |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 180 | gchar *savefile = NULL; |
Benjamin Otte | 5f83249 | 2002-04-16 14:45:53 +0000 | [diff] [blame] | 181 | gchar *exclude_args = NULL; |
Benjamin Otte | 1952e9d | 2002-02-24 17:08:07 +0000 | [diff] [blame] | 182 | struct poptOption options[] = { |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 183 | {"silent", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &silent, 0, |
| 184 | "do not output status information", NULL}, |
Benjamin Otte | 5f83249 | 2002-04-16 14:45:53 +0000 | [diff] [blame] | 185 | {"exclude", 'X', POPT_ARG_STRING|POPT_ARGFLAG_STRIP, &exclude_args, 0, |
| 186 | "do not output status information of TYPE", "TYPE1,TYPE2,..."}, |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 187 | {"output", 'o', POPT_ARG_STRING|POPT_ARGFLAG_STRIP, &savefile, 0, |
| 188 | "save xml representation of pipeline to FILE and exit", "FILE"}, |
Benjamin Otte | 1952e9d | 2002-02-24 17:08:07 +0000 | [diff] [blame] | 189 | POPT_TABLEEND |
| 190 | }; |
| 191 | |
Erik Walthinsen | 2671b85 | 2001-01-09 04:39:35 +0000 | [diff] [blame] | 192 | GstElement *pipeline; |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 193 | gchar **argvn; |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 194 | GError *error = NULL; |
Wim Taymans | 6476189 | 2002-11-20 21:29:29 +0000 | [diff] [blame] | 195 | gint res = 0; |
Erik Walthinsen | 2671b85 | 2001-01-09 04:39:35 +0000 | [diff] [blame] | 196 | |
Wim Taymans | 6dc4fb7 | 2001-12-14 14:28:27 +0000 | [diff] [blame] | 197 | free (malloc (8)); /* -lefence */ |
| 198 | |
David Schleef | 96b9f9d | 2002-11-14 02:49:16 +0000 | [diff] [blame] | 199 | fault_setup(); |
| 200 | |
Benjamin Otte | 1952e9d | 2002-02-24 17:08:07 +0000 | [diff] [blame] | 201 | gst_init_with_popt_table (&argc, &argv, options); |
Andy Wingo | f38969f | 2002-01-14 04:09:56 +0000 | [diff] [blame] | 202 | |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 203 | /* make a null-terminated version of argv */ |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 204 | argvn = g_new0 (char*, argc); |
Andy Wingo | aa29faa | 2002-01-15 05:57:14 +0000 | [diff] [blame] | 205 | memcpy (argvn, argv+1, sizeof (char*) * (argc-1)); |
Andy Wingo | f38969f | 2002-01-14 04:09:56 +0000 | [diff] [blame] | 206 | if (strstr (argv[0], "gst-xmllaunch")) { |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 207 | pipeline = xmllaunch_parse_cmdline ((const gchar**)argvn); |
Andy Wingo | f38969f | 2002-01-14 04:09:56 +0000 | [diff] [blame] | 208 | } else { |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 209 | pipeline = (GstElement*) gst_parse_launchv ((const gchar**)argvn, &error); |
Wim Taymans | 86bdfc6 | 2001-05-20 20:06:09 +0000 | [diff] [blame] | 210 | } |
Wim Taymans | d9e80e9 | 2002-09-17 21:32:26 +0000 | [diff] [blame] | 211 | g_free (argvn); |
Erik Walthinsen | 0ee5688 | 2000-12-31 10:46:16 +0000 | [diff] [blame] | 212 | |
Andy Wingo | f38969f | 2002-01-14 04:09:56 +0000 | [diff] [blame] | 213 | if (!pipeline) { |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 214 | 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 Walthinsen | b4dcb2f | 2001-06-02 18:26:25 +0000 | [diff] [blame] | 218 | exit(1); |
| 219 | } |
Andy Wingo | f38969f | 2002-01-14 04:09:56 +0000 | [diff] [blame] | 220 | |
Benjamin Otte | 1952e9d | 2002-02-24 17:08:07 +0000 | [diff] [blame] | 221 | if (!silent) |
Benjamin Otte | 5f83249 | 2002-04-16 14:45:53 +0000 | [diff] [blame] | 222 | { |
Benjamin Otte | 8e5c223 | 2002-04-17 00:18:04 +0000 | [diff] [blame] | 223 | gchar **exclude_list = exclude_args ? g_strsplit (exclude_args, ",", 0) : NULL; |
Wim Taymans | 7fc1800 | 2002-07-30 19:25:24 +0000 | [diff] [blame] | 224 | g_signal_connect (pipeline, "deep_notify", G_CALLBACK (gst_element_default_deep_notify), exclude_list); |
Benjamin Otte | 5f83249 | 2002-04-16 14:45:53 +0000 | [diff] [blame] | 225 | } |
Wim Taymans | 7fc1800 | 2002-07-30 19:25:24 +0000 | [diff] [blame] | 226 | g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), NULL); |
Benjamin Otte | 7e4e644 | 2002-02-06 07:10:37 +0000 | [diff] [blame] | 227 | |
Erik Walthinsen | d574ab8 | 2001-10-17 10:21:27 +0000 | [diff] [blame] | 228 | #ifndef GST_DISABLE_LOADSAVE |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 229 | if (savefile) { |
Andy Wingo | d262bea | 2002-01-11 15:49:47 +0000 | [diff] [blame] | 230 | gst_xml_write_file (GST_ELEMENT (pipeline), fopen (savefile, "w")); |
Richard Boulton | 216e862 | 2001-06-19 10:34:15 +0000 | [diff] [blame] | 231 | } |
Erik Walthinsen | d574ab8 | 2001-10-17 10:21:27 +0000 | [diff] [blame] | 232 | #endif |
Andy Wingo | f38969f | 2002-01-14 04:09:56 +0000 | [diff] [blame] | 233 | |
Andy Wingo | 70cfc6c | 2002-04-07 23:32:16 +0000 | [diff] [blame] | 234 | if (!savefile) { |
Wim Taymans | b02211c | 2001-12-22 21:26:56 +0000 | [diff] [blame] | 235 | gst_buffer_print_stats(); |
Wim Taymans | 550446c | 2002-07-08 19:23:59 +0000 | [diff] [blame] | 236 | gst_event_print_stats(); |
| 237 | |
Richard Boulton | 216e862 | 2001-06-19 10:34:15 +0000 | [diff] [blame] | 238 | fprintf(stderr,"RUNNING pipeline\n"); |
Wim Taymans | f7d73c9 | 2002-12-08 20:08:39 +0000 | [diff] [blame] | 239 | if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_FAILURE) { |
Wim Taymans | d61cbc8 | 2001-12-12 18:31:25 +0000 | [diff] [blame] | 240 | fprintf(stderr,"pipeline doesn't want to play\n"); |
Wim Taymans | 6476189 | 2002-11-20 21:29:29 +0000 | [diff] [blame] | 241 | res = -1; |
| 242 | goto end; |
Wim Taymans | d61cbc8 | 2001-12-12 18:31:25 +0000 | [diff] [blame] | 243 | } |
Erik Walthinsen | 043f623 | 2001-04-15 22:54:57 +0000 | [diff] [blame] | 244 | |
Wim Taymans | 086de42 | 2002-05-08 20:40:48 +0000 | [diff] [blame] | 245 | s_clock = gst_bin_get_clock (GST_BIN (pipeline)); |
| 246 | |
Andy Wingo | cfb228b | 2002-03-30 19:31:14 +0000 | [diff] [blame] | 247 | if (!GST_FLAG_IS_SET (GST_OBJECT (pipeline), GST_BIN_SELF_SCHEDULABLE)) { |
Andy Wingo | a43fade | 2002-03-18 04:41:37 +0000 | [diff] [blame] | 248 | g_idle_add (idle_func, pipeline); |
| 249 | gst_main (); |
| 250 | } else { |
Andy Wingo | cfb228b | 2002-03-30 19:31:14 +0000 | [diff] [blame] | 251 | g_print ("waiting for the state change...\n"); |
| 252 | gst_element_wait_state_change (pipeline); |
Wim Taymans | 7fc1800 | 2002-07-30 19:25:24 +0000 | [diff] [blame] | 253 | g_print ("got the state change...\n"); |
Andy Wingo | a43fade | 2002-03-18 04:41:37 +0000 | [diff] [blame] | 254 | } |
Erik Walthinsen | e318439 | 2001-01-04 10:47:39 +0000 | [diff] [blame] | 255 | |
Richard Boulton | 216e862 | 2001-06-19 10:34:15 +0000 | [diff] [blame] | 256 | gst_element_set_state (pipeline, GST_STATE_NULL); |
| 257 | } |
Wim Taymans | 6476189 | 2002-11-20 21:29:29 +0000 | [diff] [blame] | 258 | |
| 259 | end: |
| 260 | gst_buffer_print_stats(); |
| 261 | gst_event_print_stats(); |
| 262 | |
Wim Taymans | 34f0521 | 2001-12-19 19:23:51 +0000 | [diff] [blame] | 263 | gst_object_unref (GST_OBJECT (pipeline)); |
Wim Taymans | 7ccc2cf | 2000-08-28 20:20:55 +0000 | [diff] [blame] | 264 | |
Wim Taymans | 6476189 | 2002-11-20 21:29:29 +0000 | [diff] [blame] | 265 | return res; |
Erik Walthinsen | 0ec4008 | 2000-01-30 10:44:33 +0000 | [diff] [blame] | 266 | } |
David Schleef | 96b9f9d | 2002-11-14 02:49:16 +0000 | [diff] [blame] | 267 | |