3 * tests for the ipcpipelinesrc/ipcpipelinesink elements
5 * Copyright (C) 2015-2017 YouView TV Ltd
6 * Author: Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
7 * Author: George Kiagiadakis <george.kiagiadakis@collabora.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
29 #define _GNU_SOURCE /* See feature_test_macros(7) */
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <gst/check/gstcheck.h>
42 pipe2 (int pipedes[2], int flags)
44 int ret = pipe (pipedes);
48 ret = fcntl (pipedes[0], F_SETFL, flags);
51 ret = fcntl (pipedes[1], F_SETFL, flags);
59 /* This enum contains flags that are used to configure the setup that
60 * test_base() will do internally */
63 /* Features related to the multi-process setup */
64 TEST_FEATURE_SPLIT_SINKS = 0x1, /* separate audio and video sink processes */
65 TEST_FEATURE_RECOVERY_SLAVE_PROCESS = 0x2,
66 TEST_FEATURE_RECOVERY_MASTER_PROCESS = 0x4,
68 TEST_FEATURE_HAS_VIDEO = 0x10,
69 TEST_FEATURE_LIVE = 0x20, /* sets is-live=true in {audio,video}testsrc */
70 TEST_FEATURE_ASYNC_SINK = 0x40, /* sets sync=false in fakesink */
71 TEST_FEATURE_ERROR_SINK = 0x80, /* generates error message in the slave */
72 TEST_FEATURE_LONG_DURATION = 0x100, /* bigger num-buffers in {audio,video}testsrc */
73 TEST_FEATURE_FILTER_SINK_CAPS = 0x200, /* plugs capsfilter before fakesink */
75 /* Source selection; Use only one of those, do not combine! */
76 TEST_FEATURE_TEST_SOURCE = 0x400,
77 TEST_FEATURE_WAV_SOURCE = 0x800,
78 TEST_FEATURE_MPEGTS_SOURCE = 0x1000 | TEST_FEATURE_HAS_VIDEO,
79 TEST_FEATURE_LIVE_A_SOURCE =
80 TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_LIVE | TEST_FEATURE_ASYNC_SINK,
81 TEST_FEATURE_LIVE_AV_SOURCE =
82 TEST_FEATURE_LIVE_A_SOURCE | TEST_FEATURE_HAS_VIDEO,
85 /* This is the data structure that each function of the each test receives
86 * in user_data. It contains pointers to stack-allocated, test-specific
87 * structures that contain the test parameters (input data), the runtime
88 * data of the master (source) process (master data) and the runtime data
89 * of the slave (sink) process (slave data) */
92 gpointer id; /* input data struct */
93 gpointer md; /* master data struct */
94 gpointer sd; /* slave data struct */
96 TestFeatures features; /* the features that this test is running with */
98 /* whether there is both an audio and a video stream
99 * in this process'es pipeline */
100 gboolean two_streams;
102 /* the pipeline of this process; could be either master or slave */
105 /* this callback will be called in the master process when
106 * the master gets STATE_CHANGED with the new state being state_target */
107 void (*state_changed_cb) (gpointer);
108 GstState state_target;
110 /* used by EXCLUSIVE_CALL() */
111 gint exclusive_call_counter;
114 /* All pipelines do not start buffers at exactly zero, so we consider
115 timestamps within a small tolerance to be zero */
116 #define CLOSE_ENOUGH_TO_ZERO (GST_SECOND / 5)
123 #define MESSAGE_AT 600
127 /* Rough duration of the sample files we use */
128 #define MPEGTS_SAMPLE_ROUGH_DURATION (GST_SECOND * 64 / 10)
129 #define WAV_SAMPLE_ROUGH_DURATION (GST_SECOND * 65 / 10)
137 static GMainLoop *loop;
138 static gboolean child_dead;
139 static int pipesfa[2], pipesba[2], pipesfv[2], pipesbv[2];
140 static int ctlsock[2];
141 static int recovery_pid = 0;
142 static int check_fd = -1;
143 static GList *weak_refs = NULL;
147 #define FAIL_IF(x) do { lock_check (); fail_if(x); unlock_check (); } while(0)
148 #define FAIL_UNLESS(x) do { lock_check (); fail_unless(x); unlock_check (); } while(0)
149 #define FAIL_UNLESS_EQUALS_INT(x,y) do { lock_check (); fail_unless_equals_int(x,y); unlock_check (); } while(0)
150 #define FAIL() do { lock_check (); fail(); unlock_check (); } while(0)
155 flock (check_fd, LOCK_EX);
161 flock (check_fd, LOCK_UN);
168 check_fd = g_file_open_tmp (NULL, &name, NULL);
173 /* tracking for ipcpipeline elements; this is used mainly to detect leaks,
174 * but also to provide a method for calling "disconnect" on all of them
175 * in the tests that require it */
178 remove_weak_ref (GstElement * element)
180 weak_refs = g_list_remove (weak_refs, element);
184 add_weak_ref (GstElement * element)
186 weak_refs = g_list_append (weak_refs, element);
187 g_object_weak_ref (G_OBJECT (element), (GWeakNotify) remove_weak_ref,
192 disconnect_ipcpipeline_elements (void)
196 for (l = weak_refs; l; l = l->next) {
197 g_signal_emit_by_name (G_OBJECT (l->data), "disconnect", NULL);
201 /* helper functions */
203 #define EXCLUSIVE_CALL(td,func) \
205 if (!td->two_streams || \
206 g_atomic_int_add (&td->exclusive_call_counter, 1) == 1) { \
212 cleanup_bus (GstElement * pipeline)
214 gst_bus_remove_watch (GST_ELEMENT_BUS (pipeline));
215 gst_bus_set_flushing (GST_ELEMENT_BUS (pipeline), TRUE);
219 setup_log (const char *logfile, int append)
223 f = fopen (logfile, append ? "a+" : "w");
224 gst_debug_add_log_function (gst_debug_log_default, f, NULL);
228 create_pipeline (const char *type)
230 GstElement *pipeline;
232 pipeline = gst_element_factory_make (type, NULL);
233 FAIL_UNLESS (pipeline);
239 to_be_removed_quark (void)
243 q = g_quark_from_static_string ("to_be_removed");
248 are_caps_audio (const GstCaps * caps)
250 GstStructure *structure;
253 structure = gst_caps_get_structure (caps, 0);
254 name = gst_structure_get_name (structure);
255 return g_str_has_prefix (name, "audio/");
259 are_caps_video (const GstCaps * caps)
261 GstStructure *structure;
264 structure = gst_caps_get_structure (caps, 0);
265 name = gst_structure_get_name (structure);
266 return (g_str_has_prefix (name, "video/")
267 && strcmp (name, "video/x-dvd-subpicture"));
271 caps2idx (GstCaps * caps, gboolean two_streams)
278 if (are_caps_audio (caps)) {
280 } else if (are_caps_video (caps)) {
290 pad2idx (GstPad * pad, gboolean two_streams)
298 caps = gst_pad_get_current_caps (pad);
300 caps = gst_pad_get_pad_template_caps (pad);
303 idx = caps2idx (caps, two_streams);
305 gst_caps_unref (caps);
310 stop_pipeline (gpointer user_data)
312 GstElement *pipeline = user_data;
313 GstStateChangeReturn ret;
315 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
316 FAIL_IF (ret == GST_STATE_CHANGE_FAILURE);
317 gst_object_unref (pipeline);
318 g_main_loop_quit (loop);
323 hook_peer_probe_types (const GValue * sinkv, GstPadProbeCallback probe,
324 unsigned int types, gpointer user_data)
329 sink = g_value_get_object (sinkv);
331 pad = gst_element_get_static_pad (sink, "sink");
333 peer = gst_pad_get_peer (pad);
335 gst_pad_add_probe (peer, types, probe, user_data, NULL);
336 gst_object_unref (peer);
337 gst_object_unref (pad);
341 hook_probe_types (const GValue * sinkv, GstPadProbeCallback probe,
342 unsigned int types, gpointer user_data)
347 sink = g_value_get_object (sinkv);
349 pad = gst_element_get_static_pad (sink, "sink");
351 gst_pad_add_probe (pad, types, probe, user_data, NULL);
352 gst_object_unref (pad);
356 hook_probe (const GValue * sinkv, GstPadProbeCallback probe, gpointer user_data)
358 hook_probe_types (sinkv, probe,
359 GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH |
360 GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, user_data);
363 /* the master process'es async GstBus callback */
365 master_bus_msg (GstBus * bus, GstMessage * message, gpointer user_data)
367 test_data *td = user_data;
369 switch (GST_MESSAGE_TYPE (message)) {
370 case GST_MESSAGE_ERROR:{
374 /* elements we are removing might error out as they are taken out
375 of the pipeline, and fail to push. We don't care about those. */
376 if (g_object_get_qdata (G_OBJECT (GST_MESSAGE_SRC (message)),
377 to_be_removed_quark ()))
380 gst_message_parse_error (message, &err, &dbg);
381 g_printerr ("ERROR: %s\n", err->message);
383 g_printerr ("ERROR debug information: %s\n", dbg);
386 g_assert_not_reached ();
389 case GST_MESSAGE_WARNING:{
393 gst_message_parse_warning (message, &err, &dbg);
394 g_printerr ("WARNING: %s\n", err->message);
396 g_printerr ("WARNING debug information: %s\n", dbg);
399 g_assert_not_reached ();
402 case GST_MESSAGE_EOS:
403 g_main_loop_quit (loop);
405 case GST_MESSAGE_STATE_CHANGED:
406 if (GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (td->p)
407 && td->state_changed_cb) {
409 gst_message_parse_state_changed (message, NULL, &state, NULL);
410 if (state == td->state_target)
411 td->state_changed_cb (td);
420 /* source construction functions */
423 create_wavparse_source_loc (const char *loc, int fdina, int fdouta)
425 GstElement *sbin, *pipeline, *filesrc, *ipcpipelinesink;
428 pipeline = create_pipeline ("pipeline");
430 gst_parse_bin_from_description ("pushfilesrc name=filesrc ! wavparse",
432 FAIL_IF (e || !sbin);
433 gst_element_set_name (sbin, "source");
434 filesrc = gst_bin_get_by_name (GST_BIN (sbin), "filesrc");
435 FAIL_UNLESS (filesrc);
436 g_object_set (filesrc, "location", loc, NULL);
437 gst_object_unref (filesrc);
439 gst_element_factory_make ("ipcpipelinesink", "ipcpipelinesink");
440 add_weak_ref (ipcpipelinesink);
441 g_object_set (ipcpipelinesink, "fdin", fdina, "fdout", fdouta, NULL);
442 gst_bin_add_many (GST_BIN (pipeline), sbin, ipcpipelinesink, NULL);
443 FAIL_UNLESS (gst_element_link_many (sbin, ipcpipelinesink, NULL));
449 on_pad_added (GstElement * element, GstPad * pad, gpointer data)
453 GstBin *pipeline = data;
456 caps = gst_pad_get_current_caps (pad);
458 caps = gst_pad_get_pad_template_caps (pad);
460 if (are_caps_video (caps)) {
461 next = gst_bin_get_by_name (GST_BIN (pipeline), "vqueue");
462 } else if (are_caps_audio (caps)) {
463 next = gst_bin_get_by_name (GST_BIN (pipeline), "aqueue");
465 gst_caps_unref (caps);
468 gst_caps_unref (caps);
471 sink_pad = gst_element_get_static_pad (next, "sink");
472 FAIL_UNLESS (sink_pad);
473 FAIL_UNLESS (gst_pad_link (pad, sink_pad) == GST_PAD_LINK_OK);
474 gst_object_unref (sink_pad);
476 gst_object_unref (next);
480 create_mpegts_source_loc (const char *loc, int fdina, int fdouta, int fdinv,
483 GstElement *pipeline, *filesrc, *tsdemux, *aqueue, *vqueue, *aipcpipelinesink,
486 pipeline = create_pipeline ("pipeline");
487 filesrc = gst_element_factory_make ("filesrc", NULL);
488 g_object_set (filesrc, "location", loc, NULL);
489 tsdemux = gst_element_factory_make ("tsdemux", NULL);
490 g_signal_connect (tsdemux, "pad-added", G_CALLBACK (on_pad_added), pipeline);
491 aqueue = gst_element_factory_make ("queue", "aqueue");
492 aipcpipelinesink = gst_element_factory_make ("ipcpipelinesink", NULL);
493 add_weak_ref (aipcpipelinesink);
494 g_object_set (aipcpipelinesink, "fdin", fdina, "fdout", fdouta, NULL);
495 vqueue = gst_element_factory_make ("queue", "vqueue");
496 vipcpipelinesink = gst_element_factory_make ("ipcpipelinesink", NULL);
497 add_weak_ref (vipcpipelinesink);
498 g_object_set (vipcpipelinesink, "fdin", fdinv, "fdout", fdoutv, NULL);
499 gst_bin_add_many (GST_BIN (pipeline), filesrc, tsdemux, aqueue,
500 aipcpipelinesink, vqueue, vipcpipelinesink, NULL);
501 FAIL_UNLESS (gst_element_link_many (filesrc, tsdemux, NULL));
502 FAIL_UNLESS (gst_element_link_many (aqueue, aipcpipelinesink, NULL));
503 FAIL_UNLESS (gst_element_link_many (vqueue, vipcpipelinesink, NULL));
509 create_test_source (gboolean live, int fdina, int fdouta, int fdinv, int fdoutv,
510 gboolean audio, gboolean video, gboolean Long)
512 GstElement *pipeline, *audiotestsrc, *aipcpipelinesink;
513 GstElement *videotestsrc, *vipcpipelinesink;
514 int L = Long ? 2 : 1;
516 pipeline = create_pipeline ("pipeline");
519 audiotestsrc = gst_element_factory_make ("audiotestsrc", "audiotestsrc");
520 g_object_set (audiotestsrc, "is-live", live, "num-buffers",
521 live ? 270 * L : 600, NULL);
522 aipcpipelinesink = gst_element_factory_make ("ipcpipelinesink",
524 add_weak_ref (aipcpipelinesink);
525 g_object_set (aipcpipelinesink, "fdin", fdina, "fdout", fdouta, NULL);
526 gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, aipcpipelinesink, NULL);
527 FAIL_UNLESS (gst_element_link_many (audiotestsrc, aipcpipelinesink, NULL));
531 videotestsrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
532 g_object_set (videotestsrc, "is-live", live, "num-buffers",
533 live ? 190 * L : 600, NULL);
535 gst_element_factory_make ("ipcpipelinesink", "vipcpipelinesink");
536 add_weak_ref (vipcpipelinesink);
537 g_object_set (vipcpipelinesink, "fdin", fdinv, "fdout", fdoutv, NULL);
538 gst_bin_add_many (GST_BIN (pipeline), videotestsrc, vipcpipelinesink, NULL);
539 FAIL_UNLESS (gst_element_link_many (videotestsrc, vipcpipelinesink, NULL));
546 create_source (TestFeatures features, int fdina, int fdouta, int fdinv,
547 int fdoutv, test_data * td)
549 GstElement *pipeline = NULL;
550 gboolean live = ! !(features & TEST_FEATURE_LIVE);
551 gboolean longdur = ! !(features & TEST_FEATURE_LONG_DURATION);
552 gboolean has_video = ! !(features & TEST_FEATURE_HAS_VIDEO);
554 if (features & TEST_FEATURE_TEST_SOURCE) {
556 pipeline = create_test_source (live, fdina, fdouta, fdinv, fdoutv, TRUE,
558 } else if (features & TEST_FEATURE_WAV_SOURCE) {
559 pipeline = create_wavparse_source_loc ("../../tests/files/sine.wav", fdina,
561 } else if (features & TEST_FEATURE_MPEGTS_SOURCE) {
562 pipeline = create_mpegts_source_loc ("../../tests/files/test.ts", fdina,
563 fdouta, fdinv, fdoutv);
565 g_assert_not_reached ();
568 td->two_streams = has_video;
572 gst_bus_add_watch (GST_ELEMENT_BUS (pipeline), master_bus_msg, td);
577 /* sink construction */
580 create_sink (TestFeatures features, GstElement ** slave_pipeline,
581 int fdin, int fdout, const char *filter_caps)
583 GstElement *ipcpipelinesrc, *fakesink, *identity, *capsfilter, *endpoint;
586 if (!*slave_pipeline)
587 *slave_pipeline = create_pipeline ("ipcslavepipeline");
589 gst_object_ref (*slave_pipeline);
590 ipcpipelinesrc = gst_element_factory_make ("ipcpipelinesrc", NULL);
591 add_weak_ref (ipcpipelinesrc);
592 g_object_set (ipcpipelinesrc, "fdin", fdin, "fdout", fdout, NULL);
593 fakesink = gst_element_factory_make ("fakesink", NULL);
594 g_object_set (fakesink, "sync", !(features & TEST_FEATURE_ASYNC_SINK), NULL);
595 gst_bin_add_many (GST_BIN (*slave_pipeline), ipcpipelinesrc, fakesink, NULL);
596 endpoint = ipcpipelinesrc;
598 if (features & TEST_FEATURE_ERROR_SINK &&
599 !g_strcmp0 (filter_caps, "audio/x-raw")) {
600 identity = gst_element_factory_make ("identity", "error-element");
601 g_object_set (identity, "error-after", 5, NULL);
602 gst_bin_add (GST_BIN (*slave_pipeline), identity);
603 FAIL_UNLESS (gst_element_link_many (endpoint, identity, NULL));
607 if ((features & TEST_FEATURE_FILTER_SINK_CAPS) && filter_caps) {
608 capsfilter = gst_element_factory_make ("capsfilter", NULL);
609 caps = gst_caps_from_string (filter_caps);
611 g_object_set (capsfilter, "caps", caps, NULL);
612 gst_caps_unref (caps);
613 gst_bin_add (GST_BIN (*slave_pipeline), capsfilter);
614 FAIL_UNLESS (gst_element_link_many (endpoint, capsfilter, NULL));
615 endpoint = capsfilter;
617 FAIL_UNLESS (gst_element_link_many (endpoint, fakesink, NULL));
619 return *slave_pipeline;
623 ensure_sink_setup (GstElement * sink, void (*setup_sink) (GstElement *, void *),
626 static GQuark setup_done = 0;
627 test_data *td = user_data;
630 setup_done = g_quark_from_static_string ("setup_done");
635 if (sink && setup_sink && !g_object_get_qdata (G_OBJECT (sink), setup_done)) {
636 g_object_set_qdata (G_OBJECT (sink), setup_done, GINT_TO_POINTER (1));
637 setup_sink (sink, user_data);
641 /* GstCheck multi-process setup helpers */
644 on_child_exit (int signal)
647 if (waitpid (-1, &status, 0) > 0 && status) {
656 die_on_child_death (void)
660 memset (&sa, 0, sizeof (sa));
661 sa.sa_handler = on_child_exit;
662 sigaction (SIGCHLD, &sa, NULL);
666 wait_for_recovery (void)
670 FAIL_UNLESS (ctlsock[1]);
671 FAIL_UNLESS (read (ctlsock[1], &value, sizeof (int)) == sizeof (int));
672 FAIL_UNLESS (value == MSG_START);
679 FAIL_UNLESS (ctlsock[1]);
680 FAIL_UNLESS (write (ctlsock[1], &value, sizeof (int)) == sizeof (int));
684 recreate_crashed_slave_process (void)
686 int value = MSG_START;
687 /* We don't recreate, because there seems to be some subtle issues
688 with forking after gst has started running. So we create a new
689 recovery process at start, and wake it up after the current
690 slave dies, so it can take its place. It's a bit hacky, but it
691 works. The spare process waits for SIGUSR2 to setup a replacement
692 pipeline and connect to the master. */
693 FAIL_UNLESS (recovery_pid);
694 FAIL_UNLESS (ctlsock[0]);
695 FAIL_UNLESS (write (ctlsock[0], &value, sizeof (int)) == sizeof (int));
696 FAIL_UNLESS (read (ctlsock[0], &value, sizeof (int)) == sizeof (int));
697 FAIL_UNLESS (value == MSG_ACK);
701 crash (gpointer user_data)
707 unwind (gpointer user_data)
709 g_main_loop_quit (loop);
714 on_unwind (int signal)
716 g_idle_add (unwind, NULL);
720 listen_for_unwind (void)
724 memset (&sa, 0, sizeof (sa));
725 sa.sa_handler = on_unwind;
726 sigaction (SIGUSR1, &sa, NULL);
730 stop_listening_for_unwind (void)
734 memset (&sa, 0, sizeof (sa));
735 sa.sa_handler = SIG_DFL;
736 sigaction (SIGUSR1, &sa, NULL);
739 #define TEST_BASE(...) test_base(__FUNCTION__,##__VA_ARGS__)
742 * This is the main function driving the tests. All tests configure it
743 * by way of all the function pointers it takes as arguments, which have
744 * self-explanatory names.
745 * Most tests are run over a number of different pipelines with the same
746 * configuration (eg, a wavparse based pipeline, a live pipeline with
747 * test audio/video, etc). Those pipelines that have more than one sink
748 * (eg, MPEG-TS source demuxing audio and video) have a version with a
749 * single slave pipeline and process, and a version with the audio and
750 * video sinks in two different processes, each with its slave pipeline.
751 * The master and slave crash tests are also run via this function, and
752 * have specific code (grep for recovery).
753 * There is a fair amount of hairy stuff to do with letting the main
754 * check process when a subprocess has failed. Best not to look at it
755 * and let it do its thing.
756 * To add new tests, duplicate a set of tests, eg the *_end_of_stream
757 * ones, and s/_end_of_stream/new_test_name/g. Then do the same for
758 * the functions they pass as parameters to test_base. Typically, the
759 * source creation sets a message hook to catch things like async-done
760 * messages. Sink creation typically adds a probe to check that events,
761 * buffers, etc, come through as expected. The two success functions
762 * check all went well for the source and sink. Note that since all of
763 * these functions take the same user data structure, and the process
764 * will fork, writing something from one process will not be reflected
765 * in the other, so there is usually a subset of data relevant to the
766 * source, and another to the sink. But some have data relevant to both,
767 * it depends on the test and what you are doing.
768 * New tests do not have to use this framework, it just avoids spending
769 * more time and effort on multi process handling.
772 test_base (const char *name, TestFeatures features,
773 void (*run_source) (GstElement *, void *),
774 void (*setup_sink) (GstElement *, void *),
775 void (*check_success_source) (void *),
776 void (*check_success_sink) (void *),
777 gpointer input_data, gpointer master_data, gpointer slave_data)
779 GstElement *source = NULL, *asink = NULL, *vsink = NULL;
780 GstElement *slave_pipeline = NULL;
781 GstStateChangeReturn ret;
782 gboolean c_src, c_sink;
785 int master_recovery_pid_comm[2] = { -1, -1 };
786 test_data td = { input_data, master_data, slave_data, features, FALSE, NULL,
787 NULL, GST_STATE_NULL, 0
790 g_print ("Testing: %s\n", name);
794 FAIL_IF (pipe2 (pipesfa, O_NONBLOCK) < 0);
795 FAIL_IF (pipe2 (pipesba, O_NONBLOCK) < 0);
796 FAIL_IF (pipe2 (pipesfv, O_NONBLOCK) < 0);
797 FAIL_IF (pipe2 (pipesbv, O_NONBLOCK) < 0);
798 FAIL_IF (socketpair (PF_UNIX, SOCK_STREAM, 0, ctlsock) < 0);
800 FAIL_IF (pipesfa[0] < 0);
801 FAIL_IF (pipesfa[1] < 0);
802 FAIL_IF (pipesba[0] < 0);
803 FAIL_IF (pipesba[1] < 0);
804 FAIL_IF (pipesfv[0] < 0);
805 FAIL_IF (pipesfv[1] < 0);
806 FAIL_IF (pipesbv[0] < 0);
807 FAIL_IF (pipesbv[1] < 0);
809 gst_debug_remove_log_function (gst_debug_log_default);
811 listen_for_unwind ();
814 if (features & TEST_FEATURE_RECOVERY_MASTER_PROCESS) {
815 /* the other master will let us know its child's PID so we can unwind
816 it when we're finished */
817 FAIL_IF (pipe2 (master_recovery_pid_comm, O_NONBLOCK) < 0);
819 recovery_pid = fork ();
820 if (recovery_pid > 0) {
821 /* we're the main process that libcheck waits for */
822 die_on_child_death ();
825 /* leave some time for the slave to timeout (1 second), record error, etc */
826 g_usleep (1500 * 1000);
828 /* Discard anything that was sent to the previous process when it died */
829 while (read (pipesba[0], &x, 1) == 1);
831 FAIL_UNLESS (read (master_recovery_pid_comm[0], &pid,
832 sizeof (pid)) == sizeof (pid));
834 setup_log ("gstsrc.log", TRUE);
835 source = create_source (features, pipesba[0], pipesfa[1], pipesbv[0],
837 FAIL_UNLESS (source);
839 run_source (source, &td);
844 if (features & TEST_FEATURE_RECOVERY_SLAVE_PROCESS) {
845 recovery_pid = fork ();
847 wait_for_recovery ();
849 /* Discard anything that was sent to the previous process when it died */
850 while (read (pipesfa[0], &x, 1) == 1);
852 setup_log ("gstasink.log", TRUE);
853 asink = create_sink (features, &slave_pipeline, pipesfa[0], pipesba[1],
856 ensure_sink_setup (asink, setup_sink, &td);
865 if (features & TEST_FEATURE_RECOVERY_MASTER_PROCESS) {
866 FAIL_UNLESS (write (master_recovery_pid_comm[1], &pid,
867 sizeof (pid)) == sizeof (pid));
869 die_on_child_death ();
870 if (features & TEST_FEATURE_SPLIT_SINKS) {
874 die_on_child_death ();
883 setup_log ("gstsrc.log", FALSE);
884 source = create_source (features, pipesba[0], pipesfa[1], pipesbv[0],
886 FAIL_UNLESS (source);
887 run_source (source, &td);
890 setup_log ("gstasink.log", FALSE);
891 asink = create_sink (features, &slave_pipeline, pipesfa[0], pipesba[1],
896 td.two_streams = (features & TEST_FEATURE_HAS_VIDEO) &&
897 !(features & TEST_FEATURE_SPLIT_SINKS);
899 if (features & TEST_FEATURE_HAS_VIDEO) {
900 setup_log ("gstvsink.log", FALSE);
901 vsink = create_sink (features, &slave_pipeline, pipesfv[0], pipesbv[1],
905 if (!(features & TEST_FEATURE_SPLIT_SINKS)) {
906 setup_log ("gstasink.log", FALSE);
907 asink = create_sink (features, &slave_pipeline, pipesfa[0], pipesba[1],
914 ensure_sink_setup (asink, setup_sink, &td);
915 ensure_sink_setup (vsink, setup_sink, &td);
917 loop = g_main_loop_new (NULL, FALSE);
918 g_main_loop_run (loop);
920 /* tell the child process to unwind too */
921 stop_listening_for_unwind ();
924 ret = gst_element_set_state (source, GST_STATE_NULL);
925 FAIL_UNLESS (ret == GST_STATE_CHANGE_SUCCESS
926 || ret == GST_STATE_CHANGE_ASYNC);
932 g_main_loop_unref (loop);
935 cleanup_bus (source);
936 if (check_success_source)
937 check_success_source (&td);
943 if (check_success_sink)
944 check_success_sink (&td);
947 disconnect_ipcpipeline_elements ();
958 /* If we have a child, we must now wait for it to be finished.
959 We can't just waitpid, because this child might be still doing
960 its shutdown, and might assert, and the die_on_child_death
961 function will exit with the right exit code if so. So we wait
962 for the child_dead boolean to be set, which die_on_child_death
963 sets if the child dies normally. */
970 FAIL_UNLESS_EQUALS_INT (GST_OBJECT_REFCOUNT_VALUE (source), 1);
971 gst_object_unref (source);
973 /* asink and vsink may be the same object, so refcount is not sure to be 1 */
975 gst_object_unref (asink);
977 gst_object_unref (vsink);
979 /* cleanup tasks a bit earlier to make sure all weak refs are gone */
980 gst_task_cleanup_all ();
982 /* all ipcpipeline elements we created should now be destroyed */
985 /* to make it easier to see what leaks */
987 for (l = weak_refs; l; l = l->next) {
988 g_print ("%s has %u refs\n", GST_ELEMENT_NAME (l->data),
989 GST_OBJECT_REFCOUNT_VALUE (l->data));
996 /**** play-pause test ****/
1000 gboolean got_state_changed_to_playing[2];
1001 gboolean got_state_changed_to_paused;
1002 } play_pause_master_data;
1004 #define PLAY_PAUSE_MASTER_DATA_INIT { { FALSE, FALSE }, FALSE }
1008 gboolean got_caps[2];
1009 gboolean got_segment[2];
1010 gboolean got_buffer[2];
1011 } play_pause_slave_data;
1013 #define PLAY_PAUSE_SLAVE_DATA_INIT \
1014 { { FALSE, FALSE }, { FALSE, FALSE }, { FALSE, FALSE } }
1017 idlenull (gpointer user_data)
1019 test_data *td = user_data;
1020 GstStateChangeReturn ret;
1022 ret = gst_element_set_state (td->p, GST_STATE_NULL);
1023 FAIL_UNLESS (ret == GST_STATE_CHANGE_SUCCESS);
1024 gst_object_unref (td->p);
1025 g_main_loop_quit (loop);
1026 return G_SOURCE_REMOVE;
1029 static gboolean idleplay (gpointer user_data);
1031 idlepause (gpointer user_data)
1033 test_data *td = user_data;
1034 play_pause_master_data *d = td->md;
1035 GstStateChangeReturn ret;
1037 ret = gst_element_set_state (td->p, GST_STATE_PAUSED);
1038 FAIL_IF (ret == GST_STATE_CHANGE_FAILURE);
1039 if (ret == GST_STATE_CHANGE_SUCCESS || ret == GST_STATE_CHANGE_NO_PREROLL) {
1040 /* if the state change is not async, we won't get an aync-done, but
1041 this is expected, so set the flag here */
1042 d->got_state_changed_to_paused = TRUE;
1043 td->state_target = GST_STATE_PLAYING;
1044 g_timeout_add (STEP_AT, idleplay, user_data);
1045 return G_SOURCE_REMOVE;
1047 gst_object_unref (td->p);
1048 return G_SOURCE_REMOVE;
1052 idleplay (gpointer user_data)
1054 test_data *td = user_data;
1055 play_pause_master_data *d = td->md;
1056 GstStateChangeReturn ret;
1058 ret = gst_element_set_state (td->p, GST_STATE_PLAYING);
1059 FAIL_IF (ret == GST_STATE_CHANGE_FAILURE);
1060 if (ret == GST_STATE_CHANGE_SUCCESS || ret == GST_STATE_CHANGE_NO_PREROLL) {
1061 /* if the state change is not async, we won't get an aync-done, but
1062 this is expected, so set the flag here */
1063 d->got_state_changed_to_playing[1] = TRUE;
1064 td->state_target = GST_STATE_NULL;
1065 g_timeout_add (STEP_AT, idlenull, user_data);
1066 return G_SOURCE_REMOVE;
1068 gst_object_unref (td->p);
1069 return G_SOURCE_REMOVE;
1073 play_pause_on_state_changed (gpointer user_data)
1075 test_data *td = user_data;
1076 play_pause_master_data *d = td->md;
1077 GstStateChangeReturn ret;
1079 if (d->got_state_changed_to_paused) {
1080 d->got_state_changed_to_playing[1] = TRUE;
1081 td->state_target = GST_STATE_NULL;
1082 ret = gst_element_set_state (td->p, GST_STATE_NULL);
1083 FAIL_UNLESS (ret == GST_STATE_CHANGE_SUCCESS);
1084 g_main_loop_quit (loop);
1085 } else if (d->got_state_changed_to_playing[0]) {
1086 d->got_state_changed_to_paused = TRUE;
1087 td->state_target = GST_STATE_PLAYING;
1088 gst_object_ref (td->p);
1089 g_timeout_add (STEP_AT, (GSourceFunc) idleplay, td);
1091 d->got_state_changed_to_playing[0] = TRUE;
1092 td->state_target = GST_STATE_PAUSED;
1093 gst_object_ref (td->p);
1094 g_timeout_add (STEP_AT, (GSourceFunc) idlepause, td);
1099 play_pause_source (GstElement * source, void *user_data)
1101 test_data *td = user_data;
1102 GstStateChangeReturn ret;
1104 td->state_target = GST_STATE_PLAYING;
1105 td->state_changed_cb = play_pause_on_state_changed;
1106 ret = gst_element_set_state (source, GST_STATE_PLAYING);
1107 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
1110 static GstPadProbeReturn
1111 play_pause_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1113 test_data *td = user_data;
1114 play_pause_slave_data *d = td->sd;
1117 if (GST_IS_BUFFER (info->data)) {
1118 d->got_buffer[pad2idx (pad, td->two_streams)] = TRUE;
1119 } else if (GST_IS_EVENT (info->data)) {
1120 if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
1121 gst_event_parse_caps (info->data, &caps);
1122 d->got_caps[caps2idx (caps, td->two_streams)] = TRUE;
1123 } else if (GST_EVENT_TYPE (info->data) == GST_EVENT_SEGMENT) {
1124 d->got_segment[pad2idx (pad, td->two_streams)] = TRUE;
1128 return GST_PAD_PROBE_OK;
1132 hook_play_pause_probe (const GValue * v, gpointer user_data)
1134 hook_probe (v, play_pause_probe, user_data);
1138 setup_sink_play_pause (GstElement * sink, void *user_data)
1142 it = gst_bin_iterate_sinks (GST_BIN (sink));
1143 while (gst_iterator_foreach (it, hook_play_pause_probe, user_data))
1144 gst_iterator_resync (it);
1145 gst_iterator_free (it);
1149 check_success_source_play_pause (void *user_data)
1151 test_data *td = user_data;
1152 play_pause_master_data *d = td->md;
1154 FAIL_UNLESS (d->got_state_changed_to_playing[0]);
1155 FAIL_UNLESS (d->got_state_changed_to_playing[1]);
1156 FAIL_UNLESS (d->got_state_changed_to_paused);
1160 check_success_sink_play_pause (void *user_data)
1162 test_data *td = user_data;
1163 play_pause_slave_data *d = td->sd;
1166 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
1167 FAIL_UNLESS (d->got_caps[idx]);
1168 FAIL_UNLESS (d->got_segment[idx]);
1169 FAIL_UNLESS (d->got_buffer[idx]);
1173 GST_START_TEST (test_empty_play_pause)
1175 play_pause_master_data md = PLAY_PAUSE_MASTER_DATA_INIT;
1176 play_pause_slave_data sd = PLAY_PAUSE_SLAVE_DATA_INIT;
1178 TEST_BASE (TEST_FEATURE_TEST_SOURCE, play_pause_source, setup_sink_play_pause,
1179 check_success_source_play_pause, check_success_sink_play_pause, NULL, &md,
1185 GST_START_TEST (test_wavparse_play_pause)
1187 play_pause_master_data md = PLAY_PAUSE_MASTER_DATA_INIT;
1188 play_pause_slave_data sd = PLAY_PAUSE_SLAVE_DATA_INIT;
1190 TEST_BASE (TEST_FEATURE_WAV_SOURCE, play_pause_source, setup_sink_play_pause,
1191 check_success_source_play_pause, check_success_sink_play_pause, NULL, &md,
1197 GST_START_TEST (test_mpegts_play_pause)
1199 play_pause_master_data md = PLAY_PAUSE_MASTER_DATA_INIT;
1200 play_pause_slave_data sd = PLAY_PAUSE_SLAVE_DATA_INIT;
1202 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, play_pause_source,
1203 setup_sink_play_pause, check_success_source_play_pause,
1204 check_success_sink_play_pause, NULL, &md, &sd);
1209 GST_START_TEST (test_mpegts_2_play_pause)
1211 play_pause_master_data md = PLAY_PAUSE_MASTER_DATA_INIT;
1212 play_pause_slave_data sd = PLAY_PAUSE_SLAVE_DATA_INIT;
1214 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
1215 play_pause_source, setup_sink_play_pause, check_success_source_play_pause,
1216 check_success_sink_play_pause, NULL, &md, &sd);
1221 GST_START_TEST (test_live_a_play_pause)
1223 play_pause_master_data md = PLAY_PAUSE_MASTER_DATA_INIT;
1224 play_pause_slave_data sd = PLAY_PAUSE_SLAVE_DATA_INIT;
1226 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, play_pause_source,
1227 setup_sink_play_pause, check_success_source_play_pause,
1228 check_success_sink_play_pause, NULL, &md, &sd);
1233 GST_START_TEST (test_live_av_play_pause)
1235 play_pause_master_data md = PLAY_PAUSE_MASTER_DATA_INIT;
1236 play_pause_slave_data sd = PLAY_PAUSE_SLAVE_DATA_INIT;
1238 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, play_pause_source,
1239 setup_sink_play_pause, check_success_source_play_pause,
1240 check_success_sink_play_pause, NULL, &md, &sd);
1245 GST_START_TEST (test_live_av_2_play_pause)
1247 play_pause_master_data md = PLAY_PAUSE_MASTER_DATA_INIT;
1248 play_pause_slave_data sd = PLAY_PAUSE_SLAVE_DATA_INIT;
1250 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
1251 play_pause_source, setup_sink_play_pause, check_success_source_play_pause,
1252 check_success_sink_play_pause, NULL, &md, &sd);
1257 /**** flushing seek test ****/
1261 gboolean segment_seek;
1263 } flushing_seek_input_data;
1265 #define FLUSHING_SEEK_INPUT_DATA_INIT { FALSE, FALSE }
1266 #define FLUSHING_SEEK_INPUT_DATA_INIT_PAUSED { FALSE, TRUE }
1267 #define FLUSHING_SEEK_INPUT_DATA_INIT_SEGMENT_SEEK { TRUE, FALSE }
1271 gboolean got_state_changed_to_playing;
1272 gboolean got_segment_done;
1274 } flushing_seek_master_data;
1276 #define FLUSHING_SEEK_MASTER_DATA_INIT { FALSE, FALSE, FALSE }
1280 GstClockTime first_ts[2];
1281 gboolean got_caps[2];
1282 gboolean got_buffer_before_seek[2];
1283 gboolean got_buffer_after_seek[2];
1284 gboolean first_buffer_after_seek_has_timestamp_0[2];
1285 gboolean got_segment_after_seek[2];
1286 gboolean got_flush_start[2];
1287 gboolean got_flush_stop[2];
1288 } flushing_seek_slave_data;
1290 #define FLUSHING_SEEK_SLAVE_DATA_INIT { { 0, 0 }, }
1293 send_flushing_seek (gpointer user_data)
1295 test_data *td = user_data;
1296 const flushing_seek_input_data *i = td->id;
1297 flushing_seek_master_data *d = td->md;
1298 GstEvent *seek_event;
1300 if (i->segment_seek) {
1301 GST_INFO_OBJECT (td->p, "Sending segment seek");
1303 gst_event_new_seek (1.0, GST_FORMAT_TIME,
1304 GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0,
1305 GST_SEEK_TYPE_SET, 1 * GST_SECOND);
1306 FAIL_UNLESS (gst_element_send_event (td->p, seek_event));
1308 GST_INFO_OBJECT (td->p, "Sending flushing seek");
1309 gst_element_seek_simple (td->p, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 0);
1310 g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline,
1311 gst_object_ref (td->p));
1313 d->seek_sent = TRUE;
1314 return G_SOURCE_REMOVE;
1318 pause_before_seek (gpointer user_data)
1320 test_data *td = user_data;
1321 GstStateChangeReturn ret;
1323 ret = gst_element_set_state (td->p, GST_STATE_PAUSED);
1324 FAIL_IF (ret == GST_STATE_CHANGE_FAILURE);
1326 return G_SOURCE_REMOVE;
1330 flushing_seek_bus_msg (GstBus * bus, GstMessage * message, gpointer user_data)
1332 test_data *td = user_data;
1333 flushing_seek_master_data *d = td->md;
1335 if (GST_IS_PIPELINE (GST_MESSAGE_SRC (message))) {
1336 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE) {
1337 d->got_segment_done = TRUE;
1338 g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline,
1339 gst_object_ref (td->p));
1342 return master_bus_msg (bus, message, user_data);
1346 flushing_seek_on_state_changed (gpointer user_data)
1348 test_data *td = user_data;
1349 const flushing_seek_input_data *i = td->id;
1350 flushing_seek_master_data *d = td->md;
1352 if (!d->got_state_changed_to_playing) {
1353 d->got_state_changed_to_playing = TRUE;
1355 g_timeout_add (PAUSE_AT, (GSourceFunc) pause_before_seek, td);
1356 g_timeout_add (SEEK_AT, (GSourceFunc) send_flushing_seek, td);
1361 flushing_seek_source (GstElement * source, gpointer user_data)
1363 test_data *td = user_data;
1364 GstStateChangeReturn ret;
1366 /* we're on the source, there's already the basic master_bus_msg watch,
1367 and gst doesn't want more than one watch, so we remove the watch and
1368 call it directly when done in the new watch */
1369 gst_bus_remove_watch (GST_ELEMENT_BUS (source));
1370 gst_bus_add_watch (GST_ELEMENT_BUS (source), flushing_seek_bus_msg,
1372 td->state_target = GST_STATE_PLAYING;
1373 td->state_changed_cb = flushing_seek_on_state_changed;
1374 ret = gst_element_set_state (source, GST_STATE_PLAYING);
1375 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
1378 static GstPadProbeReturn
1379 flushing_seek_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1381 test_data *td = user_data;
1382 flushing_seek_slave_data *d = td->sd;
1387 if (GST_IS_BUFFER (info->data)) {
1388 idx = pad2idx (pad, td->two_streams);
1389 if (d->got_flush_stop[idx]) {
1390 if (!d->got_buffer_after_seek[idx]) {
1391 ts = GST_BUFFER_TIMESTAMP (info->data);
1392 d->first_buffer_after_seek_has_timestamp_0[idx] =
1393 (ts < d->first_ts[idx] + 10 * GST_MSECOND);
1394 d->got_buffer_after_seek[idx] = TRUE;
1396 } else if (!d->got_buffer_before_seek[idx]) {
1397 d->got_buffer_before_seek[idx] = TRUE;
1398 d->first_ts[idx] = GST_BUFFER_TIMESTAMP (info->data);
1400 } else if (GST_IS_EVENT (info->data)) {
1401 if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
1402 gst_event_parse_caps (info->data, &caps);
1403 if (are_caps_audio (caps) || are_caps_video (caps)) {
1404 idx = caps2idx (caps, td->two_streams);
1405 d->got_caps[idx] = TRUE;
1407 } else if (GST_EVENT_TYPE (info->data) == GST_EVENT_SEGMENT) {
1408 /* from the sink pipeline, we don't know whether the master issued a seek,
1409 as the seek_sent memory location isn't directly accessible to us, so we
1410 look for a segment after a buffer to mean a seek was sent */
1411 idx = pad2idx (pad, td->two_streams);
1412 if (d->got_buffer_before_seek[idx])
1413 d->got_segment_after_seek[idx] = TRUE;
1414 } else if (GST_EVENT_TYPE (info->data) == GST_EVENT_FLUSH_START) {
1415 idx = pad2idx (pad, td->two_streams);
1416 d->got_flush_start[idx] = TRUE;
1417 } else if (GST_EVENT_TYPE (info->data) == GST_EVENT_FLUSH_STOP) {
1418 idx = pad2idx (pad, td->two_streams);
1419 if (d->got_buffer_before_seek[idx])
1420 d->got_flush_stop[idx] = TRUE;
1424 return GST_PAD_PROBE_OK;
1428 hook_flushing_seek_probe (const GValue * v, gpointer user_data)
1430 hook_probe (v, flushing_seek_probe, user_data);
1434 setup_sink_flushing_seek (GstElement * sink, gpointer user_data)
1438 it = gst_bin_iterate_sinks (GST_BIN (sink));
1439 while (gst_iterator_foreach (it, hook_flushing_seek_probe, user_data))
1440 gst_iterator_resync (it);
1441 gst_iterator_free (it);
1445 check_success_source_flushing_seek (gpointer user_data)
1447 test_data *td = user_data;
1448 const flushing_seek_input_data *i = td->id;
1449 flushing_seek_master_data *d = td->md;
1451 FAIL_UNLESS (d->got_state_changed_to_playing);
1452 FAIL_UNLESS (d->seek_sent);
1453 FAIL_UNLESS (d->got_segment_done == i->segment_seek);
1457 check_success_sink_flushing_seek (gpointer user_data)
1459 test_data *td = user_data;
1460 flushing_seek_slave_data *d = td->sd;
1463 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
1464 FAIL_UNLESS (d->got_caps[idx]);
1465 FAIL_UNLESS (d->got_buffer_before_seek[idx]);
1466 FAIL_UNLESS (d->got_buffer_after_seek[idx]);
1467 FAIL_UNLESS (d->got_segment_after_seek[idx]);
1468 FAIL_UNLESS (d->got_flush_start[idx]);
1469 FAIL_UNLESS (d->got_flush_stop[idx]);
1470 FAIL_UNLESS (d->first_buffer_after_seek_has_timestamp_0[idx]);
1474 GST_START_TEST (test_empty_flushing_seek)
1476 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT;
1477 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1478 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1480 TEST_BASE (TEST_FEATURE_TEST_SOURCE, flushing_seek_source,
1481 setup_sink_flushing_seek, check_success_source_flushing_seek,
1482 check_success_sink_flushing_seek, &id, &md, &sd);
1487 GST_START_TEST (test_wavparse_flushing_seek)
1489 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT;
1490 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1491 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1493 TEST_BASE (TEST_FEATURE_WAV_SOURCE, flushing_seek_source,
1494 setup_sink_flushing_seek, check_success_source_flushing_seek,
1495 check_success_sink_flushing_seek, &id, &md, &sd);
1500 GST_START_TEST (test_mpegts_flushing_seek)
1502 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT;
1503 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1504 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1506 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, flushing_seek_source,
1507 setup_sink_flushing_seek, check_success_source_flushing_seek,
1508 check_success_sink_flushing_seek, &id, &md, &sd);
1513 GST_START_TEST (test_mpegts_2_flushing_seek)
1515 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT;
1516 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1517 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1519 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
1520 flushing_seek_source, setup_sink_flushing_seek,
1521 check_success_source_flushing_seek, check_success_sink_flushing_seek, &id,
1527 GST_START_TEST (test_live_a_flushing_seek)
1529 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT;
1530 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1531 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1533 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, flushing_seek_source,
1534 setup_sink_flushing_seek, check_success_source_flushing_seek,
1535 check_success_sink_flushing_seek, &id, &md, &sd);
1540 GST_START_TEST (test_live_av_flushing_seek)
1542 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT;
1543 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1544 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1546 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, flushing_seek_source,
1547 setup_sink_flushing_seek, check_success_source_flushing_seek,
1548 check_success_sink_flushing_seek, &id, &md, &sd);
1553 GST_START_TEST (test_live_av_2_flushing_seek)
1555 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT;
1556 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1557 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1559 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
1560 flushing_seek_source, setup_sink_flushing_seek,
1561 check_success_source_flushing_seek, check_success_sink_flushing_seek, &id,
1567 GST_START_TEST (test_empty_flushing_seek_in_pause)
1569 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_PAUSED;
1570 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1571 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1573 TEST_BASE (TEST_FEATURE_TEST_SOURCE, flushing_seek_source,
1574 setup_sink_flushing_seek, check_success_source_flushing_seek,
1575 check_success_sink_flushing_seek, &id, &md, &sd);
1580 GST_START_TEST (test_wavparse_flushing_seek_in_pause)
1582 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_PAUSED;
1583 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1584 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1586 TEST_BASE (TEST_FEATURE_WAV_SOURCE, flushing_seek_source,
1587 setup_sink_flushing_seek, check_success_source_flushing_seek,
1588 check_success_sink_flushing_seek, &id, &md, &sd);
1593 GST_START_TEST (test_mpegts_flushing_seek_in_pause)
1595 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_PAUSED;
1596 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1597 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1599 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, flushing_seek_source,
1600 setup_sink_flushing_seek, check_success_source_flushing_seek,
1601 check_success_sink_flushing_seek, &id, &md, &sd);
1606 GST_START_TEST (test_mpegts_2_flushing_seek_in_pause)
1608 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_PAUSED;
1609 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1610 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1612 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
1613 flushing_seek_source, setup_sink_flushing_seek,
1614 check_success_source_flushing_seek,
1615 check_success_sink_flushing_seek, &id, &md, &sd);
1620 GST_START_TEST (test_empty_segment_seek)
1622 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_SEGMENT_SEEK;
1623 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1624 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1626 TEST_BASE (TEST_FEATURE_TEST_SOURCE, flushing_seek_source,
1627 setup_sink_flushing_seek, check_success_source_flushing_seek,
1628 check_success_sink_flushing_seek, &id, &md, &sd);
1633 GST_START_TEST (test_wavparse_segment_seek)
1635 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_SEGMENT_SEEK;
1636 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1637 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1639 TEST_BASE (TEST_FEATURE_WAV_SOURCE, flushing_seek_source,
1640 setup_sink_flushing_seek, check_success_source_flushing_seek,
1641 check_success_sink_flushing_seek, &id, &md, &sd);
1646 GST_START_TEST (test_live_a_segment_seek)
1648 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_SEGMENT_SEEK;
1649 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1650 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1652 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE,
1653 flushing_seek_source, setup_sink_flushing_seek,
1654 check_success_source_flushing_seek,
1655 check_success_sink_flushing_seek, &id, &md, &sd);
1660 GST_START_TEST (test_live_av_segment_seek)
1662 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_SEGMENT_SEEK;
1663 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1664 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1666 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE,
1667 flushing_seek_source, setup_sink_flushing_seek,
1668 check_success_source_flushing_seek,
1669 check_success_sink_flushing_seek, &id, &md, &sd);
1674 GST_START_TEST (test_live_av_2_segment_seek)
1676 flushing_seek_input_data id = FLUSHING_SEEK_INPUT_DATA_INIT_SEGMENT_SEEK;
1677 flushing_seek_master_data md = FLUSHING_SEEK_MASTER_DATA_INIT;
1678 flushing_seek_slave_data sd = FLUSHING_SEEK_SLAVE_DATA_INIT;
1680 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
1681 flushing_seek_source, setup_sink_flushing_seek,
1682 check_success_source_flushing_seek,
1683 check_success_sink_flushing_seek, &id, &md, &sd);
1688 /**** seek stress test ****/
1692 gint n_flushing_seeks;
1693 gint n_paused_seeks;
1694 gint n_segment_seeks;
1695 } seek_stress_input_data;
1699 gboolean got_state_changed_to_playing;
1703 } seek_stress_master_data;
1706 send_seek_stress (gpointer user_data)
1708 test_data *td = user_data;
1709 seek_stress_input_data *i = td->id;
1710 seek_stress_master_data *d = td->md;
1711 GstEvent *seek_event;
1712 unsigned int available, seekidx;
1713 GstClockTime t, base;
1715 /* Live streams don't like to be seeked too far away from the
1716 "current" time, since they're live, so always seek near the
1717 "real" time, so we still exercise seeking to another position
1718 but still land somewhere close enough to "live" position. */
1719 t = (g_get_monotonic_time () - d->t0) * 1000;
1720 base = t > GST_SECOND / 2 ? t - GST_SECOND / 2 : 0;
1721 t = base + g_random_int_range (0, GST_SECOND);
1723 /* pick a random seek type among the ones we have left */
1724 available = i->n_flushing_seeks + i->n_paused_seeks + i->n_segment_seeks;
1725 if (available == 0) {
1726 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (td->p),
1727 GST_DEBUG_GRAPH_SHOW_ALL, "inter.test.toplaying");
1728 FAIL_UNLESS (gst_element_set_state (td->p,
1729 GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE);
1730 g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline,
1731 gst_object_ref (td->p));
1732 gst_object_unref (td->p);
1733 return G_SOURCE_REMOVE;
1736 seekidx = rand () % available;
1737 if (seekidx < i->n_flushing_seeks) {
1738 GST_INFO_OBJECT (td->p, "Sending flushing seek to %" GST_TIME_FORMAT,
1740 FAIL_UNLESS (gst_element_set_state (td->p,
1741 GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE);
1742 FAIL_UNLESS (gst_element_seek_simple (td->p, GST_FORMAT_TIME,
1743 GST_SEEK_FLAG_FLUSH, t));
1744 --i->n_flushing_seeks;
1745 return G_SOURCE_CONTINUE;
1747 seekidx -= i->n_flushing_seeks;
1749 if (seekidx < i->n_paused_seeks) {
1750 GST_INFO_OBJECT (td->p,
1751 "Sending flushing seek in paused to %" GST_TIME_FORMAT,
1753 FAIL_UNLESS (gst_element_set_state (td->p,
1754 GST_STATE_PAUSED) != GST_STATE_CHANGE_FAILURE);
1755 FAIL_UNLESS (gst_element_seek_simple (td->p, GST_FORMAT_TIME,
1756 GST_SEEK_FLAG_FLUSH, t));
1757 --i->n_paused_seeks;
1758 return G_SOURCE_CONTINUE;
1760 seekidx -= i->n_paused_seeks;
1762 GST_INFO_OBJECT (td->p, "Sending segment seek to %" GST_TIME_FORMAT,
1765 gst_event_new_seek (1.0, GST_FORMAT_TIME,
1766 GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, t,
1767 GST_SEEK_TYPE_SET, t + 5 * GST_SECOND);
1768 FAIL_UNLESS (gst_element_send_event (td->p, seek_event));
1769 --i->n_segment_seeks;
1770 return G_SOURCE_CONTINUE;
1774 seek_stress_bus_msg (GstBus * bus, GstMessage * message, gpointer user_data)
1776 test_data *td = user_data;
1777 seek_stress_master_data *d = td->md;
1779 if (GST_IS_PIPELINE (GST_MESSAGE_SRC (message))) {
1780 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS ||
1781 GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE) {
1785 return master_bus_msg (bus, message, user_data);
1789 seek_stress_on_state_changed (gpointer user_data)
1791 test_data *td = user_data;
1792 seek_stress_master_data *d = td->md;
1794 if (!d->got_state_changed_to_playing) {
1795 d->got_state_changed_to_playing = TRUE;
1796 d->t0 = g_get_monotonic_time ();
1797 gst_object_ref (td->p);
1798 g_timeout_add (10, (GSourceFunc) send_seek_stress, td);
1803 seek_stress_source (GstElement * source, gpointer user_data)
1805 test_data *td = user_data;
1806 GstStateChangeReturn ret;
1808 /* we're on the source, there's already the basic master_bus_msg watch,
1809 and gst doesn't want more than one watch, so we remove the watch and
1810 call it directly when done in the new watch */
1811 gst_bus_remove_watch (GST_ELEMENT_BUS (source));
1812 gst_bus_add_watch (GST_ELEMENT_BUS (source), seek_stress_bus_msg, user_data);
1813 td->state_target = GST_STATE_PLAYING;
1814 td->state_changed_cb = seek_stress_on_state_changed;
1815 ret = gst_element_set_state (source, GST_STATE_PLAYING);
1816 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
1820 check_success_source_seek_stress (gpointer user_data)
1822 test_data *td = user_data;
1823 seek_stress_input_data *i = td->id;
1824 seek_stress_master_data *d = td->md;
1826 FAIL_UNLESS (d->got_state_changed_to_playing);
1827 FAIL_UNLESS_EQUALS_INT (i->n_flushing_seeks, 0);
1828 FAIL_UNLESS_EQUALS_INT (i->n_paused_seeks, 0);
1829 FAIL_UNLESS_EQUALS_INT (i->n_segment_seeks, 0);
1830 FAIL_IF (d->got_eos);
1833 GST_START_TEST (test_empty_seek_stress)
1835 seek_stress_input_data id = { 100, 100, 100 };
1836 seek_stress_master_data md = { 0 };
1838 TEST_BASE (TEST_FEATURE_TEST_SOURCE, seek_stress_source, NULL,
1839 check_success_source_seek_stress, NULL, &id, &md, NULL);
1844 GST_START_TEST (test_wavparse_seek_stress)
1846 seek_stress_input_data id = { 100, 100, 100 };
1847 seek_stress_master_data md = { 0 };
1849 TEST_BASE (TEST_FEATURE_WAV_SOURCE, seek_stress_source, NULL,
1850 check_success_source_seek_stress, NULL, &id, &md, NULL);
1855 GST_START_TEST (test_mpegts_seek_stress)
1857 seek_stress_input_data id = { 100, 100, 0 };
1858 seek_stress_master_data md = { 0 };
1860 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, seek_stress_source, NULL,
1861 check_success_source_seek_stress, NULL, &id, &md, NULL);
1866 GST_START_TEST (test_mpegts_2_seek_stress)
1868 seek_stress_input_data id = { 100, 100, 0 };
1869 seek_stress_master_data md = { 0 };
1871 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
1872 seek_stress_source, NULL, check_success_source_seek_stress, NULL, &id,
1878 GST_START_TEST (test_live_a_seek_stress)
1880 seek_stress_input_data id = { 100, 0, 100 };
1881 seek_stress_master_data md = { 0 };
1883 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE | TEST_FEATURE_LONG_DURATION,
1884 seek_stress_source, NULL, check_success_source_seek_stress, NULL, &id,
1890 GST_START_TEST (test_live_av_seek_stress)
1892 seek_stress_input_data id = { 100, 0, 100 };
1893 seek_stress_master_data md = { 0 };
1895 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_LONG_DURATION,
1896 seek_stress_source, NULL, check_success_source_seek_stress, NULL, &id,
1902 GST_START_TEST (test_live_av_2_seek_stress)
1904 seek_stress_input_data id = { 100, 0, 100 };
1905 seek_stress_master_data md = { 0 };
1907 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_LONG_DURATION |
1908 TEST_FEATURE_SPLIT_SINKS,
1909 seek_stress_source, NULL, check_success_source_seek_stress, NULL, &id,
1915 /**** upstream query test ****/
1919 GstClockTime expected_duration;
1921 /* In this test, the source does a position query (in the source pipeline
1922 process), and must check its return against the last buffer timestamp
1923 in the sink pipeline process. We open a pipe to let the sink send us
1924 the timestamps it receives so the source can make the comparison. */
1926 } upstream_query_input_data;
1930 gboolean got_state_changed_to_playing;
1931 gboolean got_correct_position;
1932 gboolean got_correct_duration;
1933 GstClockTime last_buffer_ts;
1934 } upstream_query_master_data;
1938 gboolean got_caps[2];
1939 gboolean got_buffer[2];
1940 GstClockTime last_buffer_ts;
1941 } upstream_query_slave_data;
1944 send_upstream_queries (gpointer user_data)
1946 test_data *td = user_data;
1947 upstream_query_input_data *i = td->id;
1948 upstream_query_master_data *d = td->md;
1949 gint64 pos, dur, last;
1951 FAIL_UNLESS (gst_element_query_position (td->p, GST_FORMAT_TIME, &pos));
1953 /* read up the buffer ts sent by the sink process till the last one */
1954 while (read (i->ts_pipes[0], &last, sizeof (last)) == sizeof (last)) {
1955 /* timestamps may not be increasing because we are getting ts from
1956 * both the audio and video streams; the position query will report
1958 if (last > d->last_buffer_ts)
1959 d->last_buffer_ts = last;
1961 if (ABS ((gint64) (pos - d->last_buffer_ts)) <= CLOSE_ENOUGH_TO_ZERO)
1962 d->got_correct_position = TRUE;
1964 FAIL_UNLESS (gst_element_query_duration (td->p, GST_FORMAT_TIME, &dur));
1965 if (GST_CLOCK_TIME_IS_VALID (i->expected_duration)) {
1966 GstClockTimeDiff diff = GST_CLOCK_DIFF (dur, i->expected_duration);
1967 if (diff >= -CLOSE_ENOUGH_TO_ZERO && diff <= CLOSE_ENOUGH_TO_ZERO)
1968 d->got_correct_duration = TRUE;
1970 if (!GST_CLOCK_TIME_IS_VALID (dur))
1971 d->got_correct_duration = TRUE;
1974 g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline, td->p);
1979 upstream_query_on_state_changed (gpointer user_data)
1981 test_data *td = user_data;
1982 upstream_query_master_data *d = td->md;
1984 if (!d->got_state_changed_to_playing) {
1985 d->got_state_changed_to_playing = TRUE;
1986 gst_object_ref (td->p);
1987 g_timeout_add (QUERY_AT, (GSourceFunc) send_upstream_queries, td);
1992 upstream_query_source (GstElement * source, gpointer user_data)
1994 test_data *td = user_data;
1995 GstStateChangeReturn ret;
1997 td->state_changed_cb = upstream_query_on_state_changed;
1998 td->state_target = GST_STATE_PLAYING;
1999 ret = gst_element_set_state (source, GST_STATE_PLAYING);
2000 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
2003 static GstPadProbeReturn
2004 upstream_query_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2006 test_data *td = user_data;
2007 upstream_query_input_data *i = td->id;
2008 upstream_query_slave_data *d = td->sd;
2011 if (GST_IS_BUFFER (info->data)) {
2012 d->got_buffer[pad2idx (pad, td->two_streams)] = TRUE;
2013 if (GST_BUFFER_TIMESTAMP_IS_VALID (info->data)) {
2014 d->last_buffer_ts = GST_BUFFER_TIMESTAMP (info->data);
2015 FAIL_UNLESS (write (i->ts_pipes[1], &d->last_buffer_ts,
2016 sizeof (d->last_buffer_ts)) == sizeof (d->last_buffer_ts));
2018 } else if (GST_IS_EVENT (info->data)) {
2019 if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
2020 gst_event_parse_caps (info->data, &caps);
2021 d->got_caps[caps2idx (caps, td->two_streams)] = TRUE;
2025 return GST_PAD_PROBE_OK;
2029 hook_upstream_query_probe (const GValue * v, gpointer user_data)
2031 hook_probe (v, upstream_query_probe, user_data);
2035 setup_sink_upstream_query (GstElement * sink, gpointer user_data)
2039 it = gst_bin_iterate_sinks (GST_BIN (sink));
2040 while (gst_iterator_foreach (it, hook_upstream_query_probe, user_data))
2041 gst_iterator_resync (it);
2042 gst_iterator_free (it);
2046 check_success_source_upstream_query (gpointer user_data)
2048 test_data *td = user_data;
2049 upstream_query_master_data *d = td->md;
2051 FAIL_UNLESS (d->got_state_changed_to_playing);
2052 FAIL_UNLESS (d->got_correct_position);
2053 FAIL_UNLESS (d->got_correct_duration);
2057 check_success_sink_upstream_query (gpointer user_data)
2059 test_data *td = user_data;
2060 upstream_query_slave_data *d = td->sd;
2063 for (idx = 0; idx < (td->two_streams ? 2 : 1); ++idx) {
2064 FAIL_UNLESS (d->got_caps[idx]);
2065 FAIL_UNLESS (d->got_buffer[idx]);
2069 GST_START_TEST (test_empty_upstream_query)
2071 upstream_query_input_data id = { GST_CLOCK_TIME_NONE, };
2072 upstream_query_master_data md = { 0 };
2073 upstream_query_slave_data sd = { {0}
2076 FAIL_UNLESS (pipe2 (id.ts_pipes, O_NONBLOCK) == 0);
2077 TEST_BASE (TEST_FEATURE_TEST_SOURCE, upstream_query_source,
2078 setup_sink_upstream_query, check_success_source_upstream_query,
2079 check_success_sink_upstream_query, &id, &md, &sd);
2080 close (id.ts_pipes[0]);
2081 close (id.ts_pipes[1]);
2086 GST_START_TEST (test_wavparse_upstream_query)
2088 upstream_query_input_data id = { WAV_SAMPLE_ROUGH_DURATION, };
2089 upstream_query_master_data md = { 0 };
2090 upstream_query_slave_data sd = { {0}
2093 FAIL_UNLESS (pipe2 (id.ts_pipes, O_NONBLOCK) == 0);
2094 TEST_BASE (TEST_FEATURE_WAV_SOURCE, upstream_query_source,
2095 setup_sink_upstream_query, check_success_source_upstream_query,
2096 check_success_sink_upstream_query, &id, &md, &sd);
2097 close (id.ts_pipes[0]);
2098 close (id.ts_pipes[1]);
2103 GST_START_TEST (test_mpegts_upstream_query)
2105 upstream_query_input_data id = { MPEGTS_SAMPLE_ROUGH_DURATION, };
2106 upstream_query_master_data md = { 0 };
2107 upstream_query_slave_data sd = { {0}
2110 FAIL_UNLESS (pipe2 (id.ts_pipes, O_NONBLOCK) == 0);
2111 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, upstream_query_source,
2112 setup_sink_upstream_query, check_success_source_upstream_query,
2113 check_success_sink_upstream_query, &id, &md, &sd);
2114 close (id.ts_pipes[0]);
2115 close (id.ts_pipes[1]);
2120 GST_START_TEST (test_mpegts_2_upstream_query)
2122 upstream_query_input_data id = { MPEGTS_SAMPLE_ROUGH_DURATION, };
2123 upstream_query_master_data md = { 0 };
2124 upstream_query_slave_data sd = { {0}
2127 FAIL_UNLESS (pipe2 (id.ts_pipes, O_NONBLOCK) == 0);
2128 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
2129 upstream_query_source, setup_sink_upstream_query,
2130 check_success_source_upstream_query, check_success_sink_upstream_query,
2132 close (id.ts_pipes[0]);
2133 close (id.ts_pipes[1]);
2138 GST_START_TEST (test_live_a_upstream_query)
2140 upstream_query_input_data id = { GST_CLOCK_TIME_NONE, };
2141 upstream_query_master_data md = { 0 };
2142 upstream_query_slave_data sd = { {0}
2145 FAIL_UNLESS (pipe2 (id.ts_pipes, O_NONBLOCK) == 0);
2146 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE,
2147 upstream_query_source, setup_sink_upstream_query,
2148 check_success_source_upstream_query, check_success_sink_upstream_query,
2150 close (id.ts_pipes[0]);
2151 close (id.ts_pipes[1]);
2156 GST_START_TEST (test_live_av_upstream_query)
2158 upstream_query_input_data id = { GST_CLOCK_TIME_NONE, };
2159 upstream_query_master_data md = { 0 };
2160 upstream_query_slave_data sd = { {0}
2163 FAIL_UNLESS (pipe2 (id.ts_pipes, O_NONBLOCK) == 0);
2164 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE,
2165 upstream_query_source, setup_sink_upstream_query,
2166 check_success_source_upstream_query, check_success_sink_upstream_query,
2168 close (id.ts_pipes[0]);
2169 close (id.ts_pipes[1]);
2174 GST_START_TEST (test_live_av_2_upstream_query)
2176 upstream_query_input_data id = { GST_CLOCK_TIME_NONE, };
2177 upstream_query_master_data md = { 0 };
2178 upstream_query_slave_data sd = { {0}
2181 FAIL_UNLESS (pipe2 (id.ts_pipes, O_NONBLOCK) == 0);
2182 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
2183 upstream_query_source, setup_sink_upstream_query,
2184 check_success_source_upstream_query, check_success_sink_upstream_query,
2186 close (id.ts_pipes[0]);
2187 close (id.ts_pipes[1]);
2192 /**** message test ****/
2196 gboolean got_state_changed_to_playing;
2197 guint8 num_got_message;
2198 guint8 num_sent_message;
2199 } message_master_data;
2202 send_ipcpipeline_test_message_event (const GValue * v, gpointer user_data)
2204 test_data *td = user_data;
2205 message_master_data *d = td->md;
2206 GstElement *element = g_value_get_object (v);
2210 d->num_sent_message++;
2212 msg = gst_message_new_element (GST_OBJECT (element),
2213 gst_structure_new_empty ("ipcpipeline-test"));
2214 ret = gst_element_send_event (element,
2215 gst_event_new_sink_message ("ipcpipeline-test", msg));
2217 gst_message_unref (msg);
2221 send_sink_message (gpointer user_data)
2223 test_data *td = user_data;
2226 it = gst_bin_iterate_sources (GST_BIN (td->p));
2227 while (gst_iterator_foreach (it, send_ipcpipeline_test_message_event, td))
2228 gst_iterator_resync (it);
2229 gst_iterator_free (it);
2231 gst_object_unref (td->p);
2232 return G_SOURCE_REMOVE;
2236 message_bus_msg (GstBus * bus, GstMessage * message, gpointer user_data)
2238 test_data *td = user_data;
2239 message_master_data *d = td->md;
2240 const GstStructure *structure;
2242 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT) {
2243 structure = gst_message_get_structure (message);
2244 FAIL_UNLESS (structure);
2245 if (gst_structure_has_name (structure, "ipcpipeline-test")) {
2246 d->num_got_message++;
2247 if (d->num_got_message == d->num_sent_message)
2248 g_main_loop_quit (loop);
2251 return master_bus_msg (bus, message, user_data);
2255 message_on_state_changed (gpointer user_data)
2257 test_data *td = user_data;
2258 message_master_data *d = td->md;
2260 if (!d->got_state_changed_to_playing) {
2261 d->got_state_changed_to_playing = TRUE;
2262 gst_object_ref (td->p);
2263 g_timeout_add (MESSAGE_AT, (GSourceFunc) send_sink_message, td);
2268 message_source (GstElement * source, gpointer user_data)
2270 test_data *td = user_data;
2271 GstStateChangeReturn ret;
2273 /* we're on the source, there's already the basic master_bus_msg watch,
2274 and gst doesn't want more than one watch, so we remove the watch and
2275 call it directly when done in the new watch */
2276 gst_bus_remove_watch (GST_ELEMENT_BUS (source));
2277 gst_bus_add_watch (GST_ELEMENT_BUS (source), message_bus_msg, user_data);
2278 td->state_target = GST_STATE_PLAYING;
2279 td->state_changed_cb = message_on_state_changed;
2280 ret = gst_element_set_state (source, GST_STATE_PLAYING);
2281 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
2285 check_success_source_message (gpointer user_data)
2287 test_data *td = user_data;
2288 message_master_data *d = td->md;
2290 FAIL_UNLESS (d->got_state_changed_to_playing);
2291 FAIL_UNLESS_EQUALS_INT (d->num_got_message, d->num_sent_message);
2294 GST_START_TEST (test_empty_message)
2296 message_master_data md = { 0 };
2297 TEST_BASE (TEST_FEATURE_TEST_SOURCE, message_source, NULL,
2298 check_success_source_message, NULL, NULL, &md, NULL);
2303 GST_START_TEST (test_wavparse_message)
2305 message_master_data md = { 0 };
2306 TEST_BASE (TEST_FEATURE_WAV_SOURCE, message_source, NULL,
2307 check_success_source_message, NULL, NULL, &md, NULL);
2312 GST_START_TEST (test_live_a_message)
2314 message_master_data md = { 0 };
2315 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, message_source, NULL,
2316 check_success_source_message, NULL, NULL, &md, NULL);
2321 GST_START_TEST (test_live_av_message)
2323 message_master_data md = { 0 };
2324 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, message_source, NULL,
2325 check_success_source_message, NULL, NULL, &md, NULL);
2330 GST_START_TEST (test_live_av_2_message)
2332 message_master_data md = { 0 };
2333 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
2334 message_source, NULL, check_success_source_message, NULL, NULL, &md,
2340 /**** end of stream test ****/
2344 gboolean got_state_changed_to_playing;
2345 } end_of_stream_master_data;
2349 gboolean got_buffer[2];
2350 gboolean got_eos[2];
2351 } end_of_stream_slave_data;
2354 end_of_stream_on_state_changed (gpointer user_data)
2356 test_data *td = user_data;
2357 end_of_stream_master_data *d = td->md;
2359 if (!d->got_state_changed_to_playing)
2360 d->got_state_changed_to_playing = TRUE;
2364 end_of_stream_source (GstElement * source, gpointer user_data)
2366 test_data *td = user_data;
2367 GstStateChangeReturn ret;
2369 td->state_changed_cb = end_of_stream_on_state_changed;
2370 td->state_target = GST_STATE_PLAYING;
2371 ret = gst_element_set_state (source, GST_STATE_PLAYING);
2372 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
2375 static GstPadProbeReturn
2376 end_of_stream_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2378 test_data *td = user_data;
2379 end_of_stream_slave_data *d = td->sd;
2381 if (GST_IS_BUFFER (info->data)) {
2382 d->got_buffer[pad2idx (pad, td->two_streams)] = TRUE;
2383 } else if (GST_IS_EVENT (info->data)) {
2384 if (GST_EVENT_TYPE (info->data) == GST_EVENT_EOS) {
2385 d->got_eos[pad2idx (pad, td->two_streams)] = TRUE;
2389 return GST_PAD_PROBE_OK;
2393 hook_end_of_stream_probe (const GValue * v, gpointer user_data)
2395 hook_probe (v, end_of_stream_probe, user_data);
2399 setup_sink_end_of_stream (GstElement * sink, gpointer user_data)
2403 it = gst_bin_iterate_sinks (GST_BIN (sink));
2404 while (gst_iterator_foreach (it, hook_end_of_stream_probe, user_data))
2405 gst_iterator_resync (it);
2406 gst_iterator_free (it);
2410 check_success_source_end_of_stream (gpointer user_data)
2412 test_data *td = user_data;
2413 end_of_stream_master_data *d = td->md;
2415 FAIL_UNLESS (d->got_state_changed_to_playing);
2419 check_success_sink_end_of_stream (gpointer user_data)
2421 test_data *td = user_data;
2422 end_of_stream_slave_data *d = td->sd;
2425 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
2426 FAIL_UNLESS (d->got_buffer[idx]);
2427 FAIL_UNLESS (d->got_eos[idx]);
2431 GST_START_TEST (test_empty_end_of_stream)
2433 end_of_stream_master_data md = { 0 };
2434 end_of_stream_slave_data sd = { {0}
2437 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_ASYNC_SINK,
2438 end_of_stream_source, setup_sink_end_of_stream,
2439 check_success_source_end_of_stream, check_success_sink_end_of_stream,
2445 GST_START_TEST (test_wavparse_end_of_stream)
2447 end_of_stream_master_data md = { 0 };
2448 end_of_stream_slave_data sd = { {0}
2451 TEST_BASE (TEST_FEATURE_WAV_SOURCE | TEST_FEATURE_ASYNC_SINK,
2452 end_of_stream_source, setup_sink_end_of_stream,
2453 check_success_source_end_of_stream, check_success_sink_end_of_stream,
2459 GST_START_TEST (test_mpegts_end_of_stream)
2461 end_of_stream_master_data md = { 0 };
2462 end_of_stream_slave_data sd = { {0}
2465 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_ASYNC_SINK,
2466 end_of_stream_source, setup_sink_end_of_stream,
2467 check_success_source_end_of_stream, check_success_sink_end_of_stream,
2473 GST_START_TEST (test_mpegts_2_end_of_stream)
2475 end_of_stream_master_data md = { 0 };
2476 end_of_stream_slave_data sd = { {0}
2479 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS |
2480 TEST_FEATURE_ASYNC_SINK,
2481 end_of_stream_source, setup_sink_end_of_stream,
2482 check_success_source_end_of_stream, check_success_sink_end_of_stream,
2488 GST_START_TEST (test_live_a_end_of_stream)
2490 end_of_stream_master_data md = { 0 };
2491 end_of_stream_slave_data sd = { {0}
2494 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE,
2495 end_of_stream_source, setup_sink_end_of_stream,
2496 check_success_source_end_of_stream, check_success_sink_end_of_stream,
2502 GST_START_TEST (test_live_av_end_of_stream)
2504 end_of_stream_master_data md = { 0 };
2505 end_of_stream_slave_data sd = { {0}
2508 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE,
2509 end_of_stream_source, setup_sink_end_of_stream,
2510 check_success_source_end_of_stream, check_success_sink_end_of_stream,
2516 GST_START_TEST (test_live_av_2_end_of_stream)
2518 end_of_stream_master_data md = { 0 };
2519 end_of_stream_slave_data sd = { {0}
2522 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
2523 end_of_stream_source, setup_sink_end_of_stream,
2524 check_success_source_end_of_stream, check_success_sink_end_of_stream,
2530 /**** reverse playback test ****/
2534 gboolean got_state_changed_to_playing;
2536 } reverse_playback_master_data;
2540 gboolean got_segment_with_negative_rate;
2541 gboolean got_buffer_after_segment_with_negative_rate;
2542 GstClockTime first_backward_buffer_timestamp;
2543 gboolean got_buffer_one_second_early;
2544 } reverse_playback_slave_data;
2547 play_backwards (gpointer user_data)
2549 test_data *td = user_data;
2550 reverse_playback_master_data *d = td->md;
2554 FAIL_UNLESS (gst_element_query_position (td->p, GST_FORMAT_TIME, &pos));
2557 gst_element_seek (td->p, -0.5, GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, 0,
2558 GST_SEEK_TYPE_SET, pos);
2560 d->seek_sent = TRUE;
2562 gst_object_unref (td->p);
2563 return G_SOURCE_REMOVE;
2567 reverse_playback_on_state_changed (gpointer user_data)
2569 test_data *td = user_data;
2570 reverse_playback_master_data *d = td->md;
2572 if (!d->got_state_changed_to_playing) {
2573 d->got_state_changed_to_playing = TRUE;
2574 gst_object_ref (td->p);
2575 g_timeout_add (2000, (GSourceFunc) play_backwards, td);
2580 reverse_playback_source (GstElement * source, gpointer user_data)
2582 test_data *td = user_data;
2583 GstStateChangeReturn ret;
2585 td->state_target = GST_STATE_PLAYING;
2586 td->state_changed_cb = reverse_playback_on_state_changed;
2587 ret = gst_element_set_state (source, GST_STATE_PLAYING);
2588 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
2591 static GstPadProbeReturn
2592 reverse_playback_probe (GstPad * pad, GstPadProbeInfo * info,
2595 test_data *td = user_data;
2596 reverse_playback_slave_data *d = td->sd;
2598 if (GST_IS_EVENT (info->data)) {
2599 if (GST_EVENT_TYPE (info->data) == GST_EVENT_SEGMENT) {
2600 const GstSegment *s;
2601 gst_event_parse_segment (GST_EVENT (info->data), &s);
2603 d->got_segment_with_negative_rate = TRUE;
2605 } else if (GST_IS_BUFFER (info->data)) {
2606 GstClockTime ts = GST_BUFFER_TIMESTAMP (info->data);
2607 if (GST_CLOCK_TIME_IS_VALID (ts)) {
2608 if (d->got_segment_with_negative_rate) {
2609 if (d->got_buffer_after_segment_with_negative_rate) {
2610 /* We test for 1 second, not just earlier, to make sure we don't
2611 just see B frames, or whatever else */
2612 if (ts < d->first_backward_buffer_timestamp - GST_SECOND) {
2613 d->got_buffer_one_second_early = TRUE;
2616 d->got_buffer_after_segment_with_negative_rate = TRUE;
2617 d->first_backward_buffer_timestamp = ts;
2623 return GST_PAD_PROBE_OK;
2627 hook_reverse_playback_probe (const GValue * v, gpointer user_data)
2629 hook_probe (v, reverse_playback_probe, user_data);
2633 setup_sink_reverse_playback (GstElement * sink, gpointer user_data)
2637 it = gst_bin_iterate_sinks (GST_BIN (sink));
2638 while (gst_iterator_foreach (it, hook_reverse_playback_probe, user_data))
2639 gst_iterator_resync (it);
2640 gst_iterator_free (it);
2644 check_success_source_reverse_playback (gpointer user_data)
2646 test_data *td = user_data;
2647 reverse_playback_master_data *d = td->md;
2649 FAIL_UNLESS (d->got_state_changed_to_playing);
2650 FAIL_UNLESS (d->seek_sent);
2654 check_success_sink_reverse_playback (gpointer user_data)
2656 test_data *td = user_data;
2657 reverse_playback_slave_data *d = td->sd;
2659 FAIL_UNLESS (d->got_segment_with_negative_rate);
2660 FAIL_UNLESS (d->got_buffer_after_segment_with_negative_rate);
2661 FAIL_UNLESS (GST_CLOCK_TIME_IS_VALID (d->first_backward_buffer_timestamp));
2662 FAIL_UNLESS (d->first_backward_buffer_timestamp >= GST_SECOND);
2663 FAIL_UNLESS (d->got_buffer_one_second_early);
2666 GST_START_TEST (test_a_reverse_playback)
2668 reverse_playback_master_data md = { 0 };
2669 reverse_playback_slave_data sd = { 0 };
2671 TEST_BASE (TEST_FEATURE_TEST_SOURCE,
2672 reverse_playback_source, setup_sink_reverse_playback,
2673 check_success_source_reverse_playback,
2674 check_success_sink_reverse_playback, NULL, &md, &sd);
2679 GST_START_TEST (test_av_reverse_playback)
2681 reverse_playback_master_data md = { 0 };
2682 reverse_playback_slave_data sd = { 0 };
2684 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_HAS_VIDEO,
2685 reverse_playback_source, setup_sink_reverse_playback,
2686 check_success_source_reverse_playback,
2687 check_success_sink_reverse_playback, NULL, &md, &sd);
2692 GST_START_TEST (test_av_2_reverse_playback)
2694 reverse_playback_master_data md = { 0 };
2695 reverse_playback_slave_data sd = { 0 };
2697 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_HAS_VIDEO |
2698 TEST_FEATURE_SPLIT_SINKS,
2699 reverse_playback_source, setup_sink_reverse_playback,
2700 check_success_source_reverse_playback,
2701 check_success_sink_reverse_playback, NULL, &md, &sd);
2706 /**** tags test ****/
2717 gboolean got_state_changed_to_playing;
2718 gboolean tags_sent[2][N_TEST_TAGS];
2723 gboolean tags_received[N_TEST_TAGS];
2727 send_tags_on_pad (GstPad * pad, gpointer user_data)
2729 test_data *td = user_data;
2730 tags_master_data *d = td->md;
2734 idx = pad2idx (pad, td->two_streams);
2736 e = gst_event_new_tag (gst_tag_list_new_empty ());
2737 FAIL_UNLESS (gst_pad_send_event (pad, e));
2738 d->tags_sent[idx][TEST_TAG_EMPTY] = TRUE;
2740 e = gst_event_new_tag (gst_tag_list_new (GST_TAG_TITLE, "title",
2741 GST_TAG_BITRATE, 56000, NULL));
2742 FAIL_UNLESS (gst_pad_send_event (pad, e));
2743 d->tags_sent[idx][TEST_TAG_TWO_TAGS] = TRUE;
2746 static GstPadProbeReturn
2747 tags_probe_source (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2749 test_data *td = user_data;
2750 tags_master_data *d = td->md;
2753 if (GST_IS_BUFFER (info->data)) {
2754 ts = GST_BUFFER_TIMESTAMP (info->data);
2755 if (GST_CLOCK_TIME_IS_VALID (ts) && ts > STEP_AT * GST_MSECOND) {
2756 gint idx = pad2idx (pad, td->two_streams);
2757 if (!d->tags_sent[idx][0]) {
2758 GstPad *peer = gst_pad_get_peer (pad);
2760 send_tags_on_pad (peer, td);
2761 gst_object_unref (peer);
2762 EXCLUSIVE_CALL (td, g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline,
2763 gst_object_ref (td->p)));
2768 return GST_PAD_PROBE_OK;
2772 hook_tags_probe_source (const GValue * v, gpointer user_data)
2774 hook_peer_probe_types (v, tags_probe_source,
2775 GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, user_data);
2779 tags_on_state_changed (gpointer user_data)
2781 test_data *td = user_data;
2782 tags_master_data *d = td->md;
2785 if (!d->got_state_changed_to_playing) {
2786 d->got_state_changed_to_playing = TRUE;
2788 it = gst_bin_iterate_sinks (GST_BIN (td->p));
2789 while (gst_iterator_foreach (it, hook_tags_probe_source, user_data))
2790 gst_iterator_resync (it);
2791 gst_iterator_free (it);
2796 tags_source (GstElement * source, gpointer user_data)
2798 test_data *td = user_data;
2799 GstStateChangeReturn ret;
2801 td->state_target = GST_STATE_PLAYING;
2802 td->state_changed_cb = tags_on_state_changed;
2803 ret = gst_element_set_state (source, GST_STATE_PLAYING);
2804 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
2807 static GstPadProbeReturn
2808 tags_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2810 test_data *td = user_data;
2811 tags_slave_data *d = td->sd;
2813 gchar *fstring = NULL;
2815 if (GST_IS_EVENT (info->data)) {
2816 if (GST_EVENT_TYPE (info->data) == GST_EVENT_TAG) {
2817 GstTagList *taglist = NULL;
2818 gst_event_parse_tag (GST_EVENT (info->data), &taglist);
2819 FAIL_UNLESS (taglist);
2820 if (gst_tag_list_is_empty (taglist)) {
2821 d->tags_received[TEST_TAG_EMPTY] = TRUE;
2822 } else if (gst_tag_list_get_string (taglist, GST_TAG_TITLE, &fstring)
2823 && !strcmp (fstring, "title")
2824 && gst_tag_list_get_uint (taglist, GST_TAG_BITRATE, &funsigned)
2825 && funsigned == 56000) {
2826 d->tags_received[TEST_TAG_TWO_TAGS] = TRUE;
2832 return GST_PAD_PROBE_OK;
2836 hook_tags_probe (const GValue * v, gpointer user_data)
2838 hook_probe (v, tags_probe, user_data);
2842 setup_sink_tags (GstElement * sink, gpointer user_data)
2846 it = gst_bin_iterate_sinks (GST_BIN (sink));
2847 while (gst_iterator_foreach (it, hook_tags_probe, user_data))
2848 gst_iterator_resync (it);
2849 gst_iterator_free (it);
2853 check_success_source_tags (gpointer user_data)
2855 test_data *td = user_data;
2856 tags_master_data *d = td->md;
2859 FAIL_UNLESS (d->got_state_changed_to_playing);
2860 for (n = 0; n < N_TEST_TAGS; ++n) {
2861 FAIL_UNLESS (d->tags_sent[n]);
2866 check_success_sink_tags (gpointer user_data)
2868 test_data *td = user_data;
2869 tags_slave_data *d = td->sd;
2872 for (n = 0; n < N_TEST_TAGS; ++n) {
2873 FAIL_UNLESS (d->tags_received[n]);
2877 GST_START_TEST (test_empty_tags)
2879 tags_master_data md = { 0 };
2880 tags_slave_data sd = { {0}
2883 TEST_BASE (TEST_FEATURE_TEST_SOURCE, tags_source, setup_sink_tags,
2884 check_success_source_tags, check_success_sink_tags, NULL, &md, &sd);
2889 GST_START_TEST (test_wavparse_tags)
2891 tags_master_data md = { 0 };
2892 tags_slave_data sd = { {0}
2895 TEST_BASE (TEST_FEATURE_WAV_SOURCE, tags_source, setup_sink_tags,
2896 check_success_source_tags, check_success_sink_tags, NULL, &md, &sd);
2901 GST_START_TEST (test_mpegts_tags)
2903 tags_master_data md = { 0 };
2904 tags_slave_data sd = { {0}
2907 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, tags_source, setup_sink_tags,
2908 check_success_source_tags, check_success_sink_tags, NULL, &md, &sd);
2913 GST_START_TEST (test_mpegts_2_tags)
2915 tags_master_data md = { 0 };
2916 tags_slave_data sd = { {0}
2919 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS, tags_source,
2920 setup_sink_tags, check_success_source_tags, check_success_sink_tags, NULL,
2926 GST_START_TEST (test_live_a_tags)
2928 tags_master_data md = { 0 };
2929 tags_slave_data sd = { {0}
2932 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, tags_source, setup_sink_tags,
2933 check_success_source_tags, check_success_sink_tags, NULL, &md, &sd);
2938 GST_START_TEST (test_live_av_tags)
2940 tags_master_data md = { 0 };
2941 tags_slave_data sd = { {0}
2944 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, tags_source, setup_sink_tags,
2945 check_success_source_tags, check_success_sink_tags, NULL, &md, &sd);
2950 GST_START_TEST (test_live_av_2_tags)
2952 tags_master_data md = { 0 };
2953 tags_slave_data sd = { {0}
2956 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
2957 tags_source, setup_sink_tags, check_success_source_tags,
2958 check_success_sink_tags, NULL, &md, &sd);
2963 /**** nagivation test ****/
2967 TEST_NAV_MOUSE_MOVE,
2974 gboolean got_state_changed_to_playing;
2975 gboolean navigation_received[N_NAVIGATION_EVENTS];
2976 } navigation_master_data;
2981 gboolean navigation_sent[N_NAVIGATION_EVENTS];
2983 } navigation_slave_data;
2985 static GstPadProbeReturn
2986 navigation_probe_source (GstPad * pad, GstPadProbeInfo * info,
2989 test_data *td = user_data;
2990 navigation_master_data *d = td->md;
2991 const GstStructure *s;
2992 const gchar *string, *key;
2995 if (GST_IS_EVENT (info->data)) {
2996 if (GST_EVENT_TYPE (info->data) == GST_EVENT_NAVIGATION) {
2997 s = gst_event_get_structure (info->data);
3001 string = gst_structure_get_string (s, "event");
3002 if (string && !strcmp (string, "mouse-move")) {
3003 if (gst_structure_get_double (s, "pointer_x", &x) && x == 4.7) {
3004 if (gst_structure_get_double (s, "pointer_y", &y) && y == 0.1) {
3005 d->navigation_received[TEST_NAV_MOUSE_MOVE] = TRUE;
3011 string = gst_structure_get_string (s, "event");
3012 if (string && !strcmp (string, "key-press")) {
3013 key = gst_structure_get_string (s, "key");
3014 if (key && !strcmp (key, "Left")) {
3015 d->navigation_received[TEST_NAV_KEY_PRESS] = TRUE;
3019 /* drop at this point to imply successful handling; the upstream filesrc
3020 * does not know how to handle navigation events and returns FALSE,
3021 * which makes the test fail */
3022 return GST_PAD_PROBE_DROP;
3025 return GST_PAD_PROBE_OK;
3029 hook_navigation_probe_source (const GValue * v, gpointer user_data)
3031 hook_probe_types (v, navigation_probe_source,
3032 GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, user_data);
3036 navigation_on_state_changed (gpointer user_data)
3038 test_data *td = user_data;
3039 navigation_master_data *d = td->md;
3041 if (!d->got_state_changed_to_playing)
3042 d->got_state_changed_to_playing = TRUE;
3046 navigation_source (GstElement * source, void *user_data)
3048 test_data *td = user_data;
3049 GstStateChangeReturn ret;
3052 it = gst_bin_iterate_sinks (GST_BIN (source));
3053 while (gst_iterator_foreach (it, hook_navigation_probe_source, user_data))
3054 gst_iterator_resync (it);
3055 gst_iterator_free (it);
3057 td->state_target = GST_STATE_PLAYING;
3058 td->state_changed_cb = navigation_on_state_changed;
3059 ret = gst_element_set_state (source, GST_STATE_PLAYING);
3060 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
3064 send_navigation_event (const GValue * v, gpointer user_data)
3066 test_data *td = user_data;
3067 navigation_slave_data *d = td->sd;
3073 sink = g_value_get_object (v);
3075 pad = gst_element_get_static_pad (sink, "sink");
3077 peer = gst_pad_get_peer (pad);
3079 gst_object_unref (pad);
3082 case TEST_NAV_MOUSE_MOVE:
3083 s = gst_structure_new ("application/x-gst-navigation", "event",
3084 G_TYPE_STRING, "mouse-move", "button", G_TYPE_INT, 0, "pointer_x",
3085 G_TYPE_DOUBLE, 4.7, "pointer_y", G_TYPE_DOUBLE, 0.1, NULL);
3086 e = gst_event_new_navigation (s);
3088 case TEST_NAV_KEY_PRESS:
3089 s = gst_structure_new ("application/x-gst-navigation", "event",
3090 G_TYPE_STRING, "key-press", "key", G_TYPE_STRING, "Left", NULL);
3091 e = gst_event_new_navigation (s);
3096 FAIL_UNLESS (gst_pad_send_event (peer, e));
3097 d->navigation_sent[d->step] = TRUE;
3099 gst_object_unref (peer);
3103 step_navigation (gpointer user_data)
3105 test_data *td = user_data;
3106 navigation_slave_data *d = td->sd;
3109 it = gst_bin_iterate_sinks (GST_BIN (td->p));
3110 while (gst_iterator_foreach (it, send_navigation_event, user_data))
3111 gst_iterator_resync (it);
3112 gst_iterator_free (it);
3114 if (++d->step < N_NAVIGATION_EVENTS)
3115 return G_SOURCE_CONTINUE;
3117 /* we are in the slave; send EOS to force the master to stop the pipeline */
3118 gst_element_post_message (GST_ELEMENT (td->p),
3119 gst_message_new_eos (GST_OBJECT (td->p)));
3121 gst_object_unref (td->p);
3122 return G_SOURCE_REMOVE;
3125 static GstPadProbeReturn
3126 navigation_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
3128 test_data *td = user_data;
3129 navigation_slave_data *d = td->sd;
3132 if (GST_IS_BUFFER (info->data)) {
3133 ts = GST_BUFFER_TIMESTAMP (info->data);
3134 if (GST_CLOCK_TIME_IS_VALID (ts) && ts > STEP_AT * GST_MSECOND) {
3137 gst_object_ref (td->p);
3138 g_timeout_add (50, step_navigation, td);
3143 return GST_PAD_PROBE_OK;
3147 hook_navigation_probe (const GValue * v, gpointer user_data)
3149 hook_probe (v, navigation_probe, user_data);
3153 setup_sink_navigation (GstElement * sink, gpointer user_data)
3157 it = gst_bin_iterate_sinks (GST_BIN (sink));
3158 while (gst_iterator_foreach (it, hook_navigation_probe, user_data))
3159 gst_iterator_resync (it);
3160 gst_iterator_free (it);
3164 check_success_source_navigation (gpointer user_data)
3166 test_data *td = user_data;
3167 navigation_master_data *d = td->md;
3170 FAIL_UNLESS (d->got_state_changed_to_playing);
3171 for (n = 0; n < N_NAVIGATION_EVENTS; ++n) {
3172 FAIL_UNLESS (d->navigation_received[n]);
3177 check_success_sink_navigation (gpointer user_data)
3179 test_data *td = user_data;
3180 navigation_slave_data *d = td->sd;
3183 FAIL_UNLESS (d->started);
3184 for (n = 0; n < N_NAVIGATION_EVENTS; ++n) {
3185 FAIL_UNLESS (d->navigation_sent[n]);
3189 GST_START_TEST (test_non_live_av_navigation)
3191 navigation_master_data md = { 0 };
3192 navigation_slave_data sd = { 0 };
3194 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, navigation_source,
3195 setup_sink_navigation, check_success_source_navigation,
3196 check_success_sink_navigation, NULL, &md, &sd);
3201 GST_START_TEST (test_non_live_av_2_navigation)
3203 navigation_master_data md = { 0 };
3204 navigation_slave_data sd = { 0 };
3206 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
3207 navigation_source, setup_sink_navigation, check_success_source_navigation,
3208 check_success_sink_navigation, NULL, &md, &sd);
3213 GST_START_TEST (test_live_av_navigation)
3215 navigation_master_data md = { 0 };
3216 navigation_slave_data sd = { 0 };
3218 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, navigation_source,
3219 setup_sink_navigation, check_success_source_navigation,
3220 check_success_sink_navigation, NULL, &md, &sd);
3225 GST_START_TEST (test_live_av_2_navigation)
3227 navigation_master_data md = { 0 };
3228 navigation_slave_data sd = { 0 };
3230 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
3231 navigation_source, setup_sink_navigation, check_success_source_navigation,
3232 check_success_sink_navigation, NULL, &md, &sd);
3237 /**** reconfigure test ****/
3241 gboolean got_state_changed_to_playing;
3242 gboolean reconfigure_sent[2];
3243 } reconfigure_master_data;
3247 gboolean reconfigure_scheduled;
3248 gboolean reconfigure_sent[2];
3249 gboolean got_caps[2][2];
3250 } reconfigure_slave_data;
3252 static GstPadProbeReturn
3253 reconfigure_source_probe (GstPad * pad, GstPadProbeInfo * info,
3256 test_data *td = user_data;
3257 reconfigure_master_data *d = td->md;
3259 if (GST_EVENT_TYPE (info->data) == GST_EVENT_RECONFIGURE) {
3260 gint idx = pad2idx (pad, td->two_streams);
3261 d->reconfigure_sent[idx] = TRUE;
3262 EXCLUSIVE_CALL (td, g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline,
3263 gst_object_ref (td->p)));
3266 return GST_PAD_PROBE_OK;
3270 hook_reconfigure_source_probe (const GValue * v, gpointer user_data)
3272 hook_probe_types (v, reconfigure_source_probe,
3273 GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, user_data);
3277 reconfigure_on_state_changed (gpointer user_data)
3279 test_data *td = user_data;
3280 reconfigure_master_data *d = td->md;
3282 if (!d->got_state_changed_to_playing)
3283 d->got_state_changed_to_playing = TRUE;
3287 reconfigure_source (GstElement * source, gpointer user_data)
3289 test_data *td = user_data;
3290 GstStateChangeReturn ret;
3293 it = gst_bin_iterate_sinks (GST_BIN (source));
3294 while (gst_iterator_foreach (it, hook_reconfigure_source_probe, user_data))
3295 gst_iterator_resync (it);
3296 gst_iterator_free (it);
3298 td->state_target = GST_STATE_PLAYING;
3299 td->state_changed_cb = reconfigure_on_state_changed;
3300 ret = gst_element_set_state (source, GST_STATE_PLAYING);
3301 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
3305 send_reconfigure_on_element (const GValue * v, gpointer user_data)
3307 test_data *td = user_data;
3308 reconfigure_slave_data *d = td->sd;
3309 GstElement *sink, *capsfilter;
3311 GstCaps *caps = NULL;
3313 sink = g_value_get_object (v);
3315 pad = gst_element_get_static_pad (sink, "sink");
3318 // look for the previous element, change caps if a capsfilter
3319 peer = gst_pad_get_peer (pad);
3321 capsfilter = GST_ELEMENT (gst_pad_get_parent (peer));
3322 g_object_get (capsfilter, "caps", &caps, NULL);
3324 caps = gst_caps_make_writable (caps);
3325 if (!strcmp (gst_structure_get_name (gst_caps_get_structure (caps, 0)),
3327 gst_caps_set_simple (caps, "rate", G_TYPE_INT, 48000, NULL);
3329 gst_caps_set_simple (caps, "width", G_TYPE_INT, 320, "height", G_TYPE_INT,
3332 g_object_set (capsfilter, "caps", caps, NULL);
3333 FAIL_UNLESS (capsfilter);
3335 gst_object_unref (capsfilter);
3336 gst_object_unref (peer);
3338 d->reconfigure_sent[caps2idx (caps, td->two_streams)] = TRUE;
3340 gst_caps_unref (caps);
3341 gst_object_unref (pad);
3345 send_reconfigure (gpointer user_data)
3347 test_data *td = user_data;
3350 it = gst_bin_iterate_sinks (GST_BIN (td->p));
3351 while (gst_iterator_foreach (it, send_reconfigure_on_element, user_data))
3352 gst_iterator_resync (it);
3353 gst_iterator_free (it);
3355 gst_object_unref (td->p);
3356 return G_SOURCE_REMOVE;
3359 static GstPadProbeReturn
3360 reconfigure_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
3362 test_data *td = user_data;
3363 reconfigure_slave_data *d = td->sd;
3368 if (GST_IS_BUFFER (info->data)) {
3369 ts = GST_BUFFER_TIMESTAMP (info->data);
3370 if (GST_CLOCK_TIME_IS_VALID (ts) && ts >= STEP_AT * GST_MSECOND) {
3371 if (!d->reconfigure_scheduled) {
3372 d->reconfigure_scheduled = TRUE;
3373 gst_object_ref (td->p);
3374 g_idle_add ((GSourceFunc) send_reconfigure, td);
3377 } else if (GST_IS_EVENT (info->data)) {
3378 if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
3379 gst_event_parse_caps (GST_EVENT (info->data), &caps);
3380 idx = caps2idx (caps, td->two_streams);
3381 if (d->reconfigure_sent[idx]) {
3382 d->got_caps[idx][1] = TRUE;
3384 d->got_caps[idx][0] = TRUE;
3389 return GST_PAD_PROBE_OK;
3393 hook_reconfigure_probe (const GValue * v, gpointer user_data)
3395 hook_probe (v, reconfigure_probe, user_data);
3399 setup_sink_reconfigure (GstElement * sink, gpointer user_data)
3403 it = gst_bin_iterate_sinks (GST_BIN (sink));
3404 while (gst_iterator_foreach (it, hook_reconfigure_probe, user_data))
3405 gst_iterator_resync (it);
3406 gst_iterator_free (it);
3410 check_success_source_reconfigure (gpointer user_data)
3412 test_data *td = user_data;
3413 reconfigure_master_data *d = td->md;
3416 FAIL_UNLESS (d->got_state_changed_to_playing);
3417 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
3418 FAIL_UNLESS (d->reconfigure_sent[idx]);
3423 check_success_sink_reconfigure (gpointer user_data)
3425 test_data *td = user_data;
3426 reconfigure_slave_data *d = td->sd;
3429 FAIL_UNLESS (d->reconfigure_scheduled);
3430 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
3431 FAIL_UNLESS (d->reconfigure_sent[idx]);
3432 FAIL_UNLESS (d->got_caps[idx][0]);
3433 FAIL_UNLESS (d->got_caps[idx][1]);
3437 GST_START_TEST (test_non_live_a_reconfigure)
3439 reconfigure_master_data md = { 0 };
3440 reconfigure_slave_data sd = { 0 };
3442 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_FILTER_SINK_CAPS,
3443 reconfigure_source, setup_sink_reconfigure,
3444 check_success_source_reconfigure, check_success_sink_reconfigure, NULL,
3450 GST_START_TEST (test_non_live_av_reconfigure)
3452 reconfigure_master_data md = { 0 };
3453 reconfigure_slave_data sd = { 0 };
3455 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_HAS_VIDEO |
3456 TEST_FEATURE_FILTER_SINK_CAPS,
3457 reconfigure_source, setup_sink_reconfigure,
3458 check_success_source_reconfigure, check_success_sink_reconfigure, NULL,
3464 GST_START_TEST (test_live_a_reconfigure)
3466 reconfigure_master_data md = { 0 };
3467 reconfigure_slave_data sd = { 0 };
3469 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE | TEST_FEATURE_FILTER_SINK_CAPS,
3470 reconfigure_source, setup_sink_reconfigure,
3471 check_success_source_reconfigure, check_success_sink_reconfigure, NULL,
3477 GST_START_TEST (test_live_av_reconfigure)
3479 reconfigure_master_data md = { 0 };
3480 reconfigure_slave_data sd = { 0 };
3482 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_FILTER_SINK_CAPS,
3483 reconfigure_source, setup_sink_reconfigure,
3484 check_success_source_reconfigure, check_success_sink_reconfigure, NULL,
3490 /**** state changes test ****/
3495 GHashTable *fdin, *fdout;
3496 gboolean waiting_state_change;
3497 } state_changes_master_data;
3506 } state_changes_slave_data;
3509 set_fdin (gpointer key, gpointer value, gpointer user_data)
3511 g_object_set (key, "fdin", GPOINTER_TO_INT (value), NULL);
3515 set_fdout (gpointer key, gpointer value, gpointer user_data)
3517 g_object_set (key, "fdout", GPOINTER_TO_INT (value), NULL);
3522 * 0: READY NULL READY PAUSED READY PAUSED READY NULL
3523 * 8: READY PAUSED PLAYING PAUSED PLAYING PAUSED READY PAUSED READY NULL
3525 * 19: READY NULL READY PAUSED READY PAUSED READY NULL
3526 * 27: READY PAUSED PLAYING PAUSED PLAYING PAUSED READY PAUSED READY NULL
3528 * 38: READY NULL READY PAUSED READY PAUSED READY NULL
3529 * 46: READY PAUSED PLAYING PAUSED PLAYING
3533 step_state_changes (gpointer user_data)
3535 test_data *td = user_data;
3536 state_changes_master_data *d = td->md;
3537 gboolean ret = G_SOURCE_CONTINUE;
3538 GstStateChangeReturn scret = GST_STATE_CHANGE_FAILURE;
3542 if (d->waiting_state_change)
3545 switch (d->step++) {
3554 scret = gst_element_set_state (td->p, GST_STATE_NULL);
3555 FAIL_UNLESS_EQUALS_INT (scret, GST_STATE_CHANGE_SUCCESS);
3569 scret = gst_element_set_state (td->p, GST_STATE_READY);
3570 FAIL_UNLESS_EQUALS_INT (scret, GST_STATE_CHANGE_SUCCESS);
3579 /* while we are disconnected, we can't do NULL -> READY */
3580 scret = gst_element_set_state (td->p, GST_STATE_READY);
3581 FAIL_UNLESS_EQUALS_INT (scret, GST_STATE_CHANGE_FAILURE);
3593 td->state_target = GST_STATE_PAUSED;
3594 scret = gst_element_set_state (td->p, GST_STATE_PAUSED);
3595 FAIL_IF (scret == GST_STATE_CHANGE_FAILURE);
3603 /* while we are disconnected, we can't do NULL -> READY */
3604 scret = gst_element_set_state (td->p, GST_STATE_PAUSED);
3605 FAIL_UNLESS_EQUALS_INT (scret, GST_STATE_CHANGE_FAILURE);
3611 td->state_target = GST_STATE_PLAYING;
3612 scret = gst_element_set_state (td->p, GST_STATE_PLAYING);
3613 FAIL_IF (scret == GST_STATE_CHANGE_FAILURE);
3617 /* while we are disconnected, we can't do NULL -> READY */
3618 scret = gst_element_set_state (td->p, GST_STATE_PLAYING);
3619 FAIL_UNLESS_EQUALS_INT (scret, GST_STATE_CHANGE_FAILURE);
3622 d->fdin = g_hash_table_new (g_direct_hash, g_direct_equal);
3623 d->fdout = g_hash_table_new (g_direct_hash, g_direct_equal);
3624 for (l = weak_refs; l; l = l->next) {
3625 g_object_get (l->data, "fdin", &fdin, "fdout", &fdout, NULL);
3626 g_hash_table_insert (d->fdin, (gpointer) l->data,
3627 GINT_TO_POINTER (fdin));
3628 g_hash_table_insert (d->fdout, (gpointer) l->data,
3629 GINT_TO_POINTER (fdout));
3630 g_signal_emit_by_name (G_OBJECT (l->data), "disconnect", NULL);
3634 g_hash_table_foreach (d->fdin, set_fdin, NULL);
3635 g_hash_table_foreach (d->fdout, set_fdout, NULL);
3636 g_hash_table_destroy (d->fdin);
3637 g_hash_table_destroy (d->fdout);
3640 /* send EOS early to avoid waiting for the actual end of the file */
3641 gst_element_send_event (td->p, gst_event_new_eos ());
3642 gst_object_unref (td->p);
3643 ret = G_SOURCE_REMOVE;
3647 if (scret == GST_STATE_CHANGE_ASYNC)
3648 d->waiting_state_change = TRUE;
3655 state_changes_state_changed (gpointer user_data)
3657 test_data *td = user_data;
3658 state_changes_master_data *d = td->md;
3660 d->waiting_state_change = FALSE;
3664 state_changes_source (GstElement * source, gpointer user_data)
3666 test_data *td = user_data;
3667 state_changes_master_data *d = td->md;
3669 gst_object_ref (source);
3670 g_timeout_add (STEP_AT, (GSourceFunc) step_state_changes, td);
3672 d->waiting_state_change = FALSE;
3673 td->state_changed_cb = state_changes_state_changed;
3676 static GstBusSyncReply
3677 state_changes_sink_bus_msg (GstBus * bus, GstMessage * message,
3680 test_data *td = user_data;
3681 state_changes_slave_data *d = td->sd;
3683 switch (GST_MESSAGE_TYPE (message)) {
3684 case GST_MESSAGE_EOS:
3687 case GST_MESSAGE_STATE_CHANGED:
3688 if (GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (td->p)) {
3690 gst_message_parse_state_changed (message, NULL, &state, NULL);
3692 case GST_STATE_NULL:
3695 case GST_STATE_READY:
3698 case GST_STATE_PAUSED:
3701 case GST_STATE_PLAYING:
3712 return GST_BUS_PASS;
3716 setup_sink_state_changes (GstElement * sink, gpointer user_data)
3718 g_object_set (sink, "auto-flush-bus", FALSE, NULL);
3719 gst_bus_set_sync_handler (GST_ELEMENT_BUS (sink), state_changes_sink_bus_msg,
3724 check_success_source_state_changes (gpointer user_data)
3726 test_data *td = user_data;
3727 state_changes_master_data *d = td->md;
3729 FAIL_UNLESS_EQUALS_INT (d->step, 52);
3733 check_success_sink_state_changes (gpointer user_data)
3735 test_data *td = user_data;
3736 state_changes_slave_data *d = td->sd;
3739 bus = gst_pipeline_get_bus (GST_PIPELINE (td->p));
3740 gst_bus_set_flushing (bus, TRUE);
3741 gst_object_unref (bus);
3743 FAIL_UNLESS (d->got_eos);
3744 FAIL_UNLESS_EQUALS_INT (d->n_null, 6);
3745 FAIL_UNLESS_EQUALS_INT (d->n_ready, 13);
3746 FAIL_UNLESS_EQUALS_INT (d->n_paused, 11);
3747 FAIL_UNLESS_EQUALS_INT (d->n_playing, 4);
3750 GST_START_TEST (test_empty_state_changes)
3752 state_changes_master_data md = { 0 };
3753 state_changes_slave_data sd = { 0 };
3755 TEST_BASE (TEST_FEATURE_TEST_SOURCE, state_changes_source,
3756 setup_sink_state_changes, check_success_source_state_changes,
3757 check_success_sink_state_changes, NULL, &md, &sd);
3762 GST_START_TEST (test_wavparse_state_changes)
3764 state_changes_master_data md = { 0 };
3765 state_changes_slave_data sd = { 0 };
3767 TEST_BASE (TEST_FEATURE_WAV_SOURCE, state_changes_source,
3768 setup_sink_state_changes, check_success_source_state_changes,
3769 check_success_sink_state_changes, NULL, &md, &sd);
3774 GST_START_TEST (test_mpegts_state_changes)
3776 state_changes_master_data md = { 0 };
3777 state_changes_slave_data sd = { 0 };
3779 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, state_changes_source,
3780 setup_sink_state_changes, check_success_source_state_changes,
3781 check_success_sink_state_changes, NULL, &md, &sd);
3786 GST_START_TEST (test_mpegts_2_state_changes)
3788 state_changes_master_data md = { 0 };
3789 state_changes_slave_data sd = { 0 };
3791 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
3792 state_changes_source, setup_sink_state_changes,
3793 check_success_source_state_changes, check_success_sink_state_changes,
3799 /**** state changes stress test ****/
3803 gint n_state_changes;
3804 } state_changes_stress_input_data;
3808 gboolean got_state_changed_to_playing;
3809 gboolean async_state_change_completed;
3810 } state_changes_stress_master_data;
3813 step_state_changes_stress (gpointer user_data)
3815 test_data *td = user_data;
3816 state_changes_stress_input_data *i = td->id;
3817 state_changes_stress_master_data *d = td->md;
3818 static const GstState states[] =
3819 { GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING };
3821 GstStateChangeReturn ret;
3823 /* wait for async state change to complete before continuing */
3824 if (!d->async_state_change_completed)
3825 return G_SOURCE_CONTINUE;
3827 if (i->n_state_changes == 0) {
3828 ret = gst_element_set_state (td->p, GST_STATE_PLAYING);
3829 FAIL_IF (ret == GST_STATE_CHANGE_FAILURE);
3830 g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline, td->p);
3831 return G_SOURCE_REMOVE;
3833 --i->n_state_changes;
3835 state = states[rand () % 4];
3836 ret = gst_element_set_state (td->p, state);
3837 FAIL_IF (ret == GST_STATE_CHANGE_FAILURE);
3839 if (ret == GST_STATE_CHANGE_ASYNC) {
3840 td->state_target = state;
3841 d->async_state_change_completed = FALSE;
3844 return G_SOURCE_CONTINUE;
3848 state_changes_stress_on_state_changed (gpointer user_data)
3850 test_data *td = user_data;
3851 state_changes_stress_master_data *d = td->md;
3853 if (!d->got_state_changed_to_playing) {
3854 d->got_state_changed_to_playing = TRUE;
3855 gst_object_ref (td->p);
3856 g_timeout_add (50, (GSourceFunc) step_state_changes_stress, td);
3858 d->async_state_change_completed = TRUE;
3862 state_changes_stress_source (GstElement * source, gpointer user_data)
3864 test_data *td = user_data;
3865 GstStateChangeReturn ret;
3867 td->state_target = GST_STATE_PLAYING;
3868 td->state_changed_cb = state_changes_stress_on_state_changed;
3869 ret = gst_element_set_state (source, GST_STATE_PLAYING);
3870 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
3874 check_success_source_state_changes_stress (gpointer user_data)
3876 test_data *td = user_data;
3877 state_changes_stress_input_data *i = td->id;
3878 state_changes_stress_master_data *d = td->md;
3880 FAIL_UNLESS (d->got_state_changed_to_playing);
3881 FAIL_UNLESS_EQUALS_INT (i->n_state_changes, 0);
3884 GST_START_TEST (test_empty_state_changes_stress)
3886 state_changes_stress_input_data id = { 500 };
3887 state_changes_stress_master_data md = { 0 };
3889 TEST_BASE (TEST_FEATURE_TEST_SOURCE, state_changes_stress_source, NULL,
3890 check_success_source_state_changes_stress, NULL, &id, &md, NULL);
3895 GST_START_TEST (test_wavparse_state_changes_stress)
3897 state_changes_stress_input_data id = { 500 };
3898 state_changes_stress_master_data md = { 0 };
3900 TEST_BASE (TEST_FEATURE_WAV_SOURCE, state_changes_stress_source, NULL,
3901 check_success_source_state_changes_stress, NULL, &id, &md, NULL);
3906 GST_START_TEST (test_mpegts_state_changes_stress)
3908 state_changes_stress_input_data id = { 500 };
3909 state_changes_stress_master_data md = { 0 };
3911 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, state_changes_stress_source, NULL,
3912 check_success_source_state_changes_stress, NULL, &id, &md, NULL);
3917 GST_START_TEST (test_mpegts_2_state_changes_stress)
3919 state_changes_stress_input_data id = { 500 };
3920 state_changes_stress_master_data md = { 0 };
3922 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
3923 state_changes_stress_source, NULL,
3924 check_success_source_state_changes_stress, NULL, &id, &md, NULL);
3929 GST_START_TEST (test_live_a_state_changes_stress)
3931 state_changes_stress_input_data id = { 500 };
3932 state_changes_stress_master_data md = { 0 };
3934 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, state_changes_stress_source, NULL,
3935 check_success_source_state_changes_stress, NULL, &id, &md, NULL);
3940 GST_START_TEST (test_live_av_state_changes_stress)
3942 state_changes_stress_input_data id = { 500 };
3943 state_changes_stress_master_data md = { 0 };
3945 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, state_changes_stress_source, NULL,
3946 check_success_source_state_changes_stress, NULL, &id, &md, NULL);
3951 GST_START_TEST (test_live_av_2_state_changes_stress)
3953 state_changes_stress_input_data id = { 500 };
3954 state_changes_stress_master_data md = { 0 };
3956 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
3957 state_changes_stress_source, NULL,
3958 check_success_source_state_changes_stress, NULL, &id, &md, NULL);
3963 /**** serialized query test ****/
3967 gboolean sent_query[2];
3968 gboolean got_query_reply[2];
3970 } serialized_query_master_data;
3975 } serialized_query_slave_data;
3978 send_drain (gpointer user_data)
3980 test_data *td = user_data;
3981 serialized_query_master_data *d = td->md;
3985 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
3986 q = gst_query_new_drain ();
3987 FAIL_UNLESS (gst_pad_query (d->pad[idx], q));
3988 d->got_query_reply[idx] = TRUE;
3989 gst_query_unref (q);
3990 gst_object_unref (d->pad[idx]);
3993 g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline, gst_object_ref (td->p));
3994 return G_SOURCE_REMOVE;
3997 static GstPadProbeReturn
3998 serialized_query_probe_source (GstPad * pad, GstPadProbeInfo * info,
4001 test_data *td = user_data;
4002 serialized_query_master_data *d = td->md;
4006 if (GST_IS_BUFFER (info->data)) {
4007 ts = GST_BUFFER_TIMESTAMP (info->data);
4008 idx = pad2idx (pad, td->two_streams);
4009 if (!d->sent_query[idx] && GST_CLOCK_TIME_IS_VALID (ts)
4010 && ts > STEP_AT * GST_MSECOND) {
4011 d->sent_query[idx] = TRUE;
4012 d->pad[idx] = gst_object_ref (pad);
4013 EXCLUSIVE_CALL (td, g_idle_add (send_drain, td));
4016 return GST_PAD_PROBE_OK;
4020 hook_serialized_query_probe_source (const GValue * v, gpointer user_data)
4022 hook_probe (v, serialized_query_probe_source, user_data);
4026 serialized_query_source (GstElement * source, gpointer user_data)
4029 GstStateChangeReturn ret;
4031 it = gst_bin_iterate_sinks (GST_BIN (source));
4032 while (gst_iterator_foreach (it, hook_serialized_query_probe_source,
4034 gst_iterator_resync (it);
4035 gst_iterator_free (it);
4037 ret = gst_element_set_state (source, GST_STATE_PLAYING);
4038 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC
4039 || ret == GST_STATE_CHANGE_SUCCESS);
4042 static GstPadProbeReturn
4043 serialized_query_probe (GstPad * pad, GstPadProbeInfo * info,
4046 test_data *td = user_data;
4047 serialized_query_slave_data *d = td->sd;
4049 if (GST_IS_QUERY (info->data)) {
4050 if (GST_QUERY_TYPE (info->data) == GST_QUERY_DRAIN) {
4051 d->got_query = TRUE;
4054 return GST_PAD_PROBE_OK;
4058 hook_serialized_query_probe (const GValue * v, gpointer user_data)
4060 hook_probe (v, serialized_query_probe, user_data);
4064 setup_sink_serialized_query (GstElement * sink, gpointer user_data)
4068 it = gst_bin_iterate_sinks (GST_BIN (sink));
4069 while (gst_iterator_foreach (it, hook_serialized_query_probe, user_data))
4070 gst_iterator_resync (it);
4071 gst_iterator_free (it);
4075 check_success_source_serialized_query (gpointer user_data)
4077 test_data *td = user_data;
4078 serialized_query_master_data *d = td->md;
4081 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
4082 FAIL_UNLESS (d->sent_query[idx]);
4083 FAIL_UNLESS (d->got_query_reply[idx]);
4088 check_success_sink_serialized_query (gpointer user_data)
4090 test_data *td = user_data;
4091 serialized_query_slave_data *d = td->sd;
4093 FAIL_UNLESS (d->got_query);
4096 GST_START_TEST (test_empty_serialized_query)
4098 serialized_query_master_data md = { {0} };
4099 serialized_query_slave_data sd = { 0 };
4101 TEST_BASE (TEST_FEATURE_TEST_SOURCE, serialized_query_source,
4102 setup_sink_serialized_query, check_success_source_serialized_query,
4103 check_success_sink_serialized_query, NULL, &md, &sd);
4108 GST_START_TEST (test_wavparse_serialized_query)
4110 serialized_query_master_data md = { {0} };
4111 serialized_query_slave_data sd = { 0 };
4113 TEST_BASE (TEST_FEATURE_WAV_SOURCE, serialized_query_source,
4114 setup_sink_serialized_query, check_success_source_serialized_query,
4115 check_success_sink_serialized_query, NULL, &md, &sd);
4120 GST_START_TEST (test_mpegts_serialized_query)
4122 serialized_query_master_data md = { {0} };
4123 serialized_query_slave_data sd = { 0 };
4125 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, serialized_query_source,
4126 setup_sink_serialized_query, check_success_source_serialized_query,
4127 check_success_sink_serialized_query, NULL, &md, &sd);
4132 GST_START_TEST (test_mpegts_2_serialized_query)
4134 serialized_query_master_data md = { {0} };
4135 serialized_query_slave_data sd = { 0 };
4137 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
4138 serialized_query_source, setup_sink_serialized_query,
4139 check_success_source_serialized_query,
4140 check_success_sink_serialized_query, NULL, &md, &sd);
4145 GST_START_TEST (test_live_a_serialized_query)
4147 serialized_query_master_data md = { {0} };
4148 serialized_query_slave_data sd = { 0 };
4150 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, serialized_query_source,
4151 setup_sink_serialized_query, check_success_source_serialized_query,
4152 check_success_sink_serialized_query, NULL, &md, &sd);
4157 GST_START_TEST (test_live_av_serialized_query)
4159 serialized_query_master_data md = { {0} };
4160 serialized_query_slave_data sd = { 0 };
4162 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, serialized_query_source,
4163 setup_sink_serialized_query, check_success_source_serialized_query,
4164 check_success_sink_serialized_query, NULL, &md, &sd);
4169 GST_START_TEST (test_live_av_2_serialized_query)
4171 serialized_query_master_data md = { {0} };
4172 serialized_query_slave_data sd = { 0 };
4174 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
4175 serialized_query_source, setup_sink_serialized_query,
4176 check_success_source_serialized_query,
4177 check_success_sink_serialized_query, NULL, &md, &sd);
4182 /**** non serialized event test ****/
4186 gboolean sent_event[2];
4187 } non_serialized_event_master_data;
4192 } non_serialized_event_slave_data;
4194 static GstPadProbeReturn
4195 non_serialized_event_probe_source (GstPad * pad, GstPadProbeInfo * info,
4198 test_data *td = user_data;
4199 non_serialized_event_master_data *d = td->md;
4204 if (GST_IS_BUFFER (info->data)) {
4205 ts = GST_BUFFER_TIMESTAMP (info->data);
4206 idx = pad2idx (pad, td->two_streams);
4207 if (!d->sent_event[idx]
4208 && GST_CLOCK_TIME_IS_VALID (ts) && ts > STEP_AT * GST_MSECOND) {
4209 e = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB,
4210 gst_structure_new ("name", "field", G_TYPE_INT, 42, NULL));
4212 FAIL_UNLESS (gst_pad_send_event (pad, e));
4213 d->sent_event[idx] = TRUE;
4214 EXCLUSIVE_CALL (td, g_timeout_add (STEP_AT, (GSourceFunc) stop_pipeline,
4215 gst_object_ref (td->p)));
4218 return GST_PAD_PROBE_OK;
4222 hook_non_serialized_event_probe_source (const GValue * v, gpointer user_data)
4224 hook_probe (v, non_serialized_event_probe_source, user_data);
4228 non_serialized_event_source (GstElement * source, gpointer user_data)
4231 GstStateChangeReturn ret;
4233 it = gst_bin_iterate_sinks (GST_BIN (source));
4234 while (gst_iterator_foreach (it, hook_non_serialized_event_probe_source,
4236 gst_iterator_resync (it);
4237 gst_iterator_free (it);
4239 ret = gst_element_set_state (source, GST_STATE_PLAYING);
4240 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC
4241 || ret == GST_STATE_CHANGE_SUCCESS);
4244 static GstPadProbeReturn
4245 non_serialized_event_probe (GstPad * pad, GstPadProbeInfo * info,
4248 test_data *td = user_data;
4249 non_serialized_event_slave_data *d = td->sd;
4250 const GstStructure *s;
4253 if (GST_IS_EVENT (info->data)) {
4254 if (GST_EVENT_TYPE (info->data) == GST_EVENT_CUSTOM_DOWNSTREAM_OOB) {
4255 s = gst_event_get_structure (info->data);
4256 FAIL_UNLESS (!strcmp (gst_structure_get_name (s), "name"));
4257 FAIL_UNLESS (gst_structure_get_int (s, "field", &val));
4258 FAIL_UNLESS (val == 42);
4259 d->got_event = TRUE;
4262 return GST_PAD_PROBE_OK;
4266 hook_non_serialized_event_probe (const GValue * v, gpointer user_data)
4268 hook_probe (v, non_serialized_event_probe, user_data);
4272 setup_sink_non_serialized_event (GstElement * sink, gpointer user_data)
4276 it = gst_bin_iterate_sinks (GST_BIN (sink));
4277 while (gst_iterator_foreach (it, hook_non_serialized_event_probe, user_data))
4278 gst_iterator_resync (it);
4279 gst_iterator_free (it);
4283 check_success_source_non_serialized_event (gpointer user_data)
4285 test_data *td = user_data;
4286 non_serialized_event_master_data *d = td->md;
4289 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
4290 FAIL_UNLESS (d->sent_event[idx]);
4295 check_success_sink_non_serialized_event (gpointer user_data)
4297 test_data *td = user_data;
4298 non_serialized_event_slave_data *d = td->sd;
4300 FAIL_UNLESS (d->got_event);
4303 GST_START_TEST (test_empty_non_serialized_event)
4305 non_serialized_event_master_data md = { {0} };
4306 non_serialized_event_slave_data sd = { 0 };
4308 TEST_BASE (TEST_FEATURE_TEST_SOURCE, non_serialized_event_source,
4309 setup_sink_non_serialized_event,
4310 check_success_source_non_serialized_event,
4311 check_success_sink_non_serialized_event, NULL, &md, &sd);
4316 GST_START_TEST (test_wavparse_non_serialized_event)
4318 non_serialized_event_master_data md = { {0} };
4319 non_serialized_event_slave_data sd = { 0 };
4321 TEST_BASE (TEST_FEATURE_WAV_SOURCE, non_serialized_event_source,
4322 setup_sink_non_serialized_event,
4323 check_success_source_non_serialized_event,
4324 check_success_sink_non_serialized_event, NULL, &md, &sd);
4329 GST_START_TEST (test_mpegts_non_serialized_event)
4331 non_serialized_event_master_data md = { {0} };
4332 non_serialized_event_slave_data sd = { 0 };
4334 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, non_serialized_event_source,
4335 setup_sink_non_serialized_event,
4336 check_success_source_non_serialized_event,
4337 check_success_sink_non_serialized_event, NULL, &md, &sd);
4342 GST_START_TEST (test_mpegts_2_non_serialized_event)
4344 non_serialized_event_master_data md = { {0} };
4345 non_serialized_event_slave_data sd = { 0 };
4347 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS,
4348 non_serialized_event_source, setup_sink_non_serialized_event,
4349 check_success_source_non_serialized_event,
4350 check_success_sink_non_serialized_event, NULL, &md, &sd);
4355 GST_START_TEST (test_live_a_non_serialized_event)
4357 non_serialized_event_master_data md = { {0} };
4358 non_serialized_event_slave_data sd = { 0 };
4360 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, non_serialized_event_source,
4361 setup_sink_non_serialized_event,
4362 check_success_source_non_serialized_event,
4363 check_success_sink_non_serialized_event, NULL, &md, &sd);
4368 GST_START_TEST (test_live_av_non_serialized_event)
4370 non_serialized_event_master_data md = { {0} };
4371 non_serialized_event_slave_data sd = { 0 };
4373 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, non_serialized_event_source,
4374 setup_sink_non_serialized_event,
4375 check_success_source_non_serialized_event,
4376 check_success_sink_non_serialized_event, NULL, &md, &sd);
4381 GST_START_TEST (test_live_av_2_non_serialized_event)
4383 non_serialized_event_master_data md = { {0} };
4384 non_serialized_event_slave_data sd = { 0 };
4386 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
4387 non_serialized_event_source, setup_sink_non_serialized_event,
4388 check_success_source_non_serialized_event,
4389 check_success_sink_non_serialized_event, NULL, &md, &sd);
4394 /**** meta test ****/
4398 TEST_META_PROTECTION = 0,
4404 gboolean meta_sent[N_TEST_META];
4409 gboolean meta_received[N_TEST_META];
4412 static GstPadProbeReturn
4413 meta_probe_source (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
4415 test_data *td = user_data;
4416 meta_master_data *d = td->md;
4418 GstProtectionMeta *meta;
4420 if (GST_IS_BUFFER (info->data)) {
4421 buffer = GST_BUFFER (info->data);
4423 gst_buffer_add_protection_meta (buffer, gst_structure_new ("name",
4424 "somefield", G_TYPE_INT, 42, NULL));
4426 d->meta_sent[TEST_META_PROTECTION] = TRUE;
4428 return GST_PAD_PROBE_OK;
4432 hook_meta_probe_source (const GValue * v, gpointer user_data)
4434 hook_probe (v, meta_probe_source, user_data);
4438 meta_source (GstElement * source, gpointer user_data)
4441 GstStateChangeReturn ret;
4443 it = gst_bin_iterate_sinks (GST_BIN (source));
4444 while (gst_iterator_foreach (it, hook_meta_probe_source, user_data))
4445 gst_iterator_resync (it);
4446 gst_iterator_free (it);
4448 ret = gst_element_set_state (source, GST_STATE_PLAYING);
4449 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC
4450 || ret == GST_STATE_CHANGE_SUCCESS);
4452 g_timeout_add (STOP_AT, (GSourceFunc) stop_pipeline, gst_object_ref (source));
4456 scan_meta (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
4458 test_data *td = user_data;
4459 meta_slave_data *d = td->sd;
4462 GstProtectionMeta *pmeta;
4464 if ((*meta)->info->api == GST_PROTECTION_META_API_TYPE) {
4465 pmeta = (GstProtectionMeta *) * meta;
4466 FAIL_UNLESS (GST_IS_STRUCTURE (pmeta->info));
4467 s = GST_STRUCTURE (pmeta->info);
4468 FAIL_UNLESS (!strcmp (gst_structure_get_name (s), "name"));
4469 FAIL_UNLESS (gst_structure_get_int (s, "somefield", &val));
4470 FAIL_UNLESS (val == 42);
4471 d->meta_received[TEST_META_PROTECTION] = TRUE;
4476 static GstPadProbeReturn
4477 meta_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
4479 if (GST_IS_BUFFER (info->data)) {
4480 gst_buffer_foreach_meta (info->data, scan_meta, user_data);
4482 return GST_PAD_PROBE_OK;
4486 hook_meta_probe (const GValue * v, gpointer user_data)
4488 hook_probe (v, meta_probe, user_data);
4492 setup_sink_meta (GstElement * sink, gpointer user_data)
4496 it = gst_bin_iterate_sinks (GST_BIN (sink));
4497 while (gst_iterator_foreach (it, hook_meta_probe, user_data))
4498 gst_iterator_resync (it);
4499 gst_iterator_free (it);
4503 check_success_source_meta (gpointer user_data)
4505 test_data *td = user_data;
4506 meta_master_data *d = td->md;
4509 for (n = 0; n < N_TEST_META; ++n)
4510 FAIL_UNLESS (d->meta_sent[n]);
4514 check_success_sink_meta (gpointer user_data)
4516 test_data *td = user_data;
4517 meta_slave_data *d = td->sd;
4520 for (n = 0; n < N_TEST_META; ++n)
4521 FAIL_UNLESS (d->meta_received[n]);
4524 GST_START_TEST (test_empty_meta)
4526 meta_master_data md = { {0}
4528 meta_slave_data sd = { {0}
4531 TEST_BASE (TEST_FEATURE_TEST_SOURCE, meta_source, setup_sink_meta,
4532 check_success_source_meta, check_success_sink_meta, NULL, &md, &sd);
4537 GST_START_TEST (test_wavparse_meta)
4539 meta_master_data md = { {0}
4541 meta_slave_data sd = { {0}
4544 TEST_BASE (TEST_FEATURE_WAV_SOURCE, meta_source, setup_sink_meta,
4545 check_success_source_meta, check_success_sink_meta, NULL, &md, &sd);
4550 GST_START_TEST (test_mpegts_meta)
4552 meta_master_data md = { {0}
4554 meta_slave_data sd = { {0}
4557 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE, meta_source, setup_sink_meta,
4558 check_success_source_meta, check_success_sink_meta, NULL, &md, &sd);
4563 GST_START_TEST (test_mpegts_2_meta)
4565 meta_master_data md = { {0}
4567 meta_slave_data sd = { {0}
4570 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_SPLIT_SINKS, meta_source,
4571 setup_sink_meta, check_success_source_meta, check_success_sink_meta,
4577 GST_START_TEST (test_live_a_meta)
4579 meta_master_data md = { {0}
4581 meta_slave_data sd = { {0}
4584 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE, meta_source, setup_sink_meta,
4585 check_success_source_meta, check_success_sink_meta, NULL, &md, &sd);
4590 GST_START_TEST (test_live_av_meta)
4592 meta_master_data md = { {0}
4594 meta_slave_data sd = { {0}
4597 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, meta_source, setup_sink_meta,
4598 check_success_source_meta, check_success_sink_meta, NULL, &md, &sd);
4603 GST_START_TEST (test_live_av_2_meta)
4605 meta_master_data md = { {0}
4607 meta_slave_data sd = { {0}
4610 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
4611 meta_source, setup_sink_meta, check_success_source_meta,
4612 check_success_sink_meta, NULL, &md, &sd);
4617 /**** source change test ****/
4621 void (*switcher) (GstElement *, char *name);
4622 } source_change_input_data;
4626 gboolean source_change_scheduled;
4627 gboolean source_changed;
4628 } source_change_master_data;
4632 gboolean got_caps[2][2];
4633 gboolean got_buffer[2][2];
4635 } source_change_slave_data;
4638 stop_source (gpointer user_data)
4640 GstElement *source = user_data;
4642 FAIL_UNLESS (gst_element_set_state (source,
4643 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
4644 gst_object_unref (source);
4649 remove_source (gpointer user_data)
4651 GstElement *source = user_data;
4653 FAIL_UNLESS (gst_element_set_state (source,
4654 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
4655 gst_bin_remove (GST_BIN (GST_ELEMENT_PARENT (source)), source);
4660 switch_to_aiff (GstElement * pipeline, char *name)
4662 GstElement *sbin, *filesrc, *ipcpipelinesink;
4666 gst_parse_bin_from_description ("pushfilesrc name=filesrc ! aiffparse",
4668 FAIL_IF (e || !sbin);
4669 gst_element_set_name (sbin, name);
4670 filesrc = gst_bin_get_by_name (GST_BIN (sbin), "filesrc");
4671 FAIL_UNLESS (filesrc);
4672 g_object_set (filesrc, "location", "../../tests/files/s16be-id3v2.aiff",
4674 gst_object_unref (filesrc);
4675 gst_bin_add (GST_BIN (pipeline), sbin);
4676 ipcpipelinesink = gst_bin_get_by_name (GST_BIN (pipeline), "ipcpipelinesink");
4677 FAIL_UNLESS (ipcpipelinesink);
4678 FAIL_UNLESS (gst_element_link (sbin, ipcpipelinesink));
4679 gst_object_unref (ipcpipelinesink);
4680 gst_element_sync_state_with_parent (sbin);
4685 switch_av (GstElement * pipeline, char *name, gboolean live, gboolean Long)
4687 GstElement *src, *ipcpipelinesink;
4688 gint L = Long ? 10 : 1;
4690 if (g_str_has_prefix (name, "videotestsrc")) {
4691 /* replace video source with audio source */
4692 src = gst_element_factory_make ("audiotestsrc", NULL);
4694 g_object_set (src, "is-live", live, "num-buffers", live ? 27 * L : -1,
4696 gst_bin_add (GST_BIN (pipeline), src);
4698 gst_bin_get_by_name (GST_BIN (pipeline), "vipcpipelinesink");
4699 FAIL_UNLESS (ipcpipelinesink);
4700 FAIL_UNLESS (gst_element_link (src, ipcpipelinesink));
4701 gst_object_unref (ipcpipelinesink);
4702 gst_element_sync_state_with_parent (src);
4705 if (g_str_has_prefix (name, "audiotestsrc")) {
4706 /* replace audio source with video source */
4707 src = gst_element_factory_make ("videotestsrc", NULL);
4709 g_object_set (src, "is-live", live, "num-buffers", live ? 19 * L : -1,
4711 gst_bin_add (GST_BIN (pipeline), src);
4713 gst_bin_get_by_name (GST_BIN (pipeline), "aipcpipelinesink");
4714 FAIL_UNLESS (ipcpipelinesink);
4715 FAIL_UNLESS (gst_element_link (src, ipcpipelinesink));
4716 gst_object_unref (ipcpipelinesink);
4717 gst_element_sync_state_with_parent (src);
4724 switch_live_av (GstElement * pipeline, char *name)
4726 switch_av (pipeline, name, TRUE, FALSE);
4729 static GstPadProbeReturn
4730 change_source_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
4732 test_data *td = user_data;
4733 const source_change_input_data *i = td->id;
4734 source_change_master_data *d = td->md;
4738 peer = gst_pad_get_peer (pad);
4740 FAIL_UNLESS (gst_pad_unlink (pad, peer));
4741 gst_object_unref (peer);
4743 source = GST_ELEMENT (gst_element_get_parent (pad));
4744 FAIL_UNLESS (source);
4745 g_object_set_qdata (G_OBJECT (source), to_be_removed_quark (),
4746 GINT_TO_POINTER (1));
4748 gst_bin_remove (GST_BIN (GST_ELEMENT_PARENT (source)), source);
4749 (*i->switcher) (td->p, gst_element_get_name (source));
4751 g_idle_add (stop_source, source);
4753 d->source_changed = TRUE;
4755 gst_object_unref (td->p);
4756 return GST_PAD_PROBE_REMOVE;
4760 change_source (gpointer user_data)
4762 test_data *td = user_data;
4765 static const char *const names[] =
4766 { "source", "audiotestsrc", "videotestsrc" };
4767 gboolean found = FALSE;
4770 for (n = 0; n < G_N_ELEMENTS (names); ++n) {
4771 source = gst_bin_get_by_name (GST_BIN (td->p), names[n]);
4774 pad = gst_element_get_static_pad (source, "src");
4776 gst_object_ref (td->p);
4777 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, change_source_blocked,
4779 gst_object_unref (pad);
4780 gst_object_unref (source);
4783 FAIL_UNLESS (found);
4785 gst_object_unref (td->p);
4786 return G_SOURCE_REMOVE;
4790 source_change_on_state_changed (gpointer user_data)
4792 test_data *td = user_data;
4793 source_change_master_data *d = td->md;
4795 if (!d->source_change_scheduled) {
4796 d->source_change_scheduled = TRUE;
4797 gst_object_ref (td->p);
4798 g_timeout_add (STEP_AT, change_source, td);
4803 source_change_source (GstElement * source, gpointer user_data)
4805 test_data *td = user_data;
4806 GstStateChangeReturn ret;
4808 td->state_target = GST_STATE_PLAYING;
4809 td->state_changed_cb = source_change_on_state_changed;
4810 ret = gst_element_set_state (source, GST_STATE_PLAYING);
4811 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC
4812 || ret == GST_STATE_CHANGE_SUCCESS);
4816 scppad2idx (GstPad * pad, gboolean two_streams, GstCaps * newcaps)
4818 static GQuark scpidx = 0;
4824 scpidx = g_quark_from_static_string ("scpidx");
4829 p = g_object_get_qdata (G_OBJECT (pad), scpidx);
4831 return GPOINTER_TO_INT (p) - 1;
4833 caps = gst_pad_get_current_caps (pad);
4835 caps = gst_pad_get_pad_template_caps (pad);
4836 if ((!caps || gst_caps_is_any (caps)) && newcaps)
4837 caps = gst_caps_ref (newcaps);
4839 idx = caps2idx (caps, two_streams);
4840 gst_caps_unref (caps);
4841 g_object_set_qdata (G_OBJECT (pad), scpidx, GINT_TO_POINTER (idx + 1));
4845 static GstPadProbeReturn
4846 source_change_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
4848 test_data *td = user_data;
4849 source_change_slave_data *d = td->sd;
4853 if (GST_IS_BUFFER (info->data)) {
4854 idx = scppad2idx (pad, td->two_streams, NULL);
4855 if (d->got_caps[idx][1])
4856 d->got_buffer[idx][1] = TRUE;
4857 else if (d->got_caps[idx][0])
4858 d->got_buffer[idx][0] = TRUE;
4859 } else if (GST_IS_EVENT (info->data)) {
4860 if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
4861 gst_event_parse_caps (info->data, &caps);
4862 idx = scppad2idx (pad, td->two_streams, caps);
4863 if (!d->got_caps[idx][0]) {
4864 FAIL_IF (d->caps[idx]);
4865 d->got_caps[idx][0] = TRUE;
4866 d->caps[idx] = gst_caps_ref (caps);
4868 FAIL_UNLESS (d->caps);
4869 if (gst_caps_is_equal (caps, d->caps[idx])) {
4872 gst_caps_replace (&d->caps[idx], NULL);
4873 d->got_caps[idx][1] = TRUE;
4878 return GST_PAD_PROBE_OK;
4882 hook_source_change_probe (const GValue * v, gpointer user_data)
4884 hook_probe (v, source_change_probe, user_data);
4888 setup_sink_source_change (GstElement * sink, gpointer user_data)
4892 it = gst_bin_iterate_sinks (GST_BIN (sink));
4893 while (gst_iterator_foreach (it, hook_source_change_probe, user_data))
4894 gst_iterator_resync (it);
4895 gst_iterator_free (it);
4899 check_success_source_source_change (gpointer user_data)
4901 test_data *td = user_data;
4902 source_change_master_data *d = td->md;
4904 FAIL_UNLESS (d->source_change_scheduled);
4905 FAIL_UNLESS (d->source_changed);
4909 check_success_sink_source_change (gpointer user_data)
4911 test_data *td = user_data;
4912 source_change_slave_data *d = td->sd;
4915 for (idx = 0; idx < (td->two_streams ? 2 : 1); idx++) {
4916 FAIL_UNLESS (d->got_caps[idx][0]);
4917 FAIL_UNLESS (d->got_buffer[idx][0]);
4918 FAIL_UNLESS (d->got_caps[idx][1]);
4919 FAIL_UNLESS (d->got_buffer[idx][1]);
4923 GST_START_TEST (test_non_live_source_change)
4925 source_change_input_data id = { switch_to_aiff };
4926 source_change_master_data md = { 0 };
4927 source_change_slave_data sd = { {{0}
4931 TEST_BASE (TEST_FEATURE_WAV_SOURCE, source_change_source,
4932 setup_sink_source_change, check_success_source_source_change,
4933 check_success_sink_source_change, &id, &md, &sd);
4938 GST_START_TEST (test_live_av_source_change)
4940 source_change_input_data id = { switch_live_av };
4941 source_change_master_data md = { 0 };
4942 source_change_slave_data sd = { {{0}
4946 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, source_change_source,
4947 setup_sink_source_change, check_success_source_source_change,
4948 check_success_sink_source_change, &id, &md, &sd);
4953 GST_START_TEST (test_live_av_2_source_change)
4955 source_change_input_data id = { switch_live_av };
4956 source_change_master_data md = { 0 };
4957 source_change_slave_data sd = { {{0}
4961 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
4962 source_change_source, setup_sink_source_change,
4963 check_success_source_source_change, check_success_sink_source_change,
4969 /**** dynamic pipeline change stress test ****/
4974 void (*switcher0) (test_data *);
4976 void (*switcher1) (test_data *);
4977 } dynamic_pipeline_change_stress_input_data;
4983 guint n_blocks_left;
4984 guint n_blocks_done;
4985 gboolean adding_probes;
4986 gboolean dynamic_pipeline_change_stress_scheduled;
4987 } dynamic_pipeline_change_stress_master_data;
4989 static gboolean dynamic_pipeline_change_stress_step (gpointer user_data);
4991 static GstPadProbeReturn
4992 dynamic_pipeline_change_stress_source_blocked_switch_av (GstPad * pad,
4993 GstPadProbeInfo * info, gpointer user_data)
4995 test_data *td = user_data;
4996 dynamic_pipeline_change_stress_master_data *d = td->md;
5000 /* An idle pad probe could be called directly from the gst_pad_add_probe call
5001 if the pad happens to be idle right now. This would deadlock us though, as
5002 we need all pads to be blocked at the same time, so we need the iteration
5003 over all pads to be done before the pad probes execute. So we keep track of
5004 whether we're iterating to add the probes, and pass if so. */
5005 if (d->adding_probes) {
5006 return GST_PAD_PROBE_PASS;
5009 peer = gst_pad_get_peer (pad);
5011 FAIL_UNLESS (gst_pad_unlink (pad, peer));
5012 gst_object_unref (peer);
5014 source = GST_ELEMENT (gst_element_get_parent (pad));
5015 FAIL_UNLESS (source);
5016 g_object_set_qdata (G_OBJECT (source), to_be_removed_quark (),
5017 GINT_TO_POINTER (1));
5019 /* we want all pads to be blocked before we proceed */
5020 g_mutex_lock (&d->mutex);
5022 while (d->n_blocks_left > 0)
5023 g_cond_wait (&d->cond, &d->mutex);
5024 g_mutex_unlock (&d->mutex);
5025 g_cond_broadcast (&d->cond);
5027 g_mutex_lock (&d->mutex);
5028 switch_av (td->p, gst_element_get_name (source),
5029 ! !(td->features & TEST_FEATURE_LIVE), TRUE);
5030 g_mutex_unlock (&d->mutex);
5032 g_idle_add_full (G_PRIORITY_HIGH, remove_source, source, g_object_unref);
5034 if (g_atomic_int_dec_and_test (&d->n_blocks_done))
5035 g_timeout_add (STEP_AT, dynamic_pipeline_change_stress_step, td);
5037 return GST_PAD_PROBE_REMOVE;
5041 change_audio_channel (GstElement * pipeline, char *name,
5042 const char *ipcpipelinesink_name, gboolean live)
5044 GstElement *src, *ipcpipelinesink;
5046 /* replace audio source with video source */
5047 src = gst_element_factory_make ("audiotestsrc", NULL);
5049 g_object_set (src, "is-live", live, "num-buffers", live ? 190 : -1, NULL);
5051 gst_bin_add (GST_BIN (pipeline), src);
5053 gst_bin_get_by_name (GST_BIN (pipeline), ipcpipelinesink_name);
5054 FAIL_UNLESS (ipcpipelinesink);
5055 FAIL_UNLESS (gst_element_link (src, ipcpipelinesink));
5056 gst_object_unref (ipcpipelinesink);
5057 gst_element_sync_state_with_parent (src);
5062 static GstPadProbeReturn
5063 dynamic_pipeline_change_stress_source_blocked_change_audio_channel (GstPad *
5064 pad, GstPadProbeInfo * info, gpointer user_data)
5066 test_data *td = user_data;
5067 dynamic_pipeline_change_stress_master_data *d = td->md;
5070 const char *ipcpipelinesink_name;
5072 /* An idle pad probe could be called directly from the gst_pad_add_probe call
5073 if the pad happens to be idle right now. This would deadlock us though, as
5074 we need all pads to be blocked at the same time, so we need the iteration
5075 over all pads to be done before the pad probes execute. So we keep track of
5076 whether we're iterating to add the probes, and pass if so. */
5077 if (d->adding_probes) {
5078 return GST_PAD_PROBE_PASS;
5081 peer = gst_pad_get_peer (pad);
5083 ipcpipelinesink_name = GST_ELEMENT_NAME (GST_PAD_PARENT (peer));
5084 FAIL_UNLESS (gst_pad_unlink (pad, peer));
5085 gst_object_unref (peer);
5087 source = GST_ELEMENT (gst_element_get_parent (pad));
5088 FAIL_UNLESS (source);
5089 g_object_set_qdata (G_OBJECT (source), to_be_removed_quark (),
5090 GINT_TO_POINTER (1));
5092 /* we want all pads to be blocked before we proceed */
5093 g_mutex_lock (&d->mutex);
5095 while (d->n_blocks_left > 0)
5096 g_cond_wait (&d->cond, &d->mutex);
5097 g_cond_broadcast (&d->cond);
5098 g_mutex_unlock (&d->mutex);
5100 g_mutex_lock (&d->mutex);
5101 change_audio_channel (td->p, gst_element_get_name (source),
5102 ipcpipelinesink_name, ! !(td->features & TEST_FEATURE_LIVE));
5103 g_mutex_unlock (&d->mutex);
5105 g_idle_add_full (G_PRIORITY_HIGH, remove_source, source, g_object_unref);
5107 if (g_atomic_int_dec_and_test (&d->n_blocks_done))
5108 g_timeout_add (STEP_AT, dynamic_pipeline_change_stress_step, td);
5110 return GST_PAD_PROBE_REMOVE;
5115 const char *const *names;
5117 GstPadProbeReturn (*f) (GstPad * pad, GstPadProbeInfo * info,
5118 gpointer user_data);
5120 } block_if_named_data;
5123 block_if_named (const GValue * v, gpointer user_data)
5125 block_if_named_data *bind = user_data;
5130 e = g_value_get_object (v);
5132 for (n = 0; n < bind->n_names; ++n) {
5133 if (g_str_has_prefix (GST_ELEMENT_NAME (e), bind->names[n])) {
5134 pad = gst_element_get_static_pad (e, "src");
5137 if (!g_object_get_qdata (G_OBJECT (e), to_be_removed_quark ()))
5138 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, bind->f, bind->td,
5140 gst_object_unref (pad);
5146 count_audio_sources (const GValue * v, gpointer user_data)
5150 e = g_value_get_object (v);
5153 // we don't want to count the sources that are in the process
5154 // of being removed asynchronously
5155 if (g_object_get_qdata (G_OBJECT (e), to_be_removed_quark ()))
5158 if (g_str_has_prefix (GST_ELEMENT_NAME (e), "audiotestsrc"))
5159 ++ * (guint *) user_data;
5163 dynamic_pipeline_change_stress_swap_source (test_data * td)
5165 dynamic_pipeline_change_stress_master_data *d = td->md;
5166 static const char *const names[] =
5167 { "source", "audiotestsrc", "videotestsrc" };
5168 block_if_named_data bind = { names, sizeof (names) / sizeof (names[0]),
5169 dynamic_pipeline_change_stress_source_blocked_switch_av, td
5173 /* we have two sources, we need to wait for both */
5174 d->n_blocks_left = d->n_blocks_done = 2;
5176 it = gst_bin_iterate_sources (GST_BIN (td->p));
5177 d->adding_probes = TRUE;
5178 while (gst_iterator_foreach (it, block_if_named, &bind)) {
5179 GST_INFO_OBJECT (td->p, "Resync");
5180 gst_iterator_resync (it);
5182 d->adding_probes = FALSE;
5183 gst_iterator_free (it);
5187 dynamic_pipeline_change_stress_change_audio_channel (test_data * td)
5189 dynamic_pipeline_change_stress_master_data *d = td->md;
5190 static const char *const names[] = { "audiotestsrc" };
5191 block_if_named_data bind = { names, sizeof (names) / sizeof (names[0]),
5192 dynamic_pipeline_change_stress_source_blocked_change_audio_channel, td
5195 guint audio_sources;
5197 /* we have either zero or one audio source */
5198 it = gst_bin_iterate_sources (GST_BIN (td->p));
5200 while (gst_iterator_foreach (it, count_audio_sources, &audio_sources)) {
5201 GST_INFO_OBJECT (td->p, "Resync");
5202 gst_iterator_resync (it);
5204 gst_iterator_free (it);
5205 d->n_blocks_left = d->n_blocks_done = audio_sources;
5207 it = gst_bin_iterate_sources (GST_BIN (td->p));
5208 d->adding_probes = TRUE;
5209 while (gst_iterator_foreach (it, block_if_named, &bind)) {
5210 GST_INFO_OBJECT (td->p, "Resync");
5211 gst_iterator_resync (it);
5213 d->adding_probes = FALSE;
5214 gst_iterator_free (it);
5218 dynamic_pipeline_change_stress_step (gpointer user_data)
5220 test_data *td = user_data;
5221 dynamic_pipeline_change_stress_input_data *i = td->id;
5222 guint available, idx;
5224 /* pick a random action among the ones we have left */
5225 available = i->n_switches_0 + i->n_switches_1;
5226 if (available == 0) {
5227 GST_INFO_OBJECT (td->p, "Destroying pipeline");
5228 FAIL_UNLESS (gst_element_set_state (td->p,
5229 GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE);
5230 g_timeout_add (STEP_AT, stop_pipeline, td->p);
5231 return G_SOURCE_REMOVE;
5234 idx = rand () % available;
5235 if (idx < i->n_switches_0) {
5236 (*i->switcher0) (td);
5238 return G_SOURCE_REMOVE;
5240 idx -= i->n_switches_0;
5242 if (idx < i->n_switches_1) {
5243 (*i->switcher1) (td);
5245 return G_SOURCE_REMOVE;
5247 idx -= i->n_switches_1;
5249 return G_SOURCE_REMOVE;
5253 dynamic_pipeline_change_stress_on_state_changed (gpointer user_data)
5255 test_data *td = user_data;
5256 dynamic_pipeline_change_stress_master_data *d = td->md;
5258 if (!d->dynamic_pipeline_change_stress_scheduled) {
5259 d->dynamic_pipeline_change_stress_scheduled = TRUE;
5260 gst_object_ref (td->p);
5261 g_timeout_add (STEP_AT, dynamic_pipeline_change_stress_step, td);
5266 dynamic_pipeline_change_stress (GstElement * source, gpointer user_data)
5268 test_data *td = user_data;
5269 dynamic_pipeline_change_stress_master_data *d = td->md;
5270 GstStateChangeReturn ret;
5272 g_mutex_init (&d->mutex);
5273 g_cond_init (&d->cond);
5275 td->state_target = GST_STATE_PLAYING;
5276 td->state_changed_cb = dynamic_pipeline_change_stress_on_state_changed;
5277 ret = gst_element_set_state (source, GST_STATE_PLAYING);
5278 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC
5279 || ret == GST_STATE_CHANGE_SUCCESS);
5283 check_success_source_dynamic_pipeline_change_stress (gpointer user_data)
5285 test_data *td = user_data;
5286 dynamic_pipeline_change_stress_input_data *i = td->id;
5287 dynamic_pipeline_change_stress_master_data *d = td->md;
5289 FAIL_UNLESS (d->dynamic_pipeline_change_stress_scheduled);
5290 FAIL_UNLESS_EQUALS_INT (i->n_switches_0, 0);
5291 FAIL_UNLESS_EQUALS_INT (i->n_switches_1, 0);
5293 g_cond_clear (&d->cond);
5294 g_mutex_clear (&d->mutex);
5297 GST_START_TEST (test_non_live_av_dynamic_pipeline_change_stress)
5299 dynamic_pipeline_change_stress_input_data id = { 100,
5300 dynamic_pipeline_change_stress_swap_source, 100,
5301 dynamic_pipeline_change_stress_change_audio_channel
5303 dynamic_pipeline_change_stress_master_data md = { {0} };
5305 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_HAS_VIDEO,
5306 dynamic_pipeline_change_stress, NULL,
5307 check_success_source_dynamic_pipeline_change_stress, NULL, &id, &md,
5313 GST_START_TEST (test_non_live_av_2_dynamic_pipeline_change_stress)
5315 dynamic_pipeline_change_stress_input_data id = { 100,
5316 dynamic_pipeline_change_stress_swap_source, 100,
5317 dynamic_pipeline_change_stress_change_audio_channel
5319 dynamic_pipeline_change_stress_master_data md = { {0} };
5321 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_HAS_VIDEO |
5322 TEST_FEATURE_SPLIT_SINKS, dynamic_pipeline_change_stress, NULL,
5323 check_success_source_dynamic_pipeline_change_stress, NULL, &id, &md,
5329 GST_START_TEST (test_live_av_dynamic_pipeline_change_stress)
5331 dynamic_pipeline_change_stress_input_data id = { 100,
5332 dynamic_pipeline_change_stress_swap_source, 100,
5333 dynamic_pipeline_change_stress_change_audio_channel
5335 dynamic_pipeline_change_stress_master_data md = { {0} };
5337 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE, dynamic_pipeline_change_stress, NULL,
5338 check_success_source_dynamic_pipeline_change_stress, NULL, &id, &md,
5344 GST_START_TEST (test_live_av_2_dynamic_pipeline_change_stress)
5346 dynamic_pipeline_change_stress_input_data id = { 100,
5347 dynamic_pipeline_change_stress_swap_source, 100,
5348 dynamic_pipeline_change_stress_change_audio_channel
5350 dynamic_pipeline_change_stress_master_data md = { {0} };
5352 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_SPLIT_SINKS,
5353 dynamic_pipeline_change_stress, NULL,
5354 check_success_source_dynamic_pipeline_change_stress, NULL, &id, &md,
5360 /**** error from slave test ****/
5365 } error_from_slave_input_data;
5369 gboolean second_pass;
5370 gboolean got_state_changed_to_playing_on_first_pass;
5371 gboolean got_error_on_first_pass;
5372 gboolean got_state_changed_to_playing_on_second_pass;
5373 gboolean got_error_on_second_pass;
5374 } error_from_slave_master_data;
5377 bump_through_NULL (gpointer user_data)
5379 test_data *td = user_data;
5380 error_from_slave_input_data *i = td->id;
5381 error_from_slave_master_data *d = td->md;
5382 GstStateChangeReturn ret;
5385 ret = gst_element_set_state (td->p, GST_STATE_NULL);
5387 FAIL_UNLESS (ret == GST_STATE_CHANGE_SUCCESS);
5389 FAIL_UNLESS (gst_element_get_state (td->p, NULL, NULL,
5390 GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_SUCCESS);
5392 d->second_pass = TRUE;
5395 recreate_crashed_slave_process ();
5396 /* give the process time to be created in the other process */
5397 g_usleep (500 * 1000);
5399 /* reconnect to to slave process */
5400 sink = gst_bin_get_by_name (GST_BIN (td->p), "ipcpipelinesink");
5402 g_object_set (sink, "fdin", pipesba[0], "fdout", pipesfa[1], NULL);
5403 gst_object_unref (sink);
5406 ret = gst_element_set_state (td->p, GST_STATE_PLAYING);
5407 FAIL_UNLESS (ret == GST_STATE_CHANGE_SUCCESS
5408 || ret == GST_STATE_CHANGE_ASYNC);
5410 g_timeout_add (STOP_AT, (GSourceFunc) stop_pipeline, td->p);
5411 return G_SOURCE_REMOVE;
5415 disconnect (const GValue * v, gpointer user_data)
5419 e = g_value_get_object (v);
5421 g_signal_emit_by_name (G_OBJECT (e), "disconnect", NULL);
5425 error_from_slave_source_bus_msg (GstBus * bus, GstMessage * message,
5428 test_data *td = user_data;
5429 error_from_slave_input_data *i = td->id;
5430 error_from_slave_master_data *d = td->md;
5432 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
5433 if (!d->second_pass) {
5434 if (!d->got_error_on_first_pass) {
5437 d->got_error_on_first_pass = TRUE;
5440 it = gst_bin_iterate_sinks (GST_BIN (td->p));
5441 while (gst_iterator_foreach (it, disconnect, NULL))
5442 gst_iterator_resync (it);
5443 gst_iterator_free (it);
5446 gst_object_ref (td->p);
5447 g_timeout_add (STEP_AT, bump_through_NULL, td);
5450 /* don't pass the expected error */
5453 } else if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS) {
5454 if (!d->second_pass) {
5455 /* We'll get an expected EOS as the source reacts to the error */
5459 return master_bus_msg (bus, message, user_data);
5463 error_from_slave_on_state_changed (gpointer user_data)
5465 test_data *td = user_data;
5466 error_from_slave_master_data *d = td->md;
5469 d->got_state_changed_to_playing_on_second_pass = TRUE;
5471 d->got_state_changed_to_playing_on_first_pass = TRUE;
5475 error_from_slave_position_getter (GstElement * element)
5479 /* we do not care about the result */
5480 gst_element_query_position (element, GST_FORMAT_TIME, &pos);
5486 error_from_slave_source (GstElement * source, gpointer user_data)
5488 test_data *td = user_data;
5489 GstStateChangeReturn ret;
5491 /* we're on the source, there's already the basic master_bus_msg watch,
5492 and gst doesn't want more than one watch, so we remove the watch and
5493 call it directly when done in the new watch */
5494 gst_bus_remove_watch (GST_ELEMENT_BUS (source));
5495 gst_bus_add_watch (GST_ELEMENT_BUS (source), error_from_slave_source_bus_msg,
5497 g_timeout_add (STEP_AT, (GSourceFunc) error_from_slave_position_getter,
5500 td->state_changed_cb = error_from_slave_on_state_changed;
5501 td->state_target = GST_STATE_PLAYING;
5502 ret = gst_element_set_state (source, GST_STATE_PLAYING);
5503 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC);
5507 error_from_slave_sink_bus_msg (GstBus * bus, GstMessage * message,
5510 test_data *td = user_data;
5511 error_from_slave_input_data *i = td->id;
5513 switch (GST_MESSAGE_TYPE (message)) {
5514 case GST_MESSAGE_ERROR:
5515 if (!strcmp (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)),
5517 g_object_set (GST_MESSAGE_SRC (message), "error-after", -1, NULL);
5519 case GST_MESSAGE_ASYNC_DONE:
5520 if (GST_IS_PIPELINE (GST_MESSAGE_SRC (message))) {
5521 /* We have two identical processes, and only one must crash. They can
5522 be distinguished by recovery_pid, however. */
5523 if (i->crash && recovery_pid)
5524 g_timeout_add (CRASH_AT, (GSourceFunc) crash, NULL);
5534 setup_sink_error_from_slave (GstElement * sink, gpointer user_data)
5536 gst_bus_add_watch (GST_ELEMENT_BUS (sink), error_from_slave_sink_bus_msg,
5541 check_success_source_error_from_slave (gpointer user_data)
5543 test_data *td = user_data;
5544 error_from_slave_master_data *d = td->md;
5546 FAIL_UNLESS (d->second_pass);
5547 FAIL_UNLESS (d->got_state_changed_to_playing_on_first_pass);
5548 FAIL_UNLESS (d->got_state_changed_to_playing_on_second_pass);
5549 FAIL_UNLESS (d->got_error_on_first_pass);
5550 FAIL_IF (d->got_error_on_second_pass);
5553 GST_START_TEST (test_empty_error_from_slave)
5555 error_from_slave_input_data id = { FALSE };
5556 error_from_slave_master_data md = { 0 };
5558 TEST_BASE (TEST_FEATURE_TEST_SOURCE | TEST_FEATURE_ERROR_SINK,
5559 error_from_slave_source, setup_sink_error_from_slave,
5560 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5565 GST_START_TEST (test_wavparse_error_from_slave)
5567 error_from_slave_input_data id = { FALSE };
5568 error_from_slave_master_data md = { 0 };
5570 TEST_BASE (TEST_FEATURE_WAV_SOURCE | TEST_FEATURE_ERROR_SINK,
5571 error_from_slave_source, setup_sink_error_from_slave,
5572 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5577 GST_START_TEST (test_mpegts_error_from_slave)
5579 error_from_slave_input_data id = { FALSE };
5580 error_from_slave_master_data md = { 0 };
5582 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_ERROR_SINK,
5583 error_from_slave_source, setup_sink_error_from_slave,
5584 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5589 GST_START_TEST (test_mpegts_2_error_from_slave)
5591 error_from_slave_input_data id = { FALSE };
5592 error_from_slave_master_data md = { 0 };
5594 TEST_BASE (TEST_FEATURE_MPEGTS_SOURCE | TEST_FEATURE_ERROR_SINK |
5595 TEST_FEATURE_SPLIT_SINKS,
5596 error_from_slave_source, setup_sink_error_from_slave,
5597 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5602 GST_START_TEST (test_live_a_error_from_slave)
5604 error_from_slave_input_data id = { FALSE };
5605 error_from_slave_master_data md = { 0 };
5607 TEST_BASE (TEST_FEATURE_LIVE_A_SOURCE | TEST_FEATURE_ERROR_SINK,
5608 error_from_slave_source, setup_sink_error_from_slave,
5609 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5614 GST_START_TEST (test_live_av_error_from_slave)
5616 error_from_slave_input_data id = { FALSE };
5617 error_from_slave_master_data md = { 0 };
5619 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_ERROR_SINK,
5620 error_from_slave_source, setup_sink_error_from_slave,
5621 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5626 GST_START_TEST (test_live_av_2_error_from_slave)
5628 error_from_slave_input_data id = { FALSE };
5629 error_from_slave_master_data md = { 0 };
5631 TEST_BASE (TEST_FEATURE_LIVE_AV_SOURCE | TEST_FEATURE_ERROR_SINK |
5632 TEST_FEATURE_SPLIT_SINKS,
5633 error_from_slave_source, setup_sink_error_from_slave,
5634 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5639 GST_START_TEST (test_wavparse_slave_process_crash)
5641 error_from_slave_input_data id = { TRUE };
5642 error_from_slave_master_data md = { 0 };
5644 TEST_BASE (TEST_FEATURE_WAV_SOURCE | TEST_FEATURE_RECOVERY_SLAVE_PROCESS,
5645 error_from_slave_source, setup_sink_error_from_slave,
5646 check_success_source_error_from_slave, NULL, &id, &md, NULL);
5651 /**** master process crash test ****/
5655 gboolean got_state_changed_to_playing;
5656 } master_process_crash_master_data;
5662 } master_process_crash_slave_data;
5665 master_process_crash_on_state_changed (gpointer user_data)
5667 test_data *td = user_data;
5668 master_process_crash_master_data *d = td->md;
5670 if (!d->got_state_changed_to_playing) {
5671 d->got_state_changed_to_playing = TRUE;
5673 /* We have two identical processes, and only one must crash. They can
5674 be distinguished by recovery_pid, however. */
5676 g_timeout_add (CRASH_AT, (GSourceFunc) crash, NULL);
5681 master_process_crash_source (GstElement * source, gpointer user_data)
5683 test_data *td = user_data;
5684 GstStateChangeReturn ret;
5686 td->state_target = GST_STATE_PLAYING;
5687 td->state_changed_cb = master_process_crash_on_state_changed;
5688 ret = gst_element_set_state (source, GST_STATE_PLAYING);
5689 FAIL_UNLESS (ret == GST_STATE_CHANGE_ASYNC
5690 || ret == GST_STATE_CHANGE_SUCCESS);
5693 static GstPadProbeReturn
5694 master_process_crash_probe (GstPad * pad, GstPadProbeInfo * info,
5697 test_data *td = user_data;
5698 master_process_crash_slave_data *d = td->sd;
5700 if (GST_IS_EVENT (info->data)) {
5701 if (GST_EVENT_TYPE (info->data) == GST_EVENT_EOS) {
5706 return GST_PAD_PROBE_OK;
5710 hook_master_process_crash_probe (const GValue * v, gpointer user_data)
5712 hook_probe (v, master_process_crash_probe, user_data);
5716 go_to_NULL_and_reconnect (gpointer user_data)
5718 GstElement *pipeline = user_data;
5719 GstStateChangeReturn ret;
5722 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
5723 FAIL_IF (ret == GST_STATE_CHANGE_FAILURE);
5725 /* reconnect to to master process */
5726 src = gst_bin_get_by_name (GST_BIN (pipeline), "ipcpipelinesrc0");
5728 g_object_set (src, "fdin", pipesfa[0], "fdout", pipesba[1], NULL);
5729 gst_object_unref (src);
5731 gst_object_unref (pipeline);
5732 return G_SOURCE_REMOVE;
5736 master_process_crash_bus_msg (GstBus * bus, GstMessage * message,
5739 test_data *td = user_data;
5740 master_process_crash_slave_data *d = td->sd;
5743 switch (GST_MESSAGE_TYPE (message)) {
5744 case GST_MESSAGE_ERROR:
5745 if (!d->got_error) {
5746 it = gst_bin_iterate_sources (GST_BIN (td->p));
5747 while (gst_iterator_foreach (it, disconnect, NULL))
5748 gst_iterator_resync (it);
5749 gst_iterator_free (it);
5750 g_timeout_add (10, (GSourceFunc) go_to_NULL_and_reconnect,
5751 gst_object_ref (td->p));
5752 d->got_error = TRUE;
5762 setup_sink_master_process_crash (GstElement * sink, gpointer user_data)
5766 it = gst_bin_iterate_sinks (GST_BIN (sink));
5767 while (gst_iterator_foreach (it, hook_master_process_crash_probe, user_data))
5768 gst_iterator_resync (it);
5769 gst_iterator_free (it);
5771 gst_bus_add_watch (GST_ELEMENT_BUS (sink), master_process_crash_bus_msg,
5776 check_success_source_master_process_crash (gpointer user_data)
5778 test_data *td = user_data;
5779 master_process_crash_master_data *d = td->md;
5781 FAIL_UNLESS (d->got_state_changed_to_playing);
5785 check_success_sink_master_process_crash (gpointer user_data)
5787 test_data *td = user_data;
5788 master_process_crash_slave_data *d = td->sd;
5790 FAIL_UNLESS (d->got_error);
5791 FAIL_UNLESS (d->got_eos);
5794 GST_START_TEST (test_wavparse_master_process_crash)
5796 master_process_crash_master_data md = { 0 };
5797 master_process_crash_slave_data sd = { 0 };
5799 TEST_BASE (TEST_FEATURE_WAV_SOURCE | TEST_FEATURE_RECOVERY_MASTER_PROCESS,
5800 master_process_crash_source, setup_sink_master_process_crash,
5801 check_success_source_master_process_crash,
5802 check_success_sink_master_process_crash, NULL, &md, &sd);
5808 ipcpipeline_suite (void)
5810 Suite *s = suite_create ("ipcpipeline");
5811 TCase *tc_chain = tcase_create ("general");
5815 suite_add_tcase (s, tc_chain);
5816 tcase_set_timeout (tc_chain, 180);
5818 /* play_pause tests put the pipeline in PLAYING state, then in
5819 PAUSED state, then in PLAYING state again. The sink expects
5820 async-done messages or state change successes. */
5822 tcase_add_test (tc_chain, test_empty_play_pause);
5823 tcase_add_test (tc_chain, test_wavparse_play_pause);
5824 tcase_add_test (tc_chain, test_mpegts_play_pause);
5825 tcase_add_test (tc_chain, test_mpegts_2_play_pause);
5826 tcase_add_test (tc_chain, test_live_a_play_pause);
5827 tcase_add_test (tc_chain, test_live_av_play_pause);
5828 tcase_add_test (tc_chain, test_live_av_2_play_pause);
5831 /* flushing_seek tests perform a flushing seek in PLAYING
5832 state. The sinks check a buffer with the target timestamp
5833 is received after the seek. */
5835 tcase_add_test (tc_chain, test_empty_flushing_seek);
5836 tcase_add_test (tc_chain, test_wavparse_flushing_seek);
5837 tcase_add_test (tc_chain, test_mpegts_flushing_seek);
5838 tcase_add_test (tc_chain, test_mpegts_2_flushing_seek);
5839 tcase_add_test (tc_chain, test_live_a_flushing_seek);
5840 tcase_add_test (tc_chain, test_live_av_flushing_seek);
5841 tcase_add_test (tc_chain, test_live_av_2_flushing_seek);
5844 /* flushing_seek_in_pause tests perform a flushing seek in
5845 PAUSED state. These are disabled for live pipelines since
5846 those will not generate data in PAUSED, so we won't get
5849 tcase_add_test (tc_chain, test_empty_flushing_seek_in_pause);
5850 tcase_add_test (tc_chain, test_wavparse_flushing_seek_in_pause);
5851 tcase_add_test (tc_chain, test_mpegts_flushing_seek_in_pause);
5852 tcase_add_test (tc_chain, test_mpegts_2_flushing_seek_in_pause);
5853 /* live scenarios skipped: live sources do not generate buffers
5857 /* segment_seek tests perform a segment seek in PLAYING
5858 state. The sinks check a buffer with the target timestamp
5859 is received after the seek, and that a SEGMENT_DONE is
5860 received at the end of the segment. */
5862 tcase_add_test (tc_chain, test_empty_segment_seek);
5863 tcase_add_test (tc_chain, test_wavparse_segment_seek);
5864 /* mpegts skipped: tsdemux does not support segment seeks */
5865 tcase_add_test (tc_chain, test_live_a_segment_seek);
5866 tcase_add_test (tc_chain, test_live_av_segment_seek);
5867 tcase_add_test (tc_chain, test_live_av_2_segment_seek);
5870 /* seek_stress tests perform stress testing on seeks, then waits
5871 in PLAYING for EOS or segment-done. */
5873 tcase_add_test (tc_chain, test_empty_seek_stress);
5874 tcase_add_test (tc_chain, test_wavparse_seek_stress);
5875 tcase_add_test (tc_chain, test_mpegts_seek_stress);
5876 tcase_add_test (tc_chain, test_mpegts_2_seek_stress);
5877 tcase_add_test (tc_chain, test_live_a_seek_stress);
5878 tcase_add_test (tc_chain, test_live_av_seek_stress);
5879 tcase_add_test (tc_chain, test_live_av_2_seek_stress);
5882 /* upstream_query tests send position and duration queries, and
5883 checks the results are as expected. */
5885 tcase_add_test (tc_chain, test_empty_upstream_query);
5886 tcase_add_test (tc_chain, test_wavparse_upstream_query);
5887 tcase_add_test (tc_chain, test_mpegts_upstream_query);
5888 tcase_add_test (tc_chain, test_mpegts_2_upstream_query);
5889 tcase_add_test (tc_chain, test_live_a_upstream_query);
5890 tcase_add_test (tc_chain, test_live_av_upstream_query);
5891 tcase_add_test (tc_chain, test_live_av_2_upstream_query);
5894 /* message tests send a sink message downstream, which causes
5895 the sinks to reply with the embedded event, which is checked.
5896 This is not possible when elements go into pull mode. */
5898 tcase_add_test (tc_chain, test_empty_message);
5899 tcase_add_test (tc_chain, test_wavparse_message);
5900 /* mpegts skipped because it goes into pull mode:
5901 https://bugzilla.gnome.org/show_bug.cgi?id=751637 */
5902 tcase_add_test (tc_chain, test_live_a_message);
5903 tcase_add_test (tc_chain, test_live_av_message);
5904 tcase_add_test (tc_chain, test_live_av_2_message);
5907 /* end_of_stream tests check the EOS event and message are
5908 properly received when the stream reaches its end. */
5910 tcase_add_test (tc_chain, test_empty_end_of_stream);
5911 tcase_add_test (tc_chain, test_wavparse_end_of_stream);
5912 tcase_add_test (tc_chain, test_mpegts_end_of_stream);
5913 tcase_add_test (tc_chain, test_mpegts_2_end_of_stream);
5914 tcase_add_test (tc_chain, test_live_a_end_of_stream);
5915 tcase_add_test (tc_chain, test_live_av_end_of_stream);
5916 tcase_add_test (tc_chain, test_live_av_2_end_of_stream);
5919 /* reverse_playback tests issue a seek with negative rate,
5920 and check buffers timestamp are in decreasing order.
5921 This does not work with sources which do not support
5922 negative playback rate (live ones, and some demuxers). */
5924 /* wavparse and tsdemux does not support backward playback */
5925 tcase_add_test (tc_chain, test_a_reverse_playback);
5926 tcase_add_test (tc_chain, test_av_reverse_playback);
5927 tcase_add_test (tc_chain, test_av_2_reverse_playback);
5930 /* tags tests check tags are carried to the slave. */
5932 tcase_add_test (tc_chain, test_empty_tags);
5933 tcase_add_test (tc_chain, test_wavparse_tags);
5934 tcase_add_test (tc_chain, test_mpegts_tags);
5935 tcase_add_test (tc_chain, test_mpegts_2_tags);
5936 tcase_add_test (tc_chain, test_live_a_tags);
5937 tcase_add_test (tc_chain, test_live_av_tags);
5938 tcase_add_test (tc_chain, test_live_av_2_tags);
5941 /* reconfigure tests that pipeline reconfiguration via
5942 the reconfigure event works */
5944 tcase_add_test (tc_chain, test_non_live_a_reconfigure);
5945 tcase_add_test (tc_chain, test_non_live_av_reconfigure);
5946 tcase_add_test (tc_chain, test_live_a_reconfigure);
5947 tcase_add_test (tc_chain, test_live_av_reconfigure);
5950 /* state_change tests issue a number of state changes in
5951 (hopefully) all interesting configurations, and checks
5952 the state changes occurred on the slave pipeline. The links
5953 are disconnected and reconnected to check it all still
5954 works after this. */
5956 tcase_add_test (tc_chain, test_empty_state_changes);
5957 tcase_add_test (tc_chain, test_wavparse_state_changes);
5958 tcase_add_test (tc_chain, test_mpegts_state_changes);
5959 tcase_add_test (tc_chain, test_mpegts_2_state_changes);
5960 /* live scenarios skipped: live sources will cause no buffer
5961 * to flow in PAUSED, so the pipeline will only finish READY->PAUSED
5962 * once switching to PLAYING */
5965 /* state_changes_stress tests change state randomly and rapidly. */
5967 tcase_add_test (tc_chain, test_empty_state_changes_stress);
5968 tcase_add_test (tc_chain, test_wavparse_state_changes_stress);
5969 tcase_add_test (tc_chain, test_mpegts_state_changes_stress);
5970 tcase_add_test (tc_chain, test_mpegts_2_state_changes_stress);
5971 tcase_add_test (tc_chain, test_live_a_state_changes_stress);
5972 tcase_add_test (tc_chain, test_live_av_state_changes_stress);
5973 tcase_add_test (tc_chain, test_live_av_2_state_changes_stress);
5976 /* serialized_query tests checks that a serialized query is
5977 handled by the slave pipeline. */
5979 tcase_add_test (tc_chain, test_empty_serialized_query);
5980 tcase_add_test (tc_chain, test_wavparse_serialized_query);
5981 tcase_add_test (tc_chain, test_mpegts_serialized_query);
5982 tcase_add_test (tc_chain, test_mpegts_2_serialized_query);
5983 tcase_add_test (tc_chain, test_live_a_serialized_query);
5984 tcase_add_test (tc_chain, test_live_av_serialized_query);
5985 tcase_add_test (tc_chain, test_live_av_2_serialized_query);
5988 /* non_serialized_event tests checks that a non serialized event
5989 is handled by the slave pipeline. */
5991 tcase_add_test (tc_chain, test_empty_non_serialized_event);
5992 tcase_add_test (tc_chain, test_wavparse_non_serialized_event);
5993 tcase_add_test (tc_chain, test_mpegts_non_serialized_event);
5994 tcase_add_test (tc_chain, test_mpegts_2_non_serialized_event);
5995 tcase_add_test (tc_chain, test_live_a_non_serialized_event);
5996 tcase_add_test (tc_chain, test_live_av_non_serialized_event);
5997 tcase_add_test (tc_chain, test_live_av_2_non_serialized_event);
6000 /* meta tests checks that GstMeta on buffers are correctly
6001 received by the slave pipeline. */
6003 tcase_add_test (tc_chain, test_empty_meta);
6004 tcase_add_test (tc_chain, test_wavparse_meta);
6005 tcase_add_test (tc_chain, test_mpegts_meta);
6006 tcase_add_test (tc_chain, test_mpegts_2_meta);
6007 tcase_add_test (tc_chain, test_live_a_meta);
6008 tcase_add_test (tc_chain, test_live_av_meta);
6009 tcase_add_test (tc_chain, test_live_av_2_meta);
6012 /* source_change tests checks that the pipelines can handle a
6013 change of source/caps. */
6015 tcase_add_test (tc_chain, test_non_live_source_change);
6016 tcase_add_test (tc_chain, test_live_av_source_change);
6017 tcase_add_test (tc_chain, test_live_av_2_source_change);
6020 /* navigation tests checks that navigation events from the slave
6021 are received by the master. */
6023 tcase_add_test (tc_chain, test_non_live_av_navigation);
6024 tcase_add_test (tc_chain, test_non_live_av_2_navigation);
6025 tcase_add_test (tc_chain, test_live_av_navigation);
6026 tcase_add_test (tc_chain, test_live_av_2_navigation);
6029 /* dynamic_pipeline_change_stress tests stress tests dynamic
6030 pipeline changes. */
6032 tcase_add_test (tc_chain, test_non_live_av_dynamic_pipeline_change_stress);
6033 tcase_add_test (tc_chain,
6034 test_non_live_av_2_dynamic_pipeline_change_stress);
6035 tcase_add_test (tc_chain, test_live_av_dynamic_pipeline_change_stress);
6036 tcase_add_test (tc_chain, test_live_av_2_dynamic_pipeline_change_stress);
6039 /* error_from_slave tests checks an error message issued
6040 by the slave pipeline is received by the master pipeline. */
6042 tcase_add_test (tc_chain, test_empty_error_from_slave);
6043 tcase_add_test (tc_chain, test_wavparse_error_from_slave);
6044 tcase_add_test (tc_chain, test_mpegts_error_from_slave);
6045 tcase_add_test (tc_chain, test_mpegts_2_error_from_slave);
6046 tcase_add_test (tc_chain, test_live_a_error_from_slave);
6047 tcase_add_test (tc_chain, test_live_av_error_from_slave);
6048 tcase_add_test (tc_chain, test_live_av_2_error_from_slave);
6051 /* slave_process_crash tests test that a crash of the slave
6052 process can be recovered from by the master, which can
6053 replace the slave process and continue. */
6054 tcase_add_test (tc_chain, test_wavparse_slave_process_crash);
6056 /* master_process_crash tests test that a crash of the master
6057 process can be recovered from by the slave. I don't recall
6058 how the recovery from that works, but it does! A watchdog
6059 process replaces the master process, and the slave will
6060 go to NULL and reconnect after it gets a timeout talking
6061 with the master pipeline. */
6062 tcase_add_test (tc_chain, test_wavparse_master_process_crash);
6067 GST_CHECK_MAIN (ipcpipeline);