allow pad push if peer is active
[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 "gstutils.h"
27 #include "gstelement.h"
28 #include "gsttype.h"
29 #include "gstbin.h"
30 #include "gstscheduler.h"
31 #include "gstevent.h"
32 #include "gstinfo.h"
33
34 enum {
35   TEMPL_PAD_CREATED,
36   /* FILL ME */
37   TEMPL_LAST_SIGNAL
38 };
39
40 static GstObject *padtemplate_parent_class = NULL;
41 static guint gst_pad_template_signals[TEMPL_LAST_SIGNAL] = { 0 };
42
43 GType _gst_pad_type = 0;
44
45 /***** Start with the base GstPad class *****/
46 static void             gst_pad_class_init              (GstPadClass *klass);
47 static void             gst_pad_init                    (GstPad *pad);
48 static void             gst_pad_dispose                 (GObject *object);
49
50 static gboolean         gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, 
51                                                          GstCaps *caps, gboolean clear);
52 static void             gst_pad_set_pad_template        (GstPad *pad, GstPadTemplate *templ);
53
54 #ifndef GST_DISABLE_LOADSAVE
55 static xmlNodePtr       gst_pad_save_thyself            (GstObject *object, xmlNodePtr parent);
56 #endif
57
58 static GstObject *pad_parent_class = NULL;
59
60 GType
61 gst_pad_get_type (void) 
62 {
63   if (!_gst_pad_type) {
64     static const GTypeInfo pad_info = {
65       sizeof (GstPadClass), NULL, NULL,
66       (GClassInitFunc) gst_pad_class_init, NULL, NULL,
67       sizeof (GstPad), 
68       32,
69       (GInstanceInitFunc) gst_pad_init, NULL
70     };
71     _gst_pad_type = g_type_register_static (GST_TYPE_OBJECT, "GstPad", 
72                                             &pad_info, 0);
73   }
74   return _gst_pad_type;
75 }
76
77 static void
78 gst_pad_class_init (GstPadClass *klass)
79 {
80   GObjectClass *gobject_class;
81
82   gobject_class = (GObjectClass*) klass;
83
84   pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
85
86   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
87 }
88
89 static void
90 gst_pad_init (GstPad *pad)
91 {
92   /* all structs are initialized to NULL by glib */
93 }
94 static void
95 gst_pad_dispose (GObject *object)
96 {
97   GstPad *pad = GST_PAD (object);
98
99   gst_pad_set_pad_template (pad, NULL);
100
101   G_OBJECT_CLASS (pad_parent_class)->dispose (object);
102 }
103
104
105
106 /***** Then do the Real Pad *****/
107 /* Pad signals and args */
108 enum {
109   REAL_CAPS_NEGO_FAILED,
110   REAL_LINKED,
111   REAL_UNLINKED,
112   /* FILL ME */
113   REAL_LAST_SIGNAL
114 };
115
116 enum {
117   REAL_ARG_0,
118   REAL_ARG_CAPS,
119   REAL_ARG_ACTIVE,
120   /* FILL ME */
121 };
122
123 static void     gst_real_pad_class_init         (GstRealPadClass *klass);
124 static void     gst_real_pad_init               (GstRealPad *pad);
125 static void     gst_real_pad_dispose            (GObject *object);
126
127 static void     gst_real_pad_set_property       (GObject *object, guint prop_id,
128                                                  const GValue *value, 
129                                                  GParamSpec *pspec);
130 static void     gst_real_pad_get_property       (GObject *object, guint prop_id,
131                                                  GValue *value, 
132                                                  GParamSpec *pspec);
133
134 GType _gst_real_pad_type = 0;
135
136 static GstPad *real_pad_parent_class = NULL;
137 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
138
139 GType
140 gst_real_pad_get_type (void) {
141   if (!_gst_real_pad_type) {
142     static const GTypeInfo pad_info = {
143       sizeof (GstRealPadClass), NULL, NULL,
144       (GClassInitFunc) gst_real_pad_class_init, NULL, NULL,
145       sizeof (GstRealPad),
146       32,
147       (GInstanceInitFunc) gst_real_pad_init, NULL
148     };
149     _gst_real_pad_type = g_type_register_static (GST_TYPE_PAD, "GstRealPad", 
150                                                  &pad_info, 0);
151   }
152   return _gst_real_pad_type;
153 }
154
155 static void
156 gst_real_pad_class_init (GstRealPadClass *klass)
157 {
158   GObjectClass *gobject_class;
159   GstObjectClass *gstobject_class;
160
161   gobject_class = (GObjectClass*) klass;
162   gstobject_class = (GstObjectClass*) klass;
163
164   real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
165
166   gobject_class->dispose  = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
167   gobject_class->set_property  = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
168   gobject_class->get_property  = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
169
170   gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
171     g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
172                   G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
173                   gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
174                   G_TYPE_POINTER);
175   gst_real_pad_signals[REAL_LINKED] =
176     g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
177                   G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
178                   gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
179                   G_TYPE_POINTER);
180   gst_real_pad_signals[REAL_UNLINKED] =
181     g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
182                   G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL,
183                   gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
184                   G_TYPE_POINTER);
185
186 /*  gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
187 /*                           GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
188   g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
189     g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
190                           TRUE, G_PARAM_READWRITE));
191   g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_CAPS,
192     g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
193                         GST_TYPE_CAPS, G_PARAM_READABLE));
194
195 #ifndef GST_DISABLE_LOADSAVE
196   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
197 #endif
198   gstobject_class->path_string_separator = ".";
199 }
200
201 static void
202 gst_real_pad_init (GstRealPad *pad)
203 {
204   pad->direction = GST_PAD_UNKNOWN;
205   pad->peer = NULL;
206
207   pad->chainfunc = NULL;
208   pad->getfunc = NULL;
209
210   pad->chainhandler = NULL;
211   pad->gethandler = NULL;
212
213   pad->bufferpoolfunc = NULL;
214   pad->ghostpads = NULL;
215   pad->caps = NULL;
216
217   pad->linkfunc = NULL;
218   pad->getcapsfunc = NULL;
219
220   pad->convertfunc      = gst_pad_convert_default;
221   pad->eventfunc        = gst_pad_event_default;
222   pad->convertfunc      = gst_pad_convert_default;
223   pad->queryfunc        = gst_pad_query_default;
224   pad->intlinkfunc      = gst_pad_get_internal_links_default;
225
226   pad->eventmaskfunc    = gst_pad_get_event_masks_default;
227   pad->formatsfunc      = gst_pad_get_formats_default;
228   pad->querytypefunc    = gst_pad_get_query_types_default;
229
230   GST_FLAG_SET (pad, GST_PAD_DISABLED);
231   GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING);
232   
233   gst_probe_dispatcher_init (&pad->probedisp);
234 }
235
236 static void
237 gst_real_pad_set_property (GObject *object, guint prop_id, 
238                            const GValue *value, GParamSpec *pspec)
239 {
240   g_return_if_fail (GST_IS_PAD (object));
241
242   switch (prop_id) {
243     case REAL_ARG_ACTIVE:
244       gst_pad_set_active (GST_PAD (object), g_value_get_boolean (value));
245       break;
246     default:
247       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
248       break;
249   }
250 }
251
252 static void
253 gst_real_pad_get_property (GObject *object, guint prop_id, 
254                            GValue *value, GParamSpec *pspec)
255 {
256   g_return_if_fail (GST_IS_PAD (object));
257
258   switch (prop_id) {
259     case REAL_ARG_ACTIVE:
260       g_value_set_boolean (value, !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
261       break;
262     case REAL_ARG_CAPS:
263       g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object)));
264       break;
265     default:
266       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
267       break;
268   }
269 }
270
271
272 /**
273  * gst_pad_custom_new:
274  * @type: the #Gtype of the pad.
275  * @name: the name of the new pad.
276  * @direction: the #GstPadDirection of the pad.
277  *
278  * Creates a new pad with the given name and type in the given direction.
279  * If name is NULL, a guaranteed unique name (across all pads) 
280  * will be assigned.
281  *
282  * Returns: a new #GstPad, or NULL in case of an error.
283  */
284 GstPad*
285 gst_pad_custom_new (GType type, const gchar *name,
286                     GstPadDirection direction)
287 {
288   GstRealPad *pad;
289
290   g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
291
292   pad = g_object_new (type, NULL);
293   gst_object_set_name (GST_OBJECT (pad), name);
294   GST_RPAD_DIRECTION (pad) = direction;
295
296   return GST_PAD (pad);
297 }
298
299 /**
300  * gst_pad_new:
301  * @name: the name of the new pad.
302  * @direction: the #GstPadDirection of the pad.
303  *
304  * Creates a new real pad with the given name in the given direction.
305  * If name is NULL, a guaranteed unique name (across all pads) 
306  * will be assigned.
307  *
308  * Returns: a new #GstPad, or NULL in case of an error.
309  */
310 GstPad*
311 gst_pad_new (const gchar *name,
312              GstPadDirection direction)
313 {
314   return gst_pad_custom_new (gst_real_pad_get_type (), name, direction);
315 }
316
317 /**
318  * gst_pad_custom_new_from_template:
319  * @type: the custom #GType of the pad.
320  * @templ: the #GstPadTemplate to instantiate from.
321  * @name: the name of the new pad.
322  *
323  * Creates a new custom pad with the given name from the given template.
324  * If name is NULL, a guaranteed unique name (across all pads) 
325  * will be assigned.
326  *
327  * Returns: a new #GstPad, or NULL in case of an error.
328  */
329 GstPad*
330 gst_pad_custom_new_from_template (GType type, GstPadTemplate *templ,
331                                   const gchar *name)
332 {
333   GstPad *pad;
334
335   g_return_val_if_fail (templ != NULL, NULL);
336
337   pad = gst_pad_new (name, templ->direction);
338   gst_pad_set_pad_template (pad, templ);
339
340   return pad;
341 }
342
343 /**
344  * gst_pad_new_from_template:
345  * @templ: the pad template to use
346  * @name: the name of the element
347  *
348  * Creates a new real pad with the given name from the given template.
349  * If name is NULL, a guaranteed unique name (across all pads) 
350  * will be assigned.
351  *
352  * Returns: a new #GstPad, or NULL in case of an error.
353  */
354 GstPad*
355 gst_pad_new_from_template (GstPadTemplate *templ, const gchar *name)
356 {
357   return gst_pad_custom_new_from_template (gst_real_pad_get_type (), 
358                                            templ, name);
359 }
360
361 /**
362  * gst_pad_get_direction:
363  * @pad: a #GstPad to get the direction of.
364  *
365  * Gets the direction of the pad.
366  *
367  * Returns: the #GstPadDirection of the pad.
368  */
369 GstPadDirection
370 gst_pad_get_direction (GstPad *pad)
371 {
372   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
373
374   return GST_PAD_DIRECTION (pad);
375 }
376
377 /**
378  * gst_pad_set_active:
379  * @pad: the #GstPad to activate or deactivate.
380  * @active: TRUE to activate the pad.
381  *
382  * Activates or deactivates the given pad.
383  */
384 void
385 gst_pad_set_active (GstPad *pad, gboolean active)
386 {
387   GstRealPad *realpad;
388   gboolean old;
389
390   g_return_if_fail (GST_IS_PAD (pad));
391
392   old = GST_PAD_IS_ACTIVE (pad);
393
394   if (old == active)
395     return;
396
397   realpad = GST_PAD_REALIZE (pad);
398
399   if (active) {
400     GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s", 
401                GST_DEBUG_PAD_NAME (realpad));
402     GST_FLAG_UNSET (realpad, GST_PAD_DISABLED);
403   } else {
404     GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s", 
405                GST_DEBUG_PAD_NAME (realpad));
406     GST_FLAG_SET (realpad, GST_PAD_DISABLED);
407   }
408   if (old != active)
409     g_object_notify (G_OBJECT (realpad), "active");
410 }
411
412 /**
413  * gst_pad_is_active:
414  * @pad: the #GstPad to query
415  *
416  * Query if a pad is active
417  *
418  * Returns: TRUE if the pad is active.
419  */
420 gboolean
421 gst_pad_is_active (GstPad *pad)
422 {
423   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
424
425   return !GST_FLAG_IS_SET (pad, GST_PAD_DISABLED);
426 }
427
428 /**
429  * gst_pad_set_name:
430  * @pad: a #GstPad to set the name of.
431  * @name: the name of the pad.
432  *
433  * Sets the name of a pad.  If name is NULL, then a guaranteed unique
434  * name will be assigned.
435  */
436 void
437 gst_pad_set_name (GstPad *pad, const gchar *name)
438 {
439   g_return_if_fail (GST_IS_PAD (pad));
440
441   gst_object_set_name (GST_OBJECT (pad), name);
442 }
443
444 /**
445  * gst_pad_get_name:
446  * @pad: a #GstPad to get the name of.
447  *
448  * Gets the name of a pad.
449  *
450  * Returns: the name of the pad.  This is not a newly allocated pointer
451  * so you must not free it.
452  */
453 const gchar*
454 gst_pad_get_name (GstPad *pad)
455 {
456   g_return_val_if_fail (pad != NULL, NULL);
457   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
458
459   return GST_OBJECT_NAME (pad);
460 }
461
462 /**
463  * gst_pad_set_chain_function:
464  * @pad: a #GstPad to set the chain function for.
465  * @chain: the #GstPadChainFunction to set.
466  *
467  * Sets the given chain function for the pad.
468  */
469 void 
470 gst_pad_set_chain_function (GstPad *pad, GstPadChainFunction chain)
471 {
472   g_return_if_fail (pad != NULL);
473   g_return_if_fail (GST_IS_REAL_PAD (pad));
474   g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK);
475
476   GST_RPAD_CHAINFUNC (pad) = chain;
477   GST_CAT_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s",
478              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain));
479 }
480
481 /**
482  * gst_pad_set_get_function:
483  * @pad: a #GstPad to set the get function for.
484  * @get: the #GstPadGetFunction to set.
485  *
486  * Sets the given get function for the pad.
487  */
488 void
489 gst_pad_set_get_function (GstPad *pad,
490                           GstPadGetFunction get)
491 {
492   g_return_if_fail (pad != NULL);
493   g_return_if_fail (GST_IS_REAL_PAD (pad));
494   g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
495
496   GST_RPAD_GETFUNC (pad) = get;
497   
498   GST_CAT_DEBUG (GST_CAT_PADS, "getfunc for %s:%s  set to %s",
499              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
500 }
501
502 /**
503  * gst_pad_set_event_function:
504  * @pad: a #GstPad to set the event handler for.
505  * @event: the #GstPadEventFunction to set.
506  *
507  * Sets the given event handler for the pad.
508  */
509 void
510 gst_pad_set_event_function (GstPad *pad,
511                             GstPadEventFunction event)
512 {
513   g_return_if_fail (GST_IS_REAL_PAD (pad));
514   g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
515
516   GST_RPAD_EVENTFUNC (pad) = event;
517
518   GST_CAT_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s  set to %s",
519              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event));
520 }
521
522 /**
523  * gst_pad_set_event_mask_function:
524  * @pad: a #GstPad to set the event mask function for.
525  * @mask_func: the #GstPadEventMaskFunction to set.
526  *
527  * Sets the given event mask function for the pad.
528  */
529 void
530 gst_pad_set_event_mask_function (GstPad *pad, 
531                                  GstPadEventMaskFunction mask_func)
532 {
533   g_return_if_fail (GST_IS_REAL_PAD (pad));
534
535   GST_RPAD_EVENTMASKFUNC (pad) = mask_func;
536
537   GST_CAT_DEBUG (GST_CAT_PADS, "eventmaskfunc for %s:%s  set to %s",
538              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (mask_func));
539 }
540
541 /**
542  * gst_pad_get_event_masks:
543  * @pad: a #GstPad to get the event mask for.
544  *
545  * Gets the array of eventmasks from the given pad.
546  *
547  * Returns: an array with eventmasks, the list is ended 
548  * with 0
549  */
550 const GstEventMask*
551 gst_pad_get_event_masks (GstPad *pad)
552 {
553   GstRealPad *rpad;
554   
555   if (pad == NULL)
556     return FALSE;
557
558   rpad = GST_PAD_REALIZE (pad);
559
560   g_return_val_if_fail (rpad, FALSE);
561
562   if (GST_RPAD_EVENTMASKFUNC (rpad))
563     return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD_CAST (pad));
564
565   return NULL;
566 }
567
568 static gboolean
569 gst_pad_get_event_masks_dispatcher (GstPad *pad, const GstEventMask **data)
570 {
571   *data = gst_pad_get_event_masks (pad);
572
573   return TRUE;
574 }
575
576 /**
577  * gst_pad_get_event_masks_default:
578  * @pad: a #GstPad to get the event mask for.
579  *
580  * Invokes the default event masks dispatcher on the pad.
581  *
582  * Returns: an array with eventmasks, the list is ended 
583  * with 0
584  */
585 const GstEventMask* 
586 gst_pad_get_event_masks_default (GstPad *pad)
587 {
588   GstEventMask *result = NULL;
589
590   gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
591                            gst_pad_get_event_masks_dispatcher, &result);
592
593   return result;
594 }
595
596 /**
597  * gst_pad_set_convert_function:
598  * @pad: a #GstPad to set the convert function for.
599  * @convert: the #GstPadConvertFunction to set.
600  *
601  * Sets the given convert function for the pad.
602  */
603 void
604 gst_pad_set_convert_function (GstPad *pad,
605                               GstPadConvertFunction convert)
606 {
607   g_return_if_fail (pad != NULL);
608   g_return_if_fail (GST_IS_REAL_PAD (pad));
609
610   GST_RPAD_CONVERTFUNC (pad) = convert;
611
612   GST_CAT_DEBUG (GST_CAT_PADS, "convertfunc for %s:%s  set to %s",
613              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (convert));
614 }
615
616 /**
617  * gst_pad_set_query_function:
618  * @pad: the #GstPad to set the query function for.
619  * @query: the #GstPadQueryFunction to set.
620  *
621  * Set the given query function for the pad.
622  */
623 void
624 gst_pad_set_query_function (GstPad *pad, GstPadQueryFunction query)
625 {
626   g_return_if_fail (pad != NULL);
627   g_return_if_fail (GST_IS_REAL_PAD (pad));
628
629   GST_RPAD_QUERYFUNC (pad) = query;
630
631   GST_CAT_DEBUG (GST_CAT_PADS, "queryfunc for %s:%s  set to %s",
632              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
633 }
634
635 /**
636  * gst_pad_set_query_type_function:
637  * @pad: the #GstPad to set the query type function for.
638  * @type_func: the #GstPadQueryTypeFunction to set.
639  *
640  * Set the given query type function for the pad.
641  */
642 void
643 gst_pad_set_query_type_function (GstPad *pad, GstPadQueryTypeFunction type_func)
644 {
645   g_return_if_fail (pad != NULL);
646   g_return_if_fail (GST_IS_REAL_PAD (pad));
647
648   GST_RPAD_QUERYTYPEFUNC (pad) = type_func;
649
650   GST_CAT_DEBUG (GST_CAT_PADS, "querytypefunc for %s:%s  set to %s",
651              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (type_func));
652 }
653
654 /**
655  * gst_pad_get_query_types:
656  * @pad: the #GstPad to query
657  *
658  * Get an array of supported queries that can be performed
659  * on this pad.
660  *
661  * Returns: an array of querytypes anded with 0.
662  */
663 const GstQueryType*
664 gst_pad_get_query_types (GstPad *pad)
665 {
666   GstRealPad *rpad;
667   
668   if (pad == NULL)
669     return FALSE;
670
671   rpad = GST_PAD_REALIZE (pad);
672
673   g_return_val_if_fail (rpad, FALSE);
674
675   if (GST_RPAD_QUERYTYPEFUNC (rpad))
676     return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD_CAST (pad));
677
678   return NULL;
679 }
680
681 static gboolean
682 gst_pad_get_query_types_dispatcher (GstPad *pad, const GstQueryType **data)
683 {
684   *data = gst_pad_get_query_types (pad);
685
686   return TRUE;
687 }
688
689 /**
690  * gst_pad_get_query_types_default:
691  * @pad: the #GstPad to query
692  *
693  * Invoke the default dispatcher for the query types on
694  * the pad.
695  *
696  * Returns: an array of querytypes anded with 0.
697  */
698 const GstQueryType*
699 gst_pad_get_query_types_default (GstPad *pad)
700 {
701   GstQueryType *result = NULL;
702
703   gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
704                            gst_pad_get_query_types_dispatcher, &result);
705
706   return result;
707 }
708
709 /**
710  * gst_pad_set_internal_link_function:
711  * @pad: a #GstPad to set the internal link function for.
712  * @intlink: the #GstPadIntLinkFunction to set.
713  *
714  * Sets the given internal link function for the pad.
715  */
716 void
717 gst_pad_set_internal_link_function (GstPad *pad, 
718                                           GstPadIntLinkFunction intlink)
719 {
720   g_return_if_fail (pad != NULL);
721   g_return_if_fail (GST_IS_REAL_PAD (pad));
722
723   GST_RPAD_INTLINKFUNC (pad) = intlink;
724   GST_CAT_DEBUG (GST_CAT_PADS, "internal link for %s:%s  set to %s",
725              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intlink));
726 }
727
728 /**
729  * gst_pad_set_formats_function:
730  * @pad: the #GstPad to set the formats function for.
731  * @formats: the #GstPadFormatsFunction to set.
732  *
733  * Sets the given formats function for the pad.
734  */
735 void
736 gst_pad_set_formats_function (GstPad *pad, GstPadFormatsFunction formats)
737 {
738   g_return_if_fail (pad != NULL);
739   g_return_if_fail (GST_IS_REAL_PAD (pad));
740
741   GST_RPAD_FORMATSFUNC (pad) = formats;
742   GST_CAT_DEBUG (GST_CAT_PADS, "formats function for %s:%s  set to %s",
743              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (formats));
744 }
745
746 /**
747  * gst_pad_set_link_function:
748  * @pad: a #GstPad to set the link function for.
749  * @link: the #GstPadLinkFunction to set.
750  *
751  * Sets the given link function for the pad. It will be called
752  * when the pad is linked or relinked with caps.
753  */
754 void
755 gst_pad_set_link_function (GstPad *pad,
756                               GstPadLinkFunction link)
757 {
758   g_return_if_fail (pad != NULL);
759   g_return_if_fail (GST_IS_REAL_PAD (pad));
760
761   GST_RPAD_LINKFUNC (pad) = link;
762   GST_CAT_DEBUG (GST_CAT_PADS, "linkfunc for %s:%s set to %s",
763              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (link));
764 }
765
766 /**
767  * gst_pad_set_unlink_function:
768  * @pad: a #GstPad to set the unlink function for.
769  * @unlink: the #GstPadUnlinkFunction to set.
770  *
771  * Sets the given unlink function for the pad. It will be called
772  * when the pad is unlinked.
773  */
774 void
775 gst_pad_set_unlink_function (GstPad *pad,
776                               GstPadUnlinkFunction unlink)
777 {
778   g_return_if_fail (pad != NULL);
779   g_return_if_fail (GST_IS_REAL_PAD (pad));
780
781   GST_RPAD_UNLINKFUNC (pad) = unlink;
782   GST_CAT_DEBUG (GST_CAT_PADS, "unlinkfunc for %s:%s set to %s",
783              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (unlink));
784 }
785
786 /**
787  * gst_pad_set_getcaps_function:
788  * @pad: a #GstPad to set the getcaps function for.
789  * @getcaps: the #GstPadGetCapsFunction to set.
790  *
791  * Sets the given getcaps function for the pad.
792  */
793 void
794 gst_pad_set_getcaps_function (GstPad *pad,
795                               GstPadGetCapsFunction getcaps)
796 {
797   g_return_if_fail (pad != NULL);
798   g_return_if_fail (GST_IS_REAL_PAD (pad));
799
800   GST_RPAD_GETCAPSFUNC (pad) = getcaps;
801   GST_CAT_DEBUG (GST_CAT_PADS, "getcapsfunc for %s:%s set to %s",
802              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
803 }
804 /**
805  * gst_pad_set_bufferpool_function:
806  * @pad: a #GstPad to set the bufferpool function for.
807  * @bufpool: the #GstPadBufferPoolFunction to set.
808  *
809  * Sets the given bufferpool function for the pad. Note that the
810  * bufferpool function can only be set on sinkpads.
811  */
812 void
813 gst_pad_set_bufferpool_function (GstPad *pad,
814                                  GstPadBufferPoolFunction bufpool)
815 {
816   g_return_if_fail (pad != NULL);
817   g_return_if_fail (GST_IS_REAL_PAD (pad));
818   g_return_if_fail (GST_PAD_IS_SINK (pad));
819
820   GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool;
821   GST_CAT_DEBUG (GST_CAT_PADS, "bufferpoolfunc for %s:%s set to %s",
822              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (bufpool));
823 }
824
825 /**
826  * gst_pad_unlink:
827  * @srcpad: the source #GstPad to unlink.
828  * @sinkpad: the sink #GstPad to unlink.
829  *
830  * Unlinks the source pad from the sink pad.
831  */
832 void
833 gst_pad_unlink (GstPad *srcpad,
834                     GstPad *sinkpad)
835 {
836   GstRealPad *realsrc, *realsink;
837   GstScheduler *src_sched, *sink_sched;
838
839   /* generic checks */
840   g_return_if_fail (srcpad != NULL);
841   g_return_if_fail (GST_IS_PAD (srcpad));
842   g_return_if_fail (sinkpad != NULL);
843   g_return_if_fail (GST_IS_PAD (sinkpad));
844
845   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)",
846             GST_DEBUG_PAD_NAME (srcpad), srcpad, 
847             GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
848
849   /* now we need to deal with the real/ghost stuff */
850   realsrc = GST_PAD_REALIZE (srcpad);
851   realsink = GST_PAD_REALIZE (sinkpad);
852
853   g_return_if_fail (GST_RPAD_PEER (realsrc) != NULL);
854   g_return_if_fail (GST_RPAD_PEER (realsink) == realsrc);
855
856   if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
857       (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
858     GstRealPad *temppad;
859
860     temppad = realsrc;
861     realsrc = realsink;
862     realsink = temppad;
863   }
864   g_return_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
865                     (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK));
866
867   if (GST_RPAD_UNLINKFUNC (srcpad)) {
868     GST_RPAD_UNLINKFUNC (srcpad) (srcpad);
869   }
870   if (GST_RPAD_UNLINKFUNC (sinkpad)) {
871     GST_RPAD_UNLINKFUNC (sinkpad) (sinkpad);
872   }
873
874   /* get the schedulers before we unlink */
875   src_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsrc));
876   sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsink));
877
878   /* first clear peers */
879   GST_RPAD_PEER (realsrc) = NULL;
880   GST_RPAD_PEER (realsink) = NULL;
881
882   /* reset the filters, both filters are refcounted once */
883   if (GST_RPAD_FILTER (realsrc)) {
884     gst_caps_replace (&GST_RPAD_FILTER (realsink), NULL);
885     gst_caps_replace (&GST_RPAD_FILTER (realsrc), NULL);
886   }
887
888   /* now tell the scheduler */
889   if (src_sched && src_sched == sink_sched) {
890     gst_scheduler_pad_unlink (src_sched, 
891                               GST_PAD_CAST (realsrc), 
892                               GST_PAD_CAST (realsink));
893   }
894
895   /* hold a reference, as they can go away in the signal handlers */
896   gst_object_ref (GST_OBJECT (realsrc));
897   gst_object_ref (GST_OBJECT (realsink));
898
899   /* fire off a signal to each of the pads telling them 
900    * that they've been unlinked */
901   g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_UNLINKED], 
902                  0, realsink);
903   g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_UNLINKED], 
904                  0, realsrc);
905
906   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
907             GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
908
909   gst_object_unref (GST_OBJECT (realsrc));
910   gst_object_unref (GST_OBJECT (realsink));
911 }
912
913 static gboolean
914 gst_pad_check_schedulers (GstRealPad *realsrc, GstRealPad *realsink)
915 {
916   GstScheduler *src_sched, *sink_sched;
917   gint num_decoupled = 0;
918
919   src_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsrc));
920   sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsink));
921
922   if (src_sched && sink_sched) {
923     if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
924       num_decoupled++;
925     if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
926       num_decoupled++;
927
928     if (src_sched != sink_sched && num_decoupled != 1) {
929       return FALSE;
930     }
931   }
932   return TRUE;
933 }
934
935 /**
936  * gst_pad_can_link_filtered:
937  * @srcpad: the source #GstPad to link.
938  * @sinkpad: the sink #GstPad to link.
939  * @filtercaps: the filter #GstCaps.
940  *
941  * Checks if the source pad and the sink pad can be linked when constrained
942  * by the given filter caps.
943  *
944  * Returns: TRUE if the pads can be linked, FALSE otherwise.
945  */
946 gboolean
947 gst_pad_can_link_filtered (GstPad *srcpad, GstPad *sinkpad,
948                            GstCaps *filtercaps)
949 {
950   GstRealPad *realsrc, *realsink;
951
952   /* generic checks */
953   g_return_val_if_fail (srcpad != NULL, FALSE);
954   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
955   g_return_val_if_fail (sinkpad != NULL, FALSE);
956   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
957
958   /* now we need to deal with the real/ghost stuff */
959   realsrc = GST_PAD_REALIZE (srcpad);
960   realsink = GST_PAD_REALIZE (sinkpad);
961
962   g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
963   g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
964   g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, FALSE);
965   g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, FALSE);
966
967   if (!gst_pad_check_schedulers (realsrc, realsink)) {
968     g_warning ("linking pads with different scheds requires "
969                "exactly one decoupled element (queue)");
970     return FALSE;
971   }
972
973   /* check if the directions are compatible */
974   if (!(((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
975          (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) ||
976         ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
977          (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK))))
978     return FALSE;
979
980   return TRUE;
981 }
982 /**
983  * gst_pad_can_link:
984  * @srcpad: the source #GstPad to link.
985  * @sinkpad: the sink #GstPad to link.
986  *
987  * Checks if the source pad and the sink pad can be link.
988  *
989  * Returns: TRUE if the pads can be linked, FALSE otherwise.
990  */
991 gboolean
992 gst_pad_can_link (GstPad *srcpad, GstPad *sinkpad)
993 {
994   return gst_pad_can_link_filtered (srcpad, sinkpad, NULL);
995 }
996
997 /**
998  * gst_pad_link_filtered:
999  * @srcpad: the source #GstPad to link.
1000  * @sinkpad: the sink #GstPad to link.
1001  * @filtercaps: the filter #GstCaps.
1002  *
1003  * Links the source pad and the sink pad, constrained
1004  * by the given filter caps. This function sinks the caps.
1005  *
1006  * Returns: TRUE if the pads have been linked, FALSE otherwise.
1007  */
1008 gboolean
1009 gst_pad_link_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
1010 {
1011   GstRealPad *realsrc, *realsink;
1012   GstScheduler *src_sched, *sink_sched;
1013
1014   /* generic checks */
1015   g_return_val_if_fail (srcpad != NULL, FALSE);
1016   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1017   g_return_val_if_fail (sinkpad != NULL, FALSE);
1018   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1019
1020   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
1021             GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1022
1023   /* now we need to deal with the real/ghost stuff */
1024   realsrc = GST_PAD_REALIZE (srcpad);
1025   realsink = GST_PAD_REALIZE (sinkpad);
1026
1027   if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
1028     GST_CAT_INFO (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
1029               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1030   }
1031   /* FIXME: shouldn't we convert this to g_return_val_if_fail? */
1032   if (GST_RPAD_PEER (realsrc) != NULL) {
1033     GST_CAT_INFO (GST_CAT_PADS, "Real source pad %s:%s has a peer, failed",
1034               GST_DEBUG_PAD_NAME (realsrc));
1035     return FALSE;
1036   }
1037   if (GST_RPAD_PEER (realsink) != NULL) {
1038     GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has a peer, failed",
1039               GST_DEBUG_PAD_NAME (realsink));
1040     return FALSE;
1041   }
1042   if (GST_PAD_PARENT (realsrc) == NULL) {
1043     GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
1044               GST_DEBUG_PAD_NAME (realsrc));
1045     return FALSE;
1046   }
1047   if (GST_PAD_PARENT (realsink) == NULL) {
1048     GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has no parent, failed",
1049               GST_DEBUG_PAD_NAME (realsrc));
1050     return FALSE;
1051   }
1052
1053   if (!gst_pad_check_schedulers (realsrc, realsink)) {
1054     g_warning ("linking pads with different scheds requires "
1055                "exactly one decoupled element (such as queue)");
1056     return FALSE;
1057   }
1058   
1059   /* check for reversed directions and swap if necessary */
1060   if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
1061       (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
1062     GstRealPad *temppad;
1063
1064     temppad = realsrc;
1065     realsrc = realsink;
1066     realsink = temppad;
1067   }
1068   if (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC) {
1069     GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s is not a source pad, failed",
1070               GST_DEBUG_PAD_NAME (realsrc));
1071     return FALSE;
1072   }    
1073   if (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK) {
1074     GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s is not a sink pad, failed",
1075               GST_DEBUG_PAD_NAME (realsink));
1076     return FALSE;
1077   }    
1078   /* first set peers */
1079   GST_RPAD_PEER (realsrc) = realsink;
1080   GST_RPAD_PEER (realsink) = realsrc;
1081
1082   /* try to negotiate the pads, we don't need to clear the caps here */
1083   if (!gst_pad_try_relink_filtered_func (realsrc, realsink,
1084                                          filtercaps, FALSE)) {
1085     GST_CAT_DEBUG (GST_CAT_CAPS, "relink_filtered_func failed, can't link");
1086
1087     GST_RPAD_PEER (realsrc) = NULL;
1088     GST_RPAD_PEER (realsink) = NULL;
1089
1090     return FALSE;
1091   }
1092
1093   /* fire off a signal to each of the pads telling them 
1094    * that they've been linked */
1095   g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_LINKED], 
1096                  0, realsink);
1097   g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_LINKED], 
1098                  0, realsrc);
1099
1100   src_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsrc));
1101   sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsink));
1102
1103   /* now tell the scheduler */
1104   if (src_sched && src_sched == sink_sched) {
1105     gst_scheduler_pad_link (src_sched, 
1106                             GST_PAD_CAST (realsrc), GST_PAD_CAST (realsink));
1107   }
1108   else {
1109     GST_CAT_INFO (GST_CAT_PADS, "not telling link to scheduler %s:%s and %s:%s, %p %p",
1110             GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
1111             src_sched, sink_sched);
1112   }
1113
1114   GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
1115             GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1116
1117   return TRUE;
1118 }
1119
1120 /**
1121  * gst_pad_link:
1122  * @srcpad: the source #GstPad to link.
1123  * @sinkpad: the sink #GstPad to link.
1124  *
1125  * Links the source pad to the sink pad.
1126  *
1127  * Returns: TRUE if the pad could be linked, FALSE otherwise.
1128  */
1129 gboolean
1130 gst_pad_link (GstPad *srcpad, GstPad *sinkpad)
1131 {
1132   return gst_pad_link_filtered (srcpad, sinkpad, NULL);
1133 }
1134
1135 /**
1136  * gst_pad_set_parent:
1137  * @pad: a #GstPad to set the parent of.
1138  * @parent: the new parent #GstElement.
1139  *
1140  * Sets the parent object of a pad.
1141  */
1142 void
1143 gst_pad_set_parent (GstPad *pad, GstElement *parent)
1144 {
1145   g_return_if_fail (pad != NULL);
1146   g_return_if_fail (GST_IS_PAD (pad));
1147   g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
1148   g_return_if_fail (parent != NULL);
1149   g_return_if_fail (GST_IS_OBJECT (parent));
1150   g_return_if_fail ((gpointer) pad != (gpointer) parent);
1151
1152   gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (parent));
1153 }
1154
1155 /**
1156  * gst_pad_get_parent:
1157  * @pad: the #GstPad to get the parent of.
1158  *
1159  * Gets the parent object of this pad.
1160  *
1161  * Returns: the parent #GstElement.
1162  */
1163 GstElement*
1164 gst_pad_get_parent (GstPad *pad)
1165 {
1166   g_return_val_if_fail (pad != NULL, NULL);
1167   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1168
1169   return GST_PAD_PARENT (pad);
1170 }
1171
1172 static void
1173 gst_pad_set_pad_template (GstPad *pad, GstPadTemplate *templ)
1174 {
1175   /* this function would need checks if it weren't static */
1176
1177   gst_object_replace ((GstObject **) &pad->padtemplate, (GstObject *) templ);
1178   
1179   if (templ)
1180     g_signal_emit (G_OBJECT (templ), gst_pad_template_signals[TEMPL_PAD_CREATED], 0, pad);
1181
1182 /**
1183  * gst_pad_get_pad_template:
1184  * @pad: a #GstPad to get the pad template of.
1185  *
1186  * Gets the pad template object of this pad.
1187  *
1188  * Returns: the #GstPadTemplate from which this pad was instantiated.
1189  */
1190 GstPadTemplate*
1191 gst_pad_get_pad_template (GstPad *pad)
1192 {
1193   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1194
1195   return GST_PAD_PAD_TEMPLATE (pad); 
1196 }
1197
1198
1199 /**
1200  * gst_pad_get_scheduler:
1201  * @pad: a #GstPad to get the scheduler of.
1202  *
1203  * Gets the scheduler of the pad. Since the pad does not
1204  * have a scheduler of its own, the scheduler of the parent
1205  * is taken. For decoupled pads, the scheduler of the peer
1206  * parent is taken.
1207  *
1208  * Returns: the #GstScheduler of the pad.
1209  */
1210 GstScheduler*
1211 gst_pad_get_scheduler (GstPad *pad)
1212 {
1213   GstScheduler *scheduler = NULL;
1214   GstElement *parent;
1215   
1216   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1217   
1218   parent = gst_pad_get_parent (pad);
1219   if (parent) {
1220     if (GST_FLAG_IS_SET (parent, GST_ELEMENT_DECOUPLED)) {
1221       GstRealPad *peer = GST_RPAD_PEER (pad);
1222
1223       if (peer) {
1224         scheduler = gst_element_get_scheduler (gst_pad_get_parent (GST_PAD_CAST (peer)));
1225       }
1226     }
1227     else {
1228       scheduler = gst_element_get_scheduler (parent);
1229     }
1230   }
1231  
1232   return scheduler;
1233 }
1234
1235 /**
1236  * gst_pad_get_real_parent:
1237  * @pad: a #GstPad to get the real parent of.
1238  *
1239  * Gets the real parent object of this pad. If the pad
1240  * is a ghost pad, the actual owner of the real pad is
1241  * returned, as opposed to #gst_pad_get_parent().
1242  *
1243  * Returns: the parent #GstElement.
1244  */
1245 GstElement*
1246 gst_pad_get_real_parent (GstPad *pad)
1247 {
1248   g_return_val_if_fail (pad != NULL, NULL);
1249   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1250
1251   return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
1252 }
1253
1254 /**
1255  * gst_pad_add_ghost_pad:
1256  * @pad: a #GstPad to attach the ghost pad to.
1257  * @ghostpad: the ghost #GstPad to to the pad.
1258  *
1259  * Adds a ghost pad to a pad.
1260  */
1261 void
1262 gst_pad_add_ghost_pad (GstPad *pad,
1263                        GstPad *ghostpad)
1264 {
1265   GstRealPad *realpad;
1266
1267   g_return_if_fail (pad != NULL);
1268   g_return_if_fail (GST_IS_PAD (pad));
1269   g_return_if_fail (ghostpad != NULL);
1270   g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
1271
1272   realpad = GST_PAD_REALIZE (pad);
1273
1274   realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
1275 }
1276
1277
1278 /**
1279  * gst_pad_remove_ghost_pad:
1280  * @pad: a #GstPad to remove the ghost pad from.
1281  * @ghostpad: the ghost #GstPad to remove from the pad.
1282  *
1283  * Removes a ghost pad from a pad.
1284  */
1285 void
1286 gst_pad_remove_ghost_pad (GstPad *pad,
1287                           GstPad *ghostpad)
1288 {
1289   GstRealPad *realpad;
1290
1291   g_return_if_fail (GST_IS_PAD (pad));
1292   g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
1293   realpad = GST_PAD_REALIZE (pad);
1294   g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad);
1295
1296   realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
1297   GST_GPAD_REALPAD (ghostpad) = NULL;
1298 }
1299
1300 /**
1301  * gst_pad_get_ghost_pad_list:
1302  * @pad: a #GstPad to get the ghost pads of.
1303  *
1304  * Gets the ghost pads of this pad.
1305  *
1306  * Returns: a #GList of ghost pads.
1307  */
1308 GList*
1309 gst_pad_get_ghost_pad_list (GstPad *pad)
1310 {
1311   g_return_val_if_fail (pad != NULL, NULL);
1312   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1313
1314   return GST_PAD_REALIZE(pad)->ghostpads;
1315 }
1316
1317 /* an internal caps negotiation helper function:
1318  * 
1319  * 1. optionally calls the pad link function with the provided caps
1320  * 2. deals with the result code of the link function
1321  * 3. sets fixed caps on the pad.
1322  */
1323 static GstPadLinkReturn
1324 gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
1325 {
1326   GstCaps *allowed = NULL;
1327   GstPadTemplate *template;
1328   GstElement *parent = GST_PAD_PARENT (pad);
1329
1330   g_return_val_if_fail (pad != NULL, GST_PAD_LINK_REFUSED);
1331   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_LINK_REFUSED);
1332
1333   /* if this pad has a parent and the parent is not READY, delay the
1334    * negotiation */
1335   if (parent && GST_STATE (parent) < GST_STATE_READY)
1336   {
1337     GST_CAT_DEBUG (GST_CAT_CAPS, "parent %s of pad %s:%s is not READY",
1338                GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (pad));
1339     return GST_PAD_LINK_DELAYED;
1340   }
1341           
1342   GST_CAT_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
1343             caps, GST_DEBUG_PAD_NAME (pad));
1344
1345   /* first see if we have to check against a filter, we ref the caps here as we're
1346    * going to unref it later on */
1347   if (!(allowed = gst_caps_ref (GST_RPAD_FILTER (pad)))) {
1348     /* no filter, make sure we check against the padtemplate then */
1349     if ((template = gst_pad_get_pad_template (GST_PAD_CAST (pad)))) {
1350       allowed = gst_pad_template_get_caps (template);
1351     }
1352   }
1353   
1354   /* do we have to check the caps against something? */
1355   if (allowed) {
1356     GstCaps *intersection;
1357
1358     /* check against calculated caps */
1359     intersection = gst_caps_intersect (caps, allowed);
1360
1361     /* oops, empty intersection, caps don"t have anything in common */
1362     if (!intersection) {
1363       GST_CAT_INFO (GST_CAT_CAPS, "caps did not intersect with %s:%s's allowed caps",
1364                 GST_DEBUG_PAD_NAME (pad));
1365       gst_caps_debug (caps, "caps themselves (attemped to set)");
1366       gst_caps_debug (allowed,
1367                       "allowed caps that did not agree with caps");
1368       gst_caps_unref (allowed);
1369       return GST_PAD_LINK_REFUSED;
1370     }
1371     /* caps checks out fine, we can unref the intersection now */
1372     gst_caps_unref (intersection);
1373     gst_caps_unref (allowed);
1374     /* given that the caps are fixed, we know that their intersection with the
1375      * padtemplate caps is the same as caps itself */
1376   }
1377
1378   /* we need to notify the link function */
1379   if (notify && GST_RPAD_LINKFUNC (pad)) {
1380     GstPadLinkReturn res;
1381     gchar *debug_string;
1382     gboolean negotiating;
1383
1384     GST_CAT_INFO (GST_CAT_CAPS, "calling link function on pad %s:%s",
1385             GST_DEBUG_PAD_NAME (pad));
1386
1387     negotiating = GST_FLAG_IS_SET (pad, GST_PAD_NEGOTIATING);
1388
1389     /* set the NEGOTIATING flag if not already done */
1390     if (!negotiating)
1391       GST_FLAG_SET (pad, GST_PAD_NEGOTIATING);
1392     
1393     /* call the link function */
1394     res = GST_RPAD_LINKFUNC (pad) (GST_PAD (pad), caps);
1395
1396     /* unset again after negotiating only if we set it  */
1397     if (!negotiating)
1398       GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING);
1399
1400     switch (res) {
1401       case GST_PAD_LINK_REFUSED:
1402         debug_string = "REFUSED";
1403         break;
1404       case GST_PAD_LINK_OK:
1405         debug_string = "OK";
1406         break;
1407       case GST_PAD_LINK_DONE:
1408         debug_string = "DONE";
1409         break;
1410       case GST_PAD_LINK_DELAYED:
1411         debug_string = "DELAYED";
1412         break;
1413       default:
1414         g_warning ("unknown return code from link function of pad %s:%s %d",
1415                    GST_DEBUG_PAD_NAME (pad), res);
1416         return GST_PAD_LINK_REFUSED;
1417     }
1418
1419     GST_CAT_INFO (GST_CAT_CAPS, 
1420               "got reply %s (%d) from link function on pad %s:%s",
1421               debug_string, res, GST_DEBUG_PAD_NAME (pad));
1422
1423     /* done means the link function called another caps negotiate function
1424      * on this pad that succeeded, we dont need to continue */
1425     if (res == GST_PAD_LINK_DONE) {
1426       GST_CAT_INFO (GST_CAT_CAPS, "pad %s:%s is done", GST_DEBUG_PAD_NAME (pad));
1427       return GST_PAD_LINK_DONE;
1428     }
1429     if (res == GST_PAD_LINK_REFUSED) {
1430       GST_CAT_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps",
1431                 GST_DEBUG_PAD_NAME (pad));
1432       return GST_PAD_LINK_REFUSED;
1433     }
1434   }
1435   /* we can only set caps on the pad if they are fixed */
1436   if (GST_CAPS_IS_FIXED (caps)) {
1437
1438     GST_CAT_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
1439               GST_DEBUG_PAD_NAME (pad));
1440     /* if we got this far all is ok, remove the old caps, set the new one */
1441     gst_caps_replace_sink (&GST_PAD_CAPS (pad), caps);
1442
1443     g_object_notify (G_OBJECT (pad), "caps");
1444   }
1445   else {
1446     GST_CAT_INFO (GST_CAT_CAPS, 
1447               "caps are not fixed on pad %s:%s, not setting them yet",
1448               GST_DEBUG_PAD_NAME (pad));
1449
1450     return GST_PAD_LINK_DELAYED;
1451   }
1452   return GST_PAD_LINK_OK;
1453 }
1454
1455 /**
1456  * gst_pad_try_set_caps:
1457  * @pad: a #GstPad to try to set the caps on.
1458  * @caps: the #GstCaps to set.
1459  *
1460  * Tries to set the caps on the given pad. Ownership is always taken 
1461  * of the caps, so you will need to unref non-floating caps.
1462  *
1463  * Returns: A #GstPadLinkReturn value indicating whether the caps
1464  *              could be set.
1465  */
1466 GstPadLinkReturn
1467 gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
1468 {
1469   GstRealPad *peer, *realpad;
1470   GstPadLinkReturn set_retval;
1471
1472   realpad = GST_PAD_REALIZE (pad);
1473   peer = GST_RPAD_PEER (realpad);
1474
1475   GST_CAT_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
1476             caps, GST_DEBUG_PAD_NAME (realpad));
1477
1478   gst_caps_debug (caps, "caps that we are trying to set");
1479
1480   /* try to take ownership */
1481   gst_caps_ref (caps);
1482   gst_caps_sink (caps);
1483
1484   /* setting non fixed caps on a pad is not allowed */
1485   if (!GST_CAPS_IS_FIXED (caps)) {
1486     GST_CAT_INFO (GST_CAT_CAPS, 
1487               "trying to set unfixed caps on pad %s:%s, not allowed",
1488               GST_DEBUG_PAD_NAME (realpad));
1489     g_warning ("trying to set non fixed caps on pad %s:%s, not allowed",
1490                GST_DEBUG_PAD_NAME (realpad));
1491
1492     gst_caps_debug (caps, "unfixed caps");
1493     set_retval = GST_PAD_LINK_DELAYED;
1494     goto done;
1495   }
1496
1497   /* if we have a peer try to set the caps, notifying the peerpad
1498    * if it has a link function */
1499   if (peer && ((set_retval = gst_pad_try_set_caps_func (peer, caps, TRUE)) <= 0))
1500   {
1501     GST_CAT_INFO (GST_CAT_CAPS, "tried to set caps on peerpad %s:%s but couldn't, return value %d",
1502               GST_DEBUG_PAD_NAME (peer), set_retval);
1503     goto done;
1504   }
1505
1506   /* then try to set our own caps, we don't need to be notified */
1507   if ((set_retval = gst_pad_try_set_caps_func (realpad, caps, FALSE)) <= 0)
1508   {
1509     GST_CAT_INFO (GST_CAT_CAPS, "tried to set own caps on pad %s:%s but couldn't, return value %d",
1510               GST_DEBUG_PAD_NAME (realpad), set_retval);
1511     goto done;
1512   }
1513   GST_CAT_INFO (GST_CAT_CAPS, "succeeded setting caps %p on pad %s:%s, return value %d",
1514             caps, GST_DEBUG_PAD_NAME (realpad), set_retval);
1515   g_assert (GST_PAD_CAPS (pad));
1516
1517 done:                     
1518   /* if we took ownership, the caps will be freed */
1519   gst_caps_unref (caps);
1520
1521   return set_retval;
1522 }
1523
1524 /* this is a caps negotiation convenience routine, it:
1525  *
1526  * 1. optionally clears any pad caps.
1527  * 2. calculates the intersection between the two pad tamplate/getcaps caps.
1528  * 3. calculates the intersection with the (optional) filtercaps.
1529  * 4. stores the intersection in the pad filter.
1530  * 5. stores the app filtercaps in the pad appfilter.
1531  * 6. starts the caps negotiation.
1532  */
1533 static gboolean
1534 gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, 
1535                                   GstCaps *filtercaps, gboolean clear)
1536 {
1537   GstCaps *srccaps, *sinkcaps;
1538   GstCaps *intersection = NULL;
1539   GstRealPad *realsrc, *realsink;
1540
1541   realsrc = GST_PAD_REALIZE (srcpad);
1542   realsink = GST_PAD_REALIZE (sinkpad);
1543
1544   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1545   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1546
1547   /* optinally clear the caps */
1548   if (clear) {
1549     GST_CAT_INFO (GST_CAT_PADS, 
1550               "start relink filtered %s:%s and %s:%s, clearing caps",
1551               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1552
1553     gst_caps_replace (&GST_PAD_CAPS (GST_PAD (realsrc)), NULL);
1554     gst_caps_replace (&GST_PAD_CAPS (GST_PAD (realsink)), NULL);
1555     gst_caps_replace (&GST_RPAD_FILTER (realsrc), NULL); 
1556     gst_caps_replace (&GST_RPAD_FILTER (realsink), NULL); 
1557   }
1558   else {
1559     GST_CAT_INFO (GST_CAT_PADS, "start relink filtered %s:%s and %s:%s",
1560         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1561   }
1562
1563   srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1564   GST_CAT_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1565              GST_DEBUG_PAD_NAME (realsrc));
1566   gst_caps_debug (srccaps, "caps of src pad (pre-relink)");
1567   sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1568   GST_CAT_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1569              GST_DEBUG_PAD_NAME (realsink));
1570   gst_caps_debug (sinkcaps, "caps of sink pad (pre-relink)");
1571
1572   /* first take the intersection of the pad caps */
1573   intersection = gst_caps_intersect (srccaps, sinkcaps);
1574   gst_caps_debug (intersection, "caps of intersection");
1575
1576   /* if we have no intersection but one of the caps was not NULL.. */
1577   if (!intersection && (srccaps || sinkcaps)) {
1578     /* the intersection is NULL but the pad caps were not both NULL,
1579      * this means they have no common format */
1580     GST_CAT_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s have no common type",
1581               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1582     /* make sure any floating caps from gst_pad_get_caps are freed here */
1583     gst_caps_sink (srccaps);
1584     gst_caps_sink (sinkcaps);
1585     return FALSE;
1586   } else  {
1587     GST_CAT_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s intersected to %s caps",
1588        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink), 
1589        (intersection ?
1590            (GST_CAPS_IS_FIXED (intersection) ? "fixed" : "variable") :
1591            "NULL"));
1592
1593     /* we don't need those anymore, as the caps can be floating */
1594     gst_caps_sink (srccaps);
1595     gst_caps_sink (sinkcaps);
1596
1597     /* then filter this against the app filter */
1598     if (filtercaps) {
1599       GstCaps *filtered_intersection;
1600       
1601       filtered_intersection = gst_caps_intersect (intersection, 
1602                                                   filtercaps);
1603
1604       gst_caps_sink (intersection);
1605
1606       if (!filtered_intersection) {
1607         GST_CAT_INFO (GST_CAT_PADS, 
1608                   "filtered link between pads %s:%s and %s:%s is empty",
1609                   GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1610         return FALSE;
1611       }
1612       intersection = filtered_intersection;
1613
1614       /* keep a reference to the app caps */
1615       gst_caps_replace_sink (&GST_RPAD_APPFILTER (realsink), filtercaps);
1616       gst_caps_replace_sink (&GST_RPAD_APPFILTER (realsrc), filtercaps);
1617     }
1618   }
1619   GST_CAT_DEBUG (GST_CAT_CAPS, "setting filter for link to:");
1620   gst_caps_debug (intersection, "filter for link");
1621
1622   /* both the app filter and the filter, while stored on both peer pads, 
1623    * are equal to the same thing on both */
1624   gst_caps_replace_sink (&GST_RPAD_FILTER (realsrc), intersection); 
1625   gst_caps_replace_sink (&GST_RPAD_FILTER (realsink), intersection); 
1626   gst_caps_sink (intersection);
1627
1628   return gst_pad_perform_negotiate (GST_PAD (realsrc), GST_PAD (realsink));
1629 }
1630
1631 /**
1632  * gst_pad_perform_negotiate:
1633  * @srcpad: the source #GstPad.
1634  * @sinkpad: the sink #GstPad.
1635  *
1636  * Tries to negotiate the pads.
1637  *
1638  * Returns: TRUE if the pads were succesfully negotiated, FALSE otherwise.
1639  */
1640 gboolean
1641 gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad) 
1642 {
1643   GstCaps *intersection, *filtered_intersection;
1644   GstRealPad *realsrc, *realsink;
1645   GstCaps *srccaps, *sinkcaps, *filter;
1646   gboolean res = TRUE;
1647   GstElement *parent;
1648   
1649
1650   g_return_val_if_fail (srcpad != NULL, FALSE);
1651   g_return_val_if_fail (sinkpad != NULL, FALSE);
1652   
1653   realsrc = GST_PAD_REALIZE (srcpad);
1654   realsink = GST_PAD_REALIZE (sinkpad);
1655     
1656   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1657   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1658
1659   /* shortcut negotiation */
1660   parent = GST_PAD_PARENT (realsrc);
1661   if (parent && GST_STATE (parent) < GST_STATE_READY) {
1662     GST_CAT_DEBUG (GST_CAT_CAPS, "parent %s of pad %s:%s is not READY",
1663                GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (realsrc));
1664     return TRUE;
1665   }
1666   parent = GST_PAD_PARENT (realsink);
1667   if (parent && GST_STATE (parent) < GST_STATE_READY) {
1668     GST_CAT_DEBUG (GST_CAT_CAPS, "parent %s of pad %s:%s is not READY",
1669                GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (realsink));
1670     return TRUE;
1671   }
1672
1673   GST_CAT_INFO (GST_CAT_PADS, "perform negotiate for link %s:%s-%s:%s",
1674               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1675
1676   filter = GST_RPAD_APPFILTER (realsrc);
1677   if (filter) {
1678     GST_CAT_INFO (GST_CAT_PADS, "dumping filter for link %s:%s-%s:%s",
1679               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1680     gst_caps_debug (filter, "link filter caps");
1681   }
1682
1683   /* calculate the new caps here */
1684   srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1685   GST_CAT_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1686              GST_DEBUG_PAD_NAME (realsrc));
1687   gst_caps_debug (srccaps, 
1688                   "src caps, awaiting negotiation, after applying filter");
1689   sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1690   GST_CAT_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1691              GST_DEBUG_PAD_NAME (realsink));
1692   gst_caps_debug (sinkcaps, 
1693                   "sink caps, awaiting negotiation, after applying filter");
1694   intersection = gst_caps_intersect (srccaps, sinkcaps);
1695   filtered_intersection = gst_caps_intersect (intersection, filter);
1696   gst_caps_unref (intersection);
1697
1698   /* no negotiation is performed if the pads have filtercaps */
1699   if (filtered_intersection) {
1700     GstPadLinkReturn link_res;
1701
1702     link_res = gst_pad_try_set_caps_func (realsrc, filtered_intersection, TRUE);
1703     if (link_res == GST_PAD_LINK_REFUSED) 
1704       goto error;
1705     if (link_res == GST_PAD_LINK_DONE) 
1706       goto success;
1707
1708     link_res = gst_pad_try_set_caps_func (realsink, filtered_intersection, TRUE);
1709     if (link_res == GST_PAD_LINK_REFUSED) 
1710       goto error;
1711     if (link_res == GST_PAD_LINK_DONE) 
1712       goto success;
1713   }
1714   /* no filtered_intersection, some pads had caps and ther was a filter */
1715   else if ((srccaps || sinkcaps) && filter) {
1716     goto error;
1717   }
1718
1719 success:
1720 cleanup:
1721   gst_caps_sink (srccaps);
1722   gst_caps_sink (sinkcaps);
1723   gst_caps_unref (filtered_intersection);
1724   return res;
1725
1726 error:
1727   res = FALSE;
1728   goto cleanup;
1729 }
1730
1731 /**
1732  * gst_pad_try_relink_filtered:
1733  * @srcpad: the source #GstPad to relink.
1734  * @sinkpad: the sink #GstPad to relink.
1735  * @filtercaps: the #GstPad to use as a filter in the relink.
1736  *
1737  * Tries to relink the given source and sink pad, constrained by the given
1738  * capabilities.
1739  *
1740  * Returns: TRUE if the pads were succesfully renegotiated, FALSE otherwise.
1741  */
1742 gboolean
1743 gst_pad_try_relink_filtered (GstPad *srcpad, GstPad *sinkpad, 
1744                                 GstCaps *filtercaps)
1745 {
1746   GstRealPad *realsrc, *realsink;
1747
1748   g_return_val_if_fail (srcpad != NULL, FALSE);
1749   g_return_val_if_fail (sinkpad != NULL, FALSE);
1750
1751   realsrc = GST_PAD_REALIZE (srcpad);
1752   realsink = GST_PAD_REALIZE (sinkpad);
1753
1754   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1755   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1756   
1757   return gst_pad_try_relink_filtered_func (realsrc, realsink, 
1758                                            filtercaps, TRUE);
1759 }
1760
1761 /**
1762  * gst_pad_relink_filtered:
1763  * @srcpad: the source #GstPad to relink.
1764  * @sinkpad: the sink #GstPad to relink.
1765  * @filtercaps: the #GstPad to use as a filter in the relink.
1766  *
1767  * Relinks the given source and sink pad, constrained by the given
1768  * capabilities.  If the relink fails, the pads are unlinked
1769  * and FALSE is returned.
1770  *
1771  * Returns: TRUE if the pads were succesfully relinked, FALSE otherwise.
1772  */
1773 gboolean
1774 gst_pad_relink_filtered (GstPad *srcpad, GstPad *sinkpad, 
1775                             GstCaps *filtercaps)
1776 {
1777   GstRealPad *realsrc, *realsink;
1778
1779   g_return_val_if_fail (srcpad != NULL, FALSE);
1780   g_return_val_if_fail (sinkpad != NULL, FALSE);
1781
1782   realsrc = GST_PAD_REALIZE (srcpad);
1783   realsink = GST_PAD_REALIZE (sinkpad);
1784
1785   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1786   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1787   
1788   if (!gst_pad_try_relink_filtered_func (realsrc, realsink, 
1789                                          filtercaps, TRUE)) 
1790   {
1791     gst_pad_unlink (srcpad, GST_PAD (GST_PAD_PEER (srcpad)));
1792     return FALSE;
1793   }
1794   return TRUE;
1795 }
1796
1797 /**
1798  * gst_pad_proxy_link:
1799  * @pad: a #GstPad to proxy to.
1800  * @caps: the #GstCaps to use in proxying.
1801  *
1802  * Proxies the link function to the specified pad.
1803  *
1804  * Returns: TRUE if the peer pad accepted the caps, FALSE otherwise.
1805  */
1806 GstPadLinkReturn
1807 gst_pad_proxy_link (GstPad *pad, GstCaps *caps)
1808 {
1809   GstRealPad *peer, *realpad;
1810
1811   realpad = GST_PAD_REALIZE (pad);
1812
1813   peer = GST_RPAD_PEER (realpad);
1814
1815   GST_CAT_INFO (GST_CAT_CAPS, "proxy link to pad %s:%s",
1816             GST_DEBUG_PAD_NAME (realpad));
1817
1818   if (peer && gst_pad_try_set_caps_func (peer, caps, TRUE) < 0)
1819     return GST_PAD_LINK_REFUSED;
1820   if (gst_pad_try_set_caps_func (realpad, caps, FALSE) < 0)
1821     return GST_PAD_LINK_REFUSED;
1822
1823   if (peer) {
1824     gst_caps_debug (caps, "proxy link filter");
1825
1826     GST_CAT_INFO (GST_CAT_CAPS, "setting filter on %s:%s and %s:%s",
1827               GST_DEBUG_PAD_NAME (peer), GST_DEBUG_PAD_NAME (realpad));
1828
1829     gst_caps_replace_sink (&GST_RPAD_FILTER (peer), caps); 
1830     gst_caps_replace_sink (&GST_RPAD_FILTER (realpad), caps); 
1831   }
1832
1833   return GST_PAD_LINK_OK;
1834 }
1835
1836 /**
1837  * gst_pad_get_caps:
1838  * @pad: a  #GstPad to get the capabilities of.
1839  *
1840  * Gets the capabilities of this pad.
1841  *
1842  * Returns: the #GstCaps of this pad. This function potentially
1843  * returns a floating caps, so use gst_caps_sink to get rid of
1844  * it.
1845  */
1846 GstCaps*
1847 gst_pad_get_caps (GstPad *pad)
1848 {
1849   GstRealPad *realpad;
1850
1851   g_return_val_if_fail (pad != NULL, NULL);
1852   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1853
1854   realpad = GST_PAD_REALIZE (pad);
1855
1856   GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
1857             GST_DEBUG_PAD_NAME (realpad), realpad);
1858
1859   /* note that we will not _ref the caps here as this function might be 
1860    * called recursively */
1861   if (GST_PAD_CAPS (realpad)) {
1862     GST_CAT_DEBUG (GST_CAT_CAPS, "using pad real caps %p", GST_PAD_CAPS (realpad));
1863     return GST_PAD_CAPS (realpad);
1864   }
1865   else if GST_RPAD_GETCAPSFUNC (realpad) {
1866     GstCaps *caps;
1867
1868     GST_CAT_DEBUG (GST_CAT_CAPS, "using pad get function");
1869     caps = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad), NULL);
1870     if(caps)g_return_val_if_fail(caps->refcount > 0, NULL);
1871
1872     return caps;
1873   }
1874   else if (GST_PAD_PAD_TEMPLATE (realpad)) {
1875     GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad);
1876     GST_CAT_DEBUG (GST_CAT_CAPS, "using pad template %p with caps %p", 
1877                templ, GST_PAD_TEMPLATE_CAPS (templ));
1878     return GST_PAD_TEMPLATE_CAPS (templ);
1879   }
1880   GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
1881
1882   return NULL;
1883 }
1884
1885 /**
1886  * gst_pad_get_pad_template_caps:
1887  * @pad: a #GstPad to get the template capabilities from.
1888  *
1889  * Gets the template capabilities of this pad.
1890  *
1891  * Returns: the template #GstCaps of this pad, unref the caps
1892  * if you no longer need it.
1893  */
1894 GstCaps*
1895 gst_pad_get_pad_template_caps (GstPad *pad)
1896 {
1897   g_return_val_if_fail (pad != NULL, NULL);
1898   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1899
1900   if (GST_PAD_PAD_TEMPLATE (pad))
1901     return gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad)));
1902
1903   return NULL;
1904 }
1905
1906 /**
1907  * gst_pad_template_get_caps_by_name:
1908  * @templ: a #GstPadTemplate to get the capabilities of.
1909  * @name: the name of the capability to get.
1910  *
1911  * Gets the capability with the given name from this pad template.
1912  *
1913  * Returns: the #GstCaps, or NULL if not found or in case of an error. unref 
1914  * the caps if you no longer need it.
1915  */
1916 GstCaps*
1917 gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
1918 {
1919   GstCaps *caps;
1920
1921   g_return_val_if_fail (templ != NULL, NULL);
1922
1923   caps = GST_PAD_TEMPLATE_CAPS (templ);
1924   if (!caps) 
1925     return NULL;
1926
1927   return gst_caps_ref (gst_caps_get_by_name (caps, name));
1928 }
1929
1930 /**
1931  * gst_pad_check_compatibility:
1932  * @srcpad: the source #GstPad to check.
1933  * @sinkpad: the sink #GstPad to check against.
1934  *
1935  * Checks if two pads have compatible capabilities.
1936  *
1937  * Returns: TRUE if they are compatible or if the capabilities
1938  * could not be checked
1939  */
1940 gboolean
1941 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
1942 {
1943   g_return_val_if_fail (srcpad != NULL, FALSE);
1944   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1945   g_return_val_if_fail (sinkpad != NULL, FALSE);
1946   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1947
1948   if (GST_PAD_CAPS (srcpad) && GST_PAD_CAPS (sinkpad)) {
1949     if (!gst_caps_is_always_compatible (GST_PAD_CAPS (srcpad), 
1950                                         GST_PAD_CAPS (sinkpad))) {
1951       return FALSE;
1952     }
1953     else {
1954       return TRUE;
1955     }
1956   }
1957   else {
1958     GST_CAT_DEBUG (GST_CAT_PADS, 
1959                "could not check capabilities of pads (%s:%s) and (%s:%s) %p %p",
1960                GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad), 
1961                GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
1962     return TRUE;
1963   }
1964 }
1965
1966 /**
1967  * gst_pad_get_peer:
1968  * @pad: a #GstPad to get the peer of.
1969  *
1970  * Gets the peer pad of this pad.
1971  *
1972  * Returns: the peer #GstPad.
1973  */
1974 GstPad*
1975 gst_pad_get_peer (GstPad *pad)
1976 {
1977   g_return_val_if_fail (pad != NULL, NULL);
1978   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1979
1980   return GST_PAD (GST_PAD_PEER (pad));
1981 }
1982
1983 /**
1984  * gst_pad_get_allowed_caps:
1985  * @pad: a #GstPad to get the allowed caps of.
1986  *
1987  * Gets the capabilities of the allowed media types that can
1988  * flow through this pad.  The caller must free the resulting caps.
1989  *
1990  * Returns: the allowed #GstCaps of the pad link. unref the caps if
1991  * you no longer need it.
1992  */
1993 GstCaps*
1994 gst_pad_get_allowed_caps (GstPad *pad)
1995 {
1996   GstCaps *caps;
1997   GstRealPad *realpad;
1998
1999   g_return_val_if_fail (pad != NULL, NULL);
2000   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2001
2002   realpad = GST_PAD_REALIZE (pad);
2003
2004   GST_CAT_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s", 
2005              GST_DEBUG_PAD_NAME (pad));
2006
2007   caps = gst_caps_ref (GST_RPAD_FILTER (realpad));
2008
2009   return caps;
2010 }
2011
2012 /**
2013  * gst_pad_recalc_allowed_caps:
2014  * @pad: a #GstPad to recalculate the capablities of.
2015  *
2016  * Attempts to relink the pad to its peer through its filter, 
2017  * set with gst_pad_[re]link_filtered. This function is useful when a
2018  * plug-in has new capabilities on a pad and wants to notify the peer.
2019  *
2020  * Returns: TRUE on success, FALSE otherwise.
2021  */
2022 gboolean
2023 gst_pad_recalc_allowed_caps (GstPad *pad)
2024 {
2025   GstRealPad *peer;
2026
2027   g_return_val_if_fail (pad != NULL, FALSE);
2028   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2029
2030   GST_CAT_DEBUG (GST_CAT_PROPERTIES, "set allowed caps of %s:%s", 
2031              GST_DEBUG_PAD_NAME (pad));
2032
2033
2034   peer = GST_RPAD_PEER (pad);
2035   if (peer)
2036     return gst_pad_try_relink_filtered (pad, GST_PAD (peer), 
2037                                         GST_RPAD_APPFILTER (pad));
2038
2039   return TRUE;
2040 }
2041
2042 /**
2043  * gst_pad_recover_caps_error:
2044  * @pad: a #GstPad that had a failed capsnego
2045  * @allowed: possible caps for the link
2046  *
2047  * Attempt to recover from a failed caps negotiation. This function
2048  * is typically called by a plugin that exhausted its list of caps
2049  * and wants the application to resolve the issue. The application
2050  * should connect to the pad's caps_nego_failed signal and should
2051  * resolve the issue by connecting another element for example.
2052  *
2053  * Returns: TRUE when the issue was resolved, dumps detailed information
2054  * on the console and returns FALSE otherwise.
2055  */
2056 gboolean
2057 gst_pad_recover_caps_error (GstPad *pad, GstCaps *allowed)
2058 {
2059   GstElement *parent;
2060   
2061   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2062
2063   /* see if someone can resolve this */
2064   if (g_signal_has_handler_pending (G_OBJECT (pad), 
2065         gst_real_pad_signals[REAL_CAPS_NEGO_FAILED], 0, FALSE))
2066   {
2067     /* clear pad caps first */
2068     gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
2069
2070     /* lets hope some signal manages to set the caps again */
2071     g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_CAPS_NEGO_FAILED], 0, allowed);
2072
2073     /* if the pad has caps now or is disabled, it's ok */
2074     if (GST_PAD_CAPS (pad) != NULL || !GST_PAD_IS_ACTIVE (pad))
2075       return TRUE;
2076   }
2077
2078   /* report error */
2079   parent = gst_pad_get_parent (pad);
2080   gst_element_error (parent, "negotiation failed on pad %s:%s",
2081                   GST_DEBUG_PAD_NAME (pad));
2082
2083   return FALSE;
2084 }
2085
2086 /**
2087  * gst_pad_get_bufferpool:
2088  * @pad: a #GstPad to get the bufferpool from.
2089  *
2090  * Gets the bufferpool of the peer pad of the given pad.Note that
2091  * a bufferpool can only be obtained from a srcpad.
2092  *
2093  * Returns: the #GstBufferPool, or NULL in case of an error.
2094  */
2095 GstBufferPool*          
2096 gst_pad_get_bufferpool (GstPad *pad)
2097 {
2098   GstRealPad *peer;
2099
2100   g_return_val_if_fail (pad != NULL, NULL);
2101   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2102   g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL);
2103    
2104   peer = GST_RPAD_PEER (pad);
2105
2106   if (!peer)
2107     return NULL;
2108
2109   GST_CAT_DEBUG (GST_CAT_BUFFER, "(%s:%s): getting bufferpool", GST_DEBUG_PAD_NAME (pad));
2110
2111   if (peer->bufferpoolfunc) {
2112     GST_CAT_DEBUG (GST_CAT_PADS, 
2113                "calling bufferpoolfunc &%s (@%p) of peer pad %s:%s",
2114                GST_DEBUG_FUNCPTR_NAME (peer->bufferpoolfunc), 
2115                &peer->bufferpoolfunc, GST_DEBUG_PAD_NAME (((GstPad*) peer)));
2116     return (peer->bufferpoolfunc) (((GstPad*) peer));
2117   } else {
2118     GST_CAT_DEBUG (GST_CAT_PADS, "no bufferpoolfunc for peer pad %s:%s at %p",
2119                GST_DEBUG_PAD_NAME (((GstPad*) peer)), &peer->bufferpoolfunc);
2120     return NULL;
2121   }
2122 }
2123
2124 static void
2125 gst_real_pad_dispose (GObject *object)
2126 {
2127   GstPad *pad = GST_PAD (object);
2128   
2129   /* No linked pad can ever be disposed.
2130    * It has to have a parent to be linked 
2131    * and a parent would hold a reference */
2132   g_assert (GST_PAD_PEER (pad) == NULL);
2133
2134   GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s", GST_DEBUG_PAD_NAME(pad));
2135
2136   /* we destroy the ghostpads, because they are nothing without the real pad */
2137   if (GST_REAL_PAD (pad)->ghostpads) {
2138     GList *orig, *ghostpads;
2139
2140     orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
2141
2142     while (ghostpads) {
2143       GstPad *ghostpad = GST_PAD (ghostpads->data);
2144
2145       if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))){
2146         GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'", 
2147                    GST_OBJECT_NAME (GST_OBJECT_PARENT (ghostpad)));
2148
2149         gst_element_remove_ghost_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), GST_PAD (ghostpad));
2150       }
2151       ghostpads = g_list_next (ghostpads);
2152     }
2153     g_list_free (orig);
2154     g_list_free (GST_REAL_PAD(pad)->ghostpads);
2155   }
2156
2157   gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
2158   gst_caps_replace (&GST_RPAD_APPFILTER (pad), NULL);
2159
2160   if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
2161     GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
2162                GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
2163     
2164     gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
2165   }
2166   
2167   G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
2168 }
2169
2170
2171 #ifndef GST_DISABLE_LOADSAVE
2172 /* FIXME: why isn't this on a GstElement ? */
2173 /**
2174  * gst_pad_load_and_link:
2175  * @self: an #xmlNodePtr to read the description from.
2176  * @parent: the #GstObject element that owns the pad.
2177  *
2178  * Reads the pad definition from the XML node and links the given pad
2179  * in the element to a pad of an element up in the hierarchy.
2180  */
2181 void
2182 gst_pad_load_and_link (xmlNodePtr self, GstObject *parent)
2183 {
2184   xmlNodePtr field = self->xmlChildrenNode;
2185   GstPad *pad = NULL, *targetpad;
2186   gchar *peer = NULL;
2187   gchar **split;
2188   GstElement *target;
2189   GstObject *grandparent;
2190
2191   while (field) {
2192     if (!strcmp (field->name, "name")) {
2193       pad = gst_element_get_pad (GST_ELEMENT (parent), 
2194                                  xmlNodeGetContent (field));
2195     }
2196     else if (!strcmp(field->name, "peer")) {
2197       peer = xmlNodeGetContent (field);
2198     }
2199     field = field->next;
2200   }
2201   g_return_if_fail (pad != NULL);
2202
2203   if (peer == NULL) return;
2204
2205   split = g_strsplit (peer, ".", 2);
2206
2207   if (split[0] == NULL || split[1] == NULL) {
2208     GST_CAT_DEBUG (GST_CAT_XML, 
2209                "Could not parse peer '%s' for pad %s:%s, leaving unlinked",
2210                peer, GST_DEBUG_PAD_NAME (pad));
2211     return;
2212   }
2213   
2214   g_return_if_fail (split[0] != NULL);
2215   g_return_if_fail (split[1] != NULL);
2216
2217   grandparent = gst_object_get_parent (parent);
2218
2219   if (grandparent && GST_IS_BIN (grandparent)) {
2220     target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
2221   }
2222   else
2223     goto cleanup;
2224
2225   if (target == NULL) goto cleanup;
2226
2227   targetpad = gst_element_get_pad (target, split[1]);
2228
2229   if (targetpad == NULL) goto cleanup;
2230
2231   gst_pad_link (pad, targetpad);
2232
2233 cleanup:
2234   g_strfreev (split);
2235 }
2236
2237 /**
2238  * gst_pad_save_thyself:
2239  * @pad: a #GstPad to save.
2240  * @parent: the parent #xmlNodePtr to save the description in.
2241  *
2242  * Saves the pad into an xml representation.
2243  *
2244  * Returns: the #xmlNodePtr representation of the pad.
2245  */
2246 static xmlNodePtr
2247 gst_pad_save_thyself (GstObject *object, xmlNodePtr parent)
2248 {
2249   GstRealPad *realpad;
2250   GstPad *peer;
2251
2252   g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
2253
2254   realpad = GST_REAL_PAD (object);
2255
2256   xmlNewChild (parent, NULL, "name", GST_PAD_NAME (realpad));
2257   if (GST_RPAD_PEER (realpad) != NULL) {
2258     gchar *content;
2259     
2260     peer = GST_PAD (GST_RPAD_PEER (realpad));
2261     /* first check to see if the peer's parent's parent is the same */
2262     /* we just save it off */
2263     content = g_strdup_printf ("%s.%s",
2264                                GST_OBJECT_NAME (GST_PAD_PARENT (peer)),
2265                                GST_PAD_NAME (peer));
2266     xmlNewChild (parent, NULL, "peer", content);
2267     g_free (content);
2268   } else
2269     xmlNewChild (parent, NULL, "peer", "");
2270
2271   return parent;
2272 }
2273
2274 /* FIXME: shouldn't pad and ghost be switched ?
2275  */
2276 /**
2277  * gst_ghost_pad_save_thyself:
2278  * @pad: a ghost #GstPad to save.
2279  * @parent: the parent #xmlNodePtr to save the description in.
2280  *
2281  * Saves the ghost pad into an xml representation.
2282  *
2283  * Returns: the #xmlNodePtr representation of the pad.
2284  */
2285 xmlNodePtr
2286 gst_ghost_pad_save_thyself (GstPad *pad, xmlNodePtr parent)
2287 {
2288   xmlNodePtr self;
2289
2290   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
2291
2292   self = xmlNewChild (parent, NULL, "ghostpad", NULL);
2293   xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
2294   xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
2295
2296   /* FIXME FIXME FIXME! */
2297
2298   return self;
2299 }
2300 #endif /* GST_DISABLE_LOADSAVE */
2301
2302 /**
2303  * gst_pad_push:
2304  * @pad: a #GstPad to push the buffer out of.
2305  * @buf: the #GstBuffer to push.
2306  *
2307  * Pushes a buffer to the peer of the pad.
2308  */
2309 void 
2310 gst_pad_push (GstPad *pad, GstBuffer *buf) 
2311 {
2312   GstRealPad *peer;
2313   GstData *data = GST_DATA(buf);
2314
2315   g_assert (GST_IS_PAD (pad));
2316   GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, pad, "pushing");
2317
2318   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
2319
2320   if (!gst_probe_dispatcher_dispatch (&(GST_REAL_PAD (pad)->probedisp), &data))
2321     return;
2322
2323   peer = GST_RPAD_PEER (pad);
2324
2325   if (!peer) {
2326     g_warning ("push on pad %s:%s but it is unlinked", 
2327                GST_DEBUG_PAD_NAME (pad));
2328   }
2329   else {
2330     if (!GST_IS_EVENT (data) && !GST_PAD_IS_ACTIVE (peer)) {
2331       g_warning ("push on peer of pad %s:%s but peer is not active", 
2332                  GST_DEBUG_PAD_NAME (pad));
2333       return;
2334     }
2335
2336     if (peer->chainhandler) {
2337       if (data) {
2338         GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, pad,
2339                    "calling chainhandler &%s of peer pad %s:%s",
2340                    GST_DEBUG_FUNCPTR_NAME (peer->chainhandler), 
2341                    GST_DEBUG_PAD_NAME (GST_PAD (peer)));
2342         if (!gst_probe_dispatcher_dispatch (&peer->probedisp, &data))
2343           return;
2344
2345         (peer->chainhandler) (GST_PAD_CAST (peer), (GstBuffer *)data);
2346         return;
2347       }
2348       else {
2349         g_warning ("trying to push a NULL buffer on pad %s:%s", 
2350                    GST_DEBUG_PAD_NAME (peer));
2351         return;
2352       }
2353     } 
2354     else {
2355       g_warning ("internal error: push on pad %s:%s but it has no chainhandler",
2356                  GST_DEBUG_PAD_NAME (peer));
2357     }
2358   }
2359   /* clean up the mess here */
2360   if (data != NULL) gst_data_unref (data);
2361 }
2362
2363 /**
2364  * gst_pad_pull:
2365  * @pad: a #GstPad to pull a buffer from.
2366  *
2367  * Pulls a buffer from the peer pad.
2368  *
2369  * Returns: a new #GstBuffer from the peer pad.
2370  */
2371 GstBuffer*
2372 gst_pad_pull (GstPad *pad) 
2373 {
2374   GstRealPad *peer;
2375   
2376   GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, pad, "pulling");
2377
2378   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, 
2379                         GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT)));
2380
2381   peer = GST_RPAD_PEER (pad);
2382
2383   if (!peer) {
2384     gst_element_error (GST_PAD_PARENT (pad), 
2385                        "pull on pad %s:%s but it was unlinked", 
2386                        GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), 
2387                        GST_PAD_NAME (pad), NULL);
2388   }
2389   else {
2390 restart:
2391     if (peer->gethandler) {
2392       GstData *data;
2393
2394       GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, pad, 
2395                           "calling gethandler %s of peer pad %s:%s",
2396                           GST_DEBUG_FUNCPTR_NAME (peer->gethandler), 
2397                           GST_DEBUG_PAD_NAME (peer));
2398
2399       data = GST_DATA((peer->gethandler) (GST_PAD_CAST (peer)));
2400
2401       if (data) {
2402         if (!gst_probe_dispatcher_dispatch (&peer->probedisp, &data))
2403           goto restart;
2404         return GST_BUFFER(data);
2405       }
2406
2407       /* no null buffers allowed */
2408       gst_element_error (GST_PAD_PARENT (pad), 
2409                          "NULL buffer during pull on %s:%s", 
2410                          GST_DEBUG_PAD_NAME (pad));
2411           
2412     } else {
2413       gst_element_error (GST_PAD_PARENT (pad), 
2414                          "internal error: pull on pad %s:%s "
2415                          "but the peer pad %s:%s has no gethandler", 
2416                          GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));
2417     }
2418   }
2419   return GST_BUFFER (gst_event_new (GST_EVENT_INTERRUPT));
2420 }
2421
2422 /**
2423  * gst_pad_select:
2424  * @padlist: a #GList of pads.
2425  *
2426  * Waits for a buffer on any of the list of pads.
2427  *
2428  * Returns: the #GstPad that has a buffer available. 
2429  * Use #gst_pad_pull() to get the buffer.
2430  */
2431 GstPad*
2432 gst_pad_select (GList *padlist)
2433 {
2434   GstPad *pad;
2435
2436   pad = gst_scheduler_pad_select (GST_PAD_PARENT (padlist->data)->sched, 
2437                                   padlist);
2438   return pad;
2439 }
2440
2441 /**
2442  * gst_pad_selectv:
2443  * @pad: a first #GstPad to perform the select on.
2444  * @...: A NULL-terminated list of more pads to select on.
2445  *
2446  * Waits for a buffer on the given set of pads.
2447  *
2448  * Returns: the #GstPad that has a buffer available.
2449  * Use #gst_pad_pull() to get the buffer.
2450  */
2451 GstPad*
2452 gst_pad_selectv (GstPad *pad, ...)
2453 {
2454   GstPad *result;
2455   GList *padlist = NULL;
2456   va_list var_args;
2457
2458   if (pad == NULL)
2459     return NULL;
2460
2461   va_start (var_args, pad);
2462
2463   while (pad) {
2464     padlist = g_list_prepend (padlist, pad);
2465     pad = va_arg (var_args, GstPad *);
2466   }
2467   result = gst_pad_select (padlist);
2468   g_list_free (padlist);
2469
2470   va_end (var_args);
2471   
2472   return result;
2473 }
2474
2475 /************************************************************************
2476  *
2477  * templates
2478  *
2479  */
2480 static void             gst_pad_template_class_init     (GstPadTemplateClass *klass);
2481 static void             gst_pad_template_init           (GstPadTemplate *templ);
2482 static void             gst_pad_template_dispose        (GObject *object);
2483
2484 GType
2485 gst_pad_template_get_type (void)
2486 {
2487   static GType padtemplate_type = 0;
2488
2489   if (!padtemplate_type) {
2490     static const GTypeInfo padtemplate_info = {
2491       sizeof (GstPadTemplateClass), NULL, NULL,
2492       (GClassInitFunc) gst_pad_template_class_init, NULL, NULL,
2493       sizeof (GstPadTemplate),
2494       32,
2495       (GInstanceInitFunc) gst_pad_template_init, NULL
2496     };
2497     padtemplate_type = g_type_register_static(GST_TYPE_OBJECT, "GstPadTemplate",
2498                                               &padtemplate_info, 0);
2499   }
2500   return padtemplate_type;
2501 }
2502
2503 static void
2504 gst_pad_template_class_init (GstPadTemplateClass *klass)
2505 {
2506   GObjectClass *gobject_class;
2507   GstObjectClass *gstobject_class;
2508
2509   gobject_class = (GObjectClass*) klass;
2510   gstobject_class = (GstObjectClass*) klass;
2511
2512   padtemplate_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
2513
2514   gst_pad_template_signals[TEMPL_PAD_CREATED] =
2515     g_signal_new ("pad_created", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
2516                   G_STRUCT_OFFSET (GstPadTemplateClass, pad_created), 
2517                   NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
2518                   G_TYPE_POINTER);
2519
2520   gobject_class->dispose = gst_pad_template_dispose;
2521
2522   gstobject_class->path_string_separator = "*";
2523 }
2524
2525 static void
2526 gst_pad_template_init (GstPadTemplate *templ)
2527 {
2528 }
2529
2530 static void
2531 gst_pad_template_dispose (GObject *object)
2532 {
2533   GstPadTemplate *templ = GST_PAD_TEMPLATE (object);
2534
2535   g_free (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
2536   gst_caps_unref (GST_PAD_TEMPLATE_CAPS (templ));
2537
2538   G_OBJECT_CLASS (padtemplate_parent_class)->dispose (object);
2539 }
2540
2541 /* ALWAYS padtemplates cannot have conversion specifications, it doesn't make
2542  * sense.
2543  * SOMETIMES padtemplates can do whatever they want, they are provided by the
2544  * element.
2545  * REQUEST padtemplates can be reverse-parsed (the user asks for 'sink1', the
2546  * 'sink%d' template is automatically selected), so we need to restrict their
2547  * naming.
2548  */
2549 static gboolean
2550 name_is_valid (const gchar *name, GstPadPresence presence)
2551 {
2552   const gchar *str;
2553   
2554   if (presence == GST_PAD_ALWAYS) {
2555     if (strchr (name, '%')) {
2556       g_warning ("invalid name template %s: conversion specifications are not"
2557                  " allowed for GST_PAD_ALWAYS padtemplates", name);
2558       return FALSE;
2559     }
2560   } else if (presence == GST_PAD_REQUEST) {
2561     if ((str = strchr (name, '%')) && strchr (str + 1, '%')) {
2562       g_warning ("invalid name template %s: only one conversion specification"
2563                  " allowed in GST_PAD_REQUEST padtemplate", name);
2564       return FALSE;
2565     }
2566     if (str && (*(str+1) != 's' && *(str+1) != 'd')) {
2567       g_warning ("invalid name template %s: conversion specification must be of"
2568                  " type '%%d' or '%%s' for GST_PAD_REQUEST padtemplate", name);
2569       return FALSE;
2570     }
2571     if (str && (*(str+2) != '\0')) {
2572       g_warning ("invalid name template %s: conversion specification must"
2573                  " appear at the end of the GST_PAD_REQUEST padtemplate name", 
2574                  name);
2575       return FALSE;
2576     }
2577   }
2578   
2579   return TRUE;
2580 }
2581
2582 /**
2583  * gst_pad_template_newv:
2584  * @name_template: the name template.
2585  * @direction: the #GstPadDirection of the template.
2586  * @presence: the #GstPadPresence of the pad.
2587  * @caps: a #GstCaps set for the template.
2588  * @var_args: a NULL-terminated list of #GstCaps.
2589  *
2590  * Creates a new pad template with a name according to the given template
2591  * and with the given arguments.
2592  *
2593  * Returns: a new #GstPadTemplate.
2594  */
2595 GstPadTemplate*
2596 gst_pad_template_newv (const gchar *name_template,
2597                        GstPadDirection direction, GstPadPresence presence,
2598                        GstCaps *caps, va_list var_args)
2599 {
2600   GstPadTemplate *new;
2601   GstCaps *thecaps = NULL;
2602
2603   g_return_val_if_fail (name_template != NULL, NULL);
2604
2605   if (!name_is_valid (name_template, presence))
2606     return NULL;
2607
2608   new = g_object_new (gst_pad_template_get_type (),
2609                       "name", name_template,
2610                       NULL);
2611
2612   GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name_template);
2613   GST_PAD_TEMPLATE_DIRECTION (new) = direction;
2614   GST_PAD_TEMPLATE_PRESENCE (new) = presence;
2615
2616   GST_FLAG_SET (GST_OBJECT (new), GST_PAD_TEMPLATE_FIXED);
2617   while (caps) {
2618     if (!GST_CAPS_IS_FIXED (caps)) {
2619       GST_FLAG_UNSET (GST_OBJECT (new), GST_PAD_TEMPLATE_FIXED);
2620     }
2621     thecaps = gst_caps_append (thecaps, caps);
2622     caps = va_arg (var_args, GstCaps*);
2623   }
2624   
2625   GST_PAD_TEMPLATE_CAPS (new) = thecaps;
2626   gst_caps_ref (thecaps);
2627   gst_caps_sink (thecaps);
2628
2629   return new;
2630 }
2631
2632 /**
2633  * gst_pad_template_new:
2634  * @name_template: the name template.
2635  * @direction: the #GstPadDirection of the template.
2636  * @presence: the #GstPadPresence of the pad.
2637  * @caps: a #GstCaps set for the template.
2638  * @...: a NULL-terminated list of #GstCaps.
2639  *
2640  * Creates a new pad template with a name according to the given template
2641  * and with the given arguments.
2642  *
2643  * Returns: a new #GstPadTemplate.
2644  */
2645 GstPadTemplate*
2646 gst_pad_template_new (const gchar *name_template,
2647                      GstPadDirection direction, GstPadPresence presence,
2648                      GstCaps *caps, ...)
2649 {
2650   GstPadTemplate *new;
2651   va_list var_args;
2652
2653   va_start (var_args, caps);
2654
2655   new = gst_pad_template_newv (name_template, direction, presence, 
2656                                caps, var_args);
2657
2658   va_end (var_args);
2659
2660   return new;
2661 }
2662
2663 /**
2664  * gst_pad_template_get_caps:
2665  * @templ: a #GstPadTemplate to get capabilities of.
2666  *
2667  * Gets the capabilities of the pad template.
2668  *
2669  * Returns: the #GstCaps of the pad template. unref the caps
2670  * after use.
2671  */
2672 GstCaps*
2673 gst_pad_template_get_caps (GstPadTemplate *templ)
2674 {
2675   g_return_val_if_fail (templ != NULL, NULL);
2676
2677   return gst_caps_ref (GST_PAD_TEMPLATE_CAPS (templ));
2678 }
2679
2680 /**
2681  * gst_pad_set_element_private:
2682  * @pad: the #GstPad to set the private data of.
2683  * @priv: The private data to attach to the pad.
2684  *
2685  * Set the given private data gpointer on the pad. 
2686  * This function can only be used by the element that owns the pad.
2687  */
2688 void
2689 gst_pad_set_element_private (GstPad *pad, gpointer priv)
2690 {
2691   pad->element_private = priv;
2692 }
2693
2694 /**
2695  * gst_pad_get_element_private:
2696  * @pad: the #GstPad to get the private data of.
2697  *
2698  * Gets the private data of a pad.
2699  *
2700  * Returns: a #gpointer to the private data.
2701  */
2702 gpointer
2703 gst_pad_get_element_private (GstPad *pad)
2704 {
2705   return pad->element_private;
2706 }
2707
2708
2709 /***** ghost pads *****/
2710 GType _gst_ghost_pad_type = 0;
2711
2712 static void     gst_ghost_pad_class_init        (GstGhostPadClass *klass);
2713 static void     gst_ghost_pad_init              (GstGhostPad *pad);
2714 static void     gst_ghost_pad_dispose           (GObject *object);
2715
2716 static GstPad *ghost_pad_parent_class = NULL;
2717 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
2718
2719 GType
2720 gst_ghost_pad_get_type (void) 
2721 {
2722   if (!_gst_ghost_pad_type) {
2723     static const GTypeInfo pad_info = {
2724       sizeof (GstGhostPadClass), NULL, NULL,
2725       (GClassInitFunc) gst_ghost_pad_class_init, NULL, NULL,
2726       sizeof (GstGhostPad),
2727       8,
2728       (GInstanceInitFunc) gst_ghost_pad_init,
2729       NULL
2730     };
2731     _gst_ghost_pad_type = g_type_register_static (GST_TYPE_PAD, "GstGhostPad", 
2732                                                   &pad_info, 0);
2733   }
2734   return _gst_ghost_pad_type;
2735 }
2736
2737 static void
2738 gst_ghost_pad_class_init (GstGhostPadClass *klass)
2739 {
2740   GObjectClass *gobject_class;
2741
2742   gobject_class = (GObjectClass*) klass;
2743
2744   ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
2745
2746   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
2747 }
2748
2749 static void
2750 gst_ghost_pad_init (GstGhostPad *pad)
2751 {
2752   /* zeroed by glib */
2753 }
2754 static void
2755 gst_ghost_pad_dispose (GObject *object)
2756 {
2757   GstGhostPad *pad = GST_GHOST_PAD (object);
2758
2759   if (pad->realpad)
2760     gst_pad_remove_ghost_pad((GstPad *) pad->realpad, (GstPad *) pad);
2761
2762   G_OBJECT_CLASS (ghost_pad_parent_class)->dispose (object);
2763 }
2764
2765 /**
2766  * gst_ghost_pad_new:
2767  * @name: the name of the new ghost pad.
2768  * @pad: the #GstPad to create a ghost pad for.
2769  *
2770  * Creates a new ghost pad associated with the given pad, and names it with
2771  * the given name.  If name is NULL, a guaranteed unique name (across all
2772  * ghost pads) will be assigned (most likely of the form ghostpad%d).
2773  *
2774  * Returns: a new ghost #GstPad, or NULL in case of an error.
2775  */
2776
2777 GstPad*
2778 gst_ghost_pad_new (const gchar *name,
2779                    GstPad *pad)
2780 {
2781   GstGhostPad *ghostpad;
2782   GstRealPad *realpad;
2783
2784   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2785
2786   ghostpad = g_object_new (gst_ghost_pad_get_type () ,NULL);
2787   gst_pad_set_name (GST_PAD (ghostpad), name);
2788
2789   realpad = (GstRealPad *) pad;
2790
2791   while (!GST_IS_REAL_PAD (realpad)) {
2792     realpad = GST_PAD_REALIZE (realpad);
2793   }
2794   GST_GPAD_REALPAD (ghostpad) = realpad;
2795   gst_pad_set_pad_template (GST_PAD (ghostpad), GST_PAD_PAD_TEMPLATE (pad));
2796
2797   /* add ourselves to the real pad's list of ghostpads */
2798   gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));
2799
2800   /* FIXME need to ref the real pad here... ? */
2801
2802   GST_CAT_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\"", 
2803              gst_pad_get_name (GST_PAD (ghostpad)));
2804
2805   return GST_PAD (ghostpad);
2806 }
2807
2808 /**
2809  * gst_pad_get_internal_links_default:
2810  * @pad: the #GstPad to get the internal links of.
2811  *
2812  * Gets a list of pads to which the given pad is linked to
2813  * inside of the parent element.
2814  * This is the default handler, and thus returns a list of all of the
2815  * pads inside the parent element with opposite direction.
2816  * The caller must free this list after use.
2817  *
2818  * Returns: a newly allocated #GList of pads.
2819  */
2820 GList*
2821 gst_pad_get_internal_links_default (GstPad *pad)
2822 {
2823   GList *res = NULL;
2824   GstElement *parent;
2825   GList *parent_pads;
2826   GstPadDirection direction;
2827   GstRealPad *rpad;
2828   
2829   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2830
2831   rpad = GST_PAD_REALIZE (pad);
2832   direction = rpad->direction;
2833
2834   parent = GST_PAD_PARENT (rpad);
2835   parent_pads = parent->pads;
2836
2837   while (parent_pads) {
2838     GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data);
2839     
2840     if (parent_pad->direction != direction) {
2841       res = g_list_prepend (res, parent_pad);
2842     }
2843     
2844     parent_pads = g_list_next (parent_pads);
2845   }
2846
2847   return res;
2848 }
2849
2850 /**
2851  * gst_pad_get_internal_links:
2852  * @pad: the #GstPad to get the internal links of.
2853  *
2854  * Gets a list of pads to which the given pad is linked to
2855  * inside of the parent element.
2856  * The caller must free this list after use.
2857  *
2858  * Returns: a newly allocated #GList of pads.
2859  */
2860 GList*
2861 gst_pad_get_internal_links (GstPad *pad)
2862 {
2863   GList *res = NULL;
2864   GstRealPad *rpad;
2865
2866   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2867
2868   rpad = GST_PAD_REALIZE (pad);
2869
2870   if (GST_RPAD_INTLINKFUNC (rpad))
2871     res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD_CAST (rpad));
2872
2873   return res;
2874 }
2875
2876
2877 static gboolean 
2878 gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, 
2879                                 GstEvent *event)
2880 {
2881   GList *orig, *pads;
2882
2883   orig = pads = gst_pad_get_internal_links (pad);
2884
2885   while (pads) {
2886     GstPad *eventpad = GST_PAD (pads->data);
2887     pads = g_list_next (pads);
2888
2889     /* for all pads in the opposite direction that are linked */
2890     if (GST_PAD_IS_LINKED (eventpad)) {
2891       if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
2892         /* increase the refcount */
2893         gst_event_ref (event);
2894         gst_pad_push (eventpad, GST_BUFFER (event));
2895       }
2896       else {
2897         GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
2898
2899         /* we only send the event on one pad, multi-sinkpad elements 
2900          * should implement a handler */
2901         g_list_free (orig);
2902         return gst_pad_send_event (peerpad, event);
2903       }
2904     }
2905   }
2906   gst_event_unref (event);
2907   g_list_free (orig);
2908   return TRUE;
2909 }
2910
2911 /**
2912  * gst_pad_event_default:
2913  * @pad: a #GstPad to call the default event handler on.
2914  * @event: the #GstEvent to handle.
2915  *
2916  * Invokes the default event handler for the given pad.
2917  *
2918  * Returns: TRUE if the event was sent succesfully.
2919  */
2920 gboolean 
2921 gst_pad_event_default (GstPad *pad, GstEvent *event)
2922 {
2923   GstElement *element;
2924   
2925   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2926   g_return_val_if_fail (event, FALSE);
2927   
2928   element = GST_PAD_PARENT (pad);
2929
2930   switch (GST_EVENT_TYPE (event)) {
2931     case GST_EVENT_EOS:
2932       gst_pad_event_default_dispatch (pad, element, event);
2933       gst_element_set_eos (element);
2934       break;
2935     case GST_EVENT_DISCONTINUOUS:
2936     {
2937       guint64 time;
2938               
2939       if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)) {
2940         if (gst_element_requires_clock (element) && element->clock) {
2941           gst_clock_handle_discont (element->clock, time); 
2942         }
2943       }
2944     }
2945     case GST_EVENT_FLUSH:
2946     default:
2947       return gst_pad_event_default_dispatch (pad, element, event);
2948   }
2949   return TRUE;
2950 }
2951
2952 /**
2953  * gst_pad_dispatcher:
2954  * @pad: a #GstPad to dispatch.
2955  * @dispatch: the #GstDispatcherFunction to call.
2956  * @data: gpointer user data passed to the dispatcher function.
2957  *
2958  * Invokes the given dispatcher function on all pads that are 
2959  * internally linked to the given pad. 
2960  * The GstPadDispatcherFunction should return TRUE when no further pads 
2961  * need to be processed.
2962  *
2963  * Returns: TRUE if one of the dispatcher functions returned TRUE.
2964  */
2965 gboolean
2966 gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch, 
2967                     gpointer data)
2968 {
2969   gboolean res = FALSE;
2970   GList *int_pads, *orig;
2971   
2972   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2973   g_return_val_if_fail (data, FALSE);
2974
2975   orig = int_pads = gst_pad_get_internal_links (pad);
2976
2977   while (int_pads) {
2978     GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data);
2979     GstRealPad *int_peer = GST_RPAD_PEER (int_rpad);
2980
2981     if (int_peer) {
2982       res = dispatch (GST_PAD_CAST (int_peer), data);
2983       if (res)
2984         break;
2985     }
2986     int_pads = g_list_next (int_pads);
2987   }
2988
2989   g_list_free (orig);
2990   
2991   return res;
2992 }
2993
2994 /**
2995  * gst_pad_send_event:
2996  * @pad: a #GstPad to send the event to.
2997  * @event: the #GstEvent to send to the pad.
2998  *
2999  * Sends the event to the pad.
3000  *
3001  * Returns: TRUE if the event was handled.
3002  */
3003 gboolean
3004 gst_pad_send_event (GstPad *pad, GstEvent *event)
3005 {
3006   gboolean success = FALSE;
3007   GstRealPad *rpad;
3008
3009   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3010   g_return_val_if_fail (event, FALSE);
3011
3012   rpad = GST_PAD_REALIZE (pad);
3013
3014   if (GST_EVENT_SRC (event) == NULL)
3015     GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad));
3016
3017   GST_CAT_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s",
3018                   GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad));
3019
3020   if (GST_RPAD_EVENTHANDLER (rpad))
3021     success = GST_RPAD_EVENTHANDLER (rpad) (GST_PAD_CAST (rpad), event);
3022   else {
3023     g_warning ("pad %s:%s has no event handler", GST_DEBUG_PAD_NAME (rpad));
3024     gst_event_unref (event);
3025   }
3026
3027   return success;
3028 }
3029
3030 typedef struct 
3031 {
3032   GstFormat      src_format;
3033   gint64         src_value;
3034   GstFormat      *dest_format;
3035   gint64         *dest_value;
3036 } GstPadConvertData;
3037
3038 static gboolean
3039 gst_pad_convert_dispatcher (GstPad *pad, GstPadConvertData *data)
3040 {
3041   return gst_pad_convert (pad, data->src_format, data->src_value, 
3042                                data->dest_format, data->dest_value);
3043 }
3044
3045 /**
3046  * gst_pad_convert_default:
3047  * @pad: a #GstPad to invoke the default converter on.
3048  * @src_format: the source #GstFormat.
3049  * @src_value: the source value.
3050  * @dest_format: a pointer to the destination #GstFormat.
3051  * @dest_value: a pointer to the destination value.
3052  *
3053  * Invokes the default converter on a pad. 
3054  * This will forward the call to the pad obtained 
3055  * using the internal link of
3056  * the element.
3057  *
3058  * Returns: TRUE if the conversion could be performed.
3059  */
3060 gboolean
3061 gst_pad_convert_default (GstPad *pad, 
3062                          GstFormat src_format,  gint64  src_value,
3063                          GstFormat *dest_format, gint64 *dest_value)
3064 {
3065   GstPadConvertData data;
3066
3067   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3068   g_return_val_if_fail (dest_format, FALSE);
3069   g_return_val_if_fail (dest_value, FALSE);
3070
3071   data.src_format = src_format;
3072   data.src_value = src_value;
3073   data.dest_format = dest_format;
3074   data.dest_value = dest_value;
3075
3076   return gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
3077                                     gst_pad_convert_dispatcher, &data);
3078 }
3079
3080 /**
3081  * gst_pad_convert:
3082  * @pad: a #GstPad to invoke the default converter on.
3083  * @src_format: the source #GstFormat.
3084  * @src_value: the source value.
3085  * @dest_format: a pointer to the destination #GstFormat.
3086  * @dest_value: a pointer to the destination value.
3087  *
3088  * Invokes a conversion on the pad.
3089  *
3090  * Returns: TRUE if the conversion could be performed.
3091  */
3092 gboolean
3093 gst_pad_convert (GstPad *pad, 
3094                  GstFormat src_format,  gint64  src_value,
3095                  GstFormat *dest_format, gint64 *dest_value)
3096 {
3097   GstRealPad *rpad;
3098   
3099   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3100   g_return_val_if_fail (dest_format, FALSE);
3101   g_return_val_if_fail (dest_value, FALSE);
3102
3103   if (src_format == *dest_format) {
3104     *dest_value = src_value; 
3105     return TRUE;
3106   }     
3107
3108   rpad = GST_PAD_REALIZE (pad);
3109
3110   if (GST_RPAD_CONVERTFUNC (rpad)) {
3111     return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD_CAST (rpad), src_format, 
3112                                         src_value, dest_format, dest_value);
3113   }
3114
3115   return FALSE;
3116 }
3117
3118 typedef struct 
3119 {
3120   GstQueryType    type;
3121   GstFormat      *format;
3122   gint64         *value;
3123 } GstPadQueryData;
3124
3125 static gboolean
3126 gst_pad_query_dispatcher (GstPad *pad, GstPadQueryData *data)
3127 {
3128   return gst_pad_query (pad, data->type, data->format, data->value);
3129 }
3130
3131 /**
3132  * gst_pad_query_default:
3133  * @pad: a #GstPad to invoke the default query on.
3134  * @type: the #GstQueryType of the query to perform.
3135  * @format: a pointer to the #GstFormat of the result.
3136  * @value: a pointer to the result.
3137  *
3138  * Invokes the default query function on a pad. 
3139  *
3140  * Returns: TRUE if the query could be performed.
3141  */
3142 gboolean
3143 gst_pad_query_default (GstPad *pad, GstQueryType type,
3144                        GstFormat *format,  gint64 *value)
3145 {
3146   GstPadQueryData data;
3147
3148   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3149   g_return_val_if_fail (format, FALSE);
3150   g_return_val_if_fail (value, FALSE);
3151
3152   data.type = type;
3153   data.format = format;
3154   data.value = value;
3155
3156   return gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
3157                                    gst_pad_query_dispatcher, &data);
3158 }
3159
3160 /**
3161  * gst_pad_query:
3162  * @pad: a #GstPad to invoke the default query on.
3163  * @type: the #GstQueryType of the query to perform.
3164  * @format: a pointer to the #GstFormat asked for.
3165  *          On return contains the #GstFormat used.
3166  * @value: a pointer to the result.
3167  *
3168  * Queries a pad for one of the available properties. The format will be
3169  * adjusted to the actual format used when specifying formats such as 
3170  * GST_FORMAT_DEFAULT.
3171  * FIXME: Tell if the format can be adjusted when specifying a definite format.
3172  *
3173  * Returns: TRUE if the query could be performed.
3174  */
3175 gboolean
3176 gst_pad_query (GstPad *pad, GstQueryType type,
3177                GstFormat *format, gint64 *value) 
3178 {
3179   GstRealPad *rpad;
3180   
3181   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3182   g_return_val_if_fail (format, FALSE);
3183   g_return_val_if_fail (value, FALSE);
3184
3185   rpad = GST_PAD_REALIZE (pad);
3186
3187   g_return_val_if_fail (rpad, FALSE);
3188
3189   if (GST_RPAD_QUERYFUNC (rpad))
3190     return GST_RPAD_QUERYFUNC (rpad) (GST_PAD_CAST (pad), type, format, value);
3191
3192   return FALSE;
3193 }
3194
3195 static gboolean
3196 gst_pad_get_formats_dispatcher (GstPad *pad, const GstFormat **data)
3197 {
3198   *data = gst_pad_get_formats (pad);
3199
3200   return TRUE;
3201 }
3202
3203 /**
3204  * gst_pad_get_formats_default:
3205  * @pad: a #GstPad to query
3206  *
3207  * Invoke the default format dispatcher for the pad.
3208  *
3209  * Returns: An array of GstFormats ended with a 0 value.
3210  */
3211 const GstFormat*
3212 gst_pad_get_formats_default (GstPad *pad)
3213 {
3214   GstFormat *result = NULL;
3215
3216   gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
3217                       gst_pad_get_formats_dispatcher, &result);
3218
3219   return result;
3220 }
3221
3222 /**
3223  * gst_pad_get_formats:
3224  * @pad: a #GstPad to query
3225  *
3226  * Gets the list of supported formats from the pad.
3227  *
3228  * Returns: An array of GstFormats ended with a 0 value.
3229  */
3230 const GstFormat*
3231 gst_pad_get_formats (GstPad *pad)
3232 {
3233   GstRealPad *rpad;
3234   
3235   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
3236
3237   rpad = GST_PAD_REALIZE (pad);
3238
3239   if (GST_RPAD_FORMATSFUNC (rpad))
3240     return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD_CAST (pad));
3241
3242   return NULL;
3243 }