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 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
131 /* can't set caps on flushing sinkpad */
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", 3);
136 gst_pad_set_active (sink, TRUE);
137 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
138 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
140 plr = gst_pad_link (src, sink);
141 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
142 /* src caps added to pending caps on sink */
143 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
145 gst_pad_unlink (src, sink);
146 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
149 gst_object_unref (src);
150 gst_object_unref (sink);
151 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
153 gst_caps_unref (caps);
158 GST_START_TEST (test_get_allowed_caps)
161 GstCaps *caps, *gotcaps;
163 GstPadLinkReturn plr;
165 ASSERT_CRITICAL (gst_pad_get_allowed_caps (NULL));
167 buffer = gst_buffer_new ();
168 ASSERT_CRITICAL (gst_pad_get_allowed_caps ((GstPad *) buffer));
169 gst_buffer_unref (buffer);
171 src = gst_pad_new ("src", GST_PAD_SRC);
172 fail_if (src == NULL);
173 caps = gst_pad_get_allowed_caps (src);
174 fail_unless (caps == NULL);
176 caps = gst_caps_from_string ("foo/bar");
178 sink = gst_pad_new ("sink", GST_PAD_SINK);
179 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
180 fail_if (gst_pad_set_caps (sink, caps) == TRUE);
181 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
183 gst_pad_set_active (sink, TRUE);
184 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
185 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
187 plr = gst_pad_link (src, sink);
188 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
190 gotcaps = gst_pad_get_allowed_caps (src);
191 fail_if (gotcaps == NULL);
193 /* FIXME, does not work, caps events are different so the sinkpad loses caps
195 fail_unless (gst_caps_is_equal (gotcaps, caps));
198 ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 1);
199 gst_caps_unref (gotcaps);
201 gst_pad_unlink (src, sink);
204 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
205 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
206 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
208 gst_object_unref (src);
209 gst_object_unref (sink);
211 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
212 gst_caps_unref (caps);
218 name_is_valid (const gchar * name, GstPadPresence presence)
221 GstCaps *any = GST_CAPS_ANY;
223 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
225 gst_object_unref (GST_OBJECT (new));
231 GST_START_TEST (test_name_is_valid)
233 gboolean result = FALSE;
235 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
236 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
237 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
240 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
241 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
242 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
243 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
244 ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
246 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
247 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
253 _probe_handler (GstPad * pad, GstBuffer * buffer, gpointer userdata)
255 gint ret = GPOINTER_TO_INT (userdata);
262 GST_START_TEST (test_push_unlinked)
269 src = gst_pad_new ("src", GST_PAD_SRC);
270 fail_if (src == NULL);
271 caps = gst_pad_get_allowed_caps (src);
272 fail_unless (caps == NULL);
274 caps = gst_caps_from_string ("foo/bar");
276 gst_pad_set_caps (src, caps);
277 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
279 /* pushing on an unlinked pad will drop the buffer */
280 buffer = gst_buffer_new ();
281 gst_buffer_ref (buffer);
282 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
283 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
284 gst_buffer_unref (buffer);
286 /* adding a probe that returns FALSE will drop the buffer without trying
288 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
289 GINT_TO_POINTER (0));
290 buffer = gst_buffer_new ();
291 gst_buffer_ref (buffer);
292 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
293 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
294 gst_buffer_unref (buffer);
295 gst_pad_remove_buffer_probe (src, id);
297 /* adding a probe that returns TRUE will still chain the buffer,
298 * and hence drop because pad is unlinked */
299 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
300 GINT_TO_POINTER (1));
301 buffer = gst_buffer_new ();
302 gst_buffer_ref (buffer);
303 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
304 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
305 gst_buffer_unref (buffer);
306 gst_pad_remove_buffer_probe (src, id);
310 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
311 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
313 gst_object_unref (src);
315 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
316 gst_caps_unref (caps);
321 GST_START_TEST (test_push_linked)
324 GstPadLinkReturn plr;
330 sink = gst_pad_new ("sink", GST_PAD_SINK);
331 fail_if (sink == NULL);
332 gst_pad_set_chain_function (sink, gst_check_chain_func);
334 src = gst_pad_new ("src", GST_PAD_SRC);
335 fail_if (src == NULL);
337 caps = gst_caps_from_string ("foo/bar");
339 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
341 gst_pad_set_caps (src, caps);
342 gst_pad_set_active (sink, TRUE);
343 gst_pad_set_caps (sink, caps);
344 /* one for me and one for each set_caps */
345 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
347 plr = gst_pad_link (src, sink);
348 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
349 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
351 buffer = gst_buffer_new ();
353 /* FIXME, new pad should be flushing */
354 gst_buffer_ref (buffer);
355 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
356 gst_buffer_ref (buffer);
357 fail_unless (gst_pad_chain (sink, buffer) == GST_FLOW_WRONG_STATE);
361 gst_pad_set_active (src, TRUE);
362 gst_pad_set_active (sink, TRUE);
365 /* pushing on a linked pad will drop the ref to the buffer */
366 gst_buffer_ref (buffer);
367 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
368 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
369 gst_buffer_unref (buffer);
370 fail_unless_equals_int (g_list_length (buffers), 1);
371 buffer = GST_BUFFER (buffers->data);
372 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
373 gst_buffer_unref (buffer);
374 g_list_free (buffers);
377 /* adding a probe that returns FALSE will drop the buffer without trying
379 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
380 GINT_TO_POINTER (0));
381 buffer = gst_buffer_new ();
382 gst_buffer_ref (buffer);
383 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
384 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
385 gst_buffer_unref (buffer);
386 gst_pad_remove_buffer_probe (src, id);
387 fail_unless_equals_int (g_list_length (buffers), 0);
389 /* adding a probe that returns TRUE will still chain the buffer */
390 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
391 GINT_TO_POINTER (1));
392 buffer = gst_buffer_new ();
393 gst_buffer_ref (buffer);
394 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
395 gst_pad_remove_buffer_probe (src, id);
397 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
398 gst_buffer_unref (buffer);
399 fail_unless_equals_int (g_list_length (buffers), 1);
400 buffer = GST_BUFFER (buffers->data);
401 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
402 gst_buffer_unref (buffer);
403 g_list_free (buffers);
407 gst_pad_unlink (src, sink);
408 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
409 gst_object_unref (src);
410 gst_object_unref (sink);
411 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
413 gst_caps_unref (caps);
419 buffer_from_string (const gchar * str)
426 buf = gst_buffer_new_and_alloc (size);
428 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
429 memcpy (data, str, size);
430 gst_buffer_unmap (buf, data, size);
436 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
441 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
442 res = memcmp (data, str, size) == 0;
443 GST_DEBUG ("%s <-> %s: %d", (gchar *) data, str, res);
444 gst_buffer_unmap (buf, data, size);
449 GST_START_TEST (test_push_buffer_list_compat)
452 GstPadLinkReturn plr;
459 sink = gst_pad_new ("sink", GST_PAD_SINK);
460 fail_if (sink == NULL);
461 gst_pad_set_chain_function (sink, gst_check_chain_func);
462 /* leave chainlistfunc unset */
464 src = gst_pad_new ("src", GST_PAD_SRC);
465 fail_if (src == NULL);
467 caps = gst_caps_from_string ("foo/bar");
469 gst_pad_set_caps (src, caps);
470 gst_pad_set_active (sink, TRUE);
471 gst_pad_set_caps (sink, caps);
473 plr = gst_pad_link (src, sink);
474 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
476 list = gst_buffer_list_new ();
479 gst_pad_set_active (src, TRUE);
480 gst_pad_set_active (sink, TRUE);
483 /* adding to a buffer list will drop the ref to the buffer */
484 len = gst_buffer_list_len (list);
486 gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
487 gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
489 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
490 fail_unless_equals_int (g_list_length (buffers), 2);
491 buffer = GST_BUFFER (buffers->data);
492 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
493 fail_unless (buffer_compare (buffer, "ListGroup", 9));
494 gst_buffer_unref (buffer);
495 buffers = g_list_delete_link (buffers, buffers);
496 buffer = GST_BUFFER (buffers->data);
497 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
498 fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
499 gst_buffer_unref (buffer);
500 buffers = g_list_delete_link (buffers, buffers);
501 fail_unless (buffers == NULL);
504 gst_pad_unlink (src, sink);
505 gst_object_unref (src);
506 gst_object_unref (sink);
507 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
508 gst_caps_unref (caps);
513 GST_START_TEST (test_flowreturn)
518 /* test some of the macros */
519 ret = GST_FLOW_UNEXPECTED;
520 fail_if (strcmp (gst_flow_get_name (ret), "unexpected"));
521 quark = gst_flow_to_quark (ret);
522 fail_if (strcmp (g_quark_to_string (quark), "unexpected"));
524 ret = GST_FLOW_RESEND;
525 fail_if (strcmp (gst_flow_get_name (ret), "resend"));
526 quark = gst_flow_to_quark (ret);
527 fail_if (strcmp (g_quark_to_string (quark), "resend"));
530 ret = GST_FLOW_CUSTOM_SUCCESS;
531 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
532 quark = gst_flow_to_quark (ret);
533 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
535 ret = GST_FLOW_CUSTOM_ERROR;
536 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
537 quark = gst_flow_to_quark (ret);
538 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
540 /* custom returns clamping */
541 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
542 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
543 quark = gst_flow_to_quark (ret);
544 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
546 ret = GST_FLOW_CUSTOM_ERROR - 2;
547 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
548 quark = gst_flow_to_quark (ret);
549 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
552 ret = GST_FLOW_CUSTOM_ERROR + 2;
553 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
554 quark = gst_flow_to_quark (ret);
555 fail_unless (quark == 0);
560 GST_START_TEST (test_push_negotiation)
563 GstPadLinkReturn plr;
565 gst_caps_from_string ("audio/x-raw-int,width={16,32},depth={16,32}");
567 gst_caps_from_string ("audio/x-raw-int,width=32,depth={16,32}");
568 GstPadTemplate *src_template;
569 GstPadTemplate *sink_template;
574 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
575 GST_PAD_ALWAYS, srccaps);
576 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
577 GST_PAD_ALWAYS, sinkcaps);
578 gst_caps_unref (srccaps);
579 gst_caps_unref (sinkcaps);
581 sink = gst_pad_new_from_template (sink_template, "sink");
582 fail_if (sink == NULL);
583 gst_pad_set_chain_function (sink, gst_check_chain_func);
585 src = gst_pad_new_from_template (src_template, "src");
586 fail_if (src == NULL);
588 plr = gst_pad_link (src, sink);
589 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
591 buffer = gst_buffer_new ();
594 gst_pad_set_active (src, TRUE);
595 gst_pad_set_active (sink, TRUE);
597 caps = gst_caps_from_string ("audio/x-raw-int,width=16,depth=16");
599 /* Should fail if src pad caps are incompatible with sink pad caps */
600 gst_pad_set_caps (src, caps);
601 fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
604 gst_pad_unlink (src, sink);
605 gst_object_unref (src);
606 gst_object_unref (sink);
607 gst_caps_unref (caps);
608 gst_object_unref (sink_template);
609 gst_object_unref (src_template);
614 /* see that an unref also unlinks the pads */
615 GST_START_TEST (test_src_unref_unlink)
619 GstPadLinkReturn plr;
621 sink = gst_pad_new ("sink", GST_PAD_SINK);
622 fail_if (sink == NULL);
624 src = gst_pad_new ("src", GST_PAD_SRC);
625 fail_if (src == NULL);
627 caps = gst_caps_from_string ("foo/bar");
629 gst_pad_set_caps (src, caps);
630 gst_pad_set_active (sink, TRUE);
631 gst_pad_set_caps (sink, caps);
633 plr = gst_pad_link (src, sink);
634 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
636 /* unref the srcpad */
637 gst_object_unref (src);
639 /* sink should be unlinked now */
640 fail_if (gst_pad_is_linked (sink));
643 gst_object_unref (sink);
644 gst_caps_unref (caps);
649 /* see that an unref also unlinks the pads */
650 GST_START_TEST (test_sink_unref_unlink)
654 GstPadLinkReturn plr;
656 sink = gst_pad_new ("sink", GST_PAD_SINK);
657 fail_if (sink == NULL);
659 src = gst_pad_new ("src", GST_PAD_SRC);
660 fail_if (src == NULL);
662 caps = gst_caps_from_string ("foo/bar");
664 gst_pad_set_caps (src, caps);
665 gst_pad_set_active (sink, TRUE);
666 gst_pad_set_caps (sink, caps);
668 plr = gst_pad_link (src, sink);
669 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
671 /* unref the sinkpad */
672 gst_object_unref (sink);
674 /* src should be unlinked now */
675 fail_if (gst_pad_is_linked (src));
678 gst_object_unref (src);
679 gst_caps_unref (caps);
685 unblock_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
687 gboolean *bool_user_data = (gboolean *) user_data;
689 /* here we should have blocked == 1 unblocked == 0 */
690 fail_unless (bool_user_data[0] == TRUE);
691 fail_unless (bool_user_data[1] == FALSE);
693 bool_user_data[1] = TRUE;
697 block_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
699 gboolean *bool_user_data = (gboolean *) user_data;
701 /* here we should have blocked == 0 unblocked == 0 */
702 fail_unless (bool_user_data[0] == FALSE);
703 fail_unless (bool_user_data[1] == FALSE);
705 bool_user_data[0] = blocked;
707 gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, user_data);
710 GST_START_TEST (test_block_async)
713 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
715 gboolean data[2] = { FALSE, FALSE };
717 pad = gst_pad_new ("src", GST_PAD_SRC);
718 fail_unless (pad != NULL);
720 gst_pad_set_active (pad, TRUE);
721 gst_pad_set_blocked_async (pad, TRUE, block_async_cb, &data);
723 fail_unless (data[0] == FALSE);
724 fail_unless (data[1] == FALSE);
725 gst_pad_push (pad, gst_buffer_new ());
727 gst_object_unref (pad);
734 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
736 gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, NULL);
740 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
742 static int n_calls = 0;
743 gboolean *bool_user_data = (gboolean *) user_data;
746 /* we expect this callback to be called only once */
747 g_warn_if_reached ();
749 *bool_user_data = blocked;
751 /* replace block_async_first with block_async_second so next time the pad is
752 * blocked the latter should be called */
753 gst_pad_set_blocked_async (pad, TRUE, block_async_second, NULL);
755 /* unblock temporarily, in the next push block_async_second should be called
757 gst_pad_push_event (pad, gst_event_new_flush_start ());
760 GST_START_TEST (test_block_async_replace_callback)
765 pad = gst_pad_new ("src", GST_PAD_SRC);
766 fail_unless (pad != NULL);
767 gst_pad_set_active (pad, TRUE);
769 gst_pad_set_blocked_async (pad, TRUE, block_async_first, &blocked);
772 gst_pad_push (pad, gst_buffer_new ());
773 fail_unless (blocked == TRUE);
774 /* block_async_first flushes to unblock */
775 gst_pad_push_event (pad, gst_event_new_flush_stop ());
777 /* push again, this time block_async_second should be called */
778 gst_pad_push (pad, gst_buffer_new ());
779 fail_unless (blocked == TRUE);
781 gst_object_unref (pad);
788 block_async_full_destroy (gpointer user_data)
790 gint *state = (gint *) user_data;
792 fail_unless (*state < 2);
794 GST_DEBUG ("setting state to 2");
799 block_async_full_cb (GstPad * pad, gboolean blocked, gpointer user_data)
801 *(gint *) user_data = (gint) blocked;
803 gst_pad_push_event (pad, gst_event_new_flush_start ());
804 GST_DEBUG ("setting state to 1");
807 GST_START_TEST (test_block_async_full_destroy)
810 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
813 pad = gst_pad_new ("src", GST_PAD_SRC);
814 fail_unless (pad != NULL);
815 gst_pad_set_active (pad, TRUE);
817 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
818 &state, block_async_full_destroy);
819 fail_unless (state == 0);
821 gst_pad_push (pad, gst_buffer_new ());
822 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
824 fail_unless (state == 1);
825 gst_pad_push_event (pad, gst_event_new_flush_stop ());
827 /* pad was already blocked so nothing happens */
828 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
829 &state, block_async_full_destroy);
830 fail_unless (state == 1);
832 /* unblock with the same data, callback is called */
833 gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
834 &state, block_async_full_destroy);
835 fail_unless (state == 2);
837 /* block with the same data, callback is called */
839 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
840 &state, block_async_full_destroy);
841 fail_unless (state == 2);
843 /* now change user_data (to NULL in this case) so destroy_notify should be
846 gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
847 NULL, block_async_full_destroy);
848 fail_unless (state == 2);
850 gst_object_unref (pad);
855 GST_START_TEST (test_block_async_full_destroy_dispose)
858 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
861 pad = gst_pad_new ("src", GST_PAD_SRC);
862 fail_unless (pad != NULL);
863 gst_pad_set_active (pad, TRUE);
865 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
866 &state, block_async_full_destroy);
868 gst_pad_push (pad, gst_buffer_new ());
869 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
871 fail_unless_equals_int (state, 1);
872 gst_pad_push_event (pad, gst_event_new_flush_stop ());
874 /* gst_pad_dispose calls the destroy_notify function if necessary */
875 gst_object_unref (pad);
877 fail_unless_equals_int (state, 2);
884 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
886 gboolean *bool_user_data = (gboolean *) user_data;
888 /* here we should have blocked == 1 unblocked == 0 */
890 fail_unless (blocked == FALSE);
892 fail_unless (bool_user_data[0] == TRUE);
893 fail_unless (bool_user_data[1] == TRUE);
894 fail_unless (bool_user_data[2] == FALSE);
896 bool_user_data[2] = TRUE;
901 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
903 g_warn_if_reached ();
907 block_async_second_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
909 gboolean *bool_user_data = (gboolean *) user_data;
911 fail_unless (blocked == TRUE);
913 fail_unless (bool_user_data[0] == TRUE);
914 fail_unless (bool_user_data[1] == FALSE);
915 fail_unless (bool_user_data[2] == FALSE);
917 bool_user_data[1] = TRUE;
919 fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_no_flush_cb,
924 block_async_first_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
926 static int n_calls = 0;
927 gboolean *bool_user_data = (gboolean *) user_data;
929 fail_unless (blocked == TRUE);
932 /* we expect this callback to be called only once */
933 g_warn_if_reached ();
935 *bool_user_data = blocked;
937 fail_unless (bool_user_data[0] == TRUE);
938 fail_unless (bool_user_data[1] == FALSE);
939 fail_unless (bool_user_data[2] == FALSE);
941 fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_not_called,
944 /* replace block_async_first with block_async_second so next time the pad is
945 * blocked the latter should be called */
946 fail_unless (gst_pad_set_blocked_async (pad, TRUE,
947 block_async_second_no_flush, user_data));
950 GST_START_TEST (test_block_async_replace_callback_no_flush)
953 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
955 pad = gst_pad_new ("src", GST_PAD_SRC);
956 fail_unless (pad != NULL);
957 gst_pad_set_active (pad, TRUE);
959 fail_unless (gst_pad_set_blocked_async (pad, TRUE, block_async_first_no_flush,
962 gst_pad_push (pad, gst_buffer_new ());
963 fail_unless (bool_user_data[0] == TRUE);
964 fail_unless (bool_user_data[1] == TRUE);
965 fail_unless (bool_user_data[2] == TRUE);
967 gst_object_unref (pad);
976 Suite *s = suite_create ("GstPad");
977 TCase *tc_chain = tcase_create ("general");
979 /* turn off timeout */
980 tcase_set_timeout (tc_chain, 60);
982 suite_add_tcase (s, tc_chain);
983 tcase_add_test (tc_chain, test_link);
984 tcase_add_test (tc_chain, test_refcount);
985 tcase_add_test (tc_chain, test_get_allowed_caps);
986 tcase_add_test (tc_chain, test_link_unlink_threaded);
987 tcase_add_test (tc_chain, test_name_is_valid);
988 tcase_add_test (tc_chain, test_push_unlinked);
989 tcase_add_test (tc_chain, test_push_linked);
990 tcase_add_test (tc_chain, test_push_buffer_list_compat);
991 tcase_add_test (tc_chain, test_flowreturn);
992 tcase_add_test (tc_chain, test_push_negotiation);
993 tcase_add_test (tc_chain, test_src_unref_unlink);
994 tcase_add_test (tc_chain, test_sink_unref_unlink);
995 tcase_add_test (tc_chain, test_block_async);
997 tcase_add_test (tc_chain, test_block_async_replace_callback);
999 tcase_add_test (tc_chain, test_block_async_full_destroy);
1000 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
1001 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1006 GST_CHECK_MAIN (gst_pad);