dbd4ab91765409fa6c5990037fdb1de1f1783208
[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 pad_probe_remove_notifiy_called = FALSE;
1148
1149 static GstPadProbeReturn
1150 probe_remove_self_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1151 {
1152   gst_pad_remove_probe (pad, info->id);
1153
1154   fail_unless (pad->num_probes == 0);
1155   fail_unless (pad->num_blocked == 0);
1156
1157   return GST_PAD_PROBE_REMOVE;
1158 }
1159
1160 static void
1161 probe_remove_notify_cb (gpointer data)
1162 {
1163   fail_unless (pad_probe_remove_notifiy_called == FALSE);
1164   pad_probe_remove_notifiy_called = TRUE;
1165 }
1166
1167 GST_START_TEST (test_pad_probe_remove)
1168 {
1169   GstPad *pad;
1170
1171   pad = gst_pad_new ("src", GST_PAD_SRC);
1172   fail_unless (pad != NULL);
1173
1174   gst_pad_set_active (pad, TRUE);
1175   fail_unless (pad->num_probes == 0);
1176   fail_unless (pad->num_blocked == 0);
1177   gst_pad_add_probe (pad,
1178       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
1179       probe_remove_self_cb, NULL, probe_remove_notify_cb);
1180   fail_unless (pad->num_probes == 1);
1181   fail_unless (pad->num_blocked == 1);
1182
1183   pad_probe_remove_notifiy_called = FALSE;
1184   gst_pad_push_event (pad, gst_event_new_stream_start ("asda"));
1185
1186   fail_unless (pad->num_probes == 0);
1187   fail_unless (pad->num_blocked == 0);
1188
1189   gst_object_unref (pad);
1190 }
1191
1192 GST_END_TEST;
1193
1194 typedef struct
1195 {
1196   gulong probe_id;
1197   GstPad *probe_pad;
1198   GThread *thread;
1199 } BlockReplaceProbeHelper;
1200
1201 static gpointer
1202 unblock_probe_thread (gpointer user_data)
1203 {
1204   BlockReplaceProbeHelper *helper = user_data;
1205
1206   GST_INFO_OBJECT (helper->probe_pad, "removing probe to unblock pad");
1207   gst_pad_remove_probe (helper->probe_pad, helper->probe_id);
1208   return NULL;
1209 }
1210
1211 static GstPadProbeReturn
1212 block_and_replace_buffer_probe_cb (GstPad * pad, GstPadProbeInfo * info,
1213     gpointer user_data)
1214 {
1215   BlockReplaceProbeHelper *helper = user_data;
1216
1217   GST_INFO_OBJECT (pad, "about to block pad, replacing buffer");
1218
1219   /* we want to block, but also drop this buffer */
1220   gst_buffer_unref (GST_BUFFER (info->data));
1221   info->data = NULL;
1222
1223   helper->thread =
1224       g_thread_new ("gst-pad-test-thread", unblock_probe_thread, helper);
1225
1226   return GST_PAD_PROBE_OK;
1227 }
1228
1229 GST_START_TEST (test_pad_probe_block_and_drop_buffer)
1230 {
1231   BlockReplaceProbeHelper helper;
1232   GstFlowReturn flow;
1233   GstPad *src, *sink;
1234
1235   src = gst_pad_new ("src", GST_PAD_SRC);
1236   gst_pad_set_active (src, TRUE);
1237   sink = gst_pad_new ("sink", GST_PAD_SINK);
1238   gst_pad_set_chain_function (sink, gst_check_chain_func);
1239   gst_pad_set_active (sink, TRUE);
1240
1241   fail_unless (gst_pad_push_event (src,
1242           gst_event_new_stream_start ("test")) == TRUE);
1243   fail_unless (gst_pad_push_event (src,
1244           gst_event_new_segment (&dummy_segment)) == TRUE);
1245
1246   fail_unless_equals_int (gst_pad_link (src, sink), GST_PAD_LINK_OK);
1247
1248   helper.probe_id = gst_pad_add_probe (src,
1249       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1250       block_and_replace_buffer_probe_cb, &helper, NULL);
1251   helper.probe_pad = src;
1252
1253   /* push a buffer so the events are propagated downstream */
1254   flow = gst_pad_push (src, gst_buffer_new ());
1255
1256   g_thread_join (helper.thread);
1257
1258   fail_unless_equals_int (flow, GST_FLOW_OK);
1259
1260   /* no buffer should have made it through to the sink pad, and especially
1261    * not a NULL pointer buffer */
1262   fail_if (buffers && buffers->data == NULL);
1263   fail_unless (buffers == NULL);
1264
1265   gst_object_unref (src);
1266   gst_object_unref (sink);
1267 }
1268
1269 GST_END_TEST;
1270
1271 static GstPadProbeReturn
1272 probe_block_a (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1273 {
1274   return GST_PAD_PROBE_OK;
1275 }
1276
1277 static GstPadProbeReturn
1278 probe_block_b (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1279 {
1280   gboolean *probe_b_called = user_data;
1281
1282   *probe_b_called = TRUE;
1283
1284   return GST_PAD_PROBE_OK;
1285 }
1286
1287 static GstPadProbeReturn
1288 probe_block_c (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1289 {
1290   gboolean *probe_c_called = user_data;
1291
1292   *probe_c_called = TRUE;
1293
1294   return GST_PAD_PROBE_REMOVE;
1295 }
1296
1297 GST_START_TEST (test_pad_probe_block_add_remove)
1298 {
1299   GstPad *pad;
1300   GThread *thread;
1301   gulong probe_a, probe_b;
1302   gboolean probe_b_called = FALSE;
1303   gboolean probe_c_called = FALSE;
1304
1305   pad = gst_pad_new ("src", GST_PAD_SRC);
1306   fail_unless (pad != NULL);
1307
1308   gst_pad_set_active (pad, TRUE);
1309   fail_unless (pad->num_probes == 0);
1310   fail_unless (pad->num_blocked == 0);
1311
1312   fail_unless (gst_pad_push_event (pad,
1313           gst_event_new_stream_start ("test")) == TRUE);
1314   fail_unless (gst_pad_push_event (pad,
1315           gst_event_new_segment (&dummy_segment)) == TRUE);
1316
1317   probe_a = gst_pad_add_probe (pad,
1318       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1319       probe_block_a, NULL, NULL);
1320
1321   fail_unless (pad->num_probes == 1);
1322   fail_unless (pad->num_blocked == 1);
1323
1324   thread = g_thread_try_new ("gst-check", (GThreadFunc) push_buffer_async,
1325       pad, NULL);
1326
1327   /* wait for the block */
1328   while (!gst_pad_is_blocking (pad)) {
1329     g_usleep (10000);
1330   }
1331
1332   probe_b = gst_pad_add_probe (pad,
1333       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1334       probe_block_b, &probe_b_called, NULL);
1335
1336   gst_pad_remove_probe (pad, probe_a);
1337
1338   /* wait for the callback */
1339   while (!probe_b_called) {
1340     g_usleep (10000);
1341   }
1342
1343   /* wait for the block */
1344   while (!gst_pad_is_blocking (pad)) {
1345     g_usleep (10000);
1346   }
1347
1348   gst_pad_add_probe (pad,
1349       GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
1350       probe_block_c, &probe_c_called, NULL);
1351
1352   gst_pad_remove_probe (pad, probe_b);
1353
1354   /* wait for the callback */
1355   while (!probe_c_called) {
1356     g_usleep (10000);
1357   }
1358
1359   /* wait for the unblock */
1360   while (gst_pad_is_blocking (pad)) {
1361     g_usleep (10000);
1362   }
1363
1364   gst_object_unref (pad);
1365
1366   g_thread_join (thread);
1367 }
1368
1369 GST_END_TEST;
1370
1371 static gboolean src_flush_start_probe_called = FALSE;
1372 static gboolean src_flush_stop_probe_called = FALSE;
1373 static gboolean sink_flush_start_probe_called = FALSE;
1374 static gboolean sink_flush_stop_probe_called = FALSE;
1375
1376 static GstPadProbeReturn
1377 flush_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1378 {
1379   GstEvent *event;
1380
1381   if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_FLUSH))
1382     goto out;
1383
1384   event = gst_pad_probe_info_get_event (info);
1385   switch (GST_EVENT_TYPE (event)) {
1386     case GST_EVENT_FLUSH_START:
1387       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1388         src_flush_start_probe_called = TRUE;
1389       else
1390         sink_flush_start_probe_called = TRUE;
1391       break;
1392     case GST_EVENT_FLUSH_STOP:
1393       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1394         src_flush_stop_probe_called = TRUE;
1395       else
1396         sink_flush_stop_probe_called = TRUE;
1397       break;
1398     default:
1399       break;
1400   }
1401
1402 out:
1403   return GST_PAD_PROBE_OK;
1404 }
1405
1406 GST_START_TEST (test_pad_probe_flush_events)
1407 {
1408   GstPad *src, *sink;
1409
1410   src = gst_pad_new ("src", GST_PAD_SRC);
1411   sink = gst_pad_new ("sink", GST_PAD_SINK);
1412   gst_pad_set_chain_function (sink, gst_check_chain_func);
1413   gst_pad_set_active (src, TRUE);
1414   gst_pad_set_active (sink, TRUE);
1415
1416   fail_unless (gst_pad_push_event (src,
1417           gst_event_new_stream_start ("test")) == TRUE);
1418   fail_unless (gst_pad_push_event (src,
1419           gst_event_new_segment (&dummy_segment)) == TRUE);
1420
1421   fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1422
1423   gst_pad_add_probe (src,
1424       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1425       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1426   gst_pad_add_probe (sink,
1427       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1428       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1429
1430   gst_pad_push_event (src, gst_event_new_flush_start ());
1431   gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
1432
1433   fail_unless (gst_pad_push_event (src,
1434           gst_event_new_segment (&dummy_segment)) == TRUE);
1435
1436   /* push a buffer so the events are propagated downstream */
1437   gst_pad_push (src, gst_buffer_new ());
1438
1439   fail_unless (src_flush_start_probe_called);
1440   fail_unless (src_flush_stop_probe_called);
1441   fail_unless (sink_flush_start_probe_called);
1442   fail_unless (sink_flush_stop_probe_called);
1443
1444   gst_object_unref (src);
1445   gst_object_unref (sink);
1446 }
1447
1448 GST_END_TEST;
1449
1450 static gboolean got_notify;
1451
1452 static void
1453 caps_notify (GstPad * pad, GParamSpec * spec, gpointer data)
1454 {
1455   got_notify = TRUE;
1456 }
1457
1458 static void
1459 test_queue_src_caps_notify (gboolean link_queue)
1460 {
1461   GstElement *queue;
1462   GstPad *src, *sink, *another_pad;
1463   GstCaps *caps;
1464
1465   queue = gst_element_factory_make ("queue", NULL);
1466   fail_unless (queue != NULL);
1467
1468   src = gst_element_get_static_pad (queue, "src");
1469   fail_unless (src != NULL);
1470
1471   sink = gst_element_get_static_pad (queue, "sink");
1472   fail_unless (sink != NULL);
1473
1474   if (link_queue) {
1475     another_pad = gst_pad_new ("sink", GST_PAD_SINK);
1476     fail_unless (another_pad != NULL);
1477     gst_pad_set_active (another_pad, TRUE);
1478
1479     gst_pad_link_full (src, another_pad, GST_PAD_LINK_CHECK_NOTHING);
1480   } else {
1481     another_pad = NULL;
1482   }
1483
1484   gst_element_set_state (queue, GST_STATE_PLAYING);
1485
1486   got_notify = FALSE;
1487
1488   g_signal_connect (src, "notify::caps", G_CALLBACK (caps_notify), NULL);
1489
1490   caps = gst_caps_from_string ("caps");
1491   gst_pad_send_event (sink, gst_event_new_caps (caps));
1492   gst_caps_unref (caps);
1493
1494   while (got_notify == FALSE)
1495     g_usleep (10000);
1496
1497   gst_element_set_state (queue, GST_STATE_NULL);
1498
1499   gst_object_unref (src);
1500   gst_object_unref (sink);
1501   gst_object_unref (queue);
1502   if (another_pad) {
1503     gst_object_unref (another_pad);
1504   }
1505 }
1506
1507 GST_START_TEST (test_queue_src_caps_notify_linked)
1508 {
1509   test_queue_src_caps_notify (TRUE);
1510 }
1511
1512 GST_END_TEST
1513 GST_START_TEST (test_queue_src_caps_notify_not_linked)
1514 {
1515   /* This test will fail because queue doesn't set the caps
1516      on src pad unless it is linked */
1517   test_queue_src_caps_notify (FALSE);
1518 }
1519
1520 GST_END_TEST;
1521
1522 #if 0
1523 static void
1524 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
1525 {
1526   gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
1527 }
1528
1529 static void
1530 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
1531 {
1532   static int n_calls = 0;
1533   gboolean *bool_user_data = (gboolean *) user_data;
1534
1535   if (++n_calls > 1)
1536     /* we expect this callback to be called only once */
1537     g_warn_if_reached ();
1538
1539   *bool_user_data = blocked;
1540
1541   /* replace block_async_first with block_async_second so next time the pad is
1542    * blocked the latter should be called */
1543   gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
1544
1545   /* unblock temporarily, in the next push block_async_second should be called
1546    */
1547   gst_pad_push_event (pad, gst_event_new_flush_start ());
1548 }
1549
1550 GST_START_TEST (test_block_async_replace_callback)
1551 {
1552   GstPad *pad;
1553   gboolean blocked;
1554
1555   pad = gst_pad_new ("src", GST_PAD_SRC);
1556   fail_unless (pad != NULL);
1557   gst_pad_set_active (pad, TRUE);
1558
1559   gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
1560   blocked = FALSE;
1561
1562   gst_pad_push (pad, gst_buffer_new ());
1563   fail_unless (blocked == TRUE);
1564   /* block_async_first flushes to unblock */
1565   gst_pad_push_event (pad, gst_event_new_flush_stop ());
1566
1567   /* push again, this time block_async_second should be called */
1568   gst_pad_push (pad, gst_buffer_new ());
1569   fail_unless (blocked == TRUE);
1570
1571   gst_object_unref (pad);
1572 }
1573
1574 GST_END_TEST;
1575 #endif
1576
1577 static void
1578 block_async_full_destroy (gpointer user_data)
1579 {
1580   gint *state = (gint *) user_data;
1581
1582   fail_unless (*state < 2);
1583
1584   GST_DEBUG ("setting state to 2");
1585   *state = 2;
1586 }
1587
1588 static GstPadProbeReturn
1589 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1590 {
1591   *(gint *) user_data = (gint) TRUE;
1592
1593   gst_pad_push_event (pad, gst_event_new_flush_start ());
1594   GST_DEBUG ("setting state to 1");
1595
1596   return GST_PAD_PROBE_OK;
1597 }
1598
1599 GST_START_TEST (test_block_async_full_destroy)
1600 {
1601   GstPad *pad;
1602   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1603   gint state = 0;
1604   gulong id;
1605
1606   pad = gst_pad_new ("src", GST_PAD_SRC);
1607   fail_unless (pad != NULL);
1608   gst_pad_set_active (pad, TRUE);
1609
1610   fail_unless (gst_pad_push_event (pad,
1611           gst_event_new_stream_start ("test")) == TRUE);
1612   fail_unless (gst_pad_push_event (pad,
1613           gst_event_new_segment (&dummy_segment)) == TRUE);
1614
1615   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1616       &state, block_async_full_destroy);
1617   fail_unless (state == 0);
1618
1619   gst_pad_push (pad, gst_buffer_new ());
1620   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1621    */
1622   fail_unless (state == 1);
1623   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1624
1625   /* unblock callback is called */
1626   gst_pad_remove_probe (pad, id);
1627   fail_unless (state == 2);
1628
1629   gst_object_unref (pad);
1630 }
1631
1632 GST_END_TEST;
1633
1634 GST_START_TEST (test_block_async_full_destroy_dispose)
1635 {
1636   GstPad *pad;
1637   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1638   gint state = 0;
1639
1640   pad = gst_pad_new ("src", GST_PAD_SRC);
1641   fail_unless (pad != NULL);
1642   gst_pad_set_active (pad, TRUE);
1643
1644   fail_unless (gst_pad_push_event (pad,
1645           gst_event_new_stream_start ("test")) == TRUE);
1646   fail_unless (gst_pad_push_event (pad,
1647           gst_event_new_segment (&dummy_segment)) == TRUE);
1648
1649   (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1650       &state, block_async_full_destroy);
1651
1652   gst_pad_push (pad, gst_buffer_new ());
1653   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1654    */
1655   fail_unless_equals_int (state, 1);
1656   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1657
1658   /* gst_BLOCK calls the destroy_notify function if necessary */
1659   gst_object_unref (pad);
1660
1661   fail_unless_equals_int (state, 2);
1662 }
1663
1664 GST_END_TEST;
1665
1666
1667 #if 0
1668 static void
1669 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
1670 {
1671   gboolean *bool_user_data = (gboolean *) user_data;
1672
1673   /* here we should have blocked == 1 unblocked == 0 */
1674
1675   fail_unless (blocked == FALSE);
1676
1677   fail_unless (bool_user_data[0] == TRUE);
1678   fail_unless (bool_user_data[1] == TRUE);
1679   fail_unless (bool_user_data[2] == FALSE);
1680
1681   bool_user_data[2] = TRUE;
1682 }
1683 #endif
1684
1685
1686 #if 0
1687 static void
1688 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
1689 {
1690   g_warn_if_reached ();
1691 }
1692 #endif
1693
1694 static GstPadProbeReturn
1695 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
1696     gpointer user_data)
1697 {
1698   gboolean *bool_user_data = (gboolean *) user_data;
1699
1700   GST_DEBUG ("second probe called");
1701
1702   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1703
1704   fail_unless (bool_user_data[0] == TRUE);
1705   fail_unless (bool_user_data[1] == FALSE);
1706   fail_unless (bool_user_data[2] == FALSE);
1707
1708   bool_user_data[1] = TRUE;
1709
1710   GST_DEBUG ("removing second probe with id %lu", id);
1711   gst_pad_remove_probe (pad, id);
1712
1713   return GST_PAD_PROBE_OK;
1714 }
1715
1716 static GstPadProbeReturn
1717 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
1718     gpointer user_data)
1719 {
1720   static int n_calls = 0;
1721   gboolean *bool_user_data = (gboolean *) user_data;
1722
1723   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1724
1725   GST_DEBUG ("first probe called");
1726
1727   if (++n_calls > 1)
1728     /* we expect this callback to be called only once */
1729     g_warn_if_reached ();
1730
1731   *bool_user_data = TRUE;
1732
1733   fail_unless (bool_user_data[0] == TRUE);
1734   fail_unless (bool_user_data[1] == FALSE);
1735   fail_unless (bool_user_data[2] == FALSE);
1736
1737   GST_DEBUG ("removing first probe with id %lu", id);
1738   gst_pad_remove_probe (pad, id);
1739
1740   GST_DEBUG ("adding second probe");
1741   /* replace block_async_first with block_async_second so next time the pad is
1742    * blocked the latter should be called */
1743   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1744       block_async_second_no_flush, user_data, NULL);
1745   GST_DEBUG ("added probe with id %lu", id);
1746
1747   return GST_PAD_PROBE_OK;
1748 }
1749
1750 GST_START_TEST (test_block_async_replace_callback_no_flush)
1751 {
1752   GstPad *pad;
1753   gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
1754
1755   pad = gst_pad_new ("src", GST_PAD_SRC);
1756   fail_unless (pad != NULL);
1757   gst_pad_set_active (pad, TRUE);
1758
1759   fail_unless (gst_pad_push_event (pad,
1760           gst_event_new_stream_start ("test")) == TRUE);
1761   fail_unless (gst_pad_push_event (pad,
1762           gst_event_new_segment (&dummy_segment)) == TRUE);
1763
1764   GST_DEBUG ("adding probe");
1765   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1766       block_async_first_no_flush, bool_user_data, NULL);
1767   GST_DEBUG ("added probe with id %lu", id);
1768   fail_if (id == 0);
1769
1770   GST_DEBUG ("pushing buffer");
1771   gst_pad_push (pad, gst_buffer_new ());
1772   fail_unless (bool_user_data[0] == TRUE);
1773   fail_unless (bool_user_data[1] == TRUE);
1774   fail_unless (bool_user_data[2] == FALSE);
1775
1776   gst_object_unref (pad);
1777 }
1778
1779 GST_END_TEST;
1780
1781 static gint sticky_count;
1782
1783 static gboolean
1784 test_sticky_events_handler (GstPad * pad, GstObject * parent, GstEvent * event)
1785 {
1786   GST_DEBUG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
1787
1788   switch (sticky_count) {
1789     case 0:
1790       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
1791       break;
1792     case 1:
1793     {
1794       GstCaps *caps;
1795       GstStructure *s;
1796
1797       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
1798
1799       gst_event_parse_caps (event, &caps);
1800       fail_unless (gst_caps_get_size (caps) == 1);
1801       s = gst_caps_get_structure (caps, 0);
1802       fail_unless (gst_structure_has_name (s, "foo/baz"));
1803       break;
1804     }
1805     case 2:
1806       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1807       break;
1808     default:
1809       fail_unless (FALSE);
1810       break;
1811   }
1812
1813   gst_event_unref (event);
1814   sticky_count++;
1815
1816   return TRUE;
1817 }
1818
1819 static GstFlowReturn
1820 test_sticky_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1821 {
1822   gst_buffer_unref (buffer);
1823   return GST_FLOW_OK;
1824 }
1825
1826 GST_START_TEST (test_sticky_events)
1827 {
1828   GstPad *srcpad, *sinkpad;
1829   GstCaps *caps;
1830   GstSegment seg;
1831   gchar *id;
1832
1833   /* make unlinked srcpad */
1834   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1835   fail_unless (srcpad != NULL);
1836   gst_pad_set_active (srcpad, TRUE);
1837
1838   /* test stream-start */
1839   fail_unless (gst_pad_get_stream_id (srcpad) == NULL);
1840
1841   /* push an event, it should be sticky on the srcpad */
1842   fail_unless (gst_pad_push_event (srcpad,
1843           gst_event_new_stream_start ("test")) == TRUE);
1844
1845   /* let's see if it stuck */
1846   id = gst_pad_get_stream_id (srcpad);
1847   fail_unless_equals_string (id, "test");
1848   g_free (id);
1849
1850   /* make a caps event */
1851   caps = gst_caps_new_empty_simple ("foo/bar");
1852   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1853   gst_caps_unref (caps);
1854
1855   /* make segment event */
1856   gst_segment_init (&seg, GST_FORMAT_TIME);
1857   gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
1858
1859   /* now make a sinkpad */
1860   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1861   fail_unless (sinkpad != NULL);
1862   sticky_count = 0;
1863   gst_pad_set_event_function (sinkpad, test_sticky_events_handler);
1864   gst_pad_set_chain_function (sinkpad, test_sticky_chain);
1865   fail_unless (sticky_count == 0);
1866   gst_pad_set_active (sinkpad, TRUE);
1867
1868   /* link the pads */
1869   gst_pad_link (srcpad, sinkpad);
1870   /* should not trigger events */
1871   fail_unless (sticky_count == 0);
1872
1873   /* caps replaces old caps event at position 2, the pushes all
1874    * pending events */
1875   caps = gst_caps_new_empty_simple ("foo/baz");
1876   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1877   gst_caps_unref (caps);
1878
1879   /* should have triggered 2 events, the segment event is still pending */
1880   fail_unless_equals_int (sticky_count, 2);
1881
1882   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
1883
1884   /* should have triggered 3 events */
1885   fail_unless_equals_int (sticky_count, 3);
1886
1887   gst_object_unref (srcpad);
1888   gst_object_unref (sinkpad);
1889 }
1890
1891 GST_END_TEST;
1892
1893 static GstFlowReturn next_return;
1894
1895 static GstFlowReturn
1896 test_lastflow_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1897 {
1898   gst_buffer_unref (buffer);
1899   return next_return;
1900 }
1901
1902 GST_START_TEST (test_last_flow_return_push)
1903 {
1904   GstPad *srcpad, *sinkpad;
1905   GstSegment seg;
1906
1907   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1908   fail_unless (srcpad != NULL);
1909   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1910   fail_unless (sinkpad != NULL);
1911   gst_pad_set_chain_function (sinkpad, test_lastflow_chain);
1912   gst_pad_link (srcpad, sinkpad);
1913
1914   /* initial value is flushing */
1915   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
1916
1917   /* when active it goes to ok */
1918   gst_pad_set_active (srcpad, TRUE);
1919   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
1920   gst_pad_set_active (sinkpad, TRUE);
1921
1922   /* startup events */
1923   gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
1924   gst_segment_init (&seg, GST_FORMAT_TIME);
1925   gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
1926
1927
1928   /* push Ok */
1929   next_return = GST_FLOW_OK;
1930   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
1931   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
1932
1933   /* push not-linked */
1934   next_return = GST_FLOW_NOT_LINKED;
1935   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
1936   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
1937
1938   /* push not-linked */
1939   next_return = GST_FLOW_NOT_NEGOTIATED;
1940   fail_unless (gst_pad_push (srcpad,
1941           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
1942   fail_unless (gst_pad_get_last_flow_return (srcpad) ==
1943       GST_FLOW_NOT_NEGOTIATED);
1944
1945   /* push error */
1946   next_return = GST_FLOW_ERROR;
1947   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_ERROR);
1948   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
1949
1950   /* back to ok */
1951   next_return = GST_FLOW_OK;
1952   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
1953   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
1954
1955   /* unlinked push */
1956   gst_pad_unlink (srcpad, sinkpad);
1957   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
1958   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
1959
1960   gst_pad_link (srcpad, sinkpad);
1961   fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
1962   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
1963
1964   gst_object_unref (srcpad);
1965   gst_object_unref (sinkpad);
1966 }
1967
1968 GST_END_TEST;
1969
1970 static GstFlowReturn
1971 test_lastflow_getrange (GstPad * pad, GstObject * parent, guint64 offset,
1972     guint length, GstBuffer ** buf)
1973 {
1974   if (next_return == GST_FLOW_OK)
1975     *buf = gst_buffer_new ();
1976   else
1977     *buf = NULL;
1978   return next_return;
1979 }
1980
1981 static gboolean
1982 test_lastflow_activate_pull_func (GstPad * pad, GstObject * object)
1983 {
1984   return gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE);
1985 }
1986
1987 GST_START_TEST (test_last_flow_return_pull)
1988 {
1989   GstPad *srcpad, *sinkpad;
1990   GstBuffer *buf = NULL;
1991
1992   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1993   fail_unless (srcpad != NULL);
1994   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1995   fail_unless (sinkpad != NULL);
1996   gst_pad_set_getrange_function (srcpad, test_lastflow_getrange);
1997   gst_pad_set_activate_function (sinkpad, test_lastflow_activate_pull_func);
1998   gst_pad_link (srcpad, sinkpad);
1999
2000   /* initial value is flushing */
2001   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
2002
2003   /* when active it goes to ok */
2004   gst_pad_set_active (sinkpad, TRUE);
2005   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2006   gst_pad_set_active (srcpad, TRUE);
2007
2008   /* pull Ok */
2009   next_return = GST_FLOW_OK;
2010   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2011   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2012   gst_buffer_unref (buf);
2013   buf = NULL;
2014
2015   /* pull not-linked */
2016   next_return = GST_FLOW_NOT_LINKED;
2017   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2018   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2019
2020   /* pull error */
2021   next_return = GST_FLOW_ERROR;
2022   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_ERROR);
2023   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
2024
2025   /* pull not-nego */
2026   next_return = GST_FLOW_NOT_NEGOTIATED;
2027   fail_unless (gst_pad_pull_range (sinkpad, 0, 1,
2028           &buf) == GST_FLOW_NOT_NEGOTIATED);
2029   fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
2030       GST_FLOW_NOT_NEGOTIATED);
2031
2032   /* pull ok again */
2033   next_return = GST_FLOW_OK;
2034   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
2035   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
2036   gst_buffer_unref (buf);
2037   buf = NULL;
2038
2039   /* unlinked pads */
2040   gst_pad_unlink (srcpad, sinkpad);
2041   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
2042   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
2043
2044   /* eos */
2045   gst_pad_link (srcpad, sinkpad);
2046   next_return = GST_FLOW_EOS;
2047   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_EOS);
2048   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
2049
2050   gst_object_unref (srcpad);
2051   gst_object_unref (sinkpad);
2052 }
2053
2054 GST_END_TEST;
2055
2056 GST_START_TEST (test_flush_stop_inactive)
2057 {
2058   GstPad *sinkpad, *srcpad;
2059
2060   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
2061   fail_unless (sinkpad != NULL);
2062
2063   /* new pads are inactive and flushing */
2064   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2065   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2066
2067   /* this should fail, pad is inactive */
2068   fail_if (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2069
2070   /* nothing should have changed */
2071   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2072   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2073
2074   gst_pad_set_active (sinkpad, TRUE);
2075
2076   /* pad is now active an not flushing anymore */
2077   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2078   fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2079
2080   /* do flush, does not deactivate the pad */
2081   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_start ()));
2082   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2083   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2084
2085   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE)));
2086   fail_unless (GST_PAD_IS_ACTIVE (sinkpad));
2087   fail_if (GST_PAD_IS_FLUSHING (sinkpad));
2088
2089   gst_pad_set_active (sinkpad, FALSE);
2090   fail_if (GST_PAD_IS_ACTIVE (sinkpad));
2091   fail_unless (GST_PAD_IS_FLUSHING (sinkpad));
2092
2093   gst_object_unref (sinkpad);
2094
2095   /* we should not be able to push on an inactive srcpad */
2096   srcpad = gst_pad_new ("src", GST_PAD_SRC);
2097   fail_unless (srcpad != NULL);
2098
2099   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2100   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2101
2102   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2103
2104   /* should still be inactive and flushing */
2105   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2106   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2107
2108   gst_pad_set_active (srcpad, TRUE);
2109
2110   /* pad is now active an not flushing anymore */
2111   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2112   fail_if (GST_PAD_IS_FLUSHING (srcpad));
2113
2114   /* do flush, does not deactivate the pad */
2115   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_start ()));
2116   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2117   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2118
2119   fail_if (gst_pad_push_event (srcpad, gst_event_new_flush_stop (FALSE)));
2120   fail_unless (GST_PAD_IS_ACTIVE (srcpad));
2121   fail_if (GST_PAD_IS_FLUSHING (srcpad));
2122
2123   gst_pad_set_active (srcpad, FALSE);
2124   fail_if (GST_PAD_IS_ACTIVE (srcpad));
2125   fail_unless (GST_PAD_IS_FLUSHING (srcpad));
2126
2127   gst_object_unref (srcpad);
2128 }
2129
2130 GST_END_TEST;
2131
2132 static Suite *
2133 gst_pad_suite (void)
2134 {
2135   Suite *s = suite_create ("GstPad");
2136   TCase *tc_chain = tcase_create ("general");
2137
2138   /* turn off timeout */
2139   tcase_set_timeout (tc_chain, 60);
2140
2141   gst_segment_init (&dummy_segment, GST_FORMAT_BYTES);
2142
2143   suite_add_tcase (s, tc_chain);
2144   tcase_add_test (tc_chain, test_link);
2145   tcase_add_test (tc_chain, test_refcount);
2146   tcase_add_test (tc_chain, test_get_allowed_caps);
2147   tcase_add_test (tc_chain, test_sticky_caps_unlinked);
2148   tcase_add_test (tc_chain, test_sticky_caps_unlinked_incompatible);
2149   tcase_add_test (tc_chain, test_sticky_caps_flushing);
2150   tcase_add_test (tc_chain, test_link_unlink_threaded);
2151   tcase_add_test (tc_chain, test_name_is_valid);
2152   tcase_add_test (tc_chain, test_push_unlinked);
2153   tcase_add_test (tc_chain, test_push_linked);
2154   tcase_add_test (tc_chain, test_push_linked_flushing);
2155   tcase_add_test (tc_chain, test_push_buffer_list_compat);
2156   tcase_add_test (tc_chain, test_flowreturn);
2157   tcase_add_test (tc_chain, test_push_negotiation);
2158   tcase_add_test (tc_chain, test_src_unref_unlink);
2159   tcase_add_test (tc_chain, test_sink_unref_unlink);
2160   tcase_add_test (tc_chain, test_block_async);
2161   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_block);
2162   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_blocking);
2163   tcase_add_test (tc_chain, test_pad_probe_remove);
2164   tcase_add_test (tc_chain, test_pad_probe_block_add_remove);
2165   tcase_add_test (tc_chain, test_pad_probe_block_and_drop_buffer);
2166   tcase_add_test (tc_chain, test_pad_probe_flush_events);
2167   tcase_add_test (tc_chain, test_queue_src_caps_notify_linked);
2168   tcase_add_test (tc_chain, test_queue_src_caps_notify_not_linked);
2169 #if 0
2170   tcase_add_test (tc_chain, test_block_async_replace_callback);
2171 #endif
2172   tcase_add_test (tc_chain, test_block_async_full_destroy);
2173   tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
2174   tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
2175   tcase_add_test (tc_chain, test_sticky_events);
2176   tcase_add_test (tc_chain, test_last_flow_return_push);
2177   tcase_add_test (tc_chain, test_last_flow_return_pull);
2178   tcase_add_test (tc_chain, test_flush_stop_inactive);
2179
2180   return s;
2181 }
2182
2183 GST_CHECK_MAIN (gst_pad);