Remove 0.10-related documentation and "Since" markers
[platform/upstream/gstreamer.git] / gst / gstpad.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstpad.c: Pads for linking elements together
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 /**
23  * SECTION:gstpad
24  * @short_description: Object contained by elements that allows links to
25  *                     other elements
26  * @see_also: #GstPadTemplate, #GstElement, #GstEvent, #GstQuery, #GstBuffer
27  *
28  * A #GstElement is linked to other elements via "pads", which are extremely
29  * light-weight generic link points.
30  *
31  * Pads have a #GstPadDirection, source pads produce data, sink pads consume
32  * data.
33  *
34  * Pads are typically created from a #GstPadTemplate with
35  * gst_pad_new_from_template() and are then added to a #GstElement. This usually
36  * happens when the element is created but it can also happen dynamically based
37  * on the data that the element is processing or based on the pads that the
38  * application requests.
39  *
40  * Pads without pad templates can be created with gst_pad_new(),
41  * which takes a direction and a name as an argument.  If the name is NULL,
42  * then a guaranteed unique name will be assigned to it.
43  *
44  * A #GstElement creating a pad will typically use the various
45  * gst_pad_set_*_function() calls to register callbacks for events, queries or
46  * dataflow on the pads.
47  *
48  * gst_pad_get_parent() will retrieve the #GstElement that owns the pad.
49  *
50  * After two pads are retrieved from an element with gst_element_get_pad(),
51  * the pads can be linked with gst_pad_link(). (For quick links,
52  * you can also use gst_element_link(), which will make the obvious
53  * link for you if it's straightforward.). Pads can be unlinked again with
54  * gst_pad_unlink(). gst_pad_get_peer() can be used to check what the pad is
55  * linked to.
56  *
57  * Before dataflow is possible on the pads, they need to be activated with
58  * gst_pad_set_active().
59  *
60  * gst_pad_query() and gst_pad_peer_query() can be used to query various
61  * properties of the pad and the stream.
62  *
63  * To send a #GstEvent on a pad, use gst_pad_send_event() and
64  * gst_pad_push_event(). Some events will be sticky on the pad, meaning that
65  * after they pass on the pad they can be queried later with
66  * gst_pad_get_sticky_event() and gst_pad_sticky_events_foreach().
67  * gst_pad_get_current_caps() and gst_pad_has_current_caps() are convenience
68  * functions to query the current sticky CAPS event on a pad.
69  *
70  * GstElements will use gst_pad_push() and gst_pad_pull_range() to push out
71  * or pull in a buffer.
72  *
73  * The dataflow, events and queries that happen on a pad can be monitored with
74  * probes that can be installed with gst_pad_add_probe(). gst_pad_is_blocked()
75  * can be used to check if a block probe is installed on the pad.
76  * gst_pad_is_blocking() checks if the blocking probe is currently blocking the
77  * pad. gst_pad_remove_probe() is used to remove a previously installed probe
78  * and unblock blocking probes if any.
79  *
80  * Pad have an offset that can be retrieved with gst_pad_get_offset(). This
81  * offset will be applied to the running_time of all data passing over the pad.
82  * gst_pad_set_offset() can be used to change the offset.
83  *
84  * Convenience functions exist to start, pause and stop the task on a pad with
85  * gst_pad_start_task(), gst_pad_pause_task() and gst_pad_stop_task()
86  * respectively.
87  *
88  * Last reviewed on 2012-03-29 (0.11.3)
89  */
90
91 #include "gst_private.h"
92
93 #include "gstpad.h"
94 #include "gstpadtemplate.h"
95 #include "gstenumtypes.h"
96 #include "gstutils.h"
97 #include "gstinfo.h"
98 #include "gsterror.h"
99 #include "gstvalue.h"
100 #include "glib-compat-private.h"
101
102 GST_DEBUG_CATEGORY_STATIC (debug_dataflow);
103 #define GST_CAT_DEFAULT GST_CAT_PADS
104
105 /* Pad signals and args */
106 enum
107 {
108   PAD_LINKED,
109   PAD_UNLINKED,
110   /* FILL ME */
111   LAST_SIGNAL
112 };
113
114 enum
115 {
116   PAD_PROP_0,
117   PAD_PROP_CAPS,
118   PAD_PROP_DIRECTION,
119   PAD_PROP_TEMPLATE,
120   /* FILL ME */
121 };
122
123 #define GST_PAD_GET_PRIVATE(obj)  \
124    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_PAD, GstPadPrivate))
125
126 /* we have a pending and an active event on the pad. On source pads only the
127  * active event is used. On sinkpads, events are copied to the pending entry and
128  * moved to the active event when the eventfunc returned TRUE. */
129 typedef struct
130 {
131   gboolean received;
132   GstEvent *event;
133 } PadEvent;
134
135 struct _GstPadPrivate
136 {
137   guint events_cookie;
138   GArray *events;
139
140   gint using;
141   guint probe_list_cookie;
142   guint probe_cookie;
143 };
144
145 typedef struct
146 {
147   GHook hook;
148   guint cookie;
149 } GstProbe;
150
151 #define PROBE_COOKIE(h) (((GstProbe *)(h))->cookie)
152
153 typedef struct
154 {
155   GstPad *pad;
156   GstPadProbeInfo *info;
157   gboolean dropped;
158   gboolean pass;
159   gboolean marshalled;
160   guint cookie;
161 } ProbeMarshall;
162
163 static void gst_pad_dispose (GObject * object);
164 static void gst_pad_finalize (GObject * object);
165 static void gst_pad_set_property (GObject * object, guint prop_id,
166     const GValue * value, GParamSpec * pspec);
167 static void gst_pad_get_property (GObject * object, guint prop_id,
168     GValue * value, GParamSpec * pspec);
169
170 static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
171 static gboolean gst_pad_activate_default (GstPad * pad, GstObject * parent);
172 static GstFlowReturn gst_pad_chain_list_default (GstPad * pad,
173     GstObject * parent, GstBufferList * list);
174
175 static GstFlowReturn gst_pad_send_event_unchecked (GstPad * pad,
176     GstEvent * event, GstPadProbeType type);
177 static GstFlowReturn gst_pad_push_event_unchecked (GstPad * pad,
178     GstEvent * event, GstPadProbeType type);
179
180 static guint gst_pad_signals[LAST_SIGNAL] = { 0 };
181
182 static GParamSpec *pspec_caps = NULL;
183
184 /* quarks for probe signals */
185 static GQuark buffer_quark;
186 static GQuark buffer_list_quark;
187 static GQuark event_quark;
188
189 typedef struct
190 {
191   const gint ret;
192   const gchar *name;
193   GQuark quark;
194 } GstFlowQuarks;
195
196 static GstFlowQuarks flow_quarks[] = {
197   {GST_FLOW_CUSTOM_SUCCESS, "custom-success", 0},
198   {GST_FLOW_OK, "ok", 0},
199   {GST_FLOW_NOT_LINKED, "not-linked", 0},
200   {GST_FLOW_FLUSHING, "flushing", 0},
201   {GST_FLOW_EOS, "eos", 0},
202   {GST_FLOW_NOT_NEGOTIATED, "not-negotiated", 0},
203   {GST_FLOW_ERROR, "error", 0},
204   {GST_FLOW_NOT_SUPPORTED, "not-supported", 0},
205   {GST_FLOW_CUSTOM_ERROR, "custom-error", 0}
206 };
207
208 /**
209  * gst_flow_get_name:
210  * @ret: a #GstFlowReturn to get the name of.
211  *
212  * Gets a string representing the given flow return.
213  *
214  * Returns: a static string with the name of the flow return.
215  */
216 const gchar *
217 gst_flow_get_name (GstFlowReturn ret)
218 {
219   gint i;
220
221   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
222
223   for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) {
224     if (ret == flow_quarks[i].ret)
225       return flow_quarks[i].name;
226   }
227   return "unknown";
228 }
229
230 /**
231  * gst_flow_to_quark:
232  * @ret: a #GstFlowReturn to get the quark of.
233  *
234  * Get the unique quark for the given GstFlowReturn.
235  *
236  * Returns: the quark associated with the flow return or 0 if an
237  * invalid return was specified.
238  */
239 GQuark
240 gst_flow_to_quark (GstFlowReturn ret)
241 {
242   gint i;
243
244   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
245
246   for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) {
247     if (ret == flow_quarks[i].ret)
248       return flow_quarks[i].quark;
249   }
250   return 0;
251 }
252
253 #define _do_init \
254 { \
255   gint i; \
256   \
257   buffer_quark = g_quark_from_static_string ("buffer"); \
258   buffer_list_quark = g_quark_from_static_string ("bufferlist"); \
259   event_quark = g_quark_from_static_string ("event"); \
260   \
261   for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) {                    \
262     flow_quarks[i].quark = g_quark_from_static_string (flow_quarks[i].name); \
263   } \
264   \
265   GST_DEBUG_CATEGORY_INIT (debug_dataflow, "GST_DATAFLOW", \
266       GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "dataflow inside pads"); \
267 }
268
269 #define gst_pad_parent_class parent_class
270 G_DEFINE_TYPE_WITH_CODE (GstPad, gst_pad, GST_TYPE_OBJECT, _do_init);
271
272 static void
273 gst_pad_class_init (GstPadClass * klass)
274 {
275   GObjectClass *gobject_class;
276   GstObjectClass *gstobject_class;
277
278   gobject_class = G_OBJECT_CLASS (klass);
279   gstobject_class = GST_OBJECT_CLASS (klass);
280
281   g_type_class_add_private (klass, sizeof (GstPadPrivate));
282
283   gobject_class->dispose = gst_pad_dispose;
284   gobject_class->finalize = gst_pad_finalize;
285   gobject_class->set_property = gst_pad_set_property;
286   gobject_class->get_property = gst_pad_get_property;
287
288   /**
289    * GstPad::linked:
290    * @pad: the pad that emitted the signal
291    * @peer: the peer pad that has been connected
292    *
293    * Signals that a pad has been linked to the peer pad.
294    */
295   gst_pad_signals[PAD_LINKED] =
296       g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
297       G_STRUCT_OFFSET (GstPadClass, linked), NULL, NULL,
298       g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
299   /**
300    * GstPad::unlinked:
301    * @pad: the pad that emitted the signal
302    * @peer: the peer pad that has been disconnected
303    *
304    * Signals that a pad has been unlinked from the peer pad.
305    */
306   gst_pad_signals[PAD_UNLINKED] =
307       g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
308       G_STRUCT_OFFSET (GstPadClass, unlinked), NULL, NULL,
309       g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
310
311   pspec_caps = g_param_spec_boxed ("caps", "Caps",
312       "The capabilities of the pad", GST_TYPE_CAPS,
313       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
314   g_object_class_install_property (gobject_class, PAD_PROP_CAPS, pspec_caps);
315
316   g_object_class_install_property (gobject_class, PAD_PROP_DIRECTION,
317       g_param_spec_enum ("direction", "Direction", "The direction of the pad",
318           GST_TYPE_PAD_DIRECTION, GST_PAD_UNKNOWN,
319           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
320
321   /* FIXME, Make G_PARAM_CONSTRUCT_ONLY when we fix ghostpads. */
322   g_object_class_install_property (gobject_class, PAD_PROP_TEMPLATE,
323       g_param_spec_object ("template", "Template",
324           "The GstPadTemplate of this pad", GST_TYPE_PAD_TEMPLATE,
325           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
326
327   gstobject_class->path_string_separator = ".";
328
329   /* Register common function pointer descriptions */
330   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_activate_default);
331   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_event_default);
332   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_query_default);
333   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_iterate_internal_links_default);
334   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_chain_list_default);
335 }
336
337 static void
338 gst_pad_init (GstPad * pad)
339 {
340   pad->priv = GST_PAD_GET_PRIVATE (pad);
341
342   GST_PAD_DIRECTION (pad) = GST_PAD_UNKNOWN;
343
344   GST_PAD_ACTIVATEFUNC (pad) = gst_pad_activate_default;
345   GST_PAD_EVENTFUNC (pad) = gst_pad_event_default;
346   GST_PAD_QUERYFUNC (pad) = gst_pad_query_default;
347   GST_PAD_ITERINTLINKFUNC (pad) = gst_pad_iterate_internal_links_default;
348   GST_PAD_CHAINLISTFUNC (pad) = gst_pad_chain_list_default;
349
350   GST_PAD_SET_FLUSHING (pad);
351
352   g_rec_mutex_init (&pad->stream_rec_lock);
353
354   g_cond_init (&pad->block_cond);
355
356   g_hook_list_init (&pad->probes, sizeof (GstProbe));
357
358   pad->priv->events = g_array_sized_new (FALSE, TRUE, sizeof (PadEvent), 16);
359 }
360
361 /* called when setting the pad inactive. It removes all sticky events from
362  * the pad */
363 static void
364 remove_events (GstPad * pad)
365 {
366   guint i, len;
367   GArray *events;
368
369   events = pad->priv->events;
370
371   len = events->len;
372   for (i = 0; i < len; i++) {
373     PadEvent *ev = &g_array_index (events, PadEvent, i);
374     gst_event_unref (ev->event);
375   }
376   GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PENDING_EVENTS);
377   g_array_set_size (events, 0);
378   pad->priv->events_cookie++;
379 }
380
381 static PadEvent *
382 find_event_by_type (GstPad * pad, GstEventType type, guint idx)
383 {
384   guint i, len;
385   GArray *events;
386   PadEvent *ev;
387
388   events = pad->priv->events;
389   len = events->len;
390
391   for (i = 0; i < len; i++) {
392     ev = &g_array_index (events, PadEvent, i);
393     if (ev->event == NULL)
394       continue;
395
396     if (GST_EVENT_TYPE (ev->event) == type) {
397       if (idx == 0)
398         goto found;
399       idx--;
400     }
401   }
402   ev = NULL;
403 found:
404   return ev;
405 }
406
407 static PadEvent *
408 find_event (GstPad * pad, GstEvent * event)
409 {
410   guint i, len;
411   GArray *events;
412   PadEvent *ev;
413
414   events = pad->priv->events;
415   len = events->len;
416
417   for (i = 0; i < len; i++) {
418     ev = &g_array_index (events, PadEvent, i);
419     if (event == ev->event)
420       goto found;
421   }
422   ev = NULL;
423 found:
424   return ev;
425 }
426
427 static void
428 remove_event_by_type (GstPad * pad, GstEventType type)
429 {
430   guint i, len;
431   GArray *events;
432   PadEvent *ev;
433
434   events = pad->priv->events;
435   len = events->len;
436
437   i = 0;
438   while (i < len) {
439     ev = &g_array_index (events, PadEvent, i);
440     if (ev->event == NULL)
441       goto next;
442
443     if (GST_EVENT_TYPE (ev->event) != type)
444       goto next;
445
446     gst_event_unref (ev->event);
447     g_array_remove_index (events, i);
448     len--;
449     pad->priv->events_cookie++;
450     continue;
451
452   next:
453     i++;
454   }
455 }
456
457 /* check all events on srcpad against those on sinkpad. All events that are not
458  * on sinkpad are marked as received=FALSE and the PENDING_EVENTS is set on the
459  * srcpad so that the events will be sent next time */
460 static void
461 schedule_events (GstPad * srcpad, GstPad * sinkpad)
462 {
463   gint i, len;
464   GArray *events;
465   PadEvent *ev;
466   gboolean pending = FALSE;
467
468   events = srcpad->priv->events;
469   len = events->len;
470
471   for (i = 0; i < len; i++) {
472     ev = &g_array_index (events, PadEvent, i);
473     if (ev->event == NULL)
474       continue;
475
476     if (sinkpad == NULL || !find_event (sinkpad, ev->event)) {
477       ev->received = FALSE;
478       pending = TRUE;
479     }
480   }
481   if (pending)
482     GST_OBJECT_FLAG_SET (srcpad, GST_PAD_FLAG_PENDING_EVENTS);
483 }
484
485 typedef gboolean (*PadEventFunction) (GstPad * pad, PadEvent * ev,
486     gpointer user_data);
487
488 /* should be called with pad LOCK */
489 static void
490 events_foreach (GstPad * pad, PadEventFunction func, gpointer user_data)
491 {
492   guint i, len;
493   GArray *events;
494   gboolean ret;
495   guint cookie;
496
497   events = pad->priv->events;
498
499 restart:
500   cookie = pad->priv->events_cookie;
501   i = 0;
502   len = events->len;
503   while (i < len) {
504     PadEvent *ev, ev_ret;
505
506     ev = &g_array_index (events, PadEvent, i);
507     if (G_UNLIKELY (ev->event == NULL))
508       goto next;
509
510     /* take aditional ref, func might release the lock */
511     ev_ret.event = gst_event_ref (ev->event);
512     ev_ret.received = ev->received;
513
514     ret = func (pad, &ev_ret, user_data);
515
516     /* recheck the cookie, lock might have been released and the list could have
517      * changed */
518     if (G_UNLIKELY (cookie != pad->priv->events_cookie)) {
519       if (G_LIKELY (ev_ret.event))
520         gst_event_unref (ev_ret.event);
521       goto restart;
522     }
523
524     /* store the received state */
525     ev->received = ev_ret.received;
526
527     /* if the event changed, we need to do something */
528     if (G_UNLIKELY (ev->event != ev_ret.event)) {
529       if (G_UNLIKELY (ev_ret.event == NULL)) {
530         /* function unreffed and set the event to NULL, remove it */
531         g_array_remove_index (events, i);
532         len--;
533         cookie = ++pad->priv->events_cookie;
534         continue;
535       } else {
536         /* function gave a new event for us */
537         gst_event_take (&ev->event, ev_ret.event);
538       }
539     } else {
540       /* just unref, nothing changed */
541       gst_event_unref (ev_ret.event);
542     }
543     if (!ret)
544       break;
545   next:
546     i++;
547   }
548 }
549
550 /* should be called with LOCK */
551 static GstEvent *
552 apply_pad_offset (GstPad * pad, GstEvent * event)
553 {
554   /* check if we need to adjust the segment */
555   if (pad->offset != 0) {
556     GstSegment segment;
557
558     /* copy segment values */
559     gst_event_copy_segment (event, &segment);
560     gst_event_unref (event);
561
562     /* adjust and make a new event with the offset applied */
563     segment.base += pad->offset;
564     event = gst_event_new_segment (&segment);
565   }
566   return event;
567 }
568
569 /* should be called with the OBJECT_LOCK */
570 static GstCaps *
571 get_pad_caps (GstPad * pad)
572 {
573   GstCaps *caps = NULL;
574   PadEvent *ev;
575
576   ev = find_event_by_type (pad, GST_EVENT_CAPS, 0);
577   if (ev && ev->event)
578     gst_event_parse_caps (ev->event, &caps);
579
580   return caps;
581 }
582
583 static void
584 gst_pad_dispose (GObject * object)
585 {
586   GstPad *pad = GST_PAD_CAST (object);
587   GstPad *peer;
588
589   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pad, "dispose");
590
591   /* unlink the peer pad */
592   if ((peer = gst_pad_get_peer (pad))) {
593     /* window for MT unsafeness, someone else could unlink here
594      * and then we call unlink with wrong pads. The unlink
595      * function would catch this and safely return failed. */
596     if (GST_PAD_IS_SRC (pad))
597       gst_pad_unlink (pad, peer);
598     else
599       gst_pad_unlink (peer, pad);
600
601     gst_object_unref (peer);
602   }
603
604   gst_pad_set_pad_template (pad, NULL);
605
606   remove_events (pad);
607
608   g_hook_list_clear (&pad->probes);
609
610   G_OBJECT_CLASS (parent_class)->dispose (object);
611 }
612
613 static void
614 gst_pad_finalize (GObject * object)
615 {
616   GstPad *pad = GST_PAD_CAST (object);
617   GstTask *task;
618
619   /* in case the task is still around, clean it up */
620   if ((task = GST_PAD_TASK (pad))) {
621     gst_task_join (task);
622     GST_PAD_TASK (pad) = NULL;
623     gst_object_unref (task);
624   }
625
626   if (pad->activatenotify)
627     pad->activatenotify (pad->activatedata);
628   if (pad->activatemodenotify)
629     pad->activatemodenotify (pad->activatemodedata);
630   if (pad->linknotify)
631     pad->linknotify (pad->linkdata);
632   if (pad->unlinknotify)
633     pad->unlinknotify (pad->unlinkdata);
634   if (pad->chainnotify)
635     pad->chainnotify (pad->chaindata);
636   if (pad->chainlistnotify)
637     pad->chainlistnotify (pad->chainlistdata);
638   if (pad->getrangenotify)
639     pad->getrangenotify (pad->getrangedata);
640   if (pad->eventnotify)
641     pad->eventnotify (pad->eventdata);
642   if (pad->querynotify)
643     pad->querynotify (pad->querydata);
644   if (pad->iterintlinknotify)
645     pad->iterintlinknotify (pad->iterintlinkdata);
646
647   g_rec_mutex_clear (&pad->stream_rec_lock);
648   g_cond_clear (&pad->block_cond);
649   g_array_free (pad->priv->events, TRUE);
650
651   G_OBJECT_CLASS (parent_class)->finalize (object);
652 }
653
654 static void
655 gst_pad_set_property (GObject * object, guint prop_id,
656     const GValue * value, GParamSpec * pspec)
657 {
658   g_return_if_fail (GST_IS_PAD (object));
659
660   switch (prop_id) {
661     case PAD_PROP_DIRECTION:
662       GST_PAD_DIRECTION (object) = (GstPadDirection) g_value_get_enum (value);
663       break;
664     case PAD_PROP_TEMPLATE:
665       gst_pad_set_pad_template (GST_PAD_CAST (object),
666           (GstPadTemplate *) g_value_get_object (value));
667       break;
668     default:
669       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
670       break;
671   }
672 }
673
674 static void
675 gst_pad_get_property (GObject * object, guint prop_id,
676     GValue * value, GParamSpec * pspec)
677 {
678   g_return_if_fail (GST_IS_PAD (object));
679
680   switch (prop_id) {
681     case PAD_PROP_CAPS:
682       GST_OBJECT_LOCK (object);
683       g_value_set_boxed (value, get_pad_caps (GST_PAD_CAST (object)));
684       GST_OBJECT_UNLOCK (object);
685       break;
686     case PAD_PROP_DIRECTION:
687       g_value_set_enum (value, GST_PAD_DIRECTION (object));
688       break;
689     case PAD_PROP_TEMPLATE:
690       g_value_set_object (value, GST_PAD_PAD_TEMPLATE (object));
691       break;
692     default:
693       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
694       break;
695   }
696 }
697
698 /**
699  * gst_pad_new:
700  * @name: the name of the new pad.
701  * @direction: the #GstPadDirection of the pad.
702  *
703  * Creates a new pad with the given name in the given direction.
704  * If name is NULL, a guaranteed unique name (across all pads)
705  * will be assigned.
706  * This function makes a copy of the name so you can safely free the name.
707  *
708  * Returns: (transfer floating): a new #GstPad, or NULL in case of an error.
709  *
710  * MT safe.
711  */
712 GstPad *
713 gst_pad_new (const gchar * name, GstPadDirection direction)
714 {
715   return g_object_new (GST_TYPE_PAD,
716       "name", name, "direction", direction, NULL);
717 }
718
719 /**
720  * gst_pad_new_from_template:
721  * @templ: the pad template to use
722  * @name: the name of the element
723  *
724  * Creates a new pad with the given name from the given template.
725  * If name is NULL, a guaranteed unique name (across all pads)
726  * will be assigned.
727  * This function makes a copy of the name so you can safely free the name.
728  *
729  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
730  */
731 GstPad *
732 gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
733 {
734   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
735
736   return g_object_new (GST_TYPE_PAD,
737       "name", name, "direction", templ->direction, "template", templ, NULL);
738 }
739
740 /**
741  * gst_pad_new_from_static_template:
742  * @templ: the #GstStaticPadTemplate to use
743  * @name: the name of the element
744  *
745  * Creates a new pad with the given name from the given static template.
746  * If name is NULL, a guaranteed unique name (across all pads)
747  * will be assigned.
748  * This function makes a copy of the name so you can safely free the name.
749  *
750  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
751  */
752 GstPad *
753 gst_pad_new_from_static_template (GstStaticPadTemplate * templ,
754     const gchar * name)
755 {
756   GstPad *pad;
757   GstPadTemplate *template;
758
759   template = gst_static_pad_template_get (templ);
760   pad = gst_pad_new_from_template (template, name);
761   gst_object_unref (template);
762   return pad;
763 }
764
765 #define ACQUIRE_PARENT(pad, parent, label)                      \
766   G_STMT_START {                                                \
767     if (G_LIKELY ((parent = GST_OBJECT_PARENT (pad))))          \
768       gst_object_ref (parent);                                  \
769     else if (G_LIKELY (GST_PAD_NEEDS_PARENT (pad)))             \
770       goto label;                                               \
771   } G_STMT_END
772
773 #define RELEASE_PARENT(parent)                                  \
774   G_STMT_START {                                                \
775     if (G_LIKELY (parent))                                      \
776       gst_object_unref (parent);                                \
777   } G_STMT_END
778
779 /**
780  * gst_pad_get_direction:
781  * @pad: a #GstPad to get the direction of.
782  *
783  * Gets the direction of the pad. The direction of the pad is
784  * decided at construction time so this function does not take
785  * the LOCK.
786  *
787  * Returns: the #GstPadDirection of the pad.
788  *
789  * MT safe.
790  */
791 GstPadDirection
792 gst_pad_get_direction (GstPad * pad)
793 {
794   GstPadDirection result;
795
796   /* PAD_UNKNOWN is a little silly but we need some sort of
797    * error return value */
798   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
799
800   result = GST_PAD_DIRECTION (pad);
801
802   return result;
803 }
804
805 static gboolean
806 gst_pad_activate_default (GstPad * pad, GstObject * parent)
807 {
808   return gst_pad_activate_mode (pad, GST_PAD_MODE_PUSH, TRUE);
809 }
810
811 #ifndef GST_DISABLE_GST_DEBUG
812 static const gchar *
813 gst_pad_mode_get_name (GstPadMode mode)
814 {
815   switch (mode) {
816     case GST_PAD_MODE_NONE:
817       return "none";
818     case GST_PAD_MODE_PUSH:
819       return "push";
820     case GST_PAD_MODE_PULL:
821       return "pull";
822     default:
823       break;
824   }
825   return "unknown";
826 }
827 #endif
828
829 static void
830 pre_activate (GstPad * pad, GstPadMode new_mode)
831 {
832   switch (new_mode) {
833     case GST_PAD_MODE_NONE:
834       GST_OBJECT_LOCK (pad);
835       GST_DEBUG_OBJECT (pad, "setting PAD_MODE NONE, set flushing");
836       GST_PAD_SET_FLUSHING (pad);
837       GST_PAD_MODE (pad) = new_mode;
838       /* unlock blocked pads so element can resume and stop */
839       GST_PAD_BLOCK_BROADCAST (pad);
840       GST_OBJECT_UNLOCK (pad);
841       break;
842     case GST_PAD_MODE_PUSH:
843     case GST_PAD_MODE_PULL:
844       GST_OBJECT_LOCK (pad);
845       GST_DEBUG_OBJECT (pad, "setting pad into %s mode, unset flushing",
846           gst_pad_mode_get_name (new_mode));
847       GST_PAD_UNSET_FLUSHING (pad);
848       GST_PAD_MODE (pad) = new_mode;
849       if (GST_PAD_IS_SINK (pad)) {
850         GstPad *peer;
851         /* make sure the peer src pad sends us all events */
852         if ((peer = GST_PAD_PEER (pad))) {
853           gst_object_ref (peer);
854           GST_OBJECT_UNLOCK (pad);
855
856           GST_DEBUG_OBJECT (pad, "reschedule events on peer %s:%s",
857               GST_DEBUG_PAD_NAME (peer));
858
859           GST_OBJECT_LOCK (peer);
860           schedule_events (peer, NULL);
861           GST_OBJECT_UNLOCK (peer);
862
863           gst_object_unref (peer);
864         } else {
865           GST_OBJECT_UNLOCK (pad);
866         }
867       } else {
868         GST_OBJECT_UNLOCK (pad);
869       }
870       break;
871   }
872 }
873
874 static void
875 post_activate (GstPad * pad, GstPadMode new_mode)
876 {
877   switch (new_mode) {
878     case GST_PAD_MODE_NONE:
879       /* ensures that streaming stops */
880       GST_PAD_STREAM_LOCK (pad);
881       GST_DEBUG_OBJECT (pad, "stopped streaming");
882       GST_OBJECT_LOCK (pad);
883       remove_events (pad);
884       GST_OBJECT_UNLOCK (pad);
885       GST_PAD_STREAM_UNLOCK (pad);
886       break;
887     case GST_PAD_MODE_PUSH:
888     case GST_PAD_MODE_PULL:
889       /* NOP */
890       break;
891   }
892 }
893
894 /**
895  * gst_pad_set_active:
896  * @pad: the #GstPad to activate or deactivate.
897  * @active: whether or not the pad should be active.
898  *
899  * Activates or deactivates the given pad.
900  * Normally called from within core state change functions.
901  *
902  * If @active, makes sure the pad is active. If it is already active, either in
903  * push or pull mode, just return. Otherwise dispatches to the pad's activate
904  * function to perform the actual activation.
905  *
906  * If not @active, checks the pad's current mode and calls
907  * gst_pad_activate_push() or gst_pad_activate_pull(), as appropriate, with a
908  * FALSE argument.
909  *
910  * Returns: #TRUE if the operation was successful.
911  *
912  * MT safe.
913  */
914 gboolean
915 gst_pad_set_active (GstPad * pad, gboolean active)
916 {
917   GstObject *parent;
918   GstPadMode old;
919   gboolean ret = FALSE;
920
921   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
922
923   GST_OBJECT_LOCK (pad);
924   old = GST_PAD_MODE (pad);
925   ACQUIRE_PARENT (pad, parent, no_parent);
926   GST_OBJECT_UNLOCK (pad);
927
928   if (active) {
929     if (old == GST_PAD_MODE_NONE) {
930       GST_DEBUG_OBJECT (pad, "activating pad from none");
931       ret = (GST_PAD_ACTIVATEFUNC (pad)) (pad, parent);
932     } else {
933       GST_DEBUG_OBJECT (pad, "pad was active in %s mode",
934           gst_pad_mode_get_name (old));
935       ret = TRUE;
936     }
937   } else {
938     if (old == GST_PAD_MODE_NONE) {
939       GST_DEBUG_OBJECT (pad, "pad was inactive");
940       ret = TRUE;
941     } else {
942       GST_DEBUG_OBJECT (pad, "deactivating pad from %s mode",
943           gst_pad_mode_get_name (old));
944       ret = gst_pad_activate_mode (pad, old, FALSE);
945     }
946   }
947
948   RELEASE_PARENT (parent);
949
950   if (G_UNLIKELY (!ret))
951     goto failed;
952
953   if (!active) {
954     GST_OBJECT_LOCK (pad);
955     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
956     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
957     GST_OBJECT_UNLOCK (pad);
958   }
959   return ret;
960
961   /* ERRORS */
962 no_parent:
963   {
964     GST_DEBUG_OBJECT (pad, "no parent");
965     GST_OBJECT_UNLOCK (pad);
966     return FALSE;
967   }
968 failed:
969   {
970     GST_OBJECT_LOCK (pad);
971     if (!active) {
972       g_critical ("Failed to deactivate pad %s:%s, very bad",
973           GST_DEBUG_PAD_NAME (pad));
974     } else {
975       GST_WARNING_OBJECT (pad, "Failed to activate pad");
976     }
977     GST_OBJECT_UNLOCK (pad);
978     return FALSE;
979   }
980 }
981
982 /**
983  * gst_pad_activate_mode:
984  * @pad: the #GstPad to activate or deactivate.
985  * @mode: the requested activation mode
986  * @active: whether or not the pad should be active.
987  *
988  * Activates or deactivates the given pad in @mode via dispatching to the
989  * pad's activatemodefunc. For use from within pad activation functions only.
990  *
991  * If you don't know what this is, you probably don't want to call it.
992  *
993  * Returns: TRUE if the operation was successful.
994  *
995  * MT safe.
996  */
997 gboolean
998 gst_pad_activate_mode (GstPad * pad, GstPadMode mode, gboolean active)
999 {
1000   gboolean res = FALSE;
1001   GstObject *parent;
1002   GstPadMode old, new;
1003   GstPadDirection dir;
1004   GstPad *peer;
1005
1006   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1007
1008   GST_OBJECT_LOCK (pad);
1009   old = GST_PAD_MODE (pad);
1010   dir = GST_PAD_DIRECTION (pad);
1011   ACQUIRE_PARENT (pad, parent, no_parent);
1012   GST_OBJECT_UNLOCK (pad);
1013
1014   new = active ? mode : GST_PAD_MODE_NONE;
1015
1016   if (old == new)
1017     goto was_ok;
1018
1019   if (active && old != mode && old != GST_PAD_MODE_NONE) {
1020     /* pad was activate in the wrong direction, deactivate it
1021      * and reactivate it in the requested mode */
1022     GST_DEBUG_OBJECT (pad, "deactivating pad from %s mode",
1023         gst_pad_mode_get_name (old));
1024
1025     if (G_UNLIKELY (!gst_pad_activate_mode (pad, old, FALSE)))
1026       goto deactivate_failed;
1027   }
1028
1029   switch (mode) {
1030     case GST_PAD_MODE_PULL:
1031     {
1032       if (dir == GST_PAD_SINK) {
1033         if ((peer = gst_pad_get_peer (pad))) {
1034           GST_DEBUG_OBJECT (pad, "calling peer");
1035           if (G_UNLIKELY (!gst_pad_activate_mode (peer, mode, active)))
1036             goto peer_failed;
1037           gst_object_unref (peer);
1038         } else {
1039           /* there is no peer, this is only fatal when we activate. When we
1040            * deactivate, we must assume the application has unlinked the peer and
1041            * will deactivate it eventually. */
1042           if (active)
1043             goto not_linked;
1044           else
1045             GST_DEBUG_OBJECT (pad, "deactivating unlinked pad");
1046         }
1047       } else {
1048         if (G_UNLIKELY (GST_PAD_GETRANGEFUNC (pad) == NULL))
1049           goto failure;         /* Can't activate pull on a src without a
1050                                    getrange function */
1051       }
1052       break;
1053     }
1054     default:
1055       break;
1056   }
1057
1058   pre_activate (pad, new);
1059
1060   if (GST_PAD_ACTIVATEMODEFUNC (pad)) {
1061     if (G_UNLIKELY (!GST_PAD_ACTIVATEMODEFUNC (pad) (pad, parent, mode,
1062                 active)))
1063       goto failure;
1064   } else {
1065     /* can happen for sinks of passthrough elements */
1066   }
1067
1068   post_activate (pad, new);
1069
1070   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "%s in %s mode",
1071       active ? "activated" : "deactivated", gst_pad_mode_get_name (mode));
1072
1073 exit_success:
1074   res = TRUE;
1075 exit:
1076   RELEASE_PARENT (parent);
1077
1078   return res;
1079
1080 no_parent:
1081   {
1082     GST_DEBUG_OBJECT (pad, "no parent");
1083     GST_OBJECT_UNLOCK (pad);
1084     return FALSE;
1085   }
1086 was_ok:
1087   {
1088     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "already %s in %s mode",
1089         active ? "activated" : "deactivated", gst_pad_mode_get_name (mode));
1090     goto exit_success;
1091   }
1092 deactivate_failed:
1093   {
1094     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
1095         "failed to %s in switch to %s mode from %s mode",
1096         (active ? "activate" : "deactivate"), gst_pad_mode_get_name (mode),
1097         gst_pad_mode_get_name (old));
1098     goto exit;
1099   }
1100 peer_failed:
1101   {
1102     GST_OBJECT_LOCK (peer);
1103     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
1104         "activate_mode on peer (%s:%s) failed", GST_DEBUG_PAD_NAME (peer));
1105     GST_OBJECT_UNLOCK (peer);
1106     gst_object_unref (peer);
1107     goto exit;
1108   }
1109 not_linked:
1110   {
1111     GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "can't activate unlinked sink "
1112         "pad in pull mode");
1113     goto exit;
1114   }
1115 failure:
1116   {
1117     GST_OBJECT_LOCK (pad);
1118     GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "failed to %s in %s mode",
1119         active ? "activate" : "deactivate", gst_pad_mode_get_name (mode));
1120     GST_PAD_SET_FLUSHING (pad);
1121     GST_PAD_MODE (pad) = old;
1122     GST_OBJECT_UNLOCK (pad);
1123     goto exit;
1124   }
1125 }
1126
1127 /**
1128  * gst_pad_is_active:
1129  * @pad: the #GstPad to query
1130  *
1131  * Query if a pad is active
1132  *
1133  * Returns: TRUE if the pad is active.
1134  *
1135  * MT safe.
1136  */
1137 gboolean
1138 gst_pad_is_active (GstPad * pad)
1139 {
1140   gboolean result = FALSE;
1141
1142   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1143
1144   GST_OBJECT_LOCK (pad);
1145   result = GST_PAD_IS_ACTIVE (pad);
1146   GST_OBJECT_UNLOCK (pad);
1147
1148   return result;
1149 }
1150
1151 /**
1152  * gst_pad_add_probe:
1153  * @pad: the #GstPad to add the probe to
1154  * @mask: the probe mask
1155  * @callback: #GstPadProbeCallback that will be called with notifications of
1156  *           the pad state
1157  * @user_data: (closure): user data passed to the callback
1158  * @destroy_data: #GDestroyNotify for user_data
1159  *
1160  * Be notified of different states of pads. The provided callback is called for
1161  * every state that matches @mask.
1162  *
1163  * Returns: an id or 0 on error. The id can be used to remove the probe with
1164  * gst_pad_remove_probe().
1165  *
1166  * MT safe.
1167  */
1168 gulong
1169 gst_pad_add_probe (GstPad * pad, GstPadProbeType mask,
1170     GstPadProbeCallback callback, gpointer user_data,
1171     GDestroyNotify destroy_data)
1172 {
1173   GHook *hook;
1174   gulong res;
1175
1176   g_return_val_if_fail (GST_IS_PAD (pad), 0);
1177   g_return_val_if_fail (mask != 0, 0);
1178
1179   GST_OBJECT_LOCK (pad);
1180
1181   /* make a new probe */
1182   hook = g_hook_alloc (&pad->probes);
1183
1184   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "adding probe for mask 0x%08x",
1185       mask);
1186
1187   /* when no contraints are given for the types, assume all types are
1188    * acceptable */
1189   if ((mask & GST_PAD_PROBE_TYPE_ALL_BOTH) == 0)
1190     mask |= GST_PAD_PROBE_TYPE_ALL_BOTH;
1191   if ((mask & GST_PAD_PROBE_TYPE_SCHEDULING) == 0)
1192     mask |= GST_PAD_PROBE_TYPE_SCHEDULING;
1193
1194   /* store our flags and other fields */
1195   hook->flags |= (mask << G_HOOK_FLAG_USER_SHIFT);
1196   hook->func = callback;
1197   hook->data = user_data;
1198   hook->destroy = destroy_data;
1199   PROBE_COOKIE (hook) = (pad->priv->probe_cookie - 1);
1200
1201   /* add the probe */
1202   g_hook_prepend (&pad->probes, hook);
1203   pad->num_probes++;
1204   /* incremenent cookie so that the new hook get's called */
1205   pad->priv->probe_list_cookie++;
1206
1207   /* get the id of the hook, we return this and it can be used to remove the
1208    * probe later */
1209   res = hook->hook_id;
1210
1211   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got probe id %lu", res);
1212
1213   if (mask & GST_PAD_PROBE_TYPE_BLOCKING) {
1214     /* we have a block probe */
1215     pad->num_blocked++;
1216     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_BLOCKED);
1217     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "added blocking probe, "
1218         "now %d blocking probes", pad->num_blocked);
1219   }
1220
1221   /* call the callback if we need to be called for idle callbacks */
1222   if ((mask & GST_PAD_PROBE_TYPE_IDLE) && (callback != NULL)) {
1223     if (pad->priv->using > 0) {
1224       /* the pad is in use, we can't signal the idle callback yet. Since we set the
1225        * flag above, the last thread to leave the push will do the callback. New
1226        * threads going into the push will block. */
1227       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
1228           "pad is in use, delay idle callback");
1229       GST_OBJECT_UNLOCK (pad);
1230     } else {
1231       GstPadProbeInfo info = { GST_PAD_PROBE_TYPE_IDLE, res, };
1232
1233       /* the pad is idle now, we can signal the idle callback now */
1234       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
1235           "pad is idle, trigger idle callback");
1236       GST_OBJECT_UNLOCK (pad);
1237
1238       callback (pad, &info, user_data);
1239     }
1240   } else {
1241     GST_OBJECT_UNLOCK (pad);
1242   }
1243   return res;
1244 }
1245
1246 static void
1247 cleanup_hook (GstPad * pad, GHook * hook)
1248 {
1249   GstPadProbeType type;
1250
1251   type = (hook->flags) >> G_HOOK_FLAG_USER_SHIFT;
1252
1253   if (type & GST_PAD_PROBE_TYPE_BLOCKING) {
1254     /* unblock when we remove the last blocking probe */
1255     pad->num_blocked--;
1256     GST_DEBUG_OBJECT (pad, "remove blocking probe, now %d left",
1257         pad->num_blocked);
1258     if (pad->num_blocked == 0) {
1259       GST_DEBUG_OBJECT (pad, "last blocking probe removed, unblocking");
1260       GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_BLOCKED);
1261       GST_PAD_BLOCK_BROADCAST (pad);
1262     }
1263   }
1264   g_hook_destroy_link (&pad->probes, hook);
1265   pad->num_probes--;
1266 }
1267
1268 /**
1269  * gst_pad_remove_probe:
1270  * @pad: the #GstPad with the probe
1271  * @id: the probe id to remove
1272  *
1273  * Remove the probe with @id from @pad.
1274  *
1275  * MT safe.
1276  */
1277 void
1278 gst_pad_remove_probe (GstPad * pad, gulong id)
1279 {
1280   GHook *hook;
1281
1282   g_return_if_fail (GST_IS_PAD (pad));
1283
1284   GST_OBJECT_LOCK (pad);
1285
1286   hook = g_hook_get (&pad->probes, id);
1287   if (hook == NULL)
1288     goto not_found;
1289
1290   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "removing hook %ld",
1291       hook->hook_id);
1292   cleanup_hook (pad, hook);
1293   GST_OBJECT_UNLOCK (pad);
1294
1295   return;
1296
1297 not_found:
1298   {
1299     GST_OBJECT_UNLOCK (pad);
1300     g_warning ("%s: pad `%p' has no probe with id `%lu'", G_STRLOC, pad, id);
1301     return;
1302   }
1303 }
1304
1305 /**
1306  * gst_pad_is_blocked:
1307  * @pad: the #GstPad to query
1308  *
1309  * Checks if the pad is blocked or not. This function returns the
1310  * last requested state of the pad. It is not certain that the pad
1311  * is actually blocking at this point (see gst_pad_is_blocking()).
1312  *
1313  * Returns: TRUE if the pad is blocked.
1314  *
1315  * MT safe.
1316  */
1317 gboolean
1318 gst_pad_is_blocked (GstPad * pad)
1319 {
1320   gboolean result = FALSE;
1321
1322   g_return_val_if_fail (GST_IS_PAD (pad), result);
1323
1324   GST_OBJECT_LOCK (pad);
1325   result = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_BLOCKED);
1326   GST_OBJECT_UNLOCK (pad);
1327
1328   return result;
1329 }
1330
1331 /**
1332  * gst_pad_is_blocking:
1333  * @pad: the #GstPad to query
1334  *
1335  * Checks if the pad is blocking or not. This is a guaranteed state
1336  * of whether the pad is actually blocking on a #GstBuffer or a #GstEvent.
1337  *
1338  * Returns: TRUE if the pad is blocking.
1339  *
1340  * MT safe.
1341  */
1342 gboolean
1343 gst_pad_is_blocking (GstPad * pad)
1344 {
1345   gboolean result = FALSE;
1346
1347   g_return_val_if_fail (GST_IS_PAD (pad), result);
1348
1349   GST_OBJECT_LOCK (pad);
1350   /* the blocking flag is only valid if the pad is not flushing */
1351   result = GST_PAD_IS_BLOCKING (pad) && !GST_PAD_IS_FLUSHING (pad);
1352   GST_OBJECT_UNLOCK (pad);
1353
1354   return result;
1355 }
1356
1357 /**
1358  * gst_pad_check_reconfigure:
1359  * @pad: the #GstPad to check
1360  *
1361  * Check and clear the #GST_PAD_FLAG_NEED_RECONFIGURE flag on @pad and return %TRUE
1362  * if the flag was set.
1363  *
1364  * Returns: %TRUE is the GST_PAD_FLAG_NEED_RECONFIGURE flag was set on @pad.
1365  */
1366 gboolean
1367 gst_pad_check_reconfigure (GstPad * pad)
1368 {
1369   gboolean reconfigure;
1370
1371   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1372
1373   GST_OBJECT_LOCK (pad);
1374   reconfigure = GST_PAD_NEEDS_RECONFIGURE (pad);
1375   if (reconfigure)
1376     GST_DEBUG_OBJECT (pad, "remove RECONFIGURE flag");
1377   GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
1378   GST_OBJECT_UNLOCK (pad);
1379
1380   return reconfigure;
1381 }
1382
1383 /**
1384  * gst_pad_mark_reconfigure:
1385  * @pad: the #GstPad to mark
1386  *
1387  * Mark a pad for needing reconfiguration. The next call to
1388  * gst_pad_check_reconfigure() will return %TRUE after this call.
1389  */
1390 void
1391 gst_pad_mark_reconfigure (GstPad * pad)
1392 {
1393   g_return_if_fail (GST_IS_PAD (pad));
1394
1395   GST_OBJECT_LOCK (pad);
1396   GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
1397   GST_OBJECT_UNLOCK (pad);
1398 }
1399
1400 /**
1401  * gst_pad_set_activate_function:
1402  * @p: a #GstPad.
1403  * @f: the #GstPadActivateFunction to set.
1404  *
1405  * Calls gst_pad_set_activate_function_full() with NULL for the user_data and
1406  * notify.
1407  */
1408 /**
1409  * gst_pad_set_activate_function_full:
1410  * @pad: a #GstPad.
1411  * @activate: the #GstPadActivateFunction to set.
1412  * @user_data: user_data passed to @notify
1413  * @notify: notify called when @activate will not be used anymore.
1414  *
1415  * Sets the given activate function for @pad. The activate function will
1416  * dispatch to gst_pad_activate_push() or gst_pad_activate_pull() to perform
1417  * the actual activation. Only makes sense to set on sink pads.
1418  *
1419  * Call this function if your sink pad can start a pull-based task.
1420  */
1421 void
1422 gst_pad_set_activate_function_full (GstPad * pad,
1423     GstPadActivateFunction activate, gpointer user_data, GDestroyNotify notify)
1424 {
1425   g_return_if_fail (GST_IS_PAD (pad));
1426
1427   if (pad->activatenotify)
1428     pad->activatenotify (pad->activatedata);
1429   GST_PAD_ACTIVATEFUNC (pad) = activate;
1430   pad->activatedata = user_data;
1431   pad->activatenotify = notify;
1432
1433   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "activatefunc set to %s",
1434       GST_DEBUG_FUNCPTR_NAME (activate));
1435 }
1436
1437 /**
1438  * gst_pad_set_activatemode_function:
1439  * @p: a #GstPad.
1440  * @f: the #GstPadActivateModeFunction to set.
1441  *
1442  * Calls gst_pad_set_activatemode_function_full() with NULL for the user_data and
1443  * notify.
1444  */
1445 /**
1446  * gst_pad_set_activatemode_function_full:
1447  * @pad: a #GstPad.
1448  * @activatemode: the #GstPadActivateModeFunction to set.
1449  * @user_data: user_data passed to @notify
1450  * @notify: notify called when @activatemode will not be used anymore.
1451  *
1452  * Sets the given activate_mode function for the pad. An activate_mode function
1453  * prepares the element for data passing.
1454  */
1455 void
1456 gst_pad_set_activatemode_function_full (GstPad * pad,
1457     GstPadActivateModeFunction activatemode, gpointer user_data,
1458     GDestroyNotify notify)
1459 {
1460   g_return_if_fail (GST_IS_PAD (pad));
1461
1462   if (pad->activatemodenotify)
1463     pad->activatemodenotify (pad->activatemodedata);
1464   GST_PAD_ACTIVATEMODEFUNC (pad) = activatemode;
1465   pad->activatemodedata = user_data;
1466   pad->activatemodenotify = notify;
1467
1468   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "activatemodefunc set to %s",
1469       GST_DEBUG_FUNCPTR_NAME (activatemode));
1470 }
1471
1472 /**
1473  * gst_pad_set_chain_function:
1474  * @p: a sink #GstPad.
1475  * @f: the #GstPadChainFunction to set.
1476  *
1477  * Calls gst_pad_set_chain_function_full() with NULL for the user_data and
1478  * notify.
1479  */
1480 /**
1481  * gst_pad_set_chain_function_full:
1482  * @pad: a sink #GstPad.
1483  * @chain: the #GstPadChainFunction to set.
1484  * @user_data: user_data passed to @notify
1485  * @notify: notify called when @chain will not be used anymore.
1486  *
1487  * Sets the given chain function for the pad. The chain function is called to
1488  * process a #GstBuffer input buffer. see #GstPadChainFunction for more details.
1489  */
1490 void
1491 gst_pad_set_chain_function_full (GstPad * pad, GstPadChainFunction chain,
1492     gpointer user_data, GDestroyNotify notify)
1493 {
1494   g_return_if_fail (GST_IS_PAD (pad));
1495   g_return_if_fail (GST_PAD_IS_SINK (pad));
1496
1497   if (pad->chainnotify)
1498     pad->chainnotify (pad->chaindata);
1499   GST_PAD_CHAINFUNC (pad) = chain;
1500   pad->chaindata = user_data;
1501   pad->chainnotify = notify;
1502
1503   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "chainfunc set to %s",
1504       GST_DEBUG_FUNCPTR_NAME (chain));
1505 }
1506
1507 /**
1508  * gst_pad_set_chain_list_function:
1509  * @p: a sink #GstPad.
1510  * @f: the #GstPadChainListFunction to set.
1511  *
1512  * Calls gst_pad_set_chain_list_function_full() with NULL for the user_data and
1513  * notify.
1514  */
1515 /**
1516  * gst_pad_set_chain_list_function_full:
1517  * @pad: a sink #GstPad.
1518  * @chainlist: the #GstPadChainListFunction to set.
1519  * @user_data: user_data passed to @notify
1520  * @notify: notify called when @chainlist will not be used anymore.
1521  *
1522  * Sets the given chain list function for the pad. The chainlist function is
1523  * called to process a #GstBufferList input buffer list. See
1524  * #GstPadChainListFunction for more details.
1525  */
1526 void
1527 gst_pad_set_chain_list_function_full (GstPad * pad,
1528     GstPadChainListFunction chainlist, gpointer user_data,
1529     GDestroyNotify notify)
1530 {
1531   g_return_if_fail (GST_IS_PAD (pad));
1532   g_return_if_fail (GST_PAD_IS_SINK (pad));
1533
1534   if (pad->chainlistnotify)
1535     pad->chainlistnotify (pad->chainlistdata);
1536   GST_PAD_CHAINLISTFUNC (pad) = chainlist;
1537   pad->chainlistdata = user_data;
1538   pad->chainlistnotify = notify;
1539
1540   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "chainlistfunc set to %s",
1541       GST_DEBUG_FUNCPTR_NAME (chainlist));
1542 }
1543
1544 /**
1545  * gst_pad_set_getrange_function:
1546  * @p: a source #GstPad.
1547  * @f: the #GstPadGetRangeFunction to set.
1548  *
1549  * Calls gst_pad_set_getrange_function_full() with NULL for the user_data and
1550  * notify.
1551  */
1552 /**
1553  * gst_pad_set_getrange_function_full:
1554  * @pad: a source #GstPad.
1555  * @get: the #GstPadGetRangeFunction to set.
1556  * @user_data: user_data passed to @notify
1557  * @notify: notify called when @get will not be used anymore.
1558  *
1559  * Sets the given getrange function for the pad. The getrange function is
1560  * called to produce a new #GstBuffer to start the processing pipeline. see
1561  * #GstPadGetRangeFunction for a description of the getrange function.
1562  */
1563 void
1564 gst_pad_set_getrange_function_full (GstPad * pad, GstPadGetRangeFunction get,
1565     gpointer user_data, GDestroyNotify notify)
1566 {
1567   g_return_if_fail (GST_IS_PAD (pad));
1568   g_return_if_fail (GST_PAD_IS_SRC (pad));
1569
1570   if (pad->getrangenotify)
1571     pad->getrangenotify (pad->getrangedata);
1572   GST_PAD_GETRANGEFUNC (pad) = get;
1573   pad->getrangedata = user_data;
1574   pad->getrangenotify = notify;
1575
1576   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "getrangefunc set to %s",
1577       GST_DEBUG_FUNCPTR_NAME (get));
1578 }
1579
1580 /**
1581  * gst_pad_set_event_function:
1582  * @p: a #GstPad of either direction.
1583  * @f: the #GstPadEventFunction to set.
1584  *
1585  * Calls gst_pad_set_event_function_full() with NULL for the user_data and
1586  * notify.
1587  */
1588 /**
1589  * gst_pad_set_event_function_full:
1590  * @pad: a #GstPad of either direction.
1591  * @event: the #GstPadEventFunction to set.
1592  * @user_data: user_data passed to @notify
1593  * @notify: notify called when @event will not be used anymore.
1594  *
1595  * Sets the given event handler for the pad.
1596  */
1597 void
1598 gst_pad_set_event_function_full (GstPad * pad, GstPadEventFunction event,
1599     gpointer user_data, GDestroyNotify notify)
1600 {
1601   g_return_if_fail (GST_IS_PAD (pad));
1602
1603   if (pad->eventnotify)
1604     pad->eventnotify (pad->eventdata);
1605   GST_PAD_EVENTFUNC (pad) = event;
1606   pad->eventdata = user_data;
1607   pad->eventnotify = notify;
1608
1609   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "eventfunc for set to %s",
1610       GST_DEBUG_FUNCPTR_NAME (event));
1611 }
1612
1613 /**
1614  * gst_pad_set_query_function:
1615  * @p: a #GstPad of either direction.
1616  * @f: the #GstPadQueryFunction to set.
1617  *
1618  * Calls gst_pad_set_query_function_full() with NULL for the user_data and
1619  * notify.
1620  */
1621 /**
1622  * gst_pad_set_query_function_full:
1623  * @pad: a #GstPad of either direction.
1624  * @query: the #GstPadQueryFunction to set.
1625  * @user_data: user_data passed to @notify
1626  * @notify: notify called when @query will not be used anymore.
1627  *
1628  * Set the given query function for the pad.
1629  */
1630 void
1631 gst_pad_set_query_function_full (GstPad * pad, GstPadQueryFunction query,
1632     gpointer user_data, GDestroyNotify notify)
1633 {
1634   g_return_if_fail (GST_IS_PAD (pad));
1635
1636   if (pad->querynotify)
1637     pad->querynotify (pad->querydata);
1638   GST_PAD_QUERYFUNC (pad) = query;
1639   pad->querydata = user_data;
1640   pad->querynotify = notify;
1641
1642   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "queryfunc set to %s",
1643       GST_DEBUG_FUNCPTR_NAME (query));
1644 }
1645
1646 /**
1647  * gst_pad_set_iterate_internal_links_function:
1648  * @p: a #GstPad of either direction.
1649  * @f: the #GstPadIterIntLinkFunction to set.
1650  *
1651  * Calls gst_pad_set_iterate_internal_links_function_full() with NULL
1652  * for the user_data and notify.
1653  */
1654 /**
1655  * gst_pad_set_iterate_internal_links_function_full:
1656  * @pad: a #GstPad of either direction.
1657  * @iterintlink: the #GstPadIterIntLinkFunction to set.
1658  * @user_data: user_data passed to @notify
1659  * @notify: notify called when @iterintlink will not be used anymore.
1660  *
1661  * Sets the given internal link iterator function for the pad.
1662  */
1663 void
1664 gst_pad_set_iterate_internal_links_function_full (GstPad * pad,
1665     GstPadIterIntLinkFunction iterintlink, gpointer user_data,
1666     GDestroyNotify notify)
1667 {
1668   g_return_if_fail (GST_IS_PAD (pad));
1669
1670   if (pad->iterintlinknotify)
1671     pad->iterintlinknotify (pad->iterintlinkdata);
1672   GST_PAD_ITERINTLINKFUNC (pad) = iterintlink;
1673   pad->iterintlinkdata = user_data;
1674   pad->iterintlinknotify = notify;
1675
1676   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "internal link iterator set to %s",
1677       GST_DEBUG_FUNCPTR_NAME (iterintlink));
1678 }
1679
1680 /**
1681  * gst_pad_set_link_function:
1682  * @p: a #GstPad.
1683  * @f: the #GstPadLinkFunction to set.
1684  *
1685  * Calls gst_pad_set_link_function_full() with NULL
1686  * for the user_data and notify.
1687  */
1688 /**
1689  * gst_pad_set_link_function_full:
1690  * @pad: a #GstPad.
1691  * @link: the #GstPadLinkFunction to set.
1692  * @user_data: user_data passed to @notify
1693  * @notify: notify called when @link will not be used anymore.
1694  *
1695  * Sets the given link function for the pad. It will be called when
1696  * the pad is linked with another pad.
1697  *
1698  * The return value #GST_PAD_LINK_OK should be used when the connection can be
1699  * made.
1700  *
1701  * The return value #GST_PAD_LINK_REFUSED should be used when the connection
1702  * cannot be made for some reason.
1703  *
1704  * If @link is installed on a source pad, it should call the #GstPadLinkFunction
1705  * of the peer sink pad, if present.
1706  */
1707 void
1708 gst_pad_set_link_function_full (GstPad * pad, GstPadLinkFunction link,
1709     gpointer user_data, GDestroyNotify notify)
1710 {
1711   g_return_if_fail (GST_IS_PAD (pad));
1712
1713   if (pad->linknotify)
1714     pad->linknotify (pad->linkdata);
1715   GST_PAD_LINKFUNC (pad) = link;
1716   pad->linkdata = user_data;
1717   pad->linknotify = notify;
1718
1719   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "linkfunc set to %s",
1720       GST_DEBUG_FUNCPTR_NAME (link));
1721 }
1722
1723 /**
1724  * gst_pad_set_unlink_function:
1725  * @p: a #GstPad.
1726  * @f: the #GstPadUnlinkFunction to set.
1727  *
1728  * Calls gst_pad_set_unlink_function_full() with NULL
1729  * for the user_data and notify.
1730  */
1731 /**
1732  * gst_pad_set_unlink_function_full:
1733  * @pad: a #GstPad.
1734  * @unlink: the #GstPadUnlinkFunction to set.
1735  * @user_data: user_data passed to @notify
1736  * @notify: notify called when @unlink will not be used anymore.
1737  *
1738  * Sets the given unlink function for the pad. It will be called
1739  * when the pad is unlinked.
1740  */
1741 void
1742 gst_pad_set_unlink_function_full (GstPad * pad, GstPadUnlinkFunction unlink,
1743     gpointer user_data, GDestroyNotify notify)
1744 {
1745   g_return_if_fail (GST_IS_PAD (pad));
1746
1747   if (pad->unlinknotify)
1748     pad->unlinknotify (pad->unlinkdata);
1749   GST_PAD_UNLINKFUNC (pad) = unlink;
1750   pad->unlinkdata = user_data;
1751   pad->unlinknotify = notify;
1752
1753   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "unlinkfunc set to %s",
1754       GST_DEBUG_FUNCPTR_NAME (unlink));
1755 }
1756
1757 /**
1758  * gst_pad_unlink:
1759  * @srcpad: the source #GstPad to unlink.
1760  * @sinkpad: the sink #GstPad to unlink.
1761  *
1762  * Unlinks the source pad from the sink pad. Will emit the #GstPad::unlinked
1763  * signal on both pads.
1764  *
1765  * Returns: TRUE if the pads were unlinked. This function returns FALSE if
1766  * the pads were not linked together.
1767  *
1768  * MT safe.
1769  */
1770 gboolean
1771 gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
1772 {
1773   gboolean result = FALSE;
1774   GstElement *parent = NULL;
1775
1776   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1777   g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), FALSE);
1778   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1779   g_return_val_if_fail (GST_PAD_IS_SINK (sinkpad), FALSE);
1780
1781   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)",
1782       GST_DEBUG_PAD_NAME (srcpad), srcpad,
1783       GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
1784
1785   /* We need to notify the parent before taking any pad locks as the bin in
1786    * question might be waiting for a lock on the pad while holding its lock
1787    * that our message will try to take. */
1788   if ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (srcpad)))) {
1789     if (GST_IS_ELEMENT (parent)) {
1790       gst_element_post_message (parent,
1791           gst_message_new_structure_change (GST_OBJECT_CAST (sinkpad),
1792               GST_STRUCTURE_CHANGE_TYPE_PAD_UNLINK, parent, TRUE));
1793     } else {
1794       gst_object_unref (parent);
1795       parent = NULL;
1796     }
1797   }
1798
1799   GST_OBJECT_LOCK (srcpad);
1800   GST_OBJECT_LOCK (sinkpad);
1801
1802   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != sinkpad))
1803     goto not_linked_together;
1804
1805   if (GST_PAD_UNLINKFUNC (srcpad)) {
1806     GST_PAD_UNLINKFUNC (srcpad) (srcpad);
1807   }
1808   if (GST_PAD_UNLINKFUNC (sinkpad)) {
1809     GST_PAD_UNLINKFUNC (sinkpad) (sinkpad);
1810   }
1811
1812   /* first clear peers */
1813   GST_PAD_PEER (srcpad) = NULL;
1814   GST_PAD_PEER (sinkpad) = NULL;
1815
1816   GST_OBJECT_UNLOCK (sinkpad);
1817   GST_OBJECT_UNLOCK (srcpad);
1818
1819   /* fire off a signal to each of the pads telling them
1820    * that they've been unlinked */
1821   g_signal_emit (srcpad, gst_pad_signals[PAD_UNLINKED], 0, sinkpad);
1822   g_signal_emit (sinkpad, gst_pad_signals[PAD_UNLINKED], 0, srcpad);
1823
1824   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
1825       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1826
1827   result = TRUE;
1828
1829 done:
1830   if (parent != NULL) {
1831     gst_element_post_message (parent,
1832         gst_message_new_structure_change (GST_OBJECT_CAST (sinkpad),
1833             GST_STRUCTURE_CHANGE_TYPE_PAD_UNLINK, parent, FALSE));
1834     gst_object_unref (parent);
1835   }
1836   return result;
1837
1838   /* ERRORS */
1839 not_linked_together:
1840   {
1841     /* we do not emit a warning in this case because unlinking cannot
1842      * be made MT safe.*/
1843     GST_OBJECT_UNLOCK (sinkpad);
1844     GST_OBJECT_UNLOCK (srcpad);
1845     goto done;
1846   }
1847 }
1848
1849 /**
1850  * gst_pad_is_linked:
1851  * @pad: pad to check
1852  *
1853  * Checks if a @pad is linked to another pad or not.
1854  *
1855  * Returns: TRUE if the pad is linked, FALSE otherwise.
1856  *
1857  * MT safe.
1858  */
1859 gboolean
1860 gst_pad_is_linked (GstPad * pad)
1861 {
1862   gboolean result;
1863
1864   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1865
1866   GST_OBJECT_LOCK (pad);
1867   result = (GST_PAD_PEER (pad) != NULL);
1868   GST_OBJECT_UNLOCK (pad);
1869
1870   return result;
1871 }
1872
1873 /* get the caps from both pads and see if the intersection
1874  * is not empty.
1875  *
1876  * This function should be called with the pad LOCK on both
1877  * pads
1878  */
1879 static gboolean
1880 gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink,
1881     GstPadLinkCheck flags)
1882 {
1883   GstCaps *srccaps = NULL;
1884   GstCaps *sinkcaps = NULL;
1885   gboolean compatible = FALSE;
1886
1887   if (!(flags & (GST_PAD_LINK_CHECK_CAPS | GST_PAD_LINK_CHECK_TEMPLATE_CAPS)))
1888     return TRUE;
1889
1890   /* Doing the expensive caps checking takes priority over only checking the template caps */
1891   if (flags & GST_PAD_LINK_CHECK_CAPS) {
1892     GST_OBJECT_UNLOCK (sink);
1893     GST_OBJECT_UNLOCK (src);
1894
1895     srccaps = gst_pad_query_caps (src, NULL);
1896     sinkcaps = gst_pad_query_caps (sink, NULL);
1897
1898     GST_OBJECT_LOCK (src);
1899     GST_OBJECT_LOCK (sink);
1900   } else {
1901     /* If one of the two pads doesn't have a template, consider the intersection
1902      * as valid.*/
1903     if (G_UNLIKELY ((GST_PAD_PAD_TEMPLATE (src) == NULL)
1904             || (GST_PAD_PAD_TEMPLATE (sink) == NULL))) {
1905       compatible = TRUE;
1906       goto done;
1907     }
1908     srccaps = gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (src)));
1909     sinkcaps =
1910         gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (sink)));
1911   }
1912
1913   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, src, "src caps %" GST_PTR_FORMAT,
1914       srccaps);
1915   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, sink, "sink caps %" GST_PTR_FORMAT,
1916       sinkcaps);
1917
1918   /* if we have caps on both pads we can check the intersection. If one
1919    * of the caps is NULL, we return TRUE. */
1920   if (G_UNLIKELY (srccaps == NULL || sinkcaps == NULL)) {
1921     if (srccaps)
1922       gst_caps_unref (srccaps);
1923     if (sinkcaps)
1924       gst_caps_unref (sinkcaps);
1925     goto done;
1926   }
1927
1928   compatible = gst_caps_can_intersect (srccaps, sinkcaps);
1929   gst_caps_unref (srccaps);
1930   gst_caps_unref (sinkcaps);
1931
1932 done:
1933   GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible",
1934       (compatible ? "" : "not"));
1935
1936   return compatible;
1937 }
1938
1939 /* check if the grandparents of both pads are the same.
1940  * This check is required so that we don't try to link
1941  * pads from elements in different bins without ghostpads.
1942  *
1943  * The LOCK should be held on both pads
1944  */
1945 static gboolean
1946 gst_pad_link_check_hierarchy (GstPad * src, GstPad * sink)
1947 {
1948   GstObject *psrc, *psink;
1949
1950   psrc = GST_OBJECT_PARENT (src);
1951   psink = GST_OBJECT_PARENT (sink);
1952
1953   /* if one of the pads has no parent, we allow the link */
1954   if (G_UNLIKELY (psrc == NULL || psink == NULL))
1955     goto no_parent;
1956
1957   /* only care about parents that are elements */
1958   if (G_UNLIKELY (!GST_IS_ELEMENT (psrc) || !GST_IS_ELEMENT (psink)))
1959     goto no_element_parent;
1960
1961   /* if the parents are the same, we have a loop */
1962   if (G_UNLIKELY (psrc == psink))
1963     goto same_parents;
1964
1965   /* if they both have a parent, we check the grandparents. We can not lock
1966    * the parent because we hold on the child (pad) and the locking order is
1967    * parent >> child. */
1968   psrc = GST_OBJECT_PARENT (psrc);
1969   psink = GST_OBJECT_PARENT (psink);
1970
1971   /* if they have grandparents but they are not the same */
1972   if (G_UNLIKELY (psrc != psink))
1973     goto wrong_grandparents;
1974
1975   return TRUE;
1976
1977   /* ERRORS */
1978 no_parent:
1979   {
1980     GST_CAT_DEBUG (GST_CAT_CAPS,
1981         "one of the pads has no parent %" GST_PTR_FORMAT " and %"
1982         GST_PTR_FORMAT, psrc, psink);
1983     return TRUE;
1984   }
1985 no_element_parent:
1986   {
1987     GST_CAT_DEBUG (GST_CAT_CAPS,
1988         "one of the pads has no element parent %" GST_PTR_FORMAT " and %"
1989         GST_PTR_FORMAT, psrc, psink);
1990     return TRUE;
1991   }
1992 same_parents:
1993   {
1994     GST_CAT_DEBUG (GST_CAT_CAPS, "pads have same parent %" GST_PTR_FORMAT,
1995         psrc);
1996     return FALSE;
1997   }
1998 wrong_grandparents:
1999   {
2000     GST_CAT_DEBUG (GST_CAT_CAPS,
2001         "pads have different grandparents %" GST_PTR_FORMAT " and %"
2002         GST_PTR_FORMAT, psrc, psink);
2003     return FALSE;
2004   }
2005 }
2006
2007 /* FIXME leftover from an attempt at refactoring... */
2008 /* call with the two pads unlocked, when this function returns GST_PAD_LINK_OK,
2009  * the two pads will be locked in the srcpad, sinkpad order. */
2010 static GstPadLinkReturn
2011 gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
2012 {
2013   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
2014       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2015
2016   GST_OBJECT_LOCK (srcpad);
2017
2018   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != NULL))
2019     goto src_was_linked;
2020
2021   GST_OBJECT_LOCK (sinkpad);
2022
2023   if (G_UNLIKELY (GST_PAD_PEER (sinkpad) != NULL))
2024     goto sink_was_linked;
2025
2026   /* check hierarchy, pads can only be linked if the grandparents
2027    * are the same. */
2028   if ((flags & GST_PAD_LINK_CHECK_HIERARCHY)
2029       && !gst_pad_link_check_hierarchy (srcpad, sinkpad))
2030     goto wrong_hierarchy;
2031
2032   /* check pad caps for non-empty intersection */
2033   if (!gst_pad_link_check_compatible_unlocked (srcpad, sinkpad, flags))
2034     goto no_format;
2035
2036   /* FIXME check pad scheduling for non-empty intersection */
2037
2038   return GST_PAD_LINK_OK;
2039
2040 src_was_linked:
2041   {
2042     GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was already linked to %s:%s",
2043         GST_DEBUG_PAD_NAME (srcpad),
2044         GST_DEBUG_PAD_NAME (GST_PAD_PEER (srcpad)));
2045     /* we do not emit a warning in this case because unlinking cannot
2046      * be made MT safe.*/
2047     GST_OBJECT_UNLOCK (srcpad);
2048     return GST_PAD_LINK_WAS_LINKED;
2049   }
2050 sink_was_linked:
2051   {
2052     GST_CAT_INFO (GST_CAT_PADS, "sink %s:%s was already linked to %s:%s",
2053         GST_DEBUG_PAD_NAME (sinkpad),
2054         GST_DEBUG_PAD_NAME (GST_PAD_PEER (sinkpad)));
2055     /* we do not emit a warning in this case because unlinking cannot
2056      * be made MT safe.*/
2057     GST_OBJECT_UNLOCK (sinkpad);
2058     GST_OBJECT_UNLOCK (srcpad);
2059     return GST_PAD_LINK_WAS_LINKED;
2060   }
2061 wrong_hierarchy:
2062   {
2063     GST_CAT_INFO (GST_CAT_PADS, "pads have wrong hierarchy");
2064     GST_OBJECT_UNLOCK (sinkpad);
2065     GST_OBJECT_UNLOCK (srcpad);
2066     return GST_PAD_LINK_WRONG_HIERARCHY;
2067   }
2068 no_format:
2069   {
2070     GST_CAT_INFO (GST_CAT_PADS, "caps are incompatible");
2071     GST_OBJECT_UNLOCK (sinkpad);
2072     GST_OBJECT_UNLOCK (srcpad);
2073     return GST_PAD_LINK_NOFORMAT;
2074   }
2075 }
2076
2077 /**
2078  * gst_pad_can_link:
2079  * @srcpad: the source #GstPad.
2080  * @sinkpad: the sink #GstPad.
2081  *
2082  * Checks if the source pad and the sink pad are compatible so they can be
2083  * linked.
2084  *
2085  * Returns: TRUE if the pads can be linked.
2086  */
2087 gboolean
2088 gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
2089 {
2090   GstPadLinkReturn result;
2091
2092   /* generic checks */
2093   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
2094   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
2095
2096   GST_CAT_INFO (GST_CAT_PADS, "check if %s:%s can link with %s:%s",
2097       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2098
2099   /* gst_pad_link_prepare does everything for us, we only release the locks
2100    * on the pads that it gets us. If this function returns !OK the locks are not
2101    * taken anymore. */
2102   result = gst_pad_link_prepare (srcpad, sinkpad, GST_PAD_LINK_CHECK_DEFAULT);
2103   if (result != GST_PAD_LINK_OK)
2104     goto done;
2105
2106   GST_OBJECT_UNLOCK (srcpad);
2107   GST_OBJECT_UNLOCK (sinkpad);
2108
2109 done:
2110   return result == GST_PAD_LINK_OK;
2111 }
2112
2113 /**
2114  * gst_pad_link_full:
2115  * @srcpad: the source #GstPad to link.
2116  * @sinkpad: the sink #GstPad to link.
2117  * @flags: the checks to validate when linking
2118  *
2119  * Links the source pad and the sink pad.
2120  *
2121  * This variant of #gst_pad_link provides a more granular control on the
2122  * checks being done when linking. While providing some considerable speedups
2123  * the caller of this method must be aware that wrong usage of those flags
2124  * can cause severe issues. Refer to the documentation of #GstPadLinkCheck
2125  * for more information.
2126  *
2127  * MT Safe.
2128  *
2129  * Returns: A result code indicating if the connection worked or
2130  *          what went wrong.
2131  */
2132 GstPadLinkReturn
2133 gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
2134 {
2135   GstPadLinkReturn result;
2136   GstElement *parent;
2137   GstPadLinkFunction srcfunc, sinkfunc;
2138
2139   g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
2140   g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), GST_PAD_LINK_WRONG_DIRECTION);
2141   g_return_val_if_fail (GST_IS_PAD (sinkpad), GST_PAD_LINK_REFUSED);
2142   g_return_val_if_fail (GST_PAD_IS_SINK (sinkpad),
2143       GST_PAD_LINK_WRONG_DIRECTION);
2144
2145   /* Notify the parent early. See gst_pad_unlink for details. */
2146   if (G_LIKELY ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (srcpad))))) {
2147     if (G_LIKELY (GST_IS_ELEMENT (parent))) {
2148       gst_element_post_message (parent,
2149           gst_message_new_structure_change (GST_OBJECT_CAST (sinkpad),
2150               GST_STRUCTURE_CHANGE_TYPE_PAD_LINK, parent, TRUE));
2151     } else {
2152       gst_object_unref (parent);
2153       parent = NULL;
2154     }
2155   }
2156
2157   /* prepare will also lock the two pads */
2158   result = gst_pad_link_prepare (srcpad, sinkpad, flags);
2159
2160   if (G_UNLIKELY (result != GST_PAD_LINK_OK))
2161     goto done;
2162
2163   /* must set peers before calling the link function */
2164   GST_PAD_PEER (srcpad) = sinkpad;
2165   GST_PAD_PEER (sinkpad) = srcpad;
2166
2167   /* check events, when something is different, mark pending */
2168   schedule_events (srcpad, sinkpad);
2169
2170   /* get the link functions */
2171   srcfunc = GST_PAD_LINKFUNC (srcpad);
2172   sinkfunc = GST_PAD_LINKFUNC (sinkpad);
2173
2174   if (G_UNLIKELY (srcfunc || sinkfunc)) {
2175     /* custom link functions, execute them */
2176     GST_OBJECT_UNLOCK (sinkpad);
2177     GST_OBJECT_UNLOCK (srcpad);
2178
2179     if (srcfunc) {
2180       /* this one will call the peer link function */
2181       result = srcfunc (srcpad, sinkpad);
2182     } else if (sinkfunc) {
2183       /* if no source link function, we need to call the sink link
2184        * function ourselves. */
2185       result = sinkfunc (sinkpad, srcpad);
2186     }
2187
2188     GST_OBJECT_LOCK (srcpad);
2189     GST_OBJECT_LOCK (sinkpad);
2190
2191     /* we released the lock, check if the same pads are linked still */
2192     if (GST_PAD_PEER (srcpad) != sinkpad || GST_PAD_PEER (sinkpad) != srcpad)
2193       goto concurrent_link;
2194
2195     if (G_UNLIKELY (result != GST_PAD_LINK_OK))
2196       goto link_failed;
2197   }
2198   GST_OBJECT_UNLOCK (sinkpad);
2199   GST_OBJECT_UNLOCK (srcpad);
2200
2201   /* fire off a signal to each of the pads telling them
2202    * that they've been linked */
2203   g_signal_emit (srcpad, gst_pad_signals[PAD_LINKED], 0, sinkpad);
2204   g_signal_emit (sinkpad, gst_pad_signals[PAD_LINKED], 0, srcpad);
2205
2206   GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
2207       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2208
2209   gst_pad_send_event (srcpad, gst_event_new_reconfigure ());
2210
2211 done:
2212   if (G_LIKELY (parent)) {
2213     gst_element_post_message (parent,
2214         gst_message_new_structure_change (GST_OBJECT_CAST (sinkpad),
2215             GST_STRUCTURE_CHANGE_TYPE_PAD_LINK, parent, FALSE));
2216     gst_object_unref (parent);
2217   }
2218
2219   return result;
2220
2221   /* ERRORS */
2222 concurrent_link:
2223   {
2224     GST_CAT_INFO (GST_CAT_PADS, "concurrent link between %s:%s and %s:%s",
2225         GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2226     GST_OBJECT_UNLOCK (sinkpad);
2227     GST_OBJECT_UNLOCK (srcpad);
2228
2229     /* The other link operation succeeded first */
2230     result = GST_PAD_LINK_WAS_LINKED;
2231     goto done;
2232   }
2233 link_failed:
2234   {
2235     GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed",
2236         GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2237
2238     GST_PAD_PEER (srcpad) = NULL;
2239     GST_PAD_PEER (sinkpad) = NULL;
2240
2241     GST_OBJECT_UNLOCK (sinkpad);
2242     GST_OBJECT_UNLOCK (srcpad);
2243
2244     goto done;
2245   }
2246 }
2247
2248 /**
2249  * gst_pad_link:
2250  * @srcpad: the source #GstPad to link.
2251  * @sinkpad: the sink #GstPad to link.
2252  *
2253  * Links the source pad and the sink pad.
2254  *
2255  * Returns: A result code indicating if the connection worked or
2256  *          what went wrong.
2257  *
2258  * MT Safe.
2259  */
2260 GstPadLinkReturn
2261 gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
2262 {
2263   return gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_DEFAULT);
2264 }
2265
2266 static void
2267 gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
2268 {
2269   GstPadTemplate **template_p;
2270
2271   /* this function would need checks if it weren't static */
2272
2273   GST_OBJECT_LOCK (pad);
2274   template_p = &pad->padtemplate;
2275   gst_object_replace ((GstObject **) template_p, (GstObject *) templ);
2276   GST_OBJECT_UNLOCK (pad);
2277
2278   if (templ)
2279     gst_pad_template_pad_created (templ, pad);
2280 }
2281
2282 /**
2283  * gst_pad_get_pad_template:
2284  * @pad: a #GstPad.
2285  *
2286  * Gets the template for @pad.
2287  *
2288  * Returns: (transfer full): the #GstPadTemplate from which this pad was
2289  *     instantiated, or %NULL if this pad has no template. Unref after
2290  *     usage.
2291  */
2292 GstPadTemplate *
2293 gst_pad_get_pad_template (GstPad * pad)
2294 {
2295   GstPadTemplate *templ;
2296
2297   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2298
2299   templ = GST_PAD_PAD_TEMPLATE (pad);
2300
2301   return (templ ? gst_object_ref (templ) : NULL);
2302 }
2303
2304 /**
2305  * gst_pad_has_current_caps:
2306  * @pad: a  #GstPad to check
2307  *
2308  * Check if @pad has caps set on it with a #GST_EVENT_CAPS event.
2309  *
2310  * Returns: TRUE when @pad has caps associated with it.
2311  */
2312 gboolean
2313 gst_pad_has_current_caps (GstPad * pad)
2314 {
2315   gboolean result;
2316   GstCaps *caps;
2317
2318   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2319
2320   GST_OBJECT_LOCK (pad);
2321   caps = get_pad_caps (pad);
2322   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
2323       "check current pad caps %" GST_PTR_FORMAT, caps);
2324   result = (caps != NULL);
2325   GST_OBJECT_UNLOCK (pad);
2326
2327   return result;
2328 }
2329
2330 /**
2331  * gst_pad_get_current_caps:
2332  * @pad: a  #GstPad to get the current capabilities of.
2333  *
2334  * Gets the capabilities currently configured on @pad with the last
2335  * #GST_EVENT_CAPS event.
2336  *
2337  * Returns: the current caps of the pad with incremented ref-count.
2338  */
2339 GstCaps *
2340 gst_pad_get_current_caps (GstPad * pad)
2341 {
2342   GstCaps *result;
2343
2344   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2345
2346   GST_OBJECT_LOCK (pad);
2347   if ((result = get_pad_caps (pad)))
2348     gst_caps_ref (result);
2349   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
2350       "get current pad caps %" GST_PTR_FORMAT, result);
2351   GST_OBJECT_UNLOCK (pad);
2352
2353   return result;
2354 }
2355
2356 /**
2357  * gst_pad_get_pad_template_caps:
2358  * @pad: a #GstPad to get the template capabilities from.
2359  *
2360  * Gets the capabilities for @pad's template.
2361  *
2362  * Returns: (transfer full): the #GstCaps of this pad template.
2363  * Unref after usage.
2364  */
2365 GstCaps *
2366 gst_pad_get_pad_template_caps (GstPad * pad)
2367 {
2368   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2369
2370   if (GST_PAD_PAD_TEMPLATE (pad))
2371     return gst_pad_template_get_caps (GST_PAD_PAD_TEMPLATE (pad));
2372
2373   return gst_caps_ref (GST_CAPS_ANY);
2374 }
2375
2376 /**
2377  * gst_pad_get_peer:
2378  * @pad: a #GstPad to get the peer of.
2379  *
2380  * Gets the peer of @pad. This function refs the peer pad so
2381  * you need to unref it after use.
2382  *
2383  * Returns: (transfer full): the peer #GstPad. Unref after usage.
2384  *
2385  * MT safe.
2386  */
2387 GstPad *
2388 gst_pad_get_peer (GstPad * pad)
2389 {
2390   GstPad *result;
2391
2392   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2393
2394   GST_OBJECT_LOCK (pad);
2395   result = GST_PAD_PEER (pad);
2396   if (result)
2397     gst_object_ref (result);
2398   GST_OBJECT_UNLOCK (pad);
2399
2400   return result;
2401 }
2402
2403 /**
2404  * gst_pad_get_allowed_caps:
2405  * @pad: a #GstPad.
2406  *
2407  * Gets the capabilities of the allowed media types that can flow through
2408  * @pad and its peer.
2409  *
2410  * The allowed capabilities is calculated as the intersection of the results of
2411  * calling gst_pad_query_caps() on @pad and its peer. The caller owns a reference
2412  * on the resulting caps.
2413  *
2414  * Returns: (transfer full): the allowed #GstCaps of the pad link. Unref the
2415  *     caps when you no longer need it. This function returns NULL when @pad
2416  *     has no peer.
2417  *
2418  * MT safe.
2419  */
2420 GstCaps *
2421 gst_pad_get_allowed_caps (GstPad * pad)
2422 {
2423   GstCaps *mycaps;
2424   GstCaps *caps;
2425   GstCaps *peercaps;
2426   GstPad *peer;
2427
2428   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2429
2430   GST_OBJECT_LOCK (pad);
2431   peer = GST_PAD_PEER (pad);
2432   if (G_UNLIKELY (peer == NULL))
2433     goto no_peer;
2434
2435   GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "getting allowed caps");
2436
2437   gst_object_ref (peer);
2438   GST_OBJECT_UNLOCK (pad);
2439   mycaps = gst_pad_query_caps (pad, NULL);
2440
2441   peercaps = gst_pad_query_caps (peer, NULL);
2442   gst_object_unref (peer);
2443
2444   caps = gst_caps_intersect (mycaps, peercaps);
2445   gst_caps_unref (peercaps);
2446   gst_caps_unref (mycaps);
2447
2448   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "allowed caps %" GST_PTR_FORMAT,
2449       caps);
2450
2451   return caps;
2452
2453 no_peer:
2454   {
2455     GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "no peer");
2456     GST_OBJECT_UNLOCK (pad);
2457
2458     return NULL;
2459   }
2460 }
2461
2462 /**
2463  * gst_pad_iterate_internal_links_default:
2464  * @pad: the #GstPad to get the internal links of.
2465  * @parent: the parent of @pad or NULL
2466  *
2467  * Iterate the list of pads to which the given pad is linked to inside of
2468  * the parent element.
2469  * This is the default handler, and thus returns an iterator of all of the
2470  * pads inside the parent element with opposite direction.
2471  *
2472  * The caller must free this iterator after use with gst_iterator_free().
2473  *
2474  * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
2475  * returned pad with gst_object_unref().
2476  */
2477 GstIterator *
2478 gst_pad_iterate_internal_links_default (GstPad * pad, GstObject * parent)
2479 {
2480   GstIterator *res;
2481   GList **padlist;
2482   guint32 *cookie;
2483   GMutex *lock;
2484   gpointer owner;
2485   GstElement *eparent;
2486
2487   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2488
2489   if (parent != NULL && GST_IS_ELEMENT (parent)) {
2490     eparent = GST_ELEMENT_CAST (gst_object_ref (parent));
2491   } else {
2492     GST_OBJECT_LOCK (pad);
2493     eparent = GST_PAD_PARENT (pad);
2494     if (!eparent || !GST_IS_ELEMENT (eparent))
2495       goto no_parent;
2496
2497     gst_object_ref (eparent);
2498     GST_OBJECT_UNLOCK (pad);
2499   }
2500
2501   if (pad->direction == GST_PAD_SRC)
2502     padlist = &eparent->sinkpads;
2503   else
2504     padlist = &eparent->srcpads;
2505
2506   GST_DEBUG_OBJECT (pad, "Making iterator");
2507
2508   cookie = &eparent->pads_cookie;
2509   owner = eparent;
2510   lock = GST_OBJECT_GET_LOCK (eparent);
2511
2512   res = gst_iterator_new_list (GST_TYPE_PAD,
2513       lock, cookie, padlist, (GObject *) owner, NULL);
2514
2515   gst_object_unref (owner);
2516
2517   return res;
2518
2519   /* ERRORS */
2520 no_parent:
2521   {
2522     GST_OBJECT_UNLOCK (pad);
2523     GST_DEBUG_OBJECT (pad, "no parent element");
2524     return NULL;
2525   }
2526 }
2527
2528 /**
2529  * gst_pad_iterate_internal_links:
2530  * @pad: the GstPad to get the internal links of.
2531  *
2532  * Gets an iterator for the pads to which the given pad is linked to inside
2533  * of the parent element.
2534  *
2535  * Each #GstPad element yielded by the iterator will have its refcount increased,
2536  * so unref after use.
2537  *
2538  * Free-function: gst_iterator_free
2539  *
2540  * Returns: (transfer full): a new #GstIterator of #GstPad or %NULL when the
2541  *     pad does not have an iterator function configured. Use
2542  *     gst_iterator_free() after usage.
2543  */
2544 GstIterator *
2545 gst_pad_iterate_internal_links (GstPad * pad)
2546 {
2547   GstIterator *res = NULL;
2548   GstObject *parent;
2549
2550   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2551
2552   GST_OBJECT_LOCK (pad);
2553   ACQUIRE_PARENT (pad, parent, no_parent);
2554   GST_OBJECT_UNLOCK (pad);
2555
2556   if (GST_PAD_ITERINTLINKFUNC (pad))
2557     res = GST_PAD_ITERINTLINKFUNC (pad) (pad, parent);
2558
2559   RELEASE_PARENT (parent);
2560
2561   return res;
2562
2563   /* ERRORS */
2564 no_parent:
2565   {
2566     GST_DEBUG_OBJECT (pad, "no parent");
2567     GST_OBJECT_UNLOCK (pad);
2568     return FALSE;
2569   }
2570 }
2571
2572 /**
2573  * gst_pad_forward:
2574  * @pad: a #GstPad
2575  * @forward: (scope call): a #GstPadForwardFunction
2576  * @user_data: user data passed to @forward
2577  *
2578  * Calls @forward for all internally linked pads of @pad. This function deals with
2579  * dynamically changing internal pads and will make sure that the @forward
2580  * function is only called once for each pad.
2581  *
2582  * When @forward returns TRUE, no further pads will be processed.
2583  *
2584  * Returns: TRUE if one of the dispatcher functions returned TRUE.
2585  */
2586 gboolean
2587 gst_pad_forward (GstPad * pad, GstPadForwardFunction forward,
2588     gpointer user_data)
2589 {
2590   gboolean result = FALSE;
2591   GstIterator *iter;
2592   gboolean done = FALSE;
2593   GValue item = { 0, };
2594   GList *pushed_pads = NULL;
2595
2596   iter = gst_pad_iterate_internal_links (pad);
2597
2598   if (!iter)
2599     goto no_iter;
2600
2601   while (!done) {
2602     switch (gst_iterator_next (iter, &item)) {
2603       case GST_ITERATOR_OK:
2604       {
2605         GstPad *intpad;
2606
2607         intpad = g_value_get_object (&item);
2608
2609         /* if already pushed, skip. FIXME, find something faster to tag pads */
2610         if (intpad == NULL || g_list_find (pushed_pads, intpad)) {
2611           g_value_reset (&item);
2612           break;
2613         }
2614
2615         GST_LOG_OBJECT (pad, "calling forward function on pad %s:%s",
2616             GST_DEBUG_PAD_NAME (intpad));
2617         done = result = forward (intpad, user_data);
2618
2619         pushed_pads = g_list_prepend (pushed_pads, intpad);
2620
2621         g_value_reset (&item);
2622         break;
2623       }
2624       case GST_ITERATOR_RESYNC:
2625         /* We don't reset the result here because we don't push the event
2626          * again on pads that got the event already and because we need
2627          * to consider the result of the previous pushes */
2628         gst_iterator_resync (iter);
2629         break;
2630       case GST_ITERATOR_ERROR:
2631         GST_ERROR_OBJECT (pad, "Could not iterate over internally linked pads");
2632         done = TRUE;
2633         break;
2634       case GST_ITERATOR_DONE:
2635         done = TRUE;
2636         break;
2637     }
2638   }
2639   g_value_unset (&item);
2640   gst_iterator_free (iter);
2641
2642   g_list_free (pushed_pads);
2643
2644 no_iter:
2645   return result;
2646 }
2647
2648 typedef struct
2649 {
2650   GstEvent *event;
2651   gboolean result;
2652   gboolean dispatched;
2653 } EventData;
2654
2655 static gboolean
2656 event_forward_func (GstPad * pad, EventData * data)
2657 {
2658   /* for each pad we send to, we should ref the event; it's up
2659    * to downstream to unref again when handled. */
2660   GST_LOG_OBJECT (pad, "Reffing and pushing event %p (%s) to %s:%s",
2661       data->event, GST_EVENT_TYPE_NAME (data->event), GST_DEBUG_PAD_NAME (pad));
2662
2663   data->result |= gst_pad_push_event (pad, gst_event_ref (data->event));
2664
2665   data->dispatched = TRUE;
2666
2667   /* don't stop */
2668   return FALSE;
2669 }
2670
2671 /**
2672  * gst_pad_event_default:
2673  * @pad: a #GstPad to call the default event handler on.
2674  * @parent: the parent of @pad or NULL
2675  * @event: (transfer full): the #GstEvent to handle.
2676  *
2677  * Invokes the default event handler for the given pad.
2678  *
2679  * The EOS event will pause the task associated with @pad before it is forwarded
2680  * to all internally linked pads,
2681  *
2682  * The the event is sent to all pads internally linked to @pad. This function
2683  * takes ownership of @event.
2684  *
2685  * Returns: TRUE if the event was sent successfully.
2686  */
2687 gboolean
2688 gst_pad_event_default (GstPad * pad, GstObject * parent, GstEvent * event)
2689 {
2690   gboolean result, forward = TRUE;
2691
2692   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2693   g_return_val_if_fail (event != NULL, FALSE);
2694
2695   GST_LOG_OBJECT (pad, "default event handler");
2696
2697   switch (GST_EVENT_TYPE (event)) {
2698     case GST_EVENT_CAPS:
2699       forward = GST_PAD_IS_PROXY_CAPS (pad);
2700       result = TRUE;
2701       break;
2702     default:
2703       break;
2704   }
2705
2706   if (forward) {
2707     EventData data;
2708
2709     data.event = event;
2710     data.dispatched = FALSE;
2711     data.result = FALSE;
2712
2713     gst_pad_forward (pad, (GstPadForwardFunction) event_forward_func, &data);
2714
2715     /* for sinkpads without a parent element or without internal links, nothing
2716      * will be dispatched but we still want to return TRUE. */
2717     if (data.dispatched)
2718       result = data.result;
2719     else
2720       result = TRUE;
2721   }
2722
2723   gst_event_unref (event);
2724
2725   return result;
2726 }
2727
2728 /* Default accept caps implementation just checks against
2729  * the allowed caps for the pad */
2730 static gboolean
2731 gst_pad_query_accept_caps_default (GstPad * pad, GstQuery * query)
2732 {
2733   /* get the caps and see if it intersects to something not empty */
2734   GstCaps *caps, *allowed;
2735   gboolean result;
2736
2737   GST_DEBUG_OBJECT (pad, "query accept-caps %" GST_PTR_FORMAT, query);
2738
2739   /* first forward the query to internally linked pads when we are dealing with
2740    * a PROXY CAPS */
2741   if (GST_PAD_IS_PROXY_CAPS (pad)) {
2742     if ((result = gst_pad_proxy_query_accept_caps (pad, query))) {
2743       goto done;
2744     }
2745   }
2746
2747   GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pad,
2748       "fallback ACCEPT_CAPS query, consider implementing a specialized version");
2749
2750   allowed = gst_pad_query_caps (pad, NULL);
2751   gst_query_parse_accept_caps (query, &caps);
2752
2753   if (allowed) {
2754     GST_DEBUG_OBJECT (pad, "allowed caps %" GST_PTR_FORMAT, allowed);
2755     result = gst_caps_is_subset (caps, allowed);
2756     gst_caps_unref (allowed);
2757   } else {
2758     GST_DEBUG_OBJECT (pad, "no caps allowed on the pad");
2759     result = FALSE;
2760   }
2761   gst_query_set_accept_caps_result (query, result);
2762
2763 done:
2764   return TRUE;
2765 }
2766
2767 /* Default caps implementation */
2768 static gboolean
2769 gst_pad_query_caps_default (GstPad * pad, GstQuery * query)
2770 {
2771   GstCaps *result = NULL, *filter;
2772   GstPadTemplate *templ;
2773   gboolean fixed_caps;
2774
2775   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
2776
2777   gst_query_parse_caps (query, &filter);
2778
2779   /* first try to proxy if we must */
2780   if (GST_PAD_IS_PROXY_CAPS (pad)) {
2781     if ((gst_pad_proxy_query_caps (pad, query))) {
2782       gst_query_parse_caps_result (query, &result);
2783       goto filter_done;
2784     }
2785   }
2786
2787   /* no proxy or it failed, do default handling */
2788   fixed_caps = GST_PAD_IS_FIXED_CAPS (pad);
2789
2790   GST_OBJECT_LOCK (pad);
2791   if (fixed_caps) {
2792     /* fixed caps, try the negotiated caps first */
2793     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "fixed pad caps: trying pad caps");
2794     if ((result = get_pad_caps (pad)))
2795       goto filter_done_unlock;
2796   }
2797
2798   if ((templ = GST_PAD_PAD_TEMPLATE (pad))) {
2799     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "trying pad template caps");
2800     if ((result = GST_PAD_TEMPLATE_CAPS (templ)))
2801       goto filter_done_unlock;
2802   }
2803
2804   if (!fixed_caps) {
2805     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
2806         "non-fixed pad caps: trying pad caps");
2807     /* non fixed caps, try the negotiated caps */
2808     if ((result = get_pad_caps (pad)))
2809       goto filter_done_unlock;
2810   }
2811
2812   /* this almost never happens */
2813   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "pad has no caps");
2814   result = GST_CAPS_ANY;
2815
2816 filter_done_unlock:
2817   GST_OBJECT_UNLOCK (pad);
2818
2819 filter_done:
2820   /* run the filter on the result */
2821   if (filter) {
2822     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
2823         "using caps %p %" GST_PTR_FORMAT " with filter %p %"
2824         GST_PTR_FORMAT, result, result, filter, filter);
2825     result = gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
2826     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "result %p %" GST_PTR_FORMAT,
2827         result, result);
2828   } else {
2829     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
2830         "using caps %p %" GST_PTR_FORMAT, result, result);
2831     result = gst_caps_ref (result);
2832   }
2833
2834   gst_query_set_caps_result (query, result);
2835   gst_caps_unref (result);
2836
2837   return TRUE;
2838 }
2839
2840 typedef struct
2841 {
2842   GstQuery *query;
2843   gboolean result;
2844   gboolean dispatched;
2845 } QueryData;
2846
2847 static gboolean
2848 query_forward_func (GstPad * pad, QueryData * data)
2849 {
2850   GST_LOG_OBJECT (pad, "query peer %p (%s) of %s:%s",
2851       data->query, GST_EVENT_TYPE_NAME (data->query), GST_DEBUG_PAD_NAME (pad));
2852
2853   data->result |= gst_pad_peer_query (pad, data->query);
2854
2855   data->dispatched = TRUE;
2856
2857   /* stop on first successful reply */
2858   return data->result;
2859 }
2860
2861 /**
2862  * gst_pad_query_default:
2863  * @pad: a #GstPad to call the default query handler on.
2864  * @parent: the parent of @pad or NULL
2865  * @query: (transfer none): the #GstQuery to handle.
2866  *
2867  * Invokes the default query handler for the given pad.
2868  * The query is sent to all pads internally linked to @pad. Note that
2869  * if there are many possible sink pads that are internally linked to
2870  * @pad, only one will be sent the query.
2871  * Multi-sinkpad elements should implement custom query handlers.
2872  *
2873  * Returns: TRUE if the query was performed successfully.
2874  */
2875 gboolean
2876 gst_pad_query_default (GstPad * pad, GstObject * parent, GstQuery * query)
2877 {
2878   gboolean forward, ret = FALSE;
2879
2880   switch (GST_QUERY_TYPE (query)) {
2881     case GST_QUERY_SCHEDULING:
2882       forward = FALSE;
2883       break;
2884     case GST_QUERY_ALLOCATION:
2885       forward = GST_PAD_IS_PROXY_ALLOCATION (pad);
2886       break;
2887     case GST_QUERY_ACCEPT_CAPS:
2888       ret = gst_pad_query_accept_caps_default (pad, query);
2889       forward = FALSE;
2890       break;
2891     case GST_QUERY_CAPS:
2892       ret = gst_pad_query_caps_default (pad, query);
2893       forward = FALSE;
2894       break;
2895     case GST_QUERY_POSITION:
2896     case GST_QUERY_SEEKING:
2897     case GST_QUERY_FORMATS:
2898     case GST_QUERY_LATENCY:
2899     case GST_QUERY_JITTER:
2900     case GST_QUERY_RATE:
2901     case GST_QUERY_CONVERT:
2902     default:
2903       forward = TRUE;
2904       break;
2905   }
2906
2907   GST_DEBUG_OBJECT (pad, "%sforwarding %p (%s) query", (forward ? "" : "not "),
2908       query, GST_QUERY_TYPE_NAME (query));
2909
2910   if (forward) {
2911     QueryData data;
2912
2913     data.query = query;
2914     data.dispatched = FALSE;
2915     data.result = FALSE;
2916
2917     gst_pad_forward (pad, (GstPadForwardFunction) query_forward_func, &data);
2918
2919     if (data.dispatched) {
2920       ret = data.result;
2921     } else {
2922       /* nothing dispatched, assume drained */
2923       if (GST_QUERY_TYPE (query) == GST_QUERY_DRAIN)
2924         ret = TRUE;
2925       else
2926         ret = FALSE;
2927     }
2928   }
2929   return ret;
2930 }
2931
2932 static void
2933 probe_hook_marshal (GHook * hook, ProbeMarshall * data)
2934 {
2935   GstPad *pad = data->pad;
2936   GstPadProbeInfo *info = data->info;
2937   GstPadProbeType type, flags;
2938   GstPadProbeCallback callback;
2939   GstPadProbeReturn ret;
2940
2941   /* if we have called this callback, do nothing */
2942   if (PROBE_COOKIE (hook) == data->cookie) {
2943     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2944         "hook %lu, cookie %u already called", hook->hook_id,
2945         PROBE_COOKIE (hook));
2946     return;
2947   }
2948
2949   PROBE_COOKIE (hook) = data->cookie;
2950
2951   flags = hook->flags >> G_HOOK_FLAG_USER_SHIFT;
2952   type = info->type;
2953
2954   /* one of the data types */
2955   if ((flags & GST_PAD_PROBE_TYPE_ALL_BOTH & type) == 0)
2956     goto no_match;
2957   /* one of the scheduling types */
2958   if ((flags & GST_PAD_PROBE_TYPE_SCHEDULING & type) == 0)
2959     goto no_match;
2960   /* one of the blocking types must match */
2961   if ((type & GST_PAD_PROBE_TYPE_BLOCKING) &&
2962       (flags & GST_PAD_PROBE_TYPE_BLOCKING & type) == 0)
2963     goto no_match;
2964   /* only probes that have GST_PAD_PROBE_TYPE_EVENT_FLUSH set */
2965   if ((type & GST_PAD_PROBE_TYPE_EVENT_FLUSH) &&
2966       (flags & GST_PAD_PROBE_TYPE_EVENT_FLUSH & type) == 0)
2967     goto no_match;
2968
2969   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2970       "hook %lu, cookie %u with flags 0x%08x matches", hook->hook_id,
2971       PROBE_COOKIE (hook), flags);
2972
2973   data->marshalled = TRUE;
2974
2975   callback = (GstPadProbeCallback) hook->func;
2976   if (callback == NULL)
2977     return;
2978
2979   info->id = hook->hook_id;
2980
2981   GST_OBJECT_UNLOCK (pad);
2982
2983   ret = callback (pad, info, hook->data);
2984
2985   GST_OBJECT_LOCK (pad);
2986
2987   switch (ret) {
2988     case GST_PAD_PROBE_REMOVE:
2989       /* remove the probe */
2990       GST_DEBUG_OBJECT (pad, "asked to remove hook");
2991       cleanup_hook (pad, hook);
2992       break;
2993     case GST_PAD_PROBE_DROP:
2994       /* need to drop the data, make sure other probes don't get called
2995        * anymore */
2996       GST_DEBUG_OBJECT (pad, "asked to drop item");
2997       info->type = GST_PAD_PROBE_TYPE_INVALID;
2998       data->dropped = TRUE;
2999       break;
3000     case GST_PAD_PROBE_PASS:
3001       /* inform the pad block to let things pass */
3002       GST_DEBUG_OBJECT (pad, "asked to pass item");
3003       data->pass = TRUE;
3004       break;
3005     default:
3006       GST_DEBUG_OBJECT (pad, "probe returned %d", ret);
3007       break;
3008   }
3009   return;
3010
3011 no_match:
3012   {
3013     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3014         "hook %lu, cookie %u with flags 0x%08x does not match %08x",
3015         hook->hook_id, PROBE_COOKIE (hook), flags, info->type);
3016     return;
3017   }
3018 }
3019
3020 /* a probe that does not take or return any data */
3021 #define PROBE_NO_DATA(pad,mask,label,defaultval)                \
3022   G_STMT_START {                                                \
3023     if (G_UNLIKELY (pad->num_probes)) {                         \
3024       /* pass NULL as the data item */                          \
3025       GstPadProbeInfo info = { mask, 0, NULL, 0, 0 };           \
3026       ret = do_probe_callbacks (pad, &info, defaultval);        \
3027       if (G_UNLIKELY (ret != defaultval && ret != GST_FLOW_OK)) \
3028         goto label;                                             \
3029     }                                                           \
3030   } G_STMT_END
3031
3032 #define PROBE_FULL(pad,mask,data,offs,size,label)               \
3033   G_STMT_START {                                                \
3034     if (G_UNLIKELY (pad->num_probes)) {                         \
3035       /* pass the data item */                                  \
3036       GstPadProbeInfo info = { mask, 0, data, offs, size };     \
3037       ret = do_probe_callbacks (pad, &info, GST_FLOW_OK);       \
3038       /* store the possibly updated data item */                \
3039       data = GST_PAD_PROBE_INFO_DATA (&info);                   \
3040       /* if something went wrong, exit */                       \
3041       if (G_UNLIKELY (ret != GST_FLOW_OK))                      \
3042         goto label;                                             \
3043     }                                                           \
3044   } G_STMT_END
3045
3046 #define PROBE_PUSH(pad,mask,data,label)                          \
3047   PROBE_FULL(pad, mask, data, -1, -1, label);
3048 #define PROBE_PULL(pad,mask,data,offs,size,label)                \
3049   PROBE_FULL(pad, mask, data, offs, size, label);
3050
3051 static GstFlowReturn
3052 do_probe_callbacks (GstPad * pad, GstPadProbeInfo * info,
3053     GstFlowReturn defaultval)
3054 {
3055   ProbeMarshall data;
3056   guint cookie;
3057   gboolean is_block;
3058
3059   data.pad = pad;
3060   data.info = info;
3061   data.pass = FALSE;
3062   data.marshalled = FALSE;
3063   data.dropped = FALSE;
3064   data.cookie = ++pad->priv->probe_cookie;
3065
3066   is_block =
3067       (info->type & GST_PAD_PROBE_TYPE_BLOCK) == GST_PAD_PROBE_TYPE_BLOCK;
3068
3069 again:
3070   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3071       "do probes cookie %u", data.cookie);
3072   cookie = pad->priv->probe_list_cookie;
3073
3074   g_hook_list_marshal (&pad->probes, TRUE,
3075       (GHookMarshaller) probe_hook_marshal, &data);
3076
3077   /* if the list changed, call the new callbacks (they will not have their
3078    * cookie set to data.cookie */
3079   if (cookie != pad->priv->probe_list_cookie) {
3080     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3081         "probe list changed, restarting");
3082     goto again;
3083   }
3084
3085   /* the first item that dropped will stop the hooks and then we drop here */
3086   if (data.dropped)
3087     goto dropped;
3088
3089   /* if no handler matched and we are blocking, let the item pass */
3090   if (!data.marshalled && is_block)
3091     goto passed;
3092
3093   /* At this point, all handlers returned either OK or PASS. If one handler
3094    * returned PASS, let the item pass */
3095   if (data.pass)
3096     goto passed;
3097
3098   if (is_block) {
3099     while (GST_PAD_IS_BLOCKED (pad)) {
3100       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3101           "we are blocked %d times", pad->num_blocked);
3102
3103       /* we might have released the lock */
3104       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3105         goto flushing;
3106
3107       /* now we block the streaming thread. It can be unlocked when we
3108        * deactivate the pad (which will also set the FLUSHING flag) or
3109        * when the pad is unblocked. A flushing event will also unblock
3110        * the pad after setting the FLUSHING flag. */
3111       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3112           "Waiting to be unblocked or set flushing");
3113       GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_BLOCKING);
3114       GST_PAD_BLOCK_WAIT (pad);
3115       GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_BLOCKING);
3116       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "We got unblocked");
3117
3118       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3119         goto flushing;
3120     }
3121   }
3122
3123   return defaultval;
3124
3125   /* ERRORS */
3126 flushing:
3127   {
3128     GST_DEBUG_OBJECT (pad, "pad is flushing");
3129     return GST_FLOW_FLUSHING;
3130   }
3131 dropped:
3132   {
3133     GST_DEBUG_OBJECT (pad, "data is dropped");
3134     return GST_FLOW_CUSTOM_SUCCESS;
3135   }
3136 passed:
3137   {
3138     /* FIXME : Should we return FLOW_OK or the defaultval ?? */
3139     GST_DEBUG_OBJECT (pad, "data is passed");
3140     return GST_FLOW_OK;
3141   }
3142 }
3143
3144 /* pad offsets */
3145
3146 /**
3147  * gst_pad_get_offset:
3148  * @pad: a #GstPad
3149  *
3150  * Get the offset applied to the running time of @pad. @pad has to be a source
3151  * pad.
3152  *
3153  * Returns: the offset.
3154  */
3155 gint64
3156 gst_pad_get_offset (GstPad * pad)
3157 {
3158   gint64 result;
3159
3160   g_return_val_if_fail (GST_IS_PAD (pad), 0);
3161
3162   GST_OBJECT_LOCK (pad);
3163   result = pad->offset;
3164   GST_OBJECT_UNLOCK (pad);
3165
3166   return result;
3167 }
3168
3169 /**
3170  * gst_pad_set_offset:
3171  * @pad: a #GstPad
3172  * @offset: the offset
3173  *
3174  * Set the offset that will be applied to the running time of @pad.
3175  */
3176 void
3177 gst_pad_set_offset (GstPad * pad, gint64 offset)
3178 {
3179   PadEvent *ev;
3180
3181   g_return_if_fail (GST_IS_PAD (pad));
3182
3183   GST_OBJECT_LOCK (pad);
3184   /* if nothing changed, do nothing */
3185   if (pad->offset == offset)
3186     goto done;
3187
3188   pad->offset = offset;
3189   GST_DEBUG_OBJECT (pad, "changed offset to %" G_GINT64_FORMAT, offset);
3190
3191   /* sinkpads will apply their offset the next time a segment
3192    * event is received. */
3193   if (GST_PAD_IS_SINK (pad))
3194     goto done;
3195
3196   /* resend the last segment event on next buffer push */
3197   if ((ev = find_event_by_type (pad, GST_EVENT_SEGMENT, 0))) {
3198     ev->received = FALSE;
3199     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
3200   }
3201
3202 done:
3203   GST_OBJECT_UNLOCK (pad);
3204 }
3205
3206 typedef struct
3207 {
3208   GstFlowReturn ret;
3209
3210   /* If TRUE and ret is not OK this means
3211    * that pushing the EOS event failed
3212    */
3213   gboolean was_eos;
3214 } PushStickyData;
3215
3216 /* should be called with pad LOCK */
3217 static gboolean
3218 push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
3219 {
3220   PushStickyData *data = user_data;
3221   GstEvent *event = ev->event;
3222
3223   if (ev->received) {
3224     GST_DEBUG_OBJECT (pad, "event %s was already received",
3225         GST_EVENT_TYPE_NAME (event));
3226     return TRUE;
3227   }
3228
3229   data->ret = gst_pad_push_event_unchecked (pad, gst_event_ref (event),
3230       GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
3231
3232   switch (data->ret) {
3233     case GST_FLOW_OK:
3234       ev->received = TRUE;
3235       GST_DEBUG_OBJECT (pad, "event %s marked received",
3236           GST_EVENT_TYPE_NAME (event));
3237       break;
3238     case GST_FLOW_NOT_LINKED:
3239       /* not linked is not a problem, we are sticky so the event will be
3240        * sent later but only for non-EOS events */
3241       GST_DEBUG_OBJECT (pad, "pad was not linked");
3242       if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
3243         data->ret = GST_FLOW_OK;
3244       /* fallthrough */
3245     default:
3246       GST_DEBUG_OBJECT (pad, "mark pending events");
3247       GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
3248       break;
3249   }
3250
3251   if (data->ret != GST_FLOW_OK && GST_EVENT_TYPE (event) == GST_EVENT_EOS)
3252     data->was_eos = TRUE;
3253
3254   return data->ret == GST_FLOW_OK;
3255 }
3256
3257 /* check sticky events and push them when needed. should be called
3258  * with pad LOCK */
3259 static inline GstFlowReturn
3260 check_sticky (GstPad * pad)
3261 {
3262   PushStickyData data = { GST_FLOW_OK, FALSE };
3263
3264   if (G_UNLIKELY (GST_PAD_HAS_PENDING_EVENTS (pad))) {
3265     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PENDING_EVENTS);
3266
3267     GST_DEBUG_OBJECT (pad, "pushing all sticky events");
3268     events_foreach (pad, push_sticky, &data);
3269
3270     /* If there's an EOS event we must push it downstream
3271      * even if sending a previous sticky event failed.
3272      * Otherwise the pipeline might wait forever for EOS.
3273      *
3274      * Only do this if pushing another event than the EOS
3275      * event failed.
3276      */
3277     if (data.ret != GST_FLOW_OK && !data.was_eos) {
3278       PadEvent *ev = find_event_by_type (pad, GST_EVENT_EOS, 0);
3279
3280       if (ev && !ev->received) {
3281         data.ret = gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event),
3282             GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
3283       }
3284     }
3285   }
3286   return data.ret;
3287 }
3288
3289
3290 /**
3291  * gst_pad_query:
3292  * @pad: a #GstPad to invoke the default query on.
3293  * @query: (transfer none): the #GstQuery to perform.
3294  *
3295  * Dispatches a query to a pad. The query should have been allocated by the
3296  * caller via one of the type-specific allocation functions. The element that
3297  * the pad belongs to is responsible for filling the query with an appropriate
3298  * response, which should then be parsed with a type-specific query parsing
3299  * function.
3300  *
3301  * Again, the caller is responsible for both the allocation and deallocation of
3302  * the query structure.
3303  *
3304  * Please also note that some queries might need a running pipeline to work.
3305  *
3306  * Returns: TRUE if the query could be performed.
3307  */
3308 gboolean
3309 gst_pad_query (GstPad * pad, GstQuery * query)
3310 {
3311   GstObject *parent;
3312   gboolean res, serialized;
3313   GstPadQueryFunction func;
3314   GstPadProbeType type;
3315   GstFlowReturn ret;
3316
3317   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3318   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
3319
3320   if (GST_PAD_IS_SRC (pad)) {
3321     if (G_UNLIKELY (!GST_QUERY_IS_UPSTREAM (query)))
3322       goto wrong_direction;
3323     type = GST_PAD_PROBE_TYPE_QUERY_UPSTREAM;
3324   } else if (GST_PAD_IS_SINK (pad)) {
3325     if (G_UNLIKELY (!GST_QUERY_IS_DOWNSTREAM (query)))
3326       goto wrong_direction;
3327     type = GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM;
3328   } else
3329     goto unknown_direction;
3330
3331   GST_DEBUG_OBJECT (pad, "doing query %p (%s)", query,
3332       GST_QUERY_TYPE_NAME (query));
3333
3334   serialized = GST_QUERY_IS_SERIALIZED (query);
3335   if (G_UNLIKELY (serialized))
3336     GST_PAD_STREAM_LOCK (pad);
3337
3338   GST_OBJECT_LOCK (pad);
3339   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH |
3340       GST_PAD_PROBE_TYPE_BLOCK, query, probe_stopped);
3341   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, query, probe_stopped);
3342
3343   ACQUIRE_PARENT (pad, parent, no_parent);
3344   GST_OBJECT_UNLOCK (pad);
3345
3346   if ((func = GST_PAD_QUERYFUNC (pad)) == NULL)
3347     goto no_func;
3348
3349   res = func (pad, parent, query);
3350
3351   RELEASE_PARENT (parent);
3352
3353   GST_DEBUG_OBJECT (pad, "sent query %p (%s), result %d", query,
3354       GST_QUERY_TYPE_NAME (query), res);
3355
3356   if (res != TRUE)
3357     goto query_failed;
3358
3359   GST_OBJECT_LOCK (pad);
3360   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PULL, query, probe_stopped);
3361   GST_OBJECT_UNLOCK (pad);
3362
3363   if (G_UNLIKELY (serialized))
3364     GST_PAD_STREAM_UNLOCK (pad);
3365
3366   return res;
3367
3368   /* ERRORS */
3369 wrong_direction:
3370   {
3371     g_warning ("pad %s:%s query %s in wrong direction",
3372         GST_DEBUG_PAD_NAME (pad), GST_QUERY_TYPE_NAME (query));
3373     return FALSE;
3374   }
3375 unknown_direction:
3376   {
3377     g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
3378     return FALSE;
3379   }
3380 no_parent:
3381   {
3382     GST_DEBUG_OBJECT (pad, "had no parent");
3383     GST_OBJECT_UNLOCK (pad);
3384     if (G_UNLIKELY (serialized))
3385       GST_PAD_STREAM_UNLOCK (pad);
3386     return FALSE;
3387   }
3388 no_func:
3389   {
3390     GST_DEBUG_OBJECT (pad, "had no query function");
3391     RELEASE_PARENT (parent);
3392     if (G_UNLIKELY (serialized))
3393       GST_PAD_STREAM_UNLOCK (pad);
3394     return FALSE;
3395   }
3396 query_failed:
3397   {
3398     GST_DEBUG_OBJECT (pad, "query failed");
3399     if (G_UNLIKELY (serialized))
3400       GST_PAD_STREAM_UNLOCK (pad);
3401     return FALSE;
3402   }
3403 probe_stopped:
3404   {
3405     GST_DEBUG_OBJECT (pad, "probe stopped: %s", gst_flow_get_name (ret));
3406     GST_OBJECT_UNLOCK (pad);
3407     if (G_UNLIKELY (serialized))
3408       GST_PAD_STREAM_UNLOCK (pad);
3409
3410     /* if a probe dropped, we don't sent it further but assume that the probe
3411      * answered the query and return TRUE */
3412     if (ret == GST_FLOW_CUSTOM_SUCCESS)
3413       res = TRUE;
3414     else
3415       res = FALSE;
3416
3417     return res;
3418   }
3419 }
3420
3421 /**
3422  * gst_pad_peer_query:
3423  * @pad: a #GstPad to invoke the peer query on.
3424  * @query: (transfer none): the #GstQuery to perform.
3425  *
3426  * Performs gst_pad_query() on the peer of @pad.
3427  *
3428  * The caller is responsible for both the allocation and deallocation of
3429  * the query structure.
3430  *
3431  * Returns: TRUE if the query could be performed. This function returns %FALSE
3432  * if @pad has no peer.
3433  */
3434 gboolean
3435 gst_pad_peer_query (GstPad * pad, GstQuery * query)
3436 {
3437   GstPad *peerpad;
3438   GstPadProbeType type;
3439   gboolean res, serialized;
3440   GstFlowReturn ret;
3441
3442   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3443   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
3444
3445   if (GST_PAD_IS_SRC (pad)) {
3446     if (G_UNLIKELY (!GST_QUERY_IS_DOWNSTREAM (query)))
3447       goto wrong_direction;
3448     type = GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM;
3449   } else if (GST_PAD_IS_SINK (pad)) {
3450     if (G_UNLIKELY (!GST_QUERY_IS_UPSTREAM (query)))
3451       goto wrong_direction;
3452     type = GST_PAD_PROBE_TYPE_QUERY_UPSTREAM;
3453   } else
3454     goto unknown_direction;
3455
3456   GST_DEBUG_OBJECT (pad, "peer query %p (%s)", query,
3457       GST_QUERY_TYPE_NAME (query));
3458
3459   serialized = GST_QUERY_IS_SERIALIZED (query);
3460
3461   GST_OBJECT_LOCK (pad);
3462   if (GST_PAD_IS_SRC (pad) && serialized) {
3463     /* all serialized queries on the srcpad trigger push of
3464      * sticky events */
3465     if (!check_sticky (pad) == GST_FLOW_OK)
3466       goto sticky_failed;
3467   }
3468
3469   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH |
3470       GST_PAD_PROBE_TYPE_BLOCK, query, probe_stopped);
3471   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, query, probe_stopped);
3472
3473   peerpad = GST_PAD_PEER (pad);
3474   if (G_UNLIKELY (peerpad == NULL))
3475     goto no_peer;
3476
3477   gst_object_ref (peerpad);
3478   GST_OBJECT_UNLOCK (pad);
3479
3480   res = gst_pad_query (peerpad, query);
3481
3482   gst_object_unref (peerpad);
3483
3484   if (res != TRUE)
3485     goto query_failed;
3486
3487   GST_OBJECT_LOCK (pad);
3488   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PULL, query, probe_stopped);
3489   GST_OBJECT_UNLOCK (pad);
3490
3491   return res;
3492
3493   /* ERRORS */
3494 wrong_direction:
3495   {
3496     g_warning ("pad %s:%s query %s in wrong direction",
3497         GST_DEBUG_PAD_NAME (pad), GST_QUERY_TYPE_NAME (query));
3498     return FALSE;
3499   }
3500 unknown_direction:
3501   {
3502     g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
3503     return FALSE;
3504   }
3505 sticky_failed:
3506   {
3507     GST_WARNING_OBJECT (pad, "could not send sticky events");
3508     GST_OBJECT_UNLOCK (pad);
3509     return FALSE;
3510   }
3511 no_peer:
3512   {
3513     GST_WARNING_OBJECT (pad, "pad has no peer");
3514     GST_OBJECT_UNLOCK (pad);
3515     return FALSE;
3516   }
3517 query_failed:
3518   {
3519     GST_DEBUG_OBJECT (pad, "query failed");
3520     return FALSE;
3521   }
3522 probe_stopped:
3523   {
3524     GST_DEBUG_OBJECT (pad, "probe stopped: %s", gst_flow_get_name (ret));
3525     GST_OBJECT_UNLOCK (pad);
3526
3527     /* if a probe dropped, we don't sent it further but assume that the probe
3528      * answered the query and return TRUE */
3529     if (ret == GST_FLOW_CUSTOM_SUCCESS)
3530       res = TRUE;
3531     else
3532       res = FALSE;
3533
3534     return res;
3535   }
3536 }
3537
3538 /**********************************************************************
3539  * Data passing functions
3540  */
3541
3542 /* this is the chain function that does not perform the additional argument
3543  * checking for that little extra speed.
3544  */
3545 static inline GstFlowReturn
3546 gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
3547 {
3548   GstFlowReturn ret;
3549   GstObject *parent;
3550
3551   GST_PAD_STREAM_LOCK (pad);
3552
3553   GST_OBJECT_LOCK (pad);
3554   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3555     goto flushing;
3556
3557   if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
3558     goto eos;
3559
3560   if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
3561     goto wrong_mode;
3562
3563   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_BLOCK, data, probe_stopped);
3564
3565   PROBE_PUSH (pad, type, data, probe_stopped);
3566
3567   parent = GST_OBJECT_PARENT (pad);
3568   GST_OBJECT_UNLOCK (pad);
3569
3570   /* NOTE: we read the chainfunc unlocked.
3571    * we cannot hold the lock for the pad so we might send
3572    * the data to the wrong function. This is not really a
3573    * problem since functions are assigned at creation time
3574    * and don't change that often... */
3575   if (G_LIKELY (type & GST_PAD_PROBE_TYPE_BUFFER)) {
3576     GstPadChainFunction chainfunc;
3577
3578     if (G_UNLIKELY ((chainfunc = GST_PAD_CHAINFUNC (pad)) == NULL))
3579       goto no_function;
3580
3581     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3582         "calling chainfunction &%s with buffer %" GST_PTR_FORMAT,
3583         GST_DEBUG_FUNCPTR_NAME (chainfunc), GST_BUFFER (data));
3584
3585     ret = chainfunc (pad, parent, GST_BUFFER_CAST (data));
3586
3587     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3588         "called chainfunction &%s with buffer %p, returned %s",
3589         GST_DEBUG_FUNCPTR_NAME (chainfunc), data, gst_flow_get_name (ret));
3590   } else {
3591     GstPadChainListFunction chainlistfunc;
3592
3593     if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL))
3594       goto no_function;
3595
3596     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3597         "calling chainlistfunction &%s",
3598         GST_DEBUG_FUNCPTR_NAME (chainlistfunc));
3599
3600     ret = chainlistfunc (pad, parent, GST_BUFFER_LIST_CAST (data));
3601
3602     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3603         "called chainlistfunction &%s, returned %s",
3604         GST_DEBUG_FUNCPTR_NAME (chainlistfunc), gst_flow_get_name (ret));
3605   }
3606
3607   GST_PAD_STREAM_UNLOCK (pad);
3608
3609   return ret;
3610
3611   /* ERRORS */
3612 flushing:
3613   {
3614     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3615         "chaining, but pad was flushing");
3616     GST_OBJECT_UNLOCK (pad);
3617     GST_PAD_STREAM_UNLOCK (pad);
3618     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3619     return GST_FLOW_FLUSHING;
3620   }
3621 eos:
3622   {
3623     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "chaining, but pad was EOS");
3624     GST_OBJECT_UNLOCK (pad);
3625     GST_PAD_STREAM_UNLOCK (pad);
3626     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3627     return GST_FLOW_EOS;
3628   }
3629 wrong_mode:
3630   {
3631     g_critical ("chain on pad %s:%s but it was not in push mode",
3632         GST_DEBUG_PAD_NAME (pad));
3633     GST_OBJECT_UNLOCK (pad);
3634     GST_PAD_STREAM_UNLOCK (pad);
3635     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3636     return GST_FLOW_ERROR;
3637   }
3638 probe_stopped:
3639   {
3640     GST_OBJECT_UNLOCK (pad);
3641     GST_PAD_STREAM_UNLOCK (pad);
3642     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3643
3644     switch (ret) {
3645       case GST_FLOW_CUSTOM_SUCCESS:
3646         GST_DEBUG_OBJECT (pad, "dropped buffer");
3647         ret = GST_FLOW_OK;
3648         break;
3649       default:
3650         GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
3651         break;
3652     }
3653     return ret;
3654   }
3655 no_function:
3656   {
3657     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3658     g_critical ("chain on pad %s:%s but it has no chainfunction",
3659         GST_DEBUG_PAD_NAME (pad));
3660     GST_PAD_STREAM_UNLOCK (pad);
3661     return GST_FLOW_NOT_SUPPORTED;
3662   }
3663 }
3664
3665 /**
3666  * gst_pad_chain:
3667  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
3668  * @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
3669  *     if not.
3670  *
3671  * Chain a buffer to @pad.
3672  *
3673  * The function returns #GST_FLOW_FLUSHING if the pad was flushing.
3674  *
3675  * If the buffer type is not acceptable for @pad (as negotiated with a
3676  * preceeding GST_EVENT_CAPS event), this function returns
3677  * #GST_FLOW_NOT_NEGOTIATED.
3678  *
3679  * The function proceeds calling the chain function installed on @pad (see
3680  * gst_pad_set_chain_function()) and the return value of that function is
3681  * returned to the caller. #GST_FLOW_NOT_SUPPORTED is returned if @pad has no
3682  * chain function.
3683  *
3684  * In all cases, success or failure, the caller loses its reference to @buffer
3685  * after calling this function.
3686  *
3687  * Returns: a #GstFlowReturn from the pad.
3688  *
3689  * MT safe.
3690  */
3691 GstFlowReturn
3692 gst_pad_chain (GstPad * pad, GstBuffer * buffer)
3693 {
3694   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3695   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
3696   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
3697
3698   return gst_pad_chain_data_unchecked (pad,
3699       GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, buffer);
3700 }
3701
3702 static GstFlowReturn
3703 gst_pad_chain_list_default (GstPad * pad, GstObject * parent,
3704     GstBufferList * list)
3705 {
3706   guint i, len;
3707   GstBuffer *buffer;
3708   GstFlowReturn ret;
3709
3710   GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
3711
3712   len = gst_buffer_list_length (list);
3713
3714   ret = GST_FLOW_OK;
3715   for (i = 0; i < len; i++) {
3716     buffer = gst_buffer_list_get (list, i);
3717     ret =
3718         gst_pad_chain_data_unchecked (pad,
3719         GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH,
3720         gst_buffer_ref (buffer));
3721     if (ret != GST_FLOW_OK)
3722       break;
3723   }
3724   gst_buffer_list_unref (list);
3725
3726   return ret;
3727 }
3728
3729 /**
3730  * gst_pad_chain_list:
3731  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
3732  * @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
3733  *     if not.
3734  *
3735  * Chain a bufferlist to @pad.
3736  *
3737  * The function returns #GST_FLOW_FLUSHING if the pad was flushing.
3738  *
3739  * If @pad was not negotiated properly with a CAPS event, this function
3740  * returns #GST_FLOW_NOT_NEGOTIATED.
3741  *
3742  * The function proceeds calling the chainlist function installed on @pad (see
3743  * gst_pad_set_chain_list_function()) and the return value of that function is
3744  * returned to the caller. #GST_FLOW_NOT_SUPPORTED is returned if @pad has no
3745  * chainlist function.
3746  *
3747  * In all cases, success or failure, the caller loses its reference to @list
3748  * after calling this function.
3749  *
3750  * MT safe.
3751  *
3752  * Returns: a #GstFlowReturn from the pad.
3753  */
3754 GstFlowReturn
3755 gst_pad_chain_list (GstPad * pad, GstBufferList * list)
3756 {
3757   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3758   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
3759   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
3760
3761   return gst_pad_chain_data_unchecked (pad,
3762       GST_PAD_PROBE_TYPE_BUFFER_LIST | GST_PAD_PROBE_TYPE_PUSH, list);
3763 }
3764
3765 static GstFlowReturn
3766 gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
3767 {
3768   GstPad *peer;
3769   GstFlowReturn ret;
3770
3771   GST_OBJECT_LOCK (pad);
3772   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3773     goto flushing;
3774
3775   if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
3776     goto eos;
3777
3778   if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
3779     goto wrong_mode;
3780
3781   if (G_UNLIKELY ((ret = check_sticky (pad))) != GST_FLOW_OK)
3782     goto events_error;
3783
3784   /* do block probes */
3785   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_BLOCK, data, probe_stopped);
3786
3787   /* do post-blocking probes */
3788   PROBE_PUSH (pad, type, data, probe_stopped);
3789
3790   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
3791     goto not_linked;
3792
3793   /* take ref to peer pad before releasing the lock */
3794   gst_object_ref (peer);
3795   pad->priv->using++;
3796   GST_OBJECT_UNLOCK (pad);
3797
3798   ret = gst_pad_chain_data_unchecked (peer, type, data);
3799
3800   gst_object_unref (peer);
3801
3802   GST_OBJECT_LOCK (pad);
3803   pad->priv->using--;
3804   if (pad->priv->using == 0) {
3805     /* pad is not active anymore, trigger idle callbacks */
3806     PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE,
3807         probe_stopped, ret);
3808   }
3809   GST_OBJECT_UNLOCK (pad);
3810
3811   return ret;
3812
3813   /* ERROR recovery here */
3814   /* ERRORS */
3815 flushing:
3816   {
3817     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3818         "pushing, but pad was flushing");
3819     GST_OBJECT_UNLOCK (pad);
3820     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3821     return GST_FLOW_FLUSHING;
3822   }
3823 eos:
3824   {
3825     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but pad was EOS");
3826     GST_OBJECT_UNLOCK (pad);
3827     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3828     return GST_FLOW_EOS;
3829   }
3830 wrong_mode:
3831   {
3832     g_critical ("pushing on pad %s:%s but it was not activated in push mode",
3833         GST_DEBUG_PAD_NAME (pad));
3834     GST_OBJECT_UNLOCK (pad);
3835     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3836     return GST_FLOW_ERROR;
3837   }
3838 events_error:
3839   {
3840     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3841         "error pushing events, return %s", gst_flow_get_name (ret));
3842     GST_OBJECT_UNLOCK (pad);
3843     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3844     return ret;
3845   }
3846 probe_stopped:
3847   {
3848     GST_OBJECT_UNLOCK (pad);
3849     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3850
3851     switch (ret) {
3852       case GST_FLOW_CUSTOM_SUCCESS:
3853         GST_DEBUG_OBJECT (pad, "dropped buffer");
3854         ret = GST_FLOW_OK;
3855         break;
3856       default:
3857         GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
3858         break;
3859     }
3860     return ret;
3861   }
3862 not_linked:
3863   {
3864     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3865         "pushing, but it was not linked");
3866     GST_OBJECT_UNLOCK (pad);
3867     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3868     return GST_FLOW_NOT_LINKED;
3869   }
3870 }
3871
3872 /**
3873  * gst_pad_push:
3874  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
3875  * @buffer: (transfer full): the #GstBuffer to push returns GST_FLOW_ERROR
3876  *     if not.
3877  *
3878  * Pushes a buffer to the peer of @pad.
3879  *
3880  * This function will call installed block probes before triggering any
3881  * installed data probes.
3882  *
3883  * The function proceeds calling gst_pad_chain() on the peer pad and returns
3884  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
3885  * be returned.
3886  *
3887  * In all cases, success or failure, the caller loses its reference to @buffer
3888  * after calling this function.
3889  *
3890  * Returns: a #GstFlowReturn from the peer pad.
3891  *
3892  * MT safe.
3893  */
3894 GstFlowReturn
3895 gst_pad_push (GstPad * pad, GstBuffer * buffer)
3896 {
3897   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3898   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
3899   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
3900
3901   return gst_pad_push_data (pad,
3902       GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, buffer);
3903 }
3904
3905 /**
3906  * gst_pad_push_list:
3907  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
3908  * @list: (transfer full): the #GstBufferList to push returns GST_FLOW_ERROR
3909  *     if not.
3910  *
3911  * Pushes a buffer list to the peer of @pad.
3912  *
3913  * This function will call installed block probes before triggering any
3914  * installed data probes.
3915  *
3916  * The function proceeds calling the chain function on the peer pad and returns
3917  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
3918  * be returned. If the peer pad does not have any installed chainlist function
3919  * every group buffer of the list will be merged into a normal #GstBuffer and
3920  * chained via gst_pad_chain().
3921  *
3922  * In all cases, success or failure, the caller loses its reference to @list
3923  * after calling this function.
3924  *
3925  * Returns: a #GstFlowReturn from the peer pad.
3926  *
3927  * MT safe.
3928  */
3929 GstFlowReturn
3930 gst_pad_push_list (GstPad * pad, GstBufferList * list)
3931 {
3932   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3933   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
3934   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
3935
3936   return gst_pad_push_data (pad,
3937       GST_PAD_PROBE_TYPE_BUFFER_LIST | GST_PAD_PROBE_TYPE_PUSH, list);
3938 }
3939
3940 static GstFlowReturn
3941 gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
3942     GstBuffer ** buffer)
3943 {
3944   GstFlowReturn ret;
3945   GstPadGetRangeFunction getrangefunc;
3946   GstObject *parent;
3947   GstBuffer *res_buf;
3948
3949   GST_PAD_STREAM_LOCK (pad);
3950
3951   GST_OBJECT_LOCK (pad);
3952   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3953     goto flushing;
3954
3955   if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PULL))
3956     goto wrong_mode;
3957
3958   if (G_UNLIKELY ((ret = check_sticky (pad))) != GST_FLOW_OK)
3959     goto events_error;
3960
3961   res_buf = *buffer;
3962
3963   /* when one of the probes returns DROPPED, probe_stopped will be called
3964    * and we skip calling the getrange function, res_buf should then contain a
3965    * valid result buffer */
3966   PROBE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK,
3967       res_buf, offset, size, probe_stopped);
3968
3969   ACQUIRE_PARENT (pad, parent, no_parent);
3970   GST_OBJECT_UNLOCK (pad);
3971
3972   if (G_UNLIKELY ((getrangefunc = GST_PAD_GETRANGEFUNC (pad)) == NULL))
3973     goto no_function;
3974
3975   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3976       "calling getrangefunc %s, offset %"
3977       G_GUINT64_FORMAT ", size %u",
3978       GST_DEBUG_FUNCPTR_NAME (getrangefunc), offset, size);
3979
3980   ret = getrangefunc (pad, parent, offset, size, &res_buf);
3981
3982   RELEASE_PARENT (parent);
3983
3984   if (G_UNLIKELY (ret != GST_FLOW_OK))
3985     goto get_range_failed;
3986
3987   /* can only fire the signal if we have a valid buffer */
3988   GST_OBJECT_LOCK (pad);
3989 probed_data:
3990   PROBE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BUFFER,
3991       res_buf, offset, size, probe_stopped_unref);
3992   GST_OBJECT_UNLOCK (pad);
3993
3994   GST_PAD_STREAM_UNLOCK (pad);
3995
3996   *buffer = res_buf;
3997
3998   return ret;
3999
4000   /* ERRORS */
4001 flushing:
4002   {
4003     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
4004         "getrange, but pad was flushing");
4005     GST_OBJECT_UNLOCK (pad);
4006     GST_PAD_STREAM_UNLOCK (pad);
4007     return GST_FLOW_FLUSHING;
4008   }
4009 wrong_mode:
4010   {
4011     g_critical ("getrange on pad %s:%s but it was not activated in pull mode",
4012         GST_DEBUG_PAD_NAME (pad));
4013     GST_OBJECT_UNLOCK (pad);
4014     GST_PAD_STREAM_UNLOCK (pad);
4015     return GST_FLOW_ERROR;
4016   }
4017 events_error:
4018   {
4019     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "error pushing events");
4020     GST_OBJECT_UNLOCK (pad);
4021     GST_PAD_STREAM_UNLOCK (pad);
4022     return ret;
4023   }
4024 no_parent:
4025   {
4026     GST_DEBUG_OBJECT (pad, "no parent");
4027     GST_OBJECT_UNLOCK (pad);
4028     GST_PAD_STREAM_UNLOCK (pad);
4029     return GST_FLOW_FLUSHING;
4030   }
4031 no_function:
4032   {
4033     g_critical ("getrange on pad %s:%s but it has no getrangefunction",
4034         GST_DEBUG_PAD_NAME (pad));
4035     RELEASE_PARENT (parent);
4036     GST_PAD_STREAM_UNLOCK (pad);
4037     return GST_FLOW_NOT_SUPPORTED;
4038   }
4039 probe_stopped:
4040   {
4041     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
4042         "probe returned %s", gst_flow_get_name (ret));
4043     if (ret == GST_FLOW_CUSTOM_SUCCESS) {
4044       if (res_buf) {
4045         /* the probe filled the buffer and asks us to not call the getrange
4046          * anymore, we continue with the post probes then. */
4047         GST_DEBUG_OBJECT (pad, "handled buffer");
4048         ret = GST_FLOW_OK;
4049         goto probed_data;
4050       } else {
4051         /* no buffer, we are EOS */
4052         GST_DEBUG_OBJECT (pad, "no buffer, return EOS");
4053         ret = GST_FLOW_EOS;
4054       }
4055     }
4056     GST_OBJECT_UNLOCK (pad);
4057     GST_PAD_STREAM_UNLOCK (pad);
4058
4059     return ret;
4060   }
4061 probe_stopped_unref:
4062   {
4063     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
4064         "probe returned %s", gst_flow_get_name (ret));
4065     /* if we drop here, it signals EOS */
4066     if (ret == GST_FLOW_CUSTOM_SUCCESS)
4067       ret = GST_FLOW_EOS;
4068     GST_OBJECT_UNLOCK (pad);
4069     GST_PAD_STREAM_UNLOCK (pad);
4070     if (*buffer == NULL)
4071       gst_buffer_unref (res_buf);
4072     return ret;
4073   }
4074 get_range_failed:
4075   {
4076     GST_PAD_STREAM_UNLOCK (pad);
4077     GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
4078         (ret >= GST_FLOW_EOS) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
4079         pad, "getrange failed, flow: %s", gst_flow_get_name (ret));
4080     return ret;
4081   }
4082 }
4083
4084 /**
4085  * gst_pad_get_range:
4086  * @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
4087  * @offset: The start offset of the buffer
4088  * @size: The length of the buffer
4089  * @buffer: (out callee-allocates): a pointer to hold the #GstBuffer,
4090  *     returns #GST_FLOW_ERROR if %NULL.
4091  *
4092  * When @pad is flushing this function returns #GST_FLOW_FLUSHING
4093  * immediately and @buffer is %NULL.
4094  *
4095  * Calls the getrange function of @pad, see #GstPadGetRangeFunction for a
4096  * description of a getrange function. If @pad has no getrange function
4097  * installed (see gst_pad_set_getrange_function()) this function returns
4098  * #GST_FLOW_NOT_SUPPORTED.
4099  *
4100  * If @buffer points to a variable holding NULL, a valid new #GstBuffer will be
4101  * placed in @buffer when this function returns #GST_FLOW_OK. The new buffer
4102  * must be freed with gst_buffer_unref() after usage.
4103  *
4104  * When @buffer points to a variable that points to a valid #GstBuffer, the
4105  * buffer will be filled with the result data when this function returns
4106  * #GST_FLOW_OK. If the provided buffer is larger than @size, only
4107  * @size bytes will be filled in the result buffer and its size will be updated
4108  * accordingly.
4109  *
4110  * Note that less than @size bytes can be returned in @buffer when, for example,
4111  * an EOS condition is near or when @buffer is not large enough to hold @size
4112  * bytes. The caller should check the result buffer size to get the result size.
4113  *
4114  * When this function returns any other result value than #GST_FLOW_OK, @buffer
4115  * will be unchanged.
4116  *
4117  * This is a lowlevel function. Usualy gst_pad_pull_range() is used.
4118  *
4119  * Returns: a #GstFlowReturn from the pad.
4120  *
4121  * MT safe.
4122  */
4123 GstFlowReturn
4124 gst_pad_get_range (GstPad * pad, guint64 offset, guint size,
4125     GstBuffer ** buffer)
4126 {
4127   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
4128   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
4129   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
4130   g_return_val_if_fail (*buffer == NULL
4131       || GST_IS_BUFFER (*buffer), GST_FLOW_ERROR);
4132
4133   return gst_pad_get_range_unchecked (pad, offset, size, buffer);
4134 }
4135
4136 /**
4137  * gst_pad_pull_range:
4138  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
4139  * @offset: The start offset of the buffer
4140  * @size: The length of the buffer
4141  * @buffer: (out callee-allocates): a pointer to hold the #GstBuffer, returns
4142  *     GST_FLOW_ERROR if %NULL.
4143  *
4144  * Pulls a @buffer from the peer pad or fills up a provided buffer.
4145  *
4146  * This function will first trigger the pad block signal if it was
4147  * installed.
4148  *
4149  * When @pad is not linked #GST_FLOW_NOT_LINKED is returned else this
4150  * function returns the result of gst_pad_get_range() on the peer pad.
4151  * See gst_pad_get_range() for a list of return values and for the
4152  * semantics of the arguments of this function.
4153  *
4154  * If @buffer points to a variable holding NULL, a valid new #GstBuffer will be
4155  * placed in @buffer when this function returns #GST_FLOW_OK. The new buffer
4156  * must be freed with gst_buffer_unref() after usage. When this function
4157  * returns any other result value, @buffer will still point to NULL.
4158  *
4159  * When @buffer points to a variable that points to a valid #GstBuffer, the
4160  * buffer will be filled with the result data when this function returns
4161  * #GST_FLOW_OK. When this function returns any other result value,
4162  * @buffer will be unchanged. If the provided buffer is larger than @size, only
4163  * @size bytes will be filled in the result buffer and its size will be updated
4164  * accordingly.
4165  *
4166  * Note that less than @size bytes can be returned in @buffer when, for example,
4167  * an EOS condition is near or when @buffer is not large enough to hold @size
4168  * bytes. The caller should check the result buffer size to get the result size.
4169  *
4170  * Returns: a #GstFlowReturn from the peer pad.
4171  *
4172  * MT safe.
4173  */
4174 GstFlowReturn
4175 gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
4176     GstBuffer ** buffer)
4177 {
4178   GstPad *peer;
4179   GstFlowReturn ret;
4180   GstBuffer *res_buf;
4181
4182   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
4183   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
4184   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
4185   g_return_val_if_fail (*buffer == NULL
4186       || GST_IS_BUFFER (*buffer), GST_FLOW_ERROR);
4187
4188   GST_OBJECT_LOCK (pad);
4189   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4190     goto flushing;
4191
4192   if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PULL))
4193     goto wrong_mode;
4194
4195   res_buf = *buffer;
4196
4197   /* when one of the probes returns DROPPED, probe_stopped will be
4198    * called and we skip calling the peer getrange function. *buffer should then
4199    * contain a valid buffer */
4200   PROBE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK,
4201       res_buf, offset, size, probe_stopped);
4202
4203   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
4204     goto not_linked;
4205
4206   gst_object_ref (peer);
4207   pad->priv->using++;
4208   GST_OBJECT_UNLOCK (pad);
4209
4210   ret = gst_pad_get_range_unchecked (peer, offset, size, &res_buf);
4211
4212   gst_object_unref (peer);
4213
4214   GST_OBJECT_LOCK (pad);
4215   pad->priv->using--;
4216   if (pad->priv->using == 0) {
4217     /* pad is not active anymore, trigger idle callbacks */
4218     PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_IDLE,
4219         probe_stopped_unref, ret);
4220   }
4221
4222   if (G_UNLIKELY (ret != GST_FLOW_OK))
4223     goto pull_range_failed;
4224
4225 probed_data:
4226   PROBE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BUFFER,
4227       res_buf, offset, size, probe_stopped_unref);
4228
4229   GST_OBJECT_UNLOCK (pad);
4230
4231   *buffer = res_buf;
4232
4233   return ret;
4234
4235   /* ERROR recovery here */
4236 flushing:
4237   {
4238     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
4239         "pullrange, but pad was flushing");
4240     GST_OBJECT_UNLOCK (pad);
4241     return GST_FLOW_FLUSHING;
4242   }
4243 wrong_mode:
4244   {
4245     g_critical ("pullrange on pad %s:%s but it was not activated in pull mode",
4246         GST_DEBUG_PAD_NAME (pad));
4247     GST_OBJECT_UNLOCK (pad);
4248     return GST_FLOW_ERROR;
4249   }
4250 probe_stopped:
4251   {
4252     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pre probe returned %s",
4253         gst_flow_get_name (ret));
4254     if (ret == GST_FLOW_CUSTOM_SUCCESS) {
4255       if (res_buf) {
4256         /* the probe filled the buffer and asks us to not forward to the peer
4257          * anymore, we continue with the post probes then */
4258         GST_DEBUG_OBJECT (pad, "handled buffer");
4259         ret = GST_FLOW_OK;
4260         goto probed_data;
4261       } else {
4262         /* no buffer, we are EOS then */
4263         GST_DEBUG_OBJECT (pad, "no buffer, return EOS");
4264         ret = GST_FLOW_EOS;
4265       }
4266     }
4267     GST_OBJECT_UNLOCK (pad);
4268     return ret;
4269   }
4270 not_linked:
4271   {
4272     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
4273         "pulling range, but it was not linked");
4274     GST_OBJECT_UNLOCK (pad);
4275     return GST_FLOW_NOT_LINKED;
4276   }
4277 pull_range_failed:
4278   {
4279     GST_OBJECT_UNLOCK (pad);
4280     GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
4281         (ret >= GST_FLOW_EOS) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
4282         pad, "pullrange failed, flow: %s", gst_flow_get_name (ret));
4283     return ret;
4284   }
4285 probe_stopped_unref:
4286   {
4287     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
4288         "post probe returned %s", gst_flow_get_name (ret));
4289     GST_OBJECT_UNLOCK (pad);
4290     /* if we drop here, it signals EOS */
4291     if (ret == GST_FLOW_CUSTOM_SUCCESS)
4292       ret = GST_FLOW_EOS;
4293     if (*buffer == NULL)
4294       gst_buffer_unref (res_buf);
4295     return ret;
4296   }
4297 }
4298
4299 static gboolean
4300 gst_pad_store_sticky_event (GstPad * pad, GstEvent * event, gboolean locked)
4301 {
4302   guint i, len;
4303   GstEventType type;
4304   GArray *events;
4305   gboolean res = FALSE;
4306   const gchar *name = NULL;
4307
4308   type = GST_EVENT_TYPE (event);
4309   if (type & GST_EVENT_TYPE_STICKY_MULTI)
4310     name = gst_structure_get_name (gst_event_get_structure (event));
4311
4312   events = pad->priv->events;
4313   len = events->len;
4314
4315   for (i = 0; i < len; i++) {
4316     PadEvent *ev = &g_array_index (events, PadEvent, i);
4317
4318     if (ev->event == NULL)
4319       continue;
4320
4321     if (type == GST_EVENT_TYPE (ev->event)) {
4322       /* matching types, check matching name if needed */
4323       if (name && !gst_event_has_name (ev->event, name))
4324         continue;
4325
4326       /* overwrite */
4327       if ((res = gst_event_replace (&ev->event, event)))
4328         ev->received = FALSE;
4329       break;
4330     }
4331   }
4332   if (i == len) {
4333     PadEvent ev;
4334     ev.event = gst_event_ref (event);
4335     ev.received = FALSE;
4336     g_array_append_val (events, ev);
4337     res = TRUE;
4338   }
4339
4340   if (res) {
4341     pad->priv->events_cookie++;
4342     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
4343
4344     GST_LOG_OBJECT (pad, "stored sticky event %s", GST_EVENT_TYPE_NAME (event));
4345
4346     switch (GST_EVENT_TYPE (event)) {
4347       case GST_EVENT_CAPS:
4348         if (locked)
4349           GST_OBJECT_UNLOCK (pad);
4350
4351         GST_DEBUG_OBJECT (pad, "notify caps");
4352         g_object_notify_by_pspec ((GObject *) pad, pspec_caps);
4353
4354         if (locked)
4355           GST_OBJECT_LOCK (pad);
4356         break;
4357       default:
4358         break;
4359     }
4360   }
4361   return res;
4362 }
4363
4364 /* should be called with pad LOCK */
4365 static GstFlowReturn
4366 gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
4367     GstPadProbeType type)
4368 {
4369   GstFlowReturn ret;
4370   GstPad *peerpad;
4371   GstEventType event_type;
4372
4373   /* Two checks to be made:
4374    * . (un)set the FLUSHING flag for flushing events,
4375    * . handle pad blocking */
4376   event_type = GST_EVENT_TYPE (event);
4377   switch (event_type) {
4378     case GST_EVENT_FLUSH_START:
4379       GST_PAD_SET_FLUSHING (pad);
4380
4381       GST_PAD_BLOCK_BROADCAST (pad);
4382       type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
4383       break;
4384     case GST_EVENT_FLUSH_STOP:
4385       GST_PAD_UNSET_FLUSHING (pad);
4386
4387       /* Remove sticky EOS events */
4388       GST_LOG_OBJECT (pad, "Removing pending EOS events");
4389       remove_event_by_type (pad, GST_EVENT_EOS);
4390       GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
4391
4392       type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
4393       break;
4394     default:
4395     {
4396       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4397         goto flushed;
4398
4399       /* No need to check for EOS here as either the caller (gst_pad_push_event())
4400        * checked already or this is called as part of pushing sticky events,
4401        * in which case we still want to forward the EOS event downstream.
4402        */
4403
4404       switch (GST_EVENT_TYPE (event)) {
4405         case GST_EVENT_SEGMENT:
4406           /* pass the adjusted segment event on. We need to do this even if
4407            * there is no peer pad because of the probes. */
4408           event = apply_pad_offset (pad, event);
4409           break;
4410         case GST_EVENT_RECONFIGURE:
4411           if (GST_PAD_IS_SINK (pad))
4412             GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
4413           break;
4414         default:
4415           break;
4416       }
4417       PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH |
4418           GST_PAD_PROBE_TYPE_BLOCK, event, probe_stopped);
4419       break;
4420     }
4421   }
4422
4423   /* send probes after modifying the events above */
4424   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, event, probe_stopped);
4425
4426   /* now check the peer pad */
4427   peerpad = GST_PAD_PEER (pad);
4428   if (peerpad == NULL)
4429     goto not_linked;
4430
4431   gst_object_ref (peerpad);
4432   pad->priv->using++;
4433   GST_OBJECT_UNLOCK (pad);
4434
4435   GST_LOG_OBJECT (pad, "sending event %p (%s) to peerpad %" GST_PTR_FORMAT,
4436       event, GST_EVENT_TYPE_NAME (event), peerpad);
4437
4438   ret = gst_pad_send_event_unchecked (peerpad, event, type);
4439
4440   /* Note: we gave away ownership of the event at this point but we can still
4441    * print the old pointer */
4442   GST_LOG_OBJECT (pad,
4443       "sent event %p to peerpad %" GST_PTR_FORMAT ", ret %s", event, peerpad,
4444       gst_flow_get_name (ret));
4445
4446   gst_object_unref (peerpad);
4447
4448   GST_OBJECT_LOCK (pad);
4449   pad->priv->using--;
4450   if (pad->priv->using == 0) {
4451     /* pad is not active anymore, trigger idle callbacks */
4452     PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE,
4453         idle_probe_stopped, ret);
4454   }
4455   return ret;
4456
4457   /* ERROR handling */
4458 flushed:
4459   {
4460     GST_DEBUG_OBJECT (pad, "We're flushing");
4461     gst_event_unref (event);
4462     return GST_FLOW_FLUSHING;
4463   }
4464 probe_stopped:
4465   {
4466     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
4467     gst_event_unref (event);
4468
4469     switch (ret) {
4470       case GST_FLOW_CUSTOM_SUCCESS:
4471         GST_DEBUG_OBJECT (pad, "dropped event");
4472         ret = GST_FLOW_OK;
4473         break;
4474       default:
4475         GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
4476         break;
4477     }
4478     return ret;
4479   }
4480 not_linked:
4481   {
4482     GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
4483     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
4484     gst_event_unref (event);
4485
4486     /* unlinked pads should not influence latency configuration */
4487     if (event_type == GST_EVENT_LATENCY)
4488       return GST_FLOW_OK;
4489
4490     return GST_FLOW_NOT_LINKED;
4491   }
4492 idle_probe_stopped:
4493   {
4494     GST_DEBUG_OBJECT (pad, "Idle probe returned %s", gst_flow_get_name (ret));
4495     return ret;
4496   }
4497 }
4498
4499 /**
4500  * gst_pad_push_event:
4501  * @pad: a #GstPad to push the event to.
4502  * @event: (transfer full): the #GstEvent to send to the pad.
4503  *
4504  * Sends the event to the peer of the given pad. This function is
4505  * mainly used by elements to send events to their peer
4506  * elements.
4507  *
4508  * This function takes owership of the provided event so you should
4509  * gst_event_ref() it if you want to reuse the event after this call.
4510  *
4511  * Returns: TRUE if the event was handled.
4512  *
4513  * MT safe.
4514  */
4515 gboolean
4516 gst_pad_push_event (GstPad * pad, GstEvent * event)
4517 {
4518   gboolean res = FALSE;
4519   GstPadProbeType type;
4520   gboolean sticky, serialized;
4521
4522   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4523   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
4524
4525   if (GST_PAD_IS_SRC (pad)) {
4526     if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event)))
4527       goto wrong_direction;
4528     type = GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM;
4529   } else if (GST_PAD_IS_SINK (pad)) {
4530     if (G_UNLIKELY (!GST_EVENT_IS_UPSTREAM (event)))
4531       goto wrong_direction;
4532     /* events pushed on sinkpad never are sticky */
4533     type = GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;
4534   } else
4535     goto unknown_direction;
4536
4537   GST_OBJECT_LOCK (pad);
4538   sticky = GST_EVENT_IS_STICKY (event);
4539   serialized = GST_EVENT_IS_SERIALIZED (event);
4540
4541   if (sticky) {
4542     /* can't store on flushing pads */
4543     if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4544       goto flushed;
4545
4546     if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
4547       goto eos;
4548
4549     /* srcpad sticky events are store immediately, the received flag is set
4550      * to FALSE and will be set to TRUE when we can successfully push the
4551      * event to the peer pad */
4552     if (gst_pad_store_sticky_event (pad, event, TRUE)) {
4553       GST_DEBUG_OBJECT (pad, "event %s updated", GST_EVENT_TYPE_NAME (event));
4554     }
4555     if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
4556       GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
4557   }
4558   if (GST_PAD_IS_SRC (pad) && (serialized || sticky)) {
4559     /* all serialized or sticky events on the srcpad trigger push of
4560      * sticky events */
4561     res = (check_sticky (pad) == GST_FLOW_OK);
4562   }
4563   if (!sticky) {
4564     /* other events are pushed right away */
4565     res = (gst_pad_push_event_unchecked (pad, event, type) == GST_FLOW_OK);
4566   } else {
4567     /* Errors in sticky event pushing are no problem and ignored here
4568      * as they will cause more meaningful errors during data flow.
4569      * For EOS events, that are not followed by data flow, we still
4570      * return FALSE here though.
4571      */
4572     if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
4573       res = TRUE;
4574     gst_event_unref (event);
4575   }
4576   GST_OBJECT_UNLOCK (pad);
4577
4578   return res;
4579
4580   /* ERROR handling */
4581 wrong_direction:
4582   {
4583     g_warning ("pad %s:%s pushing %s event in wrong direction",
4584         GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
4585     gst_event_unref (event);
4586     return FALSE;
4587   }
4588 unknown_direction:
4589   {
4590     g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
4591     gst_event_unref (event);
4592     return FALSE;
4593   }
4594 flushed:
4595   {
4596     GST_DEBUG_OBJECT (pad, "We're flushing");
4597     GST_OBJECT_UNLOCK (pad);
4598     gst_event_unref (event);
4599     return FALSE;
4600   }
4601 eos:
4602   {
4603     GST_DEBUG_OBJECT (pad, "We're EOS");
4604     GST_OBJECT_UNLOCK (pad);
4605     gst_event_unref (event);
4606     return FALSE;
4607   }
4608 }
4609
4610 /* Check if we can call the event function with the given event */
4611 static GstFlowReturn
4612 pre_eventfunc_check (GstPad * pad, GstEvent * event)
4613 {
4614   GstCaps *caps;
4615
4616   switch (GST_EVENT_TYPE (event)) {
4617     case GST_EVENT_CAPS:
4618     {
4619       /* backwards compatibility mode for caps */
4620       gst_event_parse_caps (event, &caps);
4621
4622       if (!gst_pad_query_accept_caps (pad, caps))
4623         goto not_accepted;
4624       break;
4625     }
4626     default:
4627       break;
4628   }
4629   return GST_FLOW_OK;
4630
4631   /* ERRORS */
4632 not_accepted:
4633   {
4634     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
4635         "caps %" GST_PTR_FORMAT " not accepted", caps);
4636     return GST_FLOW_NOT_NEGOTIATED;
4637   }
4638 }
4639
4640 static GstFlowReturn
4641 gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
4642     GstPadProbeType type)
4643 {
4644   GstFlowReturn ret;
4645   GstEventType event_type;
4646   gboolean serialized, need_unlock = FALSE, sticky;
4647   GstPadEventFunction eventfunc;
4648   GstObject *parent;
4649
4650   GST_OBJECT_LOCK (pad);
4651   if (GST_PAD_IS_SINK (pad))
4652     serialized = GST_EVENT_IS_SERIALIZED (event);
4653   else
4654     serialized = FALSE;
4655   sticky = GST_EVENT_IS_STICKY (event);
4656   event_type = GST_EVENT_TYPE (event);
4657   switch (event_type) {
4658     case GST_EVENT_FLUSH_START:
4659       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad,
4660           "have event type %d (FLUSH_START)", GST_EVENT_TYPE (event));
4661
4662       /* can't even accept a flush begin event when flushing */
4663       if (GST_PAD_IS_FLUSHING (pad))
4664         goto flushing;
4665
4666       GST_PAD_SET_FLUSHING (pad);
4667       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "set flush flag");
4668       break;
4669     case GST_EVENT_FLUSH_STOP:
4670       if (G_LIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_NONE)) {
4671         GST_PAD_UNSET_FLUSHING (pad);
4672         GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "cleared flush flag");
4673       }
4674       /* Remove pending EOS events */
4675       GST_LOG_OBJECT (pad, "Removing pending EOS events");
4676       remove_event_by_type (pad, GST_EVENT_EOS);
4677       GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
4678
4679       GST_OBJECT_UNLOCK (pad);
4680       /* grab stream lock */
4681       GST_PAD_STREAM_LOCK (pad);
4682       need_unlock = TRUE;
4683       GST_OBJECT_LOCK (pad);
4684       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4685         goto flushing;
4686       break;
4687     case GST_EVENT_RECONFIGURE:
4688       if (GST_PAD_IS_SRC (pad))
4689         GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
4690     default:
4691       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad,
4692           "have event type %" GST_PTR_FORMAT, event);
4693
4694       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4695         goto flushing;
4696
4697       if (serialized) {
4698         if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
4699           goto eos;
4700
4701         /* lock order: STREAM_LOCK, LOCK, recheck flushing. */
4702         GST_OBJECT_UNLOCK (pad);
4703         GST_PAD_STREAM_LOCK (pad);
4704         need_unlock = TRUE;
4705         GST_OBJECT_LOCK (pad);
4706         if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4707           goto flushing;
4708
4709         if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
4710           goto eos;
4711       }
4712
4713       switch (GST_EVENT_TYPE (event)) {
4714         case GST_EVENT_SEGMENT:
4715           event = apply_pad_offset (pad, event);
4716           break;
4717         default:
4718           break;
4719       }
4720
4721       /* now do the probe */
4722       PROBE_PUSH (pad,
4723           type | GST_PAD_PROBE_TYPE_PUSH |
4724           GST_PAD_PROBE_TYPE_BLOCK, event, probe_stopped);
4725
4726       PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, event, probe_stopped);
4727       break;
4728   }
4729
4730   if (G_UNLIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
4731     goto no_function;
4732
4733   ACQUIRE_PARENT (pad, parent, no_parent);
4734   GST_OBJECT_UNLOCK (pad);
4735
4736   ret = pre_eventfunc_check (pad, event);
4737   if (G_UNLIKELY (ret != GST_FLOW_OK))
4738     goto precheck_failed;
4739
4740   if (sticky)
4741     gst_event_ref (event);
4742
4743   if (eventfunc (pad, parent, event)) {
4744     ret = GST_FLOW_OK;
4745   } else {
4746     /* something went wrong */
4747     switch (event_type) {
4748       case GST_EVENT_CAPS:
4749         ret = GST_FLOW_NOT_NEGOTIATED;
4750         break;
4751       default:
4752         ret = GST_FLOW_ERROR;
4753         break;
4754     }
4755   }
4756   RELEASE_PARENT (parent);
4757
4758   GST_DEBUG_OBJECT (pad, "sent event, ret %s", gst_flow_get_name (ret));
4759
4760   if (sticky) {
4761     if (ret == GST_FLOW_OK) {
4762       /* after the event function accepted the event, we can store the sticky
4763        * event on the pad */
4764       gst_pad_store_sticky_event (pad, event, FALSE);
4765       if (event_type == GST_EVENT_EOS)
4766         GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
4767     }
4768     gst_event_unref (event);
4769   }
4770
4771   if (need_unlock)
4772     GST_PAD_STREAM_UNLOCK (pad);
4773
4774   return ret;
4775
4776   /* ERROR handling */
4777 flushing:
4778   {
4779     GST_OBJECT_UNLOCK (pad);
4780     if (need_unlock)
4781       GST_PAD_STREAM_UNLOCK (pad);
4782     GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad,
4783         "Received event on flushing pad. Discarding");
4784     gst_event_unref (event);
4785     return GST_FLOW_FLUSHING;
4786   }
4787 eos:
4788   {
4789     GST_OBJECT_UNLOCK (pad);
4790     if (need_unlock)
4791       GST_PAD_STREAM_UNLOCK (pad);
4792     GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad,
4793         "Received event on EOS pad. Discarding");
4794     gst_event_unref (event);
4795     return GST_FLOW_EOS;
4796   }
4797 probe_stopped:
4798   {
4799     GST_OBJECT_UNLOCK (pad);
4800     if (need_unlock)
4801       GST_PAD_STREAM_UNLOCK (pad);
4802     gst_event_unref (event);
4803
4804     switch (ret) {
4805       case GST_FLOW_CUSTOM_SUCCESS:
4806         GST_DEBUG_OBJECT (pad, "dropped event");
4807         ret = GST_FLOW_OK;
4808         break;
4809       default:
4810         GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
4811         break;
4812     }
4813     return ret;
4814   }
4815 no_function:
4816   {
4817     g_warning ("pad %s:%s has no event handler, file a bug.",
4818         GST_DEBUG_PAD_NAME (pad));
4819     GST_OBJECT_UNLOCK (pad);
4820     if (need_unlock)
4821       GST_PAD_STREAM_UNLOCK (pad);
4822     gst_event_unref (event);
4823     return GST_FLOW_NOT_SUPPORTED;
4824   }
4825 no_parent:
4826   {
4827     GST_DEBUG_OBJECT (pad, "no parent");
4828     GST_OBJECT_UNLOCK (pad);
4829     if (need_unlock)
4830       GST_PAD_STREAM_UNLOCK (pad);
4831     gst_event_unref (event);
4832     return GST_FLOW_FLUSHING;
4833   }
4834 precheck_failed:
4835   {
4836     GST_DEBUG_OBJECT (pad, "pre event check failed");
4837     RELEASE_PARENT (parent);
4838     if (need_unlock)
4839       GST_PAD_STREAM_UNLOCK (pad);
4840     gst_event_unref (event);
4841     return ret;
4842   }
4843 }
4844
4845 /**
4846  * gst_pad_send_event:
4847  * @pad: a #GstPad to send the event to.
4848  * @event: (transfer full): the #GstEvent to send to the pad.
4849  *
4850  * Sends the event to the pad. This function can be used
4851  * by applications to send events in the pipeline.
4852  *
4853  * If @pad is a source pad, @event should be an upstream event. If @pad is a
4854  * sink pad, @event should be a downstream event. For example, you would not
4855  * send a #GST_EVENT_EOS on a src pad; EOS events only propagate downstream.
4856  * Furthermore, some downstream events have to be serialized with data flow,
4857  * like EOS, while some can travel out-of-band, like #GST_EVENT_FLUSH_START. If
4858  * the event needs to be serialized with data flow, this function will take the
4859  * pad's stream lock while calling its event function.
4860  *
4861  * To find out whether an event type is upstream, downstream, or downstream and
4862  * serialized, see #GstEventTypeFlags, gst_event_type_get_flags(),
4863  * #GST_EVENT_IS_UPSTREAM, #GST_EVENT_IS_DOWNSTREAM, and
4864  * #GST_EVENT_IS_SERIALIZED. Note that in practice that an application or
4865  * plugin doesn't need to bother itself with this information; the core handles
4866  * all necessary locks and checks.
4867  *
4868  * This function takes owership of the provided event so you should
4869  * gst_event_ref() it if you want to reuse the event after this call.
4870  *
4871  * Returns: TRUE if the event was handled.
4872  */
4873 gboolean
4874 gst_pad_send_event (GstPad * pad, GstEvent * event)
4875 {
4876   gboolean result;
4877   GstPadProbeType type;
4878
4879   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4880   g_return_val_if_fail (event != NULL, FALSE);
4881
4882   if (GST_PAD_IS_SINK (pad)) {
4883     if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event)))
4884       goto wrong_direction;
4885     type = GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM;
4886   } else if (GST_PAD_IS_SRC (pad)) {
4887     if (G_UNLIKELY (!GST_EVENT_IS_UPSTREAM (event)))
4888       goto wrong_direction;
4889     type = GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;
4890   } else
4891     goto unknown_direction;
4892
4893   if (gst_pad_send_event_unchecked (pad, event, type) != GST_FLOW_OK)
4894     result = FALSE;
4895   else
4896     result = TRUE;
4897
4898   return result;
4899
4900   /* ERROR handling */
4901 wrong_direction:
4902   {
4903     g_warning ("pad %s:%s sending %s event in wrong direction",
4904         GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
4905     gst_event_unref (event);
4906     return FALSE;
4907   }
4908 unknown_direction:
4909   {
4910     g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
4911     gst_event_unref (event);
4912     return FALSE;
4913   }
4914 }
4915
4916 /**
4917  * gst_pad_set_element_private:
4918  * @pad: the #GstPad to set the private data of.
4919  * @priv: The private data to attach to the pad.
4920  *
4921  * Set the given private data gpointer on the pad.
4922  * This function can only be used by the element that owns the pad.
4923  * No locking is performed in this function.
4924  */
4925 void
4926 gst_pad_set_element_private (GstPad * pad, gpointer priv)
4927 {
4928   pad->element_private = priv;
4929 }
4930
4931 /**
4932  * gst_pad_get_element_private:
4933  * @pad: the #GstPad to get the private data of.
4934  *
4935  * Gets the private data of a pad.
4936  * No locking is performed in this function.
4937  *
4938  * Returns: (transfer none): a #gpointer to the private data.
4939  */
4940 gpointer
4941 gst_pad_get_element_private (GstPad * pad)
4942 {
4943   return pad->element_private;
4944 }
4945
4946 /**
4947  * gst_pad_get_sticky_event:
4948  * @pad: the #GstPad to get the event from.
4949  * @event_type: the #GstEventType that should be retrieved.
4950  * @idx: the index of the event
4951  *
4952  * Returns a new reference of the sticky event of type @event_type
4953  * from the event.
4954  *
4955  * Returns: (transfer full): a #GstEvent of type @event_type or NULL when no
4956  * event of @event_type was on @pad. Unref after usage.
4957  */
4958 GstEvent *
4959 gst_pad_get_sticky_event (GstPad * pad, GstEventType event_type, guint idx)
4960 {
4961   GstEvent *event = NULL;
4962   PadEvent *ev;
4963
4964   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
4965   g_return_val_if_fail ((event_type & GST_EVENT_TYPE_STICKY) != 0, NULL);
4966
4967   GST_OBJECT_LOCK (pad);
4968   ev = find_event_by_type (pad, event_type, idx);
4969   if (ev && (event = ev->event))
4970     gst_event_ref (event);
4971   GST_OBJECT_UNLOCK (pad);
4972
4973   return event;
4974 }
4975
4976 typedef struct
4977 {
4978   GstPadStickyEventsForeachFunction func;
4979   gpointer user_data;
4980 } ForeachDispatch;
4981
4982 static gboolean
4983 foreach_dispatch_function (GstPad * pad, PadEvent * ev, gpointer user_data)
4984 {
4985   ForeachDispatch *data = user_data;
4986   gboolean ret;
4987
4988   GST_OBJECT_UNLOCK (pad);
4989
4990   ret = data->func (pad, &ev->event, data->user_data);
4991
4992   GST_OBJECT_LOCK (pad);
4993
4994   return ret;
4995 }
4996
4997 /**
4998  * gst_pad_sticky_events_foreach:
4999  * @pad: the #GstPad that should be used for iteration.
5000  * @foreach_func: (scope call): the #GstPadStickyEventsForeachFunction that
5001  *                should be called for every event.
5002  * @user_data: (closure): the optional user data.
5003  *
5004  * Iterates all sticky events on @pad and calls @foreach_func for every
5005  * event. If @foreach_func returns %FALSE the iteration is immediately stopped.
5006  */
5007 void
5008 gst_pad_sticky_events_foreach (GstPad * pad,
5009     GstPadStickyEventsForeachFunction foreach_func, gpointer user_data)
5010 {
5011   ForeachDispatch data;
5012
5013   g_return_if_fail (GST_IS_PAD (pad));
5014   g_return_if_fail (foreach_func != NULL);
5015
5016   data.func = foreach_func;
5017   data.user_data = user_data;
5018
5019   GST_OBJECT_LOCK (pad);
5020   events_foreach (pad, foreach_dispatch_function, &data);
5021   GST_OBJECT_UNLOCK (pad);
5022 }
5023
5024 static void
5025 do_stream_status (GstPad * pad, GstStreamStatusType type,
5026     GThread * thread, GstTask * task)
5027 {
5028   GstElement *parent;
5029
5030   GST_DEBUG_OBJECT (pad, "doing stream-status %d", type);
5031
5032   if ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (pad)))) {
5033     if (GST_IS_ELEMENT (parent)) {
5034       GstMessage *message;
5035       GValue value = { 0 };
5036
5037       if (type == GST_STREAM_STATUS_TYPE_ENTER) {
5038         gchar *tname, *ename, *pname;
5039
5040         /* create a good task name */
5041         ename = gst_element_get_name (parent);
5042         pname = gst_pad_get_name (pad);
5043         tname = g_strdup_printf ("%s:%s", ename, pname);
5044         g_free (ename);
5045         g_free (pname);
5046
5047         gst_object_set_name (GST_OBJECT_CAST (task), tname);
5048         g_free (tname);
5049       }
5050
5051       message = gst_message_new_stream_status (GST_OBJECT_CAST (pad),
5052           type, parent);
5053
5054       g_value_init (&value, GST_TYPE_TASK);
5055       g_value_set_object (&value, task);
5056       gst_message_set_stream_status_object (message, &value);
5057       g_value_unset (&value);
5058
5059       GST_DEBUG_OBJECT (pad, "posting stream-status %d", type);
5060       gst_element_post_message (parent, message);
5061     }
5062     gst_object_unref (parent);
5063   }
5064 }
5065
5066 static void
5067 pad_enter_thread (GstTask * task, GThread * thread, gpointer user_data)
5068 {
5069   do_stream_status (GST_PAD_CAST (user_data), GST_STREAM_STATUS_TYPE_ENTER,
5070       thread, task);
5071 }
5072
5073 static void
5074 pad_leave_thread (GstTask * task, GThread * thread, gpointer user_data)
5075 {
5076   do_stream_status (GST_PAD_CAST (user_data), GST_STREAM_STATUS_TYPE_LEAVE,
5077       thread, task);
5078 }
5079
5080 /**
5081  * gst_pad_start_task:
5082  * @pad: the #GstPad to start the task of
5083  * @func: the task function to call
5084  * @user_data: user data passed to the task function
5085  * @notify: called when @user_data is no longer referenced
5086  *
5087  * Starts a task that repeatedly calls @func with @user_data. This function
5088  * is mostly used in pad activation functions to start the dataflow.
5089  * The #GST_PAD_STREAM_LOCK of @pad will automatically be acquired
5090  * before @func is called.
5091  *
5092  * Returns: a %TRUE if the task could be started.
5093  */
5094 gboolean
5095 gst_pad_start_task (GstPad * pad, GstTaskFunction func, gpointer user_data,
5096     GDestroyNotify notify)
5097 {
5098   GstTask *task;
5099   gboolean res;
5100
5101   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
5102   g_return_val_if_fail (func != NULL, FALSE);
5103
5104   GST_DEBUG_OBJECT (pad, "start task");
5105
5106   GST_OBJECT_LOCK (pad);
5107   task = GST_PAD_TASK (pad);
5108   if (task == NULL) {
5109     task = gst_task_new (func, user_data, notify);
5110     gst_task_set_lock (task, GST_PAD_GET_STREAM_LOCK (pad));
5111     gst_task_set_enter_callback (task, pad_enter_thread, pad, NULL);
5112     gst_task_set_leave_callback (task, pad_leave_thread, pad, NULL);
5113     GST_INFO_OBJECT (pad, "created task %p", task);
5114     GST_PAD_TASK (pad) = task;
5115     gst_object_ref (task);
5116     /* release lock to post the message */
5117     GST_OBJECT_UNLOCK (pad);
5118
5119     do_stream_status (pad, GST_STREAM_STATUS_TYPE_CREATE, NULL, task);
5120
5121     gst_object_unref (task);
5122
5123     GST_OBJECT_LOCK (pad);
5124     /* nobody else is supposed to have changed the pad now */
5125     if (GST_PAD_TASK (pad) != task)
5126       goto concurrent_stop;
5127   }
5128   res = gst_task_set_state (task, GST_TASK_STARTED);
5129   GST_OBJECT_UNLOCK (pad);
5130
5131   return res;
5132
5133   /* ERRORS */
5134 concurrent_stop:
5135   {
5136     GST_OBJECT_UNLOCK (pad);
5137     return TRUE;
5138   }
5139 }
5140
5141 /**
5142  * gst_pad_pause_task:
5143  * @pad: the #GstPad to pause the task of
5144  *
5145  * Pause the task of @pad. This function will also wait until the
5146  * function executed by the task is finished if this function is not
5147  * called from the task function.
5148  *
5149  * Returns: a TRUE if the task could be paused or FALSE when the pad
5150  * has no task.
5151  */
5152 gboolean
5153 gst_pad_pause_task (GstPad * pad)
5154 {
5155   GstTask *task;
5156   gboolean res;
5157
5158   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
5159
5160   GST_DEBUG_OBJECT (pad, "pause task");
5161
5162   GST_OBJECT_LOCK (pad);
5163   task = GST_PAD_TASK (pad);
5164   if (task == NULL)
5165     goto no_task;
5166   res = gst_task_set_state (task, GST_TASK_PAUSED);
5167   GST_OBJECT_UNLOCK (pad);
5168
5169   /* wait for task function to finish, this lock is recursive so it does nothing
5170    * when the pause is called from the task itself */
5171   GST_PAD_STREAM_LOCK (pad);
5172   GST_PAD_STREAM_UNLOCK (pad);
5173
5174   return res;
5175
5176 no_task:
5177   {
5178     GST_DEBUG_OBJECT (pad, "pad has no task");
5179     GST_OBJECT_UNLOCK (pad);
5180     return FALSE;
5181   }
5182 }
5183
5184 /**
5185  * gst_pad_stop_task:
5186  * @pad: the #GstPad to stop the task of
5187  *
5188  * Stop the task of @pad. This function will also make sure that the
5189  * function executed by the task will effectively stop if not called
5190  * from the GstTaskFunction.
5191  *
5192  * This function will deadlock if called from the GstTaskFunction of
5193  * the task. Use gst_task_pause() instead.
5194  *
5195  * Regardless of whether the pad has a task, the stream lock is acquired and
5196  * released so as to ensure that streaming through this pad has finished.
5197  *
5198  * Returns: a TRUE if the task could be stopped or FALSE on error.
5199  */
5200 gboolean
5201 gst_pad_stop_task (GstPad * pad)
5202 {
5203   GstTask *task;
5204   gboolean res;
5205
5206   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
5207
5208   GST_DEBUG_OBJECT (pad, "stop task");
5209
5210   GST_OBJECT_LOCK (pad);
5211   task = GST_PAD_TASK (pad);
5212   if (task == NULL)
5213     goto no_task;
5214   GST_PAD_TASK (pad) = NULL;
5215   res = gst_task_set_state (task, GST_TASK_STOPPED);
5216   GST_OBJECT_UNLOCK (pad);
5217
5218   GST_PAD_STREAM_LOCK (pad);
5219   GST_PAD_STREAM_UNLOCK (pad);
5220
5221   if (!gst_task_join (task))
5222     goto join_failed;
5223
5224   gst_object_unref (task);
5225
5226   return res;
5227
5228 no_task:
5229   {
5230     GST_DEBUG_OBJECT (pad, "no task");
5231     GST_OBJECT_UNLOCK (pad);
5232
5233     GST_PAD_STREAM_LOCK (pad);
5234     GST_PAD_STREAM_UNLOCK (pad);
5235
5236     /* this is not an error */
5237     return TRUE;
5238   }
5239 join_failed:
5240   {
5241     /* this is bad, possibly the application tried to join the task from
5242      * the task's thread. We install the task again so that it will be stopped
5243      * again from the right thread next time hopefully. */
5244     GST_OBJECT_LOCK (pad);
5245     GST_DEBUG_OBJECT (pad, "join failed");
5246     /* we can only install this task if there was no other task */
5247     if (GST_PAD_TASK (pad) == NULL)
5248       GST_PAD_TASK (pad) = task;
5249     GST_OBJECT_UNLOCK (pad);
5250
5251     return FALSE;
5252   }
5253 }