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