- Removed deprecated buffer flags.
[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
34 GType _gst_pad_type = 0;
35
36 /***** Start with the base GstPad class *****/
37 static void             gst_pad_class_init              (GstPadClass *klass);
38 static void             gst_pad_init                    (GstPad *pad);
39
40 #ifndef GST_DISABLE_LOADSAVE
41 static xmlNodePtr       gst_pad_save_thyself            (GstObject *object, xmlNodePtr parent);
42 #endif
43
44 static GstObject *pad_parent_class = NULL;
45
46 GType
47 gst_pad_get_type(void) 
48 {
49   if (!_gst_pad_type) {
50     static const GTypeInfo pad_info = {
51       sizeof(GstPadClass),
52       NULL,
53       NULL,
54       (GClassInitFunc)gst_pad_class_init,
55       NULL,
56       NULL,
57       sizeof(GstPad),
58       32,
59       (GInstanceInitFunc)gst_pad_init,
60       NULL
61     };
62     _gst_pad_type = g_type_register_static(GST_TYPE_OBJECT, "GstPad", &pad_info, 0);
63   }
64   return _gst_pad_type;
65 }
66
67 static void
68 gst_pad_class_init (GstPadClass *klass)
69 {
70   pad_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
71 }
72
73 static void
74 gst_pad_init (GstPad *pad)
75 {
76   pad->element_private = NULL;
77
78   pad->padtemplate = NULL;
79 }
80
81
82
83 /***** Then do the Real Pad *****/
84 /* Pad signals and args */
85 enum {
86   REAL_SET_ACTIVE,
87   REAL_CAPS_CHANGED,
88   REAL_CAPS_NEGO_FAILED,
89   REAL_CONNECTED,
90   REAL_DISCONNECTED,
91   REAL_EVENT_RECEIVED,
92   /* FILL ME */
93   REAL_LAST_SIGNAL
94 };
95
96 enum {
97   REAL_ARG_0,
98   REAL_ARG_ACTIVE,
99   /* FILL ME */
100 };
101
102 static void     gst_real_pad_class_init         (GstRealPadClass *klass);
103 static void     gst_real_pad_init               (GstRealPad *pad);
104
105 static void     gst_real_pad_set_property       (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
106 static void     gst_real_pad_get_property       (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
107
108 static void     gst_real_pad_dispose            (GObject *object);
109
110 static void     gst_pad_push_func               (GstPad *pad, GstBuffer *buf);
111
112 GType _gst_real_pad_type = 0;
113
114 static GstPad *real_pad_parent_class = NULL;
115 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
116
117 GType
118 gst_real_pad_get_type(void) {
119   if (!_gst_real_pad_type) {
120     static const GTypeInfo pad_info = {
121       sizeof(GstRealPadClass),
122       NULL,
123       NULL,
124       (GClassInitFunc)gst_real_pad_class_init,
125       NULL,
126       NULL,
127       sizeof(GstRealPad),
128       32,
129       (GInstanceInitFunc)gst_real_pad_init,
130       NULL
131     };
132     _gst_real_pad_type = g_type_register_static(GST_TYPE_PAD, "GstRealPad", &pad_info, 0);
133   }
134   return _gst_real_pad_type;
135 }
136
137 static void
138 gst_real_pad_class_init (GstRealPadClass *klass)
139 {
140   GObjectClass *gobject_class;
141   GstObjectClass *gstobject_class;
142
143   gobject_class = (GObjectClass*) klass;
144   gstobject_class = (GstObjectClass*) klass;
145
146   real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
147
148   gobject_class->dispose  = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
149   gobject_class->set_property  = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
150   gobject_class->get_property  = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
151
152   gst_real_pad_signals[REAL_SET_ACTIVE] =
153     g_signal_new ("set_active", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
154                     G_STRUCT_OFFSET (GstRealPadClass, set_active), NULL, NULL,
155                     gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1,
156                     G_TYPE_BOOLEAN);
157   gst_real_pad_signals[REAL_CAPS_CHANGED] =
158     g_signal_new ("caps_changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
159                     G_STRUCT_OFFSET (GstRealPadClass, caps_changed), NULL, NULL,
160                     gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
161                     G_TYPE_POINTER);
162   gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
163     g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
164                     G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
165                     gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
166                     G_TYPE_POINTER);
167   gst_real_pad_signals[REAL_CONNECTED] =
168     g_signal_new ("connected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
169                     G_STRUCT_OFFSET (GstRealPadClass, connected), NULL, NULL,
170                     gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
171                     G_TYPE_POINTER);
172   gst_real_pad_signals[REAL_DISCONNECTED] =
173     g_signal_new ("disconnected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
174                     G_STRUCT_OFFSET (GstRealPadClass, disconnected), NULL, NULL,
175                     gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
176                     G_TYPE_POINTER);
177   gst_real_pad_signals[REAL_EVENT_RECEIVED] =
178     g_signal_new ("event_received", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
179                     G_STRUCT_OFFSET (GstRealPadClass, event_received), NULL, NULL,
180                     gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
181                     G_TYPE_POINTER);
182
183 /*  gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
184 /*                           GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
185   g_object_class_install_property (G_OBJECT_CLASS(klass), REAL_ARG_ACTIVE,
186     g_param_spec_boolean("active","Active","Whether the pad is active.",
187                          TRUE,G_PARAM_READWRITE));
188
189 #ifndef GST_DISABLE_LOADSAVE
190   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR(gst_pad_save_thyself);
191 #endif
192   gstobject_class->path_string_separator = ".";
193 }
194
195 static void
196 gst_real_pad_init (GstRealPad *pad)
197 {
198   pad->direction = GST_PAD_UNKNOWN;
199   pad->peer = NULL;
200
201   pad->sched = NULL;
202   pad->sched_private = NULL;
203
204   pad->chainfunc = NULL;
205   pad->getfunc = NULL;
206   pad->getregionfunc = NULL;
207
208   pad->chainhandler = GST_DEBUG_FUNCPTR(gst_pad_push_func);
209   pad->gethandler = NULL;
210   pad->pullregionfunc = NULL;
211
212   pad->bufferpoolfunc = NULL;
213   pad->ghostpads = NULL;
214   pad->caps = NULL;
215 }
216
217 static void
218 gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
219 {
220   g_return_if_fail(GST_IS_PAD(object));
221
222   switch (prop_id) {
223     case REAL_ARG_ACTIVE:
224       if (g_value_get_boolean(value)) {
225         GST_DEBUG(GST_CAT_PADS,"activating pad %s:%s\n",GST_DEBUG_PAD_NAME(object));
226         GST_FLAG_UNSET(object,GST_PAD_DISABLED);
227       } else {
228         GST_DEBUG(GST_CAT_PADS,"de-activating pad %s:%s\n",GST_DEBUG_PAD_NAME(object));
229         GST_FLAG_SET(object,GST_PAD_DISABLED);
230       }
231       g_signal_emit(G_OBJECT(object), gst_real_pad_signals[REAL_SET_ACTIVE], 0,
232                       ! GST_FLAG_IS_SET(object,GST_PAD_DISABLED));
233       break;
234     default:
235       break;
236   }
237 }
238
239 static void
240 gst_real_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
241 {
242   /* it's not null if we got it, but it might not be ours */
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     default:
250       break;
251   }
252 }
253
254
255 /**
256  * gst_pad_new:
257  * @name: name of new pad
258  * @direction: either GST_PAD_SRC or GST_PAD_SINK
259  *
260  * Create a new pad with given name.
261  *
262  * Returns: new pad
263  */
264 GstPad*
265 gst_pad_new (gchar *name,
266              GstPadDirection direction)
267 {
268   GstRealPad *pad;
269
270   g_return_val_if_fail (name != NULL, NULL);
271   g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
272
273   pad = g_object_new (gst_real_pad_get_type (), NULL);
274   gst_object_set_name (GST_OBJECT (pad), name);
275   GST_RPAD_DIRECTION(pad) = direction;
276
277   return GST_PAD(pad);
278 }
279
280 /**
281  * gst_pad_new_from_template:
282  * @templ: the pad template to use
283  * @name: the name of the element
284  *
285  * Create a new pad with given name from the given template.
286  *
287  * Returns: new pad
288  */
289 GstPad*
290 gst_pad_new_from_template (GstPadTemplate *templ,
291                            gchar *name)
292 {
293   GstPad *pad;
294
295   g_return_val_if_fail (name != NULL, NULL);
296   g_return_val_if_fail (templ != NULL, NULL);
297
298   pad = gst_pad_new (name, templ->direction);
299   
300   gst_object_ref (GST_OBJECT (templ));
301   GST_PAD_PADTEMPLATE(pad) = templ;
302   
303   return pad;
304 }
305
306 /**
307  * gst_pad_get_direction:
308  * @pad: the Pad to get the direction from
309  *
310  * Get the direction of the pad.
311  *
312  * Returns: the direction of the pad
313  */
314 GstPadDirection
315 gst_pad_get_direction (GstPad *pad)
316 {
317   g_return_val_if_fail (pad != NULL, GST_PAD_UNKNOWN);
318   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
319
320   return GST_PAD_DIRECTION(pad);
321 }
322
323 /**
324  * gst_pad_set_name:
325  * @pad: the pad to set the name of
326  * @name: the name of the pad
327  *
328  * Set the name of a pad.
329  */
330 void
331 gst_pad_set_name (GstPad *pad,
332                   const gchar *name)
333 {
334   g_return_if_fail (pad != NULL);
335   g_return_if_fail (GST_IS_PAD (pad));
336
337   gst_object_set_name (GST_OBJECT (pad), name);
338 }
339
340 /**
341  * gst_pad_get_name:
342  * @pad: the pad to get the name of
343  *
344  * Get the name of a pad.
345  *
346  * Returns: the name of the pad, don't free.
347  */
348 const gchar*
349 gst_pad_get_name (GstPad *pad)
350 {
351   g_return_val_if_fail (pad != NULL, NULL);
352   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
353
354   return GST_OBJECT_NAME (pad);
355 }
356
357 /**
358  * gst_pad_set_chain_function:
359  * @pad: the pad to set the chain function for
360  * @chain: the chain function
361  *
362  * Set the given chain function for the pad.
363  */
364 void gst_pad_set_chain_function (GstPad *pad,
365                                  GstPadChainFunction chain)
366 {
367   g_return_if_fail (pad != NULL);
368   g_return_if_fail (GST_IS_REAL_PAD (pad));
369
370   GST_RPAD_CHAINFUNC(pad) = chain;
371   GST_DEBUG (GST_CAT_PADS,"chainfunc for %s:%s set to %s\n",
372              GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(chain));
373 }
374
375 /**
376  * gst_pad_set_get_function:
377  * @pad: the pad to set the get function for
378  * @get: the get function
379  *
380  * Set the given get function for the pad.
381  */
382 void
383 gst_pad_set_get_function (GstPad *pad,
384                           GstPadGetFunction get)
385 {
386   g_return_if_fail (pad != NULL);
387   g_return_if_fail (GST_IS_REAL_PAD (pad));
388
389   GST_RPAD_GETFUNC(pad) = get;
390   GST_DEBUG (GST_CAT_PADS,"getfunc for %s:%s  set to %s\n",
391              GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(get));
392 }
393
394 /**
395  * gst_pad_set_event_function:
396  * @pad: the pad to set the event handler for
397  * @event: the event handler
398  *
399  * Set the given event handler for the pad.
400  */
401 void
402 gst_pad_set_event_function (GstPad *pad,
403                             GstPadEventFunction event)
404 {
405   g_return_if_fail (pad != NULL);
406   g_return_if_fail (GST_IS_REAL_PAD (pad));
407
408   GST_RPAD_EVENTFUNC(pad) = event;
409   GST_DEBUG (GST_CAT_PADS,"eventfunc for %s:%s  set to %s\n",
410              GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(event));
411 }
412
413 /**
414  * gst_pad_set_getregion_function:
415  * @pad: the pad to set the getregion function for
416  * @getregion: the getregion function
417  *
418  * Set the given getregion function for the pad.
419  */
420 void
421 gst_pad_set_getregion_function (GstPad *pad,
422                                 GstPadGetRegionFunction getregion)
423 {
424   g_return_if_fail (pad != NULL);
425   g_return_if_fail (GST_IS_REAL_PAD (pad));
426
427   GST_RPAD_GETREGIONFUNC(pad) = getregion;
428   GST_DEBUG (GST_CAT_PADS,"getregionfunc for %s:%s set to %s\n",
429              GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(getregion));
430 }
431
432 /**
433  * gst_pad_set_negotiate_function:
434  * @pad: the pad to set the negotiate function for
435  * @nego: the negotiate function
436  *
437  * Set the given negotiate function for the pad.
438  */
439 void
440 gst_pad_set_negotiate_function (GstPad *pad,
441                                 GstPadNegotiateFunction nego)
442 {
443   g_return_if_fail (pad != NULL);
444   g_return_if_fail (GST_IS_REAL_PAD (pad));
445
446   GST_RPAD_NEGOTIATEFUNC(pad) = nego;
447   GST_DEBUG (GST_CAT_PADS,"negotiatefunc for %s:%s set to %s\n",
448              GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(nego));
449 }
450
451 /**
452  * gst_pad_set_newcaps_function:
453  * @pad: the pad to set the newcaps function for
454  * @newcaps: the newcaps function
455  *
456  * Set the given newcaps function for the pad.
457  */
458 void
459 gst_pad_set_newcaps_function (GstPad *pad,
460                               GstPadNewCapsFunction newcaps)
461 {
462   g_return_if_fail (pad != NULL);
463   g_return_if_fail (GST_IS_REAL_PAD (pad));
464
465   GST_RPAD_NEWCAPSFUNC (pad) = newcaps;
466   GST_DEBUG (GST_CAT_PADS,"newcapsfunc for %s:%s set to %s\n",
467              GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(newcaps));
468 }
469
470 /**
471  * gst_pad_set_bufferpool_function:
472  * @pad: the pad to set the bufferpool function for
473  * @bufpool: the bufferpool function
474  *
475  * Set the given bufferpool function for the pad.
476  */
477 void
478 gst_pad_set_bufferpool_function (GstPad *pad,
479                                  GstPadBufferPoolFunction bufpool)
480 {
481   g_return_if_fail (pad != NULL);
482   g_return_if_fail (GST_IS_REAL_PAD (pad));
483
484   GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool;
485   GST_DEBUG (GST_CAT_PADS,"bufferpoolfunc for %s:%s set to %s\n",
486              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME(bufpool));
487 }
488
489 static void
490 gst_pad_push_func(GstPad *pad, GstBuffer *buf)
491 {
492   if (GST_RPAD_CHAINFUNC(GST_RPAD_PEER(pad)) != NULL) {
493     GST_DEBUG (GST_CAT_DATAFLOW,"calling chain function %s\n",
494                GST_DEBUG_FUNCPTR_NAME(GST_RPAD_CHAINFUNC(GST_RPAD_PEER(pad))));
495     (GST_RPAD_CHAINFUNC(GST_RPAD_PEER(pad)))(pad,buf);
496   } else {
497     GST_DEBUG (GST_CAT_DATAFLOW,"default pad_push handler in place, no chain function\n");
498     g_warning ("(internal error) default pad_push in place for pad %s:%s but it has no chain function", 
499                     GST_DEBUG_PAD_NAME (pad));
500   }
501 }
502
503
504 /**
505  * gst_pad_disconnect:
506  * @srcpad: the source pad to disconnect
507  * @sinkpad: the sink pad to disconnect
508  *
509  * Disconnects the source pad from the sink pad.
510  */
511 void
512 gst_pad_disconnect (GstPad *srcpad,
513                     GstPad *sinkpad)
514 {
515   GstRealPad *realsrc, *realsink;
516
517   /* generic checks */
518   g_return_if_fail (srcpad != NULL);
519   g_return_if_fail (GST_IS_PAD (srcpad));
520   g_return_if_fail (sinkpad != NULL);
521   g_return_if_fail (GST_IS_PAD (sinkpad));
522
523   GST_INFO (GST_CAT_ELEMENT_PADS, "disconnecting %s:%s(%p) and %s:%s(%p)",
524             GST_DEBUG_PAD_NAME(srcpad), srcpad, GST_DEBUG_PAD_NAME(sinkpad), sinkpad);
525
526   /* now we need to deal with the real/ghost stuff */
527   realsrc = GST_PAD_REALIZE(srcpad);
528   realsink = GST_PAD_REALIZE(sinkpad);
529
530   g_return_if_fail (GST_RPAD_PEER(realsrc) != NULL);
531   g_return_if_fail (GST_RPAD_PEER(realsink) != NULL);
532
533   if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) &&
534       (GST_RPAD_DIRECTION(realsink) == GST_PAD_SRC)) {
535     GstRealPad *temppad;
536
537     temppad = realsrc;
538     realsrc = realsink;
539     realsink = temppad;
540   }
541   g_return_if_fail ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
542                     (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK));
543
544   /* first clear peers */
545   GST_RPAD_PEER(realsrc) = NULL;
546   GST_RPAD_PEER(realsink) = NULL;
547
548   /* now tell the scheduler */
549   if (GST_PAD_PARENT (realsrc)->sched)
550     gst_scheduler_pad_disconnect (GST_PAD_PARENT (realsrc)->sched, (GstPad *)realsrc, (GstPad *)realsink);
551   else if (GST_PAD_PARENT (realsink)->sched)
552     gst_scheduler_pad_disconnect (GST_PAD_PARENT (realsink)->sched, (GstPad *)realsrc, (GstPad *)realsink);
553
554   /* fire off a signal to each of the pads telling them that they've been disconnected */
555   g_signal_emit(G_OBJECT(realsrc), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsink);
556   g_signal_emit(G_OBJECT(realsink), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsrc);
557
558   GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
559             GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
560 }
561
562 /**
563  * gst_pad_connect:
564  * @srcpad: the source pad to connect
565  * @sinkpad: the sink pad to connect
566  *
567  * Connects the source pad to the sink pad.
568  *
569  * You shouldn't use this API in a real application because the
570  * failure mode dumps diagnostics to stderr.  A professional
571  * application should never fail, or use gst_pad_try_connect and
572  * check the return code.
573  */
574 void
575 gst_pad_connect (GstPad *srcpad,
576                  GstPad *sinkpad)
577 {
578   if (!gst_pad_try_connect (srcpad, sinkpad)) {
579     g_warning ("couldn't connect %s:%s and %s:%s",
580                 GST_DEBUG_PAD_NAME (srcpad),
581                 GST_DEBUG_PAD_NAME (sinkpad));
582   }
583 }
584
585 /**
586  * gst_pad_try_connect:
587  * @srcpad: the source pad to connect
588  * @sinkpad: the sink pad to connect
589  *
590  * Connects the source pad to the sink pad.
591  *
592  * Returns: TRUE if the pad could be connected
593  */
594 gboolean
595 gst_pad_try_connect (GstPad *srcpad,
596                      GstPad *sinkpad)
597 {
598   GstRealPad *realsrc, *realsink;
599   gboolean negotiated = FALSE;
600
601   /* generic checks */
602   g_return_val_if_fail(srcpad != NULL, FALSE);
603   g_return_val_if_fail(GST_IS_PAD(srcpad), FALSE);
604   g_return_val_if_fail(sinkpad != NULL, FALSE);
605   g_return_val_if_fail(GST_IS_PAD(sinkpad), FALSE);
606
607   GST_INFO (GST_CAT_PADS, "connecting %s:%s and %s:%s",
608             GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
609
610   /* now we need to deal with the real/ghost stuff */
611   realsrc = GST_PAD_REALIZE(srcpad);
612   realsink = GST_PAD_REALIZE(sinkpad);
613
614   if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad))
615     GST_INFO (GST_CAT_PADS, "*actually* connecting %s:%s and %s:%s",
616               GST_DEBUG_PAD_NAME(realsrc), GST_DEBUG_PAD_NAME(realsink));
617
618   g_return_val_if_fail(GST_RPAD_PEER(realsrc) == NULL, FALSE);
619   g_return_val_if_fail(GST_RPAD_PEER(realsink) == NULL, FALSE);
620
621   /* check for reversed directions and swap if necessary */
622   if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) &&
623       (GST_RPAD_DIRECTION(realsink) == GST_PAD_SRC)) {
624     GstRealPad *temppad;
625
626     temppad = realsrc;
627     realsrc = realsink;
628     realsink = temppad;
629   }
630   g_return_val_if_fail((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
631                        (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK), FALSE);
632
633
634   /* first set peers */
635   GST_RPAD_PEER(realsrc) = realsink;
636   GST_RPAD_PEER(realsink) = realsrc;
637
638   if (GST_PAD_CAPS (srcpad)) {
639     GST_DEBUG(GST_CAT_PADS, "renegotiation from srcpad\n");
640     negotiated = gst_pad_renegotiate (srcpad);
641   }
642   else if (GST_PAD_CAPS (sinkpad)) {
643     GST_DEBUG(GST_CAT_PADS, "renegotiation from sinkpad\n");
644     negotiated = gst_pad_renegotiate (sinkpad);
645   }
646   else {
647     GST_DEBUG(GST_CAT_PADS, "not renegotiating connection\n");
648     negotiated = TRUE;
649   }
650
651   if (!negotiated) {
652     GST_INFO(GST_CAT_PADS, "pads %s:%s and %s:%s failed to negotiate, disconnecting",
653              GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
654     gst_pad_disconnect (GST_PAD (realsrc), GST_PAD (realsink));
655     return FALSE;
656   }
657
658   /* fire off a signal to each of the pads telling them that they've been connected */
659   g_signal_emit(G_OBJECT(realsrc), gst_real_pad_signals[REAL_CONNECTED], 0, realsink);
660   g_signal_emit(G_OBJECT(realsink), gst_real_pad_signals[REAL_CONNECTED], 0, realsrc);
661
662   /* now tell the scheduler(s) */
663   if (realsrc->sched)
664     gst_scheduler_pad_connect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
665   else if (realsink->sched)
666     gst_scheduler_pad_connect (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
667
668   GST_INFO (GST_CAT_PADS, "connected %s:%s and %s:%s",
669             GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
670   return TRUE;
671 }
672
673 /**
674  * gst_pad_set_parent:
675  * @pad: the pad to set the parent
676  * @parent: the object to set the parent to
677  *
678  * Sets the parent object of a pad.
679  */
680 void
681 gst_pad_set_parent (GstPad *pad,
682                     GstObject *parent)
683 {
684   g_return_if_fail (pad != NULL);
685   g_return_if_fail (GST_IS_PAD (pad));
686   g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
687   g_return_if_fail (parent != NULL);
688   g_return_if_fail (GST_IS_OBJECT (parent));
689   g_return_if_fail ((gpointer)pad != (gpointer)parent);
690
691   gst_object_set_parent (GST_OBJECT (pad), parent);
692 }
693
694 /**
695  * gst_pad_get_parent:
696  * @pad: the pad to get the parent from
697  *
698  * Get the parent object of this pad.
699  *
700  * Returns: the parent object
701  */
702 GstElement*
703 gst_pad_get_parent (GstPad *pad)
704 {
705   g_return_val_if_fail (pad != NULL, NULL);
706   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
707
708   return GST_PAD_PARENT (pad);
709 }
710
711 /**
712  * gst_pad_get_padtemplate:
713  * @pad: the pad to get the padtemplate from
714  *
715  * Get the padtemplate object of this pad.
716  *
717  * Returns: the padtemplate object
718  */
719 GstPadTemplate*
720 gst_pad_get_padtemplate (GstPad *pad)
721 {
722   g_return_val_if_fail (pad != NULL, NULL);
723   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
724
725   return GST_PAD_PADTEMPLATE (pad); 
726 }
727
728
729 /**
730  * gst_pad_set_sched:
731  * @pad: the pad to set the scheduler for
732  * @sched: The scheduler to set
733  *
734  * Set the sceduler for the pad
735  */
736 void
737 gst_pad_set_sched (GstPad *pad, GstScheduler *sched)
738 {
739   g_return_if_fail (pad != NULL);
740   g_return_if_fail (GST_IS_PAD (pad));
741  
742   GST_RPAD_SCHED(pad) = sched;
743 }
744  
745 /**
746  * gst_pad_get_sched:
747  * @pad: the pad to get the scheduler from
748  *
749  * Get the scheduler of the pad
750  *
751  * Returns: the scheduler of the pad.
752  */
753 GstScheduler*
754 gst_pad_get_sched (GstPad *pad)
755 {
756   g_return_val_if_fail (pad != NULL, NULL);
757   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
758  
759   return GST_RPAD_SCHED(pad);
760 }
761
762 /**
763  * gst_pad_get_real_parent:
764  * @pad: the pad to get the parent from
765  *
766  * Get the real parent object of this pad. If the pad
767  * is a ghostpad, the actual owner of the real pad is
768  * returned, as opposed to the gst_pad_get_parent().
769  *
770  * Returns: the parent object
771  */
772 GstElement*
773 gst_pad_get_real_parent (GstPad *pad)
774 {
775   g_return_val_if_fail (pad != NULL, NULL);
776   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
777
778   return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
779 }
780
781 /**
782  * gst_pad_add_ghost_pad:
783  * @pad: the pad to set the ghost parent
784  * @ghostpad: the ghost pad to add
785  *
786  * Add a ghost pad to a pad.
787  */
788 void
789 gst_pad_add_ghost_pad (GstPad *pad,
790                        GstPad *ghostpad)
791 {
792   GstRealPad *realpad;
793
794   g_return_if_fail (pad != NULL);
795   g_return_if_fail (GST_IS_PAD (pad));
796   g_return_if_fail (ghostpad != NULL);
797   g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
798
799   realpad = GST_PAD_REALIZE(pad);
800
801   realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
802 }
803
804
805 /**
806  * gst_pad_remove_ghost_pad:
807  * @pad: the pad to remove the ghost parent
808  * @ghostpad: the ghost pad to remove from the pad
809  *
810  * Remove a ghost pad from a pad.
811  */
812 void
813 gst_pad_remove_ghost_pad (GstPad *pad,
814                           GstPad *ghostpad)
815 {
816   GstRealPad *realpad;
817
818   g_return_if_fail (pad != NULL);
819   g_return_if_fail (GST_IS_PAD (pad));
820   g_return_if_fail (ghostpad != NULL);
821   g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
822
823   realpad = GST_PAD_REALIZE (pad);
824
825   realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
826 }
827
828 /**
829  * gst_pad_get_ghost_pad_list:
830  * @pad: the pad to get the ghost parents from
831  *
832  * Get the ghost parents of this pad.
833  *
834  * Returns: a GList of ghost pads
835  */
836 GList*
837 gst_pad_get_ghost_pad_list (GstPad *pad)
838 {
839   g_return_val_if_fail (pad != NULL, NULL);
840   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
841
842   return GST_PAD_REALIZE(pad)->ghostpads;
843 }
844
845 /**
846  * gst_pad_set_caps:
847  * @pad: the pad to set the caps to
848  * @caps: the capabilities to attach to this pad
849  *
850  * Set the capabilities of this pad.
851  *
852  * Returns: a boolean indicating the caps could be set on the pad
853  */
854 gboolean
855 gst_pad_set_caps (GstPad *pad,
856                   GstCaps *caps)
857 {
858   GstCaps *oldcaps;
859
860   g_return_val_if_fail (pad != NULL, FALSE);
861   g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);          /* NOTE this restriction */
862
863   GST_INFO (GST_CAT_CAPS, "setting caps %p on pad %s:%s",
864             caps, GST_DEBUG_PAD_NAME(pad));
865
866   if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) {
867     g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n",
868                     GST_DEBUG_PAD_NAME (pad));
869     return FALSE;
870   }
871   
872   oldcaps = GST_PAD_CAPS (pad);
873
874   if (caps)
875     gst_caps_ref (caps);
876   GST_PAD_CAPS(pad) = caps;
877
878   if (oldcaps)
879     gst_caps_unref (oldcaps);
880
881   return gst_pad_renegotiate (pad);
882 }
883
884 /**
885  * gst_pad_get_caps:
886  * @pad: the pad to get the capabilities from
887  *
888  * Get the capabilities of this pad.
889  *
890  * Returns: the capabilities of this pad
891  */
892 GstCaps*
893 gst_pad_get_caps (GstPad *pad)
894 {
895   g_return_val_if_fail (pad != NULL, NULL);
896   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
897
898   if (GST_PAD_CAPS (pad))
899     return GST_PAD_CAPS (pad);
900   else if (GST_PAD_PADTEMPLATE (pad))
901     return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
902
903   return NULL;
904 }
905
906 /**
907  * gst_pad_get_padtemplate_caps:
908  * @pad: the pad to get the capabilities from
909  *
910  * Get the capabilities of this pad.
911  *
912  * Returns: a list of the capabilities of this pad
913  */
914 GstCaps*
915 gst_pad_get_padtemplate_caps (GstPad *pad)
916 {
917   g_return_val_if_fail (pad != NULL, NULL);
918   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
919
920   if (GST_PAD_PADTEMPLATE (pad))
921     return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
922
923   return NULL;
924 }
925
926
927 /**
928  * gst_padtemplate_get_caps_by_name:
929  * @templ: the padtemplate to get the capabilities from
930  * @name: the name of the capability to get
931  *
932  * Get the capability with the given name from this padtemplate.
933  *
934  * Returns: a capability or NULL if not found
935  */
936 GstCaps*
937 gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
938 {
939   GstCaps *caps;
940
941   g_return_val_if_fail (templ != NULL, NULL);
942
943   caps = GST_PADTEMPLATE_CAPS (templ);
944   if (!caps) 
945     return NULL;
946
947   return gst_caps_get_by_name (caps, name);
948 }
949
950 /**
951  * gst_pad_check_compatibility:
952  * @srcpad: the srcpad to check
953  * @sinkpad: the sinkpad to check against
954  *
955  * Check if two pads have compatible capabilities.
956  *
957  * Returns: TRUE if they are compatible or the capabilities
958  * could not be checked
959  */
960 gboolean
961 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
962 {
963   g_return_val_if_fail (srcpad != NULL, FALSE);
964   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
965   g_return_val_if_fail (sinkpad != NULL, FALSE);
966   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
967
968   if (GST_PAD_CAPS(srcpad) && GST_PAD_CAPS(sinkpad)) {
969     if (!gst_caps_check_compatibility (GST_PAD_CAPS(srcpad), GST_PAD_CAPS(sinkpad))) {
970       return FALSE;
971     }
972     else {
973       return TRUE;
974     }
975   }
976   else {
977     GST_DEBUG (GST_CAT_PADS,"could not check capabilities of pads (%s:%s) and (%s:%s) %p %p\n",
978                     GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad), 
979                     GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
980     return TRUE;
981   }
982 }
983
984 /**
985  * gst_pad_get_peer:
986  * @pad: the pad to get the peer from
987  *
988  * Get the peer pad of this pad.
989  *
990  * Returns: the peer pad
991  */
992 GstPad*
993 gst_pad_get_peer (GstPad *pad)
994 {
995   g_return_val_if_fail (pad != NULL, NULL);
996   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
997
998   return GST_PAD(GST_PAD_PEER(pad));
999 }
1000
1001 /**
1002  * gst_pad_get_bufferpool:
1003  * @pad: the pad to get the bufferpool from
1004  *
1005  * Get the bufferpool of the peer pad of the given
1006  * pad
1007  *
1008  * Returns: The GstBufferPool or NULL.
1009  */
1010 GstBufferPool*          
1011 gst_pad_get_bufferpool (GstPad *pad)
1012 {
1013   GstRealPad *peer;
1014
1015   g_return_val_if_fail (pad != NULL, NULL);
1016   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1017    
1018   peer = GST_RPAD_PEER(pad);
1019
1020   g_return_val_if_fail (peer != NULL, NULL);
1021
1022   GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1023
1024   if (peer->bufferpoolfunc) {
1025     GST_DEBUG (GST_CAT_PADS,"calling bufferpoolfunc &%s (@%p) of peer pad %s:%s\n",
1026       GST_DEBUG_FUNCPTR_NAME(peer->bufferpoolfunc),&peer->bufferpoolfunc,GST_DEBUG_PAD_NAME(((GstPad*)peer)));
1027     return (peer->bufferpoolfunc)(((GstPad*)peer));
1028   } else {
1029     GST_DEBUG (GST_CAT_PADS,"no bufferpoolfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(((GstPad*)peer)),&peer->bufferpoolfunc);
1030     return NULL;
1031   }
1032 }
1033
1034 static void
1035 gst_real_pad_dispose (GObject *object)
1036 {
1037   GstPad *pad = GST_PAD (object);
1038   
1039   GST_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s\n", GST_DEBUG_PAD_NAME(pad));
1040
1041   if (GST_PAD (pad)->padtemplate){
1042     GST_DEBUG (GST_CAT_REFCOUNTING, "unreffing padtemplate'%s'\n",GST_OBJECT_NAME(GST_OBJECT (GST_PAD (pad)->padtemplate)));
1043     gst_object_unref (GST_OBJECT (GST_PAD (pad)->padtemplate));
1044   }
1045   
1046   if (GST_PAD_PEER (pad)){
1047     GST_DEBUG (GST_CAT_REFCOUNTING, "disconnecting pad '%s'\n",GST_OBJECT_NAME(GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
1048     gst_pad_disconnect (pad, GST_PAD (GST_PAD_PEER (pad)));
1049   }
1050   
1051   /* FIXME we should destroy the ghostpads, because they are nothing without the real pad  */
1052   if (GST_REAL_PAD (pad)->ghostpads) {
1053     GList *orig, *ghostpads;
1054
1055     orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
1056
1057     while (ghostpads) {
1058       GstPad *ghostpad = GST_PAD (ghostpads->data);
1059
1060       if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))){
1061         GST_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'\n", GST_OBJECT_NAME(GST_OBJECT_PARENT (ghostpad)));
1062         gst_element_remove_ghost_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), GST_PAD (ghostpad));
1063       }
1064       ghostpads = g_list_next (ghostpads);
1065     }
1066     g_list_free (orig);
1067     g_list_free (GST_REAL_PAD(pad)->ghostpads);
1068   }
1069
1070   if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))){
1071     GST_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'\n",GST_OBJECT_NAME(GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
1072     gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
1073   }
1074   
1075   G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
1076 }
1077
1078
1079 #ifndef GST_DISABLE_LOADSAVE
1080 /**
1081  * gst_pad_load_and_connect:
1082  * @self: the XML node to read the description from
1083  * @parent: the element that has the pad
1084  *
1085  * Read the pad definition from the XML node and connect the given pad
1086  * in element to a pad of an element up in the hierarchy.
1087  */
1088 void
1089 gst_pad_load_and_connect (xmlNodePtr self,
1090                           GstObject *parent)
1091 {
1092   xmlNodePtr field = self->xmlChildrenNode;
1093   GstPad *pad = NULL, *targetpad;
1094   guchar *peer = NULL;
1095   gchar **split;
1096   GstElement *target;
1097   GstObject *grandparent;
1098
1099   while (field) {
1100     if (!strcmp (field->name, "name")) {
1101       pad = gst_element_get_pad (GST_ELEMENT (parent), xmlNodeGetContent (field));
1102     }
1103     else if (!strcmp(field->name, "peer")) {
1104       peer = xmlNodeGetContent (field);
1105     }
1106     field = field->next;
1107   }
1108   g_return_if_fail (pad != NULL);
1109
1110   if (peer == NULL) return;
1111
1112   split = g_strsplit (peer, ".", 2);
1113
1114   g_return_if_fail (split[0] != NULL);
1115   g_return_if_fail (split[1] != NULL);
1116
1117   grandparent = gst_object_get_parent (parent);
1118
1119   if (grandparent && GST_IS_BIN (grandparent)) {
1120     target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
1121   }
1122   else
1123     goto cleanup;
1124
1125   if (target == NULL) goto cleanup;
1126
1127   targetpad = gst_element_get_pad (target, split[1]);
1128
1129   if (targetpad == NULL) goto cleanup;
1130
1131   gst_pad_connect (pad, targetpad);
1132
1133 cleanup:
1134   g_strfreev (split);
1135 }
1136 #endif /* GST_DISABLE_LOADSAVE */
1137
1138 static gboolean
1139 gst_pad_renegotiate_func (GstPad *pad, gpointer *data1, GstPad *peerpad, gpointer *data2, GstCaps **newcaps)
1140 {
1141   GstRealPad *currentpad, *otherpad;
1142   gpointer *currentdata, *otherdata;
1143   GstPadNegotiateReturn result;
1144   gint counter = 0;
1145   
1146   g_return_val_if_fail (pad != NULL, FALSE);
1147
1148   currentpad = GST_PAD_REALIZE (pad);
1149   otherpad = GST_REAL_PAD (peerpad);
1150   currentdata = data1;
1151   otherdata = data2;
1152
1153   GST_DEBUG (GST_CAT_NEGOTIATION, "negotiating pad %s:%s and %s:%s data:%p\n",
1154             GST_DEBUG_PAD_NAME(currentpad), GST_DEBUG_PAD_NAME(otherpad), currentdata);
1155
1156   do {
1157     gboolean matchtempl;
1158     
1159     if (!*newcaps) {
1160       if (otherpad->negotiatefunc) {
1161         GstRealPad *temp;
1162         gpointer *tempdata;
1163
1164         GST_DEBUG (GST_CAT_NEGOTIATION, "requesting other caps from pad %s:%s data:%p\n",
1165                         GST_DEBUG_PAD_NAME(otherpad), otherdata);
1166         otherpad->negotiatefunc (GST_PAD (otherpad), newcaps, otherdata);
1167
1168         temp = otherpad;
1169         otherpad = currentpad;
1170         currentpad = temp;
1171
1172         tempdata = otherdata;
1173         otherdata = currentdata;
1174         currentdata = tempdata;
1175       }
1176     }
1177
1178     GST_DEBUG (GST_CAT_NEGOTIATION, "checking compatibility with pad %s:%s\n",
1179                      GST_DEBUG_PAD_NAME(otherpad));
1180     matchtempl = gst_caps_check_compatibility (*newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad)));
1181
1182     GST_DEBUG (GST_CAT_NEGOTIATION, "caps compatibility check %s\n", (matchtempl?"ok":"fail"));
1183
1184     if (matchtempl) {
1185       GST_DEBUG (GST_CAT_NEGOTIATION, "checking if other pad %s:%s can negotiate data:%p\n",
1186                      GST_DEBUG_PAD_NAME(otherpad), otherdata);
1187       if (otherpad->negotiatefunc) {
1188         GstRealPad *temp;
1189         gpointer *tempdata;
1190
1191         GST_DEBUG (GST_CAT_NEGOTIATION, "switching pad for next phase\n");
1192
1193         temp = currentpad;
1194         currentpad = otherpad;
1195         otherpad = temp;
1196
1197         tempdata = otherdata;
1198         otherdata = currentdata;
1199         currentdata = tempdata;
1200       }
1201       else if (gst_caps_check_compatibility (*newcaps, GST_PAD_CAPS (otherpad))) {
1202         GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n");
1203         return TRUE;
1204       }
1205       else {
1206         *newcaps = GST_PAD_CAPS (otherpad);
1207         if (*newcaps) gst_caps_ref(*newcaps);
1208       }
1209     }
1210     else {
1211       *newcaps = GST_PAD_CAPS (otherpad);
1212       if (*newcaps) gst_caps_ref(*newcaps);
1213     }
1214
1215     counter++;
1216
1217     if (currentpad->negotiatefunc) {
1218       GST_DEBUG (GST_CAT_NEGOTIATION, "calling negotiate function on pad %s:%s data: %p\n",
1219                       GST_DEBUG_PAD_NAME (currentpad), currentdata);
1220       result = currentpad->negotiatefunc (GST_PAD (currentpad), newcaps, currentdata);
1221
1222       switch (result) {
1223         case GST_PAD_NEGOTIATE_FAIL:
1224           GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed\n");
1225           return FALSE;
1226         case GST_PAD_NEGOTIATE_AGREE:
1227           GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n");
1228           return TRUE;
1229         case GST_PAD_NEGOTIATE_TRY:
1230           GST_DEBUG (GST_CAT_NEGOTIATION, "try another option\n");
1231           break;
1232         default:
1233           GST_DEBUG (GST_CAT_NEGOTIATION, "invalid return\n");
1234           break;
1235       }
1236     }
1237     else {
1238       GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, no more options\n");
1239       return FALSE;
1240     }
1241       
1242   } while (counter < 100);
1243
1244   g_warning ("negotiation between (%s:%s) and (%s:%s) failed: too many attempts (%d)\n",
1245             GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad), counter);
1246
1247   GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, too many attempts\n");
1248   
1249   return FALSE;
1250 }
1251
1252 /**
1253  * gst_pad_renegotiate:
1254  * @pad: the pad to perform the negotiation on
1255  *
1256  * Perform the negotiation process with the peer pad.
1257  *
1258  * Returns: TRUE if the negotiation process succeded
1259  */
1260 gboolean
1261 gst_pad_renegotiate (GstPad *pad)
1262 {
1263   GstCaps *newcaps = NULL;
1264   GstRealPad *peerpad, *currentpad, *otherpad;
1265   gboolean result;
1266   gpointer data1 = NULL, data2 = NULL;
1267   
1268   g_return_val_if_fail (pad != NULL, FALSE);
1269
1270   peerpad = GST_PAD_PEER (pad);
1271
1272   currentpad = GST_PAD_REALIZE (pad);
1273
1274   if (!peerpad) {
1275     GST_DEBUG (GST_CAT_NEGOTIATION, "no peer pad for pad %s:%s\n",
1276                  GST_DEBUG_PAD_NAME(currentpad));
1277     return TRUE;
1278   }
1279    
1280   otherpad = GST_REAL_PAD (peerpad);
1281
1282   GST_INFO (GST_CAT_NEGOTIATION, "negotiating pad %s:%s and %s:%s",
1283             GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad));
1284
1285   newcaps = GST_PAD_CAPS (pad);
1286   
1287   result = gst_pad_renegotiate_func (GST_PAD (currentpad), &data1, GST_PAD (otherpad), &data2, &newcaps);
1288
1289   if (!result) {
1290     GST_DEBUG (GST_CAT_NEGOTIATION, "firing caps_nego_failed signal on %s:%s and %s:%s to give it a chance to succeed\n",
1291                GST_DEBUG_PAD_NAME(currentpad),GST_DEBUG_PAD_NAME(otherpad));
1292     g_signal_emit (G_OBJECT(currentpad), 
1293                      gst_real_pad_signals[REAL_CAPS_NEGO_FAILED], 0, &result);
1294     g_signal_emit (G_OBJECT(otherpad), 
1295                      gst_real_pad_signals[REAL_CAPS_NEGO_FAILED], 0, &result);
1296     if (result)
1297       GST_DEBUG (GST_CAT_NEGOTIATION, "caps_nego_failed handler claims success at renego, believing\n");
1298   }
1299
1300   if (result) {
1301     GST_DEBUG (GST_CAT_NEGOTIATION, "pads aggreed on caps :)\n");
1302
1303   newcaps = GST_PAD_CAPS (pad);
1304     /* g_return_val_if_fail(newcaps != NULL, FALSE);  FIXME is this valid? */
1305
1306     /* here we have some sort of aggreement of the caps */
1307     GST_PAD_CAPS (currentpad) = gst_caps_ref (newcaps);
1308     if (GST_RPAD_NEWCAPSFUNC (currentpad))
1309       GST_RPAD_NEWCAPSFUNC (currentpad) (GST_PAD (currentpad), newcaps);
1310
1311     GST_PAD_CAPS (otherpad) = gst_caps_ref (newcaps);
1312     if (GST_RPAD_NEWCAPSFUNC (otherpad))
1313       GST_RPAD_NEWCAPSFUNC (otherpad) (GST_PAD (otherpad), newcaps);
1314
1315     GST_DEBUG (GST_CAT_NEGOTIATION, "firing caps_changed signal on %s:%s and %s:%s\n",
1316                GST_DEBUG_PAD_NAME(currentpad),GST_DEBUG_PAD_NAME(otherpad));
1317     g_signal_emit (G_OBJECT(currentpad), 
1318                      gst_real_pad_signals[REAL_CAPS_CHANGED], 0, GST_PAD_CAPS(currentpad));
1319     g_signal_emit (G_OBJECT(otherpad), 
1320                      gst_real_pad_signals[REAL_CAPS_CHANGED], 0, GST_PAD_CAPS(otherpad));
1321   }
1322
1323   return result;
1324 }
1325
1326 /**
1327  * gst_pad_negotiate_proxy:
1328  * @srcpad: the pad that proxies
1329  * @destpad: the pad to proxy the negotiation to
1330  * @caps: the current caps
1331  *
1332  * Proxies the negotiation pad from srcpad to destpad. Further
1333  * negotiation is done on the peers of both pad instead.
1334  *
1335  * Returns: the result of the negotiation preocess.
1336  */
1337 GstPadNegotiateReturn
1338 gst_pad_negotiate_proxy (GstPad *srcpad, GstPad *destpad, GstCaps **caps)
1339 {
1340   GstRealPad *srcpeer;
1341   GstRealPad *destpeer;
1342   gboolean result;
1343   gpointer data1 = NULL, data2 = NULL;
1344
1345   g_return_val_if_fail (srcpad != NULL, GST_PAD_NEGOTIATE_FAIL);
1346   g_return_val_if_fail (destpad != NULL, GST_PAD_NEGOTIATE_FAIL);
1347
1348   GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation proxied from pad (%s:%s) to pad (%s:%s)\n", 
1349                   GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1350
1351   srcpeer = GST_RPAD_PEER (srcpad);
1352   destpeer = GST_RPAD_PEER (destpad);
1353
1354   if (srcpeer && destpeer) {
1355     result = gst_pad_renegotiate_func (GST_PAD (srcpeer), &data1, GST_PAD (destpeer), &data2, caps);
1356
1357     if (result) {
1358       GST_DEBUG (GST_CAT_NEGOTIATION, "pads (%s:%s) and (%s:%s) aggreed on caps :)\n",
1359                   GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1360
1361       /* here we have some sort of aggreement of the caps */
1362       GST_PAD_CAPS (destpeer) = *caps;
1363       if (GST_RPAD_NEWCAPSFUNC (destpeer))
1364         GST_RPAD_NEWCAPSFUNC (destpeer) (GST_PAD (destpeer), *caps);
1365
1366       GST_PAD_CAPS (destpad) = *caps;
1367       if (GST_RPAD_NEWCAPSFUNC (destpad))
1368         GST_RPAD_NEWCAPSFUNC (destpad) (GST_PAD (destpad), *caps);
1369     }
1370     else {
1371       GST_DEBUG (GST_CAT_NEGOTIATION, "pads did not aggree on caps :(\n");
1372       return GST_PAD_NEGOTIATE_FAIL;
1373     }
1374   }
1375   else {
1376     GST_PAD_CAPS (destpad) = *caps;
1377     if (GST_RPAD_NEWCAPSFUNC (destpad))
1378       GST_RPAD_NEWCAPSFUNC (destpad) (GST_PAD (destpad), *caps);
1379   }
1380
1381   return GST_PAD_NEGOTIATE_AGREE;
1382 }
1383
1384 #ifndef GST_DISABLE_LOADSAVE
1385 /**
1386  * gst_pad_save_thyself:
1387  * @pad: the pad to save
1388  * @parent: the parent XML node to save the description in
1389  *
1390  * Saves the pad into an xml representation
1391  *
1392  * Returns: the xml representation of the pad
1393  */
1394 static xmlNodePtr
1395 gst_pad_save_thyself (GstObject *object,
1396                       xmlNodePtr parent)
1397 {
1398   GstRealPad *realpad;
1399   GstPad *peer;
1400
1401   g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
1402
1403   realpad = GST_REAL_PAD(object);
1404
1405   xmlNewChild(parent,NULL,"name", GST_PAD_NAME (realpad));
1406   if (GST_RPAD_PEER(realpad) != NULL) {
1407     peer = GST_PAD(GST_RPAD_PEER(realpad));
1408     /* first check to see if the peer's parent's parent is the same */
1409     /* we just save it off */
1410     xmlNewChild(parent,NULL,"peer",g_strdup_printf("%s.%s",
1411                     GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer)));
1412   } else
1413     xmlNewChild(parent,NULL,"peer","");
1414
1415   return parent;
1416 }
1417
1418 /**
1419  * gst_pad_ghost_save_thyself:
1420  * @pad: the pad to save
1421  * @bin: the bin
1422  * @parent: the parent XML node to save the description in
1423  *
1424  * Saves the ghost pad into an xml representation.
1425  *
1426  * Returns: the xml representation of the pad
1427  */
1428 xmlNodePtr
1429 gst_pad_ghost_save_thyself (GstPad *pad,
1430                             GstElement *bin,
1431                             xmlNodePtr parent)
1432 {
1433   xmlNodePtr self;
1434
1435   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
1436
1437   self = xmlNewChild(parent,NULL,"ghostpad",NULL);
1438   xmlNewChild(self,NULL,"name", GST_PAD_NAME (pad));
1439   xmlNewChild(self,NULL,"parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
1440
1441   /* FIXME FIXME FIXME! */
1442
1443   return self;
1444 }
1445 #endif /* GST_DISABLE_LOADSAVE */
1446
1447 #ifndef gst_pad_push
1448 /**
1449  * gst_pad_push:
1450  * @pad: the pad to push
1451  * @buf: the buffer to push
1452  *
1453  * Push a buffer to the peer of the pad.
1454  */
1455 void 
1456 gst_pad_push (GstPad *pad, GstBuffer *buf) 
1457 {
1458   GstRealPad *peer = GST_RPAD_PEER (pad);
1459
1460   GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1461
1462   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
1463
1464   if (!peer) {
1465     g_warning ("push on pad %s:%s but it is unconnected", GST_DEBUG_PAD_NAME (pad));
1466   }
1467   else {
1468     if (peer->chainhandler) {
1469       if (buf) {
1470         GST_DEBUG (GST_CAT_DATAFLOW, "calling chainhandler &%s of peer pad %s:%s\n",
1471             GST_DEBUG_FUNCPTR_NAME (peer->chainhandler), GST_DEBUG_PAD_NAME (GST_PAD (peer)));
1472         (peer->chainhandler) (GST_PAD_CAST (peer), buf);
1473         return;
1474       }
1475       else {
1476         g_warning ("trying to push a NULL buffer on pad %s:%s", GST_DEBUG_PAD_NAME (peer));
1477         return;
1478       }
1479     } 
1480     else {
1481       g_warning ("(internal error) push on pad %s:%s but it has no chainhandler", GST_DEBUG_PAD_NAME (peer));
1482     }
1483   }
1484   /* clean up the mess here */
1485   if (buf != NULL) {
1486     if (GST_IS_BUFFER (buf))
1487       gst_buffer_unref (buf);
1488     else
1489       gst_event_free (GST_EVENT (buf));
1490   }
1491 }
1492 #endif
1493
1494 #ifndef gst_pad_pull
1495 /**
1496  * gst_pad_pull:
1497  * @pad: the pad to pull
1498  *
1499  * Pull a buffer from the peer pad.
1500  *
1501  * Returns: a new buffer from the peer pad.
1502  */
1503 GstBuffer*
1504 gst_pad_pull (GstPad *pad) 
1505 {
1506   GstRealPad *peer = GST_RPAD_PEER(pad);
1507   
1508   GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1509
1510   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1511
1512   if (!peer) {
1513     gst_element_error (GST_PAD_PARENT (pad), 
1514                     "pull on pad %s:%s but it was unconnected", 
1515                     GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
1516                     NULL);
1517   }
1518   else {
1519     if (peer->gethandler) {
1520       GstBuffer *buf;
1521
1522       GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s\n",
1523         GST_DEBUG_FUNCPTR_NAME (peer->gethandler), GST_DEBUG_PAD_NAME (peer));
1524
1525       buf = (peer->gethandler) (GST_PAD_CAST (peer));
1526       if (buf)
1527         return buf;
1528       /* no null buffers allowed */
1529       gst_element_error (GST_PAD_PARENT (pad), 
1530                     "NULL buffer during pull on %s:%s", GST_DEBUG_PAD_NAME (pad), NULL);
1531           
1532     } else {
1533       gst_element_error (GST_PAD_PARENT (pad), 
1534                     "(internal error) pull on pad %s:%s but the peer pad %s:%s has no gethandler", 
1535                     GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer),
1536                     NULL);
1537     }
1538   }
1539   return NULL;
1540 }
1541 #endif
1542
1543 #ifndef gst_pad_pullregion
1544 /**
1545  * gst_pad_pullregion:
1546  * @pad: the pad to pull the region from
1547  * @type: the regiontype
1548  * @offset: the offset/start of the buffer to pull
1549  * @len: the length of the buffer to pull
1550  *
1551  * Pull a buffer region from the peer pad. The region to pull can be 
1552  * specified with a offset/lenght pair or with a start/legnth time
1553  * indicator as specified by the type parameter.
1554  *
1555  * Returns: a new buffer from the peer pad with data in the specified
1556  * region.
1557  */
1558 GstBuffer*
1559 gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len) 
1560 {
1561   GstRealPad *peer;
1562   GstBuffer *result = NULL;
1563   
1564   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1565
1566   do {
1567     peer = GST_RPAD_PEER(pad);
1568     g_return_val_if_fail (peer != NULL, NULL);
1569
1570     if (result) 
1571       gst_buffer_unref (result);
1572
1573     GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len);
1574
1575     if (peer->pullregionfunc) {
1576       GST_DEBUG (GST_CAT_DATAFLOW, "calling pullregionfunc &%s of peer pad %s:%s\n",
1577           GST_DEBUG_FUNCPTR_NAME (peer->pullregionfunc), GST_DEBUG_PAD_NAME(GST_PAD_CAST (peer)));
1578       result = (peer->pullregionfunc) (GST_PAD_CAST (peer), type, offset, len);
1579     } else {
1580       GST_DEBUG (GST_CAT_DATAFLOW,"no pullregionfunc\n");
1581       result = NULL;
1582       break;
1583     }
1584   }
1585   /* FIXME */
1586   while (result && !(GST_BUFFER_OFFSET (result) == offset && 
1587            GST_BUFFER_SIZE (result) == len));
1588
1589   return result;
1590 }
1591 #endif
1592
1593 /**
1594  * gst_pad_peek:
1595  * @pad: the pad to peek
1596  *
1597  * Peek for a buffer from the peer pad.
1598  *
1599  * Returns: a from the peer pad or NULL if the peer has no buffer.
1600  */
1601 GstBuffer*
1602 gst_pad_peek (GstPad *pad)
1603 {
1604   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1605
1606   return GST_RPAD_BUFPEN (GST_RPAD_PEER (pad));
1607 }
1608
1609 /**
1610  * gst_pad_select:
1611  * @padlist: A list of pads 
1612  *
1613  * Wait for a buffer on the list of pads.
1614  *
1615  * Returns: The pad that has a buffer available, use 
1616  * #gst_pad_pull to get the buffer.
1617  */
1618 GstPad*
1619 gst_pad_select (GList *padlist)
1620 {
1621   GstPad *pad;
1622
1623   pad = gst_scheduler_pad_select (GST_PAD_PARENT (padlist->data)->sched, padlist);
1624
1625   return pad;
1626 }
1627
1628 /**
1629  * gst_pad_selectv:
1630  * @pad: The first pad to perform the select on 
1631  * @...: More pads
1632  *
1633  * Wait for a buffer on the given of pads.
1634  *
1635  * Returns: The pad that has a buffer available, use 
1636  * #gst_pad_pull to get the buffer.
1637  */
1638 GstPad*
1639 gst_pad_selectv (GstPad *pad, ...)
1640 {
1641   GstPad *result;
1642   GList *padlist = NULL;
1643   va_list var_args;
1644
1645   if (pad == NULL)
1646     return NULL;
1647
1648   va_start (var_args, pad);
1649
1650   while (pad) {
1651     padlist = g_list_prepend (padlist, pad);
1652     pad = va_arg (var_args, GstPad *);
1653   }
1654   result = gst_pad_select (padlist);
1655   g_list_free (padlist);
1656
1657   va_end (var_args);
1658   
1659   return result;
1660 }
1661
1662 /************************************************************************
1663  *
1664  * templates
1665  *
1666  */
1667 static void             gst_padtemplate_class_init      (GstPadTemplateClass *klass);
1668 static void             gst_padtemplate_init            (GstPadTemplate *templ);
1669
1670 enum {
1671   TEMPL_PAD_CREATED,
1672   /* FILL ME */
1673   TEMPL_LAST_SIGNAL
1674 };
1675
1676 static GstObject *padtemplate_parent_class = NULL;
1677 static guint gst_padtemplate_signals[TEMPL_LAST_SIGNAL] = { 0 };
1678
1679 GType
1680 gst_padtemplate_get_type (void)
1681 {
1682   static GType padtemplate_type = 0;
1683
1684   if (!padtemplate_type) {
1685     static const GTypeInfo padtemplate_info = {
1686       sizeof(GstPadTemplateClass),
1687       NULL,
1688       NULL,
1689       (GClassInitFunc)gst_padtemplate_class_init,
1690       NULL,
1691       NULL,
1692       sizeof(GstPadTemplate),
1693       32,
1694       (GInstanceInitFunc)gst_padtemplate_init,
1695       NULL
1696     };
1697     padtemplate_type = g_type_register_static(GST_TYPE_OBJECT, "GstPadTemplate", &padtemplate_info, 0);
1698   }
1699   return padtemplate_type;
1700 }
1701
1702 static void
1703 gst_padtemplate_class_init (GstPadTemplateClass *klass)
1704 {
1705   GObjectClass *gobject_class;
1706   GstObjectClass *gstobject_class;
1707
1708   gobject_class = (GObjectClass*)klass;
1709   gstobject_class = (GstObjectClass*)klass;
1710
1711   padtemplate_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
1712
1713   gst_padtemplate_signals[TEMPL_PAD_CREATED] =
1714     g_signal_new ("pad_created", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
1715                     G_STRUCT_OFFSET (GstPadTemplateClass, pad_created), NULL, NULL,
1716                     gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
1717                     G_TYPE_POINTER);
1718
1719
1720   gstobject_class->path_string_separator = "*";
1721 }
1722
1723 static void
1724 gst_padtemplate_init (GstPadTemplate *templ)
1725 {
1726 }
1727
1728 /**
1729  * gst_padtemplate_new:
1730  * @name_template: the name template
1731  * @direction: the direction for the template
1732  * @presence: the presence of the pad
1733  * @caps: a list of capabilities for the template
1734  * @...: more capabilities
1735  *
1736  * Creates a new padtemplate from the given arguments.
1737  *
1738  * Returns: the new padtemplate
1739  */
1740 GstPadTemplate*
1741 gst_padtemplate_new (gchar *name_template,
1742                      GstPadDirection direction, GstPadPresence presence,
1743                      GstCaps *caps, ...)
1744 {
1745   GstPadTemplate *new;
1746   va_list var_args;
1747   GstCaps *thecaps = NULL;
1748
1749   g_return_val_if_fail (name_template != NULL, NULL);
1750
1751   new = g_object_new(gst_padtemplate_get_type () ,NULL);
1752
1753   GST_PADTEMPLATE_NAME_TEMPLATE (new) = name_template;
1754   GST_PADTEMPLATE_DIRECTION (new) = direction;
1755   GST_PADTEMPLATE_PRESENCE (new) = presence;
1756
1757   va_start (var_args, caps);
1758
1759   while (caps) {
1760     thecaps = gst_caps_append (thecaps, caps);
1761     caps = va_arg (var_args, GstCaps*);
1762   }
1763   va_end (var_args);
1764   
1765   GST_PADTEMPLATE_CAPS (new) = thecaps;
1766
1767   return new;
1768 }
1769
1770 /**
1771  * gst_padtemplate_get_caps:
1772  * @templ: the padtemplate to use
1773  *
1774  * Get the capabilities of the padtemplate
1775  *
1776  * Returns: a GstCaps*
1777  */
1778 GstCaps*
1779 gst_padtemplate_get_caps (GstPadTemplate *templ)
1780 {
1781   g_return_val_if_fail (templ != NULL, NULL);
1782
1783   return GST_PADTEMPLATE_CAPS (templ);
1784 }
1785
1786 #ifndef GST_DISABLE_LOADSAVE
1787 /**
1788  * gst_padtemplate_save_thyself:
1789  * @templ: the padtemplate to save
1790  * @parent: the parent XML tree
1791  *
1792  * Saves the padtemplate into XML.
1793  *
1794  * Returns: the new XML tree
1795  */
1796 xmlNodePtr
1797 gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
1798 {
1799   xmlNodePtr subtree;
1800   guchar *presence;
1801
1802   GST_DEBUG (GST_CAT_XML,"saving padtemplate %s\n", templ->name_template);
1803
1804   xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
1805   xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
1806
1807   switch (templ->presence) {
1808     case GST_PAD_ALWAYS:
1809       presence = "always";
1810       break;
1811     case GST_PAD_SOMETIMES:
1812       presence = "sometimes";
1813       break;
1814     case GST_PAD_REQUEST:
1815       presence = "request";
1816       break;
1817     default:
1818       presence = "unknown";
1819       break;
1820   }
1821   xmlNewChild(parent,NULL,"presence", presence);
1822
1823   if (GST_PADTEMPLATE_CAPS (templ)) {
1824     subtree = xmlNewChild (parent, NULL, "caps", NULL);
1825     gst_caps_save_thyself (GST_PADTEMPLATE_CAPS (templ), subtree);
1826   }
1827
1828   return parent;
1829 }
1830
1831 /**
1832  * gst_padtemplate_load_thyself:
1833  * @parent: the source XML tree
1834  *
1835  * Loads a padtemplate from the XML tree.
1836  *
1837  * Returns: the new padtemplate
1838  */
1839 GstPadTemplate*
1840 gst_padtemplate_load_thyself (xmlNodePtr parent)
1841 {
1842   xmlNodePtr field = parent->xmlChildrenNode;
1843   GstPadTemplate *factory;
1844   gchar *name_template = NULL;
1845   GstPadDirection direction = GST_PAD_UNKNOWN;
1846   GstPadPresence presence = GST_PAD_ALWAYS;
1847   GstCaps *caps = NULL;
1848
1849   while (field) {
1850     if (!strcmp(field->name, "nametemplate")) {
1851       name_template = xmlNodeGetContent(field);
1852     }
1853     if (!strcmp(field->name, "direction")) {
1854       gchar *value = xmlNodeGetContent(field);
1855
1856       if (!strcmp(value, "sink")) {
1857         direction = GST_PAD_SINK;
1858       }
1859       else if (!strcmp(value, "src")) {
1860         direction = GST_PAD_SRC;
1861       }
1862       g_free (value);
1863     }
1864     if (!strcmp(field->name, "presence")) {
1865       gchar *value = xmlNodeGetContent(field);
1866
1867       if (!strcmp(value, "always")) {
1868         presence = GST_PAD_ALWAYS;
1869       }
1870       else if (!strcmp(value, "sometimes")) {
1871         presence = GST_PAD_SOMETIMES;
1872       }
1873       else if (!strcmp(value, "request")) {
1874         presence = GST_PAD_REQUEST;
1875       }
1876       g_free (value);
1877     }
1878     else if (!strcmp(field->name, "caps")) {
1879       caps = gst_caps_load_thyself (field);
1880     }
1881     field = field->next;
1882   }
1883
1884   factory = gst_padtemplate_new (name_template, direction, presence, caps, NULL);
1885
1886   return factory;
1887 }
1888 #endif /* !GST_DISABLE_LOADSAVE */
1889
1890
1891 /**
1892  * gst_pad_set_element_private:
1893  * @pad: the pad to set the private data to
1894  * @priv: The private data to attach to the pad
1895  *
1896  * Set the given private data pointer to the pad. This
1897  * function can only be used by the element that own the
1898  * pad.
1899  */
1900 void
1901 gst_pad_set_element_private (GstPad *pad, gpointer priv)
1902 {
1903   pad->element_private = priv;
1904 }
1905
1906 /**
1907  * gst_pad_get_element_private:
1908  * @pad: the pad to get the private data of
1909  *
1910  * Get the private data of a pad. The private data can
1911  * only be set by the parent element of this pad.
1912  *
1913  * Returns: a pointer to the private data.
1914  */
1915 gpointer
1916 gst_pad_get_element_private (GstPad *pad)
1917 {
1918   return pad->element_private;
1919 }
1920
1921
1922 /***** ghost pads *****/
1923 GType _gst_ghost_pad_type = 0;
1924
1925 static void     gst_ghost_pad_class_init         (GstGhostPadClass *klass);
1926 static void     gst_ghost_pad_init               (GstGhostPad *pad);
1927
1928 static GstPad *ghost_pad_parent_class = NULL;
1929 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
1930
1931 GType
1932 gst_ghost_pad_get_type(void) {
1933   if (!_gst_ghost_pad_type) {
1934     static const GTypeInfo pad_info = {
1935       sizeof(GstGhostPadClass),
1936       NULL,
1937       NULL,
1938       (GClassInitFunc)gst_ghost_pad_class_init,
1939       NULL,
1940       NULL,
1941       sizeof(GstGhostPad),
1942       8,
1943       (GInstanceInitFunc)gst_ghost_pad_init,
1944       NULL
1945     };
1946     _gst_ghost_pad_type = g_type_register_static(GST_TYPE_PAD, "GstGhostPad", &pad_info, 0);
1947   }
1948   return _gst_ghost_pad_type;
1949 }
1950
1951 static void
1952 gst_ghost_pad_class_init (GstGhostPadClass *klass)
1953 {
1954   GObjectClass *gobject_class;
1955
1956   gobject_class = (GObjectClass*)klass;
1957
1958   ghost_pad_parent_class = g_type_class_ref(GST_TYPE_PAD);
1959 }
1960
1961 static void
1962 gst_ghost_pad_init (GstGhostPad *pad)
1963 {
1964   pad->realpad = NULL;
1965 }
1966
1967 /**
1968  * gst_ghost_pad_new:
1969  * @name: name of the new ghost pad
1970  * @pad: the pad to create a ghost pad of
1971  *
1972  * Create a new ghost pad associated with the given pad.
1973  *
1974  * Returns: new ghost pad
1975  */
1976 GstPad*
1977 gst_ghost_pad_new (gchar *name,
1978                    GstPad *pad)
1979 {
1980   GstGhostPad *ghostpad;
1981
1982   g_return_val_if_fail (name != NULL, NULL);
1983   g_return_val_if_fail (GST_IS_PAD(pad), NULL);
1984
1985   ghostpad = g_object_new(gst_ghost_pad_get_type () ,NULL);
1986   gst_pad_set_name (GST_PAD (ghostpad), name);
1987   GST_GPAD_REALPAD(ghostpad) = GST_PAD_REALIZE(pad);
1988   GST_PAD_PADTEMPLATE(ghostpad) = GST_PAD_PADTEMPLATE(pad);
1989
1990   /* add ourselves to the real pad's list of ghostpads */
1991   gst_pad_add_ghost_pad (pad, GST_PAD(ghostpad));
1992
1993   /* FIXME need to ref the real pad here... ? */
1994
1995   GST_DEBUG(GST_CAT_PADS,"created ghost pad \"%s\"\n",name);
1996
1997   return GST_PAD(ghostpad);
1998 }
1999
2000 static void 
2001 gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, GstEvent *event)
2002 {
2003   GList *pads = element->pads;
2004
2005   while (pads) {
2006     GstPad *eventpad = GST_PAD (pads->data);
2007     pads = g_list_next (pads);
2008
2009     /* for all pads in the opposite direction that are connected */
2010     if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) && GST_PAD_CONNECTED (eventpad)) {
2011       if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
2012         gst_pad_push (eventpad, GST_BUFFER (gst_event_new (GST_EVENT_TYPE (event))));
2013         
2014       }
2015       else {
2016         GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
2017
2018         gst_pad_send_event (peerpad, gst_event_new (GST_EVENT_TYPE (event)));
2019       }
2020     }
2021   }
2022 }
2023
2024 /**
2025  * gst_pad_event_default:
2026  * @pad: the pad to operate on
2027  * @event: the event to handle
2028  *
2029  * Invoke the default event handler for the given pad.
2030  */
2031 void 
2032 gst_pad_event_default (GstPad *pad, GstEvent *event)
2033 {
2034   GstElement *element = GST_PAD_PARENT (pad);
2035
2036   g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_EVENT_RECEIVED], 0, event);
2037  
2038   switch (GST_EVENT_TYPE (event)) {
2039     case GST_EVENT_EOS:
2040       gst_element_set_eos (element);
2041       gst_pad_event_default_dispatch (pad, element, event);
2042       gst_event_free (event);
2043       /* we have to try to schedule another element because this one is disabled */
2044       gst_element_yield (element);
2045       break;
2046     case GST_EVENT_FLUSH:
2047     default:
2048       gst_pad_event_default_dispatch (pad, element, event);
2049       gst_event_free (event);
2050       break;
2051   }
2052 }
2053
2054 /**
2055  * gst_pad_send_event:
2056  * @pad: the pad to send the event to
2057  * @event: the event to send to the pad.
2058  *
2059  * Send the event to the pad.
2060  *
2061  * Returns: TRUE if the event was handled.
2062  */
2063 gboolean
2064 gst_pad_send_event (GstPad *pad, GstEvent *event)
2065 {
2066   gboolean handled = FALSE;
2067
2068   g_return_val_if_fail (event, FALSE);
2069
2070   if (GST_EVENT_SRC (event) == NULL)
2071     GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (pad));
2072
2073   GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n",
2074                   GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
2075
2076   if (GST_RPAD_EVENTFUNC (pad))
2077     handled = GST_RPAD_EVENTFUNC (pad) (pad, event);
2078   else {
2079     GST_DEBUG(GST_CAT_EVENT, "there's no event function for pad %s:%s\n", GST_DEBUG_PAD_NAME (pad));
2080   }
2081
2082   if (!handled) {
2083     GST_DEBUG(GST_CAT_EVENT, "proceeding with default event behavior here\n");
2084     gst_pad_event_default (pad, event);
2085     handled = TRUE;
2086   }
2087
2088   return handled;
2089 }
2090