Macro qtTrIdx() replaced by tr() and QT_TRANSLATE_NOOP()
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / 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 #include <gst/app/gstappbuffer.h>
8
9 /* these are the caps we are going to pass through the appsink and appsrc */
10 const gchar *audio_caps =
11     "audio/x-raw-int,channels=1,rate=8000,signed=(boolean)true,width=16,depth=16,endianness=1234";
12
13 typedef struct
14 {
15   GMainLoop *loop;
16   GstElement *source;
17   GstElement *sink;
18 } ProgramData;
19
20 /* called when the appsink notifies us that there is a new buffer ready for
21  * processing */
22 static void
23 on_new_buffer_from_source (GstElement * elt, ProgramData * data)
24 {
25   guint size;
26   gpointer raw_buffer;
27   GstBuffer *app_buffer, *buffer;
28   GstElement *source;
29
30   /* get the buffer from appsink */
31   buffer = gst_app_sink_pull_buffer (GST_APP_SINK (elt));
32
33   /* turn it into an app buffer, it's not really needed, we could simply push
34    * the retrieved buffer from appsink into appsrc just fine.  */
35   size = GST_BUFFER_SIZE (buffer);
36   g_print ("Pushing a buffer of size %d\n", size);
37   raw_buffer = g_malloc0 (size);
38   memcpy (raw_buffer, GST_BUFFER_DATA (buffer), size);
39   app_buffer = gst_app_buffer_new (raw_buffer, size, g_free, raw_buffer);
40
41   /* newer basesrc will set caps for use automatically but it does not really
42    * hurt to set it on the buffer again */
43   gst_buffer_set_caps (app_buffer, GST_BUFFER_CAPS (buffer));
44
45   /* we don't need the appsink buffer anymore */
46   gst_buffer_unref (buffer);
47
48   /* get source an push new buffer */
49   source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
50   gst_app_src_push_buffer (GST_APP_SRC (source), app_buffer);
51 }
52
53 /* called when we get a GstMessage from the source pipeline when we get EOS, we
54  * notify the appsrc of it. */
55 static gboolean
56 on_source_message (GstBus * bus, GstMessage * message, ProgramData * data)
57 {
58   GstElement *source;
59
60   switch (GST_MESSAGE_TYPE (message)) {
61     case GST_MESSAGE_EOS:
62       g_print ("The source got dry\n");
63       source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
64       gst_app_src_end_of_stream (GST_APP_SRC (source));
65       break;
66     case GST_MESSAGE_ERROR:
67       g_print ("Received error\n");
68       g_main_loop_quit (data->loop);
69       break;
70     default:
71       break;
72   }
73   return TRUE;
74 }
75
76 /* called when we get a GstMessage from the sink pipeline when we get EOS, we
77  * exit the mainloop and this testapp. */
78 static gboolean
79 on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data)
80 {
81   /* nil */
82   switch (GST_MESSAGE_TYPE (message)) {
83     case GST_MESSAGE_EOS:
84       g_print ("Finished playback\n");
85       g_main_loop_quit (data->loop);
86       break;
87     case GST_MESSAGE_ERROR:
88       g_print ("Received error\n");
89       g_main_loop_quit (data->loop);
90       break;
91     default:
92       break;
93   }
94   return TRUE;
95 }
96
97 int
98 main (int argc, char *argv[])
99 {
100   gchar *filename = NULL;
101   ProgramData *data = NULL;
102   gchar *string = NULL;
103   GstBus *bus = NULL;
104   GstElement *testsink = NULL;
105   GstElement *testsource = NULL;
106
107   gst_init (&argc, &argv);
108
109   if (argc == 2)
110     filename = g_strdup (argv[1]);
111   else
112     filename = g_strdup ("/usr/share/sounds/ekiga/ring.wav");
113
114   data = g_new0 (ProgramData, 1);
115
116   data->loop = g_main_loop_new (NULL, FALSE);
117
118   /* setting up source pipeline, we read from a file and convert to our desired
119    * caps. */
120   string =
121       g_strdup_printf
122       ("filesrc location=\"%s\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"%s\" name=testsink",
123       filename, audio_caps);
124   g_free (filename);
125   data->source = gst_parse_launch (string, NULL);
126   g_free (string);
127
128   if (data->source == NULL) {
129     g_print ("Bad source\n");
130     return -1;
131   }
132
133   /* to be notified of messages from this pipeline, mostly EOS */
134   bus = gst_element_get_bus (data->source);
135   gst_bus_add_watch (bus, (GstBusFunc) on_source_message, data);
136   gst_object_unref (bus);
137
138   /* we use appsink in push mode, it sends us a signal when data is available
139    * and we pull out the data in the signal callback. We want the appsink to
140    * push as fast as it can, hence the sync=false */
141   testsink = gst_bin_get_by_name (GST_BIN (data->source), "testsink");
142   g_object_set (G_OBJECT (testsink), "emit-signals", TRUE, "sync", FALSE, NULL);
143   g_signal_connect (testsink, "new-buffer",
144       G_CALLBACK (on_new_buffer_from_source), data);
145   gst_object_unref (testsink);
146
147   /* setting up sink pipeline, we push audio data into this pipeline that will
148    * then play it back using the default audio sink. We have no blocking
149    * behaviour on the src which means that we will push the entire file into
150    * memory. */
151   string =
152       g_strdup_printf ("appsrc name=testsource caps=\"%s\" ! autoaudiosink",
153       audio_caps);
154   data->sink = gst_parse_launch (string, NULL);
155   g_free (string);
156
157   if (data->sink == NULL) {
158     g_print ("Bad sink\n");
159     return -1;
160   }
161
162   testsource = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
163   /* configure for time-based format */
164   g_object_set (testsource, "format", GST_FORMAT_TIME, NULL);
165   /* uncomment the next line to block when appsrc has buffered enough */
166   /* g_object_set (testsource, "block", TRUE, NULL); */
167   gst_object_unref (testsource);
168
169   bus = gst_element_get_bus (data->sink);
170   gst_bus_add_watch (bus, (GstBusFunc) on_sink_message, data);
171   gst_object_unref (bus);
172
173   /* launching things */
174   gst_element_set_state (data->sink, GST_STATE_PLAYING);
175   gst_element_set_state (data->source, GST_STATE_PLAYING);
176
177   /* let's run !, this loop will quit when the sink pipeline goes EOS or when an
178    * error occurs in the source or sink pipelines. */
179   g_print ("Let's run!\n");
180   g_main_loop_run (data->loop);
181   g_print ("Going out\n");
182
183   gst_element_set_state (data->source, GST_STATE_NULL);
184   gst_element_set_state (data->sink, GST_STATE_NULL);
185
186   gst_object_unref (data->source);
187   gst_object_unref (data->sink);
188   g_main_loop_unref (data->loop);
189   g_free (data);
190
191   return 0;
192 }