7 static GList *seekable_elements = NULL;
9 static GstElement *pipeline;
10 static GtkAdjustment *adjustment;
11 static gboolean stats = FALSE;
12 static guint64 duration;
14 static guint update_id;
16 #define UPDATE_INTERVAL 500
19 make_cdaudio_pipeline (void)
23 cdaudio = gst_element_factory_make ("cdaudio", "cdaudio");
24 g_assert (cdaudio != NULL);
26 seekable_elements = g_list_prepend (seekable_elements, cdaudio);
32 format_value (GtkScale *scale,
39 real = value * duration / 100;
40 seconds = (gint64) real / GST_SECOND;
41 subseconds = (gint64) real / (GST_SECOND / 100);
43 return g_strdup_printf ("%02lld:%02lld:%02lld",
52 const GstFormat format;
55 static seek_format seek_formats[] =
57 { "tim", GST_FORMAT_TIME },
58 { "byt", GST_FORMAT_BYTES },
59 { "unt", GST_FORMAT_UNITS },
60 { "buf", GST_FORMAT_BUFFERS },
61 { "def", GST_FORMAT_DEFAULT },
66 G_GNUC_UNUSED static void
69 GList *walk = seekable_elements;
72 GstElement *element = GST_ELEMENT (walk->data);
75 g_print ("durations %8.8s: ", GST_ELEMENT_NAME (element));
76 while (seek_formats[i].name) {
81 format = seek_formats[i].format;
82 res = gst_element_query (element, GST_QUERY_TOTAL, &format, &value);
84 g_print ("%s %13lld | ", seek_formats[i].name, value);
87 g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
91 g_print (" %s\n", GST_ELEMENT_NAME (element));
92 walk = g_list_next (walk);
96 G_GNUC_UNUSED static void
99 GList *walk = seekable_elements;
102 GstElement *element = GST_ELEMENT (walk->data);
105 g_print ("positions %8.8s: ", GST_ELEMENT_NAME (element));
106 while (seek_formats[i].name) {
111 format = seek_formats[i].format;
112 res = gst_element_query (element, GST_QUERY_POSITION, &format, &value);
114 g_print ("%s %13lld | ", seek_formats[i].name, value);
117 g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
121 g_print (" %s\n", GST_ELEMENT_NAME (element));
122 walk = g_list_next (walk);
127 update_scale (gpointer data)
130 guint64 position = 0;
131 GstFormat format = GST_FORMAT_TIME;
134 clock = gst_bin_get_clock (GST_BIN (pipeline));
136 if (seekable_elements) {
137 GstElement *element = GST_ELEMENT (seekable_elements->data);
138 gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
141 position = gst_clock_get_time (clock);
145 g_print ("clock: %13llu (%s)\n", position, gst_object_get_name (GST_OBJECT (clock)));
150 gtk_adjustment_set_value (adjustment, position * 100.0 / duration);
157 iterate (gpointer data)
161 g_print ("iterate\n");
162 res = gst_bin_iterate (GST_BIN (data));
164 gtk_timeout_remove (update_id);
165 g_print ("stopping iterations\n");
171 start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
173 gst_element_set_state (pipeline, GST_STATE_PAUSED);
174 gtk_timeout_remove (update_id);
180 stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
182 gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
185 GList *walk = seekable_elements;
188 GstElement *seekable = GST_ELEMENT (walk->data);
190 g_print ("seek to %lld on element %s\n", real, GST_ELEMENT_NAME (seekable));
191 s_event = gst_event_new_seek (GST_FORMAT_TIME |
192 GST_SEEK_METHOD_SET |
193 GST_SEEK_FLAG_FLUSH, real);
195 res = gst_element_send_event (seekable, s_event);
197 walk = g_list_next (walk);
200 gst_element_set_state (pipeline, GST_STATE_PLAYING);
201 if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
202 gtk_idle_add ((GtkFunction) iterate, pipeline);
203 update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
209 play_cb (GtkButton * button, gpointer data)
211 if (gst_element_get_state (pipeline) != GST_STATE_PLAYING) {
212 gst_element_set_state (pipeline, GST_STATE_PLAYING);
213 if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
214 gtk_idle_add ((GtkFunction) iterate, pipeline);
215 update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
220 pause_cb (GtkButton * button, gpointer data)
222 if (gst_element_get_state (pipeline) != GST_STATE_PAUSED) {
223 gst_element_set_state (pipeline, GST_STATE_PAUSED);
224 gtk_timeout_remove (update_id);
229 stop_cb (GtkButton * button, gpointer data)
231 if (gst_element_get_state (pipeline) != GST_STATE_READY) {
232 gst_element_set_state (pipeline, GST_STATE_READY);
233 gtk_timeout_remove (update_id);
238 main (int argc, char **argv)
240 GtkWidget *window, *hbox, *vbox,
241 *play_button, *pause_button, *stop_button,
243 struct poptOption options[] = {
244 {"stats", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &stats, 0,
245 "Show element stats", NULL},
249 gst_init_with_popt_table (&argc, &argv, options);
250 gtk_init (&argc, &argv);
252 pipeline = make_cdaudio_pipeline ();
254 g_signal_connect (pipeline, "deep_notify", G_CALLBACK (gst_element_default_deep_notify), NULL);
255 g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), NULL);
257 /* initialize gui elements ... */
258 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
259 hbox = gtk_hbox_new (FALSE, 0);
260 vbox = gtk_vbox_new (FALSE, 0);
261 play_button = gtk_button_new_with_label ("play");
262 pause_button = gtk_button_new_with_label ("pause");
263 stop_button = gtk_button_new_with_label ("stop");
265 adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
266 hscale = gtk_hscale_new (adjustment);
267 gtk_scale_set_digits (GTK_SCALE (hscale), 2);
268 gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
270 gtk_signal_connect(GTK_OBJECT(hscale),
271 "button_press_event", G_CALLBACK (start_seek), pipeline);
272 gtk_signal_connect(GTK_OBJECT(hscale),
273 "button_release_event", G_CALLBACK (stop_seek), pipeline);
274 gtk_signal_connect(GTK_OBJECT(hscale),
275 "format_value", G_CALLBACK (format_value), pipeline);
277 /* do the packing stuff ... */
278 gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
279 gtk_container_add (GTK_CONTAINER (window), vbox);
280 gtk_container_add (GTK_CONTAINER (vbox), hbox);
281 gtk_box_pack_start (GTK_BOX (hbox), play_button, FALSE, FALSE, 2);
282 gtk_box_pack_start (GTK_BOX (hbox), pause_button, FALSE, FALSE, 2);
283 gtk_box_pack_start (GTK_BOX (hbox), stop_button, FALSE, FALSE, 2);
284 gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
286 /* connect things ... */
287 g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline);
288 g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline);
289 g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline);
290 g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
293 gtk_widget_show_all (window);
297 gst_element_set_state (pipeline, GST_STATE_NULL);