1 /* GstInterTest
2 * Copyright (C) 2011 David Schleef <ds@schleef.org>
3 * Copyright (C) 2010 Entropy Wave Inc
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <gst/gst.h>
32 #include <stdlib.h>
33
34 //#define GETTEXT_PACKAGE "intertest"
35
36
37 typedef struct _GstInterTest GstInterTest;
38 struct _GstInterTest
39 {
40 GstElement *pipeline;
41 GstBus *bus;
42 GMainLoop *main_loop;
43
44 GstElement *source_element;
45 GstElement *sink_element;
46
47 gboolean paused_for_buffering;
48 guint timer_id;
49 };
50
51 GstInterTest *gst_inter_test_new (void);
52 void gst_inter_test_free (GstInterTest * intertest);
53 void gst_inter_test_create_pipeline_server (GstInterTest * intertest);
54 void gst_inter_test_create_pipeline_vts (GstInterTest * intertest);
55 void gst_inter_test_create_pipeline_playbin (GstInterTest * intertest,
56 const char *uri);
57 void gst_inter_test_start (GstInterTest * intertest);
58 void gst_inter_test_stop (GstInterTest * intertest);
59
60 static gboolean gst_inter_test_handle_message (GstBus * bus,
61 GstMessage * message, gpointer data);
62 static gboolean onesecond_timer (gpointer priv);
63
64
65 gboolean verbose;
66
67 static GOptionEntry entries[] = {
68 {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL},
69
70 {NULL}
71
72 };
73
74 int
main(int argc,char * argv[])75 main (int argc, char *argv[])
76 {
77 GError *error = NULL;
78 GOptionContext *context;
79 GstInterTest *intertest1;
80 GstInterTest *intertest2;
81 GMainLoop *main_loop;
82
83 context = g_option_context_new ("- Internal src/sink test");
84 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
85 g_option_context_add_group (context, gst_init_get_option_group ());
86 if (!g_option_context_parse (context, &argc, &argv, &error)) {
87 g_print ("option parsing failed: %s\n", error->message);
88 g_option_context_free (context);
89 g_clear_error (&error);
90 exit (1);
91 }
92 g_option_context_free (context);
93
94 intertest1 = gst_inter_test_new ();
95 gst_inter_test_create_pipeline_server (intertest1);
96 gst_inter_test_start (intertest1);
97
98 intertest2 = gst_inter_test_new ();
99 gst_inter_test_create_pipeline_playbin (intertest2, NULL);
100 gst_inter_test_start (intertest2);
101
102 main_loop = g_main_loop_new (NULL, TRUE);
103 intertest1->main_loop = main_loop;
104 intertest2->main_loop = main_loop;
105
106 g_main_loop_run (main_loop);
107 g_main_loop_unref (main_loop);
108
109 exit (0);
110 }
111
112
113 GstInterTest *
gst_inter_test_new(void)114 gst_inter_test_new (void)
115 {
116 GstInterTest *intertest;
117
118 intertest = g_new0 (GstInterTest, 1);
119
120 return intertest;
121 }
122
123 void
gst_inter_test_free(GstInterTest * intertest)124 gst_inter_test_free (GstInterTest * intertest)
125 {
126 if (intertest->source_element) {
127 gst_object_unref (intertest->source_element);
128 intertest->source_element = NULL;
129 }
130 if (intertest->sink_element) {
131 gst_object_unref (intertest->sink_element);
132 intertest->sink_element = NULL;
133 }
134
135 if (intertest->bus) {
136 gst_object_unref (intertest->bus);
137 intertest->bus = NULL;
138 }
139
140 if (intertest->pipeline) {
141 gst_element_set_state (intertest->pipeline, GST_STATE_NULL);
142 gst_object_unref (intertest->pipeline);
143 intertest->pipeline = NULL;
144 }
145 g_free (intertest);
146 }
147
148 void
gst_inter_test_create_pipeline_playbin(GstInterTest * intertest,const char * uri)149 gst_inter_test_create_pipeline_playbin (GstInterTest * intertest,
150 const char *uri)
151 {
152 GstElement *pipeline;
153
154 if (uri == NULL) {
155 gst_inter_test_create_pipeline_vts (intertest);
156 return;
157 }
158
159 pipeline = gst_pipeline_new (NULL);
160 gst_bin_add (GST_BIN (pipeline),
161 gst_element_factory_make ("playbin", "source"));
162
163 intertest->pipeline = pipeline;
164
165 gst_pipeline_set_auto_flush_bus (GST_PIPELINE (pipeline), FALSE);
166 intertest->bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
167 gst_bus_add_watch (intertest->bus, gst_inter_test_handle_message, intertest);
168
169 intertest->source_element =
170 gst_bin_get_by_name (GST_BIN (pipeline), "source");
171 g_print ("source_element is %p\n", intertest->source_element);
172
173 g_print ("setting uri to %s\n", uri);
174 g_object_set (intertest->source_element, "uri", uri, NULL);
175 }
176
177 void
gst_inter_test_create_pipeline_vts(GstInterTest * intertest)178 gst_inter_test_create_pipeline_vts (GstInterTest * intertest)
179 {
180 GString *pipe_desc;
181 GstElement *pipeline;
182 GError *error = NULL;
183
184 pipe_desc = g_string_new ("");
185
186 g_string_append (pipe_desc, "videotestsrc name=source num-buffers=100 ! ");
187 g_string_append (pipe_desc,
188 "video/x-raw,format=(string)I420,width=320,height=240 ! ");
189 g_string_append (pipe_desc, "timeoverlay ! ");
190 g_string_append (pipe_desc, "intervideosink name=sink sync=true ");
191 g_string_append (pipe_desc,
192 "audiotestsrc samplesperbuffer=1600 num-buffers=100 ! audioconvert ! ");
193 g_string_append (pipe_desc, "interaudiosink sync=true ");
194
195 if (verbose)
196 g_print ("pipeline: %s\n", pipe_desc->str);
197
198 pipeline = (GstElement *) gst_parse_launch (pipe_desc->str, &error);
199 g_string_free (pipe_desc, TRUE);
200
201 if (error) {
202 g_print ("pipeline parsing error: %s\n", error->message);
203 gst_object_unref (pipeline);
204 g_clear_error (&error);
205 return;
206 }
207
208 intertest->pipeline = pipeline;
209
210 gst_pipeline_set_auto_flush_bus (GST_PIPELINE (pipeline), FALSE);
211 intertest->bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
212 gst_bus_add_watch (intertest->bus, gst_inter_test_handle_message, intertest);
213
214 intertest->source_element =
215 gst_bin_get_by_name (GST_BIN (pipeline), "source");
216 intertest->sink_element = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
217 }
218
219 void
gst_inter_test_create_pipeline_server(GstInterTest * intertest)220 gst_inter_test_create_pipeline_server (GstInterTest * intertest)
221 {
222 GString *pipe_desc;
223 GstElement *pipeline;
224 GError *error = NULL;
225
226 pipe_desc = g_string_new ("");
227
228 g_string_append (pipe_desc, "intervideosrc ! queue ! ");
229 g_string_append (pipe_desc, "xvimagesink name=sink ");
230 g_string_append (pipe_desc, "interaudiosrc ! queue ! ");
231 g_string_append (pipe_desc, "alsasink ");
232
233 if (verbose)
234 g_print ("pipeline: %s\n", pipe_desc->str);
235
236 pipeline = (GstElement *) gst_parse_launch (pipe_desc->str, &error);
237 g_string_free (pipe_desc, TRUE);
238
239 if (error) {
240 g_print ("pipeline parsing error: %s\n", error->message);
241 gst_object_unref (pipeline);
242 g_clear_error (&error);
243 return;
244 }
245
246 intertest->pipeline = pipeline;
247
248 gst_pipeline_set_auto_flush_bus (GST_PIPELINE (pipeline), FALSE);
249 intertest->bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
250 gst_bus_add_watch (intertest->bus, gst_inter_test_handle_message, intertest);
251
252 intertest->source_element =
253 gst_bin_get_by_name (GST_BIN (pipeline), "source");
254 intertest->sink_element = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
255 }
256
257 void
gst_inter_test_start(GstInterTest * intertest)258 gst_inter_test_start (GstInterTest * intertest)
259 {
260 gst_element_set_state (intertest->pipeline, GST_STATE_READY);
261
262 intertest->timer_id = g_timeout_add (1000, onesecond_timer, intertest);
263 }
264
265 void
gst_inter_test_stop(GstInterTest * intertest)266 gst_inter_test_stop (GstInterTest * intertest)
267 {
268 gst_element_set_state (intertest->pipeline, GST_STATE_NULL);
269
270 g_source_remove (intertest->timer_id);
271 }
272
273 static void
gst_inter_test_handle_eos(GstInterTest * intertest)274 gst_inter_test_handle_eos (GstInterTest * intertest)
275 {
276 gst_inter_test_stop (intertest);
277 }
278
279 static void
gst_inter_test_handle_error(GstInterTest * intertest,GError * error,const char * debug)280 gst_inter_test_handle_error (GstInterTest * intertest, GError * error,
281 const char *debug)
282 {
283 g_print ("error: %s\n", error->message);
284 gst_inter_test_stop (intertest);
285 }
286
287 static void
gst_inter_test_handle_warning(GstInterTest * intertest,GError * error,const char * debug)288 gst_inter_test_handle_warning (GstInterTest * intertest, GError * error,
289 const char *debug)
290 {
291 g_print ("warning: %s\n", error->message);
292 }
293
294 static void
gst_inter_test_handle_info(GstInterTest * intertest,GError * error,const char * debug)295 gst_inter_test_handle_info (GstInterTest * intertest, GError * error,
296 const char *debug)
297 {
298 g_print ("info: %s\n", error->message);
299 }
300
301 static void
gst_inter_test_handle_null_to_ready(GstInterTest * intertest)302 gst_inter_test_handle_null_to_ready (GstInterTest * intertest)
303 {
304 gst_element_set_state (intertest->pipeline, GST_STATE_PAUSED);
305
306 }
307
308 static void
gst_inter_test_handle_ready_to_paused(GstInterTest * intertest)309 gst_inter_test_handle_ready_to_paused (GstInterTest * intertest)
310 {
311 if (!intertest->paused_for_buffering) {
312 gst_element_set_state (intertest->pipeline, GST_STATE_PLAYING);
313 }
314 }
315
316 static void
gst_inter_test_handle_paused_to_playing(GstInterTest * intertest)317 gst_inter_test_handle_paused_to_playing (GstInterTest * intertest)
318 {
319
320 }
321
322 static void
gst_inter_test_handle_playing_to_paused(GstInterTest * intertest)323 gst_inter_test_handle_playing_to_paused (GstInterTest * intertest)
324 {
325
326 }
327
328 static void
gst_inter_test_handle_paused_to_ready(GstInterTest * intertest)329 gst_inter_test_handle_paused_to_ready (GstInterTest * intertest)
330 {
331
332 }
333
334 static void
gst_inter_test_handle_ready_to_null(GstInterTest * intertest)335 gst_inter_test_handle_ready_to_null (GstInterTest * intertest)
336 {
337 //g_main_loop_quit (intertest->main_loop);
338
339 }
340
341
342 static gboolean
gst_inter_test_handle_message(GstBus * bus,GstMessage * message,gpointer data)343 gst_inter_test_handle_message (GstBus * bus, GstMessage * message,
344 gpointer data)
345 {
346 GstInterTest *intertest = (GstInterTest *) data;
347
348 switch (GST_MESSAGE_TYPE (message)) {
349 case GST_MESSAGE_EOS:
350 gst_inter_test_handle_eos (intertest);
351 break;
352 case GST_MESSAGE_ERROR:
353 {
354 GError *error = NULL;
355 gchar *debug;
356
357 gst_message_parse_error (message, &error, &debug);
358 gst_inter_test_handle_error (intertest, error, debug);
359 g_clear_error (&error);
360 g_free (debug);
361 }
362 break;
363 case GST_MESSAGE_WARNING:
364 {
365 GError *error = NULL;
366 gchar *debug;
367
368 gst_message_parse_warning (message, &error, &debug);
369 gst_inter_test_handle_warning (intertest, error, debug);
370 g_clear_error (&error);
371 g_free (debug);
372 }
373 break;
374 case GST_MESSAGE_INFO:
375 {
376 GError *error = NULL;
377 gchar *debug;
378
379 gst_message_parse_info (message, &error, &debug);
380 gst_inter_test_handle_info (intertest, error, debug);
381 g_clear_error (&error);
382 g_free (debug);
383 }
384 break;
385 case GST_MESSAGE_TAG:
386 {
387 GstTagList *tag_list;
388
389 gst_message_parse_tag (message, &tag_list);
390 if (verbose)
391 g_print ("tag\n");
392 }
393 break;
394 case GST_MESSAGE_STATE_CHANGED:
395 {
396 GstState oldstate, newstate, pending;
397
398 gst_message_parse_state_changed (message, &oldstate, &newstate, &pending);
399 if (GST_ELEMENT (message->src) == intertest->pipeline) {
400 if (verbose)
401 g_print ("state change from %s to %s\n",
402 gst_element_state_get_name (oldstate),
403 gst_element_state_get_name (newstate));
404 switch (GST_STATE_TRANSITION (oldstate, newstate)) {
405 case GST_STATE_CHANGE_NULL_TO_READY:
406 gst_inter_test_handle_null_to_ready (intertest);
407 break;
408 case GST_STATE_CHANGE_READY_TO_PAUSED:
409 gst_inter_test_handle_ready_to_paused (intertest);
410 break;
411 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
412 gst_inter_test_handle_paused_to_playing (intertest);
413 break;
414 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
415 gst_inter_test_handle_playing_to_paused (intertest);
416 break;
417 case GST_STATE_CHANGE_PAUSED_TO_READY:
418 gst_inter_test_handle_paused_to_ready (intertest);
419 break;
420 case GST_STATE_CHANGE_READY_TO_NULL:
421 gst_inter_test_handle_ready_to_null (intertest);
422 break;
423 default:
424 if (verbose)
425 g_print ("unknown state change from %s to %s\n",
426 gst_element_state_get_name (oldstate),
427 gst_element_state_get_name (newstate));
428 }
429 }
430 }
431 break;
432 case GST_MESSAGE_BUFFERING:
433 {
434 int percent;
435 gst_message_parse_buffering (message, &percent);
436 //g_print("buffering %d\n", percent);
437 if (!intertest->paused_for_buffering && percent < 100) {
438 g_print ("pausing for buffing\n");
439 intertest->paused_for_buffering = TRUE;
440 gst_element_set_state (intertest->pipeline, GST_STATE_PAUSED);
441 } else if (intertest->paused_for_buffering && percent == 100) {
442 g_print ("unpausing for buffing\n");
443 intertest->paused_for_buffering = FALSE;
444 gst_element_set_state (intertest->pipeline, GST_STATE_PLAYING);
445 }
446 }
447 break;
448 case GST_MESSAGE_STATE_DIRTY:
449 case GST_MESSAGE_CLOCK_PROVIDE:
450 case GST_MESSAGE_CLOCK_LOST:
451 case GST_MESSAGE_NEW_CLOCK:
452 case GST_MESSAGE_STRUCTURE_CHANGE:
453 case GST_MESSAGE_STREAM_STATUS:
454 break;
455 case GST_MESSAGE_STEP_DONE:
456 case GST_MESSAGE_APPLICATION:
457 case GST_MESSAGE_ELEMENT:
458 case GST_MESSAGE_SEGMENT_START:
459 case GST_MESSAGE_SEGMENT_DONE:
460 case GST_MESSAGE_LATENCY:
461 case GST_MESSAGE_ASYNC_START:
462 case GST_MESSAGE_ASYNC_DONE:
463 case GST_MESSAGE_REQUEST_STATE:
464 case GST_MESSAGE_STEP_START:
465 default:
466 if (verbose) {
467 g_print ("message: %s\n", GST_MESSAGE_TYPE_NAME (message));
468 }
469 break;
470 case GST_MESSAGE_QOS:
471 break;
472 }
473
474 return TRUE;
475 }
476
477
478
479 static gboolean
onesecond_timer(gpointer priv)480 onesecond_timer (gpointer priv)
481 {
482 //GstInterTest *intertest = (GstInterTest *)priv;
483
484 g_print (".\n");
485
486 return TRUE;
487 }
488
489
490
491 /* helper functions */
492
493 #if 0
494 gboolean
495 have_element (const gchar * element_name)
496 {
497 GstPluginFeature *feature;
498
499 feature = gst_default_registry_find_feature (element_name,
500 GST_TYPE_ELEMENT_FACTORY);
501 if (feature) {
502 g_object_unref (feature);
503 return TRUE;
504 }
505 return FALSE;
506 }
507 #endif
508