2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstelement.c: The base element, all elements derive from this
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 */
26 #include <gobject/gvaluecollector.h>
27 #include "gst_private.h"
29 #include "gstelement.h"
30 #include "gstextratypes.h"
32 #include "gstscheduler.h"
37 /* Element signals and args */
52 #define CLASS(element) GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element))
54 static void gst_element_class_init (GstElementClass *klass);
55 static void gst_element_init (GstElement *element);
56 static void gst_element_base_class_init (GstElementClass *klass);
58 static void gst_element_real_set_property (GObject *object, guint prop_id,
59 const GValue *value, GParamSpec *pspec);
60 static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value,
63 static void gst_element_dispose (GObject *object);
65 static gboolean gst_element_send_event_default (GstElement *element, GstEvent *event);
66 static gboolean gst_element_query_default (GstElement *element, GstPadQueryType type,
67 GstFormat *format, gint64 *value);
69 static GstElementStateReturn gst_element_change_state (GstElement *element);
70 static void gst_element_error_func (GstElement* element, GstElement *source, gchar *errormsg);
72 #ifndef GST_DISABLE_LOADSAVE
73 static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent);
74 static void gst_element_restore_thyself (GstObject *parent, xmlNodePtr self);
77 GType _gst_element_type = 0;
79 static GstObjectClass *parent_class = NULL;
80 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
82 GType gst_element_get_type (void)
84 if (!_gst_element_type) {
85 static const GTypeInfo element_info = {
86 sizeof(GstElementClass),
87 (GBaseInitFunc)gst_element_base_class_init,
89 (GClassInitFunc)gst_element_class_init,
94 (GInstanceInitFunc)gst_element_init,
97 _gst_element_type = g_type_register_static(GST_TYPE_OBJECT, "GstElement",
98 &element_info, G_TYPE_FLAG_ABSTRACT);
100 return _gst_element_type;
104 gst_element_class_init (GstElementClass *klass)
106 GObjectClass *gobject_class;
107 GstObjectClass *gstobject_class;
109 gobject_class = (GObjectClass*) klass;
110 gstobject_class = (GstObjectClass*) klass;
112 parent_class = g_type_class_ref(GST_TYPE_OBJECT);
114 gst_element_signals[STATE_CHANGE] =
115 g_signal_new ("state_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
116 G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL,
117 gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
118 G_TYPE_INT, G_TYPE_INT);
119 gst_element_signals[NEW_PAD] =
120 g_signal_new ("new_pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
121 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
122 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
124 gst_element_signals[PAD_REMOVED] =
125 g_signal_new ("pad_removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
126 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
127 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
129 gst_element_signals[ERROR] =
130 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
131 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
132 gst_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
133 G_TYPE_OBJECT, G_TYPE_STRING);
134 gst_element_signals[EOS] =
135 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
136 G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
137 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
139 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property);
140 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_property);
142 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
144 #ifndef GST_DISABLE_LOADSAVE
145 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
146 gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
149 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
150 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
151 klass->elementfactory = NULL;
152 klass->padtemplates = NULL;
153 klass->numpadtemplates = 0;
154 klass->send_event = GST_DEBUG_FUNCPTR (gst_element_send_event_default);
155 klass->query = GST_DEBUG_FUNCPTR (gst_element_query_default);
159 gst_element_base_class_init (GstElementClass *klass)
161 GObjectClass *gobject_class;
163 gobject_class = (GObjectClass*) klass;
165 gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_element_real_set_property);
166 gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_element_real_get_property);
170 gst_element_init (GstElement *element)
172 element->current_state = GST_STATE_NULL;
173 element->pending_state = GST_STATE_VOID_PENDING;
174 element->numpads = 0;
175 element->numsrcpads = 0;
176 element->numsinkpads = 0;
177 element->pads = NULL;
178 element->loopfunc = NULL;
179 element->sched = NULL;
180 element->clock = NULL;
181 element->sched_private = NULL;
182 element->state_mutex = g_mutex_new ();
183 element->state_cond = g_cond_new ();
187 gst_element_real_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
189 GstElementClass *oclass = CLASS (object);
191 if (oclass->set_property)
192 (oclass->set_property) (object, prop_id, value, pspec);
196 gst_element_real_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
198 GstElementClass *oclass = CLASS (object);
200 if (oclass->get_property)
201 (oclass->get_property) (object, prop_id, value, pspec);
205 * gst_element_default_error:
206 * @object: a #GObject that signalled the error.
207 * @orig: the #GstObject that initiated the error.
208 * @error: the error message.
210 * Adds a default error signal callback to an
211 * element. The user data passed to the g_signal_connect is
213 * The default handler will simply print the error string
217 gst_element_default_error (GObject *object, GstObject *orig, gchar *error)
219 g_print ("ERROR: %s: %s\n", GST_OBJECT_NAME (orig), error);
223 const GParamSpec *pspec;
228 element_set_property (GstElement *element, const GParamSpec *pspec, const GValue *value)
230 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
232 prop_value->pspec = pspec;
233 prop_value->value = *value;
235 g_async_queue_push (element->prop_value_queue, prop_value);
239 element_get_property (GstElement *element, const GParamSpec *pspec, GValue *value)
241 g_mutex_lock (element->property_mutex);
242 g_object_get_property ((GObject*)element, pspec->name, value);
243 g_mutex_unlock (element->property_mutex);
247 gst_element_threadsafe_properties_pre_run (GstElement *element)
249 GST_DEBUG (GST_CAT_THREAD, "locking element %s", GST_OBJECT_NAME (element));
250 g_mutex_lock (element->property_mutex);
251 gst_element_set_pending_properties (element);
255 gst_element_threadsafe_properties_post_run (GstElement *element)
257 GST_DEBUG (GST_CAT_THREAD, "unlocking element %s", GST_OBJECT_NAME (element));
258 g_mutex_unlock (element->property_mutex);
262 * gst_element_enable_threadsafe_properties:
263 * @element: a #GstElement to enable threadsafe properties on.
265 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
266 * this element so that properties on the element can be set in a
270 gst_element_enable_threadsafe_properties (GstElement *element)
272 g_return_if_fail (GST_IS_ELEMENT (element));
274 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
275 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
276 element->post_run_func = gst_element_threadsafe_properties_post_run;
277 if (!element->prop_value_queue)
278 element->prop_value_queue = g_async_queue_new ();
279 if (!element->property_mutex)
280 element->property_mutex = g_mutex_new ();
284 * gst_element_disable_threadsafe_properties:
285 * @element: a #GstElement to disable threadsafe properties on.
287 * Removes the threadsafe properties, post- and pre-run locks from
291 gst_element_disable_threadsafe_properties (GstElement *element)
293 g_return_if_fail (GST_IS_ELEMENT (element));
295 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
296 element->pre_run_func = NULL;
297 element->post_run_func = NULL;
298 /* let's keep around that async queue */
302 * gst_element_set_pending_properties:
303 * @element: a #GstElement to set the pending properties on.
305 * Sets all pending properties on the threadsafe properties enabled
309 gst_element_set_pending_properties (GstElement *element)
311 prop_value_t *prop_value;
313 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
314 g_object_set_property ((GObject*)element, prop_value->pspec->name, &prop_value->value);
315 g_value_unset (&prop_value->value);
320 /* following 6 functions taken mostly from gobject.c */
324 * @element: a #GstElement to set properties on.
325 * @first_property_name: the first property to set.
326 * @...: value of the first property, and more properties to set, ending
329 * Sets properties on an element. If the element uses threadsafe properties,
330 * they will be queued and set on the object when it is scheduled again.
333 gst_element_set (GstElement *element, const gchar *first_property_name, ...)
337 g_return_if_fail (GST_IS_ELEMENT (element));
339 va_start (var_args, first_property_name);
340 gst_element_set_valist (element, first_property_name, var_args);
346 * @element: a #GstElement to get properties of.
347 * @first_property_name: the first property to get.
348 * @...: pointer to a variable to store the first property in, as well as
349 * more properties to get, ending with NULL.
351 * Gets properties from an element. If the element uses threadsafe properties,
352 * the element will be locked before getting the given properties.
355 gst_element_get (GstElement *element, const gchar *first_property_name, ...)
359 g_return_if_fail (GST_IS_ELEMENT (element));
361 va_start (var_args, first_property_name);
362 gst_element_get_valist (element, first_property_name, var_args);
367 * gst_element_set_valist:
368 * @element: a #GstElement to set properties on.
369 * @first_property_name: the first property to set.
370 * @var_args: the var_args list of other properties to get.
372 * Sets properties on an element. If the element uses threadsafe properties,
373 * the property change will be put on the async queue.
376 gst_element_set_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
381 g_return_if_fail (GST_IS_ELEMENT (element));
383 object = (GObject *) element;
385 GST_DEBUG (GST_CAT_PROPERTIES,
386 "setting valist of properties starting with %s on element %s",
387 first_property_name, gst_element_get_name (element));
389 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
390 g_object_set_valist (object, first_property_name, var_args);
394 g_object_ref (object);
396 name = first_property_name;
400 GValue value = { 0, };
404 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
408 g_warning ("%s: object class `%s' has no property named `%s'",
410 G_OBJECT_TYPE_NAME (object),
414 if (!(pspec->flags & G_PARAM_WRITABLE))
416 g_warning ("%s: property `%s' of object class `%s' is not writable",
419 G_OBJECT_TYPE_NAME (object));
423 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
425 G_VALUE_COLLECT (&value, var_args, 0, &error);
428 g_warning ("%s: %s", G_STRLOC, error);
431 /* we purposely leak the value here, it might not be
432 * in a sane state if an error condition occoured
437 element_set_property (element, pspec, &value);
438 g_value_unset (&value);
440 name = va_arg (var_args, gchar*);
443 g_object_unref (object);
447 * gst_element_get_valist:
448 * @element: a #GstElement to get properties of.
449 * @first_property_name: the first property to get.
450 * @var_args: the var_args list of other properties to get.
452 * Gets properties from an element. If the element uses threadsafe properties,
453 * the element will be locked before getting the given properties.
456 gst_element_get_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
461 g_return_if_fail (GST_IS_ELEMENT (element));
463 object = (GObject*)element;
465 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
466 g_object_get_valist (object, first_property_name, var_args);
470 g_object_ref (object);
472 name = first_property_name;
476 GValue value = { 0, };
480 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
484 g_warning ("%s: object class `%s' has no property named `%s'",
486 G_OBJECT_TYPE_NAME (object),
490 if (!(pspec->flags & G_PARAM_READABLE))
492 g_warning ("%s: property `%s' of object class `%s' is not readable",
495 G_OBJECT_TYPE_NAME (object));
499 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
501 element_get_property (element, pspec, &value);
503 G_VALUE_LCOPY (&value, var_args, 0, &error);
506 g_warning ("%s: %s", G_STRLOC, error);
508 g_value_unset (&value);
512 g_value_unset (&value);
514 name = va_arg (var_args, gchar*);
517 g_object_unref (object);
521 * gst_element_set_property:
522 * @element: a #GstElement to set properties on.
523 * @property_name: the first property to get.
524 * @value: the #GValue that holds the value to set.
526 * Sets a property on an element. If the element uses threadsafe properties,
527 * the property will be put on the async queue.
530 gst_element_set_property (GstElement *element, const gchar *property_name,
536 g_return_if_fail (GST_IS_ELEMENT (element));
537 g_return_if_fail (property_name != NULL);
538 g_return_if_fail (G_IS_VALUE (value));
540 object = (GObject*) element;
542 GST_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
543 property_name, gst_element_get_name (element));
544 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
545 g_object_set_property (object, property_name, value);
549 g_object_ref (object);
551 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
555 g_warning ("%s: object class `%s' has no property named `%s'",
557 G_OBJECT_TYPE_NAME (object),
560 element_set_property (element, pspec, value);
562 g_object_unref (object);
566 * gst_element_get_property:
567 * @element: a #GstElement to get properties of.
568 * @property_name: the first property to get.
569 * @value: the #GValue to store the property value in.
571 * Gets a property from an element. If the element uses threadsafe properties,
572 * the element will be locked before getting the given property.
575 gst_element_get_property (GstElement *element, const gchar *property_name, GValue *value)
580 g_return_if_fail (GST_IS_ELEMENT (element));
581 g_return_if_fail (property_name != NULL);
582 g_return_if_fail (G_IS_VALUE (value));
584 object = (GObject*)element;
586 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
587 g_object_get_property (object, property_name, value);
591 g_object_ref (object);
593 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
596 g_warning ("%s: object class `%s' has no property named `%s'",
598 G_OBJECT_TYPE_NAME (object),
602 GValue *prop_value, tmp_value = { 0, };
604 /* auto-conversion of the callers value type
606 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
608 g_value_reset (value);
611 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
613 g_warning ("can't retrieve property `%s' of type `%s' as value of type `%s'",
615 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
616 G_VALUE_TYPE_NAME (value));
617 g_object_unref (object);
622 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
623 prop_value = &tmp_value;
625 element_get_property (element, pspec, prop_value);
626 if (prop_value != value)
628 g_value_transform (prop_value, value);
629 g_value_unset (&tmp_value);
633 g_object_unref (object);
637 gst_element_request_pad (GstElement *element, GstPadTemplate *templ, const gchar* name)
639 GstPad *newpad = NULL;
640 GstElementClass *oclass;
642 oclass = CLASS (element);
643 if (oclass->request_new_pad)
644 newpad = (oclass->request_new_pad)(element, templ, name);
650 * gst_element_release_request_pad:
651 * @element: a #GstElement to release the request pad of.
652 * @pad: the #GstPad to release.
654 * Makes the element free the previously requested pad as obtained
655 * with gst_element_get_request_pad().
658 gst_element_release_request_pad (GstElement *element, GstPad *pad)
660 GstElementClass *oclass;
662 g_return_if_fail (GST_IS_ELEMENT (element));
663 g_return_if_fail (GST_IS_PAD (pad));
665 oclass = CLASS (element);
666 if (oclass->release_pad)
667 (oclass->release_pad) (element, pad);
672 * gst_element_set_name:
673 * @element: a #GstElement to set the name of.
674 * @name: the new name of the element.
676 * Sets the name of the element, getting rid of the old name if there was
680 gst_element_set_name (GstElement *element, const gchar *name)
682 g_return_if_fail (element != NULL);
683 g_return_if_fail (GST_IS_ELEMENT (element));
685 gst_object_set_name (GST_OBJECT (element), name);
689 * gst_element_get_name:
690 * @element: a #GstElement to get the name of.
692 * Gets the name of the element.
694 * Returns: the name of the element.
697 gst_element_get_name (GstElement *element)
699 g_return_val_if_fail (element != NULL, NULL);
700 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
702 return GST_OBJECT_NAME (element);
706 * gst_element_set_parent:
707 * @element: a #GstElement to set parent of.
708 * @parent: the new #GstObject parent of the object.
710 * Sets the parent of the element.
713 gst_element_set_parent (GstElement *element, GstObject *parent)
715 g_return_if_fail (element != NULL);
716 g_return_if_fail (GST_IS_ELEMENT (element));
717 g_return_if_fail (GST_OBJECT_PARENT (element) == NULL);
718 g_return_if_fail (parent != NULL);
719 g_return_if_fail (GST_IS_OBJECT (parent));
720 g_return_if_fail ((gpointer)element != (gpointer)parent);
722 gst_object_set_parent (GST_OBJECT (element), parent);
726 * gst_element_get_parent:
727 * @element: a #GstElement to get the parent of.
729 * Gets the parent of the element.
731 * Returns: the #GstObject parent of the element.
734 gst_element_get_parent (GstElement *element)
736 g_return_val_if_fail (element != NULL, NULL);
737 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
739 return GST_OBJECT_PARENT (element);
743 * gst_element_set_clock:
744 * @element: a #GstElement to set the clock for.
745 * @clock: the #GstClock to set for the element.
747 * Sets the clock for the element.
750 gst_element_set_clock (GstElement *element, GstClock *clock)
752 g_return_if_fail (element != NULL);
753 g_return_if_fail (GST_IS_ELEMENT (element));
755 if (element->setclockfunc)
756 element->setclockfunc (element, clock);
758 element->clock = clock;
762 * gst_element_get_clock:
763 * @element: a #GstElement to get the clock of.
765 * Gets the clock of the element.
767 * Returns: the #GstClock of the element.
770 gst_element_get_clock (GstElement *element)
772 g_return_val_if_fail (element != NULL, NULL);
773 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
775 if (element->getclockfunc)
776 return element->getclockfunc (element);
782 * gst_element_clock_wait:
783 * @element: a #GstElement.
784 * @clock: the #GstClock to use.
785 * @time: the #GstClockTime to wait for on the clock.
786 * @jitter: the difference between requested time and actual time.
788 * Waits for a specific time on the clock.
790 * Returns: the #GstClockReturn result of the wait operation.
793 gst_element_clock_wait (GstElement *element, GstClock *clock, GstClockTime time, GstClockTimeDiff *jitter)
797 g_return_val_if_fail (element != NULL, GST_CLOCK_ERROR);
798 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
800 if (GST_ELEMENT_SCHED (element)) {
801 res = gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, clock, time, jitter);
804 res = GST_CLOCK_TIMEOUT;
811 * gst_element_release_locks:
812 * @element: a #GstElement to release all locks on.
814 * Instruct the element to release all the locks it is holding, such as
815 * blocking reads, waiting for the clock, ...
817 * Returns: TRUE if the locks could be released.
820 gst_element_release_locks (GstElement *element)
822 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
824 if (CLASS (element)->release_locks)
825 return CLASS (element)->release_locks (element);
831 * gst_element_add_pad:
832 * @element: a #GstElement to add the pad to.
833 * @pad: the #GstPad to add to the element.
835 * Add a pad (connection point) to the element, setting the parent of the
836 * pad to the element (and thus adding a reference).
839 gst_element_add_pad (GstElement *element, GstPad *pad)
841 g_return_if_fail (element != NULL);
842 g_return_if_fail (GST_IS_ELEMENT (element));
843 g_return_if_fail (pad != NULL);
844 g_return_if_fail (GST_IS_PAD (pad));
846 /* first check to make sure the pad's parent is already set */
847 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
849 /* then check to see if there's already a pad by that name here */
850 g_return_if_fail (gst_object_check_uniqueness (element->pads, GST_PAD_NAME(pad)) == TRUE);
852 /* set the pad's parent */
853 GST_DEBUG (GST_CAT_ELEMENT_PADS,"setting parent of pad '%s' to '%s'",
854 GST_PAD_NAME (pad), GST_ELEMENT_NAME (element));
855 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
857 /* add it to the list */
858 element->pads = g_list_append (element->pads, pad);
860 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
861 element->numsrcpads++;
863 element->numsinkpads++;
865 /* emit the NEW_PAD signal */
866 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
870 * gst_element_remove_pad:
871 * @element: a #GstElement to remove pad from.
872 * @pad: the #GstPad to remove from the element.
874 * Remove a pad (connection point) from the element.
877 gst_element_remove_pad (GstElement *element, GstPad *pad)
879 g_return_if_fail (element != NULL);
880 g_return_if_fail (GST_IS_ELEMENT (element));
881 g_return_if_fail (pad != NULL);
882 g_return_if_fail (GST_IS_PAD (pad));
884 g_return_if_fail (GST_PAD_PARENT (pad) == element);
886 /* check to see if the pad is still connected */
887 /* FIXME: what if someone calls _remove_pad instead of
888 _remove_ghost_pad? */
889 if (GST_IS_REAL_PAD (pad)) {
890 g_return_if_fail (GST_RPAD_PEER (pad) == NULL);
893 /* remove it from the list */
894 element->pads = g_list_remove (element->pads, pad);
896 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
897 element->numsrcpads--;
899 element->numsinkpads--;
901 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
903 gst_object_unparent (GST_OBJECT (pad));
907 * gst_element_add_ghost_pad:
908 * @element: a #GstElement to add the ghost pad to.
909 * @pad: the #GstPad from which the new ghost pad will be created.
910 * @name: the name of the new ghost pad.
912 * Creates a ghost pad from the given pad, and adds it to the list of pads
915 * Returns: the added ghost #GstPad, or NULL, if no ghost pad was created.
918 gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
922 g_return_val_if_fail (element != NULL, NULL);
923 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
924 g_return_val_if_fail (pad != NULL, NULL);
925 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
927 /* then check to see if there's already a pad by that name here */
928 g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
930 GST_DEBUG (GST_CAT_ELEMENT_PADS,
931 "creating new ghost pad called %s, from pad %s:%s",
932 name, GST_DEBUG_PAD_NAME(pad));
933 ghostpad = gst_ghost_pad_new (name, pad);
935 /* add it to the list */
936 GST_DEBUG(GST_CAT_ELEMENT_PADS,"adding ghost pad %s to element %s",
937 name, GST_ELEMENT_NAME (element));
938 element->pads = g_list_append (element->pads, ghostpad);
940 /* set the parent of the ghostpad */
941 gst_object_set_parent (GST_OBJECT (ghostpad), GST_OBJECT (element));
943 GST_DEBUG(GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s",GST_DEBUG_PAD_NAME(ghostpad));
945 /* emit the NEW_GHOST_PAD signal */
946 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
952 * gst_element_remove_ghost_pad:
953 * @element: a #GstElement to remove the ghost pad from.
954 * @pad: ghost #GstPad to remove.
956 * Removes a ghost pad from an element.
959 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
961 g_return_if_fail (element != NULL);
962 g_return_if_fail (GST_IS_ELEMENT (element));
963 g_return_if_fail (pad != NULL);
964 g_return_if_fail (GST_IS_GHOST_PAD (pad));
966 /* FIXME this is redundant?
967 * wingo 10-july-2001: I don't think so, you have to actually remove the pad
968 * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
969 * the real pad's ghost pad list
971 gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
972 gst_element_remove_pad (element, pad);
977 * gst_element_get_pad:
978 * @element: a #GstElement to find pad of.
979 * @name: the name of the pad to retrieve.
981 * Retrieves a pad from the element by name.
983 * Returns: requested #GstPad if found, otherwise NULL.
986 gst_element_get_pad (GstElement *element, const gchar *name)
990 g_return_val_if_fail (element != NULL, NULL);
991 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
992 g_return_val_if_fail (name != NULL, NULL);
994 pad = gst_element_get_static_pad (element, name);
996 pad = gst_element_get_request_pad (element, name);
1002 * gst_element_get_static_pad:
1003 * @element: a #GstElement to find a static pad of.
1004 * @name: the name of the static #GstPad to retrieve.
1006 * Retrieves a pad from the element by name. This version only retrieves
1007 * already-existing (i.e. 'static') pads.
1009 * Returns: the requested #GstPad if found, otherwise NULL.
1012 gst_element_get_static_pad (GstElement *element, const gchar *name)
1016 g_return_val_if_fail (element != NULL, NULL);
1017 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1018 g_return_val_if_fail (name != NULL, NULL);
1020 walk = element->pads;
1024 pad = GST_PAD(walk->data);
1025 if (strcmp (GST_PAD_NAME(pad), name) == 0) {
1026 GST_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1029 walk = g_list_next (walk);
1032 GST_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"", name, GST_OBJECT_NAME (element));
1037 * gst_element_get_request_pad:
1038 * @element: a #GstElement to find a request pad of.
1039 * @name: the name of the request #GstPad to retrieve.
1041 * Retrieves a pad from the element by name. This version only retrieves
1044 * Returns: requested #GstPad if found, otherwise NULL.
1047 gst_element_get_request_pad (GstElement *element, const gchar *name)
1049 GstPadTemplate *templ = NULL;
1051 const gchar *req_name = NULL;
1052 gboolean templ_found = FALSE;
1056 gchar *str, *endptr = NULL;
1058 g_return_val_if_fail (element != NULL, NULL);
1059 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1060 g_return_val_if_fail (name != NULL, NULL);
1062 if (strstr (name, "%")) {
1063 templ = gst_element_get_pad_template (element, name);
1068 list = gst_element_get_pad_template_list(element);
1069 while (!templ_found && list) {
1070 templ = (GstPadTemplate*) list->data;
1071 if (templ->presence == GST_PAD_REQUEST) {
1072 /* we know that %s and %d are the only possibilities because of sanity
1073 checks in gst_pad_template_new */
1074 GST_DEBUG (GST_CAT_PADS, "comparing %s to %s", name, templ->name_template);
1075 if ((str = strchr (templ->name_template, '%')) &&
1076 strncmp (templ->name_template, name, str - templ->name_template) == 0 &&
1077 strlen (name) > str - templ->name_template) {
1078 data = name + (str - templ->name_template);
1079 if (*(str+1) == 'd') {
1081 n = (gint) strtol (data, &endptr, 10);
1082 if (endptr && *endptr == '\0') {
1102 pad = gst_element_request_pad (element, templ, req_name);
1108 * gst_element_get_pad_list:
1109 * @element: a #GstElement to get pads of.
1111 * Retrieves a list of the pads associated with the element.
1113 * Returns: the #GList of pads.
1116 gst_element_get_pad_list (GstElement *element)
1118 g_return_val_if_fail (element != NULL, NULL);
1119 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1121 /* return the list of pads */
1122 return element->pads;
1126 * gst_element_class_add_pad_template:
1127 * @klass: the #GstElementClass to add the pad template to.
1128 * @templ: a #GstPadTemplate to add to the element class.
1130 * Adds a padtemplate to an element class.
1131 * This is useful if you have derived a custom bin and wish to provide
1132 * an on-request pad at runtime. Plug-in writers should use
1133 * gst_element_factory_add_pad_template instead.
1136 gst_element_class_add_pad_template (GstElementClass *klass,
1137 GstPadTemplate *templ)
1139 g_return_if_fail (klass != NULL);
1140 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1141 g_return_if_fail (templ != NULL);
1142 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1144 klass->padtemplates = g_list_append (klass->padtemplates, templ);
1145 klass->numpadtemplates++;
1149 * gst_element_get_pad_template_list:
1150 * @element: a #GstElement to get pad templates of.
1152 * Retrieves a list of the pad templates associated with the element.
1154 * Returns: the #GList of padtemplates.
1157 gst_element_get_pad_template_list (GstElement *element)
1159 g_return_val_if_fail (element != NULL, NULL);
1160 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1162 return CLASS (element)->padtemplates;
1166 * gst_element_get_pad_template:
1167 * @element: a #GstElement to get the pad template of.
1168 * @name: the name of the #GstPadTemplate to get.
1170 * Retrieves a padtemplate from this element with the
1173 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1174 * No unreferencing is necessary.
1177 gst_element_get_pad_template (GstElement *element, const gchar *name)
1181 g_return_val_if_fail (element != NULL, NULL);
1182 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1183 g_return_val_if_fail (name != NULL, NULL);
1185 padlist = gst_element_get_pad_template_list (element);
1188 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1190 if (!strcmp (padtempl->name_template, name))
1193 padlist = g_list_next (padlist);
1200 * gst_element_get_compatible_pad_template:
1201 * @element: a #GstElement to get a compatible pad template for.
1202 * @compattempl: the #GstPadTemplate to find a compatible template for.
1204 * Generates a pad template for this element compatible with the given
1205 * template (meaning it is able to connect with it).
1207 * Returns: the #GstPadTemplate of the element that is compatible with
1208 * the given GstPadTemplate, or NULL if none was found. No unreferencing
1212 gst_element_get_compatible_pad_template (GstElement *element,
1213 GstPadTemplate *compattempl)
1215 GstPadTemplate *newtempl = NULL;
1218 GST_DEBUG (GST_CAT_ELEMENT_PADS, "gst_element_get_compatible_pad_template()");
1220 g_return_val_if_fail (element != NULL, NULL);
1221 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1222 g_return_val_if_fail (compattempl != NULL, NULL);
1224 padlist = gst_element_get_pad_template_list (element);
1227 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1228 gboolean comp = FALSE;
1232 * Check direction (must be opposite)
1235 GST_DEBUG (GST_CAT_CAPS, "checking direction and caps");
1236 if (padtempl->direction == GST_PAD_SRC &&
1237 compattempl->direction == GST_PAD_SINK) {
1238 GST_DEBUG (GST_CAT_CAPS, "compatible direction: found src pad template");
1239 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (padtempl),
1240 GST_PAD_TEMPLATE_CAPS (compattempl));
1241 GST_DEBUG(GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1242 } else if (padtempl->direction == GST_PAD_SINK &&
1243 compattempl->direction == GST_PAD_SRC) {
1244 GST_DEBUG (GST_CAT_CAPS, "compatible direction: found sink pad template");
1245 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1246 GST_PAD_TEMPLATE_CAPS (padtempl));
1247 GST_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1251 newtempl = padtempl;
1255 padlist = g_list_next (padlist);
1262 * gst_element_request_compatible_pad:
1263 * @element: a #GstElement to request a new pad from.
1264 * @templ: the #GstPadTemplate to which the new pad should be able to connect.
1266 * Requests a new pad from the element. The template will
1267 * be used to decide what type of pad to create. This function
1268 * is typically used for elements with a padtemplate with presence
1271 * Returns: the new #GstPad that was created, or NULL if none could be created.
1274 gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
1276 GstPadTemplate *templ_new;
1279 g_return_val_if_fail (element != NULL, NULL);
1280 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1281 g_return_val_if_fail (templ != NULL, NULL);
1283 templ_new = gst_element_get_compatible_pad_template (element, templ);
1284 if (templ_new != NULL)
1285 pad = gst_element_request_pad (element, templ_new, NULL);
1292 * gst_element_get_compatible_pad_filtered:
1293 * @element: a #GstElement in which the pad should be found.
1294 * @pad: the #GstPad to find a compatible one for.
1295 * @filtercaps: the #GstCaps to use as a filter.
1297 * Looks for an unconnected pad to which the given pad can connect to.
1298 * It is not guaranteed that connecting the pads will work, though
1299 * it should work in most cases.
1301 * Returns: the #GstPad to which a connection can be made.
1304 gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
1305 GstCaps *filtercaps)
1308 GstPadTemplate *templ;
1310 GstPad *foundpad = NULL;
1313 g_return_val_if_fail (element != NULL, NULL);
1314 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1315 g_return_val_if_fail (pad != NULL, NULL);
1316 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1318 /* let's use the real pad */
1319 pad = (GstPad *) GST_PAD_REALIZE (pad);
1320 g_return_val_if_fail (pad != NULL, NULL);
1321 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1323 /* try to get an existing unconnected pad */
1324 pads = gst_element_get_pad_list (element);
1326 GstPad *current = GST_PAD (pads->data);
1327 if ((GST_PAD_PEER (GST_PAD_REALIZE (current)) == NULL) &&
1328 gst_pad_can_connect_filtered (pad, current, filtercaps)) {
1331 pads = g_list_next (pads);
1334 /* try to create a new one */
1335 /* requesting is a little crazy, we need a template. Let's create one */
1336 if (filtercaps != NULL) {
1337 templcaps = gst_caps_intersect (filtercaps, (GstCaps *) GST_RPAD_CAPS (pad));
1338 if (templcaps == NULL)
1341 templcaps = gst_caps_copy (gst_pad_get_caps (pad));
1344 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1345 GST_PAD_ALWAYS, templcaps, NULL);
1346 foundpad = gst_element_request_compatible_pad (element, templ);
1347 gst_object_unref (GST_OBJECT (templ)); /* this will take care of the caps too */
1349 /* FIXME: this is broken, but it's in here so autoplugging elements that don't
1350 have caps on their source padtemplates (spider) can connect... */
1351 if (!foundpad && !filtercaps) {
1352 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1353 GST_PAD_ALWAYS, NULL, NULL);
1354 foundpad = gst_element_request_compatible_pad (element, templ);
1355 gst_object_unref (GST_OBJECT (templ));
1362 * gst_element_get_compatible_pad:
1363 * @element: a #GstElement in which the pad should be found.
1364 * @pad: the #GstPad to find a compatible one for.
1366 * Looks for an unconnected pad to which the given pad can connect to.
1367 * It is not guaranteed that connecting the pads will work, though
1368 * it should work in most cases.
1370 * Returns: the #GstPad to which a connection can be made, or NULL if none
1374 gst_element_get_compatible_pad (GstElement *element, GstPad *pad)
1376 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1380 * gst_element_connect_filtered:
1381 * @src: a #GstElement containing the source pad.
1382 * @dest: the #GstElement containing the destination pad.
1383 * @filtercaps: the #GstCaps to use as a filter.
1385 * Connects the source to the destination element using the filtercaps.
1386 * The connection must be from source to destination, the other
1387 * direction will not be tried.
1388 * The functions looks for existing pads that aren't connected yet.
1389 * It will use request pads if possible. But both pads will not be requested.
1390 * If multiple connections are possible, only one is established.
1392 * Returns: TRUE if the elements could be connected.
1395 gst_element_connect_filtered (GstElement *src, GstElement *dest,
1396 GstCaps *filtercaps)
1398 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1399 GstPad *srcpad, *destpad;
1400 GstPadTemplate *srctempl, *desttempl;
1403 g_return_val_if_fail (src != NULL, FALSE);
1404 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1405 g_return_val_if_fail (dest != NULL, FALSE);
1406 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1408 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying to connect element %s to element %s",
1409 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1411 srcpads = gst_element_get_pad_list (src);
1412 destpads = gst_element_get_pad_list (dest);
1414 if (srcpads || destpads) {
1415 GST_DEBUG (GST_CAT_ELEMENT_PADS, "looping through src and dest pads");
1416 /* loop through the existing pads in the source, trying to find a
1417 * compatible destination pad */
1419 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1420 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1421 GST_DEBUG_PAD_NAME (srcpad));
1422 if ((GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1423 (GST_PAD_PEER (srcpad) == NULL)) {
1424 destpad = gst_element_get_compatible_pad_filtered (dest, srcpad,
1426 if (destpad && gst_pad_connect_filtered (srcpad, destpad, filtercaps)) {
1427 GST_DEBUG (GST_CAT_ELEMENT_PADS, "connected pad %s:%s to pad %s:%s",
1428 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1432 srcpads = g_list_next (srcpads);
1435 /* loop through the existing pads in the destination */
1437 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1438 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1439 GST_DEBUG_PAD_NAME (destpad));
1440 if ((GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1441 (GST_PAD_PEER (destpad) == NULL)) {
1442 srcpad = gst_element_get_compatible_pad_filtered (src, destpad,
1444 if (srcpad && gst_pad_connect_filtered (srcpad, destpad, filtercaps)) {
1445 GST_DEBUG (GST_CAT_ELEMENT_PADS, "connected pad %s:%s to pad %s:%s",
1446 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1450 destpads = g_list_next (destpads);
1454 GST_DEBUG (GST_CAT_ELEMENT_PADS,
1455 "we might have request pads on both sides, checking...");
1456 srctempls = gst_element_get_pad_template_list (src);
1457 desttempls = gst_element_get_pad_template_list (dest);
1459 if (srctempls && desttempls) {
1461 srctempl = (GstPadTemplate*) srctempls->data;
1462 if (srctempl->presence == GST_PAD_REQUEST) {
1463 for (l=desttempls; l; l=l->next) {
1464 desttempl = (GstPadTemplate*) desttempls->data;
1465 if (desttempl->presence == GST_PAD_REQUEST &&
1466 desttempl->direction != srctempl->direction) {
1467 if (gst_caps_is_always_compatible (gst_pad_template_get_caps (srctempl),
1468 gst_pad_template_get_caps (desttempl))) {
1469 srcpad = gst_element_get_request_pad (src,
1470 srctempl->name_template);
1471 destpad = gst_element_get_request_pad (dest,
1472 desttempl->name_template);
1473 if (gst_pad_connect_filtered (srcpad, destpad, filtercaps)) {
1474 GST_DEBUG (GST_CAT_ELEMENT_PADS,
1475 "connected pad %s:%s to pad %s:%s",
1476 GST_DEBUG_PAD_NAME (srcpad),
1477 GST_DEBUG_PAD_NAME (destpad));
1480 /* FIXME: we have extraneous request pads lying around */
1485 srctempls = srctempls->next;
1489 GST_DEBUG (GST_CAT_ELEMENT_PADS, "no connection possible from %s to %s",
1490 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1495 * gst_element_connect_many:
1496 * @element_1: the first #GstElement in the connection chain.
1497 * @element_2: the second #GstElement in the connection chain.
1498 * @...: the NULL-terminated list of elements to connect in order.
1500 * Chain together a series of elements. Uses #gst_element_connect.
1502 * Returns: TRUE on success, FALSE otherwise.
1505 gst_element_connect_many (GstElement *element_1, GstElement *element_2, ...)
1509 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1510 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1511 GST_IS_ELEMENT (element_2), FALSE);
1513 va_start (args, element_2);
1516 if (!gst_element_connect (element_1, element_2))
1519 element_1 = element_2;
1520 element_2 = va_arg (args, GstElement*);
1529 * gst_element_connect:
1530 * @src: a #GstElement containing the source pad.
1531 * @dest: the #GstElement containing the destination pad.
1533 * Connects the source to the destination element.
1534 * The connection must be from source to destination, the other
1535 * direction will not be tried.
1536 * The functions looks for existing pads and request pads that aren't
1537 * connected yet. If multiple connections are possible, only one is
1540 * Returns: TRUE if the elements could be connected.
1543 gst_element_connect (GstElement *src, GstElement *dest)
1545 return gst_element_connect_filtered (src, dest, NULL);
1549 * gst_element_connect_pads_filtered:
1550 * @src: a #GstElement containing the source pad.
1551 * @srcpadname: the name of the #GstPad in source element.
1552 * @dest: the #GstElement containing the destination pad.
1553 * @destpadname: the name of the #GstPad in destination element.
1554 * @filtercaps: the #GstCaps to use as a filter.
1556 * Connects the two named pads of the source and destination elements.
1557 * Side effect is that if one of the pads has no parent, it becomes a
1558 * child of the parent of the other element. If they have different
1559 * parents, the connection fails.
1561 * Returns: TRUE if the pads could be connected.
1564 gst_element_connect_pads_filtered (GstElement *src, const gchar *srcpadname,
1565 GstElement *dest, const gchar *destpadname,
1566 GstCaps *filtercaps)
1568 GstPad *srcpad,*destpad;
1570 g_return_val_if_fail (src != NULL, FALSE);
1571 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1572 g_return_val_if_fail (srcpadname != NULL, FALSE);
1573 g_return_val_if_fail (dest != NULL, FALSE);
1574 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1575 g_return_val_if_fail (destpadname != NULL, FALSE);
1577 /* obtain the pads requested */
1578 srcpad = gst_element_get_pad (src, srcpadname);
1579 if (srcpad == NULL) {
1580 GST_ERROR (src, "source element has no pad \"%s\"", srcpadname);
1583 destpad = gst_element_get_pad (dest, destpadname);
1584 if (srcpad == NULL) {
1585 GST_ERROR (dest, "destination element has no pad \"%s\"", destpadname);
1589 /* we're satisified they can be connected, let's do it */
1590 return gst_pad_connect_filtered (srcpad, destpad, filtercaps);
1594 * gst_element_connect_pads:
1595 * @src: a #GstElement containing the source pad.
1596 * @srcpadname: the name of the #GstPad in the source element.
1597 * @dest: the #GstElement containing the destination pad.
1598 * @destpadname: the name of the #GstPad in destination element.
1600 * Connects the two named pads of the source and destination elements.
1601 * Side effect is that if one of the pads has no parent, it becomes a
1602 * child of the parent of the other element. If they have different
1603 * parents, the connection fails.
1605 * Returns: TRUE if the pads could be connected.
1608 gst_element_connect_pads (GstElement *src, const gchar *srcpadname,
1609 GstElement *dest, const gchar *destpadname)
1611 return gst_element_connect_pads_filtered (src, srcpadname, dest, destpadname, NULL);
1615 * gst_element_disconnect_pads:
1616 * @src: a #GstElement containing the source pad.
1617 * @srcpadname: the name of the #GstPad in source element.
1618 * @dest: a #GstElement containing the destination pad.
1619 * @destpadname: the name of the #GstPad in destination element.
1621 * Disconnects the two named pads of the source and destination elements.
1624 gst_element_disconnect_pads (GstElement *src, const gchar *srcpadname,
1625 GstElement *dest, const gchar *destpadname)
1627 GstPad *srcpad,*destpad;
1629 g_return_if_fail (src != NULL);
1630 g_return_if_fail (GST_IS_ELEMENT(src));
1631 g_return_if_fail (srcpadname != NULL);
1632 g_return_if_fail (dest != NULL);
1633 g_return_if_fail (GST_IS_ELEMENT(dest));
1634 g_return_if_fail (destpadname != NULL);
1636 /* obtain the pads requested */
1637 srcpad = gst_element_get_pad (src, srcpadname);
1638 if (srcpad == NULL) {
1639 GST_ERROR(src,"source element has no pad \"%s\"",srcpadname);
1642 destpad = gst_element_get_pad (dest, destpadname);
1643 if (srcpad == NULL) {
1644 GST_ERROR(dest,"destination element has no pad \"%s\"",destpadname);
1648 /* we're satisified they can be disconnected, let's do it */
1649 gst_pad_disconnect(srcpad,destpad);
1653 * gst_element_disconnect_many:
1654 * @element_1: the first #GstElement in the connection chain.
1655 * @element_2: the second #GstElement in the connection chain.
1656 * @...: the NULL-terminated list of elements to disconnect in order.
1658 * Disconnects a series of elements. Uses #gst_element_disconnect.
1661 gst_element_disconnect_many (GstElement *element_1, GstElement *element_2, ...)
1665 g_return_if_fail (element_1 != NULL && element_2 != NULL);
1666 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
1668 va_start (args, element_2);
1671 gst_element_disconnect (element_1, element_2);
1673 element_1 = element_2;
1674 element_2 = va_arg (args, GstElement*);
1681 * gst_element_disconnect:
1682 * @src: the source #GstElement to disconnect.
1683 * @dest: the sink #GstElement to disconnect.
1685 * Disconnects all source pads of the source element with all sink pads
1686 * of the sink element to which they are connected.
1689 gst_element_disconnect (GstElement *src, GstElement *dest)
1691 const GList *srcpads;
1694 g_return_if_fail (GST_IS_ELEMENT (src));
1695 g_return_if_fail (GST_IS_ELEMENT (dest));
1697 GST_DEBUG (GST_CAT_ELEMENT_PADS, "disconnecting \"%s\" and \"%s\"",
1698 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1700 srcpads = gst_element_get_pad_list (src);
1703 pad = GST_PAD_CAST (srcpads->data);
1705 if (GST_IS_REAL_PAD (pad) && GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
1706 GstPad *peerpad = GST_PAD_PEER (pad);
1709 (GST_OBJECT_PARENT (GST_PAD_PEER (peerpad)) == (GstObject*) src)) {
1710 gst_pad_disconnect (pad, peerpad);
1714 srcpads = g_list_next (srcpads);
1719 gst_element_error_func (GstElement* element, GstElement *source,
1722 /* tell the parent */
1723 if (GST_OBJECT_PARENT (element)) {
1724 GST_DEBUG (GST_CAT_EVENT, "forwarding error \"%s\" from %s to %s",
1725 errormsg, GST_ELEMENT_NAME (element),
1726 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
1728 gst_object_ref (GST_OBJECT (element));
1729 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
1730 gst_element_signals[ERROR], 0, source, errormsg);
1731 gst_object_unref (GST_OBJECT (element));
1736 gst_element_send_event_default (GstElement *element, GstEvent *event)
1738 GList *pads = element->pads;
1739 gboolean res = FALSE;
1742 GstPad *pad = GST_PAD_CAST (pads->data);
1744 if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
1745 if (GST_PAD_IS_USABLE (pad)) {
1746 res = gst_pad_send_event (GST_PAD_PEER (pad), event);
1750 pads = g_list_next (pads);
1756 * gst_element_send_event:
1757 * @element: a #GstElement to send the event to.
1758 * @event: the #GstEvent to send to the element.
1760 * Sends an event to an element. If the element doesn't
1761 * implement an event handler, the event will be forwarded
1762 * to a random sink pad.
1764 * Returns: TRUE if the event was handled.
1767 gst_element_send_event (GstElement *element, GstEvent *event)
1769 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1770 g_return_val_if_fail (event != NULL, FALSE);
1772 if (CLASS (element)->send_event)
1773 return CLASS (element)->send_event (element, event);
1779 gst_element_query_default (GstElement *element, GstPadQueryType type,
1780 GstFormat *format, gint64 *value)
1782 GList *pads = element->pads;
1783 gboolean res = FALSE;
1786 GstPad *pad = GST_PAD_CAST (pads->data);
1788 if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
1789 if (GST_PAD_IS_USABLE (pad)) {
1790 res = gst_pad_query (GST_PAD_PEER (pad), type, format, value);
1794 pads = g_list_next (pads);
1800 * gst_element_query:
1801 * @element: a #GstElement to perform the query on.
1802 * @type: the #GstPadQueryType.
1803 * @format: the #GstFormat pointer to hold the format of the result.
1804 * @value: the pointer to the value of the result.
1806 * Performs a query on the given element. If the format is set
1807 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1808 * format pointer will hold the default format.
1809 * For element that don't implement a query handler, this function
1810 * forwards the query to a random connected sinkpad of this element.
1812 * Returns: TRUE if the query could be performed.
1815 gst_element_query (GstElement *element, GstPadQueryType type,
1816 GstFormat *format, gint64 *value)
1818 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1819 g_return_val_if_fail (format != NULL, FALSE);
1820 g_return_val_if_fail (value != NULL, FALSE);
1822 if (CLASS (element)->query)
1823 return CLASS (element)->query (element, type, format, value);
1829 * gst_element_error:
1830 * @element: a #GstElement with the error.
1831 * @error: the printf-style string describing the error.
1832 * @...: the optional arguments for the string.
1834 * signals an error condition on an element.
1835 * This function is used internally by elements.
1836 * It results in the "error" signal.
1839 gst_element_error (GstElement *element, const gchar *error, ...)
1845 g_return_if_fail (GST_IS_ELEMENT (element));
1846 g_return_if_fail (error != NULL);
1848 /* create error message */
1849 va_start (var_args, error);
1850 string = g_strdup_vprintf (error, var_args);
1852 GST_INFO (GST_CAT_EVENT, "ERROR in %s: %s", GST_ELEMENT_NAME (element), string);
1854 /* emit the signal, make sure the element stays available */
1855 gst_object_ref (GST_OBJECT (element));
1856 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element, string);
1858 /* tell the scheduler */
1859 if (element->sched) {
1860 gst_scheduler_error (element->sched, element);
1864 gst_object_unref (GST_OBJECT (element));
1869 * gst_element_get_state:
1870 * @element: a #GstElement to get the state of.
1872 * Gets the state of the element.
1874 * Returns: the #GstElementState of the element.
1877 gst_element_get_state (GstElement *element)
1879 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
1881 return GST_STATE (element);
1885 * gst_element_wait_state_change:
1886 * @element: a #GstElement to wait for a state change on.
1888 * Waits and blocks until the element changed its state.
1891 gst_element_wait_state_change (GstElement *element)
1893 g_mutex_lock (element->state_mutex);
1894 g_cond_wait (element->state_cond, element->state_mutex);
1895 g_mutex_unlock (element->state_mutex);
1899 * gst_element_set_state:
1900 * @element: a #GstElement to change state of.
1901 * @state: the element's new #GstElementState.
1903 * Sets the state of the element. This function will try to set the
1904 * requested state by going through all the intermediary states and calling
1905 * the class's state change function for each.
1907 * Returns: TRUE if the state was successfully set.
1908 * (using #GstElementStateReturn).
1910 GstElementStateReturn
1911 gst_element_set_state (GstElement *element, GstElementState state)
1913 GstElementClass *oclass;
1914 GstElementState curpending;
1915 GstElementStateReturn return_val = GST_STATE_SUCCESS;
1917 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
1919 /* start with the current state */
1920 curpending = GST_STATE(element);
1922 GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "setting state from %s to %s",
1923 gst_element_state_get_name (curpending),
1924 gst_element_state_get_name (state));
1926 /* loop until the final requested state is set */
1927 while (GST_STATE (element) != state
1928 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
1929 /* move the curpending state in the correct direction */
1930 if (curpending < state)
1935 /* set the pending state variable */
1936 /* FIXME: should probably check to see that we don't already have one */
1937 GST_STATE_PENDING (element) = curpending;
1939 if (curpending != state) {
1940 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
1941 "intermediate: setting state from %s to %s",
1942 gst_element_state_get_name (GST_STATE (element)),
1943 gst_element_state_get_name (curpending));
1946 /* call the state change function so it can set the state */
1947 oclass = CLASS (element);
1948 if (oclass->change_state)
1949 return_val = (oclass->change_state) (element);
1951 switch (return_val) {
1952 case GST_STATE_FAILURE:
1953 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
1954 "have failed change_state return");
1956 case GST_STATE_ASYNC:
1957 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
1958 "element will change state async");
1960 case GST_STATE_SUCCESS:
1961 /* Last thing we do is verify that a successful state change really
1962 * did change the state... */
1963 if (GST_STATE (element) != curpending) {
1964 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
1965 "element claimed state-change success,"
1966 "but state didn't change %s, %s <-> %s",
1967 gst_element_state_get_name (GST_STATE (element)),
1968 gst_element_state_get_name (GST_STATE_PENDING (element)),
1969 gst_element_state_get_name (curpending));
1970 return GST_STATE_FAILURE;
1974 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
1975 g_assert_not_reached ();
1984 gst_element_negotiate_pads (GstElement *element)
1986 GList *pads = GST_ELEMENT_PADS (element);
1988 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "negotiating pads");
1991 GstPad *pad = GST_PAD (pads->data);
1994 pads = g_list_next (pads);
1996 if (!GST_IS_REAL_PAD (pad))
1999 srcpad = GST_PAD_REALIZE (pad);
2001 /* if we have a connection on this pad and it doesn't have caps
2002 * allready, try to negotiate */
2003 if (GST_PAD_IS_USABLE (srcpad) && !GST_PAD_CAPS (srcpad)) {
2004 GstRealPad *sinkpad;
2005 GstElementState otherstate;
2008 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2010 /* check the parent of the peer pad, if there is no parent do nothing */
2011 parent = GST_PAD_PARENT (sinkpad);
2015 otherstate = GST_STATE (parent);
2017 /* swap pads if needed */
2018 if (!GST_PAD_IS_SRC (srcpad)) {
2026 /* only try to negotiate if the peer element is in PAUSED or higher too */
2027 if (otherstate >= GST_STATE_READY) {
2028 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element,
2029 "perform negotiate for %s:%s and %s:%s",
2030 GST_DEBUG_PAD_NAME (srcpad),
2031 GST_DEBUG_PAD_NAME (sinkpad));
2032 if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad)))
2036 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element,
2037 "not negotiating %s:%s and %s:%s, not in READY yet",
2038 GST_DEBUG_PAD_NAME (srcpad),
2039 GST_DEBUG_PAD_NAME (sinkpad));
2048 gst_element_clear_pad_caps (GstElement *element)
2050 GList *pads = GST_ELEMENT_PADS (element);
2052 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "clearing pad caps");
2055 GstRealPad *pad = GST_PAD_REALIZE (pads->data);
2057 if (GST_PAD_CAPS (pad)) {
2058 GST_PAD_CAPS (pad) = NULL;
2060 pads = g_list_next (pads);
2064 static GstElementStateReturn
2065 gst_element_change_state (GstElement *element)
2067 GstElementState old_state;
2069 gint old_pending, old_transition;
2071 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2073 old_state = GST_STATE (element);
2074 old_pending = GST_STATE_PENDING (element);
2075 old_transition = GST_STATE_TRANSITION (element);
2077 if (old_pending == GST_STATE_VOID_PENDING ||
2078 old_state == GST_STATE_PENDING (element)) {
2079 GST_INFO (GST_CAT_STATES,
2080 "no state change needed for element %s (VOID_PENDING)",
2081 GST_ELEMENT_NAME (element));
2082 return GST_STATE_SUCCESS;
2085 GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %d",
2086 GST_ELEMENT_NAME (element),
2087 gst_element_state_get_name (old_state),
2088 gst_element_state_get_name (old_pending),
2089 GST_STATE_TRANSITION (element));
2091 /* we set the state change early for the negotiation functions */
2092 GST_STATE (element) = old_pending;
2093 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2095 switch (old_transition) {
2096 /* if we are going to paused, we try to negotiate the pads */
2097 case GST_STATE_READY_TO_PAUSED:
2098 if (!gst_element_negotiate_pads (element))
2101 /* going to the READY state clears all pad caps */
2102 case GST_STATE_PAUSED_TO_READY:
2103 gst_element_clear_pad_caps (element);
2109 parent = GST_ELEMENT_PARENT (element);
2111 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2112 "signaling state change from %s to %s",
2113 gst_element_state_get_name (old_state),
2114 gst_element_state_get_name (GST_STATE (element)));
2116 /* tell the scheduler if we have one */
2117 if (element->sched) {
2118 if (gst_scheduler_state_transition (element->sched, element,
2119 old_transition) != GST_STATE_SUCCESS) {
2124 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2125 0, old_state, GST_STATE (element));
2127 /* tell our parent about the state change */
2128 if (parent && GST_IS_BIN (parent)) {
2129 gst_bin_child_state_change (GST_BIN (parent), old_state,
2130 GST_STATE (element), element);
2133 /* signal the state change in case somebody is waiting for us */
2134 g_mutex_lock (element->state_mutex);
2135 g_cond_signal (element->state_cond);
2136 g_mutex_unlock (element->state_mutex);
2138 return GST_STATE_SUCCESS;
2141 /* undo the state change */
2142 GST_STATE (element) = old_state;
2143 GST_STATE_PENDING (element) = old_pending;
2145 return GST_STATE_FAILURE;
2149 * gst_element_get_factory:
2150 * @element: a #GstElement to request the element factory of.
2152 * Retrieves the factory that was used to create this element.
2154 * Returns: the #GstElementFactory used for creating this element.
2157 gst_element_get_factory (GstElement *element)
2159 GstElementClass *oclass;
2161 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2163 oclass = CLASS (element);
2165 return oclass->elementfactory;
2169 gst_element_dispose (GObject *object)
2171 GstElement *element = GST_ELEMENT (object);
2175 GST_DEBUG_ELEMENT (GST_CAT_REFCOUNTING, element, "dispose");
2177 gst_element_set_state (element, GST_STATE_NULL);
2179 /* first we break all our connections with the ouside */
2180 if (element->pads) {
2182 orig = pads = g_list_copy (element->pads);
2184 pad = GST_PAD (pads->data);
2186 if (GST_PAD_PEER (pad)) {
2187 GST_DEBUG (GST_CAT_REFCOUNTING, "disconnecting pad '%s'",
2188 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2189 gst_pad_disconnect (pad, GST_PAD (GST_PAD_PEER (pad)));
2191 gst_element_remove_pad (element, pad);
2193 pads = g_list_next (pads);
2196 g_list_free (element->pads);
2197 element->pads = NULL;
2200 element->numsrcpads = 0;
2201 element->numsinkpads = 0;
2202 element->numpads = 0;
2203 g_mutex_free (element->state_mutex);
2204 g_cond_free (element->state_cond);
2206 if (element->prop_value_queue)
2207 g_async_queue_unref (element->prop_value_queue);
2208 element->prop_value_queue = NULL;
2209 if (element->property_mutex)
2210 g_mutex_free (element->property_mutex);
2212 G_OBJECT_CLASS (parent_class)->dispose (object);
2215 #ifndef GST_DISABLE_LOADSAVE
2217 * gst_element_save_thyself:
2218 * @element: a #GstElement to save.
2219 * @parent: the xml parent node.
2221 * Saves the element as part of the given XML structure.
2223 * Returns: the new #xmlNodePtr.
2226 gst_element_save_thyself (GstObject *object,
2230 GstElementClass *oclass;
2231 GParamSpec **specs, *spec;
2233 GValue value = { 0, };
2234 GstElement *element;
2236 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2238 element = GST_ELEMENT (object);
2240 oclass = CLASS (element);
2242 xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element));
2244 if (oclass->elementfactory != NULL) {
2245 GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory;
2247 xmlNewChild (parent, NULL, "type", GST_OBJECT_NAME (factory));
2248 xmlNewChild (parent, NULL, "version", factory->details->version);
2251 /* FIXME: what is this? */
2252 /* if (element->manager) */
2253 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2256 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2258 for (i=0; i<nspecs; i++) {
2260 if (spec->flags & G_PARAM_READABLE) {
2264 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2266 g_object_get_property (G_OBJECT (element), spec->name, &value);
2267 param = xmlNewChild (parent, NULL, "param", NULL);
2268 xmlNewChild (param, NULL, "name", spec->name);
2270 if (G_IS_PARAM_SPEC_STRING (spec))
2271 contents = g_value_dup_string (&value);
2272 else if (G_IS_PARAM_SPEC_ENUM (spec))
2273 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2274 else if (G_IS_PARAM_SPEC_INT64 (spec))
2275 contents = g_strdup_printf ("%lld", g_value_get_int64 (&value));
2277 contents = g_strdup_value_contents (&value);
2279 xmlNewChild (param, NULL, "value", contents);
2282 g_value_unset(&value);
2286 pads = GST_ELEMENT_PADS (element);
2289 GstPad *pad = GST_PAD (pads->data);
2290 /* figure out if it's a direct pad or a ghostpad */
2291 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2292 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
2293 gst_object_save_thyself (GST_OBJECT (pad), padtag);
2295 pads = g_list_next (pads);
2302 gst_element_restore_thyself (GstObject *object, xmlNodePtr self)
2304 xmlNodePtr children;
2305 GstElement *element;
2307 gchar *value = NULL;
2309 element = GST_ELEMENT (object);
2310 g_return_if_fail (element != NULL);
2313 children = self->xmlChildrenNode;
2315 if (!strcmp (children->name, "param")) {
2316 xmlNodePtr child = children->xmlChildrenNode;
2319 if (!strcmp (child->name, "name")) {
2320 name = xmlNodeGetContent (child);
2322 else if (!strcmp (child->name, "value")) {
2323 value = xmlNodeGetContent (child);
2325 child = child->next;
2327 /* FIXME: can this just be g_object_set ? */
2328 gst_util_set_object_arg (G_OBJECT (element), name, value);
2330 children = children->next;
2334 children = self->xmlChildrenNode;
2336 if (!strcmp (children->name, "pad")) {
2337 gst_pad_load_and_connect (children, GST_OBJECT (element));
2339 children = children->next;
2342 if (GST_OBJECT_CLASS(parent_class)->restore_thyself)
2343 (GST_OBJECT_CLASS(parent_class)->restore_thyself) (object, self);
2345 #endif /* GST_DISABLE_LOADSAVE */
2348 * gst_element_yield:
2349 * @element: a #GstElement to yield.
2351 * Requests a yield operation for the element. The scheduler will typically
2352 * give control to another element.
2355 gst_element_yield (GstElement *element)
2357 if (GST_ELEMENT_SCHED (element)) {
2358 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
2363 * gst_element_interrupt:
2364 * @element: a #GstElement to interrupt.
2366 * Requests the scheduler of this element to interrupt the execution of
2367 * this element and scheduler another one.
2369 * Returns: TRUE if the element should exit its chain/loop/get
2370 * function ASAP, depending on the scheduler implementation.
2373 gst_element_interrupt (GstElement *element)
2375 if (GST_ELEMENT_SCHED (element)) {
2376 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
2383 * gst_element_set_scheduler:
2384 * @element: a #GstElement to set the scheduler of.
2385 * @sched: the #GstScheduler to set.
2387 * Sets the scheduler of the element. For internal use only, unless you're
2388 * writing a new bin subclass.
2391 gst_element_set_scheduler (GstElement *element,
2392 GstScheduler *sched)
2394 g_return_if_fail (GST_IS_ELEMENT (element));
2396 GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting scheduler to %p", sched);
2398 GST_ELEMENT_SCHED (element) = sched;
2402 * gst_element_get_scheduler:
2403 * @element: a #GstElement to get the scheduler of.
2405 * Returns the scheduler of the element.
2407 * Returns: the element's #GstScheduler.
2410 gst_element_get_scheduler (GstElement *element)
2412 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2414 return GST_ELEMENT_SCHED (element);
2418 * gst_element_set_loop_function:
2419 * @element: a #GstElement to set the loop function of.
2420 * @loop: Pointer to #GstElementLoopFunction.
2422 * This sets the loop function for the element. The function pointed to
2423 * can deviate from the GstElementLoopFunction definition in type of
2426 * NOTE: in order for this to take effect, the current loop function *must*
2427 * exit. Assuming the loop function itself is the only one who will cause
2428 * a new loopfunc to be assigned, this should be no problem.
2431 gst_element_set_loop_function (GstElement *element,
2432 GstElementLoopFunction loop)
2434 g_return_if_fail (GST_IS_ELEMENT (element));
2436 /* set the loop function */
2437 element->loopfunc = loop;
2439 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
2440 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
2444 * gst_element_set_eos:
2445 * @element: a #GstElement to set to the EOS state.
2447 * Perform the actions needed to bring the element in the EOS state.
2450 gst_element_set_eos (GstElement *element)
2452 g_return_if_fail (GST_IS_ELEMENT (element));
2454 GST_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
2455 GST_OBJECT_NAME (element));
2457 gst_element_set_state (element, GST_STATE_PAUSED);
2459 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
2464 * gst_element_state_get_name:
2465 * @state: a #GstElementState to get the name of.
2467 * Gets a string representing the given state.
2469 * Returns: a string with the name of the state.
2472 gst_element_state_get_name (GstElementState state)
2475 #ifdef GST_DEBUG_COLOR
2476 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2477 case GST_STATE_NULL: return "\033[01;37mNULL\033[00m";break;
2478 case GST_STATE_READY: return "\033[01;31mREADY\033[00m";break;
2479 case GST_STATE_PLAYING: return "\033[01;32mPLAYING\033[00m";break;
2480 case GST_STATE_PAUSED: return "\033[01;33mPAUSED\033[00m";break;
2482 /* This is a memory leak */
2483 return g_strdup_printf ("\033[01;37;41mUNKNOWN!\033[00m(%d)", state);
2485 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2486 case GST_STATE_NULL: return "NULL";break;
2487 case GST_STATE_READY: return "READY";break;
2488 case GST_STATE_PLAYING: return "PLAYING";break;
2489 case GST_STATE_PAUSED: return "PAUSED";break;
2490 default: return "UNKNOWN!";
2497 gst_element_populate_std_props (GObjectClass * klass, const gchar *prop_name,
2498 guint arg_id, GParamFlags flags)
2500 GQuark prop_id = g_quark_from_string (prop_name);
2503 static GQuark fd_id = 0;
2504 static GQuark blocksize_id;
2505 static GQuark bytesperread_id;
2506 static GQuark dump_id;
2507 static GQuark filesize_id;
2508 static GQuark mmapsize_id;
2509 static GQuark location_id;
2510 static GQuark offset_id;
2511 static GQuark silent_id;
2512 static GQuark touch_id;
2515 fd_id = g_quark_from_static_string ("fd");
2516 blocksize_id = g_quark_from_static_string ("blocksize");
2517 bytesperread_id = g_quark_from_static_string ("bytesperread");
2518 dump_id = g_quark_from_static_string ("dump");
2519 filesize_id = g_quark_from_static_string ("filesize");
2520 mmapsize_id = g_quark_from_static_string ("mmapsize");
2521 location_id = g_quark_from_static_string ("location");
2522 offset_id = g_quark_from_static_string ("offset");
2523 silent_id = g_quark_from_static_string ("silent");
2524 touch_id = g_quark_from_static_string ("touch");
2527 if (prop_id == fd_id) {
2528 pspec = g_param_spec_int ("fd", "File-descriptor",
2529 "File-descriptor for the file being read",
2530 0, G_MAXINT, 0, flags);
2532 else if (prop_id == blocksize_id) {
2533 pspec = g_param_spec_ulong ("blocksize", "Block Size",
2534 "Block size to read per buffer",
2535 0, G_MAXULONG, 4096, flags);
2538 else if (prop_id == bytesperread_id) {
2539 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
2540 "Number of bytes to read per buffer",
2541 G_MININT, G_MAXINT, 0, flags);
2544 else if (prop_id == dump_id) {
2545 pspec = g_param_spec_boolean ("dump", "Dump",
2546 "Dump bytes to stdout",
2550 else if (prop_id == filesize_id) {
2551 pspec = g_param_spec_int64 ("filesize", "File Size",
2552 "Size of the file being read",
2553 0, G_MAXINT64, 0, flags);
2556 else if (prop_id == mmapsize_id) {
2557 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
2558 "Size in bytes of mmap()d regions",
2559 0, G_MAXULONG, 4 * 1048576, flags);
2562 else if (prop_id == location_id) {
2563 pspec = g_param_spec_string ("location", "File Location",
2564 "Location of the file to read",
2568 else if (prop_id == offset_id) {
2569 pspec = g_param_spec_int64 ("offset", "File Offset",
2570 "Byte offset of current read pointer",
2571 0, G_MAXINT64, 0, flags);
2574 else if (prop_id == silent_id) {
2575 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
2579 else if (prop_id == touch_id) {
2580 pspec = g_param_spec_boolean ("touch", "Touch read data",
2581 "Touch data to force disk read before "
2582 "push ()", TRUE, flags);
2585 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
2586 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
2591 g_object_class_install_property (klass, arg_id, pspec);
2596 * gst_element_class_install_std_props:
2597 * @klass: the #GstElementClass to add the properties to.
2598 * @first_name: the name of the first property.
2599 * in a NULL terminated
2600 * @...: the id and flags of the first property, followed by
2601 * further 'name', 'id', 'flags' triplets and terminated by NULL.
2603 * Adds a list of standardized properties with types to the @klass.
2604 * the id is for the property switch in your get_prop method, and
2605 * the flags determine readability / writeability.
2608 gst_element_class_install_std_props (GstElementClass * klass,
2609 const gchar *first_name, ...)
2615 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
2617 va_start (args, first_name);
2622 int arg_id = va_arg (args, int);
2623 int flags = va_arg (args, int);
2625 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id, flags);
2627 name = va_arg (args, char *);
2634 * gst_element_get_managing_bin:
2635 * @element: a #GstElement to get the managing bin of.
2637 * Gets the managing bin (a pipeline or a thread, for example) of an element.
2639 * Returns: the #GstBin, or NULL on failure.
2642 gst_element_get_managing_bin (GstElement *element)
2646 g_return_val_if_fail (element != NULL, NULL);
2648 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (element)));
2650 while (bin && !GST_FLAG_IS_SET (GST_OBJECT_CAST (bin), GST_BIN_FLAG_MANAGER))
2651 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (bin)));