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_caps (sink, caps);
93 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
95 MAIN_START_THREADS (5, thread_link_unlink, NULL);
96 for (i = 0; i < 1000; ++i) {
97 gst_pad_is_linked (src);
98 gst_pad_is_linked (sink);
101 MAIN_STOP_THREADS ();
103 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
104 gst_caps_unref (caps);
106 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
107 gst_object_unref (src);
108 gst_object_unref (sink);
113 GST_START_TEST (test_refcount)
117 GstPadLinkReturn plr;
119 sink = gst_pad_new ("sink", GST_PAD_SINK);
120 fail_if (sink == NULL);
122 src = gst_pad_new ("src", GST_PAD_SRC);
123 fail_if (src == NULL);
125 caps = gst_caps_from_string ("foo/bar");
127 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
129 gst_pad_set_caps (src, caps);
130 gst_pad_set_caps (sink, caps);
131 /* one for me and one for each set_caps */
132 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
134 plr = gst_pad_link (src, sink);
135 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
136 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
138 gst_pad_unlink (src, sink);
139 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
142 gst_object_unref (src);
143 gst_object_unref (sink);
144 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
146 gst_caps_unref (caps);
151 GST_START_TEST (test_get_allowed_caps)
154 GstCaps *caps, *gotcaps;
156 GstPadLinkReturn plr;
158 ASSERT_CRITICAL (gst_pad_get_allowed_caps (NULL));
160 buffer = gst_buffer_new ();
161 ASSERT_CRITICAL (gst_pad_get_allowed_caps ((GstPad *) buffer));
162 gst_buffer_unref (buffer);
164 src = gst_pad_new ("src", GST_PAD_SRC);
165 fail_if (src == NULL);
166 caps = gst_pad_get_allowed_caps (src);
167 fail_unless (caps == NULL);
169 caps = gst_caps_from_string ("foo/bar");
171 sink = gst_pad_new ("sink", GST_PAD_SINK);
172 gst_pad_set_caps (src, caps);
173 gst_pad_set_caps (sink, caps);
174 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
176 plr = gst_pad_link (src, sink);
177 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
179 gotcaps = gst_pad_get_allowed_caps (src);
180 fail_if (gotcaps == NULL);
181 fail_unless (gst_caps_is_equal (gotcaps, caps));
183 ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 1);
184 gst_caps_unref (gotcaps);
186 gst_pad_unlink (src, sink);
189 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
190 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
191 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
193 gst_object_unref (src);
194 gst_object_unref (sink);
196 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
197 gst_caps_unref (caps);
203 name_is_valid (const gchar * name, GstPadPresence presence)
206 GstCaps *any = GST_CAPS_ANY;
208 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
210 gst_object_unref (GST_OBJECT (new));
216 GST_START_TEST (test_name_is_valid)
218 gboolean result = FALSE;
220 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
221 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
222 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
225 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
226 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
227 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
228 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
229 ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
231 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
232 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
238 _probe_handler (GstPad * pad, GstBuffer * buffer, gpointer userdata)
240 gint ret = GPOINTER_TO_INT (userdata);
247 GST_START_TEST (test_push_unlinked)
254 src = gst_pad_new ("src", GST_PAD_SRC);
255 fail_if (src == NULL);
256 caps = gst_pad_get_allowed_caps (src);
257 fail_unless (caps == NULL);
259 caps = gst_caps_from_string ("foo/bar");
261 gst_pad_set_caps (src, caps);
262 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
264 /* pushing on an unlinked pad will drop the buffer */
265 buffer = gst_buffer_new ();
266 gst_buffer_ref (buffer);
267 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
268 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
269 gst_buffer_unref (buffer);
271 /* adding a probe that returns FALSE will drop the buffer without trying
273 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
274 GINT_TO_POINTER (0));
275 buffer = gst_buffer_new ();
276 gst_buffer_ref (buffer);
277 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
278 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
279 gst_buffer_unref (buffer);
280 gst_pad_remove_buffer_probe (src, id);
282 /* adding a probe that returns TRUE will still chain the buffer,
283 * and hence drop because pad is unlinked */
284 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
285 GINT_TO_POINTER (1));
286 buffer = gst_buffer_new ();
287 gst_buffer_ref (buffer);
288 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
289 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
290 gst_buffer_unref (buffer);
291 gst_pad_remove_buffer_probe (src, id);
295 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
296 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
298 gst_object_unref (src);
300 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
301 gst_caps_unref (caps);
306 GST_START_TEST (test_push_linked)
309 GstPadLinkReturn plr;
315 sink = gst_pad_new ("sink", GST_PAD_SINK);
316 fail_if (sink == NULL);
317 gst_pad_set_chain_function (sink, gst_check_chain_func);
319 src = gst_pad_new ("src", GST_PAD_SRC);
320 fail_if (src == NULL);
322 caps = gst_caps_from_string ("foo/bar");
324 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
326 gst_pad_set_caps (src, caps);
327 gst_pad_set_caps (sink, caps);
328 /* one for me and one for each set_caps */
329 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
331 plr = gst_pad_link (src, sink);
332 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
333 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
335 buffer = gst_buffer_new ();
337 /* FIXME, new pad should be flushing */
338 gst_buffer_ref (buffer);
339 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
340 gst_buffer_ref (buffer);
341 fail_unless (gst_pad_chain (sink, buffer) == GST_FLOW_WRONG_STATE);
345 gst_pad_set_active (src, TRUE);
346 gst_pad_set_active (sink, TRUE);
349 /* pushing on a linked pad will drop the ref to the buffer */
350 gst_buffer_ref (buffer);
351 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
352 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
353 gst_buffer_unref (buffer);
354 fail_unless_equals_int (g_list_length (buffers), 1);
355 buffer = GST_BUFFER (buffers->data);
356 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
357 gst_buffer_unref (buffer);
358 g_list_free (buffers);
361 /* adding a probe that returns FALSE will drop the buffer without trying
363 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
364 GINT_TO_POINTER (0));
365 buffer = gst_buffer_new ();
366 gst_buffer_ref (buffer);
367 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
368 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
369 gst_buffer_unref (buffer);
370 gst_pad_remove_buffer_probe (src, id);
371 fail_unless_equals_int (g_list_length (buffers), 0);
373 /* adding a probe that returns TRUE will still chain the buffer */
374 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
375 GINT_TO_POINTER (1));
376 buffer = gst_buffer_new ();
377 gst_buffer_ref (buffer);
378 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
379 gst_pad_remove_buffer_probe (src, id);
381 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
382 gst_buffer_unref (buffer);
383 fail_unless_equals_int (g_list_length (buffers), 1);
384 buffer = GST_BUFFER (buffers->data);
385 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
386 gst_buffer_unref (buffer);
387 g_list_free (buffers);
391 gst_pad_unlink (src, sink);
392 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
393 gst_object_unref (src);
394 gst_object_unref (sink);
395 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
397 gst_caps_unref (caps);
402 GST_START_TEST (test_push_linked_flushing)
406 GstPadLinkReturn plr;
411 src = gst_pad_new ("src", GST_PAD_SRC);
412 fail_if (src == NULL);
413 sink = gst_pad_new ("sink", GST_PAD_SINK);
414 fail_if (sink == NULL);
415 gst_pad_set_chain_function (sink, gst_check_chain_func);
417 caps = gst_pad_get_allowed_caps (src);
418 fail_unless (caps == NULL);
419 caps = gst_pad_get_allowed_caps (sink);
420 fail_unless (caps == NULL);
422 caps = gst_caps_from_string ("foo/bar");
424 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
426 gst_pad_set_caps (src, caps);
427 gst_pad_set_caps (sink, caps);
428 /* one for me and one for each set_caps */
429 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
431 plr = gst_pad_link (src, sink);
432 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
433 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
435 /* not activating the pads here, which keeps them flushing */
437 /* pushing on a flushing pad will drop the buffer */
438 buffer = gst_buffer_new ();
439 gst_buffer_ref (buffer);
440 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
441 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
442 fail_unless_equals_int (g_list_length (buffers), 0);
443 gst_buffer_unref (buffer);
445 /* adding a probe that returns FALSE will drop the buffer without trying
447 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
448 GINT_TO_POINTER (0));
449 buffer = gst_buffer_new ();
450 gst_buffer_ref (buffer);
451 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
452 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
453 fail_unless_equals_int (g_list_length (buffers), 0);
454 gst_buffer_unref (buffer);
455 gst_pad_remove_buffer_probe (src, id);
457 /* adding a probe that returns TRUE will still chain the buffer,
458 * and hence drop because pad is flushing */
459 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
460 GINT_TO_POINTER (1));
461 buffer = gst_buffer_new ();
462 gst_buffer_ref (buffer);
463 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
464 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
465 fail_unless_equals_int (g_list_length (buffers), 0);
466 gst_buffer_unref (buffer);
467 gst_pad_remove_buffer_probe (src, id);
471 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
472 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
473 gst_pad_link (src, sink);
474 gst_object_unref (src);
475 gst_object_unref (sink);
476 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
477 gst_caps_unref (caps);
483 buffer_from_string (const gchar * str)
489 buf = gst_buffer_new_and_alloc (size);
490 memcpy (GST_BUFFER_DATA (buf), str, size);
491 GST_BUFFER_SIZE (buf) = size;
496 GST_START_TEST (test_push_buffer_list_compat)
499 GstPadLinkReturn plr;
502 GstBufferListIterator *it;
506 sink = gst_pad_new ("sink", GST_PAD_SINK);
507 fail_if (sink == NULL);
508 gst_pad_set_chain_function (sink, gst_check_chain_func);
509 /* leave chainlistfunc unset */
511 src = gst_pad_new ("src", GST_PAD_SRC);
512 fail_if (src == NULL);
514 caps = gst_caps_from_string ("foo/bar");
516 gst_pad_set_caps (src, caps);
517 gst_pad_set_caps (sink, caps);
519 plr = gst_pad_link (src, sink);
520 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
522 list = gst_buffer_list_new ();
525 gst_pad_set_active (src, TRUE);
526 gst_pad_set_active (sink, TRUE);
529 /* adding to a buffer list will drop the ref to the buffer */
530 it = gst_buffer_list_iterate (list);
531 gst_buffer_list_iterator_add_group (it);
532 gst_buffer_list_iterator_add (it, buffer_from_string ("List"));
533 gst_buffer_list_iterator_add (it, buffer_from_string ("Group"));
534 gst_buffer_list_iterator_add_group (it);
535 gst_buffer_list_iterator_add (it, buffer_from_string ("Another"));
536 gst_buffer_list_iterator_add (it, buffer_from_string ("List"));
537 gst_buffer_list_iterator_add (it, buffer_from_string ("Group"));
538 gst_buffer_list_iterator_free (it);
539 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
540 fail_unless_equals_int (g_list_length (buffers), 2);
541 buffer = GST_BUFFER (buffers->data);
542 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
543 fail_unless (memcmp (GST_BUFFER_DATA (buffer), "ListGroup", 9) == 0);
544 gst_buffer_unref (buffer);
545 buffers = g_list_delete_link (buffers, buffers);
546 buffer = GST_BUFFER (buffers->data);
547 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
548 fail_unless (memcmp (GST_BUFFER_DATA (buffer), "AnotherListGroup", 16) == 0);
549 gst_buffer_unref (buffer);
550 buffers = g_list_delete_link (buffers, buffers);
551 fail_unless (buffers == NULL);
554 gst_pad_unlink (src, sink);
555 gst_object_unref (src);
556 gst_object_unref (sink);
557 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
558 gst_caps_unref (caps);
563 GST_START_TEST (test_flowreturn)
568 /* test some of the macros */
569 ret = GST_FLOW_UNEXPECTED;
570 fail_if (strcmp (gst_flow_get_name (ret), "unexpected"));
571 quark = gst_flow_to_quark (ret);
572 fail_if (strcmp (g_quark_to_string (quark), "unexpected"));
574 ret = GST_FLOW_RESEND;
575 fail_if (strcmp (gst_flow_get_name (ret), "resend"));
576 quark = gst_flow_to_quark (ret);
577 fail_if (strcmp (g_quark_to_string (quark), "resend"));
580 ret = GST_FLOW_CUSTOM_SUCCESS;
581 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
582 quark = gst_flow_to_quark (ret);
583 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
585 ret = GST_FLOW_CUSTOM_ERROR;
586 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
587 quark = gst_flow_to_quark (ret);
588 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
590 /* custom returns clamping */
591 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
592 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
593 quark = gst_flow_to_quark (ret);
594 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
596 ret = GST_FLOW_CUSTOM_ERROR - 2;
597 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
598 quark = gst_flow_to_quark (ret);
599 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
602 ret = GST_FLOW_CUSTOM_ERROR + 2;
603 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
604 quark = gst_flow_to_quark (ret);
605 fail_unless (quark == 0);
610 GST_START_TEST (test_push_negotiation)
613 GstPadLinkReturn plr;
615 gst_caps_from_string ("audio/x-raw-int,width={16,32},depth={16,32}");
617 gst_caps_from_string ("audio/x-raw-int,width=32,depth={16,32}");
618 GstPadTemplate *src_template;
619 GstPadTemplate *sink_template;
624 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
625 GST_PAD_ALWAYS, srccaps);
626 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
627 GST_PAD_ALWAYS, sinkcaps);
629 sink = gst_pad_new_from_template (sink_template, "sink");
630 fail_if (sink == NULL);
631 gst_pad_set_chain_function (sink, gst_check_chain_func);
633 src = gst_pad_new_from_template (src_template, "src");
634 fail_if (src == NULL);
636 plr = gst_pad_link (src, sink);
637 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
639 buffer = gst_buffer_new ();
642 gst_pad_set_active (src, TRUE);
643 gst_pad_set_active (sink, TRUE);
645 caps = gst_caps_from_string ("audio/x-raw-int,width=16,depth=16");
647 /* Should fail if src pad caps are incompatible with sink pad caps */
648 gst_pad_set_caps (src, caps);
649 gst_buffer_set_caps (buffer, caps);
650 gst_buffer_ref (buffer);
651 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_NEGOTIATED);
652 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
653 gst_buffer_unref (buffer);
656 gst_pad_unlink (src, sink);
657 gst_object_unref (src);
658 gst_object_unref (sink);
659 gst_caps_unref (caps);
660 gst_object_unref (sink_template);
661 gst_object_unref (src_template);
666 /* see that an unref also unlinks the pads */
667 GST_START_TEST (test_src_unref_unlink)
671 GstPadLinkReturn plr;
673 sink = gst_pad_new ("sink", GST_PAD_SINK);
674 fail_if (sink == NULL);
676 src = gst_pad_new ("src", GST_PAD_SRC);
677 fail_if (src == NULL);
679 caps = gst_caps_from_string ("foo/bar");
681 gst_pad_set_caps (src, caps);
682 gst_pad_set_caps (sink, caps);
684 plr = gst_pad_link (src, sink);
685 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
687 /* unref the srcpad */
688 gst_object_unref (src);
690 /* sink should be unlinked now */
691 fail_if (gst_pad_is_linked (sink));
694 gst_object_unref (sink);
695 gst_caps_unref (caps);
700 /* see that an unref also unlinks the pads */
701 GST_START_TEST (test_sink_unref_unlink)
705 GstPadLinkReturn plr;
707 sink = gst_pad_new ("sink", GST_PAD_SINK);
708 fail_if (sink == NULL);
710 src = gst_pad_new ("src", GST_PAD_SRC);
711 fail_if (src == NULL);
713 caps = gst_caps_from_string ("foo/bar");
715 gst_pad_set_caps (src, caps);
716 gst_pad_set_caps (sink, caps);
718 plr = gst_pad_link (src, sink);
719 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
721 /* unref the sinkpad */
722 gst_object_unref (sink);
724 /* src should be unlinked now */
725 fail_if (gst_pad_is_linked (src));
728 gst_object_unref (src);
729 gst_caps_unref (caps);
734 /* gst_pad_get_caps should return a copy of the caps */
735 GST_START_TEST (test_get_caps_must_be_copy)
739 GstPadTemplate *templ;
741 caps = gst_caps_new_any ();
743 gst_pad_template_new ("test_templ", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
745 pad = gst_pad_new_from_template (templ, NULL);
746 fail_unless (GST_PAD_CAPS (pad) == NULL, "caps present on pad");
747 /* This is a writable copy ! */
748 caps = gst_pad_get_caps (pad);
750 /* we must own the caps */
751 ASSERT_OBJECT_REFCOUNT (caps, "caps", 1);
754 gst_object_unref (templ);
755 gst_caps_unref (caps);
756 gst_object_unref (pad);
762 unblock_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
764 gboolean *bool_user_data = (gboolean *) user_data;
766 /* here we should have blocked == 1 unblocked == 0 */
767 fail_unless (bool_user_data[0] == TRUE);
768 fail_unless (bool_user_data[1] == FALSE);
770 bool_user_data[1] = TRUE;
774 block_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
776 gboolean *bool_user_data = (gboolean *) user_data;
778 /* here we should have blocked == 0 unblocked == 0 */
779 fail_unless (bool_user_data[0] == FALSE);
780 fail_unless (bool_user_data[1] == FALSE);
782 bool_user_data[0] = blocked;
784 gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, user_data);
787 GST_START_TEST (test_block_async)
790 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
792 gboolean data[2] = { FALSE, FALSE };
794 pad = gst_pad_new ("src", GST_PAD_SRC);
795 fail_unless (pad != NULL);
797 gst_pad_set_active (pad, TRUE);
798 gst_pad_set_blocked_async (pad, TRUE, block_async_cb, &data);
800 fail_unless (data[0] == FALSE);
801 fail_unless (data[1] == FALSE);
802 gst_pad_push (pad, gst_buffer_new ());
804 gst_object_unref (pad);
811 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
813 gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, NULL);
817 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
819 static int n_calls = 0;
820 gboolean *bool_user_data = (gboolean *) user_data;
823 /* we expect this callback to be called only once */
824 g_warn_if_reached ();
826 *bool_user_data = blocked;
828 /* replace block_async_first with block_async_second so next time the pad is
829 * blocked the latter should be called */
830 gst_pad_set_blocked_async (pad, TRUE, block_async_second, NULL);
832 /* unblock temporarily, in the next push block_async_second should be called
834 gst_pad_push_event (pad, gst_event_new_flush_start ());
837 GST_START_TEST (test_block_async_replace_callback)
842 pad = gst_pad_new ("src", GST_PAD_SRC);
843 fail_unless (pad != NULL);
844 gst_pad_set_active (pad, TRUE);
846 gst_pad_set_blocked_async (pad, TRUE, block_async_first, &blocked);
849 gst_pad_push (pad, gst_buffer_new ());
850 fail_unless (blocked == TRUE);
851 /* block_async_first flushes to unblock */
852 gst_pad_push_event (pad, gst_event_new_flush_stop ());
854 /* push again, this time block_async_second should be called */
855 gst_pad_push (pad, gst_buffer_new ());
856 fail_unless (blocked == TRUE);
858 gst_object_unref (pad);
865 block_async_full_destroy (gpointer user_data)
867 gint *state = (gint *) user_data;
869 fail_unless (*state < 2);
871 GST_DEBUG ("setting state to 2");
876 block_async_full_cb (GstPad * pad, gboolean blocked, gpointer user_data)
878 *(gint *) user_data = (gint) blocked;
880 gst_pad_push_event (pad, gst_event_new_flush_start ());
881 GST_DEBUG ("setting state to 1");
884 GST_START_TEST (test_block_async_full_destroy)
887 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
890 pad = gst_pad_new ("src", GST_PAD_SRC);
891 fail_unless (pad != NULL);
892 gst_pad_set_active (pad, TRUE);
894 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
895 &state, block_async_full_destroy);
896 fail_unless (state == 0);
898 gst_pad_push (pad, gst_buffer_new ());
899 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
901 fail_unless (state == 1);
902 gst_pad_push_event (pad, gst_event_new_flush_stop ());
904 /* pad was already blocked so nothing happens */
905 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
906 &state, block_async_full_destroy);
907 fail_unless (state == 1);
909 /* unblock with the same data, callback is called */
910 gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
911 &state, block_async_full_destroy);
912 fail_unless (state == 2);
914 /* block with the same data, callback is called */
916 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
917 &state, block_async_full_destroy);
918 fail_unless (state == 2);
920 /* now change user_data (to NULL in this case) so destroy_notify should be
923 gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
924 NULL, block_async_full_destroy);
925 fail_unless (state == 2);
927 gst_object_unref (pad);
932 GST_START_TEST (test_block_async_full_destroy_dispose)
935 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
938 pad = gst_pad_new ("src", GST_PAD_SRC);
939 fail_unless (pad != NULL);
940 gst_pad_set_active (pad, TRUE);
942 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
943 &state, block_async_full_destroy);
945 gst_pad_push (pad, gst_buffer_new ());
946 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
948 fail_unless_equals_int (state, 1);
949 gst_pad_push_event (pad, gst_event_new_flush_stop ());
951 /* gst_pad_dispose calls the destroy_notify function if necessary */
952 gst_object_unref (pad);
954 fail_unless_equals_int (state, 2);
961 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
963 gboolean *bool_user_data = (gboolean *) user_data;
965 /* here we should have blocked == 1 unblocked == 0 */
967 fail_unless (blocked == FALSE);
969 fail_unless (bool_user_data[0] == TRUE);
970 fail_unless (bool_user_data[1] == TRUE);
971 fail_unless (bool_user_data[2] == FALSE);
973 bool_user_data[2] = TRUE;
978 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
980 g_warn_if_reached ();
984 block_async_second_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
986 gboolean *bool_user_data = (gboolean *) user_data;
988 fail_unless (blocked == TRUE);
990 fail_unless (bool_user_data[0] == TRUE);
991 fail_unless (bool_user_data[1] == FALSE);
992 fail_unless (bool_user_data[2] == FALSE);
994 bool_user_data[1] = TRUE;
996 fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_no_flush_cb,
1001 block_async_first_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
1003 static int n_calls = 0;
1004 gboolean *bool_user_data = (gboolean *) user_data;
1006 fail_unless (blocked == TRUE);
1009 /* we expect this callback to be called only once */
1010 g_warn_if_reached ();
1012 *bool_user_data = blocked;
1014 fail_unless (bool_user_data[0] == TRUE);
1015 fail_unless (bool_user_data[1] == FALSE);
1016 fail_unless (bool_user_data[2] == FALSE);
1018 fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_not_called,
1021 /* replace block_async_first with block_async_second so next time the pad is
1022 * blocked the latter should be called */
1023 fail_unless (gst_pad_set_blocked_async (pad, TRUE,
1024 block_async_second_no_flush, user_data));
1027 GST_START_TEST (test_block_async_replace_callback_no_flush)
1030 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
1032 pad = gst_pad_new ("src", GST_PAD_SRC);
1033 fail_unless (pad != NULL);
1034 gst_pad_set_active (pad, TRUE);
1036 fail_unless (gst_pad_set_blocked_async (pad, TRUE, block_async_first_no_flush,
1039 gst_pad_push (pad, gst_buffer_new ());
1040 fail_unless (bool_user_data[0] == TRUE);
1041 fail_unless (bool_user_data[1] == TRUE);
1042 fail_unless (bool_user_data[2] == TRUE);
1044 gst_object_unref (pad);
1051 gst_pad_suite (void)
1053 Suite *s = suite_create ("GstPad");
1054 TCase *tc_chain = tcase_create ("general");
1056 /* turn off timeout */
1057 tcase_set_timeout (tc_chain, 60);
1059 suite_add_tcase (s, tc_chain);
1060 tcase_add_test (tc_chain, test_link);
1061 tcase_add_test (tc_chain, test_refcount);
1062 tcase_add_test (tc_chain, test_get_allowed_caps);
1063 tcase_add_test (tc_chain, test_link_unlink_threaded);
1064 tcase_add_test (tc_chain, test_name_is_valid);
1065 tcase_add_test (tc_chain, test_push_unlinked);
1066 tcase_add_test (tc_chain, test_push_linked);
1067 tcase_add_test (tc_chain, test_push_linked_flushing);
1068 tcase_add_test (tc_chain, test_push_buffer_list_compat);
1069 tcase_add_test (tc_chain, test_flowreturn);
1070 tcase_add_test (tc_chain, test_push_negotiation);
1071 tcase_add_test (tc_chain, test_src_unref_unlink);
1072 tcase_add_test (tc_chain, test_sink_unref_unlink);
1073 tcase_add_test (tc_chain, test_get_caps_must_be_copy);
1074 tcase_add_test (tc_chain, test_block_async);
1076 tcase_add_test (tc_chain, test_block_async_replace_callback);
1078 tcase_add_test (tc_chain, test_block_async_full_destroy);
1079 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
1080 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1085 GST_CHECK_MAIN (gst_pad);