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_new_any ();
223 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
224 gst_caps_unref (any);
226 gst_object_unref (GST_OBJECT (new));
232 GST_START_TEST (test_name_is_valid)
234 gboolean result = FALSE;
236 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
237 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
238 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
241 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
242 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
243 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
244 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
245 ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
247 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
248 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
253 static GstProbeReturn
254 _probe_handler (GstPad * pad, GstProbeType type, GstBuffer * buffer,
257 gint ret = GPOINTER_TO_INT (userdata);
262 return GST_PROBE_DROP;
265 GST_START_TEST (test_push_unlinked)
272 src = gst_pad_new ("src", GST_PAD_SRC);
273 fail_if (src == NULL);
274 caps = gst_pad_get_allowed_caps (src);
275 fail_unless (caps == NULL);
277 caps = gst_caps_from_string ("foo/bar");
279 gst_pad_set_caps (src, caps);
280 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
282 /* pushing on an inactive pad will return wrong state */
283 buffer = gst_buffer_new ();
284 gst_buffer_ref (buffer);
285 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
286 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
287 gst_buffer_unref (buffer);
289 gst_pad_set_active (src, TRUE);
291 /* pushing on an unlinked pad will drop the buffer */
292 buffer = gst_buffer_new ();
293 gst_buffer_ref (buffer);
294 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
295 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
296 gst_buffer_unref (buffer);
298 /* adding a probe that returns FALSE will drop the buffer without trying
300 id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
301 (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (0), NULL);
302 buffer = gst_buffer_new ();
303 gst_buffer_ref (buffer);
304 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
305 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
306 gst_buffer_unref (buffer);
307 gst_pad_remove_probe (src, id);
309 /* adding a probe that returns TRUE will still chain the buffer,
310 * and hence drop because pad is unlinked */
311 id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
312 (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (1), NULL);
313 buffer = gst_buffer_new ();
314 gst_buffer_ref (buffer);
315 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
316 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
317 gst_buffer_unref (buffer);
318 gst_pad_remove_probe (src, id);
322 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
323 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
325 gst_object_unref (src);
327 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
328 gst_caps_unref (caps);
333 GST_START_TEST (test_push_linked)
336 GstPadLinkReturn plr;
342 sink = gst_pad_new ("sink", GST_PAD_SINK);
343 fail_if (sink == NULL);
344 gst_pad_set_chain_function (sink, gst_check_chain_func);
346 src = gst_pad_new ("src", GST_PAD_SRC);
347 fail_if (src == NULL);
349 caps = gst_caps_from_string ("foo/bar");
351 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
353 gst_pad_set_caps (src, caps);
354 gst_pad_set_active (sink, TRUE);
355 gst_pad_set_caps (sink, caps);
356 /* one for me and one for each set_caps */
357 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
359 plr = gst_pad_link (src, sink);
360 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
361 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
363 buffer = gst_buffer_new ();
365 /* FIXME, new pad should be flushing */
366 gst_buffer_ref (buffer);
367 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
368 gst_buffer_ref (buffer);
369 fail_unless (gst_pad_chain (sink, buffer) == GST_FLOW_WRONG_STATE);
373 gst_pad_set_active (src, TRUE);
374 gst_pad_set_active (sink, TRUE);
377 /* pushing on a linked pad will drop the ref to the buffer */
378 gst_buffer_ref (buffer);
379 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
380 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
381 gst_buffer_unref (buffer);
382 fail_unless_equals_int (g_list_length (buffers), 1);
383 buffer = GST_BUFFER (buffers->data);
384 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
385 gst_buffer_unref (buffer);
386 g_list_free (buffers);
389 /* adding a probe that returns FALSE will drop the buffer without trying
391 id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
392 (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (0), NULL);
393 buffer = gst_buffer_new ();
394 gst_buffer_ref (buffer);
395 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
396 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
397 gst_buffer_unref (buffer);
398 gst_pad_remove_probe (src, id);
399 fail_unless_equals_int (g_list_length (buffers), 0);
401 /* adding a probe that returns TRUE will still chain the buffer */
402 id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
403 (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (1), NULL);
404 buffer = gst_buffer_new ();
405 gst_buffer_ref (buffer);
406 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
407 gst_pad_remove_probe (src, id);
409 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
410 gst_buffer_unref (buffer);
411 fail_unless_equals_int (g_list_length (buffers), 1);
412 buffer = GST_BUFFER (buffers->data);
413 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
414 gst_buffer_unref (buffer);
415 g_list_free (buffers);
419 gst_pad_unlink (src, sink);
420 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
421 gst_object_unref (src);
422 gst_object_unref (sink);
423 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
425 gst_caps_unref (caps);
431 buffer_from_string (const gchar * str)
438 buf = gst_buffer_new_and_alloc (size);
440 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
441 memcpy (data, str, size);
442 gst_buffer_unmap (buf, data, size);
448 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
453 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
454 res = memcmp (data, str, size) == 0;
455 GST_DEBUG ("%s <-> %s: %d", (gchar *) data, str, res);
456 gst_buffer_unmap (buf, data, size);
461 GST_START_TEST (test_push_buffer_list_compat)
464 GstPadLinkReturn plr;
470 sink = gst_pad_new ("sink", GST_PAD_SINK);
471 fail_if (sink == NULL);
472 gst_pad_set_chain_function (sink, gst_check_chain_func);
473 /* leave chainlistfunc unset */
475 src = gst_pad_new ("src", GST_PAD_SRC);
476 fail_if (src == NULL);
478 caps = gst_caps_from_string ("foo/bar");
480 gst_pad_set_caps (src, caps);
481 gst_pad_set_active (sink, TRUE);
482 gst_pad_set_caps (sink, caps);
484 plr = gst_pad_link (src, sink);
485 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
487 list = gst_buffer_list_new ();
490 gst_pad_set_active (src, TRUE);
491 gst_pad_set_active (sink, TRUE);
494 /* adding to a buffer list will drop the ref to the buffer */
495 gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
496 gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
498 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
499 fail_unless_equals_int (g_list_length (buffers), 2);
500 buffer = GST_BUFFER (buffers->data);
501 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
502 fail_unless (buffer_compare (buffer, "ListGroup", 9));
503 gst_buffer_unref (buffer);
504 buffers = g_list_delete_link (buffers, buffers);
505 buffer = GST_BUFFER (buffers->data);
506 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
507 fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
508 gst_buffer_unref (buffer);
509 buffers = g_list_delete_link (buffers, buffers);
510 fail_unless (buffers == NULL);
513 gst_pad_unlink (src, sink);
514 gst_object_unref (src);
515 gst_object_unref (sink);
516 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
517 gst_caps_unref (caps);
522 GST_START_TEST (test_flowreturn)
527 /* test some of the macros */
529 fail_if (strcmp (gst_flow_get_name (ret), "eos"));
530 quark = gst_flow_to_quark (ret);
531 fail_if (strcmp (g_quark_to_string (quark), "eos"));
533 ret = GST_FLOW_RESEND;
534 fail_if (strcmp (gst_flow_get_name (ret), "resend"));
535 quark = gst_flow_to_quark (ret);
536 fail_if (strcmp (g_quark_to_string (quark), "resend"));
539 ret = GST_FLOW_CUSTOM_SUCCESS;
540 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
541 quark = gst_flow_to_quark (ret);
542 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
544 ret = GST_FLOW_CUSTOM_ERROR;
545 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
546 quark = gst_flow_to_quark (ret);
547 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
549 /* custom returns clamping */
550 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
551 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
552 quark = gst_flow_to_quark (ret);
553 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
555 ret = GST_FLOW_CUSTOM_ERROR - 2;
556 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
557 quark = gst_flow_to_quark (ret);
558 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
561 ret = GST_FLOW_CUSTOM_ERROR + 2;
562 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
563 quark = gst_flow_to_quark (ret);
564 fail_unless (quark == 0);
569 GST_START_TEST (test_push_negotiation)
572 GstPadLinkReturn plr;
574 gst_caps_from_string ("audio/x-raw-int,width={16,32},depth={16,32}");
576 gst_caps_from_string ("audio/x-raw-int,width=32,depth={16,32}");
577 GstPadTemplate *src_template;
578 GstPadTemplate *sink_template;
582 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
583 GST_PAD_ALWAYS, srccaps);
584 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
585 GST_PAD_ALWAYS, sinkcaps);
586 gst_caps_unref (srccaps);
587 gst_caps_unref (sinkcaps);
589 sink = gst_pad_new_from_template (sink_template, "sink");
590 fail_if (sink == NULL);
591 gst_pad_set_chain_function (sink, gst_check_chain_func);
593 src = gst_pad_new_from_template (src_template, "src");
594 fail_if (src == NULL);
596 plr = gst_pad_link (src, sink);
597 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
600 gst_pad_set_active (src, TRUE);
601 gst_pad_set_active (sink, TRUE);
603 caps = gst_caps_from_string ("audio/x-raw-int,width=16,depth=16");
605 /* Should fail if src pad caps are incompatible with sink pad caps */
606 gst_pad_set_caps (src, caps);
607 fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
610 gst_pad_unlink (src, sink);
611 gst_object_unref (src);
612 gst_object_unref (sink);
613 gst_caps_unref (caps);
614 gst_object_unref (sink_template);
615 gst_object_unref (src_template);
620 /* see that an unref also unlinks the pads */
621 GST_START_TEST (test_src_unref_unlink)
625 GstPadLinkReturn plr;
627 sink = gst_pad_new ("sink", GST_PAD_SINK);
628 fail_if (sink == NULL);
630 src = gst_pad_new ("src", GST_PAD_SRC);
631 fail_if (src == NULL);
633 caps = gst_caps_from_string ("foo/bar");
635 gst_pad_set_caps (src, caps);
636 gst_pad_set_active (sink, TRUE);
637 gst_pad_set_caps (sink, caps);
639 plr = gst_pad_link (src, sink);
640 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
642 /* unref the srcpad */
643 gst_object_unref (src);
645 /* sink should be unlinked now */
646 fail_if (gst_pad_is_linked (sink));
649 gst_object_unref (sink);
650 gst_caps_unref (caps);
655 /* see that an unref also unlinks the pads */
656 GST_START_TEST (test_sink_unref_unlink)
660 GstPadLinkReturn plr;
662 sink = gst_pad_new ("sink", GST_PAD_SINK);
663 fail_if (sink == NULL);
665 src = gst_pad_new ("src", GST_PAD_SRC);
666 fail_if (src == NULL);
668 caps = gst_caps_from_string ("foo/bar");
670 gst_pad_set_caps (src, caps);
671 gst_pad_set_active (sink, TRUE);
672 gst_pad_set_caps (sink, caps);
674 plr = gst_pad_link (src, sink);
675 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
677 /* unref the sinkpad */
678 gst_object_unref (sink);
680 /* src should be unlinked now */
681 fail_if (gst_pad_is_linked (src));
684 gst_object_unref (src);
685 gst_caps_unref (caps);
692 static GstProbeReturn
693 block_async_cb (GstPad * pad, GstProbeType type, gpointer type_data,
696 gboolean *bool_user_data = (gboolean *) user_data;
698 fail_unless ((type & GST_PROBE_TYPE_BLOCK) != 0);
700 /* here we should have blocked == 0 unblocked == 0 */
701 fail_unless (bool_user_data[0] == FALSE);
702 fail_unless (bool_user_data[1] == FALSE);
704 bool_user_data[0] = TRUE;
706 gst_pad_remove_probe (pad, id);
707 bool_user_data[1] = TRUE;
712 GST_START_TEST (test_block_async)
715 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
717 gboolean data[2] = { FALSE, FALSE };
719 pad = gst_pad_new ("src", GST_PAD_SRC);
720 fail_unless (pad != NULL);
722 gst_pad_set_active (pad, TRUE);
723 id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK, block_async_cb, &data,
726 fail_unless (data[0] == FALSE);
727 fail_unless (data[1] == FALSE);
728 gst_pad_push (pad, gst_buffer_new ());
730 gst_object_unref (pad);
737 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
739 gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
743 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
745 static int n_calls = 0;
746 gboolean *bool_user_data = (gboolean *) user_data;
749 /* we expect this callback to be called only once */
750 g_warn_if_reached ();
752 *bool_user_data = blocked;
754 /* replace block_async_first with block_async_second so next time the pad is
755 * blocked the latter should be called */
756 gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
758 /* unblock temporarily, in the next push block_async_second should be called
760 gst_pad_push_event (pad, gst_event_new_flush_start ());
763 GST_START_TEST (test_block_async_replace_callback)
768 pad = gst_pad_new ("src", GST_PAD_SRC);
769 fail_unless (pad != NULL);
770 gst_pad_set_active (pad, TRUE);
772 gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
775 gst_pad_push (pad, gst_buffer_new ());
776 fail_unless (blocked == TRUE);
777 /* block_async_first flushes to unblock */
778 gst_pad_push_event (pad, gst_event_new_flush_stop ());
780 /* push again, this time block_async_second should be called */
781 gst_pad_push (pad, gst_buffer_new ());
782 fail_unless (blocked == TRUE);
784 gst_object_unref (pad);
791 block_async_full_destroy (gpointer user_data)
793 gint *state = (gint *) user_data;
795 fail_unless (*state < 2);
797 GST_DEBUG ("setting state to 2");
801 static GstProbeReturn
802 block_async_full_cb (GstPad * pad, GstProbeType type, gpointer type_data,
805 *(gint *) user_data = (gint) TRUE;
807 gst_pad_push_event (pad, gst_event_new_flush_start ());
808 GST_DEBUG ("setting state to 1");
813 GST_START_TEST (test_block_async_full_destroy)
816 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
820 pad = gst_pad_new ("src", GST_PAD_SRC);
821 fail_unless (pad != NULL);
822 gst_pad_set_active (pad, TRUE);
824 id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK, block_async_full_cb,
825 &state, block_async_full_destroy);
826 fail_unless (state == 0);
828 gst_pad_push (pad, gst_buffer_new ());
829 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
831 fail_unless (state == 1);
832 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
834 /* unblock callback is called */
835 gst_pad_remove_probe (pad, id);
836 fail_unless (state == 2);
838 gst_object_unref (pad);
843 GST_START_TEST (test_block_async_full_destroy_dispose)
846 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
849 pad = gst_pad_new ("src", GST_PAD_SRC);
850 fail_unless (pad != NULL);
851 gst_pad_set_active (pad, TRUE);
853 (void) gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK, block_async_full_cb,
854 &state, block_async_full_destroy);
856 gst_pad_push (pad, gst_buffer_new ());
857 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
859 fail_unless_equals_int (state, 1);
860 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
862 /* gst_BLOCK calls the destroy_notify function if necessary */
863 gst_object_unref (pad);
865 fail_unless_equals_int (state, 2);
873 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
875 gboolean *bool_user_data = (gboolean *) user_data;
877 /* here we should have blocked == 1 unblocked == 0 */
879 fail_unless (blocked == FALSE);
881 fail_unless (bool_user_data[0] == TRUE);
882 fail_unless (bool_user_data[1] == TRUE);
883 fail_unless (bool_user_data[2] == FALSE);
885 bool_user_data[2] = TRUE;
892 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
894 g_warn_if_reached ();
898 static GstProbeReturn
899 block_async_second_no_flush (GstPad * pad, GstProbeType type,
900 gpointer type_data, gpointer user_data)
902 gboolean *bool_user_data = (gboolean *) user_data;
904 GST_DEBUG ("second probe called");
906 fail_unless (type & GST_PROBE_TYPE_BLOCK);
908 fail_unless (bool_user_data[0] == TRUE);
909 fail_unless (bool_user_data[1] == FALSE);
910 fail_unless (bool_user_data[2] == FALSE);
912 bool_user_data[1] = TRUE;
914 GST_DEBUG ("removing second probe with id %lu", id);
915 gst_pad_remove_probe (pad, id);
920 static GstProbeReturn
921 block_async_first_no_flush (GstPad * pad, GstProbeType type, gpointer type_data,
924 static int n_calls = 0;
925 gboolean *bool_user_data = (gboolean *) user_data;
927 fail_unless (type & GST_PROBE_TYPE_BLOCK);
929 GST_DEBUG ("first probe called");
932 /* we expect this callback to be called only once */
933 g_warn_if_reached ();
935 *bool_user_data = TRUE;
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 GST_DEBUG ("removing first probe with id %lu", id);
942 gst_pad_remove_probe (pad, id);
944 GST_DEBUG ("adding second probe");
945 /* replace block_async_first with block_async_second so next time the pad is
946 * blocked the latter should be called */
947 id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK,
948 block_async_second_no_flush, user_data, NULL);
949 GST_DEBUG ("added probe with id %lu", id);
954 GST_START_TEST (test_block_async_replace_callback_no_flush)
957 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
959 pad = gst_pad_new ("src", GST_PAD_SRC);
960 fail_unless (pad != NULL);
961 gst_pad_set_active (pad, TRUE);
963 GST_DEBUG ("adding probe");
964 id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK,
965 block_async_first_no_flush, bool_user_data, NULL);
966 GST_DEBUG ("added probe with id %lu", id);
969 GST_DEBUG ("pushing buffer");
970 gst_pad_push (pad, gst_buffer_new ());
971 fail_unless (bool_user_data[0] == TRUE);
972 fail_unless (bool_user_data[1] == TRUE);
973 fail_unless (bool_user_data[2] == FALSE);
975 gst_object_unref (pad);
984 Suite *s = suite_create ("GstPad");
985 TCase *tc_chain = tcase_create ("general");
987 /* turn off timeout */
988 tcase_set_timeout (tc_chain, 60);
990 suite_add_tcase (s, tc_chain);
991 tcase_add_test (tc_chain, test_link);
992 tcase_add_test (tc_chain, test_refcount);
993 tcase_add_test (tc_chain, test_get_allowed_caps);
994 tcase_add_test (tc_chain, test_link_unlink_threaded);
995 tcase_add_test (tc_chain, test_name_is_valid);
996 tcase_add_test (tc_chain, test_push_unlinked);
997 tcase_add_test (tc_chain, test_push_linked);
998 tcase_add_test (tc_chain, test_push_buffer_list_compat);
999 tcase_add_test (tc_chain, test_flowreturn);
1000 tcase_add_test (tc_chain, test_push_negotiation);
1001 tcase_add_test (tc_chain, test_src_unref_unlink);
1002 tcase_add_test (tc_chain, test_sink_unref_unlink);
1003 tcase_add_test (tc_chain, test_block_async);
1005 tcase_add_test (tc_chain, test_block_async_replace_callback);
1007 tcase_add_test (tc_chain, test_block_async_full_destroy);
1008 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
1009 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1014 GST_CHECK_MAIN (gst_pad);