1 /* GStreamer UDP source unit tests
2 * Copyright (C) 2011 Tim-Philipp Müller <tim centricular net>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19 #include <gst/check/gstcheck.h>
20 #include <gio/gio.h>
21 #include <stdlib.h>
22
23 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
24 GST_PAD_SINK,
25 GST_PAD_ALWAYS,
26 GST_STATIC_CAPS_ANY);
27
28 static gboolean
udpsrc_setup(GstElement ** udpsrc,GSocket ** socket,GstPad ** sinkpad,GSocketAddress ** sa)29 udpsrc_setup (GstElement ** udpsrc, GSocket ** socket,
30 GstPad ** sinkpad, GSocketAddress ** sa)
31 {
32 GInetAddress *ia;
33 int port = 0;
34 gchar *s;
35
36 *udpsrc = gst_check_setup_element ("udpsrc");
37 fail_unless (*udpsrc != NULL);
38 g_object_set (*udpsrc, "port", 0, NULL);
39
40 *sinkpad = gst_check_setup_sink_pad_by_name (*udpsrc, &sinktemplate, "src");
41 fail_unless (*sinkpad != NULL);
42 gst_pad_set_active (*sinkpad, TRUE);
43
44 gst_element_set_state (*udpsrc, GST_STATE_PLAYING);
45 g_object_get (*udpsrc, "port", &port, NULL);
46 GST_INFO ("udpsrc port = %d", port);
47
48 *socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
49 G_SOCKET_PROTOCOL_UDP, NULL);
50
51 if (*socket == NULL) {
52 GST_WARNING ("Could not create IPv4 UDP socket for unit test");
53 return FALSE;
54 }
55
56 ia = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
57 s = g_inet_address_to_string (ia);
58 GST_LOG ("inet address %s", s);
59 g_free (s);
60 *sa = g_inet_socket_address_new (ia, port);
61 g_object_unref (ia);
62
63 return TRUE;
64 }
65
GST_START_TEST(test_udpsrc_empty_packet)66 GST_START_TEST (test_udpsrc_empty_packet)
67 {
68 GSocketAddress *sa = NULL;
69 GstElement *udpsrc = NULL;
70 GSocket *socket = NULL;
71 GstPad *sinkpad = NULL;
72
73 if (!udpsrc_setup (&udpsrc, &socket, &sinkpad, &sa))
74 goto no_socket;
75
76 if (g_socket_send_to (socket, sa, "HeLL0", 0, NULL, NULL) == 0) {
77 GST_INFO ("sent 0 bytes");
78 if (g_socket_send_to (socket, sa, "HeLL0", 6, NULL, NULL) == 6) {
79 GstMapInfo map;
80 GstBuffer *buf;
81 guint len = 0;
82
83 GST_INFO ("sent 6 bytes");
84
85 g_mutex_lock (&check_mutex);
86 len = g_list_length (buffers);
87 while (len < 1) {
88 g_cond_wait (&check_cond, &check_mutex);
89 len = g_list_length (buffers);
90 GST_INFO ("%u buffers", len);
91 }
92
93 /* wait a bit more for a second buffer */
94 if (len < 2) {
95 g_cond_wait_until (&check_cond, &check_mutex,
96 g_get_monotonic_time () + G_TIME_SPAN_SECOND / 100);
97
98 len = g_list_length (buffers);
99 GST_INFO ("%u buffers", len);
100 }
101
102 fail_unless (len == 1 || len == 2);
103
104 /* last buffer should be our HeLL0 string */
105 buf = GST_BUFFER (g_list_nth_data (buffers, len - 1));
106 gst_buffer_map (buf, &map, GST_MAP_READ);
107 fail_unless_equals_int (map.size, 6);
108 fail_unless_equals_string ((gchar *) map.data, "HeLL0");
109 gst_buffer_unmap (buf, &map);
110
111 /* if there's another buffer, it should be 0 bytes */
112 if (len == 2) {
113 buf = GST_BUFFER (g_list_nth_data (buffers, 0));
114 fail_unless_equals_int (gst_buffer_get_size (buf), 0);
115 }
116 g_mutex_unlock (&check_mutex);
117 } else {
118 GST_WARNING ("send_to(6 bytes) failed");
119 }
120 } else {
121 GST_WARNING ("send_to(0 bytes) failed");
122 }
123
124 no_socket:
125
126 gst_element_set_state (udpsrc, GST_STATE_NULL);
127
128 gst_check_drop_buffers ();
129 gst_check_teardown_pad_by_name (udpsrc, "src");
130 gst_check_teardown_element (udpsrc);
131
132 g_object_unref (socket);
133 g_object_unref (sa);
134 }
135
136 GST_END_TEST;
137
GST_START_TEST(test_udpsrc)138 GST_START_TEST (test_udpsrc)
139 {
140 GSocketAddress *sa = NULL;
141 GstElement *udpsrc = NULL;
142 GSocket *socket = NULL;
143 GstPad *sinkpad = NULL;
144 GstBuffer *buf;
145 GstMemory *mem;
146 gchar data[48000];
147 gsize max_size;
148 int i, len = 0;
149 gssize sent;
150 GError *err = NULL;
151
152 for (i = 0; i < G_N_ELEMENTS (data); ++i)
153 data[i] = i & 0xff;
154
155 if (!udpsrc_setup (&udpsrc, &socket, &sinkpad, &sa))
156 goto no_socket;
157
158 if ((sent = g_socket_send_to (socket, sa, data, 48000, NULL, &err)) == -1)
159 goto send_failure;
160 fail_unless_equals_int (sent, 48000);
161
162 if ((sent = g_socket_send_to (socket, sa, data, 21000, NULL, &err)) == -1)
163 goto send_failure;
164 fail_unless_equals_int (sent, 21000);
165
166 if ((sent = g_socket_send_to (socket, sa, data, 500, NULL, &err)) == -1)
167 goto send_failure;
168 fail_unless_equals_int (sent, 500);
169
170 if ((sent = g_socket_send_to (socket, sa, data, 1600, NULL, &err)) == -1)
171 goto send_failure;
172 fail_unless_equals_int (sent, 1600);
173
174 if ((sent = g_socket_send_to (socket, sa, data, 1400, NULL, &err)) == -1)
175 goto send_failure;
176 fail_unless_equals_int (sent, 1400);
177
178 GST_INFO ("sent some packets");
179
180 g_mutex_lock (&check_mutex);
181 len = g_list_length (buffers);
182 while (len < 5) {
183 g_cond_wait (&check_cond, &check_mutex);
184 len = g_list_length (buffers);
185 GST_INFO ("%u buffers", len);
186 }
187
188 /* check that large packets are made up of multiple memory chunks and that
189 * the first one is fairly small */
190 buf = GST_BUFFER (g_list_nth_data (buffers, 0));
191 fail_unless_equals_int (gst_buffer_get_size (buf), 48000);
192 fail_unless_equals_int (gst_buffer_n_memory (buf), 2);
193 mem = gst_buffer_peek_memory (buf, 0);
194 gst_memory_get_sizes (mem, NULL, &max_size);
195 fail_unless (max_size <= 2000);
196
197 buf = GST_BUFFER (g_list_nth_data (buffers, 1));
198 fail_unless_equals_int (gst_buffer_get_size (buf), 21000);
199 fail_unless_equals_int (gst_buffer_n_memory (buf), 2);
200 mem = gst_buffer_peek_memory (buf, 0);
201 gst_memory_get_sizes (mem, NULL, &max_size);
202 fail_unless (max_size <= 2000);
203
204 buf = GST_BUFFER (g_list_nth_data (buffers, 2));
205 fail_unless_equals_int (gst_buffer_get_size (buf), 500);
206 fail_unless_equals_int (gst_buffer_n_memory (buf), 1);
207 mem = gst_buffer_peek_memory (buf, 0);
208 gst_memory_get_sizes (mem, NULL, &max_size);
209 fail_unless (max_size <= 2000);
210
211 buf = GST_BUFFER (g_list_nth_data (buffers, 3));
212 fail_unless_equals_int (gst_buffer_get_size (buf), 1600);
213 fail_unless_equals_int (gst_buffer_n_memory (buf), 2);
214 mem = gst_buffer_peek_memory (buf, 0);
215 gst_memory_get_sizes (mem, NULL, &max_size);
216 fail_unless (max_size <= 2000);
217
218 buf = GST_BUFFER (g_list_nth_data (buffers, 4));
219 fail_unless_equals_int (gst_buffer_get_size (buf), 1400);
220 fail_unless_equals_int (gst_buffer_n_memory (buf), 1);
221 mem = gst_buffer_peek_memory (buf, 0);
222 gst_memory_get_sizes (mem, NULL, &max_size);
223 fail_unless (max_size <= 2000);
224
225 g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
226 g_list_free (buffers);
227 buffers = NULL;
228
229 g_mutex_unlock (&check_mutex);
230
231 no_socket:
232 send_failure:
233 if (err) {
234 GST_WARNING ("Socket send error, skipping test: %s", err->message);
235 g_clear_error (&err);
236 }
237
238 gst_element_set_state (udpsrc, GST_STATE_NULL);
239
240 gst_check_drop_buffers ();
241 gst_check_teardown_pad_by_name (udpsrc, "src");
242 gst_check_teardown_element (udpsrc);
243
244 g_object_unref (socket);
245 g_object_unref (sa);
246 }
247
248 GST_END_TEST;
249
250 static Suite *
udpsrc_suite(void)251 udpsrc_suite (void)
252 {
253 Suite *s = suite_create ("udpsrc");
254 TCase *tc_chain = tcase_create ("udpsrc");
255
256 suite_add_tcase (s, tc_chain);
257 tcase_add_test (tc_chain, test_udpsrc_empty_packet);
258 tcase_add_test (tc_chain, test_udpsrc);
259 return s;
260 }
261
262 GST_CHECK_MAIN (udpsrc)
263