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