gst/mpegstream/: Ref events before sending them to multiple pads, after all gst_pad_s...
[platform/upstream/gstreamer.git] / examples / level / demo.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * demo.c: sample application to display VU meter-like output of level
5  * Copyright (C) 2003
6  *           Thomas Vander Stichele <thomas at apestaart dot org>
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 #include <gst/gst.h>
29 #include <gtk/gtk.h>
30
31 /* global array for the scale widgets, we'll assume stereo */
32 GtkWidget *elapsed;
33 GtkWidget *scale[2][3];
34
35 static void
36 level_callback (GstElement * element, gdouble time, gint channel,
37     gdouble rms, gdouble peak, gdouble decay)
38 {
39   gchar *label;
40
41   label = g_strdup_printf ("%.3f", time);
42   gtk_label_set (GTK_LABEL (elapsed), label);
43   g_free (label);
44   gtk_range_set_value (GTK_RANGE (scale[channel][0]), rms);
45   gtk_range_set_value (GTK_RANGE (scale[channel][1]), peak);
46   gtk_range_set_value (GTK_RANGE (scale[channel][2]), decay);
47 }
48
49 static gboolean
50 idler (gpointer data)
51 {
52   GstElement *pipeline = GST_ELEMENT (data);
53
54   g_print ("+");
55   if (gst_bin_iterate (GST_BIN (pipeline)))
56     return TRUE;
57   gtk_main_quit ();
58   return FALSE;
59 }
60
61 static void
62 setup_gui ()
63 {
64   GtkWidget *window;
65   GtkWidget *vbox;
66   GtkWidget *label, *hbox;
67   int c;
68
69   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
70   g_signal_connect (window, "destroy", gtk_main_quit, NULL);
71
72   vbox = gtk_vbox_new (TRUE, 0);
73   gtk_container_add (GTK_CONTAINER (window), vbox);
74
75   /* elapsed widget */
76   hbox = gtk_hbox_new (TRUE, 0);
77   label = gtk_label_new ("Elapsed");
78   elapsed = gtk_label_new ("0.000");
79   gtk_container_add (GTK_CONTAINER (hbox), label);
80   gtk_container_add (GTK_CONTAINER (hbox), elapsed);
81   gtk_container_add (GTK_CONTAINER (vbox), hbox);
82
83   for (c = 0; c < 2; ++c) {
84     /* RMS */
85     hbox = gtk_hbox_new (TRUE, 0);
86     label = gtk_label_new ("RMS");
87     gtk_container_add (GTK_CONTAINER (hbox), label);
88     scale[c][0] = gtk_hscale_new_with_range (-90.0, 0.0, 0.2);
89     gtk_widget_set_size_request (scale[c][0], 100, -1);
90     gtk_container_add (GTK_CONTAINER (hbox), scale[c][0]);
91     gtk_container_add (GTK_CONTAINER (vbox), hbox);
92     /* peak */
93     hbox = gtk_hbox_new (TRUE, 0);
94     label = gtk_label_new ("peak");
95     gtk_container_add (GTK_CONTAINER (hbox), label);
96     scale[c][1] = gtk_hscale_new_with_range (-90.0, 0.0, 0.2);
97     gtk_widget_set_size_request (scale[c][1], 100, -1);
98     gtk_container_add (GTK_CONTAINER (hbox), scale[c][1]);
99     gtk_container_add (GTK_CONTAINER (vbox), hbox);
100     /* decay */
101     hbox = gtk_hbox_new (TRUE, 0);
102     label = gtk_label_new ("decaying peek");
103     gtk_container_add (GTK_CONTAINER (hbox), label);
104     scale[c][2] = gtk_hscale_new_with_range (-90.0, 0.0, 0.2);
105     gtk_widget_set_size_request (scale[c][2], 100, -1);
106     gtk_container_add (GTK_CONTAINER (hbox), scale[c][2]);
107     gtk_container_add (GTK_CONTAINER (vbox), hbox);
108   }
109
110   gtk_widget_show_all (GTK_WIDGET (window));
111 }
112
113 int
114 main (int argc, char *argv[])
115 {
116
117   GstElement *pipeline = NULL;
118   GError *error = NULL;
119   GstElement *level;
120
121   gst_init (&argc, &argv);
122   gtk_init (&argc, &argv);
123
124   pipeline = gst_parse_launchv ((const gchar **) &argv[1], &error);
125   if (error) {
126     g_print ("pipeline could not be constructed: %s\n", error->message);
127     g_print ("Please give a complete pipeline  with a 'level' element.\n");
128     g_print ("Example: sinesrc ! level ! %s\n", DEFAULT_AUDIOSINK);
129     g_error_free (error);
130     return 1;
131   }
132
133   level = gst_bin_get_by_name (GST_BIN (pipeline), "level0");
134   if (level == NULL) {
135     g_print ("Please give a pipeline with a 'level' element in it\n");
136     return 1;
137   }
138
139   g_object_set (level, "signal", TRUE, NULL);
140   g_signal_connect (level, "level", G_CALLBACK (level_callback), NULL);
141
142
143   /* setup GUI */
144   setup_gui ();
145
146   /* connect level signal */
147
148   /* go to main loop */
149   gst_element_set_state (pipeline, GST_STATE_PLAYING);
150   g_idle_add (idler, pipeline);
151
152   gtk_main ();
153
154   return 0;
155 }