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