5 #include <gst/app/gstappsrc.h>
6 #include <gst/app/gstappsink.h>
8 /* these are the caps we are going to pass through the appsink and appsrc */
9 const gchar *audio_caps =
10 "audio/x-raw-int,channels=1,rate=8000,signed=(boolean)true,width=16,depth=16,endianness=1234";
19 /* called when the appsink notifies us that there is a new buffer ready for
22 on_new_buffer_from_source (GstElement * elt, ProgramData * data)
25 GstBuffer *app_buffer, *buffer;
28 /* get the buffer from appsink */
29 buffer = gst_app_sink_pull_buffer (GST_APP_SINK (elt));
31 /* turn it into an app buffer, it's not really needed, we could simply push
32 * the retrieved buffer from appsink into appsrc just fine. */
33 size = gst_buffer_get_size (buffer);
34 g_print ("Pushing a buffer of size %d\n", size);
35 app_buffer = gst_buffer_new_and_alloc (size);
37 gst_buffer_copy_into (app_buffer, buffer, GST_BUFFER_COPY_MEMORY, 0, size);
39 /* newer basesrc will set caps for use automatically but it does not really
40 * hurt to set it on the buffer again */
41 gst_buffer_set_caps (app_buffer, GST_BUFFER_CAPS (buffer));
43 /* we don't need the appsink buffer anymore */
44 gst_buffer_unref (buffer);
46 /* get source an push new buffer */
47 source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
48 gst_app_src_push_buffer (GST_APP_SRC (source), app_buffer);
51 /* called when we get a GstMessage from the source pipeline when we get EOS, we
52 * notify the appsrc of it. */
54 on_source_message (GstBus * bus, GstMessage * message, ProgramData * data)
58 switch (GST_MESSAGE_TYPE (message)) {
60 g_print ("The source got dry\n");
61 source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
62 gst_app_src_end_of_stream (GST_APP_SRC (source));
64 case GST_MESSAGE_ERROR:
65 g_print ("Received error\n");
66 g_main_loop_quit (data->loop);
74 /* called when we get a GstMessage from the sink pipeline when we get EOS, we
75 * exit the mainloop and this testapp. */
77 on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data)
80 switch (GST_MESSAGE_TYPE (message)) {
82 g_print ("Finished playback\n");
83 g_main_loop_quit (data->loop);
85 case GST_MESSAGE_ERROR:
86 g_print ("Received error\n");
87 g_main_loop_quit (data->loop);
96 main (int argc, char *argv[])
98 gchar *filename = NULL;
99 ProgramData *data = NULL;
100 gchar *string = NULL;
102 GstElement *testsink = NULL;
103 GstElement *testsource = NULL;
105 gst_init (&argc, &argv);
108 filename = g_strdup (argv[1]);
110 filename = g_strdup ("/usr/share/sounds/ekiga/ring.wav");
112 data = g_new0 (ProgramData, 1);
114 data->loop = g_main_loop_new (NULL, FALSE);
116 /* setting up source pipeline, we read from a file and convert to our desired
120 ("filesrc location=\"%s\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"%s\" name=testsink",
121 filename, audio_caps);
123 data->source = gst_parse_launch (string, NULL);
126 if (data->source == NULL) {
127 g_print ("Bad source\n");
131 /* to be notified of messages from this pipeline, mostly EOS */
132 bus = gst_element_get_bus (data->source);
133 gst_bus_add_watch (bus, (GstBusFunc) on_source_message, data);
134 gst_object_unref (bus);
136 /* we use appsink in push mode, it sends us a signal when data is available
137 * and we pull out the data in the signal callback. We want the appsink to
138 * push as fast as it can, hence the sync=false */
139 testsink = gst_bin_get_by_name (GST_BIN (data->source), "testsink");
140 g_object_set (G_OBJECT (testsink), "emit-signals", TRUE, "sync", FALSE, NULL);
141 g_signal_connect (testsink, "new-buffer",
142 G_CALLBACK (on_new_buffer_from_source), data);
143 gst_object_unref (testsink);
145 /* setting up sink pipeline, we push audio data into this pipeline that will
146 * then play it back using the default audio sink. We have no blocking
147 * behaviour on the src which means that we will push the entire file into
150 g_strdup_printf ("appsrc name=testsource caps=\"%s\" ! autoaudiosink",
152 data->sink = gst_parse_launch (string, NULL);
155 if (data->sink == NULL) {
156 g_print ("Bad sink\n");
160 testsource = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
161 /* configure for time-based format */
162 g_object_set (testsource, "format", GST_FORMAT_TIME, NULL);
163 /* uncomment the next line to block when appsrc has buffered enough */
164 /* g_object_set (testsource, "block", TRUE, NULL); */
165 gst_object_unref (testsource);
167 bus = gst_element_get_bus (data->sink);
168 gst_bus_add_watch (bus, (GstBusFunc) on_sink_message, data);
169 gst_object_unref (bus);
171 /* launching things */
172 gst_element_set_state (data->sink, GST_STATE_PLAYING);
173 gst_element_set_state (data->source, GST_STATE_PLAYING);
175 /* let's run !, this loop will quit when the sink pipeline goes EOS or when an
176 * error occurs in the source or sink pipelines. */
177 g_print ("Let's run!\n");
178 g_main_loop_run (data->loop);
179 g_print ("Going out\n");
181 gst_element_set_state (data->source, GST_STATE_NULL);
182 gst_element_set_state (data->sink, GST_STATE_NULL);
184 gst_object_unref (data->source);
185 gst_object_unref (data->sink);
186 g_main_loop_unref (data->loop);