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.
25 #include <gst/check/gstcheck.h>
27 static GstSegment dummy_segment;
29 GST_START_TEST (test_link)
37 src = gst_pad_new ("source", GST_PAD_SRC);
38 fail_if (src == NULL);
39 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
41 name = gst_pad_get_name (src);
42 fail_unless (strcmp (name, "source") == 0);
43 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
46 sink = gst_pad_new ("sink", GST_PAD_SINK);
47 fail_if (sink == NULL);
49 /* linking without templates or caps should work */
50 ret = gst_pad_link (src, sink);
51 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
52 ASSERT_OBJECT_REFCOUNT (sink, "sink pad", 1);
53 fail_unless (ret == GST_PAD_LINK_OK);
55 ASSERT_CRITICAL (gst_pad_get_pad_template (NULL));
57 srct = gst_pad_get_pad_template (src);
58 fail_unless (srct == NULL);
59 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
62 ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
63 gst_object_unref (src);
64 gst_object_unref (sink);
69 /* threaded link/unlink */
71 static GstPad *src, *sink;
74 thread_link_unlink (gpointer data)
78 while (THREAD_TEST_RUNNING ()) {
79 gst_pad_link (src, sink);
80 gst_pad_unlink (src, sink);
85 GST_START_TEST (test_link_unlink_threaded)
90 src = gst_pad_new ("source", GST_PAD_SRC);
91 fail_if (src == NULL);
92 sink = gst_pad_new ("sink", GST_PAD_SINK);
93 fail_if (sink == NULL);
95 caps = gst_caps_from_string ("foo/bar");
96 gst_pad_set_active (src, TRUE);
97 gst_pad_set_caps (src, caps);
98 gst_pad_set_active (sink, TRUE);
99 gst_pad_set_caps (sink, caps);
100 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
102 MAIN_START_THREADS (5, thread_link_unlink, NULL);
103 for (i = 0; i < 1000; ++i) {
104 gst_pad_is_linked (src);
105 gst_pad_is_linked (sink);
108 MAIN_STOP_THREADS ();
110 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
111 gst_caps_unref (caps);
113 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
114 gst_object_unref (src);
115 gst_object_unref (sink);
120 GST_START_TEST (test_refcount)
124 GstPadLinkReturn plr;
126 sink = gst_pad_new ("sink", GST_PAD_SINK);
127 fail_if (sink == NULL);
129 src = gst_pad_new ("src", GST_PAD_SRC);
130 fail_if (src == NULL);
132 caps = gst_caps_from_string ("foo/bar");
134 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
136 /* can't set caps on flushing sinkpad */
137 fail_if (gst_pad_set_caps (src, caps) == TRUE);
138 fail_if (gst_pad_set_caps (sink, caps) == TRUE);
139 /* one for me and one for each set_caps */
140 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
142 gst_pad_set_active (src, TRUE);
143 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
144 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
146 gst_pad_set_active (sink, TRUE);
147 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
148 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
150 plr = gst_pad_link (src, sink);
151 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
152 /* src caps added to pending caps on sink */
153 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
155 gst_pad_unlink (src, sink);
156 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
159 gst_object_unref (src);
160 gst_object_unref (sink);
161 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
163 gst_caps_unref (caps);
168 GST_START_TEST (test_get_allowed_caps)
171 GstCaps *caps, *gotcaps;
172 GstPadLinkReturn plr;
174 ASSERT_CRITICAL (gst_pad_get_allowed_caps (NULL));
176 src = gst_pad_new ("src", GST_PAD_SRC);
177 fail_if (src == NULL);
178 caps = gst_pad_get_allowed_caps (src);
179 fail_unless (caps == NULL);
181 caps = gst_caps_from_string ("foo/bar");
183 sink = gst_pad_new ("sink", GST_PAD_SINK);
184 gst_pad_set_active (src, TRUE);
185 /* source pad is active and will accept the caps event */
186 fail_unless (gst_pad_set_caps (src, caps) == TRUE);
187 /* sink pad is not active and will refuse the caps event */
188 fail_if (gst_pad_set_caps (sink, caps) == TRUE);
189 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
191 gst_pad_set_active (sink, TRUE);
192 /* sink pad is now active and will accept the caps event */
193 fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
194 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
196 plr = gst_pad_link (src, sink);
197 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
199 gotcaps = gst_pad_get_allowed_caps (src);
200 fail_if (gotcaps == NULL);
201 fail_unless (gst_caps_is_equal (gotcaps, caps));
203 ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 4);
204 gst_caps_unref (gotcaps);
206 gst_pad_unlink (src, sink);
209 ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
210 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
211 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
213 gst_object_unref (src);
214 gst_object_unref (sink);
216 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
217 gst_caps_unref (caps);
222 static GstCaps *event_caps = NULL;
225 sticky_event (GstPad * pad, GstObject * parent, GstEvent * event)
229 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS
230 || GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START
231 || GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
233 if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
234 gst_event_unref (event);
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);
307 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
308 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
309 gst_object_unref (src);
310 gst_object_unref (sink);
316 check_if_caps_is_accepted (GstPad * sink, const gchar * str)
321 caps = gst_caps_from_string (str);
322 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
323 ret = gst_pad_query_accept_caps (sink, caps);
324 gst_caps_unref (caps);
330 sink_query_caps (GstPad * pad, GstObject * object, GstQuery * q)
335 switch (GST_QUERY_TYPE (q)) {
339 gst_caps_from_string ("foo/bar, dummy=(int)1,"
340 " query-only-field=(int)1");
341 gst_query_set_caps_result (q, caps);
342 gst_caps_unref (caps);
344 ret = gst_pad_query_default (pad, object, q);
351 /* Tests whether acceptcaps default handler works properly
352 with all 4 possible flag combinations */
353 GST_START_TEST (test_default_accept_caps)
356 GstPadTemplate *sink_template;
359 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
360 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
361 GST_PAD_ALWAYS, caps);
362 gst_caps_unref (caps);
364 sink = gst_pad_new_from_template (sink_template, "sink");
365 fail_if (sink == NULL);
366 gst_pad_set_query_function (sink, sink_query_caps);
368 gst_object_unref (sink_template);
370 gst_pad_set_active (sink, TRUE);
372 /* 1. Check with caps query, subset check */
373 GST_PAD_UNSET_ACCEPT_INTERSECT (sink);
374 GST_PAD_UNSET_ACCEPT_TEMPLATE (sink);
375 fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
376 fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
377 fail_unless (check_if_caps_is_accepted (sink,
378 "foo/bar, dummy=(int)1, query-only-field=(int)1"));
379 fail_if (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
381 /* 2. Check with caps query, intersect check */
382 GST_PAD_SET_ACCEPT_INTERSECT (sink);
383 GST_PAD_UNSET_ACCEPT_TEMPLATE (sink);
384 fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
385 fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
386 fail_unless (check_if_caps_is_accepted (sink,
387 "foo/bar, dummy=(int)1, query-only-field=(int)1"));
388 fail_unless (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
390 /* 3. Check with template caps, subset check */
391 GST_PAD_UNSET_ACCEPT_INTERSECT (sink);
392 GST_PAD_SET_ACCEPT_TEMPLATE (sink);
393 fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
394 fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
395 fail_unless (check_if_caps_is_accepted (sink,
396 "foo/bar, dummy=(int)1, query-only-field=(int)1"));
397 fail_if (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
399 /* 3. Check with template caps, intersect check */
400 GST_PAD_SET_ACCEPT_INTERSECT (sink);
401 GST_PAD_SET_ACCEPT_TEMPLATE (sink);
402 fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
403 fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
404 fail_unless (check_if_caps_is_accepted (sink,
405 "foo/bar, dummy=(int)1, query-only-field=(int)1"));
406 fail_unless (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
408 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
409 gst_object_unref (sink);
414 /* Same as test_sticky_caps_unlinked except that the source pad
415 * has a template of ANY and we will attempt to push
416 * incompatible caps */
417 GST_START_TEST (test_sticky_caps_unlinked_incompatible)
419 GstCaps *caps, *failcaps;
420 GstPadTemplate *src_template, *sink_template;
424 /* Source pad has ANY caps
425 * Sink pad has foobar caps
426 * We will push the pony express caps (which should fail)
428 caps = gst_caps_new_any ();
429 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
430 GST_PAD_ALWAYS, caps);
431 gst_caps_unref (caps);
432 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
433 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
434 GST_PAD_ALWAYS, caps);
435 gst_caps_unref (caps);
437 src = gst_pad_new_from_template (src_template, "src");
438 fail_if (src == NULL);
439 sink = gst_pad_new_from_template (sink_template, "sink");
440 fail_if (sink == NULL);
441 gst_pad_set_event_function (sink, sticky_event);
442 gst_pad_set_chain_function (sink, gst_check_chain_func);
444 gst_object_unref (src_template);
445 gst_object_unref (sink_template);
447 gst_pad_set_active (src, TRUE);
449 fail_unless (gst_pad_push_event (src,
450 gst_event_new_stream_start ("test")) == TRUE);
452 failcaps = gst_caps_from_string ("pony/express, failure=(boolean)true");
453 ASSERT_CAPS_REFCOUNT (failcaps, "caps", 1);
455 event = gst_event_new_caps (failcaps);
456 gst_caps_unref (failcaps);
457 /* The pad isn't linked yet, and anything matches the source pad template
459 fail_unless (gst_pad_push_event (src, event) == TRUE);
460 fail_unless (event_caps == NULL);
462 fail_unless (gst_pad_push_event (src,
463 gst_event_new_segment (&dummy_segment)) == TRUE);
465 /* Linking and activating will not forward the sticky event yet... */
466 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
467 gst_pad_set_active (sink, TRUE);
468 fail_unless (event_caps == NULL);
470 /* ...but the first buffer will and should FAIL since the caps
471 * are not compatible */
472 fail_unless (gst_pad_push (src,
473 gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
474 /* We shouldn't have received the caps event since it's incompatible */
475 fail_unless (event_caps == NULL);
476 /* We shouldn't have received any buffers since caps are incompatible */
477 fail_unless_equals_int (g_list_length (buffers), 0);
479 gst_check_drop_buffers ();
481 gst_caps_replace (&event_caps, NULL);
483 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
484 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
485 gst_object_unref (src);
486 gst_object_unref (sink);
491 /* Like test_sticky_caps_unlinked, but link before caps: */
493 GST_START_TEST (test_sticky_caps_flushing)
496 GstPadTemplate *src_template, *sink_template;
500 caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
501 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
502 GST_PAD_ALWAYS, caps);
503 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
504 GST_PAD_ALWAYS, caps);
505 gst_caps_unref (caps);
507 src = gst_pad_new_from_template (src_template, "src");
508 fail_if (src == NULL);
509 sink = gst_pad_new_from_template (sink_template, "sink");
510 fail_if (sink == NULL);
511 gst_pad_set_event_function (sink, sticky_event);
512 gst_pad_set_chain_function (sink, gst_check_chain_func);
514 gst_object_unref (src_template);
515 gst_object_unref (sink_template);
517 fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
519 caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
520 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
522 event = gst_event_new_caps (caps);
524 gst_pad_set_active (src, TRUE);
525 fail_unless (gst_pad_push_event (src,
526 gst_event_new_stream_start ("test")) == TRUE);
527 /* The caps event gets accepted by the source pad (and stored) */
528 fail_unless (gst_pad_push_event (src, event) == TRUE);
529 /* But wasn't forwarded since the sink pad is flushing (not activated) */
530 fail_unless (event_caps == NULL);
532 fail_unless (gst_pad_push_event (src,
533 gst_event_new_segment (&dummy_segment)) == TRUE);
535 /* Activating will not forward the sticky event yet... */
536 gst_pad_set_active (sink, TRUE);
537 fail_unless (event_caps == NULL);
539 /* ...but the first buffer will: */
540 fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
541 fail_unless (event_caps == caps);
542 fail_unless_equals_int (g_list_length (buffers), 1);
544 gst_check_drop_buffers ();
546 gst_caps_replace (&caps, NULL);
547 gst_caps_replace (&event_caps, NULL);
549 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
550 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
551 gst_object_unref (src);
552 gst_object_unref (sink);
558 name_is_valid (const gchar * name, GstPadPresence presence)
561 GstCaps *any = gst_caps_new_any ();
563 new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
564 gst_caps_unref (any);
566 gst_object_unref (GST_OBJECT (new));
572 GST_START_TEST (test_name_is_valid)
574 gboolean result = FALSE;
576 fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
577 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
578 ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
581 fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
582 ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
583 ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
584 ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
585 fail_unless (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
587 fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
588 fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
593 static GstPadProbeReturn
594 _probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
596 GstPadProbeReturn ret = (GstPadProbeReturn) GPOINTER_TO_INT (userdata);
598 /* If we are handling the data, we unref it */
599 if (ret == GST_PAD_PROBE_HANDLED
600 && !(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_QUERY_BOTH)) {
601 GST_DEBUG_OBJECT (pad, "Unreffing data");
602 gst_mini_object_unref (info->data);
607 static GstPadProbeReturn
608 _handled_probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
610 GstFlowReturn customflow = (GstFlowReturn) GPOINTER_TO_INT (userdata);
612 /* We are handling the data, we unref it */
613 if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_QUERY_BOTH))
614 gst_mini_object_unref (info->data);
615 GST_PAD_PROBE_INFO_FLOW_RETURN (info) = customflow;
617 return GST_PAD_PROBE_HANDLED;
620 static GstPadProbeReturn
621 _cleaning_handled_probe_handler (GstPad * pad, GstPadProbeInfo * info,
624 GstFlowReturn customflow = (GstFlowReturn) GPOINTER_TO_INT (userdata);
626 /* We are handling the data, we unref it and we reset the data field */
627 if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_QUERY_BOTH))
628 gst_mini_object_unref (info->data);
629 GST_PAD_PROBE_INFO_FLOW_RETURN (info) = customflow;
630 GST_PAD_PROBE_INFO_DATA (info) = NULL;
632 return GST_PAD_PROBE_HANDLED;
637 GST_START_TEST (test_events_query_unlinked)
644 src = gst_pad_new ("src", GST_PAD_SRC);
645 fail_if (src == NULL);
646 caps = gst_pad_get_allowed_caps (src);
647 fail_unless (caps == NULL);
649 caps = gst_caps_from_string ("foo/bar");
651 gst_pad_set_active (src, TRUE);
652 fail_unless (gst_pad_push_event (src,
653 gst_event_new_stream_start ("test")) == TRUE);
654 gst_pad_set_caps (src, caps);
655 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
656 fail_unless (gst_pad_push_event (src,
657 gst_event_new_segment (&dummy_segment)) == TRUE);
658 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
660 /* Doing a query on an unlinked pad will return FALSE */
661 query = gst_query_new_duration (GST_FORMAT_TIME);
662 fail_unless (gst_pad_peer_query (src, query) == FALSE);
663 ASSERT_MINI_OBJECT_REFCOUNT (query, "query", 1);
664 gst_query_unref (query);
666 /* Add a probe that returns _DROP will make the event push return TRUE
667 * even if not linked */
668 GST_DEBUG ("event/query DROP");
669 id = gst_pad_add_probe (src,
670 GST_PAD_PROBE_TYPE_EVENT_BOTH | GST_PAD_PROBE_TYPE_QUERY_BOTH,
671 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
672 fail_unless (gst_pad_push_event (src,
673 gst_event_new_segment (&dummy_segment)) == TRUE);
674 /* Queries should still fail */
675 query = gst_query_new_duration (GST_FORMAT_TIME);
676 fail_unless (gst_pad_peer_query (src, query) == FALSE);
677 ASSERT_MINI_OBJECT_REFCOUNT (query, "query", 1);
678 gst_query_unref (query);
679 gst_pad_remove_probe (src, id);
681 /* Add a probe that returns _HANDLED will make the event push return TRUE
682 * even if not linked */
683 GST_DEBUG ("event/query HANDLED");
684 id = gst_pad_add_probe (src,
685 GST_PAD_PROBE_TYPE_EVENT_BOTH | GST_PAD_PROBE_TYPE_QUERY_BOTH,
686 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_HANDLED), NULL);
687 fail_unless (gst_pad_push_event (src,
688 gst_event_new_segment (&dummy_segment)) == TRUE);
690 /* Queries will succeed */
691 query = gst_query_new_duration (GST_FORMAT_TIME);
692 fail_unless (gst_pad_peer_query (src, query) == TRUE);
693 ASSERT_MINI_OBJECT_REFCOUNT (query, "query", 1);
694 gst_query_unref (query);
695 gst_pad_remove_probe (src, id);
698 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
699 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
701 gst_object_unref (src);
703 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
704 gst_caps_unref (caps);
709 GST_START_TEST (test_push_unlinked)
717 src = gst_pad_new ("src", GST_PAD_SRC);
718 fail_if (src == NULL);
719 caps = gst_pad_get_allowed_caps (src);
720 fail_unless (caps == NULL);
722 caps = gst_caps_from_string ("foo/bar");
724 /* pushing on an inactive pad will return wrong state */
725 GST_DEBUG ("push buffer inactive");
726 buffer = gst_buffer_new ();
727 gst_buffer_ref (buffer);
728 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
729 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
730 gst_buffer_unref (buffer);
732 gst_pad_set_active (src, TRUE);
733 fail_unless (gst_pad_push_event (src,
734 gst_event_new_stream_start ("test")) == TRUE);
735 GST_DEBUG ("push caps event inactive");
736 gst_pad_set_caps (src, caps);
737 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
738 fail_unless (gst_pad_push_event (src,
739 gst_event_new_segment (&dummy_segment)) == TRUE);
741 /* pushing on an unlinked pad will drop the buffer */
742 GST_DEBUG ("push buffer unlinked");
743 buffer = gst_buffer_new ();
744 gst_buffer_ref (buffer);
745 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
746 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
747 gst_buffer_unref (buffer);
749 /* adding a probe that returns _DROP will drop the buffer without trying
751 GST_DEBUG ("push buffer drop");
752 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
753 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
754 buffer = gst_buffer_new ();
755 gst_buffer_ref (buffer);
756 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
757 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
758 gst_buffer_unref (buffer);
759 gst_pad_remove_probe (src, id);
761 /* adding a probe that returns _HANDLED will drop the buffer without trying
763 GST_DEBUG ("push buffer handled");
764 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
765 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_HANDLED), NULL);
766 buffer = gst_buffer_new ();
767 gst_buffer_ref (buffer);
768 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
769 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
770 gst_buffer_unref (buffer);
771 gst_pad_remove_probe (src, id);
773 /* adding a probe that returns _OK will still chain the buffer,
774 * and hence drop because pad is unlinked */
775 GST_DEBUG ("push buffer ok");
776 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
777 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_OK), NULL);
778 buffer = gst_buffer_new ();
779 gst_buffer_ref (buffer);
780 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
781 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
782 gst_buffer_unref (buffer);
783 gst_pad_remove_probe (src, id);
785 GST_DEBUG ("push buffer handled and custom return");
786 for (fl = GST_FLOW_NOT_SUPPORTED; fl <= GST_FLOW_OK; fl += 1) {
787 GST_DEBUG ("Testing with %s", gst_flow_get_name (fl));
788 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
789 _handled_probe_handler, GINT_TO_POINTER (fl), NULL);
790 buffer = gst_buffer_new ();
791 gst_buffer_ref (buffer);
792 fail_unless (gst_pad_push (src, buffer) == fl);
793 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
794 gst_buffer_unref (buffer);
795 gst_pad_remove_probe (src, id);
799 /* Same thing, except that this time we also set the info data field
800 * to NULL in the probe. We can because we are returning _HANDLED */
801 GST_DEBUG ("push buffer handled and custom return (with info data NULL'ed)");
802 for (fl = GST_FLOW_NOT_SUPPORTED; fl <= GST_FLOW_OK; fl += 1) {
803 GST_DEBUG ("Testing with %s", gst_flow_get_name (fl));
804 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
805 _cleaning_handled_probe_handler, GINT_TO_POINTER (fl), NULL);
806 buffer = gst_buffer_new ();
807 gst_buffer_ref (buffer);
808 fail_unless (gst_pad_push (src, buffer) == fl);
809 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
810 gst_buffer_unref (buffer);
811 gst_pad_remove_probe (src, id);
817 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
818 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
820 gst_object_unref (src);
822 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
823 gst_caps_unref (caps);
828 GST_START_TEST (test_push_linked)
831 GstPadLinkReturn plr;
837 sink = gst_pad_new ("sink", GST_PAD_SINK);
838 fail_if (sink == NULL);
839 gst_pad_set_chain_function (sink, gst_check_chain_func);
841 src = gst_pad_new ("src", GST_PAD_SRC);
842 fail_if (src == NULL);
844 caps = gst_caps_from_string ("foo/bar");
846 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
848 gst_pad_set_active (src, TRUE);
850 fail_unless (gst_pad_push_event (src,
851 gst_event_new_stream_start ("test")) == TRUE);
853 gst_pad_set_caps (src, caps);
855 fail_unless (gst_pad_push_event (src,
856 gst_event_new_segment (&dummy_segment)) == TRUE);
858 gst_pad_set_active (sink, TRUE);
859 /* one for me and one for each set_caps */
860 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
862 plr = gst_pad_link (src, sink);
863 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
864 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
866 buffer = gst_buffer_new ();
869 /* pushing on a linked pad will drop the ref to the buffer */
870 gst_buffer_ref (buffer);
871 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
872 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
873 gst_buffer_unref (buffer);
874 fail_unless_equals_int (g_list_length (buffers), 1);
875 buffer = GST_BUFFER (buffers->data);
876 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
877 gst_buffer_unref (buffer);
878 g_list_free (buffers);
881 /* adding a probe that returns _DROP will drop the buffer without trying
883 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
884 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
885 buffer = gst_buffer_new ();
886 gst_buffer_ref (buffer);
887 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
888 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
889 gst_buffer_unref (buffer);
890 gst_pad_remove_probe (src, id);
891 fail_unless_equals_int (g_list_length (buffers), 0);
893 /* adding a probe that returns _OK will still chain the buffer */
894 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
895 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_OK), NULL);
896 buffer = gst_buffer_new ();
897 gst_buffer_ref (buffer);
898 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
899 gst_pad_remove_probe (src, id);
901 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
902 gst_buffer_unref (buffer);
903 fail_unless_equals_int (g_list_length (buffers), 1);
904 buffer = GST_BUFFER (buffers->data);
905 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
906 gst_buffer_unref (buffer);
907 g_list_free (buffers);
910 /* adding a probe that returns _HANDLED will not chain the buffer */
911 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
912 _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_HANDLED), NULL);
913 buffer = gst_buffer_new ();
914 gst_buffer_ref (buffer);
915 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
916 gst_pad_remove_probe (src, id);
918 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
919 gst_buffer_unref (buffer);
920 fail_unless_equals_int (g_list_length (buffers), 0);
921 g_list_free (buffers);
925 gst_check_drop_buffers ();
926 gst_pad_unlink (src, sink);
927 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
928 gst_object_unref (src);
929 gst_object_unref (sink);
930 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
932 gst_caps_unref (caps);
937 GST_START_TEST (test_push_linked_flushing)
941 GstPadLinkReturn plr;
946 src = gst_pad_new ("src", GST_PAD_SRC);
947 fail_if (src == NULL);
948 sink = gst_pad_new ("sink", GST_PAD_SINK);
949 fail_if (sink == NULL);
950 gst_pad_set_chain_function (sink, gst_check_chain_func);
952 caps = gst_pad_get_allowed_caps (src);
953 fail_unless (caps == NULL);
954 caps = gst_pad_get_allowed_caps (sink);
955 fail_unless (caps == NULL);
957 caps = gst_caps_from_string ("foo/bar");
959 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
961 gst_pad_set_active (src, TRUE);
962 fail_unless (gst_pad_push_event (src,
963 gst_event_new_stream_start ("test")) == TRUE);
964 gst_pad_set_caps (src, caps);
965 fail_unless (gst_pad_push_event (src,
966 gst_event_new_segment (&dummy_segment)) == TRUE);
967 /* need to activate to make it accept the caps */
968 gst_pad_set_active (sink, TRUE);
969 /* one for me and one for each set_caps */
970 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
972 plr = gst_pad_link (src, sink);
973 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
974 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
976 /* not activating the pads here, which keeps them flushing */
977 gst_pad_set_active (src, FALSE);
978 gst_pad_set_active (sink, FALSE);
980 /* pushing on a flushing pad will drop the buffer */
981 buffer = gst_buffer_new ();
982 gst_buffer_ref (buffer);
983 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
984 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
985 fail_unless_equals_int (g_list_length (buffers), 0);
986 gst_buffer_unref (buffer);
988 gst_pad_set_active (src, TRUE);
989 gst_pad_set_active (sink, FALSE);
991 fail_unless (gst_pad_push_event (src,
992 gst_event_new_stream_start ("test")) == TRUE);
993 gst_pad_set_caps (src, caps);
994 fail_unless (gst_pad_push_event (src,
995 gst_event_new_segment (&dummy_segment)) == TRUE);
996 /* adding a probe that returns _DROP will drop the buffer without trying
998 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
999 GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
1000 buffer = gst_buffer_new ();
1001 gst_buffer_ref (buffer);
1002 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
1003 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
1004 fail_unless_equals_int (g_list_length (buffers), 0);
1005 gst_buffer_unref (buffer);
1006 gst_pad_remove_probe (src, id);
1008 /* adding a probe that returns _OK will still chain the buffer,
1009 * and hence drop because pad is flushing */
1010 id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
1011 GINT_TO_POINTER (GST_PAD_PROBE_OK), NULL);
1012 buffer = gst_buffer_new ();
1013 gst_buffer_ref (buffer);
1014 fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
1015 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
1016 fail_unless_equals_int (g_list_length (buffers), 0);
1017 gst_buffer_unref (buffer);
1018 gst_pad_remove_probe (src, id);
1021 gst_check_drop_buffers ();
1022 ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
1023 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
1024 gst_pad_link (src, sink);
1025 gst_object_unref (src);
1026 gst_object_unref (sink);
1027 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
1028 gst_caps_unref (caps);
1034 buffer_from_string (const gchar * str)
1039 size = strlen (str);
1040 buf = gst_buffer_new_and_alloc (size);
1042 gst_buffer_fill (buf, 0, str, size);
1048 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
1053 fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
1054 res = memcmp (info.data, str, size) == 0;
1055 GST_MEMDUMP ("buffer data", info.data, size);
1056 GST_MEMDUMP ("compare data", (guint8 *) str, size);
1057 GST_DEBUG ("buffers match: %s", res ? "yes" : "no");
1058 gst_buffer_unmap (buf, &info);
1063 GST_START_TEST (test_push_buffer_list_compat)
1066 GstPadLinkReturn plr;
1068 GstBufferList *list;
1072 sink = gst_pad_new ("sink", GST_PAD_SINK);
1073 fail_if (sink == NULL);
1074 gst_pad_set_chain_function (sink, gst_check_chain_func);
1075 /* leave chainlistfunc unset */
1077 src = gst_pad_new ("src", GST_PAD_SRC);
1078 fail_if (src == NULL);
1080 caps = gst_caps_from_string ("foo/bar");
1082 gst_pad_set_active (src, TRUE);
1084 fail_unless (gst_pad_push_event (src,
1085 gst_event_new_stream_start ("test")) == TRUE);
1087 gst_pad_set_caps (src, caps);
1089 fail_unless (gst_pad_push_event (src,
1090 gst_event_new_segment (&dummy_segment)) == TRUE);
1092 gst_pad_set_active (sink, TRUE);
1094 plr = gst_pad_link (src, sink);
1095 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1097 list = gst_buffer_list_new ();
1100 /* adding to a buffer list will drop the ref to the buffer */
1101 gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
1102 gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
1104 fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
1105 fail_unless_equals_int (g_list_length (buffers), 2);
1106 buffer = GST_BUFFER (buffers->data);
1107 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
1108 fail_unless (buffer_compare (buffer, "ListGroup", 9));
1109 gst_buffer_unref (buffer);
1110 buffers = g_list_delete_link (buffers, buffers);
1111 buffer = GST_BUFFER (buffers->data);
1112 ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
1113 fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
1114 gst_buffer_unref (buffer);
1115 buffers = g_list_delete_link (buffers, buffers);
1116 fail_unless (buffers == NULL);
1119 gst_check_drop_buffers ();
1120 gst_pad_unlink (src, sink);
1121 gst_object_unref (src);
1122 gst_object_unref (sink);
1123 ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
1124 gst_caps_unref (caps);
1129 GST_START_TEST (test_flowreturn)
1134 /* test some of the macros */
1136 fail_if (strcmp (gst_flow_get_name (ret), "eos"));
1137 quark = gst_flow_to_quark (ret);
1138 fail_if (strcmp (g_quark_to_string (quark), "eos"));
1140 /* custom returns */
1141 ret = GST_FLOW_CUSTOM_SUCCESS;
1142 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
1143 quark = gst_flow_to_quark (ret);
1144 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
1146 ret = GST_FLOW_CUSTOM_ERROR;
1147 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
1148 quark = gst_flow_to_quark (ret);
1149 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
1151 /* custom returns clamping */
1152 ret = GST_FLOW_CUSTOM_SUCCESS + 2;
1153 fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
1154 quark = gst_flow_to_quark (ret);
1155 fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
1157 ret = GST_FLOW_CUSTOM_ERROR - 2;
1158 fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
1159 quark = gst_flow_to_quark (ret);
1160 fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
1162 /* unknown values */
1163 ret = GST_FLOW_CUSTOM_ERROR + 2;
1164 fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
1165 quark = gst_flow_to_quark (ret);
1166 fail_unless (quark == 0);
1171 GST_START_TEST (test_push_negotiation)
1174 GstPadLinkReturn plr;
1176 gst_caps_from_string ("audio/x-raw,width={16,32},depth={16,32}");
1178 gst_caps_from_string ("audio/x-raw,width=32,depth={16,32}");
1179 GstPadTemplate *src_template;
1180 GstPadTemplate *sink_template;
1184 src_template = gst_pad_template_new ("src", GST_PAD_SRC,
1185 GST_PAD_ALWAYS, srccaps);
1186 sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
1187 GST_PAD_ALWAYS, sinkcaps);
1188 gst_caps_unref (srccaps);
1189 gst_caps_unref (sinkcaps);
1191 sink = gst_pad_new_from_template (sink_template, "sink");
1192 fail_if (sink == NULL);
1193 gst_pad_set_chain_function (sink, gst_check_chain_func);
1195 src = gst_pad_new_from_template (src_template, "src");
1196 fail_if (src == NULL);
1198 plr = gst_pad_link (src, sink);
1199 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1202 gst_pad_set_active (src, TRUE);
1203 gst_pad_set_active (sink, TRUE);
1205 caps = gst_caps_from_string ("audio/x-raw,width=16,depth=16");
1207 /* Should fail if src pad caps are incompatible with sink pad caps */
1208 gst_pad_set_caps (src, caps);
1209 fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
1212 gst_check_drop_buffers ();
1213 gst_pad_unlink (src, sink);
1214 gst_object_unref (src);
1215 gst_object_unref (sink);
1216 gst_caps_unref (caps);
1217 gst_object_unref (sink_template);
1218 gst_object_unref (src_template);
1223 /* see that an unref also unlinks the pads */
1224 GST_START_TEST (test_src_unref_unlink)
1228 GstPadLinkReturn plr;
1230 sink = gst_pad_new ("sink", GST_PAD_SINK);
1231 fail_if (sink == NULL);
1233 src = gst_pad_new ("src", GST_PAD_SRC);
1234 fail_if (src == NULL);
1236 caps = gst_caps_from_string ("foo/bar");
1238 gst_pad_set_active (src, TRUE);
1239 gst_pad_set_caps (src, caps);
1240 gst_pad_set_active (sink, TRUE);
1241 gst_pad_set_caps (sink, caps);
1243 plr = gst_pad_link (src, sink);
1244 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1246 /* unref the srcpad */
1247 gst_object_unref (src);
1249 /* sink should be unlinked now */
1250 fail_if (gst_pad_is_linked (sink));
1253 gst_object_unref (sink);
1254 gst_caps_unref (caps);
1259 /* see that an unref also unlinks the pads */
1260 GST_START_TEST (test_sink_unref_unlink)
1264 GstPadLinkReturn plr;
1266 sink = gst_pad_new ("sink", GST_PAD_SINK);
1267 fail_if (sink == NULL);
1269 src = gst_pad_new ("src", GST_PAD_SRC);
1270 fail_if (src == NULL);
1272 caps = gst_caps_from_string ("foo/bar");
1274 gst_pad_set_active (src, TRUE);
1275 gst_pad_set_caps (src, caps);
1276 gst_pad_set_active (sink, TRUE);
1277 gst_pad_set_caps (sink, caps);
1279 plr = gst_pad_link (src, sink);
1280 fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1282 /* unref the sinkpad */
1283 gst_object_unref (sink);
1285 /* src should be unlinked now */
1286 fail_if (gst_pad_is_linked (src));
1289 gst_object_unref (src);
1290 gst_caps_unref (caps);
1297 static GstPadProbeReturn
1298 block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1300 gboolean *bool_user_data = (gboolean *) user_data;
1302 fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
1304 /* here we should have blocked == 0 unblocked == 0 */
1305 fail_unless (bool_user_data[0] == FALSE);
1306 fail_unless (bool_user_data[1] == FALSE);
1308 bool_user_data[0] = TRUE;
1310 gst_pad_remove_probe (pad, id);
1311 bool_user_data[1] = TRUE;
1313 return GST_PAD_PROBE_OK;
1316 GST_START_TEST (test_block_async)
1319 /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
1321 gboolean data[2] = { FALSE, FALSE };
1323 pad = gst_pad_new ("src", GST_PAD_SRC);
1324 fail_unless (pad != NULL);
1326 gst_pad_set_active (pad, TRUE);
1328 fail_unless (gst_pad_push_event (pad,
1329 gst_event_new_stream_start ("test")) == TRUE);
1330 fail_unless (gst_pad_push_event (pad,
1331 gst_event_new_segment (&dummy_segment)) == TRUE);
1333 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_cb, &data,
1336 fail_unless (data[0] == FALSE);
1337 fail_unless (data[1] == FALSE);
1338 gst_pad_push (pad, gst_buffer_new ());
1340 gst_object_unref (pad);
1345 static GstPadProbeReturn
1346 block_async_cb_return_ok (GstPad * pad, GstPadProbeInfo * info,
1349 return GST_PAD_PROBE_OK;
1353 push_buffer_async (GstPad * pad)
1355 gpointer ret = GINT_TO_POINTER (gst_pad_push (pad, gst_buffer_new ()));
1356 gst_object_unref (pad);
1361 test_pad_blocking_with_type (GstPadProbeType type)
1367 pad = gst_pad_new ("src", GST_PAD_SRC);
1368 fail_unless (pad != NULL);
1370 gst_pad_set_active (pad, TRUE);
1372 fail_unless (gst_pad_push_event (pad,
1373 gst_event_new_stream_start ("test")) == TRUE);
1374 fail_unless (gst_pad_push_event (pad,
1375 gst_event_new_segment (&dummy_segment)) == TRUE);
1377 id = gst_pad_add_probe (pad, type, block_async_cb_return_ok, NULL, NULL);
1379 thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1380 gst_object_ref (pad), NULL);
1382 /* wait for the block */
1383 while (!gst_pad_is_blocking (pad)) {
1387 /* stop with flushing */
1388 gst_pad_push_event (pad, gst_event_new_flush_start ());
1390 /* get return value from push */
1391 ret = GPOINTER_TO_INT (g_thread_join (thread));
1393 gst_pad_push_event (pad, gst_event_new_flush_stop (FALSE));
1394 /* must be wrong state */
1395 fail_unless (ret == GST_FLOW_FLUSHING);
1397 gst_object_unref (pad);
1400 GST_START_TEST (test_pad_blocking_with_probe_type_block)
1402 test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCK);
1407 GST_START_TEST (test_pad_blocking_with_probe_type_blocking)
1409 test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCKING);
1414 static gboolean idle_probe_running;
1416 static GstFlowReturn
1417 idletest_sink_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1419 if (idle_probe_running)
1420 fail ("Should not be reached");
1421 gst_buffer_unref (buf);
1425 static GstPadProbeReturn
1426 idle_probe_wait (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1428 /* it is ok to have a probe called multiple times but it is not
1429 * acceptable in our scenario */
1430 fail_if (idle_probe_running);
1432 idle_probe_running = TRUE;
1433 while (idle_probe_running) {
1437 return GST_PAD_PROBE_REMOVE;
1441 add_idle_probe_async (GstPad * pad)
1443 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, idle_probe_wait, NULL, NULL);
1444 gst_object_unref (pad);
1449 GST_START_TEST (test_pad_blocking_with_probe_type_idle)
1451 GstPad *srcpad, *sinkpad;
1452 GThread *idle_thread, *thread;
1454 srcpad = gst_pad_new ("src", GST_PAD_SRC);
1455 fail_unless (srcpad != NULL);
1456 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1457 fail_unless (sinkpad != NULL);
1459 gst_pad_set_chain_function (sinkpad, idletest_sink_pad_chain);
1461 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
1463 gst_pad_set_active (sinkpad, TRUE);
1464 gst_pad_set_active (srcpad, TRUE);
1466 fail_unless (gst_pad_push_event (srcpad,
1467 gst_event_new_stream_start ("test")) == TRUE);
1468 fail_unless (gst_pad_push_event (srcpad,
1469 gst_event_new_segment (&dummy_segment)) == TRUE);
1471 idle_probe_running = FALSE;
1473 g_thread_try_new ("gst-check", (GThreadFunc) add_idle_probe_async,
1474 gst_object_ref (srcpad), NULL);
1476 /* wait for the idle function to signal it is being called */
1477 while (!idle_probe_running) {
1481 thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1482 gst_object_ref (srcpad), NULL);
1484 while (!gst_pad_is_blocking (srcpad)) {
1488 idle_probe_running = FALSE;
1490 g_thread_join (idle_thread);
1491 g_thread_join (thread);
1492 gst_object_unref (srcpad);
1493 gst_object_unref (sinkpad);
1498 static gboolean pull_probe_called;
1499 static gboolean pull_probe_called_with_bad_type;
1500 static gboolean pull_probe_called_with_bad_data;
1502 static GstPadProbeReturn
1503 probe_pull_buffer_cb_check_buffer_return_ok (GstPad * pad,
1504 GstPadProbeInfo * info, gpointer user_data)
1506 if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
1507 if (GST_IS_BUFFER (info->data))
1508 pull_probe_called = TRUE;
1510 pull_probe_called_with_bad_data = TRUE;
1512 /* shouldn't be called */
1513 pull_probe_called_with_bad_type = TRUE;
1515 return GST_PAD_PROBE_OK;
1518 static GstFlowReturn
1519 test_probe_pull_getrange (GstPad * pad, GstObject * parent, guint64 offset,
1520 guint length, GstBuffer ** buf)
1522 *buf = gst_buffer_new ();
1527 test_probe_pull_activate_pull (GstPad * pad, GstObject * object)
1529 return gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE);
1533 pull_range_async (GstPad * pad)
1535 GstBuffer *buf = NULL;
1536 GstFlowReturn res = gst_pad_pull_range (pad, 0, 100, &buf);
1538 gst_buffer_unref (buf);
1539 gst_object_unref (pad);
1541 return GINT_TO_POINTER (res);
1544 GST_START_TEST (test_pad_probe_pull)
1546 GstPad *srcpad, *sinkpad;
1550 srcpad = gst_pad_new ("src", GST_PAD_SRC);
1551 fail_unless (srcpad != NULL);
1552 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1553 fail_unless (sinkpad != NULL);
1555 gst_pad_set_getrange_function (srcpad, test_probe_pull_getrange);
1556 gst_pad_set_activate_function (sinkpad, test_probe_pull_activate_pull);
1557 gst_pad_link (srcpad, sinkpad);
1559 gst_pad_set_active (sinkpad, TRUE);
1560 gst_pad_set_active (srcpad, TRUE);
1562 id = gst_pad_add_probe (sinkpad,
1563 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_PULL,
1564 block_async_cb_return_ok, NULL, NULL);
1566 thread = g_thread_try_new ("gst-check", (GThreadFunc) pull_range_async,
1567 gst_object_ref (sinkpad), NULL);
1569 /* wait for the block */
1570 while (!gst_pad_is_blocking (sinkpad)) {
1574 /* stop with flushing */
1575 gst_pad_push_event (srcpad, gst_event_new_flush_start ());
1577 /* get return value from push */
1578 ret = GPOINTER_TO_INT (g_thread_join (thread));
1580 gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE));
1581 /* must be wrong state */
1582 fail_unless (ret == GST_FLOW_FLUSHING);
1584 gst_object_unref (srcpad);
1585 gst_object_unref (sinkpad);
1590 static gboolean idle_probe_called;
1591 static gboolean get_range_wait;
1592 static gboolean getrange_waiting;
1594 static GstPadProbeReturn
1595 idle_cb_return_ok (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1597 idle_probe_called = TRUE;
1598 return GST_PAD_PROBE_OK;
1601 static GstFlowReturn
1602 test_probe_pull_getrange_wait (GstPad * pad, GstObject * parent, guint64 offset,
1603 guint length, GstBuffer ** buf)
1605 getrange_waiting = TRUE;
1607 *buf = gst_buffer_new ();
1608 while (get_range_wait) {
1612 getrange_waiting = FALSE;
1616 GST_START_TEST (test_pad_probe_pull_idle)
1618 GstPad *srcpad, *sinkpad;
1622 srcpad = gst_pad_new ("src", GST_PAD_SRC);
1623 fail_unless (srcpad != NULL);
1624 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1625 fail_unless (sinkpad != NULL);
1627 gst_pad_set_getrange_function (srcpad, test_probe_pull_getrange_wait);
1628 gst_pad_set_activate_function (sinkpad, test_probe_pull_activate_pull);
1629 gst_pad_link (srcpad, sinkpad);
1631 gst_pad_set_active (sinkpad, TRUE);
1632 gst_pad_set_active (srcpad, TRUE);
1634 idle_probe_called = FALSE;
1635 get_range_wait = TRUE;
1636 thread = g_thread_try_new ("gst-check", (GThreadFunc) pull_range_async,
1637 gst_object_ref (sinkpad), NULL);
1639 /* wait for the block */
1640 while (!getrange_waiting) {
1644 id = gst_pad_add_probe (sinkpad,
1645 GST_PAD_PROBE_TYPE_IDLE | GST_PAD_PROBE_TYPE_PULL,
1646 idle_cb_return_ok, NULL, NULL);
1648 fail_if (idle_probe_called);
1650 get_range_wait = FALSE;
1651 while (getrange_waiting) {
1654 while (!idle_probe_called) {
1658 ret = GPOINTER_TO_INT (g_thread_join (thread));
1659 fail_unless (ret == GST_FLOW_OK);
1660 gst_pad_set_active (srcpad, FALSE);
1661 gst_pad_set_active (sinkpad, FALSE);
1662 gst_object_unref (srcpad);
1663 gst_object_unref (sinkpad);
1669 GST_START_TEST (test_pad_probe_pull_buffer)
1671 GstPad *srcpad, *sinkpad;
1675 srcpad = gst_pad_new ("src", GST_PAD_SRC);
1676 fail_unless (srcpad != NULL);
1677 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1678 fail_unless (sinkpad != NULL);
1680 gst_pad_set_getrange_function (srcpad, test_probe_pull_getrange);
1681 gst_pad_set_activate_function (sinkpad, test_probe_pull_activate_pull);
1682 gst_pad_link (srcpad, sinkpad);
1684 gst_pad_set_active (sinkpad, TRUE);
1685 gst_pad_set_active (srcpad, TRUE);
1687 id = gst_pad_add_probe (sinkpad,
1688 GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PULL,
1689 probe_pull_buffer_cb_check_buffer_return_ok, NULL, NULL);
1691 pull_probe_called = FALSE;
1692 pull_probe_called_with_bad_type = FALSE;
1693 pull_probe_called_with_bad_data = FALSE;
1695 thread = g_thread_try_new ("gst-check", (GThreadFunc) pull_range_async,
1696 gst_object_ref (sinkpad), NULL);
1698 /* wait for the block */
1699 while (!pull_probe_called && !pull_probe_called_with_bad_data
1700 && !pull_probe_called_with_bad_type) {
1704 fail_unless (pull_probe_called);
1705 fail_if (pull_probe_called_with_bad_data);
1706 fail_if (pull_probe_called_with_bad_type);
1708 /* get return value from push */
1709 ret = GPOINTER_TO_INT (g_thread_join (thread));
1710 fail_unless (ret == GST_FLOW_OK);
1712 gst_pad_set_active (sinkpad, FALSE);
1713 gst_pad_set_active (srcpad, FALSE);
1714 gst_object_unref (srcpad);
1715 gst_object_unref (sinkpad);
1720 static gboolean pad_probe_remove_notifiy_called = FALSE;
1722 static GstPadProbeReturn
1723 probe_remove_self_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1725 gst_pad_remove_probe (pad, info->id);
1727 return GST_PAD_PROBE_REMOVE;
1731 probe_remove_notify_cb (gpointer data)
1733 fail_unless (pad_probe_remove_notifiy_called == FALSE);
1734 pad_probe_remove_notifiy_called = TRUE;
1737 GST_START_TEST (test_pad_probe_remove)
1741 pad = gst_pad_new ("src", GST_PAD_SRC);
1742 fail_unless (pad != NULL);
1744 gst_pad_set_active (pad, TRUE);
1745 fail_unless (pad->num_probes == 0);
1746 fail_unless (pad->num_blocked == 0);
1747 gst_pad_add_probe (pad,
1748 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
1749 probe_remove_self_cb, NULL, probe_remove_notify_cb);
1750 fail_unless (pad->num_probes == 1);
1751 fail_unless (pad->num_blocked == 1);
1753 pad_probe_remove_notifiy_called = FALSE;
1754 gst_pad_push_event (pad, gst_event_new_stream_start ("asda"));
1756 fail_unless (pad->num_probes == 0);
1757 fail_unless (pad->num_blocked == 0);
1759 gst_object_unref (pad);
1764 GST_START_TEST (test_pad_disjoint_blocks_probe_remove)
1768 /* Test that installing 2 separate blocking probes - one on events
1769 * and one on buffers, and then removing the blocking event probe
1770 * releases the dataflow until a buffer is caught
1772 * https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/658
1774 pad = gst_pad_new ("src", GST_PAD_SRC);
1775 fail_unless (pad != NULL);
1777 gst_pad_set_active (pad, TRUE);
1778 fail_unless (pad->num_probes == 0);
1779 fail_unless (pad->num_blocked == 0);
1780 gst_pad_add_probe (pad,
1781 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
1782 probe_remove_self_cb, NULL, probe_remove_notify_cb);
1783 fail_unless (pad->num_probes == 1);
1784 fail_unless (pad->num_blocked == 1);
1786 gst_pad_add_probe (pad,
1787 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1788 probe_remove_self_cb, NULL, probe_remove_notify_cb);
1789 fail_unless (pad->num_probes == 2);
1790 fail_unless (pad->num_blocked == 2);
1792 pad_probe_remove_notifiy_called = FALSE;
1793 gst_pad_push_event (pad, gst_event_new_stream_start ("asda"));
1795 fail_unless (gst_pad_push_event (pad,
1796 gst_event_new_segment (&dummy_segment)) == TRUE);
1798 pad_probe_remove_notifiy_called = FALSE;
1799 gst_pad_push (pad, gst_buffer_new ());
1801 fail_unless (pad->num_probes == 0);
1802 fail_unless (pad->num_blocked == 0);
1804 gst_object_unref (pad);
1815 } BlockReplaceProbeHelper;
1818 unblock_probe_thread (gpointer user_data)
1820 BlockReplaceProbeHelper *helper = user_data;
1822 GST_INFO_OBJECT (helper->probe_pad, "removing probe to unblock pad");
1823 gst_pad_remove_probe (helper->probe_pad, helper->probe_id);
1827 static GstPadProbeReturn
1828 block_and_replace_buffer_probe_cb (GstPad * pad, GstPadProbeInfo * info,
1831 BlockReplaceProbeHelper *helper = user_data;
1833 GST_INFO_OBJECT (pad, "about to block pad, replacing buffer");
1835 /* we want to block, but also drop this buffer */
1836 gst_buffer_unref (GST_BUFFER (info->data));
1840 g_thread_new ("gst-pad-test-thread", unblock_probe_thread, helper);
1842 return GST_PAD_PROBE_OK;
1845 GST_START_TEST (test_pad_probe_block_and_drop_buffer)
1847 BlockReplaceProbeHelper helper;
1851 src = gst_pad_new ("src", GST_PAD_SRC);
1852 gst_pad_set_active (src, TRUE);
1853 sink = gst_pad_new ("sink", GST_PAD_SINK);
1854 gst_pad_set_chain_function (sink, gst_check_chain_func);
1855 gst_pad_set_active (sink, TRUE);
1857 fail_unless (gst_pad_push_event (src,
1858 gst_event_new_stream_start ("test")) == TRUE);
1859 fail_unless (gst_pad_push_event (src,
1860 gst_event_new_segment (&dummy_segment)) == TRUE);
1862 fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
1864 helper.probe_id = gst_pad_add_probe (src,
1865 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1866 block_and_replace_buffer_probe_cb, &helper, NULL);
1867 helper.probe_pad = src;
1869 /* push a buffer so the events are propagated downstream */
1870 flow = gst_pad_push (src, gst_buffer_new ());
1872 g_thread_join (helper.thread);
1874 fail_unless_equals_int (flow, GST_FLOW_OK);
1876 /* no buffer should have made it through to the sink pad, and especially
1877 * not a NULL pointer buffer */
1878 fail_if (buffers && buffers->data == NULL);
1879 fail_unless (buffers == NULL);
1881 gst_check_drop_buffers ();
1882 gst_object_unref (src);
1883 gst_object_unref (sink);
1888 static GstPadProbeReturn
1889 probe_block_ok (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1891 gboolean *called = user_data;
1894 return GST_PAD_PROBE_OK;
1897 static GstPadProbeReturn
1898 probe_block_remove (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1900 gboolean *called = user_data;
1902 return GST_PAD_PROBE_REMOVE;
1905 GST_START_TEST (test_pad_probe_block_add_remove)
1909 gulong probe_a, probe_b;
1913 pad = gst_pad_new ("src", GST_PAD_SRC);
1914 fail_unless (pad != NULL);
1916 gst_pad_set_active (pad, TRUE);
1917 fail_unless (pad->num_probes == 0);
1918 fail_unless (pad->num_blocked == 0);
1920 fail_unless (gst_pad_push_event (pad,
1921 gst_event_new_stream_start ("test")) == TRUE);
1922 fail_unless (gst_pad_push_event (pad,
1923 gst_event_new_segment (&dummy_segment)) == TRUE);
1925 probe_a = gst_pad_add_probe (pad,
1926 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1927 probe_block_ok, NULL, NULL);
1929 fail_unless (pad->num_probes == 1);
1930 fail_unless (pad->num_blocked == 1);
1932 thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1933 gst_object_ref (pad), NULL);
1935 /* wait for the block */
1936 while (!gst_pad_is_blocking (pad))
1939 /* alternate 2 probes 100 times */
1940 for (r = 0; r < 100; r++) {
1942 probe_b = gst_pad_add_probe (pad,
1943 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1944 probe_block_ok, &called, NULL);
1946 gst_pad_remove_probe (pad, probe_a);
1948 /* wait for the callback */
1953 probe_a = gst_pad_add_probe (pad,
1954 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1955 probe_block_ok, &called, NULL);
1957 gst_pad_remove_probe (pad, probe_b);
1959 /* wait for the callback */
1965 gst_pad_add_probe (pad,
1966 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1967 probe_block_remove, &called, NULL);
1969 gst_pad_remove_probe (pad, probe_a);
1971 /* wait for the callback */
1975 /* wait for the unblock */
1976 while (gst_pad_is_blocking (pad))
1979 gst_object_unref (pad);
1980 g_thread_join (thread);
1985 static gboolean src_flush_start_probe_called = FALSE;
1986 static gboolean src_flush_stop_probe_called = FALSE;
1987 static gboolean sink_flush_start_probe_called = FALSE;
1988 static gboolean sink_flush_stop_probe_called = FALSE;
1990 static GstPadProbeReturn
1991 flush_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1995 if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_FLUSH))
1998 event = gst_pad_probe_info_get_event (info);
1999 switch (GST_EVENT_TYPE (event)) {
2000 case GST_EVENT_FLUSH_START:
2001 if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
2002 src_flush_start_probe_called = TRUE;
2004 sink_flush_start_probe_called = TRUE;
2006 case GST_EVENT_FLUSH_STOP:
2007 if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
2008 src_flush_stop_probe_called = TRUE;
2010 sink_flush_stop_probe_called = TRUE;
2017 return GST_PAD_PROBE_OK;
2020 GST_START_TEST (test_pad_probe_flush_events)
2024 src = gst_pad_new ("src", GST_PAD_SRC);
2025 sink = gst_pad_new ("sink", GST_PAD_SINK);
2026 gst_pad_set_chain_function (sink, gst_check_chain_func);
2027 gst_pad_set_active (src, TRUE);
2028 gst_pad_set_active (sink, TRUE);
2030 fail_unless (gst_pad_push_event (src,
2031 gst_event_new_stream_start ("test")) == TRUE);
2032 fail_unless (gst_pad_push_event (src,
2033 gst_event_new_segment (&dummy_segment)) == TRUE);
2035 fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
2037 gst_pad_add_probe (src,
2038 GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
2039 GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
2040 gst_pad_add_probe (sink,
2041 GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
2042 GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
2044 gst_pad_push_event (src, gst_event_new_flush_start ());
2045 gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
2047 fail_unless (gst_pad_push_event (src,
2048 gst_event_new_segment (&dummy_segment)) == TRUE);
2050 /* push a buffer so the events are propagated downstream */
2051 gst_pad_push (src, gst_buffer_new ());
2053 fail_unless (src_flush_start_probe_called);
2054 fail_unless (src_flush_stop_probe_called);
2055 fail_unless (sink_flush_start_probe_called);
2056 fail_unless (sink_flush_stop_probe_called);
2058 gst_check_drop_buffers ();
2059 gst_object_unref (src);
2060 gst_object_unref (sink);
2065 static gboolean probe_was_called;
2067 static GstPadProbeReturn
2068 flush_events_only_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
2070 GST_LOG_OBJECT (pad, "%" GST_PTR_FORMAT, GST_PAD_PROBE_INFO_DATA (info));
2072 probe_was_called = TRUE;
2074 return GST_PAD_PROBE_OK;
2077 GST_START_TEST (test_pad_probe_flush_events_only)
2081 src = gst_pad_new ("src", GST_PAD_SRC);
2082 sink = gst_pad_new ("sink", GST_PAD_SINK);
2083 gst_pad_set_chain_function (sink, gst_check_chain_func);
2084 gst_pad_set_active (src, TRUE);
2085 gst_pad_set_active (sink, TRUE);
2087 fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
2089 fail_unless (gst_pad_push_event (src,
2090 gst_event_new_stream_start ("test")) == TRUE);
2092 gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_EVENT_FLUSH,
2093 flush_events_only_probe, NULL, NULL);
2095 probe_was_called = FALSE;
2096 fail_unless (gst_pad_push_event (src,
2097 gst_event_new_segment (&dummy_segment)) == TRUE);
2098 fail_if (probe_was_called);
2100 fail_unless_equals_int (gst_pad_push (src, gst_buffer_new ()), GST_FLOW_OK);
2101 fail_if (probe_was_called);
2103 gst_pad_push_event (src, gst_event_new_flush_start ());
2104 fail_unless (probe_was_called);
2106 probe_was_called = FALSE;
2107 gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
2108 fail_unless (probe_was_called);
2110 gst_check_drop_buffers ();
2111 gst_object_unref (src);
2112 gst_object_unref (sink);
2117 #define NUM_PROBES 4
2120 static GstPadProbeReturn
2121 order_others_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2123 *(guint *) (user_data) = ++count;
2125 return GST_PAD_PROBE_REMOVE;
2128 GST_START_TEST (test_pad_probe_call_order)
2132 guint counters[NUM_PROBES];
2135 src = gst_pad_new ("src", GST_PAD_SRC);
2136 gst_pad_set_active (src, TRUE);
2137 sink = gst_pad_new ("sink", GST_PAD_SINK);
2138 gst_pad_set_chain_function (sink, gst_check_chain_func);
2139 gst_pad_set_active (sink, TRUE);
2141 fail_unless (gst_pad_push_event (src,
2142 gst_event_new_stream_start ("test")) == TRUE);
2143 fail_unless (gst_pad_push_event (src,
2144 gst_event_new_segment (&dummy_segment)) == TRUE);
2146 fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
2148 for (i = 0; i < NUM_PROBES; i++) {
2149 gst_pad_add_probe (src,
2150 GST_PAD_PROBE_TYPE_BUFFER, order_others_probe_cb, &(counters[i]), NULL);
2153 /* push a buffer so the events are propagated downstream */
2154 flow = gst_pad_push (src, gst_buffer_new ());
2155 fail_unless_equals_int (flow, GST_FLOW_OK);
2157 for (i = 0; i < NUM_PROBES; i++) {
2158 fail_unless (counters[i] == i + 1);
2161 gst_check_drop_buffers ();
2162 gst_object_unref (src);
2163 gst_object_unref (sink);
2168 static GstPadProbeReturn
2169 buffers_probe_handled (GstPad * pad, GstPadProbeInfo * info, gpointer gp)
2171 if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER) {
2172 GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
2174 GST_DEBUG_OBJECT (pad, "buffer: %" GST_PTR_FORMAT ", refcount: %d",
2175 buffer, (GST_MINI_OBJECT (buffer))->refcount);
2176 gst_buffer_unref (buffer);
2179 return GST_PAD_PROBE_HANDLED;
2182 static GstPadProbeReturn
2183 buffers_probe_drop (GstPad * pad, GstPadProbeInfo * info, gboolean * called)
2185 if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER) {
2186 GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
2188 GST_DEBUG_OBJECT (pad, "buffer: %" GST_PTR_FORMAT ", refcount: %d",
2189 buffer, (GST_MINI_OBJECT (buffer))->refcount);
2193 return GST_PAD_PROBE_DROP;
2196 GST_START_TEST (test_pad_probe_handled_and_drop)
2202 src = gst_pad_new ("src", GST_PAD_SRC);
2203 gst_pad_set_active (src, TRUE);
2204 sink = gst_pad_new ("sink", GST_PAD_SINK);
2205 gst_pad_set_chain_function (sink, gst_check_chain_func);
2206 gst_pad_set_active (sink, TRUE);
2208 fail_unless (gst_pad_push_event (src,
2209 gst_event_new_stream_start ("test")) == TRUE);
2210 fail_unless (gst_pad_push_event (src,
2211 gst_event_new_segment (&dummy_segment)) == TRUE);
2213 fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
2215 gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
2216 (GstPadProbeCallback) buffers_probe_handled, NULL, NULL);
2217 gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
2218 (GstPadProbeCallback) buffers_probe_drop, &called, NULL);
2221 flow = gst_pad_push (src, gst_buffer_new ());
2222 fail_unless_equals_int (flow, GST_FLOW_OK);
2225 /* no buffer should have made it through to the sink pad, and especially
2226 * not a NULL pointer buffer */
2227 fail_if (buffers && buffers->data == NULL);
2228 fail_unless (buffers == NULL);
2230 gst_object_unref (src);
2231 gst_object_unref (sink);
2236 static gboolean got_notify;
2239 caps_notify (GstPad * pad, GParamSpec * spec, gpointer data)
2245 test_queue_src_caps_notify (gboolean link_queue)
2248 GstPad *src, *sink, *another_pad;
2251 queue = gst_element_factory_make ("queue", NULL);
2252 fail_unless (queue != NULL);
2254 src = gst_element_get_static_pad (queue, "src");
2255 fail_unless (src != NULL);
2257 sink = gst_element_get_static_pad (queue, "sink");
2258 fail_unless (sink != NULL);
2261 another_pad = gst_pad_new ("sink", GST_PAD_SINK);
2262 fail_unless (another_pad != NULL);
2263 gst_pad_set_active (another_pad, TRUE);
2265 gst_pad_link_full (src, another_pad, GST_PAD_LINK_CHECK_NOTHING);
2270 gst_element_set_state (queue, GST_STATE_PLAYING);
2274 g_signal_connect (src, "notify::caps", G_CALLBACK (caps_notify), NULL);
2276 caps = gst_caps_from_string ("caps");
2277 gst_pad_send_event (sink, gst_event_new_caps (caps));
2278 gst_caps_unref (caps);
2280 while (got_notify == FALSE)
2283 gst_element_set_state (queue, GST_STATE_NULL);
2285 gst_object_unref (src);
2286 gst_object_unref (sink);
2287 gst_object_unref (queue);
2289 gst_object_unref (another_pad);
2293 GST_START_TEST (test_queue_src_caps_notify_linked)
2295 test_queue_src_caps_notify (TRUE);
2299 GST_START_TEST (test_queue_src_caps_notify_not_linked)
2301 /* This test will fail because queue doesn't set the caps
2302 on src pad unless it is linked */
2303 test_queue_src_caps_notify (FALSE);
2310 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
2312 gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
2316 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
2318 static int n_calls = 0;
2319 gboolean *bool_user_data = (gboolean *) user_data;
2322 /* we expect this callback to be called only once */
2323 g_warn_if_reached ();
2325 *bool_user_data = blocked;
2327 /* replace block_async_first with block_async_second so next time the pad is
2328 * blocked the latter should be called */
2329 gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
2331 /* unblock temporarily, in the next push block_async_second should be called
2333 gst_pad_push_event (pad, gst_event_new_flush_start ());
2336 GST_START_TEST (test_block_async_replace_callback)
2341 pad = gst_pad_new ("src", GST_PAD_SRC);
2342 fail_unless (pad != NULL);
2343 gst_pad_set_active (pad, TRUE);
2345 gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
2348 gst_pad_push (pad, gst_buffer_new ());
2349 fail_unless (blocked == TRUE);
2350 /* block_async_first flushes to unblock */
2351 gst_pad_push_event (pad, gst_event_new_flush_stop ());
2353 /* push again, this time block_async_second should be called */
2354 gst_pad_push (pad, gst_buffer_new ());
2355 fail_unless (blocked == TRUE);
2357 gst_object_unref (pad);
2364 block_async_full_destroy (gpointer user_data)
2366 gint *state = (gint *) user_data;
2368 fail_unless (*state < 2);
2370 GST_DEBUG ("setting state to 2");
2374 static GstPadProbeReturn
2375 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2377 *(gint *) user_data = (gint) TRUE;
2379 gst_pad_push_event (pad, gst_event_new_flush_start ());
2380 GST_DEBUG ("setting state to 1");
2382 return GST_PAD_PROBE_OK;
2385 GST_START_TEST (test_block_async_full_destroy)
2388 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
2392 pad = gst_pad_new ("src", GST_PAD_SRC);
2393 fail_unless (pad != NULL);
2394 gst_pad_set_active (pad, TRUE);
2396 fail_unless (gst_pad_push_event (pad,
2397 gst_event_new_stream_start ("test")) == TRUE);
2398 fail_unless (gst_pad_push_event (pad,
2399 gst_event_new_segment (&dummy_segment)) == TRUE);
2401 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
2402 &state, block_async_full_destroy);
2403 fail_unless (state == 0);
2405 gst_pad_push (pad, gst_buffer_new ());
2406 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
2408 fail_unless (state == 1);
2409 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
2411 /* unblock callback is called */
2412 gst_pad_remove_probe (pad, id);
2413 fail_unless (state == 2);
2415 gst_object_unref (pad);
2420 GST_START_TEST (test_block_async_full_destroy_dispose)
2423 /* 0 = unblocked, 1 = blocked, 2 = destroyed */
2426 pad = gst_pad_new ("src", GST_PAD_SRC);
2427 fail_unless (pad != NULL);
2428 gst_pad_set_active (pad, TRUE);
2430 fail_unless (gst_pad_push_event (pad,
2431 gst_event_new_stream_start ("test")) == TRUE);
2432 fail_unless (gst_pad_push_event (pad,
2433 gst_event_new_segment (&dummy_segment)) == TRUE);
2435 (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
2436 &state, block_async_full_destroy);
2438 gst_pad_push (pad, gst_buffer_new ());
2439 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
2441 fail_unless_equals_int (state, 1);
2442 gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
2444 /* gst_BLOCK calls the destroy_notify function if necessary */
2445 gst_object_unref (pad);
2447 fail_unless_equals_int (state, 2);
2455 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
2457 gboolean *bool_user_data = (gboolean *) user_data;
2459 /* here we should have blocked == 1 unblocked == 0 */
2461 fail_unless (blocked == FALSE);
2463 fail_unless (bool_user_data[0] == TRUE);
2464 fail_unless (bool_user_data[1] == TRUE);
2465 fail_unless (bool_user_data[2] == FALSE);
2467 bool_user_data[2] = TRUE;
2474 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
2476 g_warn_if_reached ();
2480 static GstPadProbeReturn
2481 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
2484 gboolean *bool_user_data = (gboolean *) user_data;
2486 GST_DEBUG ("second probe called");
2488 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
2490 fail_unless (bool_user_data[0] == TRUE);
2491 fail_unless (bool_user_data[1] == FALSE);
2492 fail_unless (bool_user_data[2] == FALSE);
2494 bool_user_data[1] = TRUE;
2496 GST_DEBUG ("removing second probe with id %lu", id);
2497 gst_pad_remove_probe (pad, id);
2499 return GST_PAD_PROBE_OK;
2502 static GstPadProbeReturn
2503 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
2506 static int n_calls = 0;
2507 gboolean *bool_user_data = (gboolean *) user_data;
2509 fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
2511 GST_DEBUG ("first probe called");
2514 /* we expect this callback to be called only once */
2515 g_warn_if_reached ();
2517 *bool_user_data = TRUE;
2519 fail_unless (bool_user_data[0] == TRUE);
2520 fail_unless (bool_user_data[1] == FALSE);
2521 fail_unless (bool_user_data[2] == FALSE);
2523 GST_DEBUG ("removing first probe with id %lu", id);
2524 gst_pad_remove_probe (pad, id);
2526 GST_DEBUG ("adding second probe");
2527 /* replace block_async_first with block_async_second so next time the pad is
2528 * blocked the latter should be called */
2529 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
2530 block_async_second_no_flush, user_data, NULL);
2531 GST_DEBUG ("added probe with id %lu", id);
2533 return GST_PAD_PROBE_OK;
2536 GST_START_TEST (test_block_async_replace_callback_no_flush)
2539 gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
2541 pad = gst_pad_new ("src", GST_PAD_SRC);
2542 fail_unless (pad != NULL);
2543 gst_pad_set_active (pad, TRUE);
2545 fail_unless (gst_pad_push_event (pad,
2546 gst_event_new_stream_start ("test")) == TRUE);
2547 fail_unless (gst_pad_push_event (pad,
2548 gst_event_new_segment (&dummy_segment)) == TRUE);
2550 GST_DEBUG ("adding probe");
2551 id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
2552 block_async_first_no_flush, bool_user_data, NULL);
2553 GST_DEBUG ("added probe with id %lu", id);
2556 GST_DEBUG ("pushing buffer");
2557 gst_pad_push (pad, gst_buffer_new ());
2558 fail_unless (bool_user_data[0] == TRUE);
2559 fail_unless (bool_user_data[1] == TRUE);
2560 fail_unless (bool_user_data[2] == FALSE);
2562 gst_object_unref (pad);
2567 static gint sticky_count;
2570 test_sticky_events_handler (GstPad * pad, GstObject * parent, GstEvent * event)
2572 GST_DEBUG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
2574 switch (sticky_count) {
2576 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
2583 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
2585 gst_event_parse_caps (event, &caps);
2586 fail_unless (gst_caps_get_size (caps) == 1);
2587 s = gst_caps_get_structure (caps, 0);
2588 fail_unless (gst_structure_has_name (s, "foo/baz"));
2592 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
2595 fail_unless (FALSE);
2599 gst_event_unref (event);
2605 static GstFlowReturn
2606 test_sticky_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2608 gst_buffer_unref (buffer);
2612 GST_START_TEST (test_sticky_events)
2614 GstPad *srcpad, *sinkpad;
2619 /* make unlinked srcpad */
2620 srcpad = gst_pad_new ("src", GST_PAD_SRC);
2621 fail_unless (srcpad != NULL);
2622 gst_pad_set_active (srcpad, TRUE);
2624 /* test stream-start */
2625 fail_unless (gst_pad_get_stream_id (srcpad) == NULL);
2627 /* push an event, it should be sticky on the srcpad */
2628 fail_unless (gst_pad_push_event (srcpad,
2629 gst_event_new_stream_start ("test")) == TRUE);
2631 /* let's see if it stuck */
2632 id = gst_pad_get_stream_id (srcpad);
2633 fail_unless_equals_string (id, "test");
2636 /* make a caps event */
2637 caps = gst_caps_new_empty_simple ("foo/bar");
2638 gst_pad_push_event (srcpad, gst_event_new_caps (caps));
2639 gst_caps_unref (caps);
2641 /* make segment event */
2642 gst_segment_init (&seg, GST_FORMAT_TIME);
2643 gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
2645 /* now make a sinkpad */
2646 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2647 fail_unless (sinkpad != NULL);
2649 gst_pad_set_event_function (sinkpad, test_sticky_events_handler);
2650 gst_pad_set_chain_function (sinkpad, test_sticky_chain);
2651 fail_unless (sticky_count == 0);
2652 gst_pad_set_active (sinkpad, TRUE);
2655 gst_pad_link (srcpad, sinkpad);
2656 /* should not trigger events */
2657 fail_unless (sticky_count == 0);
2659 /* caps replaces old caps event at position 2, the pushes all
2661 caps = gst_caps_new_empty_simple ("foo/baz");
2662 gst_pad_push_event (srcpad, gst_event_new_caps (caps));
2663 gst_caps_unref (caps);
2665 /* should have triggered 2 events, the segment event is still pending */
2666 fail_unless_equals_int (sticky_count, 2);
2668 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2670 /* should have triggered 3 events */
2671 fail_unless_equals_int (sticky_count, 3);
2673 gst_object_unref (srcpad);
2674 gst_object_unref (sinkpad);
2679 static GstFlowReturn next_return;
2681 static GstFlowReturn
2682 test_lastflow_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2684 gst_buffer_unref (buffer);
2688 GST_START_TEST (test_last_flow_return_push)
2690 GstPad *srcpad, *sinkpad;
2693 srcpad = gst_pad_new ("src", GST_PAD_SRC);
2694 fail_unless (srcpad != NULL);
2695 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2696 fail_unless (sinkpad != NULL);
2697 gst_pad_set_chain_function (sinkpad, test_lastflow_chain);
2698 gst_pad_link (srcpad, sinkpad);
2700 /* initial value is flushing */
2701 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
2702 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
2704 /* when active it goes to ok */
2705 gst_pad_set_active (srcpad, TRUE);
2706 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2707 gst_pad_set_active (sinkpad, TRUE);
2708 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2710 /* startup events */
2711 gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
2712 gst_segment_init (&seg, GST_FORMAT_TIME);
2713 gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
2717 next_return = GST_FLOW_OK;
2718 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2719 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2720 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2722 /* push not-linked */
2723 next_return = GST_FLOW_NOT_LINKED;
2724 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
2725 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
2726 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2728 /* push not-linked */
2729 next_return = GST_FLOW_NOT_NEGOTIATED;
2730 fail_unless (gst_pad_push (srcpad,
2731 gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
2732 fail_unless (gst_pad_get_last_flow_return (srcpad) ==
2733 GST_FLOW_NOT_NEGOTIATED);
2734 fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
2735 GST_FLOW_NOT_NEGOTIATED);
2738 next_return = GST_FLOW_ERROR;
2739 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_ERROR);
2740 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
2741 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
2744 next_return = GST_FLOW_OK;
2745 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2746 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2747 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2750 gst_pad_unlink (srcpad, sinkpad);
2751 fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
2752 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
2753 /* The last flow ret from the peer pad shouldn't have changed */
2754 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2756 gst_pad_link (srcpad, sinkpad);
2757 fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
2758 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
2759 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
2761 gst_object_unref (srcpad);
2762 gst_object_unref (sinkpad);
2767 static GstFlowReturn
2768 test_lastflow_getrange (GstPad * pad, GstObject * parent, guint64 offset,
2769 guint length, GstBuffer ** buf)
2771 if (next_return == GST_FLOW_OK)
2772 *buf = gst_buffer_new ();
2779 test_lastflow_activate_pull_func (GstPad * pad, GstObject * object)
2781 return gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE);
2784 GST_START_TEST (test_last_flow_return_pull)
2786 GstPad *srcpad, *sinkpad;
2787 GstBuffer *buf = NULL;
2789 srcpad = gst_pad_new ("src", GST_PAD_SRC);
2790 fail_unless (srcpad != NULL);
2791 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2792 fail_unless (sinkpad != NULL);
2793 gst_pad_set_getrange_function (srcpad, test_lastflow_getrange);
2794 gst_pad_set_activate_function (sinkpad, test_lastflow_activate_pull_func);
2795 gst_pad_link (srcpad, sinkpad);
2797 /* initial value is flushing */
2798 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
2799 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
2801 /* when active it goes to ok */
2802 gst_pad_set_active (sinkpad, TRUE);
2803 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2804 gst_pad_set_active (srcpad, TRUE);
2805 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2808 next_return = GST_FLOW_OK;
2809 fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2810 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2811 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2812 gst_buffer_unref (buf);
2815 /* pull not-linked */
2816 next_return = GST_FLOW_NOT_LINKED;
2817 fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2818 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2819 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
2822 next_return = GST_FLOW_ERROR;
2823 fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_ERROR);
2824 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
2825 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
2828 next_return = GST_FLOW_NOT_NEGOTIATED;
2829 fail_unless (gst_pad_pull_range (sinkpad, 0, 1,
2830 &buf) == GST_FLOW_NOT_NEGOTIATED);
2831 fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
2832 GST_FLOW_NOT_NEGOTIATED);
2833 fail_unless (gst_pad_get_last_flow_return (srcpad) ==
2834 GST_FLOW_NOT_NEGOTIATED);
2837 next_return = GST_FLOW_OK;
2838 fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2839 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2840 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2841 gst_buffer_unref (buf);
2845 gst_pad_unlink (srcpad, sinkpad);
2846 fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2847 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2848 /* Return value for the remote pad didn't change */
2849 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2852 gst_pad_link (srcpad, sinkpad);
2853 next_return = GST_FLOW_EOS;
2854 fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_EOS);
2855 fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
2856 fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
2858 gst_object_unref (srcpad);
2859 gst_object_unref (sinkpad);
2864 GST_START_TEST (test_flush_stop_inactive)
2866 GstPad *sinkpad, *srcpad;
2868 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2869 fail_unless (sinkpad != NULL);
2871 /* new pads are inactive and flushing */
2872 fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2873 fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2875 /* this should fail, pad is inactive */
2876 fail_if (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2878 /* nothing should have changed */
2879 fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2880 fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2882 gst_pad_set_active (sinkpad, TRUE);
2884 /* pad is now active an not flushing anymore */
2885 fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2886 fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2888 /* do flush, does not deactivate the pad */
2889 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_start ()));
2890 fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2891 fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2893 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2894 fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2895 fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2897 gst_pad_set_active (sinkpad, FALSE);
2898 fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2899 fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2901 gst_object_unref (sinkpad);
2903 /* we should not be able to push on an inactive srcpad */
2904 srcpad = gst_pad_new ("src", GST_PAD_SRC);
2905 fail_unless (srcpad != NULL);
2907 fail_if (GST_PAD_IS_ACTIVE (srcpad));
2908 fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2910 fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2912 /* should still be inactive and flushing */
2913 fail_if (GST_PAD_IS_ACTIVE (srcpad));
2914 fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2916 gst_pad_set_active (srcpad, TRUE);
2918 /* pad is now active an not flushing anymore */
2919 fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2920 fail_if (GST_PAD_IS_FLUSHING (srcpad));
2922 /* do flush, does not deactivate the pad */
2923 fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_start ()));
2924 fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2925 fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2927 fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2928 fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2929 fail_if (GST_PAD_IS_FLUSHING (srcpad));
2931 gst_pad_set_active (srcpad, FALSE);
2932 fail_if (GST_PAD_IS_ACTIVE (srcpad));
2933 fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2935 gst_object_unref (srcpad);
2940 /* For proxy caps flag tests */
2942 typedef struct _GstProxyTestElement GstProxyTestElement;
2943 typedef struct _GstProxyTestElementClass GstProxyTestElementClass;
2945 struct _GstProxyTestElement
2950 struct _GstProxyTestElementClass
2952 GstElementClass parent_class;
2955 G_GNUC_INTERNAL GType gst_proxytestelement_get_type (void);
2957 static GstStaticPadTemplate proxytestelement_peer_template =
2958 GST_STATIC_PAD_TEMPLATE ("sink",
2961 GST_STATIC_CAPS ("test/proxy, option=(int)1"));
2963 static GstStaticPadTemplate proxytestelement_peer_incompatible_template =
2964 GST_STATIC_PAD_TEMPLATE ("sink",
2967 GST_STATIC_CAPS ("test/proxy-incompatible"));
2969 static GstStaticPadTemplate proxytestelement_sink_template =
2970 GST_STATIC_PAD_TEMPLATE ("sink",
2973 GST_STATIC_CAPS ("test/proxy"));
2975 static GstStaticPadTemplate proxytestelement_src_template =
2976 GST_STATIC_PAD_TEMPLATE ("src",
2979 GST_STATIC_CAPS_ANY);
2981 G_DEFINE_TYPE (GstProxyTestElement, gst_proxytestelement, GST_TYPE_ELEMENT);
2984 gst_proxytestelement_class_init (GstProxyTestElementClass * klass)
2986 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
2988 gst_element_class_set_static_metadata (gstelement_class,
2989 "Proxy Test Element", "Test", "Proxy test element",
2990 "Thiago Santos <thiagoss@osg.samsung.com>");
2992 gst_element_class_add_static_pad_template (gstelement_class,
2993 &proxytestelement_sink_template);
2997 gst_proxytestelement_init (GstProxyTestElement * element)
3001 gst_pad_new_from_static_template (&proxytestelement_sink_template,
3003 GST_PAD_SET_PROXY_CAPS (sinkpad);
3004 gst_element_add_pad (GST_ELEMENT_CAST (element), sinkpad);
3007 GST_START_TEST (test_proxy_accept_caps_no_proxy)
3009 GstElement *element;
3013 gst_element_register (NULL, "proxytestelement", GST_RANK_NONE,
3014 gst_proxytestelement_get_type ());
3015 element = gst_element_factory_make ("proxytestelement", NULL);
3016 sinkpad = gst_element_get_static_pad (element, "sink");
3018 gst_element_set_state (element, GST_STATE_PLAYING);
3020 caps = gst_caps_from_string ("test/proxy");
3021 fail_unless (gst_pad_query_accept_caps (sinkpad, caps));
3022 gst_caps_unref (caps);
3024 caps = gst_caps_from_string ("test/bad");
3025 fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3026 gst_caps_unref (caps);
3028 gst_object_unref (sinkpad);
3029 gst_element_set_state (element, GST_STATE_NULL);
3030 gst_object_unref (element);
3036 GST_START_TEST (test_proxy_accept_caps_with_proxy)
3038 GstElement *element;
3039 GstPad *sinkpad, *srcpad;
3043 gst_element_register (NULL, "proxytestelement", GST_RANK_NONE,
3044 gst_proxytestelement_get_type ());
3045 element = gst_element_factory_make ("proxytestelement", NULL);
3048 gst_pad_new_from_static_template (&proxytestelement_src_template, "src");
3049 gst_element_add_pad (GST_ELEMENT_CAST (element), srcpad);
3051 sinkpad = gst_element_get_static_pad (element, "sink");
3052 srcpad = gst_element_get_static_pad (element, "src");
3055 gst_pad_new_from_static_template (&proxytestelement_peer_template,
3057 fail_unless (gst_pad_link (srcpad, peerpad) == GST_PAD_LINK_OK);
3058 gst_pad_set_active (peerpad, TRUE);
3060 gst_element_set_state (element, GST_STATE_PLAYING);
3062 caps = gst_caps_from_string ("test/bad");
3063 fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3064 gst_caps_unref (caps);
3066 caps = gst_caps_from_string ("test/proxy, option=(int)1");
3067 fail_unless (gst_pad_query_accept_caps (sinkpad, caps));
3068 gst_caps_unref (caps);
3070 caps = gst_caps_from_string ("test/proxy, option=(int)2");
3071 fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3072 gst_caps_unref (caps);
3074 gst_object_unref (sinkpad);
3075 gst_object_unref (srcpad);
3076 gst_pad_set_active (peerpad, FALSE);
3077 gst_object_unref (peerpad);
3078 gst_element_set_state (element, GST_STATE_NULL);
3079 gst_object_unref (element);
3084 GST_START_TEST (test_proxy_accept_caps_with_incompatible_proxy)
3086 GstElement *element;
3087 GstPad *sinkpad, *srcpad;
3091 gst_element_register (NULL, "proxytestelement", GST_RANK_NONE,
3092 gst_proxytestelement_get_type ());
3093 element = gst_element_factory_make ("proxytestelement", NULL);
3096 gst_pad_new_from_static_template (&proxytestelement_src_template, "src");
3097 gst_element_add_pad (GST_ELEMENT_CAST (element), srcpad);
3099 sinkpad = gst_element_get_static_pad (element, "sink");
3100 srcpad = gst_element_get_static_pad (element, "src");
3103 gst_pad_new_from_static_template
3104 (&proxytestelement_peer_incompatible_template, "sink");
3105 fail_unless (gst_pad_link (srcpad, peerpad) == GST_PAD_LINK_OK);
3107 gst_element_set_state (element, GST_STATE_PLAYING);
3109 caps = gst_caps_from_string ("test/bad");
3110 fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3111 gst_caps_unref (caps);
3113 caps = gst_caps_from_string ("test/proxy");
3114 fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3115 gst_caps_unref (caps);
3117 caps = gst_caps_from_string ("test/proxy-incompatible");
3118 fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3119 gst_caps_unref (caps);
3121 gst_object_unref (sinkpad);
3122 gst_object_unref (srcpad);
3123 gst_pad_set_active (peerpad, FALSE);
3124 gst_object_unref (peerpad);
3125 gst_element_set_state (element, GST_STATE_NULL);
3126 gst_object_unref (element);
3131 static GstSegment sink_segment;
3132 static gint sink_segment_counter;
3135 segment_event_func (GstPad * pad, GstObject * parent, GstEvent * event)
3137 switch (GST_EVENT_TYPE (event)) {
3138 case GST_EVENT_SEGMENT:
3139 gst_event_copy_segment (event, &sink_segment);
3140 sink_segment_counter++;
3146 gst_event_unref (event);
3151 test_pad_offset (gboolean on_srcpad)
3153 GstPad *srcpad, *sinkpad, *offset_pad;
3158 srcpad = gst_pad_new ("src", GST_PAD_SRC);
3159 fail_unless (srcpad != NULL);
3160 sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
3162 offset_pad = on_srcpad ? srcpad : sinkpad;
3164 gst_segment_init (&sink_segment, GST_FORMAT_UNDEFINED);
3165 sink_segment_counter = 0;
3166 gst_pad_set_chain_function (sinkpad, gst_check_chain_func);
3167 gst_pad_set_event_function (sinkpad, segment_event_func);
3169 fail_unless (sinkpad != NULL);
3170 fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK);
3171 fail_unless (gst_pad_set_active (sinkpad, TRUE));
3172 fail_unless (gst_pad_set_active (srcpad, TRUE));
3174 /* Set an offset of 5s, meaning:
3175 * segment position 0 gives running time 5s, stream time 0s
3176 * segment start of 0 should stay 0
3178 gst_pad_set_offset (offset_pad, 5 * GST_SECOND);
3180 fail_unless (gst_pad_push_event (srcpad,
3181 gst_event_new_stream_start ("test")) == TRUE);
3182 /* We should have no segment event yet */
3183 fail_if (sink_segment.format != GST_FORMAT_UNDEFINED);
3184 fail_unless_equals_int (sink_segment_counter, 0);
3186 /* Send segment event, expect it to arrive with a modified start running time */
3187 gst_segment_init (&segment, GST_FORMAT_TIME);
3188 fail_unless (gst_pad_push_event (srcpad,
3189 gst_event_new_segment (&segment)) == TRUE);
3190 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3191 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3192 GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3193 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3194 GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3195 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3197 fail_unless_equals_int (sink_segment_counter, 1);
3199 /* Send a buffer and check if all timestamps are as expected, and especially
3200 * if the buffer timestamp was not changed */
3201 buffer = gst_buffer_new ();
3202 GST_BUFFER_PTS (buffer) = 0 * GST_SECOND;
3203 fail_unless_equals_int (gst_pad_push (srcpad, buffer), GST_FLOW_OK);
3205 fail_unless_equals_int (g_list_length (buffers), 1);
3206 buffer = buffers->data;
3207 buffers = g_list_delete_link (buffers, buffers);
3208 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3209 GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 5 * GST_SECOND);
3210 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3211 GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 0 * GST_SECOND);
3212 fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0 * GST_SECOND);
3213 gst_buffer_unref (buffer);
3215 fail_unless_equals_int (sink_segment_counter, 1);
3217 /* Set a negative offset of -5s, meaning:
3218 * segment position 5s gives running time 0s, stream time 5s
3219 * segment start would have a negative running time!
3221 gst_pad_set_offset (offset_pad, -5 * GST_SECOND);
3223 /* Segment should still be the same as before */
3224 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3225 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3226 GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3227 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3228 GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3229 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3231 fail_unless_equals_int (sink_segment_counter, 1);
3233 /* Send segment event, expect it to arrive with a modified start running time */
3234 gst_segment_init (&segment, GST_FORMAT_TIME);
3235 fail_unless (gst_pad_push_event (srcpad,
3236 gst_event_new_segment (&segment)) == TRUE);
3237 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3238 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3239 GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3241 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3242 GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3244 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3246 fail_unless_equals_int (sink_segment_counter, 2);
3248 /* Send a buffer and check if all timestamps are as expected, and especially
3249 * if the buffer timestamp was not changed */
3250 buffer = gst_buffer_new ();
3251 GST_BUFFER_PTS (buffer) = 5 * GST_SECOND;
3252 fail_unless_equals_int (gst_pad_push (srcpad, buffer), GST_FLOW_OK);
3254 fail_unless_equals_int (g_list_length (buffers), 1);
3255 buffer = buffers->data;
3256 buffers = g_list_delete_link (buffers, buffers);
3257 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3258 GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 0 * GST_SECOND);
3259 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3260 GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 5 * GST_SECOND);
3261 fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 5 * GST_SECOND);
3262 gst_buffer_unref (buffer);
3264 fail_unless_equals_int (sink_segment_counter, 2);
3266 /* Set offset to 5s again, same situation as above but don't send a new
3267 * segment event. The segment should be adjusted *before* the buffer comes
3268 * out of the srcpad */
3269 gst_pad_set_offset (offset_pad, 5 * GST_SECOND);
3271 /* Segment should still be the same as before */
3272 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3273 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3274 GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3276 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3277 GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3279 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3281 fail_unless_equals_int (sink_segment_counter, 2);
3283 /* Send a buffer and check if a new segment event was sent and all buffer
3284 * timestamps are as expected */
3285 buffer = gst_buffer_new ();
3286 GST_BUFFER_PTS (buffer) = 0 * GST_SECOND;
3287 fail_unless_equals_int (gst_pad_push (srcpad, buffer), GST_FLOW_OK);
3289 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3290 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3291 GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3292 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3293 GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3294 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3296 fail_unless_equals_int (sink_segment_counter, 3);
3298 fail_unless_equals_int (g_list_length (buffers), 1);
3299 buffer = buffers->data;
3300 buffers = g_list_delete_link (buffers, buffers);
3301 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3302 GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 5 * GST_SECOND);
3303 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3304 GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 0 * GST_SECOND);
3305 fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0 * GST_SECOND);
3306 gst_buffer_unref (buffer);
3308 fail_unless_equals_int (sink_segment_counter, 3);
3310 /* Set offset to 10s and send another sticky event. In between a new
3311 * segment event should've been sent */
3312 gst_pad_set_offset (offset_pad, 10 * GST_SECOND);
3314 /* Segment should still be the same as before */
3315 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3316 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3317 GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3318 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3319 GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3320 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3321 fail_unless_equals_int (sink_segment_counter, 3);
3323 fail_unless (gst_pad_push_event (srcpad,
3324 gst_event_new_tag (gst_tag_list_new_empty ())) == TRUE);
3326 /* Segment should be updated */
3327 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3328 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3329 GST_FORMAT_TIME, sink_segment.start), 10 * GST_SECOND);
3330 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3331 GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3332 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3334 fail_unless_equals_int (sink_segment_counter, 4);
3336 /* Set offset to 15s and do a serialized query. In between a new
3337 * segment event should've been sent */
3338 gst_pad_set_offset (offset_pad, 15 * GST_SECOND);
3340 /* Segment should still be the same as before */
3341 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3342 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3343 GST_FORMAT_TIME, sink_segment.start), 10 * GST_SECOND);
3344 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3345 GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3346 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3347 fail_unless_equals_int (sink_segment_counter, 4);
3349 query = gst_query_new_drain ();
3350 gst_pad_peer_query (srcpad, query);
3351 gst_query_unref (query);
3353 /* Segment should be updated */
3354 fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3355 fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3356 GST_FORMAT_TIME, sink_segment.start), 15 * GST_SECOND);
3357 fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3358 GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3359 fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3361 fail_unless_equals_int (sink_segment_counter, 5);
3363 gst_check_drop_buffers ();
3365 fail_unless (gst_pad_set_active (sinkpad, FALSE));
3366 fail_unless (gst_pad_set_active (srcpad, FALSE));
3367 gst_object_unref (sinkpad);
3368 gst_object_unref (srcpad);
3371 GST_START_TEST (test_pad_offset_src)
3373 test_pad_offset (TRUE);
3379 gst_pad_suite (void)
3381 Suite *s = suite_create ("GstPad");
3382 TCase *tc_chain = tcase_create ("general");
3384 /* turn off timeout */
3385 tcase_set_timeout (tc_chain, 60);
3387 gst_segment_init (&dummy_segment, GST_FORMAT_BYTES);
3389 suite_add_tcase (s, tc_chain);
3390 tcase_add_test (tc_chain, test_link);
3391 tcase_add_test (tc_chain, test_refcount);
3392 tcase_add_test (tc_chain, test_get_allowed_caps);
3393 tcase_add_test (tc_chain, test_sticky_caps_unlinked);
3394 tcase_add_test (tc_chain, test_sticky_caps_unlinked_incompatible);
3395 tcase_add_test (tc_chain, test_sticky_caps_flushing);
3396 tcase_add_test (tc_chain, test_default_accept_caps);
3397 tcase_add_test (tc_chain, test_link_unlink_threaded);
3398 tcase_add_test (tc_chain, test_name_is_valid);
3399 tcase_add_test (tc_chain, test_push_unlinked);
3400 tcase_add_test (tc_chain, test_push_linked);
3401 tcase_add_test (tc_chain, test_push_linked_flushing);
3402 tcase_add_test (tc_chain, test_push_buffer_list_compat);
3403 tcase_add_test (tc_chain, test_flowreturn);
3404 tcase_add_test (tc_chain, test_push_negotiation);
3405 tcase_add_test (tc_chain, test_src_unref_unlink);
3406 tcase_add_test (tc_chain, test_sink_unref_unlink);
3407 tcase_add_test (tc_chain, test_block_async);
3408 tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_block);
3409 tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_blocking);
3410 tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_idle);
3411 tcase_add_test (tc_chain, test_pad_probe_pull);
3412 tcase_add_test (tc_chain, test_pad_probe_pull_idle);
3413 tcase_add_test (tc_chain, test_pad_probe_pull_buffer);
3414 tcase_add_test (tc_chain, test_pad_probe_remove);
3415 tcase_add_test (tc_chain, test_pad_disjoint_blocks_probe_remove);
3416 tcase_add_test (tc_chain, test_pad_probe_block_add_remove);
3417 tcase_add_test (tc_chain, test_pad_probe_block_and_drop_buffer);
3418 tcase_add_test (tc_chain, test_pad_probe_flush_events);
3419 tcase_add_test (tc_chain, test_pad_probe_flush_events_only);
3420 tcase_add_test (tc_chain, test_pad_probe_call_order);
3421 tcase_add_test (tc_chain, test_pad_probe_handled_and_drop);
3422 tcase_add_test (tc_chain, test_events_query_unlinked);
3423 tcase_add_test (tc_chain, test_queue_src_caps_notify_linked);
3424 tcase_add_test (tc_chain, test_queue_src_caps_notify_not_linked);
3426 tcase_add_test (tc_chain, test_block_async_replace_callback);
3428 tcase_add_test (tc_chain, test_block_async_full_destroy);
3429 tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
3430 tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
3431 tcase_add_test (tc_chain, test_sticky_events);
3432 tcase_add_test (tc_chain, test_last_flow_return_push);
3433 tcase_add_test (tc_chain, test_last_flow_return_pull);
3434 tcase_add_test (tc_chain, test_flush_stop_inactive);
3435 tcase_add_test (tc_chain, test_proxy_accept_caps_no_proxy);
3436 tcase_add_test (tc_chain, test_proxy_accept_caps_with_proxy);
3437 tcase_add_test (tc_chain, test_proxy_accept_caps_with_incompatible_proxy);
3438 tcase_add_test (tc_chain, test_pad_offset_src);
3443 GST_CHECK_MAIN (gst_pad);