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 static void gst_element_class_init (GstElementClass *klass);
53 static void gst_element_init (GstElement *element);
54 static void gst_element_base_class_init (GstElementClass *klass);
56 static void gst_element_real_set_property (GObject *object, guint prop_id,
57 const GValue *value, GParamSpec *pspec);
58 static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value,
61 static void gst_element_dispose (GObject *object);
63 static GstElementStateReturn gst_element_change_state (GstElement *element);
64 static void gst_element_error_func (GstElement* element, GstElement *source, gchar *errormsg);
66 #ifndef GST_DISABLE_LOADSAVE
67 static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent);
68 static void gst_element_restore_thyself (GstObject *parent, xmlNodePtr self);
71 GType _gst_element_type = 0;
73 static GstObjectClass *parent_class = NULL;
74 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
76 GType gst_element_get_type (void)
78 if (!_gst_element_type) {
79 static const GTypeInfo element_info = {
80 sizeof(GstElementClass),
81 (GBaseInitFunc)gst_element_base_class_init,
83 (GClassInitFunc)gst_element_class_init,
88 (GInstanceInitFunc)gst_element_init,
91 _gst_element_type = g_type_register_static(GST_TYPE_OBJECT, "GstElement",
92 &element_info, G_TYPE_FLAG_ABSTRACT);
94 return _gst_element_type;
98 gst_element_class_init (GstElementClass *klass)
100 GObjectClass *gobject_class;
101 GstObjectClass *gstobject_class;
103 gobject_class = (GObjectClass*) klass;
104 gstobject_class = (GstObjectClass*) klass;
106 parent_class = g_type_class_ref(GST_TYPE_OBJECT);
108 gst_element_signals[STATE_CHANGE] =
109 g_signal_new ("state_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
110 G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL,
111 gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
112 G_TYPE_INT, G_TYPE_INT);
113 gst_element_signals[NEW_PAD] =
114 g_signal_new ("new_pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
115 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
116 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
118 gst_element_signals[PAD_REMOVED] =
119 g_signal_new ("pad_removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
120 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
121 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
123 gst_element_signals[ERROR] =
124 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
125 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
126 gst_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
127 G_TYPE_OBJECT, G_TYPE_STRING);
128 gst_element_signals[EOS] =
129 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
130 G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
131 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
133 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property);
134 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_property);
136 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
138 #ifndef GST_DISABLE_LOADSAVE
139 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
140 gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
143 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
144 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
145 klass->elementfactory = NULL;
146 klass->padtemplates = NULL;
147 klass->numpadtemplates = 0;
151 gst_element_base_class_init (GstElementClass *klass)
153 GObjectClass *gobject_class;
155 gobject_class = (GObjectClass*) klass;
157 gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_element_real_set_property);
158 gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_element_real_get_property);
162 gst_element_init (GstElement *element)
164 element->current_state = GST_STATE_NULL;
165 element->pending_state = GST_STATE_VOID_PENDING;
166 element->numpads = 0;
167 element->numsrcpads = 0;
168 element->numsinkpads = 0;
169 element->pads = NULL;
170 element->loopfunc = NULL;
171 element->sched = NULL;
172 element->clock = NULL;
173 element->sched_private = NULL;
174 element->state_mutex = g_mutex_new ();
175 element->state_cond = g_cond_new ();
179 gst_element_real_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
181 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
183 if (oclass->set_property)
184 (oclass->set_property) (object, prop_id, value, pspec);
188 gst_element_real_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
190 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
192 if (oclass->get_property)
193 (oclass->get_property) (object, prop_id, value, pspec);
197 * gst_element_default_error:
198 * @object: a #GObject that signalled the error.
199 * @orig: the #GstObject that initiated the error.
200 * @error: the error message.
202 * Adds a default error signal callback to an
203 * element. The user data passed to the g_signal_connect is
205 * The default handler will simply print the error string
209 gst_element_default_error (GObject *object, GstObject *orig, gchar *error)
211 gchar *name = gst_object_get_path_string (orig);
212 g_print ("ERROR: %s: %s\n", name, error);
217 const GParamSpec *pspec;
222 element_set_property (GstElement *element, const GParamSpec *pspec, const GValue *value)
224 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
226 prop_value->pspec = pspec;
227 prop_value->value = *value;
229 g_async_queue_push (element->prop_value_queue, prop_value);
233 element_get_property (GstElement *element, const GParamSpec *pspec, GValue *value)
235 g_mutex_lock (element->property_mutex);
236 g_object_get_property ((GObject*)element, pspec->name, value);
237 g_mutex_unlock (element->property_mutex);
241 gst_element_threadsafe_properties_pre_run (GstElement *element)
243 GST_DEBUG (GST_CAT_THREAD, "locking element %s", GST_OBJECT_NAME (element));
244 g_mutex_lock (element->property_mutex);
245 gst_element_set_pending_properties (element);
249 gst_element_threadsafe_properties_post_run (GstElement *element)
251 GST_DEBUG (GST_CAT_THREAD, "unlocking element %s", GST_OBJECT_NAME (element));
252 g_mutex_unlock (element->property_mutex);
256 * gst_element_enable_threadsafe_properties:
257 * @element: a #GstElement to enable threadsafe properties on.
259 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
260 * this element so that properties on the element can be set in a
264 gst_element_enable_threadsafe_properties (GstElement *element)
266 g_return_if_fail (GST_IS_ELEMENT (element));
268 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
269 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
270 element->post_run_func = gst_element_threadsafe_properties_post_run;
271 if (!element->prop_value_queue)
272 element->prop_value_queue = g_async_queue_new ();
273 if (!element->property_mutex)
274 element->property_mutex = g_mutex_new ();
278 * gst_element_disable_threadsafe_properties:
279 * @element: a #GstElement to disable threadsafe properties on.
281 * Removes the threadsafe properties, post- and pre-run locks from
285 gst_element_disable_threadsafe_properties (GstElement *element)
287 g_return_if_fail (GST_IS_ELEMENT (element));
289 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
290 element->pre_run_func = NULL;
291 element->post_run_func = NULL;
292 /* let's keep around that async queue */
296 * gst_element_set_pending_properties:
297 * @element: a #GstElement to set the pending properties on.
299 * Sets all pending properties on the threadsafe properties enabled
303 gst_element_set_pending_properties (GstElement *element)
305 prop_value_t *prop_value;
307 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
308 g_object_set_property ((GObject*)element, prop_value->pspec->name, &prop_value->value);
309 g_value_unset (&prop_value->value);
314 /* following 6 functions taken mostly from gobject.c */
318 * @element: a #GstElement to set properties on.
319 * @first_property_name: the first property to set.
320 * @...: value of the first property, and more properties to set, ending
323 * Sets properties on an element. If the element uses threadsafe properties,
324 * they will be queued and set on the object when it is scheduled again.
327 gst_element_set (GstElement *element, const gchar *first_property_name, ...)
331 g_return_if_fail (GST_IS_ELEMENT (element));
333 va_start (var_args, first_property_name);
334 gst_element_set_valist (element, first_property_name, var_args);
340 * @element: a #GstElement to get properties of.
341 * @first_property_name: the first property to get.
342 * @...: pointer to a variable to store the first property in, as well as
343 * more properties to get, ending with NULL.
345 * Gets properties from an element. If the element uses threadsafe properties,
346 * the element will be locked before getting the given properties.
349 gst_element_get (GstElement *element, const gchar *first_property_name, ...)
353 g_return_if_fail (GST_IS_ELEMENT (element));
355 va_start (var_args, first_property_name);
356 gst_element_get_valist (element, first_property_name, var_args);
361 * gst_element_set_valist:
362 * @element: a #GstElement to set properties on.
363 * @first_property_name: the first property to set.
364 * @var_args: the var_args list of other properties to get.
366 * Sets properties on an element. If the element uses threadsafe properties,
367 * the property change will be put on the async queue.
370 gst_element_set_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
375 g_return_if_fail (GST_IS_ELEMENT (element));
377 object = (GObject *) element;
379 GST_DEBUG (GST_CAT_PROPERTIES,
380 "setting valist of properties starting with %s on element %s",
381 first_property_name, gst_element_get_name (element));
383 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
384 g_object_set_valist (object, first_property_name, var_args);
388 g_object_ref (object);
390 name = first_property_name;
394 GValue value = { 0, };
398 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
402 g_warning ("%s: object class `%s' has no property named `%s'",
404 G_OBJECT_TYPE_NAME (object),
408 if (!(pspec->flags & G_PARAM_WRITABLE))
410 g_warning ("%s: property `%s' of object class `%s' is not writable",
413 G_OBJECT_TYPE_NAME (object));
417 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
419 G_VALUE_COLLECT (&value, var_args, 0, &error);
422 g_warning ("%s: %s", G_STRLOC, error);
425 /* we purposely leak the value here, it might not be
426 * in a sane state if an error condition occoured
431 element_set_property (element, pspec, &value);
432 g_value_unset (&value);
434 name = va_arg (var_args, gchar*);
437 g_object_unref (object);
441 * gst_element_get_valist:
442 * @element: a #GstElement to get properties of.
443 * @first_property_name: the first property to get.
444 * @var_args: the var_args list of other properties to get.
446 * Gets properties from an element. If the element uses threadsafe properties,
447 * the element will be locked before getting the given properties.
450 gst_element_get_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
455 g_return_if_fail (GST_IS_ELEMENT (element));
457 object = (GObject*)element;
459 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
460 g_object_get_valist (object, first_property_name, var_args);
464 g_object_ref (object);
466 name = first_property_name;
470 GValue value = { 0, };
474 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
478 g_warning ("%s: object class `%s' has no property named `%s'",
480 G_OBJECT_TYPE_NAME (object),
484 if (!(pspec->flags & G_PARAM_READABLE))
486 g_warning ("%s: property `%s' of object class `%s' is not readable",
489 G_OBJECT_TYPE_NAME (object));
493 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
495 element_get_property (element, pspec, &value);
497 G_VALUE_LCOPY (&value, var_args, 0, &error);
500 g_warning ("%s: %s", G_STRLOC, error);
502 g_value_unset (&value);
506 g_value_unset (&value);
508 name = va_arg (var_args, gchar*);
511 g_object_unref (object);
515 * gst_element_set_property:
516 * @element: a #GstElement to set properties on.
517 * @property_name: the first property to get.
518 * @value: the #GValue that holds the value to set.
520 * Sets a property on an element. If the element uses threadsafe properties,
521 * the property will be put on the async queue.
524 gst_element_set_property (GstElement *element, const gchar *property_name,
530 g_return_if_fail (GST_IS_ELEMENT (element));
531 g_return_if_fail (property_name != NULL);
532 g_return_if_fail (G_IS_VALUE (value));
534 object = (GObject*) element;
536 GST_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
537 property_name, gst_element_get_name (element));
538 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
539 g_object_set_property (object, property_name, value);
543 g_object_ref (object);
545 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
549 g_warning ("%s: object class `%s' has no property named `%s'",
551 G_OBJECT_TYPE_NAME (object),
554 element_set_property (element, pspec, value);
556 g_object_unref (object);
560 * gst_element_get_property:
561 * @element: a #GstElement to get properties of.
562 * @property_name: the first property to get.
563 * @value: the #GValue to store the property value in.
565 * Gets a property from an element. If the element uses threadsafe properties,
566 * the element will be locked before getting the given property.
569 gst_element_get_property (GstElement *element, const gchar *property_name, GValue *value)
574 g_return_if_fail (GST_IS_ELEMENT (element));
575 g_return_if_fail (property_name != NULL);
576 g_return_if_fail (G_IS_VALUE (value));
578 object = (GObject*)element;
580 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
581 g_object_get_property (object, property_name, value);
585 g_object_ref (object);
587 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
590 g_warning ("%s: object class `%s' has no property named `%s'",
592 G_OBJECT_TYPE_NAME (object),
596 GValue *prop_value, tmp_value = { 0, };
598 /* auto-conversion of the callers value type
600 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
602 g_value_reset (value);
605 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
607 g_warning ("can't retrieve property `%s' of type `%s' as value of type `%s'",
609 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
610 G_VALUE_TYPE_NAME (value));
611 g_object_unref (object);
616 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
617 prop_value = &tmp_value;
619 element_get_property (element, pspec, prop_value);
620 if (prop_value != value)
622 g_value_transform (prop_value, value);
623 g_value_unset (&tmp_value);
627 g_object_unref (object);
631 gst_element_request_pad (GstElement *element, GstPadTemplate *templ, const gchar* name)
633 GstPad *newpad = NULL;
634 GstElementClass *oclass;
636 oclass = GST_ELEMENT_GET_CLASS (element);
638 if (oclass->request_new_pad)
639 newpad = (oclass->request_new_pad)(element, templ, name);
645 * gst_element_release_request_pad:
646 * @element: a #GstElement to release the request pad of.
647 * @pad: the #GstPad to release.
649 * Makes the element free the previously requested pad as obtained
650 * with gst_element_get_request_pad().
653 gst_element_release_request_pad (GstElement *element, GstPad *pad)
655 GstElementClass *oclass;
657 g_return_if_fail (GST_IS_ELEMENT (element));
658 g_return_if_fail (GST_IS_PAD (pad));
660 oclass = GST_ELEMENT_GET_CLASS (element);
662 if (oclass->release_pad)
663 (oclass->release_pad) (element, pad);
667 * gst_element_requires_clock:
668 * @element: a #GstElement to query
670 * Query if the element requiresd a clock
672 * Returns: TRUE if the element requires a clock
675 gst_element_requires_clock (GstElement *element)
677 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
679 return (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
683 * gst_element_provides_clock:
684 * @element: a #GstElement to query
686 * Query if the element provides a clock
688 * Returns: TRUE if the element provides a clock
691 gst_element_provides_clock (GstElement *element)
693 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
695 return (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
699 * gst_element_set_clock:
700 * @element: a #GstElement to set the clock for.
701 * @clock: the #GstClock to set for the element.
703 * Sets the clock for the element.
706 gst_element_set_clock (GstElement *element, GstClock *clock)
708 GstElementClass *oclass;
710 g_return_if_fail (GST_IS_ELEMENT (element));
712 oclass = GST_ELEMENT_GET_CLASS (element);
714 if (oclass->set_clock)
715 oclass->set_clock (element, clock);
717 gst_object_replace ((GstObject **)&element->clock, (GstObject *)clock);
721 * gst_element_get_clock:
722 * @element: a #GstElement to get the clock of.
724 * Gets the clock of the element.
726 * Returns: the #GstClock of the element.
729 gst_element_get_clock (GstElement *element)
731 GstElementClass *oclass;
733 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
735 oclass = GST_ELEMENT_GET_CLASS (element);
737 if (oclass->get_clock)
738 return oclass->get_clock (element);
744 * gst_element_clock_wait:
745 * @element: a #GstElement.
746 * @id: the #GstClock to use.
747 * @jitter: the difference between requested time and actual time.
749 * Waits for a specific time on the clock.
751 * Returns: the #GstClockReturn result of the wait operation.
754 gst_element_clock_wait (GstElement *element, GstClockID id, GstClockTimeDiff *jitter)
758 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
760 if (GST_ELEMENT_SCHED (element)) {
761 res = gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id, jitter);
764 res = GST_CLOCK_TIMEOUT;
770 * gst_element_is_indexable:
771 * @element: a #GstElement.
773 * Queries if the element can be indexed/
775 * Returns: TRUE if the element can be indexed.
778 gst_element_is_indexable (GstElement *element)
780 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
782 return (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
786 * gst_element_set_index:
787 * @element: a #GstElement.
788 * @index: a #GstIndex.
790 * Set the specified GstIndex on the element.
793 gst_element_set_index (GstElement *element, GstIndex *index)
795 GstElementClass *oclass;
797 g_return_if_fail (GST_IS_ELEMENT (element));
798 g_return_if_fail (GST_IS_INDEX (index));
800 oclass = GST_ELEMENT_GET_CLASS (element);
802 if (oclass->set_index)
803 oclass->set_index (element, index);
807 * gst_element_get_index:
808 * @element: a #GstElement.
810 * Gets the index from the element.
812 * Returns: a #GstIndex or NULL when no index was set on the
816 gst_element_get_index (GstElement *element)
818 GstElementClass *oclass;
820 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
822 oclass = GST_ELEMENT_GET_CLASS (element);
824 if (oclass->get_index)
825 return oclass->get_index (element);
831 * gst_element_release_locks:
832 * @element: a #GstElement to release all locks on.
834 * Instruct the element to release all the locks it is holding, such as
835 * blocking reads, waiting for the clock, ...
837 * Returns: TRUE if the locks could be released.
840 gst_element_release_locks (GstElement *element)
842 GstElementClass *oclass;
844 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
846 oclass = GST_ELEMENT_GET_CLASS (element);
848 if (oclass->release_locks)
849 return oclass->release_locks (element);
855 * gst_element_add_pad:
856 * @element: a #GstElement to add the pad to.
857 * @pad: the #GstPad to add to the element.
859 * Add a pad (link point) to the element, setting the parent of the
860 * pad to the element (and thus adding a reference).
863 gst_element_add_pad (GstElement *element, GstPad *pad)
865 g_return_if_fail (element != NULL);
866 g_return_if_fail (GST_IS_ELEMENT (element));
867 g_return_if_fail (pad != NULL);
868 g_return_if_fail (GST_IS_PAD (pad));
870 /* first check to make sure the pad's parent is already set */
871 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
873 /* then check to see if there's already a pad by that name here */
874 g_return_if_fail (gst_object_check_uniqueness (element->pads, GST_PAD_NAME(pad)) == TRUE);
876 /* set the pad's parent */
877 GST_DEBUG (GST_CAT_ELEMENT_PADS,"setting parent of pad '%s' to '%s'",
878 GST_PAD_NAME (pad), GST_ELEMENT_NAME (element));
879 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
881 /* add it to the list */
882 element->pads = g_list_append (element->pads, pad);
884 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
885 element->numsrcpads++;
887 element->numsinkpads++;
889 /* emit the NEW_PAD signal */
890 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
894 * gst_element_remove_pad:
895 * @element: a #GstElement to remove pad from.
896 * @pad: the #GstPad to remove from the element.
898 * Remove a pad (link point) from the element.
901 gst_element_remove_pad (GstElement *element, GstPad *pad)
903 g_return_if_fail (element != NULL);
904 g_return_if_fail (GST_IS_ELEMENT (element));
905 g_return_if_fail (pad != NULL);
906 g_return_if_fail (GST_IS_PAD (pad));
908 g_return_if_fail (GST_PAD_PARENT (pad) == element);
910 /* check to see if the pad is still linked */
911 /* FIXME: what if someone calls _remove_pad instead of
912 _remove_ghost_pad? */
913 if (GST_IS_REAL_PAD (pad)) {
914 g_return_if_fail (GST_RPAD_PEER (pad) == NULL);
917 /* remove it from the list */
918 element->pads = g_list_remove (element->pads, pad);
920 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
921 element->numsrcpads--;
923 element->numsinkpads--;
925 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
927 gst_object_unparent (GST_OBJECT (pad));
931 * gst_element_add_ghost_pad:
932 * @element: a #GstElement to add the ghost pad to.
933 * @pad: the #GstPad from which the new ghost pad will be created.
934 * @name: the name of the new ghost pad.
936 * Creates a ghost pad from the given pad, and adds it to the list of pads
939 * Returns: the added ghost #GstPad, or NULL, if no ghost pad was created.
942 gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
946 g_return_val_if_fail (element != NULL, NULL);
947 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
948 g_return_val_if_fail (pad != NULL, NULL);
949 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
951 /* then check to see if there's already a pad by that name here */
952 g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
954 GST_DEBUG (GST_CAT_ELEMENT_PADS,
955 "creating new ghost pad called %s, from pad %s:%s",
956 name, GST_DEBUG_PAD_NAME(pad));
957 ghostpad = gst_ghost_pad_new (name, pad);
959 /* add it to the list */
960 GST_DEBUG(GST_CAT_ELEMENT_PADS,"adding ghost pad %s to element %s",
961 name, GST_ELEMENT_NAME (element));
962 element->pads = g_list_append (element->pads, ghostpad);
964 /* set the parent of the ghostpad */
965 gst_object_set_parent (GST_OBJECT (ghostpad), GST_OBJECT (element));
967 GST_DEBUG(GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s",GST_DEBUG_PAD_NAME(ghostpad));
969 /* emit the NEW_GHOST_PAD signal */
970 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
976 * gst_element_remove_ghost_pad:
977 * @element: a #GstElement to remove the ghost pad from.
978 * @pad: ghost #GstPad to remove.
980 * Removes a ghost pad from an element.
983 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
985 g_return_if_fail (element != NULL);
986 g_return_if_fail (GST_IS_ELEMENT (element));
987 g_return_if_fail (pad != NULL);
988 g_return_if_fail (GST_IS_GHOST_PAD (pad));
990 /* FIXME this is redundant?
991 * wingo 10-july-2001: I don't think so, you have to actually remove the pad
992 * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
993 * the real pad's ghost pad list
995 gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
996 gst_element_remove_pad (element, pad);
1001 * gst_element_get_pad:
1002 * @element: a #GstElement to find pad of.
1003 * @name: the name of the pad to retrieve.
1005 * Retrieves a pad from the element by name.
1007 * Returns: requested #GstPad if found, otherwise NULL.
1010 gst_element_get_pad (GstElement *element, const gchar *name)
1014 g_return_val_if_fail (element != NULL, NULL);
1015 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1016 g_return_val_if_fail (name != NULL, NULL);
1018 pad = gst_element_get_static_pad (element, name);
1020 pad = gst_element_get_request_pad (element, name);
1026 * gst_element_get_static_pad:
1027 * @element: a #GstElement to find a static pad of.
1028 * @name: the name of the static #GstPad to retrieve.
1030 * Retrieves a pad from the element by name. This version only retrieves
1031 * already-existing (i.e. 'static') pads.
1033 * Returns: the requested #GstPad if found, otherwise NULL.
1036 gst_element_get_static_pad (GstElement *element, const gchar *name)
1040 g_return_val_if_fail (element != NULL, NULL);
1041 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1042 g_return_val_if_fail (name != NULL, NULL);
1044 walk = element->pads;
1048 pad = GST_PAD(walk->data);
1049 if (strcmp (GST_PAD_NAME(pad), name) == 0) {
1050 GST_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1053 walk = g_list_next (walk);
1056 GST_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"", name, GST_OBJECT_NAME (element));
1061 * gst_element_get_request_pad:
1062 * @element: a #GstElement to find a request pad of.
1063 * @name: the name of the request #GstPad to retrieve.
1065 * Retrieves a pad from the element by name. This version only retrieves
1068 * Returns: requested #GstPad if found, otherwise NULL.
1071 gst_element_get_request_pad (GstElement *element, const gchar *name)
1073 GstPadTemplate *templ = NULL;
1075 const gchar *req_name = NULL;
1076 gboolean templ_found = FALSE;
1080 gchar *str, *endptr = NULL;
1082 g_return_val_if_fail (element != NULL, NULL);
1083 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1084 g_return_val_if_fail (name != NULL, NULL);
1086 if (strstr (name, "%")) {
1087 templ = gst_element_get_pad_template (element, name);
1092 list = gst_element_get_pad_template_list(element);
1093 while (!templ_found && list) {
1094 templ = (GstPadTemplate*) list->data;
1095 if (templ->presence == GST_PAD_REQUEST) {
1096 /* we know that %s and %d are the only possibilities because of sanity
1097 checks in gst_pad_template_new */
1098 GST_DEBUG (GST_CAT_PADS, "comparing %s to %s", name, templ->name_template);
1099 if ((str = strchr (templ->name_template, '%')) &&
1100 strncmp (templ->name_template, name, str - templ->name_template) == 0 &&
1101 strlen (name) > str - templ->name_template) {
1102 data = name + (str - templ->name_template);
1103 if (*(str+1) == 'd') {
1105 n = (gint) strtol (data, &endptr, 10);
1106 if (endptr && *endptr == '\0') {
1126 pad = gst_element_request_pad (element, templ, req_name);
1132 * gst_element_get_pad_list:
1133 * @element: a #GstElement to get pads of.
1135 * Retrieves a list of the pads associated with the element.
1137 * Returns: the #GList of pads.
1140 gst_element_get_pad_list (GstElement *element)
1142 g_return_val_if_fail (element != NULL, NULL);
1143 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1145 /* return the list of pads */
1146 return element->pads;
1150 * gst_element_class_add_pad_template:
1151 * @klass: the #GstElementClass to add the pad template to.
1152 * @templ: a #GstPadTemplate to add to the element class.
1154 * Adds a padtemplate to an element class.
1155 * This is useful if you have derived a custom bin and wish to provide
1156 * an on-request pad at runtime. Plug-in writers should use
1157 * gst_element_factory_add_pad_template instead.
1160 gst_element_class_add_pad_template (GstElementClass *klass,
1161 GstPadTemplate *templ)
1163 g_return_if_fail (klass != NULL);
1164 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1165 g_return_if_fail (templ != NULL);
1166 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1168 klass->padtemplates = g_list_append (klass->padtemplates, templ);
1169 klass->numpadtemplates++;
1173 * gst_element_get_pad_template_list:
1174 * @element: a #GstElement to get pad templates of.
1176 * Retrieves a list of the pad templates associated with the element.
1178 * Returns: the #GList of padtemplates.
1181 gst_element_get_pad_template_list (GstElement *element)
1183 g_return_val_if_fail (element != NULL, NULL);
1184 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1186 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1190 * gst_element_get_pad_template:
1191 * @element: a #GstElement to get the pad template of.
1192 * @name: the name of the #GstPadTemplate to get.
1194 * Retrieves a padtemplate from this element with the
1197 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1198 * No unreferencing is necessary.
1201 gst_element_get_pad_template (GstElement *element, const gchar *name)
1205 g_return_val_if_fail (element != NULL, NULL);
1206 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1207 g_return_val_if_fail (name != NULL, NULL);
1209 padlist = gst_element_get_pad_template_list (element);
1212 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1214 if (!strcmp (padtempl->name_template, name))
1217 padlist = g_list_next (padlist);
1224 * gst_element_get_compatible_pad_template:
1225 * @element: a #GstElement to get a compatible pad template for.
1226 * @compattempl: the #GstPadTemplate to find a compatible template for.
1228 * Generates a pad template for this element compatible with the given
1229 * template (meaning it is able to link with it).
1231 * Returns: the #GstPadTemplate of the element that is compatible with
1232 * the given GstPadTemplate, or NULL if none was found. No unreferencing
1236 gst_element_get_compatible_pad_template (GstElement *element,
1237 GstPadTemplate *compattempl)
1239 GstPadTemplate *newtempl = NULL;
1242 GST_DEBUG (GST_CAT_ELEMENT_PADS, "gst_element_get_compatible_pad_template()");
1244 g_return_val_if_fail (element != NULL, NULL);
1245 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1246 g_return_val_if_fail (compattempl != NULL, NULL);
1248 padlist = gst_element_get_pad_template_list (element);
1251 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1252 gboolean comp = FALSE;
1256 * Check direction (must be opposite)
1259 GST_DEBUG (GST_CAT_CAPS, "checking direction and caps");
1260 if (padtempl->direction == GST_PAD_SRC &&
1261 compattempl->direction == GST_PAD_SINK) {
1262 GST_DEBUG (GST_CAT_CAPS, "compatible direction: found src pad template");
1263 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (padtempl),
1264 GST_PAD_TEMPLATE_CAPS (compattempl));
1265 GST_DEBUG(GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1266 } else if (padtempl->direction == GST_PAD_SINK &&
1267 compattempl->direction == GST_PAD_SRC) {
1268 GST_DEBUG (GST_CAT_CAPS, "compatible direction: found sink pad template");
1269 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1270 GST_PAD_TEMPLATE_CAPS (padtempl));
1271 GST_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1275 newtempl = padtempl;
1279 padlist = g_list_next (padlist);
1286 * gst_element_request_compatible_pad:
1287 * @element: a #GstElement to request a new pad from.
1288 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1290 * Requests a new pad from the element. The template will
1291 * be used to decide what type of pad to create. This function
1292 * is typically used for elements with a padtemplate with presence
1295 * Returns: the new #GstPad that was created, or NULL if none could be created.
1298 gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
1300 GstPadTemplate *templ_new;
1303 g_return_val_if_fail (element != NULL, NULL);
1304 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1305 g_return_val_if_fail (templ != NULL, NULL);
1307 templ_new = gst_element_get_compatible_pad_template (element, templ);
1308 if (templ_new != NULL)
1309 pad = gst_element_request_pad (element, templ_new, NULL);
1316 * gst_element_get_compatible_pad_filtered:
1317 * @element: a #GstElement in which the pad should be found.
1318 * @pad: the #GstPad to find a compatible one for.
1319 * @filtercaps: the #GstCaps to use as a filter.
1321 * Looks for an unlinked pad to which the given pad can link to.
1322 * It is not guaranteed that linking the pads will work, though
1323 * it should work in most cases.
1325 * Returns: the #GstPad to which a link can be made.
1328 gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
1329 GstCaps *filtercaps)
1332 GstPadTemplate *templ;
1334 GstPad *foundpad = NULL;
1337 g_return_val_if_fail (element != NULL, NULL);
1338 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1339 g_return_val_if_fail (pad != NULL, NULL);
1340 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1342 /* let's use the real pad */
1343 pad = (GstPad *) GST_PAD_REALIZE (pad);
1344 g_return_val_if_fail (pad != NULL, NULL);
1345 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1347 /* try to get an existing unlinked pad */
1348 pads = gst_element_get_pad_list (element);
1350 GstPad *current = GST_PAD (pads->data);
1351 if ((GST_PAD_PEER (GST_PAD_REALIZE (current)) == NULL) &&
1352 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1355 pads = g_list_next (pads);
1358 /* try to create a new one */
1359 /* requesting is a little crazy, we need a template. Let's create one */
1360 if (filtercaps != NULL) {
1361 templcaps = gst_caps_intersect (filtercaps, (GstCaps *) GST_RPAD_CAPS (pad));
1362 if (templcaps == NULL)
1365 templcaps = gst_pad_get_caps (pad);
1368 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1369 GST_PAD_ALWAYS, templcaps, NULL);
1370 foundpad = gst_element_request_compatible_pad (element, templ);
1371 gst_object_unref (GST_OBJECT (templ)); /* this will take care of the caps too */
1373 /* FIXME: this is broken, but it's in here so autoplugging elements that don't
1374 have caps on their source padtemplates (spider) can link... */
1375 if (!foundpad && !filtercaps) {
1376 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1377 GST_PAD_ALWAYS, NULL, NULL);
1378 foundpad = gst_element_request_compatible_pad (element, templ);
1379 gst_object_unref (GST_OBJECT (templ));
1386 * gst_element_get_compatible_pad:
1387 * @element: a #GstElement in which the pad should be found.
1388 * @pad: the #GstPad to find a compatible one for.
1390 * Looks for an unlinked pad to which the given pad can link to.
1391 * It is not guaranteed that linking the pads will work, though
1392 * it should work in most cases.
1394 * Returns: the #GstPad to which a link can be made, or NULL if none
1398 gst_element_get_compatible_pad (GstElement *element, GstPad *pad)
1400 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1404 * gst_element_link_filtered:
1405 * @src: a #GstElement containing the source pad.
1406 * @dest: the #GstElement containing the destination pad.
1407 * @filtercaps: the #GstCaps to use as a filter.
1409 * Links the source to the destination element using the filtercaps.
1410 * The link must be from source to destination, the other
1411 * direction will not be tried.
1412 * The functions looks for existing pads that aren't linked yet.
1413 * It will use request pads if possible. But both pads will not be requested.
1414 * If multiple links are possible, only one is established.
1416 * Returns: TRUE if the elements could be linked.
1419 gst_element_link_filtered (GstElement *src, GstElement *dest,
1420 GstCaps *filtercaps)
1422 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1423 GstPad *srcpad, *destpad;
1424 GstPadTemplate *srctempl, *desttempl;
1427 g_return_val_if_fail (src != NULL, FALSE);
1428 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1429 g_return_val_if_fail (dest != NULL, FALSE);
1430 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1432 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying to link element %s to element %s",
1433 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1435 srcpads = gst_element_get_pad_list (src);
1436 destpads = gst_element_get_pad_list (dest);
1438 if (srcpads || destpads) {
1439 GST_DEBUG (GST_CAT_ELEMENT_PADS, "looping through src and dest pads");
1440 /* loop through the existing pads in the source, trying to find a
1441 * compatible destination pad */
1443 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1444 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1445 GST_DEBUG_PAD_NAME (srcpad));
1446 if ((GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1447 (GST_PAD_PEER (srcpad) == NULL)) {
1448 destpad = gst_element_get_compatible_pad_filtered (dest, srcpad,
1450 if (destpad && gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1451 GST_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1452 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1456 srcpads = g_list_next (srcpads);
1459 /* loop through the existing pads in the destination */
1461 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1462 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1463 GST_DEBUG_PAD_NAME (destpad));
1464 if ((GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1465 (GST_PAD_PEER (destpad) == NULL)) {
1466 srcpad = gst_element_get_compatible_pad_filtered (src, destpad,
1468 if (srcpad && gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1469 GST_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1470 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1474 destpads = g_list_next (destpads);
1478 GST_DEBUG (GST_CAT_ELEMENT_PADS,
1479 "we might have request pads on both sides, checking...");
1480 srctempls = gst_element_get_pad_template_list (src);
1481 desttempls = gst_element_get_pad_template_list (dest);
1483 if (srctempls && desttempls) {
1485 srctempl = (GstPadTemplate*) srctempls->data;
1486 if (srctempl->presence == GST_PAD_REQUEST) {
1487 for (l=desttempls; l; l=l->next) {
1488 desttempl = (GstPadTemplate*) desttempls->data;
1489 if (desttempl->presence == GST_PAD_REQUEST &&
1490 desttempl->direction != srctempl->direction) {
1491 if (gst_caps_is_always_compatible (gst_pad_template_get_caps (srctempl),
1492 gst_pad_template_get_caps (desttempl))) {
1493 srcpad = gst_element_get_request_pad (src,
1494 srctempl->name_template);
1495 destpad = gst_element_get_request_pad (dest,
1496 desttempl->name_template);
1497 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1498 GST_DEBUG (GST_CAT_ELEMENT_PADS,
1499 "linked pad %s:%s to pad %s:%s",
1500 GST_DEBUG_PAD_NAME (srcpad),
1501 GST_DEBUG_PAD_NAME (destpad));
1504 /* FIXME: we have extraneous request pads lying around */
1509 srctempls = srctempls->next;
1513 GST_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1514 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1519 * gst_element_link_many:
1520 * @element_1: the first #GstElement in the link chain.
1521 * @element_2: the second #GstElement in the link chain.
1522 * @...: the NULL-terminated list of elements to link in order.
1524 * Chain together a series of elements. Uses #gst_element_link.
1526 * Returns: TRUE on success, FALSE otherwise.
1529 gst_element_link_many (GstElement *element_1, GstElement *element_2, ...)
1533 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1534 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1535 GST_IS_ELEMENT (element_2), FALSE);
1537 va_start (args, element_2);
1540 if (!gst_element_link (element_1, element_2))
1543 element_1 = element_2;
1544 element_2 = va_arg (args, GstElement*);
1554 * @src: a #GstElement containing the source pad.
1555 * @dest: the #GstElement containing the destination pad.
1557 * Links the source to the destination element.
1558 * The link must be from source to destination, the other
1559 * direction will not be tried.
1560 * The functions looks for existing pads and request pads that aren't
1561 * linked yet. If multiple links are possible, only one is
1564 * Returns: TRUE if the elements could be linked.
1567 gst_element_link (GstElement *src, GstElement *dest)
1569 return gst_element_link_filtered (src, dest, NULL);
1573 * gst_element_link_pads_filtered:
1574 * @src: a #GstElement containing the source pad.
1575 * @srcpadname: the name of the #GstPad in source element.
1576 * @dest: the #GstElement containing the destination pad.
1577 * @destpadname: the name of the #GstPad in destination element.
1578 * @filtercaps: the #GstCaps to use as a filter.
1580 * Links the two named pads of the source and destination elements.
1581 * Side effect is that if one of the pads has no parent, it becomes a
1582 * child of the parent of the other element. If they have different
1583 * parents, the link fails.
1585 * Returns: TRUE if the pads could be linked.
1588 gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
1589 GstElement *dest, const gchar *destpadname,
1590 GstCaps *filtercaps)
1592 GstPad *srcpad,*destpad;
1594 g_return_val_if_fail (src != NULL, FALSE);
1595 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1596 g_return_val_if_fail (srcpadname != NULL, FALSE);
1597 g_return_val_if_fail (dest != NULL, FALSE);
1598 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1599 g_return_val_if_fail (destpadname != NULL, FALSE);
1601 /* obtain the pads requested */
1602 srcpad = gst_element_get_pad (src, srcpadname);
1603 if (srcpad == NULL) {
1604 GST_ERROR (src, "source element has no pad \"%s\"", srcpadname);
1607 destpad = gst_element_get_pad (dest, destpadname);
1608 if (srcpad == NULL) {
1609 GST_ERROR (dest, "destination element has no pad \"%s\"", destpadname);
1613 /* we're satisified they can be linked, let's do it */
1614 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1618 * gst_element_link_pads:
1619 * @src: a #GstElement containing the source pad.
1620 * @srcpadname: the name of the #GstPad in the source element.
1621 * @dest: the #GstElement containing the destination pad.
1622 * @destpadname: the name of the #GstPad in destination element.
1624 * Links the two named pads of the source and destination elements.
1625 * Side effect is that if one of the pads has no parent, it becomes a
1626 * child of the parent of the other element. If they have different
1627 * parents, the link fails.
1629 * Returns: TRUE if the pads could be linked.
1632 gst_element_link_pads (GstElement *src, const gchar *srcpadname,
1633 GstElement *dest, const gchar *destpadname)
1635 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname, NULL);
1639 * gst_element_unlink_pads:
1640 * @src: a #GstElement containing the source pad.
1641 * @srcpadname: the name of the #GstPad in source element.
1642 * @dest: a #GstElement containing the destination pad.
1643 * @destpadname: the name of the #GstPad in destination element.
1645 * Unlinks the two named pads of the source and destination elements.
1648 gst_element_unlink_pads (GstElement *src, const gchar *srcpadname,
1649 GstElement *dest, const gchar *destpadname)
1651 GstPad *srcpad,*destpad;
1653 g_return_if_fail (src != NULL);
1654 g_return_if_fail (GST_IS_ELEMENT(src));
1655 g_return_if_fail (srcpadname != NULL);
1656 g_return_if_fail (dest != NULL);
1657 g_return_if_fail (GST_IS_ELEMENT(dest));
1658 g_return_if_fail (destpadname != NULL);
1660 /* obtain the pads requested */
1661 srcpad = gst_element_get_pad (src, srcpadname);
1662 if (srcpad == NULL) {
1663 GST_ERROR(src,"source element has no pad \"%s\"",srcpadname);
1666 destpad = gst_element_get_pad (dest, destpadname);
1667 if (srcpad == NULL) {
1668 GST_ERROR(dest,"destination element has no pad \"%s\"",destpadname);
1672 /* we're satisified they can be unlinked, let's do it */
1673 gst_pad_unlink (srcpad,destpad);
1677 * gst_element_unlink_many:
1678 * @element_1: the first #GstElement in the link chain.
1679 * @element_2: the second #GstElement in the link chain.
1680 * @...: the NULL-terminated list of elements to unlink in order.
1682 * Unlinks a series of elements. Uses #gst_element_unlink.
1685 gst_element_unlink_many (GstElement *element_1, GstElement *element_2, ...)
1689 g_return_if_fail (element_1 != NULL && element_2 != NULL);
1690 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
1692 va_start (args, element_2);
1695 gst_element_unlink (element_1, element_2);
1697 element_1 = element_2;
1698 element_2 = va_arg (args, GstElement*);
1705 * gst_element_unlink:
1706 * @src: the source #GstElement to unlink.
1707 * @dest: the sink #GstElement to unlink.
1709 * Unlinks all source pads of the source element with all sink pads
1710 * of the sink element to which they are linked.
1713 gst_element_unlink (GstElement *src, GstElement *dest)
1715 const GList *srcpads;
1718 g_return_if_fail (GST_IS_ELEMENT (src));
1719 g_return_if_fail (GST_IS_ELEMENT (dest));
1721 GST_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
1722 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1724 srcpads = gst_element_get_pad_list (src);
1727 pad = GST_PAD_CAST (srcpads->data);
1729 if (GST_IS_REAL_PAD (pad) && GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
1730 GstPad *peerpad = GST_PAD_PEER (pad);
1733 (GST_OBJECT_PARENT (GST_PAD_PEER (peerpad)) == (GstObject*) src)) {
1734 gst_pad_unlink (pad, peerpad);
1738 srcpads = g_list_next (srcpads);
1743 gst_element_error_func (GstElement* element, GstElement *source,
1746 /* tell the parent */
1747 if (GST_OBJECT_PARENT (element)) {
1748 GST_DEBUG (GST_CAT_EVENT, "forwarding error \"%s\" from %s to %s",
1749 errormsg, GST_ELEMENT_NAME (element),
1750 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
1752 gst_object_ref (GST_OBJECT (element));
1753 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
1754 gst_element_signals[ERROR], 0, source, errormsg);
1755 gst_object_unref (GST_OBJECT (element));
1760 gst_element_get_random_pad (GstElement *element, GstPadDirection dir)
1762 GList *pads = element->pads;
1763 GST_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1765 GstPad *pad = GST_PAD_CAST (pads->data);
1767 GST_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1768 GST_DEBUG_PAD_NAME (pad));
1770 if (GST_PAD_DIRECTION (pad) == dir) {
1771 if (GST_PAD_IS_LINKED (pad)) {
1775 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1776 GST_DEBUG_PAD_NAME (pad));
1780 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
1781 GST_DEBUG_PAD_NAME (pad));
1784 pads = g_list_next (pads);
1790 * gst_element_get_event_masks:
1791 * @element: a #GstElement to query
1793 * Get an array of event masks from the element.
1794 * If the element doesn't
1795 * implement an event masks function, the query will be forwarded
1796 * to a random linked sink pad.
1798 * Returns: An array of #GstEventMask elements.
1801 gst_element_get_event_masks (GstElement *element)
1803 GstElementClass *oclass;
1805 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1807 oclass = GST_ELEMENT_GET_CLASS (element);
1809 if (oclass->get_event_masks)
1810 return oclass->get_event_masks (element);
1812 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1814 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
1821 * gst_element_send_event:
1822 * @element: a #GstElement to send the event to.
1823 * @event: the #GstEvent to send to the element.
1825 * Sends an event to an element. If the element doesn't
1826 * implement an event handler, the event will be forwarded
1827 * to a random sink pad.
1829 * Returns: TRUE if the event was handled.
1832 gst_element_send_event (GstElement *element, GstEvent *event)
1834 GstElementClass *oclass;
1836 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1837 g_return_val_if_fail (event != NULL, FALSE);
1839 oclass = GST_ELEMENT_GET_CLASS (element);
1841 if (oclass->send_event)
1842 return oclass->send_event (element, event);
1844 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1846 GST_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
1847 GST_DEBUG_PAD_NAME (pad));
1848 return gst_pad_send_event (GST_PAD_PEER (pad), event);
1851 GST_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1852 GST_ELEMENT_NAME (element));
1857 * gst_element_get_query_types:
1858 * @element: a #GstElement to query
1860 * Get an array of query types from the element.
1861 * If the element doesn't
1862 * implement a query types function, the query will be forwarded
1863 * to a random sink pad.
1865 * Returns: An array of #GstQueryType elements.
1868 gst_element_get_query_types (GstElement *element)
1870 GstElementClass *oclass;
1872 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1874 oclass = GST_ELEMENT_GET_CLASS (element);
1876 if (oclass->get_query_types)
1877 return oclass->get_query_types (element);
1879 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1881 return gst_pad_get_query_types (GST_PAD_PEER (pad));
1888 * gst_element_query:
1889 * @element: a #GstElement to perform the query on.
1890 * @type: the #GstQueryType.
1891 * @format: the #GstFormat pointer to hold the format of the result.
1892 * @value: the pointer to the value of the result.
1894 * Performs a query on the given element. If the format is set
1895 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1896 * format pointer will hold the default format.
1897 * For element that don't implement a query handler, this function
1898 * forwards the query to a random usable sinkpad of this element.
1900 * Returns: TRUE if the query could be performed.
1903 gst_element_query (GstElement *element, GstQueryType type,
1904 GstFormat *format, gint64 *value)
1906 GstElementClass *oclass;
1908 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1909 g_return_val_if_fail (format != NULL, FALSE);
1910 g_return_val_if_fail (value != NULL, FALSE);
1912 oclass = GST_ELEMENT_GET_CLASS (element);
1915 return oclass->query (element, type, format, value);
1917 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1919 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
1926 * gst_element_get_formats:
1927 * @element: a #GstElement to query
1929 * Get an array of formst from the element.
1930 * If the element doesn't
1931 * implement a formats function, the query will be forwarded
1932 * to a random sink pad.
1934 * Returns: An array of #GstFormat elements.
1937 gst_element_get_formats (GstElement *element)
1939 GstElementClass *oclass;
1941 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1943 oclass = GST_ELEMENT_GET_CLASS (element);
1945 if (oclass->get_formats)
1946 return oclass->get_formats (element);
1948 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1950 return gst_pad_get_formats (GST_PAD_PEER (pad));
1957 * gst_element_convert:
1958 * @element: a #GstElement to invoke the converter on.
1959 * @src_format: the source #GstFormat.
1960 * @src_value: the source value.
1961 * @dest_format: a pointer to the destination #GstFormat.
1962 * @dest_value: a pointer to the destination value.
1964 * Invokes a conversion on the element.
1965 * If the element doesn't
1966 * implement a convert function, the query will be forwarded
1967 * to a random sink pad.
1969 * Returns: TRUE if the conversion could be performed.
1972 gst_element_convert (GstElement *element,
1973 GstFormat src_format, gint64 src_value,
1974 GstFormat *dest_format, gint64 *dest_value)
1976 GstElementClass *oclass;
1978 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1979 g_return_val_if_fail (dest_format != NULL, FALSE);
1980 g_return_val_if_fail (dest_value != NULL, FALSE);
1982 if (src_format == *dest_format) {
1983 *dest_value = src_value;
1987 oclass = GST_ELEMENT_GET_CLASS (element);
1989 if (oclass->convert)
1990 return oclass->convert (element,
1991 src_format, src_value,
1992 dest_format, dest_value);
1994 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1996 return gst_pad_convert (GST_PAD_PEER (pad),
1997 src_format, src_value,
1998 dest_format, dest_value);
2005 * gst_element_error:
2006 * @element: a #GstElement with the error.
2007 * @error: the printf-style string describing the error.
2008 * @...: the optional arguments for the string.
2010 * signals an error condition on an element.
2011 * This function is used internally by elements.
2012 * It results in the "error" signal.
2015 gst_element_error (GstElement *element, const gchar *error, ...)
2021 g_return_if_fail (GST_IS_ELEMENT (element));
2022 g_return_if_fail (error != NULL);
2024 /* create error message */
2025 va_start (var_args, error);
2026 string = g_strdup_vprintf (error, var_args);
2028 GST_INFO (GST_CAT_EVENT, "ERROR in %s: %s", GST_ELEMENT_NAME (element), string);
2030 /* emit the signal, make sure the element stays available */
2031 gst_object_ref (GST_OBJECT (element));
2032 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element, string);
2034 /* tell the scheduler */
2035 if (element->sched) {
2036 gst_scheduler_error (element->sched, element);
2039 if (GST_STATE (element) == GST_STATE_PLAYING)
2040 gst_element_set_state (element, GST_STATE_PAUSED);
2043 gst_object_unref (GST_OBJECT (element));
2048 * gst_element_get_state:
2049 * @element: a #GstElement to get the state of.
2051 * Gets the state of the element.
2053 * Returns: the #GstElementState of the element.
2056 gst_element_get_state (GstElement *element)
2058 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2060 return GST_STATE (element);
2064 * gst_element_wait_state_change:
2065 * @element: a #GstElement to wait for a state change on.
2067 * Waits and blocks until the element changed its state.
2070 gst_element_wait_state_change (GstElement *element)
2072 g_mutex_lock (element->state_mutex);
2073 g_cond_wait (element->state_cond, element->state_mutex);
2074 g_mutex_unlock (element->state_mutex);
2078 * gst_element_set_state:
2079 * @element: a #GstElement to change state of.
2080 * @state: the element's new #GstElementState.
2082 * Sets the state of the element. This function will try to set the
2083 * requested state by going through all the intermediary states and calling
2084 * the class's state change function for each.
2086 * Returns: TRUE if the state was successfully set.
2087 * (using #GstElementStateReturn).
2089 GstElementStateReturn
2090 gst_element_set_state (GstElement *element, GstElementState state)
2092 GstElementClass *oclass;
2093 GstElementState curpending;
2094 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2096 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2098 /* start with the current state */
2099 curpending = GST_STATE(element);
2101 GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "setting state from %s to %s",
2102 gst_element_state_get_name (curpending),
2103 gst_element_state_get_name (state));
2105 /* loop until the final requested state is set */
2106 while (GST_STATE (element) != state
2107 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2108 /* move the curpending state in the correct direction */
2109 if (curpending < state)
2114 /* set the pending state variable */
2115 /* FIXME: should probably check to see that we don't already have one */
2116 GST_STATE_PENDING (element) = curpending;
2118 if (curpending != state) {
2119 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2120 "intermediate: setting state from %s to %s",
2121 gst_element_state_get_name (GST_STATE (element)),
2122 gst_element_state_get_name (curpending));
2125 /* call the state change function so it can set the state */
2126 oclass = GST_ELEMENT_GET_CLASS (element);
2127 if (oclass->change_state)
2128 return_val = (oclass->change_state) (element);
2130 switch (return_val) {
2131 case GST_STATE_FAILURE:
2132 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2133 "have failed change_state return");
2135 case GST_STATE_ASYNC:
2136 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2137 "element will change state async");
2139 case GST_STATE_SUCCESS:
2140 /* Last thing we do is verify that a successful state change really
2141 * did change the state... */
2142 if (GST_STATE (element) != curpending) {
2143 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2144 "element claimed state-change success,"
2145 "but state didn't change %s, %s <-> %s",
2146 gst_element_state_get_name (GST_STATE (element)),
2147 gst_element_state_get_name (GST_STATE_PENDING (element)),
2148 gst_element_state_get_name (curpending));
2149 return GST_STATE_FAILURE;
2153 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2154 g_assert_not_reached ();
2163 gst_element_negotiate_pads (GstElement *element)
2165 GList *pads = GST_ELEMENT_PADS (element);
2167 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "negotiating pads");
2170 GstPad *pad = GST_PAD (pads->data);
2173 pads = g_list_next (pads);
2175 if (!GST_IS_REAL_PAD (pad))
2178 srcpad = GST_PAD_REALIZE (pad);
2180 /* if we have a link on this pad and it doesn't have caps
2181 * allready, try to negotiate */
2182 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2183 GstRealPad *sinkpad;
2184 GstElementState otherstate;
2187 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2189 /* check the parent of the peer pad, if there is no parent do nothing */
2190 parent = GST_PAD_PARENT (sinkpad);
2194 /* skips pads that were already negotiating */
2195 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2196 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2199 otherstate = GST_STATE (parent);
2201 /* swap pads if needed */
2202 if (!GST_PAD_IS_SRC (srcpad)) {
2210 /* only try to negotiate if the peer element is in PAUSED or higher too */
2211 if (otherstate >= GST_STATE_READY) {
2212 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element,
2213 "perform negotiate for %s:%s and %s:%s",
2214 GST_DEBUG_PAD_NAME (srcpad),
2215 GST_DEBUG_PAD_NAME (sinkpad));
2216 if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad)))
2220 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element,
2221 "not negotiating %s:%s and %s:%s, not in READY yet",
2222 GST_DEBUG_PAD_NAME (srcpad),
2223 GST_DEBUG_PAD_NAME (sinkpad));
2232 gst_element_clear_pad_caps (GstElement *element)
2234 GList *pads = GST_ELEMENT_PADS (element);
2236 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "clearing pad caps");
2239 GstRealPad *pad = GST_PAD_REALIZE (pads->data);
2241 gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
2243 pads = g_list_next (pads);
2248 gst_element_pads_activate (GstElement *element, gboolean active)
2250 GList *pads = element->pads;
2253 GstPad *pad = GST_PAD_CAST (pads->data);
2254 pads = g_list_next (pads);
2256 if (!GST_IS_REAL_PAD (pad))
2259 gst_pad_set_active (pad, active);
2263 static GstElementStateReturn
2264 gst_element_change_state (GstElement *element)
2266 GstElementState old_state;
2268 gint old_pending, old_transition;
2270 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2272 old_state = GST_STATE (element);
2273 old_pending = GST_STATE_PENDING (element);
2274 old_transition = GST_STATE_TRANSITION (element);
2276 if (old_pending == GST_STATE_VOID_PENDING ||
2277 old_state == GST_STATE_PENDING (element)) {
2278 GST_INFO (GST_CAT_STATES,
2279 "no state change needed for element %s (VOID_PENDING)",
2280 GST_ELEMENT_NAME (element));
2281 return GST_STATE_SUCCESS;
2284 GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %04x",
2285 GST_ELEMENT_NAME (element),
2286 gst_element_state_get_name (old_state),
2287 gst_element_state_get_name (old_pending),
2290 /* we set the state change early for the negotiation functions */
2291 GST_STATE (element) = old_pending;
2292 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2294 switch (old_transition) {
2295 case GST_STATE_PLAYING_TO_PAUSED:
2296 gst_element_pads_activate (element, FALSE);
2298 case GST_STATE_PAUSED_TO_PLAYING:
2299 gst_element_pads_activate (element, TRUE);
2301 /* if we are going to paused, we try to negotiate the pads */
2302 case GST_STATE_READY_TO_PAUSED:
2303 if (!gst_element_negotiate_pads (element))
2306 /* going to the READY state clears all pad caps */
2307 case GST_STATE_PAUSED_TO_READY:
2308 gst_element_clear_pad_caps (element);
2314 parent = GST_ELEMENT_PARENT (element);
2316 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2317 "signaling state change from %s to %s",
2318 gst_element_state_get_name (old_state),
2319 gst_element_state_get_name (GST_STATE (element)));
2321 /* tell the scheduler if we have one */
2322 if (element->sched) {
2323 if (gst_scheduler_state_transition (element->sched, element,
2324 old_transition) != GST_STATE_SUCCESS) {
2325 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2326 "scheduler could change state");
2331 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2332 0, old_state, GST_STATE (element));
2334 /* tell our parent about the state change */
2335 if (parent && GST_IS_BIN (parent)) {
2336 gst_bin_child_state_change (GST_BIN (parent), old_state,
2337 GST_STATE (element), element);
2340 /* signal the state change in case somebody is waiting for us */
2341 g_mutex_lock (element->state_mutex);
2342 g_cond_signal (element->state_cond);
2343 g_mutex_unlock (element->state_mutex);
2345 return GST_STATE_SUCCESS;
2348 /* undo the state change */
2349 GST_STATE (element) = old_state;
2350 GST_STATE_PENDING (element) = old_pending;
2352 return GST_STATE_FAILURE;
2356 * gst_element_get_factory:
2357 * @element: a #GstElement to request the element factory of.
2359 * Retrieves the factory that was used to create this element.
2361 * Returns: the #GstElementFactory used for creating this element.
2364 gst_element_get_factory (GstElement *element)
2366 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2368 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2372 gst_element_dispose (GObject *object)
2374 GstElement *element = GST_ELEMENT (object);
2378 GST_DEBUG_ELEMENT (GST_CAT_REFCOUNTING, element, "dispose");
2380 gst_element_set_state (element, GST_STATE_NULL);
2382 /* first we break all our links with the ouside */
2383 if (element->pads) {
2385 orig = pads = g_list_copy (element->pads);
2387 pad = GST_PAD (pads->data);
2389 if (GST_PAD_PEER (pad)) {
2390 GST_DEBUG (GST_CAT_REFCOUNTING, "unlinking pad '%s'",
2391 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2392 gst_pad_unlink (pad, GST_PAD (GST_PAD_PEER (pad)));
2394 gst_element_remove_pad (element, pad);
2396 pads = g_list_next (pads);
2399 g_list_free (element->pads);
2400 element->pads = NULL;
2403 element->numsrcpads = 0;
2404 element->numsinkpads = 0;
2405 element->numpads = 0;
2406 g_mutex_free (element->state_mutex);
2407 g_cond_free (element->state_cond);
2409 if (element->prop_value_queue)
2410 g_async_queue_unref (element->prop_value_queue);
2411 element->prop_value_queue = NULL;
2412 if (element->property_mutex)
2413 g_mutex_free (element->property_mutex);
2415 gst_object_replace ((GstObject **)&element->sched, NULL);
2416 gst_object_replace ((GstObject **)&element->clock, NULL);
2418 G_OBJECT_CLASS (parent_class)->dispose (object);
2421 #ifndef GST_DISABLE_LOADSAVE
2423 * gst_element_save_thyself:
2424 * @element: a #GstElement to save.
2425 * @parent: the xml parent node.
2427 * Saves the element as part of the given XML structure.
2429 * Returns: the new #xmlNodePtr.
2432 gst_element_save_thyself (GstObject *object,
2436 GstElementClass *oclass;
2437 GParamSpec **specs, *spec;
2439 GValue value = { 0, };
2440 GstElement *element;
2442 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2444 element = GST_ELEMENT (object);
2446 oclass = GST_ELEMENT_GET_CLASS (element);
2448 xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element));
2450 if (oclass->elementfactory != NULL) {
2451 GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory;
2453 xmlNewChild (parent, NULL, "type", GST_OBJECT_NAME (factory));
2454 xmlNewChild (parent, NULL, "version", factory->details->version);
2457 /* FIXME: what is this? */
2458 /* if (element->manager) */
2459 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2462 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2464 for (i=0; i<nspecs; i++) {
2466 if (spec->flags & G_PARAM_READABLE) {
2470 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2472 g_object_get_property (G_OBJECT (element), spec->name, &value);
2473 param = xmlNewChild (parent, NULL, "param", NULL);
2474 xmlNewChild (param, NULL, "name", spec->name);
2476 if (G_IS_PARAM_SPEC_STRING (spec))
2477 contents = g_value_dup_string (&value);
2478 else if (G_IS_PARAM_SPEC_ENUM (spec))
2479 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2480 else if (G_IS_PARAM_SPEC_INT64 (spec))
2481 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2482 g_value_get_int64 (&value));
2484 contents = g_strdup_value_contents (&value);
2486 xmlNewChild (param, NULL, "value", contents);
2489 g_value_unset(&value);
2493 pads = GST_ELEMENT_PADS (element);
2496 GstPad *pad = GST_PAD (pads->data);
2497 /* figure out if it's a direct pad or a ghostpad */
2498 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2499 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
2500 gst_object_save_thyself (GST_OBJECT (pad), padtag);
2502 pads = g_list_next (pads);
2509 gst_element_restore_thyself (GstObject *object, xmlNodePtr self)
2511 xmlNodePtr children;
2512 GstElement *element;
2514 gchar *value = NULL;
2516 element = GST_ELEMENT (object);
2517 g_return_if_fail (element != NULL);
2520 children = self->xmlChildrenNode;
2522 if (!strcmp (children->name, "param")) {
2523 xmlNodePtr child = children->xmlChildrenNode;
2526 if (!strcmp (child->name, "name")) {
2527 name = xmlNodeGetContent (child);
2529 else if (!strcmp (child->name, "value")) {
2530 value = xmlNodeGetContent (child);
2532 child = child->next;
2534 /* FIXME: can this just be g_object_set ? */
2535 gst_util_set_object_arg (G_OBJECT (element), name, value);
2537 children = children->next;
2541 children = self->xmlChildrenNode;
2543 if (!strcmp (children->name, "pad")) {
2544 gst_pad_load_and_link (children, GST_OBJECT (element));
2546 children = children->next;
2549 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2550 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2552 #endif /* GST_DISABLE_LOADSAVE */
2555 * gst_element_yield:
2556 * @element: a #GstElement to yield.
2558 * Requests a yield operation for the element. The scheduler will typically
2559 * give control to another element.
2562 gst_element_yield (GstElement *element)
2564 if (GST_ELEMENT_SCHED (element)) {
2565 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
2570 * gst_element_interrupt:
2571 * @element: a #GstElement to interrupt.
2573 * Requests the scheduler of this element to interrupt the execution of
2574 * this element and scheduler another one.
2576 * Returns: TRUE if the element should exit its chain/loop/get
2577 * function ASAP, depending on the scheduler implementation.
2580 gst_element_interrupt (GstElement *element)
2582 if (GST_ELEMENT_SCHED (element)) {
2583 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
2590 * gst_element_set_scheduler:
2591 * @element: a #GstElement to set the scheduler of.
2592 * @sched: the #GstScheduler to set.
2594 * Sets the scheduler of the element. For internal use only, unless you're
2595 * writing a new bin subclass.
2598 gst_element_set_scheduler (GstElement *element,
2599 GstScheduler *sched)
2601 g_return_if_fail (GST_IS_ELEMENT (element));
2603 GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting scheduler to %p", sched);
2605 gst_object_replace ((GstObject **)&GST_ELEMENT_SCHED (element), GST_OBJECT (sched));
2609 * gst_element_get_scheduler:
2610 * @element: a #GstElement to get the scheduler of.
2612 * Returns the scheduler of the element.
2614 * Returns: the element's #GstScheduler.
2617 gst_element_get_scheduler (GstElement *element)
2619 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2621 return GST_ELEMENT_SCHED (element);
2625 * gst_element_set_loop_function:
2626 * @element: a #GstElement to set the loop function of.
2627 * @loop: Pointer to #GstElementLoopFunction.
2629 * This sets the loop function for the element. The function pointed to
2630 * can deviate from the GstElementLoopFunction definition in type of
2633 * NOTE: in order for this to take effect, the current loop function *must*
2634 * exit. Assuming the loop function itself is the only one who will cause
2635 * a new loopfunc to be assigned, this should be no problem.
2638 gst_element_set_loop_function (GstElement *element,
2639 GstElementLoopFunction loop)
2641 g_return_if_fail (GST_IS_ELEMENT (element));
2643 /* set the loop function */
2644 element->loopfunc = loop;
2646 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
2647 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
2649 if (GST_ELEMENT_SCHED (element)) {
2650 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
2655 * gst_element_set_eos:
2656 * @element: a #GstElement to set to the EOS state.
2658 * Perform the actions needed to bring the element in the EOS state.
2661 gst_element_set_eos (GstElement *element)
2663 g_return_if_fail (GST_IS_ELEMENT (element));
2665 GST_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
2666 GST_OBJECT_NAME (element));
2668 gst_element_set_state (element, GST_STATE_PAUSED);
2670 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
2675 * gst_element_state_get_name:
2676 * @state: a #GstElementState to get the name of.
2678 * Gets a string representing the given state.
2680 * Returns: a string with the name of the state.
2683 gst_element_state_get_name (GstElementState state)
2686 #ifdef GST_DEBUG_COLOR
2687 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2688 case GST_STATE_NULL: return "\033[01;37mNULL\033[00m";break;
2689 case GST_STATE_READY: return "\033[01;31mREADY\033[00m";break;
2690 case GST_STATE_PLAYING: return "\033[01;32mPLAYING\033[00m";break;
2691 case GST_STATE_PAUSED: return "\033[01;33mPAUSED\033[00m";break;
2693 /* This is a memory leak */
2694 return g_strdup_printf ("\033[01;37;41mUNKNOWN!\033[00m(%d)", state);
2696 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2697 case GST_STATE_NULL: return "NULL";break;
2698 case GST_STATE_READY: return "READY";break;
2699 case GST_STATE_PLAYING: return "PLAYING";break;
2700 case GST_STATE_PAUSED: return "PAUSED";break;
2701 default: return "UNKNOWN!";
2708 gst_element_populate_std_props (GObjectClass * klass, const gchar *prop_name,
2709 guint arg_id, GParamFlags flags)
2711 GQuark prop_id = g_quark_from_string (prop_name);
2714 static GQuark fd_id = 0;
2715 static GQuark blocksize_id;
2716 static GQuark bytesperread_id;
2717 static GQuark dump_id;
2718 static GQuark filesize_id;
2719 static GQuark mmapsize_id;
2720 static GQuark location_id;
2721 static GQuark offset_id;
2722 static GQuark silent_id;
2723 static GQuark touch_id;
2726 fd_id = g_quark_from_static_string ("fd");
2727 blocksize_id = g_quark_from_static_string ("blocksize");
2728 bytesperread_id = g_quark_from_static_string ("bytesperread");
2729 dump_id = g_quark_from_static_string ("dump");
2730 filesize_id = g_quark_from_static_string ("filesize");
2731 mmapsize_id = g_quark_from_static_string ("mmapsize");
2732 location_id = g_quark_from_static_string ("location");
2733 offset_id = g_quark_from_static_string ("offset");
2734 silent_id = g_quark_from_static_string ("silent");
2735 touch_id = g_quark_from_static_string ("touch");
2738 if (prop_id == fd_id) {
2739 pspec = g_param_spec_int ("fd", "File-descriptor",
2740 "File-descriptor for the file being read",
2741 0, G_MAXINT, 0, flags);
2743 else if (prop_id == blocksize_id) {
2744 pspec = g_param_spec_ulong ("blocksize", "Block Size",
2745 "Block size to read per buffer",
2746 0, G_MAXULONG, 4096, flags);
2749 else if (prop_id == bytesperread_id) {
2750 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
2751 "Number of bytes to read per buffer",
2752 G_MININT, G_MAXINT, 0, flags);
2755 else if (prop_id == dump_id) {
2756 pspec = g_param_spec_boolean ("dump", "Dump",
2757 "Dump bytes to stdout",
2761 else if (prop_id == filesize_id) {
2762 pspec = g_param_spec_int64 ("filesize", "File Size",
2763 "Size of the file being read",
2764 0, G_MAXINT64, 0, flags);
2767 else if (prop_id == mmapsize_id) {
2768 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
2769 "Size in bytes of mmap()d regions",
2770 0, G_MAXULONG, 4 * 1048576, flags);
2773 else if (prop_id == location_id) {
2774 pspec = g_param_spec_string ("location", "File Location",
2775 "Location of the file to read",
2779 else if (prop_id == offset_id) {
2780 pspec = g_param_spec_int64 ("offset", "File Offset",
2781 "Byte offset of current read pointer",
2782 0, G_MAXINT64, 0, flags);
2785 else if (prop_id == silent_id) {
2786 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
2790 else if (prop_id == touch_id) {
2791 pspec = g_param_spec_boolean ("touch", "Touch read data",
2792 "Touch data to force disk read before "
2793 "push ()", TRUE, flags);
2796 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
2797 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
2802 g_object_class_install_property (klass, arg_id, pspec);
2807 * gst_element_class_install_std_props:
2808 * @klass: the #GstElementClass to add the properties to.
2809 * @first_name: the name of the first property.
2810 * in a NULL terminated
2811 * @...: the id and flags of the first property, followed by
2812 * further 'name', 'id', 'flags' triplets and terminated by NULL.
2814 * Adds a list of standardized properties with types to the @klass.
2815 * the id is for the property switch in your get_prop method, and
2816 * the flags determine readability / writeability.
2819 gst_element_class_install_std_props (GstElementClass * klass,
2820 const gchar *first_name, ...)
2826 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
2828 va_start (args, first_name);
2833 int arg_id = va_arg (args, int);
2834 int flags = va_arg (args, int);
2836 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id, flags);
2838 name = va_arg (args, char *);
2845 * gst_element_get_managing_bin:
2846 * @element: a #GstElement to get the managing bin of.
2848 * Gets the managing bin (a pipeline or a thread, for example) of an element.
2850 * Returns: the #GstBin, or NULL on failure.
2853 gst_element_get_managing_bin (GstElement *element)
2857 g_return_val_if_fail (element != NULL, NULL);
2859 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (element)));
2861 while (bin && !GST_FLAG_IS_SET (GST_OBJECT_CAST (bin), GST_BIN_FLAG_MANAGER))
2862 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (bin)));