Updated the examples exit if the pipeline doesn't want to go to the playing state.
[platform/upstream/gstreamer.git] / tools / gstreamer-launch.c
1 #include <glib.h>
2 #include <gst/gst.h>
3 #include <gst/gstparse.h>
4 #include <string.h>
5 #include <stdlib.h>
6
7 static int launch_argc;
8 static char **launch_argv;
9
10 #ifndef USE_GLIB2
11 GtkWidget *window;
12 GtkWidget *gtk_socket;
13 #endif
14
15 typedef void (*found_handler) (GstElement *element, gint xid, void *priv);
16
17 void
18 arg_search (GstBin *bin, gchar *argname, found_handler handler, void *priv)
19 {
20   GList *children;
21   gchar *ccargname;
22
23   ccargname = g_strdup_printf("::%s",argname);
24
25   children = gst_bin_get_list(bin);
26
27 #ifndef USE_GLIB2
28   while (children) {
29     GstElement *child;
30      
31     child = GST_ELEMENT (children->data);
32     children = g_list_next (children);
33
34     if (GST_IS_BIN (child)) arg_search (GST_BIN (child), argname, handler, priv);
35     else {
36       GtkType type;
37
38       type = GTK_OBJECT_TYPE (child);
39
40       while (type != GTK_TYPE_INVALID) {
41         GtkArg *args;
42         guint32 *flags;
43         guint num_args,i;
44
45         args = gtk_object_query_args(type,&flags,&num_args);
46
47         for (i=0;i<num_args;i++) {
48           if (strstr(args[i].name,ccargname)) {
49             (handler)(child, gst_util_get_int_arg (GTK_OBJECT (child), argname) ,priv);
50           }
51         }
52         type = gtk_type_parent(type);
53       }
54     }
55   }
56 #endif
57
58   g_free(ccargname);
59 }
60
61 gboolean
62 idle_func (gpointer data)
63 {
64   if (!gst_bin_iterate (GST_BIN (data))) {
65 #ifndef USE_GLIB2
66     gtk_main_quit ();
67 #endif
68     g_print ("iteration ended\n");
69     return FALSE;
70   }
71   return TRUE;
72 }
73
74 void 
75 handle_have_size (GstElement *element,int width,int height) 
76 {
77 #ifndef USE_GLIB2
78   gtk_widget_set_usize(gtk_socket,width,height);
79   gtk_widget_show_all(window);
80 #endif
81 }
82
83 void 
84 xid_handler (GstElement *element, gint xid, void *priv) 
85 {
86 #ifndef USE_GLIB2
87   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
88
89   gtk_socket = gtk_socket_new ();
90   gtk_widget_show(gtk_socket);
91
92   gtk_container_add(GTK_CONTAINER(window),gtk_socket);
93
94   gtk_widget_realize(gtk_socket);
95   gtk_socket_steal (GTK_SOCKET (gtk_socket), xid);
96
97   gtk_object_set(GTK_OBJECT(window),"allow_grow",TRUE,NULL);
98   gtk_object_set(GTK_OBJECT(window),"allow_shrink",TRUE,NULL);
99
100   gtk_signal_connect (GTK_OBJECT (element), "have_size",
101                       GTK_SIGNAL_FUNC (handle_have_size), element);
102 #endif
103 }
104
105 int
106 main(int argc, char *argv[])
107 {
108   GstElement *pipeline;
109   char **argvn;
110   gchar *cmdline;
111   int i;
112   gboolean save_pipeline = FALSE;
113   gboolean run_pipeline = TRUE;
114   gchar *savefile = "";
115
116   gst_init (&argc, &argv);
117
118   if (argc >= 3 && !strcmp(argv[1], "-o")) {
119     save_pipeline = TRUE;
120     run_pipeline = FALSE;
121     savefile = argv[2];
122     argv[2] = argv[0];
123     argv+=2;
124     argc-=2;
125   }
126
127   launch_argc = argc;
128   launch_argv = argv;
129
130   pipeline = gst_pipeline_new ("launch");
131
132   // make a null-terminated version of argv
133   argvn = g_new0 (char *,argc);
134   memcpy (argvn, argv+1, sizeof (char*) * (argc-1));
135
136   // escape spaces
137   for (i=0; i<argc-1; i++) {
138     gchar **split;
139
140     split = g_strsplit (argvn[i], " ", 0);
141
142     argvn[i] = g_strjoinv ("\\ ", split);
143     g_strfreev (split);
144   }
145   // join the argvs together
146   cmdline = g_strjoinv (" ", argvn);
147   // free the null-terminated argv
148   g_free (argvn);
149
150   // fail if there are no pipes in it (needs pipes for a pipeline
151   if (!strchr(cmdline,'!')) {
152     fprintf(stderr,"ERROR: no pipeline description found on commandline\n");
153     exit(1);
154   }
155
156   if (gst_parse_launch (cmdline, GST_BIN (pipeline)) < 0){
157     fprintf(stderr,"ERROR: pipeline description could not be parsed\n");
158     exit(1);
159   }
160
161 #ifndef GST_DISABLE_LOADSAVE
162   if (save_pipeline) {
163     xmlSaveFile (savefile, gst_xml_write (pipeline));
164   }
165 #endif
166   if (run_pipeline) {
167     arg_search(GST_BIN(pipeline),"xid",xid_handler,NULL);
168
169     fprintf(stderr,"RUNNING pipeline\n");
170     if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) {
171       fprintf(stderr,"pipeline doesn't want to play\n");
172       exit (-1);
173     }
174
175     g_idle_add(idle_func,pipeline);
176 #ifdef USE_GLIB2
177     g_main_loop_run (g_main_loop_new (NULL, FALSE));
178 #else
179     gtk_main();
180 #endif
181
182     gst_element_set_state (pipeline, GST_STATE_NULL);
183   }
184
185   return 0;
186 }