27cc978d059db411016723a282f4abc6cd7be665
[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 #include "gst_private.h"
24
25 #include "gstpad.h"
26 #include "gstmarshal.h"
27 #include "gstutils.h"
28 #include "gstelement.h"
29 #include "gstbin.h"
30 #include "gstscheduler.h"
31 #include "gstevent.h"
32 #include "gstinfo.h"
33 #include "gsterror.h"
34 #include "gstvalue.h"
35
36 GST_DEBUG_CATEGORY_STATIC (debug_dataflow);
37 #define DEBUG_DATA(obj,data,notice) G_STMT_START{\
38   if (!data) { \
39     GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "NULL data value"); \
40   } else if (GST_IS_EVENT (data)) { \
41     GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "%s event %p (type %d, refcount %d)", notice, data, \
42         GST_EVENT_TYPE (data), GST_DATA_REFCOUNT_VALUE (data)); \
43   } else { \
44     GST_CAT_LOG_OBJECT (debug_dataflow, obj, "%s buffer %p (size %u, refcount %d)", notice, data, \
45         GST_BUFFER_SIZE (data), GST_BUFFER_REFCOUNT_VALUE (data)); \
46   } \
47 }G_STMT_END
48 #define GST_CAT_DEFAULT GST_CAT_PADS
49
50 /* realize and pad and grab the lock of the realized pad. */
51 #define GST_PAD_REALIZE_AND_LOCK(pad, realpad, lost_ghostpad)   \
52   GST_LOCK (pad);                                               \
53   realpad = GST_PAD_REALIZE (pad);                              \
54   if (G_UNLIKELY (realpad == NULL)) {                           \
55     GST_UNLOCK (pad);                                           \
56     goto lost_ghostpad;                                         \
57   }                                                             \
58   if (G_UNLIKELY (pad != GST_PAD_CAST (realpad))) {             \
59     GST_LOCK (realpad);                                         \
60     GST_UNLOCK (pad);                                           \
61   }
62
63 enum
64 {
65   TEMPL_PAD_CREATED,
66   /* FILL ME */
67   TEMPL_LAST_SIGNAL
68 };
69
70 static GstObject *padtemplate_parent_class = NULL;
71 static guint gst_pad_template_signals[TEMPL_LAST_SIGNAL] = { 0 };
72
73 GType _gst_pad_type = 0;
74
75 /***** Start with the base GstPad class *****/
76 static void gst_pad_class_init (GstPadClass * klass);
77 static void gst_pad_init (GstPad * pad);
78 static void gst_pad_dispose (GObject * object);
79
80 static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
81
82 #ifndef GST_DISABLE_LOADSAVE
83 static xmlNodePtr gst_pad_save_thyself (GstObject * object, xmlNodePtr parent);
84 #endif
85
86 static GstObject *pad_parent_class = NULL;
87
88 GType
89 gst_pad_get_type (void)
90 {
91   if (!_gst_pad_type) {
92     static const GTypeInfo pad_info = {
93       sizeof (GstPadClass), NULL, NULL,
94       (GClassInitFunc) gst_pad_class_init, NULL, NULL,
95       sizeof (GstPad),
96       0,
97       (GInstanceInitFunc) gst_pad_init, NULL
98     };
99
100     _gst_pad_type = g_type_register_static (GST_TYPE_OBJECT, "GstPad",
101         &pad_info, 0);
102
103     GST_DEBUG_CATEGORY_INIT (debug_dataflow, "GST_DATAFLOW",
104         GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "dataflow inside pads");
105   }
106   return _gst_pad_type;
107 }
108
109 static void
110 gst_pad_class_init (GstPadClass * klass)
111 {
112   GObjectClass *gobject_class;
113
114   gobject_class = (GObjectClass *) klass;
115
116   pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
117
118   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
119 }
120
121 static void
122 gst_pad_init (GstPad * pad)
123 {
124   /* all structs are initialized to NULL by glib */
125 }
126 static void
127 gst_pad_dispose (GObject * object)
128 {
129   GstPad *pad = GST_PAD (object);
130
131   gst_pad_set_pad_template (pad, NULL);
132   /* FIXME, we have links to many other things like caps
133    * and the peer pad... */
134
135   G_OBJECT_CLASS (pad_parent_class)->dispose (object);
136 }
137
138
139
140 /***** Then do the Real Pad *****/
141 /* Pad signals and args */
142 enum
143 {
144   REAL_LINKED,
145   REAL_UNLINKED,
146   REAL_REQUEST_LINK,
147   /* FILL ME */
148   REAL_LAST_SIGNAL
149 };
150
151 enum
152 {
153   REAL_ARG_0,
154   REAL_ARG_CAPS,
155   REAL_ARG_ACTIVE
156       /* FILL ME */
157 };
158
159 static void gst_real_pad_class_init (GstRealPadClass * klass);
160 static void gst_real_pad_init (GstRealPad * pad);
161 static void gst_real_pad_dispose (GObject * object);
162 static void gst_real_pad_finalize (GObject * object);
163
164 static void gst_real_pad_set_property (GObject * object, guint prop_id,
165     const GValue * value, GParamSpec * pspec);
166 static void gst_real_pad_get_property (GObject * object, guint prop_id,
167     GValue * value, GParamSpec * pspec);
168 static GstCaps *gst_real_pad_get_caps_unlocked (GstRealPad * realpad);
169
170 GType _gst_real_pad_type = 0;
171
172 static GstPad *real_pad_parent_class = NULL;
173 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
174
175 GType
176 gst_real_pad_get_type (void)
177 {
178   if (!_gst_real_pad_type) {
179     static const GTypeInfo pad_info = {
180       sizeof (GstRealPadClass), NULL, NULL,
181       (GClassInitFunc) gst_real_pad_class_init, NULL, NULL,
182       sizeof (GstRealPad),
183       0,
184       (GInstanceInitFunc) gst_real_pad_init, NULL
185     };
186
187     _gst_real_pad_type = g_type_register_static (GST_TYPE_PAD, "GstRealPad",
188         &pad_info, 0);
189   }
190   return _gst_real_pad_type;
191 }
192
193 static void
194 gst_real_pad_class_init (GstRealPadClass * klass)
195 {
196   GObjectClass *gobject_class;
197   GstObjectClass *gstobject_class;
198
199   gobject_class = (GObjectClass *) klass;
200   gstobject_class = (GstObjectClass *) klass;
201
202   real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
203
204   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
205   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_real_pad_finalize);
206   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
207   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
208
209   gst_real_pad_signals[REAL_LINKED] =
210       g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
211       G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
212       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
213   gst_real_pad_signals[REAL_UNLINKED] =
214       g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
215       G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL,
216       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
217   gst_real_pad_signals[REAL_REQUEST_LINK] =
218       g_signal_new ("request_link", G_TYPE_FROM_CLASS (klass),
219       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRealPadClass, request_link), NULL,
220       NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 0);
221
222   g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
223       g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
224           TRUE, G_PARAM_READWRITE));
225   g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_CAPS,
226       g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
227           GST_TYPE_CAPS, G_PARAM_READABLE));
228
229 #ifndef GST_DISABLE_LOADSAVE
230   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
231 #endif
232   gstobject_class->path_string_separator = ".";
233 }
234
235 static void
236 gst_real_pad_init (GstRealPad * pad)
237 {
238   pad->direction = GST_PAD_UNKNOWN;
239   pad->peer = NULL;
240
241   pad->chainfunc = NULL;
242
243   pad->ghostpads = NULL;
244   pad->caps = NULL;
245
246   pad->linkfunc = NULL;
247   pad->getcapsfunc = NULL;
248
249   pad->eventfunc = gst_pad_event_default;
250   pad->convertfunc = gst_pad_convert_default;
251   pad->queryfunc = gst_pad_query_default;
252   pad->intlinkfunc = gst_pad_get_internal_links_default;
253
254   pad->eventmaskfunc = gst_pad_get_event_masks_default;
255   pad->formatsfunc = gst_pad_get_formats_default;
256   pad->querytypefunc = gst_pad_get_query_types_default;
257
258   GST_FLAG_UNSET (pad, GST_PAD_ACTIVE);
259
260   pad->preroll_lock = g_mutex_new ();
261   pad->preroll_cond = g_cond_new ();
262
263   pad->stream_rec_lock = g_new (GStaticRecMutex, 1);
264   g_static_rec_mutex_init (pad->stream_rec_lock);
265
266   pad->block_cond = g_cond_new ();
267
268   gst_probe_dispatcher_init (&pad->probedisp);
269 }
270
271 static void
272 gst_real_pad_set_property (GObject * object, guint prop_id,
273     const GValue * value, GParamSpec * pspec)
274 {
275   g_return_if_fail (GST_IS_PAD (object));
276
277   switch (prop_id) {
278     case REAL_ARG_ACTIVE:
279       g_warning ("FIXME: not useful any more!!!");
280       gst_pad_set_active (GST_PAD (object), g_value_get_boolean (value));
281       break;
282     default:
283       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
284       break;
285   }
286 }
287
288 static void
289 gst_real_pad_get_property (GObject * object, guint prop_id,
290     GValue * value, GParamSpec * pspec)
291 {
292   g_return_if_fail (GST_IS_PAD (object));
293
294   switch (prop_id) {
295     case REAL_ARG_ACTIVE:
296       g_value_set_boolean (value, GST_FLAG_IS_SET (object, GST_PAD_ACTIVE));
297       break;
298     case REAL_ARG_CAPS:
299       g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object)));
300       break;
301     default:
302       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
303       break;
304   }
305 }
306
307 /* FIXME-0.9: Replace these custom functions with proper inheritance via _init
308    functions and object properties. update: probably later in the cycle. */
309 /**
310  * gst_pad_custom_new:
311  * @type: the #Gtype of the pad.
312  * @name: the name of the new pad.
313  * @direction: the #GstPadDirection of the pad.
314  *
315  * Creates a new pad with the given name and type in the given direction.
316  * If name is NULL, a guaranteed unique name (across all pads) 
317  * will be assigned. 
318  * This function makes a copy of the name so you can safely free the name.
319  *
320  * Returns: a new #GstPad, or NULL in case of an error.
321  *
322  * MT safe.
323  */
324 GstPad *
325 gst_pad_custom_new (GType type, const gchar * name, GstPadDirection direction)
326 {
327   GstRealPad *pad;
328
329   pad = g_object_new (type, NULL);
330   gst_object_set_name (GST_OBJECT (pad), name);
331   GST_RPAD_DIRECTION (pad) = direction;
332
333   return GST_PAD_CAST (pad);
334 }
335
336 /**
337  * gst_pad_new:
338  * @name: the name of the new pad.
339  * @direction: the #GstPadDirection of the pad.
340  *
341  * Creates a new real pad with the given name in the given direction.
342  * If name is NULL, a guaranteed unique name (across all pads) 
343  * will be assigned.
344  * This function makes a copy of the name so you can safely free the name.
345  *
346  * Returns: a new #GstPad, or NULL in case of an error.
347  *
348  * MT safe.
349  */
350 GstPad *
351 gst_pad_new (const gchar * name, GstPadDirection direction)
352 {
353   return gst_pad_custom_new (gst_real_pad_get_type (), name, direction);
354 }
355
356 /**
357  * gst_pad_custom_new_from_template:
358  * @type: the custom #GType of the pad.
359  * @templ: the #GstPadTemplate to instantiate from.
360  * @name: the name of the new pad.
361  *
362  * Creates a new custom pad with the given name from the given template.
363  * If name is NULL, a guaranteed unique name (across all pads) 
364  * will be assigned.
365  * This function makes a copy of the name so you can safely free the name.
366  *
367  * Returns: a new #GstPad, or NULL in case of an error.
368  */
369 GstPad *
370 gst_pad_custom_new_from_template (GType type, GstPadTemplate * templ,
371     const gchar * name)
372 {
373   GstPad *pad;
374
375   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
376
377   pad = gst_pad_custom_new (type, name, templ->direction);
378   gst_pad_set_pad_template (pad, templ);
379
380   return pad;
381 }
382
383 /**
384  * gst_pad_new_from_template:
385  * @templ: the pad template to use
386  * @name: the name of the element
387  *
388  * Creates a new real pad with the given name from the given template.
389  * If name is NULL, a guaranteed unique name (across all pads) 
390  * will be assigned.
391  * This function makes a copy of the name so you can safely free the name.
392  *
393  * Returns: a new #GstPad, or NULL in case of an error.
394  */
395 GstPad *
396 gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
397 {
398   return gst_pad_custom_new_from_template (gst_real_pad_get_type (),
399       templ, name);
400 }
401
402 /**
403  * gst_pad_get_direction:
404  * @pad: a #GstPad to get the direction of.
405  *
406  * Gets the direction of the pad. The direction of the pad is
407  * decided at construction time so this function does not take 
408  * the LOCK.
409  *
410  * Returns: the #GstPadDirection of the pad.
411  *
412  * MT safe.
413  */
414 GstPadDirection
415 gst_pad_get_direction (GstPad * pad)
416 {
417   GstPadDirection result;
418   GstRealPad *realpad;
419
420   /* PAD_UNKNOWN is a little silly but we need some sort of
421    * error return value */
422   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
423
424   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
425   result = GST_RPAD_DIRECTION (realpad);
426   GST_UNLOCK (realpad);
427
428   return result;
429
430   /* errors */
431 lost_ghostpad:
432   {
433     return GST_PAD_UNKNOWN;
434   }
435 }
436
437 /**
438  * gst_pad_set_active:
439  * @pad: the #GstPad to activate or deactivate.
440  * @mode: the mode of the pad.
441  *
442  * Activates or deactivates the given pad in the given mode.
443  *
444  * For a source pad: PULL mode will call the getrange function,
445  * PUSH mode will require the element to call _push() on the pad.
446  *
447  * For a sink pad: PULL mode will require the element to call
448  * the _pull_range() function, PUSH mode will call the chain function.
449  *
450  * Returns: TRUE if the operation was successfull.
451  *
452  * MT safe.
453  */
454 gboolean
455 gst_pad_set_active (GstPad * pad, GstActivateMode mode)
456 {
457   GstRealPad *realpad;
458   gboolean old;
459   GstPadActivateFunction activatefunc;
460   gboolean active;
461
462   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
463
464   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
465
466   active = GST_PAD_MODE_ACTIVATE (mode);
467   old = GST_PAD_IS_ACTIVE (realpad);
468
469   /* if nothing changed, we can just exit */
470   if (G_UNLIKELY (old == active))
471     goto was_ok;
472
473   /* make sure data is disallowed when going inactive */
474   if (!active) {
475     GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s",
476         GST_DEBUG_PAD_NAME (realpad));
477     GST_FLAG_UNSET (realpad, GST_PAD_ACTIVE);
478     /* unlock blocked pads so element can resume and stop */
479     GST_PAD_BLOCK_SIGNAL (realpad);
480   }
481
482   if (active) {
483     if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SRC) {
484       if (mode == GST_ACTIVATE_PULL) {
485         if (!realpad->getrangefunc)
486           goto wrong_mode;
487       } else {
488         /* we can push if driven by a chain or loop on the sink pad.
489          * peer pad is assumed to be active now. */
490       }
491     } else {
492       /* sink pads */
493       if (mode == GST_ACTIVATE_PULL) {
494         /* the src can drive us with getrange */
495       } else {
496         if (!realpad->chainfunc)
497           goto wrong_mode;
498       }
499     }
500   }
501
502   activatefunc = realpad->activatefunc;
503   if (activatefunc) {
504     gboolean result;
505
506     GST_CAT_DEBUG (GST_CAT_PADS,
507         "calling activate function on pad %s:%s with mode %d",
508         GST_DEBUG_PAD_NAME (realpad), mode);
509
510     /* unlock so element can sync */
511     GST_UNLOCK (realpad);
512     result = activatefunc (GST_PAD_CAST (realpad), mode);
513     /* and lock again */
514     GST_LOCK (realpad);
515     if (result == FALSE)
516       goto activate_error;
517   }
518
519   /* when going to active allow data passing now */
520   if (active) {
521     GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s in mode %d",
522         GST_DEBUG_PAD_NAME (realpad), mode);
523     GST_FLAG_SET (realpad, GST_PAD_ACTIVE);
524   }
525   GST_UNLOCK (realpad);
526
527   return TRUE;
528
529 was_ok:
530   {
531     GST_CAT_DEBUG (GST_CAT_PADS,
532         "pad %s:%s was active", GST_DEBUG_PAD_NAME (realpad));
533     GST_UNLOCK (realpad);
534     return TRUE;
535   }
536   /* errors */
537 lost_ghostpad:
538   {
539     return FALSE;
540   }
541 wrong_mode:
542   {
543     GST_CAT_DEBUG (GST_CAT_PADS,
544         "pad %s:%s lacks functions to be active in mode %d",
545         GST_DEBUG_PAD_NAME (realpad), mode);
546     GST_UNLOCK (realpad);
547     return FALSE;
548   }
549 activate_error:
550   {
551     GST_CAT_DEBUG (GST_CAT_PADS,
552         "activate function returned FALSE for pad %s:%s",
553         GST_DEBUG_PAD_NAME (realpad));
554     GST_UNLOCK (realpad);
555     return FALSE;
556   }
557 }
558
559 /**
560  * gst_pad_peer_set_active:
561  * @pad: the #GstPad to activate or deactivate the peer of.
562  * @mode: the mode of the pad.
563  *
564  * Activates or deactivates the given peer of a pad. Elements
565  * that will perform a _pull_range() on their sinkpads need
566  * to call this function when the sinkpad is activated or when
567  * an internally linked source pad is activated in pull mode.
568  *
569  * Returns: TRUE if the operation was successfull.
570  *
571  * MT safe.
572  */
573 gboolean
574 gst_pad_peer_set_active (GstPad * pad, GstActivateMode mode)
575 {
576   GstPad *peer;
577   gboolean result = FALSE;
578
579   peer = gst_pad_get_peer (pad);
580   if (!peer)
581     goto no_peer;
582
583   result = gst_pad_set_active (peer, mode);
584   gst_object_unref (GST_OBJECT_CAST (peer));
585
586   return result;
587
588   /* errors */
589 no_peer:
590   {
591     return FALSE;
592   }
593 }
594
595 /**
596  * gst_pad_is_active:
597  * @pad: the #GstPad to query
598  *
599  * Query if a pad is active
600  *
601  * Returns: TRUE if the pad is active.
602  *
603  * MT safe.
604  */
605 gboolean
606 gst_pad_is_active (GstPad * pad)
607 {
608   gboolean result = FALSE;
609   GstRealPad *realpad;
610
611   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
612
613   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
614   result = GST_FLAG_IS_SET (realpad, GST_PAD_ACTIVE);
615   GST_UNLOCK (realpad);
616
617   return result;
618
619 lost_ghostpad:
620   {
621     return FALSE;
622   }
623 }
624
625 /**
626  * gst_pad_set_blocked_async:
627  * @pad: the #GstPad to block or unblock
628  * @blocked: boolean indicating we should block or unblock
629  * @callback: #GstPadBlockCallback that will be called when the
630  *            operation succeeds.
631  * @user_data: user data passed to the callback
632  *
633  * Blocks or unblocks the dataflow on a pad. The provided callback
634  * is called when the operation succeeds. This can take a while as
635  * the pad can only become blocked when real dataflow is happening.
636  * When the pipeline is stalled, for example in PAUSED, this can
637  * take an indeterminate amount of time.
638  * You can pass NULL as the callback to make this call block. Be
639  * carefull with this blocking call as it might not return for
640  * reasons stated above.
641  *
642  * Returns: TRUE if the pad could be blocked. This function can fail
643  *   if wrong parameters were passed or the pad was already in the 
644  *   requested state.
645  *
646  * MT safe.
647  */
648 gboolean
649 gst_pad_set_blocked_async (GstPad * pad, gboolean blocked,
650     GstPadBlockCallback callback, gpointer user_data)
651 {
652   gboolean was_blocked;
653   GstRealPad *realpad;
654
655   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
656
657   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
658
659   was_blocked = GST_RPAD_IS_BLOCKED (realpad);
660
661   if (G_UNLIKELY (was_blocked == blocked))
662     goto had_right_state;
663
664   if (blocked) {
665     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "blocking pad %s:%s",
666         GST_DEBUG_PAD_NAME (realpad));
667
668     GST_FLAG_SET (realpad, GST_PAD_BLOCKED);
669     realpad->block_callback = callback;
670     realpad->block_data = user_data;
671     if (!callback) {
672       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "waiting for block");
673       GST_PAD_BLOCK_WAIT (realpad);
674       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "blocked");
675     }
676   } else {
677     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "unblocking pad %s:%s",
678         GST_DEBUG_PAD_NAME (realpad));
679
680     GST_FLAG_UNSET (realpad, GST_PAD_BLOCKED);
681
682     realpad->block_callback = callback;
683     realpad->block_data = user_data;
684
685     if (callback) {
686       GST_PAD_BLOCK_SIGNAL (realpad);
687     } else {
688       GST_PAD_BLOCK_SIGNAL (realpad);
689       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "waiting for unblock");
690       GST_PAD_BLOCK_WAIT (realpad);
691       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "unblocked");
692     }
693   }
694   GST_UNLOCK (realpad);
695
696   return TRUE;
697
698 lost_ghostpad:
699   {
700     return FALSE;
701   }
702 had_right_state:
703   {
704     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad,
705         "pad %s:%s was in right state", GST_DEBUG_PAD_NAME (realpad));
706     GST_UNLOCK (realpad);
707     return FALSE;
708   }
709 }
710
711 /**
712  * gst_pad_set_blocked:
713  * @pad: the #GstPad to block or unblock
714  * @blocked: boolean indicating we should block or unblock
715  *
716  * Blocks or unblocks the dataflow on a pad. This function is
717  * a shortcut for @gst_pad_set_blocked_async() with a NULL
718  * callback.
719  *
720  * Returns: TRUE if the pad could be blocked. This function can fail
721  *   wrong parameters were passed or the pad was already in the 
722  *   requested state.
723  *
724  * MT safe.
725  */
726 gboolean
727 gst_pad_set_blocked (GstPad * pad, gboolean blocked)
728 {
729   return gst_pad_set_blocked_async (pad, blocked, NULL, NULL);
730 }
731
732 /**
733  * gst_pad_is_blocked:
734  * @pad: the #GstPad to query 
735  *
736  * Checks if the pad is blocked or not. This function returns the
737  * last requested state of the pad. It is not certain that the pad
738  * is actually blocked at this point.
739  *
740  * Returns: TRUE if the pad is blocked.
741  *
742  * MT safe.
743  */
744 gboolean
745 gst_pad_is_blocked (GstPad * pad)
746 {
747   gboolean result = FALSE;
748   GstRealPad *realpad;
749
750   g_return_val_if_fail (GST_IS_PAD (pad), result);
751
752   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
753   result = GST_FLAG_IS_SET (realpad, GST_PAD_BLOCKED);
754   GST_UNLOCK (realpad);
755
756   return result;
757
758 lost_ghostpad:
759   {
760     return FALSE;
761   }
762 }
763
764 /**
765  * gst_pad_set_activate_function:
766  * @pad: a real sink #GstPad.
767  * @chain: the #GstPadActivateFunction to set.
768  *
769  * Sets the given activate function for the pad. The activate function is called to
770  * start or stop dataflow on a pad.
771  */
772 void
773 gst_pad_set_activate_function (GstPad * pad, GstPadActivateFunction activate)
774 {
775   g_return_if_fail (GST_IS_REAL_PAD (pad));
776
777   GST_RPAD_ACTIVATEFUNC (pad) = activate;
778   GST_CAT_DEBUG (GST_CAT_PADS, "activatefunc for %s:%s set to %s",
779       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (activate));
780 }
781
782 /**
783  * gst_pad_set_loop_function:
784  * @pad: a real sink #GstPad.
785  * @chain: the #GstPadLoopFunction to set.
786  *
787  * Sets the given loop function for the pad. The loop function is called 
788  * repeadedly to pull/push buffers from/to the peer pad.
789  */
790 void
791 gst_pad_set_loop_function (GstPad * pad, GstPadLoopFunction loop)
792 {
793   g_return_if_fail (GST_IS_REAL_PAD (pad));
794
795   GST_RPAD_LOOPFUNC (pad) = loop;
796   GST_CAT_DEBUG (GST_CAT_PADS, "loopfunc for %s:%s set to %s",
797       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (loop));
798 }
799
800 /**
801  * gst_pad_set_chain_function:
802  * @pad: a real sink #GstPad.
803  * @chain: the #GstPadChainFunction to set.
804  *
805  * Sets the given chain function for the pad. The chain function is called to
806  * process a #GstBuffer input buffer.
807  */
808 void
809 gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
810 {
811   g_return_if_fail (GST_IS_REAL_PAD (pad));
812   g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK);
813
814   GST_RPAD_CHAINFUNC (pad) = chain;
815   GST_CAT_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s",
816       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain));
817 }
818
819 /**
820  * gst_pad_set_getrange_function:
821  * @pad: a real source #GstPad.
822  * @get: the #GstPadGetRangeFunction to set.
823  *
824  * Sets the given getrange function for the pad. The getrange function is called to
825  * produce a new #GstBuffer to start the processing pipeline. Getrange functions cannot
826  * return %NULL.
827  */
828 void
829 gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
830 {
831   g_return_if_fail (GST_IS_REAL_PAD (pad));
832   g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
833
834   GST_RPAD_GETRANGEFUNC (pad) = get;
835
836   GST_CAT_DEBUG (GST_CAT_PADS, "getrangefunc for %s:%s  set to %s",
837       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
838 }
839
840 /**
841  * gst_pad_set_checkgetrange_function:
842  * @pad: a real source #GstPad.
843  * @check: the #GstPadCheckGetRangeFunction to set.
844  *
845  * Sets the given checkgetrange function for the pad. Implement this function on
846  * a pad if you dynamically support getrange based scheduling on the pad.
847  */
848 void
849 gst_pad_set_checkgetrange_function (GstPad * pad,
850     GstPadCheckGetRangeFunction check)
851 {
852   g_return_if_fail (GST_IS_REAL_PAD (pad));
853   g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
854
855   GST_RPAD_CHECKGETRANGEFUNC (pad) = check;
856
857   GST_CAT_DEBUG (GST_CAT_PADS, "checkgetrangefunc for %s:%s  set to %s",
858       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (check));
859 }
860
861 /**
862  * gst_pad_set_event_function:
863  * @pad: a real source #GstPad.
864  * @event: the #GstPadEventFunction to set.
865  *
866  * Sets the given event handler for the pad.
867  */
868 void
869 gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event)
870 {
871   g_return_if_fail (GST_IS_REAL_PAD (pad));
872
873   GST_RPAD_EVENTFUNC (pad) = event;
874
875   GST_CAT_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s  set to %s",
876       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event));
877 }
878
879 /**
880  * gst_pad_set_event_mask_function:
881  * @pad: a real #GstPad of either direction.
882  * @mask_func: the #GstPadEventMaskFunction to set.
883  *
884  * Sets the given event mask function for the pad.
885  */
886 void
887 gst_pad_set_event_mask_function (GstPad * pad,
888     GstPadEventMaskFunction mask_func)
889 {
890   g_return_if_fail (GST_IS_REAL_PAD (pad));
891
892   GST_RPAD_EVENTMASKFUNC (pad) = mask_func;
893
894   GST_CAT_DEBUG (GST_CAT_PADS, "eventmaskfunc for %s:%s  set to %s",
895       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (mask_func));
896 }
897
898 /**
899  * gst_pad_get_event_masks:
900  * @pad: a #GstPad.
901  *
902  * Gets the array of eventmasks from the given pad.
903  *
904  * Returns: a zero-terminated array of #GstEventMask, or NULL if the pad does
905  * not have an event mask function.
906  */
907 const GstEventMask *
908 gst_pad_get_event_masks (GstPad * pad)
909 {
910   GstRealPad *rpad;
911
912   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
913
914   rpad = GST_PAD_REALIZE (pad);
915
916   g_return_val_if_fail (rpad, NULL);
917
918   if (GST_RPAD_EVENTMASKFUNC (rpad))
919     return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD (pad));
920
921   return NULL;
922 }
923
924 static gboolean
925 gst_pad_get_event_masks_dispatcher (GstPad * pad, const GstEventMask ** data)
926 {
927   *data = gst_pad_get_event_masks (pad);
928
929   return TRUE;
930 }
931
932 /**
933  * gst_pad_get_event_masks_default:
934  * @pad: a #GstPad.
935  *
936  * Invokes the default event masks dispatcher on the pad.
937  *
938  * Returns: a zero-terminated array of #GstEventMask, or NULL if none of the
939  * internally-linked pads have an event mask function.
940  */
941 const GstEventMask *
942 gst_pad_get_event_masks_default (GstPad * pad)
943 {
944   GstEventMask *result = NULL;
945
946   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
947
948   gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
949       gst_pad_get_event_masks_dispatcher, &result);
950
951   return result;
952 }
953
954 /**
955  * gst_pad_set_convert_function:
956  * @pad: a real #GstPad of either direction.
957  * @convert: the #GstPadConvertFunction to set.
958  *
959  * Sets the given convert function for the pad.
960  */
961 void
962 gst_pad_set_convert_function (GstPad * pad, GstPadConvertFunction convert)
963 {
964   g_return_if_fail (GST_IS_REAL_PAD (pad));
965
966   GST_RPAD_CONVERTFUNC (pad) = convert;
967
968   GST_CAT_DEBUG (GST_CAT_PADS, "convertfunc for %s:%s  set to %s",
969       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (convert));
970 }
971
972 /**
973  * gst_pad_set_query_function:
974  * @pad: a real #GstPad of either direction.
975  * @query: the #GstPadQueryFunction to set.
976  *
977  * Set the given query function for the pad.
978  */
979 void
980 gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
981 {
982   g_return_if_fail (GST_IS_REAL_PAD (pad));
983
984   GST_RPAD_QUERYFUNC (pad) = query;
985
986   GST_CAT_DEBUG (GST_CAT_PADS, "queryfunc for %s:%s  set to %s",
987       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
988 }
989
990 /**
991  * gst_pad_set_query_type_function:
992  * @pad: a real #GstPad of either direction.
993  * @type_func: the #GstPadQueryTypeFunction to set.
994  *
995  * Set the given query type function for the pad.
996  */
997 void
998 gst_pad_set_query_type_function (GstPad * pad,
999     GstPadQueryTypeFunction type_func)
1000 {
1001   g_return_if_fail (GST_IS_REAL_PAD (pad));
1002
1003   GST_RPAD_QUERYTYPEFUNC (pad) = type_func;
1004
1005   GST_CAT_DEBUG (GST_CAT_PADS, "querytypefunc for %s:%s  set to %s",
1006       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (type_func));
1007 }
1008
1009 /**
1010  * gst_pad_get_query_types:
1011  * @pad: a #GstPad.
1012  *
1013  * Get an array of supported queries that can be performed
1014  * on this pad.
1015  *
1016  * Returns: a zero-terminated array of #GstQueryType.
1017  */
1018 const GstQueryType *
1019 gst_pad_get_query_types (GstPad * pad)
1020 {
1021   GstRealPad *rpad;
1022
1023   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1024
1025   rpad = GST_PAD_REALIZE (pad);
1026
1027   g_return_val_if_fail (rpad, NULL);
1028
1029   if (GST_RPAD_QUERYTYPEFUNC (rpad))
1030     return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD (pad));
1031
1032   return NULL;
1033 }
1034
1035 static gboolean
1036 gst_pad_get_query_types_dispatcher (GstPad * pad, const GstQueryType ** data)
1037 {
1038   *data = gst_pad_get_query_types (pad);
1039
1040   return TRUE;
1041 }
1042
1043 /**
1044  * gst_pad_get_query_types_default:
1045  * @pad: a #GstPad.
1046  *
1047  * Invoke the default dispatcher for the query types on
1048  * the pad.
1049  *
1050  * Returns: an zero-terminated array of #GstQueryType, or NULL if none of the
1051  * internally-linked pads has a query types function.
1052  */
1053 const GstQueryType *
1054 gst_pad_get_query_types_default (GstPad * pad)
1055 {
1056   GstQueryType *result = NULL;
1057
1058   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1059
1060   gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
1061       gst_pad_get_query_types_dispatcher, &result);
1062
1063   return result;
1064 }
1065
1066 /**
1067  * gst_pad_set_internal_link_function:
1068  * @pad: a real #GstPad of either direction.
1069  * @intlink: the #GstPadIntLinkFunction to set.
1070  *
1071  * Sets the given internal link function for the pad.
1072  */
1073 void
1074 gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink)
1075 {
1076   g_return_if_fail (GST_IS_REAL_PAD (pad));
1077
1078   GST_RPAD_INTLINKFUNC (pad) = intlink;
1079   GST_CAT_DEBUG (GST_CAT_PADS, "internal link for %s:%s  set to %s",
1080       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intlink));
1081 }
1082
1083 /**
1084  * gst_pad_set_formats_function:
1085  * @pad: a real #GstPad of either direction.
1086  * @formats: the #GstPadFormatsFunction to set.
1087  *
1088  * Sets the given formats function for the pad.
1089  */
1090 void
1091 gst_pad_set_formats_function (GstPad * pad, GstPadFormatsFunction formats)
1092 {
1093   g_return_if_fail (GST_IS_REAL_PAD (pad));
1094
1095   GST_RPAD_FORMATSFUNC (pad) = formats;
1096   GST_CAT_DEBUG (GST_CAT_PADS, "formats function for %s:%s  set to %s",
1097       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (formats));
1098 }
1099
1100 /**
1101  * gst_pad_set_link_function:
1102  * @pad: a real #GstPad.
1103  * @link: the #GstPadLinkFunction to set.
1104  * 
1105  * Sets the given link function for the pad. It will be called when the pad is
1106  * linked or relinked with caps. The caps passed to the link function is
1107  * the filtered caps for the connnection. It can contain a non fixed caps.
1108  * 
1109  * The return value GST_PAD_LINK_OK should be used when the connection can be
1110  * made.
1111  * 
1112  * The return value GST_PAD_LINK_REFUSED should be used when the connection
1113  * cannot be made for some reason.
1114  */
1115 void
1116 gst_pad_set_link_function (GstPad * pad, GstPadLinkFunction link)
1117 {
1118   g_return_if_fail (GST_IS_REAL_PAD (pad));
1119
1120   GST_RPAD_LINKFUNC (pad) = link;
1121   GST_CAT_DEBUG (GST_CAT_PADS, "linkfunc for %s:%s set to %s",
1122       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (link));
1123 }
1124
1125 /**
1126  * gst_pad_set_unlink_function:
1127  * @pad: a real #GstPad.
1128  * @unlink: the #GstPadUnlinkFunction to set.
1129  *
1130  * Sets the given unlink function for the pad. It will be called
1131  * when the pad is unlinked.
1132  */
1133 void
1134 gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
1135 {
1136   g_return_if_fail (GST_IS_REAL_PAD (pad));
1137
1138   GST_RPAD_UNLINKFUNC (pad) = unlink;
1139   GST_CAT_DEBUG (GST_CAT_PADS, "unlinkfunc for %s:%s set to %s",
1140       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (unlink));
1141 }
1142
1143 /**
1144  * gst_pad_set_getcaps_function:
1145  * @pad: a real #GstPad.
1146  * @getcaps: the #GstPadGetCapsFunction to set.
1147  * 
1148  * Sets the given getcaps function for the pad. @getcaps should return the
1149  * allowable caps for a pad in the context of the element's state, its link to
1150  * other elements, and the devices or files it has opened. These caps must be a
1151  * subset of the pad template caps. In the NULL state with no links, @getcaps
1152  * should ideally return the same caps as the pad template. In rare
1153  * circumstances, an object property can affect the caps returned by @getcaps,
1154  * but this is discouraged.
1155  *
1156  * You do not need to call this function if @pad's allowed caps are always the
1157  * same as the pad template caps. This can only be true if the padtemplate 
1158  * has fixed simple caps.
1159  *
1160  * For most filters, the caps returned by @getcaps is directly affected by the
1161  * allowed caps on other pads. For demuxers and decoders, the caps returned by
1162  * the srcpad's getcaps function is directly related to the stream data. Again,
1163  * @getcaps should return the most specific caps it reasonably can, since this
1164  * helps with autoplugging. 
1165  *
1166  * Note that the return value from @getcaps is owned by the caller, so the caller
1167  * should unref the caps after usage.
1168  */
1169 void
1170 gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
1171 {
1172   g_return_if_fail (GST_IS_REAL_PAD (pad));
1173
1174   GST_RPAD_GETCAPSFUNC (pad) = getcaps;
1175   GST_CAT_DEBUG (GST_CAT_PADS, "getcapsfunc for %s:%s set to %s",
1176       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
1177 }
1178
1179 /**
1180  * gst_pad_set_acceptcaps_function:
1181  * @pad: a real #GstPad.
1182  * @acceptcaps: the #GstPadAcceptCapsFunction to set.
1183  *
1184  * Sets the given acceptcaps function for the pad.  The acceptcaps function
1185  * will be called to check if the pad can accept the given caps.
1186  */
1187 void
1188 gst_pad_set_acceptcaps_function (GstPad * pad,
1189     GstPadAcceptCapsFunction acceptcaps)
1190 {
1191   g_return_if_fail (GST_IS_REAL_PAD (pad));
1192
1193   GST_RPAD_ACCEPTCAPSFUNC (pad) = acceptcaps;
1194   GST_CAT_DEBUG (GST_CAT_PADS, "acceptcapsfunc for %s:%s set to %s",
1195       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (acceptcaps));
1196 }
1197
1198 /**
1199  * gst_pad_set_fixatecaps_function:
1200  * @pad: a real #GstPad.
1201  * @fixatecaps: the #GstPadFixateCapsFunction to set.
1202  *
1203  * Sets the given fixatecaps function for the pad.  The fixatecaps function
1204  * will be called whenever the default values for a GstCaps needs to be
1205  * filled in.
1206  */
1207 void
1208 gst_pad_set_fixatecaps_function (GstPad * pad,
1209     GstPadFixateCapsFunction fixatecaps)
1210 {
1211   g_return_if_fail (GST_IS_REAL_PAD (pad));
1212
1213   GST_RPAD_FIXATECAPSFUNC (pad) = fixatecaps;
1214   GST_CAT_DEBUG (GST_CAT_PADS, "fixatecapsfunc for %s:%s set to %s",
1215       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (fixatecaps));
1216 }
1217
1218 /**
1219  * gst_pad_set_setcaps_function:
1220  * @pad: a real #GstPad.
1221  * @setcaps: the #GstPadSetCapsFunction to set.
1222  *
1223  * Sets the given setcaps function for the pad.  The setcaps function
1224  * will be called whenever a buffer with a new media type is pushed or
1225  * pulled from the pad. The pad/element needs to update it's internal
1226  * structures to process the new media type. If this new type is not
1227  * acceptable, the setcaps function should return FALSE.
1228  */
1229 void
1230 gst_pad_set_setcaps_function (GstPad * pad, GstPadSetCapsFunction setcaps)
1231 {
1232   g_return_if_fail (GST_IS_REAL_PAD (pad));
1233
1234   GST_RPAD_SETCAPSFUNC (pad) = setcaps;
1235   GST_CAT_DEBUG (GST_CAT_PADS, "setcapsfunc for %s:%s set to %s",
1236       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (setcaps));
1237 }
1238
1239 /**
1240  * gst_pad_set_bufferalloc_function:
1241  * @pad: a real sink #GstPad.
1242  * @bufalloc: the #GstPadBufferAllocFunction to set.
1243  *
1244  * Sets the given bufferalloc function for the pad. Note that the
1245  * bufferalloc function can only be set on sinkpads.
1246  */
1247 void
1248 gst_pad_set_bufferalloc_function (GstPad * pad,
1249     GstPadBufferAllocFunction bufalloc)
1250 {
1251   g_return_if_fail (GST_IS_REAL_PAD (pad));
1252   g_return_if_fail (GST_PAD_IS_SINK (pad));
1253
1254   GST_RPAD_BUFFERALLOCFUNC (pad) = bufalloc;
1255   GST_CAT_DEBUG (GST_CAT_PADS, "bufferallocfunc for %s:%s set to %s",
1256       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (bufalloc));
1257 }
1258
1259 /**
1260  * gst_pad_unlink:
1261  * @srcpad: the source #GstPad to unlink.
1262  * @sinkpad: the sink #GstPad to unlink.
1263  *
1264  * Unlinks the source pad from the sink pad. Will emit the "unlinked" signal on
1265  * both pads.
1266  *
1267  * Returns: TRUE if the pads were unlinked. This function returns FALSE if
1268  * the pads were not linked together.
1269  *
1270  * MT safe.
1271  */
1272 gboolean
1273 gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
1274 {
1275   GstRealPad *realsrc, *realsink;
1276
1277   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1278   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1279
1280   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)",
1281       GST_DEBUG_PAD_NAME (srcpad), srcpad,
1282       GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
1283
1284   GST_PAD_REALIZE_AND_LOCK (srcpad, realsrc, lost_src_ghostpad);
1285
1286   if (G_UNLIKELY (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC))
1287     goto not_srcpad;
1288
1289   GST_PAD_REALIZE_AND_LOCK (sinkpad, realsink, lost_sink_ghostpad);
1290
1291   if (G_UNLIKELY (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK))
1292     goto not_sinkpad;
1293
1294   if (G_UNLIKELY (GST_RPAD_PEER (realsrc) != realsink))
1295     goto not_linked_together;
1296
1297   if (GST_RPAD_UNLINKFUNC (realsrc)) {
1298     GST_RPAD_UNLINKFUNC (realsrc) (GST_PAD (realsrc));
1299   }
1300   if (GST_RPAD_UNLINKFUNC (realsink)) {
1301     GST_RPAD_UNLINKFUNC (realsink) (GST_PAD (realsink));
1302   }
1303
1304   /* first clear peers */
1305   GST_RPAD_PEER (realsrc) = NULL;
1306   GST_RPAD_PEER (realsink) = NULL;
1307
1308   /* clear filter, note that we leave the pad caps as they are */
1309   gst_caps_replace (&GST_RPAD_APPFILTER (realsrc), NULL);
1310   gst_caps_replace (&GST_RPAD_APPFILTER (realsink), NULL);
1311
1312   GST_UNLOCK (realsink);
1313   GST_UNLOCK (realsrc);
1314
1315   /* fire off a signal to each of the pads telling them 
1316    * that they've been unlinked */
1317   g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_UNLINKED],
1318       0, realsink);
1319   g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_UNLINKED],
1320       0, realsrc);
1321
1322   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
1323       GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1324
1325   return TRUE;
1326
1327 lost_src_ghostpad:
1328   {
1329     return FALSE;
1330   }
1331 not_srcpad:
1332   {
1333     g_critical ("pad %s is not a source pad", GST_PAD_NAME (realsrc));
1334     GST_UNLOCK (realsrc);
1335     return FALSE;
1336   }
1337 lost_sink_ghostpad:
1338   {
1339     GST_UNLOCK (realsrc);
1340     return FALSE;
1341   }
1342 not_sinkpad:
1343   {
1344     g_critical ("pad %s is not a sink pad", GST_PAD_NAME (realsink));
1345     GST_UNLOCK (realsink);
1346     GST_UNLOCK (realsrc);
1347     return FALSE;
1348   }
1349 not_linked_together:
1350   {
1351     /* we do not emit a warning in this case because unlinking cannot
1352      * be made MT safe.*/
1353     GST_UNLOCK (realsink);
1354     GST_UNLOCK (realsrc);
1355     return FALSE;
1356   }
1357 }
1358
1359 /**
1360  * gst_pad_is_linked:
1361  * @pad: pad to check
1362  *
1363  * Checks if a @pad is linked to another pad or not.
1364  *
1365  * Returns: TRUE if the pad is linked, FALSE otherwise.
1366  *
1367  * MT safe.
1368  */
1369 gboolean
1370 gst_pad_is_linked (GstPad * pad)
1371 {
1372   gboolean result;
1373   GstRealPad *realpad;
1374
1375   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1376
1377   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
1378   result = (GST_PAD_PEER (realpad) != NULL);
1379   GST_UNLOCK (realpad);
1380   return result;
1381
1382 lost_ghostpad:
1383   {
1384     return FALSE;
1385   }
1386 }
1387
1388 /* FIXME leftover from an attempt at refactoring... */
1389 static GstPadLinkReturn
1390 gst_pad_link_prepare_filtered (GstPad * srcpad, GstPad * sinkpad,
1391     GstRealPad ** outrealsrc, GstRealPad ** outrealsink,
1392     const GstCaps * filtercaps)
1393 {
1394   GstRealPad *realsrc, *realsink;
1395
1396   /* generic checks */
1397   g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
1398   g_return_val_if_fail (GST_IS_PAD (sinkpad), GST_PAD_LINK_REFUSED);
1399
1400   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
1401       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1402
1403   /* now we need to deal with the real/ghost stuff */
1404   GST_PAD_REALIZE_AND_LOCK (srcpad, realsrc, lost_src_ghostpad);
1405
1406   if (G_UNLIKELY (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC))
1407     goto not_srcpad;
1408
1409   if (G_UNLIKELY (GST_RPAD_PEER (realsrc) != NULL))
1410     goto src_was_linked;
1411
1412   GST_PAD_REALIZE_AND_LOCK (sinkpad, realsink, lost_sink_ghostpad);
1413
1414   if (G_UNLIKELY (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK))
1415     goto not_sinkpad;
1416
1417   if (G_UNLIKELY (GST_RPAD_PEER (realsink) != NULL))
1418     goto sink_was_linked;
1419
1420   if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
1421     GST_CAT_INFO (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
1422         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1423   }
1424   *outrealsrc = realsrc;
1425   *outrealsink = realsink;
1426
1427   /* check pad caps for non-empty intersection */
1428   {
1429     GstCaps *srccaps;
1430     GstCaps *sinkcaps;
1431
1432     srccaps = gst_real_pad_get_caps_unlocked (realsrc);
1433     sinkcaps = gst_real_pad_get_caps_unlocked (realsink);
1434     GST_CAT_DEBUG (GST_CAT_CAPS, "got caps %p and %p", srccaps, sinkcaps);
1435
1436     if (srccaps && sinkcaps) {
1437       GstCaps *caps;
1438
1439       caps = gst_caps_intersect (srccaps, sinkcaps);
1440       GST_CAT_DEBUG (GST_CAT_CAPS,
1441           "intersection caps %p %" GST_PTR_FORMAT, caps, caps);
1442
1443       if (filtercaps) {
1444         GstCaps *tmp;
1445
1446         tmp = gst_caps_intersect (caps, filtercaps);
1447         gst_caps_unref (caps);
1448         caps = tmp;
1449       }
1450       if (!caps || gst_caps_is_empty (caps))
1451         goto no_format;
1452     }
1453   }
1454
1455   /* FIXME check pad scheduling for non-empty intersection */
1456
1457   /* update filter */
1458   if (filtercaps) {
1459     GstCaps *filtercopy;
1460
1461     filtercopy = gst_caps_copy (filtercaps);
1462     filtercopy = gst_caps_ref (filtercopy);
1463
1464     gst_caps_replace (&GST_PAD_APPFILTER (realsrc), filtercopy);
1465     gst_caps_replace (&GST_PAD_APPFILTER (realsink), filtercopy);
1466   } else {
1467     gst_caps_replace (&GST_PAD_APPFILTER (realsrc), NULL);
1468     gst_caps_replace (&GST_PAD_APPFILTER (realsink), NULL);
1469   }
1470   return GST_PAD_LINK_OK;
1471
1472 lost_src_ghostpad:
1473   {
1474     return GST_PAD_LINK_REFUSED;
1475   }
1476 not_srcpad:
1477   {
1478     g_critical ("pad %s is not a source pad", GST_PAD_NAME (realsrc));
1479     GST_UNLOCK (realsrc);
1480     return GST_PAD_LINK_WRONG_DIRECTION;
1481   }
1482 src_was_linked:
1483   {
1484     GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was linked",
1485         GST_DEBUG_PAD_NAME (realsrc));
1486     /* we do not emit a warning in this case because unlinking cannot
1487      * be made MT safe.*/
1488     GST_UNLOCK (realsrc);
1489     return GST_PAD_LINK_WAS_LINKED;
1490   }
1491 lost_sink_ghostpad:
1492   {
1493     GST_DEBUG ("lost sink ghostpad");
1494     GST_UNLOCK (realsrc);
1495     return GST_PAD_LINK_REFUSED;
1496   }
1497 not_sinkpad:
1498   {
1499     g_critical ("pad %s is not a sink pad", GST_PAD_NAME (realsink));
1500     GST_UNLOCK (realsink);
1501     GST_UNLOCK (realsrc);
1502     return GST_PAD_LINK_WRONG_DIRECTION;
1503   }
1504 sink_was_linked:
1505   {
1506     GST_CAT_INFO (GST_CAT_PADS, "sink %s:%s was linked",
1507         GST_DEBUG_PAD_NAME (realsink));
1508     /* we do not emit a warning in this case because unlinking cannot
1509      * be made MT safe.*/
1510     GST_UNLOCK (realsink);
1511     GST_UNLOCK (realsrc);
1512     return GST_PAD_LINK_WAS_LINKED;
1513   }
1514 no_format:
1515   {
1516     GST_CAT_INFO (GST_CAT_PADS, "caps are incompatible");
1517     GST_UNLOCK (realsink);
1518     GST_UNLOCK (realsrc);
1519     return GST_PAD_LINK_NOFORMAT;
1520   }
1521 }
1522
1523 /**
1524  * gst_pad_link_filtered:
1525  * @srcpad: the source #GstPad to link.
1526  * @sinkpad: the sink #GstPad to link.
1527  * @filtercaps: the filter #GstCaps.
1528  *
1529  * Links the source pad and the sink pad, constrained
1530  * by the given filter caps.
1531  *
1532  * The filtercaps will be copied and refcounted, so you should unref
1533  * it yourself after using this function.
1534  *
1535  * Returns: A result code indicating if the connection worked or
1536  *          what went wrong.
1537  *
1538  * MT Safe.
1539  */
1540 GstPadLinkReturn
1541 gst_pad_link_filtered (GstPad * srcpad, GstPad * sinkpad,
1542     const GstCaps * filtercaps)
1543 {
1544   GstRealPad *realsrc, *realsink;
1545   GstPadLinkReturn result;
1546
1547   result = gst_pad_link_prepare_filtered (srcpad, sinkpad, &realsrc, &realsink,
1548       filtercaps);
1549
1550   if (result != GST_PAD_LINK_OK)
1551     goto prepare_failed;
1552
1553   GST_UNLOCK (realsink);
1554   GST_UNLOCK (realsrc);
1555
1556   /* FIXME released the locks here, concurrent thread might link
1557    * something else. */
1558   if (GST_RPAD_LINKFUNC (realsrc)) {
1559     /* this one will call the peer link function */
1560     result =
1561         GST_RPAD_LINKFUNC (realsrc) (GST_PAD (realsrc), GST_PAD (realsink));
1562   } else if (GST_RPAD_LINKFUNC (realsink)) {
1563     /* if no source link function, we need to call the sink link
1564      * function ourselves. */
1565     result =
1566         GST_RPAD_LINKFUNC (realsink) (GST_PAD (realsink), GST_PAD (realsrc));
1567   } else {
1568     result = GST_PAD_LINK_OK;
1569   }
1570
1571   GST_LOCK (realsrc);
1572   GST_LOCK (realsink);
1573   if (result == GST_PAD_LINK_OK) {
1574     GST_RPAD_PEER (realsrc) = GST_REAL_PAD (realsink);
1575     GST_RPAD_PEER (realsink) = GST_REAL_PAD (realsrc);
1576
1577     GST_UNLOCK (realsink);
1578     GST_UNLOCK (realsrc);
1579
1580     /* fire off a signal to each of the pads telling them 
1581      * that they've been linked */
1582     g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_LINKED],
1583         0, realsink);
1584     g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_LINKED],
1585         0, realsrc);
1586
1587     GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
1588         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1589   } else {
1590     GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed",
1591         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1592
1593     /* remove the filter again */
1594     if (filtercaps) {
1595       gst_caps_replace (&GST_RPAD_APPFILTER (realsrc), NULL);
1596       gst_caps_replace (&GST_RPAD_APPFILTER (realsink), NULL);
1597     }
1598
1599     GST_UNLOCK (realsink);
1600     GST_UNLOCK (realsrc);
1601   }
1602   return result;
1603
1604 prepare_failed:
1605   {
1606     return result;
1607   }
1608 }
1609
1610 /**
1611  * gst_pad_link:
1612  * @srcpad: the source #GstPad to link.
1613  * @sinkpad: the sink #GstPad to link.
1614  *
1615  * Links the source pad to the sink pad.
1616  *
1617  * Returns: A result code indicating if the connection worked or
1618  *          what went wrong.
1619  */
1620 GstPadLinkReturn
1621 gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
1622 {
1623   return gst_pad_link_filtered (srcpad, sinkpad, NULL);
1624 }
1625
1626 static void
1627 gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
1628 {
1629   /* this function would need checks if it weren't static */
1630
1631   GST_LOCK (pad);
1632   gst_object_replace ((GstObject **) & pad->padtemplate, (GstObject *) templ);
1633   GST_UNLOCK (pad);
1634
1635   if (templ) {
1636     gst_object_sink (GST_OBJECT (templ));
1637     g_signal_emit (G_OBJECT (templ),
1638         gst_pad_template_signals[TEMPL_PAD_CREATED], 0, pad);
1639   }
1640 }
1641
1642 /**
1643  * gst_pad_get_pad_template:
1644  * @pad: a #GstPad.
1645  *
1646  * Gets the template for @pad.
1647  *
1648  * Returns: the #GstPadTemplate from which this pad was instantiated, or %NULL
1649  * if this pad has no template.
1650  */
1651 GstPadTemplate *
1652 gst_pad_get_pad_template (GstPad * pad)
1653 {
1654   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1655
1656   return GST_PAD_PAD_TEMPLATE (pad);
1657 }
1658
1659
1660 /**
1661  * gst_pad_get_real_parent:
1662  * @pad: a #GstPad to get the real parent of.
1663  *
1664  * Gets the real parent object of this pad. If the pad
1665  * is a ghost pad, the actual owner of the real pad is
1666  * returned, as opposed to #gst_pad_get_parent().
1667  * Unref the object after use.
1668  *
1669  * Returns: the parent #GstElement.
1670  *
1671  * MT safe.
1672  */
1673 GstElement *
1674 gst_pad_get_real_parent (GstPad * pad)
1675 {
1676   GstRealPad *realpad;
1677   GstElement *element;
1678
1679   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1680
1681   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
1682   element = GST_PAD_PARENT (realpad);
1683   if (element)
1684     gst_object_ref (GST_OBJECT (element));
1685   GST_UNLOCK (realpad);
1686
1687   return element;
1688
1689 lost_ghostpad:
1690   {
1691     return NULL;
1692   }
1693 }
1694
1695 /* FIXME not MT safe */
1696 static void
1697 gst_pad_add_ghost_pad (GstPad * pad, GstPad * ghostpad)
1698 {
1699   GstRealPad *realpad;
1700
1701   /* if we're ghosting a ghost pad, drill down to find the real pad */
1702   realpad = (GstRealPad *) pad;
1703   while (GST_IS_GHOST_PAD (realpad))
1704     realpad = GST_GPAD_REALPAD (realpad);
1705   g_return_if_fail (GST_IS_REAL_PAD (realpad));
1706
1707   /* will ref the pad template */
1708   GST_GPAD_REALPAD (ghostpad) = realpad;
1709   realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
1710   gst_pad_set_pad_template (GST_PAD (ghostpad), GST_PAD_PAD_TEMPLATE (pad));
1711 }
1712
1713 static void
1714 gst_pad_remove_ghost_pad (GstPad * pad, GstPad * ghostpad)
1715 {
1716   GstRealPad *realpad;
1717
1718   realpad = GST_PAD_REALIZE (pad);
1719   g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad);
1720
1721   gst_pad_set_pad_template (GST_PAD (ghostpad), NULL);
1722   realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
1723   GST_GPAD_REALPAD (ghostpad) = NULL;
1724 }
1725
1726 /**
1727  * gst_pad_relink_filtered:
1728  * @srcpad: the source #GstPad to relink.
1729  * @sinkpad: the sink #GstPad to relink.
1730  * @filtercaps: the #GstPad to use as a filter in the relink.
1731  *
1732  * Relinks the given source and sink pad, constrained by the given
1733  * capabilities.  If the relink fails, the pads are unlinked
1734  * and an error code is returned.
1735  *
1736  * Returns: The result code of the operation.
1737  *
1738  * MT safe
1739  */
1740 GstPadLinkReturn
1741 gst_pad_relink_filtered (GstPad * srcpad, GstPad * sinkpad,
1742     const GstCaps * filtercaps)
1743 {
1744   GstRealPad *realsrc, *realsink;
1745
1746   /* FIXME refactor and share code with link/unlink */
1747
1748   /* generic checks */
1749   g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
1750   g_return_val_if_fail (GST_IS_PAD (sinkpad), GST_PAD_LINK_REFUSED);
1751
1752   GST_CAT_INFO (GST_CAT_PADS, "trying to relink %s:%s and %s:%s",
1753       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1754
1755   /* now we need to deal with the real/ghost stuff */
1756   GST_PAD_REALIZE_AND_LOCK (srcpad, realsrc, lost_src_ghostpad);
1757
1758   if (G_UNLIKELY (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC))
1759     goto not_srcpad;
1760
1761   GST_PAD_REALIZE_AND_LOCK (sinkpad, realsink, lost_sink_ghostpad);
1762
1763   if (G_UNLIKELY (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK))
1764     goto not_sinkpad;
1765
1766   if (G_UNLIKELY (GST_RPAD_PEER (realsink) != realsrc))
1767     goto not_linked_together;
1768
1769   if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
1770     GST_CAT_INFO (GST_CAT_PADS, "*actually* relinking %s:%s and %s:%s",
1771         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1772   }
1773
1774   /* update filter */
1775   if (filtercaps) {
1776     GstCaps *filtercopy;
1777
1778     filtercopy = gst_caps_copy (filtercaps);
1779     filtercopy = gst_caps_ref (filtercopy);
1780
1781     gst_caps_replace (&GST_PAD_APPFILTER (realsrc), filtercopy);
1782     gst_caps_replace (&GST_PAD_APPFILTER (realsink), filtercopy);
1783   } else {
1784     gst_caps_replace (&GST_PAD_APPFILTER (realsrc), NULL);
1785     gst_caps_replace (&GST_PAD_APPFILTER (realsink), NULL);
1786   }
1787   /* clear caps to force renegotiation */
1788   gst_caps_replace (&GST_PAD_CAPS (realsrc), NULL);
1789   gst_caps_replace (&GST_PAD_CAPS (realsink), NULL);
1790   GST_UNLOCK (realsink);
1791   GST_UNLOCK (realsrc);
1792
1793   GST_CAT_INFO (GST_CAT_PADS, "relinked %s:%s and %s:%s, successful",
1794       GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1795
1796   return GST_PAD_LINK_OK;
1797
1798 lost_src_ghostpad:
1799   {
1800     return GST_PAD_LINK_REFUSED;
1801   }
1802 not_srcpad:
1803   {
1804     g_critical ("pad %s is not a source pad", GST_PAD_NAME (realsrc));
1805     GST_UNLOCK (realsrc);
1806     return GST_PAD_LINK_WRONG_DIRECTION;
1807   }
1808 lost_sink_ghostpad:
1809   {
1810     GST_DEBUG ("lost sink ghostpad");
1811     GST_UNLOCK (realsrc);
1812     return GST_PAD_LINK_REFUSED;
1813   }
1814 not_sinkpad:
1815   {
1816     g_critical ("pad %s is not a sink pad", GST_PAD_NAME (realsink));
1817     GST_UNLOCK (realsink);
1818     GST_UNLOCK (realsrc);
1819     return GST_PAD_LINK_WRONG_DIRECTION;
1820   }
1821 not_linked_together:
1822   {
1823     GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was not linked with sink %s:%s",
1824         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1825     /* we do not emit a warning in this case because unlinking cannot
1826      * be made MT safe.*/
1827     GST_UNLOCK (realsink);
1828     GST_UNLOCK (realsrc);
1829     return GST_PAD_LINK_REFUSED;
1830   }
1831 }
1832
1833 /* should be called with the pad LOCK held */
1834 static GstCaps *
1835 gst_real_pad_get_caps_unlocked (GstRealPad * realpad)
1836 {
1837   GstCaps *result = NULL, *filter;
1838
1839   GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
1840       GST_DEBUG_PAD_NAME (realpad), realpad);
1841
1842   if (GST_RPAD_GETCAPSFUNC (realpad)) {
1843     GST_CAT_DEBUG (GST_CAT_CAPS, "dispatching to pad getcaps function");
1844
1845     GST_FLAG_SET (realpad, GST_PAD_IN_GETCAPS);
1846     GST_UNLOCK (realpad);
1847     result = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD (realpad));
1848     GST_LOCK (realpad);
1849     GST_FLAG_UNSET (realpad, GST_PAD_IN_GETCAPS);
1850
1851     if (result == NULL) {
1852       g_critical ("pad %s:%s returned NULL caps from getcaps function\n",
1853           GST_DEBUG_PAD_NAME (realpad));
1854     } else {
1855 #ifndef G_DISABLE_ASSERT
1856       /* check that the returned caps are a real subset of the template caps */
1857       if (GST_PAD_PAD_TEMPLATE (realpad)) {
1858         const GstCaps *templ_caps =
1859             GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (realpad));
1860         if (!gst_caps_is_subset (result, templ_caps)) {
1861           GstCaps *temp;
1862
1863           GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, realpad,
1864               "pad returned caps %" GST_PTR_FORMAT
1865               " which are not a real subset of its template caps %"
1866               GST_PTR_FORMAT, result, templ_caps);
1867           g_warning
1868               ("pad %s:%s returned caps that are not a real subset of its template caps",
1869               GST_DEBUG_PAD_NAME (realpad));
1870           temp = gst_caps_intersect (templ_caps, result);
1871           gst_caps_unref (result);
1872           result = temp;
1873         }
1874       }
1875 #endif
1876       goto done;
1877     }
1878   }
1879   if (GST_PAD_PAD_TEMPLATE (realpad)) {
1880     GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad);
1881
1882     result = GST_PAD_TEMPLATE_CAPS (templ);
1883     GST_CAT_DEBUG (GST_CAT_CAPS,
1884         "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
1885         result);
1886
1887     result = gst_caps_ref (result);
1888     goto done;
1889   }
1890   if (GST_RPAD_CAPS (realpad)) {
1891     result = GST_RPAD_CAPS (realpad);
1892
1893     GST_CAT_DEBUG (GST_CAT_CAPS,
1894         "using pad caps %p %" GST_PTR_FORMAT, result, result);
1895
1896     result = gst_caps_ref (result);
1897     goto done;
1898   }
1899
1900   GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
1901   result = gst_caps_new_empty ();
1902
1903 done:
1904   filter = GST_RPAD_APPFILTER (realpad);
1905
1906   if (filter) {
1907     GstCaps *temp = result;
1908
1909     GST_CAT_DEBUG (GST_CAT_CAPS,
1910         "app filter %p %" GST_PTR_FORMAT, filter, filter);
1911     result = gst_caps_intersect (temp, filter);
1912     gst_caps_unref (temp);
1913     GST_CAT_DEBUG (GST_CAT_CAPS,
1914         "caps after intersection with app filter %p %" GST_PTR_FORMAT, result,
1915         result);
1916   }
1917   return result;
1918 }
1919
1920 /**
1921  * gst_pad_get_caps:
1922  * @pad: a  #GstPad to get the capabilities of.
1923  *
1924  * Gets the capabilities of this pad.
1925  *
1926  * Returns: the #GstCaps of this pad. This function returns a new caps, so use 
1927  * gst_caps_unref to get rid of it.
1928  *
1929  * MT safe.
1930  */
1931 GstCaps *
1932 gst_pad_get_caps (GstPad * pad)
1933 {
1934   GstRealPad *realpad;
1935   GstCaps *result = NULL;
1936
1937   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1938
1939   /* now we need to deal with the real/ghost stuff */
1940   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
1941
1942   GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
1943       GST_DEBUG_PAD_NAME (realpad), realpad);
1944
1945   if (G_UNLIKELY (GST_RPAD_IS_IN_GETCAPS (realpad)))
1946     goto was_dispatching;
1947
1948   result = gst_real_pad_get_caps_unlocked (realpad);
1949   GST_UNLOCK (realpad);
1950
1951   return result;
1952
1953 lost_ghostpad:
1954   {
1955     return NULL;
1956   }
1957 was_dispatching:
1958   {
1959     GST_CAT_DEBUG (GST_CAT_CAPS,
1960         "pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (realpad));
1961     g_warning ("pad %s:%s recursively called getcaps!",
1962         GST_DEBUG_PAD_NAME (realpad));
1963     GST_UNLOCK (realpad);
1964     return NULL;
1965   }
1966 }
1967
1968 /**
1969  * gst_pad_peer_get_caps:
1970  * @pad: a  #GstPad to get the peer capabilities of.
1971  *
1972  * Gets the capabilities of the peer connected to this pad.
1973  *
1974  * Returns: the #GstCaps of the peer pad. This function returns a new caps, so use 
1975  * gst_caps_unref to get rid of it.
1976  */
1977 GstCaps *
1978 gst_pad_peer_get_caps (GstPad * pad)
1979 {
1980   GstRealPad *realpad, *peerpad;
1981   GstCaps *result = NULL;
1982
1983   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1984
1985   /* now we need to deal with the real/ghost stuff */
1986   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
1987
1988   GST_CAT_DEBUG (GST_CAT_CAPS, "get peer caps of %s:%s (%p)",
1989       GST_DEBUG_PAD_NAME (realpad), realpad);
1990
1991   peerpad = GST_RPAD_PEER (realpad);
1992   if (G_UNLIKELY (peerpad == NULL))
1993     goto no_peer;
1994
1995   if (G_UNLIKELY (GST_RPAD_IS_IN_GETCAPS (peerpad)))
1996     goto was_dispatching;
1997
1998   gst_object_ref (GST_OBJECT (peerpad));
1999   GST_UNLOCK (realpad);
2000
2001   result = gst_pad_get_caps (GST_PAD_CAST (peerpad));
2002
2003   gst_object_unref (GST_OBJECT (peerpad));
2004
2005   return result;
2006
2007 lost_ghostpad:
2008   {
2009     return NULL;
2010   }
2011 no_peer:
2012   {
2013     GST_UNLOCK (realpad);
2014     return gst_caps_new_any ();
2015   }
2016 was_dispatching:
2017   {
2018     GST_CAT_DEBUG (GST_CAT_CAPS,
2019         "pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (realpad));
2020     g_warning ("pad %s:%s recursively called getcaps!",
2021         GST_DEBUG_PAD_NAME (realpad));
2022     GST_UNLOCK (realpad);
2023     return NULL;
2024   }
2025 }
2026
2027 /**
2028  * gst_pad_fixate_caps:
2029  * @pad: a  #GstPad to fixate
2030  *
2031  * Fixate a caps on the given pad.
2032  *
2033  * Returns: a fixated #GstCaps.
2034  */
2035 GstCaps *
2036 gst_pad_fixate_caps (GstPad * pad, GstCaps * caps)
2037 {
2038   /* FIXME, implement me, call the fixate function for the pad */
2039   return caps;
2040 }
2041
2042 /**
2043  * gst_pad_accept_caps:
2044  * @pad: a  #GstPad to check
2045  *
2046  * Check if the given pad accepts the caps.
2047  *
2048  * Returns: TRUE if the pad can accept the caps.
2049  */
2050 gboolean
2051 gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
2052 {
2053   GstRealPad *realpad;
2054   gboolean result;
2055
2056   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2057
2058   /* now we need to deal with the real/ghost stuff */
2059   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
2060
2061   GST_CAT_DEBUG (GST_CAT_CAPS, "pad accept caps of %s:%s (%p)",
2062       GST_DEBUG_PAD_NAME (realpad), realpad);
2063
2064   /* FIXME, call accept function */
2065   result = FALSE;
2066   GST_UNLOCK (realpad);
2067
2068   return result;
2069
2070 lost_ghostpad:
2071   {
2072     return FALSE;
2073   }
2074 }
2075
2076 /**
2077  * gst_pad_peer_accept_caps:
2078  * @pad: a  #GstPad to check
2079  *
2080  * Check if the given pad accepts the caps.
2081  *
2082  * Returns: TRUE if the pad can accept the caps.
2083  */
2084 gboolean
2085 gst_pad_peer_accept_caps (GstPad * pad, GstCaps * caps)
2086 {
2087   GstRealPad *realpad, *peerpad;
2088   gboolean result;
2089
2090   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2091
2092   /* now we need to deal with the real/ghost stuff */
2093   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
2094
2095   GST_CAT_DEBUG (GST_CAT_CAPS, "peer accept caps of %s:%s (%p)",
2096       GST_DEBUG_PAD_NAME (realpad), realpad);
2097
2098   peerpad = GST_RPAD_PEER (realpad);
2099   if (G_UNLIKELY (peerpad == NULL))
2100     goto no_peer;
2101
2102   result = gst_pad_accept_caps (GST_PAD_CAST (peerpad), caps);
2103   GST_UNLOCK (realpad);
2104
2105   return result;
2106
2107 lost_ghostpad:
2108   {
2109     return FALSE;
2110   }
2111 no_peer:
2112   {
2113     GST_UNLOCK (realpad);
2114     return TRUE;
2115   }
2116 }
2117
2118 /**
2119  * gst_pad_set_caps:
2120  * @pad: a  #GstPad to set the capabilities of.
2121  * @caps: a #GstCaps to set.
2122  *
2123  * Sets the capabilities of this pad. The caps must be fixed. Any previous
2124  * caps on the pad will be unreffed. This function refs the caps so you should
2125  * unref if as soon as you don't need it anymore.
2126  * It is possible to set NULL caps, which will make the pad unnegotiated
2127  * again.
2128  *
2129  * Returns: TRUE if the caps could be set. FALSE if the caps were not fixed
2130  * or bad parameters were provided to this function.
2131  *
2132  * MT safe.
2133  */
2134 gboolean
2135 gst_pad_set_caps (GstPad * pad, GstCaps * caps)
2136 {
2137   GstPadSetCapsFunction setcaps;
2138
2139   g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
2140
2141   GST_LOCK (pad);
2142   setcaps = GST_RPAD_SETCAPSFUNC (pad);
2143
2144   /* call setcaps function to configure the pad */
2145   if (setcaps != NULL) {
2146     if (!GST_RPAD_IS_IN_SETCAPS (pad)) {
2147       GST_FLAG_SET (pad, GST_PAD_IN_SETCAPS);
2148       GST_UNLOCK (pad);
2149       if (!setcaps (pad, caps))
2150         goto could_not_set;
2151       GST_LOCK (pad);
2152     } else {
2153       GST_CAT_DEBUG (GST_CAT_CAPS, "pad %s:%s was dispatching",
2154           GST_DEBUG_PAD_NAME (pad));
2155     }
2156   }
2157
2158   if (GST_PAD_CAPS (pad))
2159     gst_caps_unref (GST_PAD_CAPS (pad));
2160
2161   if (caps)
2162     caps = gst_caps_ref (caps);
2163
2164   GST_PAD_CAPS (pad) = caps;
2165   GST_CAT_DEBUG (GST_CAT_CAPS, "%s:%s caps %" GST_PTR_FORMAT,
2166       GST_DEBUG_PAD_NAME (pad), caps);
2167   GST_UNLOCK (pad);
2168
2169   g_object_notify (G_OBJECT (pad), "caps");
2170
2171   return TRUE;
2172
2173 could_not_set:
2174   {
2175     GST_LOCK (pad);
2176     GST_FLAG_UNSET (pad, GST_PAD_IN_SETCAPS);
2177     GST_UNLOCK (pad);
2178     GST_CAT_DEBUG (GST_CAT_CAPS, "caps %" GST_PTR_FORMAT " could not be set",
2179         caps);
2180     return FALSE;
2181   }
2182 }
2183
2184 static gboolean
2185 gst_pad_configure_sink (GstPad * pad, GstCaps * caps)
2186 {
2187   GstPadAcceptCapsFunction acceptcaps;
2188   GstPadSetCapsFunction setcaps;
2189
2190   acceptcaps = GST_RPAD_ACCEPTCAPSFUNC (pad);
2191   setcaps = GST_RPAD_SETCAPSFUNC (pad);
2192
2193   /* See if pad accepts the caps, by calling acceptcaps, only
2194    * needed if no setcaps function */
2195   if (setcaps == NULL && acceptcaps != NULL) {
2196     if (!acceptcaps (pad, caps))
2197       goto not_accepted;
2198   }
2199   /* set caps on pad if call succeeds */
2200   gst_pad_set_caps (pad, caps);
2201   /* no need to unref the caps here, set_caps takes a ref and
2202    * our ref goes away when we leave this function. */
2203
2204   return TRUE;
2205
2206 not_accepted:
2207   {
2208     GST_CAT_DEBUG (GST_CAT_CAPS, "caps %" GST_PTR_FORMAT " not accepted", caps);
2209     return FALSE;
2210   }
2211 }
2212
2213 static gboolean
2214 gst_pad_configure_src (GstPad * pad, GstCaps * caps)
2215 {
2216   GstPadAcceptCapsFunction acceptcaps;
2217   GstPadSetCapsFunction setcaps;
2218
2219   acceptcaps = GST_RPAD_ACCEPTCAPSFUNC (pad);
2220   setcaps = GST_RPAD_SETCAPSFUNC (pad);
2221
2222   /* See if pad accepts the caps, by calling acceptcaps, only
2223    * needed if no setcaps function */
2224   if (setcaps == NULL && acceptcaps != NULL) {
2225     if (!acceptcaps (pad, caps))
2226       goto not_accepted;
2227   }
2228   /* set caps on pad if call succeeds */
2229   gst_pad_set_caps (pad, caps);
2230   /* no need to unref the caps here, set_caps takes a ref and
2231    * our ref goes away when we leave this function. */
2232
2233   return TRUE;
2234
2235 not_accepted:
2236   {
2237     GST_CAT_DEBUG (GST_CAT_CAPS, "caps %" GST_PTR_FORMAT " not accepted", caps);
2238     return FALSE;
2239   }
2240 }
2241
2242 /**
2243  * gst_pad_get_pad_template_caps:
2244  * @pad: a #GstPad to get the template capabilities from.
2245  *
2246  * Gets the capabilities for @pad's template.
2247  *
2248  * Returns: the #GstCaps of this pad template. If you intend to keep a reference
2249  * on the caps, make a copy (see gst_caps_copy ()).
2250  */
2251 const GstCaps *
2252 gst_pad_get_pad_template_caps (GstPad * pad)
2253 {
2254   static GstStaticCaps anycaps = GST_STATIC_CAPS ("ANY");
2255
2256   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2257
2258   if (GST_PAD_PAD_TEMPLATE (pad))
2259     return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
2260
2261   return gst_static_caps_get (&anycaps);
2262 }
2263
2264
2265 /**
2266  * gst_pad_get_peer:
2267  * @pad: a #GstPad to get the peer of.
2268  *
2269  * Gets the peer of @pad. This function refs the peer pad so
2270  * you need to unref it after use.
2271  *
2272  * Returns: the peer #GstPad. Unref after usage.
2273  *
2274  * MT safe.
2275  */
2276 GstPad *
2277 gst_pad_get_peer (GstPad * pad)
2278 {
2279   GstRealPad *realpad;
2280   GstRealPad *result;
2281
2282   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2283
2284   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
2285   result = GST_RPAD_PEER (realpad);
2286   if (result)
2287     gst_object_ref (GST_OBJECT (result));
2288   GST_UNLOCK (realpad);
2289
2290   return GST_PAD_CAST (result);
2291
2292 lost_ghostpad:
2293   {
2294     return NULL;
2295   }
2296 }
2297
2298 /**
2299  * gst_pad_realize:
2300  * @pad: a #GstPad to realize
2301  *
2302  * If the pad is a #GstRealPad, it is simply returned, else
2303  * the #GstGhostPad will be dereffed to the real pad.
2304  *
2305  * After this function you always receive the real pad of
2306  * the provided pad.
2307  *
2308  * This function unrefs the input pad and refs the result so
2309  * that you can write constructs like:
2310  *
2311  *   pad = gst_pad_realize(pad)
2312  *
2313  * without having to unref the old pad.
2314  *
2315  * Returns: the real #GstPad or NULL when an old reference to a
2316  * ghostpad is used.
2317  *
2318  * MT safe.
2319  */
2320 GstPad *
2321 gst_pad_realize (GstPad * pad)
2322 {
2323   GstRealPad *result;
2324
2325   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2326
2327   GST_LOCK (pad);
2328   result = GST_PAD_REALIZE (pad);
2329   if (result && pad != GST_PAD_CAST (result)) {
2330     gst_object_ref (GST_OBJECT (result));
2331     GST_UNLOCK (pad);
2332     /* no other thread could dispose this since we
2333      * hold at least one ref */
2334     gst_object_unref (GST_OBJECT (pad));
2335   } else {
2336     GST_UNLOCK (pad);
2337   }
2338
2339   return GST_PAD_CAST (result);
2340 }
2341
2342 /**
2343  * gst_pad_get_allowed_caps:
2344  * @srcpad: a #GstPad, it must a a source pad.
2345  *
2346  * Gets the capabilities of the allowed media types that can flow through @pad
2347  * and its peer. The pad must be a source pad.
2348  * The caller must free the resulting caps.
2349  *
2350  * Returns: the allowed #GstCaps of the pad link.  Free the caps when
2351  * you no longer need it. This function returns NULL when the @pad has no
2352  * peer.
2353  *
2354  * MT safe.
2355  */
2356 GstCaps *
2357 gst_pad_get_allowed_caps (GstPad * srcpad)
2358 {
2359   GstCaps *mycaps;
2360   GstCaps *caps;
2361   GstCaps *peercaps;
2362   GstRealPad *realpad, *peer;
2363
2364   g_return_val_if_fail (GST_IS_PAD (srcpad), NULL);
2365
2366   GST_PAD_REALIZE_AND_LOCK (srcpad, realpad, lost_ghostpad);
2367
2368   if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
2369     goto no_peer;
2370
2371   GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting allowed caps",
2372       GST_DEBUG_PAD_NAME (realpad));
2373
2374   gst_object_ref (GST_OBJECT_CAST (peer));
2375   GST_UNLOCK (realpad);
2376   mycaps = gst_pad_get_caps (GST_PAD_CAST (realpad));
2377
2378   peercaps = gst_pad_get_caps (GST_PAD_CAST (peer));
2379   gst_object_unref (GST_OBJECT_CAST (peer));
2380
2381   caps = gst_caps_intersect (mycaps, peercaps);
2382   gst_caps_unref (peercaps);
2383   gst_caps_unref (mycaps);
2384
2385   GST_CAT_DEBUG (GST_CAT_CAPS, "allowed caps %" GST_PTR_FORMAT, caps);
2386
2387   return caps;
2388
2389 lost_ghostpad:
2390   {
2391     GST_UNLOCK (srcpad);
2392     return NULL;
2393   }
2394 no_peer:
2395   {
2396     GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
2397         GST_DEBUG_PAD_NAME (realpad));
2398     GST_UNLOCK (realpad);
2399
2400     return NULL;
2401   }
2402 }
2403
2404 /**
2405  * gst_pad_get_negotiated_caps:
2406  * @pad: a #GstPad.
2407  *
2408  * Gets the capabilities of the media type that currently flows through @pad 
2409  * and its peer.
2410  *
2411  * This function can be used on both src and sinkpads. Note that srcpads are
2412  * always negotiated before sinkpads so it is possible that the negotiated caps 
2413  * on the srcpad do not match the negotiated caps of the peer.
2414  *
2415  * Returns: the negotiated #GstCaps of the pad link.  Free the caps when
2416  * you no longer need it. This function returns NULL when the @pad has no 
2417  * peer or is not negotiated yet.
2418  *
2419  * MT safe.
2420  */
2421 GstCaps *
2422 gst_pad_get_negotiated_caps (GstPad * pad)
2423 {
2424   GstCaps *caps;
2425   GstRealPad *realpad, *peer;
2426
2427   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2428
2429   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
2430
2431   if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
2432     goto no_peer;
2433
2434   GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting negotiated caps",
2435       GST_DEBUG_PAD_NAME (realpad));
2436
2437   caps = GST_RPAD_CAPS (realpad);
2438   if (caps)
2439     gst_caps_ref (caps);
2440   GST_UNLOCK (pad);
2441
2442   GST_CAT_DEBUG (GST_CAT_CAPS, "negotiated caps %" GST_PTR_FORMAT, caps);
2443
2444   return caps;
2445
2446 lost_ghostpad:
2447   {
2448     GST_UNLOCK (pad);
2449     return NULL;
2450   }
2451 no_peer:
2452   {
2453     GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
2454         GST_DEBUG_PAD_NAME (realpad));
2455     GST_UNLOCK (realpad);
2456
2457     return NULL;
2458   }
2459 }
2460
2461 /**
2462  * gst_pad_get_filter_caps:
2463  * @pad: a real #GstPad.
2464  *
2465  * Gets the capabilities of filter that currently configured on @pad 
2466  * and its peer.
2467  *
2468  * Returns: the filter #GstCaps of the pad link.  Free the caps when
2469  * you no longer need it. This function returns NULL when the @pad has no 
2470  * peer or there is no filter configured.
2471  *
2472  * MT safe.
2473  */
2474 GstCaps *
2475 gst_pad_get_filter_caps (GstPad * pad)
2476 {
2477   GstCaps *caps;
2478   GstRealPad *realpad, *peer;
2479
2480   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2481
2482   GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
2483
2484   if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
2485     goto no_peer;
2486
2487   GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting filter caps",
2488       GST_DEBUG_PAD_NAME (realpad));
2489
2490   if ((caps = GST_RPAD_APPFILTER (realpad)) != NULL)
2491     gst_caps_ref (caps);
2492   GST_UNLOCK (pad);
2493
2494   GST_CAT_DEBUG (GST_CAT_CAPS, "filter caps %" GST_PTR_FORMAT, caps);
2495
2496   return caps;
2497
2498 lost_ghostpad:
2499   {
2500     GST_UNLOCK (pad);
2501     return NULL;
2502   }
2503 no_peer:
2504   {
2505     GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
2506         GST_DEBUG_PAD_NAME (realpad));
2507     GST_UNLOCK (realpad);
2508
2509     return NULL;
2510   }
2511 }
2512
2513 /**
2514  * gst_pad_alloc_buffer:
2515  * @pad: a source #GstPad
2516  * @offset: the offset of the new buffer in the stream
2517  * @size: the size of the new buffer
2518  * @caps: the caps of the new buffer
2519  *
2520  * Allocates a new, empty buffer optimized to push to pad @pad.  This
2521  * function only works if @pad is a source pad and a GST_REAL_PAD and
2522  * has a peer. 
2523  * You need to check the caps of the buffer after performing this 
2524  * function and renegotiate to the format if needed.
2525  *
2526  * Returns: a new, empty #GstBuffer, or NULL if wrong parameters
2527  * were provided or the peer pad is not able to provide a buffer
2528  * that can be handled by the caller.
2529  *
2530  * MT safe.
2531  */
2532 GstBuffer *
2533 gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps)
2534 {
2535   GstRealPad *peer;
2536   GstBuffer *result = NULL;
2537   GstPadBufferAllocFunction bufferallocfunc;
2538   gboolean caps_changed;
2539
2540   g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL);
2541   g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL);
2542
2543   GST_LOCK (pad);
2544   if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
2545     goto no_peer;
2546
2547   if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL)) {
2548     GST_UNLOCK (pad);
2549     goto fallback;
2550   }
2551
2552   gst_object_ref (GST_OBJECT_CAST (peer));
2553   GST_UNLOCK (pad);
2554
2555   GST_CAT_DEBUG (GST_CAT_PADS,
2556       "calling bufferallocfunc &%s (@%p) of peer pad %s:%s",
2557       GST_DEBUG_FUNCPTR_NAME (bufferallocfunc),
2558       &bufferallocfunc, GST_DEBUG_PAD_NAME (peer));
2559
2560   result = bufferallocfunc (GST_PAD_CAST (peer), offset, size, caps);
2561
2562   gst_object_unref (GST_OBJECT_CAST (peer));
2563
2564   if (G_UNLIKELY (result == NULL)) {
2565     goto fallback;
2566   }
2567
2568   /* FIXME, move capnego this into a base class? */
2569   caps = GST_BUFFER_CAPS (result);
2570   caps_changed = caps && caps != GST_RPAD_CAPS (pad);
2571   /* we got a new datatype on the pad, see if it can handle it */
2572   if (G_UNLIKELY (caps_changed)) {
2573     if (G_UNLIKELY (!gst_pad_configure_src (GST_PAD_CAST (pad), caps)))
2574       goto not_negotiated;
2575   }
2576
2577   return result;
2578
2579 no_peer:
2580   {
2581     /* pad has no peer */
2582     GST_CAT_DEBUG (GST_CAT_PADS,
2583         "%s:%s called bufferallocfunc but had no peer, returning NULL",
2584         GST_DEBUG_PAD_NAME (pad));
2585     GST_UNLOCK (pad);
2586     return NULL;
2587   }
2588   /* fallback case, allocate a buffer of our own, add pad caps. */
2589 fallback:
2590   {
2591     result = gst_buffer_new_and_alloc (size);
2592     gst_buffer_set_caps (result, caps);
2593
2594     return result;
2595   }
2596 not_negotiated:
2597   {
2598     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2599         "alloc function retured unacceptable buffer");
2600     return NULL;
2601   }
2602 }
2603
2604 static void
2605 gst_real_pad_dispose (GObject * object)
2606 {
2607   GstPad *pad;
2608   GstRealPad *rpad;
2609
2610   pad = GST_PAD (object);
2611   rpad = GST_REAL_PAD (object);
2612
2613   /* No linked pad can ever be disposed.
2614    * It has to have a parent to be linked 
2615    * and a parent would hold a reference */
2616   /* FIXME: what about if g_object_dispose is explicitly called on the pad? Is
2617      that legal? otherwise we could assert GST_OBJECT_PARENT (pad) == NULL as
2618      well... */
2619   g_assert (GST_PAD_PEER (pad) == NULL);
2620
2621   GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s",
2622       GST_DEBUG_PAD_NAME (pad));
2623
2624   /* we destroy the ghostpads, because they are nothing without the real pad */
2625   if (rpad->ghostpads) {
2626     GList *orig, *ghostpads;
2627
2628     orig = ghostpads = g_list_copy (rpad->ghostpads);
2629
2630     while (ghostpads) {
2631       GstPad *ghostpad = GST_PAD (ghostpads->data);
2632
2633       if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))) {
2634         GstElement *parent = GST_ELEMENT (GST_OBJECT_PARENT (ghostpad));
2635
2636         GST_CAT_DEBUG (GST_CAT_REFCOUNTING,
2637             "removing ghost pad from element '%s'", GST_OBJECT_NAME (parent));
2638         gst_element_remove_pad (parent, ghostpad);
2639       } else {
2640         /* handle the case where we have some floating ghost pad that was never
2641            added to an element */
2642         g_object_set (ghostpad, "real-pad", NULL, NULL);
2643       }
2644       ghostpads = g_list_next (ghostpads);
2645     }
2646     g_list_free (orig);
2647     /* as the ghost pads are removed, they remove themselves from ->ghostpads.
2648        So it should be empty now. Let's assert that. */
2649     g_assert (rpad->ghostpads == NULL);
2650   }
2651
2652   /* clear the caps */
2653   gst_caps_replace (&GST_RPAD_CAPS (pad), NULL);
2654   gst_caps_replace (&GST_RPAD_APPFILTER (pad), NULL);
2655
2656   if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
2657     GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
2658         GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
2659
2660     gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
2661   }
2662
2663   G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
2664 }
2665
2666 static void
2667 gst_real_pad_finalize (GObject * object)
2668 {
2669   GstRealPad *rpad;
2670
2671   rpad = GST_REAL_PAD (object);
2672
2673   if (rpad->stream_rec_lock) {
2674     g_static_rec_mutex_free (rpad->stream_rec_lock);
2675     rpad->stream_rec_lock = NULL;
2676   }
2677   if (rpad->preroll_lock) {
2678     g_mutex_free (rpad->preroll_lock);
2679     g_cond_free (rpad->preroll_cond);
2680     rpad->preroll_lock = NULL;
2681     rpad->preroll_cond = NULL;
2682   }
2683   if (rpad->block_cond) {
2684     g_cond_free (rpad->block_cond);
2685     rpad->block_cond = NULL;
2686   }
2687
2688   G_OBJECT_CLASS (real_pad_parent_class)->finalize (object);
2689 }
2690
2691
2692 #ifndef GST_DISABLE_LOADSAVE
2693 /* FIXME: why isn't this on a GstElement ? */
2694 /**
2695  * gst_pad_load_and_link:
2696  * @self: an #xmlNodePtr to read the description from.
2697  * @parent: the #GstObject element that owns the pad.
2698  *
2699  * Reads the pad definition from the XML node and links the given pad
2700  * in the element to a pad of an element up in the hierarchy.
2701  */
2702 void
2703 gst_pad_load_and_link (xmlNodePtr self, GstObject * parent)
2704 {
2705   xmlNodePtr field = self->xmlChildrenNode;
2706   GstPad *pad = NULL, *targetpad;
2707   gchar *peer = NULL;
2708   gchar **split;
2709   GstElement *target;
2710   GstObject *grandparent;
2711   gchar *name = NULL;
2712
2713   while (field) {
2714     if (!strcmp (field->name, "name")) {
2715       name = xmlNodeGetContent (field);
2716       pad = gst_element_get_pad (GST_ELEMENT (parent), name);
2717       g_free (name);
2718     } else if (!strcmp (field->name, "peer")) {
2719       peer = xmlNodeGetContent (field);
2720     }
2721     field = field->next;
2722   }
2723   g_return_if_fail (pad != NULL);
2724
2725   if (peer == NULL)
2726     return;
2727
2728   split = g_strsplit (peer, ".", 2);
2729
2730   if (split[0] == NULL || split[1] == NULL) {
2731     GST_CAT_DEBUG (GST_CAT_XML,
2732         "Could not parse peer '%s' for pad %s:%s, leaving unlinked",
2733         peer, GST_DEBUG_PAD_NAME (pad));
2734
2735     g_free (peer);
2736     return;
2737   }
2738   g_free (peer);
2739
2740   g_return_if_fail (split[0] != NULL);
2741   g_return_if_fail (split[1] != NULL);
2742
2743   grandparent = gst_object_get_parent (parent);
2744
2745   if (grandparent && GST_IS_BIN (grandparent)) {
2746     target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
2747   } else
2748     goto cleanup;
2749
2750   if (target == NULL)
2751     goto cleanup;
2752
2753   targetpad = gst_element_get_pad (target, split[1]);
2754
2755   if (targetpad == NULL)
2756     goto cleanup;
2757
2758   gst_pad_link (pad, targetpad);
2759
2760 cleanup:
2761   g_strfreev (split);
2762 }
2763
2764 /**
2765  * gst_pad_save_thyself:
2766  * @pad: a #GstPad to save.
2767  * @parent: the parent #xmlNodePtr to save the description in.
2768  *
2769  * Saves the pad into an xml representation.
2770  *
2771  * Returns: the #xmlNodePtr representation of the pad.
2772  */
2773 static xmlNodePtr
2774 gst_pad_save_thyself (GstObject * object, xmlNodePtr parent)
2775 {
2776   GstRealPad *realpad;
2777   GstPad *peer;
2778
2779   g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
2780
2781   realpad = GST_REAL_PAD (object);
2782
2783   xmlNewChild (parent, NULL, "name", GST_PAD_NAME (realpad));
2784   if (GST_RPAD_PEER (realpad) != NULL) {
2785     gchar *content;
2786
2787     peer = GST_PAD (GST_RPAD_PEER (realpad));
2788     /* first check to see if the peer's parent's parent is the same */
2789     /* we just save it off */
2790     content = g_strdup_printf ("%s.%s",
2791         GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer));
2792     xmlNewChild (parent, NULL, "peer", content);
2793     g_free (content);
2794   } else
2795     xmlNewChild (parent, NULL, "peer", "");
2796
2797   return parent;
2798 }
2799
2800 /**
2801  * gst_ghost_pad_save_thyself:
2802  * @pad: a ghost #GstPad to save.
2803  * @parent: the parent #xmlNodePtr to save the description in.
2804  *
2805  * Saves the ghost pad into an xml representation.
2806  *
2807  * Returns: the #xmlNodePtr representation of the pad.
2808  */
2809 xmlNodePtr
2810 gst_ghost_pad_save_thyself (GstPad * pad, xmlNodePtr parent)
2811 {
2812   xmlNodePtr self;
2813
2814   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
2815
2816   self = xmlNewChild (parent, NULL, "ghostpad", NULL);
2817   xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
2818   xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
2819
2820   /* FIXME FIXME FIXME! */
2821
2822   return self;
2823 }
2824 #endif /* GST_DISABLE_LOADSAVE */
2825
2826 /* 
2827  * should be called with pad lock held 
2828  *
2829  * MT safe.
2830  */
2831 static void
2832 handle_pad_block (GstRealPad * pad)
2833 {
2834   GstPadBlockCallback callback;
2835   gpointer user_data;
2836
2837   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2838       "signal block taken on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
2839
2840   /* need to grab extra ref for the callbacks */
2841   gst_object_ref (GST_OBJECT (pad));
2842
2843   callback = pad->block_callback;
2844   if (callback) {
2845     user_data = pad->block_data;
2846     GST_UNLOCK (pad);
2847     callback (GST_PAD_CAST (pad), TRUE, user_data);
2848     GST_LOCK (pad);
2849   } else {
2850     GST_PAD_BLOCK_SIGNAL (pad);
2851   }
2852
2853   while (GST_RPAD_IS_BLOCKED (pad))
2854     GST_PAD_BLOCK_WAIT (pad);
2855
2856   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got unblocked");
2857
2858   callback = pad->block_callback;
2859   if (callback) {
2860     user_data = pad->block_data;
2861     GST_UNLOCK (pad);
2862     callback (GST_PAD_CAST (pad), FALSE, user_data);
2863     GST_LOCK (pad);
2864   } else {
2865     GST_PAD_BLOCK_SIGNAL (pad);
2866   }
2867
2868   gst_object_unref (GST_OBJECT (pad));
2869 }
2870
2871 /**
2872  * gst_pad_push:
2873  * @pad: a source #GstPad.
2874  * @buffer: the #GstBuffer to push.
2875  *
2876  * Pushes a buffer to the peer of @pad. @pad must be linked.
2877  *
2878  * Returns: a #GstFlowReturn from the peer pad.
2879  *
2880  * MT safe.
2881  */
2882 GstFlowReturn
2883 gst_pad_push (GstPad * pad, GstBuffer * buffer)
2884 {
2885   GstRealPad *peer;
2886   GstFlowReturn ret;
2887   GstPadChainFunction chainfunc;
2888   GstCaps *caps;
2889   gboolean caps_changed;
2890
2891   g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
2892   g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC,
2893       GST_FLOW_ERROR);
2894   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
2895   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
2896
2897
2898   GST_LOCK (pad);
2899   while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad)))
2900     handle_pad_block (GST_REAL_PAD_CAST (pad));
2901
2902   if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
2903     goto not_linked;
2904
2905   if (G_UNLIKELY (!GST_RPAD_IS_ACTIVE (peer)))
2906     goto not_active;
2907
2908   if (G_UNLIKELY (GST_RPAD_IS_FLUSHING (peer)))
2909     goto flushing;
2910
2911   gst_object_ref (GST_OBJECT_CAST (peer));
2912   GST_UNLOCK (pad);
2913
2914   /* FIXME, move capnego this into a base class? */
2915   caps = GST_BUFFER_CAPS (buffer);
2916   caps_changed = caps && caps != GST_RPAD_CAPS (peer);
2917   /* we got a new datatype on the peer pad, see if it can handle it */
2918   if (G_UNLIKELY (caps_changed)) {
2919     if (G_UNLIKELY (!gst_pad_configure_sink (GST_PAD_CAST (peer), caps)))
2920       goto not_negotiated;
2921   }
2922
2923   /* NOTE: we read the peer chainfunc unlocked. 
2924    * we cannot hold the lock for the peer so we might send
2925    * the data to the wrong function. This is not really a
2926    * problem since functions are assigned at creation time
2927    * and don't change that often... */
2928   if (G_UNLIKELY ((chainfunc = peer->chainfunc) == NULL))
2929     goto no_function;
2930
2931   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2932       "calling chainfunction &%s of peer pad %s:%s",
2933       GST_DEBUG_FUNCPTR_NAME (chainfunc), GST_DEBUG_PAD_NAME (peer));
2934
2935   ret = chainfunc (GST_PAD_CAST (peer), buffer);
2936
2937   gst_object_unref (GST_OBJECT_CAST (peer));
2938
2939   return ret;
2940
2941   /* ERROR recovery here */
2942 not_linked:
2943   {
2944     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2945         "pushing, but it was not linked");
2946     GST_UNLOCK (pad);
2947     return GST_FLOW_NOT_CONNECTED;
2948   }
2949 not_active:
2950   {
2951     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2952         "pushing, but it was inactive");
2953     GST_UNLOCK (pad);
2954     return GST_FLOW_WRONG_STATE;
2955   }
2956 flushing:
2957   {
2958     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2959         "pushing, but pad was flushing");
2960     GST_UNLOCK (pad);
2961     return GST_FLOW_UNEXPECTED;
2962   }
2963 not_negotiated:
2964   {
2965     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2966         "pushing buffer but peer did not accept");
2967     return GST_FLOW_NOT_NEGOTIATED;
2968   }
2969 no_function:
2970   {
2971     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
2972         "pushing, but not chainhandler");
2973     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
2974         ("push on pad %s:%s but the peer pad %s:%s has no chainfunction",
2975             GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer)));
2976     gst_object_unref (GST_OBJECT (peer));
2977     return GST_FLOW_ERROR;
2978   }
2979 }
2980
2981 /**
2982  * gst_pad_check_pull_range:
2983  * @pad: a sink #GstRealPad.
2984  *
2985  * Checks if a #gst_pad_pull_range() can be performed on the peer
2986  * source pad. This function is used by plugins that want to check
2987  * if they can use random access on the peer source pad. 
2988  *
2989  * The peer sourcepad can implement a custom #GstPadCheckGetRangeFunction
2990  * if it needs to perform some logic to determine if pull_range is
2991  * possible.
2992  *
2993  * Returns: a gboolean with the result.
2994  *
2995  * MT safe.
2996  */
2997 gboolean
2998 gst_pad_check_pull_range (GstPad * pad)
2999 {
3000   GstRealPad *peer;
3001   gboolean ret;
3002   GstPadCheckGetRangeFunction checkgetrangefunc;
3003
3004   g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
3005
3006   GST_LOCK (pad);
3007   if (GST_RPAD_DIRECTION (pad) != GST_PAD_SINK)
3008     goto wrong_direction;
3009
3010   if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
3011     goto not_connected;
3012
3013   gst_object_ref (GST_OBJECT_CAST (peer));
3014   GST_UNLOCK (pad);
3015
3016   /* see note in above function */
3017   if (G_LIKELY ((checkgetrangefunc = peer->checkgetrangefunc) == NULL)) {
3018     ret = GST_RPAD_GETRANGEFUNC (peer) != NULL;
3019   } else {
3020     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3021         "calling checkgetrangefunc %s of peer pad %s:%s",
3022         GST_DEBUG_FUNCPTR_NAME (checkgetrangefunc), GST_DEBUG_PAD_NAME (peer));
3023
3024     ret = checkgetrangefunc (GST_PAD_CAST (peer));
3025   }
3026
3027   gst_object_unref (GST_OBJECT_CAST (peer));
3028
3029   return ret;
3030
3031   /* ERROR recovery here */
3032 wrong_direction:
3033   {
3034     GST_UNLOCK (pad);
3035     return FALSE;
3036   }
3037 not_connected:
3038   {
3039     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3040         "checking pull range, but it was not linked");
3041     GST_UNLOCK (pad);
3042     return FALSE;
3043   }
3044 }
3045
3046 /**
3047  * gst_pad_pull_range:
3048  * @pad: a sink #GstPad.
3049  * @buffer: a pointer to hold the #GstBuffer.
3050  * @offset: The start offset of the buffer
3051  * @length: The length of the buffer
3052  *
3053  * Pulls a buffer from the peer pad. @pad must be linked.
3054  *
3055  * Returns: a #GstFlowReturn from the peer pad.
3056  *
3057  * MT safe.
3058  */
3059 GstFlowReturn
3060 gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
3061     GstBuffer ** buffer)
3062 {
3063   GstRealPad *peer;
3064   GstFlowReturn ret;
3065   GstPadGetRangeFunction getrangefunc;
3066
3067   g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
3068   g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK,
3069       GST_FLOW_ERROR);
3070   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
3071
3072   GST_LOCK (pad);
3073
3074   while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad)))
3075     handle_pad_block (GST_REAL_PAD_CAST (pad));
3076
3077   if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
3078     goto not_connected;
3079
3080   if (G_UNLIKELY (!GST_RPAD_IS_ACTIVE (peer)))
3081     goto not_active;
3082
3083   if (G_UNLIKELY (GST_RPAD_IS_FLUSHING (peer)))
3084     goto flushing;
3085
3086   gst_object_ref (GST_OBJECT_CAST (peer));
3087   GST_UNLOCK (pad);
3088
3089   /* see note in above function */
3090   if (G_UNLIKELY ((getrangefunc = peer->getrangefunc) == NULL))
3091     goto no_function;
3092
3093   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3094       "calling getrangefunc %s of peer pad %s:%s, offset %"
3095       G_GUINT64_FORMAT ", size %u",
3096       GST_DEBUG_FUNCPTR_NAME (getrangefunc), GST_DEBUG_PAD_NAME (peer),
3097       offset, size);
3098
3099   ret = getrangefunc (GST_PAD_CAST (peer), offset, size, buffer);
3100
3101   gst_object_unref (GST_OBJECT_CAST (peer));
3102
3103   return ret;
3104
3105   /* ERROR recovery here */
3106 not_connected:
3107   {
3108     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3109         "pulling range, but it was not linked");
3110     GST_UNLOCK (pad);
3111     return GST_FLOW_NOT_CONNECTED;
3112   }
3113 not_active:
3114   {
3115     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3116         "pulling range, but it was inactive");
3117     GST_UNLOCK (pad);
3118     return GST_FLOW_WRONG_STATE;
3119   }
3120 flushing:
3121   {
3122     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3123         "pulling range, but pad was flushing");
3124     GST_UNLOCK (pad);
3125     return GST_FLOW_UNEXPECTED;
3126   }
3127 no_function:
3128   {
3129     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
3130         ("pullrange on pad %s:%s but the peer pad %s:%s has no getrangefunction",
3131             GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer)));
3132     gst_object_unref (GST_OBJECT (peer));
3133     return GST_FLOW_ERROR;
3134   }
3135 }
3136
3137 /************************************************************************
3138  *
3139  * templates
3140  *
3141  */
3142 static void gst_pad_template_class_init (GstPadTemplateClass * klass);
3143 static void gst_pad_template_init (GstPadTemplate * templ);
3144 static void gst_pad_template_dispose (GObject * object);
3145
3146 GType
3147 gst_pad_template_get_type (void)
3148 {
3149   static GType padtemplate_type = 0;
3150
3151   if (!padtemplate_type) {
3152     static const GTypeInfo padtemplate_info = {
3153       sizeof (GstPadTemplateClass), NULL, NULL,
3154       (GClassInitFunc) gst_pad_template_class_init, NULL, NULL,
3155       sizeof (GstPadTemplate),
3156       0,
3157       (GInstanceInitFunc) gst_pad_template_init, NULL
3158     };
3159
3160     padtemplate_type =
3161         g_type_register_static (GST_TYPE_OBJECT, "GstPadTemplate",
3162         &padtemplate_info, 0);
3163   }
3164   return padtemplate_type;
3165 }
3166
3167 static void
3168 gst_pad_template_class_init (GstPadTemplateClass * klass)
3169 {
3170   GObjectClass *gobject_class;
3171   GstObjectClass *gstobject_class;
3172
3173   gobject_class = (GObjectClass *) klass;
3174   gstobject_class = (GstObjectClass *) klass;
3175
3176   padtemplate_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
3177
3178   gst_pad_template_signals[TEMPL_PAD_CREATED] =
3179       g_signal_new ("pad-created", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
3180       G_STRUCT_OFFSET (GstPadTemplateClass, pad_created),
3181       NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
3182
3183   gobject_class->dispose = gst_pad_template_dispose;
3184
3185   gstobject_class->path_string_separator = "*";
3186 }
3187
3188 static void
3189 gst_pad_template_init (GstPadTemplate * templ)
3190 {
3191 }
3192
3193 static void
3194 gst_pad_template_dispose (GObject * object)
3195 {
3196   GstPadTemplate *templ = GST_PAD_TEMPLATE (object);
3197
3198   g_free (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3199   if (GST_PAD_TEMPLATE_CAPS (templ)) {
3200     gst_caps_unref (GST_PAD_TEMPLATE_CAPS (templ));
3201   }
3202
3203   G_OBJECT_CLASS (padtemplate_parent_class)->dispose (object);
3204 }
3205
3206 /* ALWAYS padtemplates cannot have conversion specifications, it doesn't make
3207  * sense.
3208  * SOMETIMES padtemplates can do whatever they want, they are provided by the
3209  * element.
3210  * REQUEST padtemplates can be reverse-parsed (the user asks for 'sink1', the
3211  * 'sink%d' template is automatically selected), so we need to restrict their
3212  * naming.
3213  */
3214 static gboolean
3215 name_is_valid (const gchar * name, GstPadPresence presence)
3216 {
3217   const gchar *str;
3218
3219   if (presence == GST_PAD_ALWAYS) {
3220     if (strchr (name, '%')) {
3221       g_warning ("invalid name template %s: conversion specifications are not"
3222           " allowed for GST_PAD_ALWAYS padtemplates", name);
3223       return FALSE;
3224     }
3225   } else if (presence == GST_PAD_REQUEST) {
3226     if ((str = strchr (name, '%')) && strchr (str + 1, '%')) {
3227       g_warning ("invalid name template %s: only one conversion specification"
3228           " allowed in GST_PAD_REQUEST padtemplate", name);
3229       return FALSE;
3230     }
3231     if (str && (*(str + 1) != 's' && *(str + 1) != 'd')) {
3232       g_warning ("invalid name template %s: conversion specification must be of"
3233           " type '%%d' or '%%s' for GST_PAD_REQUEST padtemplate", name);
3234       return FALSE;
3235     }
3236     if (str && (*(str + 2) != '\0')) {
3237       g_warning ("invalid name template %s: conversion specification must"
3238           " appear at the end of the GST_PAD_REQUEST padtemplate name", name);
3239       return FALSE;
3240     }
3241   }
3242
3243   return TRUE;
3244 }
3245
3246 /**
3247  * gst_static_pad_template_get:
3248  * @pad_template: the static pad template
3249  *
3250  * Converts a #GstStaticPadTemplate into a #GstPadTemplate.
3251  *
3252  * Returns: a new #GstPadTemplate.
3253  */
3254 GstPadTemplate *
3255 gst_static_pad_template_get (GstStaticPadTemplate * pad_template)
3256 {
3257   GstPadTemplate *new;
3258
3259   if (!name_is_valid (pad_template->name_template, pad_template->presence))
3260     return NULL;
3261
3262   new = g_object_new (gst_pad_template_get_type (),
3263       "name", pad_template->name_template, NULL);
3264
3265   GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (pad_template->name_template);
3266   GST_PAD_TEMPLATE_DIRECTION (new) = pad_template->direction;
3267   GST_PAD_TEMPLATE_PRESENCE (new) = pad_template->presence;
3268
3269   GST_PAD_TEMPLATE_CAPS (new) =
3270       gst_caps_copy (gst_static_caps_get (&pad_template->static_caps));
3271
3272   return new;
3273 }
3274
3275 /**
3276  * gst_pad_template_new:
3277  * @name_template: the name template.
3278  * @direction: the #GstPadDirection of the template.
3279  * @presence: the #GstPadPresence of the pad.
3280  * @caps: a #GstCaps set for the template. The caps are taken ownership of.
3281  *
3282  * Creates a new pad template with a name according to the given template
3283  * and with the given arguments. This functions takes ownership of the provided
3284  * caps, so be sure to not use them afterwards.
3285  *
3286  * Returns: a new #GstPadTemplate.
3287  */
3288 GstPadTemplate *
3289 gst_pad_template_new (const gchar * name_template,
3290     GstPadDirection direction, GstPadPresence presence, GstCaps * caps)
3291 {
3292   GstPadTemplate *new;
3293
3294   g_return_val_if_fail (name_template != NULL, NULL);
3295   g_return_val_if_fail (caps != NULL, NULL);
3296   g_return_val_if_fail (direction == GST_PAD_SRC
3297       || direction == GST_PAD_SINK, NULL);
3298   g_return_val_if_fail (presence == GST_PAD_ALWAYS
3299       || presence == GST_PAD_SOMETIMES || presence == GST_PAD_REQUEST, NULL);
3300
3301   if (!name_is_valid (name_template, presence))
3302     return NULL;
3303
3304   new = g_object_new (gst_pad_template_get_type (),
3305       "name", name_template, NULL);
3306
3307   GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name_template);
3308   GST_PAD_TEMPLATE_DIRECTION (new) = direction;
3309   GST_PAD_TEMPLATE_PRESENCE (new) = presence;
3310   GST_PAD_TEMPLATE_CAPS (new) = caps;
3311
3312   return new;
3313 }
3314
3315 /**
3316  * gst_pad_template_get_caps:
3317  * @templ: a #GstPadTemplate to get capabilities of.
3318  *
3319  * Gets the capabilities of the pad template.
3320  *
3321  * Returns: the #GstCaps of the pad template. If you need to keep a reference to
3322  * the caps, take a ref (see gst_caps_ref ()).
3323  */
3324 GstCaps *
3325 gst_pad_template_get_caps (GstPadTemplate * templ)
3326 {
3327   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
3328
3329   return GST_PAD_TEMPLATE_CAPS (templ);
3330 }
3331
3332 /**
3333  * gst_pad_set_element_private:
3334  * @pad: the #GstPad to set the private data of.
3335  * @priv: The private data to attach to the pad.
3336  *
3337  * Set the given private data gpointer on the pad. 
3338  * This function can only be used by the element that owns the pad.
3339  */
3340 void
3341 gst_pad_set_element_private (GstPad * pad, gpointer priv)
3342 {
3343   pad->element_private = priv;
3344 }
3345
3346 /**
3347  * gst_pad_get_element_private:
3348  * @pad: the #GstPad to get the private data of.
3349  *
3350  * Gets the private data of a pad.
3351  *
3352  * Returns: a #gpointer to the private data.
3353  */
3354 gpointer
3355 gst_pad_get_element_private (GstPad * pad)
3356 {
3357   return pad->element_private;
3358 }
3359
3360
3361 /***** ghost pads *****/
3362 GType _gst_ghost_pad_type = 0;
3363
3364 static void gst_ghost_pad_class_init (GstGhostPadClass * klass);
3365 static void gst_ghost_pad_init (GstGhostPad * pad);
3366 static void gst_ghost_pad_dispose (GObject * object);
3367 static void gst_ghost_pad_get_property (GObject * object, guint prop_id,
3368     GValue * value, GParamSpec * pspec);
3369 static void gst_ghost_pad_set_property (GObject * object, guint prop_id,
3370     const GValue * value, GParamSpec * pspec);
3371
3372 static GstPad *ghost_pad_parent_class = NULL;
3373
3374 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
3375 enum
3376 {
3377   GPAD_ARG_0,
3378   GPAD_ARG_REAL_PAD
3379       /* fill me */
3380 };
3381
3382 GType
3383 gst_ghost_pad_get_type (void)
3384 {
3385   if (!_gst_ghost_pad_type) {
3386     static const GTypeInfo pad_info = {
3387       sizeof (GstGhostPadClass), NULL, NULL,
3388       (GClassInitFunc) gst_ghost_pad_class_init, NULL, NULL,
3389       sizeof (GstGhostPad),
3390       0,
3391       (GInstanceInitFunc) gst_ghost_pad_init,
3392       NULL
3393     };
3394
3395     _gst_ghost_pad_type = g_type_register_static (GST_TYPE_PAD, "GstGhostPad",
3396         &pad_info, 0);
3397   }
3398   return _gst_ghost_pad_type;
3399 }
3400
3401 static void
3402 gst_ghost_pad_class_init (GstGhostPadClass * klass)
3403 {
3404   GObjectClass *gobject_class;
3405
3406   gobject_class = (GObjectClass *) klass;
3407
3408   ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
3409
3410   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
3411   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_set_property);
3412   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_get_property);
3413
3414   g_object_class_install_property (gobject_class, GPAD_ARG_REAL_PAD,
3415       g_param_spec_object ("real-pad", "Real pad",
3416           "The real pad for the ghost pad", GST_TYPE_PAD, G_PARAM_READWRITE));
3417 }
3418
3419 static void
3420 gst_ghost_pad_init (GstGhostPad * pad)
3421 {
3422   /* zeroed by glib */
3423 }
3424
3425 static void
3426 gst_ghost_pad_dispose (GObject * object)
3427 {
3428   g_object_set (object, "real-pad", NULL, NULL);
3429
3430   G_OBJECT_CLASS (ghost_pad_parent_class)->dispose (object);
3431 }
3432
3433 static void
3434 gst_ghost_pad_set_property (GObject * object, guint prop_id,
3435     const GValue * value, GParamSpec * pspec)
3436 {
3437   GstPad *ghostpad = (GstPad *) object;
3438   GstPad *oldrealpad = (GstPad *) GST_GPAD_REALPAD (ghostpad);
3439   GstPad *realpad = NULL;
3440
3441   switch (prop_id) {
3442     case GPAD_ARG_REAL_PAD:
3443       realpad = g_value_get_object (value);
3444
3445       if (oldrealpad) {
3446         if (realpad == oldrealpad)
3447           return;
3448         else
3449           gst_pad_remove_ghost_pad (oldrealpad, ghostpad);
3450       }
3451
3452       if (realpad)
3453         gst_pad_add_ghost_pad (realpad, ghostpad);
3454       break;
3455
3456     default:
3457       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3458       break;
3459   }
3460 }
3461
3462 static void
3463 gst_ghost_pad_get_property (GObject * object, guint prop_id,
3464     GValue * value, GParamSpec * pspec)
3465 {
3466   switch (prop_id) {
3467     case GPAD_ARG_REAL_PAD:
3468       g_value_set_object (value, GST_GPAD_REALPAD (object));
3469       break;
3470
3471     default:
3472       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3473       break;
3474   }
3475 }
3476
3477 /**
3478  * gst_ghost_pad_new:
3479  * @name: the name of the new ghost pad.
3480  * @pad: the #GstPad to create a ghost pad for.
3481  *
3482  * Creates a new ghost pad associated with @pad, and named @name. If @name is
3483  * %NULL, a guaranteed unique name (across all ghost pads) will be assigned.
3484  *
3485  * Returns: a new ghost #GstPad, or %NULL in case of an error.
3486  */
3487 GstPad *
3488 gst_ghost_pad_new (const gchar * name, GstPad * pad)
3489 {
3490   GstPad *gpad;
3491
3492   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3493
3494   gpad = g_object_new (GST_TYPE_GHOST_PAD, "name", name, "real-pad", pad, NULL);
3495
3496   GST_CAT_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\" for pad %s:%s",
3497       GST_OBJECT_NAME (gpad), GST_DEBUG_PAD_NAME (pad));
3498
3499   return gpad;
3500 }
3501
3502 /**
3503  * gst_pad_get_internal_links_default:
3504  * @pad: the #GstPad to get the internal links of.
3505  *
3506  * Gets a list of pads to which the given pad is linked to
3507  * inside of the parent element.
3508  * This is the default handler, and thus returns a list of all of the
3509  * pads inside the parent element with opposite direction.
3510  * The caller must free this list after use.
3511  *
3512  * Returns: a newly allocated #GList of pads.
3513  *
3514  * Not MT safe.
3515  */
3516 GList *
3517 gst_pad_get_internal_links_default (GstPad * pad)
3518 {
3519   GList *res = NULL;
3520   GstElement *parent;
3521   GList *parent_pads;
3522   GstPadDirection direction;
3523   GstRealPad *rpad;
3524
3525   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3526
3527   rpad = GST_PAD_REALIZE (pad);
3528   direction = rpad->direction;
3529
3530   parent = GST_PAD_PARENT (rpad);
3531   parent_pads = parent->pads;
3532
3533   while (parent_pads) {
3534     GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data);
3535
3536     if (parent_pad->direction != direction) {
3537       res = g_list_prepend (res, parent_pad);
3538     }
3539
3540     parent_pads = g_list_next (parent_pads);
3541   }
3542
3543   return res;
3544 }
3545
3546 /**
3547  * gst_pad_get_internal_links:
3548  * @pad: the #GstPad to get the internal links of.
3549  *
3550  * Gets a list of pads to which the given pad is linked to
3551  * inside of the parent element.
3552  * The caller must free this list after use.
3553  *
3554  * Returns: a newly allocated #GList of pads.
3555  *
3556  * Not MT safe.
3557  */
3558 GList *
3559 gst_pad_get_internal_links (GstPad * pad)
3560 {
3561   GList *res = NULL;
3562   GstRealPad *rpad;
3563
3564   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3565
3566   rpad = GST_PAD_REALIZE (pad);
3567
3568   if (GST_RPAD_INTLINKFUNC (rpad))
3569     res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD_CAST (rpad));
3570
3571   return res;
3572 }
3573
3574
3575 static gboolean
3576 gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event)
3577 {
3578   GList *orig, *pads;
3579   gboolean result;
3580
3581   GST_INFO_OBJECT (pad, "Sending event %p to all internally linked pads",
3582       event);
3583
3584   result = (GST_PAD_DIRECTION (pad) == GST_PAD_SINK);
3585
3586   orig = pads = gst_pad_get_internal_links (pad);
3587
3588   while (pads) {
3589     GstPad *eventpad = GST_PAD (pads->data);
3590
3591     pads = g_list_next (pads);
3592
3593     /* for all of the internally-linked pads that are actually linked */
3594     if (GST_PAD_IS_LINKED (eventpad)) {
3595       if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
3596         /* for each pad we send to, we should ref the event; it's up
3597          * to downstream to unref again when handled. */
3598         GST_LOG_OBJECT (pad, "Reffing and sending event %p to %s:%s", event,
3599             GST_DEBUG_PAD_NAME (eventpad));
3600         gst_event_ref (event);
3601         gst_pad_push_event (eventpad, event);
3602       } else {
3603         /* we only send the event on one pad, multi-sinkpad elements
3604          * should implement a handler */
3605         GST_LOG_OBJECT (pad, "sending event %p to one sink pad %s:%s", event,
3606             GST_DEBUG_PAD_NAME (eventpad));
3607         result = gst_pad_push_event (eventpad, event);
3608         goto done;
3609       }
3610     }
3611   }
3612   /* we handled the incoming event so we unref once */
3613   GST_LOG_OBJECT (pad, "handled event %p, unreffing", event);
3614   gst_event_unref (event);
3615
3616 done:
3617   g_list_free (orig);
3618
3619   return result;
3620 }
3621
3622 /**
3623  * gst_pad_event_default:
3624  * @pad: a #GstPad to call the default event handler on.
3625  * @event: the #GstEvent to handle.
3626  *
3627  * Invokes the default event handler for the given pad. End-of-stream and
3628  * discontinuity events are handled specially, and then the event is sent to all
3629  * pads internally linked to @pad. Note that if there are many possible sink
3630  * pads that are internally linked to @pad, only one will be sent an event.
3631  * Multi-sinkpad elements should implement custom event handlers.
3632  *
3633  * Returns: TRUE if the event was sent succesfully.
3634  */
3635 gboolean
3636 gst_pad_event_default (GstPad * pad, GstEvent * event)
3637 {
3638   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3639   g_return_val_if_fail (event != NULL, FALSE);
3640
3641   switch (GST_EVENT_TYPE (event)) {
3642     case GST_EVENT_EOS:
3643     {
3644       GstRealPad *rpad = GST_PAD_REALIZE (pad);
3645
3646       if (GST_RPAD_TASK (rpad)) {
3647         GST_DEBUG_OBJECT (rpad, "pausing task because of eos");
3648         gst_task_pause (GST_RPAD_TASK (rpad));
3649       }
3650     }
3651     default:
3652       break;
3653   }
3654
3655   return gst_pad_event_default_dispatch (pad, event);
3656 }
3657
3658 /**
3659  * gst_pad_dispatcher:
3660  * @pad: a #GstPad to dispatch.
3661  * @dispatch: the #GstDispatcherFunction to call.
3662  * @data: gpointer user data passed to the dispatcher function.
3663  *
3664  * Invokes the given dispatcher function on all pads that are 
3665  * internally linked to the given pad. 
3666  * The GstPadDispatcherFunction should return TRUE when no further pads 
3667  * need to be processed.
3668  *
3669  * Returns: TRUE if one of the dispatcher functions returned TRUE.
3670  */
3671 gboolean
3672 gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
3673     gpointer data)
3674 {
3675   gboolean res = FALSE;
3676   GList *int_pads, *orig;
3677
3678   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3679   g_return_val_if_fail (dispatch != NULL, FALSE);
3680
3681   orig = int_pads = gst_pad_get_internal_links (pad);
3682
3683   while (int_pads) {
3684     GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data);
3685     GstRealPad *int_peer = GST_RPAD_PEER (int_rpad);
3686
3687     if (int_peer) {
3688       res = dispatch (GST_PAD (int_peer), data);
3689       if (res)
3690         break;
3691     }
3692     int_pads = g_list_next (int_pads);
3693   }
3694
3695   g_list_free (orig);
3696
3697   return res;
3698 }
3699
3700 /**
3701  * gst_pad_push_event:
3702  * @pad: a #GstPad to push the event to.
3703  * @event: the #GstEvent to send to the pad.
3704  *
3705  * Sends the event to the peer of the given pad.
3706  *
3707  * Returns: TRUE if the event was handled.
3708  *
3709  * MT safe.
3710  */
3711 gboolean
3712 gst_pad_push_event (GstPad * pad, GstEvent * event)
3713 {
3714   GstRealPad *peerpad;
3715   gboolean result;
3716
3717   g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
3718   g_return_val_if_fail (event != NULL, FALSE);
3719
3720   GST_LOCK (pad);
3721   peerpad = GST_RPAD_PEER (pad);
3722   if (peerpad == NULL)
3723     goto not_linked;
3724
3725   gst_object_ref (GST_OBJECT_CAST (peerpad));
3726   GST_UNLOCK (pad);
3727
3728   result = gst_pad_send_event (GST_PAD_CAST (peerpad), event);
3729
3730   gst_object_unref (GST_OBJECT_CAST (peerpad));
3731
3732   return result;
3733
3734   /* ERROR handling */
3735 not_linked:
3736   {
3737     GST_UNLOCK (pad);
3738     return FALSE;
3739   }
3740 }
3741
3742 /**
3743  * gst_pad_send_event:
3744  * @pad: a #GstPad to send the event to.
3745  * @event: the #GstEvent to send to the pad.
3746  *
3747  * Sends the event to the pad. This function can be used
3748  * by applications to send events in the pipeline.
3749  *
3750  * Returns: TRUE if the event was handled.
3751  */
3752 gboolean
3753 gst_pad_send_event (GstPad * pad, GstEvent * event)
3754 {
3755   gboolean result = FALSE;
3756   GstRealPad *rpad;
3757   GstPadEventFunction eventfunc;
3758
3759   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3760   g_return_val_if_fail (event != NULL, FALSE);
3761
3762   rpad = GST_PAD_REALIZE (pad);
3763
3764   if (GST_EVENT_SRC (event) == NULL)
3765     GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad));
3766
3767   GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %d on pad %s:%s",
3768       GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad));
3769
3770   if (GST_PAD_IS_SINK (pad)) {
3771     if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH) {
3772       GST_CAT_DEBUG (GST_CAT_EVENT, "have flush event");
3773       GST_LOCK (pad);
3774       if (GST_EVENT_FLUSH_DONE (event)) {
3775         GST_CAT_DEBUG (GST_CAT_EVENT, "clear flush flag");
3776         GST_FLAG_UNSET (pad, GST_PAD_FLUSHING);
3777       } else {
3778         GST_CAT_DEBUG (GST_CAT_EVENT, "set flush flag");
3779         GST_FLAG_SET (pad, GST_PAD_FLUSHING);
3780       }
3781       GST_UNLOCK (pad);
3782     }
3783   }
3784
3785   if ((eventfunc = GST_RPAD_EVENTFUNC (rpad)) == NULL)
3786     goto no_function;
3787
3788   result = eventfunc (GST_PAD_CAST (rpad), event);
3789
3790   return result;
3791
3792   /* ERROR handling */
3793 no_function:
3794   {
3795     g_warning ("pad %s:%s has no event handler, file a bug.",
3796         GST_DEBUG_PAD_NAME (rpad));
3797     gst_event_unref (event);
3798     return FALSE;
3799   }
3800 }
3801
3802 typedef struct
3803 {
3804   GstFormat src_format;
3805   gint64 src_value;
3806   GstFormat *dest_format;
3807   gint64 *dest_value;
3808 }
3809 GstPadConvertData;
3810
3811 static gboolean
3812 gst_pad_convert_dispatcher (GstPad * pad, GstPadConvertData * data)
3813 {
3814   return gst_pad_convert (pad, data->src_format, data->src_value,
3815       data->dest_format, data->dest_value);
3816 }
3817
3818 /**
3819  * gst_pad_convert_default:
3820  * @pad: a #GstPad to invoke the default converter on.
3821  * @src_format: the source #GstFormat.
3822  * @src_value: the source value.
3823  * @dest_format: a pointer to the destination #GstFormat.
3824  * @dest_value: a pointer to the destination value.
3825  *
3826  * Invokes the default converter on a pad. 
3827  * This will forward the call to the pad obtained 
3828  * using the internal link of
3829  * the element.
3830  *
3831  * Returns: TRUE if the conversion could be performed.
3832  */
3833 gboolean
3834 gst_pad_convert_default (GstPad * pad,
3835     GstFormat src_format, gint64 src_value,
3836     GstFormat * dest_format, gint64 * dest_value)
3837 {
3838   GstPadConvertData data;
3839
3840   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3841   g_return_val_if_fail (dest_format != NULL, FALSE);
3842   g_return_val_if_fail (dest_value != NULL, FALSE);
3843
3844   data.src_format = src_format;
3845   data.src_value = src_value;
3846   data.dest_format = dest_format;
3847   data.dest_value = dest_value;
3848
3849   return gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
3850       gst_pad_convert_dispatcher, &data);
3851 }
3852
3853 /**
3854  * gst_pad_convert:
3855  * @pad: a #GstPad to invoke the default converter on.
3856  * @src_format: the source #GstFormat.
3857  * @src_value: the source value.
3858  * @dest_format: a pointer to the destination #GstFormat.
3859  * @dest_value: a pointer to the destination value.
3860  *
3861  * Invokes a conversion on the pad.
3862  *
3863  * Returns: TRUE if the conversion could be performed.
3864  */
3865 gboolean
3866 gst_pad_convert (GstPad * pad,
3867     GstFormat src_format, gint64 src_value,
3868     GstFormat * dest_format, gint64 * dest_value)
3869 {
3870   GstRealPad *rpad;
3871
3872   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3873   g_return_val_if_fail (dest_format != NULL, FALSE);
3874   g_return_val_if_fail (dest_value != NULL, FALSE);
3875
3876   if (src_format == *dest_format) {
3877     *dest_value = src_value;
3878     return TRUE;
3879   }
3880
3881   rpad = GST_PAD_REALIZE (pad);
3882
3883   if (GST_RPAD_CONVERTFUNC (rpad)) {
3884     return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD (rpad), src_format,
3885         src_value, dest_format, dest_value);
3886   }
3887
3888   return FALSE;
3889 }
3890
3891 typedef struct
3892 {
3893   GstQueryType type;
3894   GstFormat *format;
3895   gint64 *value;
3896 }
3897 GstPadQueryData;
3898
3899 static gboolean
3900 gst_pad_query_dispatcher (GstPad * pad, GstPadQueryData * data)
3901 {
3902   return gst_pad_query (pad, data->type, data->format, data->value);
3903 }
3904
3905 /**
3906  * gst_pad_query_default:
3907  * @pad: a #GstPad to invoke the default query on.
3908  * @type: the #GstQueryType of the query to perform.
3909  * @format: a pointer to the #GstFormat of the result.
3910  * @value: a pointer to the result.
3911  *
3912  * Invokes the default query function on a pad. 
3913  *
3914  * Returns: TRUE if the query could be performed.
3915  */
3916 gboolean
3917 gst_pad_query_default (GstPad * pad, GstQueryType type,
3918     GstFormat * format, gint64 * value)
3919 {
3920   GstPadQueryData data;
3921
3922   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3923   g_return_val_if_fail (format != NULL, FALSE);
3924   g_return_val_if_fail (value != NULL, FALSE);
3925
3926   data.type = type;
3927   data.format = format;
3928   data.value = value;
3929
3930   return gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
3931       gst_pad_query_dispatcher, &data);
3932 }
3933
3934 /**
3935  * gst_pad_query:
3936  * @pad: a #GstPad to invoke the default query on.
3937  * @type: the #GstQueryType of the query to perform.
3938  * @format: a pointer to the #GstFormat asked for.
3939  *          On return contains the #GstFormat used.
3940  * @value: a pointer to the result.
3941  *
3942  * Queries a pad for one of the available properties. The format will be
3943  * adjusted to the actual format used when specifying formats such as 
3944  * GST_FORMAT_DEFAULT.
3945  * FIXME: Tell if the format can be adjusted when specifying a definite format.
3946  *
3947  * Returns: TRUE if the query could be performed.
3948  */
3949 gboolean
3950 gst_pad_query (GstPad * pad, GstQueryType type,
3951     GstFormat * format, gint64 * value)
3952 {
3953   GstRealPad *rpad;
3954
3955   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3956   g_return_val_if_fail (format != NULL, FALSE);
3957   g_return_val_if_fail (value != NULL, FALSE);
3958
3959   rpad = GST_PAD_REALIZE (pad);
3960
3961   g_return_val_if_fail (rpad, FALSE);
3962
3963   if (GST_RPAD_QUERYFUNC (rpad))
3964     return GST_RPAD_QUERYFUNC (rpad) (GST_PAD_CAST (rpad), type, format, value);
3965
3966   return FALSE;
3967 }
3968
3969 static gboolean
3970 gst_pad_get_formats_dispatcher (GstPad * pad, const GstFormat ** data)
3971 {
3972   *data = gst_pad_get_formats (pad);
3973
3974   return TRUE;
3975 }
3976
3977 /**
3978  * gst_pad_get_formats_default:
3979  * @pad: a #GstPad to query
3980  *
3981  * Invoke the default format dispatcher for the pad.
3982  *
3983  * Returns: An array of GstFormats ended with a 0 value.
3984  */
3985 const GstFormat *
3986 gst_pad_get_formats_default (GstPad * pad)
3987 {
3988   GstFormat *result = NULL;
3989
3990   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3991
3992   gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
3993       gst_pad_get_formats_dispatcher, &result);
3994
3995   return result;
3996 }
3997
3998 /**
3999  * gst_pad_get_formats:
4000  * @pad: a #GstPad to query
4001  *
4002  * Gets the list of supported formats from the pad.
4003  *
4004  * Returns: An array of GstFormats ended with a 0 value.
4005  */
4006 const GstFormat *
4007 gst_pad_get_formats (GstPad * pad)
4008 {
4009   GstRealPad *rpad;
4010
4011   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
4012
4013   rpad = GST_PAD_REALIZE (pad);
4014
4015   if (GST_RPAD_FORMATSFUNC (rpad))
4016     return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD (pad));
4017
4018   return NULL;
4019 }