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