18ba199b98dc6926def327925da14cbc18b194ab
[platform/upstream/gstreamer.git] / tests / check / gst / gstutils.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
665 _binary_search_compare (guint32 * a, guint32 * b)
666 {
667   return *a - *b;
668 }
669
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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
1396 gst_fakereqsink_init (GstFakeReqSink * fakereqsink)
1397 {
1398 }
1399
1400 static void
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
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 *
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
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
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
1606 gst_testpadreqsink_init (GstTestPadReqSink * testpadeqsink)
1607 {
1608 }
1609
1610 static GstCaps *padreqsink_query_caps = NULL;
1611
1612 static gboolean
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
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
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
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
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 *
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);