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"
31 #include "gstscheduler.h"
36 /* Element signals and args */
51 static void gst_element_class_init (GstElementClass *klass);
52 static void gst_element_init (GstElement *element);
53 static void gst_element_base_class_init (GstElementClass *klass);
55 static void gst_element_real_set_property (GObject *object, guint prop_id,
56 const GValue *value, GParamSpec *pspec);
57 static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value,
60 static void gst_element_dispose (GObject *object);
62 static GstElementStateReturn gst_element_change_state (GstElement *element);
63 static void gst_element_error_func (GstElement* element, GstElement *source, gchar *errormsg);
65 #ifndef GST_DISABLE_LOADSAVE
66 static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent);
67 static void gst_element_restore_thyself (GstObject *parent, xmlNodePtr self);
70 GType _gst_element_type = 0;
72 static GstObjectClass *parent_class = NULL;
73 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
75 GType gst_element_get_type (void)
77 if (!_gst_element_type) {
78 static const GTypeInfo element_info = {
79 sizeof(GstElementClass),
80 (GBaseInitFunc)gst_element_base_class_init,
82 (GClassInitFunc)gst_element_class_init,
87 (GInstanceInitFunc)gst_element_init,
90 _gst_element_type = g_type_register_static(GST_TYPE_OBJECT, "GstElement",
91 &element_info, G_TYPE_FLAG_ABSTRACT);
93 return _gst_element_type;
97 gst_element_class_init (GstElementClass *klass)
99 GObjectClass *gobject_class;
100 GstObjectClass *gstobject_class;
102 gobject_class = (GObjectClass*) klass;
103 gstobject_class = (GstObjectClass*) klass;
105 parent_class = g_type_class_ref(GST_TYPE_OBJECT);
107 gst_element_signals[STATE_CHANGE] =
108 g_signal_new ("state_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
109 G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL,
110 gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
111 G_TYPE_INT, G_TYPE_INT);
112 gst_element_signals[NEW_PAD] =
113 g_signal_new ("new_pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
114 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
115 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
117 gst_element_signals[PAD_REMOVED] =
118 g_signal_new ("pad_removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
119 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
120 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
122 gst_element_signals[ERROR] =
123 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
124 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
125 gst_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
126 G_TYPE_OBJECT, G_TYPE_STRING);
127 gst_element_signals[EOS] =
128 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
129 G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
130 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
132 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property);
133 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_property);
135 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
137 #ifndef GST_DISABLE_LOADSAVE
138 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
139 gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
142 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
143 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
144 klass->elementfactory = NULL;
145 klass->padtemplates = NULL;
146 klass->numpadtemplates = 0;
150 gst_element_base_class_init (GstElementClass *klass)
152 GObjectClass *gobject_class;
154 gobject_class = (GObjectClass*) klass;
156 gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_element_real_set_property);
157 gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_element_real_get_property);
161 gst_element_init (GstElement *element)
163 element->current_state = GST_STATE_NULL;
164 element->pending_state = GST_STATE_VOID_PENDING;
165 element->numpads = 0;
166 element->numsrcpads = 0;
167 element->numsinkpads = 0;
168 element->pads = NULL;
169 element->loopfunc = NULL;
170 element->sched = NULL;
171 element->clock = NULL;
172 element->sched_private = NULL;
173 element->state_mutex = g_mutex_new ();
174 element->state_cond = g_cond_new ();
178 gst_element_real_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
180 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
182 if (oclass->set_property)
183 (oclass->set_property) (object, prop_id, value, pspec);
187 gst_element_real_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
189 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
191 if (oclass->get_property)
192 (oclass->get_property) (object, prop_id, value, pspec);
196 * gst_element_default_error:
197 * @object: a #GObject that signalled the error.
198 * @orig: the #GstObject that initiated the error.
199 * @error: the error message.
201 * Adds a default error signal callback to an
202 * element. The user data passed to the g_signal_connect is
204 * The default handler will simply print the error string
208 gst_element_default_error (GObject *object, GstObject *orig, gchar *error)
210 gchar *name = gst_object_get_path_string (orig);
211 g_print ("ERROR: %s: %s\n", name, error);
216 const GParamSpec *pspec;
221 element_set_property (GstElement *element, const GParamSpec *pspec, const GValue *value)
223 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
225 prop_value->pspec = pspec;
226 prop_value->value = *value;
228 g_async_queue_push (element->prop_value_queue, prop_value);
232 element_get_property (GstElement *element, const GParamSpec *pspec, GValue *value)
234 g_mutex_lock (element->property_mutex);
235 g_object_get_property ((GObject*)element, pspec->name, value);
236 g_mutex_unlock (element->property_mutex);
240 gst_element_threadsafe_properties_pre_run (GstElement *element)
242 GST_DEBUG (GST_CAT_THREAD, "locking element %s", GST_OBJECT_NAME (element));
243 g_mutex_lock (element->property_mutex);
244 gst_element_set_pending_properties (element);
248 gst_element_threadsafe_properties_post_run (GstElement *element)
250 GST_DEBUG (GST_CAT_THREAD, "unlocking element %s", GST_OBJECT_NAME (element));
251 g_mutex_unlock (element->property_mutex);
255 * gst_element_enable_threadsafe_properties:
256 * @element: a #GstElement to enable threadsafe properties on.
258 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
259 * this element so that properties on the element can be set in a
263 gst_element_enable_threadsafe_properties (GstElement *element)
265 g_return_if_fail (GST_IS_ELEMENT (element));
267 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
268 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
269 element->post_run_func = gst_element_threadsafe_properties_post_run;
270 if (!element->prop_value_queue)
271 element->prop_value_queue = g_async_queue_new ();
272 if (!element->property_mutex)
273 element->property_mutex = g_mutex_new ();
277 * gst_element_disable_threadsafe_properties:
278 * @element: a #GstElement to disable threadsafe properties on.
280 * Removes the threadsafe properties, post- and pre-run locks from
284 gst_element_disable_threadsafe_properties (GstElement *element)
286 g_return_if_fail (GST_IS_ELEMENT (element));
288 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
289 element->pre_run_func = NULL;
290 element->post_run_func = NULL;
291 /* let's keep around that async queue */
295 * gst_element_set_pending_properties:
296 * @element: a #GstElement to set the pending properties on.
298 * Sets all pending properties on the threadsafe properties enabled
302 gst_element_set_pending_properties (GstElement *element)
304 prop_value_t *prop_value;
306 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
307 g_object_set_property ((GObject*)element, prop_value->pspec->name, &prop_value->value);
308 g_value_unset (&prop_value->value);
313 /* following 6 functions taken mostly from gobject.c */
317 * @element: a #GstElement to set properties on.
318 * @first_property_name: the first property to set.
319 * @...: value of the first property, and more properties to set, ending
322 * Sets properties on an element. If the element uses threadsafe properties,
323 * they will be queued and set on the object when it is scheduled again.
326 gst_element_set (GstElement *element, const gchar *first_property_name, ...)
330 g_return_if_fail (GST_IS_ELEMENT (element));
332 va_start (var_args, first_property_name);
333 gst_element_set_valist (element, first_property_name, var_args);
339 * @element: a #GstElement to get properties of.
340 * @first_property_name: the first property to get.
341 * @...: pointer to a variable to store the first property in, as well as
342 * more properties to get, ending with NULL.
344 * Gets properties from an element. If the element uses threadsafe properties,
345 * the element will be locked before getting the given properties.
348 gst_element_get (GstElement *element, const gchar *first_property_name, ...)
352 g_return_if_fail (GST_IS_ELEMENT (element));
354 va_start (var_args, first_property_name);
355 gst_element_get_valist (element, first_property_name, var_args);
360 * gst_element_set_valist:
361 * @element: a #GstElement to set properties on.
362 * @first_property_name: the first property to set.
363 * @var_args: the var_args list of other properties to get.
365 * Sets properties on an element. If the element uses threadsafe properties,
366 * the property change will be put on the async queue.
369 gst_element_set_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
374 g_return_if_fail (GST_IS_ELEMENT (element));
376 object = (GObject *) element;
378 GST_DEBUG (GST_CAT_PROPERTIES,
379 "setting valist of properties starting with %s on element %s",
380 first_property_name, gst_element_get_name (element));
382 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
383 g_object_set_valist (object, first_property_name, var_args);
387 g_object_ref (object);
389 name = first_property_name;
393 GValue value = { 0, };
397 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
401 g_warning ("%s: object class `%s' has no property named `%s'",
403 G_OBJECT_TYPE_NAME (object),
407 if (!(pspec->flags & G_PARAM_WRITABLE))
409 g_warning ("%s: property `%s' of object class `%s' is not writable",
412 G_OBJECT_TYPE_NAME (object));
416 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
418 G_VALUE_COLLECT (&value, var_args, 0, &error);
421 g_warning ("%s: %s", G_STRLOC, error);
424 /* we purposely leak the value here, it might not be
425 * in a sane state if an error condition occoured
430 element_set_property (element, pspec, &value);
431 g_value_unset (&value);
433 name = va_arg (var_args, gchar*);
436 g_object_unref (object);
440 * gst_element_get_valist:
441 * @element: a #GstElement to get properties of.
442 * @first_property_name: the first property to get.
443 * @var_args: the var_args list of other properties to get.
445 * Gets properties from an element. If the element uses threadsafe properties,
446 * the element will be locked before getting the given properties.
449 gst_element_get_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
454 g_return_if_fail (GST_IS_ELEMENT (element));
456 object = (GObject*)element;
458 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
459 g_object_get_valist (object, first_property_name, var_args);
463 g_object_ref (object);
465 name = first_property_name;
469 GValue value = { 0, };
473 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
477 g_warning ("%s: object class `%s' has no property named `%s'",
479 G_OBJECT_TYPE_NAME (object),
483 if (!(pspec->flags & G_PARAM_READABLE))
485 g_warning ("%s: property `%s' of object class `%s' is not readable",
488 G_OBJECT_TYPE_NAME (object));
492 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
494 element_get_property (element, pspec, &value);
496 G_VALUE_LCOPY (&value, var_args, 0, &error);
499 g_warning ("%s: %s", G_STRLOC, error);
501 g_value_unset (&value);
505 g_value_unset (&value);
507 name = va_arg (var_args, gchar*);
510 g_object_unref (object);
514 * gst_element_set_property:
515 * @element: a #GstElement to set properties on.
516 * @property_name: the first property to get.
517 * @value: the #GValue that holds the value to set.
519 * Sets a property on an element. If the element uses threadsafe properties,
520 * the property will be put on the async queue.
523 gst_element_set_property (GstElement *element, const gchar *property_name,
529 g_return_if_fail (GST_IS_ELEMENT (element));
530 g_return_if_fail (property_name != NULL);
531 g_return_if_fail (G_IS_VALUE (value));
533 object = (GObject*) element;
535 GST_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
536 property_name, gst_element_get_name (element));
537 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
538 g_object_set_property (object, property_name, value);
542 g_object_ref (object);
544 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
548 g_warning ("%s: object class `%s' has no property named `%s'",
550 G_OBJECT_TYPE_NAME (object),
553 element_set_property (element, pspec, value);
555 g_object_unref (object);
559 * gst_element_get_property:
560 * @element: a #GstElement to get properties of.
561 * @property_name: the first property to get.
562 * @value: the #GValue to store the property value in.
564 * Gets a property from an element. If the element uses threadsafe properties,
565 * the element will be locked before getting the given property.
568 gst_element_get_property (GstElement *element, const gchar *property_name, GValue *value)
573 g_return_if_fail (GST_IS_ELEMENT (element));
574 g_return_if_fail (property_name != NULL);
575 g_return_if_fail (G_IS_VALUE (value));
577 object = (GObject*)element;
579 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
580 g_object_get_property (object, property_name, value);
584 g_object_ref (object);
586 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
589 g_warning ("%s: object class `%s' has no property named `%s'",
591 G_OBJECT_TYPE_NAME (object),
595 GValue *prop_value, tmp_value = { 0, };
597 /* auto-conversion of the callers value type
599 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
601 g_value_reset (value);
604 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
606 g_warning ("can't retrieve property `%s' of type `%s' as value of type `%s'",
608 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
609 G_VALUE_TYPE_NAME (value));
610 g_object_unref (object);
615 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
616 prop_value = &tmp_value;
618 element_get_property (element, pspec, prop_value);
619 if (prop_value != value)
621 g_value_transform (prop_value, value);
622 g_value_unset (&tmp_value);
626 g_object_unref (object);
630 gst_element_request_pad (GstElement *element, GstPadTemplate *templ, const gchar* name)
632 GstPad *newpad = NULL;
633 GstElementClass *oclass;
635 oclass = GST_ELEMENT_GET_CLASS (element);
637 if (oclass->request_new_pad)
638 newpad = (oclass->request_new_pad)(element, templ, name);
644 * gst_element_release_request_pad:
645 * @element: a #GstElement to release the request pad of.
646 * @pad: the #GstPad to release.
648 * Makes the element free the previously requested pad as obtained
649 * with gst_element_get_request_pad().
652 gst_element_release_request_pad (GstElement *element, GstPad *pad)
654 GstElementClass *oclass;
656 g_return_if_fail (GST_IS_ELEMENT (element));
657 g_return_if_fail (GST_IS_PAD (pad));
659 oclass = GST_ELEMENT_GET_CLASS (element);
661 if (oclass->release_pad)
662 (oclass->release_pad) (element, pad);
666 * gst_element_requires_clock:
667 * @element: a #GstElement to query
669 * Query if the element requiresd a clock
671 * Returns: TRUE if the element requires a clock
674 gst_element_requires_clock (GstElement *element)
676 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
678 return (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
682 * gst_element_provides_clock:
683 * @element: a #GstElement to query
685 * Query if the element provides a clock
687 * Returns: TRUE if the element provides a clock
690 gst_element_provides_clock (GstElement *element)
692 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
694 return (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
698 * gst_element_set_clock:
699 * @element: a #GstElement to set the clock for.
700 * @clock: the #GstClock to set for the element.
702 * Sets the clock for the element.
705 gst_element_set_clock (GstElement *element, GstClock *clock)
707 GstElementClass *oclass;
709 g_return_if_fail (GST_IS_ELEMENT (element));
711 oclass = GST_ELEMENT_GET_CLASS (element);
713 if (oclass->set_clock)
714 oclass->set_clock (element, clock);
716 gst_object_replace ((GstObject **)&element->clock, (GstObject *)clock);
720 * gst_element_get_clock:
721 * @element: a #GstElement to get the clock of.
723 * Gets the clock of the element.
725 * Returns: the #GstClock of the element.
728 gst_element_get_clock (GstElement *element)
730 GstElementClass *oclass;
732 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
734 oclass = GST_ELEMENT_GET_CLASS (element);
736 if (oclass->get_clock)
737 return oclass->get_clock (element);
743 * gst_element_clock_wait:
744 * @element: a #GstElement.
745 * @id: the #GstClock to use.
746 * @jitter: the difference between requested time and actual time.
748 * Waits for a specific time on the clock.
750 * Returns: the #GstClockReturn result of the wait operation.
753 gst_element_clock_wait (GstElement *element, GstClockID id, GstClockTimeDiff *jitter)
757 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
759 if (GST_ELEMENT_SCHED (element)) {
760 res = gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id, jitter);
763 res = GST_CLOCK_TIMEOUT;
768 #ifndef GST_DISABLE_INDEX
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);
832 * gst_element_release_locks:
833 * @element: a #GstElement to release all locks on.
835 * Instruct the element to release all the locks it is holding, such as
836 * blocking reads, waiting for the clock, ...
838 * Returns: TRUE if the locks could be released.
841 gst_element_release_locks (GstElement *element)
843 GstElementClass *oclass;
845 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
847 oclass = GST_ELEMENT_GET_CLASS (element);
849 if (oclass->release_locks)
850 return oclass->release_locks (element);
856 * gst_element_add_pad:
857 * @element: a #GstElement to add the pad to.
858 * @pad: the #GstPad to add to the element.
860 * Add a pad (link point) to the element, setting the parent of the
861 * pad to the element (and thus adding a reference).
862 * Pads are automatically activated when the element is in state PLAYING.
865 gst_element_add_pad (GstElement *element, GstPad *pad)
867 g_return_if_fail (element != NULL);
868 g_return_if_fail (GST_IS_ELEMENT (element));
869 g_return_if_fail (pad != NULL);
870 g_return_if_fail (GST_IS_PAD (pad));
872 /* first check to make sure the pad's parent is already set */
873 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
875 /* then check to see if there's already a pad by that name here */
876 g_return_if_fail (gst_object_check_uniqueness (element->pads, GST_PAD_NAME(pad)) == TRUE);
878 /* set the pad's parent */
879 GST_DEBUG (GST_CAT_ELEMENT_PADS,"setting parent of pad '%s' to '%s'",
880 GST_PAD_NAME (pad), GST_ELEMENT_NAME (element));
881 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
883 /* add it to the list */
884 element->pads = g_list_append (element->pads, pad);
886 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
887 element->numsrcpads++;
889 element->numsinkpads++;
891 /* activate element when we are playing */
892 if (GST_STATE (element) == GST_STATE_PLAYING)
893 gst_pad_set_active (pad, TRUE);
895 /* emit the NEW_PAD signal */
896 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
900 * gst_element_remove_pad:
901 * @element: a #GstElement to remove pad from.
902 * @pad: the #GstPad to remove from the element.
904 * Remove a pad (link point) from the element.
907 gst_element_remove_pad (GstElement *element, GstPad *pad)
909 g_return_if_fail (element != NULL);
910 g_return_if_fail (GST_IS_ELEMENT (element));
911 g_return_if_fail (pad != NULL);
912 g_return_if_fail (GST_IS_PAD (pad));
914 g_return_if_fail (GST_PAD_PARENT (pad) == element);
916 /* check to see if the pad is still linked */
917 /* FIXME: what if someone calls _remove_pad instead of
918 _remove_ghost_pad? */
919 if (GST_IS_REAL_PAD (pad)) {
920 g_return_if_fail (GST_RPAD_PEER (pad) == NULL);
923 /* remove it from the list */
924 element->pads = g_list_remove (element->pads, pad);
926 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
927 element->numsrcpads--;
929 element->numsinkpads--;
931 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
933 gst_object_unparent (GST_OBJECT (pad));
937 * gst_element_add_ghost_pad:
938 * @element: a #GstElement to add the ghost pad to.
939 * @pad: the #GstPad from which the new ghost pad will be created.
940 * @name: the name of the new ghost pad.
942 * Creates a ghost pad from the given pad, and adds it to the list of pads
945 * Returns: the added ghost #GstPad, or NULL, if no ghost pad was created.
948 gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
952 g_return_val_if_fail (element != NULL, NULL);
953 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
954 g_return_val_if_fail (pad != NULL, NULL);
955 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
957 /* then check to see if there's already a pad by that name here */
958 g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
960 GST_DEBUG (GST_CAT_ELEMENT_PADS,
961 "creating new ghost pad called %s, from pad %s:%s",
962 name, GST_DEBUG_PAD_NAME(pad));
963 ghostpad = gst_ghost_pad_new (name, pad);
965 /* add it to the list */
966 GST_DEBUG(GST_CAT_ELEMENT_PADS,"adding ghost pad %s to element %s",
967 name, GST_ELEMENT_NAME (element));
968 element->pads = g_list_append (element->pads, ghostpad);
970 /* set the parent of the ghostpad */
971 gst_object_set_parent (GST_OBJECT (ghostpad), GST_OBJECT (element));
973 GST_DEBUG(GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s",GST_DEBUG_PAD_NAME(ghostpad));
975 /* emit the NEW_GHOST_PAD signal */
976 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
982 * gst_element_remove_ghost_pad:
983 * @element: a #GstElement to remove the ghost pad from.
984 * @pad: ghost #GstPad to remove.
986 * Removes a ghost pad from an element.
989 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
991 g_return_if_fail (element != NULL);
992 g_return_if_fail (GST_IS_ELEMENT (element));
993 g_return_if_fail (pad != NULL);
994 g_return_if_fail (GST_IS_GHOST_PAD (pad));
996 /* FIXME this is redundant?
997 * wingo 10-july-2001: I don't think so, you have to actually remove the pad
998 * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
999 * the real pad's ghost pad list
1001 gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
1002 gst_element_remove_pad (element, pad);
1007 * gst_element_get_pad:
1008 * @element: a #GstElement to find pad of.
1009 * @name: the name of the pad to retrieve.
1011 * Retrieves a pad from the element by name.
1013 * Returns: requested #GstPad if found, otherwise NULL.
1016 gst_element_get_pad (GstElement *element, const gchar *name)
1020 g_return_val_if_fail (element != NULL, NULL);
1021 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1022 g_return_val_if_fail (name != NULL, NULL);
1024 pad = gst_element_get_static_pad (element, name);
1026 pad = gst_element_get_request_pad (element, name);
1032 * gst_element_get_static_pad:
1033 * @element: a #GstElement to find a static pad of.
1034 * @name: the name of the static #GstPad to retrieve.
1036 * Retrieves a pad from the element by name. This version only retrieves
1037 * already-existing (i.e. 'static') pads.
1039 * Returns: the requested #GstPad if found, otherwise NULL.
1042 gst_element_get_static_pad (GstElement *element, const gchar *name)
1046 g_return_val_if_fail (element != NULL, NULL);
1047 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1048 g_return_val_if_fail (name != NULL, NULL);
1050 walk = element->pads;
1054 pad = GST_PAD(walk->data);
1055 if (strcmp (GST_PAD_NAME(pad), name) == 0) {
1056 GST_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1059 walk = g_list_next (walk);
1062 GST_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"", name, GST_OBJECT_NAME (element));
1067 * gst_element_get_request_pad:
1068 * @element: a #GstElement to find a request pad of.
1069 * @name: the name of the request #GstPad to retrieve.
1071 * Retrieves a pad from the element by name. This version only retrieves
1074 * Returns: requested #GstPad if found, otherwise NULL.
1077 gst_element_get_request_pad (GstElement *element, const gchar *name)
1079 GstPadTemplate *templ = NULL;
1081 const gchar *req_name = NULL;
1082 gboolean templ_found = FALSE;
1086 gchar *str, *endptr = NULL;
1088 g_return_val_if_fail (element != NULL, NULL);
1089 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1090 g_return_val_if_fail (name != NULL, NULL);
1092 if (strstr (name, "%")) {
1093 templ = gst_element_get_pad_template (element, name);
1098 list = gst_element_get_pad_template_list(element);
1099 while (!templ_found && list) {
1100 templ = (GstPadTemplate*) list->data;
1101 if (templ->presence == GST_PAD_REQUEST) {
1102 /* we know that %s and %d are the only possibilities because of sanity
1103 checks in gst_pad_template_new */
1104 GST_DEBUG (GST_CAT_PADS, "comparing %s to %s", name, templ->name_template);
1105 if ((str = strchr (templ->name_template, '%')) &&
1106 strncmp (templ->name_template, name, str - templ->name_template) == 0 &&
1107 strlen (name) > str - templ->name_template) {
1108 data = name + (str - templ->name_template);
1109 if (*(str+1) == 'd') {
1111 n = (gint) strtol (data, &endptr, 10);
1112 if (endptr && *endptr == '\0') {
1132 pad = gst_element_request_pad (element, templ, req_name);
1138 * gst_element_get_pad_list:
1139 * @element: a #GstElement to get pads of.
1141 * Retrieves a list of the pads associated with the element.
1143 * Returns: the #GList of pads.
1146 gst_element_get_pad_list (GstElement *element)
1148 g_return_val_if_fail (element != NULL, NULL);
1149 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1151 /* return the list of pads */
1152 return element->pads;
1156 * gst_element_class_add_pad_template:
1157 * @klass: the #GstElementClass to add the pad template to.
1158 * @templ: a #GstPadTemplate to add to the element class.
1160 * Adds a padtemplate to an element class.
1161 * This is useful if you have derived a custom bin and wish to provide
1162 * an on-request pad at runtime. Plug-in writers should use
1163 * gst_element_factory_add_pad_template instead.
1166 gst_element_class_add_pad_template (GstElementClass *klass,
1167 GstPadTemplate *templ)
1169 g_return_if_fail (klass != NULL);
1170 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1171 g_return_if_fail (templ != NULL);
1172 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1174 klass->padtemplates = g_list_append (klass->padtemplates, templ);
1175 klass->numpadtemplates++;
1179 * gst_element_get_pad_template_list:
1180 * @element: a #GstElement to get pad templates of.
1182 * Retrieves a list of the pad templates associated with the element.
1184 * Returns: the #GList of padtemplates.
1187 gst_element_get_pad_template_list (GstElement *element)
1189 g_return_val_if_fail (element != NULL, NULL);
1190 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1192 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1196 * gst_element_get_pad_template:
1197 * @element: a #GstElement to get the pad template of.
1198 * @name: the name of the #GstPadTemplate to get.
1200 * Retrieves a padtemplate from this element with the
1203 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1204 * No unreferencing is necessary.
1207 gst_element_get_pad_template (GstElement *element, const gchar *name)
1211 g_return_val_if_fail (element != NULL, NULL);
1212 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1213 g_return_val_if_fail (name != NULL, NULL);
1215 padlist = gst_element_get_pad_template_list (element);
1218 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1220 if (!strcmp (padtempl->name_template, name))
1223 padlist = g_list_next (padlist);
1230 * gst_element_get_compatible_pad_template:
1231 * @element: a #GstElement to get a compatible pad template for.
1232 * @compattempl: the #GstPadTemplate to find a compatible template for.
1234 * Generates a pad template for this element compatible with the given
1235 * template (meaning it is able to link with it).
1237 * Returns: the #GstPadTemplate of the element that is compatible with
1238 * the given GstPadTemplate, or NULL if none was found. No unreferencing
1242 gst_element_get_compatible_pad_template (GstElement *element,
1243 GstPadTemplate *compattempl)
1245 GstPadTemplate *newtempl = NULL;
1248 GST_DEBUG (GST_CAT_ELEMENT_PADS, "gst_element_get_compatible_pad_template()");
1250 g_return_val_if_fail (element != NULL, NULL);
1251 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1252 g_return_val_if_fail (compattempl != NULL, NULL);
1254 padlist = gst_element_get_pad_template_list (element);
1257 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1258 gboolean comp = FALSE;
1262 * Check direction (must be opposite)
1265 GST_DEBUG (GST_CAT_CAPS, "checking direction and caps");
1266 if (padtempl->direction == GST_PAD_SRC &&
1267 compattempl->direction == GST_PAD_SINK) {
1268 GST_DEBUG (GST_CAT_CAPS, "compatible direction: found src pad template");
1269 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (padtempl),
1270 GST_PAD_TEMPLATE_CAPS (compattempl));
1271 GST_DEBUG(GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1272 } else if (padtempl->direction == GST_PAD_SINK &&
1273 compattempl->direction == GST_PAD_SRC) {
1274 GST_DEBUG (GST_CAT_CAPS, "compatible direction: found sink pad template");
1275 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1276 GST_PAD_TEMPLATE_CAPS (padtempl));
1277 GST_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1281 newtempl = padtempl;
1285 padlist = g_list_next (padlist);
1292 * gst_element_request_compatible_pad:
1293 * @element: a #GstElement to request a new pad from.
1294 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1296 * Requests a new pad from the element. The template will
1297 * be used to decide what type of pad to create. This function
1298 * is typically used for elements with a padtemplate with presence
1301 * Returns: the new #GstPad that was created, or NULL if none could be created.
1304 gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
1306 GstPadTemplate *templ_new;
1309 g_return_val_if_fail (element != NULL, NULL);
1310 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1311 g_return_val_if_fail (templ != NULL, NULL);
1313 templ_new = gst_element_get_compatible_pad_template (element, templ);
1314 if (templ_new != NULL)
1315 pad = gst_element_request_pad (element, templ_new, NULL);
1322 * gst_element_get_compatible_pad_filtered:
1323 * @element: a #GstElement in which the pad should be found.
1324 * @pad: the #GstPad to find a compatible one for.
1325 * @filtercaps: the #GstCaps to use as a filter.
1327 * Looks for an unlinked pad to which the given pad can link to.
1328 * It is not guaranteed that linking the pads will work, though
1329 * it should work in most cases.
1331 * Returns: the #GstPad to which a link can be made.
1334 gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
1335 GstCaps *filtercaps)
1338 GstPadTemplate *templ;
1340 GstPad *foundpad = NULL;
1343 g_return_val_if_fail (element != NULL, NULL);
1344 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1345 g_return_val_if_fail (pad != NULL, NULL);
1346 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1348 /* let's use the real pad */
1349 pad = (GstPad *) GST_PAD_REALIZE (pad);
1350 g_return_val_if_fail (pad != NULL, NULL);
1351 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1353 /* try to get an existing unlinked pad */
1354 pads = gst_element_get_pad_list (element);
1356 GstPad *current = GST_PAD (pads->data);
1357 if ((GST_PAD_PEER (GST_PAD_REALIZE (current)) == NULL) &&
1358 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1361 pads = g_list_next (pads);
1364 /* try to create a new one */
1365 /* requesting is a little crazy, we need a template. Let's create one */
1366 if (filtercaps != NULL) {
1367 templcaps = gst_caps_intersect (filtercaps, (GstCaps *) GST_RPAD_CAPS (pad));
1368 if (templcaps == NULL)
1371 templcaps = gst_pad_get_caps (pad);
1374 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1375 GST_PAD_ALWAYS, templcaps, NULL);
1376 foundpad = gst_element_request_compatible_pad (element, templ);
1377 gst_object_unref (GST_OBJECT (templ)); /* this will take care of the caps too */
1379 /* FIXME: this is broken, but it's in here so autoplugging elements that don't
1380 have caps on their source padtemplates (spider) can link... */
1381 if (!foundpad && !filtercaps) {
1382 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1383 GST_PAD_ALWAYS, NULL, NULL);
1384 foundpad = gst_element_request_compatible_pad (element, templ);
1385 gst_object_unref (GST_OBJECT (templ));
1392 * gst_element_get_compatible_pad:
1393 * @element: a #GstElement in which the pad should be found.
1394 * @pad: the #GstPad to find a compatible one for.
1396 * Looks for an unlinked pad to which the given pad can link to.
1397 * It is not guaranteed that linking the pads will work, though
1398 * it should work in most cases.
1400 * Returns: the #GstPad to which a link can be made, or NULL if none
1404 gst_element_get_compatible_pad (GstElement *element, GstPad *pad)
1406 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1410 * gst_element_link_pads_filtered:
1411 * @src: a #GstElement containing the source pad.
1412 * @srcpadname: the name of the #GstPad in source element or NULL for any element.
1413 * @dest: the #GstElement containing the destination pad.
1414 * @destpadname: the name of the #GstPad in destination element or NULL for any element.
1415 * @filtercaps: the #GstCaps to use as a filter.
1417 * Links the two named pads of the source and destination elements.
1418 * Side effect is that if one of the pads has no parent, it becomes a
1419 * child of the parent of the other element. If they have different
1420 * parents, the link fails.
1422 * Returns: TRUE if the pads could be linked.
1425 gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
1426 GstElement *dest, const gchar *destpadname,
1427 GstCaps *filtercaps)
1429 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1430 GstPad *srcpad, *destpad;
1431 GstPadTemplate *srctempl, *desttempl;
1434 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1435 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1437 GST_INFO (GST_CAT_ELEMENT_PADS, "trying to link element %s:%s to element %s:%s",
1438 GST_ELEMENT_NAME (src), srcpadname ? srcpadname : "(any)",
1439 GST_ELEMENT_NAME (dest), destpadname ? destpadname : "(any)");
1441 /* now get the pads we're trying to link and a list of all remaining pads */
1443 srcpad = gst_element_get_pad (src, srcpadname);
1445 GST_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (src), srcpadname);
1448 if (!(GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1449 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad", GST_DEBUG_PAD_NAME (srcpad));
1452 if (GST_PAD_PEER (srcpad) != NULL) {
1453 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (srcpad));
1459 srcpads = gst_element_get_pad_list (src);
1460 srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
1463 destpad = gst_element_get_pad (dest, destpadname);
1465 GST_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (dest), destpadname);
1468 if (!(GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1469 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad", GST_DEBUG_PAD_NAME (destpad));
1472 if (GST_PAD_PEER (destpad) != NULL) {
1473 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (destpad));
1479 destpads = gst_element_get_pad_list (dest);
1480 destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
1483 if (srcpadname && destpadname) {
1484 /* two explicitly specified pads */
1485 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1488 /* loop through the allowed pads in the source, trying to find a
1489 * compatible destination pad */
1490 GST_DEBUG (GST_CAT_ELEMENT_PADS, "looping through allowed src and dest pads");
1492 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1493 GST_DEBUG_PAD_NAME (srcpad));
1494 if ((GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1495 (GST_PAD_PEER (srcpad) == NULL)) {
1496 GstPad *temp = gst_element_get_compatible_pad_filtered (dest, srcpad,
1498 if (temp && gst_pad_link_filtered (srcpad, temp, filtercaps)) {
1499 GST_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1500 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1504 /* find a better way for this mess */
1506 srcpads = g_list_next (srcpads);
1508 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1513 GST_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1514 GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1518 /* loop through the existing pads in the destination */
1520 GST_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1521 GST_DEBUG_PAD_NAME (destpad));
1522 if ((GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1523 (GST_PAD_PEER (destpad) == NULL)) {
1524 GstPad *temp = gst_element_get_compatible_pad_filtered (src, destpad,
1526 if (temp && gst_pad_link_filtered (temp, destpad, filtercaps)) {
1527 GST_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1528 GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1533 destpads = g_list_next (destpads);
1535 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1540 GST_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1541 GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1545 GST_DEBUG (GST_CAT_ELEMENT_PADS,
1546 "we might have request pads on both sides, checking...");
1547 srctempls = gst_element_get_pad_template_list (src);
1548 desttempls = gst_element_get_pad_template_list (dest);
1550 if (srctempls && desttempls) {
1552 srctempl = (GstPadTemplate*) srctempls->data;
1553 if (srctempl->presence == GST_PAD_REQUEST) {
1554 for (l=desttempls; l; l=l->next) {
1555 desttempl = (GstPadTemplate*) desttempls->data;
1556 if (desttempl->presence == GST_PAD_REQUEST &&
1557 desttempl->direction != srctempl->direction) {
1558 if (gst_caps_is_always_compatible (gst_pad_template_get_caps (srctempl),
1559 gst_pad_template_get_caps (desttempl))) {
1560 srcpad = gst_element_get_request_pad (src,
1561 srctempl->name_template);
1562 destpad = gst_element_get_request_pad (dest,
1563 desttempl->name_template);
1564 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1565 GST_DEBUG (GST_CAT_ELEMENT_PADS,
1566 "linked pad %s:%s to pad %s:%s",
1567 GST_DEBUG_PAD_NAME (srcpad),
1568 GST_DEBUG_PAD_NAME (destpad));
1571 /* FIXME: we have extraneous request pads lying around */
1576 srctempls = srctempls->next;
1580 GST_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1581 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1585 * gst_element_link_filtered:
1586 * @src: a #GstElement containing the source pad.
1587 * @dest: the #GstElement containing the destination pad.
1588 * @filtercaps: the #GstCaps to use as a filter.
1590 * Links the source to the destination element using the filtercaps.
1591 * The link must be from source to destination, the other
1592 * direction will not be tried.
1593 * The functions looks for existing pads that aren't linked yet.
1594 * It will use request pads if possible. But both pads will not be requested.
1595 * If multiple links are possible, only one is established.
1597 * Returns: TRUE if the elements could be linked.
1600 gst_element_link_filtered (GstElement *src, GstElement *dest,
1601 GstCaps *filtercaps)
1603 return gst_element_link_pads_filtered (src, NULL, dest, NULL, filtercaps);
1607 * gst_element_link_many:
1608 * @element_1: the first #GstElement in the link chain.
1609 * @element_2: the second #GstElement in the link chain.
1610 * @...: the NULL-terminated list of elements to link in order.
1612 * Chain together a series of elements. Uses #gst_element_link.
1614 * Returns: TRUE on success, FALSE otherwise.
1617 gst_element_link_many (GstElement *element_1, GstElement *element_2, ...)
1621 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1622 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1623 GST_IS_ELEMENT (element_2), FALSE);
1625 va_start (args, element_2);
1628 if (!gst_element_link (element_1, element_2))
1631 element_1 = element_2;
1632 element_2 = va_arg (args, GstElement*);
1642 * @src: a #GstElement containing the source pad.
1643 * @dest: the #GstElement containing the destination pad.
1645 * Links the source to the destination element.
1646 * The link must be from source to destination, the other
1647 * direction will not be tried.
1648 * The functions looks for existing pads and request pads that aren't
1649 * linked yet. If multiple links are possible, only one is
1652 * Returns: TRUE if the elements could be linked.
1655 gst_element_link (GstElement *src, GstElement *dest)
1657 return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1661 * gst_element_link_pads:
1662 * @src: a #GstElement containing the source pad.
1663 * @srcpadname: the name of the #GstPad in the source element.
1664 * @dest: the #GstElement containing the destination pad.
1665 * @destpadname: the name of the #GstPad in destination element.
1667 * Links the two named pads of the source and destination elements.
1668 * Side effect is that if one of the pads has no parent, it becomes a
1669 * child of the parent of the other element. If they have different
1670 * parents, the link fails.
1672 * Returns: TRUE if the pads could be linked.
1675 gst_element_link_pads (GstElement *src, const gchar *srcpadname,
1676 GstElement *dest, const gchar *destpadname)
1678 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname, NULL);
1682 * gst_element_unlink_pads:
1683 * @src: a #GstElement containing the source pad.
1684 * @srcpadname: the name of the #GstPad in source element.
1685 * @dest: a #GstElement containing the destination pad.
1686 * @destpadname: the name of the #GstPad in destination element.
1688 * Unlinks the two named pads of the source and destination elements.
1691 gst_element_unlink_pads (GstElement *src, const gchar *srcpadname,
1692 GstElement *dest, const gchar *destpadname)
1694 GstPad *srcpad,*destpad;
1696 g_return_if_fail (src != NULL);
1697 g_return_if_fail (GST_IS_ELEMENT(src));
1698 g_return_if_fail (srcpadname != NULL);
1699 g_return_if_fail (dest != NULL);
1700 g_return_if_fail (GST_IS_ELEMENT(dest));
1701 g_return_if_fail (destpadname != NULL);
1703 /* obtain the pads requested */
1704 srcpad = gst_element_get_pad (src, srcpadname);
1705 if (srcpad == NULL) {
1706 GST_ERROR(src,"source element has no pad \"%s\"",srcpadname);
1709 destpad = gst_element_get_pad (dest, destpadname);
1710 if (srcpad == NULL) {
1711 GST_ERROR(dest,"destination element has no pad \"%s\"",destpadname);
1715 /* we're satisified they can be unlinked, let's do it */
1716 gst_pad_unlink (srcpad,destpad);
1720 * gst_element_unlink_many:
1721 * @element_1: the first #GstElement in the link chain.
1722 * @element_2: the second #GstElement in the link chain.
1723 * @...: the NULL-terminated list of elements to unlink in order.
1725 * Unlinks a series of elements. Uses #gst_element_unlink.
1728 gst_element_unlink_many (GstElement *element_1, GstElement *element_2, ...)
1732 g_return_if_fail (element_1 != NULL && element_2 != NULL);
1733 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
1735 va_start (args, element_2);
1738 gst_element_unlink (element_1, element_2);
1740 element_1 = element_2;
1741 element_2 = va_arg (args, GstElement*);
1748 * gst_element_unlink:
1749 * @src: the source #GstElement to unlink.
1750 * @dest: the sink #GstElement to unlink.
1752 * Unlinks all source pads of the source element with all sink pads
1753 * of the sink element to which they are linked.
1756 gst_element_unlink (GstElement *src, GstElement *dest)
1758 const GList *srcpads;
1761 g_return_if_fail (GST_IS_ELEMENT (src));
1762 g_return_if_fail (GST_IS_ELEMENT (dest));
1764 GST_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
1765 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1767 srcpads = gst_element_get_pad_list (src);
1770 pad = GST_PAD_CAST (srcpads->data);
1772 /* we only care about real src pads */
1773 if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
1774 GstPad *peerpad = GST_PAD_PEER (pad);
1776 /* see if the pad is connected and is really a pad
1779 (GST_OBJECT_PARENT (peerpad) == (GstObject*) dest))
1781 gst_pad_unlink (pad, peerpad);
1785 srcpads = g_list_next (srcpads);
1790 gst_element_error_func (GstElement* element, GstElement *source,
1793 /* tell the parent */
1794 if (GST_OBJECT_PARENT (element)) {
1795 GST_DEBUG (GST_CAT_EVENT, "forwarding error \"%s\" from %s to %s",
1796 errormsg, GST_ELEMENT_NAME (element),
1797 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
1799 gst_object_ref (GST_OBJECT (element));
1800 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
1801 gst_element_signals[ERROR], 0, source, errormsg);
1802 gst_object_unref (GST_OBJECT (element));
1807 gst_element_get_random_pad (GstElement *element, GstPadDirection dir)
1809 GList *pads = element->pads;
1810 GST_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1812 GstPad *pad = GST_PAD_CAST (pads->data);
1814 GST_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1815 GST_DEBUG_PAD_NAME (pad));
1817 if (GST_PAD_DIRECTION (pad) == dir) {
1818 if (GST_PAD_IS_LINKED (pad)) {
1822 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1823 GST_DEBUG_PAD_NAME (pad));
1827 GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
1828 GST_DEBUG_PAD_NAME (pad));
1831 pads = g_list_next (pads);
1837 * gst_element_get_event_masks:
1838 * @element: a #GstElement to query
1840 * Get an array of event masks from the element.
1841 * If the element doesn't
1842 * implement an event masks function, the query will be forwarded
1843 * to a random linked sink pad.
1845 * Returns: An array of #GstEventMask elements.
1848 gst_element_get_event_masks (GstElement *element)
1850 GstElementClass *oclass;
1852 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1854 oclass = GST_ELEMENT_GET_CLASS (element);
1856 if (oclass->get_event_masks)
1857 return oclass->get_event_masks (element);
1859 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1861 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
1868 * gst_element_send_event:
1869 * @element: a #GstElement to send the event to.
1870 * @event: the #GstEvent to send to the element.
1872 * Sends an event to an element. If the element doesn't
1873 * implement an event handler, the event will be forwarded
1874 * to a random sink pad.
1876 * Returns: TRUE if the event was handled.
1879 gst_element_send_event (GstElement *element, GstEvent *event)
1881 GstElementClass *oclass;
1883 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1884 g_return_val_if_fail (event != NULL, FALSE);
1886 oclass = GST_ELEMENT_GET_CLASS (element);
1888 if (oclass->send_event)
1889 return oclass->send_event (element, event);
1891 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1893 GST_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
1894 GST_DEBUG_PAD_NAME (pad));
1895 return gst_pad_send_event (GST_PAD_PEER (pad), event);
1898 GST_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1899 GST_ELEMENT_NAME (element));
1904 * gst_element_get_query_types:
1905 * @element: a #GstElement to query
1907 * Get an array of query types from the element.
1908 * If the element doesn't
1909 * implement a query types function, the query will be forwarded
1910 * to a random sink pad.
1912 * Returns: An array of #GstQueryType elements.
1915 gst_element_get_query_types (GstElement *element)
1917 GstElementClass *oclass;
1919 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1921 oclass = GST_ELEMENT_GET_CLASS (element);
1923 if (oclass->get_query_types)
1924 return oclass->get_query_types (element);
1926 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1928 return gst_pad_get_query_types (GST_PAD_PEER (pad));
1935 * gst_element_query:
1936 * @element: a #GstElement to perform the query on.
1937 * @type: the #GstQueryType.
1938 * @format: the #GstFormat pointer to hold the format of the result.
1939 * @value: the pointer to the value of the result.
1941 * Performs a query on the given element. If the format is set
1942 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1943 * format pointer will hold the default format.
1944 * For element that don't implement a query handler, this function
1945 * forwards the query to a random usable sinkpad of this element.
1947 * Returns: TRUE if the query could be performed.
1950 gst_element_query (GstElement *element, GstQueryType type,
1951 GstFormat *format, gint64 *value)
1953 GstElementClass *oclass;
1955 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1956 g_return_val_if_fail (format != NULL, FALSE);
1957 g_return_val_if_fail (value != NULL, FALSE);
1959 oclass = GST_ELEMENT_GET_CLASS (element);
1962 return oclass->query (element, type, format, value);
1964 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1966 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
1973 * gst_element_get_formats:
1974 * @element: a #GstElement to query
1976 * Get an array of formst from the element.
1977 * If the element doesn't
1978 * implement a formats function, the query will be forwarded
1979 * to a random sink pad.
1981 * Returns: An array of #GstFormat elements.
1984 gst_element_get_formats (GstElement *element)
1986 GstElementClass *oclass;
1988 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1990 oclass = GST_ELEMENT_GET_CLASS (element);
1992 if (oclass->get_formats)
1993 return oclass->get_formats (element);
1995 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1997 return gst_pad_get_formats (GST_PAD_PEER (pad));
2004 * gst_element_convert:
2005 * @element: a #GstElement to invoke the converter on.
2006 * @src_format: the source #GstFormat.
2007 * @src_value: the source value.
2008 * @dest_format: a pointer to the destination #GstFormat.
2009 * @dest_value: a pointer to the destination value.
2011 * Invokes a conversion on the element.
2012 * If the element doesn't
2013 * implement a convert function, the query will be forwarded
2014 * to a random sink pad.
2016 * Returns: TRUE if the conversion could be performed.
2019 gst_element_convert (GstElement *element,
2020 GstFormat src_format, gint64 src_value,
2021 GstFormat *dest_format, gint64 *dest_value)
2023 GstElementClass *oclass;
2025 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2026 g_return_val_if_fail (dest_format != NULL, FALSE);
2027 g_return_val_if_fail (dest_value != NULL, FALSE);
2029 if (src_format == *dest_format) {
2030 *dest_value = src_value;
2034 oclass = GST_ELEMENT_GET_CLASS (element);
2036 if (oclass->convert)
2037 return oclass->convert (element,
2038 src_format, src_value,
2039 dest_format, dest_value);
2041 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2043 return gst_pad_convert (GST_PAD_PEER (pad),
2044 src_format, src_value,
2045 dest_format, dest_value);
2052 * gst_element_error:
2053 * @element: a #GstElement with the error.
2054 * @error: the printf-style string describing the error.
2055 * @...: the optional arguments for the string.
2057 * signals an error condition on an element.
2058 * This function is used internally by elements.
2059 * It results in the "error" signal.
2062 gst_element_error (GstElement *element, const gchar *error, ...)
2068 g_return_if_fail (GST_IS_ELEMENT (element));
2069 g_return_if_fail (error != NULL);
2071 /* create error message */
2072 va_start (var_args, error);
2073 string = g_strdup_vprintf (error, var_args);
2075 GST_INFO (GST_CAT_EVENT, "ERROR in %s: %s", GST_ELEMENT_NAME (element), string);
2077 /* emit the signal, make sure the element stays available */
2078 gst_object_ref (GST_OBJECT (element));
2079 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element, string);
2081 /* tell the scheduler */
2082 if (element->sched) {
2083 gst_scheduler_error (element->sched, element);
2086 if (GST_STATE (element) == GST_STATE_PLAYING)
2087 gst_element_set_state (element, GST_STATE_PAUSED);
2090 gst_object_unref (GST_OBJECT (element));
2095 * gst_element_is_locked_state:
2096 * @element: a #GstElement.
2098 * Checks if the state of an element is locked.
2099 * If the state of an element is locked, state changes of the parent don't
2100 * affect the element.
2101 * This way you can leave currently unused elements inside bins. Just lock their
2102 * state before changing the state from #GST_STATE_NULL.
2104 * Returns: TRUE, if the element's state is locked.
2107 gst_element_is_locked_state (GstElement *element)
2109 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2111 return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
2114 * gst_element_set_locked_state:
2115 * @element: a #GstElement
2116 * @locked_state: TRUE to lock the element's state
2118 * Locks the state of an element, so state changes of the parent don't affect
2119 * this element anymore.
2122 gst_element_set_locked_state (GstElement *element, gboolean locked_state)
2126 g_return_if_fail (GST_IS_ELEMENT (element));
2128 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2130 if (old == locked_state)
2134 GST_DEBUG (GST_CAT_STATES, "locking state of element %s\n",
2135 GST_ELEMENT_NAME (element));
2136 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2138 GST_DEBUG (GST_CAT_STATES, "unlocking state of element %s\n",
2139 GST_ELEMENT_NAME (element));
2140 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2144 * gst_element_sync_state_with_parent:
2145 * @element: a #GstElement.
2147 * Tries to change the state of the element to the same as its parent.
2148 * If this function returns FALSE, the state of element is undefined.
2150 * Returns: TRUE, if the element's state could be synced to the parent's state.
2153 gst_element_sync_state_with_parent (GstElement *element)
2157 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2158 parent = GST_ELEMENT (GST_ELEMENT_PARENT(element));
2159 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
2161 GST_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
2162 GST_ELEMENT_NAME (element), gst_element_state_get_name (GST_STATE (element)),
2163 GST_ELEMENT_NAME (parent), gst_element_state_get_name (GST_STATE (parent)));
2164 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
2170 * gst_element_get_state:
2171 * @element: a #GstElement to get the state of.
2173 * Gets the state of the element.
2175 * Returns: the #GstElementState of the element.
2178 gst_element_get_state (GstElement *element)
2180 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2182 return GST_STATE (element);
2186 * gst_element_wait_state_change:
2187 * @element: a #GstElement to wait for a state change on.
2189 * Waits and blocks until the element changed its state.
2192 gst_element_wait_state_change (GstElement *element)
2194 g_mutex_lock (element->state_mutex);
2195 g_cond_wait (element->state_cond, element->state_mutex);
2196 g_mutex_unlock (element->state_mutex);
2200 * gst_element_set_state:
2201 * @element: a #GstElement to change state of.
2202 * @state: the element's new #GstElementState.
2204 * Sets the state of the element. This function will try to set the
2205 * requested state by going through all the intermediary states and calling
2206 * the class's state change function for each.
2208 * Returns: TRUE if the state was successfully set.
2209 * (using #GstElementStateReturn).
2211 GstElementStateReturn
2212 gst_element_set_state (GstElement *element, GstElementState state)
2214 GstElementClass *oclass;
2215 GstElementState curpending;
2216 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2218 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2220 /* start with the current state */
2221 curpending = GST_STATE(element);
2223 GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "setting state from %s to %s",
2224 gst_element_state_get_name (curpending),
2225 gst_element_state_get_name (state));
2227 /* loop until the final requested state is set */
2228 while (GST_STATE (element) != state
2229 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2230 /* move the curpending state in the correct direction */
2231 if (curpending < state)
2236 /* set the pending state variable */
2237 /* FIXME: should probably check to see that we don't already have one */
2238 GST_STATE_PENDING (element) = curpending;
2240 if (curpending != state) {
2241 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2242 "intermediate: setting state from %s to %s",
2243 gst_element_state_get_name (GST_STATE (element)),
2244 gst_element_state_get_name (curpending));
2247 /* call the state change function so it can set the state */
2248 oclass = GST_ELEMENT_GET_CLASS (element);
2249 if (oclass->change_state)
2250 return_val = (oclass->change_state) (element);
2252 switch (return_val) {
2253 case GST_STATE_FAILURE:
2254 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2255 "have failed change_state return");
2257 case GST_STATE_ASYNC:
2258 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2259 "element will change state async");
2261 case GST_STATE_SUCCESS:
2262 /* Last thing we do is verify that a successful state change really
2263 * did change the state... */
2264 /* if it did not, this is an error - fix the element that does this */
2265 if (GST_STATE (element) != curpending) {
2266 g_warning ("element %s claimed state-change success,"
2267 "but state didn't change %s, %s <-> %s, fix the element",
2268 GST_ELEMENT_NAME (element),
2269 gst_element_state_get_name (GST_STATE (element)),
2270 gst_element_state_get_name (GST_STATE_PENDING (element)),
2271 gst_element_state_get_name (curpending));
2272 return GST_STATE_FAILURE;
2276 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2277 g_assert_not_reached ();
2286 gst_element_negotiate_pads (GstElement *element)
2288 GList *pads = GST_ELEMENT_PADS (element);
2290 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "negotiating pads");
2293 GstPad *pad = GST_PAD (pads->data);
2296 pads = g_list_next (pads);
2298 if (!GST_IS_REAL_PAD (pad))
2301 srcpad = GST_PAD_REALIZE (pad);
2303 /* if we have a link on this pad and it doesn't have caps
2304 * allready, try to negotiate */
2305 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2306 GstRealPad *sinkpad;
2307 GstElementState otherstate;
2310 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2312 /* check the parent of the peer pad, if there is no parent do nothing */
2313 parent = GST_PAD_PARENT (sinkpad);
2317 /* skips pads that were already negotiating */
2318 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2319 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2322 otherstate = GST_STATE (parent);
2324 /* swap pads if needed */
2325 if (!GST_PAD_IS_SRC (srcpad)) {
2333 /* only try to negotiate if the peer element is in PAUSED or higher too */
2334 if (otherstate >= GST_STATE_READY) {
2335 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element,
2336 "perform negotiate for %s:%s and %s:%s",
2337 GST_DEBUG_PAD_NAME (srcpad),
2338 GST_DEBUG_PAD_NAME (sinkpad));
2339 if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad)))
2343 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element,
2344 "not negotiating %s:%s and %s:%s, not in READY yet",
2345 GST_DEBUG_PAD_NAME (srcpad),
2346 GST_DEBUG_PAD_NAME (sinkpad));
2355 gst_element_clear_pad_caps (GstElement *element)
2357 GList *pads = GST_ELEMENT_PADS (element);
2359 GST_DEBUG_ELEMENT (GST_CAT_CAPS, element, "clearing pad caps");
2362 GstRealPad *pad = GST_PAD_REALIZE (pads->data);
2364 gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
2366 pads = g_list_next (pads);
2371 gst_element_pads_activate (GstElement *element, gboolean active)
2373 GList *pads = element->pads;
2376 GstPad *pad = GST_PAD_CAST (pads->data);
2377 pads = g_list_next (pads);
2379 if (!GST_IS_REAL_PAD (pad))
2382 gst_pad_set_active (pad, active);
2386 static GstElementStateReturn
2387 gst_element_change_state (GstElement *element)
2389 GstElementState old_state;
2391 gint old_pending, old_transition;
2393 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2395 old_state = GST_STATE (element);
2396 old_pending = GST_STATE_PENDING (element);
2397 old_transition = GST_STATE_TRANSITION (element);
2399 if (old_pending == GST_STATE_VOID_PENDING ||
2400 old_state == GST_STATE_PENDING (element)) {
2401 GST_INFO (GST_CAT_STATES,
2402 "no state change needed for element %s (VOID_PENDING)",
2403 GST_ELEMENT_NAME (element));
2404 return GST_STATE_SUCCESS;
2407 GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %04x",
2408 GST_ELEMENT_NAME (element),
2409 gst_element_state_get_name (old_state),
2410 gst_element_state_get_name (old_pending),
2413 /* we set the state change early for the negotiation functions */
2414 GST_STATE (element) = old_pending;
2415 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2417 switch (old_transition) {
2418 case GST_STATE_PLAYING_TO_PAUSED:
2419 gst_element_pads_activate (element, FALSE);
2421 case GST_STATE_PAUSED_TO_PLAYING:
2422 gst_element_pads_activate (element, TRUE);
2424 /* if we are going to paused, we try to negotiate the pads */
2425 case GST_STATE_READY_TO_PAUSED:
2426 if (!gst_element_negotiate_pads (element))
2429 /* going to the READY state clears all pad caps */
2430 case GST_STATE_PAUSED_TO_READY:
2431 gst_element_clear_pad_caps (element);
2437 parent = GST_ELEMENT_PARENT (element);
2439 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2440 "signaling state change from %s to %s",
2441 gst_element_state_get_name (old_state),
2442 gst_element_state_get_name (GST_STATE (element)));
2444 /* tell the scheduler if we have one */
2445 if (element->sched) {
2446 if (gst_scheduler_state_transition (element->sched, element,
2447 old_transition) != GST_STATE_SUCCESS) {
2448 GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
2449 "scheduler could change state");
2454 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2455 0, old_state, GST_STATE (element));
2457 /* tell our parent about the state change */
2458 if (parent && GST_IS_BIN (parent)) {
2459 gst_bin_child_state_change (GST_BIN (parent), old_state,
2460 GST_STATE (element), element);
2463 /* signal the state change in case somebody is waiting for us */
2464 g_mutex_lock (element->state_mutex);
2465 g_cond_signal (element->state_cond);
2466 g_mutex_unlock (element->state_mutex);
2468 return GST_STATE_SUCCESS;
2471 /* undo the state change */
2472 GST_STATE (element) = old_state;
2473 GST_STATE_PENDING (element) = old_pending;
2475 return GST_STATE_FAILURE;
2479 * gst_element_get_factory:
2480 * @element: a #GstElement to request the element factory of.
2482 * Retrieves the factory that was used to create this element.
2484 * Returns: the #GstElementFactory used for creating this element.
2487 gst_element_get_factory (GstElement *element)
2489 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2491 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2495 gst_element_dispose (GObject *object)
2497 GstElement *element = GST_ELEMENT (object);
2501 GST_DEBUG_ELEMENT (GST_CAT_REFCOUNTING, element, "dispose");
2503 gst_element_set_state (element, GST_STATE_NULL);
2505 /* first we break all our links with the ouside */
2506 if (element->pads) {
2508 orig = pads = g_list_copy (element->pads);
2510 pad = GST_PAD (pads->data);
2512 if (GST_PAD_PEER (pad)) {
2513 GST_DEBUG (GST_CAT_REFCOUNTING, "unlinking pad '%s'",
2514 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2515 gst_pad_unlink (pad, GST_PAD (GST_PAD_PEER (pad)));
2517 gst_element_remove_pad (element, pad);
2519 pads = g_list_next (pads);
2522 g_list_free (element->pads);
2523 element->pads = NULL;
2526 element->numsrcpads = 0;
2527 element->numsinkpads = 0;
2528 element->numpads = 0;
2529 g_mutex_free (element->state_mutex);
2530 g_cond_free (element->state_cond);
2532 if (element->prop_value_queue)
2533 g_async_queue_unref (element->prop_value_queue);
2534 element->prop_value_queue = NULL;
2535 if (element->property_mutex)
2536 g_mutex_free (element->property_mutex);
2538 gst_object_replace ((GstObject **)&element->sched, NULL);
2539 gst_object_replace ((GstObject **)&element->clock, NULL);
2541 G_OBJECT_CLASS (parent_class)->dispose (object);
2544 #ifndef GST_DISABLE_LOADSAVE
2546 * gst_element_save_thyself:
2547 * @element: a #GstElement to save.
2548 * @parent: the xml parent node.
2550 * Saves the element as part of the given XML structure.
2552 * Returns: the new #xmlNodePtr.
2555 gst_element_save_thyself (GstObject *object,
2559 GstElementClass *oclass;
2560 GParamSpec **specs, *spec;
2562 GValue value = { 0, };
2563 GstElement *element;
2565 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2567 element = GST_ELEMENT (object);
2569 oclass = GST_ELEMENT_GET_CLASS (element);
2571 xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element));
2573 if (oclass->elementfactory != NULL) {
2574 GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory;
2576 xmlNewChild (parent, NULL, "type", GST_OBJECT_NAME (factory));
2577 xmlNewChild (parent, NULL, "version", factory->details->version);
2580 /* FIXME: what is this? */
2581 /* if (element->manager) */
2582 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2585 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2587 for (i=0; i<nspecs; i++) {
2589 if (spec->flags & G_PARAM_READABLE) {
2593 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2595 g_object_get_property (G_OBJECT (element), spec->name, &value);
2596 param = xmlNewChild (parent, NULL, "param", NULL);
2597 xmlNewChild (param, NULL, "name", spec->name);
2599 if (G_IS_PARAM_SPEC_STRING (spec))
2600 contents = g_value_dup_string (&value);
2601 else if (G_IS_PARAM_SPEC_ENUM (spec))
2602 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2603 else if (G_IS_PARAM_SPEC_INT64 (spec))
2604 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2605 g_value_get_int64 (&value));
2607 contents = g_strdup_value_contents (&value);
2609 xmlNewChild (param, NULL, "value", contents);
2612 g_value_unset(&value);
2616 pads = GST_ELEMENT_PADS (element);
2619 GstPad *pad = GST_PAD (pads->data);
2620 /* figure out if it's a direct pad or a ghostpad */
2621 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2622 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
2623 gst_object_save_thyself (GST_OBJECT (pad), padtag);
2625 pads = g_list_next (pads);
2632 gst_element_restore_thyself (GstObject *object, xmlNodePtr self)
2634 xmlNodePtr children;
2635 GstElement *element;
2637 gchar *value = NULL;
2639 element = GST_ELEMENT (object);
2640 g_return_if_fail (element != NULL);
2643 children = self->xmlChildrenNode;
2645 if (!strcmp (children->name, "param")) {
2646 xmlNodePtr child = children->xmlChildrenNode;
2649 if (!strcmp (child->name, "name")) {
2650 name = xmlNodeGetContent (child);
2652 else if (!strcmp (child->name, "value")) {
2653 value = xmlNodeGetContent (child);
2655 child = child->next;
2657 /* FIXME: can this just be g_object_set ? */
2658 gst_util_set_object_arg (G_OBJECT (element), name, value);
2660 children = children->next;
2664 children = self->xmlChildrenNode;
2666 if (!strcmp (children->name, "pad")) {
2667 gst_pad_load_and_link (children, GST_OBJECT (element));
2669 children = children->next;
2672 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2673 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2675 #endif /* GST_DISABLE_LOADSAVE */
2678 * gst_element_yield:
2679 * @element: a #GstElement to yield.
2681 * Requests a yield operation for the element. The scheduler will typically
2682 * give control to another element.
2685 gst_element_yield (GstElement *element)
2687 if (GST_ELEMENT_SCHED (element)) {
2688 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
2693 * gst_element_interrupt:
2694 * @element: a #GstElement to interrupt.
2696 * Requests the scheduler of this element to interrupt the execution of
2697 * this element and scheduler another one.
2699 * Returns: TRUE if the element should exit its chain/loop/get
2700 * function ASAP, depending on the scheduler implementation.
2703 gst_element_interrupt (GstElement *element)
2705 if (GST_ELEMENT_SCHED (element)) {
2706 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
2713 * gst_element_set_scheduler:
2714 * @element: a #GstElement to set the scheduler of.
2715 * @sched: the #GstScheduler to set.
2717 * Sets the scheduler of the element. For internal use only, unless you're
2718 * writing a new bin subclass.
2721 gst_element_set_scheduler (GstElement *element,
2722 GstScheduler *sched)
2724 g_return_if_fail (GST_IS_ELEMENT (element));
2726 GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting scheduler to %p", sched);
2728 gst_object_replace ((GstObject **)&GST_ELEMENT_SCHED (element), GST_OBJECT (sched));
2732 * gst_element_get_scheduler:
2733 * @element: a #GstElement to get the scheduler of.
2735 * Returns the scheduler of the element.
2737 * Returns: the element's #GstScheduler.
2740 gst_element_get_scheduler (GstElement *element)
2742 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2744 return GST_ELEMENT_SCHED (element);
2748 * gst_element_set_loop_function:
2749 * @element: a #GstElement to set the loop function of.
2750 * @loop: Pointer to #GstElementLoopFunction.
2752 * This sets the loop function for the element. The function pointed to
2753 * can deviate from the GstElementLoopFunction definition in type of
2756 * NOTE: in order for this to take effect, the current loop function *must*
2757 * exit. Assuming the loop function itself is the only one who will cause
2758 * a new loopfunc to be assigned, this should be no problem.
2761 gst_element_set_loop_function (GstElement *element,
2762 GstElementLoopFunction loop)
2764 gboolean need_notify = FALSE;
2766 g_return_if_fail (GST_IS_ELEMENT (element));
2768 /* if the element changed from loop based to chain/get based
2769 * or vice versa, we need to inform the scheduler about that */
2770 if ((element->loopfunc == NULL && loop != NULL) ||
2771 (element->loopfunc != NULL && loop == NULL))
2776 /* set the loop function */
2777 element->loopfunc = loop;
2780 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
2781 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
2783 if (GST_ELEMENT_SCHED (element)) {
2784 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
2790 gst_element_set_eos_recursive (GstElement *element)
2792 /* this function is only called, when we were in PLAYING before. So every
2793 parent that's PAUSED was PLAYING before. That means it has reached EOS. */
2796 GST_DEBUG (GST_CAT_EVENT, "setting recursive EOS on %s",
2797 GST_OBJECT_NAME (element));
2798 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
2800 if (!GST_OBJECT_PARENT (element))
2803 parent = GST_ELEMENT (GST_OBJECT_PARENT (element));
2804 if (GST_STATE (parent) == GST_STATE_PAUSED)
2805 gst_element_set_eos_recursive (parent);
2808 * gst_element_set_eos:
2809 * @element: a #GstElement to set to the EOS state.
2811 * Perform the actions needed to bring the element in the EOS state.
2814 gst_element_set_eos (GstElement *element)
2816 g_return_if_fail (GST_IS_ELEMENT (element));
2818 GST_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
2819 GST_OBJECT_NAME (element));
2821 if (GST_STATE (element) == GST_STATE_PLAYING) {
2822 gst_element_set_state (element, GST_STATE_PAUSED);
2823 gst_element_set_eos_recursive (element);
2825 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
2831 * gst_element_state_get_name:
2832 * @state: a #GstElementState to get the name of.
2834 * Gets a string representing the given state.
2836 * Returns: a string with the name of the state.
2839 gst_element_state_get_name (GstElementState state)
2842 #ifdef GST_DEBUG_COLOR
2843 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2844 case GST_STATE_NULL: return "\033[01;37mNULL\033[00m";break;
2845 case GST_STATE_READY: return "\033[01;31mREADY\033[00m";break;
2846 case GST_STATE_PLAYING: return "\033[01;32mPLAYING\033[00m";break;
2847 case GST_STATE_PAUSED: return "\033[01;33mPAUSED\033[00m";break;
2849 /* This is a memory leak */
2850 return g_strdup_printf ("\033[01;37;41mUNKNOWN!\033[00m(%d)", state);
2852 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2853 case GST_STATE_NULL: return "NULL";break;
2854 case GST_STATE_READY: return "READY";break;
2855 case GST_STATE_PLAYING: return "PLAYING";break;
2856 case GST_STATE_PAUSED: return "PAUSED";break;
2857 default: return "UNKNOWN!";
2864 gst_element_populate_std_props (GObjectClass * klass, const gchar *prop_name,
2865 guint arg_id, GParamFlags flags)
2867 GQuark prop_id = g_quark_from_string (prop_name);
2870 static GQuark fd_id = 0;
2871 static GQuark blocksize_id;
2872 static GQuark bytesperread_id;
2873 static GQuark dump_id;
2874 static GQuark filesize_id;
2875 static GQuark mmapsize_id;
2876 static GQuark location_id;
2877 static GQuark offset_id;
2878 static GQuark silent_id;
2879 static GQuark touch_id;
2882 fd_id = g_quark_from_static_string ("fd");
2883 blocksize_id = g_quark_from_static_string ("blocksize");
2884 bytesperread_id = g_quark_from_static_string ("bytesperread");
2885 dump_id = g_quark_from_static_string ("dump");
2886 filesize_id = g_quark_from_static_string ("filesize");
2887 mmapsize_id = g_quark_from_static_string ("mmapsize");
2888 location_id = g_quark_from_static_string ("location");
2889 offset_id = g_quark_from_static_string ("offset");
2890 silent_id = g_quark_from_static_string ("silent");
2891 touch_id = g_quark_from_static_string ("touch");
2894 if (prop_id == fd_id) {
2895 pspec = g_param_spec_int ("fd", "File-descriptor",
2896 "File-descriptor for the file being read",
2897 0, G_MAXINT, 0, flags);
2899 else if (prop_id == blocksize_id) {
2900 pspec = g_param_spec_ulong ("blocksize", "Block Size",
2901 "Block size to read per buffer",
2902 0, G_MAXULONG, 4096, flags);
2905 else if (prop_id == bytesperread_id) {
2906 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
2907 "Number of bytes to read per buffer",
2908 G_MININT, G_MAXINT, 0, flags);
2911 else if (prop_id == dump_id) {
2912 pspec = g_param_spec_boolean ("dump", "Dump",
2913 "Dump bytes to stdout",
2917 else if (prop_id == filesize_id) {
2918 pspec = g_param_spec_int64 ("filesize", "File Size",
2919 "Size of the file being read",
2920 0, G_MAXINT64, 0, flags);
2923 else if (prop_id == mmapsize_id) {
2924 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
2925 "Size in bytes of mmap()d regions",
2926 0, G_MAXULONG, 4 * 1048576, flags);
2929 else if (prop_id == location_id) {
2930 pspec = g_param_spec_string ("location", "File Location",
2931 "Location of the file to read",
2935 else if (prop_id == offset_id) {
2936 pspec = g_param_spec_int64 ("offset", "File Offset",
2937 "Byte offset of current read pointer",
2938 0, G_MAXINT64, 0, flags);
2941 else if (prop_id == silent_id) {
2942 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
2946 else if (prop_id == touch_id) {
2947 pspec = g_param_spec_boolean ("touch", "Touch read data",
2948 "Touch data to force disk read before "
2949 "push ()", TRUE, flags);
2952 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
2953 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
2958 g_object_class_install_property (klass, arg_id, pspec);
2963 * gst_element_class_install_std_props:
2964 * @klass: the #GstElementClass to add the properties to.
2965 * @first_name: the name of the first property.
2966 * in a NULL terminated
2967 * @...: the id and flags of the first property, followed by
2968 * further 'name', 'id', 'flags' triplets and terminated by NULL.
2970 * Adds a list of standardized properties with types to the @klass.
2971 * the id is for the property switch in your get_prop method, and
2972 * the flags determine readability / writeability.
2975 gst_element_class_install_std_props (GstElementClass * klass,
2976 const gchar *first_name, ...)
2982 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
2984 va_start (args, first_name);
2989 int arg_id = va_arg (args, int);
2990 int flags = va_arg (args, int);
2992 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id, flags);
2994 name = va_arg (args, char *);
3001 * gst_element_get_managing_bin:
3002 * @element: a #GstElement to get the managing bin of.
3004 * Gets the managing bin (a pipeline or a thread, for example) of an element.
3006 * Returns: the #GstBin, or NULL on failure.
3009 gst_element_get_managing_bin (GstElement *element)
3013 g_return_val_if_fail (element != NULL, NULL);
3015 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (element)));
3017 while (bin && !GST_FLAG_IS_SET (GST_OBJECT_CAST (bin), GST_BIN_FLAG_MANAGER))
3018 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (bin)));