rtsprange: use gst_util_gdouble_to_guint64 in get_seconds
[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,format=S16LE,channels=1,rate=8000, layout=interleaved";
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 GstFlowReturn
22 on_new_sample_from_sink (GstElement * elt, ProgramData * data)
23 {
24   GstSample *sample;
25   GstBuffer *app_buffer, *buffer;
26   GstElement *source;
27
28   /* get the sample from appsink */
29   sample = gst_app_sink_pull_sample (GST_APP_SINK (elt));
30   buffer = gst_sample_get_buffer (sample);
31
32   /* make a copy */
33   app_buffer = gst_buffer_copy (buffer);
34
35   /* we don't need the appsink sample anymore */
36   gst_sample_unref (sample);
37
38   /* get source an push new buffer */
39   source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
40   return gst_app_src_push_buffer (GST_APP_SRC (source), app_buffer);
41 }
42
43 /* called when we get a GstMessage from the source pipeline when we get EOS, we
44  * notify the appsrc of it. */
45 static gboolean
46 on_source_message (GstBus * bus, GstMessage * message, ProgramData * data)
47 {
48   GstElement *source;
49
50   switch (GST_MESSAGE_TYPE (message)) {
51     case GST_MESSAGE_EOS:
52       g_print ("The source got dry\n");
53       source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
54       gst_app_src_end_of_stream (GST_APP_SRC (source));
55       break;
56     case GST_MESSAGE_ERROR:
57       g_print ("Received error\n");
58       g_main_loop_quit (data->loop);
59       break;
60     default:
61       break;
62   }
63   return TRUE;
64 }
65
66 /* called when we get a GstMessage from the sink pipeline when we get EOS, we
67  * exit the mainloop and this testapp. */
68 static gboolean
69 on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data)
70 {
71   /* nil */
72   switch (GST_MESSAGE_TYPE (message)) {
73     case GST_MESSAGE_EOS:
74       g_print ("Finished playback\n");
75       g_main_loop_quit (data->loop);
76       break;
77     case GST_MESSAGE_ERROR:
78       g_print ("Received error\n");
79       g_main_loop_quit (data->loop);
80       break;
81     default:
82       break;
83   }
84   return TRUE;
85 }
86
87 int
88 main (int argc, char *argv[])
89 {
90   gchar *filename = NULL;
91   ProgramData *data = NULL;
92   gchar *string = NULL;
93   GstBus *bus = NULL;
94   GstElement *testsink = NULL;
95   GstElement *testsource = NULL;
96
97   gst_init (&argc, &argv);
98
99   if (argc == 2)
100     filename = g_strdup (argv[1]);
101   else
102     filename = g_strdup ("/usr/share/sounds/ekiga/ring.wav");
103
104   data = g_new0 (ProgramData, 1);
105
106   data->loop = g_main_loop_new (NULL, FALSE);
107
108   /* setting up source pipeline, we read from a file and convert to our desired
109    * caps. */
110   string =
111       g_strdup_printf
112       ("filesrc location=\"%s\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"%s\" name=testsink",
113       filename, audio_caps);
114   g_free (filename);
115   data->source = gst_parse_launch (string, NULL);
116   g_free (string);
117
118   if (data->source == NULL) {
119     g_print ("Bad source\n");
120     return -1;
121   }
122
123   /* to be notified of messages from this pipeline, mostly EOS */
124   bus = gst_element_get_bus (data->source);
125   gst_bus_add_watch (bus, (GstBusFunc) on_source_message, data);
126   gst_object_unref (bus);
127
128   /* we use appsink in push mode, it sends us a signal when data is available
129    * and we pull out the data in the signal callback. We want the appsink to
130    * push as fast as it can, hence the sync=false */
131   testsink = gst_bin_get_by_name (GST_BIN (data->source), "testsink");
132   g_object_set (G_OBJECT (testsink), "emit-signals", TRUE, "sync", FALSE, NULL);
133   g_signal_connect (testsink, "new-sample",
134       G_CALLBACK (on_new_sample_from_sink), data);
135   gst_object_unref (testsink);
136
137   /* setting up sink pipeline, we push audio data into this pipeline that will
138    * then play it back using the default audio sink. We have no blocking
139    * behaviour on the src which means that we will push the entire file into
140    * memory. */
141   string =
142       g_strdup_printf ("appsrc name=testsource caps=\"%s\" ! autoaudiosink",
143       audio_caps);
144   data->sink = gst_parse_launch (string, NULL);
145   g_free (string);
146
147   if (data->sink == NULL) {
148     g_print ("Bad sink\n");
149     return -1;
150   }
151
152   testsource = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
153   /* configure for time-based format */
154   g_object_set (testsource, "format", GST_FORMAT_TIME, NULL);
155   /* uncomment the next line to block when appsrc has buffered enough */
156   /* g_object_set (testsource, "block", TRUE, NULL); */
157   gst_object_unref (testsource);
158
159   bus = gst_element_get_bus (data->sink);
160   gst_bus_add_watch (bus, (GstBusFunc) on_sink_message, data);
161   gst_object_unref (bus);
162
163   /* launching things */
164   gst_element_set_state (data->sink, GST_STATE_PLAYING);
165   gst_element_set_state (data->source, GST_STATE_PLAYING);
166
167   /* let's run !, this loop will quit when the sink pipeline goes EOS or when an
168    * error occurs in the source or sink pipelines. */
169   g_print ("Let's run!\n");
170   g_main_loop_run (data->loop);
171   g_print ("Going out\n");
172
173   gst_element_set_state (data->source, GST_STATE_NULL);
174   gst_element_set_state (data->sink, GST_STATE_NULL);
175
176   gst_object_unref (data->source);
177   gst_object_unref (data->sink);
178   g_main_loop_unref (data->loop);
179   g_free (data);
180
181   return 0;
182 }