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"
40 static GstObject *padtemplate_parent_class = NULL;
41 static guint gst_pad_template_signals[TEMPL_LAST_SIGNAL] = { 0 };
43 GType _gst_pad_type = 0;
45 /***** Start with the base GstPad class *****/
46 static void gst_pad_class_init (GstPadClass *klass);
47 static void gst_pad_init (GstPad *pad);
49 static gboolean gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
50 GstCaps *caps, gboolean clear);
52 #ifndef GST_DISABLE_LOADSAVE
53 static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent);
56 static GstObject *pad_parent_class = NULL;
59 gst_pad_get_type(void)
62 static const GTypeInfo pad_info = {
66 (GClassInitFunc)gst_pad_class_init,
71 (GInstanceInitFunc)gst_pad_init,
74 _gst_pad_type = g_type_register_static(GST_TYPE_OBJECT, "GstPad", &pad_info, 0);
80 gst_pad_class_init (GstPadClass *klass)
82 pad_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
86 gst_pad_init (GstPad *pad)
88 pad->element_private = NULL;
90 pad->padtemplate = NULL;
95 /***** Then do the Real Pad *****/
96 /* Pad signals and args */
100 REAL_CAPS_NEGO_FAILED,
114 static void gst_real_pad_class_init (GstRealPadClass *klass);
115 static void gst_real_pad_init (GstRealPad *pad);
117 static void gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
118 static void gst_real_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
120 static void gst_real_pad_dispose (GObject *object);
122 static void gst_pad_push_func (GstPad *pad, GstBuffer *buf);
124 GType _gst_real_pad_type = 0;
126 static GstPad *real_pad_parent_class = NULL;
127 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
130 gst_real_pad_get_type(void) {
131 if (!_gst_real_pad_type) {
132 static const GTypeInfo pad_info = {
133 sizeof(GstRealPadClass),
136 (GClassInitFunc)gst_real_pad_class_init,
141 (GInstanceInitFunc)gst_real_pad_init,
144 _gst_real_pad_type = g_type_register_static(GST_TYPE_PAD, "GstRealPad", &pad_info, 0);
146 return _gst_real_pad_type;
150 gst_real_pad_class_init (GstRealPadClass *klass)
152 GObjectClass *gobject_class;
153 GstObjectClass *gstobject_class;
155 gobject_class = (GObjectClass*) klass;
156 gstobject_class = (GstObjectClass*) klass;
158 real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
160 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
161 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
162 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
164 gst_real_pad_signals[REAL_SET_ACTIVE] =
165 g_signal_new ("set_active", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
166 G_STRUCT_OFFSET (GstRealPadClass, set_active), NULL, NULL,
167 gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1,
169 gst_real_pad_signals[REAL_CAPS_CHANGED] =
170 g_signal_new ("caps_changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
171 G_STRUCT_OFFSET (GstRealPadClass, caps_changed), NULL, NULL,
172 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
174 gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
175 g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
176 G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
177 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
179 gst_real_pad_signals[REAL_CONNECTED] =
180 g_signal_new ("connected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
181 G_STRUCT_OFFSET (GstRealPadClass, connected), NULL, NULL,
182 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
184 gst_real_pad_signals[REAL_DISCONNECTED] =
185 g_signal_new ("disconnected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
186 G_STRUCT_OFFSET (GstRealPadClass, disconnected), NULL, NULL,
187 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
189 gst_real_pad_signals[REAL_EVENT_RECEIVED] =
190 g_signal_new ("event_received", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
191 G_STRUCT_OFFSET (GstRealPadClass, event_received), NULL, NULL,
192 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
195 /* gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
196 /* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
197 g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
198 g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
199 TRUE,G_PARAM_READWRITE));
201 #ifndef GST_DISABLE_LOADSAVE
202 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
204 gstobject_class->path_string_separator = ".";
208 gst_real_pad_init (GstRealPad *pad)
210 pad->direction = GST_PAD_UNKNOWN;
214 pad->sched_private = NULL;
216 pad->chainfunc = NULL;
219 pad->chainhandler = GST_DEBUG_FUNCPTR (gst_pad_push_func);
220 pad->gethandler = NULL;
222 pad->bufferpoolfunc = NULL;
223 pad->ghostpads = NULL;
226 pad->connectfunc = NULL;
227 pad->getcapsfunc = NULL;
229 pad->convertfunc = gst_pad_convert_default;
230 pad->eventfunc = gst_pad_event_default;
231 pad->convertfunc = gst_pad_convert_default;
232 pad->queryfunc = gst_pad_query_default;
233 pad->intconnfunc = gst_pad_get_internal_connections_default;
237 gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
239 g_return_if_fail (GST_IS_PAD (object));
242 case REAL_ARG_ACTIVE:
243 if (g_value_get_boolean (value)) {
244 GST_DEBUG (GST_CAT_PADS, "activating pad %s:%s", GST_DEBUG_PAD_NAME (object));
245 GST_FLAG_UNSET (object, GST_PAD_DISABLED);
247 GST_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s", GST_DEBUG_PAD_NAME (object));
248 GST_FLAG_SET (object, GST_PAD_DISABLED);
250 g_signal_emit (G_OBJECT (object), gst_real_pad_signals[REAL_SET_ACTIVE], 0,
251 !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
259 gst_real_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
261 /* it's not null if we got it, but it might not be ours */
262 g_return_if_fail (GST_IS_PAD (object));
265 case REAL_ARG_ACTIVE:
266 g_value_set_boolean (value, !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
275 * gst_pad_custom_new:
276 * @type: the type of the pad
277 * @name: name of new pad
278 * @direction: either GST_PAD_SRC or GST_PAD_SINK
280 * Create a new pad with given name from the given type.
285 gst_pad_custom_new (GType type, const gchar *name,
286 GstPadDirection direction)
290 g_return_val_if_fail (name != NULL, NULL);
291 g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
293 pad = g_object_new (type, NULL);
294 gst_object_set_name (GST_OBJECT (pad), name);
295 GST_RPAD_DIRECTION (pad) = direction;
297 return GST_PAD (pad);
302 * @name: name of new pad
303 * @direction: either GST_PAD_SRC or GST_PAD_SINK
305 * Create a new pad with given name.
310 gst_pad_new (const gchar *name,
311 GstPadDirection direction)
313 return gst_pad_custom_new (gst_real_pad_get_type (), name, direction);
316 * gst_pad_custom_new_from_template:
317 * @type: the custom GType for this pad
318 * @templ: the pad template to use
319 * @name: the name of the element
321 * Create a new pad with given name from the given template.
326 gst_pad_custom_new_from_template (GType type, GstPadTemplate *templ,
331 g_return_val_if_fail (name != NULL, NULL);
332 g_return_val_if_fail (templ != NULL, NULL);
334 pad = gst_pad_new (name, templ->direction);
336 gst_object_ref (GST_OBJECT (templ));
337 GST_PAD_PAD_TEMPLATE (pad) = templ;
339 g_signal_emit (G_OBJECT (templ), gst_pad_template_signals[TEMPL_PAD_CREATED], 0, pad);
345 * gst_pad_new_from_template:
346 * @templ: the pad template to use
347 * @name: the name of the element
349 * Create a new pad with given name from the given template.
354 gst_pad_new_from_template (GstPadTemplate *templ,
357 return gst_pad_custom_new_from_template (gst_real_pad_get_type (), templ, name);
361 * gst_pad_get_direction:
362 * @pad: the Pad to get the direction from
364 * Get the direction of the pad.
366 * Returns: the direction of the pad
369 gst_pad_get_direction (GstPad *pad)
371 g_return_val_if_fail (pad != NULL, GST_PAD_UNKNOWN);
372 g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
374 return GST_PAD_DIRECTION (pad);
379 * @pad: the pad to set the name of
380 * @name: the name of the pad
382 * Set the name of a pad.
385 gst_pad_set_name (GstPad *pad,
388 g_return_if_fail (pad != NULL);
389 g_return_if_fail (GST_IS_PAD (pad));
391 gst_object_set_name (GST_OBJECT (pad), name);
396 * @pad: the pad to get the name of
398 * Get the name of a pad.
400 * Returns: the name of the pad, don't free.
403 gst_pad_get_name (GstPad *pad)
405 g_return_val_if_fail (pad != NULL, NULL);
406 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
408 return GST_OBJECT_NAME (pad);
412 * gst_pad_set_chain_function:
413 * @pad: the pad to set the chain function for
414 * @chain: the chain function
416 * Set the given chain function for the pad.
419 gst_pad_set_chain_function (GstPad *pad,
420 GstPadChainFunction chain)
422 g_return_if_fail (pad != NULL);
423 g_return_if_fail (GST_IS_REAL_PAD (pad));
425 GST_RPAD_CHAINFUNC(pad) = chain;
426 GST_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s",
427 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain));
431 * gst_pad_set_get_function:
432 * @pad: the pad to set the get function for
433 * @get: the get function
435 * Set the given get function for the pad.
438 gst_pad_set_get_function (GstPad *pad,
439 GstPadGetFunction get)
441 g_return_if_fail (pad != NULL);
442 g_return_if_fail (GST_IS_REAL_PAD (pad));
444 GST_RPAD_GETFUNC(pad) = get;
445 GST_DEBUG (GST_CAT_PADS, "getfunc for %s:%s set to %s",
446 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
450 * gst_pad_set_event_function:
451 * @pad: the pad to set the event handler for
452 * @event: the event handler
454 * Set the given event handler for the pad.
457 gst_pad_set_event_function (GstPad *pad,
458 GstPadEventFunction event)
460 g_return_if_fail (pad != NULL);
461 g_return_if_fail (GST_IS_REAL_PAD (pad));
463 GST_RPAD_EVENTFUNC(pad) = event;
464 GST_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s set to %s",
465 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event));
469 * gst_pad_set_convert_function:
470 * @pad: the pad to set the event handler for
471 * @convert: the convert function
473 * Set the given convert function for the pad.
476 gst_pad_set_convert_function (GstPad *pad,
477 GstPadConvertFunction convert)
479 g_return_if_fail (pad != NULL);
480 g_return_if_fail (GST_IS_REAL_PAD (pad));
482 GST_RPAD_CONVERTFUNC(pad) = convert;
483 GST_DEBUG (GST_CAT_PADS, "convertfunc for %s:%s set to %s",
484 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (convert));
488 * gst_pad_set_query_function:
489 * @pad: the pad to set the event handler for
490 * @query: the query function
492 * Set the given query function for the pad.
495 gst_pad_set_query_function (GstPad *pad, GstPadQueryFunction query)
497 g_return_if_fail (pad != NULL);
498 g_return_if_fail (GST_IS_REAL_PAD (pad));
500 GST_RPAD_QUERYFUNC(pad) = query;
501 GST_DEBUG (GST_CAT_PADS, "queryfunc for %s:%s set to %s",
502 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
506 * gst_pad_set_internal_connection_function:
507 * @pad: the pad to set the internal connection function for
508 * @intconn: the internal connection function
510 * Set the given internal connection function for the pad.
513 gst_pad_set_internal_connection_function (GstPad *pad, GstPadIntConnFunction intconn)
515 g_return_if_fail (pad != NULL);
516 g_return_if_fail (GST_IS_REAL_PAD (pad));
518 GST_RPAD_INTCONNFUNC(pad) = intconn;
519 GST_DEBUG (GST_CAT_PADS, "internal connection for %s:%s set to %s",
520 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intconn));
524 * gst_pad_set_connect_function:
525 * @pad: the pad to set the connect function for
526 * @connect: the connect function
528 * Set the given connect function for the pad. It will be called
529 * when the pad is connected or reconnected with caps.
532 gst_pad_set_connect_function (GstPad *pad,
533 GstPadConnectFunction connect)
535 g_return_if_fail (pad != NULL);
536 g_return_if_fail (GST_IS_REAL_PAD (pad));
538 GST_RPAD_CONNECTFUNC (pad) = connect;
539 GST_DEBUG (GST_CAT_PADS, "connectfunc for %s:%s set to %s",
540 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (connect));
544 * gst_pad_set_getcaps_function:
545 * @pad: the pad to set the getcaps function for
546 * @getcaps: the getcaps function
548 * Set the given getcaps function for the pad.
551 gst_pad_set_getcaps_function (GstPad *pad,
552 GstPadGetCapsFunction getcaps)
554 g_return_if_fail (pad != NULL);
555 g_return_if_fail (GST_IS_REAL_PAD (pad));
557 GST_RPAD_GETCAPSFUNC (pad) = getcaps;
558 GST_DEBUG (GST_CAT_PADS, "getcapsfunc for %s:%s set to %s",
559 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
562 * gst_pad_set_bufferpool_function:
563 * @pad: the pad to set the bufferpool function for
564 * @bufpool: the bufferpool function
566 * Set the given bufferpool function for the pad.
569 gst_pad_set_bufferpool_function (GstPad *pad,
570 GstPadBufferPoolFunction bufpool)
572 g_return_if_fail (pad != NULL);
573 g_return_if_fail (GST_IS_REAL_PAD (pad));
575 GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool;
576 GST_DEBUG (GST_CAT_PADS, "bufferpoolfunc for %s:%s set to %s",
577 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (bufpool));
581 gst_pad_push_func(GstPad *pad, GstBuffer *buf)
583 if (GST_RPAD_CHAINFUNC (GST_RPAD_PEER (pad)) != NULL) {
584 GST_DEBUG (GST_CAT_DATAFLOW, "calling chain function %s",
585 GST_DEBUG_FUNCPTR_NAME (GST_RPAD_CHAINFUNC (GST_RPAD_PEER (pad))));
586 (GST_RPAD_CHAINFUNC (GST_RPAD_PEER (pad))) (pad, buf);
588 GST_DEBUG (GST_CAT_DATAFLOW, "default pad_push handler in place, no chain function");
589 g_warning ("(internal error) default pad_push in place for pad %s:%s but it has no chain function",
590 GST_DEBUG_PAD_NAME (pad));
596 * gst_pad_disconnect:
597 * @srcpad: the source pad to disconnect
598 * @sinkpad: the sink pad to disconnect
600 * Disconnects the source pad from the sink pad.
603 gst_pad_disconnect (GstPad *srcpad,
606 GstRealPad *realsrc, *realsink;
609 g_return_if_fail (srcpad != NULL);
610 g_return_if_fail (GST_IS_PAD (srcpad));
611 g_return_if_fail (sinkpad != NULL);
612 g_return_if_fail (GST_IS_PAD (sinkpad));
614 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnecting %s:%s(%p) and %s:%s(%p)",
615 GST_DEBUG_PAD_NAME (srcpad), srcpad, GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
617 /* now we need to deal with the real/ghost stuff */
618 realsrc = GST_PAD_REALIZE (srcpad);
619 realsink = GST_PAD_REALIZE (sinkpad);
621 g_return_if_fail (GST_RPAD_PEER (realsrc) != NULL);
622 g_return_if_fail (GST_RPAD_PEER (realsink) == realsrc);
624 if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
625 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
632 g_return_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
633 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK));
635 /* first clear peers */
636 GST_RPAD_PEER (realsrc) = NULL;
637 GST_RPAD_PEER (realsink) = NULL;
639 /* reset the filters, both filters are refcounted once */
640 if (GST_RPAD_FILTER (realsrc)) {
641 gst_caps_unref (GST_RPAD_FILTER (realsrc));
642 GST_RPAD_FILTER (realsink) = NULL;
643 GST_RPAD_FILTER (realsrc) = NULL;
646 /* now tell the scheduler */
647 if (GST_PAD_PARENT (realsrc)->sched)
648 gst_scheduler_pad_disconnect (GST_PAD_PARENT (realsrc)->sched, (GstPad *)realsrc, (GstPad *)realsink);
649 else if (GST_PAD_PARENT (realsink)->sched)
650 gst_scheduler_pad_disconnect (GST_PAD_PARENT (realsink)->sched, (GstPad *)realsrc, (GstPad *)realsink);
652 /* hold a reference, as they can go away in the signal handlers */
653 gst_object_ref (GST_OBJECT (realsrc));
654 gst_object_ref (GST_OBJECT (realsink));
656 /* fire off a signal to each of the pads telling them that they've been disconnected */
657 g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsink);
658 g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsrc);
660 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
661 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
663 gst_object_unref (GST_OBJECT (realsrc));
664 gst_object_unref (GST_OBJECT (realsink));
668 * gst_pad_can_connect_filtered:
669 * @srcpad: the source pad to connect
670 * @sinkpad: the sink pad to connect
671 * @filtercaps: the filter caps.
673 * Checks if the source pad and the sink pad can be connected.
674 * The filter indicates the media type that should flow trought this connection.
676 * Returns: TRUE if the pad can be connected, FALSE otherwise
679 gst_pad_can_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
681 gint num_decoupled = 0;
682 GstRealPad *realsrc, *realsink;
685 g_return_val_if_fail (srcpad != NULL, FALSE);
686 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
687 g_return_val_if_fail (sinkpad != NULL, FALSE);
688 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
690 /* now we need to deal with the real/ghost stuff */
691 realsrc = GST_PAD_REALIZE (srcpad);
692 realsink = GST_PAD_REALIZE (sinkpad);
694 g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
695 g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
696 g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, FALSE);
697 g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, FALSE);
699 if (realsrc->sched && realsink->sched) {
700 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
702 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
705 if (realsrc->sched != realsink->sched && num_decoupled != 1) {
706 g_warning ("connecting pads with different scheds requires exactly one decoupled element (queue)");
711 /* check if the directions are compatible */
712 if (!(((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
713 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) ||
714 ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
715 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK))))
723 * gst_pad_can_connect:
724 * @srcpad: the source pad to connect
725 * @sinkpad: the sink pad to connect
727 * Checks if the source pad can be connected to the sink pad.
729 * Returns: TRUE if the pads can be connected, FALSE otherwise
732 gst_pad_can_connect (GstPad *srcpad, GstPad *sinkpad)
734 return gst_pad_can_connect_filtered (srcpad, sinkpad, NULL);
738 * gst_pad_connect_filtered:
739 * @srcpad: the source pad to connect
740 * @sinkpad: the sink pad to connect
741 * @filtercaps: the filter caps.
743 * Connects the source pad to the sink pad. The filter indicates the media type
744 * that should flow trought this connection.
746 * Returns: TRUE if the pad could be connected, FALSE otherwise
749 gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
751 GstRealPad *realsrc, *realsink;
752 gint num_decoupled = 0;
755 g_return_val_if_fail (srcpad != NULL, FALSE);
756 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
757 g_return_val_if_fail (sinkpad != NULL, FALSE);
758 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
760 GST_INFO (GST_CAT_PADS, "connecting %s:%s and %s:%s",
761 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
763 /* now we need to deal with the real/ghost stuff */
764 realsrc = GST_PAD_REALIZE (srcpad);
765 realsink = GST_PAD_REALIZE (sinkpad);
767 if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
768 GST_INFO (GST_CAT_PADS, "*actually* connecting %s:%s and %s:%s",
769 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
772 g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
773 g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
774 g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, FALSE);
775 g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, FALSE);
777 if (realsrc->sched && realsink->sched) {
778 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
780 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
783 if (realsrc->sched != realsink->sched && num_decoupled != 1) {
784 g_warning ("connecting pads with different scheds requires exactly one decoupled element (queue)\n");
789 /* check for reversed directions and swap if necessary */
790 if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
791 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
798 g_return_val_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
799 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK), FALSE);
801 /* first set peers */
802 GST_RPAD_PEER (realsrc) = realsink;
803 GST_RPAD_PEER (realsink) = realsrc;
805 /* try to negotiate the pads, we don't need to clear the caps here */
806 if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, FALSE)) {
807 GST_DEBUG (GST_CAT_CAPS, "pads cannot connect");
809 GST_RPAD_PEER (realsrc) = NULL;
810 GST_RPAD_PEER (realsink) = NULL;
815 /* fire off a signal to each of the pads telling them that they've been connected */
816 g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_CONNECTED], 0, realsink);
817 g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_CONNECTED], 0, realsrc);
819 /* now tell the scheduler(s) */
821 gst_scheduler_pad_connect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
822 else if (realsink->sched)
823 gst_scheduler_pad_connect (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
825 GST_INFO (GST_CAT_PADS, "connected %s:%s and %s:%s",
826 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
827 gst_caps_debug (gst_pad_get_caps (GST_PAD_CAST (realsrc)), "caps of newly connected src pad");
834 * @srcpad: the source pad to connect
835 * @sinkpad: the sink pad to connect
837 * Connects the source pad to the sink pad.
839 * Returns: TRUE if the pad could be connected, FALSE otherwise
842 gst_pad_connect (GstPad *srcpad, GstPad *sinkpad)
844 return gst_pad_connect_filtered (srcpad, sinkpad, NULL);
848 * gst_pad_set_parent:
849 * @pad: the pad to set the parent
850 * @parent: the object to set the parent to
852 * Sets the parent object of a pad.
855 gst_pad_set_parent (GstPad *pad,
858 g_return_if_fail (pad != NULL);
859 g_return_if_fail (GST_IS_PAD (pad));
860 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
861 g_return_if_fail (parent != NULL);
862 g_return_if_fail (GST_IS_OBJECT (parent));
863 g_return_if_fail ((gpointer)pad != (gpointer)parent);
865 gst_object_set_parent (GST_OBJECT (pad), parent);
869 * gst_pad_get_parent:
870 * @pad: the pad to get the parent from
872 * Get the parent object of this pad.
874 * Returns: the parent object
877 gst_pad_get_parent (GstPad *pad)
879 g_return_val_if_fail (pad != NULL, NULL);
880 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
882 return GST_PAD_PARENT (pad);
886 * gst_pad_get_pad_template:
887 * @pad: the pad to get the padtemplate from
889 * Get the padtemplate object of this pad.
891 * Returns: the padtemplate object
894 gst_pad_get_pad_template (GstPad *pad)
896 g_return_val_if_fail (pad != NULL, NULL);
897 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
899 return GST_PAD_PAD_TEMPLATE (pad);
904 * gst_pad_set_scheduler:
905 * @pad: the pad to set the scheduler for
906 * @sched: The scheduler to set
908 * Set the scheduler for the pad
911 gst_pad_set_scheduler (GstPad *pad, GstScheduler *sched)
913 g_return_if_fail (pad != NULL);
914 g_return_if_fail (GST_IS_PAD (pad));
916 GST_RPAD_SCHED(pad) = sched;
920 * gst_pad_get_scheduler:
921 * @pad: the pad to get the scheduler from
923 * Get the scheduler of the pad
925 * Returns: the scheduler of the pad.
928 gst_pad_get_scheduler (GstPad *pad)
930 g_return_val_if_fail (pad != NULL, NULL);
931 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
933 return GST_RPAD_SCHED(pad);
937 * gst_pad_unset_scheduler:
938 * @pad: the pad to unset the scheduler for
940 * Unset the scheduler for the pad
943 gst_pad_unset_scheduler (GstPad *pad)
945 g_return_if_fail (pad != NULL);
946 g_return_if_fail (GST_IS_PAD (pad));
948 GST_RPAD_SCHED(pad) = NULL;
952 * gst_pad_get_real_parent:
953 * @pad: the pad to get the parent from
955 * Get the real parent object of this pad. If the pad
956 * is a ghostpad, the actual owner of the real pad is
957 * returned, as opposed to the gst_pad_get_parent().
959 * Returns: the parent object
962 gst_pad_get_real_parent (GstPad *pad)
964 g_return_val_if_fail (pad != NULL, NULL);
965 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
967 return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
971 * gst_pad_add_ghost_pad:
972 * @pad: the pad to set the ghost parent
973 * @ghostpad: the ghost pad to add
975 * Add a ghost pad to a pad.
978 gst_pad_add_ghost_pad (GstPad *pad,
983 g_return_if_fail (pad != NULL);
984 g_return_if_fail (GST_IS_PAD (pad));
985 g_return_if_fail (ghostpad != NULL);
986 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
988 realpad = GST_PAD_REALIZE (pad);
990 realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
995 * gst_pad_remove_ghost_pad:
996 * @pad: the pad to remove the ghost parent
997 * @ghostpad: the ghost pad to remove from the pad
999 * Remove a ghost pad from a pad.
1002 gst_pad_remove_ghost_pad (GstPad *pad,
1005 GstRealPad *realpad;
1007 g_return_if_fail (pad != NULL);
1008 g_return_if_fail (GST_IS_PAD (pad));
1009 g_return_if_fail (ghostpad != NULL);
1010 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
1012 realpad = GST_PAD_REALIZE (pad);
1014 realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
1018 * gst_pad_get_ghost_pad_list:
1019 * @pad: the pad to get the ghost parents from
1021 * Get the ghost parents of this pad.
1023 * Returns: a GList of ghost pads
1026 gst_pad_get_ghost_pad_list (GstPad *pad)
1028 g_return_val_if_fail (pad != NULL, NULL);
1029 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1031 return GST_PAD_REALIZE(pad)->ghostpads;
1034 /* an internal caps negotiation helper function does:
1036 * 1. optinally calls the pad connect function with the provided caps
1037 * 2. deal with the result code of the connect function
1038 * 3. set fixed caps on the pad.
1040 static GstPadConnectReturn
1041 gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
1044 GstPadTemplate *template;
1045 GstElement *parent = GST_PAD_PARENT (pad);
1047 /* thomas: FIXME: is this the right result to return ? */
1048 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_REFUSED);
1049 g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_CONNECT_REFUSED);
1051 /* if this pad has a parent and the parent is not READY, delay the
1053 if (parent && GST_STATE (parent) < GST_STATE_READY)
1055 GST_DEBUG (GST_CAT_CAPS, "parent %s of pad %s:%s is not ready",
1056 GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (pad));
1057 return GST_PAD_CONNECT_DELAYED;
1060 GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
1061 caps, GST_DEBUG_PAD_NAME (pad));
1063 if ((template = gst_pad_get_pad_template (GST_PAD_CAST (pad)))) {
1064 if (!gst_caps_intersect (caps, gst_pad_template_get_caps (template))) {
1065 GST_INFO (GST_CAT_CAPS, "caps did not intersect with %s:%s's padtemplate",
1066 GST_DEBUG_PAD_NAME (pad));
1067 gst_caps_debug (caps, "caps themselves (attemped to set)");
1068 gst_caps_debug (gst_pad_template_get_caps (template),
1069 "pad template caps that did not agree with caps");
1070 return GST_PAD_CONNECT_REFUSED;
1072 /* given that the caps are fixed, we know that their intersection with the
1073 * padtemplate caps is the same as caps itself */
1076 /* we need to notify the connect function */
1077 if (notify && GST_RPAD_CONNECTFUNC (pad)) {
1078 GstPadConnectReturn res;
1079 gchar *debug_string;
1081 GST_INFO (GST_CAT_CAPS, "calling connect function on pad %s:%s",
1082 GST_DEBUG_PAD_NAME (pad));
1084 /* call the connect function */
1085 res = GST_RPAD_CONNECTFUNC (pad) (GST_PAD (pad), caps);
1088 case GST_PAD_CONNECT_REFUSED:
1089 debug_string = "REFUSED";
1091 case GST_PAD_CONNECT_OK:
1092 debug_string = "OK";
1094 case GST_PAD_CONNECT_DONE:
1095 debug_string = "DONE";
1097 case GST_PAD_CONNECT_DELAYED:
1098 debug_string = "DELAYED";
1101 g_warning ("unknown return code from connect function of pad %s:%s %d",
1102 GST_DEBUG_PAD_NAME (pad), res);
1103 return GST_PAD_CONNECT_REFUSED;
1106 GST_INFO (GST_CAT_CAPS, "got reply %s (%d) from connect function on pad %s:%s",
1107 debug_string, res, GST_DEBUG_PAD_NAME (pad));
1109 /* done means the connect function called another caps negotiate function
1110 * on this pad that succeeded, we dont need to continue */
1111 if (res == GST_PAD_CONNECT_DONE) {
1112 GST_INFO (GST_CAT_CAPS, "pad %s:%s is done", GST_DEBUG_PAD_NAME (pad));
1113 return GST_PAD_CONNECT_DONE;
1115 if (res == GST_PAD_CONNECT_REFUSED) {
1116 GST_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps",
1117 GST_DEBUG_PAD_NAME (pad));
1118 return GST_PAD_CONNECT_REFUSED;
1121 /* we can only set caps on the pad if they are fixed */
1122 if (GST_CAPS_IS_FIXED (caps)) {
1124 GST_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
1125 GST_DEBUG_PAD_NAME (pad));
1126 /* if we got this far all is ok, remove the old caps, set the new one */
1127 oldcaps = GST_PAD_CAPS (pad);
1128 if (caps) gst_caps_ref (caps);
1129 GST_PAD_CAPS (pad) = caps;
1130 if (oldcaps) gst_caps_unref (oldcaps);
1133 GST_INFO (GST_CAT_CAPS, "caps are not fixed on pad %s:%s, not setting them yet",
1134 GST_DEBUG_PAD_NAME (pad));
1137 return GST_PAD_CONNECT_OK;
1141 * gst_pad_try_set_caps:
1142 * @pad: the pad to try to set the caps on
1143 * @caps: the caps to set
1145 * Try to set the caps on the given pad.
1147 * Returns: TRUE if the caps could be set
1150 gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
1152 GstRealPad *peer, *realpad;
1154 realpad = GST_PAD_REALIZE (pad);
1155 peer = GST_RPAD_PEER (realpad);
1157 GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
1158 caps, GST_DEBUG_PAD_NAME (realpad));
1160 gst_caps_debug (caps, "caps that we are trying to set");
1162 /* setting non fixed caps on a pad is not allowed */
1163 if (!GST_CAPS_IS_FIXED (caps)) {
1164 GST_INFO (GST_CAT_CAPS, "trying to set unfixed caps on pad %s:%s, not allowed",
1165 GST_DEBUG_PAD_NAME (realpad));
1166 g_warning ("trying to set non fixed caps on pad %s:%s, not allowed",
1167 GST_DEBUG_PAD_NAME (realpad));
1168 gst_caps_debug (caps, "unfixed caps");
1172 /* if we have a peer try to set the caps, notifying the peerpad
1173 * if it has a connect function */
1174 if (peer && (gst_pad_try_set_caps_func (peer, caps, TRUE) != GST_PAD_CONNECT_OK))
1176 GST_INFO (GST_CAT_CAPS, "tried to set caps on peerpad %s:%s but couldn't",
1177 GST_DEBUG_PAD_NAME (peer));
1181 /* then try to set our own caps, we don't need to be notified */
1182 if (gst_pad_try_set_caps_func (realpad, caps, FALSE) != GST_PAD_CONNECT_OK)
1184 GST_INFO (GST_CAT_CAPS, "tried to set own caps on pad %s:%s but couldn't",
1185 GST_DEBUG_PAD_NAME (realpad));
1188 GST_INFO (GST_CAT_CAPS, "succeeded setting caps %p on pad %s:%s",
1189 caps, GST_DEBUG_PAD_NAME (realpad));
1190 g_assert (GST_PAD_CAPS (pad));
1195 /* this is a caps negotiation convenience routine, it performs:
1197 * 1. optionally clear any pad caps
1198 * 2. calculate the intersection between the two pad tamplate/getcaps caps
1199 * 3. calculate the intersection with the (optional) filtercaps.
1200 * 4. store the intersection in the pad filter
1201 * 5. store the app filtercaps in the pad appfilter.
1202 * 6. start the caps negotiation.
1205 gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, GstCaps *filtercaps, gboolean clear)
1207 GstCaps *srccaps, *sinkcaps;
1208 GstCaps *intersection = NULL;
1209 GstRealPad *realsrc, *realsink;
1211 realsrc = GST_PAD_REALIZE (srcpad);
1212 realsink = GST_PAD_REALIZE (sinkpad);
1214 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1215 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1217 /* optinally clear the caps */
1219 GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s, clearing caps",
1220 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1222 GST_PAD_CAPS (GST_PAD (realsrc)) = NULL;
1223 GST_PAD_CAPS (GST_PAD (realsink)) = NULL;
1226 GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s",
1227 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1230 srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1231 GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsrc));
1232 gst_caps_debug (srccaps, "caps of src pad (pre-reconnect)");
1233 sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1234 GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsink));
1235 gst_caps_debug (sinkcaps, "caps of sink pad (pre-reconnect)");
1237 /* first take the intersection of the pad caps */
1238 intersection = gst_caps_intersect (srccaps, sinkcaps);
1240 /* if we have no intersection but one of the caps was not NULL.. */
1241 if (!intersection && (srccaps || sinkcaps)) {
1242 /* the intersection is NULL but the pad caps were not both NULL,
1243 * this means they have no common format */
1244 GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s have no common type",
1245 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1247 } else if (intersection) {
1248 GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s intersected to %s caps",
1249 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink),
1250 ((intersection && GST_CAPS_IS_FIXED (intersection)) ? "fixed" : "variable"));
1252 /* then filter this against the app filter */
1254 GstCaps *filtered_intersection = gst_caps_intersect (intersection, filtercaps);
1256 /* get rid of the old intersection here */
1257 gst_caps_unref (intersection);
1259 if (!filtered_intersection) {
1260 GST_INFO (GST_CAT_PADS, "filtered connection between pads %s:%s and %s:%s is empty",
1261 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1264 intersection = filtered_intersection;
1266 /* keep a reference to the app caps */
1267 GST_RPAD_APPFILTER (realsink) = filtercaps;
1268 GST_RPAD_APPFILTER (realsrc) = filtercaps;
1271 GST_DEBUG (GST_CAT_CAPS, "setting filter for connection to:");
1272 gst_caps_debug (intersection, "filter for connection");
1274 /* both the app filter and the filter, while stored on both peer pads, are the
1275 equal to the same thing on both */
1276 GST_RPAD_FILTER (realsrc) = intersection;
1277 GST_RPAD_FILTER (realsink) = intersection;
1279 return gst_pad_perform_negotiate (GST_PAD (realsrc), GST_PAD (realsink));
1283 * gst_pad_perform_negotiate:
1285 * @sinkpad: a sinkpad
1287 * Try to negotiate the pads.
1289 * Returns: a boolean indicating the pad succesfully negotiated.
1292 gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad)
1294 GstCaps *intersection, *filtered_intersection;
1295 GstRealPad *realsrc, *realsink;
1296 GstCaps *srccaps, *sinkcaps, *filter;
1298 g_return_val_if_fail (srcpad != NULL, FALSE);
1299 g_return_val_if_fail (sinkpad != NULL, FALSE);
1301 realsrc = GST_PAD_REALIZE (srcpad);
1302 realsink = GST_PAD_REALIZE (sinkpad);
1304 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1305 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1307 filter = GST_RPAD_APPFILTER (realsrc);
1309 GST_INFO (GST_CAT_PADS, "dumping filter for connection %s:%s-%s:%s",
1310 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1311 gst_caps_debug (filter, "connection filter caps");
1314 /* calculate the new caps here */
1315 srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1316 GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsrc));
1317 gst_caps_debug (srccaps, "src caps, awaiting negotiation, after applying filter");
1318 sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1319 GST_DEBUG (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsink));
1320 gst_caps_debug (sinkcaps, "sink caps, awaiting negotiation, after applying filter");
1321 intersection = gst_caps_intersect (srccaps, sinkcaps);
1322 filtered_intersection = gst_caps_intersect (intersection, filter);
1323 if (filtered_intersection) {
1324 gst_caps_unref (intersection);
1325 intersection = filtered_intersection;
1328 /* no negotiation is performed if the pads have filtercaps */
1330 GstPadConnectReturn res;
1332 res = gst_pad_try_set_caps_func (realsrc, intersection, TRUE);
1333 if (res == GST_PAD_CONNECT_REFUSED)
1335 if (res == GST_PAD_CONNECT_DONE)
1338 res = gst_pad_try_set_caps_func (realsink, intersection, TRUE);
1339 if (res == GST_PAD_CONNECT_REFUSED)
1341 if (res == GST_PAD_CONNECT_DONE)
1348 * gst_pad_try_reconnect_filtered:
1349 * @srcpad: the source"pad to reconnect
1350 * @sinkpad: the sink pad to reconnect
1351 * @filtercaps: the capabilities to use in the reconnectiong
1353 * Try to reconnect this pad and its peer with the specified caps
1355 * Returns: a boolean indicating the peer pad could accept the caps.
1358 gst_pad_try_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
1360 GstRealPad *realsrc, *realsink;
1362 g_return_val_if_fail (srcpad != NULL, FALSE);
1363 g_return_val_if_fail (sinkpad != NULL, FALSE);
1365 realsrc = GST_PAD_REALIZE (srcpad);
1366 realsink = GST_PAD_REALIZE (sinkpad);
1368 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1369 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1371 return gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE);
1375 * gst_pad_reconnect_filtered:
1376 * @srcpad: the source"pad to reconnect
1377 * @sinkpad: the sink pad to reconnect
1378 * @filtercaps: the capabilities to use in the reconnectiong
1380 * Try to reconnect this pad and its peer with the specified caps.
1382 * Returns: a boolean indicating the peer pad could accept the caps.
1383 * if FALSE is returned, the pads are disconnected.
1386 gst_pad_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
1388 GstRealPad *realsrc, *realsink;
1390 g_return_val_if_fail (srcpad != NULL, FALSE);
1391 g_return_val_if_fail (sinkpad != NULL, FALSE);
1393 realsrc = GST_PAD_REALIZE (srcpad);
1394 realsink = GST_PAD_REALIZE (sinkpad);
1396 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1397 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1399 if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE)) {
1400 gst_pad_disconnect (srcpad, GST_PAD (GST_PAD_PEER (srcpad)));
1407 * gst_pad_proxy_connect:
1408 * @pad: the pad to proxy to
1409 * @caps: the capabilities to use in the proxying
1411 * Proxy the connect function to the specified pad.
1413 * Returns: a boolean indicating the peer pad could accept the caps.
1416 gst_pad_proxy_connect (GstPad *pad, GstCaps *caps)
1418 GstRealPad *peer, *realpad;
1420 realpad = GST_PAD_REALIZE (pad);
1422 peer = GST_RPAD_PEER (realpad);
1424 GST_INFO (GST_CAT_CAPS, "proxy connect to pad %s:%s",
1425 GST_DEBUG_PAD_NAME (realpad));
1427 if (peer && gst_pad_try_set_caps_func (peer, caps, TRUE) < 0)
1428 return GST_PAD_CONNECT_REFUSED;
1429 if (gst_pad_try_set_caps_func (realpad, caps, FALSE) < 0)
1430 return GST_PAD_CONNECT_REFUSED;
1432 return GST_PAD_CONNECT_OK;
1437 * @pad: the pad to get the capabilities from
1439 * Get the capabilities of this pad.
1441 * Returns: the capabilities of this pad
1444 gst_pad_get_caps (GstPad *pad)
1446 GstRealPad *realpad;
1448 g_return_val_if_fail (pad != NULL, NULL);
1449 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1451 realpad = GST_PAD_REALIZE (pad);
1453 GST_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
1454 GST_DEBUG_PAD_NAME (realpad), realpad);
1456 if (GST_PAD_CAPS (realpad)) {
1457 GST_DEBUG (GST_CAT_CAPS, "using pad real caps");
1458 return GST_PAD_CAPS (realpad);
1460 else if GST_RPAD_GETCAPSFUNC (realpad) {
1461 GST_DEBUG (GST_CAT_CAPS, "using pad get function");
1462 return GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad), NULL);
1464 else if (GST_PAD_PAD_TEMPLATE (realpad)) {
1465 GST_DEBUG (GST_CAT_CAPS, "using pad template");
1466 return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (realpad));
1468 GST_DEBUG (GST_CAT_CAPS, "pad has no caps");
1474 * gst_pad_get_pad_template_caps:
1475 * @pad: the pad to get the capabilities from
1477 * Get the capabilities of this pad.
1479 * Returns: a list of the capabilities of this pad
1482 gst_pad_get_pad_template_caps (GstPad *pad)
1484 g_return_val_if_fail (pad != NULL, NULL);
1485 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1487 if (GST_PAD_PAD_TEMPLATE (pad))
1488 return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
1495 * gst_pad_template_get_caps_by_name:
1496 * @templ: the padtemplate to get the capabilities from
1497 * @name: the name of the capability to get
1499 * Get the capability with the given name from this padtemplate.
1501 * Returns: a capability or NULL if not found
1504 gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
1508 g_return_val_if_fail (templ != NULL, NULL);
1510 caps = GST_PAD_TEMPLATE_CAPS (templ);
1514 return gst_caps_get_by_name (caps, name);
1518 * gst_pad_check_compatibility:
1519 * @srcpad: the srcpad to check
1520 * @sinkpad: the sinkpad to check against
1522 * Check if two pads have compatible capabilities.
1524 * Returns: TRUE if they are compatible or the capabilities
1525 * could not be checked
1528 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
1530 g_return_val_if_fail (srcpad != NULL, FALSE);
1531 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1532 g_return_val_if_fail (sinkpad != NULL, FALSE);
1533 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1535 if (GST_PAD_CAPS (srcpad) && GST_PAD_CAPS (sinkpad)) {
1536 if (!gst_caps_check_compatibility (GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad))) {
1544 GST_DEBUG (GST_CAT_PADS, "could not check capabilities of pads (%s:%s) and (%s:%s) %p %p",
1545 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
1546 GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
1553 * @pad: the pad to get the peer from
1555 * Get the peer pad of this pad.
1557 * Returns: the peer pad
1560 gst_pad_get_peer (GstPad *pad)
1562 g_return_val_if_fail (pad != NULL, NULL);
1563 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1565 return GST_PAD (GST_PAD_PEER (pad));
1569 * gst_pad_get_allowed_caps:
1570 * @pad: the pad to get the allowed caps from
1572 * Get the caps of the allowed media types that can
1573 * go through this pad.
1575 * Returns: the allowed caps, newly allocated
1578 gst_pad_get_allowed_caps (GstPad *pad)
1580 g_return_val_if_fail (pad != NULL, NULL);
1581 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1583 GST_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s", GST_DEBUG_PAD_NAME (pad));
1585 return gst_caps_copy (GST_RPAD_FILTER (pad));
1589 * gst_pad_recalc_allowed_caps:
1590 * @pad: the pad to recaculate the caps of
1592 * Attempt to reconnect the pad to its peer through its filter,
1593 * set with gst_pad_[re]connect_filtered. This function is useful when a
1594 * plugin has new capabilities on a pad and wants to notify the peer.
1596 * Returns: TRUE on success, FALSE otherwise.
1599 gst_pad_recalc_allowed_caps (GstPad *pad)
1603 g_return_val_if_fail (pad != NULL, FALSE);
1604 g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1606 GST_DEBUG (GST_CAT_PROPERTIES, "set allowed caps of %s:%s", GST_DEBUG_PAD_NAME (pad));
1608 peer = GST_RPAD_PEER (pad);
1610 return gst_pad_try_reconnect_filtered (pad, GST_PAD (peer), GST_RPAD_APPFILTER (pad));
1616 * gst_pad_get_bufferpool:
1617 * @pad: the pad to get the bufferpool from
1619 * Get the bufferpool of the peer pad of the given
1622 * Returns: The GstBufferPool or NULL.
1625 gst_pad_get_bufferpool (GstPad *pad)
1629 g_return_val_if_fail (pad != NULL, NULL);
1630 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1632 peer = GST_RPAD_PEER (pad);
1637 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1639 if (peer->bufferpoolfunc) {
1640 GST_DEBUG (GST_CAT_PADS, "calling bufferpoolfunc &%s (@%p) of peer pad %s:%s",
1641 GST_DEBUG_FUNCPTR_NAME (peer->bufferpoolfunc), &peer->bufferpoolfunc, GST_DEBUG_PAD_NAME (((GstPad*) peer)));
1642 return (peer->bufferpoolfunc) (((GstPad*) peer));
1644 GST_DEBUG (GST_CAT_PADS, "no bufferpoolfunc for peer pad %s:%s at %p",
1645 GST_DEBUG_PAD_NAME (((GstPad*) peer)), &peer->bufferpoolfunc);
1651 gst_real_pad_dispose (GObject *object)
1653 GstPad *pad = GST_PAD (object);
1655 /* No connected pad can ever be disposed.
1656 * It has to have a parent to be connected and a parent would hold a reference */
1657 g_assert (GST_PAD_PEER (pad) == NULL);
1659 GST_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s", GST_DEBUG_PAD_NAME(pad));
1661 if (GST_PAD_PAD_TEMPLATE (pad)){
1662 GST_DEBUG (GST_CAT_REFCOUNTING, "unreffing padtemplate'%s'", GST_OBJECT_NAME (GST_PAD_PAD_TEMPLATE (pad)));
1663 gst_object_unref (GST_OBJECT (GST_PAD_PAD_TEMPLATE (pad)));
1664 GST_PAD_PAD_TEMPLATE (pad) = NULL;
1667 /* we destroy the ghostpads, because they are nothing without the real pad */
1668 if (GST_REAL_PAD (pad)->ghostpads) {
1669 GList *orig, *ghostpads;
1671 orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
1674 GstPad *ghostpad = GST_PAD (ghostpads->data);
1676 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))){
1677 GST_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'",
1678 GST_OBJECT_NAME (GST_OBJECT_PARENT (ghostpad)));
1680 gst_element_remove_ghost_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), GST_PAD (ghostpad));
1682 ghostpads = g_list_next (ghostpads);
1685 g_list_free (GST_REAL_PAD(pad)->ghostpads);
1688 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))){
1689 GST_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
1690 GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
1692 gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
1695 G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
1699 #ifndef GST_DISABLE_LOADSAVE
1701 * gst_pad_load_and_connect:
1702 * @self: the XML node to read the description from
1703 * @parent: the element that has the pad
1705 * Read the pad definition from the XML node and connect the given pad
1706 * in element to a pad of an element up in the hierarchy.
1709 gst_pad_load_and_connect (xmlNodePtr self,
1712 xmlNodePtr field = self->xmlChildrenNode;
1713 GstPad *pad = NULL, *targetpad;
1714 guchar *peer = NULL;
1717 GstObject *grandparent;
1720 if (!strcmp (field->name, "name")) {
1721 pad = gst_element_get_pad (GST_ELEMENT (parent), xmlNodeGetContent (field));
1723 else if (!strcmp(field->name, "peer")) {
1724 peer = xmlNodeGetContent (field);
1726 field = field->next;
1728 g_return_if_fail (pad != NULL);
1730 if (peer == NULL) return;
1732 split = g_strsplit (peer, ".", 2);
1734 g_return_if_fail (split[0] != NULL);
1735 g_return_if_fail (split[1] != NULL);
1737 grandparent = gst_object_get_parent (parent);
1739 if (grandparent && GST_IS_BIN (grandparent)) {
1740 target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
1745 if (target == NULL) goto cleanup;
1747 targetpad = gst_element_get_pad (target, split[1]);
1749 if (targetpad == NULL) goto cleanup;
1751 gst_pad_connect (pad, targetpad);
1758 * gst_pad_save_thyself:
1759 * @pad: the pad to save
1760 * @parent: the parent XML node to save the description in
1762 * Saves the pad into an xml representation
1764 * Returns: the xml representation of the pad
1767 gst_pad_save_thyself (GstObject *object,
1770 GstRealPad *realpad;
1773 g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
1775 realpad = GST_REAL_PAD(object);
1777 xmlNewChild(parent,NULL,"name", GST_PAD_NAME (realpad));
1778 if (GST_RPAD_PEER(realpad) != NULL) {
1779 peer = GST_PAD(GST_RPAD_PEER(realpad));
1780 /* first check to see if the peer's parent's parent is the same */
1781 /* we just save it off */
1782 xmlNewChild(parent,NULL,"peer",g_strdup_printf("%s.%s",
1783 GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer)));
1785 xmlNewChild(parent,NULL,"peer","");
1791 * gst_pad_ghost_save_thyself:
1792 * @pad: the pad to save
1794 * @parent: the parent XML node to save the description in
1796 * Saves the ghost pad into an xml representation.
1798 * Returns: the xml representation of the pad
1801 gst_pad_ghost_save_thyself (GstPad *pad,
1807 g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
1809 self = xmlNewChild (parent, NULL, "ghostpad", NULL);
1810 xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
1811 xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
1813 /* FIXME FIXME FIXME! */
1817 #endif /* GST_DISABLE_LOADSAVE */
1819 #ifndef gst_pad_push
1822 * @pad: the pad to push
1823 * @buf: the buffer to push
1825 * Push a buffer to the peer of the pad.
1828 gst_pad_push (GstPad *pad, GstBuffer *buf)
1830 GstRealPad *peer = GST_RPAD_PEER (pad);
1832 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1834 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
1837 g_warning ("push on pad %s:%s but it is unconnected", GST_DEBUG_PAD_NAME (pad));
1840 if (peer->chainhandler) {
1842 GST_DEBUG (GST_CAT_DATAFLOW, "calling chainhandler &%s of peer pad %s:%s",
1843 GST_DEBUG_FUNCPTR_NAME (peer->chainhandler), GST_DEBUG_PAD_NAME (GST_PAD (peer)));
1844 (peer->chainhandler) (GST_PAD_CAST (peer), buf);
1848 g_warning ("trying to push a NULL buffer on pad %s:%s", GST_DEBUG_PAD_NAME (peer));
1853 g_warning ("(internal error) push on pad %s:%s but it has no chainhandler", GST_DEBUG_PAD_NAME (peer));
1856 /* clean up the mess here */
1858 if (GST_IS_BUFFER (buf))
1859 gst_buffer_unref (buf);
1861 gst_event_free (GST_EVENT (buf));
1866 #ifndef gst_pad_pull
1869 * @pad: the pad to pull
1871 * Pull a buffer from the peer pad.
1873 * Returns: a new buffer from the peer pad.
1876 gst_pad_pull (GstPad *pad)
1880 peer = GST_RPAD_PEER (pad);
1882 GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1884 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1887 gst_element_error (GST_PAD_PARENT (pad),
1888 "pull on pad %s:%s but it was unconnected",
1889 GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
1893 if (peer->gethandler) {
1896 GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s",
1897 GST_DEBUG_FUNCPTR_NAME (peer->gethandler), GST_DEBUG_PAD_NAME (peer));
1899 buf = (peer->gethandler) (GST_PAD_CAST (peer));
1904 /* no null buffers allowed */
1905 gst_element_error (GST_PAD_PARENT (pad),
1906 "NULL buffer during pull on %s:%s", GST_DEBUG_PAD_NAME (pad), NULL);
1909 gst_element_error (GST_PAD_PARENT (pad),
1910 "(internal error) pull on pad %s:%s but the peer pad %s:%s has no gethandler",
1911 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer),
1921 * @pad: the pad to peek
1923 * Peek for a buffer from the peer pad.
1925 * Returns: a from the peer pad or NULL if the peer has no buffer.
1928 gst_pad_peek (GstPad *pad)
1930 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1932 return GST_RPAD_BUFPEN (GST_RPAD_PEER (pad));
1937 * @padlist: A list of pads
1939 * Wait for a buffer on the list of pads.
1941 * Returns: The pad that has a buffer available, use
1942 * #gst_pad_pull to get the buffer.
1945 gst_pad_select (GList *padlist)
1949 pad = gst_scheduler_pad_select (GST_PAD_PARENT (padlist->data)->sched, padlist);
1956 * @pad: The first pad to perform the select on
1959 * Wait for a buffer on the given of pads.
1961 * Returns: The pad that has a buffer available, use
1962 * #gst_pad_pull to get the buffer.
1965 gst_pad_selectv (GstPad *pad, ...)
1968 GList *padlist = NULL;
1974 va_start (var_args, pad);
1977 padlist = g_list_prepend (padlist, pad);
1978 pad = va_arg (var_args, GstPad *);
1980 result = gst_pad_select (padlist);
1981 g_list_free (padlist);
1988 /************************************************************************
1993 static void gst_pad_template_class_init (GstPadTemplateClass *klass);
1994 static void gst_pad_template_init (GstPadTemplate *templ);
1997 gst_pad_template_get_type (void)
1999 static GType padtemplate_type = 0;
2001 if (!padtemplate_type) {
2002 static const GTypeInfo padtemplate_info = {
2003 sizeof(GstPadTemplateClass),
2006 (GClassInitFunc)gst_pad_template_class_init,
2009 sizeof(GstPadTemplate),
2011 (GInstanceInitFunc)gst_pad_template_init,
2014 padtemplate_type = g_type_register_static(GST_TYPE_OBJECT, "GstPadTemplate", &padtemplate_info, 0);
2016 return padtemplate_type;
2020 gst_pad_template_class_init (GstPadTemplateClass *klass)
2022 GObjectClass *gobject_class;
2023 GstObjectClass *gstobject_class;
2025 gobject_class = (GObjectClass*)klass;
2026 gstobject_class = (GstObjectClass*)klass;
2028 padtemplate_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
2030 gst_pad_template_signals[TEMPL_PAD_CREATED] =
2031 g_signal_new ("pad_created", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
2032 G_STRUCT_OFFSET (GstPadTemplateClass, pad_created), NULL, NULL,
2033 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
2037 gstobject_class->path_string_separator = "*";
2041 gst_pad_template_init (GstPadTemplate *templ)
2045 /* ALWAYS padtemplates cannot have conversion specifications, it doesn't make
2047 * SOMETIMES padtemplates can do whatever they want, they are provided by the
2049 * REQUEST padtemplates can be reverse-parsed (the user asks for 'sink1', the
2050 * 'sink%d' template is automatically selected), so we need to restrict their
2054 name_is_valid (const gchar *name, GstPadPresence presence)
2058 if (presence == GST_PAD_ALWAYS) {
2059 if (strchr (name, '%')) {
2060 g_warning ("invalid name template %s: conversion specifications are not"
2061 " allowed for GST_PAD_ALWAYS padtemplates", name);
2064 } else if (presence == GST_PAD_REQUEST) {
2065 if ((str = strchr (name, '%')) && strchr (str + 1, '%')) {
2066 g_warning ("invalid name template %s: only one conversion specification"
2067 " allowed in GST_PAD_REQUEST padtemplate", name);
2070 if (str && (*(str+1) != 's' && *(str+1) != 'd')) {
2071 g_warning ("invalid name template %s: conversion specification must be of"
2072 " type '%%d' or '%%s' for GST_PAD_REQUEST padtemplate", name);
2075 if (str && (*(str+2) != '\0')) {
2076 g_warning ("invalid name template %s: conversion specification must appear"
2077 " at the end of the GST_PAD_REQUEST padtemplate name", name);
2086 * gst_pad_template_new:
2087 * @name_template: the name template
2088 * @direction: the direction for the template
2089 * @presence: the presence of the pad
2090 * @caps: a list of capabilities for the template
2091 * @...: more capabilities
2093 * Creates a new padtemplate from the given arguments.
2095 * Returns: the new padtemplate
2098 gst_pad_template_new (const gchar *name_template,
2099 GstPadDirection direction, GstPadPresence presence,
2102 GstPadTemplate *new;
2104 GstCaps *thecaps = NULL;
2106 g_return_val_if_fail (name_template != NULL, NULL);
2108 if (!name_is_valid (name_template, presence))
2111 new = g_object_new (gst_pad_template_get_type (),
2112 "name", name_template,
2115 GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name_template);
2116 GST_PAD_TEMPLATE_DIRECTION (new) = direction;
2117 GST_PAD_TEMPLATE_PRESENCE (new) = presence;
2119 va_start (var_args, caps);
2122 new->fixed &= caps->fixed;
2123 thecaps = gst_caps_append (thecaps, caps);
2124 caps = va_arg (var_args, GstCaps*);
2128 GST_PAD_TEMPLATE_CAPS (new) = thecaps;
2134 * gst_pad_template_get_caps:
2135 * @templ: the padtemplate to use
2137 * Get the capabilities of the padtemplate
2139 * Returns: a GstCaps*
2142 gst_pad_template_get_caps (GstPadTemplate *templ)
2144 g_return_val_if_fail (templ != NULL, NULL);
2146 return GST_PAD_TEMPLATE_CAPS (templ);
2150 * gst_pad_set_element_private:
2151 * @pad: the pad to set the private data to
2152 * @priv: The private data to attach to the pad
2154 * Set the given private data pointer to the pad. This
2155 * function can only be used by the element that own the
2159 gst_pad_set_element_private (GstPad *pad, gpointer priv)
2161 pad->element_private = priv;
2165 * gst_pad_get_element_private:
2166 * @pad: the pad to get the private data of
2168 * Get the private data of a pad. The private data can
2169 * only be set by the parent element of this pad.
2171 * Returns: a pointer to the private data.
2174 gst_pad_get_element_private (GstPad *pad)
2176 return pad->element_private;
2180 /***** ghost pads *****/
2181 GType _gst_ghost_pad_type = 0;
2183 static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
2184 static void gst_ghost_pad_init (GstGhostPad *pad);
2186 static GstPad *ghost_pad_parent_class = NULL;
2187 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
2190 gst_ghost_pad_get_type (void)
2192 if (!_gst_ghost_pad_type) {
2193 static const GTypeInfo pad_info = {
2194 sizeof (GstGhostPadClass),
2197 (GClassInitFunc) gst_ghost_pad_class_init,
2200 sizeof(GstGhostPad),
2202 (GInstanceInitFunc) gst_ghost_pad_init,
2205 _gst_ghost_pad_type = g_type_register_static (GST_TYPE_PAD, "GstGhostPad", &pad_info, 0);
2207 return _gst_ghost_pad_type;
2211 gst_ghost_pad_class_init (GstGhostPadClass *klass)
2213 GObjectClass *gobject_class;
2215 gobject_class = (GObjectClass*) klass;
2217 ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
2221 gst_ghost_pad_init (GstGhostPad *pad)
2223 pad->realpad = NULL;
2227 * gst_ghost_pad_new:
2228 * @name: name of the new ghost pad
2229 * @pad: the pad to create a ghost pad of
2231 * Create a new ghost pad associated with the given pad.
2233 * Returns: new ghost pad
2236 gst_ghost_pad_new (gchar *name,
2239 GstGhostPad *ghostpad;
2240 GstRealPad *realpad;
2242 g_return_val_if_fail (name != NULL, NULL);
2243 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2245 ghostpad = g_object_new (gst_ghost_pad_get_type () ,NULL);
2246 gst_pad_set_name (GST_PAD (ghostpad), name);
2248 realpad = (GstRealPad *) pad;
2250 while (!GST_IS_REAL_PAD (realpad)) {
2251 realpad = GST_PAD_REALIZE (realpad);
2253 GST_GPAD_REALPAD (ghostpad) = realpad;
2254 GST_PAD_PAD_TEMPLATE (ghostpad) = GST_PAD_PAD_TEMPLATE (pad);
2256 /* add ourselves to the real pad's list of ghostpads */
2257 gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));
2259 /* FIXME need to ref the real pad here... ? */
2261 GST_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\"", name);
2263 return GST_PAD (ghostpad);
2267 * gst_pad_get_internal_connections_default:
2268 * @pad: the pad to get the internal connections of
2270 * Get a GList of pads that this pad is connected to internally
2271 * to the parent element.
2273 * Returns: a GList of pads, g_list_free after use.
2276 gst_pad_get_internal_connections_default (GstPad *pad)
2281 GstPadDirection direction;
2284 g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2286 rpad = GST_PAD_REALIZE (pad);
2287 direction = rpad->direction;
2289 parent = GST_PAD_PARENT (rpad);
2290 parent_pads = parent->pads;
2292 while (parent_pads) {
2293 GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data);
2295 if (parent_pad->direction != direction) {
2296 res = g_list_prepend (res, parent_pad);
2299 parent_pads = g_list_next (parent_pads);
2306 * gst_pad_get_internal_connections:
2307 * @pad: the pad to get the internal connections of
2309 * Get a GList of pads that this pad is connected to internally
2310 * to the parent element.
2312 * Returns: a GList of pads, g_list_free after use.
2315 gst_pad_get_internal_connections (GstPad *pad)
2320 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2322 rpad = GST_PAD_REALIZE (pad);
2324 if (GST_RPAD_INTCONNFUNC (rpad))
2325 res = GST_RPAD_INTCONNFUNC (rpad) (GST_PAD_CAST (rpad));
2332 gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, GstEvent *event)
2334 GList *pads = element->pads;
2337 GstPad *eventpad = GST_PAD (pads->data);
2338 pads = g_list_next (pads);
2340 /* for all pads in the opposite direction that are connected */
2341 if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) && GST_PAD_IS_CONNECTED (eventpad)) {
2342 if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
2343 gst_pad_push (eventpad, GST_BUFFER (gst_event_copy (event)));
2346 GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
2348 /* we only send the event on one pad, multi-sinkpad elements should implement
2350 return gst_pad_send_event (peerpad, event);
2358 * gst_pad_event_default:
2359 * @pad: the pad to operate on
2360 * @event: the event to handle
2362 * Invoke the default event handler for the given pad.
2364 * Returns: TRUE if the event was sent succesfully.
2367 gst_pad_event_default (GstPad *pad, GstEvent *event)
2369 GstElement *element = GST_PAD_PARENT (pad);
2371 g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_EVENT_RECEIVED], 0, event);
2373 switch (GST_EVENT_TYPE (event)) {
2375 gst_pad_event_default_dispatch (pad, element, event);
2376 gst_element_set_eos (element);
2377 /* we have to try to schedule another element because this one is disabled */
2378 gst_element_yield (element);
2380 case GST_EVENT_DISCONTINUOUS:
2384 if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)) {
2385 if (element->setclockfunc && element->clock) {
2386 gst_clock_handle_discont (element->clock, time);
2390 case GST_EVENT_FLUSH:
2392 return gst_pad_event_default_dispatch (pad, element, event);
2398 * gst_pad_dispatcher:
2399 * @pad: the pad to dispatch
2400 * @dispatch: the GstDispatcherFunc to call
2401 * @data: data passed to the dispatcher function.
2403 * Invoke the given dispatcher function on all internally connected
2404 * pads of the given pad. The GstPadDispatcherFunc should return
2405 * TRUE when no further pads need to be preocessed.
2407 * Returns: TRUE if one of the dispatcher functions returned TRUE.
2410 gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunc dispatch, gpointer data)
2412 gboolean res = FALSE;
2413 GList *int_pads, *orig;
2415 g_return_val_if_fail (pad, FALSE);
2416 g_return_val_if_fail (data, FALSE);
2418 orig = int_pads = gst_pad_get_internal_connections (pad);
2421 GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data);
2422 GstRealPad *int_peer = GST_RPAD_PEER (int_rpad);
2424 if (int_peer && GST_PAD_IS_CONNECTED (int_peer)) {
2425 res = dispatch (GST_PAD_CAST (int_peer), data);
2429 int_pads = g_list_next (int_pads);
2438 * gst_pad_send_event:
2439 * @pad: the pad to send the event to
2440 * @event: the event to send to the pad.
2442 * Send the event to the pad.
2444 * Returns: TRUE if the event was handled.
2447 gst_pad_send_event (GstPad *pad, GstEvent *event)
2449 gboolean success = FALSE;
2451 g_return_val_if_fail (event, FALSE);
2453 if (!pad || (GST_PAD_IS_SINK (pad) && !GST_PAD_IS_CONNECTED (pad)))
2456 if (GST_EVENT_SRC (event) == NULL)
2457 GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (pad));
2459 GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s",
2460 GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
2462 if (GST_RPAD_EVENTFUNC (pad))
2463 success = GST_RPAD_EVENTFUNC (pad) (pad, event);
2465 GST_DEBUG(GST_CAT_EVENT, "there's no event function for pad %s:%s", GST_DEBUG_PAD_NAME (pad));
2473 GstFormat src_format;
2475 GstFormat *dest_format;
2477 } GstPadConvertData;
2480 gst_pad_convert_dispatcher (GstPad *pad, GstPadConvertData *data)
2482 return gst_pad_convert (pad, data->src_format, data->src_value,
2483 data->dest_format, data->dest_value);
2487 * gst_pad_convert_default:
2488 * @pad: the pad to invoke the default converter on
2489 * @src_format: the source format
2490 * @src_value: the source value
2491 * @dest_format: a pointer to the destination format
2492 * @dest_value: a pointer to the destination value
2494 * Invoke the default converter on a pad. This will forward the
2495 * call to the pad obtained using the internal connection of
2498 * Returns: TRUE if the conversion could be performed.
2501 gst_pad_convert_default (GstPad *pad,
2502 GstFormat src_format, gint64 src_value,
2503 GstFormat *dest_format, gint64 *dest_value)
2505 GstPadConvertData data;
2507 g_return_val_if_fail (pad, FALSE);
2508 g_return_val_if_fail (dest_format, FALSE);
2509 g_return_val_if_fail (dest_value, FALSE);
2511 data.src_format = src_format;
2512 data.src_value = src_value;
2513 data.dest_format = dest_format;
2514 data.dest_value = dest_value;
2516 return gst_pad_dispatcher (pad, (GstPadDispatcherFunc) gst_pad_convert_dispatcher, &data);
2521 * @pad: the pad to invoke the converter on
2522 * @src_format: the source format
2523 * @src_value: the source value
2524 * @dest_format: a pointer to the destination format
2525 * @dest_value: a pointer to the destination value
2527 * Invoke a conversion on the pad.
2529 * Returns: TRUE if the conversion could be performed.
2532 gst_pad_convert (GstPad *pad,
2533 GstFormat src_format, gint64 src_value,
2534 GstFormat *dest_format, gint64 *dest_value)
2538 g_return_val_if_fail (pad, FALSE);
2539 g_return_val_if_fail (dest_format, FALSE);
2540 g_return_val_if_fail (dest_value, FALSE);
2542 if (src_format == *dest_format) {
2543 *dest_value = src_value;
2547 rpad = GST_PAD_REALIZE (pad);
2549 g_return_val_if_fail (rpad, FALSE);
2551 if (GST_RPAD_CONVERTFUNC (rpad)) {
2552 return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD_CAST (rpad), src_format, src_value, dest_format, dest_value);
2560 GstPadQueryType type;
2566 gst_pad_query_dispatcher (GstPad *pad, GstPadQueryData *data)
2568 return gst_pad_query (pad, data->type, data->format, data->value);
2572 * gst_pad_query_default:
2573 * @pad: the pad to invoke the default query on
2574 * @type: the type of query to perform
2575 * @format: a pointer to the format of the query
2576 * @value: a pointer to the result of the query
2578 * Invoke the default query function on a pad.
2580 * Returns: TRUE if the query could be performed.
2583 gst_pad_query_default (GstPad *pad, GstPadQueryType type,
2584 GstFormat *format, gint64 *value)
2586 GstPadQueryData data;
2588 g_return_val_if_fail (pad, FALSE);
2589 g_return_val_if_fail (format, FALSE);
2590 g_return_val_if_fail (value, FALSE);
2593 data.format = format;
2596 return gst_pad_dispatcher (pad, (GstPadDispatcherFunc) gst_pad_query_dispatcher, &data);
2601 * @pad: the pad to invoke the query on
2602 * @type: the type of query to perform
2603 * @format: a pointer to the format of the query
2604 * @value: a pointer to the result of the query
2606 * Query a pad for one of the available GstPadQuery properties.
2608 * Returns: TRUE if the query could be performed.
2611 gst_pad_query (GstPad *pad, GstPadQueryType type,
2612 GstFormat *format, gint64 *value)
2619 g_return_val_if_fail (format, FALSE);
2620 g_return_val_if_fail (value, FALSE);
2622 rpad = GST_PAD_REALIZE (pad);
2624 g_return_val_if_fail (rpad, FALSE);
2626 if (GST_RPAD_QUERYFUNC (rpad))
2627 return GST_RPAD_QUERYFUNC (rpad) (GST_PAD_CAST (pad), type, format, value);