• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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