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