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