tests: pad: test that idle probe will block
[platform/upstream/gstreamer.git] / tests / check / gst / gstpad.c
1 /* GStreamer
2  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
3  *
4  * gstpad.c: Unit test for GstPad
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #include <gst/check/gstcheck.h>
23
24 static GstSegment dummy_segment;
25
26 GST_START_TEST (test_link)
27 {
28   GstPad *src, *sink;
29   GstPadTemplate *srct;
30
31   GstPadLinkReturn ret;
32   gchar *name;
33
34   src = gst_pad_new ("source", GST_PAD_SRC);
35   fail_if (src == NULL);
36   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
37
38   name = gst_pad_get_name (src);
39   fail_unless (strcmp (name, "source") == 0);
40   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
41   g_free (name);
42
43   sink = gst_pad_new ("sink", GST_PAD_SINK);
44   fail_if (sink == NULL);
45
46   /* linking without templates or caps should work */
47   ret = gst_pad_link (src, sink);
48   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
49   ASSERT_OBJECT_REFCOUNT (sink, "sink pad", 1);
50   fail_unless (ret == GST_PAD_LINK_OK);
51
52   ASSERT_CRITICAL (gst_pad_get_pad_template (NULL));
53
54   srct = gst_pad_get_pad_template (src);
55   fail_unless (srct == NULL);
56   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
57
58   /* clean up */
59   ASSERT_OBJECT_REFCOUNT (src, "source pad", 1);
60   gst_object_unref (src);
61   gst_object_unref (sink);
62 }
63
64 GST_END_TEST;
65
66 /* threaded link/unlink */
67 /* use globals */
68 static GstPad *src, *sink;
69
70 static void
71 thread_link_unlink (gpointer data)
72 {
73   THREAD_START ();
74
75   while (THREAD_TEST_RUNNING ()) {
76     gst_pad_link (src, sink);
77     gst_pad_unlink (src, sink);
78     THREAD_SWITCH ();
79   }
80 }
81
82 GST_START_TEST (test_link_unlink_threaded)
83 {
84   GstCaps *caps;
85   int i;
86
87   src = gst_pad_new ("source", GST_PAD_SRC);
88   fail_if (src == NULL);
89   sink = gst_pad_new ("sink", GST_PAD_SINK);
90   fail_if (sink == NULL);
91
92   caps = gst_caps_from_string ("foo/bar");
93   gst_pad_set_active (src, TRUE);
94   gst_pad_set_caps (src, caps);
95   gst_pad_set_active (sink, TRUE);
96   gst_pad_set_caps (sink, caps);
97   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
98
99   MAIN_START_THREADS (5, thread_link_unlink, NULL);
100   for (i = 0; i < 1000; ++i) {
101     gst_pad_is_linked (src);
102     gst_pad_is_linked (sink);
103     THREAD_SWITCH ();
104   }
105   MAIN_STOP_THREADS ();
106
107   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
108   gst_caps_unref (caps);
109
110   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
111   gst_object_unref (src);
112   gst_object_unref (sink);
113 }
114
115 GST_END_TEST;
116
117 GST_START_TEST (test_refcount)
118 {
119   GstPad *src, *sink;
120   GstCaps *caps;
121   GstPadLinkReturn plr;
122
123   sink = gst_pad_new ("sink", GST_PAD_SINK);
124   fail_if (sink == NULL);
125
126   src = gst_pad_new ("src", GST_PAD_SRC);
127   fail_if (src == NULL);
128
129   caps = gst_caps_from_string ("foo/bar");
130   /* one for me */
131   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
132
133   /* can't set caps on flushing sinkpad */
134   fail_if (gst_pad_set_caps (src, caps) == TRUE);
135   fail_if (gst_pad_set_caps (sink, caps) == TRUE);
136   /* one for me and one for each set_caps */
137   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
138
139   gst_pad_set_active (src, TRUE);
140   fail_unless (gst_pad_set_caps (src, caps) == TRUE);
141   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
142
143   gst_pad_set_active (sink, TRUE);
144   fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
145   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
146
147   plr = gst_pad_link (src, sink);
148   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
149   /* src caps added to pending caps on sink */
150   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
151
152   gst_pad_unlink (src, sink);
153   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
154
155   /* cleanup */
156   gst_object_unref (src);
157   gst_object_unref (sink);
158   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
159
160   gst_caps_unref (caps);
161 }
162
163 GST_END_TEST;
164
165 GST_START_TEST (test_get_allowed_caps)
166 {
167   GstPad *src, *sink;
168   GstCaps *caps, *gotcaps;
169   GstBuffer *buffer;
170   GstPadLinkReturn plr;
171
172   ASSERT_CRITICAL (gst_pad_get_allowed_caps (NULL));
173
174   buffer = gst_buffer_new ();
175   ASSERT_CRITICAL (gst_pad_get_allowed_caps ((GstPad *) buffer));
176   gst_buffer_unref (buffer);
177
178   src = gst_pad_new ("src", GST_PAD_SRC);
179   fail_if (src == NULL);
180   caps = gst_pad_get_allowed_caps (src);
181   fail_unless (caps == NULL);
182
183   caps = gst_caps_from_string ("foo/bar");
184
185   sink = gst_pad_new ("sink", GST_PAD_SINK);
186   gst_pad_set_active (src, TRUE);
187   /* source pad is active and will accept the caps event */
188   fail_unless (gst_pad_set_caps (src, caps) == TRUE);
189   /* sink pad is not active and will refuse the caps event */
190   fail_if (gst_pad_set_caps (sink, caps) == TRUE);
191   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
192
193   gst_pad_set_active (sink, TRUE);
194   /* sink pad is now active and will accept the caps event */
195   fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
196   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
197
198   plr = gst_pad_link (src, sink);
199   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
200
201   gotcaps = gst_pad_get_allowed_caps (src);
202   fail_if (gotcaps == NULL);
203   fail_unless (gst_caps_is_equal (gotcaps, caps));
204
205   ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 4);
206   gst_caps_unref (gotcaps);
207
208   gst_pad_unlink (src, sink);
209
210   /* cleanup */
211   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
212   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
213   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
214
215   gst_object_unref (src);
216   gst_object_unref (sink);
217
218   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
219   gst_caps_unref (caps);
220 }
221
222 GST_END_TEST;
223
224 static GstCaps *event_caps = NULL;
225
226 static gboolean
227 sticky_event (GstPad * pad, GstObject * parent, GstEvent * event)
228 {
229   GstCaps *caps;
230
231   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS
232       || GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START
233       || GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
234
235   if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
236     gst_event_unref (event);
237     return TRUE;
238   }
239
240   /* Ensure we get here just once: */
241   fail_unless (event_caps == NULL);
242
243   /* The event must arrive before any buffer: */
244   fail_unless_equals_int (g_list_length (buffers), 0);
245
246   gst_event_parse_caps (event, &caps);
247   event_caps = gst_caps_ref (caps);
248
249   gst_event_unref (event);
250
251   return TRUE;
252 }
253
254 /* Tests whether caps get properly forwarded when pads
255    are initially unlinked */
256 GST_START_TEST (test_sticky_caps_unlinked)
257 {
258   GstCaps *caps;
259   GstPadTemplate *src_template, *sink_template;
260   GstPad *src, *sink;
261   GstEvent *event;
262
263   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
264   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
265       GST_PAD_ALWAYS, caps);
266   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
267       GST_PAD_ALWAYS, caps);
268   gst_caps_unref (caps);
269
270   src = gst_pad_new_from_template (src_template, "src");
271   fail_if (src == NULL);
272   sink = gst_pad_new_from_template (sink_template, "sink");
273   fail_if (sink == NULL);
274   gst_pad_set_event_function (sink, sticky_event);
275   gst_pad_set_chain_function (sink, gst_check_chain_func);
276
277   gst_object_unref (src_template);
278   gst_object_unref (sink_template);
279
280   gst_pad_set_active (src, TRUE);
281
282   fail_unless (gst_pad_push_event (src,
283           gst_event_new_stream_start ("test")) == TRUE);
284
285   caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
286   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
287
288   event = gst_event_new_caps (caps);
289   fail_unless (gst_pad_push_event (src, event) == TRUE);
290   fail_unless (event_caps == NULL);
291
292   fail_unless (gst_pad_push_event (src,
293           gst_event_new_segment (&dummy_segment)) == TRUE);
294
295   /* Linking and activating will not forward the sticky event yet... */
296   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
297   gst_pad_set_active (sink, TRUE);
298   fail_unless (event_caps == NULL);
299
300   /* ...but the first buffer will: */
301   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
302   fail_unless (event_caps == caps);
303   fail_unless_equals_int (g_list_length (buffers), 1);
304
305   gst_check_drop_buffers ();
306
307   gst_caps_replace (&caps, NULL);
308   gst_caps_replace (&event_caps, NULL);
309   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
310   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
311   gst_object_unref (src);
312   gst_object_unref (sink);
313 }
314
315 GST_END_TEST;
316
317 /* Same as test_sticky_caps_unlinked except that the source pad
318  * has a template of ANY and we will attempt to push
319  * incompatible caps */
320 GST_START_TEST (test_sticky_caps_unlinked_incompatible)
321 {
322   GstCaps *caps, *failcaps;
323   GstPadTemplate *src_template, *sink_template;
324   GstPad *src, *sink;
325   GstEvent *event;
326
327   /* Source pad has ANY caps
328    * Sink pad has foobar caps
329    * We will push the pony express caps (which should fail)
330    */
331   caps = gst_caps_new_any ();
332   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
333       GST_PAD_ALWAYS, caps);
334   gst_caps_unref (caps);
335   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
336   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
337       GST_PAD_ALWAYS, caps);
338   gst_caps_unref (caps);
339
340   src = gst_pad_new_from_template (src_template, "src");
341   fail_if (src == NULL);
342   sink = gst_pad_new_from_template (sink_template, "sink");
343   fail_if (sink == NULL);
344   gst_pad_set_event_function (sink, sticky_event);
345   gst_pad_set_chain_function (sink, gst_check_chain_func);
346
347   gst_object_unref (src_template);
348   gst_object_unref (sink_template);
349
350   gst_pad_set_active (src, TRUE);
351
352   fail_unless (gst_pad_push_event (src,
353           gst_event_new_stream_start ("test")) == TRUE);
354
355   failcaps = gst_caps_from_string ("pony/express, failure=(boolean)true");
356   ASSERT_CAPS_REFCOUNT (failcaps, "caps", 1);
357
358   event = gst_event_new_caps (failcaps);
359   gst_caps_unref (failcaps);
360   /* The pad isn't linked yet, and anything matches the source pad template
361    * (which is ANY) */
362   fail_unless (gst_pad_push_event (src, event) == TRUE);
363   fail_unless (event_caps == NULL);
364
365   fail_unless (gst_pad_push_event (src,
366           gst_event_new_segment (&dummy_segment)) == TRUE);
367
368   /* Linking and activating will not forward the sticky event yet... */
369   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
370   gst_pad_set_active (sink, TRUE);
371   fail_unless (event_caps == NULL);
372
373   /* ...but the first buffer will and should FAIL since the caps 
374    * are not compatible */
375   fail_unless (gst_pad_push (src,
376           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
377   /* We shouldn't have received the caps event since it's incompatible */
378   fail_unless (event_caps == NULL);
379   /* We shouldn't have received any buffers since caps are incompatible */
380   fail_unless_equals_int (g_list_length (buffers), 0);
381
382   gst_check_drop_buffers ();
383
384   gst_caps_replace (&event_caps, NULL);
385
386   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
387   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
388   gst_object_unref (src);
389   gst_object_unref (sink);
390 }
391
392 GST_END_TEST;
393
394 /* Like test_sticky_caps_unlinked, but link before caps: */
395
396 GST_START_TEST (test_sticky_caps_flushing)
397 {
398   GstCaps *caps;
399   GstPadTemplate *src_template, *sink_template;
400   GstPad *src, *sink;
401   GstEvent *event;
402
403   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
404   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
405       GST_PAD_ALWAYS, caps);
406   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
407       GST_PAD_ALWAYS, caps);
408   gst_caps_unref (caps);
409
410   src = gst_pad_new_from_template (src_template, "src");
411   fail_if (src == NULL);
412   sink = gst_pad_new_from_template (sink_template, "sink");
413   fail_if (sink == NULL);
414   gst_pad_set_event_function (sink, sticky_event);
415   gst_pad_set_chain_function (sink, gst_check_chain_func);
416
417   gst_object_unref (src_template);
418   gst_object_unref (sink_template);
419
420   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
421
422   caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
423   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
424
425   event = gst_event_new_caps (caps);
426
427   gst_pad_set_active (src, TRUE);
428   fail_unless (gst_pad_push_event (src,
429           gst_event_new_stream_start ("test")) == TRUE);
430   /* The caps event gets accepted by the source pad (and stored) */
431   fail_unless (gst_pad_push_event (src, event) == TRUE);
432   /* But wasn't forwarded since the sink pad is flushing (not activated) */
433   fail_unless (event_caps == NULL);
434
435   fail_unless (gst_pad_push_event (src,
436           gst_event_new_segment (&dummy_segment)) == TRUE);
437
438   /* Activating will not forward the sticky event yet... */
439   gst_pad_set_active (sink, TRUE);
440   fail_unless (event_caps == NULL);
441
442   /* ...but the first buffer will: */
443   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
444   fail_unless (event_caps == caps);
445   fail_unless_equals_int (g_list_length (buffers), 1);
446
447   gst_check_drop_buffers ();
448
449   gst_caps_replace (&caps, NULL);
450   gst_caps_replace (&event_caps, NULL);
451
452   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
453   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
454   gst_object_unref (src);
455   gst_object_unref (sink);
456 }
457
458 GST_END_TEST;
459
460 static gboolean
461 name_is_valid (const gchar * name, GstPadPresence presence)
462 {
463   GstPadTemplate *new;
464   GstCaps *any = gst_caps_new_any ();
465
466   new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
467   gst_caps_unref (any);
468   if (new) {
469     gst_object_unref (GST_OBJECT (new));
470     return TRUE;
471   }
472   return FALSE;
473 }
474
475 GST_START_TEST (test_name_is_valid)
476 {
477   gboolean result = FALSE;
478
479   fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
480   ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
481   ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
482   fail_if (result);
483
484   fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
485   ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
486   ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
487   ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
488   ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
489
490   fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
491   fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
492 }
493
494 GST_END_TEST;
495
496 static GstPadProbeReturn
497 _probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
498 {
499   gint ret = GPOINTER_TO_INT (userdata);
500
501   if (ret == 1)
502     return GST_PAD_PROBE_OK;
503
504   return GST_PAD_PROBE_DROP;
505 }
506
507 GST_START_TEST (test_push_unlinked)
508 {
509   GstPad *src;
510   GstCaps *caps;
511   GstBuffer *buffer;
512   gulong id;
513
514   src = gst_pad_new ("src", GST_PAD_SRC);
515   fail_if (src == NULL);
516   caps = gst_pad_get_allowed_caps (src);
517   fail_unless (caps == NULL);
518
519   caps = gst_caps_from_string ("foo/bar");
520
521   /* pushing on an inactive pad will return wrong state */
522   GST_DEBUG ("push buffer inactive");
523   buffer = gst_buffer_new ();
524   gst_buffer_ref (buffer);
525   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
526   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
527   gst_buffer_unref (buffer);
528
529   gst_pad_set_active (src, TRUE);
530   fail_unless (gst_pad_push_event (src,
531           gst_event_new_stream_start ("test")) == TRUE);
532   GST_DEBUG ("push caps event inactive");
533   gst_pad_set_caps (src, caps);
534   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
535   fail_unless (gst_pad_push_event (src,
536           gst_event_new_segment (&dummy_segment)) == TRUE);
537
538   /* pushing on an unlinked pad will drop the buffer */
539   GST_DEBUG ("push buffer unlinked");
540   buffer = gst_buffer_new ();
541   gst_buffer_ref (buffer);
542   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
543   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
544   gst_buffer_unref (buffer);
545
546   /* adding a probe that returns _DROP will drop the buffer without trying
547    * to chain */
548   GST_DEBUG ("push buffer drop");
549   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
550       _probe_handler, GINT_TO_POINTER (0), NULL);
551   buffer = gst_buffer_new ();
552   gst_buffer_ref (buffer);
553   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
554   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
555   gst_buffer_unref (buffer);
556   gst_pad_remove_probe (src, id);
557
558   /* adding a probe that returns _OK will still chain the buffer,
559    * and hence drop because pad is unlinked */
560   GST_DEBUG ("push buffer ok");
561   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
562       _probe_handler, GINT_TO_POINTER (1), NULL);
563   buffer = gst_buffer_new ();
564   gst_buffer_ref (buffer);
565   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
566   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
567   gst_buffer_unref (buffer);
568   gst_pad_remove_probe (src, id);
569
570
571   /* cleanup */
572   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
573   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
574
575   gst_object_unref (src);
576
577   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
578   gst_caps_unref (caps);
579 }
580
581 GST_END_TEST;
582
583 GST_START_TEST (test_push_linked)
584 {
585   GstPad *src, *sink;
586   GstPadLinkReturn plr;
587   GstCaps *caps;
588   GstBuffer *buffer;
589   gulong id;
590
591   /* setup */
592   sink = gst_pad_new ("sink", GST_PAD_SINK);
593   fail_if (sink == NULL);
594   gst_pad_set_chain_function (sink, gst_check_chain_func);
595
596   src = gst_pad_new ("src", GST_PAD_SRC);
597   fail_if (src == NULL);
598
599   caps = gst_caps_from_string ("foo/bar");
600   /* one for me */
601   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
602
603   gst_pad_set_active (src, TRUE);
604
605   fail_unless (gst_pad_push_event (src,
606           gst_event_new_stream_start ("test")) == TRUE);
607
608   gst_pad_set_caps (src, caps);
609
610   fail_unless (gst_pad_push_event (src,
611           gst_event_new_segment (&dummy_segment)) == TRUE);
612
613   gst_pad_set_active (sink, TRUE);
614   /* one for me and one for each set_caps */
615   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
616
617   plr = gst_pad_link (src, sink);
618   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
619   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
620
621   buffer = gst_buffer_new ();
622
623   /* test */
624   /* pushing on a linked pad will drop the ref to the buffer */
625   gst_buffer_ref (buffer);
626   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
627   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
628   gst_buffer_unref (buffer);
629   fail_unless_equals_int (g_list_length (buffers), 1);
630   buffer = GST_BUFFER (buffers->data);
631   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
632   gst_buffer_unref (buffer);
633   g_list_free (buffers);
634   buffers = NULL;
635
636   /* adding a probe that returns FALSE will drop the buffer without trying
637    * to chain */
638   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
639       _probe_handler, GINT_TO_POINTER (0), NULL);
640   buffer = gst_buffer_new ();
641   gst_buffer_ref (buffer);
642   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
643   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
644   gst_buffer_unref (buffer);
645   gst_pad_remove_probe (src, id);
646   fail_unless_equals_int (g_list_length (buffers), 0);
647
648   /* adding a probe that returns TRUE will still chain the buffer */
649   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
650       _probe_handler, GINT_TO_POINTER (1), NULL);
651   buffer = gst_buffer_new ();
652   gst_buffer_ref (buffer);
653   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
654   gst_pad_remove_probe (src, id);
655
656   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
657   gst_buffer_unref (buffer);
658   fail_unless_equals_int (g_list_length (buffers), 1);
659   buffer = GST_BUFFER (buffers->data);
660   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
661   gst_buffer_unref (buffer);
662   g_list_free (buffers);
663   buffers = NULL;
664
665   /* teardown */
666   gst_pad_unlink (src, sink);
667   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
668   gst_object_unref (src);
669   gst_object_unref (sink);
670   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
671
672   gst_caps_unref (caps);
673 }
674
675 GST_END_TEST;
676
677 GST_START_TEST (test_push_linked_flushing)
678 {
679   GstPad *src, *sink;
680   GstCaps *caps;
681   GstPadLinkReturn plr;
682   GstBuffer *buffer;
683   gulong id;
684
685   /* setup */
686   src = gst_pad_new ("src", GST_PAD_SRC);
687   fail_if (src == NULL);
688   sink = gst_pad_new ("sink", GST_PAD_SINK);
689   fail_if (sink == NULL);
690   gst_pad_set_chain_function (sink, gst_check_chain_func);
691
692   caps = gst_pad_get_allowed_caps (src);
693   fail_unless (caps == NULL);
694   caps = gst_pad_get_allowed_caps (sink);
695   fail_unless (caps == NULL);
696
697   caps = gst_caps_from_string ("foo/bar");
698   /* one for me */
699   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
700
701   gst_pad_set_active (src, TRUE);
702   fail_unless (gst_pad_push_event (src,
703           gst_event_new_stream_start ("test")) == TRUE);
704   gst_pad_set_caps (src, caps);
705   fail_unless (gst_pad_push_event (src,
706           gst_event_new_segment (&dummy_segment)) == TRUE);
707   /* need to activate to make it accept the caps */
708   gst_pad_set_active (sink, TRUE);
709   /* one for me and one for each set_caps */
710   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
711
712   plr = gst_pad_link (src, sink);
713   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
714   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
715
716   /* not activating the pads here, which keeps them flushing */
717   gst_pad_set_active (src, FALSE);
718   gst_pad_set_active (sink, FALSE);
719
720   /* pushing on a flushing pad will drop the buffer */
721   buffer = gst_buffer_new ();
722   gst_buffer_ref (buffer);
723   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
724   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
725   fail_unless_equals_int (g_list_length (buffers), 0);
726   gst_buffer_unref (buffer);
727
728   gst_pad_set_active (src, TRUE);
729   gst_pad_set_active (sink, FALSE);
730
731   fail_unless (gst_pad_push_event (src,
732           gst_event_new_stream_start ("test")) == TRUE);
733   gst_pad_set_caps (src, caps);
734   fail_unless (gst_pad_push_event (src,
735           gst_event_new_segment (&dummy_segment)) == TRUE);
736   /* adding a probe that returns FALSE will drop the buffer without trying
737    * to chain */
738   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
739       GINT_TO_POINTER (0), NULL);
740   buffer = gst_buffer_new ();
741   gst_buffer_ref (buffer);
742   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
743   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
744   fail_unless_equals_int (g_list_length (buffers), 0);
745   gst_buffer_unref (buffer);
746   gst_pad_remove_probe (src, id);
747
748   /* adding a probe that returns TRUE will still chain the buffer,
749    * and hence drop because pad is flushing */
750   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
751       GINT_TO_POINTER (1), NULL);
752   buffer = gst_buffer_new ();
753   gst_buffer_ref (buffer);
754   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
755   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
756   fail_unless_equals_int (g_list_length (buffers), 0);
757   gst_buffer_unref (buffer);
758   gst_pad_remove_probe (src, id);
759
760   /* cleanup */
761   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
762   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
763   gst_pad_link (src, sink);
764   gst_object_unref (src);
765   gst_object_unref (sink);
766   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
767   gst_caps_unref (caps);
768 }
769
770 GST_END_TEST;
771
772 static GstBuffer *
773 buffer_from_string (const gchar * str)
774 {
775   guint size;
776   GstBuffer *buf;
777
778   size = strlen (str);
779   buf = gst_buffer_new_and_alloc (size);
780
781   gst_buffer_fill (buf, 0, str, size);
782
783   return buf;
784 }
785
786 static gboolean
787 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
788 {
789   gboolean res;
790   GstMapInfo info;
791
792   fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
793   res = memcmp (info.data, str, size) == 0;
794   GST_DEBUG ("%s <-> %s: %d", (gchar *) info.data, str, res);
795   gst_buffer_unmap (buf, &info);
796
797   return res;
798 }
799
800 GST_START_TEST (test_push_buffer_list_compat)
801 {
802   GstPad *src, *sink;
803   GstPadLinkReturn plr;
804   GstCaps *caps;
805   GstBufferList *list;
806   GstBuffer *buffer;
807
808   /* setup */
809   sink = gst_pad_new ("sink", GST_PAD_SINK);
810   fail_if (sink == NULL);
811   gst_pad_set_chain_function (sink, gst_check_chain_func);
812   /* leave chainlistfunc unset */
813
814   src = gst_pad_new ("src", GST_PAD_SRC);
815   fail_if (src == NULL);
816
817   caps = gst_caps_from_string ("foo/bar");
818
819   gst_pad_set_active (src, TRUE);
820
821   fail_unless (gst_pad_push_event (src,
822           gst_event_new_stream_start ("test")) == TRUE);
823
824   gst_pad_set_caps (src, caps);
825
826   fail_unless (gst_pad_push_event (src,
827           gst_event_new_segment (&dummy_segment)) == TRUE);
828
829   gst_pad_set_active (sink, TRUE);
830
831   plr = gst_pad_link (src, sink);
832   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
833
834   list = gst_buffer_list_new ();
835
836   /* test */
837   /* adding to a buffer list will drop the ref to the buffer */
838   gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
839   gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
840
841   fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
842   fail_unless_equals_int (g_list_length (buffers), 2);
843   buffer = GST_BUFFER (buffers->data);
844   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
845   fail_unless (buffer_compare (buffer, "ListGroup", 9));
846   gst_buffer_unref (buffer);
847   buffers = g_list_delete_link (buffers, buffers);
848   buffer = GST_BUFFER (buffers->data);
849   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
850   fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
851   gst_buffer_unref (buffer);
852   buffers = g_list_delete_link (buffers, buffers);
853   fail_unless (buffers == NULL);
854
855   /* teardown */
856   gst_pad_unlink (src, sink);
857   gst_object_unref (src);
858   gst_object_unref (sink);
859   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
860   gst_caps_unref (caps);
861 }
862
863 GST_END_TEST;
864
865 GST_START_TEST (test_flowreturn)
866 {
867   GstFlowReturn ret;
868   GQuark quark;
869
870   /* test some of the macros */
871   ret = GST_FLOW_EOS;
872   fail_if (strcmp (gst_flow_get_name (ret), "eos"));
873   quark = gst_flow_to_quark (ret);
874   fail_if (strcmp (g_quark_to_string (quark), "eos"));
875
876   /* custom returns */
877   ret = GST_FLOW_CUSTOM_SUCCESS;
878   fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
879   quark = gst_flow_to_quark (ret);
880   fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
881
882   ret = GST_FLOW_CUSTOM_ERROR;
883   fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
884   quark = gst_flow_to_quark (ret);
885   fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
886
887   /* custom returns clamping */
888   ret = GST_FLOW_CUSTOM_SUCCESS + 2;
889   fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
890   quark = gst_flow_to_quark (ret);
891   fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
892
893   ret = GST_FLOW_CUSTOM_ERROR - 2;
894   fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
895   quark = gst_flow_to_quark (ret);
896   fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
897
898   /* unknown values */
899   ret = GST_FLOW_CUSTOM_ERROR + 2;
900   fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
901   quark = gst_flow_to_quark (ret);
902   fail_unless (quark == 0);
903 }
904
905 GST_END_TEST;
906
907 GST_START_TEST (test_push_negotiation)
908 {
909   GstPad *src, *sink;
910   GstPadLinkReturn plr;
911   GstCaps *srccaps =
912       gst_caps_from_string ("audio/x-raw,width={16,32},depth={16,32}");
913   GstCaps *sinkcaps =
914       gst_caps_from_string ("audio/x-raw,width=32,depth={16,32}");
915   GstPadTemplate *src_template;
916   GstPadTemplate *sink_template;
917   GstCaps *caps;
918
919   /* setup */
920   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
921       GST_PAD_ALWAYS, srccaps);
922   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
923       GST_PAD_ALWAYS, sinkcaps);
924   gst_caps_unref (srccaps);
925   gst_caps_unref (sinkcaps);
926
927   sink = gst_pad_new_from_template (sink_template, "sink");
928   fail_if (sink == NULL);
929   gst_pad_set_chain_function (sink, gst_check_chain_func);
930
931   src = gst_pad_new_from_template (src_template, "src");
932   fail_if (src == NULL);
933
934   plr = gst_pad_link (src, sink);
935   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
936
937   /* activate pads */
938   gst_pad_set_active (src, TRUE);
939   gst_pad_set_active (sink, TRUE);
940
941   caps = gst_caps_from_string ("audio/x-raw,width=16,depth=16");
942
943   /* Should fail if src pad caps are incompatible with sink pad caps */
944   gst_pad_set_caps (src, caps);
945   fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
946
947   /* teardown */
948   gst_pad_unlink (src, sink);
949   gst_object_unref (src);
950   gst_object_unref (sink);
951   gst_caps_unref (caps);
952   gst_object_unref (sink_template);
953   gst_object_unref (src_template);
954 }
955
956 GST_END_TEST;
957
958 /* see that an unref also unlinks the pads */
959 GST_START_TEST (test_src_unref_unlink)
960 {
961   GstPad *src, *sink;
962   GstCaps *caps;
963   GstPadLinkReturn plr;
964
965   sink = gst_pad_new ("sink", GST_PAD_SINK);
966   fail_if (sink == NULL);
967
968   src = gst_pad_new ("src", GST_PAD_SRC);
969   fail_if (src == NULL);
970
971   caps = gst_caps_from_string ("foo/bar");
972
973   gst_pad_set_active (src, TRUE);
974   gst_pad_set_caps (src, caps);
975   gst_pad_set_active (sink, TRUE);
976   gst_pad_set_caps (sink, caps);
977
978   plr = gst_pad_link (src, sink);
979   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
980
981   /* unref the srcpad */
982   gst_object_unref (src);
983
984   /* sink should be unlinked now */
985   fail_if (gst_pad_is_linked (sink));
986
987   /* cleanup */
988   gst_object_unref (sink);
989   gst_caps_unref (caps);
990 }
991
992 GST_END_TEST;
993
994 /* see that an unref also unlinks the pads */
995 GST_START_TEST (test_sink_unref_unlink)
996 {
997   GstPad *src, *sink;
998   GstCaps *caps;
999   GstPadLinkReturn plr;
1000
1001   sink = gst_pad_new ("sink", GST_PAD_SINK);
1002   fail_if (sink == NULL);
1003
1004   src = gst_pad_new ("src", GST_PAD_SRC);
1005   fail_if (src == NULL);
1006
1007   caps = gst_caps_from_string ("foo/bar");
1008
1009   gst_pad_set_active (src, TRUE);
1010   gst_pad_set_caps (src, caps);
1011   gst_pad_set_active (sink, TRUE);
1012   gst_pad_set_caps (sink, caps);
1013
1014   plr = gst_pad_link (src, sink);
1015   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1016
1017   /* unref the sinkpad */
1018   gst_object_unref (sink);
1019
1020   /* src should be unlinked now */
1021   fail_if (gst_pad_is_linked (src));
1022
1023   /* cleanup */
1024   gst_object_unref (src);
1025   gst_caps_unref (caps);
1026 }
1027
1028 GST_END_TEST;
1029
1030 static gulong id;
1031
1032 static GstPadProbeReturn
1033 block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1034 {
1035   gboolean *bool_user_data = (gboolean *) user_data;
1036
1037   fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
1038
1039   /* here we should have blocked == 0 unblocked == 0 */
1040   fail_unless (bool_user_data[0] == FALSE);
1041   fail_unless (bool_user_data[1] == FALSE);
1042
1043   bool_user_data[0] = TRUE;
1044
1045   gst_pad_remove_probe (pad, id);
1046   bool_user_data[1] = TRUE;
1047
1048   return GST_PAD_PROBE_OK;
1049 }
1050
1051 GST_START_TEST (test_block_async)
1052 {
1053   GstPad *pad;
1054   /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
1055    * unblocked */
1056   gboolean data[2] = { FALSE, FALSE };
1057
1058   pad = gst_pad_new ("src", GST_PAD_SRC);
1059   fail_unless (pad != NULL);
1060
1061   gst_pad_set_active (pad, TRUE);
1062
1063   fail_unless (gst_pad_push_event (pad,
1064           gst_event_new_stream_start ("test")) == TRUE);
1065   fail_unless (gst_pad_push_event (pad,
1066           gst_event_new_segment (&dummy_segment)) == TRUE);
1067
1068   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_cb, &data,
1069       NULL);
1070
1071   fail_unless (data[0] == FALSE);
1072   fail_unless (data[1] == FALSE);
1073   gst_pad_push (pad, gst_buffer_new ());
1074
1075   gst_object_unref (pad);
1076 }
1077
1078 GST_END_TEST;
1079
1080 static GstPadProbeReturn
1081 block_async_cb_return_ok (GstPad * pad, GstPadProbeInfo * info,
1082     gpointer user_data)
1083 {
1084   return GST_PAD_PROBE_OK;
1085 }
1086
1087 static gpointer
1088 push_buffer_async (GstPad * pad)
1089 {
1090   return GINT_TO_POINTER (gst_pad_push (pad, gst_buffer_new ()));
1091 }
1092
1093 static void
1094 test_pad_blocking_with_type (GstPadProbeType type)
1095 {
1096   GstPad *pad;
1097   GThread *thread;
1098   GstFlowReturn ret;
1099
1100   pad = gst_pad_new ("src", GST_PAD_SRC);
1101   fail_unless (pad != NULL);
1102
1103   gst_pad_set_active (pad, TRUE);
1104
1105   fail_unless (gst_pad_push_event (pad,
1106           gst_event_new_stream_start ("test")) == TRUE);
1107   fail_unless (gst_pad_push_event (pad,
1108           gst_event_new_segment (&dummy_segment)) == TRUE);
1109
1110   id = gst_pad_add_probe (pad, type, block_async_cb_return_ok, NULL, NULL);
1111
1112   thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1113       pad, NULL);
1114
1115   /* wait for the block */
1116   while (!gst_pad_is_blocking (pad)) {
1117     g_usleep (10000);
1118   }
1119
1120   /* stop with flushing */
1121   gst_pad_push_event (pad, gst_event_new_flush_start ());
1122
1123   /* get return value from push */
1124   ret = GPOINTER_TO_INT (g_thread_join (thread));
1125   /* unflush now */
1126   gst_pad_push_event (pad, gst_event_new_flush_stop (FALSE));
1127   /* must be wrong state */
1128   fail_unless (ret == GST_FLOW_FLUSHING);
1129
1130   gst_object_unref (pad);
1131 }
1132
1133 GST_START_TEST (test_pad_blocking_with_probe_type_block)
1134 {
1135   test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCK);
1136 }
1137
1138 GST_END_TEST;
1139
1140 GST_START_TEST (test_pad_blocking_with_probe_type_blocking)
1141 {
1142   test_pad_blocking_with_type (GST_PAD_PROBE_TYPE_BLOCKING);
1143 }
1144
1145 GST_END_TEST;
1146
1147 static gboolean idle_probe_running;
1148
1149 static GstFlowReturn
1150 idletest_sink_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1151 {
1152   if (idle_probe_running)
1153     fail ("Should not be reached");
1154   return GST_FLOW_OK;
1155 }
1156
1157 static GstPadProbeReturn
1158 idle_probe_wait (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1159 {
1160   /* it is ok to have a probe called multiple times but it is not
1161    * acceptable in our scenario */
1162   fail_if (idle_probe_running);
1163
1164   idle_probe_running = TRUE;
1165   while (idle_probe_running) {
1166     g_usleep (10000);
1167   }
1168
1169   return GST_PAD_PROBE_REMOVE;
1170 }
1171
1172 static gpointer
1173 add_idle_probe_async (GstPad * pad)
1174 {
1175   gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, idle_probe_wait, NULL, NULL);
1176
1177   return NULL;
1178 }
1179
1180 GST_START_TEST (test_pad_blocking_with_probe_type_idle)
1181 {
1182   GstPad *srcpad, *sinkpad;
1183   GThread *idle_thread, *thread;
1184
1185   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1186   fail_unless (srcpad != NULL);
1187   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1188   fail_unless (sinkpad != NULL);
1189
1190   gst_pad_set_chain_function (sinkpad, idletest_sink_pad_chain);
1191
1192   fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
1193
1194   gst_pad_set_active (sinkpad, TRUE);
1195   gst_pad_set_active (srcpad, TRUE);
1196
1197   fail_unless (gst_pad_push_event (srcpad,
1198           gst_event_new_stream_start ("test")) == TRUE);
1199   fail_unless (gst_pad_push_event (srcpad,
1200           gst_event_new_segment (&dummy_segment)) == TRUE);
1201
1202   idle_probe_running = FALSE;
1203   idle_thread =
1204       g_thread_try_new ("gst-check", (GThreadFunc) add_idle_probe_async, srcpad,
1205       NULL);
1206
1207   /* wait for the idle function to signal it is being called */
1208   while (!idle_probe_running) {
1209     g_usleep (10000);
1210   }
1211
1212   thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1213       srcpad, NULL);
1214
1215   while (!gst_pad_is_blocking (srcpad)) {
1216     g_usleep (10000);
1217   }
1218
1219   idle_probe_running = FALSE;
1220
1221   g_thread_join (idle_thread);
1222   g_thread_join (thread);
1223   gst_object_unref (srcpad);
1224   gst_object_unref (sinkpad);
1225 }
1226
1227 GST_END_TEST;
1228
1229 static gboolean pad_probe_remove_notifiy_called = FALSE;
1230
1231 static GstPadProbeReturn
1232 probe_remove_self_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1233 {
1234   gst_pad_remove_probe (pad, info->id);
1235
1236   fail_unless (pad->num_probes == 0);
1237   fail_unless (pad->num_blocked == 0);
1238
1239   return GST_PAD_PROBE_REMOVE;
1240 }
1241
1242 static void
1243 probe_remove_notify_cb (gpointer data)
1244 {
1245   fail_unless (pad_probe_remove_notifiy_called == FALSE);
1246   pad_probe_remove_notifiy_called = TRUE;
1247 }
1248
1249 GST_START_TEST (test_pad_probe_remove)
1250 {
1251   GstPad *pad;
1252
1253   pad = gst_pad_new ("src", GST_PAD_SRC);
1254   fail_unless (pad != NULL);
1255
1256   gst_pad_set_active (pad, TRUE);
1257   fail_unless (pad->num_probes == 0);
1258   fail_unless (pad->num_blocked == 0);
1259   gst_pad_add_probe (pad,
1260       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
1261       probe_remove_self_cb, NULL, probe_remove_notify_cb);
1262   fail_unless (pad->num_probes == 1);
1263   fail_unless (pad->num_blocked == 1);
1264
1265   pad_probe_remove_notifiy_called = FALSE;
1266   gst_pad_push_event (pad, gst_event_new_stream_start ("asda"));
1267
1268   fail_unless (pad->num_probes == 0);
1269   fail_unless (pad->num_blocked == 0);
1270
1271   gst_object_unref (pad);
1272 }
1273
1274 GST_END_TEST;
1275
1276 typedef struct
1277 {
1278   gulong probe_id;
1279   GstPad *probe_pad;
1280   GThread *thread;
1281 } BlockReplaceProbeHelper;
1282
1283 static gpointer
1284 unblock_probe_thread (gpointer user_data)
1285 {
1286   BlockReplaceProbeHelper *helper = user_data;
1287
1288   GST_INFO_OBJECT (helper->probe_pad, "removing probe to unblock pad");
1289   gst_pad_remove_probe (helper->probe_pad, helper->probe_id);
1290   return NULL;
1291 }
1292
1293 static GstPadProbeReturn
1294 block_and_replace_buffer_probe_cb (GstPad * pad, GstPadProbeInfo * info,
1295     gpointer user_data)
1296 {
1297   BlockReplaceProbeHelper *helper = user_data;
1298
1299   GST_INFO_OBJECT (pad, "about to block pad, replacing buffer");
1300
1301   /* we want to block, but also drop this buffer */
1302   gst_buffer_unref (GST_BUFFER (info->data));
1303   info->data = NULL;
1304
1305   helper->thread =
1306       g_thread_new ("gst-pad-test-thread", unblock_probe_thread, helper);
1307
1308   return GST_PAD_PROBE_OK;
1309 }
1310
1311 GST_START_TEST (test_pad_probe_block_and_drop_buffer)
1312 {
1313   BlockReplaceProbeHelper helper;
1314   GstFlowReturn flow;
1315   GstPad *src, *sink;
1316
1317   src = gst_pad_new ("src", GST_PAD_SRC);
1318   gst_pad_set_active (src, TRUE);
1319   sink = gst_pad_new ("sink", GST_PAD_SINK);
1320   gst_pad_set_chain_function (sink, gst_check_chain_func);
1321   gst_pad_set_active (sink, TRUE);
1322
1323   fail_unless (gst_pad_push_event (src,
1324           gst_event_new_stream_start ("test")) == TRUE);
1325   fail_unless (gst_pad_push_event (src,
1326           gst_event_new_segment (&dummy_segment)) == TRUE);
1327
1328   fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
1329
1330   helper.probe_id = gst_pad_add_probe (src,
1331       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1332       block_and_replace_buffer_probe_cb, &helper, NULL);
1333   helper.probe_pad = src;
1334
1335   /* push a buffer so the events are propagated downstream */
1336   flow = gst_pad_push (src, gst_buffer_new ());
1337
1338   g_thread_join (helper.thread);
1339
1340   fail_unless_equals_int (flow, GST_FLOW_OK);
1341
1342   /* no buffer should have made it through to the sink pad, and especially
1343    * not a NULL pointer buffer */
1344   fail_if (buffers && buffers->data == NULL);
1345   fail_unless (buffers == NULL);
1346
1347   gst_object_unref (src);
1348   gst_object_unref (sink);
1349 }
1350
1351 GST_END_TEST;
1352
1353 static GstPadProbeReturn
1354 probe_block_a (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1355 {
1356   return GST_PAD_PROBE_OK;
1357 }
1358
1359 static GstPadProbeReturn
1360 probe_block_b (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1361 {
1362   gboolean *probe_b_called = user_data;
1363
1364   *probe_b_called = TRUE;
1365
1366   return GST_PAD_PROBE_OK;
1367 }
1368
1369 static GstPadProbeReturn
1370 probe_block_c (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1371 {
1372   gboolean *probe_c_called = user_data;
1373
1374   *probe_c_called = TRUE;
1375
1376   return GST_PAD_PROBE_REMOVE;
1377 }
1378
1379 GST_START_TEST (test_pad_probe_block_add_remove)
1380 {
1381   GstPad *pad;
1382   GThread *thread;
1383   gulong probe_a, probe_b;
1384   gboolean probe_b_called = FALSE;
1385   gboolean probe_c_called = FALSE;
1386
1387   pad = gst_pad_new ("src", GST_PAD_SRC);
1388   fail_unless (pad != NULL);
1389
1390   gst_pad_set_active (pad, TRUE);
1391   fail_unless (pad->num_probes == 0);
1392   fail_unless (pad->num_blocked == 0);
1393
1394   fail_unless (gst_pad_push_event (pad,
1395           gst_event_new_stream_start ("test")) == TRUE);
1396   fail_unless (gst_pad_push_event (pad,
1397           gst_event_new_segment (&dummy_segment)) == TRUE);
1398
1399   probe_a = gst_pad_add_probe (pad,
1400       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1401       probe_block_a, NULL, NULL);
1402
1403   fail_unless (pad->num_probes == 1);
1404   fail_unless (pad->num_blocked == 1);
1405
1406   thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1407       pad, NULL);
1408
1409   /* wait for the block */
1410   while (!gst_pad_is_blocking (pad)) {
1411     g_usleep (10000);
1412   }
1413
1414   probe_b = gst_pad_add_probe (pad,
1415       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1416       probe_block_b, &probe_b_called, NULL);
1417
1418   gst_pad_remove_probe (pad, probe_a);
1419
1420   /* wait for the callback */
1421   while (!probe_b_called) {
1422     g_usleep (10000);
1423   }
1424
1425   /* wait for the block */
1426   while (!gst_pad_is_blocking (pad)) {
1427     g_usleep (10000);
1428   }
1429
1430   gst_pad_add_probe (pad,
1431       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1432       probe_block_c, &probe_c_called, NULL);
1433
1434   gst_pad_remove_probe (pad, probe_b);
1435
1436   /* wait for the callback */
1437   while (!probe_c_called) {
1438     g_usleep (10000);
1439   }
1440
1441   /* wait for the unblock */
1442   while (gst_pad_is_blocking (pad)) {
1443     g_usleep (10000);
1444   }
1445
1446   gst_object_unref (pad);
1447
1448   g_thread_join (thread);
1449 }
1450
1451 GST_END_TEST;
1452
1453 static gboolean src_flush_start_probe_called = FALSE;
1454 static gboolean src_flush_stop_probe_called = FALSE;
1455 static gboolean sink_flush_start_probe_called = FALSE;
1456 static gboolean sink_flush_stop_probe_called = FALSE;
1457
1458 static GstPadProbeReturn
1459 flush_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1460 {
1461   GstEvent *event;
1462
1463   if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_FLUSH))
1464     goto out;
1465
1466   event = gst_pad_probe_info_get_event (info);
1467   switch (GST_EVENT_TYPE (event)) {
1468     case GST_EVENT_FLUSH_START:
1469       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1470         src_flush_start_probe_called = TRUE;
1471       else
1472         sink_flush_start_probe_called = TRUE;
1473       break;
1474     case GST_EVENT_FLUSH_STOP:
1475       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1476         src_flush_stop_probe_called = TRUE;
1477       else
1478         sink_flush_stop_probe_called = TRUE;
1479       break;
1480     default:
1481       break;
1482   }
1483
1484 out:
1485   return GST_PAD_PROBE_OK;
1486 }
1487
1488 GST_START_TEST (test_pad_probe_flush_events)
1489 {
1490   GstPad *src, *sink;
1491
1492   src = gst_pad_new ("src", GST_PAD_SRC);
1493   sink = gst_pad_new ("sink", GST_PAD_SINK);
1494   gst_pad_set_chain_function (sink, gst_check_chain_func);
1495   gst_pad_set_active (src, TRUE);
1496   gst_pad_set_active (sink, TRUE);
1497
1498   fail_unless (gst_pad_push_event (src,
1499           gst_event_new_stream_start ("test")) == TRUE);
1500   fail_unless (gst_pad_push_event (src,
1501           gst_event_new_segment (&dummy_segment)) == TRUE);
1502
1503   fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1504
1505   gst_pad_add_probe (src,
1506       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1507       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1508   gst_pad_add_probe (sink,
1509       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1510       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1511
1512   gst_pad_push_event (src, gst_event_new_flush_start ());
1513   gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
1514
1515   fail_unless (gst_pad_push_event (src,
1516           gst_event_new_segment (&dummy_segment)) == TRUE);
1517
1518   /* push a buffer so the events are propagated downstream */
1519   gst_pad_push (src, gst_buffer_new ());
1520
1521   fail_unless (src_flush_start_probe_called);
1522   fail_unless (src_flush_stop_probe_called);
1523   fail_unless (sink_flush_start_probe_called);
1524   fail_unless (sink_flush_stop_probe_called);
1525
1526   gst_object_unref (src);
1527   gst_object_unref (sink);
1528 }
1529
1530 GST_END_TEST;
1531
1532 static gboolean got_notify;
1533
1534 static void
1535 caps_notify (GstPad * pad, GParamSpec * spec, gpointer data)
1536 {
1537   got_notify = TRUE;
1538 }
1539
1540 static void
1541 test_queue_src_caps_notify (gboolean link_queue)
1542 {
1543   GstElement *queue;
1544   GstPad *src, *sink, *another_pad;
1545   GstCaps *caps;
1546
1547   queue = gst_element_factory_make ("queue", NULL);
1548   fail_unless (queue != NULL);
1549
1550   src = gst_element_get_static_pad (queue, "src");
1551   fail_unless (src != NULL);
1552
1553   sink = gst_element_get_static_pad (queue, "sink");
1554   fail_unless (sink != NULL);
1555
1556   if (link_queue) {
1557     another_pad = gst_pad_new ("sink", GST_PAD_SINK);
1558     fail_unless (another_pad != NULL);
1559     gst_pad_set_active (another_pad, TRUE);
1560
1561     gst_pad_link_full (src, another_pad, GST_PAD_LINK_CHECK_NOTHING);
1562   } else {
1563     another_pad = NULL;
1564   }
1565
1566   gst_element_set_state (queue, GST_STATE_PLAYING);
1567
1568   got_notify = FALSE;
1569
1570   g_signal_connect (src, "notify::caps", G_CALLBACK (caps_notify), NULL);
1571
1572   caps = gst_caps_from_string ("caps");
1573   gst_pad_send_event (sink, gst_event_new_caps (caps));
1574   gst_caps_unref (caps);
1575
1576   while (got_notify == FALSE)
1577     g_usleep (10000);
1578
1579   gst_element_set_state (queue, GST_STATE_NULL);
1580
1581   gst_object_unref (src);
1582   gst_object_unref (sink);
1583   gst_object_unref (queue);
1584   if (another_pad) {
1585     gst_object_unref (another_pad);
1586   }
1587 }
1588
1589 GST_START_TEST (test_queue_src_caps_notify_linked)
1590 {
1591   test_queue_src_caps_notify (TRUE);
1592 }
1593
1594 GST_END_TEST
1595 GST_START_TEST (test_queue_src_caps_notify_not_linked)
1596 {
1597   /* This test will fail because queue doesn't set the caps
1598      on src pad unless it is linked */
1599   test_queue_src_caps_notify (FALSE);
1600 }
1601
1602 GST_END_TEST;
1603
1604 #if 0
1605 static void
1606 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
1607 {
1608   gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
1609 }
1610
1611 static void
1612 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
1613 {
1614   static int n_calls = 0;
1615   gboolean *bool_user_data = (gboolean *) user_data;
1616
1617   if (++n_calls > 1)
1618     /* we expect this callback to be called only once */
1619     g_warn_if_reached ();
1620
1621   *bool_user_data = blocked;
1622
1623   /* replace block_async_first with block_async_second so next time the pad is
1624    * blocked the latter should be called */
1625   gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
1626
1627   /* unblock temporarily, in the next push block_async_second should be called
1628    */
1629   gst_pad_push_event (pad, gst_event_new_flush_start ());
1630 }
1631
1632 GST_START_TEST (test_block_async_replace_callback)
1633 {
1634   GstPad *pad;
1635   gboolean blocked;
1636
1637   pad = gst_pad_new ("src", GST_PAD_SRC);
1638   fail_unless (pad != NULL);
1639   gst_pad_set_active (pad, TRUE);
1640
1641   gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
1642   blocked = FALSE;
1643
1644   gst_pad_push (pad, gst_buffer_new ());
1645   fail_unless (blocked == TRUE);
1646   /* block_async_first flushes to unblock */
1647   gst_pad_push_event (pad, gst_event_new_flush_stop ());
1648
1649   /* push again, this time block_async_second should be called */
1650   gst_pad_push (pad, gst_buffer_new ());
1651   fail_unless (blocked == TRUE);
1652
1653   gst_object_unref (pad);
1654 }
1655
1656 GST_END_TEST;
1657 #endif
1658
1659 static void
1660 block_async_full_destroy (gpointer user_data)
1661 {
1662   gint *state = (gint *) user_data;
1663
1664   fail_unless (*state < 2);
1665
1666   GST_DEBUG ("setting state to 2");
1667   *state = 2;
1668 }
1669
1670 static GstPadProbeReturn
1671 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1672 {
1673   *(gint *) user_data = (gint) TRUE;
1674
1675   gst_pad_push_event (pad, gst_event_new_flush_start ());
1676   GST_DEBUG ("setting state to 1");
1677
1678   return GST_PAD_PROBE_OK;
1679 }
1680
1681 GST_START_TEST (test_block_async_full_destroy)
1682 {
1683   GstPad *pad;
1684   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1685   gint state = 0;
1686   gulong id;
1687
1688   pad = gst_pad_new ("src", GST_PAD_SRC);
1689   fail_unless (pad != NULL);
1690   gst_pad_set_active (pad, TRUE);
1691
1692   fail_unless (gst_pad_push_event (pad,
1693           gst_event_new_stream_start ("test")) == TRUE);
1694   fail_unless (gst_pad_push_event (pad,
1695           gst_event_new_segment (&dummy_segment)) == TRUE);
1696
1697   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1698       &state, block_async_full_destroy);
1699   fail_unless (state == 0);
1700
1701   gst_pad_push (pad, gst_buffer_new ());
1702   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1703    */
1704   fail_unless (state == 1);
1705   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1706
1707   /* unblock callback is called */
1708   gst_pad_remove_probe (pad, id);
1709   fail_unless (state == 2);
1710
1711   gst_object_unref (pad);
1712 }
1713
1714 GST_END_TEST;
1715
1716 GST_START_TEST (test_block_async_full_destroy_dispose)
1717 {
1718   GstPad *pad;
1719   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1720   gint state = 0;
1721
1722   pad = gst_pad_new ("src", GST_PAD_SRC);
1723   fail_unless (pad != NULL);
1724   gst_pad_set_active (pad, TRUE);
1725
1726   fail_unless (gst_pad_push_event (pad,
1727           gst_event_new_stream_start ("test")) == TRUE);
1728   fail_unless (gst_pad_push_event (pad,
1729           gst_event_new_segment (&dummy_segment)) == TRUE);
1730
1731   (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1732       &state, block_async_full_destroy);
1733
1734   gst_pad_push (pad, gst_buffer_new ());
1735   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1736    */
1737   fail_unless_equals_int (state, 1);
1738   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1739
1740   /* gst_BLOCK calls the destroy_notify function if necessary */
1741   gst_object_unref (pad);
1742
1743   fail_unless_equals_int (state, 2);
1744 }
1745
1746 GST_END_TEST;
1747
1748
1749 #if 0
1750 static void
1751 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
1752 {
1753   gboolean *bool_user_data = (gboolean *) user_data;
1754
1755   /* here we should have blocked == 1 unblocked == 0 */
1756
1757   fail_unless (blocked == FALSE);
1758
1759   fail_unless (bool_user_data[0] == TRUE);
1760   fail_unless (bool_user_data[1] == TRUE);
1761   fail_unless (bool_user_data[2] == FALSE);
1762
1763   bool_user_data[2] = TRUE;
1764 }
1765 #endif
1766
1767
1768 #if 0
1769 static void
1770 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
1771 {
1772   g_warn_if_reached ();
1773 }
1774 #endif
1775
1776 static GstPadProbeReturn
1777 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
1778     gpointer user_data)
1779 {
1780   gboolean *bool_user_data = (gboolean *) user_data;
1781
1782   GST_DEBUG ("second probe called");
1783
1784   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1785
1786   fail_unless (bool_user_data[0] == TRUE);
1787   fail_unless (bool_user_data[1] == FALSE);
1788   fail_unless (bool_user_data[2] == FALSE);
1789
1790   bool_user_data[1] = TRUE;
1791
1792   GST_DEBUG ("removing second probe with id %lu", id);
1793   gst_pad_remove_probe (pad, id);
1794
1795   return GST_PAD_PROBE_OK;
1796 }
1797
1798 static GstPadProbeReturn
1799 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
1800     gpointer user_data)
1801 {
1802   static int n_calls = 0;
1803   gboolean *bool_user_data = (gboolean *) user_data;
1804
1805   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1806
1807   GST_DEBUG ("first probe called");
1808
1809   if (++n_calls > 1)
1810     /* we expect this callback to be called only once */
1811     g_warn_if_reached ();
1812
1813   *bool_user_data = TRUE;
1814
1815   fail_unless (bool_user_data[0] == TRUE);
1816   fail_unless (bool_user_data[1] == FALSE);
1817   fail_unless (bool_user_data[2] == FALSE);
1818
1819   GST_DEBUG ("removing first probe with id %lu", id);
1820   gst_pad_remove_probe (pad, id);
1821
1822   GST_DEBUG ("adding second probe");
1823   /* replace block_async_first with block_async_second so next time the pad is
1824    * blocked the latter should be called */
1825   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1826       block_async_second_no_flush, user_data, NULL);
1827   GST_DEBUG ("added probe with id %lu", id);
1828
1829   return GST_PAD_PROBE_OK;
1830 }
1831
1832 GST_START_TEST (test_block_async_replace_callback_no_flush)
1833 {
1834   GstPad *pad;
1835   gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
1836
1837   pad = gst_pad_new ("src", GST_PAD_SRC);
1838   fail_unless (pad != NULL);
1839   gst_pad_set_active (pad, TRUE);
1840
1841   fail_unless (gst_pad_push_event (pad,
1842           gst_event_new_stream_start ("test")) == TRUE);
1843   fail_unless (gst_pad_push_event (pad,
1844           gst_event_new_segment (&dummy_segment)) == TRUE);
1845
1846   GST_DEBUG ("adding probe");
1847   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1848       block_async_first_no_flush, bool_user_data, NULL);
1849   GST_DEBUG ("added probe with id %lu", id);
1850   fail_if (id == 0);
1851
1852   GST_DEBUG ("pushing buffer");
1853   gst_pad_push (pad, gst_buffer_new ());
1854   fail_unless (bool_user_data[0] == TRUE);
1855   fail_unless (bool_user_data[1] == TRUE);
1856   fail_unless (bool_user_data[2] == FALSE);
1857
1858   gst_object_unref (pad);
1859 }
1860
1861 GST_END_TEST;
1862
1863 static gint sticky_count;
1864
1865 static gboolean
1866 test_sticky_events_handler (GstPad * pad, GstObject * parent, GstEvent * event)
1867 {
1868   GST_DEBUG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
1869
1870   switch (sticky_count) {
1871     case 0:
1872       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
1873       break;
1874     case 1:
1875     {
1876       GstCaps *caps;
1877       GstStructure *s;
1878
1879       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
1880
1881       gst_event_parse_caps (event, &caps);
1882       fail_unless (gst_caps_get_size (caps) == 1);
1883       s = gst_caps_get_structure (caps, 0);
1884       fail_unless (gst_structure_has_name (s, "foo/baz"));
1885       break;
1886     }
1887     case 2:
1888       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1889       break;
1890     default:
1891       fail_unless (FALSE);
1892       break;
1893   }
1894
1895   gst_event_unref (event);
1896   sticky_count++;
1897
1898   return TRUE;
1899 }
1900
1901 static GstFlowReturn
1902 test_sticky_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1903 {
1904   gst_buffer_unref (buffer);
1905   return GST_FLOW_OK;
1906 }
1907
1908 GST_START_TEST (test_sticky_events)
1909 {
1910   GstPad *srcpad, *sinkpad;
1911   GstCaps *caps;
1912   GstSegment seg;
1913   gchar *id;
1914
1915   /* make unlinked srcpad */
1916   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1917   fail_unless (srcpad != NULL);
1918   gst_pad_set_active (srcpad, TRUE);
1919
1920   /* test stream-start */
1921   fail_unless (gst_pad_get_stream_id (srcpad) == NULL);
1922
1923   /* push an event, it should be sticky on the srcpad */
1924   fail_unless (gst_pad_push_event (srcpad,
1925           gst_event_new_stream_start ("test")) == TRUE);
1926
1927   /* let's see if it stuck */
1928   id = gst_pad_get_stream_id (srcpad);
1929   fail_unless_equals_string (id, "test");
1930   g_free (id);
1931
1932   /* make a caps event */
1933   caps = gst_caps_new_empty_simple ("foo/bar");
1934   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1935   gst_caps_unref (caps);
1936
1937   /* make segment event */
1938   gst_segment_init (&seg, GST_FORMAT_TIME);
1939   gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
1940
1941   /* now make a sinkpad */
1942   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1943   fail_unless (sinkpad != NULL);
1944   sticky_count = 0;
1945   gst_pad_set_event_function (sinkpad, test_sticky_events_handler);
1946   gst_pad_set_chain_function (sinkpad, test_sticky_chain);
1947   fail_unless (sticky_count == 0);
1948   gst_pad_set_active (sinkpad, TRUE);
1949
1950   /* link the pads */
1951   gst_pad_link (srcpad, sinkpad);
1952   /* should not trigger events */
1953   fail_unless (sticky_count == 0);
1954
1955   /* caps replaces old caps event at position 2, the pushes all
1956    * pending events */
1957   caps = gst_caps_new_empty_simple ("foo/baz");
1958   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1959   gst_caps_unref (caps);
1960
1961   /* should have triggered 2 events, the segment event is still pending */
1962   fail_unless_equals_int (sticky_count, 2);
1963
1964   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
1965
1966   /* should have triggered 3 events */
1967   fail_unless_equals_int (sticky_count, 3);
1968
1969   gst_object_unref (srcpad);
1970   gst_object_unref (sinkpad);
1971 }
1972
1973 GST_END_TEST;
1974
1975 static GstFlowReturn next_return;
1976
1977 static GstFlowReturn
1978 test_lastflow_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1979 {
1980   gst_buffer_unref (buffer);
1981   return next_return;
1982 }
1983
1984 GST_START_TEST (test_last_flow_return_push)
1985 {
1986   GstPad *srcpad, *sinkpad;
1987   GstSegment seg;
1988
1989   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1990   fail_unless (srcpad != NULL);
1991   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1992   fail_unless (sinkpad != NULL);
1993   gst_pad_set_chain_function (sinkpad, test_lastflow_chain);
1994   gst_pad_link (srcpad, sinkpad);
1995
1996   /* initial value is flushing */
1997   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
1998
1999   /* when active it goes to ok */
2000   gst_pad_set_active (srcpad, TRUE);
2001   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2002   gst_pad_set_active (sinkpad, TRUE);
2003
2004   /* startup events */
2005   gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
2006   gst_segment_init (&seg, GST_FORMAT_TIME);
2007   gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
2008
2009
2010   /* push Ok */
2011   next_return = GST_FLOW_OK;
2012   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2013   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2014
2015   /* push not-linked */
2016   next_return = GST_FLOW_NOT_LINKED;
2017   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
2018   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
2019
2020   /* push not-linked */
2021   next_return = GST_FLOW_NOT_NEGOTIATED;
2022   fail_unless (gst_pad_push (srcpad,
2023           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
2024   fail_unless (gst_pad_get_last_flow_return (srcpad) ==
2025       GST_FLOW_NOT_NEGOTIATED);
2026
2027   /* push error */
2028   next_return = GST_FLOW_ERROR;
2029   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_ERROR);
2030   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
2031
2032   /* back to ok */
2033   next_return = GST_FLOW_OK;
2034   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
2035   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
2036
2037   /* unlinked push */
2038   gst_pad_unlink (srcpad, sinkpad);
2039   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
2040   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
2041
2042   gst_pad_link (srcpad, sinkpad);
2043   fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
2044   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
2045
2046   gst_object_unref (srcpad);
2047   gst_object_unref (sinkpad);
2048 }
2049
2050 GST_END_TEST;
2051
2052 static GstFlowReturn
2053 test_lastflow_getrange (GstPad * pad, GstObject * parent, guint64 offset,
2054     guint length, GstBuffer ** buf)
2055 {
2056   if (next_return == GST_FLOW_OK)
2057     *buf = gst_buffer_new ();
2058   else
2059     *buf = NULL;
2060   return next_return;
2061 }
2062
2063 static gboolean
2064 test_lastflow_activate_pull_func (GstPad * pad, GstObject * object)
2065 {
2066   return gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE);
2067 }
2068
2069 GST_START_TEST (test_last_flow_return_pull)
2070 {
2071   GstPad *srcpad, *sinkpad;
2072   GstBuffer *buf = NULL;
2073
2074   srcpad = gst_pad_new ("src", GST_PAD_SRC);
2075   fail_unless (srcpad != NULL);
2076   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2077   fail_unless (sinkpad != NULL);
2078   gst_pad_set_getrange_function (srcpad, test_lastflow_getrange);
2079   gst_pad_set_activate_function (sinkpad, test_lastflow_activate_pull_func);
2080   gst_pad_link (srcpad, sinkpad);
2081
2082   /* initial value is flushing */
2083   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
2084
2085   /* when active it goes to ok */
2086   gst_pad_set_active (sinkpad, TRUE);
2087   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2088   gst_pad_set_active (srcpad, TRUE);
2089
2090   /* pull Ok */
2091   next_return = GST_FLOW_OK;
2092   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2093   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2094   gst_buffer_unref (buf);
2095   buf = NULL;
2096
2097   /* pull not-linked */
2098   next_return = GST_FLOW_NOT_LINKED;
2099   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2100   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2101
2102   /* pull error */
2103   next_return = GST_FLOW_ERROR;
2104   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_ERROR);
2105   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
2106
2107   /* pull not-nego */
2108   next_return = GST_FLOW_NOT_NEGOTIATED;
2109   fail_unless (gst_pad_pull_range (sinkpad, 0, 1,
2110           &buf) == GST_FLOW_NOT_NEGOTIATED);
2111   fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
2112       GST_FLOW_NOT_NEGOTIATED);
2113
2114   /* pull ok again */
2115   next_return = GST_FLOW_OK;
2116   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2117   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2118   gst_buffer_unref (buf);
2119   buf = NULL;
2120
2121   /* unlinked pads */
2122   gst_pad_unlink (srcpad, sinkpad);
2123   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2124   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2125
2126   /* eos */
2127   gst_pad_link (srcpad, sinkpad);
2128   next_return = GST_FLOW_EOS;
2129   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_EOS);
2130   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
2131
2132   gst_object_unref (srcpad);
2133   gst_object_unref (sinkpad);
2134 }
2135
2136 GST_END_TEST;
2137
2138 GST_START_TEST (test_flush_stop_inactive)
2139 {
2140   GstPad *sinkpad, *srcpad;
2141
2142   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2143   fail_unless (sinkpad != NULL);
2144
2145   /* new pads are inactive and flushing */
2146   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2147   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2148
2149   /* this should fail, pad is inactive */
2150   fail_if (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2151
2152   /* nothing should have changed */
2153   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2154   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2155
2156   gst_pad_set_active (sinkpad, TRUE);
2157
2158   /* pad is now active an not flushing anymore */
2159   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2160   fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2161
2162   /* do flush, does not deactivate the pad */
2163   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_start ()));
2164   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2165   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2166
2167   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2168   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2169   fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2170
2171   gst_pad_set_active (sinkpad, FALSE);
2172   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2173   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2174
2175   gst_object_unref (sinkpad);
2176
2177   /* we should not be able to push on an inactive srcpad */
2178   srcpad = gst_pad_new ("src", GST_PAD_SRC);
2179   fail_unless (srcpad != NULL);
2180
2181   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2182   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2183
2184   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2185
2186   /* should still be inactive and flushing */
2187   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2188   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2189
2190   gst_pad_set_active (srcpad, TRUE);
2191
2192   /* pad is now active an not flushing anymore */
2193   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2194   fail_if (GST_PAD_IS_FLUSHING (srcpad));
2195
2196   /* do flush, does not deactivate the pad */
2197   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_start ()));
2198   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2199   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2200
2201   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2202   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2203   fail_if (GST_PAD_IS_FLUSHING (srcpad));
2204
2205   gst_pad_set_active (srcpad, FALSE);
2206   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2207   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2208
2209   gst_object_unref (srcpad);
2210 }
2211
2212 GST_END_TEST;
2213
2214 static Suite *
2215 gst_pad_suite (void)
2216 {
2217   Suite *s = suite_create ("GstPad");
2218   TCase *tc_chain = tcase_create ("general");
2219
2220   /* turn off timeout */
2221   tcase_set_timeout (tc_chain, 60);
2222
2223   gst_segment_init (&dummy_segment, GST_FORMAT_BYTES);
2224
2225   suite_add_tcase (s, tc_chain);
2226   tcase_add_test (tc_chain, test_link);
2227   tcase_add_test (tc_chain, test_refcount);
2228   tcase_add_test (tc_chain, test_get_allowed_caps);
2229   tcase_add_test (tc_chain, test_sticky_caps_unlinked);
2230   tcase_add_test (tc_chain, test_sticky_caps_unlinked_incompatible);
2231   tcase_add_test (tc_chain, test_sticky_caps_flushing);
2232   tcase_add_test (tc_chain, test_link_unlink_threaded);
2233   tcase_add_test (tc_chain, test_name_is_valid);
2234   tcase_add_test (tc_chain, test_push_unlinked);
2235   tcase_add_test (tc_chain, test_push_linked);
2236   tcase_add_test (tc_chain, test_push_linked_flushing);
2237   tcase_add_test (tc_chain, test_push_buffer_list_compat);
2238   tcase_add_test (tc_chain, test_flowreturn);
2239   tcase_add_test (tc_chain, test_push_negotiation);
2240   tcase_add_test (tc_chain, test_src_unref_unlink);
2241   tcase_add_test (tc_chain, test_sink_unref_unlink);
2242   tcase_add_test (tc_chain, test_block_async);
2243   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_block);
2244   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_blocking);
2245   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_idle);
2246   tcase_add_test (tc_chain, test_pad_probe_remove);
2247   tcase_add_test (tc_chain, test_pad_probe_block_add_remove);
2248   tcase_add_test (tc_chain, test_pad_probe_block_and_drop_buffer);
2249   tcase_add_test (tc_chain, test_pad_probe_flush_events);
2250   tcase_add_test (tc_chain, test_queue_src_caps_notify_linked);
2251   tcase_add_test (tc_chain, test_queue_src_caps_notify_not_linked);
2252 #if 0
2253   tcase_add_test (tc_chain, test_block_async_replace_callback);
2254 #endif
2255   tcase_add_test (tc_chain, test_block_async_full_destroy);
2256   tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
2257   tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
2258   tcase_add_test (tc_chain, test_sticky_events);
2259   tcase_add_test (tc_chain, test_last_flow_return_push);
2260   tcase_add_test (tc_chain, test_last_flow_return_pull);
2261   tcase_add_test (tc_chain, test_flush_stop_inactive);
2262
2263   return s;
2264 }
2265
2266 GST_CHECK_MAIN (gst_pad);