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