1 /* GStreamer
2 *
3 * unit test for audiomixer
4 *
5 * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
6 * Copyright (C) 2013 Sebastian Dröge <sebastian@centricular.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27
28 #ifdef HAVE_VALGRIND
29 # include <valgrind/valgrind.h>
30 #endif
31
32 #include <gst/check/gstcheck.h>
33 #include <gst/check/gstconsistencychecker.h>
34 #include <gst/audio/audio.h>
35 #include <gst/base/gstbasesrc.h>
36 #include <gst/controller/gstdirectcontrolbinding.h>
37 #include <gst/controller/gstinterpolationcontrolsource.h>
38
39 static GMainLoop *main_loop;
40
41 /* fixtures */
42
43 static void
test_setup(void)44 test_setup (void)
45 {
46 main_loop = g_main_loop_new (NULL, FALSE);
47 }
48
49 static void
test_teardown(void)50 test_teardown (void)
51 {
52 g_main_loop_unref (main_loop);
53 main_loop = NULL;
54 }
55
56
57 /* some test helpers */
58
59 static GstElement *
setup_pipeline(GstElement * audiomixer,gint num_srcs,GstElement * capsfilter)60 setup_pipeline (GstElement * audiomixer, gint num_srcs, GstElement * capsfilter)
61 {
62 GstElement *pipeline, *src, *sink;
63 gint i;
64
65 pipeline = gst_pipeline_new ("pipeline");
66 if (!audiomixer) {
67 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
68 }
69
70 sink = gst_element_factory_make ("fakesink", "sink");
71 gst_bin_add_many (GST_BIN (pipeline), audiomixer, sink, NULL);
72
73 if (capsfilter) {
74 gst_bin_add (GST_BIN (pipeline), capsfilter);
75 gst_element_link_many (audiomixer, capsfilter, sink, NULL);
76 } else {
77 gst_element_link (audiomixer, sink);
78 }
79
80 for (i = 0; i < num_srcs; i++) {
81 src = gst_element_factory_make ("audiotestsrc", NULL);
82 g_object_set (src, "wave", 4, NULL); /* silence */
83 gst_bin_add (GST_BIN (pipeline), src);
84 gst_element_link (src, audiomixer);
85 }
86 return pipeline;
87 }
88
89 static GstCaps *
get_element_sink_pad_caps(GstElement * pipeline,const gchar * element_name)90 get_element_sink_pad_caps (GstElement * pipeline, const gchar * element_name)
91 {
92 GstElement *sink;
93 GstCaps *caps;
94 GstPad *pad;
95
96 sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
97 pad = gst_element_get_static_pad (sink, "sink");
98 caps = gst_pad_get_current_caps (pad);
99 gst_object_unref (pad);
100 gst_object_unref (sink);
101
102 return caps;
103 }
104
105 static void
set_state_and_wait(GstElement * pipeline,GstState state)106 set_state_and_wait (GstElement * pipeline, GstState state)
107 {
108 GstStateChangeReturn state_res;
109
110 /* prepare paused/playing */
111 state_res = gst_element_set_state (pipeline, state);
112 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
113
114 /* wait for preroll */
115 state_res = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
116 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
117 }
118
119 static gboolean
set_playing(GstElement * element)120 set_playing (GstElement * element)
121 {
122 GstStateChangeReturn state_res;
123
124 state_res = gst_element_set_state (element, GST_STATE_PLAYING);
125 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
126
127 return FALSE;
128 }
129
130 static void
play_and_wait(GstElement * pipeline)131 play_and_wait (GstElement * pipeline)
132 {
133 GstStateChangeReturn state_res;
134
135 g_idle_add ((GSourceFunc) set_playing, pipeline);
136
137 GST_INFO ("running main loop");
138 g_main_loop_run (main_loop);
139
140 state_res = gst_element_set_state (pipeline, GST_STATE_NULL);
141 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
142 }
143
144 static void
message_received(GstBus * bus,GstMessage * message,GstPipeline * bin)145 message_received (GstBus * bus, GstMessage * message, GstPipeline * bin)
146 {
147 GST_INFO ("bus message from \"%" GST_PTR_FORMAT "\": %" GST_PTR_FORMAT,
148 GST_MESSAGE_SRC (message), message);
149
150 switch (message->type) {
151 case GST_MESSAGE_EOS:
152 g_main_loop_quit (main_loop);
153 break;
154 case GST_MESSAGE_WARNING:{
155 GError *gerror;
156 gchar *debug;
157
158 gst_message_parse_warning (message, &gerror, &debug);
159 gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
160 g_error_free (gerror);
161 g_free (debug);
162 break;
163 }
164 case GST_MESSAGE_ERROR:{
165 GError *gerror;
166 gchar *debug;
167
168 gst_message_parse_error (message, &gerror, &debug);
169 gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
170 g_error_free (gerror);
171 g_free (debug);
172 g_main_loop_quit (main_loop);
173 break;
174 }
175 default:
176 break;
177 }
178 }
179
180 static GstBuffer *
new_buffer(gsize num_bytes,gint data,GstClockTime ts,GstClockTime dur,GstBufferFlags flags)181 new_buffer (gsize num_bytes, gint data, GstClockTime ts, GstClockTime dur,
182 GstBufferFlags flags)
183 {
184 GstMapInfo map;
185 GstBuffer *buffer = gst_buffer_new_and_alloc (num_bytes);
186
187 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
188 memset (map.data, data, map.size);
189 gst_buffer_unmap (buffer, &map);
190 GST_BUFFER_TIMESTAMP (buffer) = ts;
191 GST_BUFFER_DURATION (buffer) = dur;
192 if (flags)
193 GST_BUFFER_FLAG_SET (buffer, flags);
194 GST_DEBUG ("created buffer %p", buffer);
195 return buffer;
196 }
197
198 /* make sure downstream gets a CAPS event before buffers are sent */
GST_START_TEST(test_caps)199 GST_START_TEST (test_caps)
200 {
201 GstElement *pipeline;
202 GstCaps *caps;
203
204 /* build pipeline */
205 pipeline = setup_pipeline (NULL, 1, NULL);
206
207 /* prepare playing */
208 set_state_and_wait (pipeline, GST_STATE_PAUSED);
209
210 /* check caps on fakesink */
211 caps = get_element_sink_pad_caps (pipeline, "sink");
212 fail_unless (caps != NULL);
213 gst_caps_unref (caps);
214
215 gst_element_set_state (pipeline, GST_STATE_NULL);
216 gst_object_unref (pipeline);
217 }
218
219 GST_END_TEST;
220
221 /* check that caps set on the property are honoured */
GST_START_TEST(test_filter_caps)222 GST_START_TEST (test_filter_caps)
223 {
224 GstElement *pipeline, *audiomixer, *capsfilter;
225 GstCaps *filter_caps, *caps;
226
227 filter_caps = gst_caps_new_simple ("audio/x-raw",
228 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
229 "layout", G_TYPE_STRING, "interleaved",
230 "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1,
231 "channel-mask", GST_TYPE_BITMASK, (guint64) 0x04, NULL);
232
233 capsfilter = gst_element_factory_make ("capsfilter", NULL);
234
235 /* build pipeline */
236 audiomixer = gst_element_factory_make ("audiomixer", NULL);
237 g_object_set (capsfilter, "caps", filter_caps, NULL);
238 pipeline = setup_pipeline (audiomixer, 1, capsfilter);
239
240 /* prepare playing */
241 set_state_and_wait (pipeline, GST_STATE_PAUSED);
242
243 /* check caps on fakesink */
244 caps = get_element_sink_pad_caps (pipeline, "sink");
245 fail_unless (caps != NULL);
246 GST_INFO_OBJECT (pipeline, "received caps: %" GST_PTR_FORMAT, caps);
247 fail_unless (gst_caps_is_equal_fixed (caps, filter_caps));
248 gst_caps_unref (caps);
249
250 gst_element_set_state (pipeline, GST_STATE_NULL);
251 gst_object_unref (pipeline);
252
253 gst_caps_unref (filter_caps);
254 }
255
256 GST_END_TEST;
257
258 static GstFormat format = GST_FORMAT_UNDEFINED;
259 static gint64 position = -1;
260
261 static void
test_event_message_received(GstBus * bus,GstMessage * message,GstPipeline * bin)262 test_event_message_received (GstBus * bus, GstMessage * message,
263 GstPipeline * bin)
264 {
265 GST_INFO ("bus message from \"%" GST_PTR_FORMAT "\": %" GST_PTR_FORMAT,
266 GST_MESSAGE_SRC (message), message);
267
268 switch (message->type) {
269 case GST_MESSAGE_SEGMENT_DONE:
270 gst_message_parse_segment_done (message, &format, &position);
271 GST_INFO ("received segment_done : %" G_GINT64_FORMAT, position);
272 g_main_loop_quit (main_loop);
273 break;
274 default:
275 g_assert_not_reached ();
276 break;
277 }
278 }
279
280
GST_START_TEST(test_event)281 GST_START_TEST (test_event)
282 {
283 GstElement *bin, *src1, *src2, *audiomixer, *sink;
284 GstBus *bus;
285 GstEvent *seek_event;
286 gboolean res;
287 GstPad *srcpad, *sinkpad;
288 GstStreamConsistency *chk_1, *chk_2, *chk_3;
289
290 GST_INFO ("preparing test");
291
292 /* build pipeline */
293 bin = gst_pipeline_new ("pipeline");
294 bus = gst_element_get_bus (bin);
295 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
296
297 src1 = gst_element_factory_make ("audiotestsrc", "src1");
298 g_object_set (src1, "wave", 4, NULL); /* silence */
299 src2 = gst_element_factory_make ("audiotestsrc", "src2");
300 g_object_set (src2, "wave", 4, NULL); /* silence */
301 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
302 sink = gst_element_factory_make ("fakesink", "sink");
303 gst_bin_add_many (GST_BIN (bin), src1, src2, audiomixer, sink, NULL);
304
305 res = gst_element_link (src1, audiomixer);
306 fail_unless (res == TRUE, NULL);
307 res = gst_element_link (src2, audiomixer);
308 fail_unless (res == TRUE, NULL);
309 res = gst_element_link (audiomixer, sink);
310 fail_unless (res == TRUE, NULL);
311
312 srcpad = gst_element_get_static_pad (audiomixer, "src");
313 chk_3 = gst_consistency_checker_new (srcpad);
314 gst_object_unref (srcpad);
315
316 /* create consistency checkers for the pads */
317 srcpad = gst_element_get_static_pad (src1, "src");
318 chk_1 = gst_consistency_checker_new (srcpad);
319 sinkpad = gst_pad_get_peer (srcpad);
320 gst_consistency_checker_add_pad (chk_3, sinkpad);
321 gst_object_unref (sinkpad);
322 gst_object_unref (srcpad);
323
324 srcpad = gst_element_get_static_pad (src2, "src");
325 chk_2 = gst_consistency_checker_new (srcpad);
326 sinkpad = gst_pad_get_peer (srcpad);
327 gst_consistency_checker_add_pad (chk_3, sinkpad);
328 gst_object_unref (sinkpad);
329 gst_object_unref (srcpad);
330
331 seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
332 GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH,
333 GST_SEEK_TYPE_SET, (GstClockTime) 0,
334 GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND);
335
336 format = GST_FORMAT_UNDEFINED;
337 position = -1;
338
339 g_signal_connect (bus, "message::segment-done",
340 (GCallback) test_event_message_received, bin);
341 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
342 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
343 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
344
345 GST_INFO ("starting test");
346
347 /* prepare playing */
348 set_state_and_wait (bin, GST_STATE_PAUSED);
349
350 res = gst_element_send_event (bin, seek_event);
351 fail_unless (res == TRUE, NULL);
352
353 /* run pipeline */
354 play_and_wait (bin);
355
356 ck_assert_int_eq (position, 2 * GST_SECOND);
357
358 /* cleanup */
359 gst_consistency_checker_free (chk_1);
360 gst_consistency_checker_free (chk_2);
361 gst_consistency_checker_free (chk_3);
362 gst_bus_remove_signal_watch (bus);
363 gst_object_unref (bus);
364 gst_object_unref (bin);
365 }
366
367 GST_END_TEST;
368
369 static guint play_count = 0;
370 static GstEvent *play_seek_event = NULL;
371
372 static void
test_play_twice_message_received(GstBus * bus,GstMessage * message,GstElement * bin)373 test_play_twice_message_received (GstBus * bus, GstMessage * message,
374 GstElement * bin)
375 {
376 gboolean res;
377 GstStateChangeReturn state_res;
378
379 GST_INFO ("bus message from \"%" GST_PTR_FORMAT "\": %" GST_PTR_FORMAT,
380 GST_MESSAGE_SRC (message), message);
381
382 switch (message->type) {
383 case GST_MESSAGE_SEGMENT_DONE:
384 play_count++;
385 if (play_count == 1) {
386 state_res = gst_element_set_state (bin, GST_STATE_READY);
387 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
388
389 /* prepare playing again */
390 set_state_and_wait (bin, GST_STATE_PAUSED);
391
392 res = gst_element_send_event (bin, gst_event_ref (play_seek_event));
393 fail_unless (res == TRUE, NULL);
394
395 state_res = gst_element_set_state (bin, GST_STATE_PLAYING);
396 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
397 } else {
398 g_main_loop_quit (main_loop);
399 }
400 break;
401 default:
402 g_assert_not_reached ();
403 break;
404 }
405 }
406
407
GST_START_TEST(test_play_twice)408 GST_START_TEST (test_play_twice)
409 {
410 GstElement *bin, *audiomixer;
411 GstBus *bus;
412 gboolean res;
413 GstPad *srcpad;
414 GstStreamConsistency *consist;
415
416 GST_INFO ("preparing test");
417
418 /* build pipeline */
419 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
420 bin = setup_pipeline (audiomixer, 2, NULL);
421 bus = gst_element_get_bus (bin);
422 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
423
424 srcpad = gst_element_get_static_pad (audiomixer, "src");
425 consist = gst_consistency_checker_new (srcpad);
426 gst_object_unref (srcpad);
427
428 play_seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
429 GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH,
430 GST_SEEK_TYPE_SET, (GstClockTime) 0,
431 GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND);
432
433 play_count = 0;
434
435 g_signal_connect (bus, "message::segment-done",
436 (GCallback) test_play_twice_message_received, bin);
437 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
438 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
439 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
440
441 GST_INFO ("starting test");
442
443 /* prepare playing */
444 set_state_and_wait (bin, GST_STATE_PAUSED);
445
446 res = gst_element_send_event (bin, gst_event_ref (play_seek_event));
447 fail_unless (res == TRUE, NULL);
448
449 GST_INFO ("seeked");
450
451 /* run pipeline */
452 play_and_wait (bin);
453
454 ck_assert_int_eq (play_count, 2);
455
456 /* cleanup */
457 gst_consistency_checker_free (consist);
458 gst_event_unref (play_seek_event);
459 gst_bus_remove_signal_watch (bus);
460 gst_object_unref (bus);
461 gst_object_unref (bin);
462 }
463
464 GST_END_TEST;
465
GST_START_TEST(test_play_twice_then_add_and_play_again)466 GST_START_TEST (test_play_twice_then_add_and_play_again)
467 {
468 GstElement *bin, *src, *audiomixer;
469 GstBus *bus;
470 gboolean res;
471 GstStateChangeReturn state_res;
472 gint i;
473 GstPad *srcpad;
474 GstStreamConsistency *consist;
475
476 GST_INFO ("preparing test");
477
478 /* build pipeline */
479 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
480 bin = setup_pipeline (audiomixer, 2, NULL);
481 bus = gst_element_get_bus (bin);
482 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
483
484 srcpad = gst_element_get_static_pad (audiomixer, "src");
485 consist = gst_consistency_checker_new (srcpad);
486 gst_object_unref (srcpad);
487
488 play_seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
489 GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH,
490 GST_SEEK_TYPE_SET, (GstClockTime) 0,
491 GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND);
492
493 g_signal_connect (bus, "message::segment-done",
494 (GCallback) test_play_twice_message_received, bin);
495 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
496 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
497 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
498
499 /* run it twice */
500 for (i = 0; i < 2; i++) {
501 play_count = 0;
502
503 GST_INFO ("starting test-loop %d", i);
504
505 /* prepare playing */
506 set_state_and_wait (bin, GST_STATE_PAUSED);
507
508 res = gst_element_send_event (bin, gst_event_ref (play_seek_event));
509 fail_unless (res == TRUE, NULL);
510
511 GST_INFO ("seeked");
512
513 /* run pipeline */
514 play_and_wait (bin);
515
516 ck_assert_int_eq (play_count, 2);
517
518 /* plug another source */
519 if (i == 0) {
520 src = gst_element_factory_make ("audiotestsrc", NULL);
521 g_object_set (src, "wave", 4, NULL); /* silence */
522 gst_bin_add (GST_BIN (bin), src);
523
524 res = gst_element_link (src, audiomixer);
525 fail_unless (res == TRUE, NULL);
526 }
527
528 gst_consistency_checker_reset (consist);
529 }
530
531 state_res = gst_element_set_state (bin, GST_STATE_NULL);
532 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
533
534 /* cleanup */
535 gst_event_unref (play_seek_event);
536 gst_consistency_checker_free (consist);
537 gst_bus_remove_signal_watch (bus);
538 gst_object_unref (bus);
539 gst_object_unref (bin);
540 }
541
542 GST_END_TEST;
543
544 /* test failing seeks on live-sources */
GST_START_TEST(test_live_seeking)545 GST_START_TEST (test_live_seeking)
546 {
547 GstElement *bin, *src1 = NULL, *cf, *src2, *audiomixer, *sink;
548 GstCaps *caps;
549 GstBus *bus;
550 gboolean res;
551 GstPad *srcpad;
552 GstPad *sinkpad;
553 gint i;
554 GstStreamConsistency *consist;
555
556 GST_INFO ("preparing test");
557 play_seek_event = NULL;
558
559 /* build pipeline */
560 bin = gst_pipeline_new ("pipeline");
561 bus = gst_element_get_bus (bin);
562 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
563
564 src1 = gst_element_factory_make ("audiotestsrc", "src1");
565 g_object_set (src1, "wave", 4, "is-live", TRUE, NULL); /* silence */
566
567 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
568 cf = gst_element_factory_make ("capsfilter", "capsfilter");
569 sink = gst_element_factory_make ("fakesink", "sink");
570
571 gst_bin_add_many (GST_BIN (bin), src1, cf, audiomixer, sink, NULL);
572 res = gst_element_link_many (src1, cf, audiomixer, sink, NULL);
573 fail_unless (res == TRUE, NULL);
574
575 /* get the caps for the livesrc, we'll reuse this for the non-live source */
576 set_state_and_wait (bin, GST_STATE_PLAYING);
577
578 sinkpad = gst_element_get_static_pad (sink, "sink");
579 fail_unless (sinkpad != NULL);
580 caps = gst_pad_get_current_caps (sinkpad);
581 fail_unless (caps != NULL);
582 gst_object_unref (sinkpad);
583
584 gst_element_set_state (bin, GST_STATE_NULL);
585
586 g_object_set (cf, "caps", caps, NULL);
587
588 src2 = gst_element_factory_make ("audiotestsrc", "src2");
589 g_object_set (src2, "wave", 4, NULL); /* silence */
590 gst_bin_add (GST_BIN (bin), src2);
591
592 res = gst_element_link_filtered (src2, audiomixer, caps);
593 fail_unless (res == TRUE, NULL);
594
595 gst_caps_unref (caps);
596
597 play_seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
598 GST_SEEK_FLAG_FLUSH,
599 GST_SEEK_TYPE_SET, (GstClockTime) 0,
600 GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND);
601
602 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
603 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
604 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
605
606 srcpad = gst_element_get_static_pad (audiomixer, "src");
607 consist = gst_consistency_checker_new (srcpad);
608 gst_object_unref (srcpad);
609
610 GST_INFO ("starting test");
611
612 /* run it twice */
613 for (i = 0; i < 2; i++) {
614
615 GST_INFO ("starting test-loop %d", i);
616
617 /* prepare playing */
618 set_state_and_wait (bin, GST_STATE_PAUSED);
619
620 res = gst_element_send_event (bin, gst_event_ref (play_seek_event));
621 fail_unless (res == TRUE, NULL);
622
623 GST_INFO ("seeked");
624
625 /* run pipeline */
626 play_and_wait (bin);
627
628 gst_consistency_checker_reset (consist);
629 }
630
631 /* cleanup */
632 GST_INFO ("cleaning up");
633 gst_consistency_checker_free (consist);
634 if (play_seek_event)
635 gst_event_unref (play_seek_event);
636 gst_bus_remove_signal_watch (bus);
637 gst_object_unref (bus);
638 gst_object_unref (bin);
639 }
640
641 GST_END_TEST;
642
643 /* check if adding pads work as expected */
GST_START_TEST(test_add_pad)644 GST_START_TEST (test_add_pad)
645 {
646 GstElement *bin, *src1, *src2, *audiomixer, *sink;
647 GstBus *bus;
648 GstPad *srcpad;
649 gboolean res;
650 GstStateChangeReturn state_res;
651
652 GST_INFO ("preparing test");
653
654 /* build pipeline */
655 bin = gst_pipeline_new ("pipeline");
656 bus = gst_element_get_bus (bin);
657 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
658
659 src1 = gst_element_factory_make ("audiotestsrc", "src1");
660 g_object_set (src1, "num-buffers", 4, "wave", /* silence */ 4, NULL);
661 src2 = gst_element_factory_make ("audiotestsrc", "src2");
662 /* one buffer less, we connect with 1 buffer of delay */
663 g_object_set (src2, "num-buffers", 3, "wave", /* silence */ 4, NULL);
664 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
665 sink = gst_element_factory_make ("fakesink", "sink");
666 gst_bin_add_many (GST_BIN (bin), src1, audiomixer, sink, NULL);
667
668 res = gst_element_link (src1, audiomixer);
669 fail_unless (res == TRUE, NULL);
670 res = gst_element_link (audiomixer, sink);
671 fail_unless (res == TRUE, NULL);
672
673 srcpad = gst_element_get_static_pad (audiomixer, "src");
674 gst_object_unref (srcpad);
675
676 g_signal_connect (bus, "message::segment-done", (GCallback) message_received,
677 bin);
678 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
679 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
680 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
681
682 GST_INFO ("starting test");
683
684 /* prepare playing */
685 set_state_and_wait (bin, GST_STATE_PAUSED);
686
687 /* add other element */
688 gst_bin_add_many (GST_BIN (bin), src2, NULL);
689
690 /* now link the second element */
691 res = gst_element_link (src2, audiomixer);
692 fail_unless (res == TRUE, NULL);
693
694 /* set to PAUSED as well */
695 state_res = gst_element_set_state (src2, GST_STATE_PAUSED);
696 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
697
698 /* now play all */
699 play_and_wait (bin);
700
701 /* cleanup */
702 gst_bus_remove_signal_watch (bus);
703 gst_object_unref (bus);
704 gst_object_unref (bin);
705 }
706
707 GST_END_TEST;
708
709 /* check if removing pads work as expected */
GST_START_TEST(test_remove_pad)710 GST_START_TEST (test_remove_pad)
711 {
712 GstElement *bin, *src, *audiomixer, *sink;
713 GstBus *bus;
714 GstPad *pad, *srcpad;
715 gboolean res;
716 GstStateChangeReturn state_res;
717
718 GST_INFO ("preparing test");
719
720 /* build pipeline */
721 bin = gst_pipeline_new ("pipeline");
722 bus = gst_element_get_bus (bin);
723 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
724
725 src = gst_element_factory_make ("audiotestsrc", "src");
726 g_object_set (src, "num-buffers", 4, "wave", 4, NULL);
727 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
728 sink = gst_element_factory_make ("fakesink", "sink");
729 gst_bin_add_many (GST_BIN (bin), src, audiomixer, sink, NULL);
730
731 res = gst_element_link (src, audiomixer);
732 fail_unless (res == TRUE, NULL);
733 res = gst_element_link (audiomixer, sink);
734 fail_unless (res == TRUE, NULL);
735
736 /* create an unconnected sinkpad in audiomixer */
737 pad = gst_element_get_request_pad (audiomixer, "sink_%u");
738 fail_if (pad == NULL, NULL);
739
740 srcpad = gst_element_get_static_pad (audiomixer, "src");
741 gst_object_unref (srcpad);
742
743 g_signal_connect (bus, "message::segment-done", (GCallback) message_received,
744 bin);
745 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
746 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
747 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
748
749 GST_INFO ("starting test");
750
751 /* prepare playing, this will not preroll as audiomixer is waiting
752 * on the unconnected sinkpad. */
753 state_res = gst_element_set_state (bin, GST_STATE_PAUSED);
754 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
755
756 /* wait for completion for one second, will return ASYNC */
757 state_res = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_SECOND);
758 ck_assert_int_eq (state_res, GST_STATE_CHANGE_ASYNC);
759
760 /* get rid of the pad now, audiomixer should stop waiting on it and
761 * continue the preroll */
762 gst_element_release_request_pad (audiomixer, pad);
763 gst_object_unref (pad);
764
765 /* wait for completion, should work now */
766 state_res =
767 gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
768 GST_CLOCK_TIME_NONE);
769 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
770
771 /* now play all */
772 play_and_wait (bin);
773
774 /* cleanup */
775 gst_bus_remove_signal_watch (bus);
776 gst_object_unref (G_OBJECT (bus));
777 gst_object_unref (G_OBJECT (bin));
778 }
779
780 GST_END_TEST;
781
782
783 static GstBuffer *handoff_buffer = NULL;
784
785 static void
handoff_buffer_cb(GstElement * fakesink,GstBuffer * buffer,GstPad * pad,gpointer user_data)786 handoff_buffer_cb (GstElement * fakesink, GstBuffer * buffer, GstPad * pad,
787 gpointer user_data)
788 {
789 GST_DEBUG ("got buffer -- SIZE: %" G_GSIZE_FORMAT
790 " -- %p PTS is %" GST_TIME_FORMAT " END is %" GST_TIME_FORMAT,
791 gst_buffer_get_size (buffer), buffer,
792 GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
793 GST_TIME_ARGS (GST_BUFFER_PTS (buffer) + GST_BUFFER_DURATION (buffer)));
794
795 gst_buffer_replace (&handoff_buffer, buffer);
796 }
797
798 /* check if clipping works as expected */
GST_START_TEST(test_clip)799 GST_START_TEST (test_clip)
800 {
801 GstSegment segment;
802 GstElement *bin, *audiomixer, *sink;
803 GstBus *bus;
804 GstPad *sinkpad;
805 gboolean res;
806 GstStateChangeReturn state_res;
807 GstFlowReturn ret;
808 GstEvent *event;
809 GstBuffer *buffer;
810 GstCaps *caps;
811 GstQuery *drain = gst_query_new_drain ();
812
813 GST_INFO ("preparing test");
814
815 /* build pipeline */
816 bin = gst_pipeline_new ("pipeline");
817 bus = gst_element_get_bus (bin);
818 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
819
820 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
821 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
822 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
823
824 /* just an audiomixer and a fakesink */
825 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
826 g_object_set (audiomixer, "output-buffer-duration", 50 * GST_MSECOND, NULL);
827 sink = gst_element_factory_make ("fakesink", "sink");
828 g_object_set (sink, "signal-handoffs", TRUE, NULL);
829 g_signal_connect (sink, "handoff", (GCallback) handoff_buffer_cb, NULL);
830 gst_bin_add_many (GST_BIN (bin), audiomixer, sink, NULL);
831
832 res = gst_element_link (audiomixer, sink);
833 fail_unless (res == TRUE, NULL);
834
835 /* set to playing */
836 state_res = gst_element_set_state (bin, GST_STATE_PLAYING);
837 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
838
839 /* create an unconnected sinkpad in audiomixer, should also automatically activate
840 * the pad */
841 sinkpad = gst_element_get_request_pad (audiomixer, "sink_%u");
842 fail_if (sinkpad == NULL, NULL);
843
844 gst_pad_send_event (sinkpad, gst_event_new_stream_start ("test"));
845
846 caps = gst_caps_new_simple ("audio/x-raw",
847 "format", G_TYPE_STRING, GST_AUDIO_NE (S16),
848 "layout", G_TYPE_STRING, "interleaved",
849 "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 2, NULL);
850
851 gst_pad_set_caps (sinkpad, caps);
852 gst_caps_unref (caps);
853
854 /* send segment to audiomixer */
855 gst_segment_init (&segment, GST_FORMAT_TIME);
856 segment.start = GST_SECOND;
857 segment.stop = 2 * GST_SECOND;
858 segment.time = 0;
859 event = gst_event_new_segment (&segment);
860 gst_pad_send_event (sinkpad, event);
861
862 /* should be clipped and ok */
863 buffer = new_buffer (44100, 0, 0, 250 * GST_MSECOND, 0);
864 GST_DEBUG ("pushing buffer %p END is %" GST_TIME_FORMAT,
865 buffer,
866 GST_TIME_ARGS (GST_BUFFER_PTS (buffer) + GST_BUFFER_DURATION (buffer)));
867 ret = gst_pad_chain (sinkpad, buffer);
868 ck_assert_int_eq (ret, GST_FLOW_OK);
869 /* The aggregation is done in a dedicated thread, so we can't
870 * know when it is actually going to happen, so we use a DRAIN query
871 * to wait for it to complete.
872 */
873 gst_pad_query (sinkpad, drain);
874 fail_unless (handoff_buffer == NULL);
875
876 /* should be partially clipped */
877 buffer = new_buffer (44100, 0, 900 * GST_MSECOND, 250 * GST_MSECOND,
878 GST_BUFFER_FLAG_DISCONT);
879 GST_DEBUG ("pushing buffer %p START %" GST_TIME_FORMAT " -- DURATION is %"
880 GST_TIME_FORMAT, buffer, GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
881 GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
882 ret = gst_pad_chain (sinkpad, buffer);
883 ck_assert_int_eq (ret, GST_FLOW_OK);
884 gst_pad_query (sinkpad, drain);
885
886 fail_unless (handoff_buffer != NULL);
887 ck_assert_int_eq (GST_BUFFER_PTS (handoff_buffer) +
888 GST_BUFFER_DURATION (handoff_buffer), 150 * GST_MSECOND);
889 gst_buffer_replace (&handoff_buffer, NULL);
890
891 /* should not be clipped */
892 buffer = new_buffer (44100, 0, 1150 * GST_MSECOND, 250 * GST_MSECOND, 0);
893 GST_DEBUG ("pushing buffer %p END is %" GST_TIME_FORMAT,
894 buffer,
895 GST_TIME_ARGS (GST_BUFFER_PTS (buffer) + GST_BUFFER_DURATION (buffer)));
896 ret = gst_pad_chain (sinkpad, buffer);
897 ck_assert_int_eq (ret, GST_FLOW_OK);
898 gst_pad_query (sinkpad, drain);
899 fail_unless (handoff_buffer != NULL);
900 ck_assert_int_eq (GST_BUFFER_PTS (handoff_buffer) +
901 GST_BUFFER_DURATION (handoff_buffer), 400 * GST_MSECOND);
902 gst_buffer_replace (&handoff_buffer, NULL);
903 fail_unless (handoff_buffer == NULL);
904
905 /* should be clipped and ok */
906 buffer = new_buffer (44100, 0, 2 * GST_SECOND, 250 * GST_MSECOND,
907 GST_BUFFER_FLAG_DISCONT);
908 GST_DEBUG ("pushing buffer %p PTS is %" GST_TIME_FORMAT
909 " END is %" GST_TIME_FORMAT,
910 buffer,
911 GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
912 GST_TIME_ARGS (GST_BUFFER_PTS (buffer) + GST_BUFFER_DURATION (buffer)));
913 ret = gst_pad_chain (sinkpad, buffer);
914 ck_assert_int_eq (ret, GST_FLOW_OK);
915 gst_pad_query (sinkpad, drain);
916 fail_unless (handoff_buffer == NULL);
917
918 gst_element_release_request_pad (audiomixer, sinkpad);
919 gst_object_unref (sinkpad);
920 gst_element_set_state (bin, GST_STATE_NULL);
921 gst_bus_remove_signal_watch (bus);
922 gst_object_unref (bus);
923 gst_object_unref (bin);
924 gst_query_unref (drain);
925 }
926
927 GST_END_TEST;
928
GST_START_TEST(test_duration_is_max)929 GST_START_TEST (test_duration_is_max)
930 {
931 GstElement *bin, *src[3], *audiomixer, *sink;
932 GstStateChangeReturn state_res;
933 GstFormat format = GST_FORMAT_TIME;
934 gboolean res;
935 gint64 duration;
936
937 GST_INFO ("preparing test");
938
939 /* build pipeline */
940 bin = gst_pipeline_new ("pipeline");
941
942 /* 3 sources, an audiomixer and a fakesink */
943 src[0] = gst_element_factory_make ("audiotestsrc", NULL);
944 src[1] = gst_element_factory_make ("audiotestsrc", NULL);
945 src[2] = gst_element_factory_make ("audiotestsrc", NULL);
946 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
947 sink = gst_element_factory_make ("fakesink", "sink");
948 gst_bin_add_many (GST_BIN (bin), src[0], src[1], src[2], audiomixer, sink,
949 NULL);
950
951 gst_element_link (src[0], audiomixer);
952 gst_element_link (src[1], audiomixer);
953 gst_element_link (src[2], audiomixer);
954 gst_element_link (audiomixer, sink);
955
956 /* irks, duration is reset on basesrc */
957 state_res = gst_element_set_state (bin, GST_STATE_PAUSED);
958 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
959
960 /* set durations on src */
961 GST_BASE_SRC (src[0])->segment.duration = 1000;
962 GST_BASE_SRC (src[1])->segment.duration = 3000;
963 GST_BASE_SRC (src[2])->segment.duration = 2000;
964
965 /* set to playing */
966 set_state_and_wait (bin, GST_STATE_PLAYING);
967
968 res = gst_element_query_duration (GST_ELEMENT (bin), format, &duration);
969 fail_unless (res, NULL);
970
971 ck_assert_int_eq (duration, 3000);
972
973 gst_element_set_state (bin, GST_STATE_NULL);
974 gst_object_unref (bin);
975 }
976
977 GST_END_TEST;
978
GST_START_TEST(test_duration_unknown_overrides)979 GST_START_TEST (test_duration_unknown_overrides)
980 {
981 GstElement *bin, *src[3], *audiomixer, *sink;
982 GstStateChangeReturn state_res;
983 GstFormat format = GST_FORMAT_TIME;
984 gboolean res;
985 gint64 duration;
986
987 GST_INFO ("preparing test");
988
989 /* build pipeline */
990 bin = gst_pipeline_new ("pipeline");
991
992 /* 3 sources, an audiomixer and a fakesink */
993 src[0] = gst_element_factory_make ("audiotestsrc", NULL);
994 src[1] = gst_element_factory_make ("audiotestsrc", NULL);
995 src[2] = gst_element_factory_make ("audiotestsrc", NULL);
996 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
997 sink = gst_element_factory_make ("fakesink", "sink");
998 gst_bin_add_many (GST_BIN (bin), src[0], src[1], src[2], audiomixer, sink,
999 NULL);
1000
1001 gst_element_link (src[0], audiomixer);
1002 gst_element_link (src[1], audiomixer);
1003 gst_element_link (src[2], audiomixer);
1004 gst_element_link (audiomixer, sink);
1005
1006 /* irks, duration is reset on basesrc */
1007 state_res = gst_element_set_state (bin, GST_STATE_PAUSED);
1008 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
1009
1010 /* set durations on src */
1011 GST_BASE_SRC (src[0])->segment.duration = GST_CLOCK_TIME_NONE;
1012 GST_BASE_SRC (src[1])->segment.duration = 3000;
1013 GST_BASE_SRC (src[2])->segment.duration = 2000;
1014
1015 /* set to playing */
1016 set_state_and_wait (bin, GST_STATE_PLAYING);
1017
1018 res = gst_element_query_duration (GST_ELEMENT (bin), format, &duration);
1019 fail_unless (res, NULL);
1020
1021 ck_assert_int_eq (duration, GST_CLOCK_TIME_NONE);
1022
1023 gst_element_set_state (bin, GST_STATE_NULL);
1024 gst_object_unref (bin);
1025 }
1026
1027 GST_END_TEST;
1028
1029
1030 static gboolean looped = FALSE;
1031
1032 static void
loop_segment_done(GstBus * bus,GstMessage * message,GstElement * bin)1033 loop_segment_done (GstBus * bus, GstMessage * message, GstElement * bin)
1034 {
1035 GST_INFO ("bus message from \"%" GST_PTR_FORMAT "\": %" GST_PTR_FORMAT,
1036 GST_MESSAGE_SRC (message), message);
1037
1038 if (looped) {
1039 g_main_loop_quit (main_loop);
1040 } else {
1041 GstEvent *seek_event;
1042 gboolean res;
1043
1044 seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
1045 GST_SEEK_FLAG_SEGMENT,
1046 GST_SEEK_TYPE_SET, (GstClockTime) 0,
1047 GST_SEEK_TYPE_SET, (GstClockTime) 1 * GST_SECOND);
1048
1049 res = gst_element_send_event (bin, seek_event);
1050 fail_unless (res == TRUE, NULL);
1051 looped = TRUE;
1052 }
1053 }
1054
GST_START_TEST(test_loop)1055 GST_START_TEST (test_loop)
1056 {
1057 GstElement *bin;
1058 GstBus *bus;
1059 GstEvent *seek_event;
1060 gboolean res;
1061
1062 GST_INFO ("preparing test");
1063
1064 /* build pipeline */
1065 bin = setup_pipeline (NULL, 2, NULL);
1066 bus = gst_element_get_bus (bin);
1067 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
1068
1069 seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
1070 GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH,
1071 GST_SEEK_TYPE_SET, (GstClockTime) 0,
1072 GST_SEEK_TYPE_SET, (GstClockTime) 1 * GST_SECOND);
1073
1074 g_signal_connect (bus, "message::segment-done",
1075 (GCallback) loop_segment_done, bin);
1076 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
1077 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
1078 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
1079
1080 GST_INFO ("starting test");
1081
1082 /* prepare playing */
1083 set_state_and_wait (bin, GST_STATE_PAUSED);
1084
1085 res = gst_element_send_event (bin, seek_event);
1086 fail_unless (res == TRUE, NULL);
1087
1088 /* run pipeline */
1089 play_and_wait (bin);
1090
1091 fail_unless (looped);
1092
1093 /* cleanup */
1094 gst_bus_remove_signal_watch (bus);
1095 gst_object_unref (bus);
1096 gst_object_unref (bin);
1097 }
1098
1099 GST_END_TEST;
1100
GST_START_TEST(test_flush_start_flush_stop)1101 GST_START_TEST (test_flush_start_flush_stop)
1102 {
1103 GstPadTemplate *sink_template;
1104 GstPad *tmppad, *srcpad1, *sinkpad1, *sinkpad2, *audiomixer_src;
1105 GstElement *pipeline, *src1, *src2, *audiomixer, *sink;
1106
1107 GST_INFO ("preparing test");
1108
1109 /* build pipeline */
1110 pipeline = gst_pipeline_new ("pipeline");
1111 src1 = gst_element_factory_make ("audiotestsrc", "src1");
1112 g_object_set (src1, "wave", 4, NULL); /* silence */
1113 src2 = gst_element_factory_make ("audiotestsrc", "src2");
1114 g_object_set (src2, "wave", 4, NULL); /* silence */
1115 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
1116 sink = gst_element_factory_make ("fakesink", "sink");
1117 gst_bin_add_many (GST_BIN (pipeline), src1, src2, audiomixer, sink, NULL);
1118
1119 sink_template =
1120 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (audiomixer),
1121 "sink_%u");
1122 fail_unless (GST_IS_PAD_TEMPLATE (sink_template));
1123 sinkpad1 = gst_element_request_pad (audiomixer, sink_template, NULL, NULL);
1124 srcpad1 = gst_element_get_static_pad (src1, "src");
1125 gst_pad_link (srcpad1, sinkpad1);
1126
1127 sinkpad2 = gst_element_request_pad (audiomixer, sink_template, NULL, NULL);
1128 tmppad = gst_element_get_static_pad (src2, "src");
1129 gst_pad_link (tmppad, sinkpad2);
1130 gst_object_unref (tmppad);
1131
1132 gst_element_link (audiomixer, sink);
1133
1134 /* prepare playing */
1135 set_state_and_wait (pipeline, GST_STATE_PLAYING);
1136
1137 audiomixer_src = gst_element_get_static_pad (audiomixer, "src");
1138 fail_if (GST_PAD_IS_FLUSHING (audiomixer_src));
1139 gst_pad_send_event (sinkpad1, gst_event_new_flush_start ());
1140 fail_if (GST_PAD_IS_FLUSHING (audiomixer_src));
1141 fail_unless (GST_PAD_IS_FLUSHING (sinkpad1));
1142 /* Hold the streamlock to make sure the flush stop is not between
1143 the attempted push of a segment event and of the following buffer. */
1144 GST_PAD_STREAM_LOCK (srcpad1);
1145 gst_pad_send_event (sinkpad1, gst_event_new_flush_stop (TRUE));
1146 GST_PAD_STREAM_UNLOCK (srcpad1);
1147 fail_if (GST_PAD_IS_FLUSHING (audiomixer_src));
1148 fail_if (GST_PAD_IS_FLUSHING (sinkpad1));
1149 gst_object_unref (audiomixer_src);
1150
1151 gst_element_release_request_pad (audiomixer, sinkpad1);
1152 gst_object_unref (sinkpad1);
1153 gst_element_release_request_pad (audiomixer, sinkpad2);
1154 gst_object_unref (sinkpad2);
1155 gst_object_unref (srcpad1);
1156
1157 /* cleanup */
1158 gst_element_set_state (pipeline, GST_STATE_NULL);
1159 gst_object_unref (pipeline);
1160 }
1161
1162 GST_END_TEST;
1163
1164 static void
handoff_buffer_collect_cb(GstElement * fakesink,GstBuffer * buffer,GstPad * pad,gpointer user_data)1165 handoff_buffer_collect_cb (GstElement * fakesink, GstBuffer * buffer,
1166 GstPad * pad, gpointer user_data)
1167 {
1168 GList **received_buffers = user_data;
1169
1170 GST_DEBUG ("got buffer %p", buffer);
1171 *received_buffers =
1172 g_list_append (*received_buffers, gst_buffer_ref (buffer));
1173 }
1174
1175 typedef void (*SendBuffersFunction) (GstPad * pad1, GstPad * pad2);
1176 typedef void (*CheckBuffersFunction) (GList * buffers);
1177
1178 static void
run_sync_test(SendBuffersFunction send_buffers,CheckBuffersFunction check_buffers)1179 run_sync_test (SendBuffersFunction send_buffers,
1180 CheckBuffersFunction check_buffers)
1181 {
1182 GstSegment segment;
1183 GstElement *bin, *audiomixer, *queue1, *queue2, *sink;
1184 GstBus *bus;
1185 GstPad *sinkpad1, *sinkpad2;
1186 GstPad *queue1_sinkpad, *queue2_sinkpad;
1187 GstPad *pad;
1188 gboolean res;
1189 GstStateChangeReturn state_res;
1190 GstEvent *event;
1191 GstCaps *caps;
1192 GList *received_buffers = NULL;
1193
1194 GST_INFO ("preparing test");
1195
1196 /* build pipeline */
1197 bin = gst_pipeline_new ("pipeline");
1198 bus = gst_element_get_bus (bin);
1199 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
1200
1201 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
1202 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
1203 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
1204
1205 /* just an audiomixer and a fakesink */
1206 queue1 = gst_element_factory_make ("queue", "queue1");
1207 queue2 = gst_element_factory_make ("queue", "queue2");
1208 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
1209 g_object_set (audiomixer, "output-buffer-duration", 500 * GST_MSECOND, NULL);
1210 sink = gst_element_factory_make ("fakesink", "sink");
1211 g_object_set (sink, "signal-handoffs", TRUE, NULL);
1212 g_signal_connect (sink, "handoff", (GCallback) handoff_buffer_collect_cb,
1213 &received_buffers);
1214 gst_bin_add_many (GST_BIN (bin), queue1, queue2, audiomixer, sink, NULL);
1215
1216 res = gst_element_link (audiomixer, sink);
1217 fail_unless (res == TRUE, NULL);
1218
1219 /* set to paused */
1220 state_res = gst_element_set_state (bin, GST_STATE_PAUSED);
1221 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
1222
1223 /* create an unconnected sinkpad in audiomixer, should also automatically activate
1224 * the pad */
1225 sinkpad1 = gst_element_get_request_pad (audiomixer, "sink_%u");
1226 fail_if (sinkpad1 == NULL, NULL);
1227
1228 queue1_sinkpad = gst_element_get_static_pad (queue1, "sink");
1229 pad = gst_element_get_static_pad (queue1, "src");
1230 fail_unless (gst_pad_link (pad, sinkpad1) == GST_PAD_LINK_OK);
1231 gst_object_unref (pad);
1232
1233 sinkpad2 = gst_element_get_request_pad (audiomixer, "sink_%u");
1234 fail_if (sinkpad2 == NULL, NULL);
1235
1236 queue2_sinkpad = gst_element_get_static_pad (queue2, "sink");
1237 pad = gst_element_get_static_pad (queue2, "src");
1238 fail_unless (gst_pad_link (pad, sinkpad2) == GST_PAD_LINK_OK);
1239 gst_object_unref (pad);
1240
1241 gst_pad_send_event (queue1_sinkpad, gst_event_new_stream_start ("test"));
1242 gst_pad_send_event (queue2_sinkpad, gst_event_new_stream_start ("test"));
1243
1244 caps = gst_caps_new_simple ("audio/x-raw",
1245 "format", G_TYPE_STRING, GST_AUDIO_NE (S16),
1246 "layout", G_TYPE_STRING, "interleaved",
1247 "rate", G_TYPE_INT, 1000, "channels", G_TYPE_INT, 1, NULL);
1248
1249 gst_pad_set_caps (queue1_sinkpad, caps);
1250 gst_pad_set_caps (queue2_sinkpad, caps);
1251 gst_caps_unref (caps);
1252
1253 /* send segment to audiomixer */
1254 gst_segment_init (&segment, GST_FORMAT_TIME);
1255 event = gst_event_new_segment (&segment);
1256 gst_pad_send_event (queue1_sinkpad, gst_event_ref (event));
1257 gst_pad_send_event (queue2_sinkpad, event);
1258
1259 /* Push buffers */
1260 send_buffers (queue1_sinkpad, queue2_sinkpad);
1261
1262 /* Set PLAYING */
1263 g_idle_add ((GSourceFunc) set_playing, bin);
1264
1265 /* Collect buffers and messages */
1266 g_main_loop_run (main_loop);
1267
1268 /* Here we get once we got EOS, for errors we failed */
1269
1270 check_buffers (received_buffers);
1271
1272 g_list_free_full (received_buffers, (GDestroyNotify) gst_buffer_unref);
1273
1274 gst_element_release_request_pad (audiomixer, sinkpad1);
1275 gst_object_unref (sinkpad1);
1276 gst_object_unref (queue1_sinkpad);
1277 gst_element_release_request_pad (audiomixer, sinkpad2);
1278 gst_object_unref (sinkpad2);
1279 gst_object_unref (queue2_sinkpad);
1280 gst_element_set_state (bin, GST_STATE_NULL);
1281 gst_bus_remove_signal_watch (bus);
1282 gst_object_unref (bus);
1283 gst_object_unref (bin);
1284 }
1285
1286 static void
send_buffers_sync(GstPad * pad1,GstPad * pad2)1287 send_buffers_sync (GstPad * pad1, GstPad * pad2)
1288 {
1289 GstBuffer *buffer;
1290 GstFlowReturn ret;
1291
1292 buffer = new_buffer (2000, 1, 1 * GST_SECOND, 1 * GST_SECOND, 0);
1293 ret = gst_pad_chain (pad1, buffer);
1294 ck_assert_int_eq (ret, GST_FLOW_OK);
1295
1296 buffer = new_buffer (2000, 1, 2 * GST_SECOND, 1 * GST_SECOND, 0);
1297 ret = gst_pad_chain (pad1, buffer);
1298 ck_assert_int_eq (ret, GST_FLOW_OK);
1299
1300 gst_pad_send_event (pad1, gst_event_new_eos ());
1301
1302 buffer = new_buffer (2000, 2, 2 * GST_SECOND, 1 * GST_SECOND, 0);
1303 ret = gst_pad_chain (pad2, buffer);
1304 ck_assert_int_eq (ret, GST_FLOW_OK);
1305
1306 buffer = new_buffer (2000, 2, 3 * GST_SECOND, 1 * GST_SECOND, 0);
1307 ret = gst_pad_chain (pad2, buffer);
1308 ck_assert_int_eq (ret, GST_FLOW_OK);
1309
1310 gst_pad_send_event (pad2, gst_event_new_eos ());
1311 }
1312
1313 static void
check_buffers_sync(GList * received_buffers)1314 check_buffers_sync (GList * received_buffers)
1315 {
1316 GstBuffer *buffer;
1317 GList *l;
1318 gint i;
1319 GstMapInfo map;
1320
1321 /* Should have 8 * 0.5s buffers */
1322 fail_unless_equals_int (g_list_length (received_buffers), 8);
1323 for (i = 0, l = received_buffers; l; l = l->next, i++) {
1324 buffer = l->data;
1325
1326 gst_buffer_map (buffer, &map, GST_MAP_READ);
1327
1328 if (i == 0 && GST_BUFFER_TIMESTAMP (buffer) == 0) {
1329 fail_unless (map.data[0] == 0);
1330 fail_unless (map.data[map.size - 1] == 0);
1331 } else if (i == 1 && GST_BUFFER_TIMESTAMP (buffer) == 500 * GST_MSECOND) {
1332 fail_unless (map.data[0] == 0);
1333 fail_unless (map.data[map.size - 1] == 0);
1334 } else if (i == 2 && GST_BUFFER_TIMESTAMP (buffer) == 1000 * GST_MSECOND) {
1335 fail_unless (map.data[0] == 1);
1336 fail_unless (map.data[map.size - 1] == 1);
1337 } else if (i == 3 && GST_BUFFER_TIMESTAMP (buffer) == 1500 * GST_MSECOND) {
1338 fail_unless (map.data[0] == 1);
1339 fail_unless (map.data[map.size - 1] == 1);
1340 } else if (i == 4 && GST_BUFFER_TIMESTAMP (buffer) == 2000 * GST_MSECOND) {
1341 fail_unless (map.data[0] == 3);
1342 fail_unless (map.data[map.size - 1] == 3);
1343 } else if (i == 5 && GST_BUFFER_TIMESTAMP (buffer) == 2500 * GST_MSECOND) {
1344 fail_unless (map.data[0] == 3);
1345 fail_unless (map.data[map.size - 1] == 3);
1346 } else if (i == 6 && GST_BUFFER_TIMESTAMP (buffer) == 3000 * GST_MSECOND) {
1347 fail_unless (map.data[0] == 2);
1348 fail_unless (map.data[map.size - 1] == 2);
1349 } else if (i == 7 && GST_BUFFER_TIMESTAMP (buffer) == 3500 * GST_MSECOND) {
1350 fail_unless (map.data[0] == 2);
1351 fail_unless (map.data[map.size - 1] == 2);
1352 } else {
1353 g_assert_not_reached ();
1354 }
1355
1356 gst_buffer_unmap (buffer, &map);
1357
1358 }
1359 }
1360
GST_START_TEST(test_sync)1361 GST_START_TEST (test_sync)
1362 {
1363 run_sync_test (send_buffers_sync, check_buffers_sync);
1364 }
1365
1366 GST_END_TEST;
1367
1368 static void
send_buffers_sync_discont(GstPad * pad1,GstPad * pad2)1369 send_buffers_sync_discont (GstPad * pad1, GstPad * pad2)
1370 {
1371 GstBuffer *buffer;
1372 GstFlowReturn ret;
1373
1374 buffer = new_buffer (2000, 1, 1 * GST_SECOND, 1 * GST_SECOND, 0);
1375 ret = gst_pad_chain (pad1, buffer);
1376 ck_assert_int_eq (ret, GST_FLOW_OK);
1377
1378 buffer = new_buffer (2000, 1, 3 * GST_SECOND, 1 * GST_SECOND,
1379 GST_BUFFER_FLAG_DISCONT);
1380 ret = gst_pad_chain (pad1, buffer);
1381 ck_assert_int_eq (ret, GST_FLOW_OK);
1382
1383 gst_pad_send_event (pad1, gst_event_new_eos ());
1384
1385 buffer = new_buffer (2000, 2, 2 * GST_SECOND, 1 * GST_SECOND, 0);
1386 ret = gst_pad_chain (pad2, buffer);
1387 ck_assert_int_eq (ret, GST_FLOW_OK);
1388
1389 buffer = new_buffer (2000, 2, 3 * GST_SECOND, 1 * GST_SECOND, 0);
1390 ret = gst_pad_chain (pad2, buffer);
1391 ck_assert_int_eq (ret, GST_FLOW_OK);
1392
1393 gst_pad_send_event (pad2, gst_event_new_eos ());
1394 }
1395
1396 static void
check_buffers_sync_discont(GList * received_buffers)1397 check_buffers_sync_discont (GList * received_buffers)
1398 {
1399 GstBuffer *buffer;
1400 GList *l;
1401 gint i;
1402 GstMapInfo map;
1403
1404 /* Should have 8 * 0.5s buffers */
1405 fail_unless_equals_int (g_list_length (received_buffers), 8);
1406 for (i = 0, l = received_buffers; l; l = l->next, i++) {
1407 buffer = l->data;
1408
1409 gst_buffer_map (buffer, &map, GST_MAP_READ);
1410
1411 if (i == 0 && GST_BUFFER_TIMESTAMP (buffer) == 0) {
1412 fail_unless (map.data[0] == 0);
1413 fail_unless (map.data[map.size - 1] == 0);
1414 } else if (i == 1 && GST_BUFFER_TIMESTAMP (buffer) == 500 * GST_MSECOND) {
1415 fail_unless (map.data[0] == 0);
1416 fail_unless (map.data[map.size - 1] == 0);
1417 } else if (i == 2 && GST_BUFFER_TIMESTAMP (buffer) == 1000 * GST_MSECOND) {
1418 fail_unless (map.data[0] == 1);
1419 fail_unless (map.data[map.size - 1] == 1);
1420 } else if (i == 3 && GST_BUFFER_TIMESTAMP (buffer) == 1500 * GST_MSECOND) {
1421 fail_unless (map.data[0] == 1);
1422 fail_unless (map.data[map.size - 1] == 1);
1423 } else if (i == 4 && GST_BUFFER_TIMESTAMP (buffer) == 2000 * GST_MSECOND) {
1424 fail_unless (map.data[0] == 2);
1425 fail_unless (map.data[map.size - 1] == 2);
1426 } else if (i == 5 && GST_BUFFER_TIMESTAMP (buffer) == 2500 * GST_MSECOND) {
1427 fail_unless (map.data[0] == 2);
1428 fail_unless (map.data[map.size - 1] == 2);
1429 } else if (i == 6 && GST_BUFFER_TIMESTAMP (buffer) == 3000 * GST_MSECOND) {
1430 fail_unless (map.data[0] == 3);
1431 fail_unless (map.data[map.size - 1] == 3);
1432 } else if (i == 7 && GST_BUFFER_TIMESTAMP (buffer) == 3500 * GST_MSECOND) {
1433 fail_unless (map.data[0] == 3);
1434 fail_unless (map.data[map.size - 1] == 3);
1435 } else {
1436 g_assert_not_reached ();
1437 }
1438
1439 gst_buffer_unmap (buffer, &map);
1440
1441 }
1442 }
1443
GST_START_TEST(test_sync_discont)1444 GST_START_TEST (test_sync_discont)
1445 {
1446 run_sync_test (send_buffers_sync_discont, check_buffers_sync_discont);
1447 }
1448
1449 GST_END_TEST;
1450
1451 static void
send_buffers_sync_unaligned(GstPad * pad1,GstPad * pad2)1452 send_buffers_sync_unaligned (GstPad * pad1, GstPad * pad2)
1453 {
1454 GstBuffer *buffer;
1455 GstFlowReturn ret;
1456
1457 buffer = new_buffer (2000, 1, 750 * GST_MSECOND, 1 * GST_SECOND, 0);
1458 ret = gst_pad_chain (pad1, buffer);
1459 ck_assert_int_eq (ret, GST_FLOW_OK);
1460
1461 buffer = new_buffer (2000, 1, 1750 * GST_MSECOND, 1 * GST_SECOND, 0);
1462 ret = gst_pad_chain (pad1, buffer);
1463 ck_assert_int_eq (ret, GST_FLOW_OK);
1464
1465 gst_pad_send_event (pad1, gst_event_new_eos ());
1466
1467 buffer = new_buffer (2000, 2, 1750 * GST_MSECOND, 1 * GST_SECOND, 0);
1468 ret = gst_pad_chain (pad2, buffer);
1469 ck_assert_int_eq (ret, GST_FLOW_OK);
1470
1471 buffer = new_buffer (2000, 2, 2750 * GST_MSECOND, 1 * GST_SECOND, 0);
1472 ret = gst_pad_chain (pad2, buffer);
1473 ck_assert_int_eq (ret, GST_FLOW_OK);
1474
1475 gst_pad_send_event (pad2, gst_event_new_eos ());
1476 }
1477
1478 static void
check_buffers_sync_unaligned(GList * received_buffers)1479 check_buffers_sync_unaligned (GList * received_buffers)
1480 {
1481 GstBuffer *buffer;
1482 GList *l;
1483 gint i;
1484 GstMapInfo map;
1485
1486 /* Should have 8 * 0.5s buffers */
1487 fail_unless_equals_int (g_list_length (received_buffers), 8);
1488 for (i = 0, l = received_buffers; l; l = l->next, i++) {
1489 buffer = l->data;
1490
1491 gst_buffer_map (buffer, &map, GST_MAP_READ);
1492
1493 if (i == 0 && GST_BUFFER_TIMESTAMP (buffer) == 0) {
1494 fail_unless (map.data[0] == 0);
1495 fail_unless (map.data[map.size - 1] == 0);
1496 } else if (i == 1 && GST_BUFFER_TIMESTAMP (buffer) == 500 * GST_MSECOND) {
1497 fail_unless (map.data[0] == 0);
1498 fail_unless (map.data[499] == 0);
1499 fail_unless (map.data[500] == 1);
1500 fail_unless (map.data[map.size - 1] == 1);
1501 } else if (i == 2 && GST_BUFFER_TIMESTAMP (buffer) == 1000 * GST_MSECOND) {
1502 fail_unless (map.data[0] == 1);
1503 fail_unless (map.data[map.size - 1] == 1);
1504 } else if (i == 3 && GST_BUFFER_TIMESTAMP (buffer) == 1500 * GST_MSECOND) {
1505 fail_unless (map.data[0] == 1);
1506 fail_unless (map.data[499] == 1);
1507 fail_unless (map.data[500] == 3);
1508 fail_unless (map.data[map.size - 1] == 3);
1509 } else if (i == 4 && GST_BUFFER_TIMESTAMP (buffer) == 2000 * GST_MSECOND) {
1510 fail_unless (map.data[0] == 3);
1511 fail_unless (map.data[499] == 3);
1512 fail_unless (map.data[500] == 3);
1513 fail_unless (map.data[map.size - 1] == 3);
1514 } else if (i == 5 && GST_BUFFER_TIMESTAMP (buffer) == 2500 * GST_MSECOND) {
1515 fail_unless (map.data[0] == 3);
1516 fail_unless (map.data[499] == 3);
1517 fail_unless (map.data[500] == 2);
1518 fail_unless (map.data[map.size - 1] == 2);
1519 } else if (i == 6 && GST_BUFFER_TIMESTAMP (buffer) == 3000 * GST_MSECOND) {
1520 fail_unless (map.data[0] == 2);
1521 fail_unless (map.data[499] == 2);
1522 fail_unless (map.data[500] == 2);
1523 fail_unless (map.data[map.size - 1] == 2);
1524 } else if (i == 7 && GST_BUFFER_TIMESTAMP (buffer) == 3500 * GST_MSECOND) {
1525 fail_unless (map.size == 500);
1526 fail_unless (GST_BUFFER_DURATION (buffer) == 250 * GST_MSECOND);
1527 fail_unless (map.data[0] == 2);
1528 fail_unless (map.data[499] == 2);
1529 } else {
1530 g_assert_not_reached ();
1531 }
1532
1533 gst_buffer_unmap (buffer, &map);
1534
1535 }
1536 }
1537
GST_START_TEST(test_sync_unaligned)1538 GST_START_TEST (test_sync_unaligned)
1539 {
1540 run_sync_test (send_buffers_sync_unaligned, check_buffers_sync_unaligned);
1541 }
1542
1543 GST_END_TEST;
1544
GST_START_TEST(test_segment_base_handling)1545 GST_START_TEST (test_segment_base_handling)
1546 {
1547 GstElement *pipeline, *sink, *mix, *src1, *src2;
1548 GstPad *srcpad, *sinkpad;
1549 GstClockTime end_time;
1550 GstSample *last_sample = NULL;
1551 GstSample *sample;
1552 GstBuffer *buf;
1553 GstCaps *caps;
1554
1555 caps = gst_caps_new_simple ("audio/x-raw", "rate", G_TYPE_INT, 44100,
1556 "channels", G_TYPE_INT, 2, NULL);
1557
1558 pipeline = gst_pipeline_new ("pipeline");
1559 mix = gst_element_factory_make ("audiomixer", "audiomixer");
1560 sink = gst_element_factory_make ("appsink", "sink");
1561 g_object_set (sink, "caps", caps, "sync", FALSE, NULL);
1562 gst_caps_unref (caps);
1563 /* 50 buffers of 1/10 sec = 5 sec */
1564 src1 = gst_element_factory_make ("audiotestsrc", "src1");
1565 g_object_set (src1, "samplesperbuffer", 4410, "num-buffers", 50, NULL);
1566 src2 = gst_element_factory_make ("audiotestsrc", "src2");
1567 g_object_set (src2, "samplesperbuffer", 4410, "num-buffers", 50, NULL);
1568 gst_bin_add_many (GST_BIN (pipeline), src1, src2, mix, sink, NULL);
1569 fail_unless (gst_element_link (mix, sink));
1570
1571 srcpad = gst_element_get_static_pad (src1, "src");
1572 sinkpad = gst_element_get_request_pad (mix, "sink_1");
1573 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
1574 gst_object_unref (sinkpad);
1575 gst_object_unref (srcpad);
1576
1577 srcpad = gst_element_get_static_pad (src2, "src");
1578 sinkpad = gst_element_get_request_pad (mix, "sink_2");
1579 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
1580 /* set a pad offset of another 5 seconds */
1581 gst_pad_set_offset (sinkpad, 5 * GST_SECOND);
1582 gst_object_unref (sinkpad);
1583 gst_object_unref (srcpad);
1584
1585 gst_element_set_state (pipeline, GST_STATE_PLAYING);
1586
1587 do {
1588 g_signal_emit_by_name (sink, "pull-sample", &sample);
1589 if (sample == NULL)
1590 break;
1591 if (last_sample)
1592 gst_sample_unref (last_sample);
1593 last_sample = sample;
1594 } while (TRUE);
1595
1596 buf = gst_sample_get_buffer (last_sample);
1597 end_time = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
1598 fail_unless_equals_int64 (end_time, 10 * GST_SECOND);
1599 gst_sample_unref (last_sample);
1600
1601 gst_element_set_state (pipeline, GST_STATE_NULL);
1602 gst_object_unref (pipeline);
1603 }
1604
1605 GST_END_TEST;
1606
1607 static void
set_pad_volume_fade(GstPad * pad,GstClockTime start,gdouble start_value,GstClockTime end,gdouble end_value)1608 set_pad_volume_fade (GstPad * pad, GstClockTime start, gdouble start_value,
1609 GstClockTime end, gdouble end_value)
1610 {
1611 GstControlSource *cs;
1612 GstTimedValueControlSource *tvcs;
1613
1614 cs = gst_interpolation_control_source_new ();
1615 fail_unless (gst_object_add_control_binding (GST_OBJECT_CAST (pad),
1616 gst_direct_control_binding_new_absolute (GST_OBJECT_CAST (pad),
1617 "volume", cs)));
1618
1619 /* set volume interpolation mode */
1620 g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
1621
1622 tvcs = (GstTimedValueControlSource *) cs;
1623 fail_unless (gst_timed_value_control_source_set (tvcs, start, start_value));
1624 fail_unless (gst_timed_value_control_source_set (tvcs, end, end_value));
1625 gst_object_unref (cs);
1626 }
1627
GST_START_TEST(test_sinkpad_property_controller)1628 GST_START_TEST (test_sinkpad_property_controller)
1629 {
1630 GstBus *bus;
1631 GstMessage *msg;
1632 GstElement *pipeline, *sink, *mix, *src1;
1633 GstPad *srcpad, *sinkpad;
1634 GError *error = NULL;
1635 gchar *debug;
1636
1637 pipeline = gst_pipeline_new ("pipeline");
1638 mix = gst_element_factory_make ("audiomixer", "audiomixer");
1639 sink = gst_element_factory_make ("fakesink", "sink");
1640 src1 = gst_element_factory_make ("audiotestsrc", "src1");
1641 g_object_set (src1, "num-buffers", 100, NULL);
1642 gst_bin_add_many (GST_BIN (pipeline), src1, mix, sink, NULL);
1643 fail_unless (gst_element_link (mix, sink));
1644
1645 srcpad = gst_element_get_static_pad (src1, "src");
1646 sinkpad = gst_element_get_request_pad (mix, "sink_0");
1647 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
1648 set_pad_volume_fade (sinkpad, 0, 0, 1.0, 2.0);
1649 gst_object_unref (sinkpad);
1650 gst_object_unref (srcpad);
1651
1652 gst_element_set_state (pipeline, GST_STATE_PLAYING);
1653
1654 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
1655 msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
1656 GST_MESSAGE_EOS | GST_MESSAGE_ERROR);
1657 switch (GST_MESSAGE_TYPE (msg)) {
1658 case GST_MESSAGE_ERROR:
1659 gst_message_parse_error (msg, &error, &debug);
1660 g_printerr ("ERROR from element %s: %s\n",
1661 GST_OBJECT_NAME (msg->src), error->message);
1662 g_printerr ("Debug info: %s\n", debug);
1663 g_error_free (error);
1664 g_free (debug);
1665 break;
1666 case GST_MESSAGE_EOS:
1667 break;
1668 default:
1669 g_assert_not_reached ();
1670 }
1671 gst_message_unref (msg);
1672 g_object_unref (bus);
1673
1674 gst_element_set_state (pipeline, GST_STATE_NULL);
1675 gst_object_unref (pipeline);
1676 }
1677
1678 GST_END_TEST;
1679
1680 static void
change_src_caps(GstElement * fakesink,GstBuffer * buffer,GstPad * pad,GstElement * capsfilter)1681 change_src_caps (GstElement * fakesink, GstBuffer * buffer, GstPad * pad,
1682 GstElement * capsfilter)
1683 {
1684 GstCaps *caps = gst_caps_new_simple ("audio/x-raw",
1685 "format", G_TYPE_STRING, GST_AUDIO_NE (S32),
1686 "layout", G_TYPE_STRING, "interleaved",
1687 "rate", G_TYPE_INT, 10, "channels", G_TYPE_INT, 1, NULL);
1688
1689 g_object_set (capsfilter, "caps", caps, NULL);
1690 gst_caps_unref (caps);
1691 g_signal_connect (fakesink, "handoff", (GCallback) handoff_buffer_cb, NULL);
1692 g_signal_handlers_disconnect_by_func (fakesink, change_src_caps, capsfilter);
1693 }
1694
1695 /* In this test, we create an input buffer with a duration of 2 seconds,
1696 * and require the audiomixer to output 1 second long buffers.
1697 * The input buffer will thus be mixed twice, and the audiomixer will
1698 * output two buffers.
1699 *
1700 * After audiomixer has output a first buffer, we change its output format
1701 * from S8 to S32. As our sample rate stays the same at 10 fps, and we use
1702 * mono, the first buffer should be 10 bytes long, and the second 40.
1703 *
1704 * The input buffer is made up of 15 0-valued bytes, and 5 1-valued bytes.
1705 * We verify that the second buffer contains 5 0-valued integers, and
1706 * 5 1 << 24 valued integers.
1707 */
GST_START_TEST(test_change_output_caps)1708 GST_START_TEST (test_change_output_caps)
1709 {
1710 GstSegment segment;
1711 GstElement *bin, *audiomixer, *capsfilter, *sink;
1712 GstBus *bus;
1713 GstPad *sinkpad;
1714 gboolean res;
1715 GstStateChangeReturn state_res;
1716 GstFlowReturn ret;
1717 GstEvent *event;
1718 GstBuffer *buffer;
1719 GstCaps *caps;
1720 GstQuery *drain = gst_query_new_drain ();
1721 GstMapInfo inmap;
1722 GstMapInfo outmap;
1723 gsize i;
1724
1725 bin = gst_pipeline_new ("pipeline");
1726 bus = gst_element_get_bus (bin);
1727 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
1728
1729 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
1730 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
1731 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
1732
1733 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
1734 g_object_set (audiomixer, "output-buffer-duration", GST_SECOND, NULL);
1735 capsfilter = gst_element_factory_make ("capsfilter", NULL);
1736 sink = gst_element_factory_make ("fakesink", "sink");
1737 g_object_set (sink, "signal-handoffs", TRUE, NULL);
1738 g_signal_connect (sink, "handoff", (GCallback) change_src_caps, capsfilter);
1739 gst_bin_add_many (GST_BIN (bin), audiomixer, capsfilter, sink, NULL);
1740
1741 res = gst_element_link_many (audiomixer, capsfilter, sink, NULL);
1742 fail_unless (res == TRUE, NULL);
1743
1744 state_res = gst_element_set_state (bin, GST_STATE_PLAYING);
1745 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
1746
1747 sinkpad = gst_element_get_request_pad (audiomixer, "sink_%u");
1748 fail_if (sinkpad == NULL, NULL);
1749
1750 gst_pad_send_event (sinkpad, gst_event_new_stream_start ("test"));
1751
1752 caps = gst_caps_new_simple ("audio/x-raw",
1753 "format", G_TYPE_STRING, "S8",
1754 "layout", G_TYPE_STRING, "interleaved",
1755 "rate", G_TYPE_INT, 10, "channels", G_TYPE_INT, 1, NULL);
1756
1757 gst_pad_set_caps (sinkpad, caps);
1758 g_object_set (capsfilter, "caps", caps, NULL);
1759 gst_caps_unref (caps);
1760
1761 gst_segment_init (&segment, GST_FORMAT_TIME);
1762 segment.start = 0;
1763 segment.stop = 2 * GST_SECOND;
1764 segment.time = 0;
1765 event = gst_event_new_segment (&segment);
1766 gst_pad_send_event (sinkpad, event);
1767
1768 gst_buffer_replace (&handoff_buffer, NULL);
1769
1770 buffer = new_buffer (20, 0, 0, 2 * GST_SECOND, 0);
1771 gst_buffer_map (buffer, &inmap, GST_MAP_WRITE);
1772 memset (inmap.data + 15, 1, 5);
1773 gst_buffer_unmap (buffer, &inmap);
1774 ret = gst_pad_chain (sinkpad, buffer);
1775 ck_assert_int_eq (ret, GST_FLOW_OK);
1776 gst_pad_query (sinkpad, drain);
1777 fail_unless (handoff_buffer != NULL);
1778 fail_unless_equals_int (gst_buffer_get_size (handoff_buffer), 40);
1779
1780 gst_buffer_map (handoff_buffer, &outmap, GST_MAP_READ);
1781 for (i = 0; i < 10; i++) {
1782 guint32 sample;
1783
1784 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1785 sample = GUINT32_FROM_LE (((guint32 *) outmap.data)[i]);
1786 #else
1787 sample = GUINT32_FROM_BE (((guint32 *) outmap.data)[i]);
1788 #endif
1789
1790 if (i < 5) {
1791 fail_unless_equals_int (sample, 0);
1792 } else {
1793 fail_unless_equals_int (sample, 1 << 24);
1794 }
1795 }
1796 gst_buffer_unmap (handoff_buffer, &outmap);
1797 gst_clear_buffer (&handoff_buffer);
1798
1799 gst_element_release_request_pad (audiomixer, sinkpad);
1800 gst_object_unref (sinkpad);
1801 gst_element_set_state (bin, GST_STATE_NULL);
1802 gst_bus_remove_signal_watch (bus);
1803 gst_object_unref (bus);
1804 gst_object_unref (bin);
1805 gst_query_unref (drain);
1806 }
1807
1808 GST_END_TEST;
1809
1810 /* In this test, we create two input buffers with a duration of 1 second,
1811 * and require the audiomixer to output 1.5 second long buffers.
1812 *
1813 * After we have input two buffers, we change the output format
1814 * from S8 to S32, then push a last buffer.
1815 *
1816 * This makes audioaggregator convert its "half-mixed" current_buffer,
1817 * we can then ensure that the second output buffer is as expected.
1818 */
GST_START_TEST(test_change_output_caps_mid_output_buffer)1819 GST_START_TEST (test_change_output_caps_mid_output_buffer)
1820 {
1821 GstSegment segment;
1822 GstElement *bin, *audiomixer, *capsfilter, *sink;
1823 GstBus *bus;
1824 GstPad *sinkpad;
1825 gboolean res;
1826 GstStateChangeReturn state_res;
1827 GstFlowReturn ret;
1828 GstEvent *event;
1829 GstBuffer *buffer;
1830 GstCaps *caps;
1831 GstQuery *drain;
1832 GstMapInfo inmap;
1833 GstMapInfo outmap;
1834 guint i;
1835
1836 bin = gst_pipeline_new ("pipeline");
1837 bus = gst_element_get_bus (bin);
1838 gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
1839
1840 g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
1841 g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
1842 g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
1843
1844 audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
1845 g_object_set (audiomixer, "output-buffer-duration", 1500 * GST_MSECOND, NULL);
1846 capsfilter = gst_element_factory_make ("capsfilter", NULL);
1847 sink = gst_element_factory_make ("fakesink", "sink");
1848 gst_bin_add_many (GST_BIN (bin), audiomixer, capsfilter, sink, NULL);
1849
1850 res = gst_element_link_many (audiomixer, capsfilter, sink, NULL);
1851 fail_unless (res == TRUE, NULL);
1852
1853 state_res = gst_element_set_state (bin, GST_STATE_PLAYING);
1854 ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
1855
1856 sinkpad = gst_element_get_request_pad (audiomixer, "sink_%u");
1857 fail_if (sinkpad == NULL, NULL);
1858
1859 gst_pad_send_event (sinkpad, gst_event_new_stream_start ("test"));
1860
1861 caps = gst_caps_new_simple ("audio/x-raw",
1862 "format", G_TYPE_STRING, "S8",
1863 "layout", G_TYPE_STRING, "interleaved",
1864 "rate", G_TYPE_INT, 10, "channels", G_TYPE_INT, 1, NULL);
1865
1866 gst_pad_set_caps (sinkpad, caps);
1867 g_object_set (capsfilter, "caps", caps, NULL);
1868 gst_caps_unref (caps);
1869
1870 gst_segment_init (&segment, GST_FORMAT_TIME);
1871 segment.start = 0;
1872 segment.stop = 3 * GST_SECOND;
1873 segment.time = 0;
1874 event = gst_event_new_segment (&segment);
1875 gst_pad_send_event (sinkpad, event);
1876
1877 buffer = new_buffer (10, 0, 0, 1 * GST_SECOND, 0);
1878 ret = gst_pad_chain (sinkpad, buffer);
1879 ck_assert_int_eq (ret, GST_FLOW_OK);
1880
1881 buffer = new_buffer (10, 0, 1 * GST_SECOND, 1 * GST_SECOND, 0);
1882 gst_buffer_map (buffer, &inmap, GST_MAP_WRITE);
1883 memset (inmap.data, 1, 10);
1884 gst_buffer_unmap (buffer, &inmap);
1885 ret = gst_pad_chain (sinkpad, buffer);
1886 ck_assert_int_eq (ret, GST_FLOW_OK);
1887
1888 drain = gst_query_new_drain ();
1889 gst_pad_query (sinkpad, drain);
1890 gst_query_unref (drain);
1891
1892 caps = gst_caps_new_simple ("audio/x-raw",
1893 "format", G_TYPE_STRING, GST_AUDIO_NE (S32),
1894 "layout", G_TYPE_STRING, "interleaved",
1895 "rate", G_TYPE_INT, 10, "channels", G_TYPE_INT, 1, NULL);
1896 g_object_set (capsfilter, "caps", caps, NULL);
1897 gst_caps_unref (caps);
1898
1899 gst_buffer_replace (&handoff_buffer, NULL);
1900 g_object_set (sink, "signal-handoffs", TRUE, NULL);
1901 g_signal_connect (sink, "handoff", (GCallback) handoff_buffer_cb, NULL);
1902
1903 buffer = new_buffer (10, 0, 2 * GST_SECOND, 1 * GST_SECOND, 0);
1904 gst_buffer_map (buffer, &inmap, GST_MAP_WRITE);
1905 memset (inmap.data, 0, 10);
1906 gst_buffer_unmap (buffer, &inmap);
1907 ret = gst_pad_chain (sinkpad, buffer);
1908 ck_assert_int_eq (ret, GST_FLOW_OK);
1909
1910 drain = gst_query_new_drain ();
1911 gst_pad_query (sinkpad, drain);
1912 gst_query_unref (drain);
1913
1914 fail_unless (handoff_buffer);
1915 fail_unless_equals_int (gst_buffer_get_size (handoff_buffer), 60);
1916
1917 gst_buffer_map (handoff_buffer, &outmap, GST_MAP_READ);
1918 for (i = 0; i < 15; i++) {
1919 guint32 sample;
1920
1921 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1922 sample = GUINT32_FROM_LE (((guint32 *) outmap.data)[i]);
1923 #else
1924 sample = GUINT32_FROM_BE (((guint32 *) outmap.data)[i]);
1925 #endif
1926
1927 if (i < 5) {
1928 fail_unless_equals_int (sample, 1 << 24);
1929 } else {
1930 fail_unless_equals_int (sample, 0);
1931 }
1932 }
1933
1934 gst_buffer_unmap (handoff_buffer, &outmap);
1935 gst_clear_buffer (&handoff_buffer);
1936
1937 gst_element_release_request_pad (audiomixer, sinkpad);
1938 gst_object_unref (sinkpad);
1939 gst_element_set_state (bin, GST_STATE_NULL);
1940 gst_bus_remove_signal_watch (bus);
1941 gst_object_unref (bus);
1942 gst_object_unref (bin);
1943 }
1944
1945 GST_END_TEST;
1946 static Suite *
audiomixer_suite(void)1947 audiomixer_suite (void)
1948 {
1949 Suite *s = suite_create ("audiomixer");
1950 TCase *tc_chain = tcase_create ("general");
1951
1952 suite_add_tcase (s, tc_chain);
1953 tcase_add_test (tc_chain, test_caps);
1954 tcase_add_test (tc_chain, test_filter_caps);
1955 tcase_add_test (tc_chain, test_event);
1956 tcase_add_test (tc_chain, test_play_twice);
1957 tcase_add_test (tc_chain, test_play_twice_then_add_and_play_again);
1958 tcase_add_test (tc_chain, test_live_seeking);
1959 tcase_add_test (tc_chain, test_add_pad);
1960 tcase_add_test (tc_chain, test_remove_pad);
1961 tcase_add_test (tc_chain, test_clip);
1962 tcase_add_test (tc_chain, test_duration_is_max);
1963 tcase_add_test (tc_chain, test_duration_unknown_overrides);
1964 tcase_add_test (tc_chain, test_loop);
1965 tcase_add_test (tc_chain, test_flush_start_flush_stop);
1966 tcase_add_test (tc_chain, test_sync);
1967 tcase_add_test (tc_chain, test_sync_discont);
1968 tcase_add_test (tc_chain, test_sync_unaligned);
1969 tcase_add_test (tc_chain, test_segment_base_handling);
1970 tcase_add_test (tc_chain, test_sinkpad_property_controller);
1971 tcase_add_checked_fixture (tc_chain, test_setup, test_teardown);
1972 tcase_add_test (tc_chain, test_change_output_caps);
1973 tcase_add_test (tc_chain, test_change_output_caps_mid_output_buffer);
1974
1975 /* Use a longer timeout */
1976 #ifdef HAVE_VALGRIND
1977 if (RUNNING_ON_VALGRIND) {
1978 tcase_set_timeout (tc_chain, 5 * 60);
1979 } else
1980 #endif
1981 {
1982 /* this is shorter than the default 60 seconds?! (tpm) */
1983 /* tcase_set_timeout (tc_chain, 6); */
1984 }
1985
1986 return s;
1987 }
1988
1989 GST_CHECK_MAIN (audiomixer);
1990