Merge branch 'master' into 0.11
[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 (intpad == NULL || 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   /* only probes that have GST_PAD_PROBE_TYPE_EVENT_FLUSH set */
2822   if ((type & GST_PAD_PROBE_TYPE_EVENT_FLUSH) &&
2823       (flags & GST_PAD_PROBE_TYPE_EVENT_FLUSH & type) == 0)
2824     goto no_match;
2825
2826   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2827       "hook %lu with flags 0x%08x matches", hook->hook_id, flags);
2828
2829   callback = (GstPadProbeCallback) hook->func;
2830   if (callback == NULL)
2831     return;
2832
2833   GST_OBJECT_UNLOCK (pad);
2834
2835   ret = callback (pad, info, hook->data);
2836
2837   GST_OBJECT_LOCK (pad);
2838   data->marshalled = TRUE;
2839
2840   switch (ret) {
2841     case GST_PAD_PROBE_REMOVE:
2842       /* remove the probe */
2843       GST_DEBUG_OBJECT (pad, "asked to remove hook");
2844       cleanup_hook (pad, hook);
2845       break;
2846     case GST_PAD_PROBE_DROP:
2847       /* need to drop the data, make sure other probes don't get called
2848        * anymore */
2849       GST_DEBUG_OBJECT (pad, "asked to drop item");
2850       info->type = GST_PAD_PROBE_TYPE_INVALID;
2851       data->dropped = TRUE;
2852       break;
2853     case GST_PAD_PROBE_PASS:
2854       /* inform the pad block to let things pass */
2855       GST_DEBUG_OBJECT (pad, "asked to pass item");
2856       data->pass = TRUE;
2857       break;
2858     default:
2859       GST_DEBUG_OBJECT (pad, "probe returned %d", ret);
2860       break;
2861   }
2862   return;
2863
2864 no_match:
2865   {
2866     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2867         "hook %lu with flags 0x%08x does not match %08x", hook->hook_id,
2868         flags, info->type);
2869     return;
2870   }
2871 }
2872
2873 #define PROBE_PRE_PULL(pad,mask,data,offs,size,label,probed,defaultval)    \
2874   G_STMT_START {                                                \
2875     if (G_UNLIKELY (pad->num_probes)) {                         \
2876       /* we start with passing NULL as the data item */         \
2877       GstPadProbeInfo info = { mask, NULL, offs, size };        \
2878       ret = do_probe_callbacks (pad, &info, defaultval);        \
2879       /* store the possibly updated data item */                \
2880       data = GST_PAD_PROBE_INFO_DATA (&info);                   \
2881       /* if something went wrong, exit */                       \
2882       if (G_UNLIKELY (ret != defaultval && ret != GST_FLOW_OK)) \
2883         goto label;                                             \
2884       /* otherwise check if the probe retured data */           \
2885       if (G_UNLIKELY (data != NULL))                            \
2886         goto probed;                                            \
2887     }                                                           \
2888   } G_STMT_END
2889
2890
2891 /* a probe that does not take or return any data */
2892 #define PROBE_NO_DATA(pad,mask,label,defaultval)                \
2893   G_STMT_START {                                                \
2894     if (G_UNLIKELY (pad->num_probes)) {                         \
2895       /* pass NULL as the data item */                          \
2896       GstPadProbeInfo info = { mask, NULL, 0, 0 };              \
2897       ret = do_probe_callbacks (pad, &info, defaultval);        \
2898       if (G_UNLIKELY (ret != defaultval && ret != GST_FLOW_OK)) \
2899         goto label;                                             \
2900     }                                                           \
2901   } G_STMT_END
2902
2903 #define PROBE_FULL(pad,mask,data,offs,size,label,defaultval)    \
2904   G_STMT_START {                                                \
2905     if (G_UNLIKELY (pad->num_probes)) {                         \
2906       GstPadProbeInfo info = { mask, data, offs, size };        \
2907       ret = do_probe_callbacks (pad, &info, defaultval);        \
2908       data = GST_PAD_PROBE_INFO_DATA (&info);                   \
2909       if (G_UNLIKELY (ret != defaultval && ret != GST_FLOW_OK)) \
2910         goto label;                                             \
2911     }                                                           \
2912   } G_STMT_END
2913
2914 #define PROBE_PUSH(pad,mask,data,label)                         \
2915   PROBE_FULL(pad, mask, data, -1, -1, label, GST_FLOW_OK);
2916 #define PROBE_PULL(pad,mask,data,offs,size,label)               \
2917   PROBE_FULL(pad, mask, data, offs, size, label, GST_FLOW_OK);
2918
2919 static GstFlowReturn
2920 do_probe_callbacks (GstPad * pad, GstPadProbeInfo * info,
2921     GstFlowReturn defaultval)
2922 {
2923   ProbeMarshall data;
2924   guint cookie;
2925   gboolean is_block;
2926
2927   data.pad = pad;
2928   data.info = info;
2929   data.pass = FALSE;
2930   data.marshalled = FALSE;
2931   data.dropped = FALSE;
2932   data.cookie = ++pad->priv->probe_cookie;
2933
2934   is_block =
2935       (info->type & GST_PAD_PROBE_TYPE_BLOCK) == GST_PAD_PROBE_TYPE_BLOCK;
2936
2937 again:
2938   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2939       "do probes cookie %u", data.cookie);
2940   cookie = pad->priv->probe_list_cookie;
2941
2942   g_hook_list_marshal (&pad->probes, TRUE,
2943       (GHookMarshaller) probe_hook_marshal, &data);
2944
2945   /* if the list changed, call the new callbacks (they will not have their
2946    * cookie set to data.cookie */
2947   if (cookie != pad->priv->probe_list_cookie) {
2948     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2949         "probe list changed, restarting");
2950     goto again;
2951   }
2952
2953   /* the first item that dropped will stop the hooks and then we drop here */
2954   if (data.dropped)
2955     goto dropped;
2956
2957   /* if no handler matched and we are blocking, let the item pass */
2958   if (!data.marshalled && is_block)
2959     goto passed;
2960
2961   /* At this point, all handlers returned either OK or PASS. If one handler
2962    * returned PASS, let the item pass */
2963   if (data.pass)
2964     goto passed;
2965
2966   if (is_block) {
2967     while (GST_PAD_IS_BLOCKED (pad)) {
2968       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2969           "we are blocked %d times", pad->num_blocked);
2970
2971       /* we might have released the lock */
2972       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
2973         goto flushing;
2974
2975       /* now we block the streaming thread. It can be unlocked when we
2976        * deactivate the pad (which will also set the FLUSHING flag) or
2977        * when the pad is unblocked. A flushing event will also unblock
2978        * the pad after setting the FLUSHING flag. */
2979       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2980           "Waiting to be unblocked or set flushing");
2981       GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_BLOCKING);
2982       GST_PAD_BLOCK_WAIT (pad);
2983       GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_BLOCKING);
2984       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "We got unblocked");
2985
2986       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
2987         goto flushing;
2988     }
2989   }
2990
2991   return defaultval;
2992
2993   /* ERRORS */
2994 flushing:
2995   {
2996     GST_DEBUG_OBJECT (pad, "pad is flushing");
2997     return GST_FLOW_WRONG_STATE;
2998   }
2999 dropped:
3000   {
3001     GST_DEBUG_OBJECT (pad, "data is dropped");
3002     return GST_FLOW_CUSTOM_SUCCESS;
3003   }
3004 passed:
3005   {
3006     /* FIXME : Should we return FLOW_OK or the defaultval ?? */
3007     GST_DEBUG_OBJECT (pad, "data is passed");
3008     return GST_FLOW_OK;
3009   }
3010 }
3011
3012 /* pad offsets */
3013
3014 /**
3015  * gst_pad_get_offset:
3016  * @pad: a #GstPad
3017  *
3018  * Get the offset applied to the running time of @pad. @pad has to be a source
3019  * pad.
3020  *
3021  * Returns: the offset.
3022  */
3023 gint64
3024 gst_pad_get_offset (GstPad * pad)
3025 {
3026   gint64 result;
3027
3028   g_return_val_if_fail (GST_IS_PAD (pad), 0);
3029
3030   GST_OBJECT_LOCK (pad);
3031   result = pad->offset;
3032   GST_OBJECT_UNLOCK (pad);
3033
3034   return result;
3035 }
3036
3037 /**
3038  * gst_pad_set_offset:
3039  * @pad: a #GstPad
3040  * @offset: the offset
3041  *
3042  * Set the offset that will be applied to the running time of @pad.
3043  */
3044 void
3045 gst_pad_set_offset (GstPad * pad, gint64 offset)
3046 {
3047   PadEvent *ev;
3048
3049   g_return_if_fail (GST_IS_PAD (pad));
3050
3051   GST_OBJECT_LOCK (pad);
3052   /* if nothing changed, do nothing */
3053   if (pad->offset == offset)
3054     goto done;
3055
3056   pad->offset = offset;
3057   GST_DEBUG_OBJECT (pad, "changed offset to %" G_GINT64_FORMAT, offset);
3058
3059   /* sinkpads will apply their offset the next time a segment
3060    * event is received. */
3061   if (GST_PAD_IS_SINK (pad))
3062     goto done;
3063
3064   /* resend the last segment event on next buffer push */
3065   if ((ev = find_event_by_type (pad, GST_EVENT_SEGMENT, 0))) {
3066     ev->received = FALSE;
3067     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
3068   }
3069
3070 done:
3071   GST_OBJECT_UNLOCK (pad);
3072 }
3073
3074
3075 /**
3076  * gst_pad_query:
3077  * @pad: a #GstPad to invoke the default query on.
3078  * @query: (transfer none): the #GstQuery to perform.
3079  *
3080  * Dispatches a query to a pad. The query should have been allocated by the
3081  * caller via one of the type-specific allocation functions. The element that
3082  * the pad belongs to is responsible for filling the query with an appropriate
3083  * response, which should then be parsed with a type-specific query parsing
3084  * function.
3085  *
3086  * Again, the caller is responsible for both the allocation and deallocation of
3087  * the query structure.
3088  *
3089  * Please also note that some queries might need a running pipeline to work.
3090  *
3091  * Returns: TRUE if the query could be performed.
3092  */
3093 gboolean
3094 gst_pad_query (GstPad * pad, GstQuery * query)
3095 {
3096   GstObject *parent;
3097   gboolean res;
3098   GstPadQueryFunction func;
3099   GstPadProbeType type;
3100   GstFlowReturn ret;
3101
3102   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3103   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
3104
3105   GST_DEBUG_OBJECT (pad, "sending query %p (%s)", query,
3106       GST_QUERY_TYPE_NAME (query));
3107
3108   if (GST_PAD_IS_SRC (pad))
3109     type = GST_PAD_PROBE_TYPE_QUERY_UPSTREAM;
3110   else
3111     type = GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM;
3112
3113   GST_OBJECT_LOCK (pad);
3114   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH |
3115       GST_PAD_PROBE_TYPE_BLOCK, query, probe_stopped);
3116   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, query, probe_stopped);
3117
3118   ACQUIRE_PARENT (pad, parent, no_parent);
3119   GST_OBJECT_UNLOCK (pad);
3120
3121   if ((func = GST_PAD_QUERYFUNC (pad)) == NULL)
3122     goto no_func;
3123
3124   res = func (pad, parent, query);
3125
3126   RELEASE_PARENT (parent);
3127
3128   GST_DEBUG_OBJECT (pad, "sent query %p (%s), result %d", query,
3129       GST_QUERY_TYPE_NAME (query), res);
3130
3131   if (res != TRUE)
3132     goto query_failed;
3133
3134   GST_OBJECT_LOCK (pad);
3135   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PULL, query, probe_stopped);
3136   GST_OBJECT_UNLOCK (pad);
3137
3138   return res;
3139
3140   /* ERRORS */
3141 no_parent:
3142   {
3143     GST_DEBUG_OBJECT (pad, "had no parent");
3144     GST_OBJECT_UNLOCK (pad);
3145     return FALSE;
3146   }
3147 no_func:
3148   {
3149     GST_DEBUG_OBJECT (pad, "had no query function");
3150     RELEASE_PARENT (parent);
3151     return FALSE;
3152   }
3153 query_failed:
3154   {
3155     GST_DEBUG_OBJECT (pad, "query failed");
3156     return FALSE;
3157   }
3158 probe_stopped:
3159   {
3160     GST_DEBUG_OBJECT (pad, "probe stopped: %s", gst_flow_get_name (ret));
3161     GST_OBJECT_UNLOCK (pad);
3162     return FALSE;
3163   }
3164 }
3165
3166 /**
3167  * gst_pad_peer_query:
3168  * @pad: a #GstPad to invoke the peer query on.
3169  * @query: (transfer none): the #GstQuery to perform.
3170  *
3171  * Performs gst_pad_query() on the peer of @pad.
3172  *
3173  * The caller is responsible for both the allocation and deallocation of
3174  * the query structure.
3175  *
3176  * Returns: TRUE if the query could be performed. This function returns %FALSE
3177  * if @pad has no peer.
3178  *
3179  * Since: 0.10.15
3180  */
3181 gboolean
3182 gst_pad_peer_query (GstPad * pad, GstQuery * query)
3183 {
3184   GstPad *peerpad;
3185   GstPadProbeType type;
3186   gboolean res;
3187   GstFlowReturn ret;
3188
3189   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3190   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
3191
3192   if (GST_PAD_IS_SRC (pad))
3193     type = GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM;
3194   else
3195     type = GST_PAD_PROBE_TYPE_QUERY_UPSTREAM;
3196
3197   GST_DEBUG_OBJECT (pad, "peer query %p (%s)", query,
3198       GST_QUERY_TYPE_NAME (query));
3199
3200   GST_OBJECT_LOCK (pad);
3201   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH |
3202       GST_PAD_PROBE_TYPE_BLOCK, query, probe_stopped);
3203   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, query, probe_stopped);
3204
3205   peerpad = GST_PAD_PEER (pad);
3206   if (G_UNLIKELY (peerpad == NULL))
3207     goto no_peer;
3208
3209   gst_object_ref (peerpad);
3210   GST_OBJECT_UNLOCK (pad);
3211
3212   res = gst_pad_query (peerpad, query);
3213
3214   gst_object_unref (peerpad);
3215
3216   if (res != TRUE)
3217     goto query_failed;
3218
3219   GST_OBJECT_LOCK (pad);
3220   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PULL, query, probe_stopped);
3221   GST_OBJECT_UNLOCK (pad);
3222
3223   return res;
3224
3225   /* ERRORS */
3226 no_peer:
3227   {
3228     GST_WARNING_OBJECT (pad, "pad has no peer");
3229     GST_OBJECT_UNLOCK (pad);
3230     return FALSE;
3231   }
3232 query_failed:
3233   {
3234     GST_DEBUG_OBJECT (pad, "query failed");
3235     return FALSE;
3236   }
3237 probe_stopped:
3238   {
3239     GST_DEBUG_OBJECT (pad, "probe stopped: %s", gst_flow_get_name (ret));
3240     GST_OBJECT_UNLOCK (pad);
3241     return FALSE;
3242   }
3243 }
3244
3245 /**********************************************************************
3246  * Data passing functions
3247  */
3248
3249 static gboolean
3250 push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
3251 {
3252   GstFlowReturn *data = user_data;
3253   gboolean stored;
3254
3255   if (ev->received) {
3256     GST_DEBUG_OBJECT (pad, "event %s was already received",
3257         GST_EVENT_TYPE_NAME (ev->event));
3258     return TRUE;
3259   }
3260   GST_OBJECT_UNLOCK (pad);
3261
3262   *data = gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event),
3263       GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, &stored);
3264
3265   GST_OBJECT_LOCK (pad);
3266   return *data == GST_FLOW_OK;
3267 }
3268
3269 /* this is the chain function that does not perform the additional argument
3270  * checking for that little extra speed.
3271  */
3272 static inline GstFlowReturn
3273 gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
3274 {
3275   GstFlowReturn ret;
3276   GstObject *parent;
3277
3278   GST_PAD_STREAM_LOCK (pad);
3279
3280   GST_OBJECT_LOCK (pad);
3281   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3282     goto flushing;
3283
3284   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_BLOCK, data, probe_stopped);
3285
3286   PROBE_PUSH (pad, type, data, probe_stopped);
3287
3288   parent = GST_OBJECT_PARENT (pad);
3289   GST_OBJECT_UNLOCK (pad);
3290
3291   /* NOTE: we read the chainfunc unlocked.
3292    * we cannot hold the lock for the pad so we might send
3293    * the data to the wrong function. This is not really a
3294    * problem since functions are assigned at creation time
3295    * and don't change that often... */
3296   if (G_LIKELY (type & GST_PAD_PROBE_TYPE_BUFFER)) {
3297     GstPadChainFunction chainfunc;
3298
3299     if (G_UNLIKELY ((chainfunc = GST_PAD_CHAINFUNC (pad)) == NULL))
3300       goto no_function;
3301
3302     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3303         "calling chainfunction &%s with buffer %" GST_PTR_FORMAT,
3304         GST_DEBUG_FUNCPTR_NAME (chainfunc), GST_BUFFER (data));
3305
3306     ret = chainfunc (pad, parent, GST_BUFFER_CAST (data));
3307
3308     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3309         "called chainfunction &%s with buffer %p, returned %s",
3310         GST_DEBUG_FUNCPTR_NAME (chainfunc), data, gst_flow_get_name (ret));
3311   } else {
3312     GstPadChainListFunction chainlistfunc;
3313
3314     if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL))
3315       goto no_function;
3316
3317     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3318         "calling chainlistfunction &%s",
3319         GST_DEBUG_FUNCPTR_NAME (chainlistfunc));
3320
3321     ret = chainlistfunc (pad, parent, GST_BUFFER_LIST_CAST (data));
3322
3323     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3324         "called chainlistfunction &%s, returned %s",
3325         GST_DEBUG_FUNCPTR_NAME (chainlistfunc), gst_flow_get_name (ret));
3326   }
3327
3328   GST_PAD_STREAM_UNLOCK (pad);
3329
3330   return ret;
3331
3332   /* ERRORS */
3333 flushing:
3334   {
3335     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3336         "chaining, but pad was flushing");
3337     GST_OBJECT_UNLOCK (pad);
3338     GST_PAD_STREAM_UNLOCK (pad);
3339     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3340     return GST_FLOW_WRONG_STATE;
3341   }
3342 probe_stopped:
3343   {
3344     GST_OBJECT_UNLOCK (pad);
3345     GST_PAD_STREAM_UNLOCK (pad);
3346     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3347
3348     switch (ret) {
3349       case GST_FLOW_CUSTOM_SUCCESS:
3350         GST_DEBUG_OBJECT (pad, "dropped buffer");
3351         ret = GST_FLOW_OK;
3352         break;
3353       default:
3354         GST_DEBUG_OBJECT (pad, "en error occured %s", gst_flow_get_name (ret));
3355         break;
3356     }
3357     return ret;
3358   }
3359 no_function:
3360   {
3361     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3362     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3363         "pushing, but not chainhandler");
3364     GST_ELEMENT_ERROR (parent, CORE, PAD, (NULL),
3365         ("push on pad %s:%s but it has no chainfunction",
3366             GST_DEBUG_PAD_NAME (pad)));
3367     GST_PAD_STREAM_UNLOCK (pad);
3368     return GST_FLOW_NOT_SUPPORTED;
3369   }
3370 }
3371
3372 /**
3373  * gst_pad_chain:
3374  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
3375  * @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
3376  *     if not.
3377  *
3378  * Chain a buffer to @pad.
3379  *
3380  * The function returns #GST_FLOW_WRONG_STATE if the pad was flushing.
3381  *
3382  * If the buffer type is not acceptable for @pad (as negotiated with a
3383  * preceeding GST_EVENT_CAPS event), this function returns
3384  * #GST_FLOW_NOT_NEGOTIATED.
3385  *
3386  * The function proceeds calling the chain function installed on @pad (see
3387  * gst_pad_set_chain_function()) and the return value of that function is
3388  * returned to the caller. #GST_FLOW_NOT_SUPPORTED is returned if @pad has no
3389  * chain function.
3390  *
3391  * In all cases, success or failure, the caller loses its reference to @buffer
3392  * after calling this function.
3393  *
3394  * Returns: a #GstFlowReturn from the pad.
3395  *
3396  * MT safe.
3397  */
3398 GstFlowReturn
3399 gst_pad_chain (GstPad * pad, GstBuffer * buffer)
3400 {
3401   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3402   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
3403   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
3404
3405   return gst_pad_chain_data_unchecked (pad,
3406       GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, buffer);
3407 }
3408
3409 static GstFlowReturn
3410 gst_pad_chain_list_default (GstPad * pad, GstObject * parent,
3411     GstBufferList * list)
3412 {
3413   guint i, len;
3414   GstBuffer *buffer;
3415   GstFlowReturn ret;
3416
3417   GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
3418
3419   len = gst_buffer_list_length (list);
3420
3421   ret = GST_FLOW_OK;
3422   for (i = 0; i < len; i++) {
3423     buffer = gst_buffer_list_get (list, i);
3424     ret =
3425         gst_pad_chain_data_unchecked (pad,
3426         GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH,
3427         gst_buffer_ref (buffer));
3428     if (ret != GST_FLOW_OK)
3429       break;
3430   }
3431   gst_buffer_list_unref (list);
3432
3433   return ret;
3434 }
3435
3436 /**
3437  * gst_pad_chain_list:
3438  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
3439  * @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
3440  *     if not.
3441  *
3442  * Chain a bufferlist to @pad.
3443  *
3444  * The function returns #GST_FLOW_WRONG_STATE if the pad was flushing.
3445  *
3446  * If @pad was not negotiated properly with a CAPS event, this function
3447  * returns #GST_FLOW_NOT_NEGOTIATED.
3448  *
3449  * The function proceeds calling the chainlist function installed on @pad (see
3450  * gst_pad_set_chain_list_function()) and the return value of that function is
3451  * returned to the caller. #GST_FLOW_NOT_SUPPORTED is returned if @pad has no
3452  * chainlist function.
3453  *
3454  * In all cases, success or failure, the caller loses its reference to @list
3455  * after calling this function.
3456  *
3457  * MT safe.
3458  *
3459  * Returns: a #GstFlowReturn from the pad.
3460  *
3461  * Since: 0.10.24
3462  */
3463 GstFlowReturn
3464 gst_pad_chain_list (GstPad * pad, GstBufferList * list)
3465 {
3466   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3467   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
3468   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
3469
3470   return gst_pad_chain_data_unchecked (pad,
3471       GST_PAD_PROBE_TYPE_BUFFER_LIST | GST_PAD_PROBE_TYPE_PUSH, list);
3472 }
3473
3474 static GstFlowReturn
3475 gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
3476 {
3477   GstPad *peer;
3478   GstFlowReturn ret;
3479
3480   GST_OBJECT_LOCK (pad);
3481   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3482     goto flushing;
3483
3484   if (G_UNLIKELY (GST_PAD_HAS_PENDING_EVENTS (pad))) {
3485     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PENDING_EVENTS);
3486
3487     GST_DEBUG_OBJECT (pad, "pushing all sticky events");
3488
3489     ret = GST_FLOW_OK;
3490     events_foreach (pad, push_sticky, &ret);
3491     if (ret != GST_FLOW_OK)
3492       goto events_error;
3493   }
3494
3495   /* do block probes */
3496   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_BLOCK, data, probe_stopped);
3497
3498   /* do post-blocking probes */
3499   PROBE_PUSH (pad, type, data, probe_stopped);
3500
3501   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
3502     goto not_linked;
3503
3504   /* take ref to peer pad before releasing the lock */
3505   gst_object_ref (peer);
3506   pad->priv->using++;
3507   GST_OBJECT_UNLOCK (pad);
3508
3509   ret = gst_pad_chain_data_unchecked (peer, type, data);
3510
3511   gst_object_unref (peer);
3512
3513   GST_OBJECT_LOCK (pad);
3514   pad->priv->using--;
3515   if (pad->priv->using == 0) {
3516     /* pad is not active anymore, trigger idle callbacks */
3517     PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE,
3518         probe_stopped, ret);
3519   }
3520   GST_OBJECT_UNLOCK (pad);
3521
3522   return ret;
3523
3524   /* ERROR recovery here */
3525   /* ERRORS */
3526 flushing:
3527   {
3528     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3529         "pushing, but pad was flushing");
3530     GST_OBJECT_UNLOCK (pad);
3531     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3532     return GST_FLOW_WRONG_STATE;
3533   }
3534 events_error:
3535   {
3536     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3537         "error pushing events, return %s", gst_flow_get_name (ret));
3538     GST_OBJECT_UNLOCK (pad);
3539     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3540     return ret;
3541   }
3542 probe_stopped:
3543   {
3544     GST_OBJECT_UNLOCK (pad);
3545     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3546
3547     switch (ret) {
3548       case GST_FLOW_CUSTOM_SUCCESS:
3549         GST_DEBUG_OBJECT (pad, "dropped buffer");
3550         ret = GST_FLOW_OK;
3551         break;
3552       default:
3553         GST_DEBUG_OBJECT (pad, "en error occured %s", gst_flow_get_name (ret));
3554         break;
3555     }
3556     return ret;
3557   }
3558 not_linked:
3559   {
3560     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3561         "pushing, but it was not linked");
3562     GST_OBJECT_UNLOCK (pad);
3563     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
3564     return GST_FLOW_NOT_LINKED;
3565   }
3566 }
3567
3568 /**
3569  * gst_pad_push:
3570  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
3571  * @buffer: (transfer full): the #GstBuffer to push returns GST_FLOW_ERROR
3572  *     if not.
3573  *
3574  * Pushes a buffer to the peer of @pad.
3575  *
3576  * This function will call installed block probes before triggering any
3577  * installed data probes.
3578  *
3579  * The function proceeds calling gst_pad_chain() on the peer pad and returns
3580  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
3581  * be returned.
3582  *
3583  * In all cases, success or failure, the caller loses its reference to @buffer
3584  * after calling this function.
3585  *
3586  * Returns: a #GstFlowReturn from the peer pad.
3587  *
3588  * MT safe.
3589  */
3590 GstFlowReturn
3591 gst_pad_push (GstPad * pad, GstBuffer * buffer)
3592 {
3593   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3594   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
3595   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
3596
3597   return gst_pad_push_data (pad,
3598       GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, buffer);
3599 }
3600
3601 /**
3602  * gst_pad_push_list:
3603  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
3604  * @list: (transfer full): the #GstBufferList to push returns GST_FLOW_ERROR
3605  *     if not.
3606  *
3607  * Pushes a buffer list to the peer of @pad.
3608  *
3609  * This function will call installed block probes before triggering any
3610  * installed data probes.
3611  *
3612  * The function proceeds calling the chain function on the peer pad and returns
3613  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
3614  * be returned. If the peer pad does not have any installed chainlist function
3615  * every group buffer of the list will be merged into a normal #GstBuffer and
3616  * chained via gst_pad_chain().
3617  *
3618  * In all cases, success or failure, the caller loses its reference to @list
3619  * after calling this function.
3620  *
3621  * Returns: a #GstFlowReturn from the peer pad.
3622  *
3623  * MT safe.
3624  *
3625  * Since: 0.10.24
3626  */
3627 GstFlowReturn
3628 gst_pad_push_list (GstPad * pad, GstBufferList * list)
3629 {
3630   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3631   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
3632   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
3633
3634   return gst_pad_push_data (pad,
3635       GST_PAD_PROBE_TYPE_BUFFER_LIST | GST_PAD_PROBE_TYPE_PUSH, list);
3636 }
3637
3638 static GstFlowReturn
3639 gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
3640     GstBuffer ** buffer)
3641 {
3642   GstFlowReturn ret;
3643   GstPadGetRangeFunction getrangefunc;
3644   GstObject *parent;
3645
3646   GST_PAD_STREAM_LOCK (pad);
3647
3648   GST_OBJECT_LOCK (pad);
3649   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3650     goto flushing;
3651
3652   if (G_UNLIKELY (GST_PAD_HAS_PENDING_EVENTS (pad))) {
3653     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PENDING_EVENTS);
3654
3655     GST_DEBUG_OBJECT (pad, "pushing all sticky events");
3656
3657     ret = GST_FLOW_OK;
3658     events_foreach (pad, push_sticky, &ret);
3659     if (ret != GST_FLOW_OK)
3660       goto events_error;
3661   }
3662
3663   /* when one of the probes returns a buffer, probed_data will be called and we
3664    * skip calling the getrange function */
3665   PROBE_PRE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK,
3666       *buffer, offset, size, probe_stopped, probed_data, GST_FLOW_OK);
3667
3668   ACQUIRE_PARENT (pad, parent, no_parent);
3669   GST_OBJECT_UNLOCK (pad);
3670
3671   if (G_UNLIKELY ((getrangefunc = GST_PAD_GETRANGEFUNC (pad)) == NULL))
3672     goto no_function;
3673
3674   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3675       "calling getrangefunc %s, offset %"
3676       G_GUINT64_FORMAT ", size %u",
3677       GST_DEBUG_FUNCPTR_NAME (getrangefunc), offset, size);
3678
3679   ret = getrangefunc (pad, parent, offset, size, buffer);
3680
3681   RELEASE_PARENT (parent);
3682
3683   if (G_UNLIKELY (ret != GST_FLOW_OK))
3684     goto get_range_failed;
3685
3686   /* can only fire the signal if we have a valid buffer */
3687   GST_OBJECT_LOCK (pad);
3688 probed_data:
3689   PROBE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BUFFER,
3690       *buffer, offset, size, probe_stopped_unref);
3691   GST_OBJECT_UNLOCK (pad);
3692
3693   GST_PAD_STREAM_UNLOCK (pad);
3694
3695   return ret;
3696
3697   /* ERRORS */
3698 flushing:
3699   {
3700     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3701         "getrange, but pad was flushing");
3702     GST_OBJECT_UNLOCK (pad);
3703     GST_PAD_STREAM_UNLOCK (pad);
3704     return GST_FLOW_WRONG_STATE;
3705   }
3706 events_error:
3707   {
3708     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "error pushing events");
3709     GST_OBJECT_UNLOCK (pad);
3710     GST_PAD_STREAM_UNLOCK (pad);
3711     return ret;
3712   }
3713 no_parent:
3714   {
3715     GST_DEBUG_OBJECT (pad, "no parent");
3716     GST_OBJECT_UNLOCK (pad);
3717     GST_PAD_STREAM_UNLOCK (pad);
3718     return GST_FLOW_WRONG_STATE;
3719   }
3720 no_function:
3721   {
3722     GST_ELEMENT_ERROR (parent, CORE, PAD, (NULL),
3723         ("getrange on pad %s:%s but it has no getrangefunction",
3724             GST_DEBUG_PAD_NAME (pad)));
3725     RELEASE_PARENT (parent);
3726     GST_PAD_STREAM_UNLOCK (pad);
3727     return GST_FLOW_NOT_SUPPORTED;
3728   }
3729 probe_stopped:
3730   {
3731     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3732         "probe returned %s", gst_flow_get_name (ret));
3733     GST_OBJECT_UNLOCK (pad);
3734     GST_PAD_STREAM_UNLOCK (pad);
3735     return ret;
3736   }
3737 probe_stopped_unref:
3738   {
3739     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3740         "probe returned %s", gst_flow_get_name (ret));
3741     GST_OBJECT_UNLOCK (pad);
3742     GST_PAD_STREAM_UNLOCK (pad);
3743     gst_buffer_unref (*buffer);
3744     *buffer = NULL;
3745     return ret;
3746   }
3747 get_range_failed:
3748   {
3749     GST_PAD_STREAM_UNLOCK (pad);
3750     *buffer = NULL;
3751     GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
3752         (ret >= GST_FLOW_EOS) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
3753         pad, "getrange failed, flow: %s", gst_flow_get_name (ret));
3754     return ret;
3755   }
3756 }
3757
3758 /**
3759  * gst_pad_get_range:
3760  * @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
3761  * @offset: The start offset of the buffer
3762  * @size: The length of the buffer
3763  * @buffer: (out callee-allocates): a pointer to hold the #GstBuffer,
3764  *     returns #GST_FLOW_ERROR if %NULL.
3765  *
3766  * When @pad is flushing this function returns #GST_FLOW_WRONG_STATE
3767  * immediately and @buffer is %NULL.
3768  *
3769  * Calls the getrange function of @pad, see #GstPadGetRangeFunction for a
3770  * description of a getrange function. If @pad has no getrange function
3771  * installed (see gst_pad_set_getrange_function()) this function returns
3772  * #GST_FLOW_NOT_SUPPORTED.
3773  *
3774  * This is a lowlevel function. Usualy gst_pad_pull_range() is used.
3775  *
3776  * Returns: a #GstFlowReturn from the pad.
3777  *
3778  * MT safe.
3779  */
3780 GstFlowReturn
3781 gst_pad_get_range (GstPad * pad, guint64 offset, guint size,
3782     GstBuffer ** buffer)
3783 {
3784   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3785   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
3786   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
3787
3788   return gst_pad_get_range_unchecked (pad, offset, size, buffer);
3789 }
3790
3791 /**
3792  * gst_pad_pull_range:
3793  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
3794  * @offset: The start offset of the buffer
3795  * @size: The length of the buffer
3796  * @buffer: (out callee-allocates): a pointer to hold the #GstBuffer, returns
3797  *     GST_FLOW_ERROR if %NULL.
3798  *
3799  * Pulls a @buffer from the peer pad.
3800  *
3801  * This function will first trigger the pad block signal if it was
3802  * installed.
3803  *
3804  * When @pad is not linked #GST_FLOW_NOT_LINKED is returned else this
3805  * function returns the result of gst_pad_get_range() on the peer pad.
3806  * See gst_pad_get_range() for a list of return values and for the
3807  * semantics of the arguments of this function.
3808  *
3809  * Returns: a #GstFlowReturn from the peer pad.
3810  * When this function returns #GST_FLOW_OK, @buffer will contain a valid
3811  * #GstBuffer that should be freed with gst_buffer_unref() after usage.
3812  * @buffer may not be used or freed when any other return value than
3813  * #GST_FLOW_OK is returned.
3814  *
3815  * MT safe.
3816  */
3817 GstFlowReturn
3818 gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
3819     GstBuffer ** buffer)
3820 {
3821   GstPad *peer;
3822   GstFlowReturn ret;
3823
3824   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
3825   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
3826   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
3827
3828   GST_OBJECT_LOCK (pad);
3829   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
3830     goto flushing;
3831
3832   /* when one of the probes returns a buffer, probed_data will be called and we
3833    * skip calling the peer getrange function */
3834   PROBE_PRE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK,
3835       *buffer, offset, size, pre_probe_stopped, probed_data, GST_FLOW_OK);
3836
3837   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
3838     goto not_linked;
3839
3840   gst_object_ref (peer);
3841   pad->priv->using++;
3842   GST_OBJECT_UNLOCK (pad);
3843
3844   ret = gst_pad_get_range_unchecked (peer, offset, size, buffer);
3845
3846   gst_object_unref (peer);
3847
3848   GST_OBJECT_LOCK (pad);
3849   pad->priv->using--;
3850   if (pad->priv->using == 0) {
3851     /* pad is not active anymore, trigger idle callbacks */
3852     PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_IDLE,
3853         post_probe_stopped, ret);
3854   }
3855
3856   if (G_UNLIKELY (ret != GST_FLOW_OK))
3857     goto pull_range_failed;
3858
3859 probed_data:
3860   PROBE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BUFFER,
3861       *buffer, offset, size, post_probe_stopped);
3862
3863   GST_OBJECT_UNLOCK (pad);
3864
3865   return ret;
3866
3867   /* ERROR recovery here */
3868 flushing:
3869   {
3870     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3871         "pullrange, but pad was flushing");
3872     GST_OBJECT_UNLOCK (pad);
3873     return GST_FLOW_WRONG_STATE;
3874   }
3875 pre_probe_stopped:
3876   {
3877     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pre probe returned %s",
3878         gst_flow_get_name (ret));
3879     GST_OBJECT_UNLOCK (pad);
3880     return ret;
3881   }
3882 not_linked:
3883   {
3884     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3885         "pulling range, but it was not linked");
3886     GST_OBJECT_UNLOCK (pad);
3887     return GST_FLOW_NOT_LINKED;
3888   }
3889 pull_range_failed:
3890   {
3891     *buffer = NULL;
3892     GST_OBJECT_UNLOCK (pad);
3893     GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
3894         (ret >= GST_FLOW_EOS) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
3895         pad, "pullrange failed, flow: %s", gst_flow_get_name (ret));
3896     return ret;
3897   }
3898 post_probe_stopped:
3899   {
3900     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3901         "post probe returned %s", gst_flow_get_name (ret));
3902     GST_OBJECT_UNLOCK (pad);
3903     if (ret == GST_FLOW_OK)
3904       gst_buffer_unref (*buffer);
3905     *buffer = NULL;
3906     return ret;
3907   }
3908 }
3909
3910 static gboolean
3911 gst_pad_store_sticky_event (GstPad * pad, GstEvent * event, gboolean locked)
3912 {
3913   guint i, len;
3914   GstEventType type;
3915   GArray *events;
3916   gboolean res = FALSE;
3917   const gchar *name = NULL;
3918
3919   type = GST_EVENT_TYPE (event);
3920   if (type & GST_EVENT_TYPE_STICKY_MULTI)
3921     name = gst_structure_get_name (gst_event_get_structure (event));
3922
3923   events = pad->priv->events;
3924   len = events->len;
3925
3926   for (i = 0; i < len; i++) {
3927     PadEvent *ev = &g_array_index (events, PadEvent, i);
3928
3929     if (ev->event == NULL)
3930       continue;
3931
3932     if (type == GST_EVENT_TYPE (ev->event)) {
3933       /* matching types, check matching name if needed */
3934       if (name && !gst_event_has_name (ev->event, name))
3935         continue;
3936
3937       /* overwrite */
3938       if ((res = gst_event_replace (&ev->event, event)))
3939         ev->received = FALSE;
3940       break;
3941     }
3942   }
3943   if (i == len) {
3944     PadEvent ev;
3945     ev.event = gst_event_ref (event);
3946     ev.received = FALSE;
3947     g_array_append_val (events, ev);
3948     res = TRUE;
3949   }
3950
3951   if (res) {
3952     pad->priv->events_cookie++;
3953     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
3954
3955     GST_LOG_OBJECT (pad, "stored sticky event %s", GST_EVENT_TYPE_NAME (event));
3956
3957     switch (GST_EVENT_TYPE (event)) {
3958       case GST_EVENT_CAPS:
3959         if (locked)
3960           GST_OBJECT_UNLOCK (pad);
3961
3962         GST_DEBUG_OBJECT (pad, "notify caps");
3963         g_object_notify_by_pspec ((GObject *) pad, pspec_caps);
3964
3965         if (locked)
3966           GST_OBJECT_LOCK (pad);
3967         break;
3968       default:
3969         break;
3970     }
3971   }
3972   return res;
3973 }
3974
3975 static GstFlowReturn
3976 gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
3977     GstPadProbeType type, gboolean * stored)
3978 {
3979   GstFlowReturn ret;
3980   GstPad *peerpad;
3981   GstEventType event_type;
3982   gboolean sticky;
3983
3984   sticky = GST_EVENT_IS_STICKY (event);
3985
3986   GST_OBJECT_LOCK (pad);
3987
3988   /* Two checks to be made:
3989    * . (un)set the FLUSHING flag for flushing events,
3990    * . handle pad blocking */
3991   event_type = GST_EVENT_TYPE (event);
3992   *stored = FALSE;
3993   switch (event_type) {
3994     case GST_EVENT_FLUSH_START:
3995       GST_PAD_SET_FLUSHING (pad);
3996
3997       GST_PAD_BLOCK_BROADCAST (pad);
3998       type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
3999       break;
4000     case GST_EVENT_FLUSH_STOP:
4001       GST_PAD_UNSET_FLUSHING (pad);
4002
4003       /* Remove sticky EOS events */
4004       GST_LOG_OBJECT (pad, "Removing pending EOS events");
4005       remove_event_by_type (pad, GST_EVENT_EOS);
4006
4007       type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
4008       break;
4009     default:
4010     {
4011       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4012         goto flushed;
4013
4014       /* store the event on the pad, but only on srcpads. We always store the
4015        * event exactly how it was sent */
4016       if (sticky) {
4017         /* srcpad sticky events are store immediately, the received flag is set
4018          * to FALSE and will be set to TRUE when we can successfully push the
4019          * event to the peer pad */
4020         if (gst_pad_store_sticky_event (pad, event, TRUE)) {
4021           GST_DEBUG_OBJECT (pad, "event %s updated",
4022               GST_EVENT_TYPE_NAME (event));
4023         }
4024         *stored = TRUE;
4025       }
4026
4027       switch (GST_EVENT_TYPE (event)) {
4028         case GST_EVENT_SEGMENT:
4029           /* pass the adjusted segment event on. We need to do this even if
4030            * there is no peer pad because of the probes. */
4031           event = apply_pad_offset (pad, event);
4032           break;
4033         case GST_EVENT_RECONFIGURE:
4034           if (GST_PAD_IS_SINK (pad))
4035             GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
4036           break;
4037         default:
4038           break;
4039       }
4040       PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH |
4041           GST_PAD_PROBE_TYPE_BLOCK, event, probe_stopped);
4042       break;
4043     }
4044   }
4045
4046   /* send probes after modifying the events above */
4047   PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, event, probe_stopped);
4048
4049   /* now check the peer pad */
4050   peerpad = GST_PAD_PEER (pad);
4051   if (peerpad == NULL)
4052     goto not_linked;
4053
4054   gst_object_ref (peerpad);
4055   pad->priv->using++;
4056   GST_OBJECT_UNLOCK (pad);
4057
4058   GST_LOG_OBJECT (pad, "sending event %p (%s) to peerpad %" GST_PTR_FORMAT,
4059       event, GST_EVENT_TYPE_NAME (event), peerpad);
4060
4061   ret = gst_pad_send_event_unchecked (peerpad, event, type);
4062
4063   /* Note: we gave away ownership of the event at this point but we can still
4064    * print the old pointer */
4065   GST_LOG_OBJECT (pad,
4066       "sent event %p to peerpad %" GST_PTR_FORMAT ", ret %s", event, peerpad,
4067       gst_flow_get_name (ret));
4068
4069   gst_object_unref (peerpad);
4070
4071   GST_OBJECT_LOCK (pad);
4072   if (sticky) {
4073     if (ret == GST_FLOW_OK) {
4074       PadEvent *ev;
4075
4076       if ((ev = find_event (pad, event)))
4077         ev->received = TRUE;
4078
4079       GST_DEBUG_OBJECT (pad, "event marked received");
4080     } else {
4081       GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
4082       GST_DEBUG_OBJECT (pad, "mark pending events");
4083     }
4084   }
4085   pad->priv->using--;
4086   if (pad->priv->using == 0) {
4087     /* pad is not active anymore, trigger idle callbacks */
4088     PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE,
4089         idle_probe_stopped, ret);
4090   }
4091   GST_OBJECT_UNLOCK (pad);
4092
4093   return ret;
4094
4095   /* ERROR handling */
4096 flushed:
4097   {
4098     GST_DEBUG_OBJECT (pad, "We're flushing");
4099     GST_OBJECT_UNLOCK (pad);
4100     gst_event_unref (event);
4101     return GST_FLOW_WRONG_STATE;
4102   }
4103 probe_stopped:
4104   {
4105     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
4106     GST_OBJECT_UNLOCK (pad);
4107     gst_event_unref (event);
4108
4109     switch (ret) {
4110       case GST_FLOW_CUSTOM_SUCCESS:
4111         GST_DEBUG_OBJECT (pad, "dropped event");
4112         ret = GST_FLOW_OK;
4113         break;
4114       default:
4115         GST_DEBUG_OBJECT (pad, "en error occured %s", gst_flow_get_name (ret));
4116         break;
4117     }
4118     return ret;
4119   }
4120 not_linked:
4121   {
4122     GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
4123     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
4124     GST_OBJECT_UNLOCK (pad);
4125     gst_event_unref (event);
4126     return sticky ? GST_FLOW_OK : GST_FLOW_NOT_LINKED;
4127   }
4128 idle_probe_stopped:
4129   {
4130     GST_DEBUG_OBJECT (pad, "Idle probe returned %s", gst_flow_get_name (ret));
4131     GST_OBJECT_UNLOCK (pad);
4132     return ret;
4133   }
4134 }
4135
4136 /**
4137  * gst_pad_push_event:
4138  * @pad: a #GstPad to push the event to.
4139  * @event: (transfer full): the #GstEvent to send to the pad.
4140  *
4141  * Sends the event to the peer of the given pad. This function is
4142  * mainly used by elements to send events to their peer
4143  * elements.
4144  *
4145  * This function takes owership of the provided event so you should
4146  * gst_event_ref() it if you want to reuse the event after this call.
4147  *
4148  * Returns: TRUE if the event was handled.
4149  *
4150  * MT safe.
4151  */
4152 gboolean
4153 gst_pad_push_event (GstPad * pad, GstEvent * event)
4154 {
4155   gboolean res;
4156   GstPadProbeType type;
4157   gboolean stored;
4158
4159   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4160   g_return_val_if_fail (event != NULL, FALSE);
4161   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
4162
4163   if (GST_PAD_IS_SRC (pad)) {
4164     if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event)))
4165       goto wrong_direction;
4166     type = GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM;
4167   } else if (GST_PAD_IS_SINK (pad)) {
4168     if (G_UNLIKELY (!GST_EVENT_IS_UPSTREAM (event)))
4169       goto wrong_direction;
4170     /* events pushed on sinkpad never are sticky */
4171     type = GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;
4172   } else
4173     goto unknown_direction;
4174
4175   if (gst_pad_push_event_unchecked (pad, event, type, &stored) != GST_FLOW_OK)
4176     res = stored ? TRUE : FALSE;
4177   else
4178     res = TRUE;
4179
4180   return res;
4181
4182   /* ERROR handling */
4183 wrong_direction:
4184   {
4185     g_warning ("pad %s:%s pushing %s event in wrong direction",
4186         GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
4187     gst_event_unref (event);
4188     return FALSE;
4189   }
4190 unknown_direction:
4191   {
4192     g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
4193     gst_event_unref (event);
4194     return FALSE;
4195   }
4196 }
4197
4198 /* Check if we can call the event function with the given event */
4199 static GstFlowReturn
4200 pre_eventfunc_check (GstPad * pad, GstEvent * event)
4201 {
4202   GstCaps *caps, *templ;
4203
4204   switch (GST_EVENT_TYPE (event)) {
4205     case GST_EVENT_CAPS:
4206     {
4207       /* backwards compatibility mode for caps */
4208       gst_event_parse_caps (event, &caps);
4209
4210       /* See if pad accepts the caps */
4211       templ = gst_pad_get_pad_template_caps (pad);
4212       if (!gst_caps_is_subset (caps, templ))
4213         goto not_accepted;
4214
4215       gst_caps_unref (templ);
4216       break;
4217     }
4218     default:
4219       break;
4220   }
4221   return GST_FLOW_OK;
4222
4223   /* ERRORS */
4224 not_accepted:
4225   {
4226     gst_caps_unref (templ);
4227     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
4228         "caps %" GST_PTR_FORMAT " not accepted", caps);
4229     return GST_FLOW_NOT_NEGOTIATED;
4230   }
4231 }
4232
4233 static GstFlowReturn
4234 gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
4235     GstPadProbeType type)
4236 {
4237   GstFlowReturn ret;
4238   GstEventType event_type;
4239   gboolean serialized, need_unlock = FALSE, sticky;
4240   GstPadEventFunction eventfunc;
4241   GstObject *parent;
4242
4243   GST_OBJECT_LOCK (pad);
4244   if (GST_PAD_IS_SINK (pad))
4245     serialized = GST_EVENT_IS_SERIALIZED (event);
4246   else
4247     serialized = FALSE;
4248   sticky = GST_EVENT_IS_STICKY (event);
4249   event_type = GST_EVENT_TYPE (event);
4250   switch (event_type) {
4251     case GST_EVENT_FLUSH_START:
4252       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad,
4253           "have event type %d (FLUSH_START)", GST_EVENT_TYPE (event));
4254
4255       /* can't even accept a flush begin event when flushing */
4256       if (GST_PAD_IS_FLUSHING (pad))
4257         goto flushing;
4258
4259       GST_PAD_SET_FLUSHING (pad);
4260       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "set flush flag");
4261       break;
4262     case GST_EVENT_FLUSH_STOP:
4263       if (G_LIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_NONE)) {
4264         GST_PAD_UNSET_FLUSHING (pad);
4265         GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "cleared flush flag");
4266       }
4267       /* Remove pending EOS events */
4268       GST_LOG_OBJECT (pad, "Removing pending EOS events");
4269       remove_event_by_type (pad, GST_EVENT_EOS);
4270
4271       GST_OBJECT_UNLOCK (pad);
4272       /* grab stream lock */
4273       GST_PAD_STREAM_LOCK (pad);
4274       need_unlock = TRUE;
4275       GST_OBJECT_LOCK (pad);
4276       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4277         goto flushing;
4278       break;
4279     case GST_EVENT_RECONFIGURE:
4280       if (GST_PAD_IS_SRC (pad))
4281         GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
4282     default:
4283       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "have event type %s",
4284           GST_EVENT_TYPE_NAME (event));
4285
4286       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4287         goto flushing;
4288
4289       if (serialized) {
4290         /* lock order: STREAM_LOCK, LOCK, recheck flushing. */
4291         GST_OBJECT_UNLOCK (pad);
4292         GST_PAD_STREAM_LOCK (pad);
4293         need_unlock = TRUE;
4294         GST_OBJECT_LOCK (pad);
4295         if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
4296           goto flushing;
4297       }
4298
4299       switch (GST_EVENT_TYPE (event)) {
4300         case GST_EVENT_SEGMENT:
4301           event = apply_pad_offset (pad, event);
4302           break;
4303         default:
4304           break;
4305       }
4306
4307       /* now do the probe */
4308       PROBE_PUSH (pad,
4309           type | GST_PAD_PROBE_TYPE_PUSH |
4310           GST_PAD_PROBE_TYPE_BLOCK, event, probe_stopped);
4311
4312       PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, event, probe_stopped);
4313       break;
4314   }
4315
4316   if (G_UNLIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
4317     goto no_function;
4318
4319   ACQUIRE_PARENT (pad, parent, no_parent);
4320   GST_OBJECT_UNLOCK (pad);
4321
4322   ret = pre_eventfunc_check (pad, event);
4323   if (G_UNLIKELY (ret != GST_FLOW_OK))
4324     goto precheck_failed;
4325
4326   if (sticky)
4327     gst_event_ref (event);
4328
4329   if (eventfunc (pad, parent, event)) {
4330     ret = GST_FLOW_OK;
4331   } else {
4332     /* something went wrong */
4333     switch (event_type) {
4334       case GST_EVENT_CAPS:
4335         ret = GST_FLOW_NOT_NEGOTIATED;
4336         break;
4337       default:
4338         ret = GST_FLOW_ERROR;
4339         break;
4340     }
4341   }
4342   RELEASE_PARENT (parent);
4343
4344   GST_DEBUG_OBJECT (pad, "sent event, ret %s", gst_flow_get_name (ret));
4345
4346   if (sticky) {
4347     if (ret == GST_FLOW_OK) {
4348       /* after the event function accepted the event, we can store the sticky
4349        * event on the pad */
4350       gst_pad_store_sticky_event (pad, event, FALSE);
4351     }
4352     gst_event_unref (event);
4353   }
4354
4355   if (need_unlock)
4356     GST_PAD_STREAM_UNLOCK (pad);
4357
4358   return ret;
4359
4360   /* ERROR handling */
4361 flushing:
4362   {
4363     GST_OBJECT_UNLOCK (pad);
4364     if (need_unlock)
4365       GST_PAD_STREAM_UNLOCK (pad);
4366     GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad,
4367         "Received event on flushing pad. Discarding");
4368     gst_event_unref (event);
4369     return GST_FLOW_WRONG_STATE;
4370   }
4371 probe_stopped:
4372   {
4373     GST_OBJECT_UNLOCK (pad);
4374     if (need_unlock)
4375       GST_PAD_STREAM_UNLOCK (pad);
4376     gst_event_unref (event);
4377
4378     switch (ret) {
4379       case GST_FLOW_CUSTOM_SUCCESS:
4380         GST_DEBUG_OBJECT (pad, "dropped event");
4381         ret = GST_FLOW_OK;
4382         break;
4383       default:
4384         GST_DEBUG_OBJECT (pad, "en error occured %s", gst_flow_get_name (ret));
4385         break;
4386     }
4387     return ret;
4388   }
4389 no_function:
4390   {
4391     g_warning ("pad %s:%s has no event handler, file a bug.",
4392         GST_DEBUG_PAD_NAME (pad));
4393     GST_OBJECT_UNLOCK (pad);
4394     if (need_unlock)
4395       GST_PAD_STREAM_UNLOCK (pad);
4396     gst_event_unref (event);
4397     return GST_FLOW_NOT_SUPPORTED;
4398   }
4399 no_parent:
4400   {
4401     GST_DEBUG_OBJECT (pad, "no parent");
4402     GST_OBJECT_UNLOCK (pad);
4403     if (need_unlock)
4404       GST_PAD_STREAM_UNLOCK (pad);
4405     gst_event_unref (event);
4406     return GST_FLOW_WRONG_STATE;
4407   }
4408 precheck_failed:
4409   {
4410     GST_DEBUG_OBJECT (pad, "pre event check failed");
4411     RELEASE_PARENT (parent);
4412     if (need_unlock)
4413       GST_PAD_STREAM_UNLOCK (pad);
4414     gst_event_unref (event);
4415     return ret;
4416   }
4417 }
4418
4419 /**
4420  * gst_pad_send_event:
4421  * @pad: a #GstPad to send the event to.
4422  * @event: (transfer full): the #GstEvent to send to the pad.
4423  *
4424  * Sends the event to the pad. This function can be used
4425  * by applications to send events in the pipeline.
4426  *
4427  * If @pad is a source pad, @event should be an upstream event. If @pad is a
4428  * sink pad, @event should be a downstream event. For example, you would not
4429  * send a #GST_EVENT_EOS on a src pad; EOS events only propagate downstream.
4430  * Furthermore, some downstream events have to be serialized with data flow,
4431  * like EOS, while some can travel out-of-band, like #GST_EVENT_FLUSH_START. If
4432  * the event needs to be serialized with data flow, this function will take the
4433  * pad's stream lock while calling its event function.
4434  *
4435  * To find out whether an event type is upstream, downstream, or downstream and
4436  * serialized, see #GstEventTypeFlags, gst_event_type_get_flags(),
4437  * #GST_EVENT_IS_UPSTREAM, #GST_EVENT_IS_DOWNSTREAM, and
4438  * #GST_EVENT_IS_SERIALIZED. Note that in practice that an application or
4439  * plugin doesn't need to bother itself with this information; the core handles
4440  * all necessary locks and checks.
4441  *
4442  * This function takes owership of the provided event so you should
4443  * gst_event_ref() it if you want to reuse the event after this call.
4444  *
4445  * Returns: TRUE if the event was handled.
4446  */
4447 gboolean
4448 gst_pad_send_event (GstPad * pad, GstEvent * event)
4449 {
4450   gboolean result;
4451   GstPadProbeType type;
4452
4453   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4454   g_return_val_if_fail (event != NULL, FALSE);
4455
4456   if (GST_PAD_IS_SINK (pad)) {
4457     if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event)))
4458       goto wrong_direction;
4459     type = GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM;
4460   } else if (GST_PAD_IS_SRC (pad)) {
4461     if (G_UNLIKELY (!GST_EVENT_IS_UPSTREAM (event)))
4462       goto wrong_direction;
4463     type = GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;
4464   } else
4465     goto unknown_direction;
4466
4467   if (gst_pad_send_event_unchecked (pad, event, type) != GST_FLOW_OK)
4468     result = FALSE;
4469   else
4470     result = TRUE;
4471
4472   return result;
4473
4474   /* ERROR handling */
4475 wrong_direction:
4476   {
4477     g_warning ("pad %s:%s sending %s event in wrong direction",
4478         GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
4479     gst_event_unref (event);
4480     return FALSE;
4481   }
4482 unknown_direction:
4483   {
4484     g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
4485     gst_event_unref (event);
4486     return FALSE;
4487   }
4488 }
4489
4490 /**
4491  * gst_pad_set_element_private:
4492  * @pad: the #GstPad to set the private data of.
4493  * @priv: The private data to attach to the pad.
4494  *
4495  * Set the given private data gpointer on the pad.
4496  * This function can only be used by the element that owns the pad.
4497  * No locking is performed in this function.
4498  */
4499 void
4500 gst_pad_set_element_private (GstPad * pad, gpointer priv)
4501 {
4502   pad->element_private = priv;
4503 }
4504
4505 /**
4506  * gst_pad_get_element_private:
4507  * @pad: the #GstPad to get the private data of.
4508  *
4509  * Gets the private data of a pad.
4510  * No locking is performed in this function.
4511  *
4512  * Returns: (transfer none): a #gpointer to the private data.
4513  */
4514 gpointer
4515 gst_pad_get_element_private (GstPad * pad)
4516 {
4517   return pad->element_private;
4518 }
4519
4520 /**
4521  * gst_pad_get_sticky_event:
4522  * @pad: the #GstPad to get the event from.
4523  * @event_type: the #GstEventType that should be retrieved.
4524  * @idx: the index of the event
4525  *
4526  * Returns a new reference of the sticky event of type @event_type
4527  * from the event.
4528  *
4529  * Returns: (transfer full): a #GstEvent of type @event_type or NULL when no
4530  * event of @event_type was on @pad. Unref after usage.
4531  */
4532 GstEvent *
4533 gst_pad_get_sticky_event (GstPad * pad, GstEventType event_type, guint idx)
4534 {
4535   GstEvent *event = NULL;
4536   PadEvent *ev;
4537
4538   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
4539   g_return_val_if_fail ((event_type & GST_EVENT_TYPE_STICKY) != 0, NULL);
4540
4541   GST_OBJECT_LOCK (pad);
4542   ev = find_event_by_type (pad, event_type, idx);
4543   if (ev && (event = ev->event))
4544     gst_event_ref (event);
4545   GST_OBJECT_UNLOCK (pad);
4546
4547   return event;
4548 }
4549
4550 typedef struct
4551 {
4552   GstPadStickyEventsForeachFunction func;
4553   gpointer user_data;
4554 } ForeachDispatch;
4555
4556 static gboolean
4557 foreach_dispatch_function (GstPad * pad, PadEvent * ev, gpointer user_data)
4558 {
4559   ForeachDispatch *data = user_data;
4560   gboolean ret;
4561
4562   GST_OBJECT_UNLOCK (pad);
4563
4564   ret = data->func (pad, &ev->event, data->user_data);
4565
4566   GST_OBJECT_LOCK (pad);
4567
4568   return ret;
4569 }
4570
4571 /**
4572  * gst_pad_sticky_events_foreach:
4573  * @pad: the #GstPad that should be used for iteration.
4574  * @foreach_func: (scope call): the #GstPadStickyEventsForeachFunction that
4575  *                should be called for every event.
4576  * @user_data: (closure): the optional user data.
4577  *
4578  * Iterates all sticky events on @pad and calls @foreach_func for every
4579  * event. If @foreach_func returns %FALSE the iteration is immediately stopped.
4580  */
4581 void
4582 gst_pad_sticky_events_foreach (GstPad * pad,
4583     GstPadStickyEventsForeachFunction foreach_func, gpointer user_data)
4584 {
4585   ForeachDispatch data;
4586
4587   g_return_if_fail (GST_IS_PAD (pad));
4588   g_return_if_fail (foreach_func != NULL);
4589
4590   data.func = foreach_func;
4591   data.user_data = user_data;
4592
4593   GST_OBJECT_LOCK (pad);
4594   events_foreach (pad, foreach_dispatch_function, &data);
4595   GST_OBJECT_UNLOCK (pad);
4596 }
4597
4598 static void
4599 do_stream_status (GstPad * pad, GstStreamStatusType type,
4600     GThread * thread, GstTask * task)
4601 {
4602   GstElement *parent;
4603
4604   GST_DEBUG_OBJECT (pad, "doing stream-status %d", type);
4605
4606   if ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (pad)))) {
4607     if (GST_IS_ELEMENT (parent)) {
4608       GstMessage *message;
4609       GValue value = { 0 };
4610
4611       if (type == GST_STREAM_STATUS_TYPE_ENTER) {
4612         gchar *tname, *ename, *pname;
4613
4614         /* create a good task name */
4615         ename = gst_element_get_name (parent);
4616         pname = gst_pad_get_name (pad);
4617         tname = g_strdup_printf ("%s:%s", ename, pname);
4618         g_free (ename);
4619         g_free (pname);
4620
4621         gst_object_set_name (GST_OBJECT_CAST (task), tname);
4622         g_free (tname);
4623       }
4624
4625       message = gst_message_new_stream_status (GST_OBJECT_CAST (pad),
4626           type, parent);
4627
4628       g_value_init (&value, GST_TYPE_TASK);
4629       g_value_set_object (&value, task);
4630       gst_message_set_stream_status_object (message, &value);
4631       g_value_unset (&value);
4632
4633       GST_DEBUG_OBJECT (pad, "posting stream-status %d", type);
4634       gst_element_post_message (parent, message);
4635     }
4636     gst_object_unref (parent);
4637   }
4638 }
4639
4640 static void
4641 pad_enter_thread (GstTask * task, GThread * thread, gpointer user_data)
4642 {
4643   do_stream_status (GST_PAD_CAST (user_data), GST_STREAM_STATUS_TYPE_ENTER,
4644       thread, task);
4645 }
4646
4647 static void
4648 pad_leave_thread (GstTask * task, GThread * thread, gpointer user_data)
4649 {
4650   do_stream_status (GST_PAD_CAST (user_data), GST_STREAM_STATUS_TYPE_LEAVE,
4651       thread, task);
4652 }
4653
4654 static GstTaskThreadCallbacks thr_callbacks = {
4655   pad_enter_thread,
4656   pad_leave_thread,
4657 };
4658
4659 /**
4660  * gst_pad_start_task:
4661  * @pad: the #GstPad to start the task of
4662  * @func: the task function to call
4663  * @data: data passed to the task function
4664  *
4665  * Starts a task that repeatedly calls @func with @data. This function
4666  * is mostly used in pad activation functions to start the dataflow.
4667  * The #GST_PAD_STREAM_LOCK of @pad will automatically be acquired
4668  * before @func is called.
4669  *
4670  * Returns: a %TRUE if the task could be started.
4671  */
4672 gboolean
4673 gst_pad_start_task (GstPad * pad, GstTaskFunction func, gpointer data)
4674 {
4675   GstTask *task;
4676   gboolean res;
4677
4678   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4679   g_return_val_if_fail (func != NULL, FALSE);
4680
4681   GST_DEBUG_OBJECT (pad, "start task");
4682
4683   GST_OBJECT_LOCK (pad);
4684   task = GST_PAD_TASK (pad);
4685   if (task == NULL) {
4686     task = gst_task_new (func, data);
4687     gst_task_set_lock (task, GST_PAD_GET_STREAM_LOCK (pad));
4688     gst_task_set_thread_callbacks (task, &thr_callbacks, pad, NULL);
4689     GST_DEBUG_OBJECT (pad, "created task");
4690     GST_PAD_TASK (pad) = task;
4691     gst_object_ref (task);
4692     /* release lock to post the message */
4693     GST_OBJECT_UNLOCK (pad);
4694
4695     do_stream_status (pad, GST_STREAM_STATUS_TYPE_CREATE, NULL, task);
4696
4697     gst_object_unref (task);
4698
4699     GST_OBJECT_LOCK (pad);
4700     /* nobody else is supposed to have changed the pad now */
4701     if (GST_PAD_TASK (pad) != task)
4702       goto concurrent_stop;
4703   }
4704   res = gst_task_set_state (task, GST_TASK_STARTED);
4705   GST_OBJECT_UNLOCK (pad);
4706
4707   return res;
4708
4709   /* ERRORS */
4710 concurrent_stop:
4711   {
4712     GST_OBJECT_UNLOCK (pad);
4713     return TRUE;
4714   }
4715 }
4716
4717 /**
4718  * gst_pad_pause_task:
4719  * @pad: the #GstPad to pause the task of
4720  *
4721  * Pause the task of @pad. This function will also wait until the
4722  * function executed by the task is finished if this function is not
4723  * called from the task function.
4724  *
4725  * Returns: a TRUE if the task could be paused or FALSE when the pad
4726  * has no task.
4727  */
4728 gboolean
4729 gst_pad_pause_task (GstPad * pad)
4730 {
4731   GstTask *task;
4732   gboolean res;
4733
4734   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4735
4736   GST_DEBUG_OBJECT (pad, "pause task");
4737
4738   GST_OBJECT_LOCK (pad);
4739   task = GST_PAD_TASK (pad);
4740   if (task == NULL)
4741     goto no_task;
4742   res = gst_task_set_state (task, GST_TASK_PAUSED);
4743   GST_OBJECT_UNLOCK (pad);
4744
4745   /* wait for task function to finish, this lock is recursive so it does nothing
4746    * when the pause is called from the task itself */
4747   GST_PAD_STREAM_LOCK (pad);
4748   GST_PAD_STREAM_UNLOCK (pad);
4749
4750   return res;
4751
4752 no_task:
4753   {
4754     GST_DEBUG_OBJECT (pad, "pad has no task");
4755     GST_OBJECT_UNLOCK (pad);
4756     return FALSE;
4757   }
4758 }
4759
4760 /**
4761  * gst_pad_stop_task:
4762  * @pad: the #GstPad to stop the task of
4763  *
4764  * Stop the task of @pad. This function will also make sure that the
4765  * function executed by the task will effectively stop if not called
4766  * from the GstTaskFunction.
4767  *
4768  * This function will deadlock if called from the GstTaskFunction of
4769  * the task. Use gst_task_pause() instead.
4770  *
4771  * Regardless of whether the pad has a task, the stream lock is acquired and
4772  * released so as to ensure that streaming through this pad has finished.
4773  *
4774  * Returns: a TRUE if the task could be stopped or FALSE on error.
4775  */
4776 gboolean
4777 gst_pad_stop_task (GstPad * pad)
4778 {
4779   GstTask *task;
4780   gboolean res;
4781
4782   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4783
4784   GST_DEBUG_OBJECT (pad, "stop task");
4785
4786   GST_OBJECT_LOCK (pad);
4787   task = GST_PAD_TASK (pad);
4788   if (task == NULL)
4789     goto no_task;
4790   GST_PAD_TASK (pad) = NULL;
4791   res = gst_task_set_state (task, GST_TASK_STOPPED);
4792   GST_OBJECT_UNLOCK (pad);
4793
4794   GST_PAD_STREAM_LOCK (pad);
4795   GST_PAD_STREAM_UNLOCK (pad);
4796
4797   if (!gst_task_join (task))
4798     goto join_failed;
4799
4800   gst_object_unref (task);
4801
4802   return res;
4803
4804 no_task:
4805   {
4806     GST_DEBUG_OBJECT (pad, "no task");
4807     GST_OBJECT_UNLOCK (pad);
4808
4809     GST_PAD_STREAM_LOCK (pad);
4810     GST_PAD_STREAM_UNLOCK (pad);
4811
4812     /* this is not an error */
4813     return TRUE;
4814   }
4815 join_failed:
4816   {
4817     /* this is bad, possibly the application tried to join the task from
4818      * the task's thread. We install the task again so that it will be stopped
4819      * again from the right thread next time hopefully. */
4820     GST_OBJECT_LOCK (pad);
4821     GST_DEBUG_OBJECT (pad, "join failed");
4822     /* we can only install this task if there was no other task */
4823     if (GST_PAD_TASK (pad) == NULL)
4824       GST_PAD_TASK (pad) = task;
4825     GST_OBJECT_UNLOCK (pad);
4826
4827     return FALSE;
4828   }
4829 }