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", 2);
105 gst_caps_unref (caps);
107 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
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", 2);
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 /* caps replaced by src caps */
143 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
145 gst_pad_unlink (src, sink);
146 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
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", 2);
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);
192 fail_unless (gst_caps_is_equal (gotcaps, caps));
194 ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 1);
195 gst_caps_unref (gotcaps);
197 gst_pad_unlink (src, sink);
200 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
201 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
202 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
204 gst_object_unref (src);
205 gst_object_unref (sink);
207 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
208 gst_caps_unref (caps);
214 name_is_valid (const gchar * name, GstPadPresence presence)
217 GstCaps *any = GST_CAPS_ANY;
219 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
221 gst_object_unref (GST_OBJECT (new));
227 GST_START_TEST (test_name_is_valid)
229 gboolean result = FALSE;
231 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
232 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
233 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
236 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
237 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
238 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
239 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
240 ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
242 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
243 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
249 _probe_handler (GstPad * pad, GstBuffer * buffer, gpointer userdata)
251 gint ret = GPOINTER_TO_INT (userdata);
258 GST_START_TEST (test_push_unlinked)
265 src = gst_pad_new ("src", GST_PAD_SRC);
266 fail_if (src == NULL);
267 caps = gst_pad_get_allowed_caps (src);
268 fail_unless (caps == NULL);
270 caps = gst_caps_from_string ("foo/bar");
272 gst_pad_set_caps (src, caps);
273 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
275 /* pushing on an unlinked pad will drop the buffer */
276 buffer = gst_buffer_new ();
277 gst_buffer_ref (buffer);
278 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
279 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
280 gst_buffer_unref (buffer);
282 /* adding a probe that returns FALSE will drop the buffer without trying
284 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
285 GINT_TO_POINTER (0));
286 buffer = gst_buffer_new ();
287 gst_buffer_ref (buffer);
288 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
289 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
290 gst_buffer_unref (buffer);
291 gst_pad_remove_buffer_probe (src, id);
293 /* adding a probe that returns TRUE will still chain the buffer,
294 * and hence drop because pad is unlinked */
295 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
296 GINT_TO_POINTER (1));
297 buffer = gst_buffer_new ();
298 gst_buffer_ref (buffer);
299 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
300 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
301 gst_buffer_unref (buffer);
302 gst_pad_remove_buffer_probe (src, id);
306 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
307 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
309 gst_object_unref (src);
311 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
312 gst_caps_unref (caps);
317 GST_START_TEST (test_push_linked)
320 GstPadLinkReturn plr;
326 sink = gst_pad_new ("sink", GST_PAD_SINK);
327 fail_if (sink == NULL);
328 gst_pad_set_chain_function (sink, gst_check_chain_func);
330 src = gst_pad_new ("src", GST_PAD_SRC);
331 fail_if (src == NULL);
333 caps = gst_caps_from_string ("foo/bar");
335 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
337 gst_pad_set_caps (src, caps);
338 gst_pad_set_active (sink, TRUE);
339 gst_pad_set_caps (sink, caps);
340 /* one for me and one for each set_caps */
341 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
343 plr = gst_pad_link (src, sink);
344 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
345 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
347 buffer = gst_buffer_new ();
349 /* FIXME, new pad should be flushing */
350 gst_buffer_ref (buffer);
351 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
352 gst_buffer_ref (buffer);
353 fail_unless (gst_pad_chain (sink, buffer) == GST_FLOW_WRONG_STATE);
357 gst_pad_set_active (src, TRUE);
358 gst_pad_set_active (sink, TRUE);
361 /* pushing on a linked pad will drop the ref to the buffer */
362 gst_buffer_ref (buffer);
363 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
364 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
365 gst_buffer_unref (buffer);
366 fail_unless_equals_int (g_list_length (buffers), 1);
367 buffer = GST_BUFFER (buffers->data);
368 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
369 gst_buffer_unref (buffer);
370 g_list_free (buffers);
373 /* adding a probe that returns FALSE will drop the buffer without trying
375 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
376 GINT_TO_POINTER (0));
377 buffer = gst_buffer_new ();
378 gst_buffer_ref (buffer);
379 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
380 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
381 gst_buffer_unref (buffer);
382 gst_pad_remove_buffer_probe (src, id);
383 fail_unless_equals_int (g_list_length (buffers), 0);
385 /* adding a probe that returns TRUE will still chain the buffer */
386 id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
387 GINT_TO_POINTER (1));
388 buffer = gst_buffer_new ();
389 gst_buffer_ref (buffer);
390 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
391 gst_pad_remove_buffer_probe (src, id);
393 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
394 gst_buffer_unref (buffer);
395 fail_unless_equals_int (g_list_length (buffers), 1);
396 buffer = GST_BUFFER (buffers->data);
397 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
398 gst_buffer_unref (buffer);
399 g_list_free (buffers);
403 gst_pad_unlink (src, sink);
404 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
405 gst_object_unref (src);
406 gst_object_unref (sink);
407 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
409 gst_caps_unref (caps);
415 buffer_from_string (const gchar * str)
422 buf = gst_buffer_new_and_alloc (size);
424 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
425 memcpy (data, str, size);
426 gst_buffer_unmap (buf, data, size);
432 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
437 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
438 res = memcmp (data, str, size) == 0;
439 GST_DEBUG ("%s <-> %s: %d", (gchar *) data, str, res);
440 gst_buffer_unmap (buf, data, size);
445 GST_START_TEST (test_push_buffer_list_compat)
448 GstPadLinkReturn plr;
455 sink = gst_pad_new ("sink", GST_PAD_SINK);
456 fail_if (sink == NULL);
457 gst_pad_set_chain_function (sink, gst_check_chain_func);
458 /* leave chainlistfunc unset */
460 src = gst_pad_new ("src", GST_PAD_SRC);
461 fail_if (src == NULL);
463 caps = gst_caps_from_string ("foo/bar");
465 gst_pad_set_caps (src, caps);
466 gst_pad_set_active (sink, TRUE);
467 gst_pad_set_caps (sink, caps);
469 plr = gst_pad_link (src, sink);
470 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
472 list = gst_buffer_list_new ();
475 gst_pad_set_active (src, TRUE);
476 gst_pad_set_active (sink, TRUE);
479 /* adding to a buffer list will drop the ref to the buffer */
480 len = gst_buffer_list_len (list);
482 gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
483 gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
485 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
486 fail_unless_equals_int (g_list_length (buffers), 2);
487 buffer = GST_BUFFER (buffers->data);
488 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
489 fail_unless (buffer_compare (buffer, "ListGroup", 9));
490 gst_buffer_unref (buffer);
491 buffers = g_list_delete_link (buffers, buffers);
492 buffer = GST_BUFFER (buffers->data);
493 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
494 fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
495 gst_buffer_unref (buffer);
496 buffers = g_list_delete_link (buffers, buffers);
497 fail_unless (buffers == NULL);
500 gst_pad_unlink (src, sink);
501 gst_object_unref (src);
502 gst_object_unref (sink);
503 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
504 gst_caps_unref (caps);
509 GST_START_TEST (test_flowreturn)
514 /* test some of the macros */
515 ret = GST_FLOW_UNEXPECTED;
516 fail_if (strcmp (gst_flow_get_name (ret), "unexpected"));
517 quark = gst_flow_to_quark (ret);
518 fail_if (strcmp (g_quark_to_string (quark), "unexpected"));
520 ret = GST_FLOW_RESEND;
521 fail_if (strcmp (gst_flow_get_name (ret), "resend"));
522 quark = gst_flow_to_quark (ret);
523 fail_if (strcmp (g_quark_to_string (quark), "resend"));
526 ret = GST_FLOW_CUSTOM_SUCCESS;
527 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
528 quark = gst_flow_to_quark (ret);
529 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
531 ret = GST_FLOW_CUSTOM_ERROR;
532 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
533 quark = gst_flow_to_quark (ret);
534 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
536 /* custom returns clamping */
537 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
538 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
539 quark = gst_flow_to_quark (ret);
540 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
542 ret = GST_FLOW_CUSTOM_ERROR - 2;
543 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
544 quark = gst_flow_to_quark (ret);
545 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
548 ret = GST_FLOW_CUSTOM_ERROR + 2;
549 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
550 quark = gst_flow_to_quark (ret);
551 fail_unless (quark == 0);
556 GST_START_TEST (test_push_negotiation)
559 GstPadLinkReturn plr;
561 gst_caps_from_string ("audio/x-raw-int,width={16,32},depth={16,32}");
563 gst_caps_from_string ("audio/x-raw-int,width=32,depth={16,32}");
564 GstPadTemplate *src_template;
565 GstPadTemplate *sink_template;
570 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
571 GST_PAD_ALWAYS, srccaps);
572 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
573 GST_PAD_ALWAYS, sinkcaps);
574 gst_caps_unref (srccaps);
575 gst_caps_unref (sinkcaps);
577 sink = gst_pad_new_from_template (sink_template, "sink");
578 fail_if (sink == NULL);
579 gst_pad_set_chain_function (sink, gst_check_chain_func);
581 src = gst_pad_new_from_template (src_template, "src");
582 fail_if (src == NULL);
584 plr = gst_pad_link (src, sink);
585 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
587 buffer = gst_buffer_new ();
590 gst_pad_set_active (src, TRUE);
591 gst_pad_set_active (sink, TRUE);
593 caps = gst_caps_from_string ("audio/x-raw-int,width=16,depth=16");
595 /* Should fail if src pad caps are incompatible with sink pad caps */
596 gst_pad_set_caps (src, caps);
597 fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
600 gst_pad_unlink (src, sink);
601 gst_object_unref (src);
602 gst_object_unref (sink);
603 gst_caps_unref (caps);
604 gst_object_unref (sink_template);
605 gst_object_unref (src_template);
610 /* see that an unref also unlinks the pads */
611 GST_START_TEST (test_src_unref_unlink)
615 GstPadLinkReturn plr;
617 sink = gst_pad_new ("sink", GST_PAD_SINK);
618 fail_if (sink == NULL);
620 src = gst_pad_new ("src", GST_PAD_SRC);
621 fail_if (src == NULL);
623 caps = gst_caps_from_string ("foo/bar");
625 gst_pad_set_caps (src, caps);
626 gst_pad_set_active (sink, TRUE);
627 gst_pad_set_caps (sink, caps);
629 plr = gst_pad_link (src, sink);
630 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
632 /* unref the srcpad */
633 gst_object_unref (src);
635 /* sink should be unlinked now */
636 fail_if (gst_pad_is_linked (sink));
639 gst_object_unref (sink);
640 gst_caps_unref (caps);
645 /* see that an unref also unlinks the pads */
646 GST_START_TEST (test_sink_unref_unlink)
650 GstPadLinkReturn plr;
652 sink = gst_pad_new ("sink", GST_PAD_SINK);
653 fail_if (sink == NULL);
655 src = gst_pad_new ("src", GST_PAD_SRC);
656 fail_if (src == NULL);
658 caps = gst_caps_from_string ("foo/bar");
660 gst_pad_set_caps (src, caps);
661 gst_pad_set_active (sink, TRUE);
662 gst_pad_set_caps (sink, caps);
664 plr = gst_pad_link (src, sink);
665 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
667 /* unref the sinkpad */
668 gst_object_unref (sink);
670 /* src should be unlinked now */
671 fail_if (gst_pad_is_linked (src));
674 gst_object_unref (src);
675 gst_caps_unref (caps);
681 unblock_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
683 gboolean *bool_user_data = (gboolean *) user_data;
685 /* here we should have blocked == 1 unblocked == 0 */
686 fail_unless (bool_user_data[0] == TRUE);
687 fail_unless (bool_user_data[1] == FALSE);
689 bool_user_data[1] = TRUE;
693 block_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
695 gboolean *bool_user_data = (gboolean *) user_data;
697 /* here we should have blocked == 0 unblocked == 0 */
698 fail_unless (bool_user_data[0] == FALSE);
699 fail_unless (bool_user_data[1] == FALSE);
701 bool_user_data[0] = blocked;
703 gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, user_data);
706 GST_START_TEST (test_block_async)
709 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
711 gboolean data[2] = { FALSE, FALSE };
713 pad = gst_pad_new ("src", GST_PAD_SRC);
714 fail_unless (pad != NULL);
716 gst_pad_set_active (pad, TRUE);
717 gst_pad_set_blocked_async (pad, TRUE, block_async_cb, &data);
719 fail_unless (data[0] == FALSE);
720 fail_unless (data[1] == FALSE);
721 gst_pad_push (pad, gst_buffer_new ());
723 gst_object_unref (pad);
730 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
732 gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, NULL);
736 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
738 static int n_calls = 0;
739 gboolean *bool_user_data = (gboolean *) user_data;
742 /* we expect this callback to be called only once */
743 g_warn_if_reached ();
745 *bool_user_data = blocked;
747 /* replace block_async_first with block_async_second so next time the pad is
748 * blocked the latter should be called */
749 gst_pad_set_blocked_async (pad, TRUE, block_async_second, NULL);
751 /* unblock temporarily, in the next push block_async_second should be called
753 gst_pad_push_event (pad, gst_event_new_flush_start ());
756 GST_START_TEST (test_block_async_replace_callback)
761 pad = gst_pad_new ("src", GST_PAD_SRC);
762 fail_unless (pad != NULL);
763 gst_pad_set_active (pad, TRUE);
765 gst_pad_set_blocked_async (pad, TRUE, block_async_first, &blocked);
768 gst_pad_push (pad, gst_buffer_new ());
769 fail_unless (blocked == TRUE);
770 /* block_async_first flushes to unblock */
771 gst_pad_push_event (pad, gst_event_new_flush_stop ());
773 /* push again, this time block_async_second should be called */
774 gst_pad_push (pad, gst_buffer_new ());
775 fail_unless (blocked == TRUE);
777 gst_object_unref (pad);
784 block_async_full_destroy (gpointer user_data)
786 gint *state = (gint *) user_data;
788 fail_unless (*state < 2);
790 GST_DEBUG ("setting state to 2");
795 block_async_full_cb (GstPad * pad, gboolean blocked, gpointer user_data)
797 *(gint *) user_data = (gint) blocked;
799 gst_pad_push_event (pad, gst_event_new_flush_start ());
800 GST_DEBUG ("setting state to 1");
803 GST_START_TEST (test_block_async_full_destroy)
806 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
809 pad = gst_pad_new ("src", GST_PAD_SRC);
810 fail_unless (pad != NULL);
811 gst_pad_set_active (pad, TRUE);
813 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
814 &state, block_async_full_destroy);
815 fail_unless (state == 0);
817 gst_pad_push (pad, gst_buffer_new ());
818 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
820 fail_unless (state == 1);
821 gst_pad_push_event (pad, gst_event_new_flush_stop ());
823 /* pad was already blocked so nothing happens */
824 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
825 &state, block_async_full_destroy);
826 fail_unless (state == 1);
828 /* unblock with the same data, callback is called */
829 gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
830 &state, block_async_full_destroy);
831 fail_unless (state == 2);
833 /* block with the same data, callback is called */
835 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
836 &state, block_async_full_destroy);
837 fail_unless (state == 2);
839 /* now change user_data (to NULL in this case) so destroy_notify should be
842 gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
843 NULL, block_async_full_destroy);
844 fail_unless (state == 2);
846 gst_object_unref (pad);
851 GST_START_TEST (test_block_async_full_destroy_dispose)
854 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
857 pad = gst_pad_new ("src", GST_PAD_SRC);
858 fail_unless (pad != NULL);
859 gst_pad_set_active (pad, TRUE);
861 gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
862 &state, block_async_full_destroy);
864 gst_pad_push (pad, gst_buffer_new ());
865 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
867 fail_unless_equals_int (state, 1);
868 gst_pad_push_event (pad, gst_event_new_flush_stop ());
870 /* gst_pad_dispose calls the destroy_notify function if necessary */
871 gst_object_unref (pad);
873 fail_unless_equals_int (state, 2);
880 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
882 gboolean *bool_user_data = (gboolean *) user_data;
884 /* here we should have blocked == 1 unblocked == 0 */
886 fail_unless (blocked == FALSE);
888 fail_unless (bool_user_data[0] == TRUE);
889 fail_unless (bool_user_data[1] == TRUE);
890 fail_unless (bool_user_data[2] == FALSE);
892 bool_user_data[2] = TRUE;
897 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
899 g_warn_if_reached ();
903 block_async_second_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
905 gboolean *bool_user_data = (gboolean *) user_data;
907 fail_unless (blocked == TRUE);
909 fail_unless (bool_user_data[0] == TRUE);
910 fail_unless (bool_user_data[1] == FALSE);
911 fail_unless (bool_user_data[2] == FALSE);
913 bool_user_data[1] = TRUE;
915 fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_no_flush_cb,
920 block_async_first_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
922 static int n_calls = 0;
923 gboolean *bool_user_data = (gboolean *) user_data;
925 fail_unless (blocked == TRUE);
928 /* we expect this callback to be called only once */
929 g_warn_if_reached ();
931 *bool_user_data = blocked;
933 fail_unless (bool_user_data[0] == TRUE);
934 fail_unless (bool_user_data[1] == FALSE);
935 fail_unless (bool_user_data[2] == FALSE);
937 fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_not_called,
940 /* replace block_async_first with block_async_second so next time the pad is
941 * blocked the latter should be called */
942 fail_unless (gst_pad_set_blocked_async (pad, TRUE,
943 block_async_second_no_flush, user_data));
946 GST_START_TEST (test_block_async_replace_callback_no_flush)
949 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
951 pad = gst_pad_new ("src", GST_PAD_SRC);
952 fail_unless (pad != NULL);
953 gst_pad_set_active (pad, TRUE);
955 fail_unless (gst_pad_set_blocked_async (pad, TRUE, block_async_first_no_flush,
958 gst_pad_push (pad, gst_buffer_new ());
959 fail_unless (bool_user_data[0] == TRUE);
960 fail_unless (bool_user_data[1] == TRUE);
961 fail_unless (bool_user_data[2] == TRUE);
963 gst_object_unref (pad);
972 Suite *s = suite_create ("GstPad");
973 TCase *tc_chain = tcase_create ("general");
975 /* turn off timeout */
976 tcase_set_timeout (tc_chain, 60);
978 suite_add_tcase (s, tc_chain);
979 tcase_add_test (tc_chain, test_link);
980 tcase_add_test (tc_chain, test_refcount);
981 tcase_add_test (tc_chain, test_get_allowed_caps);
982 tcase_add_test (tc_chain, test_link_unlink_threaded);
983 tcase_add_test (tc_chain, test_name_is_valid);
984 tcase_add_test (tc_chain, test_push_unlinked);
985 tcase_add_test (tc_chain, test_push_linked);
986 tcase_add_test (tc_chain, test_push_buffer_list_compat);
987 tcase_add_test (tc_chain, test_flowreturn);
988 tcase_add_test (tc_chain, test_push_negotiation);
989 tcase_add_test (tc_chain, test_src_unref_unlink);
990 tcase_add_test (tc_chain, test_sink_unref_unlink);
991 tcase_add_test (tc_chain, test_block_async);
993 tcase_add_test (tc_chain, test_block_async_replace_callback);
995 tcase_add_test (tc_chain, test_block_async_full_destroy);
996 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
997 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1002 GST_CHECK_MAIN (gst_pad);