1 /* GStreamer
2 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
3 * Copyright (C) <2006> Tim-Philipp Müller <tim centricular net>
4 *
5 * gstutils.c: Unit test for functions in gstutils
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., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gst/check/gstcheck.h>
28
29 #define SPECIAL_POINTER(x) ((void*)(19283847+(x)))
30
31 static int n_data_probes = 0;
32 static int n_buffer_probes = 0;
33 static int n_event_probes = 0;
34
35 static GstPadProbeReturn
probe_do_nothing(GstPad * pad,GstPadProbeInfo * info,gpointer data)36 probe_do_nothing (GstPad * pad, GstPadProbeInfo * info, gpointer data)
37 {
38 GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);
39 GST_DEBUG_OBJECT (pad, "is buffer:%d", GST_IS_BUFFER (obj));
40 return GST_PAD_PROBE_OK;
41 }
42
43 static GstPadProbeReturn
data_probe(GstPad * pad,GstPadProbeInfo * info,gpointer data)44 data_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
45 {
46 GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);
47 n_data_probes++;
48 GST_DEBUG_OBJECT (pad, "data probe %d", n_data_probes);
49 g_assert (GST_IS_BUFFER (obj) || GST_IS_EVENT (obj));
50 g_assert (data == SPECIAL_POINTER (0));
51 return GST_PAD_PROBE_OK;
52 }
53
54 static GstPadProbeReturn
buffer_probe(GstPad * pad,GstPadProbeInfo * info,gpointer data)55 buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
56 {
57 GstBuffer *obj = GST_PAD_PROBE_INFO_BUFFER (info);
58 n_buffer_probes++;
59 GST_DEBUG_OBJECT (pad, "buffer probe %d", n_buffer_probes);
60 g_assert (GST_IS_BUFFER (obj));
61 g_assert (data == SPECIAL_POINTER (1));
62 return GST_PAD_PROBE_OK;
63 }
64
65 static GstPadProbeReturn
event_probe(GstPad * pad,GstPadProbeInfo * info,gpointer data)66 event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
67 {
68 GstEvent *obj = GST_PAD_PROBE_INFO_EVENT (info);
69 n_event_probes++;
70 GST_DEBUG_OBJECT (pad, "event probe %d [%s]",
71 n_event_probes, GST_EVENT_TYPE_NAME (obj));
72 g_assert (GST_IS_EVENT (obj));
73 g_assert (data == SPECIAL_POINTER (2));
74 return GST_PAD_PROBE_OK;
75 }
76
GST_START_TEST(test_buffer_probe_n_times)77 GST_START_TEST (test_buffer_probe_n_times)
78 {
79 GstElement *pipeline, *fakesrc, *fakesink;
80 GstBus *bus;
81 GstMessage *message;
82 GstPad *pad;
83
84 pipeline = gst_element_factory_make ("pipeline", NULL);
85 fakesrc = gst_element_factory_make ("fakesrc", NULL);
86 fakesink = gst_element_factory_make ("fakesink", NULL);
87
88 g_object_set (fakesrc, "num-buffers", (int) 10, NULL);
89
90 gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
91 gst_element_link (fakesrc, fakesink);
92
93 pad = gst_element_get_static_pad (fakesink, "sink");
94
95 /* add the probes we need for the test */
96 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_BOTH, data_probe,
97 SPECIAL_POINTER (0), NULL);
98 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe,
99 SPECIAL_POINTER (1), NULL);
100 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_BOTH, event_probe,
101 SPECIAL_POINTER (2), NULL);
102
103 /* add some string probes just to test that the data is free'd
104 * properly as it should be */
105 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_BOTH, probe_do_nothing,
106 g_strdup ("data probe string"), (GDestroyNotify) g_free);
107 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, probe_do_nothing,
108 g_strdup ("buffer probe string"), (GDestroyNotify) g_free);
109 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_BOTH, probe_do_nothing,
110 g_strdup ("event probe string"), (GDestroyNotify) g_free);
111
112 gst_object_unref (pad);
113
114 gst_element_set_state (pipeline, GST_STATE_PLAYING);
115
116 bus = gst_element_get_bus (pipeline);
117 message = gst_bus_poll (bus, GST_MESSAGE_EOS, -1);
118 gst_message_unref (message);
119 gst_object_unref (bus);
120
121 g_assert (n_buffer_probes == 10); /* one for every buffer */
122 g_assert (n_event_probes == 4); /* stream-start, new segment, latency and eos */
123 g_assert (n_data_probes == 14); /* duh */
124
125 gst_element_set_state (pipeline, GST_STATE_NULL);
126 gst_object_unref (pipeline);
127
128 /* make sure nothing was sent in addition to the above when shutting down */
129 g_assert (n_buffer_probes == 10); /* one for every buffer */
130 g_assert (n_event_probes == 4); /* stream-start, new segment, latency and eos */
131 g_assert (n_data_probes == 14); /* duh */
132 } GST_END_TEST;
133
134 static int n_data_probes_once = 0;
135 static int n_buffer_probes_once = 0;
136 static int n_event_probes_once = 0;
137
138 static GstPadProbeReturn
data_probe_once(GstPad * pad,GstPadProbeInfo * info,guint * data)139 data_probe_once (GstPad * pad, GstPadProbeInfo * info, guint * data)
140 {
141 GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);
142
143 n_data_probes_once++;
144 g_assert (GST_IS_BUFFER (obj) || GST_IS_EVENT (obj));
145
146 gst_pad_remove_probe (pad, *data);
147
148 return GST_PAD_PROBE_OK;
149 }
150
151 static GstPadProbeReturn
buffer_probe_once(GstPad * pad,GstPadProbeInfo * info,guint * data)152 buffer_probe_once (GstPad * pad, GstPadProbeInfo * info, guint * data)
153 {
154 GstBuffer *obj = GST_PAD_PROBE_INFO_BUFFER (info);
155
156 n_buffer_probes_once++;
157 g_assert (GST_IS_BUFFER (obj));
158
159 gst_pad_remove_probe (pad, *data);
160
161 return GST_PAD_PROBE_OK;
162 }
163
164 static GstPadProbeReturn
event_probe_once(GstPad * pad,GstPadProbeInfo * info,guint * data)165 event_probe_once (GstPad * pad, GstPadProbeInfo * info, guint * data)
166 {
167 GstEvent *obj = GST_PAD_PROBE_INFO_EVENT (info);
168
169 n_event_probes_once++;
170 g_assert (GST_IS_EVENT (obj));
171
172 gst_pad_remove_probe (pad, *data);
173
174 return GST_PAD_PROBE_OK;
175 }
176
GST_START_TEST(test_buffer_probe_once)177 GST_START_TEST (test_buffer_probe_once)
178 {
179 GstElement *pipeline, *fakesrc, *fakesink;
180 GstBus *bus;
181 GstMessage *message;
182 GstPad *pad;
183 guint id1, id2, id3;
184
185 pipeline = gst_element_factory_make ("pipeline", NULL);
186 fakesrc = gst_element_factory_make ("fakesrc", NULL);
187 fakesink = gst_element_factory_make ("fakesink", NULL);
188
189 g_object_set (fakesrc, "num-buffers", (int) 10, NULL);
190
191 gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
192 gst_element_link (fakesrc, fakesink);
193
194 pad = gst_element_get_static_pad (fakesink, "sink");
195 id1 =
196 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_BOTH,
197 (GstPadProbeCallback) data_probe_once, &id1, NULL);
198 id2 =
199 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER,
200 (GstPadProbeCallback) buffer_probe_once, &id2, NULL);
201 id3 =
202 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
203 (GstPadProbeCallback) event_probe_once, &id3, NULL);
204 gst_object_unref (pad);
205
206 gst_element_set_state (pipeline, GST_STATE_PLAYING);
207
208 bus = gst_element_get_bus (pipeline);
209 message = gst_bus_poll (bus, GST_MESSAGE_EOS, -1);
210 gst_message_unref (message);
211 gst_object_unref (bus);
212
213 gst_element_set_state (pipeline, GST_STATE_NULL);
214 gst_object_unref (pipeline);
215
216 g_assert (n_buffer_probes_once == 1); /* can we hit it and quit? */
217 g_assert (n_event_probes_once == 1); /* i said, can we hit it and quit? */
218 g_assert (n_data_probes_once == 1); /* let's hit it and quit!!! */
219 } GST_END_TEST;
220
GST_START_TEST(test_math_scale)221 GST_START_TEST (test_math_scale)
222 {
223 fail_if (gst_util_uint64_scale_int (1, 1, 1) != 1);
224
225 fail_if (gst_util_uint64_scale_int (10, 10, 1) != 100);
226 fail_if (gst_util_uint64_scale_int (10, 10, 2) != 50);
227
228 fail_if (gst_util_uint64_scale_int (0, 10, 2) != 0);
229 fail_if (gst_util_uint64_scale_int (0, 0, 2) != 0);
230
231 fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 5, 1) != G_MAXUINT32 * 5LL);
232 fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 10, 2) != G_MAXUINT32 * 5LL);
233
234 fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 1, 5) != G_MAXUINT32 / 5LL);
235 fail_if (gst_util_uint64_scale_int (G_MAXUINT32, 2, 10) != G_MAXUINT32 / 5LL);
236
237 /* not quite overflow */
238 fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, 10,
239 10) != G_MAXUINT64 - 1);
240 fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, G_MAXINT32,
241 G_MAXINT32) != G_MAXUINT64 - 1);
242 fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 100, G_MAXINT32,
243 G_MAXINT32) != G_MAXUINT64 - 100);
244
245 /* overflow */
246 fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, 10, 1) != G_MAXUINT64);
247 fail_if (gst_util_uint64_scale_int (G_MAXUINT64 - 1, G_MAXINT32,
248 1) != G_MAXUINT64);
249
250 } GST_END_TEST;
251
GST_START_TEST(test_math_scale_round)252 GST_START_TEST (test_math_scale_round)
253 {
254 fail_if (gst_util_uint64_scale_int_round (2, 1, 2) != 1);
255 fail_if (gst_util_uint64_scale_int_round (3, 1, 2) != 2);
256 fail_if (gst_util_uint64_scale_int_round (4, 1, 2) != 2);
257
258 fail_if (gst_util_uint64_scale_int_round (200, 100, 20000) != 1);
259 fail_if (gst_util_uint64_scale_int_round (299, 100, 20000) != 1);
260 fail_if (gst_util_uint64_scale_int_round (300, 100, 20000) != 2);
261 fail_if (gst_util_uint64_scale_int_round (301, 100, 20000) != 2);
262 fail_if (gst_util_uint64_scale_int_round (400, 100, 20000) != 2);
263 } GST_END_TEST;
264
GST_START_TEST(test_math_scale_ceil)265 GST_START_TEST (test_math_scale_ceil)
266 {
267 fail_if (gst_util_uint64_scale_int_ceil (2, 1, 2) != 1);
268 fail_if (gst_util_uint64_scale_int_ceil (3, 1, 2) != 2);
269 fail_if (gst_util_uint64_scale_int_ceil (4, 1, 2) != 2);
270
271 fail_if (gst_util_uint64_scale_int_ceil (200, 100, 20000) != 1);
272 fail_if (gst_util_uint64_scale_int_ceil (299, 100, 20000) != 2);
273 fail_if (gst_util_uint64_scale_int_ceil (300, 100, 20000) != 2);
274 fail_if (gst_util_uint64_scale_int_ceil (301, 100, 20000) != 2);
275 fail_if (gst_util_uint64_scale_int_ceil (400, 100, 20000) != 2);
276 } GST_END_TEST;
277
GST_START_TEST(test_math_scale_uint64)278 GST_START_TEST (test_math_scale_uint64)
279 {
280 fail_if (gst_util_uint64_scale (1, 1, 1) != 1);
281
282 fail_if (gst_util_uint64_scale (10, 10, 1) != 100);
283 fail_if (gst_util_uint64_scale (10, 10, 2) != 50);
284
285 fail_if (gst_util_uint64_scale (0, 10, 2) != 0);
286 fail_if (gst_util_uint64_scale (0, 0, 2) != 0);
287
288 fail_if (gst_util_uint64_scale (G_MAXUINT32, 5, 1) != G_MAXUINT32 * 5LL);
289 fail_if (gst_util_uint64_scale (G_MAXUINT32, 10, 2) != G_MAXUINT32 * 5LL);
290
291 fail_if (gst_util_uint64_scale (G_MAXUINT32, 1, 5) != G_MAXUINT32 / 5LL);
292 fail_if (gst_util_uint64_scale (G_MAXUINT32, 2, 10) != G_MAXUINT32 / 5LL);
293
294 /* not quite overflow */
295 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 1, 10, 10) != G_MAXUINT64 - 1);
296 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 1, G_MAXUINT32,
297 G_MAXUINT32) != G_MAXUINT64 - 1);
298 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 100, G_MAXUINT32,
299 G_MAXUINT32) != G_MAXUINT64 - 100);
300
301 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 1, 10, 10) != G_MAXUINT64 - 1);
302 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 1, G_MAXUINT64,
303 G_MAXUINT64) != G_MAXUINT64 - 1);
304 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 100, G_MAXUINT64,
305 G_MAXUINT64) != G_MAXUINT64 - 100);
306
307 /* overflow */
308 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 1, 10, 1) != G_MAXUINT64);
309 fail_if (gst_util_uint64_scale (G_MAXUINT64 - 1, G_MAXUINT64,
310 1) != G_MAXUINT64);
311
312 } GST_END_TEST;
313
GST_START_TEST(test_math_scale_random)314 GST_START_TEST (test_math_scale_random)
315 {
316 guint64 val, num, denom, res;
317 GRand *rand;
318 gint i;
319
320 rand = g_rand_new ();
321
322 i = 100000;
323 while (i--) {
324 guint64 check, diff;
325
326 val = ((guint64) g_rand_int (rand)) << 32 | g_rand_int (rand);
327 num = ((guint64) g_rand_int (rand)) << 32 | g_rand_int (rand);
328 denom = ((guint64) g_rand_int (rand)) << 32 | g_rand_int (rand);
329
330 res = gst_util_uint64_scale (val, num, denom);
331 check = gst_gdouble_to_guint64 (gst_guint64_to_gdouble (val) *
332 gst_guint64_to_gdouble (num) / gst_guint64_to_gdouble (denom));
333
334 if (res < G_MAXUINT64 && check < G_MAXUINT64) {
335 if (res > check)
336 diff = res - check;
337 else
338 diff = check - res;
339
340 /* some arbitrary value, really.. someone do the proper math to get
341 * the upper bound */
342 if (diff > 20000)
343 fail_if (diff > 20000);
344 }
345 }
346 g_rand_free (rand);
347
348 }
349
350 GST_END_TEST;
351
GST_START_TEST(test_guint64_to_gdouble)352 GST_START_TEST (test_guint64_to_gdouble)
353 {
354 guint64 from[] = { 0, 1, 100, 10000, (guint64) (1) << 63,
355 ((guint64) (1) << 63) + 1,
356 ((guint64) (1) << 63) + (G_GINT64_CONSTANT (1) << 62)
357 };
358 gdouble to[] = { 0., 1., 100., 10000., 9223372036854775808.,
359 9223372036854775809., 13835058055282163712.
360 };
361 gdouble tolerance[] = { 0., 0., 0., 0., 0., 1., 1. };
362 gint i;
363 gdouble result;
364 gdouble delta;
365
366 for (i = 0; i < G_N_ELEMENTS (from); ++i) {
367 result = gst_util_guint64_to_gdouble (from[i]);
368 delta = ABS (to[i] - result);
369 fail_unless (delta <= tolerance[i],
370 "Could not convert %d: %" G_GUINT64_FORMAT
371 " -> %f, got %f instead, delta of %e with tolerance of %e",
372 i, from[i], to[i], result, delta, tolerance[i]);
373 }
374 }
375
376 GST_END_TEST;
377
GST_START_TEST(test_gdouble_to_guint64)378 GST_START_TEST (test_gdouble_to_guint64)
379 {
380 gdouble from[] = { 0., 1., 100., 10000., 9223372036854775808.,
381 9223372036854775809., 13835058055282163712.
382 };
383 guint64 to[] = { 0, 1, 100, 10000, (guint64) (1) << 63,
384 ((guint64) (1) << 63) + 1,
385 ((guint64) (1) << 63) + (G_GINT64_CONSTANT (1) << 62)
386 };
387 guint64 tolerance[] = { 0, 0, 0, 0, 0, 1, 1 };
388 gint i;
389 gdouble result;
390 guint64 delta;
391
392 for (i = 0; i < G_N_ELEMENTS (from); ++i) {
393 result = gst_util_gdouble_to_guint64 (from[i]);
394 delta = ABS (to[i] - result);
395 fail_unless (delta <= tolerance[i],
396 "Could not convert %f: %" G_GUINT64_FORMAT
397 " -> %d, got %d instead, delta of %e with tolerance of %e",
398 i, from[i], to[i], result, delta, tolerance[i]);
399 }
400 }
401
402 GST_END_TEST;
403
404 #ifndef GST_DISABLE_PARSE
GST_START_TEST(test_parse_bin_from_description)405 GST_START_TEST (test_parse_bin_from_description)
406 {
407 struct
408 {
409 const gchar *bin_desc;
410 const gchar *pad_names;
411 } bin_tests[] = {
412 {
413 "identity", "identity0/sink,identity0/src"}, {
414 "identity ! identity ! identity", "identity1/sink,identity3/src"}, {
415 "identity ! fakesink", "identity4/sink"}, {
416 "fakesrc ! identity", "identity5/src"}, {
417 "fakesrc ! fakesink", ""}
418 };
419 gint i;
420
421 for (i = 0; i < G_N_ELEMENTS (bin_tests); ++i) {
422 GstElement *bin, *parent;
423 GString *s;
424 GstPad *ghost_pad, *target_pad;
425 GError *err = NULL;
426
427 bin = gst_parse_bin_from_description (bin_tests[i].bin_desc, TRUE, &err);
428 if (err) {
429 g_error ("ERROR in gst_parse_bin_from_description (%s): %s",
430 bin_tests[i].bin_desc, err->message);
431 }
432 g_assert (bin != NULL);
433
434 s = g_string_new ("");
435 if ((ghost_pad = gst_element_get_static_pad (bin, "sink"))) {
436 g_assert (GST_IS_GHOST_PAD (ghost_pad));
437
438 target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (ghost_pad));
439 g_assert (target_pad != NULL);
440 g_assert (GST_IS_PAD (target_pad));
441
442 parent = gst_pad_get_parent_element (target_pad);
443 g_assert (parent != NULL);
444
445 g_string_append_printf (s, "%s/sink", GST_ELEMENT_NAME (parent));
446
447 gst_object_unref (parent);
448 gst_object_unref (target_pad);
449 gst_object_unref (ghost_pad);
450 }
451
452 if ((ghost_pad = gst_element_get_static_pad (bin, "src"))) {
453 g_assert (GST_IS_GHOST_PAD (ghost_pad));
454
455 target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (ghost_pad));
456 g_assert (target_pad != NULL);
457 g_assert (GST_IS_PAD (target_pad));
458
459 parent = gst_pad_get_parent_element (target_pad);
460 g_assert (parent != NULL);
461
462 if (s->len > 0) {
463 g_string_append (s, ",");
464 }
465
466 g_string_append_printf (s, "%s/src", GST_ELEMENT_NAME (parent));
467
468 gst_object_unref (parent);
469 gst_object_unref (target_pad);
470 gst_object_unref (ghost_pad);
471 }
472
473 if (strcmp (s->str, bin_tests[i].pad_names) != 0) {
474 g_error ("FAILED: expected '%s', got '%s' for bin '%s'",
475 bin_tests[i].pad_names, s->str, bin_tests[i].bin_desc);
476 }
477 g_string_free (s, TRUE);
478
479 gst_object_unref (bin);
480 }
481 }
482
483 GST_END_TEST;
484 #endif
485
GST_START_TEST(test_element_found_tags)486 GST_START_TEST (test_element_found_tags)
487 {
488 GstElement *pipeline, *fakesrc, *fakesink;
489 GstTagList *list;
490 GstBus *bus;
491 GstMessage *message;
492 GstPad *srcpad;
493
494 pipeline = gst_element_factory_make ("pipeline", NULL);
495 fakesrc = gst_element_factory_make ("fakesrc", NULL);
496 fakesink = gst_element_factory_make ("fakesink", NULL);
497 list = gst_tag_list_new_empty ();
498
499 g_object_set (fakesrc, "num-buffers", (int) 10, NULL);
500
501 gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
502 gst_element_link (fakesrc, fakesink);
503
504 gst_element_set_state (pipeline, GST_STATE_PLAYING);
505
506 srcpad = gst_element_get_static_pad (fakesrc, "src");
507 gst_pad_push_event (srcpad, gst_event_new_tag (list));
508 gst_object_unref (srcpad);
509
510 bus = gst_element_get_bus (pipeline);
511 message = gst_bus_poll (bus, GST_MESSAGE_EOS, -1);
512 gst_message_unref (message);
513 gst_object_unref (bus);
514
515 /* FIXME: maybe also check if the fakesink receives the message */
516
517 gst_element_set_state (pipeline, GST_STATE_NULL);
518 gst_object_unref (pipeline);
519 }
520
521 GST_END_TEST;
522
GST_START_TEST(test_element_unlink)523 GST_START_TEST (test_element_unlink)
524 {
525 GstElement *src, *sink;
526
527 src = gst_element_factory_make ("fakesrc", NULL);
528 sink = gst_element_factory_make ("fakesink", NULL);
529 fail_unless (gst_element_link (src, sink) != FALSE);
530 gst_element_unlink (src, sink);
531 gst_object_unref (src);
532 gst_object_unref (sink);
533 }
534
535 GST_END_TEST;
536
GST_START_TEST(test_set_value_from_string)537 GST_START_TEST (test_set_value_from_string)
538 {
539 GValue val = { 0, };
540
541 /* g_return_if_fail */
542 ASSERT_CRITICAL (gst_util_set_value_from_string (NULL, "xyz"));
543
544 g_value_init (&val, G_TYPE_STRING);
545 ASSERT_CRITICAL (gst_util_set_value_from_string (&val, NULL));
546 g_value_unset (&val);
547
548 /* string => string */
549 g_value_init (&val, G_TYPE_STRING);
550 gst_util_set_value_from_string (&val, "Y00");
551 fail_unless (g_value_get_string (&val) != NULL);
552 fail_unless_equals_string (g_value_get_string (&val), "Y00");
553 g_value_unset (&val);
554
555 /* string => int */
556 g_value_init (&val, G_TYPE_INT);
557 gst_util_set_value_from_string (&val, "987654321");
558 fail_unless (g_value_get_int (&val) == 987654321);
559 g_value_unset (&val);
560
561 g_value_init (&val, G_TYPE_INT);
562 ASSERT_CRITICAL (gst_util_set_value_from_string (&val, "xyz"));
563 g_value_unset (&val);
564
565 /* string => uint */
566 g_value_init (&val, G_TYPE_UINT);
567 gst_util_set_value_from_string (&val, "987654321");
568 fail_unless (g_value_get_uint (&val) == 987654321);
569 g_value_unset (&val);
570
571 /* CHECKME: is this really desired behaviour? (tpm) */
572 g_value_init (&val, G_TYPE_UINT);
573 gst_util_set_value_from_string (&val, "-999");
574 fail_unless (g_value_get_uint (&val) == ((guint) 0 - (guint) 999));
575 g_value_unset (&val);
576
577 g_value_init (&val, G_TYPE_UINT);
578 ASSERT_CRITICAL (gst_util_set_value_from_string (&val, "xyz"));
579 g_value_unset (&val);
580
581 /* string => long */
582 g_value_init (&val, G_TYPE_LONG);
583 gst_util_set_value_from_string (&val, "987654321");
584 fail_unless (g_value_get_long (&val) == 987654321);
585 g_value_unset (&val);
586
587 g_value_init (&val, G_TYPE_LONG);
588 ASSERT_CRITICAL (gst_util_set_value_from_string (&val, "xyz"));
589 g_value_unset (&val);
590
591 /* string => ulong */
592 g_value_init (&val, G_TYPE_ULONG);
593 gst_util_set_value_from_string (&val, "987654321");
594 fail_unless (g_value_get_ulong (&val) == 987654321);
595 g_value_unset (&val);
596
597 /* CHECKME: is this really desired behaviour? (tpm) */
598 g_value_init (&val, G_TYPE_ULONG);
599 gst_util_set_value_from_string (&val, "-999");
600 fail_unless (g_value_get_ulong (&val) == ((gulong) 0 - (gulong) 999));
601 g_value_unset (&val);
602
603 g_value_init (&val, G_TYPE_ULONG);
604 ASSERT_CRITICAL (gst_util_set_value_from_string (&val, "xyz"));
605 g_value_unset (&val);
606
607 /* string => boolean */
608 g_value_init (&val, G_TYPE_BOOLEAN);
609 gst_util_set_value_from_string (&val, "true");
610 fail_unless_equals_int (g_value_get_boolean (&val), TRUE);
611 g_value_unset (&val);
612
613 g_value_init (&val, G_TYPE_BOOLEAN);
614 gst_util_set_value_from_string (&val, "TRUE");
615 fail_unless_equals_int (g_value_get_boolean (&val), TRUE);
616 g_value_unset (&val);
617
618 g_value_init (&val, G_TYPE_BOOLEAN);
619 gst_util_set_value_from_string (&val, "false");
620 fail_unless_equals_int (g_value_get_boolean (&val), FALSE);
621 g_value_unset (&val);
622
623 g_value_init (&val, G_TYPE_BOOLEAN);
624 gst_util_set_value_from_string (&val, "FALSE");
625 fail_unless_equals_int (g_value_get_boolean (&val), FALSE);
626 g_value_unset (&val);
627
628 g_value_init (&val, G_TYPE_BOOLEAN);
629 gst_util_set_value_from_string (&val, "bleh");
630 fail_unless_equals_int (g_value_get_boolean (&val), FALSE);
631 g_value_unset (&val);
632
633 #if 0
634 /* string => float (yay, localisation issues involved) */
635 g_value_init (&val, G_TYPE_FLOAT);
636 gst_util_set_value_from_string (&val, "987.654");
637 fail_unless (g_value_get_float (&val) >= 987.653 &&
638 g_value_get_float (&val) <= 987.655);
639 g_value_unset (&val);
640
641 g_value_init (&val, G_TYPE_FLOAT);
642 gst_util_set_value_from_string (&val, "987,654");
643 fail_unless (g_value_get_float (&val) >= 987.653 &&
644 g_value_get_float (&val) <= 987.655);
645 g_value_unset (&val);
646
647 /* string => double (yay, localisation issues involved) */
648 g_value_init (&val, G_TYPE_DOUBLE);
649 gst_util_set_value_from_string (&val, "987.654");
650 fail_unless (g_value_get_double (&val) >= 987.653 &&
651 g_value_get_double (&val) <= 987.655);
652 g_value_unset (&val);
653
654 g_value_init (&val, G_TYPE_DOUBLE);
655 gst_util_set_value_from_string (&val, "987,654");
656 fail_unless (g_value_get_double (&val) >= 987.653 &&
657 g_value_get_double (&val) <= 987.655);
658 g_value_unset (&val);
659 #endif
660 }
661
662 GST_END_TEST;
663
664 static gint
_binary_search_compare(guint32 * a,guint32 * b)665 _binary_search_compare (guint32 * a, guint32 * b)
666 {
667 return *a - *b;
668 }
669
GST_START_TEST(test_binary_search)670 GST_START_TEST (test_binary_search)
671 {
672 guint32 data[257];
673 guint32 *match;
674 guint32 search_element = 121 * 2;
675 guint i;
676
677 for (i = 0; i < 257; i++)
678 data[i] = (i + 1) * 2;
679
680 match =
681 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
682 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_EXACT,
683 &search_element, NULL);
684 fail_unless (match != NULL);
685 fail_unless_equals_int (match - data, 120);
686
687 match =
688 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
689 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_BEFORE,
690 &search_element, NULL);
691 fail_unless (match != NULL);
692 fail_unless_equals_int (match - data, 120);
693
694 match =
695 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
696 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_AFTER,
697 &search_element, NULL);
698 fail_unless (match != NULL);
699 fail_unless_equals_int (match - data, 120);
700
701 search_element = 0;
702 match =
703 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
704 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_EXACT,
705 &search_element, NULL);
706 fail_unless (match == NULL);
707
708 match =
709 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
710 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_AFTER,
711 &search_element, NULL);
712 fail_unless (match != NULL);
713 fail_unless_equals_int (match - data, 0);
714
715 match =
716 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
717 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_BEFORE,
718 &search_element, NULL);
719 fail_unless (match == NULL);
720
721 search_element = 1000;
722 match =
723 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
724 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_EXACT,
725 &search_element, NULL);
726 fail_unless (match == NULL);
727
728 match =
729 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
730 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_AFTER,
731 &search_element, NULL);
732 fail_unless (match == NULL);
733
734 match =
735 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
736 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_BEFORE,
737 &search_element, NULL);
738 fail_unless (match != NULL);
739 fail_unless_equals_int (match - data, 256);
740
741 search_element = 121 * 2 - 1;
742 match =
743 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
744 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_EXACT,
745 &search_element, NULL);
746 fail_unless (match == NULL);
747
748 match =
749 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
750 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_AFTER,
751 &search_element, NULL);
752 fail_unless (match != NULL);
753 fail_unless_equals_int (match - data, 120);
754
755 match =
756 (guint32 *) gst_util_array_binary_search (data, 257, sizeof (guint32),
757 (GCompareDataFunc) _binary_search_compare, GST_SEARCH_MODE_BEFORE,
758 &search_element, NULL);
759 fail_unless (match != NULL);
760 fail_unless_equals_int (match - data, 119);
761
762 }
763
764 GST_END_TEST;
765
766 #ifdef HAVE_GSL
767 #ifdef HAVE_GMP
768
769 #include <gsl/gsl_rng.h>
770 #include <gmp.h>
771
772 static guint64
randguint64(gsl_rng * rng,guint64 n)773 randguint64 (gsl_rng * rng, guint64 n)
774 {
775 union
776 {
777 guint64 x;
778 struct
779 {
780 guint16 a, b, c, d;
781 } parts;
782 } x;
783 x.parts.a = gsl_rng_uniform_int (rng, 1 << 16);
784 x.parts.b = gsl_rng_uniform_int (rng, 1 << 16);
785 x.parts.c = gsl_rng_uniform_int (rng, 1 << 16);
786 x.parts.d = gsl_rng_uniform_int (rng, 1 << 16);
787 return x.x % n;
788 }
789
790
791 enum round_t
792 {
793 ROUND_TONEAREST = 0,
794 ROUND_UP,
795 ROUND_DOWN
796 };
797
798 static void
gmp_set_uint64(mpz_t mp,guint64 x)799 gmp_set_uint64 (mpz_t mp, guint64 x)
800 {
801 mpz_t two_32, tmp;
802
803 mpz_init (two_32);
804 mpz_init (tmp);
805
806 mpz_ui_pow_ui (two_32, 2, 32);
807 mpz_set_ui (mp, (unsigned long) ((x >> 32) & G_MAXUINT32));
808 mpz_mul (tmp, mp, two_32);
809 mpz_add_ui (mp, tmp, (unsigned long) (x & G_MAXUINT32));
810 mpz_clear (two_32);
811 mpz_clear (tmp);
812 }
813
814 static guint64
gmp_get_uint64(mpz_t mp)815 gmp_get_uint64 (mpz_t mp)
816 {
817 mpz_t two_64, two_32, tmp;
818 guint64 ret;
819
820 mpz_init (two_64);
821 mpz_init (two_32);
822 mpz_init (tmp);
823
824 mpz_ui_pow_ui (two_64, 2, 64);
825 mpz_ui_pow_ui (two_32, 2, 32);
826 if (mpz_cmp (tmp, two_64) >= 0)
827 return G_MAXUINT64;
828 mpz_clear (two_64);
829
830 mpz_tdiv_q (tmp, mp, two_32);
831 ret = mpz_get_ui (tmp);
832 ret <<= 32;
833 ret |= mpz_get_ui (mp);
834 mpz_clear (two_32);
835 mpz_clear (tmp);
836
837 return ret;
838 }
839
840 static guint64
gmp_scale(guint64 x,guint64 a,guint64 b,enum round_t mode)841 gmp_scale (guint64 x, guint64 a, guint64 b, enum round_t mode)
842 {
843 mpz_t mp1, mp2, mp3;
844 if (!b)
845 /* overflow */
846 return G_MAXUINT64;
847 mpz_init (mp1);
848 mpz_init (mp2);
849 mpz_init (mp3);
850
851 gmp_set_uint64 (mp1, x);
852 gmp_set_uint64 (mp3, a);
853 mpz_mul (mp2, mp1, mp3);
854 switch (mode) {
855 case ROUND_TONEAREST:
856 gmp_set_uint64 (mp1, b);
857 mpz_tdiv_q_ui (mp3, mp1, 2);
858 mpz_add (mp1, mp2, mp3);
859 mpz_set (mp2, mp1);
860 break;
861 case ROUND_UP:
862 gmp_set_uint64 (mp1, b);
863 mpz_sub_ui (mp3, mp1, 1);
864 mpz_add (mp1, mp2, mp3);
865 mpz_set (mp2, mp1);
866 break;
867 case ROUND_DOWN:
868 break;
869 }
870 gmp_set_uint64 (mp3, b);
871 mpz_tdiv_q (mp1, mp2, mp3);
872 x = gmp_get_uint64 (mp1);
873 mpz_clear (mp1);
874 mpz_clear (mp2);
875 mpz_clear (mp3);
876 return x;
877 }
878
879 static void
_gmp_test_scale(gsl_rng * rng)880 _gmp_test_scale (gsl_rng * rng)
881 {
882 guint64 bygst, bygmp;
883 guint64 a = randguint64 (rng, gsl_rng_uniform_int (rng,
884 2) ? G_MAXUINT64 : G_MAXUINT32);
885 guint64 b = randguint64 (rng, gsl_rng_uniform_int (rng, 2) ? G_MAXUINT64 - 1 : G_MAXUINT32 - 1) + 1; /* 0 not allowed */
886 guint64 val = randguint64 (rng, gmp_scale (G_MAXUINT64, b, a, ROUND_DOWN));
887 enum round_t mode = gsl_rng_uniform_int (rng, 3);
888 const char *func;
889
890 bygmp = gmp_scale (val, a, b, mode);
891 switch (mode) {
892 case ROUND_TONEAREST:
893 bygst = gst_util_uint64_scale_round (val, a, b);
894 func = "gst_util_uint64_scale_round";
895 break;
896 case ROUND_UP:
897 bygst = gst_util_uint64_scale_ceil (val, a, b);
898 func = "gst_util_uint64_scale_ceil";
899 break;
900 case ROUND_DOWN:
901 bygst = gst_util_uint64_scale (val, a, b);
902 func = "gst_util_uint64_scale";
903 break;
904 default:
905 g_assert_not_reached ();
906 break;
907 }
908 fail_unless (bygst == bygmp,
909 "error: %s(): %" G_GUINT64_FORMAT " * %" G_GUINT64_FORMAT " / %"
910 G_GUINT64_FORMAT " = %" G_GUINT64_FORMAT ", correct = %" G_GUINT64_FORMAT
911 "\n", func, val, a, b, bygst, bygmp);
912 }
913
914 static void
_gmp_test_scale_int(gsl_rng * rng)915 _gmp_test_scale_int (gsl_rng * rng)
916 {
917 guint64 bygst, bygmp;
918 gint32 a = randguint64 (rng, G_MAXINT32);
919 gint32 b = randguint64 (rng, G_MAXINT32 - 1) + 1; /* 0 not allowed */
920 guint64 val = randguint64 (rng, gmp_scale (G_MAXUINT64, b, a, ROUND_DOWN));
921 enum round_t mode = gsl_rng_uniform_int (rng, 3);
922 const char *func;
923
924 bygmp = gmp_scale (val, a, b, mode);
925 switch (mode) {
926 case ROUND_TONEAREST:
927 bygst = gst_util_uint64_scale_int_round (val, a, b);
928 func = "gst_util_uint64_scale_int_round";
929 break;
930 case ROUND_UP:
931 bygst = gst_util_uint64_scale_int_ceil (val, a, b);
932 func = "gst_util_uint64_scale_int_ceil";
933 break;
934 case ROUND_DOWN:
935 bygst = gst_util_uint64_scale_int (val, a, b);
936 func = "gst_util_uint64_scale_int";
937 break;
938 default:
939 g_assert_not_reached ();
940 break;
941 }
942 fail_unless (bygst == bygmp,
943 "error: %s(): %" G_GUINT64_FORMAT " * %d / %d = %" G_GUINT64_FORMAT
944 ", correct = %" G_GUINT64_FORMAT "\n", func, val, a, b, bygst, bygmp);
945 }
946
947 #define GMP_TEST_RUNS 100000
948
GST_START_TEST(test_math_scale_gmp)949 GST_START_TEST (test_math_scale_gmp)
950 {
951 gsl_rng *rng = gsl_rng_alloc (gsl_rng_mt19937);
952 gint n;
953
954 for (n = 0; n < GMP_TEST_RUNS; n++)
955 _gmp_test_scale (rng);
956
957 gsl_rng_free (rng);
958 }
959
960 GST_END_TEST;
961
GST_START_TEST(test_math_scale_gmp_int)962 GST_START_TEST (test_math_scale_gmp_int)
963 {
964 gsl_rng *rng = gsl_rng_alloc (gsl_rng_mt19937);
965 gint n;
966
967 for (n = 0; n < GMP_TEST_RUNS; n++)
968 _gmp_test_scale_int (rng);
969
970 gsl_rng_free (rng);
971 }
972
973 GST_END_TEST;
974
975 #endif
976 #endif
977
GST_START_TEST(test_pad_proxy_query_caps_aggregation)978 GST_START_TEST (test_pad_proxy_query_caps_aggregation)
979 {
980 GstElement *tee, *sink1, *sink2;
981 GstCaps *caps;
982 GstPad *tee_src1, *tee_src2, *tee_sink, *sink1_sink, *sink2_sink;
983
984 tee = gst_element_factory_make ("tee", "tee");
985
986 sink1 = gst_element_factory_make ("fakesink", "sink1");
987 tee_src1 = gst_element_get_request_pad (tee, "src_%u");
988 sink1_sink = gst_element_get_static_pad (sink1, "sink");
989 fail_unless_equals_int (gst_pad_link (tee_src1, sink1_sink), GST_PAD_LINK_OK);
990
991 sink2 = gst_element_factory_make ("fakesink", "sink2");
992 tee_src2 = gst_element_get_request_pad (tee, "src_%u");
993 sink2_sink = gst_element_get_static_pad (sink2, "sink");
994 fail_unless_equals_int (gst_pad_link (tee_src2, sink2_sink), GST_PAD_LINK_OK);
995
996 tee_sink = gst_element_get_static_pad (tee, "sink");
997
998 gst_element_set_state (sink1, GST_STATE_PAUSED);
999 gst_element_set_state (sink2, GST_STATE_PAUSED);
1000 gst_element_set_state (tee, GST_STATE_PAUSED);
1001
1002 /* by default, ANY caps should intersect to ANY */
1003 caps = gst_pad_query_caps (tee_sink, NULL);
1004 GST_INFO ("got caps: %" GST_PTR_FORMAT, caps);
1005 fail_unless (caps != NULL);
1006 fail_unless (gst_caps_is_any (caps));
1007 gst_caps_unref (caps);
1008
1009 /* these don't intersect we should get empty caps */
1010 caps = gst_caps_new_empty_simple ("foo/bar");
1011 fail_unless (gst_pad_set_caps (sink1_sink, caps));
1012 gst_pad_use_fixed_caps (sink1_sink);
1013 gst_caps_unref (caps);
1014
1015 caps = gst_caps_new_empty_simple ("bar/ter");
1016 fail_unless (gst_pad_set_caps (sink2_sink, caps));
1017 gst_pad_use_fixed_caps (sink2_sink);
1018 gst_caps_unref (caps);
1019
1020 caps = gst_pad_query_caps (tee_sink, NULL);
1021 GST_INFO ("got caps: %" GST_PTR_FORMAT, caps);
1022 fail_unless (caps != NULL);
1023 fail_unless (gst_caps_is_empty (caps));
1024 gst_caps_unref (caps);
1025
1026 /* test intersection */
1027 caps = gst_caps_new_simple ("foo/bar", "barversion", G_TYPE_INT, 1, NULL);
1028 GST_OBJECT_FLAG_UNSET (sink2_sink, GST_PAD_FLAG_FIXED_CAPS);
1029 fail_unless (gst_pad_set_caps (sink2_sink, caps));
1030 gst_pad_use_fixed_caps (sink2_sink);
1031 gst_caps_unref (caps);
1032
1033 caps = gst_pad_query_caps (tee_sink, NULL);
1034 GST_INFO ("got caps: %" GST_PTR_FORMAT, caps);
1035 fail_unless (caps != NULL);
1036 fail_if (gst_caps_is_empty (caps));
1037 {
1038 GstStructure *s = gst_caps_get_structure (caps, 0);
1039
1040 fail_unless_equals_string (gst_structure_get_name (s), "foo/bar");
1041 fail_unless (gst_structure_has_field_typed (s, "barversion", G_TYPE_INT));
1042 }
1043 gst_caps_unref (caps);
1044
1045 gst_element_set_state (sink1, GST_STATE_NULL);
1046 gst_element_set_state (sink2, GST_STATE_NULL);
1047 gst_element_set_state (tee, GST_STATE_NULL);
1048
1049 /* clean up */
1050 gst_element_release_request_pad (tee, tee_src1);
1051 gst_object_unref (tee_src1);
1052 gst_element_release_request_pad (tee, tee_src2);
1053 gst_object_unref (tee_src2);
1054 gst_object_unref (tee_sink);
1055 gst_object_unref (tee);
1056 gst_object_unref (sink1_sink);
1057 gst_object_unref (sink1);
1058 gst_object_unref (sink2_sink);
1059 gst_object_unref (sink2);
1060 }
1061
1062 GST_END_TEST;
1063
GST_START_TEST(test_greatest_common_divisor)1064 GST_START_TEST (test_greatest_common_divisor)
1065 {
1066 fail_if (gst_util_greatest_common_divisor (1, 1) != 1);
1067 fail_if (gst_util_greatest_common_divisor (2, 3) != 1);
1068 fail_if (gst_util_greatest_common_divisor (3, 5) != 1);
1069 fail_if (gst_util_greatest_common_divisor (-1, 1) != 1);
1070 fail_if (gst_util_greatest_common_divisor (-2, 3) != 1);
1071 fail_if (gst_util_greatest_common_divisor (-3, 5) != 1);
1072 fail_if (gst_util_greatest_common_divisor (-1, -1) != 1);
1073 fail_if (gst_util_greatest_common_divisor (-2, -3) != 1);
1074 fail_if (gst_util_greatest_common_divisor (-3, -5) != 1);
1075 fail_if (gst_util_greatest_common_divisor (1, -1) != 1);
1076 fail_if (gst_util_greatest_common_divisor (2, -3) != 1);
1077 fail_if (gst_util_greatest_common_divisor (3, -5) != 1);
1078 fail_if (gst_util_greatest_common_divisor (2, 2) != 2);
1079 fail_if (gst_util_greatest_common_divisor (2, 4) != 2);
1080 fail_if (gst_util_greatest_common_divisor (1001, 11) != 11);
1081
1082 }
1083
1084 GST_END_TEST;
1085
GST_START_TEST(test_read_macros)1086 GST_START_TEST (test_read_macros)
1087 {
1088 guint8 carray[] = "ABCDEFGH"; /* 0x41 ... 0x48 */
1089 guint32 uarray[2];
1090 guint8 *cpointer;
1091
1092 memcpy (uarray, carray, 8);
1093 cpointer = carray;
1094
1095 /* 16 bit */
1096 /* First try the standard pointer variants */
1097 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer), 0x4142);
1098 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer + 1), 0x4243);
1099 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer + 2), 0x4344);
1100 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer + 3), 0x4445);
1101 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer + 4), 0x4546);
1102 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer + 5), 0x4647);
1103 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer + 6), 0x4748);
1104
1105 fail_unless_equals_int_hex (GST_READ_UINT16_LE (cpointer), 0x4241);
1106 fail_unless_equals_int_hex (GST_READ_UINT16_LE (cpointer + 1), 0x4342);
1107 fail_unless_equals_int_hex (GST_READ_UINT16_LE (cpointer + 2), 0x4443);
1108 fail_unless_equals_int_hex (GST_READ_UINT16_LE (cpointer + 3), 0x4544);
1109 fail_unless_equals_int_hex (GST_READ_UINT16_LE (cpointer + 4), 0x4645);
1110 fail_unless_equals_int_hex (GST_READ_UINT16_LE (cpointer + 5), 0x4746);
1111 fail_unless_equals_int_hex (GST_READ_UINT16_LE (cpointer + 6), 0x4847);
1112
1113 /* On an array of guint8 */
1114 fail_unless_equals_int_hex (GST_READ_UINT16_BE (carray), 0x4142);
1115 fail_unless_equals_int_hex (GST_READ_UINT16_BE (carray + 1), 0x4243);
1116 fail_unless_equals_int_hex (GST_READ_UINT16_BE (carray + 2), 0x4344);
1117 fail_unless_equals_int_hex (GST_READ_UINT16_BE (carray + 3), 0x4445);
1118 fail_unless_equals_int_hex (GST_READ_UINT16_BE (carray + 4), 0x4546);
1119 fail_unless_equals_int_hex (GST_READ_UINT16_BE (carray + 5), 0x4647);
1120 fail_unless_equals_int_hex (GST_READ_UINT16_BE (carray + 6), 0x4748);
1121
1122 fail_unless_equals_int_hex (GST_READ_UINT16_LE (carray), 0x4241);
1123 fail_unless_equals_int_hex (GST_READ_UINT16_LE (carray + 1), 0x4342);
1124 fail_unless_equals_int_hex (GST_READ_UINT16_LE (carray + 2), 0x4443);
1125 fail_unless_equals_int_hex (GST_READ_UINT16_LE (carray + 3), 0x4544);
1126 fail_unless_equals_int_hex (GST_READ_UINT16_LE (carray + 4), 0x4645);
1127 fail_unless_equals_int_hex (GST_READ_UINT16_LE (carray + 5), 0x4746);
1128 fail_unless_equals_int_hex (GST_READ_UINT16_LE (carray + 6), 0x4847);
1129
1130 /* On an array of guint32 */
1131 fail_unless_equals_int_hex (GST_READ_UINT16_BE (uarray), 0x4142);
1132 fail_unless_equals_int_hex (GST_READ_UINT16_BE (uarray + 1), 0x4546);
1133
1134 fail_unless_equals_int_hex (GST_READ_UINT16_LE (uarray), 0x4241);
1135 fail_unless_equals_int_hex (GST_READ_UINT16_LE (uarray + 1), 0x4645);
1136
1137
1138 /* 24bit */
1139 /* First try the standard pointer variants */
1140 fail_unless_equals_int_hex (GST_READ_UINT24_BE (cpointer), 0x414243);
1141 fail_unless_equals_int_hex (GST_READ_UINT24_BE (cpointer + 1), 0x424344);
1142 fail_unless_equals_int_hex (GST_READ_UINT24_BE (cpointer + 2), 0x434445);
1143 fail_unless_equals_int_hex (GST_READ_UINT24_BE (cpointer + 3), 0x444546);
1144 fail_unless_equals_int_hex (GST_READ_UINT24_BE (cpointer + 4), 0x454647);
1145 fail_unless_equals_int_hex (GST_READ_UINT24_BE (cpointer + 5), 0x464748);
1146
1147 fail_unless_equals_int_hex (GST_READ_UINT24_LE (cpointer), 0x434241);
1148 fail_unless_equals_int_hex (GST_READ_UINT24_LE (cpointer + 1), 0x444342);
1149 fail_unless_equals_int_hex (GST_READ_UINT24_LE (cpointer + 2), 0x454443);
1150 fail_unless_equals_int_hex (GST_READ_UINT24_LE (cpointer + 3), 0x464544);
1151 fail_unless_equals_int_hex (GST_READ_UINT24_LE (cpointer + 4), 0x474645);
1152 fail_unless_equals_int_hex (GST_READ_UINT24_LE (cpointer + 5), 0x484746);
1153
1154 /* On an array of guint8 */
1155 fail_unless_equals_int_hex (GST_READ_UINT24_BE (carray), 0x414243);
1156 fail_unless_equals_int_hex (GST_READ_UINT24_BE (carray + 1), 0x424344);
1157 fail_unless_equals_int_hex (GST_READ_UINT24_BE (carray + 2), 0x434445);
1158 fail_unless_equals_int_hex (GST_READ_UINT24_BE (carray + 3), 0x444546);
1159 fail_unless_equals_int_hex (GST_READ_UINT24_BE (carray + 4), 0x454647);
1160 fail_unless_equals_int_hex (GST_READ_UINT24_BE (carray + 5), 0x464748);
1161
1162 fail_unless_equals_int_hex (GST_READ_UINT24_LE (carray), 0x434241);
1163 fail_unless_equals_int_hex (GST_READ_UINT24_LE (carray + 1), 0x444342);
1164 fail_unless_equals_int_hex (GST_READ_UINT24_LE (carray + 2), 0x454443);
1165 fail_unless_equals_int_hex (GST_READ_UINT24_LE (carray + 3), 0x464544);
1166 fail_unless_equals_int_hex (GST_READ_UINT24_LE (carray + 4), 0x474645);
1167 fail_unless_equals_int_hex (GST_READ_UINT24_LE (carray + 5), 0x484746);
1168
1169 /* On an array of guint32 */
1170 fail_unless_equals_int_hex (GST_READ_UINT24_BE (uarray), 0x414243);
1171 fail_unless_equals_int_hex (GST_READ_UINT24_BE (uarray + 1), 0x454647);
1172
1173 fail_unless_equals_int_hex (GST_READ_UINT24_LE (uarray), 0x434241);
1174 fail_unless_equals_int_hex (GST_READ_UINT24_LE (uarray + 1), 0x474645);
1175
1176
1177 /* 32bit */
1178 /* First try the standard pointer variants */
1179 fail_unless_equals_int_hex (GST_READ_UINT32_BE (cpointer), 0x41424344);
1180 fail_unless_equals_int_hex (GST_READ_UINT32_BE (cpointer + 1), 0x42434445);
1181 fail_unless_equals_int_hex (GST_READ_UINT32_BE (cpointer + 2), 0x43444546);
1182 fail_unless_equals_int_hex (GST_READ_UINT32_BE (cpointer + 3), 0x44454647);
1183 fail_unless_equals_int_hex (GST_READ_UINT32_BE (cpointer + 4), 0x45464748);
1184
1185 fail_unless_equals_int_hex (GST_READ_UINT32_LE (cpointer), 0x44434241);
1186 fail_unless_equals_int_hex (GST_READ_UINT32_LE (cpointer + 1), 0x45444342);
1187 fail_unless_equals_int_hex (GST_READ_UINT32_LE (cpointer + 2), 0x46454443);
1188 fail_unless_equals_int_hex (GST_READ_UINT32_LE (cpointer + 3), 0x47464544);
1189 fail_unless_equals_int_hex (GST_READ_UINT32_LE (cpointer + 4), 0x48474645);
1190
1191 /* On an array of guint8 */
1192 fail_unless_equals_int_hex (GST_READ_UINT32_BE (carray), 0x41424344);
1193 fail_unless_equals_int_hex (GST_READ_UINT32_BE (carray + 1), 0x42434445);
1194 fail_unless_equals_int_hex (GST_READ_UINT32_BE (carray + 2), 0x43444546);
1195 fail_unless_equals_int_hex (GST_READ_UINT32_BE (carray + 3), 0x44454647);
1196 fail_unless_equals_int_hex (GST_READ_UINT32_BE (carray + 4), 0x45464748);
1197
1198 fail_unless_equals_int_hex (GST_READ_UINT32_LE (carray), 0x44434241);
1199 fail_unless_equals_int_hex (GST_READ_UINT32_LE (carray + 1), 0x45444342);
1200 fail_unless_equals_int_hex (GST_READ_UINT32_LE (carray + 2), 0x46454443);
1201 fail_unless_equals_int_hex (GST_READ_UINT32_LE (carray + 3), 0x47464544);
1202 fail_unless_equals_int_hex (GST_READ_UINT32_LE (carray + 4), 0x48474645);
1203
1204 /* On an array of guint32 */
1205 fail_unless_equals_int_hex (GST_READ_UINT32_BE (uarray), 0x41424344);
1206 fail_unless_equals_int_hex (GST_READ_UINT32_BE (uarray + 1), 0x45464748);
1207
1208 fail_unless_equals_int_hex (GST_READ_UINT32_LE (uarray), 0x44434241);
1209 fail_unless_equals_int_hex (GST_READ_UINT32_LE (uarray + 1), 0x48474645);
1210
1211
1212 /* 64bit */
1213 fail_unless_equals_int64_hex (GST_READ_UINT64_BE (cpointer),
1214 0x4142434445464748);
1215 fail_unless_equals_int64_hex (GST_READ_UINT64_LE (cpointer),
1216 0x4847464544434241);
1217
1218 fail_unless_equals_int64_hex (GST_READ_UINT64_BE (carray),
1219 0x4142434445464748);
1220 fail_unless_equals_int64_hex (GST_READ_UINT64_LE (carray),
1221 0x4847464544434241);
1222
1223 fail_unless_equals_int64_hex (GST_READ_UINT64_BE (uarray),
1224 0x4142434445464748);
1225 fail_unless_equals_int64_hex (GST_READ_UINT64_LE (uarray),
1226 0x4847464544434241);
1227
1228 /* make sure the data argument is not duplicated inside the macro
1229 * with possibly unexpected side-effects */
1230 cpointer = carray;
1231 fail_unless_equals_int (GST_READ_UINT8 (cpointer++), 'A');
1232 fail_unless (cpointer == carray + 1);
1233
1234 cpointer = carray;
1235 fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer++), 0x4142);
1236 fail_unless (cpointer == carray + 1);
1237
1238 cpointer = carray;
1239 fail_unless_equals_int_hex (GST_READ_UINT32_BE (cpointer++), 0x41424344);
1240 fail_unless (cpointer == carray + 1);
1241
1242 cpointer = carray;
1243 fail_unless_equals_int64_hex (GST_READ_UINT64_BE (cpointer++),
1244 0x4142434445464748);
1245 fail_unless (cpointer == carray + 1);
1246 }
1247
1248 GST_END_TEST;
1249
GST_START_TEST(test_write_macros)1250 GST_START_TEST (test_write_macros)
1251 {
1252 guint8 carray[8];
1253 guint8 *cpointer;
1254
1255 /* make sure the data argument is not duplicated inside the macro
1256 * with possibly unexpected side-effects */
1257 memset (carray, 0, sizeof (carray));
1258 cpointer = carray;
1259 GST_WRITE_UINT8 (cpointer++, 'A');
1260 fail_unless_equals_pointer (cpointer, carray + 1);
1261 fail_unless_equals_int (carray[0], 'A');
1262
1263 memset (carray, 0, sizeof (carray));
1264 cpointer = carray;
1265 GST_WRITE_UINT16_BE (cpointer++, 0x4142);
1266 fail_unless_equals_pointer (cpointer, carray + 1);
1267 fail_unless_equals_int (carray[0], 'A');
1268 fail_unless_equals_int (carray[1], 'B');
1269
1270 memset (carray, 0, sizeof (carray));
1271 cpointer = carray;
1272 GST_WRITE_UINT32_BE (cpointer++, 0x41424344);
1273 fail_unless_equals_pointer (cpointer, carray + 1);
1274 fail_unless_equals_int (carray[0], 'A');
1275 fail_unless_equals_int (carray[3], 'D');
1276
1277 memset (carray, 0, sizeof (carray));
1278 cpointer = carray;
1279 GST_WRITE_UINT64_BE (cpointer++, 0x4142434445464748);
1280 fail_unless_equals_pointer (cpointer, carray + 1);
1281 fail_unless_equals_int (carray[0], 'A');
1282 fail_unless_equals_int (carray[7], 'H');
1283
1284 memset (carray, 0, sizeof (carray));
1285 cpointer = carray;
1286 GST_WRITE_UINT16_LE (cpointer++, 0x4142);
1287 fail_unless_equals_pointer (cpointer, carray + 1);
1288 fail_unless_equals_int (carray[0], 'B');
1289 fail_unless_equals_int (carray[1], 'A');
1290
1291 memset (carray, 0, sizeof (carray));
1292 cpointer = carray;
1293 GST_WRITE_UINT32_LE (cpointer++, 0x41424344);
1294 fail_unless_equals_pointer (cpointer, carray + 1);
1295 fail_unless_equals_int (carray[0], 'D');
1296 fail_unless_equals_int (carray[3], 'A');
1297
1298 memset (carray, 0, sizeof (carray));
1299 cpointer = carray;
1300 GST_WRITE_UINT64_LE (cpointer++, 0x4142434445464748);
1301 fail_unless_equals_pointer (cpointer, carray + 1);
1302 fail_unless_equals_int (carray[0], 'H');
1303 fail_unless_equals_int (carray[7], 'A');
1304 }
1305
1306 GST_END_TEST;
1307
1308 static void
count_request_pad(const GValue * item,gpointer user_data)1309 count_request_pad (const GValue * item, gpointer user_data)
1310 {
1311 GstPad *pad = GST_PAD (g_value_get_object (item));
1312 guint *count = (guint *) user_data;
1313
1314 if (GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad)) == GST_PAD_REQUEST)
1315 (*count)++;
1316 }
1317
1318 static guint
request_pads(GstElement * element)1319 request_pads (GstElement * element)
1320 {
1321 GstIterator *iter;
1322 guint pads = 0;
1323
1324 iter = gst_element_iterate_pads (element);
1325 fail_unless (gst_iterator_foreach (iter, count_request_pad, &pads) ==
1326 GST_ITERATOR_DONE);
1327 gst_iterator_free (iter);
1328
1329 return pads;
1330 }
1331
1332 static GstPadLinkReturn
refuse_to_link(GstPad * pad,GstObject * parent,GstPad * peer)1333 refuse_to_link (GstPad * pad, GstObject * parent, GstPad * peer)
1334 {
1335 return GST_PAD_LINK_REFUSED;
1336 }
1337
1338 typedef struct _GstFakeReqSink GstFakeReqSink;
1339 typedef struct _GstFakeReqSinkClass GstFakeReqSinkClass;
1340
1341 struct _GstFakeReqSink
1342 {
1343 GstElement element;
1344 };
1345
1346 struct _GstFakeReqSinkClass
1347 {
1348 GstElementClass parent_class;
1349 };
1350
1351 G_GNUC_INTERNAL GType gst_fakereqsink_get_type (void);
1352
1353 static GstStaticPadTemplate fakereqsink_sink_template =
1354 GST_STATIC_PAD_TEMPLATE ("sink_%u",
1355 GST_PAD_SINK,
1356 GST_PAD_REQUEST,
1357 GST_STATIC_CAPS_ANY);
1358
1359 G_DEFINE_TYPE (GstFakeReqSink, gst_fakereqsink, GST_TYPE_ELEMENT);
1360
1361 static GstPad *
gst_fakereqsink_request_new_pad(GstElement * element,GstPadTemplate * templ,const gchar * name,const GstCaps * caps)1362 gst_fakereqsink_request_new_pad (GstElement * element, GstPadTemplate * templ,
1363 const gchar * name, const GstCaps * caps)
1364 {
1365 GstPad *pad;
1366 pad = gst_pad_new_from_static_template (&fakereqsink_sink_template, name);
1367 gst_pad_set_link_function (pad, refuse_to_link);
1368 gst_element_add_pad (GST_ELEMENT_CAST (element), pad);
1369 return pad;
1370 }
1371
1372 static void
gst_fakereqsink_release_pad(GstElement * element,GstPad * pad)1373 gst_fakereqsink_release_pad (GstElement * element, GstPad * pad)
1374 {
1375 gst_pad_set_active (pad, FALSE);
1376 gst_element_remove_pad (element, pad);
1377 }
1378
1379 static void
gst_fakereqsink_class_init(GstFakeReqSinkClass * klass)1380 gst_fakereqsink_class_init (GstFakeReqSinkClass * klass)
1381 {
1382 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
1383
1384 gst_element_class_set_static_metadata (gstelement_class,
1385 "Fake Request Sink", "Sink", "Fake sink with request pads",
1386 "Sebastian Rasmussen <sebras@hotmail.com>");
1387
1388 gst_element_class_add_static_pad_template (gstelement_class,
1389 &fakereqsink_sink_template);
1390
1391 gstelement_class->request_new_pad = gst_fakereqsink_request_new_pad;
1392 gstelement_class->release_pad = gst_fakereqsink_release_pad;
1393 }
1394
1395 static void
gst_fakereqsink_init(GstFakeReqSink * fakereqsink)1396 gst_fakereqsink_init (GstFakeReqSink * fakereqsink)
1397 {
1398 }
1399
1400 static void
test_link(const gchar * expectation,const gchar * srcname,const gchar * srcpad,const gchar * srcstate,const gchar * sinkname,const gchar * sinkpad,const gchar * sinkstate)1401 test_link (const gchar * expectation, const gchar * srcname,
1402 const gchar * srcpad, const gchar * srcstate, const gchar * sinkname,
1403 const gchar * sinkpad, const gchar * sinkstate)
1404 {
1405 GstElement *src, *sink, *othersrc, *othersink;
1406 guint src_pads, sink_pads;
1407
1408 if (g_strcmp0 (srcname, "requestsrc") == 0)
1409 src = gst_element_factory_make ("tee", NULL);
1410 else if (g_strcmp0 (srcname, "requestsink") == 0)
1411 src = gst_element_factory_make ("funnel", NULL);
1412 else if (g_strcmp0 (srcname, "staticsrc") == 0)
1413 src = gst_element_factory_make ("fakesrc", NULL);
1414 else if (g_strcmp0 (srcname, "staticsink") == 0)
1415 src = gst_element_factory_make ("fakesink", NULL);
1416 else
1417 g_assert_not_reached ();
1418
1419 if (g_strcmp0 (sinkname, "requestsink") == 0)
1420 sink = gst_element_factory_make ("funnel", NULL);
1421 else if (g_strcmp0 (sinkname, "requestsrc") == 0)
1422 sink = gst_element_factory_make ("tee", NULL);
1423 else if (g_strcmp0 (sinkname, "staticsink") == 0)
1424 sink = gst_element_factory_make ("fakesink", NULL);
1425 else if (g_strcmp0 (sinkname, "staticsrc") == 0)
1426 sink = gst_element_factory_make ("fakesrc", NULL);
1427 else if (g_strcmp0 (sinkname, "fakerequestsink") == 0)
1428 sink = gst_element_factory_make ("fakereqsink", NULL);
1429 else
1430 g_assert_not_reached ();
1431
1432 othersrc = gst_element_factory_make ("fakesrc", NULL);
1433 othersink = gst_element_factory_make ("fakesink", NULL);
1434
1435 if (g_strcmp0 (srcstate, "linked") == 0)
1436 fail_unless (gst_element_link_pads (src, srcpad, othersink, NULL));
1437 if (g_strcmp0 (sinkstate, "linked") == 0)
1438 fail_unless (gst_element_link_pads (othersrc, NULL, sink, sinkpad));
1439 if (g_strcmp0 (srcstate, "unlinkable") == 0) {
1440 GstPad *pad = gst_element_get_static_pad (src, srcpad ? srcpad : "src");
1441 gst_pad_set_link_function (pad, refuse_to_link);
1442 gst_object_unref (pad);
1443 }
1444 if (g_strcmp0 (sinkstate, "unlinkable") == 0) {
1445 GstPad *pad = gst_element_get_static_pad (sink, sinkpad ? sinkpad : "sink");
1446 gst_pad_set_link_function (pad, refuse_to_link);
1447 gst_object_unref (pad);
1448 }
1449
1450 src_pads = request_pads (src);
1451 sink_pads = request_pads (sink);
1452 if (g_strcmp0 (expectation, "OK") == 0) {
1453 fail_unless (gst_element_link_pads (src, srcpad, sink, sinkpad));
1454 if (g_str_has_prefix (srcname, "request")) {
1455 fail_unless_equals_int (request_pads (src), src_pads + 1);
1456 } else {
1457 fail_unless_equals_int (request_pads (src), src_pads);
1458 }
1459 if (g_str_has_prefix (sinkname, "request")) {
1460 fail_unless_equals_int (request_pads (sink), sink_pads + 1);
1461 } else {
1462 fail_unless_equals_int (request_pads (sink), sink_pads);
1463 }
1464 } else {
1465 fail_if (gst_element_link_pads (src, srcpad, sink, sinkpad));
1466 fail_unless_equals_int (request_pads (src), src_pads);
1467 fail_unless_equals_int (request_pads (sink), sink_pads);
1468 }
1469
1470 gst_object_unref (othersrc);
1471 gst_object_unref (othersink);
1472
1473 gst_object_unref (src);
1474 gst_object_unref (sink);
1475 }
1476
GST_START_TEST(test_element_link)1477 GST_START_TEST (test_element_link)
1478 {
1479 /* Successful cases */
1480
1481 gst_element_register (NULL, "fakereqsink", GST_RANK_NONE,
1482 gst_fakereqsink_get_type ());
1483
1484 test_link ("OK", "staticsrc", "src", "", "staticsink", "sink", "");
1485 test_link ("OK", "staticsrc", "src", "", "requestsink", "sink_0", "");
1486 test_link ("OK", "staticsrc", "src", "", "staticsink", NULL, "");
1487 test_link ("OK", "staticsrc", "src", "", "requestsink", NULL, "");
1488 test_link ("OK", "requestsrc", "src_0", "", "staticsink", "sink", "");
1489 test_link ("OK", "requestsrc", "src_0", "", "requestsink", "sink_0", "");
1490 test_link ("OK", "requestsrc", "src_0", "", "staticsink", NULL, "");
1491 test_link ("OK", "requestsrc", "src_0", "", "requestsink", NULL, "");
1492 test_link ("OK", "staticsrc", NULL, "", "staticsink", "sink", "");
1493 test_link ("OK", "staticsrc", NULL, "", "requestsink", "sink_0", "");
1494 test_link ("OK", "staticsrc", NULL, "", "staticsink", NULL, "");
1495 test_link ("OK", "staticsrc", NULL, "", "requestsink", NULL, "");
1496 test_link ("OK", "requestsrc", NULL, "", "staticsink", "sink", "");
1497 test_link ("OK", "requestsrc", NULL, "", "requestsink", "sink_0", "");
1498 test_link ("OK", "requestsrc", NULL, "", "staticsink", NULL, "");
1499 test_link ("OK", "requestsrc", NULL, "", "requestsink", NULL, "");
1500
1501 /* Failure cases */
1502
1503 test_link ("NOK", "staticsrc", "missing", "", "staticsink", "sink", "");
1504 test_link ("NOK", "staticsink", "sink", "", "staticsink", "sink", "");
1505 test_link ("NOK", "staticsrc", "src", "linked", "staticsink", "sink", "");
1506 test_link ("NOK", "staticsrc", "src", "", "staticsink", "missing", "");
1507 test_link ("NOK", "staticsrc", "src", "", "staticsrc", "src", "");
1508 test_link ("NOK", "staticsrc", "src", "", "staticsink", "sink", "linked");
1509 test_link ("NOK", "staticsrc", "src", "", "staticsink", "sink", "unlinkable");
1510 test_link ("NOK", "staticsrc", NULL, "", "staticsink", "sink", "unlinkable");
1511 test_link ("NOK", "staticsrc", NULL, "", "staticsink", NULL, "unlinkable");
1512 test_link ("NOK", "requestsrc", "missing", "", "staticsink", "sink", "");
1513 test_link ("NOK", "requestsink", "sink_0", "", "staticsink", "sink", "");
1514 test_link ("NOK", "requestsrc", "src_0", "linked", "staticsink", "sink", "");
1515 test_link ("NOK", "requestsrc", "src_0", "", "staticsink", "missing", "");
1516 test_link ("NOK", "requestsrc", "src_0", "", "staticsrc", "src", "");
1517 test_link ("NOK", "requestsrc", "src_0", "", "staticsink", "sink", "linked");
1518 test_link ("NOK", "requestsrc", "src_0", "", "staticsink", "sink",
1519 "unlinkable");
1520 test_link ("NOK", "requestsrc", NULL, "", "staticsink", "sink", "unlinkable");
1521 test_link ("NOK", "requestsrc", NULL, "", "staticsink", NULL, "unlinkable");
1522 test_link ("NOK", "staticsrc", "missing", "", "requestsink", "sink_0", "");
1523 test_link ("NOK", "staticsink", "sink", "", "requestsink", "sink_0", "");
1524 test_link ("NOK", "staticsrc", "src", "linked", "requestsink", "sink_0", "");
1525 test_link ("NOK", "staticsrc", "src", "", "requestsink", "missing", "");
1526 test_link ("NOK", "staticsrc", "src", "", "requestsrc", "src_0", "");
1527 test_link ("NOK", "staticsrc", "src", "", "requestsink", "sink_0", "linked");
1528 test_link ("NOK", "staticsrc", "src", "unlinkable", "requestsink",
1529 "sink_0", "");
1530 test_link ("NOK", "staticsrc", NULL, "unlinkable", "requestsink",
1531 "sink_0", "");
1532 test_link ("NOK", "staticsrc", NULL, "unlinkable", "requestsink", NULL, "");
1533 test_link ("NOK", "requestsrc", "src_0", "", "staticsink", NULL,
1534 "unlinkable");
1535 test_link ("NOK", "requestsrc", NULL, "", "fakerequestsink", NULL, "");
1536 }
1537
1538 GST_END_TEST;
1539
1540 typedef struct _GstTestPadReqSink GstTestPadReqSink;
1541 typedef struct _GstTestPadReqSinkClass GstTestPadReqSinkClass;
1542
1543 struct _GstTestPadReqSink
1544 {
1545 GstElement element;
1546 };
1547
1548 struct _GstTestPadReqSinkClass
1549 {
1550 GstElementClass parent_class;
1551 };
1552
1553 G_GNUC_INTERNAL GType gst_testpadreqsink_get_type (void);
1554
1555 static GstStaticPadTemplate testpadreqsink_video_template =
1556 GST_STATIC_PAD_TEMPLATE ("video_%u",
1557 GST_PAD_SINK,
1558 GST_PAD_REQUEST,
1559 GST_STATIC_CAPS ("video/x-raw"));
1560
1561 static GstStaticPadTemplate testpadreqsink_audio_template =
1562 GST_STATIC_PAD_TEMPLATE ("audio_%u",
1563 GST_PAD_SINK,
1564 GST_PAD_REQUEST,
1565 GST_STATIC_CAPS ("audio/x-raw"));
1566
1567 G_DEFINE_TYPE (GstTestPadReqSink, gst_testpadreqsink, GST_TYPE_ELEMENT);
1568
1569 static GstPad *
gst_testpadreqsink_request_new_pad(GstElement * element,GstPadTemplate * templ,const gchar * name,const GstCaps * caps)1570 gst_testpadreqsink_request_new_pad (GstElement * element,
1571 GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
1572 {
1573 GstPad *pad;
1574 pad = gst_pad_new_from_template (templ, name);
1575 gst_pad_set_active (pad, TRUE);
1576 gst_element_add_pad (GST_ELEMENT_CAST (element), pad);
1577 return pad;
1578 }
1579
1580 static void
gst_testpadreqsink_release_pad(GstElement * element,GstPad * pad)1581 gst_testpadreqsink_release_pad (GstElement * element, GstPad * pad)
1582 {
1583 gst_pad_set_active (pad, FALSE);
1584 gst_element_remove_pad (element, pad);
1585 }
1586
1587 static void
gst_testpadreqsink_class_init(GstTestPadReqSinkClass * klass)1588 gst_testpadreqsink_class_init (GstTestPadReqSinkClass * klass)
1589 {
1590 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
1591
1592 gst_element_class_set_static_metadata (gstelement_class,
1593 "Test Pad Request Sink", "Sink", "Sink for unit tests with request pads",
1594 "Thiago Santos <thiagoss@osg.samsung.com>");
1595
1596 gst_element_class_add_static_pad_template (gstelement_class,
1597 &testpadreqsink_video_template);
1598 gst_element_class_add_static_pad_template (gstelement_class,
1599 &testpadreqsink_audio_template);
1600
1601 gstelement_class->request_new_pad = gst_testpadreqsink_request_new_pad;
1602 gstelement_class->release_pad = gst_testpadreqsink_release_pad;
1603 }
1604
1605 static void
gst_testpadreqsink_init(GstTestPadReqSink * testpadeqsink)1606 gst_testpadreqsink_init (GstTestPadReqSink * testpadeqsink)
1607 {
1608 }
1609
1610 static GstCaps *padreqsink_query_caps = NULL;
1611
1612 static gboolean
testpadreqsink_peer_query(GstPad * pad,GstObject * parent,GstQuery * query)1613 testpadreqsink_peer_query (GstPad * pad, GstObject * parent, GstQuery * query)
1614 {
1615 gboolean res;
1616
1617 switch (GST_QUERY_TYPE (query)) {
1618 case GST_QUERY_CAPS:
1619 if (padreqsink_query_caps) {
1620 gst_query_set_caps_result (query, padreqsink_query_caps);
1621 res = TRUE;
1622 break;
1623 }
1624 default:
1625 res = gst_pad_query_default (pad, parent, query);
1626 break;
1627 }
1628
1629 return res;
1630 }
1631
1632 static void
check_get_compatible_pad_request(GstElement * element,GstCaps * peer_caps,GstCaps * filter,gboolean should_get_pad,const gchar * pad_tmpl_name)1633 check_get_compatible_pad_request (GstElement * element, GstCaps * peer_caps,
1634 GstCaps * filter, gboolean should_get_pad, const gchar * pad_tmpl_name)
1635 {
1636 GstPad *peer, *requested;
1637 GstPadTemplate *tmpl;
1638
1639 gst_caps_replace (&padreqsink_query_caps, peer_caps);
1640 peer = gst_pad_new ("src", GST_PAD_SRC);
1641 gst_pad_set_query_function (peer, testpadreqsink_peer_query);
1642 requested = gst_element_get_compatible_pad (element, peer, filter);
1643
1644 if (should_get_pad) {
1645 fail_unless (requested != NULL);
1646 if (pad_tmpl_name) {
1647 tmpl = gst_pad_get_pad_template (requested);
1648 fail_unless (strcmp (GST_PAD_TEMPLATE_NAME_TEMPLATE (tmpl),
1649 pad_tmpl_name) == 0);
1650 gst_object_unref (tmpl);
1651 }
1652 gst_element_release_request_pad (element, requested);
1653 gst_object_unref (requested);
1654 } else {
1655 fail_unless (requested == NULL);
1656 }
1657
1658 if (peer_caps)
1659 gst_caps_unref (peer_caps);
1660 if (filter)
1661 gst_caps_unref (filter);
1662 gst_object_unref (peer);
1663 }
1664
GST_START_TEST(test_element_get_compatible_pad_request)1665 GST_START_TEST (test_element_get_compatible_pad_request)
1666 {
1667 GstElement *element;
1668
1669 gst_element_register (NULL, "testpadreqsink", GST_RANK_NONE,
1670 gst_testpadreqsink_get_type ());
1671
1672 element = gst_element_factory_make ("testpadreqsink", NULL);
1673
1674 /* Try with a peer pad with any caps and no filter,
1675 * returning any pad is ok */
1676 check_get_compatible_pad_request (element, NULL, NULL, TRUE, NULL);
1677 /* Try with a peer pad with any caps and video as filter */
1678 check_get_compatible_pad_request (element, NULL,
1679 gst_caps_from_string ("video/x-raw"), TRUE, "video_%u");
1680 /* Try with a peer pad with any caps and audio as filter */
1681 check_get_compatible_pad_request (element, NULL,
1682 gst_caps_from_string ("audio/x-raw"), TRUE, "audio_%u");
1683 /* Try with a peer pad with any caps and fake caps as filter */
1684 check_get_compatible_pad_request (element, NULL,
1685 gst_caps_from_string ("foo/bar"), FALSE, NULL);
1686
1687 /* Try with a peer pad with video caps and no caps as filter */
1688 check_get_compatible_pad_request (element,
1689 gst_caps_from_string ("video/x-raw"), NULL, TRUE, "video_%u");
1690 /* Try with a peer pad with audio caps and no caps as filter */
1691 check_get_compatible_pad_request (element,
1692 gst_caps_from_string ("audio/x-raw"), NULL, TRUE, "audio_%u");
1693 /* Try with a peer pad with video caps and foo caps as filter */
1694 check_get_compatible_pad_request (element,
1695 gst_caps_from_string ("video/x-raw"), gst_caps_from_string ("foo/bar"),
1696 FALSE, NULL);
1697
1698 gst_caps_replace (&padreqsink_query_caps, NULL);
1699 gst_object_unref (element);
1700 }
1701
1702 GST_END_TEST;
1703
GST_START_TEST(test_element_link_with_ghost_pads)1704 GST_START_TEST (test_element_link_with_ghost_pads)
1705 {
1706 GstElement *sink_bin, *sink2_bin, *pipeline;
1707 GstElement *src, *tee, *queue, *queue2, *sink, *sink2;
1708 GstMessage *message;
1709 GstBus *bus;
1710
1711 fail_unless (pipeline = gst_pipeline_new (NULL));
1712 fail_unless (sink_bin = gst_bin_new (NULL));
1713 fail_unless (sink2_bin = gst_bin_new (NULL));
1714 fail_unless (src = gst_element_factory_make ("fakesrc", NULL));
1715 fail_unless (tee = gst_element_factory_make ("tee", NULL));
1716 fail_unless (queue = gst_element_factory_make ("queue", NULL));
1717 fail_unless (sink = gst_element_factory_make ("fakesink", NULL));
1718 fail_unless (queue2 = gst_element_factory_make ("queue", NULL));
1719 fail_unless (sink2 = gst_element_factory_make ("fakesink", NULL));
1720
1721 gst_bin_add_many (GST_BIN (pipeline), src, tee, queue, sink, sink2_bin, NULL);
1722 fail_unless (gst_element_link_many (src, tee, queue, sink, NULL));
1723 fail_unless (gst_element_set_state (pipeline,
1724 GST_STATE_PLAYING) == GST_STATE_CHANGE_ASYNC);
1725
1726 /* wait for a buffer to arrive at the sink */
1727 bus = gst_element_get_bus (pipeline);
1728 message = gst_bus_poll (bus, GST_MESSAGE_ASYNC_DONE, -1);
1729 gst_message_unref (message);
1730 gst_object_unref (bus);
1731
1732 gst_bin_add_many (GST_BIN (sink_bin), queue2, sink2, NULL);
1733 fail_unless (gst_element_link (queue2, sink2));
1734
1735 gst_bin_add (GST_BIN (sink2_bin), sink_bin);
1736 /* The two levels of bins with the outer bin in the running state is
1737 * important, when the second ghost pad is created (from this
1738 * gst_element_link()) in the running bin, we need to activate the
1739 * created ghost pad */
1740 fail_unless (gst_element_link (tee, queue2));
1741
1742 fail_unless (gst_element_set_state (pipeline,
1743 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
1744
1745 gst_object_unref (pipeline);
1746 }
1747
1748 GST_END_TEST;
1749
1750 static const GstClockTime times1[] = {
1751 257116899087539, 120632754291904,
1752 257117935914250, 120633825367344,
1753 257119448289434, 120635306141271,
1754 257120493671524, 120636384357825,
1755 257121550784861, 120637417438878,
1756 257123042669403, 120638895344150,
1757 257124089184865, 120639971729651,
1758 257125545836474, 120641406788243,
1759 257127030618490, 120642885914220,
1760 257128033712770, 120643888843907,
1761 257129081768074, 120644981892002,
1762 257130145383845, 120646016376867,
1763 257131532530200, 120647389850987,
1764 257132578136034, 120648472767247,
1765 257134102475722, 120649953785315,
1766 257135142994788, 120651028858556,
1767 257136585079868, 120652441303624,
1768 257137618260656, 120653491627112,
1769 257139108694546, 120654963978184,
1770 257140644022048, 120656500233068,
1771 257141685671825, 120657578510655,
1772 257142741238288, 120658610889805,
1773 257144243633074, 120660093098060,
1774 257145287962271, 120661172901525,
1775 257146740596716, 120662591572179,
1776 257147757607150, 120663622822179,
1777 257149263992401, 120665135578527,
1778 257150303719290, 120666176166905,
1779 257151355569906, 120667217304601,
1780 257152430578406, 120668326099768,
1781 257153490501095, 120669360554111,
1782 257154512360784, 120670365497960,
1783 257155530610577, 120671399006259,
1784 257156562091659, 120672432728185,
1785 257157945388742, 120673800312414,
1786 257159287547073, 120675142444983,
1787 257160324912880, 120676215076817,
1788 257345408328042, 120861261738196,
1789 257346412270919, 120862265613926,
1790 257347420532284, 120863278644933,
1791 257348431187638, 120864284412754,
1792 257349439018028, 120865293110265,
1793 257351796217938, 120867651111973,
1794 257352803038092, 120868659107578,
1795 257354152688899, 120870008594883,
1796 257355157088906, 120871011097327,
1797 257356162439182, 120872016346348,
1798 257357167872040, 120873021656407,
1799 257358182440058, 120874048633945,
1800 257359198881356, 120875052265538,
1801 257100756525466, 120616619282139,
1802 257101789337770, 120617655475988,
1803 257102816323472, 120618674000157,
1804 257103822485250, 120619679005039,
1805 257104840760423, 120620710743321,
1806 257105859459496, 120621715351476,
1807 257106886662470, 120622764942539,
1808 257108387497864, 120624244221106,
1809 257109428859191, 120625321461096,
1810 257110485892785, 120626356892003,
1811 257111869872141, 120627726459874,
1812 257112915903774, 120628813190830,
1813 257114329982208, 120630187061682,
1814 257115376666026, 120631271992101
1815 };
1816
1817
1818 static const GstClockTime times2[] = {
1819 291678579009762, 162107345029507,
1820 291679770464405, 162108597684538,
1821 291680972924370, 162109745816863,
1822 291682278949629, 162111000577605,
1823 291683590706117, 162112357724822,
1824 291684792322541, 162113613156950,
1825 291685931362506, 162114760556854,
1826 291687132156589, 162115909238493,
1827 291688265012060, 162117120603240,
1828 291689372183047, 162118126279508,
1829 291705506022294, 162134329373992,
1830 291667914301004, 162096795553658,
1831 291668119537668, 162096949051905,
1832 291668274671455, 162097049238371,
1833 291668429435600, 162097256356719,
1834 291668586128535, 162097355689763,
1835 291668741306233, 162097565678460,
1836 291668893789203, 162097661044916,
1837 291669100256555, 162097865694145,
1838 291669216417563, 162098069214693,
1839 291669836394620, 162098677275530,
1840 291669990447821, 162098792601263,
1841 291670149426086, 162098916899184,
1842 291670300232152, 162099114225621,
1843 291670411261917, 162099236784112,
1844 291670598483507, 162099402158751,
1845 291671716582687, 162100558744122,
1846 291672600759788, 162101499326359,
1847 291673919988307, 162102751981384,
1848 291675174441643, 162104005551939,
1849 291676271562197, 162105105252898,
1850 291677376345374, 162106195737516
1851 };
1852
1853 static const GstClockTime times3[] = {
1854 291881924291688, 162223997578228,
1855 291883318122262, 162224167198360,
1856 291884786394838, 162224335172501,
1857 291886004374386, 162224503695531,
1858 291887224353285, 162224673560021,
1859 291888472403367, 162224843760361,
1860 291889727977561, 162225014479362,
1861 291890989982306, 162225174554558,
1862 291892247875763, 162225339753039,
1863 291893502163547, 162225673230987,
1864 291894711382216, 162225829494101,
1865 291895961021506, 162225964530832,
1866 291897251690854, 162226127287981,
1867 291898508630785, 162226303710406,
1868 291899740172868, 162226472478047,
1869 291900998878873, 162226637402085,
1870 291902334919875, 162226797873245,
1871 291903572196610, 162226964352963,
1872 291904727342699, 162227125312525,
1873 291906071189108, 162228361337153,
1874 291907308146005, 162229560625638,
1875 291908351925126, 162230604986650,
1876 291909396411423, 162231653690543,
1877 291910453965348, 162232698550995,
1878 291912096870744, 162233475264947,
1879 291913234148395, 162233606516855,
1880 291915448096576, 162233921145559,
1881 291916707748827, 162234047154298,
1882 291918737451070, 162234370837425,
1883 291919896016205, 162234705504337,
1884 291921098663980, 162234872320397,
1885 291922315691409, 162235031023366
1886 };
1887
1888 static const GstClockTime times4[] = {
1889 10, 0,
1890 20, 20,
1891 30, 40,
1892 40, 60,
1893 50, 80,
1894 60, 100
1895 };
1896
1897 struct test_entry
1898 {
1899 gint n;
1900 const GstClockTime *v;
1901 GstClockTime expect_internal;
1902 GstClockTime expect_external;
1903 guint64 expect_num;
1904 guint64 expect_denom;
1905 } times[] = {
1906 {
1907 32, times1, 257154512360784, 120670380469753, 4052622913376634109,
1908 4052799313904261962}, {
1909 64, times1, 257359198881356, 120875054227405, 2011895759027682422,
1910 2012014931360215503}, {
1911 32, times2, 291705506022294, 162134297192792, 2319535707505209857,
1912 2321009753483354451}, {
1913 32, times3, 291922315691409, 162234934150296, 1370930728180888261,
1914 4392719527011673456}, {
1915 6, times4, 60, 100, 2, 1}
1916 };
1917
GST_START_TEST(test_regression)1918 GST_START_TEST (test_regression)
1919 {
1920 GstClockTime m_num, m_den, internal, external;
1921 gdouble r_squared, rate, expect_rate;
1922 gint i;
1923
1924 for (i = 0; i < G_N_ELEMENTS (times); i++) {
1925 fail_unless (gst_calculate_linear_regression (times[i].v, NULL, times[i].n,
1926 &m_num, &m_den, &external, &internal, &r_squared));
1927
1928 GST_LOG ("xbase %" G_GUINT64_FORMAT " ybase %" G_GUINT64_FORMAT " rate = %"
1929 G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT " = %.10f r_squared %f\n",
1930 internal, external, m_num, m_den, (gdouble) (m_num) / (m_den),
1931 r_squared);
1932
1933 /* Require high correlation */
1934 fail_unless (r_squared >= 0.9);
1935
1936 fail_unless (internal == times[i].expect_internal,
1937 "Regression params %d fail. internal %" G_GUINT64_FORMAT
1938 " != expected %" G_GUINT64_FORMAT, i, internal,
1939 times[i].expect_internal);
1940 /* Rate must be within 1% tolerance */
1941 expect_rate = ((gdouble) (times[i].expect_num) / times[i].expect_denom);
1942 rate = ((gdouble) (m_num) / m_den);
1943 fail_unless ((expect_rate - rate) >= -0.1 && (expect_rate - rate) <= 0.1,
1944 "Regression params %d fail. Rate out of range. Expected %f, got %f",
1945 i, expect_rate, rate);
1946 fail_unless (external >= times[i].expect_external * 0.99 &&
1947 external <= times[i].expect_external * 1.01,
1948 "Regression params %d fail. external %" G_GUINT64_FORMAT
1949 " != expected %" G_GUINT64_FORMAT, i, external,
1950 times[i].expect_external);
1951 }
1952 }
1953
1954 GST_END_TEST;
1955
1956 static Suite *
gst_utils_suite(void)1957 gst_utils_suite (void)
1958 {
1959 Suite *s = suite_create ("GstUtils");
1960 TCase *tc_chain = tcase_create ("general");
1961
1962 suite_add_tcase (s, tc_chain);
1963 tcase_add_test (tc_chain, test_buffer_probe_n_times);
1964 tcase_add_test (tc_chain, test_buffer_probe_once);
1965 tcase_add_test (tc_chain, test_math_scale);
1966 tcase_add_test (tc_chain, test_math_scale_round);
1967 tcase_add_test (tc_chain, test_math_scale_ceil);
1968 tcase_add_test (tc_chain, test_math_scale_uint64);
1969 tcase_add_test (tc_chain, test_math_scale_random);
1970 #ifdef HAVE_GSL
1971 #ifdef HAVE_GMP
1972 tcase_add_test (tc_chain, test_math_scale_gmp);
1973 tcase_add_test (tc_chain, test_math_scale_gmp_int);
1974 #endif
1975 #endif
1976
1977 tcase_add_test (tc_chain, test_guint64_to_gdouble);
1978 tcase_add_test (tc_chain, test_gdouble_to_guint64);
1979 #ifndef GST_DISABLE_PARSE
1980 tcase_add_test (tc_chain, test_parse_bin_from_description);
1981 #endif
1982 tcase_add_test (tc_chain, test_element_found_tags);
1983 tcase_add_test (tc_chain, test_element_link);
1984 tcase_add_test (tc_chain, test_element_link_with_ghost_pads);
1985 tcase_add_test (tc_chain, test_element_unlink);
1986 tcase_add_test (tc_chain, test_element_get_compatible_pad_request);
1987 tcase_add_test (tc_chain, test_set_value_from_string);
1988 tcase_add_test (tc_chain, test_binary_search);
1989
1990 tcase_add_test (tc_chain, test_pad_proxy_query_caps_aggregation);
1991 tcase_add_test (tc_chain, test_greatest_common_divisor);
1992
1993 tcase_add_test (tc_chain, test_read_macros);
1994 tcase_add_test (tc_chain, test_write_macros);
1995 tcase_add_test (tc_chain, test_regression);
1996
1997 return s;
1998 }
1999
2000 GST_CHECK_MAIN (gst_utils);
2001