And correct even more valid sparse warnings.
[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 void
31 handoff (GstElement * fakesink, GstBuffer * buf, GstPad * pad, guint * count)
32 {
33   *count = *count + 1;
34 }
35
36 /* construct fakesrc num-buffers=3 ! tee name=t ! queue ! fakesink t. ! queue !
37  * fakesink. Each fakesink should exactly receive 3 buffers.
38  */
39 GST_START_TEST (test_num_buffers)
40 {
41 #define NUM_SUBSTREAMS 15
42 #define NUM_BUFFERS 3
43   GstElement *pipeline, *src, *tee;
44   GstElement *queues[NUM_SUBSTREAMS];
45   GstElement *sinks[NUM_SUBSTREAMS];
46   GstPad *req_pads[NUM_SUBSTREAMS];
47   guint counts[NUM_SUBSTREAMS];
48   GstBus *bus;
49   GstMessage *msg;
50   gint i;
51
52   pipeline = gst_pipeline_new ("pipeline");
53   src = gst_check_setup_element ("fakesrc");
54   g_object_set (src, "num-buffers", NUM_BUFFERS, NULL);
55   tee = gst_check_setup_element ("tee");
56   fail_unless (gst_bin_add (GST_BIN (pipeline), src));
57   fail_unless (gst_bin_add (GST_BIN (pipeline), tee));
58   fail_unless (gst_element_link (src, tee));
59
60   for (i = 0; i < NUM_SUBSTREAMS; ++i) {
61     GstPad *qpad;
62     gchar name[32];
63
64     counts[i] = 0;
65
66     queues[i] = gst_check_setup_element ("queue");
67     g_snprintf (name, 32, "queue%d", i);
68     gst_object_set_name (GST_OBJECT (queues[i]), name);
69     fail_unless (gst_bin_add (GST_BIN (pipeline), queues[i]));
70
71     sinks[i] = gst_check_setup_element ("fakesink");
72     g_snprintf (name, 32, "sink%d", i);
73     gst_object_set_name (GST_OBJECT (sinks[i]), name);
74     fail_unless (gst_bin_add (GST_BIN (pipeline), sinks[i]));
75     fail_unless (gst_element_link (queues[i], sinks[i]));
76     g_object_set (sinks[i], "signal-handoffs", TRUE, NULL);
77     g_signal_connect (sinks[i], "handoff", (GCallback) handoff, &counts[i]);
78
79     req_pads[i] = gst_element_get_request_pad (tee, "src%d");
80     fail_unless (req_pads[i] != NULL);
81
82     qpad = gst_element_get_pad (queues[i], "sink");
83     fail_unless_equals_int (gst_pad_link (req_pads[i], qpad), GST_PAD_LINK_OK);
84     gst_object_unref (qpad);
85   }
86
87   bus = gst_element_get_bus (pipeline);
88   fail_if (bus == NULL);
89   gst_element_set_state (pipeline, GST_STATE_PLAYING);
90
91   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
92   fail_if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_EOS);
93   gst_message_unref (msg);
94
95   for (i = 0; i < NUM_SUBSTREAMS; ++i) {
96     fail_unless_equals_int (counts[i], NUM_BUFFERS);
97   }
98
99   gst_element_set_state (pipeline, GST_STATE_NULL);
100   gst_object_unref (bus);
101
102   for (i = 0; i < NUM_SUBSTREAMS; ++i) {
103     gst_element_release_request_pad (tee, req_pads[i]);
104     gst_object_unref (req_pads[i]);
105   }
106   gst_object_unref (pipeline);
107 }
108
109 GST_END_TEST;
110
111 /* we use fakesrc ! tee ! fakesink and then randomly request/release and link
112  * some pads from tee. This should happily run without any errors. */
113 GST_START_TEST (test_stress)
114 {
115   GstElement *pipeline;
116   GstElement *tee;
117   gchar *desc;
118   GstBus *bus;
119   GstMessage *msg;
120   gint i;
121
122   /* Pump 1000 buffers (10 bytes each) per second through tee for 5 secs */
123   desc = "fakesrc datarate=10000 sizemin=10 sizemax=10 num-buffers=5000 ! "
124       "video/x-raw-rgb,framerate=25/1 ! tee name=t ! "
125       "queue max-size-buffers=2 ! fakesink sync=true";
126
127   pipeline = gst_parse_launch (desc, NULL);
128   fail_if (pipeline == NULL);
129
130   tee = gst_bin_get_by_name (GST_BIN (pipeline), "t");
131   fail_if (tee == NULL);
132
133   /* bring the pipeline to PLAYING, then start switching */
134   bus = gst_element_get_bus (pipeline);
135   fail_if (bus == NULL);
136   gst_element_set_state (pipeline, GST_STATE_PLAYING);
137   /* Wait for the pipeline to hit playing so that parse_launch can do the
138    * initial link, otherwise we perform linking from multiple threads and cause
139    * trouble */
140   gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
141
142   for (i = 0; i < 50000; i++) {
143     GstPad *pad;
144
145     pad = gst_element_get_request_pad (tee, "src%d");
146     gst_element_release_request_pad (tee, pad);
147     gst_object_unref (pad);
148
149     if ((msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, 0)))
150       break;
151   }
152
153   /* now wait for completion or error */
154   if (msg == NULL)
155     msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
156   fail_if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_EOS);
157   gst_message_unref (msg);
158
159   gst_element_set_state (pipeline, GST_STATE_NULL);
160   gst_object_unref (tee);
161   gst_object_unref (bus);
162   gst_object_unref (pipeline);
163 }
164
165 GST_END_TEST;
166
167 static Suite *
168 tee_suite (void)
169 {
170   Suite *s = suite_create ("tee");
171   TCase *tc_chain = tcase_create ("general");
172
173   suite_add_tcase (s, tc_chain);
174   tcase_add_test (tc_chain, test_num_buffers);
175   tcase_add_test (tc_chain, test_stress);
176
177   return s;
178 }
179
180 GST_CHECK_MAIN (tee);