• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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