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