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)
238 /* Ensure we get here just once: */
239 fail_unless (event_caps == NULL);
241 /* The event must arrive before any buffer: */
242 fail_unless_equals_int (g_list_length (buffers), 0);
244 gst_event_parse_caps (event, &caps);
245 event_caps = gst_caps_ref (caps);
247 gst_event_unref (event);
252 /* Tests whether caps get properly forwarded when pads
253 are initially unlinked */
254 GST_START_TEST (test_sticky_caps_unlinked)
257 GstPadTemplate *src_template, *sink_template;
261 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
262 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
263 GST_PAD_ALWAYS, caps);
264 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
265 GST_PAD_ALWAYS, caps);
266 gst_caps_unref (caps);
268 src = gst_pad_new_from_template (src_template, "src");
269 fail_if (src == NULL);
270 sink = gst_pad_new_from_template (sink_template, "sink");
271 fail_if (sink == NULL);
272 gst_pad_set_event_function (sink, sticky_event);
273 gst_pad_set_chain_function (sink, gst_check_chain_func);
275 gst_object_unref (src_template);
276 gst_object_unref (sink_template);
278 gst_pad_set_active (src, TRUE);
280 fail_unless (gst_pad_push_event (src,
281 gst_event_new_stream_start ("test")) == TRUE);
283 caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
284 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
286 event = gst_event_new_caps (caps);
287 fail_unless (gst_pad_push_event (src, event) == TRUE);
288 fail_unless (event_caps == NULL);
290 fail_unless (gst_pad_push_event (src,
291 gst_event_new_segment (&dummy_segment)) == TRUE);
293 /* Linking and activating will not forward the sticky event yet... */
294 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
295 gst_pad_set_active (sink, TRUE);
296 fail_unless (event_caps == NULL);
298 /* ...but the first buffer will: */
299 fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
300 fail_unless (event_caps == caps);
301 fail_unless_equals_int (g_list_length (buffers), 1);
303 gst_check_drop_buffers ();
305 gst_caps_replace (&caps, NULL);
306 gst_caps_replace (&event_caps, NULL);
308 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
309 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
310 gst_object_unref (src);
311 gst_object_unref (sink);
316 /* Same as test_sticky_caps_unlinked except that the source pad
317 * has a template of ANY and we will attempt to push
318 * incompatible caps */
319 GST_START_TEST (test_sticky_caps_unlinked_incompatible)
321 GstCaps *caps, *failcaps;
322 GstPadTemplate *src_template, *sink_template;
326 /* Source pad has ANY caps
327 * Sink pad has foobar caps
328 * We will push the pony express caps (which should fail)
330 caps = gst_caps_new_any ();
331 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
332 GST_PAD_ALWAYS, caps);
333 gst_caps_unref (caps);
334 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
335 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
336 GST_PAD_ALWAYS, caps);
337 gst_caps_unref (caps);
339 src = gst_pad_new_from_template (src_template, "src");
340 fail_if (src == NULL);
341 sink = gst_pad_new_from_template (sink_template, "sink");
342 fail_if (sink == NULL);
343 gst_pad_set_event_function (sink, sticky_event);
344 gst_pad_set_chain_function (sink, gst_check_chain_func);
346 gst_object_unref (src_template);
347 gst_object_unref (sink_template);
349 gst_pad_set_active (src, TRUE);
351 fail_unless (gst_pad_push_event (src,
352 gst_event_new_stream_start ("test")) == TRUE);
354 failcaps = gst_caps_from_string ("pony/express, failure=(boolean)true");
355 ASSERT_CAPS_REFCOUNT (failcaps, "caps", 1);
357 event = gst_event_new_caps (failcaps);
358 gst_caps_unref (failcaps);
359 /* The pad isn't linked yet, and anything matches the source pad template
361 fail_unless (gst_pad_push_event (src, event) == TRUE);
362 fail_unless (event_caps == NULL);
364 fail_unless (gst_pad_push_event (src,
365 gst_event_new_segment (&dummy_segment)) == TRUE);
367 /* Linking and activating will not forward the sticky event yet... */
368 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
369 gst_pad_set_active (sink, TRUE);
370 fail_unless (event_caps == NULL);
372 /* ...but the first buffer will and should FAIL since the caps
373 * are not compatible */
374 fail_unless (gst_pad_push (src,
375 gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
376 /* We shouldn't have received the caps event since it's incompatible */
377 fail_unless (event_caps == NULL);
378 /* We shouldn't have received any buffers since caps are incompatible */
379 fail_unless_equals_int (g_list_length (buffers), 0);
381 gst_check_drop_buffers ();
383 gst_caps_replace (&event_caps, NULL);
385 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
386 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
387 gst_object_unref (src);
388 gst_object_unref (sink);
393 /* Like test_sticky_caps_unlinked, but link before caps: */
395 GST_START_TEST (test_sticky_caps_flushing)
398 GstPadTemplate *src_template, *sink_template;
402 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
403 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
404 GST_PAD_ALWAYS, caps);
405 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
406 GST_PAD_ALWAYS, caps);
407 gst_caps_unref (caps);
409 src = gst_pad_new_from_template (src_template, "src");
410 fail_if (src == NULL);
411 sink = gst_pad_new_from_template (sink_template, "sink");
412 fail_if (sink == NULL);
413 gst_pad_set_event_function (sink, sticky_event);
414 gst_pad_set_chain_function (sink, gst_check_chain_func);
416 gst_object_unref (src_template);
417 gst_object_unref (sink_template);
419 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
421 caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
422 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
424 event = gst_event_new_caps (caps);
426 gst_pad_set_active (src, TRUE);
427 fail_unless (gst_pad_push_event (src,
428 gst_event_new_stream_start ("test")) == TRUE);
429 /* The caps event gets accepted by the source pad (and stored) */
430 fail_unless (gst_pad_push_event (src, event) == TRUE);
431 /* But wasn't forwarded since the sink pad is flushing (not activated) */
432 fail_unless (event_caps == NULL);
434 fail_unless (gst_pad_push_event (src,
435 gst_event_new_segment (&dummy_segment)) == TRUE);
437 /* Activating will not forward the sticky event yet... */
438 gst_pad_set_active (sink, TRUE);
439 fail_unless (event_caps == NULL);
441 /* ...but the first buffer will: */
442 fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
443 fail_unless (event_caps == caps);
444 fail_unless_equals_int (g_list_length (buffers), 1);
446 gst_check_drop_buffers ();
448 gst_caps_replace (&caps, NULL);
449 gst_caps_replace (&event_caps, NULL);
451 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
452 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
453 gst_object_unref (src);
454 gst_object_unref (sink);
460 name_is_valid (const gchar * name, GstPadPresence presence)
463 GstCaps *any = gst_caps_new_any ();
465 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
466 gst_caps_unref (any);
468 gst_object_unref (GST_OBJECT (new));
474 GST_START_TEST (test_name_is_valid)
476 gboolean result = FALSE;
478 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
479 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
480 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
483 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
484 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
485 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
486 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
487 ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
489 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
490 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
495 static GstPadProbeReturn
496 _probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
498 gint ret = GPOINTER_TO_INT (userdata);
501 return GST_PAD_PROBE_OK;
503 return GST_PAD_PROBE_DROP;
506 GST_START_TEST (test_push_unlinked)
513 src = gst_pad_new ("src", GST_PAD_SRC);
514 fail_if (src == NULL);
515 caps = gst_pad_get_allowed_caps (src);
516 fail_unless (caps == NULL);
518 caps = gst_caps_from_string ("foo/bar");
520 /* pushing on an inactive pad will return wrong state */
521 GST_DEBUG ("push buffer inactive");
522 buffer = gst_buffer_new ();
523 gst_buffer_ref (buffer);
524 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
525 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
526 gst_buffer_unref (buffer);
528 gst_pad_set_active (src, TRUE);
529 fail_unless (gst_pad_push_event (src,
530 gst_event_new_stream_start ("test")) == TRUE);
531 GST_DEBUG ("push caps event inactive");
532 gst_pad_set_caps (src, caps);
533 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
534 fail_unless (gst_pad_push_event (src,
535 gst_event_new_segment (&dummy_segment)) == TRUE);
537 /* pushing on an unlinked pad will drop the buffer */
538 GST_DEBUG ("push buffer unlinked");
539 buffer = gst_buffer_new ();
540 gst_buffer_ref (buffer);
541 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
542 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
543 gst_buffer_unref (buffer);
545 /* adding a probe that returns _DROP will drop the buffer without trying
547 GST_DEBUG ("push buffer drop");
548 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
549 _probe_handler, GINT_TO_POINTER (0), NULL);
550 buffer = gst_buffer_new ();
551 gst_buffer_ref (buffer);
552 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
553 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
554 gst_buffer_unref (buffer);
555 gst_pad_remove_probe (src, id);
557 /* adding a probe that returns _OK will still chain the buffer,
558 * and hence drop because pad is unlinked */
559 GST_DEBUG ("push buffer ok");
560 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
561 _probe_handler, GINT_TO_POINTER (1), NULL);
562 buffer = gst_buffer_new ();
563 gst_buffer_ref (buffer);
564 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
565 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
566 gst_buffer_unref (buffer);
567 gst_pad_remove_probe (src, id);
571 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
572 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
574 gst_object_unref (src);
576 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
577 gst_caps_unref (caps);
582 GST_START_TEST (test_push_linked)
585 GstPadLinkReturn plr;
591 sink = gst_pad_new ("sink", GST_PAD_SINK);
592 fail_if (sink == NULL);
593 gst_pad_set_chain_function (sink, gst_check_chain_func);
595 src = gst_pad_new ("src", GST_PAD_SRC);
596 fail_if (src == NULL);
598 caps = gst_caps_from_string ("foo/bar");
600 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
602 gst_pad_set_active (src, TRUE);
604 fail_unless (gst_pad_push_event (src,
605 gst_event_new_stream_start ("test")) == TRUE);
607 gst_pad_set_caps (src, caps);
609 fail_unless (gst_pad_push_event (src,
610 gst_event_new_segment (&dummy_segment)) == TRUE);
612 gst_pad_set_active (sink, TRUE);
613 /* one for me and one for each set_caps */
614 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
616 plr = gst_pad_link (src, sink);
617 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
618 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
620 buffer = gst_buffer_new ();
623 /* pushing on a linked pad will drop the ref to the buffer */
624 gst_buffer_ref (buffer);
625 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
626 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
627 gst_buffer_unref (buffer);
628 fail_unless_equals_int (g_list_length (buffers), 1);
629 buffer = GST_BUFFER (buffers->data);
630 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
631 gst_buffer_unref (buffer);
632 g_list_free (buffers);
635 /* adding a probe that returns FALSE will drop the buffer without trying
637 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
638 _probe_handler, GINT_TO_POINTER (0), NULL);
639 buffer = gst_buffer_new ();
640 gst_buffer_ref (buffer);
641 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
642 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
643 gst_buffer_unref (buffer);
644 gst_pad_remove_probe (src, id);
645 fail_unless_equals_int (g_list_length (buffers), 0);
647 /* adding a probe that returns TRUE will still chain the buffer */
648 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
649 _probe_handler, GINT_TO_POINTER (1), NULL);
650 buffer = gst_buffer_new ();
651 gst_buffer_ref (buffer);
652 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
653 gst_pad_remove_probe (src, id);
655 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
656 gst_buffer_unref (buffer);
657 fail_unless_equals_int (g_list_length (buffers), 1);
658 buffer = GST_BUFFER (buffers->data);
659 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
660 gst_buffer_unref (buffer);
661 g_list_free (buffers);
665 gst_pad_unlink (src, sink);
666 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
667 gst_object_unref (src);
668 gst_object_unref (sink);
669 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
671 gst_caps_unref (caps);
676 GST_START_TEST (test_push_linked_flushing)
680 GstPadLinkReturn plr;
685 src = gst_pad_new ("src", GST_PAD_SRC);
686 fail_if (src == NULL);
687 sink = gst_pad_new ("sink", GST_PAD_SINK);
688 fail_if (sink == NULL);
689 gst_pad_set_chain_function (sink, gst_check_chain_func);
691 caps = gst_pad_get_allowed_caps (src);
692 fail_unless (caps == NULL);
693 caps = gst_pad_get_allowed_caps (sink);
694 fail_unless (caps == NULL);
696 caps = gst_caps_from_string ("foo/bar");
698 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
700 gst_pad_set_active (src, TRUE);
701 fail_unless (gst_pad_push_event (src,
702 gst_event_new_stream_start ("test")) == TRUE);
703 gst_pad_set_caps (src, caps);
704 fail_unless (gst_pad_push_event (src,
705 gst_event_new_segment (&dummy_segment)) == TRUE);
706 /* need to activate to make it accept the caps */
707 gst_pad_set_active (sink, TRUE);
708 /* one for me and one for each set_caps */
709 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
711 plr = gst_pad_link (src, sink);
712 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
713 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
715 /* not activating the pads here, which keeps them flushing */
716 gst_pad_set_active (src, FALSE);
717 gst_pad_set_active (sink, FALSE);
719 /* pushing on a flushing pad will drop the buffer */
720 buffer = gst_buffer_new ();
721 gst_buffer_ref (buffer);
722 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
723 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
724 fail_unless_equals_int (g_list_length (buffers), 0);
725 gst_buffer_unref (buffer);
727 gst_pad_set_active (src, TRUE);
728 gst_pad_set_active (sink, FALSE);
730 fail_unless (gst_pad_push_event (src,
731 gst_event_new_stream_start ("test")) == TRUE);
732 gst_pad_set_caps (src, caps);
733 fail_unless (gst_pad_push_event (src,
734 gst_event_new_segment (&dummy_segment)) == TRUE);
735 /* adding a probe that returns FALSE will drop the buffer without trying
737 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
738 GINT_TO_POINTER (0), NULL);
739 buffer = gst_buffer_new ();
740 gst_buffer_ref (buffer);
741 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
742 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
743 fail_unless_equals_int (g_list_length (buffers), 0);
744 gst_buffer_unref (buffer);
745 gst_pad_remove_probe (src, id);
747 /* adding a probe that returns TRUE will still chain the buffer,
748 * and hence drop because pad is flushing */
749 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
750 GINT_TO_POINTER (1), NULL);
751 buffer = gst_buffer_new ();
752 gst_buffer_ref (buffer);
753 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
754 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
755 fail_unless_equals_int (g_list_length (buffers), 0);
756 gst_buffer_unref (buffer);
757 gst_pad_remove_probe (src, id);
760 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
761 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
762 gst_pad_link (src, sink);
763 gst_object_unref (src);
764 gst_object_unref (sink);
765 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
766 gst_caps_unref (caps);
772 buffer_from_string (const gchar * str)
778 buf = gst_buffer_new_and_alloc (size);
780 gst_buffer_fill (buf, 0, str, size);
786 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
791 fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
792 res = memcmp (info.data, str, size) == 0;
793 GST_DEBUG ("%s <-> %s: %d", (gchar *) info.data, str, res);
794 gst_buffer_unmap (buf, &info);
799 GST_START_TEST (test_push_buffer_list_compat)
802 GstPadLinkReturn plr;
808 sink = gst_pad_new ("sink", GST_PAD_SINK);
809 fail_if (sink == NULL);
810 gst_pad_set_chain_function (sink, gst_check_chain_func);
811 /* leave chainlistfunc unset */
813 src = gst_pad_new ("src", GST_PAD_SRC);
814 fail_if (src == NULL);
816 caps = gst_caps_from_string ("foo/bar");
818 gst_pad_set_active (src, TRUE);
820 fail_unless (gst_pad_push_event (src,
821 gst_event_new_stream_start ("test")) == TRUE);
823 gst_pad_set_caps (src, caps);
825 fail_unless (gst_pad_push_event (src,
826 gst_event_new_segment (&dummy_segment)) == TRUE);
828 gst_pad_set_active (sink, TRUE);
830 plr = gst_pad_link (src, sink);
831 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
833 list = gst_buffer_list_new ();
836 /* adding to a buffer list will drop the ref to the buffer */
837 gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
838 gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
840 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
841 fail_unless_equals_int (g_list_length (buffers), 2);
842 buffer = GST_BUFFER (buffers->data);
843 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
844 fail_unless (buffer_compare (buffer, "ListGroup", 9));
845 gst_buffer_unref (buffer);
846 buffers = g_list_delete_link (buffers, buffers);
847 buffer = GST_BUFFER (buffers->data);
848 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
849 fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
850 gst_buffer_unref (buffer);
851 buffers = g_list_delete_link (buffers, buffers);
852 fail_unless (buffers == NULL);
855 gst_pad_unlink (src, sink);
856 gst_object_unref (src);
857 gst_object_unref (sink);
858 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
859 gst_caps_unref (caps);
864 GST_START_TEST (test_flowreturn)
869 /* test some of the macros */
871 fail_if (strcmp (gst_flow_get_name (ret), "eos"));
872 quark = gst_flow_to_quark (ret);
873 fail_if (strcmp (g_quark_to_string (quark), "eos"));
876 ret = GST_FLOW_CUSTOM_SUCCESS;
877 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
878 quark = gst_flow_to_quark (ret);
879 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
881 ret = GST_FLOW_CUSTOM_ERROR;
882 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
883 quark = gst_flow_to_quark (ret);
884 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
886 /* custom returns clamping */
887 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
888 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
889 quark = gst_flow_to_quark (ret);
890 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
892 ret = GST_FLOW_CUSTOM_ERROR - 2;
893 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
894 quark = gst_flow_to_quark (ret);
895 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
898 ret = GST_FLOW_CUSTOM_ERROR + 2;
899 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
900 quark = gst_flow_to_quark (ret);
901 fail_unless (quark == 0);
906 GST_START_TEST (test_push_negotiation)
909 GstPadLinkReturn plr;
911 gst_caps_from_string ("audio/x-raw,width={16,32},depth={16,32}");
913 gst_caps_from_string ("audio/x-raw,width=32,depth={16,32}");
914 GstPadTemplate *src_template;
915 GstPadTemplate *sink_template;
919 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
920 GST_PAD_ALWAYS, srccaps);
921 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
922 GST_PAD_ALWAYS, sinkcaps);
923 gst_caps_unref (srccaps);
924 gst_caps_unref (sinkcaps);
926 sink = gst_pad_new_from_template (sink_template, "sink");
927 fail_if (sink == NULL);
928 gst_pad_set_chain_function (sink, gst_check_chain_func);
930 src = gst_pad_new_from_template (src_template, "src");
931 fail_if (src == NULL);
933 plr = gst_pad_link (src, sink);
934 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
937 gst_pad_set_active (src, TRUE);
938 gst_pad_set_active (sink, TRUE);
940 caps = gst_caps_from_string ("audio/x-raw,width=16,depth=16");
942 /* Should fail if src pad caps are incompatible with sink pad caps */
943 gst_pad_set_caps (src, caps);
944 fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
947 gst_pad_unlink (src, sink);
948 gst_object_unref (src);
949 gst_object_unref (sink);
950 gst_caps_unref (caps);
951 gst_object_unref (sink_template);
952 gst_object_unref (src_template);
957 /* see that an unref also unlinks the pads */
958 GST_START_TEST (test_src_unref_unlink)
962 GstPadLinkReturn plr;
964 sink = gst_pad_new ("sink", GST_PAD_SINK);
965 fail_if (sink == NULL);
967 src = gst_pad_new ("src", GST_PAD_SRC);
968 fail_if (src == NULL);
970 caps = gst_caps_from_string ("foo/bar");
972 gst_pad_set_active (src, TRUE);
973 gst_pad_set_caps (src, caps);
974 gst_pad_set_active (sink, TRUE);
975 gst_pad_set_caps (sink, caps);
977 plr = gst_pad_link (src, sink);
978 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
980 /* unref the srcpad */
981 gst_object_unref (src);
983 /* sink should be unlinked now */
984 fail_if (gst_pad_is_linked (sink));
987 gst_object_unref (sink);
988 gst_caps_unref (caps);
993 /* see that an unref also unlinks the pads */
994 GST_START_TEST (test_sink_unref_unlink)
998 GstPadLinkReturn plr;
1000 sink = gst_pad_new ("sink", GST_PAD_SINK);
1001 fail_if (sink == NULL);
1003 src = gst_pad_new ("src", GST_PAD_SRC);
1004 fail_if (src == NULL);
1006 caps = gst_caps_from_string ("foo/bar");
1008 gst_pad_set_active (src, TRUE);
1009 gst_pad_set_caps (src, caps);
1010 gst_pad_set_active (sink, TRUE);
1011 gst_pad_set_caps (sink, caps);
1013 plr = gst_pad_link (src, sink);
1014 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1016 /* unref the sinkpad */
1017 gst_object_unref (sink);
1019 /* src should be unlinked now */
1020 fail_if (gst_pad_is_linked (src));
1023 gst_object_unref (src);
1024 gst_caps_unref (caps);
1031 static GstPadProbeReturn
1032 block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1034 gboolean *bool_user_data = (gboolean *) user_data;
1036 fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
1038 /* here we should have blocked == 0 unblocked == 0 */
1039 fail_unless (bool_user_data[0] == FALSE);
1040 fail_unless (bool_user_data[1] == FALSE);
1042 bool_user_data[0] = TRUE;
1044 gst_pad_remove_probe (pad, id);
1045 bool_user_data[1] = TRUE;
1047 return GST_PAD_PROBE_OK;
1050 GST_START_TEST (test_block_async)
1053 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
1055 gboolean data[2] = { FALSE, FALSE };
1057 pad = gst_pad_new ("src", GST_PAD_SRC);
1058 fail_unless (pad != NULL);
1060 gst_pad_set_active (pad, TRUE);
1062 fail_unless (gst_pad_push_event (pad,
1063 gst_event_new_stream_start ("test")) == TRUE);
1064 fail_unless (gst_pad_push_event (pad,
1065 gst_event_new_segment (&dummy_segment)) == TRUE);
1067 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_cb, &data,
1070 fail_unless (data[0] == FALSE);
1071 fail_unless (data[1] == FALSE);
1072 gst_pad_push (pad, gst_buffer_new ());
1074 gst_object_unref (pad);
1079 static GstPadProbeReturn
1080 block_async_cb_return_ok (GstPad * pad, GstPadProbeInfo * info,
1083 return GST_PAD_PROBE_OK;
1087 push_buffer_async (GstPad * pad)
1089 return GINT_TO_POINTER (gst_pad_push (pad, gst_buffer_new ()));
1093 test_pad_blocking_with_type (GstPadProbeType type)
1099 pad = gst_pad_new ("src", GST_PAD_SRC);
1100 fail_unless (pad != NULL);
1102 gst_pad_set_active (pad, TRUE);
1104 fail_unless (gst_pad_push_event (pad,
1105 gst_event_new_stream_start ("test")) == TRUE);
1106 fail_unless (gst_pad_push_event (pad,
1107 gst_event_new_segment (&dummy_segment)) == TRUE);
1109 id = gst_pad_add_probe (pad, type, block_async_cb_return_ok, NULL, NULL);
1112 thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1115 /* wait for the block */
1116 while (!gst_pad_is_blocking (pad)) {
1120 /* stop with flushing */
1121 gst_pad_push_event (pad, gst_event_new_flush_start ());
1123 /* get return value from push */
1124 ret = GPOINTER_TO_INT (g_thread_join (thread));
1126 gst_pad_push_event (pad, gst_event_new_flush_stop (FALSE));
1127 /* must be wrong state */
1128 fail_unless (ret == GST_FLOW_FLUSHING);
1130 gst_object_unref (pad);
1133 GST_START_TEST (test_pad_blocking_with_probe_type_block)
1135 test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCK);
1140 GST_START_TEST (test_pad_blocking_with_probe_type_blocking)
1142 test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCKING);
1147 static gboolean pad_probe_remove_notifiy_called = FALSE;
1149 static GstPadProbeReturn
1150 probe_remove_self_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1152 gst_pad_remove_probe (pad, info->id);
1154 fail_unless (pad->num_probes == 0);
1155 fail_unless (pad->num_blocked == 0);
1157 return GST_PAD_PROBE_REMOVE;
1161 probe_remove_notify_cb (gpointer data)
1163 fail_unless (pad_probe_remove_notifiy_called == FALSE);
1164 pad_probe_remove_notifiy_called = TRUE;
1167 GST_START_TEST (test_pad_probe_remove)
1171 pad = gst_pad_new ("src", GST_PAD_SRC);
1172 fail_unless (pad != NULL);
1174 gst_pad_set_active (pad, TRUE);
1175 fail_unless (pad->num_probes == 0);
1176 fail_unless (pad->num_blocked == 0);
1177 gst_pad_add_probe (pad,
1178 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
1179 probe_remove_self_cb, NULL, probe_remove_notify_cb);
1180 fail_unless (pad->num_probes == 1);
1181 fail_unless (pad->num_blocked == 1);
1183 pad_probe_remove_notifiy_called = FALSE;
1184 gst_pad_push_event (pad, gst_event_new_stream_start ("asda"));
1186 fail_unless (pad->num_probes == 0);
1187 fail_unless (pad->num_blocked == 0);
1189 gst_object_unref (pad);
1194 static gboolean src_flush_start_probe_called = FALSE;
1195 static gboolean src_flush_stop_probe_called = FALSE;
1196 static gboolean sink_flush_start_probe_called = FALSE;
1197 static gboolean sink_flush_stop_probe_called = FALSE;
1199 static GstPadProbeReturn
1200 flush_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1204 if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_FLUSH))
1207 event = gst_pad_probe_info_get_event (info);
1208 switch (GST_EVENT_TYPE (event)) {
1209 case GST_EVENT_FLUSH_START:
1210 if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1211 src_flush_start_probe_called = TRUE;
1213 sink_flush_start_probe_called = TRUE;
1215 case GST_EVENT_FLUSH_STOP:
1216 if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1217 src_flush_stop_probe_called = TRUE;
1219 sink_flush_stop_probe_called = TRUE;
1226 return GST_PAD_PROBE_OK;
1229 GST_START_TEST (test_pad_probe_flush_events)
1233 src = gst_pad_new ("src", GST_PAD_SRC);
1234 sink = gst_pad_new ("sink", GST_PAD_SINK);
1235 gst_pad_set_chain_function (sink, gst_check_chain_func);
1236 gst_pad_set_active (src, TRUE);
1237 gst_pad_set_active (sink, TRUE);
1239 fail_unless (gst_pad_push_event (src,
1240 gst_event_new_stream_start ("test")) == TRUE);
1241 fail_unless (gst_pad_push_event (src,
1242 gst_event_new_segment (&dummy_segment)) == TRUE);
1244 fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1246 gst_pad_add_probe (src,
1247 GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1248 GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1249 gst_pad_add_probe (sink,
1250 GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1251 GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1253 gst_pad_push_event (src, gst_event_new_flush_start ());
1254 gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
1256 fail_unless (gst_pad_push_event (src,
1257 gst_event_new_segment (&dummy_segment)) == TRUE);
1259 /* push a buffer so the events are propagated downstream */
1260 gst_pad_push (src, gst_buffer_new ());
1262 fail_unless (src_flush_start_probe_called);
1263 fail_unless (src_flush_stop_probe_called);
1264 fail_unless (sink_flush_start_probe_called);
1265 fail_unless (sink_flush_stop_probe_called);
1267 gst_object_unref (src);
1268 gst_object_unref (sink);
1273 static gboolean got_notify;
1276 caps_notify (GstPad * pad, GParamSpec * spec, gpointer data)
1282 test_queue_src_caps_notify (gboolean link_queue)
1285 GstPad *src, *sink, *another_pad;
1288 queue = gst_element_factory_make ("queue", NULL);
1289 fail_unless (queue != NULL);
1291 src = gst_element_get_static_pad (queue, "src");
1292 fail_unless (src != NULL);
1294 sink = gst_element_get_static_pad (queue, "sink");
1295 fail_unless (sink != NULL);
1298 another_pad = gst_pad_new ("sink", GST_PAD_SINK);
1299 fail_unless (another_pad != NULL);
1300 gst_pad_set_active (another_pad, TRUE);
1302 gst_pad_link_full (src, another_pad, GST_PAD_LINK_CHECK_NOTHING);
1307 gst_element_set_state (queue, GST_STATE_PLAYING);
1311 g_signal_connect (src, "notify::caps", G_CALLBACK (caps_notify), NULL);
1313 caps = gst_caps_from_string ("caps");
1314 gst_pad_send_event (sink, gst_event_new_caps (caps));
1315 gst_caps_unref (caps);
1317 while (got_notify == FALSE)
1320 gst_element_set_state (queue, GST_STATE_NULL);
1322 gst_object_unref (src);
1323 gst_object_unref (sink);
1324 gst_object_unref (queue);
1326 gst_object_unref (another_pad);
1330 GST_START_TEST (test_queue_src_caps_notify_linked)
1332 test_queue_src_caps_notify (TRUE);
1336 GST_START_TEST (test_queue_src_caps_notify_not_linked)
1338 /* This test will fail because queue doesn't set the caps
1339 on src pad unless it is linked */
1340 test_queue_src_caps_notify (FALSE);
1347 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
1349 gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
1353 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
1355 static int n_calls = 0;
1356 gboolean *bool_user_data = (gboolean *) user_data;
1359 /* we expect this callback to be called only once */
1360 g_warn_if_reached ();
1362 *bool_user_data = blocked;
1364 /* replace block_async_first with block_async_second so next time the pad is
1365 * blocked the latter should be called */
1366 gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
1368 /* unblock temporarily, in the next push block_async_second should be called
1370 gst_pad_push_event (pad, gst_event_new_flush_start ());
1373 GST_START_TEST (test_block_async_replace_callback)
1378 pad = gst_pad_new ("src", GST_PAD_SRC);
1379 fail_unless (pad != NULL);
1380 gst_pad_set_active (pad, TRUE);
1382 gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
1385 gst_pad_push (pad, gst_buffer_new ());
1386 fail_unless (blocked == TRUE);
1387 /* block_async_first flushes to unblock */
1388 gst_pad_push_event (pad, gst_event_new_flush_stop ());
1390 /* push again, this time block_async_second should be called */
1391 gst_pad_push (pad, gst_buffer_new ());
1392 fail_unless (blocked == TRUE);
1394 gst_object_unref (pad);
1401 block_async_full_destroy (gpointer user_data)
1403 gint *state = (gint *) user_data;
1405 fail_unless (*state < 2);
1407 GST_DEBUG ("setting state to 2");
1411 static GstPadProbeReturn
1412 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1414 *(gint *) user_data = (gint) TRUE;
1416 gst_pad_push_event (pad, gst_event_new_flush_start ());
1417 GST_DEBUG ("setting state to 1");
1419 return GST_PAD_PROBE_OK;
1422 GST_START_TEST (test_block_async_full_destroy)
1425 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1429 pad = gst_pad_new ("src", GST_PAD_SRC);
1430 fail_unless (pad != NULL);
1431 gst_pad_set_active (pad, TRUE);
1433 fail_unless (gst_pad_push_event (pad,
1434 gst_event_new_stream_start ("test")) == TRUE);
1435 fail_unless (gst_pad_push_event (pad,
1436 gst_event_new_segment (&dummy_segment)) == TRUE);
1438 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1439 &state, block_async_full_destroy);
1440 fail_unless (state == 0);
1442 gst_pad_push (pad, gst_buffer_new ());
1443 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1445 fail_unless (state == 1);
1446 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1448 /* unblock callback is called */
1449 gst_pad_remove_probe (pad, id);
1450 fail_unless (state == 2);
1452 gst_object_unref (pad);
1457 GST_START_TEST (test_block_async_full_destroy_dispose)
1460 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1463 pad = gst_pad_new ("src", GST_PAD_SRC);
1464 fail_unless (pad != NULL);
1465 gst_pad_set_active (pad, TRUE);
1467 fail_unless (gst_pad_push_event (pad,
1468 gst_event_new_stream_start ("test")) == TRUE);
1469 fail_unless (gst_pad_push_event (pad,
1470 gst_event_new_segment (&dummy_segment)) == TRUE);
1472 (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1473 &state, block_async_full_destroy);
1475 gst_pad_push (pad, gst_buffer_new ());
1476 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1478 fail_unless_equals_int (state, 1);
1479 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1481 /* gst_BLOCK calls the destroy_notify function if necessary */
1482 gst_object_unref (pad);
1484 fail_unless_equals_int (state, 2);
1492 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
1494 gboolean *bool_user_data = (gboolean *) user_data;
1496 /* here we should have blocked == 1 unblocked == 0 */
1498 fail_unless (blocked == FALSE);
1500 fail_unless (bool_user_data[0] == TRUE);
1501 fail_unless (bool_user_data[1] == TRUE);
1502 fail_unless (bool_user_data[2] == FALSE);
1504 bool_user_data[2] = TRUE;
1511 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
1513 g_warn_if_reached ();
1517 static GstPadProbeReturn
1518 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
1521 gboolean *bool_user_data = (gboolean *) user_data;
1523 GST_DEBUG ("second probe called");
1525 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1527 fail_unless (bool_user_data[0] == TRUE);
1528 fail_unless (bool_user_data[1] == FALSE);
1529 fail_unless (bool_user_data[2] == FALSE);
1531 bool_user_data[1] = TRUE;
1533 GST_DEBUG ("removing second probe with id %lu", id);
1534 gst_pad_remove_probe (pad, id);
1536 return GST_PAD_PROBE_OK;
1539 static GstPadProbeReturn
1540 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
1543 static int n_calls = 0;
1544 gboolean *bool_user_data = (gboolean *) user_data;
1546 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1548 GST_DEBUG ("first probe called");
1551 /* we expect this callback to be called only once */
1552 g_warn_if_reached ();
1554 *bool_user_data = TRUE;
1556 fail_unless (bool_user_data[0] == TRUE);
1557 fail_unless (bool_user_data[1] == FALSE);
1558 fail_unless (bool_user_data[2] == FALSE);
1560 GST_DEBUG ("removing first probe with id %lu", id);
1561 gst_pad_remove_probe (pad, id);
1563 GST_DEBUG ("adding second probe");
1564 /* replace block_async_first with block_async_second so next time the pad is
1565 * blocked the latter should be called */
1566 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1567 block_async_second_no_flush, user_data, NULL);
1568 GST_DEBUG ("added probe with id %lu", id);
1570 return GST_PAD_PROBE_OK;
1573 GST_START_TEST (test_block_async_replace_callback_no_flush)
1576 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
1578 pad = gst_pad_new ("src", GST_PAD_SRC);
1579 fail_unless (pad != NULL);
1580 gst_pad_set_active (pad, TRUE);
1582 fail_unless (gst_pad_push_event (pad,
1583 gst_event_new_stream_start ("test")) == TRUE);
1584 fail_unless (gst_pad_push_event (pad,
1585 gst_event_new_segment (&dummy_segment)) == TRUE);
1587 GST_DEBUG ("adding probe");
1588 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1589 block_async_first_no_flush, bool_user_data, NULL);
1590 GST_DEBUG ("added probe with id %lu", id);
1593 GST_DEBUG ("pushing buffer");
1594 gst_pad_push (pad, gst_buffer_new ());
1595 fail_unless (bool_user_data[0] == TRUE);
1596 fail_unless (bool_user_data[1] == TRUE);
1597 fail_unless (bool_user_data[2] == FALSE);
1599 gst_object_unref (pad);
1604 static gint sticky_count;
1607 test_sticky_events_handler (GstPad * pad, GstObject * parent, GstEvent * event)
1609 GST_DEBUG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
1611 switch (sticky_count) {
1613 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
1620 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
1622 gst_event_parse_caps (event, &caps);
1623 fail_unless (gst_caps_get_size (caps) == 1);
1624 s = gst_caps_get_structure (caps, 0);
1625 fail_unless (gst_structure_has_name (s, "foo/baz"));
1629 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1632 fail_unless (FALSE);
1636 gst_event_unref (event);
1642 static GstFlowReturn
1643 test_sticky_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1645 gst_buffer_unref (buffer);
1649 GST_START_TEST (test_sticky_events)
1651 GstPad *srcpad, *sinkpad;
1656 /* make unlinked srcpad */
1657 srcpad = gst_pad_new ("src", GST_PAD_SRC);
1658 fail_unless (srcpad != NULL);
1659 gst_pad_set_active (srcpad, TRUE);
1661 /* test stream-start */
1662 fail_unless (gst_pad_get_stream_id (srcpad) == NULL);
1664 /* push an event, it should be sticky on the srcpad */
1665 fail_unless (gst_pad_push_event (srcpad,
1666 gst_event_new_stream_start ("test")) == TRUE);
1668 /* let's see if it stuck */
1669 id = gst_pad_get_stream_id (srcpad);
1670 fail_unless_equals_string (id, "test");
1673 /* make a caps event */
1674 caps = gst_caps_new_empty_simple ("foo/bar");
1675 gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1676 gst_caps_unref (caps);
1678 /* make segment event */
1679 gst_segment_init (&seg, GST_FORMAT_TIME);
1680 gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
1682 /* now make a sinkpad */
1683 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1684 fail_unless (sinkpad != NULL);
1686 gst_pad_set_event_function (sinkpad, test_sticky_events_handler);
1687 gst_pad_set_chain_function (sinkpad, test_sticky_chain);
1688 fail_unless (sticky_count == 0);
1689 gst_pad_set_active (sinkpad, TRUE);
1692 gst_pad_link (srcpad, sinkpad);
1693 /* should not trigger events */
1694 fail_unless (sticky_count == 0);
1696 /* caps replaces old caps event at position 2, the pushes all
1698 caps = gst_caps_new_empty_simple ("foo/baz");
1699 gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1700 gst_caps_unref (caps);
1702 /* should have triggered 2 events, the segment event is still pending */
1703 fail_unless_equals_int (sticky_count, 2);
1705 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
1707 /* should have triggered 3 events */
1708 fail_unless_equals_int (sticky_count, 3);
1710 gst_object_unref (srcpad);
1711 gst_object_unref (sinkpad);
1717 gst_pad_suite (void)
1719 Suite *s = suite_create ("GstPad");
1720 TCase *tc_chain = tcase_create ("general");
1722 /* turn off timeout */
1723 tcase_set_timeout (tc_chain, 60);
1725 gst_segment_init (&dummy_segment, GST_FORMAT_BYTES);
1727 suite_add_tcase (s, tc_chain);
1728 tcase_add_test (tc_chain, test_link);
1729 tcase_add_test (tc_chain, test_refcount);
1730 tcase_add_test (tc_chain, test_get_allowed_caps);
1731 tcase_add_test (tc_chain, test_sticky_caps_unlinked);
1732 tcase_add_test (tc_chain, test_sticky_caps_unlinked_incompatible);
1733 tcase_add_test (tc_chain, test_sticky_caps_flushing);
1734 tcase_add_test (tc_chain, test_link_unlink_threaded);
1735 tcase_add_test (tc_chain, test_name_is_valid);
1736 tcase_add_test (tc_chain, test_push_unlinked);
1737 tcase_add_test (tc_chain, test_push_linked);
1738 tcase_add_test (tc_chain, test_push_linked_flushing);
1739 tcase_add_test (tc_chain, test_push_buffer_list_compat);
1740 tcase_add_test (tc_chain, test_flowreturn);
1741 tcase_add_test (tc_chain, test_push_negotiation);
1742 tcase_add_test (tc_chain, test_src_unref_unlink);
1743 tcase_add_test (tc_chain, test_sink_unref_unlink);
1744 tcase_add_test (tc_chain, test_block_async);
1745 tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_block);
1746 tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_blocking);
1747 tcase_add_test (tc_chain, test_pad_probe_remove);
1748 tcase_add_test (tc_chain, test_pad_probe_flush_events);
1749 tcase_add_test (tc_chain, test_queue_src_caps_notify_linked);
1750 tcase_add_test (tc_chain, test_queue_src_caps_notify_not_linked);
1752 tcase_add_test (tc_chain, test_block_async_replace_callback);
1754 tcase_add_test (tc_chain, test_block_async_full_destroy);
1755 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
1756 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1757 tcase_add_test (tc_chain, test_sticky_events);
1762 GST_CHECK_MAIN (gst_pad);