1 /* GStreamer
2 *
3 * appsrc-src2.c: example for using gst_app_src_push_sample().
4 *
5 * Copyright (C) 2014 Nicola Murino <nicola.murino@gmail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #include <gst/gst.h>
24
25 #include <string.h>
26
27 #include <gst/app/gstappsrc.h>
28 #include <gst/app/gstappsink.h>
29
30 /*
31 * In this sample we show the usage of gst_app_src_push_sample in push
32 * mode, this method set the appsrc caps based on the caps from the sample
33 *
34 */
35
36 typedef struct
37 {
38 GMainLoop *loop;
39 GstElement *source;
40 GstElement *sink;
41 } ProgramData;
42
43 /* called when the appsink notifies us that there is a new buffer ready for
44 * processing */
45
46 static GstFlowReturn
on_new_sample_from_sink(GstElement * elt,ProgramData * data)47 on_new_sample_from_sink (GstElement * elt, ProgramData * data)
48 {
49 GstSample *sample;
50 GstElement *source;
51 GstFlowReturn ret;
52
53 /* get the sample from appsink */
54 sample = gst_app_sink_pull_sample (GST_APP_SINK (elt));
55
56 /* get source an push new sample */
57 source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
58 ret = gst_app_src_push_sample (GST_APP_SRC (source), sample);
59 gst_object_unref (source);
60
61 /* we don't need the appsink sample anymore */
62 gst_sample_unref (sample);
63
64 return ret;
65 }
66
67 /* called when we get a GstMessage from the source pipeline when we get EOS, we
68 * notify the appsrc of it. */
69 static gboolean
on_source_message(GstBus * bus,GstMessage * message,ProgramData * data)70 on_source_message (GstBus * bus, GstMessage * message, ProgramData * data)
71 {
72 GstElement *source;
73
74 switch (GST_MESSAGE_TYPE (message)) {
75 case GST_MESSAGE_EOS:
76 g_print ("The source got dry\n");
77 source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
78 gst_app_src_end_of_stream (GST_APP_SRC (source));
79 gst_object_unref (source);
80 break;
81 case GST_MESSAGE_ERROR:
82 g_print ("Received error\n");
83 g_main_loop_quit (data->loop);
84 break;
85 default:
86 break;
87 }
88 return TRUE;
89 }
90
91 /* called when we get a GstMessage from the sink pipeline when we get EOS, we
92 * exit the mainloop and this testapp. */
93 static gboolean
on_sink_message(GstBus * bus,GstMessage * message,ProgramData * data)94 on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data)
95 {
96 /* nil */
97 switch (GST_MESSAGE_TYPE (message)) {
98 case GST_MESSAGE_EOS:
99 g_print ("Finished playback\n");
100 g_main_loop_quit (data->loop);
101 break;
102 case GST_MESSAGE_ERROR:
103 g_print ("Received error\n");
104 g_main_loop_quit (data->loop);
105 break;
106 default:
107 break;
108 }
109 return TRUE;
110 }
111
112 int
main(int argc,char * argv[])113 main (int argc, char *argv[])
114 {
115 ProgramData *data = NULL;
116 gchar *string = NULL;
117 GstBus *bus = NULL;
118 GstElement *testsink = NULL;
119 GstElement *testsource = NULL;
120
121 gst_init (&argc, &argv);
122
123 data = g_new0 (ProgramData, 1);
124
125 data->loop = g_main_loop_new (NULL, FALSE);
126
127 /* setting up source pipeline, we read from a file and convert to our desired
128 * caps. */
129 string =
130 g_strdup_printf
131 ("audiotestsrc num-buffers=200 ! wavenc ! wavparse ! appsink name=testsink");
132 data->source = gst_parse_launch (string, NULL);
133 g_free (string);
134
135 if (data->source == NULL) {
136 g_print ("Bad source\n");
137 g_main_loop_unref (data->loop);
138 g_free (data);
139 return -1;
140 }
141
142 /* to be notified of messages from this pipeline, mostly EOS */
143 bus = gst_element_get_bus (data->source);
144 gst_bus_add_watch (bus, (GstBusFunc) on_source_message, data);
145 gst_object_unref (bus);
146
147 /* we use appsink in push mode, it sends us a signal when data is available
148 * and we pull out the data in the signal callback. We want the appsink to
149 * push as fast as it can, hence the sync=false */
150 testsink = gst_bin_get_by_name (GST_BIN (data->source), "testsink");
151 g_object_set (G_OBJECT (testsink), "emit-signals", TRUE, "sync", FALSE, NULL);
152 g_signal_connect (testsink, "new-sample",
153 G_CALLBACK (on_new_sample_from_sink), data);
154 gst_object_unref (testsink);
155
156 /* setting up sink pipeline, we push audio data into this pipeline that will
157 * then play it back using the default audio sink. */
158 string =
159 g_strdup_printf
160 ("appsrc name=testsource ! audioconvert ! audioresample ! autoaudiosink");
161 data->sink = gst_parse_launch (string, NULL);
162 g_free (string);
163
164 if (data->sink == NULL) {
165 g_print ("Bad sink\n");
166 g_main_loop_unref (data->loop);
167 g_free (data);
168 return -1;
169 }
170
171 testsource = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
172 /* configure for time-based format */
173 g_object_set (testsource, "format", GST_FORMAT_TIME, NULL);
174 /* uncomment the next line to block when appsrc has buffered enough */
175 /* g_object_set (testsource, "block", TRUE, NULL); */
176 gst_object_unref (testsource);
177
178 bus = gst_element_get_bus (data->sink);
179 gst_bus_add_watch (bus, (GstBusFunc) on_sink_message, data);
180 gst_object_unref (bus);
181
182 /* launching things */
183 gst_element_set_state (data->sink, GST_STATE_PLAYING);
184 gst_element_set_state (data->source, GST_STATE_PLAYING);
185
186 /* let's run !, this loop will quit when the sink pipeline goes EOS or when an
187 * error occurs in the source or sink pipelines. */
188 g_print ("Let's run!\n");
189 g_main_loop_run (data->loop);
190 g_print ("Going out\n");
191
192 gst_element_set_state (data->source, GST_STATE_NULL);
193 gst_element_set_state (data->sink, GST_STATE_NULL);
194
195 gst_object_unref (data->source);
196 gst_object_unref (data->sink);
197 g_main_loop_unref (data->loop);
198 g_free (data);
199
200 return 0;
201 }
202