tests: work on porting the unit tests
[platform/upstream/gstreamer.git] / tests / examples / app / appsink-src.c
1 #include <gst/gst.h>
2
3 #include <string.h>
4
5 #include <gst/app/gstappsrc.h>
6 #include <gst/app/gstappsink.h>
7
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";
11
12 typedef struct
13 {
14   GMainLoop *loop;
15   GstElement *source;
16   GstElement *sink;
17 } ProgramData;
18
19 /* called when the appsink notifies us that there is a new buffer ready for
20  * processing */
21 static void
22 on_new_buffer_from_source (GstElement * elt, ProgramData * data)
23 {
24   guint size;
25   GstBuffer *app_buffer, *buffer;
26   GstElement *source;
27
28   /* get the buffer from appsink */
29   buffer = gst_app_sink_pull_buffer (GST_APP_SINK (elt));
30
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);
36
37   gst_buffer_copy_into (app_buffer, buffer, GST_BUFFER_COPY_MEMORY, 0, size);
38
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));
42
43   /* we don't need the appsink buffer anymore */
44   gst_buffer_unref (buffer);
45
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);
49 }
50
51 /* called when we get a GstMessage from the source pipeline when we get EOS, we
52  * notify the appsrc of it. */
53 static gboolean
54 on_source_message (GstBus * bus, GstMessage * message, ProgramData * data)
55 {
56   GstElement *source;
57
58   switch (GST_MESSAGE_TYPE (message)) {
59     case GST_MESSAGE_EOS:
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));
63       break;
64     case GST_MESSAGE_ERROR:
65       g_print ("Received error\n");
66       g_main_loop_quit (data->loop);
67       break;
68     default:
69       break;
70   }
71   return TRUE;
72 }
73
74 /* called when we get a GstMessage from the sink pipeline when we get EOS, we
75  * exit the mainloop and this testapp. */
76 static gboolean
77 on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data)
78 {
79   /* nil */
80   switch (GST_MESSAGE_TYPE (message)) {
81     case GST_MESSAGE_EOS:
82       g_print ("Finished playback\n");
83       g_main_loop_quit (data->loop);
84       break;
85     case GST_MESSAGE_ERROR:
86       g_print ("Received error\n");
87       g_main_loop_quit (data->loop);
88       break;
89     default:
90       break;
91   }
92   return TRUE;
93 }
94
95 int
96 main (int argc, char *argv[])
97 {
98   gchar *filename = NULL;
99   ProgramData *data = NULL;
100   gchar *string = NULL;
101   GstBus *bus = NULL;
102   GstElement *testsink = NULL;
103   GstElement *testsource = NULL;
104
105   gst_init (&argc, &argv);
106
107   if (argc == 2)
108     filename = g_strdup (argv[1]);
109   else
110     filename = g_strdup ("/usr/share/sounds/ekiga/ring.wav");
111
112   data = g_new0 (ProgramData, 1);
113
114   data->loop = g_main_loop_new (NULL, FALSE);
115
116   /* setting up source pipeline, we read from a file and convert to our desired
117    * caps. */
118   string =
119       g_strdup_printf
120       ("filesrc location=\"%s\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"%s\" name=testsink",
121       filename, audio_caps);
122   g_free (filename);
123   data->source = gst_parse_launch (string, NULL);
124   g_free (string);
125
126   if (data->source == NULL) {
127     g_print ("Bad source\n");
128     return -1;
129   }
130
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);
135
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);
144
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
148    * memory. */
149   string =
150       g_strdup_printf ("appsrc name=testsource caps=\"%s\" ! autoaudiosink",
151       audio_caps);
152   data->sink = gst_parse_launch (string, NULL);
153   g_free (string);
154
155   if (data->sink == NULL) {
156     g_print ("Bad sink\n");
157     return -1;
158   }
159
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);
166
167   bus = gst_element_get_bus (data->sink);
168   gst_bus_add_watch (bus, (GstBusFunc) on_sink_message, data);
169   gst_object_unref (bus);
170
171   /* launching things */
172   gst_element_set_state (data->sink, GST_STATE_PLAYING);
173   gst_element_set_state (data->source, GST_STATE_PLAYING);
174
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");
180
181   gst_element_set_state (data->source, GST_STATE_NULL);
182   gst_element_set_state (data->sink, GST_STATE_NULL);
183
184   gst_object_unref (data->source);
185   gst_object_unref (data->sink);
186   g_main_loop_unref (data->loop);
187   g_free (data);
188
189   return 0;
190 }