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"
27 #include "gstelement.h"
30 #include "gstscheduler.h"
33 /***** Start with the base GstPad class *****/
34 static void gst_pad_class_init (GstPadClass *klass);
35 static void gst_pad_init (GstPad *pad);
37 static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent);
39 static GstObject *pad_parent_class = NULL;
42 gst_pad_get_type(void) {
43 static GtkType pad_type = 0;
46 static const GtkTypeInfo pad_info = {
50 (GtkClassInitFunc)gst_pad_class_init,
51 (GtkObjectInitFunc)gst_pad_init,
54 (GtkClassInitFunc)NULL,
56 pad_type = gtk_type_unique(GST_TYPE_OBJECT,&pad_info);
62 gst_pad_class_init (GstPadClass *klass)
64 pad_parent_class = gtk_type_class(GST_TYPE_OBJECT);
68 gst_pad_init (GstPad *pad)
70 pad->element_private = NULL;
72 pad->padtemplate = NULL;
77 /***** Then do the Real Pad *****/
78 /* Pad signals and args */
82 REAL_CAPS_NEGO_FAILED,
95 static void gst_real_pad_class_init (GstRealPadClass *klass);
96 static void gst_real_pad_init (GstRealPad *pad);
98 static void gst_real_pad_set_arg (GtkObject *object,GtkArg *arg,guint id);
99 static void gst_real_pad_get_arg (GtkObject *object,GtkArg *arg,guint id);
101 static void gst_real_pad_destroy (GtkObject *object);
103 static void gst_pad_push_func (GstPad *pad, GstBuffer *buf);
106 static GstPad *real_pad_parent_class = NULL;
107 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
110 gst_real_pad_get_type(void) {
111 static GtkType pad_type = 0;
114 static const GtkTypeInfo pad_info = {
117 sizeof(GstRealPadClass),
118 (GtkClassInitFunc)gst_real_pad_class_init,
119 (GtkObjectInitFunc)gst_real_pad_init,
122 (GtkClassInitFunc)NULL,
124 pad_type = gtk_type_unique(GST_TYPE_PAD,&pad_info);
130 gst_real_pad_class_init (GstRealPadClass *klass)
132 GtkObjectClass *gtkobject_class;
133 GstObjectClass *gstobject_class;
135 gtkobject_class = (GtkObjectClass*)klass;
136 gstobject_class = (GstObjectClass*)klass;
138 real_pad_parent_class = gtk_type_class(GST_TYPE_PAD);
140 gst_real_pad_signals[REAL_SET_ACTIVE] =
141 gtk_signal_new ("set_active", GTK_RUN_LAST, gtkobject_class->type,
142 GTK_SIGNAL_OFFSET (GstRealPadClass, set_active),
143 gtk_marshal_NONE__BOOL, GTK_TYPE_NONE, 1,
145 gst_real_pad_signals[REAL_CAPS_CHANGED] =
146 gtk_signal_new ("caps_changed", GTK_RUN_LAST, gtkobject_class->type,
147 GTK_SIGNAL_OFFSET (GstRealPadClass, caps_changed),
148 gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
150 gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
151 gtk_signal_new ("caps_nego_failed", GTK_RUN_LAST, gtkobject_class->type,
152 GTK_SIGNAL_OFFSET (GstRealPadClass, caps_nego_failed),
153 gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
155 gst_real_pad_signals[REAL_CONNECTED] =
156 gtk_signal_new ("connected", GTK_RUN_LAST, gtkobject_class->type,
157 GTK_SIGNAL_OFFSET (GstRealPadClass, connected),
158 gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
160 gst_real_pad_signals[REAL_DISCONNECTED] =
161 gtk_signal_new ("disconnected", GTK_RUN_LAST, gtkobject_class->type,
162 GTK_SIGNAL_OFFSET (GstRealPadClass, disconnected),
163 gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
165 gtk_object_class_add_signals (gtkobject_class, gst_real_pad_signals, REAL_LAST_SIGNAL);
167 gtk_object_add_arg_type ("GstRealPad::active", GTK_TYPE_BOOL,
168 GTK_ARG_READWRITE, REAL_ARG_ACTIVE);
170 gtkobject_class->destroy = GST_DEBUG_FUNCPTR(gst_real_pad_destroy);
171 gtkobject_class->set_arg = GST_DEBUG_FUNCPTR(gst_real_pad_set_arg);
172 gtkobject_class->get_arg = GST_DEBUG_FUNCPTR(gst_real_pad_get_arg);
174 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR(gst_pad_save_thyself);
175 gstobject_class->path_string_separator = ".";
179 gst_real_pad_init (GstRealPad *pad)
181 pad->direction = GST_PAD_UNKNOWN;
184 pad->chainfunc = NULL;
186 pad->getregionfunc = NULL;
188 pad->eosfunc = GST_DEBUG_FUNCPTR(gst_pad_eos_func);
190 pad->pushfunc = GST_DEBUG_FUNCPTR(gst_pad_push_func);
191 pad->pullfunc = NULL;
192 pad->pullregionfunc = NULL;
194 pad->bufferpoolfunc = NULL;
195 pad->ghostpads = NULL;
200 gst_real_pad_set_arg (GtkObject *object, GtkArg *arg, guint id)
202 g_return_if_fail(GST_IS_PAD(object));
205 case REAL_ARG_ACTIVE:
206 if (GTK_VALUE_BOOL(*arg)) {
207 gst_info("gstpad: activating pad\n");
208 GST_FLAG_UNSET(object,GST_PAD_DISABLED);
210 gst_info("gstpad: de-activating pad\n");
211 GST_FLAG_SET(object,GST_PAD_DISABLED);
213 gtk_signal_emit(GTK_OBJECT(object), gst_real_pad_signals[REAL_SET_ACTIVE],
214 ! GST_FLAG_IS_SET(object,GST_PAD_DISABLED));
222 gst_real_pad_get_arg (GtkObject *object, GtkArg *arg, guint id)
224 /* it's not null if we got it, but it might not be ours */
225 g_return_if_fail (GST_IS_PAD (object));
228 case REAL_ARG_ACTIVE:
229 GTK_VALUE_BOOL (*arg) = ! GST_FLAG_IS_SET (object, GST_PAD_DISABLED);
239 * @name: name of new pad
240 * @direction: either GST_PAD_SRC or GST_PAD_SINK
242 * Create a new pad with given name.
247 gst_pad_new (gchar *name,
248 GstPadDirection direction)
252 g_return_val_if_fail (name != NULL, NULL);
253 g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
255 pad = gtk_type_new (gst_real_pad_get_type ());
256 gst_object_set_name (GST_OBJECT (pad), name);
257 GST_RPAD_DIRECTION(pad) = direction;
263 * gst_pad_new_from_template:
264 * @templ: the pad template to use
265 * @name: the name of the element
267 * Create a new pad with given name from the given template.
272 gst_pad_new_from_template (GstPadTemplate *templ,
277 g_return_val_if_fail (name != NULL, NULL);
278 g_return_val_if_fail (templ != NULL, NULL);
280 pad = gst_pad_new (name, templ->direction);
281 gst_object_ref (GST_OBJECT (templ));
282 gst_object_sink (GST_OBJECT (templ));
283 GST_PAD_PADTEMPLATE(pad) = templ;
289 * gst_pad_get_direction:
290 * @pad: the Pad to get the direction from
292 * Get the direction of the pad.
294 * Returns: the direction of the pad
297 gst_pad_get_direction (GstPad *pad)
299 g_return_val_if_fail (pad != NULL, GST_PAD_UNKNOWN);
300 g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
302 return GST_PAD_DIRECTION(pad);
307 * @pad: the pad to set the name of
308 * @name: the name of the pad
310 * Set the name of a pad.
313 gst_pad_set_name (GstPad *pad,
316 g_return_if_fail (pad != NULL);
317 g_return_if_fail (GST_IS_PAD (pad));
319 gst_object_set_name (GST_OBJECT (pad), name);
324 * @pad: the pad to get the name of
326 * Get the name of a pad.
328 * Returns: the name of the pad, don't free.
331 gst_pad_get_name (GstPad *pad)
333 g_return_val_if_fail (pad != NULL, NULL);
334 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
336 return GST_OBJECT_NAME (pad);
340 * gst_pad_set_chain_function:
341 * @pad: the pad to set the chain function for
342 * @chain: the chain function
344 * Set the given chain function for the pad.
346 void gst_pad_set_chain_function (GstPad *pad,
347 GstPadChainFunction chain)
349 g_return_if_fail (pad != NULL);
350 g_return_if_fail (GST_IS_REAL_PAD (pad));
352 GST_RPAD_CHAINFUNC(pad) = chain;
353 GST_DEBUG (GST_CAT_PADS,"chainfunc for %s:%s set to %s\n",
354 GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(chain));
358 * gst_pad_set_get_function:
359 * @pad: the pad to set the get function for
360 * @get: the get function
362 * Set the given get function for the pad.
365 gst_pad_set_get_function (GstPad *pad,
366 GstPadGetFunction get)
368 g_return_if_fail (pad != NULL);
369 g_return_if_fail (GST_IS_REAL_PAD (pad));
371 GST_RPAD_GETFUNC(pad) = get;
372 GST_DEBUG (GST_CAT_PADS,"getfunc for %s:%s set to %s\n",
373 GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(get));
377 * gst_pad_set_getregion_function:
378 * @pad: the pad to set the getregion function for
379 * @getregion: the getregion function
381 * Set the given getregion function for the pad.
384 gst_pad_set_getregion_function (GstPad *pad,
385 GstPadGetRegionFunction getregion)
387 g_return_if_fail (pad != NULL);
388 g_return_if_fail (GST_IS_REAL_PAD (pad));
390 GST_RPAD_GETREGIONFUNC(pad) = getregion;
391 GST_DEBUG (GST_CAT_PADS,"getregionfunc for %s:%s set to %s\n",
392 GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(getregion));
396 * gst_pad_set_qos_function:
397 * @pad: the pad to set the qos function for
398 * @qos: the qos function
400 * Set the given qos function for the pad.
403 gst_pad_set_qos_function (GstPad *pad,
404 GstPadQoSFunction qos)
406 g_return_if_fail (pad != NULL);
407 g_return_if_fail (GST_IS_REAL_PAD (pad));
409 GST_RPAD_QOSFUNC(pad) = qos;
410 GST_DEBUG (GST_CAT_PADS,"qosfunc for %s:%s set to %s\n",
411 GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(qos));
415 * gst_pad_set_eos_function:
416 * @pad: the pad to set the eos function for
417 * @eos: the eos function
419 * Set the given EOS function for the pad.
422 gst_pad_set_eos_function (GstPad *pad,
423 GstPadEOSFunction eos)
425 g_return_if_fail (pad != NULL);
426 g_return_if_fail (GST_IS_REAL_PAD (pad));
428 GST_RPAD_EOSFUNC(pad) = eos;
429 GST_DEBUG (GST_CAT_PADS,"eosfunc for %s:%s set to %s\n",
430 GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(eos));
434 * gst_pad_set_negotiate_function:
435 * @pad: the pad to set the negotiate function for
436 * @nego: the negotiate function
438 * Set the given negotiate function for the pad.
441 gst_pad_set_negotiate_function (GstPad *pad,
442 GstPadNegotiateFunction nego)
444 g_return_if_fail (pad != NULL);
445 g_return_if_fail (GST_IS_REAL_PAD (pad));
447 GST_RPAD_NEGOTIATEFUNC(pad) = nego;
448 GST_DEBUG (GST_CAT_PADS,"negotiatefunc for %s:%s set to %s\n",
449 GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(nego));
453 * gst_pad_set_newcaps_function:
454 * @pad: the pad to set the newcaps function for
455 * @newcaps: the newcaps function
457 * Set the given newcaps function for the pad.
460 gst_pad_set_newcaps_function (GstPad *pad,
461 GstPadNewCapsFunction newcaps)
463 g_return_if_fail (pad != NULL);
464 g_return_if_fail (GST_IS_REAL_PAD (pad));
466 GST_RPAD_NEWCAPSFUNC (pad) = newcaps;
467 GST_DEBUG (GST_CAT_PADS,"newcapsfunc for %s:%s set to %s\n",
468 GST_DEBUG_PAD_NAME(pad),GST_DEBUG_FUNCPTR_NAME(newcaps));
472 * gst_pad_set_bufferpool_function:
473 * @pad: the pad to set the bufferpool function for
474 * @bufpool: the bufferpool function
476 * Set the given bufferpool function for the pad.
479 gst_pad_set_bufferpool_function (GstPad *pad,
480 GstPadBufferPoolFunction bufpool)
482 g_return_if_fail (pad != NULL);
483 g_return_if_fail (GST_IS_REAL_PAD (pad));
485 GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool;
486 GST_DEBUG (GST_CAT_PADS,"bufferpoolfunc for %s:%s set to %s\n",
487 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME(bufpool));
491 gst_pad_push_func(GstPad *pad, GstBuffer *buf)
493 if (GST_RPAD_CHAINFUNC(GST_RPAD_PEER(pad)) != NULL) {
494 GST_DEBUG (GST_CAT_DATAFLOW,"calling chain function %s\n",
495 GST_DEBUG_FUNCPTR_NAME(GST_RPAD_CHAINFUNC(GST_RPAD_PEER(pad))));
496 (GST_RPAD_CHAINFUNC(GST_RPAD_PEER(pad)))(pad,buf);
498 GST_DEBUG (GST_CAT_DATAFLOW,"got a problem here: default pad_push handler in place, no chain function\n");
504 * gst_pad_handle_qos:
505 * @pad: the pad to handle the QoS message
506 * @qos_message: the QoS message to handle
508 * Pass the qos message downstream.
511 gst_pad_handle_qos(GstPad *pad,
518 GST_DEBUG (GST_CAT_PADS,"gst_pad_handle_qos(\"%s\",%08ld)\n", GST_OBJECT_NAME (GST_PAD_PARENT (pad)),qos_message);
520 if (GST_RPAD_QOSFUNC(pad)) {
521 (GST_RPAD_QOSFUNC(pad)) (pad,qos_message);
523 element = GST_ELEMENT (GST_PAD_PARENT(GST_RPAD_PEER(pad)));
525 pads = element->pads;
526 GST_DEBUG (GST_CAT_PADS,"gst_pad_handle_qos recurse(\"%s\",%08ld)\n", GST_ELEMENT_NAME (element), qos_message);
528 target_pad = GST_PAD (pads->data);
529 if (GST_RPAD_DIRECTION(target_pad) == GST_PAD_SINK) {
530 gst_pad_handle_qos (target_pad, qos_message);
532 pads = g_list_next (pads);
540 * gst_pad_disconnect:
541 * @srcpad: the source pad to disconnect
542 * @sinkpad: the sink pad to disconnect
544 * Disconnects the source pad from the sink pad.
547 gst_pad_disconnect (GstPad *srcpad,
550 GstRealPad *realsrc, *realsink;
553 g_return_if_fail (srcpad != NULL);
554 g_return_if_fail (GST_IS_PAD (srcpad));
555 g_return_if_fail (sinkpad != NULL);
556 g_return_if_fail (GST_IS_PAD (sinkpad));
558 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnecting %s:%s(%p) and %s:%s(%p)",
559 GST_DEBUG_PAD_NAME(srcpad), srcpad, GST_DEBUG_PAD_NAME(sinkpad), sinkpad);
561 // now we need to deal with the real/ghost stuff
562 realsrc = GST_PAD_REALIZE(srcpad);
563 realsink = GST_PAD_REALIZE(sinkpad);
565 g_return_if_fail (GST_RPAD_PEER(realsrc) != NULL);
566 g_return_if_fail (GST_RPAD_PEER(realsink) != NULL);
568 if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) &&
569 (GST_RPAD_DIRECTION(realsink) == GST_PAD_SRC)) {
576 g_return_if_fail ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
577 (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK));
579 /* first clear peers */
580 GST_RPAD_PEER(realsrc) = NULL;
581 GST_RPAD_PEER(realsink) = NULL;
583 /* fire off a signal to each of the pads telling them that they've been disconnected */
584 gtk_signal_emit(GTK_OBJECT(realsrc), gst_real_pad_signals[REAL_DISCONNECTED], realsink);
585 gtk_signal_emit(GTK_OBJECT(realsink), gst_real_pad_signals[REAL_DISCONNECTED], realsrc);
587 // now tell the scheduler
589 GST_SCHEDULE_PAD_DISCONNECT (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
590 // if (realsink->sched)
591 // GST_SCHEDULE_PAD_DISCONNECT (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
593 GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
594 GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
599 * @srcpad: the source pad to connect
600 * @sinkpad: the sink pad to connect
602 * Connects the source pad to the sink pad.
604 * Returns: TRUE if the pad could be connected
607 gst_pad_connect (GstPad *srcpad,
610 GstRealPad *realsrc, *realsink;
611 gboolean negotiated = FALSE;
614 g_return_val_if_fail(srcpad != NULL, FALSE);
615 g_return_val_if_fail(GST_IS_PAD(srcpad), FALSE);
616 g_return_val_if_fail(sinkpad != NULL, FALSE);
617 g_return_val_if_fail(GST_IS_PAD(sinkpad), FALSE);
619 GST_INFO (GST_CAT_PADS, "connecting %s:%s and %s:%s",
620 GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
622 // now we need to deal with the real/ghost stuff
623 realsrc = GST_PAD_REALIZE(srcpad);
624 realsink = GST_PAD_REALIZE(sinkpad);
626 if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad))
627 GST_INFO (GST_CAT_PADS, "*actually* connecting %s:%s and %s:%s",
628 GST_DEBUG_PAD_NAME(realsrc), GST_DEBUG_PAD_NAME(realsink));
630 g_return_val_if_fail(GST_RPAD_PEER(realsrc) == NULL, FALSE);
631 g_return_val_if_fail(GST_RPAD_PEER(realsink) == NULL, FALSE);
633 /* check for reversed directions and swap if necessary */
634 if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) &&
635 (GST_RPAD_DIRECTION(realsink) == GST_PAD_SRC)) {
642 g_return_val_if_fail((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) &&
643 (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK), FALSE);
646 /* first set peers */
647 GST_RPAD_PEER(realsrc) = realsink;
648 GST_RPAD_PEER(realsink) = realsrc;
650 if (GST_PAD_CAPS (srcpad)) {
651 GST_DEBUG(GST_CAT_PADS, "renegotiation from srcpad\n");
652 negotiated = gst_pad_renegotiate (srcpad);
654 else if (GST_PAD_CAPS (sinkpad)) {
655 GST_DEBUG(GST_CAT_PADS, "renegotiation from sinkpad\n");
656 negotiated = gst_pad_renegotiate (sinkpad);
659 GST_DEBUG(GST_CAT_PADS, "not renegotiating connection\n");
664 GST_INFO(GST_CAT_PADS, "pads %s:%s and %s:%s failed to negotiate, disconnecting",
665 GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
666 gst_pad_disconnect (GST_PAD (realsrc), GST_PAD (realsink));
670 /* fire off a signal to each of the pads telling them that they've been connected */
671 gtk_signal_emit(GTK_OBJECT(realsrc), gst_real_pad_signals[REAL_CONNECTED], realsink);
672 gtk_signal_emit(GTK_OBJECT(realsink), gst_real_pad_signals[REAL_CONNECTED], realsrc);
674 // now tell the scheduler(s)
676 GST_SCHEDULE_PAD_CONNECT (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
677 else if (realsink->sched)
678 GST_SCHEDULE_PAD_CONNECT (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
680 GST_INFO (GST_CAT_PADS, "connected %s:%s and %s:%s",
681 GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
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 (GTK_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);
742 * @pad: the pad to set the scheduler for
743 * @sched: The scheduler to set
745 * Set the sceduler for the pad
748 gst_pad_set_sched (GstPad *pad, GstSchedule *sched)
750 g_return_if_fail (pad != NULL);
751 g_return_if_fail (GST_IS_PAD (pad));
753 GST_RPAD_SCHED(pad) = sched;
758 * @pad: the pad to get the scheduler from
760 * Get the scheduler of the pad
762 * Returns: the scheduler of the pad.
765 gst_pad_get_sched (GstPad *pad)
767 g_return_val_if_fail (pad != NULL, NULL);
768 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
770 return GST_RPAD_SCHED(pad);
774 * gst_pad_get_real_parent:
775 * @pad: the pad to get the parent from
777 * Get the real parent object of this pad. If the pad
778 * is a ghostpad, the actual owner of the real pad is
779 * returned, as opposed to the gst_pad_get_parent().
781 * Returns: the parent object
784 gst_pad_get_real_parent (GstPad *pad)
786 g_return_val_if_fail (pad != NULL, NULL);
787 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
789 return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
793 * gst_pad_add_ghost_pad:
794 * @pad: the pad to set the ghost parent
795 * @ghostpad: the ghost pad to add
797 * Add a ghost pad to a pad.
800 gst_pad_add_ghost_pad (GstPad *pad,
805 g_return_if_fail (pad != NULL);
806 g_return_if_fail (GST_IS_PAD (pad));
807 g_return_if_fail (ghostpad != NULL);
808 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
810 realpad = GST_PAD_REALIZE(pad);
812 realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
817 * gst_pad_remove_ghost_pad:
818 * @pad: the pad to remove the ghost parent
819 * @ghostpad: the ghost pad to remove from the pad
821 * Remove a ghost pad from a pad.
824 gst_pad_remove_ghost_pad (GstPad *pad,
829 g_return_if_fail (pad != NULL);
830 g_return_if_fail (GST_IS_PAD (pad));
831 g_return_if_fail (ghostpad != NULL);
832 g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
834 realpad = GST_PAD_REALIZE (pad);
836 realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
840 * gst_pad_get_ghost_pad_list:
841 * @pad: the pad to get the ghost parents from
843 * Get the ghost parents of this pad.
845 * Returns: a GList of ghost pads
848 gst_pad_get_ghost_pad_list (GstPad *pad)
850 g_return_val_if_fail (pad != NULL, NULL);
851 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
853 return GST_PAD_REALIZE(pad)->ghostpads;
858 * @pad: the pad to set the caps to
859 * @caps: the capabilities to attach to this pad
861 * Set the capabilities of this pad.
863 * Returns: a boolean indicating the caps could be set on the pad
866 gst_pad_set_caps (GstPad *pad,
871 g_return_val_if_fail (pad != NULL, FALSE);
872 g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); // NOTE this restriction
874 GST_INFO (GST_CAT_CAPS, "setting caps %p on pad %s:%s",
875 caps, GST_DEBUG_PAD_NAME(pad));
877 if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) {
878 g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n",
879 GST_DEBUG_PAD_NAME (pad));
883 oldcaps = GST_PAD_CAPS (pad);
887 GST_PAD_CAPS(pad) = caps;
890 gst_caps_unref (oldcaps);
892 return gst_pad_renegotiate (pad);
897 * @pad: the pad to get the capabilities from
899 * Get the capabilities of this pad.
901 * Returns: the capabilities of this pad
904 gst_pad_get_caps (GstPad *pad)
906 g_return_val_if_fail (pad != NULL, NULL);
907 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
909 if (GST_PAD_CAPS (pad))
910 return GST_PAD_CAPS (pad);
911 else if (GST_PAD_PADTEMPLATE (pad))
912 return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
918 * gst_pad_get_padtemplate_caps:
919 * @pad: the pad to get the capabilities from
921 * Get the capabilities of this pad.
923 * Returns: a list of the capabilities of this pad
926 gst_pad_get_padtemplate_caps (GstPad *pad)
928 g_return_val_if_fail (pad != NULL, NULL);
929 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
931 if (GST_PAD_PADTEMPLATE (pad))
932 return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
939 * gst_padtemplate_get_caps_by_name:
940 * @templ: the padtemplate to get the capabilities from
941 * @name: the name of the capability to get
943 * Get the capability with the given name from this padtemplate.
945 * Returns: a capability or NULL if not found
948 gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
952 g_return_val_if_fail (templ != NULL, NULL);
954 caps = GST_PADTEMPLATE_CAPS (templ);
958 return gst_caps_get_by_name (caps, name);
962 * gst_pad_check_compatibility:
963 * @srcpad: the srcpad to check
964 * @sinkpad: the sinkpad to check against
966 * Check if two pads have compatible capabilities.
968 * Returns: TRUE if they are compatible or the capabilities
969 * could not be checked
972 gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
974 g_return_val_if_fail (srcpad != NULL, FALSE);
975 g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
976 g_return_val_if_fail (sinkpad != NULL, FALSE);
977 g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
979 if (GST_PAD_CAPS(srcpad) && GST_PAD_CAPS(sinkpad)) {
980 if (!gst_caps_check_compatibility (GST_PAD_CAPS(srcpad), GST_PAD_CAPS(sinkpad))) {
988 GST_DEBUG (GST_CAT_PADS,"could not check capabilities of pads (%s:%s) and (%s:%s) %p %p\n",
989 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
990 GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
997 * @pad: the pad to get the peer from
999 * Get the peer pad of this pad.
1001 * Returns: the peer pad
1004 gst_pad_get_peer (GstPad *pad)
1006 g_return_val_if_fail (pad != NULL, NULL);
1007 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1009 return GST_PAD(GST_PAD_PEER(pad));
1013 * gst_pad_get_bufferpool:
1014 * @pad: the pad to get the bufferpool from
1016 * Get the bufferpool of the peer pad of the given
1019 * Returns: The GstBufferPool or NULL.
1022 gst_pad_get_bufferpool (GstPad *pad)
1026 g_return_val_if_fail (pad != NULL, NULL);
1027 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1029 peer = GST_RPAD_PEER(pad);
1031 g_return_val_if_fail (peer != NULL, NULL);
1033 GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1035 if (peer->bufferpoolfunc) {
1036 GST_DEBUG (GST_CAT_PADS,"calling bufferpoolfunc &%s (@%p) of peer pad %s:%s\n",
1037 GST_DEBUG_FUNCPTR_NAME(peer->bufferpoolfunc),&peer->bufferpoolfunc,GST_DEBUG_PAD_NAME(((GstPad*)peer)));
1038 return (peer->bufferpoolfunc)(((GstPad*)peer));
1040 GST_DEBUG (GST_CAT_PADS,"no bufferpoolfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(((GstPad*)peer)),&peer->bufferpoolfunc);
1046 gst_real_pad_destroy (GtkObject *object)
1048 GstPad *pad = GST_PAD (object);
1050 GST_DEBUG (GST_CAT_REFCOUNTING, "destroy %s:%s\n", GST_DEBUG_PAD_NAME(pad));
1052 if (GST_PAD (pad)->padtemplate)
1053 gst_object_unref (GST_OBJECT (GST_PAD (pad)->padtemplate));
1055 if (GST_PAD_PEER (pad))
1056 gst_pad_disconnect (pad, GST_PAD (GST_PAD_PEER (pad)));
1058 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad)))
1059 gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
1061 // FIXME we should destroy the ghostpads, because they are nothing without the real pad
1062 if (GST_REAL_PAD (pad)->ghostpads) {
1063 GList *orig, *ghostpads;
1065 orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
1068 GstPad *ghostpad = GST_PAD (ghostpads->data);
1070 if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad)))
1071 gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), ghostpad);
1073 ghostpads = g_list_next (ghostpads);
1076 g_list_free (GST_REAL_PAD(pad)->ghostpads);
1079 if (GTK_OBJECT_CLASS (real_pad_parent_class)->destroy)
1080 GTK_OBJECT_CLASS (real_pad_parent_class)->destroy (object);
1085 * gst_pad_load_and_connect:
1086 * @self: the XML node to read the description from
1087 * @parent: the element that has the pad
1089 * Read the pad definition from the XML node and connect the given pad
1090 * in element to a pad of an element up in the hierarchy.
1093 gst_pad_load_and_connect (xmlNodePtr self,
1096 xmlNodePtr field = self->xmlChildrenNode;
1097 GstPad *pad = NULL, *targetpad;
1098 guchar *peer = NULL;
1101 GstObject *grandparent;
1104 if (!strcmp (field->name, "name")) {
1105 pad = gst_element_get_pad (GST_ELEMENT (parent), xmlNodeGetContent (field));
1107 else if (!strcmp(field->name, "peer")) {
1108 peer = g_strdup (xmlNodeGetContent (field));
1110 field = field->next;
1112 g_return_if_fail (pad != NULL);
1114 if (peer == NULL) return;
1116 split = g_strsplit (peer, ".", 2);
1118 g_return_if_fail (split[0] != NULL);
1119 g_return_if_fail (split[1] != NULL);
1121 grandparent = gst_object_get_parent (parent);
1123 if (grandparent && GST_IS_BIN (grandparent)) {
1124 target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
1129 if (target == NULL) goto cleanup;
1131 targetpad = gst_element_get_pad (target, split[1]);
1133 if (targetpad == NULL) goto cleanup;
1135 gst_pad_connect (pad, targetpad);
1142 gst_pad_renegotiate_func (GstPad *pad, gpointer *data1, GstPad *peerpad, gpointer *data2, GstCaps **newcaps)
1144 GstRealPad *currentpad, *otherpad;
1145 gpointer *currentdata, *otherdata;
1146 GstPadNegotiateReturn result;
1149 g_return_val_if_fail (pad != NULL, FALSE);
1151 currentpad = GST_PAD_REALIZE (pad);
1152 otherpad = GST_REAL_PAD (peerpad);
1153 currentdata = data1;
1156 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiating pad %s:%s and %s:%s data:%p\n",
1157 GST_DEBUG_PAD_NAME(currentpad), GST_DEBUG_PAD_NAME(otherpad), currentdata);
1160 gboolean matchtempl;
1163 if (otherpad->negotiatefunc) {
1167 GST_DEBUG (GST_CAT_NEGOTIATION, "requesting other caps from pad %s:%s data:%p\n",
1168 GST_DEBUG_PAD_NAME(otherpad), otherdata);
1169 otherpad->negotiatefunc (GST_PAD (otherpad), newcaps, otherdata);
1172 otherpad = currentpad;
1175 tempdata = otherdata;
1176 otherdata = currentdata;
1177 currentdata = tempdata;
1181 GST_DEBUG (GST_CAT_NEGOTIATION, "checking compatibility with pad %s:%s\n",
1182 GST_DEBUG_PAD_NAME(otherpad));
1183 matchtempl = gst_caps_check_compatibility (*newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad)));
1185 GST_DEBUG (GST_CAT_NEGOTIATION, "caps compatibility check %s\n", (matchtempl?"ok":"fail"));
1188 GST_DEBUG (GST_CAT_NEGOTIATION, "checking if other pad %s:%s can negotiate data:%p\n",
1189 GST_DEBUG_PAD_NAME(otherpad), otherdata);
1190 if (otherpad->negotiatefunc) {
1194 GST_DEBUG (GST_CAT_NEGOTIATION, "switching pad for next phase\n");
1197 currentpad = otherpad;
1200 tempdata = otherdata;
1201 otherdata = currentdata;
1202 currentdata = tempdata;
1204 else if (gst_caps_check_compatibility (*newcaps, GST_PAD_CAPS (otherpad))) {
1205 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n");
1209 *newcaps = GST_PAD_CAPS (otherpad);
1210 if (*newcaps) gst_caps_ref(*newcaps);
1214 *newcaps = GST_PAD_CAPS (otherpad);
1215 if (*newcaps) gst_caps_ref(*newcaps);
1220 if (currentpad->negotiatefunc) {
1221 GST_DEBUG (GST_CAT_NEGOTIATION, "calling negotiate function on pad %s:%s data: %p\n",
1222 GST_DEBUG_PAD_NAME (currentpad), currentdata);
1223 result = currentpad->negotiatefunc (GST_PAD (currentpad), newcaps, currentdata);
1226 case GST_PAD_NEGOTIATE_FAIL:
1227 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed\n");
1229 case GST_PAD_NEGOTIATE_AGREE:
1230 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n");
1232 case GST_PAD_NEGOTIATE_TRY:
1233 GST_DEBUG (GST_CAT_NEGOTIATION, "try another option\n");
1236 GST_DEBUG (GST_CAT_NEGOTIATION, "invalid return\n");
1241 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, no more options\n");
1245 } while (counter < 100);
1247 g_warning ("negotiation between (%s:%s) and (%s:%s) failed: too many attempts (%d)\n",
1248 GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad), counter);
1250 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, too many attempts\n");
1256 * gst_pad_renegotiate:
1257 * @pad: the pad to perform the negotiation on
1259 * Perform the negotiation process with the peer pad.
1261 * Returns: TRUE if the negotiation process succeded
1264 gst_pad_renegotiate (GstPad *pad)
1266 GstCaps *newcaps = NULL;
1267 GstRealPad *peerpad, *currentpad, *otherpad;
1269 gpointer data1 = NULL, data2 = NULL;
1271 g_return_val_if_fail (pad != NULL, FALSE);
1273 peerpad = GST_PAD_PEER (pad);
1275 currentpad = GST_PAD_REALIZE (pad);
1278 GST_DEBUG (GST_CAT_NEGOTIATION, "no peer pad for pad %s:%s\n",
1279 GST_DEBUG_PAD_NAME(currentpad));
1283 otherpad = GST_REAL_PAD (peerpad);
1285 GST_INFO (GST_CAT_NEGOTIATION, "negotiating pad %s:%s and %s:%s",
1286 GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad));
1288 newcaps = GST_PAD_CAPS (pad);
1290 result = gst_pad_renegotiate_func (GST_PAD (currentpad), &data1, GST_PAD (otherpad), &data2, &newcaps);
1293 GST_DEBUG (GST_CAT_NEGOTIATION, "firing caps_nego_failed signal on %s:%s and %s:%s to give it a chance to succeed\n",
1294 GST_DEBUG_PAD_NAME(currentpad),GST_DEBUG_PAD_NAME(otherpad));
1295 gtk_signal_emit (GTK_OBJECT(currentpad),
1296 gst_real_pad_signals[REAL_CAPS_NEGO_FAILED],&result);
1297 gtk_signal_emit (GTK_OBJECT(otherpad),
1298 gst_real_pad_signals[REAL_CAPS_NEGO_FAILED],&result);
1300 GST_DEBUG (GST_CAT_NEGOTIATION, "caps_nego_failed handler claims success at renego, believing\n");
1304 GST_DEBUG (GST_CAT_NEGOTIATION, "pads aggreed on caps :)\n");
1306 newcaps = GST_PAD_CAPS (pad);
1307 g_return_val_if_fail(newcaps != NULL, FALSE); // FIXME is this valid?
1309 /* here we have some sort of aggreement of the caps */
1310 GST_PAD_CAPS (currentpad) = gst_caps_ref (newcaps);
1311 if (GST_RPAD_NEWCAPSFUNC (currentpad))
1312 GST_RPAD_NEWCAPSFUNC (currentpad) (GST_PAD (currentpad), newcaps);
1314 GST_PAD_CAPS (otherpad) = gst_caps_ref (newcaps);
1315 if (GST_RPAD_NEWCAPSFUNC (otherpad))
1316 GST_RPAD_NEWCAPSFUNC (otherpad) (GST_PAD (otherpad), newcaps);
1318 GST_DEBUG (GST_CAT_NEGOTIATION, "firing caps_changed signal on %s:%s and %s:%s\n",
1319 GST_DEBUG_PAD_NAME(currentpad),GST_DEBUG_PAD_NAME(otherpad));
1320 gtk_signal_emit (GTK_OBJECT(currentpad),
1321 gst_real_pad_signals[REAL_CAPS_CHANGED],GST_PAD_CAPS(currentpad));
1322 gtk_signal_emit (GTK_OBJECT(otherpad),
1323 gst_real_pad_signals[REAL_CAPS_CHANGED],GST_PAD_CAPS(otherpad));
1330 * gst_pad_negotiate_proxy:
1331 * @srcpad: the pad that proxies
1332 * @destpad: the pad to proxy the negotiation to
1333 * @caps: the current caps
1335 * Proxies the negotiation pad from srcpad to destpad. Further
1336 * negotiation is done on the peers of both pad instead.
1338 * Returns: the result of the negotiation preocess.
1340 GstPadNegotiateReturn
1341 gst_pad_negotiate_proxy (GstPad *srcpad, GstPad *destpad, GstCaps **caps)
1343 GstRealPad *srcpeer;
1344 GstRealPad *destpeer;
1346 gpointer data1 = NULL, data2 = NULL;
1348 g_return_val_if_fail (srcpad != NULL, GST_PAD_NEGOTIATE_FAIL);
1349 g_return_val_if_fail (destpad != NULL, GST_PAD_NEGOTIATE_FAIL);
1351 GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation proxied from pad (%s:%s) to pad (%s:%s)\n",
1352 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1354 srcpeer = GST_RPAD_PEER (srcpad);
1355 destpeer = GST_RPAD_PEER (destpad);
1357 if (srcpeer && destpeer) {
1358 result = gst_pad_renegotiate_func (GST_PAD (srcpeer), &data1, GST_PAD (destpeer), &data2, caps);
1361 GST_DEBUG (GST_CAT_NEGOTIATION, "pads (%s:%s) and (%s:%s) aggreed on caps :)\n",
1362 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1364 /* here we have some sort of aggreement of the caps */
1365 GST_PAD_CAPS (destpeer) = *caps;
1366 if (GST_RPAD_NEWCAPSFUNC (destpeer))
1367 GST_RPAD_NEWCAPSFUNC (destpeer) (GST_PAD (destpeer), *caps);
1369 GST_PAD_CAPS (destpad) = *caps;
1370 if (GST_RPAD_NEWCAPSFUNC (destpad))
1371 GST_RPAD_NEWCAPSFUNC (destpad) (GST_PAD (destpad), *caps);
1374 GST_DEBUG (GST_CAT_NEGOTIATION, "pads did not aggree on caps :(\n");
1375 return GST_PAD_NEGOTIATE_FAIL;
1379 return GST_PAD_NEGOTIATE_AGREE;
1383 * gst_pad_save_thyself:
1384 * @pad: the pad to save
1385 * @parent: the parent XML node to save the description in
1387 * Saves the pad into an xml representation
1389 * Returns: the xml representation of the pad
1392 gst_pad_save_thyself (GstObject *object,
1395 GstRealPad *realpad;
1398 g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
1400 realpad = GST_REAL_PAD(object);
1402 xmlNewChild(parent,NULL,"name", GST_PAD_NAME (realpad));
1403 if (GST_RPAD_PEER(realpad) != NULL) {
1404 peer = GST_PAD(GST_RPAD_PEER(realpad));
1405 // first check to see if the peer's parent's parent is the same
1406 // we just save it off
1407 xmlNewChild(parent,NULL,"peer",g_strdup_printf("%s.%s",
1408 GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer)));
1410 xmlNewChild(parent,NULL,"peer","");
1416 * gst_pad_ghost_save_thyself:
1417 * @pad: the pad to save
1419 * @parent: the parent XML node to save the description in
1421 * Saves the ghost pad into an xml representation.
1423 * Returns: the xml representation of the pad
1426 gst_pad_ghost_save_thyself (GstPad *pad,
1432 g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
1434 self = xmlNewChild(parent,NULL,"ghostpad",NULL);
1435 xmlNewChild(self,NULL,"name", GST_PAD_NAME (pad));
1436 xmlNewChild(self,NULL,"parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
1438 // FIXME FIXME FIXME!
1443 #ifndef gst_pad_push
1446 * @pad: the pad to push
1447 * @buf: the buffer to push
1449 * Push a buffer to the peer of the pad.
1452 gst_pad_push (GstPad *pad, GstBuffer *buf)
1454 GstRealPad *peer = GST_RPAD_PEER (pad);
1456 GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
1458 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
1459 g_return_if_fail (peer != NULL);
1461 if (peer->pushfunc) {
1462 GST_DEBUG (GST_CAT_DATAFLOW, "calling pushfunc &%s of peer pad %s:%s\n",
1463 GST_DEBUG_FUNCPTR_NAME (peer->pushfunc), GST_DEBUG_PAD_NAME (((GstPad*)peer)));
1464 (peer->pushfunc) (((GstPad*)peer), buf);
1466 GST_DEBUG (GST_CAT_DATAFLOW, "no pushfunc\n");
1470 #ifndef gst_pad_pull
1473 * @pad: the pad to pull
1475 * Pull a buffer from the peer pad.
1477 * Returns: a new buffer from the peer pad.
1480 gst_pad_pull (GstPad *pad)
1482 GstRealPad *peer = GST_RPAD_PEER(pad);
1484 GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
1486 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1487 g_return_val_if_fail (peer != NULL, NULL);
1489 if (peer->pullfunc) {
1490 GST_DEBUG (GST_CAT_DATAFLOW,"calling pullfunc %s of peer pad %s:%s\n",
1491 GST_DEBUG_FUNCPTR_NAME(peer->pullfunc),GST_DEBUG_PAD_NAME(peer));
1492 return (peer->pullfunc)(((GstPad*)peer));
1494 GST_DEBUG (GST_CAT_DATAFLOW,"no pullfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(((GstPad*)peer)),&peer->pullfunc);
1500 #ifndef gst_pad_pullregion
1502 * gst_pad_pullregion:
1503 * @pad: the pad to pull the region from
1504 * @type: the regiontype
1505 * @offset: the offset/start of the buffer to pull
1506 * @len: the length of the buffer to pull
1508 * Pull a buffer region from the peer pad. The region to pull can be
1509 * specified with a offset/lenght pair or with a start/legnth time
1510 * indicator as specified by the type parameter.
1512 * Returns: a new buffer from the peer pad with data in the specified
1516 gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len)
1518 GstRealPad *peer = GST_RPAD_PEER(pad);
1520 g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, NULL);
1521 g_return_val_if_fail (peer != NULL, NULL);
1523 GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len);
1525 if (peer->pullregionfunc) {
1526 GST_DEBUG (GST_CAT_DATAFLOW,"calling pullregionfunc &%s of peer pad %s:%s\n",
1527 GST_DEBUG_FUNCPTR_NAME(peer->pullregionfunc),GST_DEBUG_PAD_NAME(((GstPad*)peer)));
1528 return (peer->pullregionfunc)(((GstPad*)peer),type,offset,len);
1530 GST_DEBUG (GST_CAT_DATAFLOW,"no pullregionfunc\n");
1536 /************************************************************************
1541 static void gst_padtemplate_class_init (GstPadTemplateClass *klass);
1542 static void gst_padtemplate_init (GstPadTemplate *templ);
1550 static GstObject *padtemplate_parent_class = NULL;
1551 static guint gst_padtemplate_signals[TEMPL_LAST_SIGNAL] = { 0 };
1554 gst_padtemplate_get_type (void)
1556 static GtkType padtemplate_type = 0;
1558 if (!padtemplate_type) {
1559 static const GtkTypeInfo padtemplate_info = {
1561 sizeof(GstPadTemplate),
1562 sizeof(GstPadTemplateClass),
1563 (GtkClassInitFunc)gst_padtemplate_class_init,
1564 (GtkObjectInitFunc)gst_padtemplate_init,
1565 (GtkArgSetFunc)NULL,
1566 (GtkArgGetFunc)NULL,
1567 (GtkClassInitFunc)NULL,
1569 padtemplate_type = gtk_type_unique(GST_TYPE_OBJECT,&padtemplate_info);
1571 return padtemplate_type;
1575 gst_padtemplate_class_init (GstPadTemplateClass *klass)
1577 GtkObjectClass *gtkobject_class;
1578 GstObjectClass *gstobject_class;
1580 gtkobject_class = (GtkObjectClass*)klass;
1581 gstobject_class = (GstObjectClass*)klass;
1583 padtemplate_parent_class = gtk_type_class(GST_TYPE_OBJECT);
1585 gst_padtemplate_signals[TEMPL_PAD_CREATED] =
1586 gtk_signal_new ("pad_created", GTK_RUN_LAST, gtkobject_class->type,
1587 GTK_SIGNAL_OFFSET (GstPadTemplateClass, pad_created),
1588 gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
1591 gtk_object_class_add_signals (gtkobject_class, gst_padtemplate_signals, TEMPL_LAST_SIGNAL);
1593 gstobject_class->path_string_separator = "*";
1597 gst_padtemplate_init (GstPadTemplate *templ)
1602 * gst_padtemplate_new:
1603 * @name_template: the name template
1604 * @direction: the direction for the template
1605 * @presence: the presence of the pad
1606 * @caps: a list of capabilities for the template
1607 * @...: more capabilities
1609 * Creates a new padtemplate from the given arguments.
1611 * Returns: the new padtemplate
1614 gst_padtemplate_new (gchar *name_template,
1615 GstPadDirection direction, GstPadPresence presence,
1618 GstPadTemplate *new;
1620 GstCaps *thecaps = NULL;
1622 g_return_val_if_fail (name_template != NULL, NULL);
1624 new = gtk_type_new (gst_padtemplate_get_type ());
1626 GST_PADTEMPLATE_NAME_TEMPLATE (new) = name_template;
1627 GST_PADTEMPLATE_DIRECTION (new) = direction;
1628 GST_PADTEMPLATE_PRESENCE (new) = presence;
1630 va_start (var_args, caps);
1633 thecaps = gst_caps_append (thecaps, caps);
1634 caps = va_arg (var_args, GstCaps*);
1638 GST_PADTEMPLATE_CAPS (new) = thecaps;
1644 * gst_padtemplate_get_caps:
1645 * @templ: the padtemplate to use
1647 * Get the capabilities of the padtemplate
1649 * Returns: a GstCaps*
1652 gst_padtemplate_get_caps (GstPadTemplate *templ)
1654 g_return_val_if_fail (templ != NULL, NULL);
1656 return GST_PADTEMPLATE_CAPS (templ);
1660 * gst_padtemplate_save_thyself:
1661 * @templ: the padtemplate to save
1662 * @parent: the parent XML tree
1664 * Saves the padtemplate into XML.
1666 * Returns: the new XML tree
1669 gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
1674 GST_DEBUG (GST_CAT_XML,"saving padtemplate %s\n", templ->name_template);
1676 xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
1677 xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
1679 switch (templ->presence) {
1680 case GST_PAD_ALWAYS:
1681 presence = "always";
1683 case GST_PAD_SOMETIMES:
1684 presence = "sometimes";
1686 case GST_PAD_REQUEST:
1687 presence = "request";
1690 presence = "unknown";
1693 xmlNewChild(parent,NULL,"presence", presence);
1695 if (GST_PADTEMPLATE_CAPS (templ)) {
1696 subtree = xmlNewChild (parent, NULL, "caps", NULL);
1697 gst_caps_save_thyself (GST_PADTEMPLATE_CAPS (templ), subtree);
1704 * gst_padtemplate_load_thyself:
1705 * @parent: the source XML tree
1707 * Loads a padtemplate from the XML tree.
1709 * Returns: the new padtemplate
1712 gst_padtemplate_load_thyself (xmlNodePtr parent)
1714 xmlNodePtr field = parent->xmlChildrenNode;
1715 GstPadTemplate *factory;
1716 gchar *name_template = NULL;
1717 GstPadDirection direction = GST_PAD_UNKNOWN;
1718 GstPadPresence presence = GST_PAD_ALWAYS;
1719 GstCaps *caps = NULL;
1722 if (!strcmp(field->name, "nametemplate")) {
1723 name_template = xmlNodeGetContent(field);
1725 if (!strcmp(field->name, "direction")) {
1726 gchar *value = xmlNodeGetContent(field);
1728 if (!strcmp(value, "sink")) {
1729 direction = GST_PAD_SINK;
1731 else if (!strcmp(value, "src")) {
1732 direction = GST_PAD_SRC;
1736 if (!strcmp(field->name, "presence")) {
1737 gchar *value = xmlNodeGetContent(field);
1739 if (!strcmp(value, "always")) {
1740 presence = GST_PAD_ALWAYS;
1742 else if (!strcmp(value, "sometimes")) {
1743 presence = GST_PAD_SOMETIMES;
1745 else if (!strcmp(value, "request")) {
1746 presence = GST_PAD_REQUEST;
1750 else if (!strcmp(field->name, "caps")) {
1751 caps = gst_caps_load_thyself (field);
1753 field = field->next;
1756 factory = gst_padtemplate_new (name_template, direction, presence, caps, NULL);
1763 gst_pad_eos_func(GstPad *pad)
1765 GstElement *element;
1768 gboolean result = TRUE, success;
1770 g_return_val_if_fail (pad != NULL, FALSE);
1771 g_return_val_if_fail (GST_IS_REAL_PAD(pad), FALSE); // NOTE the restriction
1773 GST_INFO (GST_CAT_PADS,"attempting to set EOS on sink pad %s:%s",GST_DEBUG_PAD_NAME(pad));
1775 element = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (pad)));
1776 // g_return_val_if_fail (element != NULL, FALSE);
1777 // g_return_val_if_fail (GST_IS_ELEMENT(element), FALSE);
1779 pads = gst_element_get_pad_list(element);
1781 srcpad = GST_PAD(pads->data);
1782 pads = g_list_next(pads);
1784 if (gst_pad_get_direction(srcpad) == GST_PAD_SRC) {
1785 result = gst_pad_eos(GST_REAL_PAD(srcpad));
1786 if (result == FALSE) success = FALSE;
1790 if (result == FALSE) return FALSE;
1792 GST_INFO (GST_CAT_PADS,"set EOS on sink pad %s:%s",GST_DEBUG_PAD_NAME(pad));
1793 GST_FLAG_SET (pad, GST_PAD_EOS);
1795 gst_element_set_state (GST_ELEMENT(GST_PAD_PARENT(pad)), GST_STATE_READY);
1802 * @pad: the pad to set to eos
1804 * Sets the given pad to the EOS state.
1806 * Returns: TRUE if it succeeded
1809 gst_pad_set_eos(GstPad *pad)
1811 g_return_val_if_fail (pad != NULL, FALSE);
1812 g_return_val_if_fail (GST_IS_REAL_PAD(pad), FALSE); // NOTE the restriction
1813 g_return_val_if_fail (GST_PAD_CONNECTED(pad), FALSE);
1815 GST_INFO (GST_CAT_PADS,"attempting to set EOS on src pad %s:%s",GST_DEBUG_PAD_NAME(pad));
1817 if (!gst_pad_eos(GST_REAL_PAD(pad))) {
1821 GST_INFO (GST_CAT_PADS,"set EOS on src pad %s:%s",GST_DEBUG_PAD_NAME(pad));
1822 GST_FLAG_SET (pad, GST_PAD_EOS);
1824 gst_element_set_state (GST_ELEMENT(GST_PAD_PARENT(pad)), GST_STATE_READY);
1826 gst_element_signal_eos (GST_ELEMENT (GST_PAD_PARENT (pad)));
1832 * gst_pad_set_element_private:
1833 * @pad: the pad to set the private data to
1834 * @priv: The private data to attach to the pad
1836 * Set the given private data pointer to the pad. This
1837 * function can only be used by the element that own the
1841 gst_pad_set_element_private (GstPad *pad, gpointer priv)
1843 pad->element_private = priv;
1847 * gst_pad_get_element_private:
1848 * @pad: the pad to get the private data of
1850 * Get the private data of a pad. The private data can
1851 * only be set by the parent element of this pad.
1853 * Returns: a pointer to the private data.
1856 gst_pad_get_element_private (GstPad *pad)
1858 return pad->element_private;
1862 /***** ghost pads *****/
1864 static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
1865 static void gst_ghost_pad_init (GstGhostPad *pad);
1867 static GstPad *ghost_pad_parent_class = NULL;
1868 //static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 };
1871 gst_ghost_pad_get_type(void) {
1872 static GtkType pad_type = 0;
1875 static const GtkTypeInfo pad_info = {
1877 sizeof(GstGhostPad),
1878 sizeof(GstGhostPadClass),
1879 (GtkClassInitFunc)gst_ghost_pad_class_init,
1880 (GtkObjectInitFunc)gst_ghost_pad_init,
1881 (GtkArgSetFunc)NULL,
1882 (GtkArgGetFunc)NULL,
1883 (GtkClassInitFunc)NULL,
1885 pad_type = gtk_type_unique(GST_TYPE_PAD,&pad_info);
1891 gst_ghost_pad_class_init (GstGhostPadClass *klass)
1893 GtkObjectClass *gtkobject_class;
1895 gtkobject_class = (GtkObjectClass*)klass;
1897 ghost_pad_parent_class = gtk_type_class(GST_TYPE_PAD);
1901 gst_ghost_pad_init (GstGhostPad *pad)
1903 pad->realpad = NULL;
1907 * gst_ghost_pad_new:
1908 * @name: name of the new ghost pad
1909 * @pad: the pad to create a ghost pad of
1911 * Create a new ghost pad associated with the given pad.
1913 * Returns: new ghost pad
1916 gst_ghost_pad_new (gchar *name,
1919 GstGhostPad *ghostpad;
1921 g_return_val_if_fail (name != NULL, NULL);
1922 g_return_val_if_fail (GST_IS_PAD(pad), NULL);
1924 ghostpad = gtk_type_new (gst_ghost_pad_get_type ());
1925 gst_pad_set_name (GST_PAD (ghostpad), name);
1926 GST_GPAD_REALPAD(ghostpad) = GST_PAD_REALIZE(pad);
1928 // add ourselves to the real pad's list of ghostpads
1929 gst_pad_add_ghost_pad (pad, GST_PAD(ghostpad));
1931 // FIXME need to ref the real pad here... ?
1933 GST_DEBUG(GST_CAT_PADS,"created ghost pad \"%s\"\n",name);
1935 return GST_PAD(ghostpad);