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., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include <gst/check/gstcheck.h>
24 static GstSegment dummy_segment;
26 GST_START_TEST (test_link)
34 src = gst_pad_new ("source", GST_PAD_SRC);
35 fail_if (src == NULL);
36 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
38 name = gst_pad_get_name (src);
39 fail_unless (strcmp (name, "source") == 0);
40 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
43 sink = gst_pad_new ("sink", GST_PAD_SINK);
44 fail_if (sink == NULL);
46 /* linking without templates or caps should work */
47 ret = gst_pad_link (src, sink);
48 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
49 ASSERT_OBJECT_REFCOUNT (sink, "sink pad", 1);
50 fail_unless (ret == GST_PAD_LINK_OK);
52 ASSERT_CRITICAL (gst_pad_get_pad_template (NULL));
54 srct = gst_pad_get_pad_template (src);
55 fail_unless (srct == NULL);
56 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
59 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
60 gst_object_unref (src);
61 gst_object_unref (sink);
66 /* threaded link/unlink */
68 static GstPad *src, *sink;
71 thread_link_unlink (gpointer data)
75 while (THREAD_TEST_RUNNING ()) {
76 gst_pad_link (src, sink);
77 gst_pad_unlink (src, sink);
82 GST_START_TEST (test_link_unlink_threaded)
87 src = gst_pad_new ("source", GST_PAD_SRC);
88 fail_if (src == NULL);
89 sink = gst_pad_new ("sink", GST_PAD_SINK);
90 fail_if (sink == NULL);
92 caps = gst_caps_from_string ("foo/bar");
93 gst_pad_set_active (src, TRUE);
94 gst_pad_set_caps (src, caps);
95 gst_pad_set_active (sink, TRUE);
96 gst_pad_set_caps (sink, caps);
97 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
99 MAIN_START_THREADS (5, thread_link_unlink, NULL);
100 for (i = 0; i < 1000; ++i) {
101 gst_pad_is_linked (src);
102 gst_pad_is_linked (sink);
105 MAIN_STOP_THREADS ();
107 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
108 gst_caps_unref (caps);
110 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
111 gst_object_unref (src);
112 gst_object_unref (sink);
117 GST_START_TEST (test_refcount)
121 GstPadLinkReturn plr;
123 sink = gst_pad_new ("sink", GST_PAD_SINK);
124 fail_if (sink == NULL);
126 src = gst_pad_new ("src", GST_PAD_SRC);
127 fail_if (src == NULL);
129 caps = gst_caps_from_string ("foo/bar");
131 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
133 /* can't set caps on flushing sinkpad */
134 fail_if (gst_pad_set_caps (src, caps) == TRUE);
135 fail_if (gst_pad_set_caps (sink, caps) == TRUE);
136 /* one for me and one for each set_caps */
137 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
139 gst_pad_set_active (src, TRUE);
140 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
141 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
143 gst_pad_set_active (sink, TRUE);
144 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
145 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
147 plr = gst_pad_link (src, sink);
148 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
149 /* src caps added to pending caps on sink */
150 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
152 gst_pad_unlink (src, sink);
153 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
156 gst_object_unref (src);
157 gst_object_unref (sink);
158 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
160 gst_caps_unref (caps);
165 GST_START_TEST (test_get_allowed_caps)
168 GstCaps *caps, *gotcaps;
170 GstPadLinkReturn plr;
172 ASSERT_CRITICAL (gst_pad_get_allowed_caps (NULL));
174 buffer = gst_buffer_new ();
175 ASSERT_CRITICAL (gst_pad_get_allowed_caps ((GstPad *) buffer));
176 gst_buffer_unref (buffer);
178 src = gst_pad_new ("src", GST_PAD_SRC);
179 fail_if (src == NULL);
180 caps = gst_pad_get_allowed_caps (src);
181 fail_unless (caps == NULL);
183 caps = gst_caps_from_string ("foo/bar");
185 sink = gst_pad_new ("sink", GST_PAD_SINK);
186 gst_pad_set_active (src, TRUE);
187 /* source pad is active and will accept the caps event */
188 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
189 /* sink pad is not active and will refuse the caps event */
190 fail_if (gst_pad_set_caps (sink, caps) == TRUE);
191 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
193 gst_pad_set_active (sink, TRUE);
194 /* sink pad is now active and will accept the caps event */
195 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
196 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
198 plr = gst_pad_link (src, sink);
199 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
201 gotcaps = gst_pad_get_allowed_caps (src);
202 fail_if (gotcaps == NULL);
203 fail_unless (gst_caps_is_equal (gotcaps, caps));
205 ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 4);
206 gst_caps_unref (gotcaps);
208 gst_pad_unlink (src, sink);
211 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
212 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
213 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
215 gst_object_unref (src);
216 gst_object_unref (sink);
218 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
219 gst_caps_unref (caps);
224 static GstCaps *event_caps = NULL;
227 sticky_event (GstPad * pad, GstObject * parent, GstEvent * event)
231 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS
232 || GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START
233 || GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
235 if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
236 gst_event_unref (event);
240 /* Ensure we get here just once: */
241 fail_unless (event_caps == NULL);
243 /* The event must arrive before any buffer: */
244 fail_unless_equals_int (g_list_length (buffers), 0);
246 gst_event_parse_caps (event, &caps);
247 event_caps = gst_caps_ref (caps);
249 gst_event_unref (event);
254 /* Tests whether caps get properly forwarded when pads
255 are initially unlinked */
256 GST_START_TEST (test_sticky_caps_unlinked)
259 GstPadTemplate *src_template, *sink_template;
263 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
264 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
265 GST_PAD_ALWAYS, caps);
266 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
267 GST_PAD_ALWAYS, caps);
268 gst_caps_unref (caps);
270 src = gst_pad_new_from_template (src_template, "src");
271 fail_if (src == NULL);
272 sink = gst_pad_new_from_template (sink_template, "sink");
273 fail_if (sink == NULL);
274 gst_pad_set_event_function (sink, sticky_event);
275 gst_pad_set_chain_function (sink, gst_check_chain_func);
277 gst_object_unref (src_template);
278 gst_object_unref (sink_template);
280 gst_pad_set_active (src, TRUE);
282 fail_unless (gst_pad_push_event (src,
283 gst_event_new_stream_start ("test")) == TRUE);
285 caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
286 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
288 event = gst_event_new_caps (caps);
289 fail_unless (gst_pad_push_event (src, event) == TRUE);
290 fail_unless (event_caps == NULL);
292 fail_unless (gst_pad_push_event (src,
293 gst_event_new_segment (&dummy_segment)) == TRUE);
295 /* Linking and activating will not forward the sticky event yet... */
296 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
297 gst_pad_set_active (sink, TRUE);
298 fail_unless (event_caps == NULL);
300 /* ...but the first buffer will: */
301 fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
302 fail_unless (event_caps == caps);
303 fail_unless_equals_int (g_list_length (buffers), 1);
305 gst_check_drop_buffers ();
307 gst_caps_replace (&caps, NULL);
308 gst_caps_replace (&event_caps, NULL);
309 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
310 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
311 gst_object_unref (src);
312 gst_object_unref (sink);
317 /* Same as test_sticky_caps_unlinked except that the source pad
318 * has a template of ANY and we will attempt to push
319 * incompatible caps */
320 GST_START_TEST (test_sticky_caps_unlinked_incompatible)
322 GstCaps *caps, *failcaps;
323 GstPadTemplate *src_template, *sink_template;
327 /* Source pad has ANY caps
328 * Sink pad has foobar caps
329 * We will push the pony express caps (which should fail)
331 caps = gst_caps_new_any ();
332 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
333 GST_PAD_ALWAYS, caps);
334 gst_caps_unref (caps);
335 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
336 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
337 GST_PAD_ALWAYS, caps);
338 gst_caps_unref (caps);
340 src = gst_pad_new_from_template (src_template, "src");
341 fail_if (src == NULL);
342 sink = gst_pad_new_from_template (sink_template, "sink");
343 fail_if (sink == NULL);
344 gst_pad_set_event_function (sink, sticky_event);
345 gst_pad_set_chain_function (sink, gst_check_chain_func);
347 gst_object_unref (src_template);
348 gst_object_unref (sink_template);
350 gst_pad_set_active (src, TRUE);
352 fail_unless (gst_pad_push_event (src,
353 gst_event_new_stream_start ("test")) == TRUE);
355 failcaps = gst_caps_from_string ("pony/express, failure=(boolean)true");
356 ASSERT_CAPS_REFCOUNT (failcaps, "caps", 1);
358 event = gst_event_new_caps (failcaps);
359 gst_caps_unref (failcaps);
360 /* The pad isn't linked yet, and anything matches the source pad template
362 fail_unless (gst_pad_push_event (src, event) == TRUE);
363 fail_unless (event_caps == NULL);
365 fail_unless (gst_pad_push_event (src,
366 gst_event_new_segment (&dummy_segment)) == TRUE);
368 /* Linking and activating will not forward the sticky event yet... */
369 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
370 gst_pad_set_active (sink, TRUE);
371 fail_unless (event_caps == NULL);
373 /* ...but the first buffer will and should FAIL since the caps
374 * are not compatible */
375 fail_unless (gst_pad_push (src,
376 gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
377 /* We shouldn't have received the caps event since it's incompatible */
378 fail_unless (event_caps == NULL);
379 /* We shouldn't have received any buffers since caps are incompatible */
380 fail_unless_equals_int (g_list_length (buffers), 0);
382 gst_check_drop_buffers ();
384 gst_caps_replace (&event_caps, NULL);
386 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
387 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
388 gst_object_unref (src);
389 gst_object_unref (sink);
394 /* Like test_sticky_caps_unlinked, but link before caps: */
396 GST_START_TEST (test_sticky_caps_flushing)
399 GstPadTemplate *src_template, *sink_template;
403 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
404 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
405 GST_PAD_ALWAYS, caps);
406 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
407 GST_PAD_ALWAYS, caps);
408 gst_caps_unref (caps);
410 src = gst_pad_new_from_template (src_template, "src");
411 fail_if (src == NULL);
412 sink = gst_pad_new_from_template (sink_template, "sink");
413 fail_if (sink == NULL);
414 gst_pad_set_event_function (sink, sticky_event);
415 gst_pad_set_chain_function (sink, gst_check_chain_func);
417 gst_object_unref (src_template);
418 gst_object_unref (sink_template);
420 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
422 caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
423 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
425 event = gst_event_new_caps (caps);
427 gst_pad_set_active (src, TRUE);
428 fail_unless (gst_pad_push_event (src,
429 gst_event_new_stream_start ("test")) == TRUE);
430 /* The caps event gets accepted by the source pad (and stored) */
431 fail_unless (gst_pad_push_event (src, event) == TRUE);
432 /* But wasn't forwarded since the sink pad is flushing (not activated) */
433 fail_unless (event_caps == NULL);
435 fail_unless (gst_pad_push_event (src,
436 gst_event_new_segment (&dummy_segment)) == TRUE);
438 /* Activating will not forward the sticky event yet... */
439 gst_pad_set_active (sink, TRUE);
440 fail_unless (event_caps == NULL);
442 /* ...but the first buffer will: */
443 fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
444 fail_unless (event_caps == caps);
445 fail_unless_equals_int (g_list_length (buffers), 1);
447 gst_check_drop_buffers ();
449 gst_caps_replace (&caps, NULL);
450 gst_caps_replace (&event_caps, NULL);
452 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
453 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
454 gst_object_unref (src);
455 gst_object_unref (sink);
461 name_is_valid (const gchar * name, GstPadPresence presence)
464 GstCaps *any = gst_caps_new_any ();
466 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
467 gst_caps_unref (any);
469 gst_object_unref (GST_OBJECT (new));
475 GST_START_TEST (test_name_is_valid)
477 gboolean result = FALSE;
479 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
480 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
481 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
484 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
485 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
486 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
487 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
488 ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
490 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
491 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
496 static GstPadProbeReturn
497 _probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
499 gint ret = GPOINTER_TO_INT (userdata);
502 return GST_PAD_PROBE_OK;
504 return GST_PAD_PROBE_DROP;
507 GST_START_TEST (test_push_unlinked)
514 src = gst_pad_new ("src", GST_PAD_SRC);
515 fail_if (src == NULL);
516 caps = gst_pad_get_allowed_caps (src);
517 fail_unless (caps == NULL);
519 caps = gst_caps_from_string ("foo/bar");
521 /* pushing on an inactive pad will return wrong state */
522 GST_DEBUG ("push buffer inactive");
523 buffer = gst_buffer_new ();
524 gst_buffer_ref (buffer);
525 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
526 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
527 gst_buffer_unref (buffer);
529 gst_pad_set_active (src, TRUE);
530 fail_unless (gst_pad_push_event (src,
531 gst_event_new_stream_start ("test")) == TRUE);
532 GST_DEBUG ("push caps event inactive");
533 gst_pad_set_caps (src, caps);
534 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
535 fail_unless (gst_pad_push_event (src,
536 gst_event_new_segment (&dummy_segment)) == TRUE);
538 /* pushing on an unlinked pad will drop the buffer */
539 GST_DEBUG ("push buffer unlinked");
540 buffer = gst_buffer_new ();
541 gst_buffer_ref (buffer);
542 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
543 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
544 gst_buffer_unref (buffer);
546 /* adding a probe that returns _DROP will drop the buffer without trying
548 GST_DEBUG ("push buffer drop");
549 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
550 _probe_handler, GINT_TO_POINTER (0), NULL);
551 buffer = gst_buffer_new ();
552 gst_buffer_ref (buffer);
553 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
554 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
555 gst_buffer_unref (buffer);
556 gst_pad_remove_probe (src, id);
558 /* adding a probe that returns _OK will still chain the buffer,
559 * and hence drop because pad is unlinked */
560 GST_DEBUG ("push buffer ok");
561 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
562 _probe_handler, GINT_TO_POINTER (1), NULL);
563 buffer = gst_buffer_new ();
564 gst_buffer_ref (buffer);
565 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
566 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
567 gst_buffer_unref (buffer);
568 gst_pad_remove_probe (src, id);
572 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
573 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
575 gst_object_unref (src);
577 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
578 gst_caps_unref (caps);
583 GST_START_TEST (test_push_linked)
586 GstPadLinkReturn plr;
592 sink = gst_pad_new ("sink", GST_PAD_SINK);
593 fail_if (sink == NULL);
594 gst_pad_set_chain_function (sink, gst_check_chain_func);
596 src = gst_pad_new ("src", GST_PAD_SRC);
597 fail_if (src == NULL);
599 caps = gst_caps_from_string ("foo/bar");
601 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
603 gst_pad_set_active (src, TRUE);
605 fail_unless (gst_pad_push_event (src,
606 gst_event_new_stream_start ("test")) == TRUE);
608 gst_pad_set_caps (src, caps);
610 fail_unless (gst_pad_push_event (src,
611 gst_event_new_segment (&dummy_segment)) == TRUE);
613 gst_pad_set_active (sink, TRUE);
614 /* one for me and one for each set_caps */
615 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
617 plr = gst_pad_link (src, sink);
618 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
619 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
621 buffer = gst_buffer_new ();
624 /* pushing on a linked pad will drop the ref to the buffer */
625 gst_buffer_ref (buffer);
626 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
627 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
628 gst_buffer_unref (buffer);
629 fail_unless_equals_int (g_list_length (buffers), 1);
630 buffer = GST_BUFFER (buffers->data);
631 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
632 gst_buffer_unref (buffer);
633 g_list_free (buffers);
636 /* adding a probe that returns FALSE will drop the buffer without trying
638 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
639 _probe_handler, GINT_TO_POINTER (0), NULL);
640 buffer = gst_buffer_new ();
641 gst_buffer_ref (buffer);
642 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
643 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
644 gst_buffer_unref (buffer);
645 gst_pad_remove_probe (src, id);
646 fail_unless_equals_int (g_list_length (buffers), 0);
648 /* adding a probe that returns TRUE will still chain the buffer */
649 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
650 _probe_handler, GINT_TO_POINTER (1), NULL);
651 buffer = gst_buffer_new ();
652 gst_buffer_ref (buffer);
653 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
654 gst_pad_remove_probe (src, id);
656 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
657 gst_buffer_unref (buffer);
658 fail_unless_equals_int (g_list_length (buffers), 1);
659 buffer = GST_BUFFER (buffers->data);
660 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
661 gst_buffer_unref (buffer);
662 g_list_free (buffers);
666 gst_pad_unlink (src, sink);
667 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
668 gst_object_unref (src);
669 gst_object_unref (sink);
670 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
672 gst_caps_unref (caps);
677 GST_START_TEST (test_push_linked_flushing)
681 GstPadLinkReturn plr;
686 src = gst_pad_new ("src", GST_PAD_SRC);
687 fail_if (src == NULL);
688 sink = gst_pad_new ("sink", GST_PAD_SINK);
689 fail_if (sink == NULL);
690 gst_pad_set_chain_function (sink, gst_check_chain_func);
692 caps = gst_pad_get_allowed_caps (src);
693 fail_unless (caps == NULL);
694 caps = gst_pad_get_allowed_caps (sink);
695 fail_unless (caps == NULL);
697 caps = gst_caps_from_string ("foo/bar");
699 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
701 gst_pad_set_active (src, TRUE);
702 fail_unless (gst_pad_push_event (src,
703 gst_event_new_stream_start ("test")) == TRUE);
704 gst_pad_set_caps (src, caps);
705 fail_unless (gst_pad_push_event (src,
706 gst_event_new_segment (&dummy_segment)) == TRUE);
707 /* need to activate to make it accept the caps */
708 gst_pad_set_active (sink, TRUE);
709 /* one for me and one for each set_caps */
710 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
712 plr = gst_pad_link (src, sink);
713 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
714 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
716 /* not activating the pads here, which keeps them flushing */
717 gst_pad_set_active (src, FALSE);
718 gst_pad_set_active (sink, FALSE);
720 /* pushing on a flushing pad will drop the buffer */
721 buffer = gst_buffer_new ();
722 gst_buffer_ref (buffer);
723 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
724 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
725 fail_unless_equals_int (g_list_length (buffers), 0);
726 gst_buffer_unref (buffer);
728 gst_pad_set_active (src, TRUE);
729 gst_pad_set_active (sink, FALSE);
731 fail_unless (gst_pad_push_event (src,
732 gst_event_new_stream_start ("test")) == TRUE);
733 gst_pad_set_caps (src, caps);
734 fail_unless (gst_pad_push_event (src,
735 gst_event_new_segment (&dummy_segment)) == TRUE);
736 /* adding a probe that returns FALSE will drop the buffer without trying
738 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
739 GINT_TO_POINTER (0), NULL);
740 buffer = gst_buffer_new ();
741 gst_buffer_ref (buffer);
742 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
743 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
744 fail_unless_equals_int (g_list_length (buffers), 0);
745 gst_buffer_unref (buffer);
746 gst_pad_remove_probe (src, id);
748 /* adding a probe that returns TRUE will still chain the buffer,
749 * and hence drop because pad is flushing */
750 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
751 GINT_TO_POINTER (1), NULL);
752 buffer = gst_buffer_new ();
753 gst_buffer_ref (buffer);
754 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
755 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
756 fail_unless_equals_int (g_list_length (buffers), 0);
757 gst_buffer_unref (buffer);
758 gst_pad_remove_probe (src, id);
761 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
762 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
763 gst_pad_link (src, sink);
764 gst_object_unref (src);
765 gst_object_unref (sink);
766 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
767 gst_caps_unref (caps);
773 buffer_from_string (const gchar * str)
779 buf = gst_buffer_new_and_alloc (size);
781 gst_buffer_fill (buf, 0, str, size);
787 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
792 fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
793 res = memcmp (info.data, str, size) == 0;
794 GST_DEBUG ("%s <-> %s: %d", (gchar *) info.data, str, res);
795 gst_buffer_unmap (buf, &info);
800 GST_START_TEST (test_push_buffer_list_compat)
803 GstPadLinkReturn plr;
809 sink = gst_pad_new ("sink", GST_PAD_SINK);
810 fail_if (sink == NULL);
811 gst_pad_set_chain_function (sink, gst_check_chain_func);
812 /* leave chainlistfunc unset */
814 src = gst_pad_new ("src", GST_PAD_SRC);
815 fail_if (src == NULL);
817 caps = gst_caps_from_string ("foo/bar");
819 gst_pad_set_active (src, TRUE);
821 fail_unless (gst_pad_push_event (src,
822 gst_event_new_stream_start ("test")) == TRUE);
824 gst_pad_set_caps (src, caps);
826 fail_unless (gst_pad_push_event (src,
827 gst_event_new_segment (&dummy_segment)) == TRUE);
829 gst_pad_set_active (sink, TRUE);
831 plr = gst_pad_link (src, sink);
832 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
834 list = gst_buffer_list_new ();
837 /* adding to a buffer list will drop the ref to the buffer */
838 gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
839 gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
841 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
842 fail_unless_equals_int (g_list_length (buffers), 2);
843 buffer = GST_BUFFER (buffers->data);
844 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
845 fail_unless (buffer_compare (buffer, "ListGroup", 9));
846 gst_buffer_unref (buffer);
847 buffers = g_list_delete_link (buffers, buffers);
848 buffer = GST_BUFFER (buffers->data);
849 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
850 fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
851 gst_buffer_unref (buffer);
852 buffers = g_list_delete_link (buffers, buffers);
853 fail_unless (buffers == NULL);
856 gst_pad_unlink (src, sink);
857 gst_object_unref (src);
858 gst_object_unref (sink);
859 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
860 gst_caps_unref (caps);
865 GST_START_TEST (test_flowreturn)
870 /* test some of the macros */
872 fail_if (strcmp (gst_flow_get_name (ret), "eos"));
873 quark = gst_flow_to_quark (ret);
874 fail_if (strcmp (g_quark_to_string (quark), "eos"));
877 ret = GST_FLOW_CUSTOM_SUCCESS;
878 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
879 quark = gst_flow_to_quark (ret);
880 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
882 ret = GST_FLOW_CUSTOM_ERROR;
883 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
884 quark = gst_flow_to_quark (ret);
885 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
887 /* custom returns clamping */
888 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
889 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
890 quark = gst_flow_to_quark (ret);
891 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
893 ret = GST_FLOW_CUSTOM_ERROR - 2;
894 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
895 quark = gst_flow_to_quark (ret);
896 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
899 ret = GST_FLOW_CUSTOM_ERROR + 2;
900 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
901 quark = gst_flow_to_quark (ret);
902 fail_unless (quark == 0);
907 GST_START_TEST (test_push_negotiation)
910 GstPadLinkReturn plr;
912 gst_caps_from_string ("audio/x-raw,width={16,32},depth={16,32}");
914 gst_caps_from_string ("audio/x-raw,width=32,depth={16,32}");
915 GstPadTemplate *src_template;
916 GstPadTemplate *sink_template;
920 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
921 GST_PAD_ALWAYS, srccaps);
922 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
923 GST_PAD_ALWAYS, sinkcaps);
924 gst_caps_unref (srccaps);
925 gst_caps_unref (sinkcaps);
927 sink = gst_pad_new_from_template (sink_template, "sink");
928 fail_if (sink == NULL);
929 gst_pad_set_chain_function (sink, gst_check_chain_func);
931 src = gst_pad_new_from_template (src_template, "src");
932 fail_if (src == NULL);
934 plr = gst_pad_link (src, sink);
935 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
938 gst_pad_set_active (src, TRUE);
939 gst_pad_set_active (sink, TRUE);
941 caps = gst_caps_from_string ("audio/x-raw,width=16,depth=16");
943 /* Should fail if src pad caps are incompatible with sink pad caps */
944 gst_pad_set_caps (src, caps);
945 fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
948 gst_pad_unlink (src, sink);
949 gst_object_unref (src);
950 gst_object_unref (sink);
951 gst_caps_unref (caps);
952 gst_object_unref (sink_template);
953 gst_object_unref (src_template);
958 /* see that an unref also unlinks the pads */
959 GST_START_TEST (test_src_unref_unlink)
963 GstPadLinkReturn plr;
965 sink = gst_pad_new ("sink", GST_PAD_SINK);
966 fail_if (sink == NULL);
968 src = gst_pad_new ("src", GST_PAD_SRC);
969 fail_if (src == NULL);
971 caps = gst_caps_from_string ("foo/bar");
973 gst_pad_set_active (src, TRUE);
974 gst_pad_set_caps (src, caps);
975 gst_pad_set_active (sink, TRUE);
976 gst_pad_set_caps (sink, caps);
978 plr = gst_pad_link (src, sink);
979 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
981 /* unref the srcpad */
982 gst_object_unref (src);
984 /* sink should be unlinked now */
985 fail_if (gst_pad_is_linked (sink));
988 gst_object_unref (sink);
989 gst_caps_unref (caps);
994 /* see that an unref also unlinks the pads */
995 GST_START_TEST (test_sink_unref_unlink)
999 GstPadLinkReturn plr;
1001 sink = gst_pad_new ("sink", GST_PAD_SINK);
1002 fail_if (sink == NULL);
1004 src = gst_pad_new ("src", GST_PAD_SRC);
1005 fail_if (src == NULL);
1007 caps = gst_caps_from_string ("foo/bar");
1009 gst_pad_set_active (src, TRUE);
1010 gst_pad_set_caps (src, caps);
1011 gst_pad_set_active (sink, TRUE);
1012 gst_pad_set_caps (sink, caps);
1014 plr = gst_pad_link (src, sink);
1015 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1017 /* unref the sinkpad */
1018 gst_object_unref (sink);
1020 /* src should be unlinked now */
1021 fail_if (gst_pad_is_linked (src));
1024 gst_object_unref (src);
1025 gst_caps_unref (caps);
1032 static GstPadProbeReturn
1033 block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1035 gboolean *bool_user_data = (gboolean *) user_data;
1037 fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
1039 /* here we should have blocked == 0 unblocked == 0 */
1040 fail_unless (bool_user_data[0] == FALSE);
1041 fail_unless (bool_user_data[1] == FALSE);
1043 bool_user_data[0] = TRUE;
1045 gst_pad_remove_probe (pad, id);
1046 bool_user_data[1] = TRUE;
1048 return GST_PAD_PROBE_OK;
1051 GST_START_TEST (test_block_async)
1054 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
1056 gboolean data[2] = { FALSE, FALSE };
1058 pad = gst_pad_new ("src", GST_PAD_SRC);
1059 fail_unless (pad != NULL);
1061 gst_pad_set_active (pad, TRUE);
1063 fail_unless (gst_pad_push_event (pad,
1064 gst_event_new_stream_start ("test")) == TRUE);
1065 fail_unless (gst_pad_push_event (pad,
1066 gst_event_new_segment (&dummy_segment)) == TRUE);
1068 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_cb, &data,
1071 fail_unless (data[0] == FALSE);
1072 fail_unless (data[1] == FALSE);
1073 gst_pad_push (pad, gst_buffer_new ());
1075 gst_object_unref (pad);
1080 static GstPadProbeReturn
1081 block_async_cb_return_ok (GstPad * pad, GstPadProbeInfo * info,
1084 return GST_PAD_PROBE_OK;
1088 push_buffer_async (GstPad * pad)
1090 return GINT_TO_POINTER (gst_pad_push (pad, gst_buffer_new ()));
1094 test_pad_blocking_with_type (GstPadProbeType type)
1100 pad = gst_pad_new ("src", GST_PAD_SRC);
1101 fail_unless (pad != NULL);
1103 gst_pad_set_active (pad, TRUE);
1105 fail_unless (gst_pad_push_event (pad,
1106 gst_event_new_stream_start ("test")) == TRUE);
1107 fail_unless (gst_pad_push_event (pad,
1108 gst_event_new_segment (&dummy_segment)) == TRUE);
1110 id = gst_pad_add_probe (pad, type, block_async_cb_return_ok, NULL, NULL);
1113 thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1116 /* wait for the block */
1117 while (!gst_pad_is_blocking (pad)) {
1121 /* stop with flushing */
1122 gst_pad_push_event (pad, gst_event_new_flush_start ());
1124 /* get return value from push */
1125 ret = GPOINTER_TO_INT (g_thread_join (thread));
1127 gst_pad_push_event (pad, gst_event_new_flush_stop (FALSE));
1128 /* must be wrong state */
1129 fail_unless (ret == GST_FLOW_FLUSHING);
1131 gst_object_unref (pad);
1134 GST_START_TEST (test_pad_blocking_with_probe_type_block)
1136 test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCK);
1141 GST_START_TEST (test_pad_blocking_with_probe_type_blocking)
1143 test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCKING);
1148 static gboolean pad_probe_remove_notifiy_called = FALSE;
1150 static GstPadProbeReturn
1151 probe_remove_self_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1153 gst_pad_remove_probe (pad, info->id);
1155 fail_unless (pad->num_probes == 0);
1156 fail_unless (pad->num_blocked == 0);
1158 return GST_PAD_PROBE_REMOVE;
1162 probe_remove_notify_cb (gpointer data)
1164 fail_unless (pad_probe_remove_notifiy_called == FALSE);
1165 pad_probe_remove_notifiy_called = TRUE;
1168 GST_START_TEST (test_pad_probe_remove)
1172 pad = gst_pad_new ("src", GST_PAD_SRC);
1173 fail_unless (pad != NULL);
1175 gst_pad_set_active (pad, TRUE);
1176 fail_unless (pad->num_probes == 0);
1177 fail_unless (pad->num_blocked == 0);
1178 gst_pad_add_probe (pad,
1179 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
1180 probe_remove_self_cb, NULL, probe_remove_notify_cb);
1181 fail_unless (pad->num_probes == 1);
1182 fail_unless (pad->num_blocked == 1);
1184 pad_probe_remove_notifiy_called = FALSE;
1185 gst_pad_push_event (pad, gst_event_new_stream_start ("asda"));
1187 fail_unless (pad->num_probes == 0);
1188 fail_unless (pad->num_blocked == 0);
1190 gst_object_unref (pad);
1195 static gboolean src_flush_start_probe_called = FALSE;
1196 static gboolean src_flush_stop_probe_called = FALSE;
1197 static gboolean sink_flush_start_probe_called = FALSE;
1198 static gboolean sink_flush_stop_probe_called = FALSE;
1200 static GstPadProbeReturn
1201 flush_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1205 if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_FLUSH))
1208 event = gst_pad_probe_info_get_event (info);
1209 switch (GST_EVENT_TYPE (event)) {
1210 case GST_EVENT_FLUSH_START:
1211 if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1212 src_flush_start_probe_called = TRUE;
1214 sink_flush_start_probe_called = TRUE;
1216 case GST_EVENT_FLUSH_STOP:
1217 if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1218 src_flush_stop_probe_called = TRUE;
1220 sink_flush_stop_probe_called = TRUE;
1227 return GST_PAD_PROBE_OK;
1230 GST_START_TEST (test_pad_probe_flush_events)
1234 src = gst_pad_new ("src", GST_PAD_SRC);
1235 sink = gst_pad_new ("sink", GST_PAD_SINK);
1236 gst_pad_set_chain_function (sink, gst_check_chain_func);
1237 gst_pad_set_active (src, TRUE);
1238 gst_pad_set_active (sink, TRUE);
1240 fail_unless (gst_pad_push_event (src,
1241 gst_event_new_stream_start ("test")) == TRUE);
1242 fail_unless (gst_pad_push_event (src,
1243 gst_event_new_segment (&dummy_segment)) == TRUE);
1245 fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1247 gst_pad_add_probe (src,
1248 GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1249 GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1250 gst_pad_add_probe (sink,
1251 GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1252 GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1254 gst_pad_push_event (src, gst_event_new_flush_start ());
1255 gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
1257 fail_unless (gst_pad_push_event (src,
1258 gst_event_new_segment (&dummy_segment)) == TRUE);
1260 /* push a buffer so the events are propagated downstream */
1261 gst_pad_push (src, gst_buffer_new ());
1263 fail_unless (src_flush_start_probe_called);
1264 fail_unless (src_flush_stop_probe_called);
1265 fail_unless (sink_flush_start_probe_called);
1266 fail_unless (sink_flush_stop_probe_called);
1268 gst_object_unref (src);
1269 gst_object_unref (sink);
1274 static gboolean got_notify;
1277 caps_notify (GstPad * pad, GParamSpec * spec, gpointer data)
1283 test_queue_src_caps_notify (gboolean link_queue)
1286 GstPad *src, *sink, *another_pad;
1289 queue = gst_element_factory_make ("queue", NULL);
1290 fail_unless (queue != NULL);
1292 src = gst_element_get_static_pad (queue, "src");
1293 fail_unless (src != NULL);
1295 sink = gst_element_get_static_pad (queue, "sink");
1296 fail_unless (sink != NULL);
1299 another_pad = gst_pad_new ("sink", GST_PAD_SINK);
1300 fail_unless (another_pad != NULL);
1301 gst_pad_set_active (another_pad, TRUE);
1303 gst_pad_link_full (src, another_pad, GST_PAD_LINK_CHECK_NOTHING);
1308 gst_element_set_state (queue, GST_STATE_PLAYING);
1312 g_signal_connect (src, "notify::caps", G_CALLBACK (caps_notify), NULL);
1314 caps = gst_caps_from_string ("caps");
1315 gst_pad_send_event (sink, gst_event_new_caps (caps));
1316 gst_caps_unref (caps);
1318 while (got_notify == FALSE)
1321 gst_element_set_state (queue, GST_STATE_NULL);
1323 gst_object_unref (src);
1324 gst_object_unref (sink);
1325 gst_object_unref (queue);
1327 gst_object_unref (another_pad);
1331 GST_START_TEST (test_queue_src_caps_notify_linked)
1333 test_queue_src_caps_notify (TRUE);
1337 GST_START_TEST (test_queue_src_caps_notify_not_linked)
1339 /* This test will fail because queue doesn't set the caps
1340 on src pad unless it is linked */
1341 test_queue_src_caps_notify (FALSE);
1348 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
1350 gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
1354 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
1356 static int n_calls = 0;
1357 gboolean *bool_user_data = (gboolean *) user_data;
1360 /* we expect this callback to be called only once */
1361 g_warn_if_reached ();
1363 *bool_user_data = blocked;
1365 /* replace block_async_first with block_async_second so next time the pad is
1366 * blocked the latter should be called */
1367 gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
1369 /* unblock temporarily, in the next push block_async_second should be called
1371 gst_pad_push_event (pad, gst_event_new_flush_start ());
1374 GST_START_TEST (test_block_async_replace_callback)
1379 pad = gst_pad_new ("src", GST_PAD_SRC);
1380 fail_unless (pad != NULL);
1381 gst_pad_set_active (pad, TRUE);
1383 gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
1386 gst_pad_push (pad, gst_buffer_new ());
1387 fail_unless (blocked == TRUE);
1388 /* block_async_first flushes to unblock */
1389 gst_pad_push_event (pad, gst_event_new_flush_stop ());
1391 /* push again, this time block_async_second should be called */
1392 gst_pad_push (pad, gst_buffer_new ());
1393 fail_unless (blocked == TRUE);
1395 gst_object_unref (pad);
1402 block_async_full_destroy (gpointer user_data)
1404 gint *state = (gint *) user_data;
1406 fail_unless (*state < 2);
1408 GST_DEBUG ("setting state to 2");
1412 static GstPadProbeReturn
1413 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1415 *(gint *) user_data = (gint) TRUE;
1417 gst_pad_push_event (pad, gst_event_new_flush_start ());
1418 GST_DEBUG ("setting state to 1");
1420 return GST_PAD_PROBE_OK;
1423 GST_START_TEST (test_block_async_full_destroy)
1426 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1430 pad = gst_pad_new ("src", GST_PAD_SRC);
1431 fail_unless (pad != NULL);
1432 gst_pad_set_active (pad, TRUE);
1434 fail_unless (gst_pad_push_event (pad,
1435 gst_event_new_stream_start ("test")) == TRUE);
1436 fail_unless (gst_pad_push_event (pad,
1437 gst_event_new_segment (&dummy_segment)) == TRUE);
1439 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1440 &state, block_async_full_destroy);
1441 fail_unless (state == 0);
1443 gst_pad_push (pad, gst_buffer_new ());
1444 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1446 fail_unless (state == 1);
1447 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1449 /* unblock callback is called */
1450 gst_pad_remove_probe (pad, id);
1451 fail_unless (state == 2);
1453 gst_object_unref (pad);
1458 GST_START_TEST (test_block_async_full_destroy_dispose)
1461 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1464 pad = gst_pad_new ("src", GST_PAD_SRC);
1465 fail_unless (pad != NULL);
1466 gst_pad_set_active (pad, TRUE);
1468 fail_unless (gst_pad_push_event (pad,
1469 gst_event_new_stream_start ("test")) == TRUE);
1470 fail_unless (gst_pad_push_event (pad,
1471 gst_event_new_segment (&dummy_segment)) == TRUE);
1473 (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1474 &state, block_async_full_destroy);
1476 gst_pad_push (pad, gst_buffer_new ());
1477 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1479 fail_unless_equals_int (state, 1);
1480 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1482 /* gst_BLOCK calls the destroy_notify function if necessary */
1483 gst_object_unref (pad);
1485 fail_unless_equals_int (state, 2);
1493 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
1495 gboolean *bool_user_data = (gboolean *) user_data;
1497 /* here we should have blocked == 1 unblocked == 0 */
1499 fail_unless (blocked == FALSE);
1501 fail_unless (bool_user_data[0] == TRUE);
1502 fail_unless (bool_user_data[1] == TRUE);
1503 fail_unless (bool_user_data[2] == FALSE);
1505 bool_user_data[2] = TRUE;
1512 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
1514 g_warn_if_reached ();
1518 static GstPadProbeReturn
1519 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
1522 gboolean *bool_user_data = (gboolean *) user_data;
1524 GST_DEBUG ("second probe called");
1526 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1528 fail_unless (bool_user_data[0] == TRUE);
1529 fail_unless (bool_user_data[1] == FALSE);
1530 fail_unless (bool_user_data[2] == FALSE);
1532 bool_user_data[1] = TRUE;
1534 GST_DEBUG ("removing second probe with id %lu", id);
1535 gst_pad_remove_probe (pad, id);
1537 return GST_PAD_PROBE_OK;
1540 static GstPadProbeReturn
1541 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
1544 static int n_calls = 0;
1545 gboolean *bool_user_data = (gboolean *) user_data;
1547 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1549 GST_DEBUG ("first probe called");
1552 /* we expect this callback to be called only once */
1553 g_warn_if_reached ();
1555 *bool_user_data = TRUE;
1557 fail_unless (bool_user_data[0] == TRUE);
1558 fail_unless (bool_user_data[1] == FALSE);
1559 fail_unless (bool_user_data[2] == FALSE);
1561 GST_DEBUG ("removing first probe with id %lu", id);
1562 gst_pad_remove_probe (pad, id);
1564 GST_DEBUG ("adding second probe");
1565 /* replace block_async_first with block_async_second so next time the pad is
1566 * blocked the latter should be called */
1567 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1568 block_async_second_no_flush, user_data, NULL);
1569 GST_DEBUG ("added probe with id %lu", id);
1571 return GST_PAD_PROBE_OK;
1574 GST_START_TEST (test_block_async_replace_callback_no_flush)
1577 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
1579 pad = gst_pad_new ("src", GST_PAD_SRC);
1580 fail_unless (pad != NULL);
1581 gst_pad_set_active (pad, TRUE);
1583 fail_unless (gst_pad_push_event (pad,
1584 gst_event_new_stream_start ("test")) == TRUE);
1585 fail_unless (gst_pad_push_event (pad,
1586 gst_event_new_segment (&dummy_segment)) == TRUE);
1588 GST_DEBUG ("adding probe");
1589 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1590 block_async_first_no_flush, bool_user_data, NULL);
1591 GST_DEBUG ("added probe with id %lu", id);
1594 GST_DEBUG ("pushing buffer");
1595 gst_pad_push (pad, gst_buffer_new ());
1596 fail_unless (bool_user_data[0] == TRUE);
1597 fail_unless (bool_user_data[1] == TRUE);
1598 fail_unless (bool_user_data[2] == FALSE);
1600 gst_object_unref (pad);
1605 static gint sticky_count;
1608 test_sticky_events_handler (GstPad * pad, GstObject * parent, GstEvent * event)
1610 GST_DEBUG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
1612 switch (sticky_count) {
1614 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
1621 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
1623 gst_event_parse_caps (event, &caps);
1624 fail_unless (gst_caps_get_size (caps) == 1);
1625 s = gst_caps_get_structure (caps, 0);
1626 fail_unless (gst_structure_has_name (s, "foo/baz"));
1630 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1633 fail_unless (FALSE);
1637 gst_event_unref (event);
1643 static GstFlowReturn
1644 test_sticky_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1646 gst_buffer_unref (buffer);
1650 GST_START_TEST (test_sticky_events)
1652 GstPad *srcpad, *sinkpad;
1657 /* make unlinked srcpad */
1658 srcpad = gst_pad_new ("src", GST_PAD_SRC);
1659 fail_unless (srcpad != NULL);
1660 gst_pad_set_active (srcpad, TRUE);
1662 /* test stream-start */
1663 fail_unless (gst_pad_get_stream_id (srcpad) == NULL);
1665 /* push an event, it should be sticky on the srcpad */
1666 fail_unless (gst_pad_push_event (srcpad,
1667 gst_event_new_stream_start ("test")) == TRUE);
1669 /* let's see if it stuck */
1670 id = gst_pad_get_stream_id (srcpad);
1671 fail_unless_equals_string (id, "test");
1674 /* make a caps event */
1675 caps = gst_caps_new_empty_simple ("foo/bar");
1676 gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1677 gst_caps_unref (caps);
1679 /* make segment event */
1680 gst_segment_init (&seg, GST_FORMAT_TIME);
1681 gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
1683 /* now make a sinkpad */
1684 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1685 fail_unless (sinkpad != NULL);
1687 gst_pad_set_event_function (sinkpad, test_sticky_events_handler);
1688 gst_pad_set_chain_function (sinkpad, test_sticky_chain);
1689 fail_unless (sticky_count == 0);
1690 gst_pad_set_active (sinkpad, TRUE);
1693 gst_pad_link (srcpad, sinkpad);
1694 /* should not trigger events */
1695 fail_unless (sticky_count == 0);
1697 /* caps replaces old caps event at position 2, the pushes all
1699 caps = gst_caps_new_empty_simple ("foo/baz");
1700 gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1701 gst_caps_unref (caps);
1703 /* should have triggered 2 events, the segment event is still pending */
1704 fail_unless_equals_int (sticky_count, 2);
1706 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
1708 /* should have triggered 3 events */
1709 fail_unless_equals_int (sticky_count, 3);
1711 gst_object_unref (srcpad);
1712 gst_object_unref (sinkpad);
1718 gst_pad_suite (void)
1720 Suite *s = suite_create ("GstPad");
1721 TCase *tc_chain = tcase_create ("general");
1723 /* turn off timeout */
1724 tcase_set_timeout (tc_chain, 60);
1726 gst_segment_init (&dummy_segment, GST_FORMAT_BYTES);
1728 suite_add_tcase (s, tc_chain);
1729 tcase_add_test (tc_chain, test_link);
1730 tcase_add_test (tc_chain, test_refcount);
1731 tcase_add_test (tc_chain, test_get_allowed_caps);
1732 tcase_add_test (tc_chain, test_sticky_caps_unlinked);
1733 tcase_add_test (tc_chain, test_sticky_caps_unlinked_incompatible);
1734 tcase_add_test (tc_chain, test_sticky_caps_flushing);
1735 tcase_add_test (tc_chain, test_link_unlink_threaded);
1736 tcase_add_test (tc_chain, test_name_is_valid);
1737 tcase_add_test (tc_chain, test_push_unlinked);
1738 tcase_add_test (tc_chain, test_push_linked);
1739 tcase_add_test (tc_chain, test_push_linked_flushing);
1740 tcase_add_test (tc_chain, test_push_buffer_list_compat);
1741 tcase_add_test (tc_chain, test_flowreturn);
1742 tcase_add_test (tc_chain, test_push_negotiation);
1743 tcase_add_test (tc_chain, test_src_unref_unlink);
1744 tcase_add_test (tc_chain, test_sink_unref_unlink);
1745 tcase_add_test (tc_chain, test_block_async);
1746 tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_block);
1747 tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_blocking);
1748 tcase_add_test (tc_chain, test_pad_probe_remove);
1749 tcase_add_test (tc_chain, test_pad_probe_flush_events);
1750 tcase_add_test (tc_chain, test_queue_src_caps_notify_linked);
1751 tcase_add_test (tc_chain, test_queue_src_caps_notify_not_linked);
1753 tcase_add_test (tc_chain, test_block_async_replace_callback);
1755 tcase_add_test (tc_chain, test_block_async_full_destroy);
1756 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
1757 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1758 tcase_add_test (tc_chain, test_sticky_events);
1763 GST_CHECK_MAIN (gst_pad);