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