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 static gboolean gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
41 GstCaps *caps, gboolean clear);
43 #ifndef GST_DISABLE_LOADSAVE
44 static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent);
47 static GstObject *pad_parent_class = NULL;
50 gst_pad_get_type(void)
53 static const GTypeInfo pad_info = {
57 (GClassInitFunc)gst_pad_class_init,
62 (GInstanceInitFunc)gst_pad_init,
65 _gst_pad_type = g_type_register_static(GST_TYPE_OBJECT, "GstPad", &pad_info, 0);
71 gst_pad_class_init (GstPadClass *klass)
73 pad_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
77 gst_pad_init (GstPad *pad)
79 pad->element_private = NULL;
81 pad->padtemplate = NULL;
86 /***** Then do the Real Pad *****/
87 /* Pad signals and args */
91 REAL_CAPS_NEGO_FAILED,
105 static void gst_real_pad_class_init (GstRealPadClass *klass);
106 static void gst_real_pad_init (GstRealPad *pad);
108 static void gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
109 static void gst_real_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
111 static void gst_real_pad_dispose (GObject *object);
113 static void gst_pad_push_func (GstPad *pad, GstBuffer *buf);
115 GType _gst_real_pad_type = 0;
117 static GstPad *real_pad_parent_class = NULL;
118 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
121 gst_real_pad_get_type(void) {
122 if (!_gst_real_pad_type) {
123 static const GTypeInfo pad_info = {
124 sizeof(GstRealPadClass),
127 (GClassInitFunc)gst_real_pad_class_init,
132 (GInstanceInitFunc)gst_real_pad_init,
135 _gst_real_pad_type = g_type_register_static(GST_TYPE_PAD, "GstRealPad", &pad_info, 0);
137 return _gst_real_pad_type;
141 gst_real_pad_class_init (GstRealPadClass *klass)
143 GObjectClass *gobject_class;
144 GstObjectClass *gstobject_class;
146 gobject_class = (GObjectClass*) klass;
147 gstobject_class = (GstObjectClass*) klass;
149 real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
151 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
152 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
153 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
155 gst_real_pad_signals[REAL_SET_ACTIVE] =
156 g_signal_new ("set_active", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
157 G_STRUCT_OFFSET (GstRealPadClass, set_active), NULL, NULL,
158 gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1,
160 gst_real_pad_signals[REAL_CAPS_CHANGED] =
161 g_signal_new ("caps_changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
162 G_STRUCT_OFFSET (GstRealPadClass, caps_changed), NULL, NULL,
163 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
165 gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
166 g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
167 G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
168 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
170 gst_real_pad_signals[REAL_CONNECTED] =
171 g_signal_new ("connected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
172 G_STRUCT_OFFSET (GstRealPadClass, connected), NULL, NULL,
173 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
175 gst_real_pad_signals[REAL_DISCONNECTED] =
176 g_signal_new ("disconnected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
177 G_STRUCT_OFFSET (GstRealPadClass, disconnected), NULL, NULL,
178 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
180 gst_real_pad_signals[REAL_EVENT_RECEIVED] =
181 g_signal_new ("event_received", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
182 G_STRUCT_OFFSET (GstRealPadClass, event_received), NULL, NULL,
183 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
186 /* gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
187 /* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
188 g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
189 g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
190 TRUE,G_PARAM_READWRITE));
192 #ifndef GST_DISABLE_LOADSAVE
193 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
195 gstobject_class->path_string_separator = ".";
199 gst_real_pad_init (GstRealPad *pad)
201 pad->direction = GST_PAD_UNKNOWN;
205 pad->sched_private = NULL;
207 pad->chainfunc = NULL;
209 pad->getregionfunc = NULL;
211 pad->chainhandler = GST_DEBUG_FUNCPTR (gst_pad_push_func);
212 pad->gethandler = NULL;
213 pad->pullregionfunc = NULL;
215 pad->bufferpoolfunc = NULL;
216 pad->ghostpads = NULL;
219 pad->connectfunc = NULL;
220 pad->getcapsfunc = NULL;
224 gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
226 g_return_if_fail (GST_IS_PAD (object));
229 case REAL_ARG_ACTIVE:
230 if (g_value_get_boolean (value)) {
231 GST_DEBUG (GST_CAT_PADS, "activating pad %s:%s\n", GST_DEBUG_PAD_NAME (object));
232 GST_FLAG_UNSET (object, GST_PAD_DISABLED);
234 GST_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s\n", GST_DEBUG_PAD_NAME (object));
235 GST_FLAG_SET (object, GST_PAD_DISABLED);
237 g_signal_emit (G_OBJECT (object), gst_real_pad_signals[REAL_SET_ACTIVE], 0,
238 !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
246 gst_real_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
248 /* it's not null if we got it, but it might not be ours */
249 g_return_if_fail (GST_IS_PAD (object));
252 case REAL_ARG_ACTIVE:
253 g_value_set_boolean (value, !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
263 * @name: name of new pad
264 * @direction: either GST_PAD_SRC or GST_PAD_SINK
266 * Create a new pad with given name.
271 gst_pad_new (gchar *name,
272 GstPadDirection direction)
276 g_return_val_if_fail (name != NULL, NULL);
277 g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
279 pad = g_object_new (gst_real_pad_get_type (), NULL);
280 gst_object_set_name (GST_OBJECT (pad), name);
281 GST_RPAD_DIRECTION (pad) = direction;
283 return GST_PAD (pad);
287 * gst_pad_new_from_template:
288 * @templ: the pad template to use
289 * @name: the name of the element
291 * Create a new pad with given name from the given template.
296 gst_pad_new_from_template (GstPadTemplate *templ,
301 g_return_val_if_fail (name != NULL, NULL);
302 g_return_val_if_fail (templ != NULL, NULL);
304 pad = gst_pad_new (name, templ->direction);
306 gst_object_ref (GST_OBJECT (templ));
307 GST_PAD_PADTEMPLATE (pad) = templ;
313 * gst_pad_get_direction:
314 * @pad: the Pad to get the direction from
316 * Get the direction of the pad.
318 * Returns: the direction of the pad
321 gst_pad_get_direction (GstPad *pad)
323 g_return_val_if_fail (pad != NULL, GST_PAD_UNKNOWN);
324 g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
326 return GST_PAD_DIRECTION (pad);
331 * @pad: the pad to set the name of
332 * @name: the name of the pad
334 * Set the name of a pad.
337 gst_pad_set_name (GstPad *pad,
340 g_return_if_fail (pad != NULL);
341 g_return_if_fail (GST_IS_PAD (pad));
343 gst_object_set_name (GST_OBJECT (pad), name);
348 * @pad: the pad to get the name of
350 * Get the name of a pad.
352 * Returns: the name of the pad, don't free.
355 gst_pad_get_name (GstPad *pad)
357 g_return_val_if_fail (pad != NULL, NULL);
358 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
360 return GST_OBJECT_NAME (pad);
364 * gst_pad_set_chain_function:
365 * @pad: the pad to set the chain function for
366 * @chain: the chain function
368 * Set the given chain function for the pad.
371 gst_pad_set_chain_function (GstPad *pad,
372 GstPadChainFunction chain)
374 g_return_if_fail (pad != NULL);
375 g_return_if_fail (GST_IS_REAL_PAD (pad));
377 GST_RPAD_CHAINFUNC(pad) = chain;
378 GST_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s\n",
379 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain));
383 * gst_pad_set_get_function:
384 * @pad: the pad to set the get function for
385 * @get: the get function
387 * Set the given get function for the pad.
390 gst_pad_set_get_function (GstPad *pad,
391 GstPadGetFunction get)
393 g_return_if_fail (pad != NULL);
394 g_return_if_fail (GST_IS_REAL_PAD (pad));
396 GST_RPAD_GETFUNC(pad) = get;
397 GST_DEBUG (GST_CAT_PADS, "getfunc for %s:%s set to %s\n",
398 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
402 * gst_pad_set_event_function:
403 * @pad: the pad to set the event handler for
404 * @event: the event handler
406 * Set the given event handler for the pad.
409 gst_pad_set_event_function (GstPad *pad,
410 GstPadEventFunction event)
412 g_return_if_fail (pad != NULL);
413 g_return_if_fail (GST_IS_REAL_PAD (pad));
415 GST_RPAD_EVENTFUNC(pad) = event;
416 GST_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s set to %s\n",
417 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event));
421 * gst_pad_set_getregion_function:
422 * @pad: the pad to set the getregion function for
423 * @getregion: the getregion function
425 * Set the given getregion function for the pad.
428 gst_pad_set_getregion_function (GstPad *pad,
429 GstPadGetRegionFunction getregion)
431 g_return_if_fail (pad != NULL);
432 g_return_if_fail (GST_IS_REAL_PAD (pad));
434 GST_RPAD_GETREGIONFUNC(pad) = getregion;
435 GST_DEBUG (GST_CAT_PADS, "getregionfunc for %s:%s set to %s\n",
436 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getregion));
440 * gst_pad_set_connect_function:
441 * @pad: the pad to set the connect function for
442 * @connect: the connect function
444 * Set the given connect function for the pad. It will be called
445 * when the pad is connected or reconnected with caps.
448 gst_pad_set_connect_function (GstPad *pad,
449 GstPadConnectFunction connect)
451 g_return_if_fail (pad != NULL);
452 g_return_if_fail (GST_IS_REAL_PAD (pad));
454 GST_RPAD_CONNECTFUNC (pad) = connect;
455 GST_DEBUG (GST_CAT_PADS, "connectfunc for %s:%s set to %s\n",
456 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (connect));
460 * gst_pad_set_getcaps_function:
461 * @pad: the pad to set the getcaps function for
462 * @getcaps: the getcaps function
464 * Set the given getcaps function for the pad.
467 gst_pad_set_getcaps_function (GstPad *pad,
468 GstPadGetCapsFunction getcaps)
470 g_return_if_fail (pad != NULL);
471 g_return_if_fail (GST_IS_REAL_PAD (pad));
473 GST_RPAD_GETCAPSFUNC (pad) = getcaps;
474 GST_DEBUG (GST_CAT_PADS, "getcapsfunc for %s:%s set to %s\n",
475 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
478 * gst_pad_set_bufferpool_function:
479 * @pad: the pad to set the bufferpool function for
480 * @bufpool: the bufferpool function
482 * Set the given bufferpool function for the pad.
485 gst_pad_set_bufferpool_function (GstPad *pad,
486 GstPadBufferPoolFunction bufpool)
488 g_return_if_fail (pad != NULL);
489 g_return_if_fail (GST_IS_REAL_PAD (pad));
491 GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool;
492 GST_DEBUG (GST_CAT_PADS, "bufferpoolfunc for %s:%s set to %s\n",
493 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (bufpool));
497 gst_pad_push_func(GstPad *pad, GstBuffer *buf)
499 if (GST_RPAD_CHAINFUNC (GST_RPAD_PEER (pad)) != NULL) {
500 GST_DEBUG (GST_CAT_DATAFLOW, "calling chain function %s\n",
501 GST_DEBUG_FUNCPTR_NAME (GST_RPAD_CHAINFUNC (GST_RPAD_PEER (pad))));
502 (GST_RPAD_CHAINFUNC (GST_RPAD_PEER (pad))) (pad, buf);
504 GST_DEBUG (GST_CAT_DATAFLOW, "default pad_push handler in place, no chain function\n");
505 g_warning ("(internal error) default pad_push in place for pad %s:%s but it has no chain function",
506 GST_DEBUG_PAD_NAME (pad));
512 * gst_pad_disconnect:
513 * @srcpad: the source pad to disconnect
514 * @sinkpad: the sink pad to disconnect
516 * Disconnects the source pad from the sink pad.
519 gst_pad_disconnect (GstPad *srcpad,
522 GstRealPad *realsrc, *realsink;
525 g_return_if_fail (srcpad != NULL);
526 g_return_if_fail (GST_IS_PAD (srcpad));
527 g_return_if_fail (sinkpad != NULL);
528 g_return_if_fail (GST_IS_PAD (sinkpad));
530 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnecting %s:%s(%p) and %s:%s(%p)",
531 GST_DEBUG_PAD_NAME (srcpad), srcpad, GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
533 /* now we need to deal with the real/ghost stuff */
534 realsrc = GST_PAD_REALIZE (srcpad);
535 realsink = GST_PAD_REALIZE (sinkpad);
537 g_return_if_fail (GST_RPAD_PEER (realsrc) != NULL);
538 g_return_if_fail (GST_RPAD_PEER (realsink) != NULL);
540 if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
541 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
548 g_return_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
549 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK));
551 /* first clear peers */
552 GST_RPAD_PEER (realsrc) = NULL;
553 GST_RPAD_PEER (realsink) = NULL;
555 /* reset the filters, both filters are refcounted once */
556 if (GST_RPAD_FILTER (realsrc)) {
557 gst_caps_unref (GST_RPAD_FILTER (realsrc));
558 GST_RPAD_FILTER (realsink) = NULL;
559 GST_RPAD_FILTER (realsrc) = NULL;
562 /* now tell the scheduler */
563 if (GST_PAD_PARENT (realsrc)->sched)
564 gst_scheduler_pad_disconnect (GST_PAD_PARENT (realsrc)->sched, (GstPad *)realsrc, (GstPad *)realsink);
565 else if (GST_PAD_PARENT (realsink)->sched)
566 gst_scheduler_pad_disconnect (GST_PAD_PARENT (realsink)->sched, (GstPad *)realsrc, (GstPad *)realsink);
568 /* hold a reference, as they can go away in the signal handlers */
569 gst_object_ref (GST_OBJECT (realsrc));
570 gst_object_ref (GST_OBJECT (realsink));
572 /* fire off a signal to each of the pads telling them that they've been disconnected */
573 g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsink);
574 g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsrc);
576 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
577 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
579 gst_object_unref (GST_OBJECT (realsrc));
580 gst_object_unref (GST_OBJECT (realsink));
584 * gst_pad_can_connect_filtered:
585 * @srcpad: the source pad to connect
586 * @sinkpad: the sink pad to connect
587 * @filtercaps: the filter caps.
589 * Checks if the source pad and the sink pad can be connected.
590 * The filter indicates the media type that should flow trought this connection.
592 * Returns: TRUE if the pad can be connected, FALSE otherwise
595 gst_pad_can_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
597 gint num_decoupled = 0;
598 GstRealPad *realsrc, *realsink;
601 g_return_val_if_fail (srcpad != NULL, FALSE);
602 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
603 g_return_val_if_fail (sinkpad != NULL, FALSE);
604 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
606 /* now we need to deal with the real/ghost stuff */
607 realsrc = GST_PAD_REALIZE (srcpad);
608 realsink = GST_PAD_REALIZE (sinkpad);
610 g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
611 g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
612 g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, FALSE);
613 g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, FALSE);
615 if (realsrc->sched && realsink->sched) {
616 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
618 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
621 if (realsrc->sched != realsink->sched && num_decoupled != 1) {
622 g_warning ("connecting pads with different scheds requires exactly one decoupled element (queue)");
627 /* check if the directions are compatible */
628 if (!(((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
629 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) ||
630 ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
631 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK))))
639 * gst_pad_can_connect:
640 * @srcpad: the source pad to connect
641 * @sinkpad: the sink pad to connect
643 * Checks if the source pad can be connected to the sink pad.
645 * Returns: TRUE if the pads can be connected, FALSE otherwise
648 gst_pad_can_connect (GstPad *srcpad, GstPad *sinkpad)
650 return gst_pad_can_connect_filtered (srcpad, sinkpad, NULL);
654 * gst_pad_connect_filtered:
655 * @srcpad: the source pad to connect
656 * @sinkpad: the sink pad to connect
657 * @filtercaps: the filter caps.
659 * Connects the source pad to the sink pad. The filter indicates the media type
660 * that should flow trought this connection.
662 * Returns: TRUE if the pad could be connected, FALSE otherwise
665 gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
667 GstRealPad *realsrc, *realsink;
668 gint num_decoupled = 0;
671 g_return_val_if_fail (srcpad != NULL, FALSE);
672 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
673 g_return_val_if_fail (sinkpad != NULL, FALSE);
674 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
676 GST_INFO (GST_CAT_PADS, "connecting %s:%s and %s:%s",
677 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
679 /* now we need to deal with the real/ghost stuff */
680 realsrc = GST_PAD_REALIZE (srcpad);
681 realsink = GST_PAD_REALIZE (sinkpad);
683 if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
684 GST_INFO (GST_CAT_PADS, "*actually* connecting %s:%s and %s:%s",
685 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
688 g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
689 g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
690 g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, FALSE);
691 g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, FALSE);
693 if (realsrc->sched && realsink->sched) {
694 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
696 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
699 if (realsrc->sched != realsink->sched && num_decoupled != 1) {
700 g_warning ("connecting pads with different scheds requires exactly one decoupled element (queue)\n");
705 /* check for reversed directions and swap if necessary */
706 if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
707 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
714 g_return_val_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
715 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK), FALSE);
717 /* first set peers */
718 GST_RPAD_PEER (realsrc) = realsink;
719 GST_RPAD_PEER (realsink) = realsrc;
721 /* try to negotiate the pads, we don't need to clear the caps here */
722 if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, FALSE)) {
723 GST_DEBUG (GST_CAT_CAPS, "pads cannot connect\n");
725 GST_RPAD_PEER (realsrc) = NULL;
726 GST_RPAD_PEER (realsink) = NULL;
731 /* fire off a signal to each of the pads telling them that they've been connected */
732 g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_CONNECTED], 0, realsink);
733 g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_CONNECTED], 0, realsrc);
735 /* now tell the scheduler(s) */
737 gst_scheduler_pad_connect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
738 else if (realsink->sched)
739 gst_scheduler_pad_connect (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
741 GST_INFO (GST_CAT_PADS, "connected %s:%s and %s:%s",
742 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
743 gst_caps_debug (gst_pad_get_caps (GST_PAD_CAST (realsrc)), "caps of newly connected src pad");
750 * @srcpad: the source pad to connect
751 * @sinkpad: the sink pad to connect
753 * Connects the source pad to the sink pad.
755 * Returns: TRUE if the pad could be connected, FALSE otherwise
758 gst_pad_connect (GstPad *srcpad, GstPad *sinkpad)
760 return gst_pad_connect_filtered (srcpad, sinkpad, NULL);
764 * gst_pad_set_parent:
765 * @pad: the pad to set the parent
766 * @parent: the object to set the parent to
768 * Sets the parent object of a pad.
771 gst_pad_set_parent (GstPad *pad,
774 g_return_if_fail (pad != NULL);
775 g_return_if_fail (GST_IS_PAD (pad));
776 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
777 g_return_if_fail (parent != NULL);
778 g_return_if_fail (GST_IS_OBJECT (parent));
779 g_return_if_fail ((gpointer)pad != (gpointer)parent);
781 gst_object_set_parent (GST_OBJECT (pad), parent);
785 * gst_pad_get_parent:
786 * @pad: the pad to get the parent from
788 * Get the parent object of this pad.
790 * Returns: the parent object
793 gst_pad_get_parent (GstPad *pad)
795 g_return_val_if_fail (pad != NULL, NULL);
796 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
798 return GST_PAD_PARENT (pad);
802 * gst_pad_get_padtemplate:
803 * @pad: the pad to get the padtemplate from
805 * Get the padtemplate object of this pad.
807 * Returns: the padtemplate object
810 gst_pad_get_padtemplate (GstPad *pad)
812 g_return_val_if_fail (pad != NULL, NULL);
813 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
815 return GST_PAD_PADTEMPLATE (pad);
821 * @pad: the pad to set the scheduler for
822 * @sched: The scheduler to set
824 * Set the scheduler for the pad
827 gst_pad_set_sched (GstPad *pad, GstScheduler *sched)
829 g_return_if_fail (pad != NULL);
830 g_return_if_fail (GST_IS_PAD (pad));
832 GST_RPAD_SCHED(pad) = sched;
837 * @pad: the pad to get the scheduler from
839 * Get the scheduler of the pad
841 * Returns: the scheduler of the pad.
844 gst_pad_get_sched (GstPad *pad)
846 g_return_val_if_fail (pad != NULL, NULL);
847 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
849 return GST_RPAD_SCHED(pad);
853 * gst_pad_unset_sched:
854 * @pad: the pad to unset the scheduler for
856 * Unset the scheduler for the pad
859 gst_pad_unset_sched (GstPad *pad)
861 g_return_if_fail (pad != NULL);
862 g_return_if_fail (GST_IS_PAD (pad));
864 GST_RPAD_SCHED(pad) = NULL;
868 * gst_pad_get_real_parent:
869 * @pad: the pad to get the parent from
871 * Get the real parent object of this pad. If the pad
872 * is a ghostpad, the actual owner of the real pad is
873 * returned, as opposed to the gst_pad_get_parent().
875 * Returns: the parent object
878 gst_pad_get_real_parent (GstPad *pad)
880 g_return_val_if_fail (pad != NULL, NULL);
881 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
883 return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
887 * gst_pad_add_ghost_pad:
888 * @pad: the pad to set the ghost parent
889 * @ghostpad: the ghost pad to add
891 * Add a ghost pad to a pad.
894 gst_pad_add_ghost_pad (GstPad *pad,
899 g_return_if_fail (pad != NULL);
900 g_return_if_fail (GST_IS_PAD (pad));
901 g_return_if_fail (ghostpad != NULL);
902 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
904 realpad = GST_PAD_REALIZE (pad);
906 realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
911 * gst_pad_remove_ghost_pad:
912 * @pad: the pad to remove the ghost parent
913 * @ghostpad: the ghost pad to remove from the pad
915 * Remove a ghost pad from a pad.
918 gst_pad_remove_ghost_pad (GstPad *pad,
923 g_return_if_fail (pad != NULL);
924 g_return_if_fail (GST_IS_PAD (pad));
925 g_return_if_fail (ghostpad != NULL);
926 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
928 realpad = GST_PAD_REALIZE (pad);
930 realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
934 * gst_pad_get_ghost_pad_list:
935 * @pad: the pad to get the ghost parents from
937 * Get the ghost parents of this pad.
939 * Returns: a GList of ghost pads
942 gst_pad_get_ghost_pad_list (GstPad *pad)
944 g_return_val_if_fail (pad != NULL, NULL);
945 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
947 return GST_PAD_REALIZE(pad)->ghostpads;
950 /* an internal caps negotiation helper function does:
952 * 1. optinally calls the pad connect function with the provided caps
953 * 2. deal with the result code of the connect function
954 * 3. set fixed caps on the pad.
956 static GstPadConnectReturn
957 gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
960 GstPadTemplate *template;
961 GstElement *parent = GST_PAD_PARENT (pad);
963 /* thomas: FIXME: is this the right result to return ? */
964 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_REFUSED);
965 g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_CONNECT_REFUSED);
967 /* if this pad has a parent and the parent is not READY, delay the
969 if (parent && GST_STATE (parent) < GST_STATE_READY)
971 GST_DEBUG (GST_CAT_CAPS, "parent %s of pad %s:%s is not ready\n",
972 GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (pad));
973 return GST_PAD_CONNECT_DELAYED;
976 GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
977 caps, GST_DEBUG_PAD_NAME (pad));
979 if ((template = gst_pad_get_padtemplate (GST_PAD_CAST (pad)))) {
980 if (!gst_caps_intersect (caps, gst_padtemplate_get_caps (template))) {
981 GST_INFO (GST_CAT_CAPS, "caps did not intersect with %s:%s's padtemplate",
982 GST_DEBUG_PAD_NAME (pad));
983 gst_caps_debug (gst_padtemplate_get_caps (template),
984 "pad template caps that did not agree with caps");
985 return GST_PAD_CONNECT_REFUSED;
987 /* given that the caps are fixed, we know that their intersection with the
988 * padtemplate caps is the same as caps itself */
991 /* we need to notify the connect function */
992 if (notify && GST_RPAD_CONNECTFUNC (pad)) {
993 GstPadConnectReturn res;
996 GST_INFO (GST_CAT_CAPS, "calling connect function on pad %s:%s",
997 GST_DEBUG_PAD_NAME (pad));
999 /* call the connect function */
1000 res = GST_RPAD_CONNECTFUNC (pad) (GST_PAD (pad), caps);
1003 case GST_PAD_CONNECT_REFUSED:
1004 debug_string = "REFUSED";
1006 case GST_PAD_CONNECT_OK:
1007 debug_string = "OK";
1009 case GST_PAD_CONNECT_DONE:
1010 debug_string = "DONE";
1012 case GST_PAD_CONNECT_DELAYED:
1013 debug_string = "DELAYED";
1016 g_warning ("unknown return code from connect function of pad %s:%s",
1017 GST_DEBUG_PAD_NAME (pad));
1018 return GST_PAD_CONNECT_REFUSED;
1021 GST_INFO (GST_CAT_CAPS, "got reply %s (%d) from connect function on pad %s:%s",
1022 debug_string, res, GST_DEBUG_PAD_NAME (pad));
1024 /* done means the connect function called another caps negotiate function
1025 * on this pad that succeeded, we dont need to continue */
1026 if (res == GST_PAD_CONNECT_DONE) {
1027 GST_INFO (GST_CAT_CAPS, "pad %s:%s is done", GST_DEBUG_PAD_NAME (pad));
1028 return GST_PAD_CONNECT_DONE;
1030 if (res == GST_PAD_CONNECT_REFUSED) {
1031 GST_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps",
1032 GST_DEBUG_PAD_NAME (pad));
1033 return GST_PAD_CONNECT_REFUSED;
1036 /* we can only set caps on the pad if they are fixed */
1037 if (GST_CAPS_IS_FIXED (caps)) {
1039 GST_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
1040 GST_DEBUG_PAD_NAME (pad));
1041 /* if we got this far all is ok, remove the old caps, set the new one */
1042 oldcaps = GST_PAD_CAPS (pad);
1043 if (caps) gst_caps_ref (caps);
1044 GST_PAD_CAPS (pad) = caps;
1045 if (oldcaps) gst_caps_unref (oldcaps);
1048 GST_INFO (GST_CAT_CAPS, "caps are not fixed on pad %s:%s, not setting them yet",
1049 GST_DEBUG_PAD_NAME (pad));
1052 return GST_PAD_CONNECT_OK;
1056 * gst_pad_try_set_caps:
1057 * @pad: the pad to try to set the caps on
1058 * @caps: the caps to set
1060 * Try to set the caps on the given pad.
1062 * Returns: TRUE if the caps could be set
1065 gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
1067 GstRealPad *peer, *realpad;
1069 realpad = GST_PAD_REALIZE (pad);
1070 peer = GST_RPAD_PEER (realpad);
1072 GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
1073 caps, GST_DEBUG_PAD_NAME (realpad));
1075 gst_caps_debug (caps, "caps that we are trying to set");
1077 /* setting non fixed caps on a pad is not allowed */
1078 if (!GST_CAPS_IS_FIXED (caps)) {
1079 GST_INFO (GST_CAT_CAPS, "trying to set unfixed caps on pad %s:%s, not allowed",
1080 GST_DEBUG_PAD_NAME (realpad));
1081 g_warning ("trying to set non fixed caps on pad %s:%s, not allowed",
1082 GST_DEBUG_PAD_NAME (realpad));
1083 gst_caps_debug (caps, "unfixed caps");
1087 /* if we have a peer try to set the caps, notifying the peerpad
1088 * if it has a connect function */
1089 if (peer && (gst_pad_try_set_caps_func (peer, caps, TRUE) != GST_PAD_CONNECT_OK))
1091 GST_INFO (GST_CAT_CAPS, "tried to set caps on peerpad %s:%s but couldn't",
1092 GST_DEBUG_PAD_NAME (peer));
1096 /* then try to set our own caps, we don't need to be notified */
1097 if (gst_pad_try_set_caps_func (realpad, caps, FALSE) != GST_PAD_CONNECT_OK)
1099 GST_INFO (GST_CAT_CAPS, "tried to set own caps on pad %s:%s but couldn't",
1100 GST_DEBUG_PAD_NAME (realpad));
1103 GST_INFO (GST_CAT_CAPS, "succeeded setting caps %p on pad %s:%s",
1104 caps, GST_DEBUG_PAD_NAME (realpad));
1105 g_assert (GST_PAD_CAPS (pad));
1110 /* this is a caps negotiation convenience routine, it performs:
1112 * 1. optionally clear any pad caps
1113 * 2. calculate the intersection between the two pad tamplate/getcaps caps
1114 * 3. calculate the intersection with the (optional) filtercaps.
1115 * 4. store the intersection in the pad filter
1116 * 5. store the app filtercaps in the pad appfilter.
1117 * 6. start the caps negotiation.
1120 gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, GstCaps *filtercaps, gboolean clear)
1122 GstCaps *srccaps, *sinkcaps;
1123 GstCaps *intersection = NULL;
1124 GstRealPad *realsrc, *realsink;
1126 realsrc = GST_PAD_REALIZE (srcpad);
1127 realsink = GST_PAD_REALIZE (sinkpad);
1129 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1130 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1132 /* optinally clear the caps */
1134 GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s, clearing caps",
1135 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1137 GST_PAD_CAPS (GST_PAD (realsrc)) = NULL;
1138 GST_PAD_CAPS (GST_PAD (realsink)) = NULL;
1141 GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s",
1142 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1145 srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1146 GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsrc));
1147 gst_caps_debug (srccaps, "caps of src pad (pre-reconnect)");
1148 sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1149 GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsink));
1150 gst_caps_debug (sinkcaps, "caps of sink pad (pre-reconnect)");
1152 /* first take the intersection of the pad caps */
1153 intersection = gst_caps_intersect (srccaps, sinkcaps);
1155 /* if we have no intersection but one of the caps was not NULL.. */
1156 if (!intersection && (srccaps || sinkcaps)) {
1157 /* the intersection is NULL but the pad caps were not both NULL,
1158 * this means they have no common format */
1159 GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s have no common type",
1160 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1162 } else if (intersection) {
1163 GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s intersected to %s caps",
1164 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink),
1165 ((intersection && GST_CAPS_IS_FIXED (intersection)) ? "fixed" : "variable"));
1167 /* then filter this against the app filter */
1169 GstCaps *filtered_intersection = gst_caps_intersect (intersection, filtercaps);
1171 /* get rid of the old intersection here */
1172 gst_caps_unref (intersection);
1174 if (!filtered_intersection) {
1175 GST_INFO (GST_CAT_PADS, "filtered connection between pads %s:%s and %s:%s is empty",
1176 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1179 intersection = filtered_intersection;
1181 /* keep a reference to the app caps */
1182 GST_RPAD_APPFILTER (realsink) = filtercaps;
1183 GST_RPAD_APPFILTER (realsrc) = filtercaps;
1186 GST_DEBUG (GST_CAT_CAPS, "setting filter for connection to:\n");
1187 gst_caps_debug (intersection, "filter for connection");
1189 /* both the app filter and the filter, while stored on both peer pads, are the
1190 equal to the same thing on both */
1191 GST_RPAD_FILTER (realsrc) = intersection;
1192 GST_RPAD_FILTER (realsink) = intersection;
1194 return gst_pad_perform_negotiate (GST_PAD (realsrc), GST_PAD (realsink));
1198 * gst_pad_perform_negotiate:
1200 * @sinkpad: a sinkpad
1202 * Try to negotiate the pads.
1204 * Returns: a boolean indicating the pad succesfully negotiated.
1207 gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad)
1209 GstCaps *intersection, *filtered_intersection;
1210 GstRealPad *realsrc, *realsink;
1211 GstCaps *srccaps, *sinkcaps, *filter;
1213 g_return_val_if_fail (srcpad != NULL, FALSE);
1214 g_return_val_if_fail (sinkpad != NULL, FALSE);
1216 realsrc = GST_PAD_REALIZE (srcpad);
1217 realsink = GST_PAD_REALIZE (sinkpad);
1219 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1220 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1222 filter = GST_RPAD_APPFILTER (realsrc);
1224 GST_INFO (GST_CAT_PADS, "dumping filter for connection %s:%s-%s:%s",
1225 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1226 gst_caps_debug (filter, "connection filter caps");
1229 /* calculate the new caps here */
1230 srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1231 GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsrc));
1232 gst_caps_debug (srccaps, "src caps, awaiting negotiation, after applying filter");
1233 sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1234 GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsink));
1235 gst_caps_debug (sinkcaps, "sink caps, awaiting negotiation, after applying filter");
1236 intersection = gst_caps_intersect (srccaps, sinkcaps);
1237 filtered_intersection = gst_caps_intersect (intersection, filter);
1238 if (filtered_intersection) {
1239 gst_caps_unref (intersection);
1240 intersection = filtered_intersection;
1243 /* no negotiation is performed if the pads have filtercaps */
1245 GstPadConnectReturn res;
1247 res = gst_pad_try_set_caps_func (realsrc, intersection, TRUE);
1248 if (res == GST_PAD_CONNECT_REFUSED)
1250 if (res == GST_PAD_CONNECT_DONE)
1253 res = gst_pad_try_set_caps_func (realsink, intersection, TRUE);
1254 if (res == GST_PAD_CONNECT_REFUSED)
1256 if (res == GST_PAD_CONNECT_DONE)
1263 * gst_pad_try_reconnect_filtered:
1264 * @pad: the pad to reconnect
1265 * @caps: the capabilities to use in the reconnectiong
1267 * Try to reconnect this pad and its peer with the specified caps
1269 * Returns: a boolean indicating the peer pad could accept the caps.
1272 gst_pad_try_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
1274 GstRealPad *realsrc, *realsink;
1276 g_return_val_if_fail (srcpad != NULL, FALSE);
1277 g_return_val_if_fail (sinkpad != NULL, FALSE);
1279 realsrc = GST_PAD_REALIZE (srcpad);
1280 realsink = GST_PAD_REALIZE (sinkpad);
1282 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1283 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1285 return gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE);
1289 * gst_pad_reconnect_filtered:
1290 * @pad: the pad to reconnect
1291 * @caps: the capabilities to use in the reconnectiong
1293 * Try to reconnect this pad and its peer with the specified caps.
1295 * Returns: a boolean indicating the peer pad could accept the caps.
1296 * if FALSE is returned, the pads are disconnected.
1299 gst_pad_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
1301 GstRealPad *realsrc, *realsink;
1303 g_return_val_if_fail (srcpad != NULL, FALSE);
1304 g_return_val_if_fail (sinkpad != NULL, FALSE);
1306 realsrc = GST_PAD_REALIZE (srcpad);
1307 realsink = GST_PAD_REALIZE (sinkpad);
1309 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1310 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1312 if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE)) {
1313 gst_pad_disconnect (srcpad, GST_PAD (GST_PAD_PEER (srcpad)));
1320 * gst_pad_proxy_connect:
1321 * @pad: the pad to proxy to
1322 * @caps: the capabilities to use in the proxying
1324 * Proxy the connect function to the specified pad.
1326 * Returns: a boolean indicating the peer pad could accept the caps.
1329 gst_pad_proxy_connect (GstPad *pad, GstCaps *caps)
1331 GstRealPad *peer, *realpad;
1333 realpad = GST_PAD_REALIZE (pad);
1335 peer = GST_RPAD_PEER (realpad);
1337 GST_INFO (GST_CAT_CAPS, "proxy connect to pad %s:%s",
1338 GST_DEBUG_PAD_NAME (realpad));
1340 if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE))
1341 return GST_PAD_CONNECT_REFUSED;
1342 if (!gst_pad_try_set_caps_func (realpad, caps, FALSE))
1343 return GST_PAD_CONNECT_REFUSED;
1345 return GST_PAD_CONNECT_OK;
1350 * @pad: the pad to get the capabilities from
1352 * Get the capabilities of this pad.
1354 * Returns: the capabilities of this pad
1357 gst_pad_get_caps (GstPad *pad)
1359 GstRealPad *realpad;
1361 g_return_val_if_fail (pad != NULL, NULL);
1362 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1364 realpad = GST_PAD_REALIZE (pad);
1366 GST_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)\n",
1367 GST_DEBUG_PAD_NAME (realpad), realpad);
1369 if (GST_PAD_CAPS (realpad)) {
1370 GST_DEBUG (GST_CAT_CAPS, "using pad real caps\n");
1371 return GST_PAD_CAPS (realpad);
1373 else if GST_RPAD_GETCAPSFUNC (realpad) {
1374 GST_DEBUG (GST_CAT_CAPS, "using pad get function\n");
1375 return GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad), NULL);
1377 else if (GST_PAD_PADTEMPLATE (realpad)) {
1378 GST_DEBUG (GST_CAT_CAPS, "using pad template\n");
1379 return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (realpad));
1381 GST_DEBUG (GST_CAT_CAPS, "pad has no caps\n");
1387 * gst_pad_get_padtemplate_caps:
1388 * @pad: the pad to get the capabilities from
1390 * Get the capabilities of this pad.
1392 * Returns: a list of the capabilities of this pad
1395 gst_pad_get_padtemplate_caps (GstPad *pad)
1397 g_return_val_if_fail (pad != NULL, NULL);
1398 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1400 if (GST_PAD_PADTEMPLATE (pad))
1401 return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
1408 * gst_padtemplate_get_caps_by_name:
1409 * @templ: the padtemplate to get the capabilities from
1410 * @name: the name of the capability to get
1412 * Get the capability with the given name from this padtemplate.
1414 * Returns: a capability or NULL if not found
1417 gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
1421 g_return_val_if_fail (templ != NULL, NULL);
1423 caps = GST_PADTEMPLATE_CAPS (templ);
1427 return gst_caps_get_by_name (caps, name);
1431 * gst_pad_check_compatibility:
1432 * @srcpad: the srcpad to check
1433 * @sinkpad: the sinkpad to check against
1435 * Check if two pads have compatible capabilities.
1437 * Returns: TRUE if they are compatible or the capabilities
1438 * could not be checked
1441 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
1443 g_return_val_if_fail (srcpad != NULL, FALSE);
1444 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1445 g_return_val_if_fail (sinkpad != NULL, FALSE);
1446 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1448 if (GST_PAD_CAPS (srcpad) && GST_PAD_CAPS (sinkpad)) {
1449 if (!gst_caps_check_compatibility (GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad))) {
1457 GST_DEBUG (GST_CAT_PADS, "could not check capabilities of pads (%s:%s) and (%s:%s) %p %p\n",
1458 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
1459 GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
1466 * @pad: the pad to get the peer from
1468 * Get the peer pad of this pad.
1470 * Returns: the peer pad
1473 gst_pad_get_peer (GstPad *pad)
1475 g_return_val_if_fail (pad != NULL, NULL);
1476 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1478 return GST_PAD (GST_PAD_PEER (pad));
1482 * gst_pad_get_allowed_caps:
1483 * @pad: the pad to get the allowed caps from
1485 * Get the caps of the allowed media types that can
1486 * go through this pad.
1488 * Returns: the allowed caps, newly allocated
1491 gst_pad_get_allowed_caps (GstPad *pad)
1493 g_return_val_if_fail (pad != NULL, NULL);
1494 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1496 GST_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s\n", GST_DEBUG_PAD_NAME (pad));
1498 return gst_caps_copy (GST_RPAD_FILTER (pad));
1502 * gst_pad_recac_allowed_caps:
1503 * @pad: the pad to recaculate the caps of
1505 * Attempt to reconnect the pad to its peer through its filter, set with gst_pad_[re]connect_filtered.
1506 * FIXME: no one calls this function. why is it here?
1508 * Returns: TRUE on success, FALSE otherwise.
1511 gst_pad_recalc_allowed_caps (GstPad *pad)
1515 g_return_val_if_fail (pad != NULL, FALSE);
1516 g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1518 GST_DEBUG (GST_CAT_PROPERTIES, "set allowed caps of %s:%s\n", GST_DEBUG_PAD_NAME (pad));
1520 peer = GST_RPAD_PEER (pad);
1522 return gst_pad_try_reconnect_filtered (pad, GST_PAD (peer), GST_RPAD_APPFILTER (pad));
1528 * gst_pad_get_bufferpool:
1529 * @pad: the pad to get the bufferpool from
1531 * Get the bufferpool of the peer pad of the given
1534 * Returns: The GstBufferPool or NULL.
1537 gst_pad_get_bufferpool (GstPad *pad)
1541 g_return_val_if_fail (pad != NULL, NULL);
1542 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1544 peer = GST_RPAD_PEER (pad);
1549 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1551 if (peer->bufferpoolfunc) {
1552 GST_DEBUG (GST_CAT_PADS, "calling bufferpoolfunc &%s (@%p) of peer pad %s:%s\n",
1553 GST_DEBUG_FUNCPTR_NAME (peer->bufferpoolfunc), &peer->bufferpoolfunc, GST_DEBUG_PAD_NAME (((GstPad*) peer)));
1554 return (peer->bufferpoolfunc) (((GstPad*) peer));
1556 GST_DEBUG (GST_CAT_PADS, "no bufferpoolfunc for peer pad %s:%s at %p\n",
1557 GST_DEBUG_PAD_NAME (((GstPad*) peer)), &peer->bufferpoolfunc);
1563 gst_real_pad_dispose (GObject *object)
1565 GstPad *pad = GST_PAD (object);
1567 /* No connected pad can ever be disposed.
1568 * It has to have a parent to be connected and a parent would hold a reference */
1569 g_assert (GST_PAD_PEER (pad) == NULL);
1571 GST_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s\n", GST_DEBUG_PAD_NAME(pad));
1573 if (GST_PAD_PADTEMPLATE (pad)){
1574 GST_DEBUG (GST_CAT_REFCOUNTING, "unreffing padtemplate'%s'\n", GST_OBJECT_NAME (GST_PAD_PADTEMPLATE (pad)));
1575 gst_object_unref (GST_OBJECT (GST_PAD_PADTEMPLATE (pad)));
1576 GST_PAD_PADTEMPLATE (pad) = NULL;
1579 /* we destroy the ghostpads, because they are nothing without the real pad */
1580 if (GST_REAL_PAD (pad)->ghostpads) {
1581 GList *orig, *ghostpads;
1583 orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
1586 GstPad *ghostpad = GST_PAD (ghostpads->data);
1588 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))){
1589 GST_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'\n",
1590 GST_OBJECT_NAME (GST_OBJECT_PARENT (ghostpad)));
1592 gst_element_remove_ghost_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), GST_PAD (ghostpad));
1594 ghostpads = g_list_next (ghostpads);
1597 g_list_free (GST_REAL_PAD(pad)->ghostpads);
1600 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))){
1601 GST_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'\n",
1602 GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
1604 gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
1607 G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
1611 #ifndef GST_DISABLE_LOADSAVE
1613 * gst_pad_load_and_connect:
1614 * @self: the XML node to read the description from
1615 * @parent: the element that has the pad
1617 * Read the pad definition from the XML node and connect the given pad
1618 * in element to a pad of an element up in the hierarchy.
1621 gst_pad_load_and_connect (xmlNodePtr self,
1624 xmlNodePtr field = self->xmlChildrenNode;
1625 GstPad *pad = NULL, *targetpad;
1626 guchar *peer = NULL;
1629 GstObject *grandparent;
1632 if (!strcmp (field->name, "name")) {
1633 pad = gst_element_get_pad (GST_ELEMENT (parent), xmlNodeGetContent (field));
1635 else if (!strcmp(field->name, "peer")) {
1636 peer = xmlNodeGetContent (field);
1638 field = field->next;
1640 g_return_if_fail (pad != NULL);
1642 if (peer == NULL) return;
1644 split = g_strsplit (peer, ".", 2);
1646 g_return_if_fail (split[0] != NULL);
1647 g_return_if_fail (split[1] != NULL);
1649 grandparent = gst_object_get_parent (parent);
1651 if (grandparent && GST_IS_BIN (grandparent)) {
1652 target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
1657 if (target == NULL) goto cleanup;
1659 targetpad = gst_element_get_pad (target, split[1]);
1661 if (targetpad == NULL) goto cleanup;
1663 gst_pad_connect (pad, targetpad);
1670 * gst_pad_save_thyself:
1671 * @pad: the pad to save
1672 * @parent: the parent XML node to save the description in
1674 * Saves the pad into an xml representation
1676 * Returns: the xml representation of the pad
1679 gst_pad_save_thyself (GstObject *object,
1682 GstRealPad *realpad;
1685 g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
1687 realpad = GST_REAL_PAD(object);
1689 xmlNewChild(parent,NULL,"name", GST_PAD_NAME (realpad));
1690 if (GST_RPAD_PEER(realpad) != NULL) {
1691 peer = GST_PAD(GST_RPAD_PEER(realpad));
1692 /* first check to see if the peer's parent's parent is the same */
1693 /* we just save it off */
1694 xmlNewChild(parent,NULL,"peer",g_strdup_printf("%s.%s",
1695 GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer)));
1697 xmlNewChild(parent,NULL,"peer","");
1703 * gst_pad_ghost_save_thyself:
1704 * @pad: the pad to save
1706 * @parent: the parent XML node to save the description in
1708 * Saves the ghost pad into an xml representation.
1710 * Returns: the xml representation of the pad
1713 gst_pad_ghost_save_thyself (GstPad *pad,
1719 g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
1721 self = xmlNewChild (parent, NULL, "ghostpad", NULL);
1722 xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
1723 xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
1725 /* FIXME FIXME FIXME! */
1729 #endif /* GST_DISABLE_LOADSAVE */
1731 #ifndef gst_pad_push
1734 * @pad: the pad to push
1735 * @buf: the buffer to push
1737 * Push a buffer to the peer of the pad.
1740 gst_pad_push (GstPad *pad, GstBuffer *buf)
1742 GstRealPad *peer = GST_RPAD_PEER (pad);
1744 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1746 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
1749 g_warning ("push on pad %s:%s but it is unconnected", GST_DEBUG_PAD_NAME (pad));
1752 if (peer->chainhandler) {
1754 GST_DEBUG (GST_CAT_DATAFLOW, "calling chainhandler &%s of peer pad %s:%s\n",
1755 GST_DEBUG_FUNCPTR_NAME (peer->chainhandler), GST_DEBUG_PAD_NAME (GST_PAD (peer)));
1756 (peer->chainhandler) (GST_PAD_CAST (peer), buf);
1760 g_warning ("trying to push a NULL buffer on pad %s:%s", GST_DEBUG_PAD_NAME (peer));
1765 g_warning ("(internal error) push on pad %s:%s but it has no chainhandler", GST_DEBUG_PAD_NAME (peer));
1768 /* clean up the mess here */
1770 if (GST_IS_BUFFER (buf))
1771 gst_buffer_unref (buf);
1773 gst_event_free (GST_EVENT (buf));
1778 #ifndef gst_pad_pull
1781 * @pad: the pad to pull
1783 * Pull a buffer from the peer pad.
1785 * Returns: a new buffer from the peer pad.
1788 gst_pad_pull (GstPad *pad)
1790 GstRealPad *peer = GST_RPAD_PEER(pad);
1792 GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1794 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1797 gst_element_error (GST_PAD_PARENT (pad),
1798 "pull on pad %s:%s but it was unconnected",
1799 GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
1803 if (peer->gethandler) {
1806 GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s\n",
1807 GST_DEBUG_FUNCPTR_NAME (peer->gethandler), GST_DEBUG_PAD_NAME (peer));
1809 buf = (peer->gethandler) (GST_PAD_CAST (peer));
1812 /* no null buffers allowed */
1813 gst_element_error (GST_PAD_PARENT (pad),
1814 "NULL buffer during pull on %s:%s", GST_DEBUG_PAD_NAME (pad), NULL);
1817 gst_element_error (GST_PAD_PARENT (pad),
1818 "(internal error) pull on pad %s:%s but the peer pad %s:%s has no gethandler",
1819 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer),
1827 #ifndef gst_pad_pullregion
1829 * gst_pad_pullregion:
1830 * @pad: the pad to pull the region from
1831 * @type: the regiontype
1832 * @offset: the offset/start of the buffer to pull
1833 * @len: the length of the buffer to pull
1835 * Pull a buffer region from the peer pad. The region to pull can be
1836 * specified with a offset/lenght pair or with a start/legnth time
1837 * indicator as specified by the type parameter.
1839 * Returns: a new buffer from the peer pad with data in the specified
1843 gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len)
1846 GstBuffer *result = NULL;
1848 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1851 peer = GST_RPAD_PEER(pad);
1852 g_return_val_if_fail (peer != NULL, NULL);
1855 gst_buffer_unref (result);
1857 GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len);
1859 if (peer->pullregionfunc) {
1860 GST_DEBUG (GST_CAT_DATAFLOW, "calling pullregionfunc &%s of peer pad %s:%s\n",
1861 GST_DEBUG_FUNCPTR_NAME (peer->pullregionfunc), GST_DEBUG_PAD_NAME(GST_PAD_CAST (peer)));
1862 result = (peer->pullregionfunc) (GST_PAD_CAST (peer), type, offset, len);
1864 GST_DEBUG (GST_CAT_DATAFLOW,"no pullregionfunc\n");
1870 while (result && !(GST_BUFFER_OFFSET (result) == offset &&
1871 GST_BUFFER_SIZE (result) == len));
1879 * @pad: the pad to peek
1881 * Peek for a buffer from the peer pad.
1883 * Returns: a from the peer pad or NULL if the peer has no buffer.
1886 gst_pad_peek (GstPad *pad)
1888 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1890 return GST_RPAD_BUFPEN (GST_RPAD_PEER (pad));
1895 * @padlist: A list of pads
1897 * Wait for a buffer on the list of pads.
1899 * Returns: The pad that has a buffer available, use
1900 * #gst_pad_pull to get the buffer.
1903 gst_pad_select (GList *padlist)
1907 pad = gst_scheduler_pad_select (GST_PAD_PARENT (padlist->data)->sched, padlist);
1914 * @pad: The first pad to perform the select on
1917 * Wait for a buffer on the given of pads.
1919 * Returns: The pad that has a buffer available, use
1920 * #gst_pad_pull to get the buffer.
1923 gst_pad_selectv (GstPad *pad, ...)
1926 GList *padlist = NULL;
1932 va_start (var_args, pad);
1935 padlist = g_list_prepend (padlist, pad);
1936 pad = va_arg (var_args, GstPad *);
1938 result = gst_pad_select (padlist);
1939 g_list_free (padlist);
1946 /************************************************************************
1951 static void gst_padtemplate_class_init (GstPadTemplateClass *klass);
1952 static void gst_padtemplate_init (GstPadTemplate *templ);
1960 static GstObject *padtemplate_parent_class = NULL;
1961 static guint gst_padtemplate_signals[TEMPL_LAST_SIGNAL] = { 0 };
1964 gst_padtemplate_get_type (void)
1966 static GType padtemplate_type = 0;
1968 if (!padtemplate_type) {
1969 static const GTypeInfo padtemplate_info = {
1970 sizeof(GstPadTemplateClass),
1973 (GClassInitFunc)gst_padtemplate_class_init,
1976 sizeof(GstPadTemplate),
1978 (GInstanceInitFunc)gst_padtemplate_init,
1981 padtemplate_type = g_type_register_static(GST_TYPE_OBJECT, "GstPadTemplate", &padtemplate_info, 0);
1983 return padtemplate_type;
1987 gst_padtemplate_class_init (GstPadTemplateClass *klass)
1989 GObjectClass *gobject_class;
1990 GstObjectClass *gstobject_class;
1992 gobject_class = (GObjectClass*)klass;
1993 gstobject_class = (GstObjectClass*)klass;
1995 padtemplate_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
1997 gst_padtemplate_signals[TEMPL_PAD_CREATED] =
1998 g_signal_new ("pad_created", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
1999 G_STRUCT_OFFSET (GstPadTemplateClass, pad_created), NULL, NULL,
2000 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
2004 gstobject_class->path_string_separator = "*";
2008 gst_padtemplate_init (GstPadTemplate *templ)
2012 /* ALWAYS padtemplates cannot have conversion specifications, it doesn't make
2014 * SOMETIMES padtemplates can do whatever they want, they are provided by the
2016 * REQUEST padtemplates can be reverse-parsed (the user asks for 'sink1', the
2017 * 'sink%d' template is automatically selected), so we need to restrict their
2021 name_is_valid (const gchar *name, GstPadPresence presence)
2025 if (presence == GST_PAD_ALWAYS) {
2026 if (strchr (name, '%')) {
2027 g_warning ("invalid name template %s: conversion specifications are not"
2028 " allowed for GST_PAD_ALWAYS padtemplates", name);
2031 } else if (presence == GST_PAD_REQUEST) {
2032 if ((str = strchr (name, '%')) && strchr (str + 1, '%')) {
2033 g_warning ("invalid name template %s: only one conversion specification"
2034 " allowed in GST_PAD_REQUEST padtemplate", name);
2037 if (str && (*(str+1) != 's' && *(str+1) != 'd')) {
2038 g_warning ("invalid name template %s: conversion specification must be of"
2039 " type '%%d' or '%%s' for GST_PAD_REQUEST padtemplate", name);
2048 * gst_padtemplate_new:
2049 * @name_template: the name template
2050 * @direction: the direction for the template
2051 * @presence: the presence of the pad
2052 * @caps: a list of capabilities for the template
2053 * @...: more capabilities
2055 * Creates a new padtemplate from the given arguments.
2057 * Returns: the new padtemplate
2060 gst_padtemplate_new (gchar *name_template,
2061 GstPadDirection direction, GstPadPresence presence,
2064 GstPadTemplate *new;
2066 GstCaps *thecaps = NULL;
2068 g_return_val_if_fail (name_template != NULL, NULL);
2070 if (!name_is_valid (name_template, presence))
2073 new = g_object_new(gst_padtemplate_get_type () ,NULL);
2075 GST_PADTEMPLATE_NAME_TEMPLATE (new) = name_template;
2076 GST_PADTEMPLATE_DIRECTION (new) = direction;
2077 GST_PADTEMPLATE_PRESENCE (new) = presence;
2079 va_start (var_args, caps);
2082 new->fixed &= caps->fixed;
2083 thecaps = gst_caps_append (thecaps, caps);
2084 caps = va_arg (var_args, GstCaps*);
2088 GST_PADTEMPLATE_CAPS (new) = thecaps;
2094 * gst_padtemplate_get_caps:
2095 * @templ: the padtemplate to use
2097 * Get the capabilities of the padtemplate
2099 * Returns: a GstCaps*
2102 gst_padtemplate_get_caps (GstPadTemplate *templ)
2104 g_return_val_if_fail (templ != NULL, NULL);
2106 return GST_PADTEMPLATE_CAPS (templ);
2109 #ifndef GST_DISABLE_LOADSAVE
2111 * gst_padtemplate_save_thyself:
2112 * @templ: the padtemplate to save
2113 * @parent: the parent XML tree
2115 * Saves the padtemplate into XML.
2117 * Returns: the new XML tree
2120 gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
2125 GST_DEBUG (GST_CAT_XML,"saving padtemplate %s\n", templ->name_template);
2127 xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
2128 xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
2130 switch (templ->presence) {
2131 case GST_PAD_ALWAYS:
2132 presence = "always";
2134 case GST_PAD_SOMETIMES:
2135 presence = "sometimes";
2137 case GST_PAD_REQUEST:
2138 presence = "request";
2141 presence = "unknown";
2144 xmlNewChild(parent,NULL,"presence", presence);
2146 if (GST_PADTEMPLATE_CAPS (templ)) {
2147 subtree = xmlNewChild (parent, NULL, "caps", NULL);
2148 gst_caps_save_thyself (GST_PADTEMPLATE_CAPS (templ), subtree);
2155 * gst_padtemplate_load_thyself:
2156 * @parent: the source XML tree
2158 * Loads a padtemplate from the XML tree.
2160 * Returns: the new padtemplate
2163 gst_padtemplate_load_thyself (xmlNodePtr parent)
2165 xmlNodePtr field = parent->xmlChildrenNode;
2166 GstPadTemplate *factory;
2167 gchar *name_template = NULL;
2168 GstPadDirection direction = GST_PAD_UNKNOWN;
2169 GstPadPresence presence = GST_PAD_ALWAYS;
2170 GstCaps *caps = NULL;
2173 if (!strcmp(field->name, "nametemplate")) {
2174 name_template = xmlNodeGetContent(field);
2176 if (!strcmp(field->name, "direction")) {
2177 gchar *value = xmlNodeGetContent(field);
2179 if (!strcmp(value, "sink")) {
2180 direction = GST_PAD_SINK;
2182 else if (!strcmp(value, "src")) {
2183 direction = GST_PAD_SRC;
2187 if (!strcmp(field->name, "presence")) {
2188 gchar *value = xmlNodeGetContent(field);
2190 if (!strcmp(value, "always")) {
2191 presence = GST_PAD_ALWAYS;
2193 else if (!strcmp(value, "sometimes")) {
2194 presence = GST_PAD_SOMETIMES;
2196 else if (!strcmp(value, "request")) {
2197 presence = GST_PAD_REQUEST;
2201 else if (!strcmp(field->name, "caps")) {
2202 caps = gst_caps_load_thyself (field);
2204 field = field->next;
2207 factory = gst_padtemplate_new (name_template, direction, presence, caps, NULL);
2211 #endif /* !GST_DISABLE_LOADSAVE */
2215 * gst_pad_set_element_private:
2216 * @pad: the pad to set the private data to
2217 * @priv: The private data to attach to the pad
2219 * Set the given private data pointer to the pad. This
2220 * function can only be used by the element that own the
2224 gst_pad_set_element_private (GstPad *pad, gpointer priv)
2226 pad->element_private = priv;
2230 * gst_pad_get_element_private:
2231 * @pad: the pad to get the private data of
2233 * Get the private data of a pad. The private data can
2234 * only be set by the parent element of this pad.
2236 * Returns: a pointer to the private data.
2239 gst_pad_get_element_private (GstPad *pad)
2241 return pad->element_private;
2245 /***** ghost pads *****/
2246 GType _gst_ghost_pad_type = 0;
2248 static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
2249 static void gst_ghost_pad_init (GstGhostPad *pad);
2251 static GstPad *ghost_pad_parent_class = NULL;
2252 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
2255 gst_ghost_pad_get_type(void) {
2256 if (!_gst_ghost_pad_type) {
2257 static const GTypeInfo pad_info = {
2258 sizeof(GstGhostPadClass),
2261 (GClassInitFunc)gst_ghost_pad_class_init,
2264 sizeof(GstGhostPad),
2266 (GInstanceInitFunc)gst_ghost_pad_init,
2269 _gst_ghost_pad_type = g_type_register_static(GST_TYPE_PAD, "GstGhostPad", &pad_info, 0);
2271 return _gst_ghost_pad_type;
2275 gst_ghost_pad_class_init (GstGhostPadClass *klass)
2277 GObjectClass *gobject_class;
2279 gobject_class = (GObjectClass*)klass;
2281 ghost_pad_parent_class = g_type_class_ref(GST_TYPE_PAD);
2285 gst_ghost_pad_init (GstGhostPad *pad)
2287 pad->realpad = NULL;
2291 * gst_ghost_pad_new:
2292 * @name: name of the new ghost pad
2293 * @pad: the pad to create a ghost pad of
2295 * Create a new ghost pad associated with the given pad.
2297 * Returns: new ghost pad
2300 gst_ghost_pad_new (gchar *name,
2303 GstGhostPad *ghostpad;
2304 GstRealPad *realpad;
2306 g_return_val_if_fail (name != NULL, NULL);
2307 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2309 ghostpad = g_object_new (gst_ghost_pad_get_type () ,NULL);
2310 gst_pad_set_name (GST_PAD (ghostpad), name);
2312 realpad = (GstRealPad *) pad;
2314 while (!GST_IS_REAL_PAD (realpad)) {
2315 realpad = GST_PAD_REALIZE (realpad);
2317 GST_GPAD_REALPAD (ghostpad) = realpad;
2318 GST_PAD_PADTEMPLATE (ghostpad) = GST_PAD_PADTEMPLATE (pad);
2320 /* add ourselves to the real pad's list of ghostpads */
2321 gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));
2323 /* FIXME need to ref the real pad here... ? */
2325 GST_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\"\n", name);
2327 return GST_PAD (ghostpad);
2331 gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, GstEvent *event)
2333 GList *pads = element->pads;
2336 GstPad *eventpad = GST_PAD (pads->data);
2337 pads = g_list_next (pads);
2339 /* for all pads in the opposite direction that are connected */
2340 if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) && GST_PAD_IS_CONNECTED (eventpad)) {
2341 if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
2342 gst_pad_push (eventpad, GST_BUFFER (gst_event_copy (event)));
2345 GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
2347 gst_pad_send_event (peerpad, gst_event_copy (event));
2354 * gst_pad_event_default:
2355 * @pad: the pad to operate on
2356 * @event: the event to handle
2358 * Invoke the default event handler for the given pad.
2361 gst_pad_event_default (GstPad *pad, GstEvent *event)
2363 GstElement *element = GST_PAD_PARENT (pad);
2365 g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_EVENT_RECEIVED], 0, event);
2367 switch (GST_EVENT_TYPE (event)) {
2369 gst_element_set_eos (element);
2370 gst_pad_event_default_dispatch (pad, element, event);
2371 /* we have to try to schedule another element because this one is disabled */
2372 gst_element_yield (element);
2374 case GST_EVENT_FLUSH:
2376 gst_pad_event_default_dispatch (pad, element, event);
2382 * gst_pad_send_event:
2383 * @pad: the pad to send the event to
2384 * @event: the event to send to the pad.
2386 * Send the event to the pad.
2388 * Returns: TRUE if the event was handled.
2391 gst_pad_send_event (GstPad *pad, GstEvent *event)
2393 gboolean handled = FALSE;
2395 g_return_val_if_fail (event, FALSE);
2397 if (GST_EVENT_SRC (event) == NULL)
2398 GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (pad));
2400 GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n",
2401 GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
2403 if (GST_RPAD_EVENTFUNC (pad))
2404 handled = GST_RPAD_EVENTFUNC (pad) (pad, event);
2406 GST_DEBUG(GST_CAT_EVENT, "there's no event function for pad %s:%s\n", GST_DEBUG_PAD_NAME (pad));
2410 GST_DEBUG(GST_CAT_EVENT, "proceeding with default event behavior here\n");
2411 gst_pad_event_default (pad, event);