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