Make sure we don't set caps that violate the (app)filter
[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, *allowed = NULL;
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   /* first see if we have to check against a filter */
1256   if (!(allowed = GST_RPAD_FILTER (pad))) {
1257     /* no filter, make sure we check against the padtemplate then */
1258     if ((template = gst_pad_get_pad_template (GST_PAD_CAST (pad)))) {
1259       allowed = gst_pad_template_get_caps (template);
1260     }
1261   }
1262   
1263   /* do we have to check the caps against something? */
1264   if (allowed) {
1265     GstCaps *intersection;
1266
1267     /* check against calculated caps */
1268     intersection = gst_caps_intersect (caps, allowed);
1269
1270     /* oops, empty intersection, caps don"t have anything in common */
1271     if (!intersection) {
1272       GST_INFO (GST_CAT_CAPS, "caps did not intersect with %s:%s's allowed caps",
1273                 GST_DEBUG_PAD_NAME (pad));
1274       gst_caps_debug (caps, "caps themselves (attemped to set)");
1275       gst_caps_debug (allowed,
1276                       "allowed caps that did not agree with caps");
1277       return GST_PAD_CONNECT_REFUSED;
1278     }
1279     /* caps checks out fine, we can unref the intersection now */
1280     gst_caps_unref (intersection);
1281     /* given that the caps are fixed, we know that their intersection with the
1282      * padtemplate caps is the same as caps itself */
1283   }
1284
1285   /* we need to notify the connect function */
1286   if (notify && GST_RPAD_CONNECTFUNC (pad)) {
1287     GstPadConnectReturn res;
1288     gchar *debug_string;
1289
1290     GST_INFO (GST_CAT_CAPS, "calling connect function on pad %s:%s",
1291             GST_DEBUG_PAD_NAME (pad));
1292
1293     /* call the connect function */
1294     res = GST_RPAD_CONNECTFUNC (pad) (GST_PAD (pad), caps);
1295
1296     switch (res) {
1297       case GST_PAD_CONNECT_REFUSED:
1298         debug_string = "REFUSED";
1299         break;
1300       case GST_PAD_CONNECT_OK:
1301         debug_string = "OK";
1302         break;
1303       case GST_PAD_CONNECT_DONE:
1304         debug_string = "DONE";
1305         break;
1306       case GST_PAD_CONNECT_DELAYED:
1307         debug_string = "DELAYED";
1308         break;
1309       default:
1310         g_warning ("unknown return code from connect function of pad %s:%s %d",
1311                    GST_DEBUG_PAD_NAME (pad), res);
1312         return GST_PAD_CONNECT_REFUSED;
1313     }
1314
1315     GST_INFO (GST_CAT_CAPS, 
1316               "got reply %s (%d) from connect function on pad %s:%s",
1317               debug_string, res, GST_DEBUG_PAD_NAME (pad));
1318
1319     /* done means the connect function called another caps negotiate function
1320      * on this pad that succeeded, we dont need to continue */
1321     if (res == GST_PAD_CONNECT_DONE) {
1322       GST_INFO (GST_CAT_CAPS, "pad %s:%s is done", GST_DEBUG_PAD_NAME (pad));
1323       return GST_PAD_CONNECT_DONE;
1324     }
1325     if (res == GST_PAD_CONNECT_REFUSED) {
1326       GST_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps",
1327                 GST_DEBUG_PAD_NAME (pad));
1328       return GST_PAD_CONNECT_REFUSED;
1329     }
1330   }
1331   /* we can only set caps on the pad if they are fixed */
1332   if (GST_CAPS_IS_FIXED (caps)) {
1333
1334     GST_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
1335               GST_DEBUG_PAD_NAME (pad));
1336     /* if we got this far all is ok, remove the old caps, set the new one */
1337     oldcaps = GST_PAD_CAPS (pad);
1338     if (caps) gst_caps_ref (caps);
1339     GST_PAD_CAPS (pad) = caps;
1340     if (oldcaps) gst_caps_unref (oldcaps);
1341
1342     g_object_notify (G_OBJECT (pad), "caps");
1343   }
1344   else {
1345     GST_INFO (GST_CAT_CAPS, 
1346               "caps are not fixed on pad %s:%s, not setting them yet",
1347               GST_DEBUG_PAD_NAME (pad));
1348   }
1349   return GST_PAD_CONNECT_OK;
1350 }
1351
1352 /**
1353  * gst_pad_try_set_caps:
1354  * @pad: a #GstPad to try to set the caps on.
1355  * @caps: the #GstCaps to set.
1356  *
1357  * Tries to set the caps on the given pad.
1358  *
1359  * Returns: A GstPadConnectReturn value indicating whether the caps
1360  *              could be set.
1361  */
1362 GstPadConnectReturn
1363 gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
1364 {
1365   GstRealPad *peer, *realpad;
1366   GstPadConnectReturn set_retval;
1367
1368   realpad = GST_PAD_REALIZE (pad);
1369   peer = GST_RPAD_PEER (realpad);
1370
1371   GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
1372             caps, GST_DEBUG_PAD_NAME (realpad));
1373
1374   gst_caps_debug (caps, "caps that we are trying to set");
1375
1376   /* setting non fixed caps on a pad is not allowed */
1377   if (!GST_CAPS_IS_FIXED (caps)) {
1378   GST_INFO (GST_CAT_CAPS, 
1379             "trying to set unfixed caps on pad %s:%s, not allowed",
1380             GST_DEBUG_PAD_NAME (realpad));
1381     g_warning ("trying to set non fixed caps on pad %s:%s, not allowed",
1382                GST_DEBUG_PAD_NAME (realpad));
1383     gst_caps_debug (caps, "unfixed caps");
1384     return GST_PAD_CONNECT_DELAYED;
1385   }
1386
1387   /* if we have a peer try to set the caps, notifying the peerpad
1388    * if it has a connect function */
1389   if (peer && ((set_retval = gst_pad_try_set_caps_func (peer, caps, TRUE)) <= 0))
1390   {
1391     GST_INFO (GST_CAT_CAPS, "tried to set caps on peerpad %s:%s but couldn't, return value %d",
1392               GST_DEBUG_PAD_NAME (peer), set_retval);
1393     return set_retval;
1394   }
1395
1396   /* then try to set our own caps, we don't need to be notified */
1397   if ((set_retval = gst_pad_try_set_caps_func (realpad, caps, FALSE)) <= 0)
1398   {
1399     GST_INFO (GST_CAT_CAPS, "tried to set own caps on pad %s:%s but couldn't, return value %d",
1400               GST_DEBUG_PAD_NAME (realpad), set_retval);
1401     return set_retval;
1402   }
1403   GST_INFO (GST_CAT_CAPS, "succeeded setting caps %p on pad %s:%s, return value %d",
1404             caps, GST_DEBUG_PAD_NAME (realpad), set_retval);
1405   g_assert (GST_PAD_CAPS (pad));
1406                           
1407   return set_retval;
1408 }
1409
1410 /* this is a caps negotiation convenience routine, it:
1411  *
1412  * 1. optionally clears any pad caps.
1413  * 2. calculates the intersection between the two pad tamplate/getcaps caps.
1414  * 3. calculates the intersection with the (optional) filtercaps.
1415  * 4. stores the intersection in the pad filter.
1416  * 5. stores the app filtercaps in the pad appfilter.
1417  * 6. starts the caps negotiation.
1418  */
1419 static gboolean
1420 gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, 
1421                                      GstCaps *filtercaps, gboolean clear)
1422 {
1423   GstCaps *srccaps, *sinkcaps;
1424   GstCaps *intersection = NULL;
1425   GstRealPad *realsrc, *realsink;
1426
1427   realsrc = GST_PAD_REALIZE (srcpad);
1428   realsink = GST_PAD_REALIZE (sinkpad);
1429
1430   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1431   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1432
1433   /* optinally clear the caps */
1434   if (clear) {
1435     GST_INFO (GST_CAT_PADS, 
1436               "start reconnect filtered %s:%s and %s:%s, clearing caps",
1437               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1438
1439     GST_PAD_CAPS (GST_PAD (realsrc)) = NULL;
1440     GST_PAD_CAPS (GST_PAD (realsink)) = NULL;
1441   }
1442   else {
1443     GST_INFO (GST_CAT_PADS, "start reconnect filtered %s:%s and %s:%s",
1444         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1445   }
1446
1447   srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1448   GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1449              GST_DEBUG_PAD_NAME (realsrc));
1450   gst_caps_debug (srccaps, "caps of src pad (pre-reconnect)");
1451   sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1452   GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1453              GST_DEBUG_PAD_NAME (realsink));
1454   gst_caps_debug (sinkcaps, "caps of sink pad (pre-reconnect)");
1455
1456   /* first take the intersection of the pad caps */
1457   intersection = gst_caps_intersect (srccaps, sinkcaps);
1458   gst_caps_debug (intersection, "caps of intersection");
1459
1460   /* if we have no intersection but one of the caps was not NULL.. */
1461   if (!intersection && (srccaps || sinkcaps)) {
1462     /* the intersection is NULL but the pad caps were not both NULL,
1463      * this means they have no common format */
1464     GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s have no common type",
1465               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1466     return FALSE;
1467   } else if (intersection) {
1468     GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s intersected to %s caps",
1469          GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink), 
1470          ((intersection && GST_CAPS_IS_FIXED (intersection)) ? "fixed" : "variable"));
1471
1472     /* then filter this against the app filter */
1473     if (filtercaps) {
1474       GstCaps *filtered_intersection = gst_caps_intersect (intersection, 
1475                                                            filtercaps);
1476
1477       /* get rid of the old intersection here */
1478       gst_caps_unref (intersection);
1479
1480       if (!filtered_intersection) {
1481         GST_INFO (GST_CAT_PADS, 
1482                   "filtered connection between pads %s:%s and %s:%s is empty",
1483                   GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1484         return FALSE;
1485       }
1486       intersection = filtered_intersection;
1487
1488       /* keep a reference to the app caps */
1489       GST_RPAD_APPFILTER (realsink) = filtercaps;
1490       GST_RPAD_APPFILTER (realsrc) = filtercaps;
1491     }
1492   }
1493   GST_DEBUG (GST_CAT_CAPS, "setting filter for connection to:");
1494   gst_caps_debug (intersection, "filter for connection");
1495
1496   /* both the app filter and the filter, while stored on both peer pads, 
1497    * are equal to the same thing on both */
1498   GST_RPAD_FILTER (realsrc) = intersection; 
1499   GST_RPAD_FILTER (realsink) = intersection; 
1500
1501   return gst_pad_perform_negotiate (GST_PAD (realsrc), GST_PAD (realsink));
1502 }
1503
1504 /**
1505  * gst_pad_perform_negotiate:
1506  * @srcpad: the source #GstPad.
1507  * @sinkpad: the sink #GstPad.
1508  *
1509  * Tries to negotiate the pads.
1510  *
1511  * Returns: TRUE if the pads were succesfully negotiated, FALSE otherwise.
1512  */
1513 gboolean
1514 gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad) 
1515 {
1516   GstCaps *intersection, *filtered_intersection;
1517   GstRealPad *realsrc, *realsink;
1518   GstCaps *srccaps, *sinkcaps, *filter;
1519
1520   g_return_val_if_fail (srcpad != NULL, FALSE);
1521   g_return_val_if_fail (sinkpad != NULL, FALSE);
1522   
1523   realsrc = GST_PAD_REALIZE (srcpad);
1524   realsink = GST_PAD_REALIZE (sinkpad);
1525     
1526   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1527   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1528
1529   filter = GST_RPAD_APPFILTER (realsrc);
1530   if (filter) {
1531     GST_INFO (GST_CAT_PADS, "dumping filter for connection %s:%s-%s:%s",
1532               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1533     gst_caps_debug (filter, "connection filter caps");
1534   }
1535
1536   /* calculate the new caps here */
1537   srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1538   GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1539              GST_DEBUG_PAD_NAME (realsrc));
1540   gst_caps_debug (srccaps, 
1541                   "src caps, awaiting negotiation, after applying filter");
1542   sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1543   GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", 
1544              GST_DEBUG_PAD_NAME (realsink));
1545   gst_caps_debug (sinkcaps, 
1546                   "sink caps, awaiting negotiation, after applying filter");
1547   intersection = gst_caps_intersect (srccaps, sinkcaps);
1548   filtered_intersection = gst_caps_intersect (intersection, filter);
1549   if (filtered_intersection) {
1550     gst_caps_unref (intersection);
1551     intersection = filtered_intersection;
1552   }
1553
1554   /* no negotiation is performed if the pads have filtercaps */
1555   if (intersection) {
1556     GstPadConnectReturn res;
1557
1558     res = gst_pad_try_set_caps_func (realsrc, intersection, TRUE);
1559     if (res == GST_PAD_CONNECT_REFUSED) 
1560       return FALSE;
1561     if (res == GST_PAD_CONNECT_DONE) 
1562       return TRUE;
1563
1564     res = gst_pad_try_set_caps_func (realsink, intersection, TRUE);
1565     if (res == GST_PAD_CONNECT_REFUSED) 
1566       return FALSE;
1567     if (res == GST_PAD_CONNECT_DONE) 
1568       return TRUE;
1569   }
1570   return TRUE;
1571 }
1572
1573 /**
1574  * gst_pad_try_reconnect_filtered:
1575  * @srcpad: the source #GstPad to reconnect.
1576  * @sinkpad: the sink #GstPad to reconnect.
1577  * @filtercaps: the #GstPad to use as a filter in the reconnection.
1578  *
1579  * Tries to reconnect the given source and sink pad, constrained by the given
1580  * capabilities.
1581  *
1582  * Returns: TRUE if the pads were succesfully renegotiated, FALSE otherwise.
1583  */
1584 gboolean
1585 gst_pad_try_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, 
1586                                 GstCaps *filtercaps)
1587 {
1588   GstRealPad *realsrc, *realsink;
1589
1590   g_return_val_if_fail (srcpad != NULL, FALSE);
1591   g_return_val_if_fail (sinkpad != NULL, FALSE);
1592
1593   realsrc = GST_PAD_REALIZE (srcpad);
1594   realsink = GST_PAD_REALIZE (sinkpad);
1595
1596   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1597   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1598   
1599   return gst_pad_try_reconnect_filtered_func (realsrc, realsink, 
1600                                               filtercaps, TRUE);
1601 }
1602
1603 /**
1604  * gst_pad_reconnect_filtered:
1605  * @srcpad: the source #GstPad to reconnect.
1606  * @sinkpad: the sink #GstPad to reconnect.
1607  * @filtercaps: the #GstPad to use as a filter in the reconnection.
1608  *
1609  * Reconnects the given source and sink pad, constrained by the given
1610  * capabilities.  If the reconnection fails, the pads are disconnected
1611  * and FALSE is returned.
1612  *
1613  * Returns: TRUE if the pads were succesfully reconnected, FALSE otherwise.
1614  */
1615 gboolean
1616 gst_pad_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, 
1617                             GstCaps *filtercaps)
1618 {
1619   GstRealPad *realsrc, *realsink;
1620
1621   g_return_val_if_fail (srcpad != NULL, FALSE);
1622   g_return_val_if_fail (sinkpad != NULL, FALSE);
1623
1624   realsrc = GST_PAD_REALIZE (srcpad);
1625   realsink = GST_PAD_REALIZE (sinkpad);
1626
1627   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1628   g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1629   
1630   if (! gst_pad_try_reconnect_filtered_func (realsrc, realsink, 
1631                                              filtercaps, TRUE)) {
1632     gst_pad_disconnect (srcpad, GST_PAD (GST_PAD_PEER (srcpad)));
1633     return FALSE;
1634   }
1635   return TRUE;
1636 }
1637
1638 /**
1639  * gst_pad_proxy_connect:
1640  * @pad: a #GstPad to proxy to.
1641  * @caps: the #GstCaps to use in proxying.
1642  *
1643  * Proxies the connect function to the specified pad.
1644  *
1645  * Returns: TRUE if the peer pad accepted the caps, FALSE otherwise.
1646  */
1647 GstPadConnectReturn
1648 gst_pad_proxy_connect (GstPad *pad, GstCaps *caps)
1649 {
1650   GstRealPad *peer, *realpad;
1651
1652   realpad = GST_PAD_REALIZE (pad);
1653
1654   peer = GST_RPAD_PEER (realpad);
1655
1656   GST_INFO (GST_CAT_CAPS, "proxy connect to pad %s:%s",
1657             GST_DEBUG_PAD_NAME (realpad));
1658
1659   if (peer && gst_pad_try_set_caps_func (peer, caps, TRUE) < 0)
1660     return GST_PAD_CONNECT_REFUSED;
1661   if (gst_pad_try_set_caps_func (realpad, caps, FALSE) < 0)
1662     return GST_PAD_CONNECT_REFUSED;
1663
1664   return GST_PAD_CONNECT_OK;
1665 }
1666
1667 /**
1668  * gst_pad_get_caps:
1669  * @pad: a  #GstPad to get the capabilities of.
1670  *
1671  * Gets the capabilities of this pad.
1672  *
1673  * Returns: the #GstCaps of this pad.
1674  */
1675 GstCaps*
1676 gst_pad_get_caps (GstPad *pad)
1677 {
1678   GstRealPad *realpad;
1679
1680   g_return_val_if_fail (pad != NULL, NULL);
1681   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1682
1683   realpad = GST_PAD_REALIZE (pad);
1684
1685   GST_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
1686             GST_DEBUG_PAD_NAME (realpad), realpad);
1687
1688   if (GST_PAD_CAPS (realpad)) {
1689     GST_DEBUG (GST_CAT_CAPS, "using pad real caps %p", GST_PAD_CAPS (realpad));
1690     return GST_PAD_CAPS (realpad);
1691   }
1692   else if GST_RPAD_GETCAPSFUNC (realpad) {
1693     GST_DEBUG (GST_CAT_CAPS, "using pad get function");
1694     return GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad), NULL);
1695   }
1696   else if (GST_PAD_PAD_TEMPLATE (realpad)) {
1697     GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad);
1698     GST_DEBUG (GST_CAT_CAPS, "using pad template %p with caps %p", 
1699                templ, GST_PAD_TEMPLATE_CAPS (templ));
1700     return GST_PAD_TEMPLATE_CAPS (templ);
1701   }
1702   GST_DEBUG (GST_CAT_CAPS, "pad has no caps");
1703
1704   return NULL;
1705 }
1706
1707 /**
1708  * gst_pad_get_pad_template_caps:
1709  * @pad: a #GstPad to get the template capabilities from.
1710  *
1711  * Gets the template capabilities of this pad.
1712  *
1713  * Returns: the template #GstCaps of this pad.
1714  */
1715 GstCaps*
1716 gst_pad_get_pad_template_caps (GstPad *pad)
1717 {
1718   g_return_val_if_fail (pad != NULL, NULL);
1719   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1720
1721   if (GST_PAD_PAD_TEMPLATE (pad))
1722     return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
1723
1724   return NULL;
1725 }
1726
1727 /**
1728  * gst_pad_template_get_caps_by_name:
1729  * @templ: a #GstPadTemplate to get the capabilities of.
1730  * @name: the name of the capability to get.
1731  *
1732  * Gets the capability with the given name from this pad template.
1733  *
1734  * Returns: the #GstCaps, or NULL if not found or in case of an error.
1735  */
1736 GstCaps*
1737 gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
1738 {
1739   GstCaps *caps;
1740
1741   g_return_val_if_fail (templ != NULL, NULL);
1742
1743   caps = GST_PAD_TEMPLATE_CAPS (templ);
1744   if (!caps) 
1745     return NULL;
1746
1747   return gst_caps_get_by_name (caps, name);
1748 }
1749
1750 /**
1751  * gst_pad_check_compatibility:
1752  * @srcpad: the source #GstPad to check.
1753  * @sinkpad: the sink #GstPad to check against.
1754  *
1755  * Checks if two pads have compatible capabilities.
1756  *
1757  * Returns: TRUE if they are compatible or if the capabilities
1758  * could not be checked
1759  */
1760 gboolean
1761 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
1762 {
1763   g_return_val_if_fail (srcpad != NULL, FALSE);
1764   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1765   g_return_val_if_fail (sinkpad != NULL, FALSE);
1766   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1767
1768   if (GST_PAD_CAPS (srcpad) && GST_PAD_CAPS (sinkpad)) {
1769     if (!gst_caps_is_always_compatible (GST_PAD_CAPS (srcpad), 
1770                                         GST_PAD_CAPS (sinkpad))) {
1771       return FALSE;
1772     }
1773     else {
1774       return TRUE;
1775     }
1776   }
1777   else {
1778     GST_DEBUG (GST_CAT_PADS, 
1779                "could not check capabilities of pads (%s:%s) and (%s:%s) %p %p",
1780                GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad), 
1781                GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
1782     return TRUE;
1783   }
1784 }
1785
1786 /**
1787  * gst_pad_get_peer:
1788  * @pad: a #GstPad to get the peer of.
1789  *
1790  * Gets the peer pad of this pad.
1791  *
1792  * Returns: the peer #GstPad.
1793  */
1794 GstPad*
1795 gst_pad_get_peer (GstPad *pad)
1796 {
1797   g_return_val_if_fail (pad != NULL, NULL);
1798   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1799
1800   return GST_PAD (GST_PAD_PEER (pad));
1801 }
1802
1803 /**
1804  * gst_pad_get_allowed_caps:
1805  * @pad: a #GstPad to get the allowed caps of.
1806  *
1807  * Gets the capabilities of the allowed media types that can
1808  * flow through this pad.  The caller must free the resulting caps.
1809  *
1810  * Returns: a newly allocated copy of the allowed #GstCaps.
1811  */
1812 GstCaps*
1813 gst_pad_get_allowed_caps (GstPad *pad)
1814 {
1815   g_return_val_if_fail (pad != NULL, NULL);
1816   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1817
1818   GST_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s", 
1819              GST_DEBUG_PAD_NAME (pad));
1820
1821   return gst_caps_copy (GST_RPAD_FILTER (pad));
1822 }
1823
1824 /**
1825  * gst_pad_recalc_allowed_caps:
1826  * @pad: a #GstPad to recalculate the capablities of.
1827  *
1828  * Attempts to reconnect the pad to its peer through its filter, 
1829  * set with gst_pad_[re]connect_filtered. This function is useful when a
1830  * plug-in has new capabilities on a pad and wants to notify the peer.
1831  *
1832  * Returns: TRUE on success, FALSE otherwise.
1833  */
1834 gboolean
1835 gst_pad_recalc_allowed_caps (GstPad *pad)
1836 {
1837   GstRealPad *peer;
1838
1839   g_return_val_if_fail (pad != NULL, FALSE);
1840   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1841
1842   GST_DEBUG (GST_CAT_PROPERTIES, "set allowed caps of %s:%s", 
1843              GST_DEBUG_PAD_NAME (pad));
1844
1845   peer = GST_RPAD_PEER (pad);
1846   if (peer)
1847     return gst_pad_try_reconnect_filtered (pad, GST_PAD (peer), 
1848                                            GST_RPAD_APPFILTER (pad));
1849
1850   return TRUE;
1851 }
1852
1853 /**
1854  * gst_pad_get_bufferpool:
1855  * @pad: a #GstPad to get the bufferpool from.
1856  *
1857  * Gets the bufferpool of the peer pad of the given pad.
1858  *
1859  * Returns: the #GstBufferPool, or NULL in case of an error.
1860  */
1861 GstBufferPool*          
1862 gst_pad_get_bufferpool (GstPad *pad)
1863 {
1864   GstRealPad *peer;
1865
1866   g_return_val_if_fail (pad != NULL, NULL);
1867   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1868    
1869   peer = GST_RPAD_PEER (pad);
1870
1871   if (!peer)
1872     return NULL;
1873
1874   GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1875
1876   if (peer->bufferpoolfunc) {
1877     GST_DEBUG (GST_CAT_PADS, 
1878                "calling bufferpoolfunc &%s (@%p) of peer pad %s:%s",
1879                GST_DEBUG_FUNCPTR_NAME (peer->bufferpoolfunc), 
1880                &peer->bufferpoolfunc, GST_DEBUG_PAD_NAME (((GstPad*) peer)));
1881     return (peer->bufferpoolfunc) (((GstPad*) peer));
1882   } else {
1883     GST_DEBUG (GST_CAT_PADS, "no bufferpoolfunc for peer pad %s:%s at %p",
1884                GST_DEBUG_PAD_NAME (((GstPad*) peer)), &peer->bufferpoolfunc);
1885     return NULL;
1886   }
1887 }
1888
1889 static void
1890 gst_real_pad_dispose (GObject *object)
1891 {
1892   GstPad *pad = GST_PAD (object);
1893   
1894   /* No connected pad can ever be disposed.
1895    * It has to have a parent to be connected 
1896    * and a parent would hold a reference */
1897   g_assert (GST_PAD_PEER (pad) == NULL);
1898
1899   GST_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s", GST_DEBUG_PAD_NAME(pad));
1900
1901   if (GST_PAD_PAD_TEMPLATE (pad)){
1902     GST_DEBUG (GST_CAT_REFCOUNTING, "unreffing padtemplate'%s'", 
1903                GST_OBJECT_NAME (GST_PAD_PAD_TEMPLATE (pad)));
1904     gst_object_unref (GST_OBJECT (GST_PAD_PAD_TEMPLATE (pad)));
1905     GST_PAD_PAD_TEMPLATE (pad) = NULL;
1906   }
1907   
1908   /* we destroy the ghostpads, because they are nothing without the real pad */
1909   if (GST_REAL_PAD (pad)->ghostpads) {
1910     GList *orig, *ghostpads;
1911
1912     orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
1913
1914     while (ghostpads) {
1915       GstPad *ghostpad = GST_PAD (ghostpads->data);
1916
1917       if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))){
1918         GST_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'", 
1919                    GST_OBJECT_NAME (GST_OBJECT_PARENT (ghostpad)));
1920
1921         gst_element_remove_ghost_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), GST_PAD (ghostpad));
1922       }
1923       ghostpads = g_list_next (ghostpads);
1924     }
1925     g_list_free (orig);
1926     g_list_free (GST_REAL_PAD(pad)->ghostpads);
1927   }
1928
1929   if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
1930     GST_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
1931                GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
1932     
1933     gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
1934   }
1935   
1936   G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
1937 }
1938
1939
1940 #ifndef GST_DISABLE_LOADSAVE
1941 /* FIXME: why isn't this on a GstElement ? */
1942 /**
1943  * gst_pad_load_and_connect:
1944  * @self: an #xmlNodePtr to read the description from.
1945  * @parent: the #GstObject element that owns the pad.
1946  *
1947  * Reads the pad definition from the XML node and connects the given pad
1948  * in the element to a pad of an element up in the hierarchy.
1949  */
1950 void
1951 gst_pad_load_and_connect (xmlNodePtr self, GstObject *parent)
1952 {
1953   xmlNodePtr field = self->xmlChildrenNode;
1954   GstPad *pad = NULL, *targetpad;
1955   gchar *peer = NULL;
1956   gchar **split;
1957   GstElement *target;
1958   GstObject *grandparent;
1959
1960   while (field) {
1961     if (!strcmp (field->name, "name")) {
1962       pad = gst_element_get_pad (GST_ELEMENT (parent), 
1963                                  xmlNodeGetContent (field));
1964     }
1965     else if (!strcmp(field->name, "peer")) {
1966       peer = xmlNodeGetContent (field);
1967     }
1968     field = field->next;
1969   }
1970   g_return_if_fail (pad != NULL);
1971
1972   if (peer == NULL) return;
1973
1974   split = g_strsplit (peer, ".", 2);
1975
1976   if (split[0] == NULL || split[1] == NULL) {
1977     GST_DEBUG (GST_CAT_XML, 
1978                "Could not parse peer '%s' for pad %s:%s, leaving unconnected",
1979                peer, GST_DEBUG_PAD_NAME (pad));
1980     return;
1981   }
1982   
1983   g_return_if_fail (split[0] != NULL);
1984   g_return_if_fail (split[1] != NULL);
1985
1986   grandparent = gst_object_get_parent (parent);
1987
1988   if (grandparent && GST_IS_BIN (grandparent)) {
1989     target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
1990   }
1991   else
1992     goto cleanup;
1993
1994   if (target == NULL) goto cleanup;
1995
1996   targetpad = gst_element_get_pad (target, split[1]);
1997
1998   if (targetpad == NULL) goto cleanup;
1999
2000   gst_pad_connect (pad, targetpad);
2001
2002 cleanup:
2003   g_strfreev (split);
2004 }
2005
2006 /**
2007  * gst_pad_save_thyself:
2008  * @pad: a #GstPad to save.
2009  * @parent: the parent #xmlNodePtr to save the description in.
2010  *
2011  * Saves the pad into an xml representation.
2012  *
2013  * Returns: the #xmlNodePtr representation of the pad.
2014  */
2015 static xmlNodePtr
2016 gst_pad_save_thyself (GstObject *object, xmlNodePtr parent)
2017 {
2018   GstRealPad *realpad;
2019   GstPad *peer;
2020
2021   g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
2022
2023   realpad = GST_REAL_PAD (object);
2024
2025   xmlNewChild (parent, NULL, "name", GST_PAD_NAME (realpad));
2026   if (GST_RPAD_PEER (realpad) != NULL) {
2027     gchar *content;
2028     
2029     peer = GST_PAD (GST_RPAD_PEER (realpad));
2030     /* first check to see if the peer's parent's parent is the same */
2031     /* we just save it off */
2032     content = g_strdup_printf ("%s.%s",
2033                                GST_OBJECT_NAME (GST_PAD_PARENT (peer)),
2034                                GST_PAD_NAME (peer));
2035     xmlNewChild (parent, NULL, "peer", content);
2036     g_free (content);
2037   } else
2038     xmlNewChild (parent, NULL, "peer", "");
2039
2040   return parent;
2041 }
2042
2043 /* FIXME: shouldn't pad and ghost be switched ?
2044  * FIXME: shouldn't the bin argument be dumped ?
2045  */
2046 /**
2047  * gst_ghost_pad_save_thyself:
2048  * @pad: a ghost #GstPad to save.
2049  * @bin: the #bin
2050  * @parent: the parent #xmlNodePtr to save the description in.
2051  *
2052  * Saves the ghost pad into an xml representation.
2053  *
2054  * Returns: the #xmlNodePtr representation of the pad.
2055  */
2056 xmlNodePtr
2057 gst_ghost_pad_save_thyself (GstPad *pad, xmlNodePtr parent)
2058 {
2059   xmlNodePtr self;
2060
2061   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
2062
2063   self = xmlNewChild (parent, NULL, "ghostpad", NULL);
2064   xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
2065   xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
2066
2067   /* FIXME FIXME FIXME! */
2068
2069   return self;
2070 }
2071 #endif /* GST_DISABLE_LOADSAVE */
2072
2073 /**
2074  * gst_pad_push:
2075  * @pad: a #GstPad to push the buffer out of.
2076  * @buf: the #GstBuffer to push.
2077  *
2078  * Pushes a buffer to the peer of the pad.
2079  */
2080 void 
2081 gst_pad_push (GstPad *pad, GstBuffer *buf) 
2082 {
2083   GstRealPad *peer = GST_RPAD_PEER (pad);
2084
2085   GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
2086
2087   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
2088
2089   if (!gst_probe_dispatcher_dispatch (&(GST_REAL_PAD (pad)->probedisp), GST_DATA (buf)))
2090     return;
2091
2092   if (!peer) {
2093     g_warning ("push on pad %s:%s but it is unconnected", 
2094                GST_DEBUG_PAD_NAME (pad));
2095   }
2096   else {
2097     if (peer->chainhandler) {
2098       if (buf) {
2099         GST_DEBUG (GST_CAT_DATAFLOW, 
2100                    "calling chainhandler &%s of peer pad %s:%s",
2101                    GST_DEBUG_FUNCPTR_NAME (peer->chainhandler), 
2102                    GST_DEBUG_PAD_NAME (GST_PAD (peer)));
2103         if (!gst_probe_dispatcher_dispatch (&peer->probedisp, GST_DATA (buf)))
2104           return;
2105
2106         (peer->chainhandler) (GST_PAD_CAST (peer), buf);
2107         return;
2108       }
2109       else {
2110         g_warning ("trying to push a NULL buffer on pad %s:%s", 
2111                    GST_DEBUG_PAD_NAME (peer));
2112         return;
2113       }
2114     } 
2115     else {
2116       g_warning ("internal error: push on pad %s:%s but it has no chainhandler",
2117                  GST_DEBUG_PAD_NAME (peer));
2118     }
2119   }
2120   /* clean up the mess here */
2121   if (buf != NULL) gst_data_unref (GST_DATA (buf));
2122 }
2123
2124 /**
2125  * gst_pad_pull:
2126  * @pad: a #GstPad to pull a buffer from.
2127  *
2128  * Pulls a buffer from the peer pad.
2129  *
2130  * Returns: a new #GstBuffer from the peer pad.
2131  */
2132 GstBuffer*
2133 gst_pad_pull (GstPad *pad) 
2134 {
2135   GstRealPad *peer;
2136
2137   peer = GST_RPAD_PEER (pad);
2138   
2139   GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
2140
2141   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
2142
2143   if (!peer) {
2144     gst_element_error (GST_PAD_PARENT (pad), 
2145                        "pull on pad %s:%s but it was unconnected", 
2146                        GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), 
2147                        GST_PAD_NAME (pad), NULL);
2148   }
2149   else {
2150     if (peer->gethandler) {
2151       GstBuffer *buf;
2152
2153       GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s",
2154                  GST_DEBUG_FUNCPTR_NAME (peer->gethandler), 
2155                  GST_DEBUG_PAD_NAME (peer));
2156
2157       buf = (peer->gethandler) (GST_PAD_CAST (peer));
2158
2159       if (buf) {
2160         if (!gst_probe_dispatcher_dispatch (&peer->probedisp, GST_DATA (buf)))
2161           return NULL;
2162
2163         return buf;
2164       }
2165
2166       /* no null buffers allowed */
2167       gst_element_error (GST_PAD_PARENT (pad), 
2168                          "NULL buffer during pull on %s:%s", 
2169                          GST_DEBUG_PAD_NAME (pad), NULL);
2170           
2171     } else {
2172       gst_element_error (GST_PAD_PARENT (pad), 
2173                          "internal error: pull on pad %s:%s "
2174                          "but the peer pad %s:%s has no gethandler", 
2175                          GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer),
2176                          NULL);
2177     }
2178   }
2179   return NULL;
2180 }
2181
2182 /**
2183  * gst_pad_select:
2184  * @padlist: a #GList of pads.
2185  *
2186  * Waits for a buffer on any of the list of pads.
2187  *
2188  * Returns: the #GstPad that has a buffer available. 
2189  * Use #gst_pad_pull() to get the buffer.
2190  */
2191 GstPad*
2192 gst_pad_select (GList *padlist)
2193 {
2194   GstPad *pad;
2195
2196   pad = gst_scheduler_pad_select (GST_PAD_PARENT (padlist->data)->sched, 
2197                                   padlist);
2198   return pad;
2199 }
2200
2201 /**
2202  * gst_pad_selectv:
2203  * @pad: a first #GstPad to perform the select on.
2204  * @...: A NULL-terminated list of more pads to select on.
2205  *
2206  * Waits for a buffer on the given set of pads.
2207  *
2208  * Returns: the #GstPad that has a buffer available.
2209  * Use #gst_pad_pull() to get the buffer.
2210  */
2211 GstPad*
2212 gst_pad_selectv (GstPad *pad, ...)
2213 {
2214   GstPad *result;
2215   GList *padlist = NULL;
2216   va_list var_args;
2217
2218   if (pad == NULL)
2219     return NULL;
2220
2221   va_start (var_args, pad);
2222
2223   while (pad) {
2224     padlist = g_list_prepend (padlist, pad);
2225     pad = va_arg (var_args, GstPad *);
2226   }
2227   result = gst_pad_select (padlist);
2228   g_list_free (padlist);
2229
2230   va_end (var_args);
2231   
2232   return result;
2233 }
2234
2235 /************************************************************************
2236  *
2237  * templates
2238  *
2239  */
2240 static void             gst_pad_template_class_init     (GstPadTemplateClass *klass);
2241 static void             gst_pad_template_init           (GstPadTemplate *templ);
2242
2243 GType
2244 gst_pad_template_get_type (void)
2245 {
2246   static GType padtemplate_type = 0;
2247
2248   if (!padtemplate_type) {
2249     static const GTypeInfo padtemplate_info = {
2250       sizeof (GstPadTemplateClass), NULL, NULL,
2251       (GClassInitFunc) gst_pad_template_class_init, NULL, NULL,
2252       sizeof (GstPadTemplate),
2253       32,
2254       (GInstanceInitFunc) gst_pad_template_init, NULL
2255     };
2256     padtemplate_type = g_type_register_static(GST_TYPE_OBJECT, "GstPadTemplate",
2257                                               &padtemplate_info, 0);
2258   }
2259   return padtemplate_type;
2260 }
2261
2262 static void
2263 gst_pad_template_class_init (GstPadTemplateClass *klass)
2264 {
2265   GObjectClass *gobject_class;
2266   GstObjectClass *gstobject_class;
2267
2268   gobject_class = (GObjectClass*) klass;
2269   gstobject_class = (GstObjectClass*) klass;
2270
2271   padtemplate_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
2272
2273   gst_pad_template_signals[TEMPL_PAD_CREATED] =
2274     g_signal_new ("pad_created", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
2275                   G_STRUCT_OFFSET (GstPadTemplateClass, pad_created), 
2276                   NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
2277                   G_TYPE_POINTER);
2278
2279   gstobject_class->path_string_separator = "*";
2280 }
2281
2282 static void
2283 gst_pad_template_init (GstPadTemplate *templ)
2284 {
2285 }
2286
2287 /* ALWAYS padtemplates cannot have conversion specifications, it doesn't make
2288  * sense.
2289  * SOMETIMES padtemplates can do whatever they want, they are provided by the
2290  * element.
2291  * REQUEST padtemplates can be reverse-parsed (the user asks for 'sink1', the
2292  * 'sink%d' template is automatically selected), so we need to restrict their
2293  * naming.
2294  */
2295 static gboolean
2296 name_is_valid (const gchar *name, GstPadPresence presence)
2297 {
2298   const gchar *str;
2299   
2300   if (presence == GST_PAD_ALWAYS) {
2301     if (strchr (name, '%')) {
2302       g_warning ("invalid name template %s: conversion specifications are not"
2303                  " allowed for GST_PAD_ALWAYS padtemplates", name);
2304       return FALSE;
2305     }
2306   } else if (presence == GST_PAD_REQUEST) {
2307     if ((str = strchr (name, '%')) && strchr (str + 1, '%')) {
2308       g_warning ("invalid name template %s: only one conversion specification"
2309                  " allowed in GST_PAD_REQUEST padtemplate", name);
2310       return FALSE;
2311     }
2312     if (str && (*(str+1) != 's' && *(str+1) != 'd')) {
2313       g_warning ("invalid name template %s: conversion specification must be of"
2314                  " type '%%d' or '%%s' for GST_PAD_REQUEST padtemplate", name);
2315       return FALSE;
2316     }
2317     if (str && (*(str+2) != '\0')) {
2318       g_warning ("invalid name template %s: conversion specification must"
2319                  " appear at the end of the GST_PAD_REQUEST padtemplate name", 
2320                  name);
2321       return FALSE;
2322     }
2323   }
2324   
2325   return TRUE;
2326 }
2327
2328 /**
2329  * gst_pad_template_new:
2330  * @name_template: the name template.
2331  * @direction: the #GstPadDirection of the template.
2332  * @presence: the #GstPadPresence of the pad.
2333  * @caps: a #GstCaps set for the template.
2334  * @...: a NULL-terminated list of #GstCaps.
2335  *
2336  * Creates a new pad template with a name according to the given template
2337  * and with the given arguments.
2338  *
2339  * Returns: a new #GstPadTemplate.
2340  */
2341 GstPadTemplate*
2342 gst_pad_template_new (const gchar *name_template,
2343                      GstPadDirection direction, GstPadPresence presence,
2344                      GstCaps *caps, ...)
2345 {
2346   GstPadTemplate *new;
2347   va_list var_args;
2348   GstCaps *thecaps = NULL;
2349
2350   g_return_val_if_fail (name_template != NULL, NULL);
2351
2352   if (!name_is_valid (name_template, presence))
2353     return NULL;
2354
2355   new = g_object_new (gst_pad_template_get_type (),
2356                       "name", name_template,
2357                       NULL);
2358
2359   GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name_template);
2360   GST_PAD_TEMPLATE_DIRECTION (new) = direction;
2361   GST_PAD_TEMPLATE_PRESENCE (new) = presence;
2362
2363   va_start (var_args, caps);
2364
2365   while (caps) {
2366     new->fixed &= caps->fixed;
2367     thecaps = gst_caps_append (thecaps, gst_caps_ref (caps));
2368     caps = va_arg (var_args, GstCaps*);
2369   }
2370   va_end (var_args);
2371   
2372   GST_PAD_TEMPLATE_CAPS (new) = thecaps;
2373
2374   return new;
2375 }
2376
2377 /**
2378  * gst_pad_template_get_caps:
2379  * @templ: a #GstPadTemplate to get capabilities of.
2380  *
2381  * Gets the capabilities of the pad template.
2382  *
2383  * Returns: the #GstCaps of the pad template.
2384  */
2385 GstCaps*
2386 gst_pad_template_get_caps (GstPadTemplate *templ)
2387 {
2388   g_return_val_if_fail (templ != NULL, NULL);
2389
2390   return GST_PAD_TEMPLATE_CAPS (templ);
2391 }
2392
2393 /**
2394  * gst_pad_set_element_private:
2395  * @pad: the #GstPad to set the private data of.
2396  * @priv: The private data to attach to the pad.
2397  *
2398  * Set the given private data gpointer on the pad. 
2399  * This function can only be used by the element that owns the pad.
2400  */
2401 void
2402 gst_pad_set_element_private (GstPad *pad, gpointer priv)
2403 {
2404   pad->element_private = priv;
2405 }
2406
2407 /**
2408  * gst_pad_get_element_private:
2409  * @pad: the #GstPad to get the private data of.
2410  *
2411  * Gets the private data of a pad.
2412  *
2413  * Returns: a #gpointer to the private data.
2414  */
2415 gpointer
2416 gst_pad_get_element_private (GstPad *pad)
2417 {
2418   return pad->element_private;
2419 }
2420
2421
2422 /***** ghost pads *****/
2423 GType _gst_ghost_pad_type = 0;
2424
2425 static void     gst_ghost_pad_class_init         (GstGhostPadClass *klass);
2426 static void     gst_ghost_pad_init               (GstGhostPad *pad);
2427
2428 static GstPad *ghost_pad_parent_class = NULL;
2429 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
2430
2431 GType
2432 gst_ghost_pad_get_type (void) 
2433 {
2434   if (!_gst_ghost_pad_type) {
2435     static const GTypeInfo pad_info = {
2436       sizeof (GstGhostPadClass), NULL, NULL,
2437       (GClassInitFunc) gst_ghost_pad_class_init, NULL, NULL,
2438       sizeof (GstGhostPad),
2439       8,
2440       (GInstanceInitFunc) gst_ghost_pad_init,
2441       NULL
2442     };
2443     _gst_ghost_pad_type = g_type_register_static (GST_TYPE_PAD, "GstGhostPad", 
2444                                                   &pad_info, 0);
2445   }
2446   return _gst_ghost_pad_type;
2447 }
2448
2449 static void
2450 gst_ghost_pad_class_init (GstGhostPadClass *klass)
2451 {
2452   GObjectClass *gobject_class;
2453
2454   gobject_class = (GObjectClass*) klass;
2455
2456   ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
2457 }
2458
2459 static void
2460 gst_ghost_pad_init (GstGhostPad *pad)
2461 {
2462   pad->realpad = NULL;
2463 }
2464
2465 /**
2466  * gst_ghost_pad_new:
2467  * @name: the name of the new ghost pad.
2468  * @pad: the #GstPad to create a ghost pad for.
2469  *
2470  * Creates a new ghost pad associated with the given pad, and names it with
2471  * the given name.  If name is NULL, a guaranteed unique name (across all
2472  * ghost pads) will be assigned (most likely of the form ghostpad%d).
2473  *
2474  * Returns: a new ghost #GstPad, or NULL in case of an error.
2475  */
2476
2477 GstPad*
2478 gst_ghost_pad_new (const gchar *name,
2479                    GstPad *pad)
2480 {
2481   GstGhostPad *ghostpad;
2482   GstRealPad *realpad;
2483
2484   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2485
2486   ghostpad = g_object_new (gst_ghost_pad_get_type () ,NULL);
2487   gst_pad_set_name (GST_PAD (ghostpad), name);
2488
2489   realpad = (GstRealPad *) pad;
2490
2491   while (!GST_IS_REAL_PAD (realpad)) {
2492     realpad = GST_PAD_REALIZE (realpad);
2493   }
2494   GST_GPAD_REALPAD (ghostpad) = realpad;
2495   GST_PAD_PAD_TEMPLATE (ghostpad) = GST_PAD_PAD_TEMPLATE (pad);
2496
2497   /* add ourselves to the real pad's list of ghostpads */
2498   gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));
2499
2500   /* FIXME need to ref the real pad here... ? */
2501
2502   GST_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\"", 
2503              gst_pad_get_name (GST_PAD (ghostpad)));
2504
2505   return GST_PAD (ghostpad);
2506 }
2507
2508 /**
2509  * gst_pad_get_internal_connections_default:
2510  * @pad: the #GstPad to get the internal connections of.
2511  *
2512  * Gets a list of pads to which the given pad is connected to
2513  * inside of the parent element.
2514  * This is the default handler, and thus returns a list of all of the
2515  * pads inside the parent element with opposite direction.
2516  * The caller must free this list after use.
2517  *
2518  * Returns: a newly allocated #GList of pads.
2519  */
2520 GList*
2521 gst_pad_get_internal_connections_default (GstPad *pad)
2522 {
2523   GList *res = NULL;
2524   GstElement *parent;
2525   GList *parent_pads;
2526   GstPadDirection direction;
2527   GstRealPad *rpad;
2528   
2529   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2530
2531   rpad = GST_PAD_REALIZE (pad);
2532   direction = rpad->direction;
2533
2534   parent = GST_PAD_PARENT (rpad);
2535   parent_pads = parent->pads;
2536
2537   while (parent_pads) {
2538     GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data);
2539     
2540     if (parent_pad->direction != direction) {
2541       res = g_list_prepend (res, parent_pad);
2542     }
2543     
2544     parent_pads = g_list_next (parent_pads);
2545   }
2546
2547   return res;
2548 }
2549
2550 /**
2551  * gst_pad_get_internal_connections:
2552  * @pad: the #GstPad to get the internal connections of.
2553  *
2554  * Gets a list of pads to which the given pad is connected to
2555  * inside of the parent element.
2556  * The caller must free this list after use.
2557  *
2558  * Returns: a newly allocated #GList of pads.
2559  */
2560 GList*
2561 gst_pad_get_internal_connections (GstPad *pad)
2562 {
2563   GList *res = NULL;
2564   GstRealPad *rpad;
2565
2566   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2567
2568   rpad = GST_PAD_REALIZE (pad);
2569
2570   if (GST_RPAD_INTCONNFUNC (rpad))
2571     res = GST_RPAD_INTCONNFUNC (rpad) (GST_PAD_CAST (rpad));
2572
2573   return res;
2574 }
2575
2576
2577 static gboolean 
2578 gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, 
2579                                 GstEvent *event)
2580 {
2581   GList *pads = element->pads;
2582
2583   while (pads) {
2584     GstPad *eventpad = GST_PAD (pads->data);
2585     pads = g_list_next (pads);
2586
2587     /* for all pads in the opposite direction that are connected */
2588     if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) 
2589      && GST_PAD_IS_USABLE (eventpad)) {
2590       if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
2591         /* increase the refcount */
2592         gst_event_ref (event);
2593         gst_pad_push (eventpad, GST_BUFFER (event));
2594       }
2595       else {
2596         GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
2597
2598         /* we only send the event on one pad, multi-sinkpad elements 
2599          * should implement a handler */
2600         return gst_pad_send_event (peerpad, event);
2601       }
2602     }
2603   }
2604   gst_event_unref (event);
2605   return TRUE;
2606 }
2607
2608 /**
2609  * gst_pad_event_default:
2610  * @pad: a #GstPad to call the default event handler on.
2611  * @event: the #GstEvent to handle.
2612  *
2613  * Invokes the default event handler for the given pad.
2614  *
2615  * Returns: TRUE if the event was sent succesfully.
2616  */
2617 gboolean 
2618 gst_pad_event_default (GstPad *pad, GstEvent *event)
2619 {
2620   GstElement *element;
2621   
2622   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2623   g_return_val_if_fail (event, FALSE);
2624   
2625   element = GST_PAD_PARENT (pad);
2626
2627   switch (GST_EVENT_TYPE (event)) {
2628     case GST_EVENT_EOS:
2629       gst_pad_event_default_dispatch (pad, element, event);
2630       gst_element_set_eos (element);
2631       /* we have to try to schedule another element 
2632        * because this one is disabled */
2633       gst_element_yield (element);
2634       break;
2635     case GST_EVENT_DISCONTINUOUS:
2636     case GST_EVENT_FLUSH:
2637     default:
2638       return gst_pad_event_default_dispatch (pad, element, event);
2639   }
2640   return TRUE;
2641 }
2642
2643 /**
2644  * gst_pad_dispatcher:
2645  * @pad: a #GstPad to dispatch.
2646  * @dispatch: the #GstDispatcherFunction to call.
2647  * @data: gpointer user data passed to the dispatcher function.
2648  *
2649  * Invokes the given dispatcher function on all pads that are 
2650  * internally connected to the given pad. 
2651  * The GstPadDispatcherFunction should return TRUE when no further pads 
2652  * need to be processed.
2653  *
2654  * Returns: TRUE if one of the dispatcher functions returned TRUE.
2655  */
2656 gboolean
2657 gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch, 
2658                     gpointer data)
2659 {
2660   gboolean res = FALSE;
2661   GList *int_pads, *orig;
2662   
2663   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2664   g_return_val_if_fail (data, FALSE);
2665
2666   orig = int_pads = gst_pad_get_internal_connections (pad);
2667
2668   while (int_pads) {
2669     GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data);
2670     GstRealPad *int_peer = GST_RPAD_PEER (int_rpad);
2671
2672     if (int_peer && GST_PAD_IS_USABLE (int_peer)) {
2673       res = dispatch (GST_PAD_CAST (int_peer), data);
2674       if (res)
2675         break;
2676     }
2677     int_pads = g_list_next (int_pads);
2678   }
2679
2680   g_list_free (orig);
2681   
2682   return res;
2683 }
2684
2685 /**
2686  * gst_pad_send_event:
2687  * @pad: a #GstPad to send the event to.
2688  * @event: the #GstEvent to send to the pad.
2689  *
2690  * Sends the event to the pad.
2691  *
2692  * Returns: TRUE if the event was handled.
2693  */
2694 gboolean
2695 gst_pad_send_event (GstPad *pad, GstEvent *event)
2696 {
2697   gboolean success = FALSE;
2698   GstRealPad *rpad;
2699
2700   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2701   g_return_val_if_fail (event, FALSE);
2702
2703   rpad = GST_PAD_REALIZE (pad);
2704
2705   /* don't send events on usuable pads */
2706   if (GST_PAD_IS_SINK (rpad) && !GST_PAD_IS_USABLE (rpad)) {
2707     GST_DEBUG (GST_CAT_EVENT, "pad %s:%s is not usable", 
2708                GST_DEBUG_PAD_NAME (rpad));
2709     return FALSE;
2710   }
2711
2712   if (GST_EVENT_SRC (event) == NULL)
2713     GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad));
2714
2715   GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s",
2716                   GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad));
2717
2718   if (GST_RPAD_EVENTFUNC (rpad))
2719     success = GST_RPAD_EVENTFUNC (rpad) (GST_PAD_CAST (rpad), event);
2720   else {
2721     GST_DEBUG (GST_CAT_EVENT, "there's no event function for pad %s:%s", 
2722                GST_DEBUG_PAD_NAME (rpad));
2723     gst_event_unref (event);
2724   }
2725
2726   return success;
2727 }
2728
2729 typedef struct 
2730 {
2731   GstFormat      src_format;
2732   gint64         src_value;
2733   GstFormat      *dest_format;
2734   gint64         *dest_value;
2735 } GstPadConvertData;
2736
2737 static gboolean
2738 gst_pad_convert_dispatcher (GstPad *pad, GstPadConvertData *data)
2739 {
2740   return gst_pad_convert (pad, data->src_format, data->src_value, 
2741                                data->dest_format, data->dest_value);
2742 }
2743
2744 /**
2745  * gst_pad_convert_default:
2746  * @pad: a #GstPad to invoke the default converter on.
2747  * @src_format: the source #GstFormat.
2748  * @src_value: the source value.
2749  * @dest_format: a pointer to the destination #GstFormat.
2750  * @dest_value: a pointer to the destination value.
2751  *
2752  * Invokes the default converter on a pad. 
2753  * This will forward the call to the pad obtained 
2754  * using the internal connection of
2755  * the element.
2756  *
2757  * Returns: TRUE if the conversion could be performed.
2758  */
2759 gboolean
2760 gst_pad_convert_default (GstPad *pad, 
2761                          GstFormat src_format,  gint64  src_value,
2762                          GstFormat *dest_format, gint64 *dest_value)
2763 {
2764   GstPadConvertData data;
2765
2766   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2767   g_return_val_if_fail (dest_format, FALSE);
2768   g_return_val_if_fail (dest_value, FALSE);
2769
2770   data.src_format = src_format;
2771   data.src_value = src_value;
2772   data.dest_format = dest_format;
2773   data.dest_value = dest_value;
2774
2775   return gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
2776                                     gst_pad_convert_dispatcher, &data);
2777 }
2778
2779 /**
2780  * gst_pad_convert:
2781  * @pad: a #GstPad to invoke the default converter on.
2782  * @src_format: the source #GstFormat.
2783  * @src_value: the source value.
2784  * @dest_format: a pointer to the destination #GstFormat.
2785  * @dest_value: a pointer to the destination value.
2786  *
2787  * Invokes a conversion on the pad.
2788  *
2789  * Returns: TRUE if the conversion could be performed.
2790  */
2791 gboolean
2792 gst_pad_convert (GstPad *pad, 
2793                  GstFormat src_format,  gint64  src_value,
2794                  GstFormat *dest_format, gint64 *dest_value)
2795 {
2796   GstRealPad *rpad;
2797   
2798   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2799   g_return_val_if_fail (dest_format, FALSE);
2800   g_return_val_if_fail (dest_value, FALSE);
2801
2802   if (src_format == *dest_format) {
2803     *dest_value = src_value; 
2804     return TRUE;
2805   }     
2806
2807   rpad = GST_PAD_REALIZE (pad);
2808
2809   if (GST_RPAD_CONVERTFUNC (rpad)) {
2810     return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD_CAST (rpad), src_format, 
2811                                         src_value, dest_format, dest_value);
2812   }
2813
2814   return FALSE;
2815 }
2816
2817 typedef struct 
2818 {
2819   GstPadQueryType type;
2820   GstFormat      *format;
2821   gint64         *value;
2822 } GstPadQueryData;
2823
2824 static gboolean
2825 gst_pad_query_dispatcher (GstPad *pad, GstPadQueryData *data)
2826 {
2827   return gst_pad_query (pad, data->type, data->format, data->value);
2828 }
2829
2830 /**
2831  * gst_pad_query_default:
2832  * @pad: a #GstPad to invoke the default query on.
2833  * @type: the #GstPadQueryType of the query to perform.
2834  * @format: a pointer to the #GstFormat of the result.
2835  * @value: a pointer to the result.
2836  *
2837  * Invokes the default query function on a pad. 
2838  *
2839  * Returns: TRUE if the query could be performed.
2840  */
2841 gboolean
2842 gst_pad_query_default (GstPad *pad, GstPadQueryType type,
2843                        GstFormat *format,  gint64 *value)
2844 {
2845   GstPadQueryData data;
2846
2847   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2848   g_return_val_if_fail (format, FALSE);
2849   g_return_val_if_fail (value, FALSE);
2850
2851   data.type = type;
2852   data.format = format;
2853   data.value = value;
2854
2855   return gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
2856                                    gst_pad_query_dispatcher, &data);
2857 }
2858
2859 /**
2860  * gst_pad_query:
2861  * @pad: a #GstPad to invoke the default query on.
2862  * @type: the #GstPadQueryType of the query to perform.
2863  * @format: a pointer to the #GstFormat of the result.
2864  * @value: a pointer to the result.
2865  *
2866  * Queries a pad for one of the available properties.
2867  *
2868  * Returns: TRUE if the query could be performed.
2869  */
2870 gboolean
2871 gst_pad_query (GstPad *pad, GstPadQueryType type,
2872                GstFormat *format, gint64 *value) 
2873 {
2874   GstRealPad *rpad;
2875   
2876   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2877   g_return_val_if_fail (format, FALSE);
2878   g_return_val_if_fail (value, FALSE);
2879
2880   rpad = GST_PAD_REALIZE (pad);
2881
2882   g_return_val_if_fail (rpad, FALSE);
2883
2884   if (GST_RPAD_QUERYFUNC (rpad))
2885     return GST_RPAD_QUERYFUNC (rpad) (GST_PAD_CAST (pad), type, format, value);
2886
2887   return FALSE;
2888 }
2889
2890 gboolean
2891 gst_pad_handles_format (GstPad *pad, GstFormat format)
2892 {
2893   const GstFormat *formats;
2894
2895   formats = gst_pad_get_formats (pad);
2896   if (!formats)
2897     return FALSE;
2898
2899   while (*formats) {
2900     if (*formats == format)
2901       return TRUE;
2902
2903     formats++;
2904   }
2905
2906   return FALSE;
2907 }
2908
2909 static gboolean
2910 gst_pad_get_formats_dispatcher (GstPad *pad, const GstFormat **data)
2911 {
2912   *data = gst_pad_get_formats (pad);
2913
2914   return TRUE;
2915 }
2916
2917 const GstFormat*
2918 gst_pad_get_formats_default (GstPad *pad)
2919 {
2920   GstFormat *result = NULL;
2921
2922   gst_pad_dispatcher (pad, (GstPadDispatcherFunction) 
2923                       gst_pad_get_formats_dispatcher, &result);
2924
2925   return result;
2926 }
2927
2928 const GstFormat*
2929 gst_pad_get_formats (GstPad *pad)
2930 {
2931   GstRealPad *rpad;
2932   
2933   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2934
2935   rpad = GST_PAD_REALIZE (pad);
2936
2937   if (GST_RPAD_FORMATSFUNC (rpad))
2938     return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD_CAST (pad));
2939
2940   return NULL;
2941 }
2942