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 /* fire off a signal to each of the pads telling them that they've been disconnected */
569 g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsink);
570 g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsrc);
572 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
573 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
577 * gst_pad_connect_filtered:
578 * @srcpad: the source pad to connect
579 * @sinkpad: the sink pad to connect
580 * @filtercaps: the filter caps.
582 * Connects the source pad to the sink pad. The filter indicates the media type
583 * that should flow trought this connection.
585 * Returns: TRUE if the pad could be connected, FALSE otherwise
588 gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
590 GstRealPad *realsrc, *realsink;
591 gint num_decoupled = 0;
594 g_return_val_if_fail (srcpad != NULL, FALSE);
595 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
596 g_return_val_if_fail (sinkpad != NULL, FALSE);
597 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
599 GST_INFO (GST_CAT_PADS, "connecting %s:%s and %s:%s",
600 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
602 /* now we need to deal with the real/ghost stuff */
603 realsrc = GST_PAD_REALIZE (srcpad);
604 realsink = GST_PAD_REALIZE (sinkpad);
606 if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
607 GST_INFO (GST_CAT_PADS, "*actually* connecting %s:%s and %s:%s",
608 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
611 g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
612 g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
613 g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, FALSE);
614 g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, FALSE);
616 if (realsrc->sched && realsink->sched) {
617 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
619 if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
622 if (realsrc->sched != realsink->sched && num_decoupled != 1) {
623 g_warning ("connecting pads with different scheds requires exactly one decoupled element (queue)\n");
628 /* check for reversed directions and swap if necessary */
629 if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
630 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
637 g_return_val_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
638 (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK), FALSE);
640 /* first set peers */
641 GST_RPAD_PEER (realsrc) = realsink;
642 GST_RPAD_PEER (realsink) = realsrc;
644 /* try to negotiate the pads, we don't need to clear the caps here */
645 if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, FALSE)) {
646 GST_DEBUG (GST_CAT_CAPS, "pads cannot connect\n");
648 GST_RPAD_PEER (realsrc) = NULL;
649 GST_RPAD_PEER (realsink) = NULL;
654 /* fire off a signal to each of the pads telling them that they've been connected */
655 g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_CONNECTED], 0, realsink);
656 g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_CONNECTED], 0, realsrc);
658 /* now tell the scheduler(s) */
660 gst_scheduler_pad_connect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
661 else if (realsink->sched)
662 gst_scheduler_pad_connect (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
664 GST_INFO (GST_CAT_PADS, "connected %s:%s and %s:%s",
665 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
672 * @srcpad: the source pad to connect
673 * @sinkpad: the sink pad to connect
675 * Connects the source pad to the sink pad.
677 * Returns: TRUE if the pad could be connected, FALSE otherwise
680 gst_pad_connect (GstPad *srcpad, GstPad *sinkpad)
682 return gst_pad_connect_filtered (srcpad, sinkpad, NULL);
686 * gst_pad_set_parent:
687 * @pad: the pad to set the parent
688 * @parent: the object to set the parent to
690 * Sets the parent object of a pad.
693 gst_pad_set_parent (GstPad *pad,
696 g_return_if_fail (pad != NULL);
697 g_return_if_fail (GST_IS_PAD (pad));
698 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
699 g_return_if_fail (parent != NULL);
700 g_return_if_fail (GST_IS_OBJECT (parent));
701 g_return_if_fail ((gpointer)pad != (gpointer)parent);
703 gst_object_set_parent (GST_OBJECT (pad), parent);
707 * gst_pad_get_parent:
708 * @pad: the pad to get the parent from
710 * Get the parent object of this pad.
712 * Returns: the parent object
715 gst_pad_get_parent (GstPad *pad)
717 g_return_val_if_fail (pad != NULL, NULL);
718 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
720 return GST_PAD_PARENT (pad);
724 * gst_pad_get_padtemplate:
725 * @pad: the pad to get the padtemplate from
727 * Get the padtemplate object of this pad.
729 * Returns: the padtemplate object
732 gst_pad_get_padtemplate (GstPad *pad)
734 g_return_val_if_fail (pad != NULL, NULL);
735 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
737 return GST_PAD_PADTEMPLATE (pad);
743 * @pad: the pad to set the scheduler for
744 * @sched: The scheduler to set
746 * Set the scheduler for the pad
749 gst_pad_set_sched (GstPad *pad, GstScheduler *sched)
751 g_return_if_fail (pad != NULL);
752 g_return_if_fail (GST_IS_PAD (pad));
754 GST_RPAD_SCHED(pad) = sched;
759 * @pad: the pad to get the scheduler from
761 * Get the scheduler of the pad
763 * Returns: the scheduler of the pad.
766 gst_pad_get_sched (GstPad *pad)
768 g_return_val_if_fail (pad != NULL, NULL);
769 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
771 return GST_RPAD_SCHED(pad);
775 * gst_pad_unset_sched:
776 * @pad: the pad to unset the scheduler for
778 * Unset the scheduler for the pad
781 gst_pad_unset_sched (GstPad *pad)
783 g_return_if_fail (pad != NULL);
784 g_return_if_fail (GST_IS_PAD (pad));
786 GST_RPAD_SCHED(pad) = NULL;
790 * gst_pad_get_real_parent:
791 * @pad: the pad to get the parent from
793 * Get the real parent object of this pad. If the pad
794 * is a ghostpad, the actual owner of the real pad is
795 * returned, as opposed to the gst_pad_get_parent().
797 * Returns: the parent object
800 gst_pad_get_real_parent (GstPad *pad)
802 g_return_val_if_fail (pad != NULL, NULL);
803 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
805 return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
809 * gst_pad_add_ghost_pad:
810 * @pad: the pad to set the ghost parent
811 * @ghostpad: the ghost pad to add
813 * Add a ghost pad to a pad.
816 gst_pad_add_ghost_pad (GstPad *pad,
821 g_return_if_fail (pad != NULL);
822 g_return_if_fail (GST_IS_PAD (pad));
823 g_return_if_fail (ghostpad != NULL);
824 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
826 realpad = GST_PAD_REALIZE (pad);
828 realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
833 * gst_pad_remove_ghost_pad:
834 * @pad: the pad to remove the ghost parent
835 * @ghostpad: the ghost pad to remove from the pad
837 * Remove a ghost pad from a pad.
840 gst_pad_remove_ghost_pad (GstPad *pad,
845 g_return_if_fail (pad != NULL);
846 g_return_if_fail (GST_IS_PAD (pad));
847 g_return_if_fail (ghostpad != NULL);
848 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
850 realpad = GST_PAD_REALIZE (pad);
852 realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
856 * gst_pad_get_ghost_pad_list:
857 * @pad: the pad to get the ghost parents from
859 * Get the ghost parents of this pad.
861 * Returns: a GList of ghost pads
864 gst_pad_get_ghost_pad_list (GstPad *pad)
866 g_return_val_if_fail (pad != NULL, NULL);
867 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
869 return GST_PAD_REALIZE(pad)->ghostpads;
872 /* an internal caps negotiation helper function does:
874 * 1. optinally calls the pad connect function with the provided caps
875 * 2. deal with the result code of the connect function
876 * 3. set fixed caps on the pad.
878 static GstPadConnectReturn
879 gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
882 GstElement *parent = GST_PAD_PARENT (pad);
884 /* if this pad has a parent and the parent is not READY, delay the
886 if (parent && GST_STATE (parent) < GST_STATE_READY)
887 return GST_PAD_CONNECT_DELAYED;
889 GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
890 caps, GST_DEBUG_PAD_NAME (pad));
892 /* we need to notify the connect function */
893 if (notify && GST_RPAD_CONNECTFUNC (pad)) {
894 GstPadConnectReturn res;
897 GST_INFO (GST_CAT_CAPS, "calling connect function on pad %s:%s",
898 GST_DEBUG_PAD_NAME (pad));
900 /* call the connect function */
901 res = GST_RPAD_CONNECTFUNC (pad) (GST_PAD (pad), caps);
904 case GST_PAD_CONNECT_REFUSED:
905 debug_string = "REFUSED";
907 case GST_PAD_CONNECT_OK:
910 case GST_PAD_CONNECT_DONE:
911 debug_string = "DONE";
913 case GST_PAD_CONNECT_DELAYED:
914 debug_string = "DELAYED";
917 g_warning ("unknown return code from connect function of pad %s:%s",
918 GST_DEBUG_PAD_NAME (pad));
919 return GST_PAD_CONNECT_REFUSED;
922 GST_INFO (GST_CAT_CAPS, "got reply %s (%d) from connect function on pad %s:%s",
923 debug_string, res, GST_DEBUG_PAD_NAME (pad));
925 /* done means the connect function called another caps negotiate function
926 * on this pad that succeeded, we dont need to continue */
927 if (res == GST_PAD_CONNECT_DONE) {
928 GST_INFO (GST_CAT_CAPS, "pad %s:%s is done", GST_DEBUG_PAD_NAME (pad));
929 return GST_PAD_CONNECT_DONE;
931 if (res == GST_PAD_CONNECT_REFUSED) {
932 GST_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps",
933 GST_DEBUG_PAD_NAME (pad));
934 return GST_PAD_CONNECT_REFUSED;
937 /* we can only set caps on the pad if they are ficed */
938 if (GST_CAPS_IS_FIXED (caps)) {
940 GST_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
941 GST_DEBUG_PAD_NAME (pad));
942 /* if we got this far all is ok, remove the old caps, set the new one */
943 oldcaps = GST_PAD_CAPS (pad);
944 if (caps) gst_caps_ref (caps);
945 GST_PAD_CAPS (pad) = caps;
946 if (oldcaps) gst_caps_unref (oldcaps);
949 GST_INFO (GST_CAT_CAPS, "caps are not fixed on pad %s:%s, not setting them yet",
950 GST_DEBUG_PAD_NAME (pad));
953 return GST_PAD_CONNECT_OK;
957 * gst_pad_try_set_caps:
958 * @pad: the pad to try to set the caps on
959 * @caps: the caps to set
961 * Try to set the caps on the given pad.
963 * Returns: TRUE if the caps could be set
966 gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
969 GstRealPad *peer, *realpad;
971 realpad = GST_PAD_REALIZE (pad);
972 peer = GST_RPAD_PEER (realpad);
974 GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
975 caps, GST_DEBUG_PAD_NAME (realpad));
977 /* setting non fixed caps on a pad is not allowed */
978 if (!GST_CAPS_IS_FIXED (caps)) {
979 g_warning ("trying to set non fixed caps on pad %s:%s",
980 GST_DEBUG_PAD_NAME (realpad));
981 gst_caps_debug (caps);
984 /* if we have a peer try to set the caps, notifying the peerpad
985 * if it has a connect function */
986 if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE))
988 /* then try to set our own caps, we don't need to be notified */
989 if (!gst_pad_try_set_caps_func (realpad, caps, FALSE))
995 /* this is a caps negotiation convenience routine, it performs:
997 * 1. optionally clear any pad caps
998 * 2. calculate the intersection between the two pad tamplate/getcaps caps
999 * 3. calculate the intersection with the (optional) filtercaps.
1000 * 4. store the intersection in the pad filter
1001 * 5. store the app filtercaps in the pad appfilter.
1002 * 6. start the caps negotiation.
1005 gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, GstCaps *filtercaps, gboolean clear)
1007 GstCaps *srccaps, *sinkcaps;
1008 GstCaps *intersection = NULL;
1009 GstRealPad *realsrc, *realsink;
1011 realsrc = GST_PAD_REALIZE (srcpad);
1012 realsink = GST_PAD_REALIZE (sinkpad);
1014 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1015 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1017 /* optinally clear the caps */
1019 GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s, clearing caps",
1020 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1022 GST_PAD_CAPS (GST_PAD (realsrc)) = NULL;
1023 GST_PAD_CAPS (GST_PAD (realsink)) = NULL;
1026 GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s",
1027 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1030 srccaps = gst_pad_get_caps (GST_PAD (realsrc));
1031 GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsrc));
1032 gst_caps_debug (srccaps);
1033 sinkcaps = gst_pad_get_caps (GST_PAD (realsink));
1034 GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsink));
1035 gst_caps_debug (sinkcaps);
1037 /* first take the intersection of the pad caps */
1038 intersection = gst_caps_intersect (srccaps, sinkcaps);
1040 /* if we have no intersection but one of the caps was not NULL.. */
1041 if (!intersection && (srccaps || sinkcaps )) {
1042 /* the intersection is NULL but the pad caps were not both NULL,
1043 * this means they have no common format */
1044 GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s have no common type",
1045 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1049 GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s intersected to %s caps",
1050 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink),
1051 ((intersection && GST_CAPS_IS_FIXED (intersection)) ? "fixed" : "variable"));
1053 /* then filter this against the app filter */
1055 GstCaps *filtered_intersection = gst_caps_intersect (intersection, filtercaps);
1057 /* get rid of the old intersection here */
1058 gst_caps_unref (intersection);
1060 if (!filtered_intersection) {
1061 GST_INFO (GST_CAT_PADS, "filtered connection between pads %s:%s and %s:%s is empty",
1062 GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1065 intersection = filtered_intersection;
1067 /* keep a reference to the app caps */
1068 GST_RPAD_APPFILTER (realsink) = filtercaps;
1069 GST_RPAD_APPFILTER (realsrc) = filtercaps;
1072 GST_DEBUG (GST_CAT_CAPS, "setting filter for connection to:\n");
1073 gst_caps_debug (intersection);
1075 GST_RPAD_FILTER (realsrc) = intersection;
1076 GST_RPAD_FILTER (realsink) = intersection;
1078 return gst_pad_perform_negotiate (GST_PAD (realsrc), GST_PAD (realsink));
1082 * gst_pad_perform_negotiate:
1084 * @sinkpad: a sinkpad
1086 * Try to negotiate the pads.
1088 * Returns: a boolean indicating the pad succesfully negotiated.
1091 gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad)
1093 GstCaps *intersection;
1094 GstRealPad *realsrc, *realsink;
1096 g_return_val_if_fail (srcpad != NULL, FALSE);
1097 g_return_val_if_fail (sinkpad != NULL, FALSE);
1099 realsrc = GST_PAD_REALIZE (srcpad);
1100 realsink = GST_PAD_REALIZE (sinkpad);
1102 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1103 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1105 /* it doesn't matter which filter we take */
1106 intersection = GST_RPAD_FILTER (realsrc);
1108 /* no negotiation is performed it the pads have filtercaps */
1110 GstPadConnectReturn res;
1112 res = gst_pad_try_set_caps_func (realsrc, intersection, TRUE);
1113 if (res == GST_PAD_CONNECT_REFUSED)
1115 if (res == GST_PAD_CONNECT_DONE)
1118 res = gst_pad_try_set_caps_func (realsink, intersection, TRUE);
1119 if (res == GST_PAD_CONNECT_REFUSED)
1121 if (res == GST_PAD_CONNECT_DONE)
1128 * gst_pad_try_reconnect_filtered:
1129 * @pad: the pad to reconnect
1130 * @caps: the capabilities to use in the reconnectiong
1132 * Try to reconnect this pad and its peer with the specified caps
1134 * Returns: a boolean indicating the peer pad could accept the caps.
1137 gst_pad_try_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
1139 GstRealPad *realsrc, *realsink;
1141 g_return_val_if_fail (srcpad != NULL, FALSE);
1142 g_return_val_if_fail (sinkpad != NULL, FALSE);
1144 realsrc = GST_PAD_REALIZE (srcpad);
1145 realsink = GST_PAD_REALIZE (sinkpad);
1147 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1148 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1150 return gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE);
1154 * gst_pad_reconnect_filtered:
1155 * @pad: the pad to reconnect
1156 * @caps: the capabilities to use in the reconnectiong
1158 * Try to reconnect this pad and its peer with the specified caps.
1160 * Returns: a boolean indicating the peer pad could accept the caps.
1161 * if FALSE is returned, the pads are disconnected.
1164 gst_pad_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
1166 GstRealPad *realsrc, *realsink;
1168 g_return_val_if_fail (srcpad != NULL, FALSE);
1169 g_return_val_if_fail (sinkpad != NULL, FALSE);
1171 realsrc = GST_PAD_REALIZE (srcpad);
1172 realsink = GST_PAD_REALIZE (sinkpad);
1174 g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
1175 g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
1177 if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE)) {
1178 gst_pad_disconnect (srcpad, GST_PAD (GST_PAD_PEER (srcpad)));
1185 * gst_pad_proxy_connect:
1186 * @pad: the pad to proxy to
1187 * @caps: the capabilities to use in the proxying
1189 * Proxy the connect function to the specified pad.
1191 * Returns: a boolean indicating the peer pad could accept the caps.
1194 gst_pad_proxy_connect (GstPad *pad, GstCaps *caps)
1196 GstRealPad *peer, *realpad;
1198 realpad = GST_PAD_REALIZE (pad);
1200 peer = GST_RPAD_PEER (realpad);
1202 GST_INFO (GST_CAT_CAPS, "proxy connect to pad %s:%s",
1203 GST_DEBUG_PAD_NAME (realpad));
1205 if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE))
1206 return GST_PAD_CONNECT_REFUSED;
1207 if (!gst_pad_try_set_caps_func (realpad, caps, FALSE))
1208 return GST_PAD_CONNECT_REFUSED;
1210 return GST_PAD_CONNECT_OK;
1215 * @pad: the pad to get the capabilities from
1217 * Get the capabilities of this pad.
1219 * Returns: the capabilities of this pad
1222 gst_pad_get_caps (GstPad *pad)
1224 GstRealPad *realpad;
1226 g_return_val_if_fail (pad != NULL, NULL);
1227 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1229 realpad = GST_PAD_REALIZE (pad);
1231 GST_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)\n",
1232 GST_DEBUG_PAD_NAME (realpad), realpad);
1234 if (GST_PAD_CAPS (realpad)) {
1235 GST_DEBUG (GST_CAT_CAPS, "using pad real caps\n");
1236 return GST_PAD_CAPS (realpad);
1238 else if GST_RPAD_GETCAPSFUNC (realpad) {
1239 GST_DEBUG (GST_CAT_CAPS, "using pad get function\n");
1240 return GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad), NULL);
1242 else if (GST_PAD_PADTEMPLATE (realpad)) {
1243 GST_DEBUG (GST_CAT_CAPS, "using pad template\n");
1244 return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (realpad));
1246 GST_DEBUG (GST_CAT_CAPS, "pad has no caps\n");
1252 * gst_pad_get_padtemplate_caps:
1253 * @pad: the pad to get the capabilities from
1255 * Get the capabilities of this pad.
1257 * Returns: a list of the capabilities of this pad
1260 gst_pad_get_padtemplate_caps (GstPad *pad)
1262 g_return_val_if_fail (pad != NULL, NULL);
1263 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1265 if (GST_PAD_PADTEMPLATE (pad))
1266 return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
1273 * gst_padtemplate_get_caps_by_name:
1274 * @templ: the padtemplate to get the capabilities from
1275 * @name: the name of the capability to get
1277 * Get the capability with the given name from this padtemplate.
1279 * Returns: a capability or NULL if not found
1282 gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
1286 g_return_val_if_fail (templ != NULL, NULL);
1288 caps = GST_PADTEMPLATE_CAPS (templ);
1292 return gst_caps_get_by_name (caps, name);
1296 * gst_pad_check_compatibility:
1297 * @srcpad: the srcpad to check
1298 * @sinkpad: the sinkpad to check against
1300 * Check if two pads have compatible capabilities.
1302 * Returns: TRUE if they are compatible or the capabilities
1303 * could not be checked
1306 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
1308 g_return_val_if_fail (srcpad != NULL, FALSE);
1309 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1310 g_return_val_if_fail (sinkpad != NULL, FALSE);
1311 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1313 if (GST_PAD_CAPS (srcpad) && GST_PAD_CAPS (sinkpad)) {
1314 if (!gst_caps_check_compatibility (GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad))) {
1322 GST_DEBUG (GST_CAT_PADS, "could not check capabilities of pads (%s:%s) and (%s:%s) %p %p\n",
1323 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
1324 GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
1331 * @pad: the pad to get the peer from
1333 * Get the peer pad of this pad.
1335 * Returns: the peer pad
1338 gst_pad_get_peer (GstPad *pad)
1340 g_return_val_if_fail (pad != NULL, NULL);
1341 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1343 return GST_PAD (GST_PAD_PEER (pad));
1347 * gst_pad_get_allowed_caps:
1348 * @pad: the pad to get the allowed caps from
1350 * Gst the caps of the allowed media types that can
1351 * go through this pad.
1353 * Returns: the allowed caps
1356 gst_pad_get_allowed_caps (GstPad *pad)
1358 g_return_val_if_fail (pad != NULL, NULL);
1359 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1361 GST_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s\n", GST_DEBUG_PAD_NAME (pad));
1363 return gst_caps_copy (GST_RPAD_FILTER (pad));
1367 * gst_pad_get_allowed_caps:
1368 * @pad: the pad to get the allowed caps from
1370 * Gst the caps of the allowed media types that can
1371 * go through this pad.
1373 * Returns: the allowed caps
1376 gst_pad_recalc_allowed_caps (GstPad *pad)
1380 g_return_if_fail (pad != NULL);
1381 g_return_if_fail (GST_IS_PAD (pad));
1383 GST_DEBUG (GST_CAT_PROPERTIES, "set allowed caps of %s:%s\n", GST_DEBUG_PAD_NAME (pad));
1385 peer = GST_RPAD_PEER (pad);
1387 gst_pad_try_reconnect_filtered (pad, GST_PAD (peer), GST_RPAD_APPFILTER (pad));
1391 * gst_pad_get_bufferpool:
1392 * @pad: the pad to get the bufferpool from
1394 * Get the bufferpool of the peer pad of the given
1397 * Returns: The GstBufferPool or NULL.
1400 gst_pad_get_bufferpool (GstPad *pad)
1404 g_return_val_if_fail (pad != NULL, NULL);
1405 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1407 peer = GST_RPAD_PEER (pad);
1412 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1414 if (peer->bufferpoolfunc) {
1415 GST_DEBUG (GST_CAT_PADS, "calling bufferpoolfunc &%s (@%p) of peer pad %s:%s\n",
1416 GST_DEBUG_FUNCPTR_NAME (peer->bufferpoolfunc), &peer->bufferpoolfunc, GST_DEBUG_PAD_NAME (((GstPad*) peer)));
1417 return (peer->bufferpoolfunc) (((GstPad*) peer));
1419 GST_DEBUG (GST_CAT_PADS, "no bufferpoolfunc for peer pad %s:%s at %p\n",
1420 GST_DEBUG_PAD_NAME (((GstPad*) peer)), &peer->bufferpoolfunc);
1426 gst_real_pad_dispose (GObject *object)
1428 GstPad *pad = GST_PAD (object);
1430 GST_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s\n", GST_DEBUG_PAD_NAME(pad));
1432 if (GST_PAD (pad)->padtemplate){
1433 GST_DEBUG (GST_CAT_REFCOUNTING, "unreffing padtemplate'%s'\n",GST_OBJECT_NAME(GST_OBJECT (GST_PAD (pad)->padtemplate)));
1434 gst_object_unref (GST_OBJECT (GST_PAD (pad)->padtemplate));
1437 if (GST_PAD_PEER (pad)){
1438 GST_DEBUG (GST_CAT_REFCOUNTING, "disconnecting pad '%s'\n",GST_OBJECT_NAME(GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
1439 gst_pad_disconnect (pad, GST_PAD (GST_PAD_PEER (pad)));
1442 /* we destroy the ghostpads, because they are nothing without the real pad */
1443 if (GST_REAL_PAD (pad)->ghostpads) {
1444 GList *orig, *ghostpads;
1446 orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
1449 GstPad *ghostpad = GST_PAD (ghostpads->data);
1451 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))){
1452 GST_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'\n",
1453 GST_OBJECT_NAME (GST_OBJECT_PARENT (ghostpad)));
1455 gst_element_remove_ghost_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), GST_PAD (ghostpad));
1457 ghostpads = g_list_next (ghostpads);
1460 g_list_free (GST_REAL_PAD(pad)->ghostpads);
1463 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))){
1464 GST_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'\n",
1465 GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
1467 gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
1470 G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
1474 #ifndef GST_DISABLE_LOADSAVE
1476 * gst_pad_load_and_connect:
1477 * @self: the XML node to read the description from
1478 * @parent: the element that has the pad
1480 * Read the pad definition from the XML node and connect the given pad
1481 * in element to a pad of an element up in the hierarchy.
1484 gst_pad_load_and_connect (xmlNodePtr self,
1487 xmlNodePtr field = self->xmlChildrenNode;
1488 GstPad *pad = NULL, *targetpad;
1489 guchar *peer = NULL;
1492 GstObject *grandparent;
1495 if (!strcmp (field->name, "name")) {
1496 pad = gst_element_get_pad (GST_ELEMENT (parent), xmlNodeGetContent (field));
1498 else if (!strcmp(field->name, "peer")) {
1499 peer = xmlNodeGetContent (field);
1501 field = field->next;
1503 g_return_if_fail (pad != NULL);
1505 if (peer == NULL) return;
1507 split = g_strsplit (peer, ".", 2);
1509 g_return_if_fail (split[0] != NULL);
1510 g_return_if_fail (split[1] != NULL);
1512 grandparent = gst_object_get_parent (parent);
1514 if (grandparent && GST_IS_BIN (grandparent)) {
1515 target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
1520 if (target == NULL) goto cleanup;
1522 targetpad = gst_element_get_pad (target, split[1]);
1524 if (targetpad == NULL) goto cleanup;
1526 gst_pad_connect (pad, targetpad);
1533 * gst_pad_save_thyself:
1534 * @pad: the pad to save
1535 * @parent: the parent XML node to save the description in
1537 * Saves the pad into an xml representation
1539 * Returns: the xml representation of the pad
1542 gst_pad_save_thyself (GstObject *object,
1545 GstRealPad *realpad;
1548 g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
1550 realpad = GST_REAL_PAD(object);
1552 xmlNewChild(parent,NULL,"name", GST_PAD_NAME (realpad));
1553 if (GST_RPAD_PEER(realpad) != NULL) {
1554 peer = GST_PAD(GST_RPAD_PEER(realpad));
1555 /* first check to see if the peer's parent's parent is the same */
1556 /* we just save it off */
1557 xmlNewChild(parent,NULL,"peer",g_strdup_printf("%s.%s",
1558 GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer)));
1560 xmlNewChild(parent,NULL,"peer","");
1566 * gst_pad_ghost_save_thyself:
1567 * @pad: the pad to save
1569 * @parent: the parent XML node to save the description in
1571 * Saves the ghost pad into an xml representation.
1573 * Returns: the xml representation of the pad
1576 gst_pad_ghost_save_thyself (GstPad *pad,
1582 g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
1584 self = xmlNewChild (parent, NULL, "ghostpad", NULL);
1585 xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
1586 xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
1588 /* FIXME FIXME FIXME! */
1592 #endif /* GST_DISABLE_LOADSAVE */
1594 #ifndef gst_pad_push
1597 * @pad: the pad to push
1598 * @buf: the buffer to push
1600 * Push a buffer to the peer of the pad.
1603 gst_pad_push (GstPad *pad, GstBuffer *buf)
1605 GstRealPad *peer = GST_RPAD_PEER (pad);
1607 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1609 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
1612 g_warning ("push on pad %s:%s but it is unconnected", GST_DEBUG_PAD_NAME (pad));
1615 if (peer->chainhandler) {
1617 GST_DEBUG (GST_CAT_DATAFLOW, "calling chainhandler &%s of peer pad %s:%s\n",
1618 GST_DEBUG_FUNCPTR_NAME (peer->chainhandler), GST_DEBUG_PAD_NAME (GST_PAD (peer)));
1619 (peer->chainhandler) (GST_PAD_CAST (peer), buf);
1623 g_warning ("trying to push a NULL buffer on pad %s:%s", GST_DEBUG_PAD_NAME (peer));
1628 g_warning ("(internal error) push on pad %s:%s but it has no chainhandler", GST_DEBUG_PAD_NAME (peer));
1631 /* clean up the mess here */
1633 if (GST_IS_BUFFER (buf))
1634 gst_buffer_unref (buf);
1636 gst_event_free (GST_EVENT (buf));
1641 #ifndef gst_pad_pull
1644 * @pad: the pad to pull
1646 * Pull a buffer from the peer pad.
1648 * Returns: a new buffer from the peer pad.
1651 gst_pad_pull (GstPad *pad)
1653 GstRealPad *peer = GST_RPAD_PEER(pad);
1655 GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1657 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1660 gst_element_error (GST_PAD_PARENT (pad),
1661 "pull on pad %s:%s but it was unconnected",
1662 GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
1666 if (peer->gethandler) {
1669 GST_DEBUG (GST_CAT_DATAFLOW, "calling gethandler %s of peer pad %s:%s\n",
1670 GST_DEBUG_FUNCPTR_NAME (peer->gethandler), GST_DEBUG_PAD_NAME (peer));
1672 buf = (peer->gethandler) (GST_PAD_CAST (peer));
1675 /* no null buffers allowed */
1676 gst_element_error (GST_PAD_PARENT (pad),
1677 "NULL buffer during pull on %s:%s", GST_DEBUG_PAD_NAME (pad), NULL);
1680 gst_element_error (GST_PAD_PARENT (pad),
1681 "(internal error) pull on pad %s:%s but the peer pad %s:%s has no gethandler",
1682 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer),
1690 #ifndef gst_pad_pullregion
1692 * gst_pad_pullregion:
1693 * @pad: the pad to pull the region from
1694 * @type: the regiontype
1695 * @offset: the offset/start of the buffer to pull
1696 * @len: the length of the buffer to pull
1698 * Pull a buffer region from the peer pad. The region to pull can be
1699 * specified with a offset/lenght pair or with a start/legnth time
1700 * indicator as specified by the type parameter.
1702 * Returns: a new buffer from the peer pad with data in the specified
1706 gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len)
1709 GstBuffer *result = NULL;
1711 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1714 peer = GST_RPAD_PEER(pad);
1715 g_return_val_if_fail (peer != NULL, NULL);
1718 gst_buffer_unref (result);
1720 GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len);
1722 if (peer->pullregionfunc) {
1723 GST_DEBUG (GST_CAT_DATAFLOW, "calling pullregionfunc &%s of peer pad %s:%s\n",
1724 GST_DEBUG_FUNCPTR_NAME (peer->pullregionfunc), GST_DEBUG_PAD_NAME(GST_PAD_CAST (peer)));
1725 result = (peer->pullregionfunc) (GST_PAD_CAST (peer), type, offset, len);
1727 GST_DEBUG (GST_CAT_DATAFLOW,"no pullregionfunc\n");
1733 while (result && !(GST_BUFFER_OFFSET (result) == offset &&
1734 GST_BUFFER_SIZE (result) == len));
1742 * @pad: the pad to peek
1744 * Peek for a buffer from the peer pad.
1746 * Returns: a from the peer pad or NULL if the peer has no buffer.
1749 gst_pad_peek (GstPad *pad)
1751 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1753 return GST_RPAD_BUFPEN (GST_RPAD_PEER (pad));
1758 * @padlist: A list of pads
1760 * Wait for a buffer on the list of pads.
1762 * Returns: The pad that has a buffer available, use
1763 * #gst_pad_pull to get the buffer.
1766 gst_pad_select (GList *padlist)
1770 pad = gst_scheduler_pad_select (GST_PAD_PARENT (padlist->data)->sched, padlist);
1777 * @pad: The first pad to perform the select on
1780 * Wait for a buffer on the given of pads.
1782 * Returns: The pad that has a buffer available, use
1783 * #gst_pad_pull to get the buffer.
1786 gst_pad_selectv (GstPad *pad, ...)
1789 GList *padlist = NULL;
1795 va_start (var_args, pad);
1798 padlist = g_list_prepend (padlist, pad);
1799 pad = va_arg (var_args, GstPad *);
1801 result = gst_pad_select (padlist);
1802 g_list_free (padlist);
1809 /************************************************************************
1814 static void gst_padtemplate_class_init (GstPadTemplateClass *klass);
1815 static void gst_padtemplate_init (GstPadTemplate *templ);
1823 static GstObject *padtemplate_parent_class = NULL;
1824 static guint gst_padtemplate_signals[TEMPL_LAST_SIGNAL] = { 0 };
1827 gst_padtemplate_get_type (void)
1829 static GType padtemplate_type = 0;
1831 if (!padtemplate_type) {
1832 static const GTypeInfo padtemplate_info = {
1833 sizeof(GstPadTemplateClass),
1836 (GClassInitFunc)gst_padtemplate_class_init,
1839 sizeof(GstPadTemplate),
1841 (GInstanceInitFunc)gst_padtemplate_init,
1844 padtemplate_type = g_type_register_static(GST_TYPE_OBJECT, "GstPadTemplate", &padtemplate_info, 0);
1846 return padtemplate_type;
1850 gst_padtemplate_class_init (GstPadTemplateClass *klass)
1852 GObjectClass *gobject_class;
1853 GstObjectClass *gstobject_class;
1855 gobject_class = (GObjectClass*)klass;
1856 gstobject_class = (GstObjectClass*)klass;
1858 padtemplate_parent_class = g_type_class_ref(GST_TYPE_OBJECT);
1860 gst_padtemplate_signals[TEMPL_PAD_CREATED] =
1861 g_signal_new ("pad_created", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
1862 G_STRUCT_OFFSET (GstPadTemplateClass, pad_created), NULL, NULL,
1863 gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
1867 gstobject_class->path_string_separator = "*";
1871 gst_padtemplate_init (GstPadTemplate *templ)
1876 * gst_padtemplate_new:
1877 * @name_template: the name template
1878 * @direction: the direction for the template
1879 * @presence: the presence of the pad
1880 * @caps: a list of capabilities for the template
1881 * @...: more capabilities
1883 * Creates a new padtemplate from the given arguments.
1885 * Returns: the new padtemplate
1888 gst_padtemplate_new (gchar *name_template,
1889 GstPadDirection direction, GstPadPresence presence,
1892 GstPadTemplate *new;
1894 GstCaps *thecaps = NULL;
1896 g_return_val_if_fail (name_template != NULL, NULL);
1898 new = g_object_new(gst_padtemplate_get_type () ,NULL);
1900 GST_PADTEMPLATE_NAME_TEMPLATE (new) = name_template;
1901 GST_PADTEMPLATE_DIRECTION (new) = direction;
1902 GST_PADTEMPLATE_PRESENCE (new) = presence;
1904 va_start (var_args, caps);
1907 new->fixed &= caps->fixed;
1908 thecaps = gst_caps_append (thecaps, caps);
1909 caps = va_arg (var_args, GstCaps*);
1913 GST_PADTEMPLATE_CAPS (new) = thecaps;
1919 * gst_padtemplate_get_caps:
1920 * @templ: the padtemplate to use
1922 * Get the capabilities of the padtemplate
1924 * Returns: a GstCaps*
1927 gst_padtemplate_get_caps (GstPadTemplate *templ)
1929 g_return_val_if_fail (templ != NULL, NULL);
1931 return GST_PADTEMPLATE_CAPS (templ);
1934 #ifndef GST_DISABLE_LOADSAVE
1936 * gst_padtemplate_save_thyself:
1937 * @templ: the padtemplate to save
1938 * @parent: the parent XML tree
1940 * Saves the padtemplate into XML.
1942 * Returns: the new XML tree
1945 gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
1950 GST_DEBUG (GST_CAT_XML,"saving padtemplate %s\n", templ->name_template);
1952 xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
1953 xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
1955 switch (templ->presence) {
1956 case GST_PAD_ALWAYS:
1957 presence = "always";
1959 case GST_PAD_SOMETIMES:
1960 presence = "sometimes";
1962 case GST_PAD_REQUEST:
1963 presence = "request";
1966 presence = "unknown";
1969 xmlNewChild(parent,NULL,"presence", presence);
1971 if (GST_PADTEMPLATE_CAPS (templ)) {
1972 subtree = xmlNewChild (parent, NULL, "caps", NULL);
1973 gst_caps_save_thyself (GST_PADTEMPLATE_CAPS (templ), subtree);
1980 * gst_padtemplate_load_thyself:
1981 * @parent: the source XML tree
1983 * Loads a padtemplate from the XML tree.
1985 * Returns: the new padtemplate
1988 gst_padtemplate_load_thyself (xmlNodePtr parent)
1990 xmlNodePtr field = parent->xmlChildrenNode;
1991 GstPadTemplate *factory;
1992 gchar *name_template = NULL;
1993 GstPadDirection direction = GST_PAD_UNKNOWN;
1994 GstPadPresence presence = GST_PAD_ALWAYS;
1995 GstCaps *caps = NULL;
1998 if (!strcmp(field->name, "nametemplate")) {
1999 name_template = xmlNodeGetContent(field);
2001 if (!strcmp(field->name, "direction")) {
2002 gchar *value = xmlNodeGetContent(field);
2004 if (!strcmp(value, "sink")) {
2005 direction = GST_PAD_SINK;
2007 else if (!strcmp(value, "src")) {
2008 direction = GST_PAD_SRC;
2012 if (!strcmp(field->name, "presence")) {
2013 gchar *value = xmlNodeGetContent(field);
2015 if (!strcmp(value, "always")) {
2016 presence = GST_PAD_ALWAYS;
2018 else if (!strcmp(value, "sometimes")) {
2019 presence = GST_PAD_SOMETIMES;
2021 else if (!strcmp(value, "request")) {
2022 presence = GST_PAD_REQUEST;
2026 else if (!strcmp(field->name, "caps")) {
2027 caps = gst_caps_load_thyself (field);
2029 field = field->next;
2032 factory = gst_padtemplate_new (name_template, direction, presence, caps, NULL);
2036 #endif /* !GST_DISABLE_LOADSAVE */
2040 * gst_pad_set_element_private:
2041 * @pad: the pad to set the private data to
2042 * @priv: The private data to attach to the pad
2044 * Set the given private data pointer to the pad. This
2045 * function can only be used by the element that own the
2049 gst_pad_set_element_private (GstPad *pad, gpointer priv)
2051 pad->element_private = priv;
2055 * gst_pad_get_element_private:
2056 * @pad: the pad to get the private data of
2058 * Get the private data of a pad. The private data can
2059 * only be set by the parent element of this pad.
2061 * Returns: a pointer to the private data.
2064 gst_pad_get_element_private (GstPad *pad)
2066 return pad->element_private;
2070 /***** ghost pads *****/
2071 GType _gst_ghost_pad_type = 0;
2073 static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
2074 static void gst_ghost_pad_init (GstGhostPad *pad);
2076 static GstPad *ghost_pad_parent_class = NULL;
2077 /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
2080 gst_ghost_pad_get_type(void) {
2081 if (!_gst_ghost_pad_type) {
2082 static const GTypeInfo pad_info = {
2083 sizeof(GstGhostPadClass),
2086 (GClassInitFunc)gst_ghost_pad_class_init,
2089 sizeof(GstGhostPad),
2091 (GInstanceInitFunc)gst_ghost_pad_init,
2094 _gst_ghost_pad_type = g_type_register_static(GST_TYPE_PAD, "GstGhostPad", &pad_info, 0);
2096 return _gst_ghost_pad_type;
2100 gst_ghost_pad_class_init (GstGhostPadClass *klass)
2102 GObjectClass *gobject_class;
2104 gobject_class = (GObjectClass*)klass;
2106 ghost_pad_parent_class = g_type_class_ref(GST_TYPE_PAD);
2110 gst_ghost_pad_init (GstGhostPad *pad)
2112 pad->realpad = NULL;
2116 * gst_ghost_pad_new:
2117 * @name: name of the new ghost pad
2118 * @pad: the pad to create a ghost pad of
2120 * Create a new ghost pad associated with the given pad.
2122 * Returns: new ghost pad
2125 gst_ghost_pad_new (gchar *name,
2128 GstGhostPad *ghostpad;
2130 g_return_val_if_fail (name != NULL, NULL);
2131 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2133 ghostpad = g_object_new (gst_ghost_pad_get_type () ,NULL);
2134 gst_pad_set_name (GST_PAD (ghostpad), name);
2135 GST_GPAD_REALPAD (ghostpad) = GST_PAD_REALIZE (pad);
2136 GST_PAD_PADTEMPLATE (ghostpad) = GST_PAD_PADTEMPLATE (pad);
2138 /* add ourselves to the real pad's list of ghostpads */
2139 gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));
2141 /* FIXME need to ref the real pad here... ? */
2143 GST_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\"\n", name);
2145 return GST_PAD (ghostpad);
2149 gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, GstEvent *event)
2151 GList *pads = element->pads;
2154 GstPad *eventpad = GST_PAD (pads->data);
2155 pads = g_list_next (pads);
2157 /* for all pads in the opposite direction that are connected */
2158 if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) && GST_PAD_IS_CONNECTED (eventpad)) {
2159 if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
2160 gst_pad_push (eventpad, GST_BUFFER (gst_event_new (GST_EVENT_TYPE (event))));
2163 GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
2165 gst_pad_send_event (peerpad, gst_event_new (GST_EVENT_TYPE (event)));
2172 * gst_pad_event_default:
2173 * @pad: the pad to operate on
2174 * @event: the event to handle
2176 * Invoke the default event handler for the given pad.
2179 gst_pad_event_default (GstPad *pad, GstEvent *event)
2181 GstElement *element = GST_PAD_PARENT (pad);
2183 g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_EVENT_RECEIVED], 0, event);
2185 switch (GST_EVENT_TYPE (event)) {
2187 gst_element_set_eos (element);
2188 gst_pad_event_default_dispatch (pad, element, event);
2189 gst_event_free (event);
2190 /* we have to try to schedule another element because this one is disabled */
2191 gst_element_yield (element);
2193 case GST_EVENT_FLUSH:
2195 gst_pad_event_default_dispatch (pad, element, event);
2196 gst_event_free (event);
2202 * gst_pad_send_event:
2203 * @pad: the pad to send the event to
2204 * @event: the event to send to the pad.
2206 * Send the event to the pad.
2208 * Returns: TRUE if the event was handled.
2211 gst_pad_send_event (GstPad *pad, GstEvent *event)
2213 gboolean handled = FALSE;
2215 g_return_val_if_fail (event, FALSE);
2217 if (GST_EVENT_SRC (event) == NULL)
2218 GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (pad));
2220 GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n",
2221 GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
2223 if (GST_RPAD_EVENTFUNC (pad))
2224 handled = GST_RPAD_EVENTFUNC (pad) (pad, event);
2226 GST_DEBUG(GST_CAT_EVENT, "there's no event function for pad %s:%s\n", GST_DEBUG_PAD_NAME (pad));
2230 GST_DEBUG(GST_CAT_EVENT, "proceeding with default event behavior here\n");
2231 gst_pad_event_default (pad, event);