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