e55ffbc4aa4e435a118e642ab0dde1779720a2bb
[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     return TRUE;
237
238   /* Ensure we get here just once: */
239   fail_unless (event_caps == NULL);
240
241   /* The event must arrive before any buffer: */
242   fail_unless_equals_int (g_list_length (buffers), 0);
243
244   gst_event_parse_caps (event, &caps);
245   event_caps = gst_caps_ref (caps);
246
247   gst_event_unref (event);
248
249   return TRUE;
250 }
251
252 /* Tests whether caps get properly forwarded when pads
253    are initially unlinked */
254 GST_START_TEST (test_sticky_caps_unlinked)
255 {
256   GstCaps *caps;
257   GstPadTemplate *src_template, *sink_template;
258   GstPad *src, *sink;
259   GstEvent *event;
260
261   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
262   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
263       GST_PAD_ALWAYS, caps);
264   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
265       GST_PAD_ALWAYS, caps);
266   gst_caps_unref (caps);
267
268   src = gst_pad_new_from_template (src_template, "src");
269   fail_if (src == NULL);
270   sink = gst_pad_new_from_template (sink_template, "sink");
271   fail_if (sink == NULL);
272   gst_pad_set_event_function (sink, sticky_event);
273   gst_pad_set_chain_function (sink, gst_check_chain_func);
274
275   gst_object_unref (src_template);
276   gst_object_unref (sink_template);
277
278   gst_pad_set_active (src, TRUE);
279
280   fail_unless (gst_pad_push_event (src,
281           gst_event_new_stream_start ("test")) == TRUE);
282
283   caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
284   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
285
286   event = gst_event_new_caps (caps);
287   fail_unless (gst_pad_push_event (src, event) == TRUE);
288   fail_unless (event_caps == NULL);
289
290   fail_unless (gst_pad_push_event (src,
291           gst_event_new_segment (&dummy_segment)) == TRUE);
292
293   /* Linking and activating will not forward the sticky event yet... */
294   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
295   gst_pad_set_active (sink, TRUE);
296   fail_unless (event_caps == NULL);
297
298   /* ...but the first buffer will: */
299   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
300   fail_unless (event_caps == caps);
301   fail_unless_equals_int (g_list_length (buffers), 1);
302
303   gst_check_drop_buffers ();
304
305   gst_caps_replace (&caps, NULL);
306   gst_caps_replace (&event_caps, NULL);
307
308   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
309   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
310   gst_object_unref (src);
311   gst_object_unref (sink);
312 }
313
314 GST_END_TEST;
315
316 /* Same as test_sticky_caps_unlinked except that the source pad
317  * has a template of ANY and we will attempt to push
318  * incompatible caps */
319 GST_START_TEST (test_sticky_caps_unlinked_incompatible)
320 {
321   GstCaps *caps, *failcaps;
322   GstPadTemplate *src_template, *sink_template;
323   GstPad *src, *sink;
324   GstEvent *event;
325
326   /* Source pad has ANY caps
327    * Sink pad has foobar caps
328    * We will push the pony express caps (which should fail)
329    */
330   caps = gst_caps_new_any ();
331   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
332       GST_PAD_ALWAYS, caps);
333   gst_caps_unref (caps);
334   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
335   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
336       GST_PAD_ALWAYS, caps);
337   gst_caps_unref (caps);
338
339   src = gst_pad_new_from_template (src_template, "src");
340   fail_if (src == NULL);
341   sink = gst_pad_new_from_template (sink_template, "sink");
342   fail_if (sink == NULL);
343   gst_pad_set_event_function (sink, sticky_event);
344   gst_pad_set_chain_function (sink, gst_check_chain_func);
345
346   gst_object_unref (src_template);
347   gst_object_unref (sink_template);
348
349   gst_pad_set_active (src, TRUE);
350
351   fail_unless (gst_pad_push_event (src,
352           gst_event_new_stream_start ("test")) == TRUE);
353
354   failcaps = gst_caps_from_string ("pony/express, failure=(boolean)true");
355   ASSERT_CAPS_REFCOUNT (failcaps, "caps", 1);
356
357   event = gst_event_new_caps (failcaps);
358   gst_caps_unref (failcaps);
359   /* The pad isn't linked yet, and anything matches the source pad template
360    * (which is ANY) */
361   fail_unless (gst_pad_push_event (src, event) == TRUE);
362   fail_unless (event_caps == NULL);
363
364   fail_unless (gst_pad_push_event (src,
365           gst_event_new_segment (&dummy_segment)) == TRUE);
366
367   /* Linking and activating will not forward the sticky event yet... */
368   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
369   gst_pad_set_active (sink, TRUE);
370   fail_unless (event_caps == NULL);
371
372   /* ...but the first buffer will and should FAIL since the caps 
373    * are not compatible */
374   fail_unless (gst_pad_push (src,
375           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
376   /* We shouldn't have received the caps event since it's incompatible */
377   fail_unless (event_caps == NULL);
378   /* We shouldn't have received any buffers since caps are incompatible */
379   fail_unless_equals_int (g_list_length (buffers), 0);
380
381   gst_check_drop_buffers ();
382
383   gst_caps_replace (&event_caps, NULL);
384
385   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
386   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
387   gst_object_unref (src);
388   gst_object_unref (sink);
389 }
390
391 GST_END_TEST;
392
393 /* Like test_sticky_caps_unlinked, but link before caps: */
394
395 GST_START_TEST (test_sticky_caps_flushing)
396 {
397   GstCaps *caps;
398   GstPadTemplate *src_template, *sink_template;
399   GstPad *src, *sink;
400   GstEvent *event;
401
402   caps = gst_caps_from_string ("foo/bar, dummy=(int){1, 2}");
403   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
404       GST_PAD_ALWAYS, caps);
405   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
406       GST_PAD_ALWAYS, caps);
407   gst_caps_unref (caps);
408
409   src = gst_pad_new_from_template (src_template, "src");
410   fail_if (src == NULL);
411   sink = gst_pad_new_from_template (sink_template, "sink");
412   fail_if (sink == NULL);
413   gst_pad_set_event_function (sink, sticky_event);
414   gst_pad_set_chain_function (sink, gst_check_chain_func);
415
416   gst_object_unref (src_template);
417   gst_object_unref (sink_template);
418
419   fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (src, sink)));
420
421   caps = gst_caps_from_string ("foo/bar, dummy=(int)1");
422   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
423
424   event = gst_event_new_caps (caps);
425
426   gst_pad_set_active (src, TRUE);
427   fail_unless (gst_pad_push_event (src,
428           gst_event_new_stream_start ("test")) == TRUE);
429   /* The caps event gets accepted by the source pad (and stored) */
430   fail_unless (gst_pad_push_event (src, event) == TRUE);
431   /* But wasn't forwarded since the sink pad is flushing (not activated) */
432   fail_unless (event_caps == NULL);
433
434   fail_unless (gst_pad_push_event (src,
435           gst_event_new_segment (&dummy_segment)) == TRUE);
436
437   /* Activating will not forward the sticky event yet... */
438   gst_pad_set_active (sink, TRUE);
439   fail_unless (event_caps == NULL);
440
441   /* ...but the first buffer will: */
442   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
443   fail_unless (event_caps == caps);
444   fail_unless_equals_int (g_list_length (buffers), 1);
445
446   gst_check_drop_buffers ();
447
448   gst_caps_replace (&caps, NULL);
449   gst_caps_replace (&event_caps, NULL);
450
451   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
452   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
453   gst_object_unref (src);
454   gst_object_unref (sink);
455 }
456
457 GST_END_TEST;
458
459 static gboolean
460 name_is_valid (const gchar * name, GstPadPresence presence)
461 {
462   GstPadTemplate *new;
463   GstCaps *any = gst_caps_new_any ();
464
465   new = gst_pad_template_new (name, GST_PAD_SRC, presence, any);
466   gst_caps_unref (any);
467   if (new) {
468     gst_object_unref (GST_OBJECT (new));
469     return TRUE;
470   }
471   return FALSE;
472 }
473
474 GST_START_TEST (test_name_is_valid)
475 {
476   gboolean result = FALSE;
477
478   fail_unless (name_is_valid ("src", GST_PAD_ALWAYS));
479   ASSERT_WARNING (name_is_valid ("src%", GST_PAD_ALWAYS));
480   ASSERT_WARNING (result = name_is_valid ("src%d", GST_PAD_ALWAYS));
481   fail_if (result);
482
483   fail_unless (name_is_valid ("src", GST_PAD_REQUEST));
484   ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
485   ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
486   ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
487   ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
488
489   fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
490   fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
491 }
492
493 GST_END_TEST;
494
495 static GstPadProbeReturn
496 _probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
497 {
498   gint ret = GPOINTER_TO_INT (userdata);
499
500   if (ret == 1)
501     return GST_PAD_PROBE_OK;
502
503   return GST_PAD_PROBE_DROP;
504 }
505
506 GST_START_TEST (test_push_unlinked)
507 {
508   GstPad *src;
509   GstCaps *caps;
510   GstBuffer *buffer;
511   gulong id;
512
513   src = gst_pad_new ("src", GST_PAD_SRC);
514   fail_if (src == NULL);
515   caps = gst_pad_get_allowed_caps (src);
516   fail_unless (caps == NULL);
517
518   caps = gst_caps_from_string ("foo/bar");
519
520   /* pushing on an inactive pad will return wrong state */
521   GST_DEBUG ("push buffer inactive");
522   buffer = gst_buffer_new ();
523   gst_buffer_ref (buffer);
524   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
525   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
526   gst_buffer_unref (buffer);
527
528   gst_pad_set_active (src, TRUE);
529   fail_unless (gst_pad_push_event (src,
530           gst_event_new_stream_start ("test")) == TRUE);
531   GST_DEBUG ("push caps event inactive");
532   gst_pad_set_caps (src, caps);
533   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
534   fail_unless (gst_pad_push_event (src,
535           gst_event_new_segment (&dummy_segment)) == TRUE);
536
537   /* pushing on an unlinked pad will drop the buffer */
538   GST_DEBUG ("push buffer unlinked");
539   buffer = gst_buffer_new ();
540   gst_buffer_ref (buffer);
541   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
542   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
543   gst_buffer_unref (buffer);
544
545   /* adding a probe that returns _DROP will drop the buffer without trying
546    * to chain */
547   GST_DEBUG ("push buffer drop");
548   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
549       _probe_handler, GINT_TO_POINTER (0), NULL);
550   buffer = gst_buffer_new ();
551   gst_buffer_ref (buffer);
552   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
553   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
554   gst_buffer_unref (buffer);
555   gst_pad_remove_probe (src, id);
556
557   /* adding a probe that returns _OK will still chain the buffer,
558    * and hence drop because pad is unlinked */
559   GST_DEBUG ("push buffer ok");
560   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
561       _probe_handler, GINT_TO_POINTER (1), NULL);
562   buffer = gst_buffer_new ();
563   gst_buffer_ref (buffer);
564   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
565   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
566   gst_buffer_unref (buffer);
567   gst_pad_remove_probe (src, id);
568
569
570   /* cleanup */
571   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
572   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
573
574   gst_object_unref (src);
575
576   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
577   gst_caps_unref (caps);
578 }
579
580 GST_END_TEST;
581
582 GST_START_TEST (test_push_linked)
583 {
584   GstPad *src, *sink;
585   GstPadLinkReturn plr;
586   GstCaps *caps;
587   GstBuffer *buffer;
588   gulong id;
589
590   /* setup */
591   sink = gst_pad_new ("sink", GST_PAD_SINK);
592   fail_if (sink == NULL);
593   gst_pad_set_chain_function (sink, gst_check_chain_func);
594
595   src = gst_pad_new ("src", GST_PAD_SRC);
596   fail_if (src == NULL);
597
598   caps = gst_caps_from_string ("foo/bar");
599   /* one for me */
600   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
601
602   gst_pad_set_active (src, TRUE);
603
604   fail_unless (gst_pad_push_event (src,
605           gst_event_new_stream_start ("test")) == TRUE);
606
607   gst_pad_set_caps (src, caps);
608
609   fail_unless (gst_pad_push_event (src,
610           gst_event_new_segment (&dummy_segment)) == TRUE);
611
612   gst_pad_set_active (sink, TRUE);
613   /* one for me and one for each set_caps */
614   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
615
616   plr = gst_pad_link (src, sink);
617   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
618   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
619
620   buffer = gst_buffer_new ();
621
622   /* test */
623   /* pushing on a linked pad will drop the ref to the buffer */
624   gst_buffer_ref (buffer);
625   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
626   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
627   gst_buffer_unref (buffer);
628   fail_unless_equals_int (g_list_length (buffers), 1);
629   buffer = GST_BUFFER (buffers->data);
630   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
631   gst_buffer_unref (buffer);
632   g_list_free (buffers);
633   buffers = NULL;
634
635   /* adding a probe that returns FALSE will drop the buffer without trying
636    * to chain */
637   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
638       _probe_handler, GINT_TO_POINTER (0), NULL);
639   buffer = gst_buffer_new ();
640   gst_buffer_ref (buffer);
641   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
642   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
643   gst_buffer_unref (buffer);
644   gst_pad_remove_probe (src, id);
645   fail_unless_equals_int (g_list_length (buffers), 0);
646
647   /* adding a probe that returns TRUE will still chain the buffer */
648   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER,
649       _probe_handler, GINT_TO_POINTER (1), NULL);
650   buffer = gst_buffer_new ();
651   gst_buffer_ref (buffer);
652   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
653   gst_pad_remove_probe (src, id);
654
655   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
656   gst_buffer_unref (buffer);
657   fail_unless_equals_int (g_list_length (buffers), 1);
658   buffer = GST_BUFFER (buffers->data);
659   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
660   gst_buffer_unref (buffer);
661   g_list_free (buffers);
662   buffers = NULL;
663
664   /* teardown */
665   gst_pad_unlink (src, sink);
666   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
667   gst_object_unref (src);
668   gst_object_unref (sink);
669   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
670
671   gst_caps_unref (caps);
672 }
673
674 GST_END_TEST;
675
676 GST_START_TEST (test_push_linked_flushing)
677 {
678   GstPad *src, *sink;
679   GstCaps *caps;
680   GstPadLinkReturn plr;
681   GstBuffer *buffer;
682   gulong id;
683
684   /* setup */
685   src = gst_pad_new ("src", GST_PAD_SRC);
686   fail_if (src == NULL);
687   sink = gst_pad_new ("sink", GST_PAD_SINK);
688   fail_if (sink == NULL);
689   gst_pad_set_chain_function (sink, gst_check_chain_func);
690
691   caps = gst_pad_get_allowed_caps (src);
692   fail_unless (caps == NULL);
693   caps = gst_pad_get_allowed_caps (sink);
694   fail_unless (caps == NULL);
695
696   caps = gst_caps_from_string ("foo/bar");
697   /* one for me */
698   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
699
700   gst_pad_set_active (src, TRUE);
701   fail_unless (gst_pad_push_event (src,
702           gst_event_new_stream_start ("test")) == TRUE);
703   gst_pad_set_caps (src, caps);
704   fail_unless (gst_pad_push_event (src,
705           gst_event_new_segment (&dummy_segment)) == TRUE);
706   /* need to activate to make it accept the caps */
707   gst_pad_set_active (sink, TRUE);
708   /* one for me and one for each set_caps */
709   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
710
711   plr = gst_pad_link (src, sink);
712   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
713   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
714
715   /* not activating the pads here, which keeps them flushing */
716   gst_pad_set_active (src, FALSE);
717   gst_pad_set_active (sink, FALSE);
718
719   /* pushing on a flushing pad will drop the buffer */
720   buffer = gst_buffer_new ();
721   gst_buffer_ref (buffer);
722   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
723   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
724   fail_unless_equals_int (g_list_length (buffers), 0);
725   gst_buffer_unref (buffer);
726
727   gst_pad_set_active (src, TRUE);
728   gst_pad_set_active (sink, FALSE);
729
730   fail_unless (gst_pad_push_event (src,
731           gst_event_new_stream_start ("test")) == TRUE);
732   gst_pad_set_caps (src, caps);
733   fail_unless (gst_pad_push_event (src,
734           gst_event_new_segment (&dummy_segment)) == TRUE);
735   /* adding a probe that returns FALSE will drop the buffer without trying
736    * to chain */
737   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
738       GINT_TO_POINTER (0), NULL);
739   buffer = gst_buffer_new ();
740   gst_buffer_ref (buffer);
741   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
742   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
743   fail_unless_equals_int (g_list_length (buffers), 0);
744   gst_buffer_unref (buffer);
745   gst_pad_remove_probe (src, id);
746
747   /* adding a probe that returns TRUE will still chain the buffer,
748    * and hence drop because pad is flushing */
749   id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BUFFER, _probe_handler,
750       GINT_TO_POINTER (1), NULL);
751   buffer = gst_buffer_new ();
752   gst_buffer_ref (buffer);
753   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_FLUSHING);
754   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
755   fail_unless_equals_int (g_list_length (buffers), 0);
756   gst_buffer_unref (buffer);
757   gst_pad_remove_probe (src, id);
758
759   /* cleanup */
760   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
761   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
762   gst_pad_link (src, sink);
763   gst_object_unref (src);
764   gst_object_unref (sink);
765   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
766   gst_caps_unref (caps);
767 }
768
769 GST_END_TEST;
770
771 static GstBuffer *
772 buffer_from_string (const gchar * str)
773 {
774   guint size;
775   GstBuffer *buf;
776
777   size = strlen (str);
778   buf = gst_buffer_new_and_alloc (size);
779
780   gst_buffer_fill (buf, 0, str, size);
781
782   return buf;
783 }
784
785 static gboolean
786 buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
787 {
788   gboolean res;
789   GstMapInfo info;
790
791   fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
792   res = memcmp (info.data, str, size) == 0;
793   GST_DEBUG ("%s <-> %s: %d", (gchar *) info.data, str, res);
794   gst_buffer_unmap (buf, &info);
795
796   return res;
797 }
798
799 GST_START_TEST (test_push_buffer_list_compat)
800 {
801   GstPad *src, *sink;
802   GstPadLinkReturn plr;
803   GstCaps *caps;
804   GstBufferList *list;
805   GstBuffer *buffer;
806
807   /* setup */
808   sink = gst_pad_new ("sink", GST_PAD_SINK);
809   fail_if (sink == NULL);
810   gst_pad_set_chain_function (sink, gst_check_chain_func);
811   /* leave chainlistfunc unset */
812
813   src = gst_pad_new ("src", GST_PAD_SRC);
814   fail_if (src == NULL);
815
816   caps = gst_caps_from_string ("foo/bar");
817
818   gst_pad_set_active (src, TRUE);
819
820   fail_unless (gst_pad_push_event (src,
821           gst_event_new_stream_start ("test")) == TRUE);
822
823   gst_pad_set_caps (src, caps);
824
825   fail_unless (gst_pad_push_event (src,
826           gst_event_new_segment (&dummy_segment)) == TRUE);
827
828   gst_pad_set_active (sink, TRUE);
829
830   plr = gst_pad_link (src, sink);
831   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
832
833   list = gst_buffer_list_new ();
834
835   /* test */
836   /* adding to a buffer list will drop the ref to the buffer */
837   gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
838   gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
839
840   fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
841   fail_unless_equals_int (g_list_length (buffers), 2);
842   buffer = GST_BUFFER (buffers->data);
843   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
844   fail_unless (buffer_compare (buffer, "ListGroup", 9));
845   gst_buffer_unref (buffer);
846   buffers = g_list_delete_link (buffers, buffers);
847   buffer = GST_BUFFER (buffers->data);
848   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
849   fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
850   gst_buffer_unref (buffer);
851   buffers = g_list_delete_link (buffers, buffers);
852   fail_unless (buffers == NULL);
853
854   /* teardown */
855   gst_pad_unlink (src, sink);
856   gst_object_unref (src);
857   gst_object_unref (sink);
858   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
859   gst_caps_unref (caps);
860 }
861
862 GST_END_TEST;
863
864 GST_START_TEST (test_flowreturn)
865 {
866   GstFlowReturn ret;
867   GQuark quark;
868
869   /* test some of the macros */
870   ret = GST_FLOW_EOS;
871   fail_if (strcmp (gst_flow_get_name (ret), "eos"));
872   quark = gst_flow_to_quark (ret);
873   fail_if (strcmp (g_quark_to_string (quark), "eos"));
874
875   /* custom returns */
876   ret = GST_FLOW_CUSTOM_SUCCESS;
877   fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
878   quark = gst_flow_to_quark (ret);
879   fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
880
881   ret = GST_FLOW_CUSTOM_ERROR;
882   fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
883   quark = gst_flow_to_quark (ret);
884   fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
885
886   /* custom returns clamping */
887   ret = GST_FLOW_CUSTOM_SUCCESS + 2;
888   fail_if (strcmp (gst_flow_get_name (ret), "custom-success"));
889   quark = gst_flow_to_quark (ret);
890   fail_if (strcmp (g_quark_to_string (quark), "custom-success"));
891
892   ret = GST_FLOW_CUSTOM_ERROR - 2;
893   fail_if (strcmp (gst_flow_get_name (ret), "custom-error"));
894   quark = gst_flow_to_quark (ret);
895   fail_if (strcmp (g_quark_to_string (quark), "custom-error"));
896
897   /* unknown values */
898   ret = GST_FLOW_CUSTOM_ERROR + 2;
899   fail_if (strcmp (gst_flow_get_name (ret), "unknown"));
900   quark = gst_flow_to_quark (ret);
901   fail_unless (quark == 0);
902 }
903
904 GST_END_TEST;
905
906 GST_START_TEST (test_push_negotiation)
907 {
908   GstPad *src, *sink;
909   GstPadLinkReturn plr;
910   GstCaps *srccaps =
911       gst_caps_from_string ("audio/x-raw,width={16,32},depth={16,32}");
912   GstCaps *sinkcaps =
913       gst_caps_from_string ("audio/x-raw,width=32,depth={16,32}");
914   GstPadTemplate *src_template;
915   GstPadTemplate *sink_template;
916   GstCaps *caps;
917
918   /* setup */
919   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
920       GST_PAD_ALWAYS, srccaps);
921   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
922       GST_PAD_ALWAYS, sinkcaps);
923   gst_caps_unref (srccaps);
924   gst_caps_unref (sinkcaps);
925
926   sink = gst_pad_new_from_template (sink_template, "sink");
927   fail_if (sink == NULL);
928   gst_pad_set_chain_function (sink, gst_check_chain_func);
929
930   src = gst_pad_new_from_template (src_template, "src");
931   fail_if (src == NULL);
932
933   plr = gst_pad_link (src, sink);
934   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
935
936   /* activate pads */
937   gst_pad_set_active (src, TRUE);
938   gst_pad_set_active (sink, TRUE);
939
940   caps = gst_caps_from_string ("audio/x-raw,width=16,depth=16");
941
942   /* Should fail if src pad caps are incompatible with sink pad caps */
943   gst_pad_set_caps (src, caps);
944   fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
945
946   /* teardown */
947   gst_pad_unlink (src, sink);
948   gst_object_unref (src);
949   gst_object_unref (sink);
950   gst_caps_unref (caps);
951   gst_object_unref (sink_template);
952   gst_object_unref (src_template);
953 }
954
955 GST_END_TEST;
956
957 /* see that an unref also unlinks the pads */
958 GST_START_TEST (test_src_unref_unlink)
959 {
960   GstPad *src, *sink;
961   GstCaps *caps;
962   GstPadLinkReturn plr;
963
964   sink = gst_pad_new ("sink", GST_PAD_SINK);
965   fail_if (sink == NULL);
966
967   src = gst_pad_new ("src", GST_PAD_SRC);
968   fail_if (src == NULL);
969
970   caps = gst_caps_from_string ("foo/bar");
971
972   gst_pad_set_active (src, TRUE);
973   gst_pad_set_caps (src, caps);
974   gst_pad_set_active (sink, TRUE);
975   gst_pad_set_caps (sink, caps);
976
977   plr = gst_pad_link (src, sink);
978   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
979
980   /* unref the srcpad */
981   gst_object_unref (src);
982
983   /* sink should be unlinked now */
984   fail_if (gst_pad_is_linked (sink));
985
986   /* cleanup */
987   gst_object_unref (sink);
988   gst_caps_unref (caps);
989 }
990
991 GST_END_TEST;
992
993 /* see that an unref also unlinks the pads */
994 GST_START_TEST (test_sink_unref_unlink)
995 {
996   GstPad *src, *sink;
997   GstCaps *caps;
998   GstPadLinkReturn plr;
999
1000   sink = gst_pad_new ("sink", GST_PAD_SINK);
1001   fail_if (sink == NULL);
1002
1003   src = gst_pad_new ("src", GST_PAD_SRC);
1004   fail_if (src == NULL);
1005
1006   caps = gst_caps_from_string ("foo/bar");
1007
1008   gst_pad_set_active (src, TRUE);
1009   gst_pad_set_caps (src, caps);
1010   gst_pad_set_active (sink, TRUE);
1011   gst_pad_set_caps (sink, caps);
1012
1013   plr = gst_pad_link (src, sink);
1014   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
1015
1016   /* unref the sinkpad */
1017   gst_object_unref (sink);
1018
1019   /* src should be unlinked now */
1020   fail_if (gst_pad_is_linked (src));
1021
1022   /* cleanup */
1023   gst_object_unref (src);
1024   gst_caps_unref (caps);
1025 }
1026
1027 GST_END_TEST;
1028
1029 static gulong id;
1030
1031 static GstPadProbeReturn
1032 block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1033 {
1034   gboolean *bool_user_data = (gboolean *) user_data;
1035
1036   fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
1037
1038   /* here we should have blocked == 0 unblocked == 0 */
1039   fail_unless (bool_user_data[0] == FALSE);
1040   fail_unless (bool_user_data[1] == FALSE);
1041
1042   bool_user_data[0] = TRUE;
1043
1044   gst_pad_remove_probe (pad, id);
1045   bool_user_data[1] = TRUE;
1046
1047   return GST_PAD_PROBE_OK;
1048 }
1049
1050 GST_START_TEST (test_block_async)
1051 {
1052   GstPad *pad;
1053   /* we set data[0] = TRUE when the pad is blocked, data[1] = TRUE when it's
1054    * unblocked */
1055   gboolean data[2] = { FALSE, FALSE };
1056
1057   pad = gst_pad_new ("src", GST_PAD_SRC);
1058   fail_unless (pad != NULL);
1059
1060   gst_pad_set_active (pad, TRUE);
1061
1062   fail_unless (gst_pad_push_event (pad,
1063           gst_event_new_stream_start ("test")) == TRUE);
1064   fail_unless (gst_pad_push_event (pad,
1065           gst_event_new_segment (&dummy_segment)) == TRUE);
1066
1067   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_cb, &data,
1068       NULL);
1069
1070   fail_unless (data[0] == FALSE);
1071   fail_unless (data[1] == FALSE);
1072   gst_pad_push (pad, gst_buffer_new ());
1073
1074   gst_object_unref (pad);
1075 }
1076
1077 GST_END_TEST;
1078
1079 static GstPadProbeReturn
1080 block_async_cb_return_ok (GstPad * pad, GstPadProbeInfo * info,
1081     gpointer user_data)
1082 {
1083   return GST_PAD_PROBE_OK;
1084 }
1085
1086 static gpointer
1087 push_buffer_async (GstPad * pad)
1088 {
1089   return GINT_TO_POINTER (gst_pad_push (pad, gst_buffer_new ()));
1090 }
1091
1092 static void
1093 test_pad_blocking_with_type (GstPadProbeType type)
1094 {
1095   GstPad *pad;
1096   GThread *thread;
1097   GstFlowReturn ret;
1098
1099   pad = gst_pad_new ("src", GST_PAD_SRC);
1100   fail_unless (pad != NULL);
1101
1102   gst_pad_set_active (pad, TRUE);
1103
1104   fail_unless (gst_pad_push_event (pad,
1105           gst_event_new_stream_start ("test")) == TRUE);
1106   fail_unless (gst_pad_push_event (pad,
1107           gst_event_new_segment (&dummy_segment)) == TRUE);
1108
1109   id = gst_pad_add_probe (pad, type, block_async_cb_return_ok, NULL, NULL);
1110
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 static gboolean src_flush_start_probe_called = FALSE;
1195 static gboolean src_flush_stop_probe_called = FALSE;
1196 static gboolean sink_flush_start_probe_called = FALSE;
1197 static gboolean sink_flush_stop_probe_called = FALSE;
1198
1199 static GstPadProbeReturn
1200 flush_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1201 {
1202   GstEvent *event;
1203
1204   if (!(GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_FLUSH))
1205     goto out;
1206
1207   event = gst_pad_probe_info_get_event (info);
1208   switch (GST_EVENT_TYPE (event)) {
1209     case GST_EVENT_FLUSH_START:
1210       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1211         src_flush_start_probe_called = TRUE;
1212       else
1213         sink_flush_start_probe_called = TRUE;
1214       break;
1215     case GST_EVENT_FLUSH_STOP:
1216       if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
1217         src_flush_stop_probe_called = TRUE;
1218       else
1219         sink_flush_stop_probe_called = TRUE;
1220       break;
1221     default:
1222       break;
1223   }
1224
1225 out:
1226   return GST_PAD_PROBE_OK;
1227 }
1228
1229 GST_START_TEST (test_pad_probe_flush_events)
1230 {
1231   GstPad *src, *sink;
1232
1233   src = gst_pad_new ("src", GST_PAD_SRC);
1234   sink = gst_pad_new ("sink", GST_PAD_SINK);
1235   gst_pad_set_chain_function (sink, gst_check_chain_func);
1236   gst_pad_set_active (src, TRUE);
1237   gst_pad_set_active (sink, TRUE);
1238
1239   fail_unless (gst_pad_push_event (src,
1240           gst_event_new_stream_start ("test")) == TRUE);
1241   fail_unless (gst_pad_push_event (src,
1242           gst_event_new_segment (&dummy_segment)) == TRUE);
1243
1244   fail_unless (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1245
1246   gst_pad_add_probe (src,
1247       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1248       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1249   gst_pad_add_probe (sink,
1250       GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
1251       GST_PAD_PROBE_TYPE_EVENT_FLUSH, flush_probe_cb, NULL, NULL);
1252
1253   gst_pad_push_event (src, gst_event_new_flush_start ());
1254   gst_pad_push_event (src, gst_event_new_flush_stop (TRUE));
1255
1256   fail_unless (gst_pad_push_event (src,
1257           gst_event_new_segment (&dummy_segment)) == TRUE);
1258
1259   /* push a buffer so the events are propagated downstream */
1260   gst_pad_push (src, gst_buffer_new ());
1261
1262   fail_unless (src_flush_start_probe_called);
1263   fail_unless (src_flush_stop_probe_called);
1264   fail_unless (sink_flush_start_probe_called);
1265   fail_unless (sink_flush_stop_probe_called);
1266
1267   gst_object_unref (src);
1268   gst_object_unref (sink);
1269 }
1270
1271 GST_END_TEST;
1272
1273 static gboolean got_notify;
1274
1275 static void
1276 caps_notify (GstPad * pad, GParamSpec * spec, gpointer data)
1277 {
1278   got_notify = TRUE;
1279 }
1280
1281 static void
1282 test_queue_src_caps_notify (gboolean link_queue)
1283 {
1284   GstElement *queue;
1285   GstPad *src, *sink, *another_pad;
1286   GstCaps *caps;
1287
1288   queue = gst_element_factory_make ("queue", NULL);
1289   fail_unless (queue != NULL);
1290
1291   src = gst_element_get_static_pad (queue, "src");
1292   fail_unless (src != NULL);
1293
1294   sink = gst_element_get_static_pad (queue, "sink");
1295   fail_unless (sink != NULL);
1296
1297   if (link_queue) {
1298     another_pad = gst_pad_new ("sink", GST_PAD_SINK);
1299     fail_unless (another_pad != NULL);
1300     gst_pad_set_active (another_pad, TRUE);
1301
1302     gst_pad_link_full (src, another_pad, GST_PAD_LINK_CHECK_NOTHING);
1303   } else {
1304     another_pad = NULL;
1305   }
1306
1307   gst_element_set_state (queue, GST_STATE_PLAYING);
1308
1309   got_notify = FALSE;
1310
1311   g_signal_connect (src, "notify::caps", G_CALLBACK (caps_notify), NULL);
1312
1313   caps = gst_caps_from_string ("caps");
1314   gst_pad_send_event (sink, gst_event_new_caps (caps));
1315   gst_caps_unref (caps);
1316
1317   while (got_notify == FALSE)
1318     g_usleep (10000);
1319
1320   gst_element_set_state (queue, GST_STATE_NULL);
1321
1322   gst_object_unref (src);
1323   gst_object_unref (sink);
1324   gst_object_unref (queue);
1325   if (another_pad) {
1326     gst_object_unref (another_pad);
1327   }
1328 }
1329
1330 GST_START_TEST (test_queue_src_caps_notify_linked)
1331 {
1332   test_queue_src_caps_notify (TRUE);
1333 }
1334
1335 GST_END_TEST
1336 GST_START_TEST (test_queue_src_caps_notify_not_linked)
1337 {
1338   /* This test will fail because queue doesn't set the caps
1339      on src pad unless it is linked */
1340   test_queue_src_caps_notify (FALSE);
1341 }
1342
1343 GST_END_TEST;
1344
1345 #if 0
1346 static void
1347 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
1348 {
1349   gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
1350 }
1351
1352 static void
1353 block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
1354 {
1355   static int n_calls = 0;
1356   gboolean *bool_user_data = (gboolean *) user_data;
1357
1358   if (++n_calls > 1)
1359     /* we expect this callback to be called only once */
1360     g_warn_if_reached ();
1361
1362   *bool_user_data = blocked;
1363
1364   /* replace block_async_first with block_async_second so next time the pad is
1365    * blocked the latter should be called */
1366   gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
1367
1368   /* unblock temporarily, in the next push block_async_second should be called
1369    */
1370   gst_pad_push_event (pad, gst_event_new_flush_start ());
1371 }
1372
1373 GST_START_TEST (test_block_async_replace_callback)
1374 {
1375   GstPad *pad;
1376   gboolean blocked;
1377
1378   pad = gst_pad_new ("src", GST_PAD_SRC);
1379   fail_unless (pad != NULL);
1380   gst_pad_set_active (pad, TRUE);
1381
1382   gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
1383   blocked = FALSE;
1384
1385   gst_pad_push (pad, gst_buffer_new ());
1386   fail_unless (blocked == TRUE);
1387   /* block_async_first flushes to unblock */
1388   gst_pad_push_event (pad, gst_event_new_flush_stop ());
1389
1390   /* push again, this time block_async_second should be called */
1391   gst_pad_push (pad, gst_buffer_new ());
1392   fail_unless (blocked == TRUE);
1393
1394   gst_object_unref (pad);
1395 }
1396
1397 GST_END_TEST;
1398 #endif
1399
1400 static void
1401 block_async_full_destroy (gpointer user_data)
1402 {
1403   gint *state = (gint *) user_data;
1404
1405   fail_unless (*state < 2);
1406
1407   GST_DEBUG ("setting state to 2");
1408   *state = 2;
1409 }
1410
1411 static GstPadProbeReturn
1412 block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1413 {
1414   *(gint *) user_data = (gint) TRUE;
1415
1416   gst_pad_push_event (pad, gst_event_new_flush_start ());
1417   GST_DEBUG ("setting state to 1");
1418
1419   return GST_PAD_PROBE_OK;
1420 }
1421
1422 GST_START_TEST (test_block_async_full_destroy)
1423 {
1424   GstPad *pad;
1425   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1426   gint state = 0;
1427   gulong id;
1428
1429   pad = gst_pad_new ("src", GST_PAD_SRC);
1430   fail_unless (pad != NULL);
1431   gst_pad_set_active (pad, TRUE);
1432
1433   fail_unless (gst_pad_push_event (pad,
1434           gst_event_new_stream_start ("test")) == TRUE);
1435   fail_unless (gst_pad_push_event (pad,
1436           gst_event_new_segment (&dummy_segment)) == TRUE);
1437
1438   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1439       &state, block_async_full_destroy);
1440   fail_unless (state == 0);
1441
1442   gst_pad_push (pad, gst_buffer_new ());
1443   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1444    */
1445   fail_unless (state == 1);
1446   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1447
1448   /* unblock callback is called */
1449   gst_pad_remove_probe (pad, id);
1450   fail_unless (state == 2);
1451
1452   gst_object_unref (pad);
1453 }
1454
1455 GST_END_TEST;
1456
1457 GST_START_TEST (test_block_async_full_destroy_dispose)
1458 {
1459   GstPad *pad;
1460   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
1461   gint state = 0;
1462
1463   pad = gst_pad_new ("src", GST_PAD_SRC);
1464   fail_unless (pad != NULL);
1465   gst_pad_set_active (pad, TRUE);
1466
1467   fail_unless (gst_pad_push_event (pad,
1468           gst_event_new_stream_start ("test")) == TRUE);
1469   fail_unless (gst_pad_push_event (pad,
1470           gst_event_new_segment (&dummy_segment)) == TRUE);
1471
1472   (void) gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK, block_async_full_cb,
1473       &state, block_async_full_destroy);
1474
1475   gst_pad_push (pad, gst_buffer_new ());
1476   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
1477    */
1478   fail_unless_equals_int (state, 1);
1479   gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
1480
1481   /* gst_BLOCK calls the destroy_notify function if necessary */
1482   gst_object_unref (pad);
1483
1484   fail_unless_equals_int (state, 2);
1485 }
1486
1487 GST_END_TEST;
1488
1489
1490 #if 0
1491 static void
1492 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
1493 {
1494   gboolean *bool_user_data = (gboolean *) user_data;
1495
1496   /* here we should have blocked == 1 unblocked == 0 */
1497
1498   fail_unless (blocked == FALSE);
1499
1500   fail_unless (bool_user_data[0] == TRUE);
1501   fail_unless (bool_user_data[1] == TRUE);
1502   fail_unless (bool_user_data[2] == FALSE);
1503
1504   bool_user_data[2] = TRUE;
1505 }
1506 #endif
1507
1508
1509 #if 0
1510 static void
1511 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
1512 {
1513   g_warn_if_reached ();
1514 }
1515 #endif
1516
1517 static GstPadProbeReturn
1518 block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
1519     gpointer user_data)
1520 {
1521   gboolean *bool_user_data = (gboolean *) user_data;
1522
1523   GST_DEBUG ("second probe called");
1524
1525   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1526
1527   fail_unless (bool_user_data[0] == TRUE);
1528   fail_unless (bool_user_data[1] == FALSE);
1529   fail_unless (bool_user_data[2] == FALSE);
1530
1531   bool_user_data[1] = TRUE;
1532
1533   GST_DEBUG ("removing second probe with id %lu", id);
1534   gst_pad_remove_probe (pad, id);
1535
1536   return GST_PAD_PROBE_OK;
1537 }
1538
1539 static GstPadProbeReturn
1540 block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
1541     gpointer user_data)
1542 {
1543   static int n_calls = 0;
1544   gboolean *bool_user_data = (gboolean *) user_data;
1545
1546   fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
1547
1548   GST_DEBUG ("first probe called");
1549
1550   if (++n_calls > 1)
1551     /* we expect this callback to be called only once */
1552     g_warn_if_reached ();
1553
1554   *bool_user_data = TRUE;
1555
1556   fail_unless (bool_user_data[0] == TRUE);
1557   fail_unless (bool_user_data[1] == FALSE);
1558   fail_unless (bool_user_data[2] == FALSE);
1559
1560   GST_DEBUG ("removing first probe with id %lu", id);
1561   gst_pad_remove_probe (pad, id);
1562
1563   GST_DEBUG ("adding second probe");
1564   /* replace block_async_first with block_async_second so next time the pad is
1565    * blocked the latter should be called */
1566   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1567       block_async_second_no_flush, user_data, NULL);
1568   GST_DEBUG ("added probe with id %lu", id);
1569
1570   return GST_PAD_PROBE_OK;
1571 }
1572
1573 GST_START_TEST (test_block_async_replace_callback_no_flush)
1574 {
1575   GstPad *pad;
1576   gboolean bool_user_data[3] = { FALSE, FALSE, FALSE };
1577
1578   pad = gst_pad_new ("src", GST_PAD_SRC);
1579   fail_unless (pad != NULL);
1580   gst_pad_set_active (pad, TRUE);
1581
1582   fail_unless (gst_pad_push_event (pad,
1583           gst_event_new_stream_start ("test")) == TRUE);
1584   fail_unless (gst_pad_push_event (pad,
1585           gst_event_new_segment (&dummy_segment)) == TRUE);
1586
1587   GST_DEBUG ("adding probe");
1588   id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK,
1589       block_async_first_no_flush, bool_user_data, NULL);
1590   GST_DEBUG ("added probe with id %lu", id);
1591   fail_if (id == 0);
1592
1593   GST_DEBUG ("pushing buffer");
1594   gst_pad_push (pad, gst_buffer_new ());
1595   fail_unless (bool_user_data[0] == TRUE);
1596   fail_unless (bool_user_data[1] == TRUE);
1597   fail_unless (bool_user_data[2] == FALSE);
1598
1599   gst_object_unref (pad);
1600 }
1601
1602 GST_END_TEST;
1603
1604 static gint sticky_count;
1605
1606 static gboolean
1607 test_sticky_events_handler (GstPad * pad, GstObject * parent, GstEvent * event)
1608 {
1609   GST_DEBUG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
1610
1611   switch (sticky_count) {
1612     case 0:
1613       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
1614       break;
1615     case 1:
1616     {
1617       GstCaps *caps;
1618       GstStructure *s;
1619
1620       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
1621
1622       gst_event_parse_caps (event, &caps);
1623       fail_unless (gst_caps_get_size (caps) == 1);
1624       s = gst_caps_get_structure (caps, 0);
1625       fail_unless (gst_structure_has_name (s, "foo/baz"));
1626       break;
1627     }
1628     case 2:
1629       fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1630       break;
1631     default:
1632       fail_unless (FALSE);
1633       break;
1634   }
1635
1636   gst_event_unref (event);
1637   sticky_count++;
1638
1639   return TRUE;
1640 }
1641
1642 static GstFlowReturn
1643 test_sticky_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1644 {
1645   gst_buffer_unref (buffer);
1646   return GST_FLOW_OK;
1647 }
1648
1649 GST_START_TEST (test_sticky_events)
1650 {
1651   GstPad *srcpad, *sinkpad;
1652   GstCaps *caps;
1653   GstSegment seg;
1654   gchar *id;
1655
1656   /* make unlinked srcpad */
1657   srcpad = gst_pad_new ("src", GST_PAD_SRC);
1658   fail_unless (srcpad != NULL);
1659   gst_pad_set_active (srcpad, TRUE);
1660
1661   /* test stream-start */
1662   fail_unless (gst_pad_get_stream_id (srcpad) == NULL);
1663
1664   /* push an event, it should be sticky on the srcpad */
1665   fail_unless (gst_pad_push_event (srcpad,
1666           gst_event_new_stream_start ("test")) == TRUE);
1667
1668   /* let's see if it stuck */
1669   id = gst_pad_get_stream_id (srcpad);
1670   fail_unless_equals_string (id, "test");
1671   g_free (id);
1672
1673   /* make a caps event */
1674   caps = gst_caps_new_empty_simple ("foo/bar");
1675   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1676   gst_caps_unref (caps);
1677
1678   /* make segment event */
1679   gst_segment_init (&seg, GST_FORMAT_TIME);
1680   gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
1681
1682   /* now make a sinkpad */
1683   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
1684   fail_unless (sinkpad != NULL);
1685   sticky_count = 0;
1686   gst_pad_set_event_function (sinkpad, test_sticky_events_handler);
1687   gst_pad_set_chain_function (sinkpad, test_sticky_chain);
1688   fail_unless (sticky_count == 0);
1689   gst_pad_set_active (sinkpad, TRUE);
1690
1691   /* link the pads */
1692   gst_pad_link (srcpad, sinkpad);
1693   /* should not trigger events */
1694   fail_unless (sticky_count == 0);
1695
1696   /* caps replaces old caps event at position 2, the pushes all
1697    * pending events */
1698   caps = gst_caps_new_empty_simple ("foo/baz");
1699   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
1700   gst_caps_unref (caps);
1701
1702   /* should have triggered 2 events, the segment event is still pending */
1703   fail_unless_equals_int (sticky_count, 2);
1704
1705   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
1706
1707   /* should have triggered 3 events */
1708   fail_unless_equals_int (sticky_count, 3);
1709
1710   gst_object_unref (srcpad);
1711   gst_object_unref (sinkpad);
1712 }
1713
1714 GST_END_TEST;
1715
1716 static Suite *
1717 gst_pad_suite (void)
1718 {
1719   Suite *s = suite_create ("GstPad");
1720   TCase *tc_chain = tcase_create ("general");
1721
1722   /* turn off timeout */
1723   tcase_set_timeout (tc_chain, 60);
1724
1725   gst_segment_init (&dummy_segment, GST_FORMAT_BYTES);
1726
1727   suite_add_tcase (s, tc_chain);
1728   tcase_add_test (tc_chain, test_link);
1729   tcase_add_test (tc_chain, test_refcount);
1730   tcase_add_test (tc_chain, test_get_allowed_caps);
1731   tcase_add_test (tc_chain, test_sticky_caps_unlinked);
1732   tcase_add_test (tc_chain, test_sticky_caps_unlinked_incompatible);
1733   tcase_add_test (tc_chain, test_sticky_caps_flushing);
1734   tcase_add_test (tc_chain, test_link_unlink_threaded);
1735   tcase_add_test (tc_chain, test_name_is_valid);
1736   tcase_add_test (tc_chain, test_push_unlinked);
1737   tcase_add_test (tc_chain, test_push_linked);
1738   tcase_add_test (tc_chain, test_push_linked_flushing);
1739   tcase_add_test (tc_chain, test_push_buffer_list_compat);
1740   tcase_add_test (tc_chain, test_flowreturn);
1741   tcase_add_test (tc_chain, test_push_negotiation);
1742   tcase_add_test (tc_chain, test_src_unref_unlink);
1743   tcase_add_test (tc_chain, test_sink_unref_unlink);
1744   tcase_add_test (tc_chain, test_block_async);
1745   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_block);
1746   tcase_add_test (tc_chain, test_pad_blocking_with_probe_type_blocking);
1747   tcase_add_test (tc_chain, test_pad_probe_remove);
1748   tcase_add_test (tc_chain, test_pad_probe_flush_events);
1749   tcase_add_test (tc_chain, test_queue_src_caps_notify_linked);
1750   tcase_add_test (tc_chain, test_queue_src_caps_notify_not_linked);
1751 #if 0
1752   tcase_add_test (tc_chain, test_block_async_replace_callback);
1753 #endif
1754   tcase_add_test (tc_chain, test_block_async_full_destroy);
1755   tcase_add_test (tc_chain, test_block_async_full_destroy_dispose);
1756   tcase_add_test (tc_chain, test_block_async_replace_callback_no_flush);
1757   tcase_add_test (tc_chain, test_sticky_events);
1758
1759   return s;
1760 }
1761
1762 GST_CHECK_MAIN (gst_pad);