2 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
4 * gstpad.c: Unit test for GstPad
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include <gst/check/gstcheck.h>
24 GST_START_TEST (test_link)
32 src = gst_pad_new ("source", GST_PAD_SRC);
33 fail_if (src == NULL);
34 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
36 name = gst_pad_get_name (src);
37 fail_unless (strcmp (name, "source") == 0);
38 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
41 sink = gst_pad_new ("sink", GST_PAD_SINK);
42 fail_if (sink == NULL);
44 /* linking without templates or caps should fail */
45 ret = gst_pad_link (src, sink);
46 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
47 ASSERT_OBJECT_REFCOUNT (sink, "sink pad", 1);
48 fail_unless (ret == GST_PAD_LINK_NOFORMAT);
50 ASSERT_CRITICAL (gst_pad_get_pad_template (NULL));
52 srct = gst_pad_get_pad_template (src);
53 fail_unless (srct == NULL);
54 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
57 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
58 gst_object_unref (src);
59 gst_object_unref (sink);
64 /* threaded link/unlink */
66 static GstPad *src, *sink;
69 thread_link_unlink (gpointer data)
73 while (THREAD_TEST_RUNNING ()) {
74 gst_pad_link (src, sink);
75 gst_pad_unlink (src, sink);
80 GST_START_TEST (test_link_unlink_threaded)
85 src = gst_pad_new ("source", GST_PAD_SRC);
86 fail_if (src == NULL);
87 sink = gst_pad_new ("sink", GST_PAD_SINK);
88 fail_if (sink == NULL);
90 caps = gst_caps_from_string ("foo/bar");
91 gst_pad_set_caps (src, caps);
92 gst_pad_set_active (sink, TRUE);
93 gst_pad_set_caps (sink, caps);
94 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
96 MAIN_START_THREADS (5, thread_link_unlink, NULL);
97 for (i = 0; i < 1000; ++i) {
98 gst_pad_is_linked (src);
99 gst_pad_is_linked (sink);
102 MAIN_STOP_THREADS ();
104 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
105 gst_caps_unref (caps);
107 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
108 gst_object_unref (src);
109 gst_object_unref (sink);
114 GST_START_TEST (test_refcount)
118 GstPadLinkReturn plr;
120 sink = gst_pad_new ("sink", GST_PAD_SINK);
121 fail_if (sink == NULL);
123 src = gst_pad_new ("src", GST_PAD_SRC);
124 fail_if (src == NULL);
126 caps = gst_caps_from_string ("foo/bar");
128 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
130 /* can't set caps on flushing sinkpad */
131 fail_if (gst_pad_set_caps (src, caps) == TRUE);
132 fail_if (gst_pad_set_caps (sink, caps) == TRUE);
133 /* one for me and one for each set_caps */
134 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
136 gst_pad_set_active (src, TRUE);
137 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
138 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
140 gst_pad_set_active (sink, TRUE);
141 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
142 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
144 plr = gst_pad_link (src, sink);
145 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
146 /* src caps added to pending caps on sink */
147 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
149 gst_pad_unlink (src, sink);
150 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
153 gst_object_unref (src);
154 gst_object_unref (sink);
155 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
157 gst_caps_unref (caps);
162 GST_START_TEST (test_get_allowed_caps)
165 GstCaps *caps, *gotcaps;
167 GstPadLinkReturn plr;
169 ASSERT_CRITICAL (gst_pad_get_allowed_caps (NULL));
171 buffer = gst_buffer_new ();
172 ASSERT_CRITICAL (gst_pad_get_allowed_caps ((GstPad *) buffer));
173 gst_buffer_unref (buffer);
175 src = gst_pad_new ("src", GST_PAD_SRC);
176 fail_if (src == NULL);
177 caps = gst_pad_get_allowed_caps (src);
178 fail_unless (caps == NULL);
180 caps = gst_caps_from_string ("foo/bar");
182 sink = gst_pad_new ("sink", GST_PAD_SINK);
183 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
184 fail_if (gst_pad_set_caps (sink, caps) == TRUE);
185 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
187 gst_pad_set_active (sink, TRUE);
188 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
189 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
191 plr = gst_pad_link (src, sink);
192 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
194 gotcaps = gst_pad_get_allowed_caps (src);
195 fail_if (gotcaps == NULL);
197 /* FIXME, does not work, caps events are different so the sinkpad loses caps
199 fail_unless (gst_caps_is_equal (gotcaps, caps));
202 ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 1);
203 gst_caps_unref (gotcaps);
205 gst_pad_unlink (src, sink);
208 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
209 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
210 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
212 gst_object_unref (src);
213 gst_object_unref (sink);
215 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
216 gst_caps_unref (caps);
221 static GstCaps *event_caps = NULL;
224 sticky_event (GstPad * pad, GstObject * parent, GstEvent * event)
228 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
230 /* Ensure we get here just once: */
231 fail_unless (event_caps == NULL);
233 /* The event must arrive before any buffer: */
234 fail_unless_equals_int (g_list_length (buffers), 0);
236 gst_event_parse_caps (event, &caps);
237 event_caps = gst_caps_ref (caps);
239 gst_event_unref (event);
244 GST_START_TEST (test_sticky_caps_unlinked)
247 GstPadTemplate *src_template, *sink_template;
251 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
252 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
253 GST_PAD_ALWAYS, caps);
254 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
255 GST_PAD_ALWAYS, caps);
256 gst_caps_unref (caps);
258 src = gst_pad_new_from_template (src_template, "src");
259 fail_if (src == NULL);
260 sink = gst_pad_new_from_template (sink_template, "sink");
261 fail_if (sink == NULL);
262 gst_pad_set_event_function (sink, sticky_event);
263 gst_pad_set_chain_function (sink, gst_check_chain_func);
265 gst_object_unref (src_template);
266 gst_object_unref (sink_template);
268 caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
269 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
271 event = gst_event_new_caps (caps);
272 /* Pad is still inactive but the event gets stored sticky, so push is
274 fail_unless (gst_pad_push_event (src, event) == TRUE);
275 fail_unless (event_caps == NULL);
277 /* Linking and activating will not forward the sticky event yet... */
278 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
279 gst_pad_set_active (src, TRUE);
280 gst_pad_set_active (sink, TRUE);
281 fail_unless (event_caps == NULL);
283 /* ...but the first buffer will: */
284 fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
285 fail_unless (event_caps == caps);
286 fail_unless_equals_int (g_list_length (buffers), 1);
288 gst_caps_replace (&caps, NULL);
289 gst_caps_replace (&event_caps, NULL);
291 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
292 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
293 gst_object_unref (src);
294 gst_object_unref (sink);
299 /* Like test_sticky_caps_unlinked, but link before caps: */
301 GST_START_TEST (test_sticky_caps_flushing)
304 GstPadTemplate *src_template, *sink_template;
308 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
309 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
310 GST_PAD_ALWAYS, caps);
311 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
312 GST_PAD_ALWAYS, caps);
313 gst_caps_unref (caps);
315 src = gst_pad_new_from_template (src_template, "src");
316 fail_if (src == NULL);
317 sink = gst_pad_new_from_template (sink_template, "sink");
318 fail_if (sink == NULL);
319 gst_pad_set_event_function (sink, sticky_event);
320 gst_pad_set_chain_function (sink, gst_check_chain_func);
322 gst_object_unref (src_template);
323 gst_object_unref (sink_template);
325 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
327 caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
328 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
330 event = gst_event_new_caps (caps);
331 /* Pads are still inactive but event gets stored sticky, so push is
333 fail_unless (gst_pad_push_event (src, event) == TRUE);
334 fail_unless (event_caps == NULL);
336 /* Activating will not forward the sticky event yet... */
337 gst_pad_set_active (src, TRUE);
338 gst_pad_set_active (sink, TRUE);
339 fail_unless (event_caps == NULL);
341 /* ...but the first buffer will: */
342 fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
343 fail_unless (event_caps == caps);
344 fail_unless_equals_int (g_list_length (buffers), 1);
346 gst_caps_replace (&caps, NULL);
347 gst_caps_replace (&event_caps, NULL);
349 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
350 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
351 gst_object_unref (src);
352 gst_object_unref (sink);
358 name_is_valid (const gchar * name, GstPadPresence presence)
361 GstCaps *any = gst_caps_new_any ();
363 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
364 gst_caps_unref (any);
366 gst_object_unref (GST_OBJECT (new));
372 GST_START_TEST (test_name_is_valid)
374 gboolean result = FALSE;
376 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
377 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
378 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
381 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
382 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
383 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
384 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
385 ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
387 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
388 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
393 static GstPadProbeReturn
394 _probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
396 gint ret = GPOINTER_TO_INT (userdata);
399 return GST_PAD_PROBE_OK;
401 return GST_PAD_PROBE_DROP;
404 GST_START_TEST (test_push_unlinked)
411 src = gst_pad_new ("src", GST_PAD_SRC);
412 fail_if (src == NULL);
413 caps = gst_pad_get_allowed_caps (src);
414 fail_unless (caps == NULL);
416 caps = gst_caps_from_string ("foo/bar");
418 gst_pad_set_caps (src, caps);
419 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
421 /* pushing on an inactive pad will return wrong state */
422 buffer = gst_buffer_new ();
423 gst_buffer_ref (buffer);
424 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
425 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
426 gst_buffer_unref (buffer);
428 gst_pad_set_active (src, TRUE);
430 /* pushing on an unlinked pad will drop the buffer */
431 buffer = gst_buffer_new ();
432 gst_buffer_ref (buffer);
433 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
434 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
435 gst_buffer_unref (buffer);
437 /* adding a probe that returns _DROP will drop the buffer without trying
439 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
440 _probe_handler, GINT_TO_POINTER (0), NULL);
441 buffer = gst_buffer_new ();
442 gst_buffer_ref (buffer);
443 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
444 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
445 gst_buffer_unref (buffer);
446 gst_pad_remove_probe (src, id);
448 /* adding a probe that returns _OK will still chain the buffer,
449 * and hence drop because pad is unlinked */
450 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
451 _probe_handler, GINT_TO_POINTER (1), NULL);
452 buffer = gst_buffer_new ();
453 gst_buffer_ref (buffer);
454 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
455 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
456 gst_buffer_unref (buffer);
457 gst_pad_remove_probe (src, id);
461 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
462 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
464 gst_object_unref (src);
466 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
467 gst_caps_unref (caps);
472 GST_START_TEST (test_push_linked)
475 GstPadLinkReturn plr;
481 sink = gst_pad_new ("sink", GST_PAD_SINK);
482 fail_if (sink == NULL);
483 gst_pad_set_chain_function (sink, gst_check_chain_func);
485 src = gst_pad_new ("src", GST_PAD_SRC);
486 fail_if (src == NULL);
488 caps = gst_caps_from_string ("foo/bar");
490 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
492 gst_pad_set_caps (src, caps);
493 gst_pad_set_active (sink, TRUE);
494 gst_pad_set_caps (sink, caps);
495 /* one for me and one for each set_caps */
496 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
498 plr = gst_pad_link (src, sink);
499 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
500 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
502 buffer = gst_buffer_new ();
504 /* FIXME, new pad should be flushing */
505 gst_buffer_ref (buffer);
506 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
507 gst_buffer_ref (buffer);
508 fail_unless (gst_pad_chain (sink, buffer) == GST_FLOW_WRONG_STATE);
512 gst_pad_set_active (src, TRUE);
513 gst_pad_set_active (sink, TRUE);
516 /* pushing on a linked pad will drop the ref to the buffer */
517 gst_buffer_ref (buffer);
518 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
519 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
520 gst_buffer_unref (buffer);
521 fail_unless_equals_int (g_list_length (buffers), 1);
522 buffer = GST_BUFFER (buffers->data);
523 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
524 gst_buffer_unref (buffer);
525 g_list_free (buffers);
528 /* adding a probe that returns FALSE will drop the buffer without trying
530 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
531 _probe_handler, GINT_TO_POINTER (0), NULL);
532 buffer = gst_buffer_new ();
533 gst_buffer_ref (buffer);
534 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
535 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
536 gst_buffer_unref (buffer);
537 gst_pad_remove_probe (src, id);
538 fail_unless_equals_int (g_list_length (buffers), 0);
540 /* adding a probe that returns TRUE will still chain the buffer */
541 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
542 _probe_handler, GINT_TO_POINTER (1), NULL);
543 buffer = gst_buffer_new ();
544 gst_buffer_ref (buffer);
545 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
546 gst_pad_remove_probe (src, id);
548 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
549 gst_buffer_unref (buffer);
550 fail_unless_equals_int (g_list_length (buffers), 1);
551 buffer = GST_BUFFER (buffers->data);
552 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
553 gst_buffer_unref (buffer);
554 g_list_free (buffers);
558 gst_pad_unlink (src, sink);
559 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
560 gst_object_unref (src);
561 gst_object_unref (sink);
562 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
564 gst_caps_unref (caps);
569 GST_START_TEST (test_push_linked_flushing)
573 GstPadLinkReturn plr;
578 src = gst_pad_new ("src", GST_PAD_SRC);
579 fail_if (src == NULL);
580 sink = gst_pad_new ("sink", GST_PAD_SINK);
581 fail_if (sink == NULL);
582 gst_pad_set_chain_function (sink, gst_check_chain_func);
584 caps = gst_pad_get_allowed_caps (src);
585 fail_unless (caps == NULL);
586 caps = gst_pad_get_allowed_caps (sink);
587 fail_unless (caps == NULL);
589 caps = gst_caps_from_string ("foo/bar");
591 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
593 gst_pad_set_caps (src, caps);
594 /* need to activate to make it accept the caps */
595 gst_pad_set_active (sink, TRUE);
596 gst_pad_set_caps (sink, caps);
597 /* one for me and one for each set_caps */
598 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
600 plr = gst_pad_link (src, sink);
601 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
602 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
604 /* not activating the pads here, which keeps them flushing */
606 /* pushing on a flushing pad will drop the buffer */
607 buffer = gst_buffer_new ();
608 gst_buffer_ref (buffer);
609 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
610 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
611 fail_unless_equals_int (g_list_length (buffers), 0);
612 gst_buffer_unref (buffer);
614 gst_pad_set_active (src, TRUE);
615 gst_pad_set_active (sink, FALSE);
617 /* adding a probe that returns FALSE will drop the buffer without trying
619 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
620 GINT_TO_POINTER (0), NULL);
621 buffer = gst_buffer_new ();
622 gst_buffer_ref (buffer);
623 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
624 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
625 fail_unless_equals_int (g_list_length (buffers), 0);
626 gst_buffer_unref (buffer);
627 gst_pad_remove_probe (src, id);
629 /* adding a probe that returns TRUE will still chain the buffer,
630 * and hence drop because pad is flushing */
631 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
632 GINT_TO_POINTER (1), NULL);
633 buffer = gst_buffer_new ();
634 gst_buffer_ref (buffer);
635 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
636 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
637 fail_unless_equals_int (g_list_length (buffers), 0);
638 gst_buffer_unref (buffer);
639 gst_pad_remove_probe (src, id);
642 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
643 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
644 gst_pad_link (src, sink);
645 gst_object_unref (src);
646 gst_object_unref (sink);
647 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
648 gst_caps_unref (caps);
654 buffer_from_string (const gchar * str)
661 buf = gst_buffer_new_and_alloc (size);
663 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
664 memcpy (data, str, size);
665 gst_buffer_unmap (buf, data, size);
671 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
676 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
677 res = memcmp (data, str, size) == 0;
678 GST_DEBUG ("%s <-> %s: %d", (gchar *) data, str, res);
679 gst_buffer_unmap (buf, data, size);
684 GST_START_TEST (test_push_buffer_list_compat)
687 GstPadLinkReturn plr;
693 sink = gst_pad_new ("sink", GST_PAD_SINK);
694 fail_if (sink == NULL);
695 gst_pad_set_chain_function (sink, gst_check_chain_func);
696 /* leave chainlistfunc unset */
698 src = gst_pad_new ("src", GST_PAD_SRC);
699 fail_if (src == NULL);
701 caps = gst_caps_from_string ("foo/bar");
703 gst_pad_set_caps (src, caps);
704 gst_pad_set_active (sink, TRUE);
705 gst_pad_set_caps (sink, caps);
707 plr = gst_pad_link (src, sink);
708 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
710 list = gst_buffer_list_new ();
713 gst_pad_set_active (src, TRUE);
714 gst_pad_set_active (sink, TRUE);
717 /* adding to a buffer list will drop the ref to the buffer */
718 gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
719 gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
721 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
722 fail_unless_equals_int (g_list_length (buffers), 2);
723 buffer = GST_BUFFER (buffers->data);
724 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
725 fail_unless (buffer_compare (buffer, "ListGroup", 9));
726 gst_buffer_unref (buffer);
727 buffers = g_list_delete_link (buffers, buffers);
728 buffer = GST_BUFFER (buffers->data);
729 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
730 fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
731 gst_buffer_unref (buffer);
732 buffers = g_list_delete_link (buffers, buffers);
733 fail_unless (buffers == NULL);
736 gst_pad_unlink (src, sink);
737 gst_object_unref (src);
738 gst_object_unref (sink);
739 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
740 gst_caps_unref (caps);
745 GST_START_TEST (test_flowreturn)
750 /* test some of the macros */
752 fail_if (strcmp (gst_flow_get_name (ret), "eos"));
753 quark = gst_flow_to_quark (ret);
754 fail_if (strcmp (g_quark_to_string (quark), "eos"));
756 ret = GST_FLOW_RESEND;
757 fail_if (strcmp (gst_flow_get_name (ret), "resend"));
758 quark = gst_flow_to_quark (ret);
759 fail_if (strcmp (g_quark_to_string (quark), "resend"));
762 ret = GST_FLOW_CUSTOM_SUCCESS;
763 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
764 quark = gst_flow_to_quark (ret);
765 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
767 ret = GST_FLOW_CUSTOM_ERROR;
768 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
769 quark = gst_flow_to_quark (ret);
770 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
772 /* custom returns clamping */
773 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
774 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
775 quark = gst_flow_to_quark (ret);
776 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
778 ret = GST_FLOW_CUSTOM_ERROR - 2;
779 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
780 quark = gst_flow_to_quark (ret);
781 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
784 ret = GST_FLOW_CUSTOM_ERROR + 2;
785 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
786 quark = gst_flow_to_quark (ret);
787 fail_unless (quark == 0);
792 GST_START_TEST (test_push_negotiation)
795 GstPadLinkReturn plr;
797 gst_caps_from_string ("audio/x-raw-int,width={16,32},depth={16,32}");
799 gst_caps_from_string ("audio/x-raw-int,width=32,depth={16,32}");
800 GstPadTemplate *src_template;
801 GstPadTemplate *sink_template;
805 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
806 GST_PAD_ALWAYS, srccaps);
807 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
808 GST_PAD_ALWAYS, sinkcaps);
809 gst_caps_unref (srccaps);
810 gst_caps_unref (sinkcaps);
812 sink = gst_pad_new_from_template (sink_template, "sink");
813 fail_if (sink == NULL);
814 gst_pad_set_chain_function (sink, gst_check_chain_func);
816 src = gst_pad_new_from_template (src_template, "src");
817 fail_if (src == NULL);
819 plr = gst_pad_link (src, sink);
820 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
823 gst_pad_set_active (src, TRUE);
824 gst_pad_set_active (sink, TRUE);
826 caps = gst_caps_from_string ("audio/x-raw-int,width=16,depth=16");
828 /* Should fail if src pad caps are incompatible with sink pad caps */
829 gst_pad_set_caps (src, caps);
830 fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
833 gst_pad_unlink (src, sink);
834 gst_object_unref (src);
835 gst_object_unref (sink);
836 gst_caps_unref (caps);
837 gst_object_unref (sink_template);
838 gst_object_unref (src_template);
843 /* see that an unref also unlinks the pads */
844 GST_START_TEST (test_src_unref_unlink)
848 GstPadLinkReturn plr;
850 sink = gst_pad_new ("sink", GST_PAD_SINK);
851 fail_if (sink == NULL);
853 src = gst_pad_new ("src", GST_PAD_SRC);
854 fail_if (src == NULL);
856 caps = gst_caps_from_string ("foo/bar");
858 gst_pad_set_caps (src, caps);
859 gst_pad_set_active (sink, TRUE);
860 gst_pad_set_caps (sink, caps);
862 plr = gst_pad_link (src, sink);
863 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
865 /* unref the srcpad */
866 gst_object_unref (src);
868 /* sink should be unlinked now */
869 fail_if (gst_pad_is_linked (sink));
872 gst_object_unref (sink);
873 gst_caps_unref (caps);
878 /* see that an unref also unlinks the pads */
879 GST_START_TEST (test_sink_unref_unlink)
883 GstPadLinkReturn plr;
885 sink = gst_pad_new ("sink", GST_PAD_SINK);
886 fail_if (sink == NULL);
888 src = gst_pad_new ("src", GST_PAD_SRC);
889 fail_if (src == NULL);
891 caps = gst_caps_from_string ("foo/bar");
893 gst_pad_set_caps (src, caps);
894 gst_pad_set_active (sink, TRUE);
895 gst_pad_set_caps (sink, caps);
897 plr = gst_pad_link (src, sink);
898 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
900 /* unref the sinkpad */
901 gst_object_unref (sink);
903 /* src should be unlinked now */
904 fail_if (gst_pad_is_linked (src));
907 gst_object_unref (src);
908 gst_caps_unref (caps);
915 static GstPadProbeReturn
916 block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
918 gboolean *bool_user_data = (gboolean *) user_data;
920 fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
922 /* here we should have blocked == 0 unblocked == 0 */
923 fail_unless (bool_user_data[0] == FALSE);
924 fail_unless (bool_user_data[1] == FALSE);
926 bool_user_data[0] = TRUE;
928 gst_pad_remove_probe (pad, id);
929 bool_user_data[1] = TRUE;
931 return GST_PAD_PROBE_OK;
934 GST_START_TEST (test_block_async)
937 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
939 gboolean data[2] = { FALSE, FALSE };
941 pad = gst_pad_new ("src", GST_PAD_SRC);
942 fail_unless (pad != NULL);
944 gst_pad_set_active (pad, TRUE);
945 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_cb, &data,
948 fail_unless (data[0] == FALSE);
949 fail_unless (data[1] == FALSE);
950 gst_pad_push (pad, gst_buffer_new ());
952 gst_object_unref (pad);
959 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
961 gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
965 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
967 static int n_calls = 0;
968 gboolean *bool_user_data = (gboolean *) user_data;
971 /* we expect this callback to be called only once */
972 g_warn_if_reached ();
974 *bool_user_data = blocked;
976 /* replace block_async_first with block_async_second so next time the pad is
977 * blocked the latter should be called */
978 gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
980 /* unblock temporarily, in the next push block_async_second should be called
982 gst_pad_push_event (pad, gst_event_new_flush_start ());
985 GST_START_TEST (test_block_async_replace_callback)
990 pad = gst_pad_new ("src", GST_PAD_SRC);
991 fail_unless (pad != NULL);
992 gst_pad_set_active (pad, TRUE);
994 gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
997 gst_pad_push (pad, gst_buffer_new ());
998 fail_unless (blocked == TRUE);
999 /* block_async_first flushes to unblock */
1000 gst_pad_push_event (pad, gst_event_new_flush_stop ());
1002 /* push again, this time block_async_second should be called */
1003 gst_pad_push (pad, gst_buffer_new ());
1004 fail_unless (blocked == TRUE);
1006 gst_object_unref (pad);
1013 block_async_full_destroy (gpointer user_data)
1015 gint *state = (gint *) user_data;
1017 fail_unless (*state < 2);
1019 GST_DEBUG ("setting state to 2");
1023 static GstPadProbeReturn
1024 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1026 *(gint *) user_data = (gint) TRUE;
1028 gst_pad_push_event (pad, gst_event_new_flush_start ());
1029 GST_DEBUG ("setting state to 1");
1031 return GST_PAD_PROBE_OK;
1034 GST_START_TEST (test_block_async_full_destroy)
1037 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1041 pad = gst_pad_new ("src", GST_PAD_SRC);
1042 fail_unless (pad != NULL);
1043 gst_pad_set_active (pad, TRUE);
1045 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1046 &state, block_async_full_destroy);
1047 fail_unless (state == 0);
1049 gst_pad_push (pad, gst_buffer_new ());
1050 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1052 fail_unless (state == 1);
1053 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1055 /* unblock callback is called */
1056 gst_pad_remove_probe (pad, id);
1057 fail_unless (state == 2);
1059 gst_object_unref (pad);
1064 GST_START_TEST (test_block_async_full_destroy_dispose)
1067 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1070 pad = gst_pad_new ("src", GST_PAD_SRC);
1071 fail_unless (pad != NULL);
1072 gst_pad_set_active (pad, TRUE);
1074 (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1075 &state, block_async_full_destroy);
1077 gst_pad_push (pad, gst_buffer_new ());
1078 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1080 fail_unless_equals_int (state, 1);
1081 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1083 /* gst_BLOCK calls the destroy_notify function if necessary */
1084 gst_object_unref (pad);
1086 fail_unless_equals_int (state, 2);
1094 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
1096 gboolean *bool_user_data = (gboolean *) user_data;
1098 /* here we should have blocked == 1 unblocked == 0 */
1100 fail_unless (blocked == FALSE);
1102 fail_unless (bool_user_data[0] == TRUE);
1103 fail_unless (bool_user_data[1] == TRUE);
1104 fail_unless (bool_user_data[2] == FALSE);
1106 bool_user_data[2] = TRUE;
1113 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
1115 g_warn_if_reached ();
1119 static GstPadProbeReturn
1120 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
1123 gboolean *bool_user_data = (gboolean *) user_data;
1125 GST_DEBUG ("second probe called");
1127 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1129 fail_unless (bool_user_data[0] == TRUE);
1130 fail_unless (bool_user_data[1] == FALSE);
1131 fail_unless (bool_user_data[2] == FALSE);
1133 bool_user_data[1] = TRUE;
1135 GST_DEBUG ("removing second probe with id %lu", id);
1136 gst_pad_remove_probe (pad, id);
1138 return GST_PAD_PROBE_OK;
1141 static GstPadProbeReturn
1142 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
1145 static int n_calls = 0;
1146 gboolean *bool_user_data = (gboolean *) user_data;
1148 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1150 GST_DEBUG ("first probe called");
1153 /* we expect this callback to be called only once */
1154 g_warn_if_reached ();
1156 *bool_user_data = TRUE;
1158 fail_unless (bool_user_data[0] == TRUE);
1159 fail_unless (bool_user_data[1] == FALSE);
1160 fail_unless (bool_user_data[2] == FALSE);
1162 GST_DEBUG ("removing first probe with id %lu", id);
1163 gst_pad_remove_probe (pad, id);
1165 GST_DEBUG ("adding second probe");
1166 /* replace block_async_first with block_async_second so next time the pad is
1167 * blocked the latter should be called */
1168 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1169 block_async_second_no_flush, user_data, NULL);
1170 GST_DEBUG ("added probe with id %lu", id);
1172 return GST_PAD_PROBE_OK;
1175 GST_START_TEST (test_block_async_replace_callback_no_flush)
1178 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
1180 pad = gst_pad_new ("src", GST_PAD_SRC);
1181 fail_unless (pad != NULL);
1182 gst_pad_set_active (pad, TRUE);
1184 GST_DEBUG ("adding probe");
1185 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1186 block_async_first_no_flush, bool_user_data, NULL);
1187 GST_DEBUG ("added probe with id %lu", id);
1190 GST_DEBUG ("pushing buffer");
1191 gst_pad_push (pad, gst_buffer_new ());
1192 fail_unless (bool_user_data[0] == TRUE);
1193 fail_unless (bool_user_data[1] == TRUE);
1194 fail_unless (bool_user_data[2] == FALSE);
1196 gst_object_unref (pad);
1203 gst_pad_suite (void)
1205 Suite *s = suite_create ("GstPad");
1206 TCase *tc_chain = tcase_create ("general");
1208 /* turn off timeout */
1209 tcase_set_timeout (tc_chain, 60);
1211 suite_add_tcase (s, tc_chain);
1212 tcase_add_test (tc_chain, test_link);
1213 tcase_add_test (tc_chain, test_refcount);
1214 tcase_add_test (tc_chain, test_get_allowed_caps);
1215 tcase_add_test (tc_chain, test_sticky_caps_unlinked);
1216 tcase_add_test (tc_chain, test_sticky_caps_flushing);
1217 tcase_add_test (tc_chain, test_link_unlink_threaded);
1218 tcase_add_test (tc_chain, test_name_is_valid);
1219 tcase_add_test (tc_chain, test_push_unlinked);
1220 tcase_add_test (tc_chain, test_push_linked);
1221 tcase_add_test (tc_chain, test_push_linked_flushing);
1222 tcase_add_test (tc_chain, test_push_buffer_list_compat);
1223 tcase_add_test (tc_chain, test_flowreturn);
1224 tcase_add_test (tc_chain, test_push_negotiation);
1225 tcase_add_test (tc_chain, test_src_unref_unlink);
1226 tcase_add_test (tc_chain, test_sink_unref_unlink);
1227 tcase_add_test (tc_chain, test_block_async);
1229 tcase_add_test (tc_chain, test_block_async_replace_callback);
1231 tcase_add_test (tc_chain, test_block_async_full_destroy);
1232 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
1233 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1238 GST_CHECK_MAIN (gst_pad);