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