5ac6c4e77cdb1b342e3f2f92bbea67375a97e18f
[platform/upstream/gstreamer.git] / tests / check / gst / gstpad.c
1 /* GStreamer
2  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
3  *
4  * gstpad.c: Unit test for GstPad
5  *
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.
10  *
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.
15  *
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.
20  */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gst/check/gstcheck.h>
26
27 static GstSegment dummy_segment;
28
29 GST_START_TEST (test_link)
30 {
31   GstPad *src, *sink;
32   GstPadTemplate *srct;
33
34   GstPadLinkReturn ret;
35   gchar *name;
36
37   src = gst_pad_new ("source", GST_PAD_SRC);
38   fail_if (src == NULL);
39   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
40
41   name = gst_pad_get_name (src);
42   fail_unless (strcmp (name, "source") == 0);
43   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
44   g_free (name);
45
46   sink = gst_pad_new ("sink", GST_PAD_SINK);
47   fail_if (sink == NULL);
48
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);
54
55   ASSERT_CRITICAL (gst_pad_get_pad_template (NULL));
56
57   srct = gst_pad_get_pad_template (src);
58   fail_unless (srct == NULL);
59   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
60
61   /* clean up */
62   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
63   gst_object_unref (src);
64   gst_object_unref (sink);
65 }
66
67 GST_END_TEST;
68
69 /* threaded link/unlink */
70 /* use globals */
71 static GstPad *src, *sink;
72
73 static void
74 thread_link_unlink (gpointer data)
75 {
76   THREAD_START ();
77
78   while (THREAD_TEST_RUNNING ()) {
79     gst_pad_link (src, sink);
80     gst_pad_unlink (src, sink);
81     THREAD_SWITCH ();
82   }
83 }
84
85 GST_START_TEST (test_link_unlink_threaded)
86 {
87   GstCaps *caps;
88   int i;
89
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);
94
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);
101
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);
106     THREAD_SWITCH ();
107   }
108   MAIN_STOP_THREADS ();
109
110   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
111   gst_caps_unref (caps);
112
113   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
114   gst_object_unref (src);
115   gst_object_unref (sink);
116 }
117
118 GST_END_TEST;
119
120 GST_START_TEST (test_refcount)
121 {
122   GstPad *src, *sink;
123   GstCaps *caps;
124   GstPadLinkReturn plr;
125
126   sink = gst_pad_new ("sink", GST_PAD_SINK);
127   fail_if (sink == NULL);
128
129   src = gst_pad_new ("src", GST_PAD_SRC);
130   fail_if (src == NULL);
131
132   caps = gst_caps_from_string ("foo/bar");
133   /* one for me */
134   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
135
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);
141
142   gst_pad_set_active (src, TRUE);
143   fail_unless (gst_pad_set_caps (src, caps) == TRUE);
144   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
145
146   gst_pad_set_active (sink, TRUE);
147   fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
148   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
149
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);
154
155   gst_pad_unlink (src, sink);
156   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
157
158   /* cleanup */
159   gst_object_unref (src);
160   gst_object_unref (sink);
161   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
162
163   gst_caps_unref (caps);
164 }
165
166 GST_END_TEST;
167
168 GST_START_TEST (test_get_allowed_caps)
169 {
170   GstPad *src, *sink;
171   GstCaps *caps, *gotcaps;
172   GstBuffer *buffer;
173   GstPadLinkReturn plr;
174
175   ASSERT_CRITICAL (gst_pad_get_allowed_caps (NULL));
176
177   buffer = gst_buffer_new ();
178   ASSERT_CRITICAL (gst_pad_get_allowed_caps ((GstPad *) buffer));
179   gst_buffer_unref (buffer);
180
181   src = gst_pad_new ("src", GST_PAD_SRC);
182   fail_if (src == NULL);
183   caps = gst_pad_get_allowed_caps (src);
184   fail_unless (caps == NULL);
185
186   caps = gst_caps_from_string ("foo/bar");
187
188   sink = gst_pad_new ("sink", GST_PAD_SINK);
189   gst_pad_set_active (src, TRUE);
190   /* source pad is active and will accept the caps event */
191   fail_unless (gst_pad_set_caps (src, caps) == TRUE);
192   /* sink pad is not active and will refuse the caps event */
193   fail_if (gst_pad_set_caps (sink, caps) == TRUE);
194   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
195
196   gst_pad_set_active (sink, TRUE);
197   /* sink pad is now active and will accept the caps event */
198   fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
199   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
200
201   plr = gst_pad_link (src, sink);
202   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
203
204   gotcaps = gst_pad_get_allowed_caps (src);
205   fail_if (gotcaps == NULL);
206   fail_unless (gst_caps_is_equal (gotcaps, caps));
207
208   ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 4);
209   gst_caps_unref (gotcaps);
210
211   gst_pad_unlink (src, sink);
212
213   /* cleanup */
214   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
215   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
216   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
217
218   gst_object_unref (src);
219   gst_object_unref (sink);
220
221   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
222   gst_caps_unref (caps);
223 }
224
225 GST_END_TEST;
226
227 static GstCaps *event_caps = NULL;
228
229 static gboolean
230 sticky_event (GstPad * pad, GstObject * parent, GstEvent * event)
231 {
232   GstCaps *caps;
233
234   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS
235       || GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START
236       || GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
237
238   if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
239     gst_event_unref (event);
240     return TRUE;
241   }
242
243   /* Ensure we get here just once: */
244   fail_unless (event_caps == NULL);
245
246   /* The event must arrive before any buffer: */
247   fail_unless_equals_int (g_list_length (buffers), 0);
248
249   gst_event_parse_caps (event, &caps);
250   event_caps = gst_caps_ref (caps);
251
252   gst_event_unref (event);
253
254   return TRUE;
255 }
256
257 /* Tests whether caps get properly forwarded when pads
258    are initially unlinked */
259 GST_START_TEST (test_sticky_caps_unlinked)
260 {
261   GstCaps *caps;
262   GstPadTemplate *src_template, *sink_template;
263   GstPad *src, *sink;
264   GstEvent *event;
265
266   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
267   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
268       GST_PAD_ALWAYS, caps);
269   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
270       GST_PAD_ALWAYS, caps);
271   gst_caps_unref (caps);
272
273   src = gst_pad_new_from_template (src_template, "src");
274   fail_if (src == NULL);
275   sink = gst_pad_new_from_template (sink_template, "sink");
276   fail_if (sink == NULL);
277   gst_pad_set_event_function (sink, sticky_event);
278   gst_pad_set_chain_function (sink, gst_check_chain_func);
279
280   gst_object_unref (src_template);
281   gst_object_unref (sink_template);
282
283   gst_pad_set_active (src, TRUE);
284
285   fail_unless (gst_pad_push_event (src,
286           gst_event_new_stream_start ("test")) == TRUE);
287
288   caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
289   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
290
291   event = gst_event_new_caps (caps);
292   fail_unless (gst_pad_push_event (src, event) == TRUE);
293   fail_unless (event_caps == NULL);
294
295   fail_unless (gst_pad_push_event (src,
296           gst_event_new_segment (&dummy_segment)) == TRUE);
297
298   /* Linking and activating will not forward the sticky event yet... */
299   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
300   gst_pad_set_active (sink, TRUE);
301   fail_unless (event_caps == NULL);
302
303   /* ...but the first buffer will: */
304   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
305   fail_unless (event_caps == caps);
306   fail_unless_equals_int (g_list_length (buffers), 1);
307
308   gst_check_drop_buffers ();
309
310   gst_caps_replace (&caps, NULL);
311   gst_caps_replace (&event_caps, NULL);
312   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
313   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
314   gst_object_unref (src);
315   gst_object_unref (sink);
316 }
317
318 GST_END_TEST;
319
320 static gboolean
321 check_if_caps_is_accepted (GstPad * sink, const gchar * str)
322 {
323   GstCaps *caps;
324   gboolean ret;
325
326   caps = gst_caps_from_string (str);
327   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
328   ret = gst_pad_query_accept_caps (sink, caps);
329   gst_caps_unref (caps);
330
331   return ret;
332 }
333
334 static gboolean
335 sink_query_caps (GstPad * pad, GstObject * object, GstQuery * q)
336 {
337   gboolean ret;
338   GstCaps *caps;
339
340   switch (GST_QUERY_TYPE (q)) {
341     case GST_QUERY_CAPS:
342       ret = TRUE;
343       caps =
344           gst_caps_from_string ("foo/bar, dummy=(int)1,"
345           " query-only-field=(int)1");
346       gst_query_set_caps_result (q, caps);
347       gst_caps_unref (caps);
348     default:
349       ret = gst_pad_query_default (pad, object, q);
350       break;
351   }
352
353   return ret;
354 }
355
356 /* Tests whether acceptcaps default handler works properly
357    with all 4 possible flag combinations */
358 GST_START_TEST (test_default_accept_caps)
359 {
360   GstCaps *caps;
361   GstPadTemplate *sink_template;
362   GstPad *sink;
363
364   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
365   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
366       GST_PAD_ALWAYS, caps);
367   gst_caps_unref (caps);
368
369   sink = gst_pad_new_from_template (sink_template, "sink");
370   fail_if (sink == NULL);
371   gst_pad_set_query_function (sink, sink_query_caps);
372
373   gst_object_unref (sink_template);
374
375   gst_pad_set_active (sink, TRUE);
376
377   /* 1. Check with caps query, subset check */
378   GST_PAD_UNSET_ACCEPT_INTERSECT (sink);
379   GST_PAD_UNSET_ACCEPT_TEMPLATE (sink);
380   fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
381   fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
382   fail_unless (check_if_caps_is_accepted (sink,
383           "foo/bar, dummy=(int)1, query-only-field=(int)1"));
384   fail_if (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
385
386   /* 2. Check with caps query, intersect check */
387   GST_PAD_SET_ACCEPT_INTERSECT (sink);
388   GST_PAD_UNSET_ACCEPT_TEMPLATE (sink);
389   fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
390   fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
391   fail_unless (check_if_caps_is_accepted (sink,
392           "foo/bar, dummy=(int)1, query-only-field=(int)1"));
393   fail_unless (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
394
395   /* 3. Check with template caps, subset check */
396   GST_PAD_UNSET_ACCEPT_INTERSECT (sink);
397   GST_PAD_SET_ACCEPT_TEMPLATE (sink);
398   fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
399   fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
400   fail_unless (check_if_caps_is_accepted (sink,
401           "foo/bar, dummy=(int)1, query-only-field=(int)1"));
402   fail_if (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
403
404   /* 3. Check with template caps, intersect check */
405   GST_PAD_SET_ACCEPT_INTERSECT (sink);
406   GST_PAD_SET_ACCEPT_TEMPLATE (sink);
407   fail_unless (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)1"));
408   fail_if (check_if_caps_is_accepted (sink, "foo/bar, dummy=(int)3"));
409   fail_unless (check_if_caps_is_accepted (sink,
410           "foo/bar, dummy=(int)1, query-only-field=(int)1"));
411   fail_unless (check_if_caps_is_accepted (sink, "foo/bar, extra-field=(int)1"));
412
413   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
414   gst_object_unref (sink);
415 }
416
417 GST_END_TEST;
418
419 /* Same as test_sticky_caps_unlinked except that the source pad
420  * has a template of ANY and we will attempt to push
421  * incompatible caps */
422 GST_START_TEST (test_sticky_caps_unlinked_incompatible)
423 {
424   GstCaps *caps, *failcaps;
425   GstPadTemplate *src_template, *sink_template;
426   GstPad *src, *sink;
427   GstEvent *event;
428
429   /* Source pad has ANY caps
430    * Sink pad has foobar caps
431    * We will push the pony express caps (which should fail)
432    */
433   caps = gst_caps_new_any ();
434   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
435       GST_PAD_ALWAYS, caps);
436   gst_caps_unref (caps);
437   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
438   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
439       GST_PAD_ALWAYS, caps);
440   gst_caps_unref (caps);
441
442   src = gst_pad_new_from_template (src_template, "src");
443   fail_if (src == NULL);
444   sink = gst_pad_new_from_template (sink_template, "sink");
445   fail_if (sink == NULL);
446   gst_pad_set_event_function (sink, sticky_event);
447   gst_pad_set_chain_function (sink, gst_check_chain_func);
448
449   gst_object_unref (src_template);
450   gst_object_unref (sink_template);
451
452   gst_pad_set_active (src, TRUE);
453
454   fail_unless (gst_pad_push_event (src,
455           gst_event_new_stream_start ("test")) == TRUE);
456
457   failcaps = gst_caps_from_string ("pony/express, failure=(boolean)true");
458   ASSERT_CAPS_REFCOUNT (failcaps, "caps", 1);
459
460   event = gst_event_new_caps (failcaps);
461   gst_caps_unref (failcaps);
462   /* The pad isn't linked yet, and anything matches the source pad template
463    * (which is ANY) */
464   fail_unless (gst_pad_push_event (src, event) == TRUE);
465   fail_unless (event_caps == NULL);
466
467   fail_unless (gst_pad_push_event (src,
468           gst_event_new_segment (&dummy_segment)) == TRUE);
469
470   /* Linking and activating will not forward the sticky event yet... */
471   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
472   gst_pad_set_active (sink, TRUE);
473   fail_unless (event_caps == NULL);
474
475   /* ...but the first buffer will and should FAIL since the caps 
476    * are not compatible */
477   fail_unless (gst_pad_push (src,
478           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
479   /* We shouldn't have received the caps event since it's incompatible */
480   fail_unless (event_caps == NULL);
481   /* We shouldn't have received any buffers since caps are incompatible */
482   fail_unless_equals_int (g_list_length (buffers), 0);
483
484   gst_check_drop_buffers ();
485
486   gst_caps_replace (&event_caps, NULL);
487
488   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
489   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
490   gst_object_unref (src);
491   gst_object_unref (sink);
492 }
493
494 GST_END_TEST;
495
496 /* Like test_sticky_caps_unlinked, but link before caps: */
497
498 GST_START_TEST (test_sticky_caps_flushing)
499 {
500   GstCaps *caps;
501   GstPadTemplate *src_template, *sink_template;
502   GstPad *src, *sink;
503   GstEvent *event;
504
505   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
506   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
507       GST_PAD_ALWAYS, caps);
508   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
509       GST_PAD_ALWAYS, caps);
510   gst_caps_unref (caps);
511
512   src = gst_pad_new_from_template (src_template, "src");
513   fail_if (src == NULL);
514   sink = gst_pad_new_from_template (sink_template, "sink");
515   fail_if (sink == NULL);
516   gst_pad_set_event_function (sink, sticky_event);
517   gst_pad_set_chain_function (sink, gst_check_chain_func);
518
519   gst_object_unref (src_template);
520   gst_object_unref (sink_template);
521
522   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
523
524   caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
525   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
526
527   event = gst_event_new_caps (caps);
528
529   gst_pad_set_active (src, TRUE);
530   fail_unless (gst_pad_push_event (src,
531           gst_event_new_stream_start ("test")) == TRUE);
532   /* The caps event gets accepted by the source pad (and stored) */
533   fail_unless (gst_pad_push_event (src, event) == TRUE);
534   /* But wasn't forwarded since the sink pad is flushing (not activated) */
535   fail_unless (event_caps == NULL);
536
537   fail_unless (gst_pad_push_event (src,
538           gst_event_new_segment (&dummy_segment)) == TRUE);
539
540   /* Activating will not forward the sticky event yet... */
541   gst_pad_set_active (sink, TRUE);
542   fail_unless (event_caps == NULL);
543
544   /* ...but the first buffer will: */
545   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
546   fail_unless (event_caps == caps);
547   fail_unless_equals_int (g_list_length (buffers), 1);
548
549   gst_check_drop_buffers ();
550
551   gst_caps_replace (&caps, NULL);
552   gst_caps_replace (&event_caps, NULL);
553
554   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
555   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
556   gst_object_unref (src);
557   gst_object_unref (sink);
558 }
559
560 GST_END_TEST;
561
562 static gboolean
563 name_is_valid (const gchar * name, GstPadPresence presence)
564 {
565   GstPadTemplate *new;
566   GstCaps *any = gst_caps_new_any ();
567
568   new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
569   gst_caps_unref (any);
570   if (new) {
571     gst_object_unref (GST_OBJECT (new));
572     return TRUE;
573   }
574   return FALSE;
575 }
576
577 GST_START_TEST (test_name_is_valid)
578 {
579   gboolean result = FALSE;
580
581   fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
582   ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
583   ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
584   fail_if (result);
585
586   fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
587   ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
588   ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
589   ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
590   fail_unless (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
591
592   fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
593   fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
594 }
595
596 GST_END_TEST;
597
598 static GstPadProbeReturn
599 _probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
600 {
601   GstPadProbeReturn ret = (GstPadProbeReturn) GPOINTER_TO_INT (userdata);
602
603   /* If we are handling the data, we unref it */
604   if (ret == GST_PAD_PROBE_HANDLED
605       && !(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_QUERY_BOTH)) {
606     GST_DEBUG_OBJECT (pad, "Unreffing data");
607     gst_mini_object_unref (info->data);
608   }
609   return ret;
610 }
611
612 static GstPadProbeReturn
613 _handled_probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
614 {
615   GstFlowReturn customflow = (GstFlowReturn) GPOINTER_TO_INT (userdata);
616
617   /* We are handling the data, we unref it */
618   if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_QUERY_BOTH))
619     gst_mini_object_unref (info->data);
620   GST_PAD_PROBE_INFO_FLOW_RETURN (info) = customflow;
621
622   return GST_PAD_PROBE_HANDLED;
623 }
624
625
626
627 GST_START_TEST (test_events_query_unlinked)
628 {
629   GstPad *src;
630   GstCaps *caps;
631   gulong id;
632   GstQuery *query;
633
634   src = gst_pad_new ("src", GST_PAD_SRC);
635   fail_if (src == NULL);
636   caps = gst_pad_get_allowed_caps (src);
637   fail_unless (caps == NULL);
638
639   caps = gst_caps_from_string ("foo/bar");
640
641   gst_pad_set_active (src, TRUE);
642   fail_unless (gst_pad_push_event (src,
643           gst_event_new_stream_start ("test")) == TRUE);
644   gst_pad_set_caps (src, caps);
645   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
646   fail_unless (gst_pad_push_event (src,
647           gst_event_new_segment (&dummy_segment)) == TRUE);
648   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
649
650   /* Doing a query on an unlinked pad will return FALSE */
651   query = gst_query_new_duration (GST_FORMAT_TIME);
652   fail_unless (gst_pad_peer_query (src, query) == FALSE);
653   ASSERT_MINI_OBJECT_REFCOUNT (query, "query", 1);
654   gst_query_unref (query);
655
656   /* Add a probe that returns _DROP will make the event push return TRUE
657    * even if not linked */
658   GST_DEBUG ("event/query DROP");
659   id = gst_pad_add_probe (src,
660       GST_PAD_PROBE_TYPE_EVENT_BOTH | GST_PAD_PROBE_TYPE_QUERY_BOTH,
661       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
662   fail_unless (gst_pad_push_event (src,
663           gst_event_new_segment (&dummy_segment)) == TRUE);
664   /* Queries should still fail */
665   query = gst_query_new_duration (GST_FORMAT_TIME);
666   fail_unless (gst_pad_peer_query (src, query) == FALSE);
667   ASSERT_MINI_OBJECT_REFCOUNT (query, "query", 1);
668   gst_query_unref (query);
669   gst_pad_remove_probe (src, id);
670
671   /* Add a probe that returns _HANDLED will make the event push return TRUE
672    * even if not linked */
673   GST_DEBUG ("event/query HANDLED");
674   id = gst_pad_add_probe (src,
675       GST_PAD_PROBE_TYPE_EVENT_BOTH | GST_PAD_PROBE_TYPE_QUERY_BOTH,
676       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_HANDLED), NULL);
677   fail_unless (gst_pad_push_event (src,
678           gst_event_new_segment (&dummy_segment)) == TRUE);
679
680   /* Queries will succeed */
681   query = gst_query_new_duration (GST_FORMAT_TIME);
682   fail_unless (gst_pad_peer_query (src, query) == TRUE);
683   ASSERT_MINI_OBJECT_REFCOUNT (query, "query", 1);
684   gst_query_unref (query);
685   gst_pad_remove_probe (src, id);
686
687   /* cleanup */
688   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
689   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
690
691   gst_object_unref (src);
692
693   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
694   gst_caps_unref (caps);
695 }
696
697 GST_END_TEST;
698
699 GST_START_TEST (test_push_unlinked)
700 {
701   GstPad *src;
702   GstCaps *caps;
703   GstBuffer *buffer;
704   gulong id;
705   GstFlowReturn fl;
706
707   src = gst_pad_new ("src", GST_PAD_SRC);
708   fail_if (src == NULL);
709   caps = gst_pad_get_allowed_caps (src);
710   fail_unless (caps == NULL);
711
712   caps = gst_caps_from_string ("foo/bar");
713
714   /* pushing on an inactive pad will return wrong state */
715   GST_DEBUG ("push buffer inactive");
716   buffer = gst_buffer_new ();
717   gst_buffer_ref (buffer);
718   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
719   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
720   gst_buffer_unref (buffer);
721
722   gst_pad_set_active (src, TRUE);
723   fail_unless (gst_pad_push_event (src,
724           gst_event_new_stream_start ("test")) == TRUE);
725   GST_DEBUG ("push caps event inactive");
726   gst_pad_set_caps (src, caps);
727   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
728   fail_unless (gst_pad_push_event (src,
729           gst_event_new_segment (&dummy_segment)) == TRUE);
730
731   /* pushing on an unlinked pad will drop the buffer */
732   GST_DEBUG ("push buffer unlinked");
733   buffer = gst_buffer_new ();
734   gst_buffer_ref (buffer);
735   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
736   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
737   gst_buffer_unref (buffer);
738
739   /* adding a probe that returns _DROP will drop the buffer without trying
740    * to chain */
741   GST_DEBUG ("push buffer drop");
742   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
743       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
744   buffer = gst_buffer_new ();
745   gst_buffer_ref (buffer);
746   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
747   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
748   gst_buffer_unref (buffer);
749   gst_pad_remove_probe (src, id);
750
751   /* adding a probe that returns _HANDLED will drop the buffer without trying
752    * to chain */
753   GST_DEBUG ("push buffer handled");
754   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
755       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_HANDLED), NULL);
756   buffer = gst_buffer_new ();
757   gst_buffer_ref (buffer);
758   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
759   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
760   gst_buffer_unref (buffer);
761   gst_pad_remove_probe (src, id);
762
763   /* adding a probe that returns _OK will still chain the buffer,
764    * and hence drop because pad is unlinked */
765   GST_DEBUG ("push buffer ok");
766   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
767       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_OK), NULL);
768   buffer = gst_buffer_new ();
769   gst_buffer_ref (buffer);
770   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
771   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
772   gst_buffer_unref (buffer);
773   gst_pad_remove_probe (src, id);
774
775   GST_DEBUG ("push buffer handled and custom return");
776   for (fl = GST_FLOW_NOT_SUPPORTED; fl <= GST_FLOW_OK; fl += 1) {
777     GST_DEBUG ("Testing with %s", gst_flow_get_name (fl));
778     id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
779         _handled_probe_handler, GINT_TO_POINTER (fl), NULL);
780     buffer = gst_buffer_new ();
781     gst_buffer_ref (buffer);
782     fail_unless (gst_pad_push (src, buffer) == fl);
783     ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
784     gst_buffer_unref (buffer);
785     gst_pad_remove_probe (src, id);
786
787   }
788
789
790   /* cleanup */
791   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
792   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
793
794   gst_object_unref (src);
795
796   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
797   gst_caps_unref (caps);
798 }
799
800 GST_END_TEST;
801
802 GST_START_TEST (test_push_linked)
803 {
804   GstPad *src, *sink;
805   GstPadLinkReturn plr;
806   GstCaps *caps;
807   GstBuffer *buffer;
808   gulong id;
809
810   /* setup */
811   sink = gst_pad_new ("sink", GST_PAD_SINK);
812   fail_if (sink == NULL);
813   gst_pad_set_chain_function (sink, gst_check_chain_func);
814
815   src = gst_pad_new ("src", GST_PAD_SRC);
816   fail_if (src == NULL);
817
818   caps = gst_caps_from_string ("foo/bar");
819   /* one for me */
820   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
821
822   gst_pad_set_active (src, TRUE);
823
824   fail_unless (gst_pad_push_event (src,
825           gst_event_new_stream_start ("test")) == TRUE);
826
827   gst_pad_set_caps (src, caps);
828
829   fail_unless (gst_pad_push_event (src,
830           gst_event_new_segment (&dummy_segment)) == TRUE);
831
832   gst_pad_set_active (sink, TRUE);
833   /* one for me and one for each set_caps */
834   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
835
836   plr = gst_pad_link (src, sink);
837   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
838   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
839
840   buffer = gst_buffer_new ();
841
842   /* test */
843   /* pushing on a linked pad will drop the ref to the buffer */
844   gst_buffer_ref (buffer);
845   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
846   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
847   gst_buffer_unref (buffer);
848   fail_unless_equals_int (g_list_length (buffers), 1);
849   buffer = GST_BUFFER (buffers->data);
850   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
851   gst_buffer_unref (buffer);
852   g_list_free (buffers);
853   buffers = NULL;
854
855   /* adding a probe that returns _DROP will drop the buffer without trying
856    * to chain */
857   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
858       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
859   buffer = gst_buffer_new ();
860   gst_buffer_ref (buffer);
861   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
862   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
863   gst_buffer_unref (buffer);
864   gst_pad_remove_probe (src, id);
865   fail_unless_equals_int (g_list_length (buffers), 0);
866
867   /* adding a probe that returns _OK will still chain the buffer */
868   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
869       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_OK), NULL);
870   buffer = gst_buffer_new ();
871   gst_buffer_ref (buffer);
872   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
873   gst_pad_remove_probe (src, id);
874
875   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
876   gst_buffer_unref (buffer);
877   fail_unless_equals_int (g_list_length (buffers), 1);
878   buffer = GST_BUFFER (buffers->data);
879   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
880   gst_buffer_unref (buffer);
881   g_list_free (buffers);
882   buffers = NULL;
883
884   /* adding a probe that returns _HANDLED will not chain the buffer */
885   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
886       _probe_handler, GINT_TO_POINTER (GST_PAD_PROBE_HANDLED), NULL);
887   buffer = gst_buffer_new ();
888   gst_buffer_ref (buffer);
889   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
890   gst_pad_remove_probe (src, id);
891
892   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
893   gst_buffer_unref (buffer);
894   fail_unless_equals_int (g_list_length (buffers), 0);
895   g_list_free (buffers);
896   buffers = NULL;
897
898   /* teardown */
899   gst_check_drop_buffers ();
900   gst_pad_unlink (src, sink);
901   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
902   gst_object_unref (src);
903   gst_object_unref (sink);
904   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
905
906   gst_caps_unref (caps);
907 }
908
909 GST_END_TEST;
910
911 GST_START_TEST (test_push_linked_flushing)
912 {
913   GstPad *src, *sink;
914   GstCaps *caps;
915   GstPadLinkReturn plr;
916   GstBuffer *buffer;
917   gulong id;
918
919   /* setup */
920   src = gst_pad_new ("src", GST_PAD_SRC);
921   fail_if (src == NULL);
922   sink = gst_pad_new ("sink", GST_PAD_SINK);
923   fail_if (sink == NULL);
924   gst_pad_set_chain_function (sink, gst_check_chain_func);
925
926   caps = gst_pad_get_allowed_caps (src);
927   fail_unless (caps == NULL);
928   caps = gst_pad_get_allowed_caps (sink);
929   fail_unless (caps == NULL);
930
931   caps = gst_caps_from_string ("foo/bar");
932   /* one for me */
933   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
934
935   gst_pad_set_active (src, TRUE);
936   fail_unless (gst_pad_push_event (src,
937           gst_event_new_stream_start ("test")) == TRUE);
938   gst_pad_set_caps (src, caps);
939   fail_unless (gst_pad_push_event (src,
940           gst_event_new_segment (&dummy_segment)) == TRUE);
941   /* need to activate to make it accept the caps */
942   gst_pad_set_active (sink, TRUE);
943   /* one for me and one for each set_caps */
944   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
945
946   plr = gst_pad_link (src, sink);
947   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
948   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
949
950   /* not activating the pads here, which keeps them flushing */
951   gst_pad_set_active (src, FALSE);
952   gst_pad_set_active (sink, FALSE);
953
954   /* pushing on a flushing pad will drop the buffer */
955   buffer = gst_buffer_new ();
956   gst_buffer_ref (buffer);
957   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
958   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
959   fail_unless_equals_int (g_list_length (buffers), 0);
960   gst_buffer_unref (buffer);
961
962   gst_pad_set_active (src, TRUE);
963   gst_pad_set_active (sink, FALSE);
964
965   fail_unless (gst_pad_push_event (src,
966           gst_event_new_stream_start ("test")) == TRUE);
967   gst_pad_set_caps (src, caps);
968   fail_unless (gst_pad_push_event (src,
969           gst_event_new_segment (&dummy_segment)) == TRUE);
970   /* adding a probe that returns _DROP will drop the buffer without trying
971    * to chain */
972   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
973       GINT_TO_POINTER (GST_PAD_PROBE_DROP), NULL);
974   buffer = gst_buffer_new ();
975   gst_buffer_ref (buffer);
976   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
977   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
978   fail_unless_equals_int (g_list_length (buffers), 0);
979   gst_buffer_unref (buffer);
980   gst_pad_remove_probe (src, id);
981
982   /* adding a probe that returns _OK will still chain the buffer,
983    * and hence drop because pad is flushing */
984   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
985       GINT_TO_POINTER (GST_PAD_PROBE_OK), NULL);
986   buffer = gst_buffer_new ();
987   gst_buffer_ref (buffer);
988   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
989   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
990   fail_unless_equals_int (g_list_length (buffers), 0);
991   gst_buffer_unref (buffer);
992   gst_pad_remove_probe (src, id);
993
994   /* cleanup */
995   gst_check_drop_buffers ();
996   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
997   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
998   gst_pad_link (src, sink);
999   gst_object_unref (src);
1000   gst_object_unref (sink);
1001   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
1002   gst_caps_unref (caps);
1003 }
1004
1005 GST_END_TEST;
1006
1007 static GstBuffer *
1008 buffer_from_string (const gchar * str)
1009 {
1010   guint size;
1011   GstBuffer *buf;
1012
1013   size = strlen (str);
1014   buf = gst_buffer_new_and_alloc (size);
1015
1016   gst_buffer_fill (buf, 0, str, size);
1017
1018   return buf;
1019 }
1020
1021 static gboolean
1022 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
1023 {
1024   gboolean res;
1025   GstMapInfo info;
1026
1027   fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
1028   res = memcmp (info.data, str, size) == 0;
1029   GST_MEMDUMP ("buffer  data", info.data, size);
1030   GST_MEMDUMP ("compare data", (guint8 *) str, size);
1031   GST_DEBUG ("buffers match: %s", res ? "yes" : "no");
1032   gst_buffer_unmap (buf, &info);
1033
1034   return res;
1035 }
1036
1037 GST_START_TEST (test_push_buffer_list_compat)
1038 {
1039   GstPad *src, *sink;
1040   GstPadLinkReturn plr;
1041   GstCaps *caps;
1042   GstBufferList *list;
1043   GstBuffer *buffer;
1044
1045   /* setup */
1046   sink = gst_pad_new ("sink", GST_PAD_SINK);
1047   fail_if (sink == NULL);
1048   gst_pad_set_chain_function (sink, gst_check_chain_func);
1049   /* leave chainlistfunc unset */
1050
1051   src = gst_pad_new ("src", GST_PAD_SRC);
1052   fail_if (src == NULL);
1053
1054   caps = gst_caps_from_string ("foo/bar");
1055
1056   gst_pad_set_active (src, TRUE);
1057
1058   fail_unless (gst_pad_push_event (src,
1059           gst_event_new_stream_start ("test")) == TRUE);
1060
1061   gst_pad_set_caps (src, caps);
1062
1063   fail_unless (gst_pad_push_event (src,
1064           gst_event_new_segment (&dummy_segment)) == TRUE);
1065
1066   gst_pad_set_active (sink, TRUE);
1067
1068   plr = gst_pad_link (src, sink);
1069   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1070
1071   list = gst_buffer_list_new ();
1072
1073   /* test */
1074   /* adding to a buffer list will drop the ref to the buffer */
1075   gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
1076   gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
1077
1078   fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
1079   fail_unless_equals_int (g_list_length (buffers), 2);
1080   buffer = GST_BUFFER (buffers->data);
1081   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
1082   fail_unless (buffer_compare (buffer, "ListGroup", 9));
1083   gst_buffer_unref (buffer);
1084   buffers = g_list_delete_link (buffers, buffers);
1085   buffer = GST_BUFFER (buffers->data);
1086   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
1087   fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
1088   gst_buffer_unref (buffer);
1089   buffers = g_list_delete_link (buffers, buffers);
1090   fail_unless (buffers == NULL);
1091
1092   /* teardown */
1093   gst_check_drop_buffers ();
1094   gst_pad_unlink (src, sink);
1095   gst_object_unref (src);
1096   gst_object_unref (sink);
1097   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
1098   gst_caps_unref (caps);
1099 }
1100
1101 GST_END_TEST;
1102
1103 GST_START_TEST (test_flowreturn)
1104 {
1105   GstFlowReturn ret;
1106   GQuark quark;
1107
1108   /* test some of the macros */
1109   ret = GST_FLOW_EOS;
1110   fail_if (strcmp (gst_flow_get_name (ret), "eos"));
1111   quark = gst_flow_to_quark (ret);
1112   fail_if (strcmp (g_quark_to_string (quark), "eos"));
1113
1114   /* custom returns */
1115   ret = GST_FLOW_CUSTOM_SUCCESS;
1116   fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
1117   quark = gst_flow_to_quark (ret);
1118   fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
1119
1120   ret = GST_FLOW_CUSTOM_ERROR;
1121   fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
1122   quark = gst_flow_to_quark (ret);
1123   fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
1124
1125   /* custom returns clamping */
1126   ret = GST_FLOW_CUSTOM_SUCCESS + 2;
1127   fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
1128   quark = gst_flow_to_quark (ret);
1129   fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
1130
1131   ret = GST_FLOW_CUSTOM_ERROR - 2;
1132   fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
1133   quark = gst_flow_to_quark (ret);
1134   fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
1135
1136   /* unknown values */
1137   ret = GST_FLOW_CUSTOM_ERROR + 2;
1138   fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
1139   quark = gst_flow_to_quark (ret);
1140   fail_unless (quark == 0);
1141 }
1142
1143 GST_END_TEST;
1144
1145 GST_START_TEST (test_push_negotiation)
1146 {
1147   GstPad *src, *sink;
1148   GstPadLinkReturn plr;
1149   GstCaps *srccaps =
1150       gst_caps_from_string ("audio/x-raw,width={16,32},depth={16,32}");
1151   GstCaps *sinkcaps =
1152       gst_caps_from_string ("audio/x-raw,width=32,depth={16,32}");
1153   GstPadTemplate *src_template;
1154   GstPadTemplate *sink_template;
1155   GstCaps *caps;
1156
1157   /* setup */
1158   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
1159       GST_PAD_ALWAYS, srccaps);
1160   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
1161       GST_PAD_ALWAYS, sinkcaps);
1162   gst_caps_unref (srccaps);
1163   gst_caps_unref (sinkcaps);
1164
1165   sink = gst_pad_new_from_template (sink_template, "sink");
1166   fail_if (sink == NULL);
1167   gst_pad_set_chain_function (sink, gst_check_chain_func);
1168
1169   src = gst_pad_new_from_template (src_template, "src");
1170   fail_if (src == NULL);
1171
1172   plr = gst_pad_link (src, sink);
1173   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1174
1175   /* activate pads */
1176   gst_pad_set_active (src, TRUE);
1177   gst_pad_set_active (sink, TRUE);
1178
1179   caps = gst_caps_from_string ("audio/x-raw,width=16,depth=16");
1180
1181   /* Should fail if src pad caps are incompatible with sink pad caps */
1182   gst_pad_set_caps (src, caps);
1183   fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
1184
1185   /* teardown */
1186   gst_check_drop_buffers ();
1187   gst_pad_unlink (src, sink);
1188   gst_object_unref (src);
1189   gst_object_unref (sink);
1190   gst_caps_unref (caps);
1191   gst_object_unref (sink_template);
1192   gst_object_unref (src_template);
1193 }
1194
1195 GST_END_TEST;
1196
1197 /* see that an unref also unlinks the pads */
1198 GST_START_TEST (test_src_unref_unlink)
1199 {
1200   GstPad *src, *sink;
1201   GstCaps *caps;
1202   GstPadLinkReturn plr;
1203
1204   sink = gst_pad_new ("sink", GST_PAD_SINK);
1205   fail_if (sink == NULL);
1206
1207   src = gst_pad_new ("src", GST_PAD_SRC);
1208   fail_if (src == NULL);
1209
1210   caps = gst_caps_from_string ("foo/bar");
1211
1212   gst_pad_set_active (src, TRUE);
1213   gst_pad_set_caps (src, caps);
1214   gst_pad_set_active (sink, TRUE);
1215   gst_pad_set_caps (sink, caps);
1216
1217   plr = gst_pad_link (src, sink);
1218   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1219
1220   /* unref the srcpad */
1221   gst_object_unref (src);
1222
1223   /* sink should be unlinked now */
1224   fail_if (gst_pad_is_linked (sink));
1225
1226   /* cleanup */
1227   gst_object_unref (sink);
1228   gst_caps_unref (caps);
1229 }
1230
1231 GST_END_TEST;
1232
1233 /* see that an unref also unlinks the pads */
1234 GST_START_TEST (test_sink_unref_unlink)
1235 {
1236   GstPad *src, *sink;
1237   GstCaps *caps;
1238   GstPadLinkReturn plr;
1239
1240   sink = gst_pad_new ("sink", GST_PAD_SINK);
1241   fail_if (sink == NULL);
1242
1243   src = gst_pad_new ("src", GST_PAD_SRC);
1244   fail_if (src == NULL);
1245
1246   caps = gst_caps_from_string ("foo/bar");
1247
1248   gst_pad_set_active (src, TRUE);
1249   gst_pad_set_caps (src, caps);
1250   gst_pad_set_active (sink, TRUE);
1251   gst_pad_set_caps (sink, caps);
1252
1253   plr = gst_pad_link (src, sink);
1254   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1255
1256   /* unref the sinkpad */
1257   gst_object_unref (sink);
1258
1259   /* src should be unlinked now */
1260   fail_if (gst_pad_is_linked (src));
1261
1262   /* cleanup */
1263   gst_object_unref (src);
1264   gst_caps_unref (caps);
1265 }
1266
1267 GST_END_TEST;
1268
1269 static gulong id;
1270
1271 static GstPadProbeReturn
1272 block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1273 {
1274   gboolean *bool_user_data = (gboolean *) user_data;
1275
1276   fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
1277
1278   /* here we should have blocked == 0 unblocked == 0 */
1279   fail_unless (bool_user_data[0] == FALSE);
1280   fail_unless (bool_user_data[1] == FALSE);
1281
1282   bool_user_data[0] = TRUE;
1283
1284   gst_pad_remove_probe (pad, id);
1285   bool_user_data[1] = TRUE;
1286
1287   return GST_PAD_PROBE_OK;
1288 }
1289
1290 GST_START_TEST (test_block_async)
1291 {
1292   GstPad *pad;
1293   /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
1294    * unblocked */
1295   gboolean data[2] = { FALSE, FALSE };
1296
1297   pad = gst_pad_new ("src", GST_PAD_SRC);
1298   fail_unless (pad != NULL);
1299
1300   gst_pad_set_active (pad, TRUE);
1301
1302   fail_unless (gst_pad_push_event (pad,
1303           gst_event_new_stream_start ("test")) == TRUE);
1304   fail_unless (gst_pad_push_event (pad,
1305           gst_event_new_segment (&dummy_segment)) == TRUE);
1306
1307   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_cb, &data,
1308       NULL);
1309
1310   fail_unless (data[0] == FALSE);
1311   fail_unless (data[1] == FALSE);
1312   gst_pad_push (pad, gst_buffer_new ());
1313
1314   gst_object_unref (pad);
1315 }
1316
1317 GST_END_TEST;
1318
1319 static GstPadProbeReturn
1320 block_async_cb_return_ok (GstPad * pad, GstPadProbeInfo * info,
1321     gpointer user_data)
1322 {
1323   return GST_PAD_PROBE_OK;
1324 }
1325
1326 static gpointer
1327 push_buffer_async (GstPad * pad)
1328 {
1329   return GINT_TO_POINTER (gst_pad_push (pad, gst_buffer_new ()));
1330 }
1331
1332 static void
1333 test_pad_blocking_with_type (GstPadProbeType type)
1334 {
1335   GstPad *pad;
1336   GThread *thread;
1337   GstFlowReturn ret;
1338
1339   pad = gst_pad_new ("src", GST_PAD_SRC);
1340   fail_unless (pad != NULL);
1341
1342   gst_pad_set_active (pad, TRUE);
1343
1344   fail_unless (gst_pad_push_event (pad,
1345           gst_event_new_stream_start ("test")) == TRUE);
1346   fail_unless (gst_pad_push_event (pad,
1347           gst_event_new_segment (&dummy_segment)) == TRUE);
1348
1349   id = gst_pad_add_probe (pad, type, block_async_cb_return_ok, NULL, NULL);
1350
1351   thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1352       pad, NULL);
1353
1354   /* wait for the block */
1355   while (!gst_pad_is_blocking (pad)) {
1356     g_usleep (10000);
1357   }
1358
1359   /* stop with flushing */
1360   gst_pad_push_event (pad, gst_event_new_flush_start ());
1361
1362   /* get return value from push */
1363   ret = GPOINTER_TO_INT (g_thread_join (thread));
1364   /* unflush now */
1365   gst_pad_push_event (pad, gst_event_new_flush_stop (FALSE));
1366   /* must be wrong state */
1367   fail_unless (ret == GST_FLOW_FLUSHING);
1368
1369   gst_object_unref (pad);
1370 }
1371
1372 GST_START_TEST (test_pad_blocking_with_probe_type_block)
1373 {
1374   test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCK);
1375 }
1376
1377 GST_END_TEST;
1378
1379 GST_START_TEST (test_pad_blocking_with_probe_type_blocking)
1380 {
1381   test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCKING);
1382 }
1383
1384 GST_END_TEST;
1385
1386 static gboolean idle_probe_running;
1387
1388 static GstFlowReturn
1389 idletest_sink_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1390 {
1391   if (idle_probe_running)
1392     fail ("Should not be reached");
1393   gst_buffer_unref (buf);
1394   return GST_FLOW_OK;
1395 }
1396
1397 static GstPadProbeReturn
1398 idle_probe_wait (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1399 {
1400   /* it is ok to have a probe called multiple times but it is not
1401    * acceptable in our scenario */
1402   fail_if (idle_probe_running);
1403
1404   idle_probe_running = TRUE;
1405   while (idle_probe_running) {
1406     g_usleep (10000);
1407   }
1408
1409   return GST_PAD_PROBE_REMOVE;
1410 }
1411
1412 static gpointer
1413 add_idle_probe_async (GstPad * pad)
1414 {
1415   gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, idle_probe_wait, NULL, NULL);
1416
1417   return NULL;
1418 }
1419
1420 GST_START_TEST (test_pad_blocking_with_probe_type_idle)
1421 {
1422   GstPad *srcpad, *sinkpad;
1423   GThread *idle_thread, *thread;
1424
1425   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1426   fail_unless (srcpad != NULL);
1427   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1428   fail_unless (sinkpad != NULL);
1429
1430   gst_pad_set_chain_function (sinkpad, idletest_sink_pad_chain);
1431
1432   fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
1433
1434   gst_pad_set_active (sinkpad, TRUE);
1435   gst_pad_set_active (srcpad, TRUE);
1436
1437   fail_unless (gst_pad_push_event (srcpad,
1438           gst_event_new_stream_start ("test")) == TRUE);
1439   fail_unless (gst_pad_push_event (srcpad,
1440           gst_event_new_segment (&dummy_segment)) == TRUE);
1441
1442   idle_probe_running = FALSE;
1443   idle_thread =
1444       g_thread_try_new ("gst-check", (GThreadFunc) add_idle_probe_async, srcpad,
1445       NULL);
1446
1447   /* wait for the idle function to signal it is being called */
1448   while (!idle_probe_running) {
1449     g_usleep (10000);
1450   }
1451
1452   thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1453       srcpad, NULL);
1454
1455   while (!gst_pad_is_blocking (srcpad)) {
1456     g_usleep (10000);
1457   }
1458
1459   idle_probe_running = FALSE;
1460
1461   g_thread_join (idle_thread);
1462   g_thread_join (thread);
1463   gst_object_unref (srcpad);
1464   gst_object_unref (sinkpad);
1465 }
1466
1467 GST_END_TEST;
1468
1469 static gboolean pull_probe_called;
1470 static gboolean pull_probe_called_with_bad_type;
1471 static gboolean pull_probe_called_with_bad_data;
1472
1473 static GstPadProbeReturn
1474 probe_pull_buffer_cb_check_buffer_return_ok (GstPad * pad,
1475     GstPadProbeInfo * info, gpointer user_data)
1476 {
1477   if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
1478     if (GST_IS_BUFFER (info->data))
1479       pull_probe_called = TRUE;
1480     else
1481       pull_probe_called_with_bad_data = TRUE;
1482   } else {
1483     /* shouldn't be called */
1484     pull_probe_called_with_bad_type = TRUE;
1485   }
1486   return GST_PAD_PROBE_OK;
1487 }
1488
1489 static GstFlowReturn
1490 test_probe_pull_getrange (GstPad * pad, GstObject * parent, guint64 offset,
1491     guint length, GstBuffer ** buf)
1492 {
1493   *buf = gst_buffer_new ();
1494   return GST_FLOW_OK;
1495 }
1496
1497 static gboolean
1498 test_probe_pull_activate_pull (GstPad * pad, GstObject * object)
1499 {
1500   return gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE);
1501 }
1502
1503 static gpointer
1504 pull_range_async (GstPad * pad)
1505 {
1506   GstBuffer *buf = NULL;
1507   GstFlowReturn res = gst_pad_pull_range (pad, 0, 100, &buf);
1508   if (buf)
1509     gst_buffer_unref (buf);
1510   return GINT_TO_POINTER (res);
1511 }
1512
1513 GST_START_TEST (test_pad_probe_pull)
1514 {
1515   GstPad *srcpad, *sinkpad;
1516   GThread *thread;
1517   GstFlowReturn ret;
1518
1519   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1520   fail_unless (srcpad != NULL);
1521   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1522   fail_unless (sinkpad != NULL);
1523
1524   gst_pad_set_getrange_function (srcpad, test_probe_pull_getrange);
1525   gst_pad_set_activate_function (sinkpad, test_probe_pull_activate_pull);
1526   gst_pad_link (srcpad, sinkpad);
1527
1528   gst_pad_set_active (sinkpad, TRUE);
1529   gst_pad_set_active (srcpad, TRUE);
1530
1531   id = gst_pad_add_probe (sinkpad,
1532       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_PULL,
1533       block_async_cb_return_ok, NULL, NULL);
1534
1535   thread = g_thread_try_new ("gst-check", (GThreadFunc) pull_range_async,
1536       sinkpad, NULL);
1537
1538   /* wait for the block */
1539   while (!gst_pad_is_blocking (sinkpad)) {
1540     g_usleep (10000);
1541   }
1542
1543   /* stop with flushing */
1544   gst_pad_push_event (srcpad, gst_event_new_flush_start ());
1545
1546   /* get return value from push */
1547   ret = GPOINTER_TO_INT (g_thread_join (thread));
1548   /* unflush now */
1549   gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE));
1550   /* must be wrong state */
1551   fail_unless (ret == GST_FLOW_FLUSHING);
1552
1553   gst_object_unref (srcpad);
1554   gst_object_unref (sinkpad);
1555 }
1556
1557 GST_END_TEST;
1558
1559 static gboolean idle_probe_called;
1560 static gboolean get_range_wait;
1561 static gboolean getrange_waiting;
1562
1563 static GstPadProbeReturn
1564 idle_cb_return_ok (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1565 {
1566   idle_probe_called = TRUE;
1567   return GST_PAD_PROBE_OK;
1568 }
1569
1570 static GstFlowReturn
1571 test_probe_pull_getrange_wait (GstPad * pad, GstObject * parent, guint64 offset,
1572     guint length, GstBuffer ** buf)
1573 {
1574   getrange_waiting = TRUE;
1575
1576   *buf = gst_buffer_new ();
1577   while (get_range_wait) {
1578     g_usleep (10000);
1579   }
1580
1581   getrange_waiting = FALSE;
1582   return GST_FLOW_OK;
1583 }
1584
1585 GST_START_TEST (test_pad_probe_pull_idle)
1586 {
1587   GstPad *srcpad, *sinkpad;
1588   GThread *thread;
1589   GstFlowReturn ret;
1590
1591   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1592   fail_unless (srcpad != NULL);
1593   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1594   fail_unless (sinkpad != NULL);
1595
1596   gst_pad_set_getrange_function (srcpad, test_probe_pull_getrange_wait);
1597   gst_pad_set_activate_function (sinkpad, test_probe_pull_activate_pull);
1598   gst_pad_link (srcpad, sinkpad);
1599
1600   gst_pad_set_active (sinkpad, TRUE);
1601   gst_pad_set_active (srcpad, TRUE);
1602
1603   idle_probe_called = FALSE;
1604   get_range_wait = TRUE;
1605   thread = g_thread_try_new ("gst-check", (GThreadFunc) pull_range_async,
1606       sinkpad, NULL);
1607
1608   /* wait for the block */
1609   while (!getrange_waiting) {
1610     g_usleep (10000);
1611   }
1612
1613   id = gst_pad_add_probe (sinkpad,
1614       GST_PAD_PROBE_TYPE_IDLE | GST_PAD_PROBE_TYPE_PULL,
1615       idle_cb_return_ok, NULL, NULL);
1616
1617   fail_if (idle_probe_called);
1618
1619   get_range_wait = FALSE;
1620   while (getrange_waiting) {
1621     g_usleep (10000);
1622   }
1623   while (!idle_probe_called) {
1624     g_usleep (10000);
1625   }
1626
1627   ret = GPOINTER_TO_INT (g_thread_join (thread));
1628   fail_unless (ret == GST_FLOW_OK);
1629   gst_pad_set_active (srcpad, FALSE);
1630   gst_pad_set_active (sinkpad, FALSE);
1631   gst_object_unref (srcpad);
1632   gst_object_unref (sinkpad);
1633 }
1634
1635 GST_END_TEST;
1636
1637
1638 GST_START_TEST (test_pad_probe_pull_buffer)
1639 {
1640   GstPad *srcpad, *sinkpad;
1641   GThread *thread;
1642   GstFlowReturn ret;
1643
1644   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1645   fail_unless (srcpad != NULL);
1646   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1647   fail_unless (sinkpad != NULL);
1648
1649   gst_pad_set_getrange_function (srcpad, test_probe_pull_getrange);
1650   gst_pad_set_activate_function (sinkpad, test_probe_pull_activate_pull);
1651   gst_pad_link (srcpad, sinkpad);
1652
1653   gst_pad_set_active (sinkpad, TRUE);
1654   gst_pad_set_active (srcpad, TRUE);
1655
1656   id = gst_pad_add_probe (sinkpad,
1657       GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PULL,
1658       probe_pull_buffer_cb_check_buffer_return_ok, NULL, NULL);
1659
1660   pull_probe_called = FALSE;
1661   pull_probe_called_with_bad_type = FALSE;
1662   pull_probe_called_with_bad_data = FALSE;
1663
1664   thread = g_thread_try_new ("gst-check", (GThreadFunc) pull_range_async,
1665       sinkpad, NULL);
1666
1667   /* wait for the block */
1668   while (!pull_probe_called && !pull_probe_called_with_bad_data
1669       && !pull_probe_called_with_bad_type) {
1670     g_usleep (10000);
1671   }
1672
1673   fail_unless (pull_probe_called);
1674   fail_if (pull_probe_called_with_bad_data);
1675   fail_if (pull_probe_called_with_bad_type);
1676
1677   /* get return value from push */
1678   ret = GPOINTER_TO_INT (g_thread_join (thread));
1679   fail_unless (ret == GST_FLOW_OK);
1680
1681   gst_pad_set_active (sinkpad, FALSE);
1682   gst_pad_set_active (srcpad, FALSE);
1683   gst_object_unref (srcpad);
1684   gst_object_unref (sinkpad);
1685 }
1686
1687 GST_END_TEST;
1688
1689 static gboolean pad_probe_remove_notifiy_called = FALSE;
1690
1691 static GstPadProbeReturn
1692 probe_remove_self_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1693 {
1694   gst_pad_remove_probe (pad, info->id);
1695
1696   fail_unless (pad->num_probes == 0);
1697   fail_unless (pad->num_blocked == 0);
1698
1699   return GST_PAD_PROBE_REMOVE;
1700 }
1701
1702 static void
1703 probe_remove_notify_cb (gpointer data)
1704 {
1705   fail_unless (pad_probe_remove_notifiy_called == FALSE);
1706   pad_probe_remove_notifiy_called = TRUE;
1707 }
1708
1709 GST_START_TEST (test_pad_probe_remove)
1710 {
1711   GstPad *pad;
1712
1713   pad = gst_pad_new ("src", GST_PAD_SRC);
1714   fail_unless (pad != NULL);
1715
1716   gst_pad_set_active (pad, TRUE);
1717   fail_unless (pad->num_probes == 0);
1718   fail_unless (pad->num_blocked == 0);
1719   gst_pad_add_probe (pad,
1720       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
1721       probe_remove_self_cb, NULL, probe_remove_notify_cb);
1722   fail_unless (pad->num_probes == 1);
1723   fail_unless (pad->num_blocked == 1);
1724
1725   pad_probe_remove_notifiy_called = FALSE;
1726   gst_pad_push_event (pad, gst_event_new_stream_start ("asda"));
1727
1728   fail_unless (pad->num_probes == 0);
1729   fail_unless (pad->num_blocked == 0);
1730
1731   gst_object_unref (pad);
1732 }
1733
1734 GST_END_TEST;
1735
1736 typedef struct
1737 {
1738   gulong probe_id;
1739   GstPad *probe_pad;
1740   GThread *thread;
1741 } BlockReplaceProbeHelper;
1742
1743 static gpointer
1744 unblock_probe_thread (gpointer user_data)
1745 {
1746   BlockReplaceProbeHelper *helper = user_data;
1747
1748   GST_INFO_OBJECT (helper->probe_pad, "removing probe to unblock pad");
1749   gst_pad_remove_probe (helper->probe_pad, helper->probe_id);
1750   return NULL;
1751 }
1752
1753 static GstPadProbeReturn
1754 block_and_replace_buffer_probe_cb (GstPad * pad, GstPadProbeInfo * info,
1755     gpointer user_data)
1756 {
1757   BlockReplaceProbeHelper *helper = user_data;
1758
1759   GST_INFO_OBJECT (pad, "about to block pad, replacing buffer");
1760
1761   /* we want to block, but also drop this buffer */
1762   gst_buffer_unref (GST_BUFFER (info->data));
1763   info->data = NULL;
1764
1765   helper->thread =
1766       g_thread_new ("gst-pad-test-thread", unblock_probe_thread, helper);
1767
1768   return GST_PAD_PROBE_OK;
1769 }
1770
1771 GST_START_TEST (test_pad_probe_block_and_drop_buffer)
1772 {
1773   BlockReplaceProbeHelper helper;
1774   GstFlowReturn flow;
1775   GstPad *src, *sink;
1776
1777   src = gst_pad_new ("src", GST_PAD_SRC);
1778   gst_pad_set_active (src, TRUE);
1779   sink = gst_pad_new ("sink", GST_PAD_SINK);
1780   gst_pad_set_chain_function (sink, gst_check_chain_func);
1781   gst_pad_set_active (sink, TRUE);
1782
1783   fail_unless (gst_pad_push_event (src,
1784           gst_event_new_stream_start ("test")) == TRUE);
1785   fail_unless (gst_pad_push_event (src,
1786           gst_event_new_segment (&dummy_segment)) == TRUE);
1787
1788   fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
1789
1790   helper.probe_id = gst_pad_add_probe (src,
1791       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1792       block_and_replace_buffer_probe_cb, &helper, NULL);
1793   helper.probe_pad = src;
1794
1795   /* push a buffer so the events are propagated downstream */
1796   flow = gst_pad_push (src, gst_buffer_new ());
1797
1798   g_thread_join (helper.thread);
1799
1800   fail_unless_equals_int (flow, GST_FLOW_OK);
1801
1802   /* no buffer should have made it through to the sink pad, and especially
1803    * not a NULL pointer buffer */
1804   fail_if (buffers && buffers->data == NULL);
1805   fail_unless (buffers == NULL);
1806
1807   gst_check_drop_buffers ();
1808   gst_object_unref (src);
1809   gst_object_unref (sink);
1810 }
1811
1812 GST_END_TEST;
1813
1814 static GstPadProbeReturn
1815 probe_block_ok (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1816 {
1817   gboolean *called = user_data;
1818   if (called)
1819     *called = TRUE;
1820   return GST_PAD_PROBE_OK;
1821 }
1822
1823 static GstPadProbeReturn
1824 probe_block_remove (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1825 {
1826   gboolean *called = user_data;
1827   *called = TRUE;
1828   return GST_PAD_PROBE_REMOVE;
1829 }
1830
1831 GST_START_TEST (test_pad_probe_block_add_remove)
1832 {
1833   GstPad *pad;
1834   GThread *thread;
1835   gulong probe_a, probe_b;
1836   gboolean called;
1837   guint r;
1838
1839   pad = gst_pad_new ("src", GST_PAD_SRC);
1840   fail_unless (pad != NULL);
1841
1842   gst_pad_set_active (pad, TRUE);
1843   fail_unless (pad->num_probes == 0);
1844   fail_unless (pad->num_blocked == 0);
1845
1846   fail_unless (gst_pad_push_event (pad,
1847           gst_event_new_stream_start ("test")) == TRUE);
1848   fail_unless (gst_pad_push_event (pad,
1849           gst_event_new_segment (&dummy_segment)) == TRUE);
1850
1851   probe_a = gst_pad_add_probe (pad,
1852       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1853       probe_block_ok, NULL, NULL);
1854
1855   fail_unless (pad->num_probes == 1);
1856   fail_unless (pad->num_blocked == 1);
1857
1858   thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1859       pad, NULL);
1860
1861     /* wait for the block */
1862   while (!gst_pad_is_blocking (pad))
1863     g_thread_yield ();
1864
1865   /* alternate 2 probes 100 times */
1866   for (r = 0; r < 100; r++) {
1867     called = FALSE;
1868     probe_b = gst_pad_add_probe (pad,
1869         GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1870         probe_block_ok, &called, NULL);
1871
1872     gst_pad_remove_probe (pad, probe_a);
1873
1874     /* wait for the callback */
1875     while (!called)
1876       g_thread_yield ();
1877
1878     called = FALSE;
1879     probe_a = gst_pad_add_probe (pad,
1880         GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1881         probe_block_ok, &called, NULL);
1882
1883     gst_pad_remove_probe (pad, probe_b);
1884
1885     /* wait for the callback */
1886     while (!called)
1887       g_thread_yield ();
1888   }
1889
1890   called = FALSE;
1891   gst_pad_add_probe (pad,
1892       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1893       probe_block_remove, &called, NULL);
1894
1895   gst_pad_remove_probe (pad, probe_a);
1896
1897   /* wait for the callback */
1898   while (!called)
1899     g_thread_yield ();
1900
1901   /* wait for the unblock */
1902   while (gst_pad_is_blocking (pad))
1903     g_thread_yield ();
1904
1905   gst_object_unref (pad);
1906   g_thread_join (thread);
1907 }
1908
1909 GST_END_TEST;
1910
1911 static gboolean src_flush_start_probe_called = FALSE;
1912 static gboolean src_flush_stop_probe_called = FALSE;
1913 static gboolean sink_flush_start_probe_called = FALSE;
1914 static gboolean sink_flush_stop_probe_called = FALSE;
1915
1916 static GstPadProbeReturn
1917 flush_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1918 {
1919   GstEvent *event;
1920
1921   if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_FLUSH))
1922     goto out;
1923
1924   event = gst_pad_probe_info_get_event (info);
1925   switch (GST_EVENT_TYPE (event)) {
1926     case GST_EVENT_FLUSH_START:
1927       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1928         src_flush_start_probe_called = TRUE;
1929       else
1930         sink_flush_start_probe_called = TRUE;
1931       break;
1932     case GST_EVENT_FLUSH_STOP:
1933       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1934         src_flush_stop_probe_called = TRUE;
1935       else
1936         sink_flush_stop_probe_called = TRUE;
1937       break;
1938     default:
1939       break;
1940   }
1941
1942 out:
1943   return GST_PAD_PROBE_OK;
1944 }
1945
1946 GST_START_TEST (test_pad_probe_flush_events)
1947 {
1948   GstPad *src, *sink;
1949
1950   src = gst_pad_new ("src", GST_PAD_SRC);
1951   sink = gst_pad_new ("sink", GST_PAD_SINK);
1952   gst_pad_set_chain_function (sink, gst_check_chain_func);
1953   gst_pad_set_active (src, TRUE);
1954   gst_pad_set_active (sink, TRUE);
1955
1956   fail_unless (gst_pad_push_event (src,
1957           gst_event_new_stream_start ("test")) == TRUE);
1958   fail_unless (gst_pad_push_event (src,
1959           gst_event_new_segment (&dummy_segment)) == TRUE);
1960
1961   fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1962
1963   gst_pad_add_probe (src,
1964       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1965       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1966   gst_pad_add_probe (sink,
1967       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1968       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1969
1970   gst_pad_push_event (src, gst_event_new_flush_start ());
1971   gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
1972
1973   fail_unless (gst_pad_push_event (src,
1974           gst_event_new_segment (&dummy_segment)) == TRUE);
1975
1976   /* push a buffer so the events are propagated downstream */
1977   gst_pad_push (src, gst_buffer_new ());
1978
1979   fail_unless (src_flush_start_probe_called);
1980   fail_unless (src_flush_stop_probe_called);
1981   fail_unless (sink_flush_start_probe_called);
1982   fail_unless (sink_flush_stop_probe_called);
1983
1984   gst_check_drop_buffers ();
1985   gst_object_unref (src);
1986   gst_object_unref (sink);
1987 }
1988
1989 GST_END_TEST;
1990
1991 static gboolean probe_was_called;
1992
1993 static GstPadProbeReturn
1994 flush_events_only_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
1995 {
1996   GST_LOG_OBJECT (pad, "%" GST_PTR_FORMAT, GST_PAD_PROBE_INFO_DATA (info));
1997
1998   probe_was_called = TRUE;
1999
2000   return GST_PAD_PROBE_OK;
2001 }
2002
2003 GST_START_TEST (test_pad_probe_flush_events_only)
2004 {
2005   GstPad *src, *sink;
2006
2007   src = gst_pad_new ("src", GST_PAD_SRC);
2008   sink = gst_pad_new ("sink", GST_PAD_SINK);
2009   gst_pad_set_chain_function (sink, gst_check_chain_func);
2010   gst_pad_set_active (src, TRUE);
2011   gst_pad_set_active (sink, TRUE);
2012
2013   fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
2014
2015   fail_unless (gst_pad_push_event (src,
2016           gst_event_new_stream_start ("test")) == TRUE);
2017
2018   gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_EVENT_FLUSH,
2019       flush_events_only_probe, NULL, NULL);
2020
2021   probe_was_called = FALSE;
2022   fail_unless (gst_pad_push_event (src,
2023           gst_event_new_segment (&dummy_segment)) == TRUE);
2024   fail_if (probe_was_called);
2025
2026   fail_unless_equals_int (gst_pad_push (src, gst_buffer_new ()), GST_FLOW_OK);
2027   fail_if (probe_was_called);
2028
2029   gst_pad_push_event (src, gst_event_new_flush_start ());
2030   fail_unless (probe_was_called);
2031
2032   probe_was_called = FALSE;
2033   gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
2034   fail_unless (probe_was_called);
2035
2036   gst_check_drop_buffers ();
2037   gst_object_unref (src);
2038   gst_object_unref (sink);
2039 }
2040
2041 GST_END_TEST;
2042
2043 #define NUM_PROBES 4
2044 static guint count;
2045
2046 static GstPadProbeReturn
2047 order_others_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2048 {
2049   *(guint *) (user_data) = ++count;
2050
2051   return GST_PAD_PROBE_REMOVE;
2052 }
2053
2054 GST_START_TEST (test_pad_probe_call_order)
2055 {
2056   GstFlowReturn flow;
2057   GstPad *src, *sink;
2058   guint counters[NUM_PROBES];
2059   guint i;
2060
2061   src = gst_pad_new ("src", GST_PAD_SRC);
2062   gst_pad_set_active (src, TRUE);
2063   sink = gst_pad_new ("sink", GST_PAD_SINK);
2064   gst_pad_set_chain_function (sink, gst_check_chain_func);
2065   gst_pad_set_active (sink, TRUE);
2066
2067   fail_unless (gst_pad_push_event (src,
2068           gst_event_new_stream_start ("test")) == TRUE);
2069   fail_unless (gst_pad_push_event (src,
2070           gst_event_new_segment (&dummy_segment)) == TRUE);
2071
2072   fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
2073
2074   for (i = 0; i < NUM_PROBES; i++) {
2075     gst_pad_add_probe (src,
2076         GST_PAD_PROBE_TYPE_BUFFER, order_others_probe_cb, &(counters[i]), NULL);
2077   }
2078
2079   /* push a buffer so the events are propagated downstream */
2080   flow = gst_pad_push (src, gst_buffer_new ());
2081   fail_unless_equals_int (flow, GST_FLOW_OK);
2082
2083   for (i = 0; i < NUM_PROBES; i++) {
2084     fail_unless (counters[i] == i + 1);
2085   }
2086
2087   gst_check_drop_buffers ();
2088   gst_object_unref (src);
2089   gst_object_unref (sink);
2090 }
2091
2092 GST_END_TEST;
2093
2094 static GstPadProbeReturn
2095 buffers_probe_handled (GstPad * pad, GstPadProbeInfo * info, gpointer gp)
2096 {
2097   if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER) {
2098     GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
2099
2100     GST_DEBUG_OBJECT (pad, "buffer: %" GST_PTR_FORMAT ", refcount: %d",
2101         buffer, (GST_MINI_OBJECT (buffer))->refcount);
2102     gst_buffer_unref (buffer);
2103   }
2104
2105   return GST_PAD_PROBE_HANDLED;
2106 }
2107
2108 static GstPadProbeReturn
2109 buffers_probe_drop (GstPad * pad, GstPadProbeInfo * info, gboolean * called)
2110 {
2111   if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER) {
2112     GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
2113
2114     GST_DEBUG_OBJECT (pad, "buffer: %" GST_PTR_FORMAT ", refcount: %d",
2115         buffer, (GST_MINI_OBJECT (buffer))->refcount);
2116     *called = TRUE;
2117   }
2118
2119   return GST_PAD_PROBE_DROP;
2120 }
2121
2122 GST_START_TEST (test_pad_probe_handled_and_drop)
2123 {
2124   GstFlowReturn flow;
2125   GstPad *src, *sink;
2126   gboolean called;
2127
2128   src = gst_pad_new ("src", GST_PAD_SRC);
2129   gst_pad_set_active (src, TRUE);
2130   sink = gst_pad_new ("sink", GST_PAD_SINK);
2131   gst_pad_set_chain_function (sink, gst_check_chain_func);
2132   gst_pad_set_active (sink, TRUE);
2133
2134   fail_unless (gst_pad_push_event (src,
2135           gst_event_new_stream_start ("test")) == TRUE);
2136   fail_unless (gst_pad_push_event (src,
2137           gst_event_new_segment (&dummy_segment)) == TRUE);
2138
2139   fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
2140
2141   gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
2142       (GstPadProbeCallback) buffers_probe_handled, NULL, NULL);
2143   gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
2144       (GstPadProbeCallback) buffers_probe_drop, &called, NULL);
2145
2146   called = FALSE;
2147   flow = gst_pad_push (src, gst_buffer_new ());
2148   fail_unless_equals_int (flow, GST_FLOW_OK);
2149   fail_if (called);
2150
2151   /* no buffer should have made it through to the sink pad, and especially
2152    * not a NULL pointer buffer */
2153   fail_if (buffers && buffers->data == NULL);
2154   fail_unless (buffers == NULL);
2155
2156   gst_object_unref (src);
2157   gst_object_unref (sink);
2158 }
2159
2160 GST_END_TEST;
2161
2162 static gboolean got_notify;
2163
2164 static void
2165 caps_notify (GstPad * pad, GParamSpec * spec, gpointer data)
2166 {
2167   got_notify = TRUE;
2168 }
2169
2170 static void
2171 test_queue_src_caps_notify (gboolean link_queue)
2172 {
2173   GstElement *queue;
2174   GstPad *src, *sink, *another_pad;
2175   GstCaps *caps;
2176
2177   queue = gst_element_factory_make ("queue", NULL);
2178   fail_unless (queue != NULL);
2179
2180   src = gst_element_get_static_pad (queue, "src");
2181   fail_unless (src != NULL);
2182
2183   sink = gst_element_get_static_pad (queue, "sink");
2184   fail_unless (sink != NULL);
2185
2186   if (link_queue) {
2187     another_pad = gst_pad_new ("sink", GST_PAD_SINK);
2188     fail_unless (another_pad != NULL);
2189     gst_pad_set_active (another_pad, TRUE);
2190
2191     gst_pad_link_full (src, another_pad, GST_PAD_LINK_CHECK_NOTHING);
2192   } else {
2193     another_pad = NULL;
2194   }
2195
2196   gst_element_set_state (queue, GST_STATE_PLAYING);
2197
2198   got_notify = FALSE;
2199
2200   g_signal_connect (src, "notify::caps", G_CALLBACK (caps_notify), NULL);
2201
2202   caps = gst_caps_from_string ("caps");
2203   gst_pad_send_event (sink, gst_event_new_caps (caps));
2204   gst_caps_unref (caps);
2205
2206   while (got_notify == FALSE)
2207     g_usleep (10000);
2208
2209   gst_element_set_state (queue, GST_STATE_NULL);
2210
2211   gst_object_unref (src);
2212   gst_object_unref (sink);
2213   gst_object_unref (queue);
2214   if (another_pad) {
2215     gst_object_unref (another_pad);
2216   }
2217 }
2218
2219 GST_START_TEST (test_queue_src_caps_notify_linked)
2220 {
2221   test_queue_src_caps_notify (TRUE);
2222 }
2223
2224 GST_END_TEST
2225 GST_START_TEST (test_queue_src_caps_notify_not_linked)
2226 {
2227   /* This test will fail because queue doesn't set the caps
2228      on src pad unless it is linked */
2229   test_queue_src_caps_notify (FALSE);
2230 }
2231
2232 GST_END_TEST;
2233
2234 #if 0
2235 static void
2236 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
2237 {
2238   gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
2239 }
2240
2241 static void
2242 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
2243 {
2244   static int n_calls = 0;
2245   gboolean *bool_user_data = (gboolean *) user_data;
2246
2247   if (++n_calls > 1)
2248     /* we expect this callback to be called only once */
2249     g_warn_if_reached ();
2250
2251   *bool_user_data = blocked;
2252
2253   /* replace block_async_first with block_async_second so next time the pad is
2254    * blocked the latter should be called */
2255   gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
2256
2257   /* unblock temporarily, in the next push block_async_second should be called
2258    */
2259   gst_pad_push_event (pad, gst_event_new_flush_start ());
2260 }
2261
2262 GST_START_TEST (test_block_async_replace_callback)
2263 {
2264   GstPad *pad;
2265   gboolean blocked;
2266
2267   pad = gst_pad_new ("src", GST_PAD_SRC);
2268   fail_unless (pad != NULL);
2269   gst_pad_set_active (pad, TRUE);
2270
2271   gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
2272   blocked = FALSE;
2273
2274   gst_pad_push (pad, gst_buffer_new ());
2275   fail_unless (blocked == TRUE);
2276   /* block_async_first flushes to unblock */
2277   gst_pad_push_event (pad, gst_event_new_flush_stop ());
2278
2279   /* push again, this time block_async_second should be called */
2280   gst_pad_push (pad, gst_buffer_new ());
2281   fail_unless (blocked == TRUE);
2282
2283   gst_object_unref (pad);
2284 }
2285
2286 GST_END_TEST;
2287 #endif
2288
2289 static void
2290 block_async_full_destroy (gpointer user_data)
2291 {
2292   gint *state = (gint *) user_data;
2293
2294   fail_unless (*state < 2);
2295
2296   GST_DEBUG ("setting state to 2");
2297   *state = 2;
2298 }
2299
2300 static GstPadProbeReturn
2301 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2302 {
2303   *(gint *) user_data = (gint) TRUE;
2304
2305   gst_pad_push_event (pad, gst_event_new_flush_start ());
2306   GST_DEBUG ("setting state to 1");
2307
2308   return GST_PAD_PROBE_OK;
2309 }
2310
2311 GST_START_TEST (test_block_async_full_destroy)
2312 {
2313   GstPad *pad;
2314   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
2315   gint state = 0;
2316   gulong id;
2317
2318   pad = gst_pad_new ("src", GST_PAD_SRC);
2319   fail_unless (pad != NULL);
2320   gst_pad_set_active (pad, TRUE);
2321
2322   fail_unless (gst_pad_push_event (pad,
2323           gst_event_new_stream_start ("test")) == TRUE);
2324   fail_unless (gst_pad_push_event (pad,
2325           gst_event_new_segment (&dummy_segment)) == TRUE);
2326
2327   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
2328       &state, block_async_full_destroy);
2329   fail_unless (state == 0);
2330
2331   gst_pad_push (pad, gst_buffer_new ());
2332   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
2333    */
2334   fail_unless (state == 1);
2335   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
2336
2337   /* unblock callback is called */
2338   gst_pad_remove_probe (pad, id);
2339   fail_unless (state == 2);
2340
2341   gst_object_unref (pad);
2342 }
2343
2344 GST_END_TEST;
2345
2346 GST_START_TEST (test_block_async_full_destroy_dispose)
2347 {
2348   GstPad *pad;
2349   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
2350   gint state = 0;
2351
2352   pad = gst_pad_new ("src", GST_PAD_SRC);
2353   fail_unless (pad != NULL);
2354   gst_pad_set_active (pad, TRUE);
2355
2356   fail_unless (gst_pad_push_event (pad,
2357           gst_event_new_stream_start ("test")) == TRUE);
2358   fail_unless (gst_pad_push_event (pad,
2359           gst_event_new_segment (&dummy_segment)) == TRUE);
2360
2361   (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
2362       &state, block_async_full_destroy);
2363
2364   gst_pad_push (pad, gst_buffer_new ());
2365   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
2366    */
2367   fail_unless_equals_int (state, 1);
2368   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
2369
2370   /* gst_BLOCK calls the destroy_notify function if necessary */
2371   gst_object_unref (pad);
2372
2373   fail_unless_equals_int (state, 2);
2374 }
2375
2376 GST_END_TEST;
2377
2378
2379 #if 0
2380 static void
2381 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
2382 {
2383   gboolean *bool_user_data = (gboolean *) user_data;
2384
2385   /* here we should have blocked == 1 unblocked == 0 */
2386
2387   fail_unless (blocked == FALSE);
2388
2389   fail_unless (bool_user_data[0] == TRUE);
2390   fail_unless (bool_user_data[1] == TRUE);
2391   fail_unless (bool_user_data[2] == FALSE);
2392
2393   bool_user_data[2] = TRUE;
2394 }
2395 #endif
2396
2397
2398 #if 0
2399 static void
2400 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
2401 {
2402   g_warn_if_reached ();
2403 }
2404 #endif
2405
2406 static GstPadProbeReturn
2407 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
2408     gpointer user_data)
2409 {
2410   gboolean *bool_user_data = (gboolean *) user_data;
2411
2412   GST_DEBUG ("second probe called");
2413
2414   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
2415
2416   fail_unless (bool_user_data[0] == TRUE);
2417   fail_unless (bool_user_data[1] == FALSE);
2418   fail_unless (bool_user_data[2] == FALSE);
2419
2420   bool_user_data[1] = TRUE;
2421
2422   GST_DEBUG ("removing second probe with id %lu", id);
2423   gst_pad_remove_probe (pad, id);
2424
2425   return GST_PAD_PROBE_OK;
2426 }
2427
2428 static GstPadProbeReturn
2429 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
2430     gpointer user_data)
2431 {
2432   static int n_calls = 0;
2433   gboolean *bool_user_data = (gboolean *) user_data;
2434
2435   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
2436
2437   GST_DEBUG ("first probe called");
2438
2439   if (++n_calls > 1)
2440     /* we expect this callback to be called only once */
2441     g_warn_if_reached ();
2442
2443   *bool_user_data = TRUE;
2444
2445   fail_unless (bool_user_data[0] == TRUE);
2446   fail_unless (bool_user_data[1] == FALSE);
2447   fail_unless (bool_user_data[2] == FALSE);
2448
2449   GST_DEBUG ("removing first probe with id %lu", id);
2450   gst_pad_remove_probe (pad, id);
2451
2452   GST_DEBUG ("adding second probe");
2453   /* replace block_async_first with block_async_second so next time the pad is
2454    * blocked the latter should be called */
2455   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
2456       block_async_second_no_flush, user_data, NULL);
2457   GST_DEBUG ("added probe with id %lu", id);
2458
2459   return GST_PAD_PROBE_OK;
2460 }
2461
2462 GST_START_TEST (test_block_async_replace_callback_no_flush)
2463 {
2464   GstPad *pad;
2465   gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
2466
2467   pad = gst_pad_new ("src", GST_PAD_SRC);
2468   fail_unless (pad != NULL);
2469   gst_pad_set_active (pad, TRUE);
2470
2471   fail_unless (gst_pad_push_event (pad,
2472           gst_event_new_stream_start ("test")) == TRUE);
2473   fail_unless (gst_pad_push_event (pad,
2474           gst_event_new_segment (&dummy_segment)) == TRUE);
2475
2476   GST_DEBUG ("adding probe");
2477   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
2478       block_async_first_no_flush, bool_user_data, NULL);
2479   GST_DEBUG ("added probe with id %lu", id);
2480   fail_if (id == 0);
2481
2482   GST_DEBUG ("pushing buffer");
2483   gst_pad_push (pad, gst_buffer_new ());
2484   fail_unless (bool_user_data[0] == TRUE);
2485   fail_unless (bool_user_data[1] == TRUE);
2486   fail_unless (bool_user_data[2] == FALSE);
2487
2488   gst_object_unref (pad);
2489 }
2490
2491 GST_END_TEST;
2492
2493 static gint sticky_count;
2494
2495 static gboolean
2496 test_sticky_events_handler (GstPad * pad, GstObject * parent, GstEvent * event)
2497 {
2498   GST_DEBUG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
2499
2500   switch (sticky_count) {
2501     case 0:
2502       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
2503       break;
2504     case 1:
2505     {
2506       GstCaps *caps;
2507       GstStructure *s;
2508
2509       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
2510
2511       gst_event_parse_caps (event, &caps);
2512       fail_unless (gst_caps_get_size (caps) == 1);
2513       s = gst_caps_get_structure (caps, 0);
2514       fail_unless (gst_structure_has_name (s, "foo/baz"));
2515       break;
2516     }
2517     case 2:
2518       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
2519       break;
2520     default:
2521       fail_unless (FALSE);
2522       break;
2523   }
2524
2525   gst_event_unref (event);
2526   sticky_count++;
2527
2528   return TRUE;
2529 }
2530
2531 static GstFlowReturn
2532 test_sticky_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2533 {
2534   gst_buffer_unref (buffer);
2535   return GST_FLOW_OK;
2536 }
2537
2538 GST_START_TEST (test_sticky_events)
2539 {
2540   GstPad *srcpad, *sinkpad;
2541   GstCaps *caps;
2542   GstSegment seg;
2543   gchar *id;
2544
2545   /* make unlinked srcpad */
2546   srcpad = gst_pad_new ("src", GST_PAD_SRC);
2547   fail_unless (srcpad != NULL);
2548   gst_pad_set_active (srcpad, TRUE);
2549
2550   /* test stream-start */
2551   fail_unless (gst_pad_get_stream_id (srcpad) == NULL);
2552
2553   /* push an event, it should be sticky on the srcpad */
2554   fail_unless (gst_pad_push_event (srcpad,
2555           gst_event_new_stream_start ("test")) == TRUE);
2556
2557   /* let's see if it stuck */
2558   id = gst_pad_get_stream_id (srcpad);
2559   fail_unless_equals_string (id, "test");
2560   g_free (id);
2561
2562   /* make a caps event */
2563   caps = gst_caps_new_empty_simple ("foo/bar");
2564   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
2565   gst_caps_unref (caps);
2566
2567   /* make segment event */
2568   gst_segment_init (&seg, GST_FORMAT_TIME);
2569   gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
2570
2571   /* now make a sinkpad */
2572   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2573   fail_unless (sinkpad != NULL);
2574   sticky_count = 0;
2575   gst_pad_set_event_function (sinkpad, test_sticky_events_handler);
2576   gst_pad_set_chain_function (sinkpad, test_sticky_chain);
2577   fail_unless (sticky_count == 0);
2578   gst_pad_set_active (sinkpad, TRUE);
2579
2580   /* link the pads */
2581   gst_pad_link (srcpad, sinkpad);
2582   /* should not trigger events */
2583   fail_unless (sticky_count == 0);
2584
2585   /* caps replaces old caps event at position 2, the pushes all
2586    * pending events */
2587   caps = gst_caps_new_empty_simple ("foo/baz");
2588   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
2589   gst_caps_unref (caps);
2590
2591   /* should have triggered 2 events, the segment event is still pending */
2592   fail_unless_equals_int (sticky_count, 2);
2593
2594   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2595
2596   /* should have triggered 3 events */
2597   fail_unless_equals_int (sticky_count, 3);
2598
2599   gst_object_unref (srcpad);
2600   gst_object_unref (sinkpad);
2601 }
2602
2603 GST_END_TEST;
2604
2605 static GstFlowReturn next_return;
2606
2607 static GstFlowReturn
2608 test_lastflow_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2609 {
2610   gst_buffer_unref (buffer);
2611   return next_return;
2612 }
2613
2614 GST_START_TEST (test_last_flow_return_push)
2615 {
2616   GstPad *srcpad, *sinkpad;
2617   GstSegment seg;
2618
2619   srcpad = gst_pad_new ("src", GST_PAD_SRC);
2620   fail_unless (srcpad != NULL);
2621   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2622   fail_unless (sinkpad != NULL);
2623   gst_pad_set_chain_function (sinkpad, test_lastflow_chain);
2624   gst_pad_link (srcpad, sinkpad);
2625
2626   /* initial value is flushing */
2627   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
2628
2629   /* when active it goes to ok */
2630   gst_pad_set_active (srcpad, TRUE);
2631   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2632   gst_pad_set_active (sinkpad, TRUE);
2633
2634   /* startup events */
2635   gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
2636   gst_segment_init (&seg, GST_FORMAT_TIME);
2637   gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
2638
2639
2640   /* push Ok */
2641   next_return = GST_FLOW_OK;
2642   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2643   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2644
2645   /* push not-linked */
2646   next_return = GST_FLOW_NOT_LINKED;
2647   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
2648   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
2649
2650   /* push not-linked */
2651   next_return = GST_FLOW_NOT_NEGOTIATED;
2652   fail_unless (gst_pad_push (srcpad,
2653           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
2654   fail_unless (gst_pad_get_last_flow_return (srcpad) ==
2655       GST_FLOW_NOT_NEGOTIATED);
2656
2657   /* push error */
2658   next_return = GST_FLOW_ERROR;
2659   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_ERROR);
2660   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
2661
2662   /* back to ok */
2663   next_return = GST_FLOW_OK;
2664   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2665   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2666
2667   /* unlinked push */
2668   gst_pad_unlink (srcpad, sinkpad);
2669   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
2670   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
2671
2672   gst_pad_link (srcpad, sinkpad);
2673   fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
2674   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
2675
2676   gst_object_unref (srcpad);
2677   gst_object_unref (sinkpad);
2678 }
2679
2680 GST_END_TEST;
2681
2682 static GstFlowReturn
2683 test_lastflow_getrange (GstPad * pad, GstObject * parent, guint64 offset,
2684     guint length, GstBuffer ** buf)
2685 {
2686   if (next_return == GST_FLOW_OK)
2687     *buf = gst_buffer_new ();
2688   else
2689     *buf = NULL;
2690   return next_return;
2691 }
2692
2693 static gboolean
2694 test_lastflow_activate_pull_func (GstPad * pad, GstObject * object)
2695 {
2696   return gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE);
2697 }
2698
2699 GST_START_TEST (test_last_flow_return_pull)
2700 {
2701   GstPad *srcpad, *sinkpad;
2702   GstBuffer *buf = NULL;
2703
2704   srcpad = gst_pad_new ("src", GST_PAD_SRC);
2705   fail_unless (srcpad != NULL);
2706   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2707   fail_unless (sinkpad != NULL);
2708   gst_pad_set_getrange_function (srcpad, test_lastflow_getrange);
2709   gst_pad_set_activate_function (sinkpad, test_lastflow_activate_pull_func);
2710   gst_pad_link (srcpad, sinkpad);
2711
2712   /* initial value is flushing */
2713   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
2714
2715   /* when active it goes to ok */
2716   gst_pad_set_active (sinkpad, TRUE);
2717   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2718   gst_pad_set_active (srcpad, TRUE);
2719
2720   /* pull Ok */
2721   next_return = GST_FLOW_OK;
2722   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2723   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2724   gst_buffer_unref (buf);
2725   buf = NULL;
2726
2727   /* pull not-linked */
2728   next_return = GST_FLOW_NOT_LINKED;
2729   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2730   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2731
2732   /* pull error */
2733   next_return = GST_FLOW_ERROR;
2734   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_ERROR);
2735   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
2736
2737   /* pull not-nego */
2738   next_return = GST_FLOW_NOT_NEGOTIATED;
2739   fail_unless (gst_pad_pull_range (sinkpad, 0, 1,
2740           &buf) == GST_FLOW_NOT_NEGOTIATED);
2741   fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
2742       GST_FLOW_NOT_NEGOTIATED);
2743
2744   /* pull ok again */
2745   next_return = GST_FLOW_OK;
2746   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2747   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2748   gst_buffer_unref (buf);
2749   buf = NULL;
2750
2751   /* unlinked pads */
2752   gst_pad_unlink (srcpad, sinkpad);
2753   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2754   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2755
2756   /* eos */
2757   gst_pad_link (srcpad, sinkpad);
2758   next_return = GST_FLOW_EOS;
2759   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_EOS);
2760   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
2761
2762   gst_object_unref (srcpad);
2763   gst_object_unref (sinkpad);
2764 }
2765
2766 GST_END_TEST;
2767
2768 GST_START_TEST (test_flush_stop_inactive)
2769 {
2770   GstPad *sinkpad, *srcpad;
2771
2772   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2773   fail_unless (sinkpad != NULL);
2774
2775   /* new pads are inactive and flushing */
2776   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2777   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2778
2779   /* this should fail, pad is inactive */
2780   fail_if (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2781
2782   /* nothing should have changed */
2783   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2784   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2785
2786   gst_pad_set_active (sinkpad, TRUE);
2787
2788   /* pad is now active an not flushing anymore */
2789   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2790   fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2791
2792   /* do flush, does not deactivate the pad */
2793   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_start ()));
2794   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2795   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2796
2797   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2798   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2799   fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2800
2801   gst_pad_set_active (sinkpad, FALSE);
2802   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2803   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2804
2805   gst_object_unref (sinkpad);
2806
2807   /* we should not be able to push on an inactive srcpad */
2808   srcpad = gst_pad_new ("src", GST_PAD_SRC);
2809   fail_unless (srcpad != NULL);
2810
2811   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2812   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2813
2814   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2815
2816   /* should still be inactive and flushing */
2817   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2818   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2819
2820   gst_pad_set_active (srcpad, TRUE);
2821
2822   /* pad is now active an not flushing anymore */
2823   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2824   fail_if (GST_PAD_IS_FLUSHING (srcpad));
2825
2826   /* do flush, does not deactivate the pad */
2827   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_start ()));
2828   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2829   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2830
2831   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2832   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2833   fail_if (GST_PAD_IS_FLUSHING (srcpad));
2834
2835   gst_pad_set_active (srcpad, FALSE);
2836   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2837   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2838
2839   gst_object_unref (srcpad);
2840 }
2841
2842 GST_END_TEST;
2843
2844 /* For proxy caps flag tests */
2845
2846 typedef struct _GstProxyTestElement GstProxyTestElement;
2847 typedef struct _GstProxyTestElementClass GstProxyTestElementClass;
2848
2849 struct _GstProxyTestElement
2850 {
2851   GstElement element;
2852 };
2853
2854 struct _GstProxyTestElementClass
2855 {
2856   GstElementClass parent_class;
2857 };
2858
2859 G_GNUC_INTERNAL GType gst_proxytestelement_get_type (void);
2860
2861 static GstStaticPadTemplate proxytestelement_peer_template =
2862 GST_STATIC_PAD_TEMPLATE ("sink",
2863     GST_PAD_SINK,
2864     GST_PAD_ALWAYS,
2865     GST_STATIC_CAPS ("test/proxy, option=(int)1"));
2866
2867 static GstStaticPadTemplate proxytestelement_peer_incompatible_template =
2868 GST_STATIC_PAD_TEMPLATE ("sink",
2869     GST_PAD_SINK,
2870     GST_PAD_ALWAYS,
2871     GST_STATIC_CAPS ("test/proxy-incompatible"));
2872
2873 static GstStaticPadTemplate proxytestelement_sink_template =
2874 GST_STATIC_PAD_TEMPLATE ("sink",
2875     GST_PAD_SINK,
2876     GST_PAD_ALWAYS,
2877     GST_STATIC_CAPS ("test/proxy"));
2878
2879 static GstStaticPadTemplate proxytestelement_src_template =
2880 GST_STATIC_PAD_TEMPLATE ("src",
2881     GST_PAD_SRC,
2882     GST_PAD_ALWAYS,
2883     GST_STATIC_CAPS_ANY);
2884
2885 G_DEFINE_TYPE (GstProxyTestElement, gst_proxytestelement, GST_TYPE_ELEMENT);
2886
2887 static void
2888 gst_proxytestelement_class_init (GstProxyTestElementClass * klass)
2889 {
2890   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
2891
2892   gst_element_class_set_static_metadata (gstelement_class,
2893       "Proxy Test Element", "Test", "Proxy test element",
2894       "Thiago Santos <thiagoss@osg.samsung.com>");
2895
2896   gst_element_class_add_static_pad_template (gstelement_class,
2897       &proxytestelement_sink_template);
2898 }
2899
2900 static void
2901 gst_proxytestelement_init (GstProxyTestElement * element)
2902 {
2903   GstPad *sinkpad;
2904   sinkpad =
2905       gst_pad_new_from_static_template (&proxytestelement_sink_template,
2906       "sink");
2907   GST_PAD_SET_PROXY_CAPS (sinkpad);
2908   gst_element_add_pad (GST_ELEMENT_CAST (element), sinkpad);
2909 }
2910
2911 GST_START_TEST (test_proxy_accept_caps_no_proxy)
2912 {
2913   GstElement *element;
2914   GstPad *sinkpad;
2915   GstCaps *caps;
2916
2917   gst_element_register (NULL, "proxytestelement", GST_RANK_NONE,
2918       gst_proxytestelement_get_type ());
2919   element = gst_element_factory_make ("proxytestelement", NULL);
2920   sinkpad = gst_element_get_static_pad (element, "sink");
2921
2922   gst_element_set_state (element, GST_STATE_PLAYING);
2923
2924   caps = gst_caps_from_string ("test/proxy");
2925   fail_unless (gst_pad_query_accept_caps (sinkpad, caps));
2926   gst_caps_unref (caps);
2927
2928   caps = gst_caps_from_string ("test/bad");
2929   fail_if (gst_pad_query_accept_caps (sinkpad, caps));
2930   gst_caps_unref (caps);
2931
2932   gst_object_unref (sinkpad);
2933   gst_element_set_state (element, GST_STATE_NULL);
2934   gst_object_unref (element);
2935 }
2936
2937 GST_END_TEST;
2938
2939
2940 GST_START_TEST (test_proxy_accept_caps_with_proxy)
2941 {
2942   GstElement *element;
2943   GstPad *sinkpad, *srcpad;
2944   GstPad *peerpad;
2945   GstCaps *caps;
2946
2947   gst_element_register (NULL, "proxytestelement", GST_RANK_NONE,
2948       gst_proxytestelement_get_type ());
2949   element = gst_element_factory_make ("proxytestelement", NULL);
2950
2951   srcpad =
2952       gst_pad_new_from_static_template (&proxytestelement_src_template, "src");
2953   gst_element_add_pad (GST_ELEMENT_CAST (element), srcpad);
2954
2955   sinkpad = gst_element_get_static_pad (element, "sink");
2956   srcpad = gst_element_get_static_pad (element, "src");
2957
2958   peerpad =
2959       gst_pad_new_from_static_template (&proxytestelement_peer_template,
2960       "sink");
2961   fail_unless (gst_pad_link (srcpad, peerpad) == GST_PAD_LINK_OK);
2962   gst_pad_set_active (peerpad, TRUE);
2963
2964   gst_element_set_state (element, GST_STATE_PLAYING);
2965
2966   caps = gst_caps_from_string ("test/bad");
2967   fail_if (gst_pad_query_accept_caps (sinkpad, caps));
2968   gst_caps_unref (caps);
2969
2970   caps = gst_caps_from_string ("test/proxy, option=(int)1");
2971   fail_unless (gst_pad_query_accept_caps (sinkpad, caps));
2972   gst_caps_unref (caps);
2973
2974   caps = gst_caps_from_string ("test/proxy, option=(int)2");
2975   fail_if (gst_pad_query_accept_caps (sinkpad, caps));
2976   gst_caps_unref (caps);
2977
2978   gst_object_unref (sinkpad);
2979   gst_object_unref (srcpad);
2980   gst_pad_set_active (peerpad, FALSE);
2981   gst_object_unref (peerpad);
2982   gst_element_set_state (element, GST_STATE_NULL);
2983   gst_object_unref (element);
2984 }
2985
2986 GST_END_TEST;
2987
2988 GST_START_TEST (test_proxy_accept_caps_with_incompatible_proxy)
2989 {
2990   GstElement *element;
2991   GstPad *sinkpad, *srcpad;
2992   GstPad *peerpad;
2993   GstCaps *caps;
2994
2995   gst_element_register (NULL, "proxytestelement", GST_RANK_NONE,
2996       gst_proxytestelement_get_type ());
2997   element = gst_element_factory_make ("proxytestelement", NULL);
2998
2999   srcpad =
3000       gst_pad_new_from_static_template (&proxytestelement_src_template, "src");
3001   gst_element_add_pad (GST_ELEMENT_CAST (element), srcpad);
3002
3003   sinkpad = gst_element_get_static_pad (element, "sink");
3004   srcpad = gst_element_get_static_pad (element, "src");
3005
3006   peerpad =
3007       gst_pad_new_from_static_template
3008       (&proxytestelement_peer_incompatible_template, "sink");
3009   fail_unless (gst_pad_link (srcpad, peerpad) == GST_PAD_LINK_OK);
3010
3011   gst_element_set_state (element, GST_STATE_PLAYING);
3012
3013   caps = gst_caps_from_string ("test/bad");
3014   fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3015   gst_caps_unref (caps);
3016
3017   caps = gst_caps_from_string ("test/proxy");
3018   fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3019   gst_caps_unref (caps);
3020
3021   caps = gst_caps_from_string ("test/proxy-incompatible");
3022   fail_if (gst_pad_query_accept_caps (sinkpad, caps));
3023   gst_caps_unref (caps);
3024
3025   gst_object_unref (sinkpad);
3026   gst_object_unref (srcpad);
3027   gst_pad_set_active (peerpad, FALSE);
3028   gst_object_unref (peerpad);
3029   gst_element_set_state (element, GST_STATE_NULL);
3030   gst_object_unref (element);
3031 }
3032
3033 GST_END_TEST;
3034
3035 static GstSegment sink_segment;
3036 static gint sink_segment_counter;
3037
3038 static gboolean
3039 segment_event_func (GstPad * pad, GstObject * parent, GstEvent * event)
3040 {
3041   switch (GST_EVENT_TYPE (event)) {
3042     case GST_EVENT_SEGMENT:
3043       gst_event_copy_segment (event, &sink_segment);
3044       sink_segment_counter++;
3045       break;
3046     default:
3047       break;
3048   }
3049
3050   gst_event_unref (event);
3051   return TRUE;
3052 }
3053
3054 static void
3055 test_pad_offset (gboolean on_srcpad)
3056 {
3057   GstPad *srcpad, *sinkpad, *offset_pad;
3058   GstSegment segment;
3059   GstBuffer *buffer;
3060   GstQuery *query;
3061
3062   srcpad = gst_pad_new ("src", GST_PAD_SRC);
3063   fail_unless (srcpad != NULL);
3064   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
3065
3066   offset_pad = on_srcpad ? srcpad : sinkpad;
3067
3068   gst_segment_init (&sink_segment, GST_FORMAT_UNDEFINED);
3069   sink_segment_counter = 0;
3070   gst_pad_set_chain_function (sinkpad, gst_check_chain_func);
3071   gst_pad_set_event_function (sinkpad, segment_event_func);
3072
3073   fail_unless (sinkpad != NULL);
3074   fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK);
3075   fail_unless (gst_pad_set_active (sinkpad, TRUE));
3076   fail_unless (gst_pad_set_active (srcpad, TRUE));
3077
3078   /* Set an offset of 5s, meaning:
3079    * segment position 0 gives running time 5s, stream time 0s
3080    * segment start of 0 should stay 0
3081    */
3082   gst_pad_set_offset (offset_pad, 5 * GST_SECOND);
3083
3084   fail_unless (gst_pad_push_event (srcpad,
3085           gst_event_new_stream_start ("test")) == TRUE);
3086   /* We should have no segment event yet */
3087   fail_if (sink_segment.format != GST_FORMAT_UNDEFINED);
3088   fail_unless_equals_int (sink_segment_counter, 0);
3089
3090   /* Send segment event, expect it to arrive with a modified start running time */
3091   gst_segment_init (&segment, GST_FORMAT_TIME);
3092   fail_unless (gst_pad_push_event (srcpad,
3093           gst_event_new_segment (&segment)) == TRUE);
3094   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3095   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3096           GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3097   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3098           GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3099   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3100
3101   fail_unless_equals_int (sink_segment_counter, 1);
3102
3103   /* Send a buffer and check if all timestamps are as expected, and especially
3104    * if the buffer timestamp was not changed */
3105   buffer = gst_buffer_new ();
3106   GST_BUFFER_PTS (buffer) = 0 * GST_SECOND;
3107   fail_unless_equals_int (gst_pad_push (srcpad, buffer), GST_FLOW_OK);
3108
3109   fail_unless_equals_int (g_list_length (buffers), 1);
3110   buffer = buffers->data;
3111   buffers = g_list_delete_link (buffers, buffers);
3112   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3113           GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 5 * GST_SECOND);
3114   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3115           GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 0 * GST_SECOND);
3116   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0 * GST_SECOND);
3117   gst_buffer_unref (buffer);
3118
3119   fail_unless_equals_int (sink_segment_counter, 1);
3120
3121   /* Set a negative offset of -5s, meaning:
3122    * segment position 5s gives running time 0s, stream time 5s
3123    * segment start would have a negative running time!
3124    */
3125   gst_pad_set_offset (offset_pad, -5 * GST_SECOND);
3126
3127   /* Segment should still be the same as before */
3128   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3129   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3130           GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3131   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3132           GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3133   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3134
3135   fail_unless_equals_int (sink_segment_counter, 1);
3136
3137   /* Send segment event, expect it to arrive with a modified start running time */
3138   gst_segment_init (&segment, GST_FORMAT_TIME);
3139   fail_unless (gst_pad_push_event (srcpad,
3140           gst_event_new_segment (&segment)) == TRUE);
3141   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3142   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3143           GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3144       0 * GST_SECOND);
3145   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3146           GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3147       5 * GST_SECOND);
3148   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3149
3150   fail_unless_equals_int (sink_segment_counter, 2);
3151
3152   /* Send a buffer and check if all timestamps are as expected, and especially
3153    * if the buffer timestamp was not changed */
3154   buffer = gst_buffer_new ();
3155   GST_BUFFER_PTS (buffer) = 5 * GST_SECOND;
3156   fail_unless_equals_int (gst_pad_push (srcpad, buffer), GST_FLOW_OK);
3157
3158   fail_unless_equals_int (g_list_length (buffers), 1);
3159   buffer = buffers->data;
3160   buffers = g_list_delete_link (buffers, buffers);
3161   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3162           GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 0 * GST_SECOND);
3163   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3164           GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 5 * GST_SECOND);
3165   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 5 * GST_SECOND);
3166   gst_buffer_unref (buffer);
3167
3168   fail_unless_equals_int (sink_segment_counter, 2);
3169
3170   /* Set offset to 5s again, same situation as above but don't send a new
3171    * segment event. The segment should be adjusted *before* the buffer comes
3172    * out of the srcpad */
3173   gst_pad_set_offset (offset_pad, 5 * GST_SECOND);
3174
3175   /* Segment should still be the same as before */
3176   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3177   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3178           GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3179       0 * GST_SECOND);
3180   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3181           GST_FORMAT_TIME, sink_segment.start + 5 * GST_SECOND),
3182       5 * GST_SECOND);
3183   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3184
3185   fail_unless_equals_int (sink_segment_counter, 2);
3186
3187   /* Send a buffer and check if a new segment event was sent and all buffer
3188    * timestamps are as expected */
3189   buffer = gst_buffer_new ();
3190   GST_BUFFER_PTS (buffer) = 0 * GST_SECOND;
3191   fail_unless_equals_int (gst_pad_push (srcpad, buffer), GST_FLOW_OK);
3192
3193   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3194   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3195           GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3196   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3197           GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3198   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3199
3200   fail_unless_equals_int (sink_segment_counter, 3);
3201
3202   fail_unless_equals_int (g_list_length (buffers), 1);
3203   buffer = buffers->data;
3204   buffers = g_list_delete_link (buffers, buffers);
3205   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3206           GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 5 * GST_SECOND);
3207   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3208           GST_FORMAT_TIME, GST_BUFFER_PTS (buffer)), 0 * GST_SECOND);
3209   fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer), 0 * GST_SECOND);
3210   gst_buffer_unref (buffer);
3211
3212   fail_unless_equals_int (sink_segment_counter, 3);
3213
3214   /* Set offset to 10s and send another sticky event. In between a new
3215    * segment event should've been sent */
3216   gst_pad_set_offset (offset_pad, 10 * GST_SECOND);
3217
3218   /* Segment should still be the same as before */
3219   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3220   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3221           GST_FORMAT_TIME, sink_segment.start), 5 * GST_SECOND);
3222   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3223           GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3224   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3225   fail_unless_equals_int (sink_segment_counter, 3);
3226
3227   fail_unless (gst_pad_push_event (srcpad,
3228           gst_event_new_tag (gst_tag_list_new_empty ())) == TRUE);
3229
3230   /* Segment should be updated */
3231   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3232   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3233           GST_FORMAT_TIME, sink_segment.start), 10 * GST_SECOND);
3234   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3235           GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3236   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3237
3238   fail_unless_equals_int (sink_segment_counter, 4);
3239
3240   /* Set offset to 15s and do a serialized query. In between a new
3241    * segment event should've been sent */
3242   gst_pad_set_offset (offset_pad, 15 * GST_SECOND);
3243
3244   /* Segment should still be the same as before */
3245   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3246   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3247           GST_FORMAT_TIME, sink_segment.start), 10 * GST_SECOND);
3248   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3249           GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3250   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3251   fail_unless_equals_int (sink_segment_counter, 4);
3252
3253   query = gst_query_new_drain ();
3254   gst_pad_peer_query (srcpad, query);
3255   gst_query_unref (query);
3256
3257   /* Segment should be updated */
3258   fail_if (sink_segment.format == GST_FORMAT_UNDEFINED);
3259   fail_unless_equals_uint64 (gst_segment_to_running_time (&sink_segment,
3260           GST_FORMAT_TIME, sink_segment.start), 15 * GST_SECOND);
3261   fail_unless_equals_uint64 (gst_segment_to_stream_time (&sink_segment,
3262           GST_FORMAT_TIME, sink_segment.start), 0 * GST_SECOND);
3263   fail_unless_equals_uint64 (sink_segment.start, 0 * GST_SECOND);
3264
3265   fail_unless_equals_int (sink_segment_counter, 5);
3266
3267   gst_check_drop_buffers ();
3268
3269   fail_unless (gst_pad_set_active (sinkpad, FALSE));
3270   fail_unless (gst_pad_set_active (srcpad, FALSE));
3271   gst_object_unref (sinkpad);
3272   gst_object_unref (srcpad);
3273 }
3274
3275 GST_START_TEST (test_pad_offset_src)
3276 {
3277   test_pad_offset (TRUE);
3278 }
3279
3280 GST_END_TEST;
3281
3282 static Suite *
3283 gst_pad_suite (void)
3284 {
3285   Suite *s = suite_create ("GstPad");
3286   TCase *tc_chain = tcase_create ("general");
3287
3288   /* turn off timeout */
3289   tcase_set_timeout (tc_chain, 60);
3290
3291   gst_segment_init (&dummy_segment, GST_FORMAT_BYTES);
3292
3293   suite_add_tcase (s, tc_chain);
3294   tcase_add_test (tc_chain, test_link);
3295   tcase_add_test (tc_chain, test_refcount);
3296   tcase_add_test (tc_chain, test_get_allowed_caps);
3297   tcase_add_test (tc_chain, test_sticky_caps_unlinked);
3298   tcase_add_test (tc_chain, test_sticky_caps_unlinked_incompatible);
3299   tcase_add_test (tc_chain, test_sticky_caps_flushing);
3300   tcase_add_test (tc_chain, test_default_accept_caps);
3301   tcase_add_test (tc_chain, test_link_unlink_threaded);
3302   tcase_add_test (tc_chain, test_name_is_valid);
3303   tcase_add_test (tc_chain, test_push_unlinked);
3304   tcase_add_test (tc_chain, test_push_linked);
3305   tcase_add_test (tc_chain, test_push_linked_flushing);
3306   tcase_add_test (tc_chain, test_push_buffer_list_compat);
3307   tcase_add_test (tc_chain, test_flowreturn);
3308   tcase_add_test (tc_chain, test_push_negotiation);
3309   tcase_add_test (tc_chain, test_src_unref_unlink);
3310   tcase_add_test (tc_chain, test_sink_unref_unlink);
3311   tcase_add_test (tc_chain, test_block_async);
3312   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_block);
3313   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_blocking);
3314   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_idle);
3315   tcase_add_test (tc_chain, test_pad_probe_pull);
3316   tcase_add_test (tc_chain, test_pad_probe_pull_idle);
3317   tcase_add_test (tc_chain, test_pad_probe_pull_buffer);
3318   tcase_add_test (tc_chain, test_pad_probe_remove);
3319   tcase_add_test (tc_chain, test_pad_probe_block_add_remove);
3320   tcase_add_test (tc_chain, test_pad_probe_block_and_drop_buffer);
3321   tcase_add_test (tc_chain, test_pad_probe_flush_events);
3322   tcase_add_test (tc_chain, test_pad_probe_flush_events_only);
3323   tcase_add_test (tc_chain, test_pad_probe_call_order);
3324   tcase_add_test (tc_chain, test_pad_probe_handled_and_drop);
3325   tcase_add_test (tc_chain, test_events_query_unlinked);
3326   tcase_add_test (tc_chain, test_queue_src_caps_notify_linked);
3327   tcase_add_test (tc_chain, test_queue_src_caps_notify_not_linked);
3328 #if 0
3329   tcase_add_test (tc_chain, test_block_async_replace_callback);
3330 #endif
3331   tcase_add_test (tc_chain, test_block_async_full_destroy);
3332   tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
3333   tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
3334   tcase_add_test (tc_chain, test_sticky_events);
3335   tcase_add_test (tc_chain, test_last_flow_return_push);
3336   tcase_add_test (tc_chain, test_last_flow_return_pull);
3337   tcase_add_test (tc_chain, test_flush_stop_inactive);
3338   tcase_add_test (tc_chain, test_proxy_accept_caps_no_proxy);
3339   tcase_add_test (tc_chain, test_proxy_accept_caps_with_proxy);
3340   tcase_add_test (tc_chain, test_proxy_accept_caps_with_incompatible_proxy);
3341   tcase_add_test (tc_chain, test_pad_offset_src);
3342
3343   return s;
3344 }
3345
3346 GST_CHECK_MAIN (gst_pad);