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