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