2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstpad.c: Pads for connecting elements together
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.
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.
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.
23 /* #define GST_DEBUG_ENABLED */
24 #include "gst_private.h"
28 #include "gstelement.h"
31 #include "gstscheduler.h"
34 GType _gst_pad_type = 0;
36 /***** Start with the base GstPad class *****/
37 static void gst_pad_class_init (GstPadClass *klass);
38 static void gst_pad_init (GstPad *pad);
40 #ifndef GST_DISABLE_LOADSAVE
41 static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent);
44 static GstObject *pad_parent_class = NULL;
47 gst_pad_get_type(void)
50 static const GTypeInfo pad_info = {
54 (GClassInitFunc)gst_pad_class_init,
59 (GInstanceInitFunc)gst_pad_init,
62 _gst_pad_type = g_type_register_static(GST_TYPE_OBJECT, "GstPad", &pad_info, 0);
68 gst_pad_class_init (GstPadClass *klass)
70 pad_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
74 gst_pad_init (GstPad *pad)
76 pad->element_private = NULL;
78 pad->padtemplate = NULL;
83 /***** Then do the Real Pad *****/
84 /* Pad signals and args */
88 REAL_CAPS_NEGO_FAILED,
102 static void gst_real_pad_class_init (GstRealPadClass *klass);
103 static void gst_real_pad_init (GstRealPad *pad);
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);
108 static void gst_real_pad_dispose (GObject *object);
110 static void gst_pad_push_func (GstPad *pad, GstBuffer *buf);
112 GType _gst_real_pad_type = 0;
114 static GstPad *real_pad_parent_class = NULL;
115 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
118 gst_real_pad_get_type(void) {
119 if (!_gst_real_pad_type) {
120 static const GTypeInfo pad_info = {
121 sizeof(GstRealPadClass),
124 (GClassInitFunc)gst_real_pad_class_init,
129 (GInstanceInitFunc)gst_real_pad_init,
132 _gst_real_pad_type = g_type_register_static(GST_TYPE_PAD, "GstRealPad", &pad_info, 0);
134 return _gst_real_pad_type;
138 gst_real_pad_class_init (GstRealPadClass *klass)
140 GObjectClass *gobject_class;
141 GstObjectClass *gstobject_class;
143 gobject_class = (GObjectClass*) klass;
144 gstobject_class = (GstObjectClass*) klass;
146 real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
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);
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,
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,
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,
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,
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,
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,
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));
189 #ifndef GST_DISABLE_LOADSAVE
190 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR(gst_pad_save_thyself);
192 gstobject_class->path_string_separator = ".";
196 gst_real_pad_init (GstRealPad *pad)
198 pad->direction = GST_PAD_UNKNOWN;
202 pad->sched_private = NULL;
204 pad->chainfunc = NULL;
206 pad->getregionfunc = NULL;
208 pad->chainhandler = GST_DEBUG_FUNCPTR(gst_pad_push_func);
209 pad->gethandler = NULL;
210 pad->pullregionfunc = NULL;
212 pad->bufferpoolfunc = NULL;
213 pad->ghostpads = NULL;
218 gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
220 g_return_if_fail(GST_IS_PAD(object));
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);
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);
231 g_signal_emit(G_OBJECT(object), gst_real_pad_signals[REAL_SET_ACTIVE], 0,
232 ! GST_FLAG_IS_SET(object,GST_PAD_DISABLED));
240 gst_real_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
242 /* it's not null if we got it, but it might not be ours */
243 g_return_if_fail (GST_IS_PAD (object));
246 case REAL_ARG_ACTIVE:
247 g_value_set_boolean(value, ! GST_FLAG_IS_SET (object, GST_PAD_DISABLED) );
257 * @name: name of new pad
258 * @direction: either GST_PAD_SRC or GST_PAD_SINK
260 * Create a new pad with given name.
265 gst_pad_new (gchar *name,
266 GstPadDirection direction)
270 g_return_val_if_fail (name != NULL, NULL);
271 g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
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;
281 * gst_pad_new_from_template:
282 * @templ: the pad template to use
283 * @name: the name of the element
285 * Create a new pad with given name from the given template.
290 gst_pad_new_from_template (GstPadTemplate *templ,
295 g_return_val_if_fail (name != NULL, NULL);
296 g_return_val_if_fail (templ != NULL, NULL);
298 pad = gst_pad_new (name, templ->direction);
300 gst_object_ref (GST_OBJECT (templ));
301 GST_PAD_PADTEMPLATE(pad) = templ;
307 * gst_pad_get_direction:
308 * @pad: the Pad to get the direction from
310 * Get the direction of the pad.
312 * Returns: the direction of the pad
315 gst_pad_get_direction (GstPad *pad)
317 g_return_val_if_fail (pad != NULL, GST_PAD_UNKNOWN);
318 g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
320 return GST_PAD_DIRECTION(pad);
325 * @pad: the pad to set the name of
326 * @name: the name of the pad
328 * Set the name of a pad.
331 gst_pad_set_name (GstPad *pad,
334 g_return_if_fail (pad != NULL);
335 g_return_if_fail (GST_IS_PAD (pad));
337 gst_object_set_name (GST_OBJECT (pad), name);
342 * @pad: the pad to get the name of
344 * Get the name of a pad.
346 * Returns: the name of the pad, don't free.
349 gst_pad_get_name (GstPad *pad)
351 g_return_val_if_fail (pad != NULL, NULL);
352 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
354 return GST_OBJECT_NAME (pad);
358 * gst_pad_set_chain_function:
359 * @pad: the pad to set the chain function for
360 * @chain: the chain function
362 * Set the given chain function for the pad.
364 void gst_pad_set_chain_function (GstPad *pad,
365 GstPadChainFunction chain)
367 g_return_if_fail (pad != NULL);
368 g_return_if_fail (GST_IS_REAL_PAD (pad));
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));
376 * gst_pad_set_get_function:
377 * @pad: the pad to set the get function for
378 * @get: the get function
380 * Set the given get function for the pad.
383 gst_pad_set_get_function (GstPad *pad,
384 GstPadGetFunction get)
386 g_return_if_fail (pad != NULL);
387 g_return_if_fail (GST_IS_REAL_PAD (pad));
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));
395 * gst_pad_set_event_function:
396 * @pad: the pad to set the event handler for
397 * @event: the event handler
399 * Set the given event handler for the pad.
402 gst_pad_set_event_function (GstPad *pad,
403 GstPadEventFunction event)
405 g_return_if_fail (pad != NULL);
406 g_return_if_fail (GST_IS_REAL_PAD (pad));
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));
414 * gst_pad_set_getregion_function:
415 * @pad: the pad to set the getregion function for
416 * @getregion: the getregion function
418 * Set the given getregion function for the pad.
421 gst_pad_set_getregion_function (GstPad *pad,
422 GstPadGetRegionFunction getregion)
424 g_return_if_fail (pad != NULL);
425 g_return_if_fail (GST_IS_REAL_PAD (pad));
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));
433 * gst_pad_set_negotiate_function:
434 * @pad: the pad to set the negotiate function for
435 * @nego: the negotiate function
437 * Set the given negotiate function for the pad.
440 gst_pad_set_negotiate_function (GstPad *pad,
441 GstPadNegotiateFunction nego)
443 g_return_if_fail (pad != NULL);
444 g_return_if_fail (GST_IS_REAL_PAD (pad));
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));
452 * gst_pad_set_newcaps_function:
453 * @pad: the pad to set the newcaps function for
454 * @newcaps: the newcaps function
456 * Set the given newcaps function for the pad.
459 gst_pad_set_newcaps_function (GstPad *pad,
460 GstPadNewCapsFunction newcaps)
462 g_return_if_fail (pad != NULL);
463 g_return_if_fail (GST_IS_REAL_PAD (pad));
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));
471 * gst_pad_set_bufferpool_function:
472 * @pad: the pad to set the bufferpool function for
473 * @bufpool: the bufferpool function
475 * Set the given bufferpool function for the pad.
478 gst_pad_set_bufferpool_function (GstPad *pad,
479 GstPadBufferPoolFunction bufpool)
481 g_return_if_fail (pad != NULL);
482 g_return_if_fail (GST_IS_REAL_PAD (pad));
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));
490 gst_pad_push_func(GstPad *pad, GstBuffer *buf)
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);
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));
505 * gst_pad_disconnect:
506 * @srcpad: the source pad to disconnect
507 * @sinkpad: the sink pad to disconnect
509 * Disconnects the source pad from the sink pad.
512 gst_pad_disconnect (GstPad *srcpad,
515 GstRealPad *realsrc, *realsink;
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));
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);
526 /* now we need to deal with the real/ghost stuff */
527 realsrc = GST_PAD_REALIZE(srcpad);
528 realsink = GST_PAD_REALIZE(sinkpad);
530 g_return_if_fail (GST_RPAD_PEER(realsrc) != NULL);
531 g_return_if_fail (GST_RPAD_PEER(realsink) != NULL);
533 if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) &&
534 (GST_RPAD_DIRECTION(realsink) == GST_PAD_SRC)) {
541 g_return_if_fail ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
542 (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK));
544 /* first clear peers */
545 GST_RPAD_PEER(realsrc) = NULL;
546 GST_RPAD_PEER(realsink) = NULL;
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);
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);
558 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
559 GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
564 * @srcpad: the source pad to connect
565 * @sinkpad: the sink pad to connect
567 * Connects the source pad to the sink pad.
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.
575 gst_pad_connect (GstPad *srcpad,
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));
586 * gst_pad_try_connect:
587 * @srcpad: the source pad to connect
588 * @sinkpad: the sink pad to connect
590 * Connects the source pad to the sink pad.
592 * Returns: TRUE if the pad could be connected
595 gst_pad_try_connect (GstPad *srcpad,
598 GstRealPad *realsrc, *realsink;
599 gboolean negotiated = FALSE;
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);
607 GST_INFO (GST_CAT_PADS, "connecting %s:%s and %s:%s",
608 GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
610 /* now we need to deal with the real/ghost stuff */
611 realsrc = GST_PAD_REALIZE(srcpad);
612 realsink = GST_PAD_REALIZE(sinkpad);
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));
618 g_return_val_if_fail(GST_RPAD_PEER(realsrc) == NULL, FALSE);
619 g_return_val_if_fail(GST_RPAD_PEER(realsink) == NULL, FALSE);
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)) {
630 g_return_val_if_fail((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
631 (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK), FALSE);
634 /* first set peers */
635 GST_RPAD_PEER(realsrc) = realsink;
636 GST_RPAD_PEER(realsink) = realsrc;
638 if (GST_PAD_CAPS (srcpad)) {
639 GST_DEBUG(GST_CAT_PADS, "renegotiation from srcpad\n");
640 negotiated = gst_pad_renegotiate (srcpad);
642 else if (GST_PAD_CAPS (sinkpad)) {
643 GST_DEBUG(GST_CAT_PADS, "renegotiation from sinkpad\n");
644 negotiated = gst_pad_renegotiate (sinkpad);
647 GST_DEBUG(GST_CAT_PADS, "not renegotiating connection\n");
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));
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);
662 /* now tell the scheduler(s) */
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);
668 GST_INFO (GST_CAT_PADS, "connected %s:%s and %s:%s",
669 GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
674 * gst_pad_set_parent:
675 * @pad: the pad to set the parent
676 * @parent: the object to set the parent to
678 * Sets the parent object of a pad.
681 gst_pad_set_parent (GstPad *pad,
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);
691 gst_object_set_parent (GST_OBJECT (pad), parent);
695 * gst_pad_get_parent:
696 * @pad: the pad to get the parent from
698 * Get the parent object of this pad.
700 * Returns: the parent object
703 gst_pad_get_parent (GstPad *pad)
705 g_return_val_if_fail (pad != NULL, NULL);
706 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
708 return GST_PAD_PARENT (pad);
712 * gst_pad_get_padtemplate:
713 * @pad: the pad to get the padtemplate from
715 * Get the padtemplate object of this pad.
717 * Returns: the padtemplate object
720 gst_pad_get_padtemplate (GstPad *pad)
722 g_return_val_if_fail (pad != NULL, NULL);
723 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
725 return GST_PAD_PADTEMPLATE (pad);
731 * @pad: the pad to set the scheduler for
732 * @sched: The scheduler to set
734 * Set the sceduler for the pad
737 gst_pad_set_sched (GstPad *pad, GstScheduler *sched)
739 g_return_if_fail (pad != NULL);
740 g_return_if_fail (GST_IS_PAD (pad));
742 GST_RPAD_SCHED(pad) = sched;
747 * @pad: the pad to get the scheduler from
749 * Get the scheduler of the pad
751 * Returns: the scheduler of the pad.
754 gst_pad_get_sched (GstPad *pad)
756 g_return_val_if_fail (pad != NULL, NULL);
757 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
759 return GST_RPAD_SCHED(pad);
763 * gst_pad_get_real_parent:
764 * @pad: the pad to get the parent from
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().
770 * Returns: the parent object
773 gst_pad_get_real_parent (GstPad *pad)
775 g_return_val_if_fail (pad != NULL, NULL);
776 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
778 return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
782 * gst_pad_add_ghost_pad:
783 * @pad: the pad to set the ghost parent
784 * @ghostpad: the ghost pad to add
786 * Add a ghost pad to a pad.
789 gst_pad_add_ghost_pad (GstPad *pad,
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));
799 realpad = GST_PAD_REALIZE(pad);
801 realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
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
810 * Remove a ghost pad from a pad.
813 gst_pad_remove_ghost_pad (GstPad *pad,
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));
823 realpad = GST_PAD_REALIZE (pad);
825 realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
829 * gst_pad_get_ghost_pad_list:
830 * @pad: the pad to get the ghost parents from
832 * Get the ghost parents of this pad.
834 * Returns: a GList of ghost pads
837 gst_pad_get_ghost_pad_list (GstPad *pad)
839 g_return_val_if_fail (pad != NULL, NULL);
840 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
842 return GST_PAD_REALIZE(pad)->ghostpads;
847 * @pad: the pad to set the caps to
848 * @caps: the capabilities to attach to this pad
850 * Set the capabilities of this pad.
852 * Returns: a boolean indicating the caps could be set on the pad
855 gst_pad_set_caps (GstPad *pad,
860 g_return_val_if_fail (pad != NULL, FALSE);
861 g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); /* NOTE this restriction */
863 GST_INFO (GST_CAT_CAPS, "setting caps %p on pad %s:%s",
864 caps, GST_DEBUG_PAD_NAME(pad));
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));
872 oldcaps = GST_PAD_CAPS (pad);
876 GST_PAD_CAPS(pad) = caps;
879 gst_caps_unref (oldcaps);
881 return gst_pad_renegotiate (pad);
886 * @pad: the pad to get the capabilities from
888 * Get the capabilities of this pad.
890 * Returns: the capabilities of this pad
893 gst_pad_get_caps (GstPad *pad)
895 g_return_val_if_fail (pad != NULL, NULL);
896 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
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));
907 * gst_pad_get_padtemplate_caps:
908 * @pad: the pad to get the capabilities from
910 * Get the capabilities of this pad.
912 * Returns: a list of the capabilities of this pad
915 gst_pad_get_padtemplate_caps (GstPad *pad)
917 g_return_val_if_fail (pad != NULL, NULL);
918 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
920 if (GST_PAD_PADTEMPLATE (pad))
921 return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
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
932 * Get the capability with the given name from this padtemplate.
934 * Returns: a capability or NULL if not found
937 gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
941 g_return_val_if_fail (templ != NULL, NULL);
943 caps = GST_PADTEMPLATE_CAPS (templ);
947 return gst_caps_get_by_name (caps, name);
951 * gst_pad_check_compatibility:
952 * @srcpad: the srcpad to check
953 * @sinkpad: the sinkpad to check against
955 * Check if two pads have compatible capabilities.
957 * Returns: TRUE if they are compatible or the capabilities
958 * could not be checked
961 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
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);
968 if (GST_PAD_CAPS(srcpad) && GST_PAD_CAPS(sinkpad)) {
969 if (!gst_caps_check_compatibility (GST_PAD_CAPS(srcpad), GST_PAD_CAPS(sinkpad))) {
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));
986 * @pad: the pad to get the peer from
988 * Get the peer pad of this pad.
990 * Returns: the peer pad
993 gst_pad_get_peer (GstPad *pad)
995 g_return_val_if_fail (pad != NULL, NULL);
996 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
998 return GST_PAD(GST_PAD_PEER(pad));
1002 * gst_pad_get_bufferpool:
1003 * @pad: the pad to get the bufferpool from
1005 * Get the bufferpool of the peer pad of the given
1008 * Returns: The GstBufferPool or NULL.
1011 gst_pad_get_bufferpool (GstPad *pad)
1015 g_return_val_if_fail (pad != NULL, NULL);
1016 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1018 peer = GST_RPAD_PEER(pad);
1020 g_return_val_if_fail (peer != NULL, NULL);
1022 GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
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));
1029 GST_DEBUG (GST_CAT_PADS,"no bufferpoolfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(((GstPad*)peer)),&peer->bufferpoolfunc);
1035 gst_real_pad_dispose (GObject *object)
1037 GstPad *pad = GST_PAD (object);
1039 GST_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s\n", GST_DEBUG_PAD_NAME(pad));
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));
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)));
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;
1055 orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
1058 GstPad *ghostpad = GST_PAD (ghostpads->data);
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));
1064 ghostpads = g_list_next (ghostpads);
1067 g_list_free (GST_REAL_PAD(pad)->ghostpads);
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);
1075 G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
1079 #ifndef GST_DISABLE_LOADSAVE
1081 * gst_pad_load_and_connect:
1082 * @self: the XML node to read the description from
1083 * @parent: the element that has the pad
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.
1089 gst_pad_load_and_connect (xmlNodePtr self,
1092 xmlNodePtr field = self->xmlChildrenNode;
1093 GstPad *pad = NULL, *targetpad;
1094 guchar *peer = NULL;
1097 GstObject *grandparent;
1100 if (!strcmp (field->name, "name")) {
1101 pad = gst_element_get_pad (GST_ELEMENT (parent), xmlNodeGetContent (field));
1103 else if (!strcmp(field->name, "peer")) {
1104 peer = xmlNodeGetContent (field);
1106 field = field->next;
1108 g_return_if_fail (pad != NULL);
1110 if (peer == NULL) return;
1112 split = g_strsplit (peer, ".", 2);
1114 g_return_if_fail (split[0] != NULL);
1115 g_return_if_fail (split[1] != NULL);
1117 grandparent = gst_object_get_parent (parent);
1119 if (grandparent && GST_IS_BIN (grandparent)) {
1120 target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
1125 if (target == NULL) goto cleanup;
1127 targetpad = gst_element_get_pad (target, split[1]);
1129 if (targetpad == NULL) goto cleanup;
1131 gst_pad_connect (pad, targetpad);
1136 #endif /* GST_DISABLE_LOADSAVE */
1139 gst_pad_renegotiate_func (GstPad *pad, gpointer *data1, GstPad *peerpad, gpointer *data2, GstCaps **newcaps)
1141 GstRealPad *currentpad, *otherpad;
1142 gpointer *currentdata, *otherdata;
1143 GstPadNegotiateReturn result;
1146 g_return_val_if_fail (pad != NULL, FALSE);
1148 currentpad = GST_PAD_REALIZE (pad);
1149 otherpad = GST_REAL_PAD (peerpad);
1150 currentdata = data1;
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);
1157 gboolean matchtempl;
1160 if (otherpad->negotiatefunc) {
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);
1169 otherpad = currentpad;
1172 tempdata = otherdata;
1173 otherdata = currentdata;
1174 currentdata = tempdata;
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)));
1182 GST_DEBUG (GST_CAT_NEGOTIATION, "caps compatibility check %s\n", (matchtempl?"ok":"fail"));
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) {
1191 GST_DEBUG (GST_CAT_NEGOTIATION, "switching pad for next phase\n");
1194 currentpad = otherpad;
1197 tempdata = otherdata;
1198 otherdata = currentdata;
1199 currentdata = tempdata;
1201 else if (gst_caps_check_compatibility (*newcaps, GST_PAD_CAPS (otherpad))) {
1202 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n");
1206 *newcaps = GST_PAD_CAPS (otherpad);
1207 if (*newcaps) gst_caps_ref(*newcaps);
1211 *newcaps = GST_PAD_CAPS (otherpad);
1212 if (*newcaps) gst_caps_ref(*newcaps);
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);
1223 case GST_PAD_NEGOTIATE_FAIL:
1224 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed\n");
1226 case GST_PAD_NEGOTIATE_AGREE:
1227 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n");
1229 case GST_PAD_NEGOTIATE_TRY:
1230 GST_DEBUG (GST_CAT_NEGOTIATION, "try another option\n");
1233 GST_DEBUG (GST_CAT_NEGOTIATION, "invalid return\n");
1238 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, no more options\n");
1242 } while (counter < 100);
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);
1247 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, too many attempts\n");
1253 * gst_pad_renegotiate:
1254 * @pad: the pad to perform the negotiation on
1256 * Perform the negotiation process with the peer pad.
1258 * Returns: TRUE if the negotiation process succeded
1261 gst_pad_renegotiate (GstPad *pad)
1263 GstCaps *newcaps = NULL;
1264 GstRealPad *peerpad, *currentpad, *otherpad;
1266 gpointer data1 = NULL, data2 = NULL;
1268 g_return_val_if_fail (pad != NULL, FALSE);
1270 peerpad = GST_PAD_PEER (pad);
1272 currentpad = GST_PAD_REALIZE (pad);
1275 GST_DEBUG (GST_CAT_NEGOTIATION, "no peer pad for pad %s:%s\n",
1276 GST_DEBUG_PAD_NAME(currentpad));
1280 otherpad = GST_REAL_PAD (peerpad);
1282 GST_INFO (GST_CAT_NEGOTIATION, "negotiating pad %s:%s and %s:%s",
1283 GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad));
1285 newcaps = GST_PAD_CAPS (pad);
1287 result = gst_pad_renegotiate_func (GST_PAD (currentpad), &data1, GST_PAD (otherpad), &data2, &newcaps);
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);
1297 GST_DEBUG (GST_CAT_NEGOTIATION, "caps_nego_failed handler claims success at renego, believing\n");
1301 GST_DEBUG (GST_CAT_NEGOTIATION, "pads aggreed on caps :)\n");
1303 newcaps = GST_PAD_CAPS (pad);
1304 /* g_return_val_if_fail(newcaps != NULL, FALSE); FIXME is this valid? */
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);
1311 GST_PAD_CAPS (otherpad) = gst_caps_ref (newcaps);
1312 if (GST_RPAD_NEWCAPSFUNC (otherpad))
1313 GST_RPAD_NEWCAPSFUNC (otherpad) (GST_PAD (otherpad), newcaps);
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));
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
1332 * Proxies the negotiation pad from srcpad to destpad. Further
1333 * negotiation is done on the peers of both pad instead.
1335 * Returns: the result of the negotiation preocess.
1337 GstPadNegotiateReturn
1338 gst_pad_negotiate_proxy (GstPad *srcpad, GstPad *destpad, GstCaps **caps)
1340 GstRealPad *srcpeer;
1341 GstRealPad *destpeer;
1343 gpointer data1 = NULL, data2 = NULL;
1345 g_return_val_if_fail (srcpad != NULL, GST_PAD_NEGOTIATE_FAIL);
1346 g_return_val_if_fail (destpad != NULL, GST_PAD_NEGOTIATE_FAIL);
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));
1351 srcpeer = GST_RPAD_PEER (srcpad);
1352 destpeer = GST_RPAD_PEER (destpad);
1354 if (srcpeer && destpeer) {
1355 result = gst_pad_renegotiate_func (GST_PAD (srcpeer), &data1, GST_PAD (destpeer), &data2, caps);
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));
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);
1366 GST_PAD_CAPS (destpad) = *caps;
1367 if (GST_RPAD_NEWCAPSFUNC (destpad))
1368 GST_RPAD_NEWCAPSFUNC (destpad) (GST_PAD (destpad), *caps);
1371 GST_DEBUG (GST_CAT_NEGOTIATION, "pads did not aggree on caps :(\n");
1372 return GST_PAD_NEGOTIATE_FAIL;
1376 GST_PAD_CAPS (destpad) = *caps;
1377 if (GST_RPAD_NEWCAPSFUNC (destpad))
1378 GST_RPAD_NEWCAPSFUNC (destpad) (GST_PAD (destpad), *caps);
1381 return GST_PAD_NEGOTIATE_AGREE;
1384 #ifndef GST_DISABLE_LOADSAVE
1386 * gst_pad_save_thyself:
1387 * @pad: the pad to save
1388 * @parent: the parent XML node to save the description in
1390 * Saves the pad into an xml representation
1392 * Returns: the xml representation of the pad
1395 gst_pad_save_thyself (GstObject *object,
1398 GstRealPad *realpad;
1401 g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
1403 realpad = GST_REAL_PAD(object);
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)));
1413 xmlNewChild(parent,NULL,"peer","");
1419 * gst_pad_ghost_save_thyself:
1420 * @pad: the pad to save
1422 * @parent: the parent XML node to save the description in
1424 * Saves the ghost pad into an xml representation.
1426 * Returns: the xml representation of the pad
1429 gst_pad_ghost_save_thyself (GstPad *pad,
1435 g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
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)));
1441 /* FIXME FIXME FIXME! */
1445 #endif /* GST_DISABLE_LOADSAVE */
1447 #ifndef gst_pad_push
1450 * @pad: the pad to push
1451 * @buf: the buffer to push
1453 * Push a buffer to the peer of the pad.
1456 gst_pad_push (GstPad *pad, GstBuffer *buf)
1458 GstRealPad *peer = GST_RPAD_PEER (pad);
1460 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1462 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
1465 g_warning ("push on pad %s:%s but it is unconnected", GST_DEBUG_PAD_NAME (pad));
1468 if (peer->chainhandler) {
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);
1476 g_warning ("trying to push a NULL buffer on pad %s:%s", GST_DEBUG_PAD_NAME (peer));
1481 g_warning ("(internal error) push on pad %s:%s but it has no chainhandler", GST_DEBUG_PAD_NAME (peer));
1484 /* clean up the mess here */
1486 if (GST_IS_BUFFER (buf))
1487 gst_buffer_unref (buf);
1489 gst_event_free (GST_EVENT (buf));
1494 #ifndef gst_pad_pull
1497 * @pad: the pad to pull
1499 * Pull a buffer from the peer pad.
1501 * Returns: a new buffer from the peer pad.
1504 gst_pad_pull (GstPad *pad)
1506 GstRealPad *peer = GST_RPAD_PEER(pad);
1508 GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1510 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
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),
1519 if (peer->gethandler) {
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));
1525 buf = (peer->gethandler) (GST_PAD_CAST (peer));
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);
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),
1543 #ifndef gst_pad_pullregion
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
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.
1555 * Returns: a new buffer from the peer pad with data in the specified
1559 gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len)
1562 GstBuffer *result = NULL;
1564 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1567 peer = GST_RPAD_PEER(pad);
1568 g_return_val_if_fail (peer != NULL, NULL);
1571 gst_buffer_unref (result);
1573 GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len);
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);
1580 GST_DEBUG (GST_CAT_DATAFLOW,"no pullregionfunc\n");
1586 while (result && !(GST_BUFFER_OFFSET (result) == offset &&
1587 GST_BUFFER_SIZE (result) == len));
1595 * @pad: the pad to peek
1597 * Peek for a buffer from the peer pad.
1599 * Returns: a from the peer pad or NULL if the peer has no buffer.
1602 gst_pad_peek (GstPad *pad)
1604 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1606 return GST_RPAD_BUFPEN (GST_RPAD_PEER (pad));
1611 * @padlist: A list of pads
1613 * Wait for a buffer on the list of pads.
1615 * Returns: The pad that has a buffer available, use
1616 * #gst_pad_pull to get the buffer.
1619 gst_pad_select (GList *padlist)
1623 pad = gst_scheduler_pad_select (GST_PAD_PARENT (padlist->data)->sched, padlist);
1630 * @pad: The first pad to perform the select on
1633 * Wait for a buffer on the given of pads.
1635 * Returns: The pad that has a buffer available, use
1636 * #gst_pad_pull to get the buffer.
1639 gst_pad_selectv (GstPad *pad, ...)
1642 GList *padlist = NULL;
1648 va_start (var_args, pad);
1651 padlist = g_list_prepend (padlist, pad);
1652 pad = va_arg (var_args, GstPad *);
1654 result = gst_pad_select (padlist);
1655 g_list_free (padlist);
1662 /************************************************************************
1667 static void gst_padtemplate_class_init (GstPadTemplateClass *klass);
1668 static void gst_padtemplate_init (GstPadTemplate *templ);
1676 static GstObject *padtemplate_parent_class = NULL;
1677 static guint gst_padtemplate_signals[TEMPL_LAST_SIGNAL] = { 0 };
1680 gst_padtemplate_get_type (void)
1682 static GType padtemplate_type = 0;
1684 if (!padtemplate_type) {
1685 static const GTypeInfo padtemplate_info = {
1686 sizeof(GstPadTemplateClass),
1689 (GClassInitFunc)gst_padtemplate_class_init,
1692 sizeof(GstPadTemplate),
1694 (GInstanceInitFunc)gst_padtemplate_init,
1697 padtemplate_type = g_type_register_static(GST_TYPE_OBJECT, "GstPadTemplate", &padtemplate_info, 0);
1699 return padtemplate_type;
1703 gst_padtemplate_class_init (GstPadTemplateClass *klass)
1705 GObjectClass *gobject_class;
1706 GstObjectClass *gstobject_class;
1708 gobject_class = (GObjectClass*)klass;
1709 gstobject_class = (GstObjectClass*)klass;
1711 padtemplate_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
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,
1720 gstobject_class->path_string_separator = "*";
1724 gst_padtemplate_init (GstPadTemplate *templ)
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
1736 * Creates a new padtemplate from the given arguments.
1738 * Returns: the new padtemplate
1741 gst_padtemplate_new (gchar *name_template,
1742 GstPadDirection direction, GstPadPresence presence,
1745 GstPadTemplate *new;
1747 GstCaps *thecaps = NULL;
1749 g_return_val_if_fail (name_template != NULL, NULL);
1751 new = g_object_new(gst_padtemplate_get_type () ,NULL);
1753 GST_PADTEMPLATE_NAME_TEMPLATE (new) = name_template;
1754 GST_PADTEMPLATE_DIRECTION (new) = direction;
1755 GST_PADTEMPLATE_PRESENCE (new) = presence;
1757 va_start (var_args, caps);
1760 thecaps = gst_caps_append (thecaps, caps);
1761 caps = va_arg (var_args, GstCaps*);
1765 GST_PADTEMPLATE_CAPS (new) = thecaps;
1771 * gst_padtemplate_get_caps:
1772 * @templ: the padtemplate to use
1774 * Get the capabilities of the padtemplate
1776 * Returns: a GstCaps*
1779 gst_padtemplate_get_caps (GstPadTemplate *templ)
1781 g_return_val_if_fail (templ != NULL, NULL);
1783 return GST_PADTEMPLATE_CAPS (templ);
1786 #ifndef GST_DISABLE_LOADSAVE
1788 * gst_padtemplate_save_thyself:
1789 * @templ: the padtemplate to save
1790 * @parent: the parent XML tree
1792 * Saves the padtemplate into XML.
1794 * Returns: the new XML tree
1797 gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
1802 GST_DEBUG (GST_CAT_XML,"saving padtemplate %s\n", templ->name_template);
1804 xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
1805 xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
1807 switch (templ->presence) {
1808 case GST_PAD_ALWAYS:
1809 presence = "always";
1811 case GST_PAD_SOMETIMES:
1812 presence = "sometimes";
1814 case GST_PAD_REQUEST:
1815 presence = "request";
1818 presence = "unknown";
1821 xmlNewChild(parent,NULL,"presence", presence);
1823 if (GST_PADTEMPLATE_CAPS (templ)) {
1824 subtree = xmlNewChild (parent, NULL, "caps", NULL);
1825 gst_caps_save_thyself (GST_PADTEMPLATE_CAPS (templ), subtree);
1832 * gst_padtemplate_load_thyself:
1833 * @parent: the source XML tree
1835 * Loads a padtemplate from the XML tree.
1837 * Returns: the new padtemplate
1840 gst_padtemplate_load_thyself (xmlNodePtr parent)
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;
1850 if (!strcmp(field->name, "nametemplate")) {
1851 name_template = xmlNodeGetContent(field);
1853 if (!strcmp(field->name, "direction")) {
1854 gchar *value = xmlNodeGetContent(field);
1856 if (!strcmp(value, "sink")) {
1857 direction = GST_PAD_SINK;
1859 else if (!strcmp(value, "src")) {
1860 direction = GST_PAD_SRC;
1864 if (!strcmp(field->name, "presence")) {
1865 gchar *value = xmlNodeGetContent(field);
1867 if (!strcmp(value, "always")) {
1868 presence = GST_PAD_ALWAYS;
1870 else if (!strcmp(value, "sometimes")) {
1871 presence = GST_PAD_SOMETIMES;
1873 else if (!strcmp(value, "request")) {
1874 presence = GST_PAD_REQUEST;
1878 else if (!strcmp(field->name, "caps")) {
1879 caps = gst_caps_load_thyself (field);
1881 field = field->next;
1884 factory = gst_padtemplate_new (name_template, direction, presence, caps, NULL);
1888 #endif /* !GST_DISABLE_LOADSAVE */
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
1896 * Set the given private data pointer to the pad. This
1897 * function can only be used by the element that own the
1901 gst_pad_set_element_private (GstPad *pad, gpointer priv)
1903 pad->element_private = priv;
1907 * gst_pad_get_element_private:
1908 * @pad: the pad to get the private data of
1910 * Get the private data of a pad. The private data can
1911 * only be set by the parent element of this pad.
1913 * Returns: a pointer to the private data.
1916 gst_pad_get_element_private (GstPad *pad)
1918 return pad->element_private;
1922 /***** ghost pads *****/
1923 GType _gst_ghost_pad_type = 0;
1925 static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
1926 static void gst_ghost_pad_init (GstGhostPad *pad);
1928 static GstPad *ghost_pad_parent_class = NULL;
1929 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
1932 gst_ghost_pad_get_type(void) {
1933 if (!_gst_ghost_pad_type) {
1934 static const GTypeInfo pad_info = {
1935 sizeof(GstGhostPadClass),
1938 (GClassInitFunc)gst_ghost_pad_class_init,
1941 sizeof(GstGhostPad),
1943 (GInstanceInitFunc)gst_ghost_pad_init,
1946 _gst_ghost_pad_type = g_type_register_static(GST_TYPE_PAD, "GstGhostPad", &pad_info, 0);
1948 return _gst_ghost_pad_type;
1952 gst_ghost_pad_class_init (GstGhostPadClass *klass)
1954 GObjectClass *gobject_class;
1956 gobject_class = (GObjectClass*)klass;
1958 ghost_pad_parent_class = g_type_class_ref(GST_TYPE_PAD);
1962 gst_ghost_pad_init (GstGhostPad *pad)
1964 pad->realpad = NULL;
1968 * gst_ghost_pad_new:
1969 * @name: name of the new ghost pad
1970 * @pad: the pad to create a ghost pad of
1972 * Create a new ghost pad associated with the given pad.
1974 * Returns: new ghost pad
1977 gst_ghost_pad_new (gchar *name,
1980 GstGhostPad *ghostpad;
1982 g_return_val_if_fail (name != NULL, NULL);
1983 g_return_val_if_fail (GST_IS_PAD(pad), NULL);
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);
1990 /* add ourselves to the real pad's list of ghostpads */
1991 gst_pad_add_ghost_pad (pad, GST_PAD(ghostpad));
1993 /* FIXME need to ref the real pad here... ? */
1995 GST_DEBUG(GST_CAT_PADS,"created ghost pad \"%s\"\n",name);
1997 return GST_PAD(ghostpad);
2001 gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, GstEvent *event)
2003 GList *pads = element->pads;
2006 GstPad *eventpad = GST_PAD (pads->data);
2007 pads = g_list_next (pads);
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))));
2016 GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
2018 gst_pad_send_event (peerpad, gst_event_new (GST_EVENT_TYPE (event)));
2025 * gst_pad_event_default:
2026 * @pad: the pad to operate on
2027 * @event: the event to handle
2029 * Invoke the default event handler for the given pad.
2032 gst_pad_event_default (GstPad *pad, GstEvent *event)
2034 GstElement *element = GST_PAD_PARENT (pad);
2036 g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_EVENT_RECEIVED], 0, event);
2038 switch (GST_EVENT_TYPE (event)) {
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);
2046 case GST_EVENT_FLUSH:
2048 gst_pad_event_default_dispatch (pad, element, event);
2049 gst_event_free (event);
2055 * gst_pad_send_event:
2056 * @pad: the pad to send the event to
2057 * @event: the event to send to the pad.
2059 * Send the event to the pad.
2061 * Returns: TRUE if the event was handled.
2064 gst_pad_send_event (GstPad *pad, GstEvent *event)
2066 gboolean handled = FALSE;
2068 g_return_val_if_fail (event, FALSE);
2070 if (GST_EVENT_SRC (event) == NULL)
2071 GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (pad));
2073 GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n",
2074 GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
2076 if (GST_RPAD_EVENTFUNC (pad))
2077 handled = GST_RPAD_EVENTFUNC (pad) (pad, event);
2079 GST_DEBUG(GST_CAT_EVENT, "there's no event function for pad %s:%s\n", GST_DEBUG_PAD_NAME (pad));
2083 GST_DEBUG(GST_CAT_EVENT, "proceeding with default event behavior here\n");
2084 gst_pad_event_default (pad, event);