tests/check/elements/tee.c: Make the tee stress-test a little less stressful so it...
[platform/upstream/gstreamer.git] / tests / check / elements / tee.c
1 /* GStreamer
2  *
3  * unit test for tee
4  *
5  * Copyright (C) <2007> Wim Taymans <wim dot taymans at gmail dot com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27
28 #include <gst/check/gstcheck.h>
29
30 static gint count1;
31 static gint count2;
32
33 static void
34 handoff (GstElement * fakesink, GstBuffer * buf, GstPad * pad, guint * count)
35 {
36   *count = *count + 1;
37 }
38
39 /* construct fakesrc num-buffers=3 ! tee name=t ! queue ! fakesink t. ! queue !
40  * fakesink. Each fakesink should exactly receive 3 buffers.
41  */
42 GST_START_TEST (test_num_buffers)
43 {
44   GstElement *pipeline;
45   GstElement *f1, *f2;
46   gchar *desc;
47   GstBus *bus;
48   GstMessage *msg;
49
50   desc = "fakesrc num-buffers=3 ! tee name=t ! queue ! fakesink name=f1 "
51       "t. ! queue ! fakesink name=f2";
52   pipeline = gst_parse_launch (desc, NULL);
53   fail_if (pipeline == NULL);
54
55   f1 = gst_bin_get_by_name (GST_BIN (pipeline), "f1");
56   fail_if (f1 == NULL);
57   f2 = gst_bin_get_by_name (GST_BIN (pipeline), "f2");
58   fail_if (f2 == NULL);
59
60   count1 = 0;
61   count2 = 0;
62
63   g_object_set (G_OBJECT (f1), "signal-handoffs", TRUE, NULL);
64   g_signal_connect (G_OBJECT (f1), "handoff", (GCallback) handoff, &count1);
65   g_object_set (G_OBJECT (f2), "signal-handoffs", TRUE, NULL);
66   g_signal_connect (G_OBJECT (f2), "handoff", (GCallback) handoff, &count2);
67
68   bus = gst_element_get_bus (pipeline);
69   fail_if (bus == NULL);
70   gst_element_set_state (pipeline, GST_STATE_PLAYING);
71
72   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
73   fail_if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_EOS);
74   gst_message_unref (msg);
75
76   fail_if (count1 != 3);
77   fail_if (count2 != 3);
78
79   gst_element_set_state (pipeline, GST_STATE_NULL);
80   gst_object_unref (f1);
81   gst_object_unref (f2);
82   gst_object_unref (bus);
83   gst_object_unref (pipeline);
84 }
85
86 GST_END_TEST;
87
88 /* we use fakesrc ! tee ! fakesink and then randomly request/release and link
89  * some pads from tee. This should happily run without any errors. */
90 GST_START_TEST (test_stress)
91 {
92   GstElement *pipeline;
93   GstElement *tee;
94   gchar *desc;
95   GstBus *bus;
96   GstMessage *msg;
97   gint i;
98
99   /* Pump 1000 buffers (10 bytes each) per second through tee for 5 secs */
100   desc = "fakesrc datarate=10000 sizemin=10 sizemax=10 num-buffers=5000 ! "
101       "video/x-raw-rgb,framerate=25/1 ! tee name=t ! "
102       "queue max-size-buffers=2 ! fakesink sync=true";
103
104   pipeline = gst_parse_launch (desc, NULL);
105   fail_if (pipeline == NULL);
106
107   tee = gst_bin_get_by_name (GST_BIN (pipeline), "t");
108   fail_if (tee == NULL);
109
110   /* bring the pipeline to PLAYING, then start switching */
111   bus = gst_element_get_bus (pipeline);
112   fail_if (bus == NULL);
113   gst_element_set_state (pipeline, GST_STATE_PLAYING);
114   /* Wait for the pipeline to hit playing so that parse_launch can do the
115    * initial link, otherwise we perform linking from multiple threads and cause
116    * trouble */
117   gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
118
119   for (i = 0; i < 50000; i++) {
120     GstPad *pad;
121
122     pad = gst_element_get_request_pad (tee, "src%d");
123     gst_element_release_request_pad (tee, pad);
124     gst_object_unref (pad);
125
126     if ((msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, 0)))
127       break;
128   }
129
130   /* now wait for completion or error */
131   if (msg == NULL)
132     msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
133   fail_if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_EOS);
134   gst_message_unref (msg);
135
136   gst_element_set_state (pipeline, GST_STATE_NULL);
137   gst_object_unref (tee);
138   gst_object_unref (bus);
139   gst_object_unref (pipeline);
140 }
141
142 GST_END_TEST;
143
144 Suite *
145 tee_suite (void)
146 {
147   Suite *s = suite_create ("tee");
148   TCase *tc_chain = tcase_create ("general");
149
150   suite_add_tcase (s, tc_chain);
151   tcase_add_test (tc_chain, test_num_buffers);
152   tcase_add_test (tc_chain, test_stress);
153
154   return s;
155 }
156
157 GST_CHECK_MAIN (tee);