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.
25 #include <gobject/gvaluecollector.h>
26 #include "gst_private.h"
28 #include "gstelement.h"
30 #include "gstscheduler.h"
35 /* Element signals and args */
50 extern void __gst_element_details_clear (GstElementDetails *dp);
51 extern void __gst_element_details_set (GstElementDetails *dest,
52 const GstElementDetails *src);
54 static void gst_element_class_init (GstElementClass *klass);
55 static void gst_element_init (GstElement *element);
56 static void gst_element_base_class_init (gpointer g_class);
57 static void gst_element_base_class_finalize (gpointer g_class);
59 static void gst_element_real_set_property (GObject *object, guint prop_id,
60 const GValue *value, GParamSpec *pspec);
61 static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value,
64 static void gst_element_dispose (GObject *object);
66 static GstElementStateReturn gst_element_change_state (GstElement *element);
67 static void gst_element_error_func (GstElement* element, GstElement *source, gchar *errormsg);
69 #ifndef GST_DISABLE_LOADSAVE
70 static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent);
71 static void gst_element_restore_thyself (GstObject *parent, xmlNodePtr self);
74 GType _gst_element_type = 0;
76 static GstObjectClass *parent_class = NULL;
77 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
79 GType gst_element_get_type (void)
81 if (!_gst_element_type) {
82 static const GTypeInfo element_info = {
83 sizeof(GstElementClass),
84 gst_element_base_class_init,
85 gst_element_base_class_finalize,
86 (GClassInitFunc)gst_element_class_init,
91 (GInstanceInitFunc)gst_element_init,
94 _gst_element_type = g_type_register_static(GST_TYPE_OBJECT, "GstElement",
95 &element_info, G_TYPE_FLAG_ABSTRACT);
97 return _gst_element_type;
101 gst_element_class_init (GstElementClass *klass)
103 GObjectClass *gobject_class;
104 GstObjectClass *gstobject_class;
106 gobject_class = (GObjectClass*) klass;
107 gstobject_class = (GstObjectClass*) klass;
109 parent_class = g_type_class_ref(GST_TYPE_OBJECT);
111 gst_element_signals[STATE_CHANGE] =
112 g_signal_new ("state_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
113 G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL,
114 gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
115 G_TYPE_INT, G_TYPE_INT);
116 gst_element_signals[NEW_PAD] =
117 g_signal_new ("new_pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
118 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
119 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
121 gst_element_signals[PAD_REMOVED] =
122 g_signal_new ("pad_removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
123 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
124 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
126 gst_element_signals[ERROR] =
127 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
128 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
129 gst_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
130 G_TYPE_OBJECT, G_TYPE_STRING);
131 gst_element_signals[EOS] =
132 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
133 G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
134 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
136 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property);
137 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_property);
139 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
141 #ifndef GST_DISABLE_LOADSAVE
142 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
143 gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
146 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
147 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
148 klass->padtemplates = NULL;
149 klass->numpadtemplates = 0;
151 klass->elementfactory = NULL;
155 gst_element_base_class_init (gpointer g_class)
157 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
159 gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_element_real_set_property);
160 gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_element_real_get_property);
164 gst_element_base_class_finalize (gpointer g_class)
166 GstElementClass *klass = GST_ELEMENT_CLASS (klass);
168 g_list_foreach (klass->padtemplates, (GFunc) g_object_unref, NULL);
169 g_list_free (klass->padtemplates);
170 __gst_element_details_clear (&klass->details);
174 gst_element_init (GstElement *element)
176 element->current_state = GST_STATE_NULL;
177 element->pending_state = GST_STATE_VOID_PENDING;
178 element->numpads = 0;
179 element->numsrcpads = 0;
180 element->numsinkpads = 0;
181 element->pads = NULL;
182 element->loopfunc = NULL;
183 element->sched = NULL;
184 element->clock = NULL;
185 element->sched_private = NULL;
186 element->state_mutex = g_mutex_new ();
187 element->state_cond = g_cond_new ();
191 gst_element_real_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
193 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
195 if (oclass->set_property)
196 (oclass->set_property) (object, prop_id, value, pspec);
200 gst_element_real_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
202 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
204 if (oclass->get_property)
205 (oclass->get_property) (object, prop_id, value, pspec);
209 * gst_element_default_error:
210 * @object: a #GObject that signalled the error.
211 * @orig: the #GstObject that initiated the error.
212 * @error: the error message.
214 * Adds a default error signal callback to an
215 * element. The user data passed to the g_signal_connect is
217 * The default handler will simply print the error string
221 gst_element_default_error (GObject *object, GstObject *orig, gchar *error)
223 gchar *name = gst_object_get_path_string (orig);
224 g_print ("ERROR: %s: %s\n", name, error);
229 const GParamSpec *pspec;
234 element_set_property (GstElement *element, const GParamSpec *pspec, const GValue *value)
236 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
238 prop_value->pspec = pspec;
239 prop_value->value = *value;
241 g_async_queue_push (element->prop_value_queue, prop_value);
245 element_get_property (GstElement *element, const GParamSpec *pspec, GValue *value)
247 g_mutex_lock (element->property_mutex);
248 g_object_get_property ((GObject*)element, pspec->name, value);
249 g_mutex_unlock (element->property_mutex);
253 gst_element_threadsafe_properties_pre_run (GstElement *element)
255 GST_CAT_DEBUG (GST_CAT_THREAD, "locking element %s", GST_OBJECT_NAME (element));
256 g_mutex_lock (element->property_mutex);
257 gst_element_set_pending_properties (element);
261 gst_element_threadsafe_properties_post_run (GstElement *element)
263 GST_CAT_DEBUG (GST_CAT_THREAD, "unlocking element %s", GST_OBJECT_NAME (element));
264 g_mutex_unlock (element->property_mutex);
268 * gst_element_enable_threadsafe_properties:
269 * @element: a #GstElement to enable threadsafe properties on.
271 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
272 * this element so that properties on the element can be set in a
276 gst_element_enable_threadsafe_properties (GstElement *element)
278 g_return_if_fail (GST_IS_ELEMENT (element));
280 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
281 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
282 element->post_run_func = gst_element_threadsafe_properties_post_run;
283 if (!element->prop_value_queue)
284 element->prop_value_queue = g_async_queue_new ();
285 if (!element->property_mutex)
286 element->property_mutex = g_mutex_new ();
290 * gst_element_disable_threadsafe_properties:
291 * @element: a #GstElement to disable threadsafe properties on.
293 * Removes the threadsafe properties, post- and pre-run locks from
297 gst_element_disable_threadsafe_properties (GstElement *element)
299 g_return_if_fail (GST_IS_ELEMENT (element));
301 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
302 element->pre_run_func = NULL;
303 element->post_run_func = NULL;
304 /* let's keep around that async queue */
308 * gst_element_set_pending_properties:
309 * @element: a #GstElement to set the pending properties on.
311 * Sets all pending properties on the threadsafe properties enabled
315 gst_element_set_pending_properties (GstElement *element)
317 prop_value_t *prop_value;
319 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
320 g_object_set_property ((GObject*)element, prop_value->pspec->name, &prop_value->value);
321 g_value_unset (&prop_value->value);
326 /* following 6 functions taken mostly from gobject.c */
330 * @element: a #GstElement to set properties on.
331 * @first_property_name: the first property to set.
332 * @...: value of the first property, and more properties to set, ending
335 * Sets properties on an element. If the element uses threadsafe properties,
336 * they will be queued and set on the object when it is scheduled again.
339 gst_element_set (GstElement *element, const gchar *first_property_name, ...)
343 g_return_if_fail (GST_IS_ELEMENT (element));
345 va_start (var_args, first_property_name);
346 gst_element_set_valist (element, first_property_name, var_args);
352 * @element: a #GstElement to get properties of.
353 * @first_property_name: the first property to get.
354 * @...: pointer to a variable to store the first property in, as well as
355 * more properties to get, ending with NULL.
357 * Gets properties from an element. If the element uses threadsafe properties,
358 * the element will be locked before getting the given properties.
361 gst_element_get (GstElement *element, const gchar *first_property_name, ...)
365 g_return_if_fail (GST_IS_ELEMENT (element));
367 va_start (var_args, first_property_name);
368 gst_element_get_valist (element, first_property_name, var_args);
373 * gst_element_set_valist:
374 * @element: a #GstElement to set properties on.
375 * @first_property_name: the first property to set.
376 * @var_args: the var_args list of other properties to get.
378 * Sets properties on an element. If the element uses threadsafe properties,
379 * the property change will be put on the async queue.
382 gst_element_set_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
387 g_return_if_fail (GST_IS_ELEMENT (element));
389 object = (GObject *) element;
391 GST_CAT_DEBUG (GST_CAT_PROPERTIES,
392 "setting valist of properties starting with %s on element %s",
393 first_property_name, gst_element_get_name (element));
395 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
396 g_object_set_valist (object, first_property_name, var_args);
400 g_object_ref (object);
402 name = first_property_name;
406 GValue value = { 0, };
410 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
414 g_warning ("%s: object class `%s' has no property named `%s'",
416 G_OBJECT_TYPE_NAME (object),
420 if (!(pspec->flags & G_PARAM_WRITABLE))
422 g_warning ("%s: property `%s' of object class `%s' is not writable",
425 G_OBJECT_TYPE_NAME (object));
429 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
431 G_VALUE_COLLECT (&value, var_args, 0, &error);
434 g_warning ("%s: %s", G_STRLOC, error);
437 /* we purposely leak the value here, it might not be
438 * in a sane state if an error condition occoured
443 element_set_property (element, pspec, &value);
444 g_value_unset (&value);
446 name = va_arg (var_args, gchar*);
449 g_object_unref (object);
453 * gst_element_get_valist:
454 * @element: a #GstElement to get properties of.
455 * @first_property_name: the first property to get.
456 * @var_args: the var_args list of other properties to get.
458 * Gets properties from an element. If the element uses threadsafe properties,
459 * the element will be locked before getting the given properties.
462 gst_element_get_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
467 g_return_if_fail (GST_IS_ELEMENT (element));
469 object = (GObject*)element;
471 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
472 g_object_get_valist (object, first_property_name, var_args);
476 g_object_ref (object);
478 name = first_property_name;
482 GValue value = { 0, };
486 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
490 g_warning ("%s: object class `%s' has no property named `%s'",
492 G_OBJECT_TYPE_NAME (object),
496 if (!(pspec->flags & G_PARAM_READABLE))
498 g_warning ("%s: property `%s' of object class `%s' is not readable",
501 G_OBJECT_TYPE_NAME (object));
505 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
507 element_get_property (element, pspec, &value);
509 G_VALUE_LCOPY (&value, var_args, 0, &error);
512 g_warning ("%s: %s", G_STRLOC, error);
514 g_value_unset (&value);
518 g_value_unset (&value);
520 name = va_arg (var_args, gchar*);
523 g_object_unref (object);
527 * gst_element_set_property:
528 * @element: a #GstElement to set properties on.
529 * @property_name: the first property to get.
530 * @value: the #GValue that holds the value to set.
532 * Sets a property on an element. If the element uses threadsafe properties,
533 * the property will be put on the async queue.
536 gst_element_set_property (GstElement *element, const gchar *property_name,
542 g_return_if_fail (GST_IS_ELEMENT (element));
543 g_return_if_fail (property_name != NULL);
544 g_return_if_fail (G_IS_VALUE (value));
546 object = (GObject*) element;
548 GST_CAT_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
549 property_name, gst_element_get_name (element));
550 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
551 g_object_set_property (object, property_name, value);
555 g_object_ref (object);
557 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
561 g_warning ("%s: object class `%s' has no property named `%s'",
563 G_OBJECT_TYPE_NAME (object),
566 element_set_property (element, pspec, value);
568 g_object_unref (object);
572 * gst_element_get_property:
573 * @element: a #GstElement to get properties of.
574 * @property_name: the first property to get.
575 * @value: the #GValue to store the property value in.
577 * Gets a property from an element. If the element uses threadsafe properties,
578 * the element will be locked before getting the given property.
581 gst_element_get_property (GstElement *element, const gchar *property_name, GValue *value)
586 g_return_if_fail (GST_IS_ELEMENT (element));
587 g_return_if_fail (property_name != NULL);
588 g_return_if_fail (G_IS_VALUE (value));
590 object = (GObject*)element;
592 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
593 g_object_get_property (object, property_name, value);
597 g_object_ref (object);
599 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
602 g_warning ("%s: object class `%s' has no property named `%s'",
604 G_OBJECT_TYPE_NAME (object),
608 GValue *prop_value, tmp_value = { 0, };
610 /* auto-conversion of the callers value type
612 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
614 g_value_reset (value);
617 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
619 g_warning ("can't retrieve property `%s' of type `%s' as value of type `%s'",
621 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
622 G_VALUE_TYPE_NAME (value));
623 g_object_unref (object);
628 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
629 prop_value = &tmp_value;
631 element_get_property (element, pspec, prop_value);
632 if (prop_value != value)
634 g_value_transform (prop_value, value);
635 g_value_unset (&tmp_value);
639 g_object_unref (object);
643 gst_element_request_pad (GstElement *element, GstPadTemplate *templ, const gchar* name)
645 GstPad *newpad = NULL;
646 GstElementClass *oclass;
648 oclass = GST_ELEMENT_GET_CLASS (element);
650 if (oclass->request_new_pad)
651 newpad = (oclass->request_new_pad)(element, templ, name);
657 * gst_element_release_request_pad:
658 * @element: a #GstElement to release the request pad of.
659 * @pad: the #GstPad to release.
661 * Makes the element free the previously requested pad as obtained
662 * with gst_element_get_request_pad().
665 gst_element_release_request_pad (GstElement *element, GstPad *pad)
667 GstElementClass *oclass;
669 g_return_if_fail (GST_IS_ELEMENT (element));
670 g_return_if_fail (GST_IS_PAD (pad));
672 oclass = GST_ELEMENT_GET_CLASS (element);
674 if (oclass->release_pad)
675 (oclass->release_pad) (element, pad);
679 * gst_element_requires_clock:
680 * @element: a #GstElement to query
682 * Query if the element requiresd a clock
684 * Returns: TRUE if the element requires a clock
687 gst_element_requires_clock (GstElement *element)
689 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
691 return (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
695 * gst_element_provides_clock:
696 * @element: a #GstElement to query
698 * Query if the element provides a clock
700 * Returns: TRUE if the element provides a clock
703 gst_element_provides_clock (GstElement *element)
705 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
707 return (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
711 * gst_element_set_clock:
712 * @element: a #GstElement to set the clock for.
713 * @clock: the #GstClock to set for the element.
715 * Sets the clock for the element.
718 gst_element_set_clock (GstElement *element, GstClock *clock)
720 GstElementClass *oclass;
722 g_return_if_fail (GST_IS_ELEMENT (element));
724 oclass = GST_ELEMENT_GET_CLASS (element);
726 if (oclass->set_clock)
727 oclass->set_clock (element, clock);
729 gst_object_replace ((GstObject **)&element->clock, (GstObject *)clock);
733 * gst_element_get_clock:
734 * @element: a #GstElement to get the clock of.
736 * Gets the clock of the element.
738 * Returns: the #GstClock of the element.
741 gst_element_get_clock (GstElement *element)
743 GstElementClass *oclass;
745 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
747 oclass = GST_ELEMENT_GET_CLASS (element);
749 if (oclass->get_clock)
750 return oclass->get_clock (element);
756 * gst_element_clock_wait:
757 * @element: a #GstElement.
758 * @id: the #GstClock to use.
759 * @jitter: the difference between requested time and actual time.
761 * Waits for a specific time on the clock.
763 * Returns: the #GstClockReturn result of the wait operation.
766 gst_element_clock_wait (GstElement *element, GstClockID id, GstClockTimeDiff *jitter)
770 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
772 if (GST_ELEMENT_SCHED (element)) {
773 GST_CAT_DEBUG (GST_CAT_CLOCK, "waiting on scheduler clock");
774 res = gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id, jitter);
777 GST_CAT_DEBUG (GST_CAT_CLOCK, "no scheduler, returning GST_CLOCK_TIMEOUT");
778 res = GST_CLOCK_TIMEOUT;
784 #ifndef GST_DISABLE_INDEX
786 * gst_element_is_indexable:
787 * @element: a #GstElement.
789 * Queries if the element can be indexed/
791 * Returns: TRUE if the element can be indexed.
794 gst_element_is_indexable (GstElement *element)
796 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
798 return (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
802 * gst_element_set_index:
803 * @element: a #GstElement.
804 * @index: a #GstIndex.
806 * Set the specified GstIndex on the element.
809 gst_element_set_index (GstElement *element, GstIndex *index)
811 GstElementClass *oclass;
813 g_return_if_fail (GST_IS_ELEMENT (element));
814 g_return_if_fail (GST_IS_INDEX (index));
816 oclass = GST_ELEMENT_GET_CLASS (element);
818 if (oclass->set_index)
819 oclass->set_index (element, index);
823 * gst_element_get_index:
824 * @element: a #GstElement.
826 * Gets the index from the element.
828 * Returns: a #GstIndex or NULL when no index was set on the
832 gst_element_get_index (GstElement *element)
834 GstElementClass *oclass;
836 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
838 oclass = GST_ELEMENT_GET_CLASS (element);
840 if (oclass->get_index)
841 return oclass->get_index (element);
848 * gst_element_release_locks:
849 * @element: a #GstElement to release all locks on.
851 * Instruct the element to release all the locks it is holding, such as
852 * blocking reads, waiting for the clock, ...
854 * Returns: TRUE if the locks could be released.
857 gst_element_release_locks (GstElement *element)
859 GstElementClass *oclass;
861 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
863 oclass = GST_ELEMENT_GET_CLASS (element);
865 if (oclass->release_locks)
866 return oclass->release_locks (element);
872 * gst_element_add_pad:
873 * @element: a #GstElement to add the pad to.
874 * @pad: the #GstPad to add to the element.
876 * Add a pad (link point) to the element, setting the parent of the
877 * pad to the element (and thus adding a reference).
878 * Pads are automatically activated when the element is in state PLAYING.
881 gst_element_add_pad (GstElement *element, GstPad *pad)
883 g_return_if_fail (GST_IS_ELEMENT (element));
884 g_return_if_fail (GST_IS_PAD (pad));
886 /* first check to make sure the pad's parent is already set */
887 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
889 /* then check to see if there's already a pad by that name here */
890 g_return_if_fail (gst_object_check_uniqueness (element->pads, GST_PAD_NAME(pad)) == TRUE);
892 /* set the pad's parent */
893 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"setting parent of pad '%s' to '%s'",
894 GST_PAD_NAME (pad), GST_STR_NULL (GST_ELEMENT_NAME (element)));
895 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
897 /* add it to the list */
898 element->pads = g_list_append (element->pads, pad);
900 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
901 element->numsrcpads++;
903 element->numsinkpads++;
905 /* activate element when we are playing */
906 if (GST_STATE (element) == GST_STATE_PLAYING)
907 gst_pad_set_active (pad, TRUE);
909 /* emit the NEW_PAD signal */
910 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
914 * gst_element_remove_pad:
915 * @element: a #GstElement to remove pad from.
916 * @pad: the #GstPad to remove from the element.
918 * Remove a pad (link point) from the element.
921 gst_element_remove_pad (GstElement *element, GstPad *pad)
923 g_return_if_fail (element != NULL);
924 g_return_if_fail (GST_IS_ELEMENT (element));
925 g_return_if_fail (pad != NULL);
926 g_return_if_fail (GST_IS_PAD (pad));
928 g_return_if_fail (GST_PAD_PARENT (pad) == element);
930 /* check to see if the pad is still linked */
931 /* FIXME: what if someone calls _remove_pad instead of
932 _remove_ghost_pad? */
933 if (GST_IS_REAL_PAD (pad)) {
934 g_return_if_fail (GST_RPAD_PEER (pad) == NULL);
937 /* remove it from the list */
938 element->pads = g_list_remove (element->pads, pad);
940 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
941 element->numsrcpads--;
943 element->numsinkpads--;
945 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
947 gst_object_unparent (GST_OBJECT (pad));
951 * gst_element_add_ghost_pad:
952 * @element: a #GstElement to add the ghost pad to.
953 * @pad: the #GstPad from which the new ghost pad will be created.
954 * @name: the name of the new ghost pad.
956 * Creates a ghost pad from the given pad, and adds it to the list of pads
959 * Returns: the added ghost #GstPad, or NULL, if no ghost pad was created.
962 gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
966 g_return_val_if_fail (element != NULL, NULL);
967 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
968 g_return_val_if_fail (pad != NULL, NULL);
969 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
971 /* then check to see if there's already a pad by that name here */
972 g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
974 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
975 "creating new ghost pad called %s, from pad %s:%s",
976 name, GST_DEBUG_PAD_NAME(pad));
977 ghostpad = gst_ghost_pad_new (name, pad);
979 /* add it to the list */
980 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"adding ghost pad %s to element %s",
981 name, GST_ELEMENT_NAME (element));
982 element->pads = g_list_append (element->pads, ghostpad);
984 /* set the parent of the ghostpad */
985 gst_object_set_parent (GST_OBJECT (ghostpad), GST_OBJECT (element));
987 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s",GST_DEBUG_PAD_NAME(ghostpad));
989 /* emit the NEW_GHOST_PAD signal */
990 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
996 * gst_element_remove_ghost_pad:
997 * @element: a #GstElement to remove the ghost pad from.
998 * @pad: ghost #GstPad to remove.
1000 * Removes a ghost pad from an element.
1003 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
1005 g_return_if_fail (GST_IS_ELEMENT (element));
1006 g_return_if_fail (GST_IS_GHOST_PAD (pad));
1008 /* FIXME this is redundant?
1009 * wingo 10-july-2001: I don't think so, you have to actually remove the pad
1010 * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
1011 * the real pad's ghost pad list
1013 gst_object_ref (GST_OBJECT (pad));
1014 gst_element_remove_pad (element, pad);
1015 gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
1016 gst_object_unref (GST_OBJECT (pad));
1021 * gst_element_get_pad:
1022 * @element: a #GstElement to find pad of.
1023 * @name: the name of the pad to retrieve.
1025 * Retrieves a pad from the element by name.
1027 * Returns: requested #GstPad if found, otherwise NULL.
1030 gst_element_get_pad (GstElement *element, const gchar *name)
1034 g_return_val_if_fail (element != NULL, NULL);
1035 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1036 g_return_val_if_fail (name != NULL, NULL);
1038 pad = gst_element_get_static_pad (element, name);
1040 pad = gst_element_get_request_pad (element, name);
1046 * gst_element_get_static_pad:
1047 * @element: a #GstElement to find a static pad of.
1048 * @name: the name of the static #GstPad to retrieve.
1050 * Retrieves a pad from the element by name. This version only retrieves
1051 * already-existing (i.e. 'static') pads.
1053 * Returns: the requested #GstPad if found, otherwise NULL.
1056 gst_element_get_static_pad (GstElement *element, const gchar *name)
1060 g_return_val_if_fail (element != NULL, NULL);
1061 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1062 g_return_val_if_fail (name != NULL, NULL);
1064 walk = element->pads;
1068 pad = GST_PAD(walk->data);
1069 if (strcmp (GST_PAD_NAME(pad), name) == 0) {
1070 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1073 walk = g_list_next (walk);
1076 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"", name, GST_OBJECT_NAME (element));
1081 * gst_element_get_request_pad:
1082 * @element: a #GstElement to find a request pad of.
1083 * @name: the name of the request #GstPad to retrieve.
1085 * Retrieves a pad from the element by name. This version only retrieves
1088 * Returns: requested #GstPad if found, otherwise NULL.
1091 gst_element_get_request_pad (GstElement *element, const gchar *name)
1093 GstPadTemplate *templ = NULL;
1095 const gchar *req_name = NULL;
1096 gboolean templ_found = FALSE;
1100 gchar *str, *endptr = NULL;
1102 g_return_val_if_fail (element != NULL, NULL);
1103 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1104 g_return_val_if_fail (name != NULL, NULL);
1106 if (strstr (name, "%")) {
1107 templ = gst_element_get_pad_template (element, name);
1112 list = gst_element_get_pad_template_list(element);
1113 while (!templ_found && list) {
1114 templ = (GstPadTemplate*) list->data;
1115 if (templ->presence == GST_PAD_REQUEST) {
1116 /* we know that %s and %d are the only possibilities because of sanity
1117 checks in gst_pad_template_new */
1118 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name, templ->name_template);
1119 if ((str = strchr (templ->name_template, '%')) &&
1120 strncmp (templ->name_template, name, str - templ->name_template) == 0 &&
1121 strlen (name) > str - templ->name_template) {
1122 data = name + (str - templ->name_template);
1123 if (*(str+1) == 'd') {
1125 n = (gint) strtol (data, &endptr, 10);
1126 if (endptr && *endptr == '\0') {
1146 pad = gst_element_request_pad (element, templ, req_name);
1152 * gst_element_get_pad_list:
1153 * @element: a #GstElement to get pads of.
1155 * Retrieves a list of the pads associated with the element.
1157 * Returns: the #GList of pads.
1160 gst_element_get_pad_list (GstElement *element)
1162 g_return_val_if_fail (element != NULL, NULL);
1163 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1165 /* return the list of pads */
1166 return element->pads;
1170 * gst_element_class_add_pad_template:
1171 * @klass: the #GstElementClass to add the pad template to.
1172 * @templ: a #GstPadTemplate to add to the element class.
1174 * Adds a padtemplate to an element class. This is mainly used in the _base_init
1175 * functions of classes.
1178 gst_element_class_add_pad_template (GstElementClass *klass,
1179 GstPadTemplate *templ)
1181 g_return_if_fail (klass != NULL);
1182 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1183 g_return_if_fail (templ != NULL);
1184 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1186 klass->padtemplates = g_list_append (klass->padtemplates, templ);
1187 klass->numpadtemplates++;
1191 * gst_element_class_set_details:
1192 * @klass: class to set details for
1193 * @details: details to set
1195 * Sets the detailed information for a #GstElementClass.
1196 * <note>This function is for use in _base_init functions only.</note>
1199 gst_element_class_set_details (GstElementClass *klass, GstElementDetails *details)
1201 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1202 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1204 __gst_element_details_set (&klass->details, details);
1208 * gst_element_get_pad_template_list:
1209 * @element: a #GstElement to get pad templates of.
1211 * Retrieves a list of the pad templates associated with the element.
1213 * Returns: the #GList of padtemplates.
1216 gst_element_get_pad_template_list (GstElement *element)
1218 g_return_val_if_fail (element != NULL, NULL);
1219 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1221 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1225 * gst_element_get_pad_template:
1226 * @element: a #GstElement to get the pad template of.
1227 * @name: the name of the #GstPadTemplate to get.
1229 * Retrieves a padtemplate from this element with the
1232 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1233 * No unreferencing is necessary.
1236 gst_element_get_pad_template (GstElement *element, const gchar *name)
1240 g_return_val_if_fail (element != NULL, NULL);
1241 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1242 g_return_val_if_fail (name != NULL, NULL);
1244 padlist = gst_element_get_pad_template_list (element);
1247 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1249 if (!strcmp (padtempl->name_template, name))
1252 padlist = g_list_next (padlist);
1259 * gst_element_get_compatible_pad_template:
1260 * @element: a #GstElement to get a compatible pad template for.
1261 * @compattempl: the #GstPadTemplate to find a compatible template for.
1263 * Generates a pad template for this element compatible with the given
1264 * template (meaning it is able to link with it).
1266 * Returns: the #GstPadTemplate of the element that is compatible with
1267 * the given GstPadTemplate, or NULL if none was found. No unreferencing
1271 gst_element_get_compatible_pad_template (GstElement *element,
1272 GstPadTemplate *compattempl)
1274 GstPadTemplate *newtempl = NULL;
1277 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "gst_element_get_compatible_pad_template()");
1279 g_return_val_if_fail (element != NULL, NULL);
1280 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1281 g_return_val_if_fail (compattempl != NULL, NULL);
1283 padlist = gst_element_get_pad_template_list (element);
1286 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1287 gboolean comp = FALSE;
1291 * Check direction (must be opposite)
1294 GST_CAT_DEBUG (GST_CAT_CAPS, "checking direction and caps");
1295 if (padtempl->direction == GST_PAD_SRC &&
1296 compattempl->direction == GST_PAD_SINK) {
1297 GST_CAT_DEBUG (GST_CAT_CAPS, "compatible direction: found src pad template");
1298 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1299 GST_PAD_TEMPLATE_CAPS (padtempl));
1300 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1301 } else if (padtempl->direction == GST_PAD_SINK &&
1302 compattempl->direction == GST_PAD_SRC) {
1303 GST_CAT_DEBUG (GST_CAT_CAPS, "compatible direction: found sink pad template");
1304 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1305 GST_PAD_TEMPLATE_CAPS (padtempl));
1306 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1310 newtempl = padtempl;
1314 padlist = g_list_next (padlist);
1321 * gst_element_request_compatible_pad:
1322 * @element: a #GstElement to request a new pad from.
1323 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1325 * Requests a new pad from the element. The template will
1326 * be used to decide what type of pad to create. This function
1327 * is typically used for elements with a padtemplate with presence
1330 * Returns: the new #GstPad that was created, or NULL if none could be created.
1333 gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
1335 GstPadTemplate *templ_new;
1338 g_return_val_if_fail (element != NULL, NULL);
1339 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1340 g_return_val_if_fail (templ != NULL, NULL);
1342 templ_new = gst_element_get_compatible_pad_template (element, templ);
1343 if (templ_new != NULL)
1344 pad = gst_element_request_pad (element, templ_new, NULL);
1351 * gst_element_get_compatible_pad_filtered:
1352 * @element: a #GstElement in which the pad should be found.
1353 * @pad: the #GstPad to find a compatible one for.
1354 * @filtercaps: the #GstCaps to use as a filter.
1356 * Looks for an unlinked pad to which the given pad can link to.
1357 * It is not guaranteed that linking the pads will work, though
1358 * it should work in most cases.
1360 * Returns: the #GstPad to which a link can be made.
1363 gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
1364 GstCaps *filtercaps)
1367 GstPadTemplate *templ;
1369 GstPad *foundpad = NULL;
1372 g_return_val_if_fail (element != NULL, NULL);
1373 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1374 g_return_val_if_fail (pad != NULL, NULL);
1375 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1377 /* let's use the real pad */
1378 pad = (GstPad *) GST_PAD_REALIZE (pad);
1379 g_return_val_if_fail (pad != NULL, NULL);
1380 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1382 /* try to get an existing unlinked pad */
1383 pads = gst_element_get_pad_list (element);
1385 GstPad *current = GST_PAD (pads->data);
1386 if ((GST_PAD_PEER (GST_PAD_REALIZE (current)) == NULL) &&
1387 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1390 pads = g_list_next (pads);
1393 /* try to create a new one */
1394 /* requesting is a little crazy, we need a template. Let's create one */
1395 if (filtercaps != NULL) {
1396 templcaps = gst_caps_intersect (filtercaps, (GstCaps *) GST_RPAD_CAPS (pad));
1397 if (templcaps == NULL)
1400 templcaps = gst_pad_get_caps (pad);
1403 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1404 GST_PAD_ALWAYS, templcaps, NULL);
1405 foundpad = gst_element_request_compatible_pad (element, templ);
1406 gst_object_unref (GST_OBJECT (templ)); /* this will take care of the caps too */
1408 /* FIXME: this is broken, but it's in here so autoplugging elements that don't
1409 have caps on their source padtemplates (spider) can link... */
1410 if (!foundpad && !filtercaps) {
1411 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
1412 GST_PAD_ALWAYS, NULL, NULL);
1413 foundpad = gst_element_request_compatible_pad (element, templ);
1414 gst_object_unref (GST_OBJECT (templ));
1421 * gst_element_get_compatible_pad:
1422 * @element: a #GstElement in which the pad should be found.
1423 * @pad: the #GstPad to find a compatible one for.
1425 * Looks for an unlinked pad to which the given pad can link to.
1426 * It is not guaranteed that linking the pads will work, though
1427 * it should work in most cases.
1429 * Returns: the #GstPad to which a link can be made, or NULL if none
1433 gst_element_get_compatible_pad (GstElement *element, GstPad *pad)
1435 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1439 * gst_element_link_pads_filtered:
1440 * @src: a #GstElement containing the source pad.
1441 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1442 * @dest: the #GstElement containing the destination pad.
1443 * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1444 * @filtercaps: the #GstCaps to use as a filter.
1446 * Links the two named pads of the source and destination elements.
1447 * Side effect is that if one of the pads has no parent, it becomes a
1448 * child of the parent of the other element. If they have different
1449 * parents, the link fails.
1451 * Returns: TRUE if the pads could be linked.
1454 gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
1455 GstElement *dest, const gchar *destpadname,
1456 GstCaps *filtercaps)
1458 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1459 GstPad *srcpad, *destpad;
1460 GstPadTemplate *srctempl, *desttempl;
1463 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1464 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1466 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "trying to link element %s:%s to element %s:%s",
1467 GST_ELEMENT_NAME (src), srcpadname ? srcpadname : "(any)",
1468 GST_ELEMENT_NAME (dest), destpadname ? destpadname : "(any)");
1470 /* now get the pads we're trying to link and a list of all remaining pads */
1472 srcpad = gst_element_get_pad (src, srcpadname);
1474 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (src), srcpadname);
1477 if (!(GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1478 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad", GST_DEBUG_PAD_NAME (srcpad));
1481 if (GST_PAD_PEER (srcpad) != NULL) {
1482 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (srcpad));
1488 srcpads = gst_element_get_pad_list (src);
1489 srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
1492 destpad = gst_element_get_pad (dest, destpadname);
1494 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (dest), destpadname);
1497 if (!(GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1498 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad", GST_DEBUG_PAD_NAME (destpad));
1501 if (GST_PAD_PEER (destpad) != NULL) {
1502 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (destpad));
1508 destpads = gst_element_get_pad_list (dest);
1509 destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
1512 if (srcpadname && destpadname) {
1513 /* two explicitly specified pads */
1514 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1517 /* loop through the allowed pads in the source, trying to find a
1518 * compatible destination pad */
1519 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "looping through allowed src and dest pads");
1521 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1522 GST_DEBUG_PAD_NAME (srcpad));
1523 if ((GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1524 (GST_PAD_PEER (srcpad) == NULL)) {
1525 GstPad *temp = gst_element_get_compatible_pad_filtered (dest, srcpad,
1527 if (temp && gst_pad_link_filtered (srcpad, temp, filtercaps)) {
1528 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1529 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1533 /* find a better way for this mess */
1535 srcpads = g_list_next (srcpads);
1537 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1542 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1543 GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1547 /* loop through the existing pads in the destination */
1549 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1550 GST_DEBUG_PAD_NAME (destpad));
1551 if ((GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1552 (GST_PAD_PEER (destpad) == NULL)) {
1553 GstPad *temp = gst_element_get_compatible_pad_filtered (src, destpad,
1555 if (temp && gst_pad_link_filtered (temp, destpad, filtercaps)) {
1556 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1557 GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1562 destpads = g_list_next (destpads);
1564 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1569 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1570 GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1574 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1575 "we might have request pads on both sides, checking...");
1576 srctempls = gst_element_get_pad_template_list (src);
1577 desttempls = gst_element_get_pad_template_list (dest);
1579 if (srctempls && desttempls) {
1581 srctempl = (GstPadTemplate*) srctempls->data;
1582 if (srctempl->presence == GST_PAD_REQUEST) {
1583 for (l=desttempls; l; l=l->next) {
1584 desttempl = (GstPadTemplate*) desttempls->data;
1585 if (desttempl->presence == GST_PAD_REQUEST &&
1586 desttempl->direction != srctempl->direction) {
1587 if (gst_caps_is_always_compatible (gst_pad_template_get_caps (srctempl),
1588 gst_pad_template_get_caps (desttempl))) {
1589 srcpad = gst_element_get_request_pad (src,
1590 srctempl->name_template);
1591 destpad = gst_element_get_request_pad (dest,
1592 desttempl->name_template);
1593 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1594 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1595 "linked pad %s:%s to pad %s:%s",
1596 GST_DEBUG_PAD_NAME (srcpad),
1597 GST_DEBUG_PAD_NAME (destpad));
1600 /* FIXME: we have extraneous request pads lying around */
1605 srctempls = srctempls->next;
1609 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1610 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1614 * gst_element_link_filtered:
1615 * @src: a #GstElement containing the source pad.
1616 * @dest: the #GstElement containing the destination pad.
1617 * @filtercaps: the #GstCaps to use as a filter.
1619 * Links the source to the destination element using the filtercaps.
1620 * The link must be from source to destination, the other
1621 * direction will not be tried.
1622 * The functions looks for existing pads that aren't linked yet.
1623 * It will use request pads if possible. But both pads will not be requested.
1624 * If multiple links are possible, only one is established.
1626 * Returns: TRUE if the elements could be linked.
1629 gst_element_link_filtered (GstElement *src, GstElement *dest,
1630 GstCaps *filtercaps)
1632 return gst_element_link_pads_filtered (src, NULL, dest, NULL, filtercaps);
1636 * gst_element_link_many:
1637 * @element_1: the first #GstElement in the link chain.
1638 * @element_2: the second #GstElement in the link chain.
1639 * @...: the NULL-terminated list of elements to link in order.
1641 * Chain together a series of elements. Uses #gst_element_link.
1643 * Returns: TRUE on success, FALSE otherwise.
1646 gst_element_link_many (GstElement *element_1, GstElement *element_2, ...)
1650 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1651 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1652 GST_IS_ELEMENT (element_2), FALSE);
1654 va_start (args, element_2);
1657 if (!gst_element_link (element_1, element_2))
1660 element_1 = element_2;
1661 element_2 = va_arg (args, GstElement*);
1671 * @src: a #GstElement containing the source pad.
1672 * @dest: the #GstElement containing the destination pad.
1674 * Links the source to the destination element.
1675 * The link must be from source to destination, the other
1676 * direction will not be tried.
1677 * The functions looks for existing pads and request pads that aren't
1678 * linked yet. If multiple links are possible, only one is
1681 * Returns: TRUE if the elements could be linked.
1684 gst_element_link (GstElement *src, GstElement *dest)
1686 return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1690 * gst_element_link_pads:
1691 * @src: a #GstElement containing the source pad.
1692 * @srcpadname: the name of the #GstPad in the source element.
1693 * @dest: the #GstElement containing the destination pad.
1694 * @destpadname: the name of the #GstPad in destination element.
1696 * Links the two named pads of the source and destination elements.
1697 * Side effect is that if one of the pads has no parent, it becomes a
1698 * child of the parent of the other element. If they have different
1699 * parents, the link fails.
1701 * Returns: TRUE if the pads could be linked.
1704 gst_element_link_pads (GstElement *src, const gchar *srcpadname,
1705 GstElement *dest, const gchar *destpadname)
1707 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname, NULL);
1711 * gst_element_unlink_pads:
1712 * @src: a #GstElement containing the source pad.
1713 * @srcpadname: the name of the #GstPad in source element.
1714 * @dest: a #GstElement containing the destination pad.
1715 * @destpadname: the name of the #GstPad in destination element.
1717 * Unlinks the two named pads of the source and destination elements.
1720 gst_element_unlink_pads (GstElement *src, const gchar *srcpadname,
1721 GstElement *dest, const gchar *destpadname)
1723 GstPad *srcpad,*destpad;
1725 g_return_if_fail (src != NULL);
1726 g_return_if_fail (GST_IS_ELEMENT(src));
1727 g_return_if_fail (srcpadname != NULL);
1728 g_return_if_fail (dest != NULL);
1729 g_return_if_fail (GST_IS_ELEMENT(dest));
1730 g_return_if_fail (destpadname != NULL);
1732 /* obtain the pads requested */
1733 srcpad = gst_element_get_pad (src, srcpadname);
1734 if (srcpad == NULL) {
1735 GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
1738 destpad = gst_element_get_pad (dest, destpadname);
1739 if (srcpad == NULL) {
1740 GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"", destpadname);
1744 /* we're satisified they can be unlinked, let's do it */
1745 gst_pad_unlink (srcpad,destpad);
1749 * gst_element_unlink_many:
1750 * @element_1: the first #GstElement in the link chain.
1751 * @element_2: the second #GstElement in the link chain.
1752 * @...: the NULL-terminated list of elements to unlink in order.
1754 * Unlinks a series of elements. Uses #gst_element_unlink.
1757 gst_element_unlink_many (GstElement *element_1, GstElement *element_2, ...)
1761 g_return_if_fail (element_1 != NULL && element_2 != NULL);
1762 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
1764 va_start (args, element_2);
1767 gst_element_unlink (element_1, element_2);
1769 element_1 = element_2;
1770 element_2 = va_arg (args, GstElement*);
1777 * gst_element_unlink:
1778 * @src: the source #GstElement to unlink.
1779 * @dest: the sink #GstElement to unlink.
1781 * Unlinks all source pads of the source element with all sink pads
1782 * of the sink element to which they are linked.
1785 gst_element_unlink (GstElement *src, GstElement *dest)
1787 const GList *srcpads;
1790 g_return_if_fail (GST_IS_ELEMENT (src));
1791 g_return_if_fail (GST_IS_ELEMENT (dest));
1793 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
1794 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1796 srcpads = gst_element_get_pad_list (src);
1799 pad = GST_PAD_CAST (srcpads->data);
1801 /* we only care about real src pads */
1802 if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
1803 GstPad *peerpad = GST_PAD_PEER (pad);
1805 /* see if the pad is connected and is really a pad
1808 (GST_OBJECT_PARENT (peerpad) == (GstObject*) dest))
1810 gst_pad_unlink (pad, peerpad);
1814 srcpads = g_list_next (srcpads);
1819 gst_element_error_func (GstElement* element, GstElement *source,
1822 /* tell the parent */
1823 if (GST_OBJECT_PARENT (element)) {
1824 GST_CAT_DEBUG (GST_CAT_EVENT, "forwarding error \"%s\" from %s to %s",
1825 errormsg, GST_ELEMENT_NAME (element),
1826 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
1828 gst_object_ref (GST_OBJECT (element));
1829 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
1830 gst_element_signals[ERROR], 0, source, errormsg);
1831 gst_object_unref (GST_OBJECT (element));
1836 gst_element_get_random_pad (GstElement *element, GstPadDirection dir)
1838 GList *pads = element->pads;
1839 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1841 GstPad *pad = GST_PAD_CAST (pads->data);
1843 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1844 GST_DEBUG_PAD_NAME (pad));
1846 if (GST_PAD_DIRECTION (pad) == dir) {
1847 if (GST_PAD_IS_LINKED (pad)) {
1851 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1852 GST_DEBUG_PAD_NAME (pad));
1856 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
1857 GST_DEBUG_PAD_NAME (pad));
1860 pads = g_list_next (pads);
1866 * gst_element_get_event_masks:
1867 * @element: a #GstElement to query
1869 * Get an array of event masks from the element.
1870 * If the element doesn't
1871 * implement an event masks function, the query will be forwarded
1872 * to a random linked sink pad.
1874 * Returns: An array of #GstEventMask elements.
1877 gst_element_get_event_masks (GstElement *element)
1879 GstElementClass *oclass;
1881 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1883 oclass = GST_ELEMENT_GET_CLASS (element);
1885 if (oclass->get_event_masks)
1886 return oclass->get_event_masks (element);
1888 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1890 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
1897 * gst_element_send_event:
1898 * @element: a #GstElement to send the event to.
1899 * @event: the #GstEvent to send to the element.
1901 * Sends an event to an element. If the element doesn't
1902 * implement an event handler, the event will be forwarded
1903 * to a random sink pad.
1905 * Returns: TRUE if the event was handled.
1908 gst_element_send_event (GstElement *element, GstEvent *event)
1910 GstElementClass *oclass;
1912 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1913 g_return_val_if_fail (event != NULL, FALSE);
1915 oclass = GST_ELEMENT_GET_CLASS (element);
1917 if (oclass->send_event)
1918 return oclass->send_event (element, event);
1920 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1922 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
1923 GST_DEBUG_PAD_NAME (pad));
1924 return gst_pad_send_event (GST_PAD_PEER (pad), event);
1927 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1928 GST_ELEMENT_NAME (element));
1934 * @element: a #GstElement to send the event to.
1935 * @seek_type: the method to use for seeking.
1936 * @offset: the offset to seek to.
1938 * Sends a seek event to an element.
1940 * Returns: TRUE if the event was handled.
1943 gst_element_seek (GstElement *element,
1944 GstSeekType seek_type,
1947 GstEvent *event = gst_event_new_seek (seek_type, offset);
1949 return gst_element_send_event (element, event);
1953 * gst_element_get_query_types:
1954 * @element: a #GstElement to query
1956 * Get an array of query types from the element.
1957 * If the element doesn't
1958 * implement a query types function, the query will be forwarded
1959 * to a random sink pad.
1961 * Returns: An array of #GstQueryType elements.
1964 gst_element_get_query_types (GstElement *element)
1966 GstElementClass *oclass;
1968 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1970 oclass = GST_ELEMENT_GET_CLASS (element);
1972 if (oclass->get_query_types)
1973 return oclass->get_query_types (element);
1975 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1977 return gst_pad_get_query_types (GST_PAD_PEER (pad));
1984 * gst_element_query:
1985 * @element: a #GstElement to perform the query on.
1986 * @type: the #GstQueryType.
1987 * @format: the #GstFormat pointer to hold the format of the result.
1988 * @value: the pointer to the value of the result.
1990 * Performs a query on the given element. If the format is set
1991 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1992 * format pointer will hold the default format.
1993 * For element that don't implement a query handler, this function
1994 * forwards the query to a random usable sinkpad of this element.
1996 * Returns: TRUE if the query could be performed.
1999 gst_element_query (GstElement *element, GstQueryType type,
2000 GstFormat *format, gint64 *value)
2002 GstElementClass *oclass;
2004 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2005 g_return_val_if_fail (format != NULL, FALSE);
2006 g_return_val_if_fail (value != NULL, FALSE);
2008 oclass = GST_ELEMENT_GET_CLASS (element);
2011 return oclass->query (element, type, format, value);
2013 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2015 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
2022 * gst_element_get_formats:
2023 * @element: a #GstElement to query
2025 * Get an array of formst from the element.
2026 * If the element doesn't
2027 * implement a formats function, the query will be forwarded
2028 * to a random sink pad.
2030 * Returns: An array of #GstFormat elements.
2033 gst_element_get_formats (GstElement *element)
2035 GstElementClass *oclass;
2037 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2039 oclass = GST_ELEMENT_GET_CLASS (element);
2041 if (oclass->get_formats)
2042 return oclass->get_formats (element);
2044 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2046 return gst_pad_get_formats (GST_PAD_PEER (pad));
2053 * gst_element_convert:
2054 * @element: a #GstElement to invoke the converter on.
2055 * @src_format: the source #GstFormat.
2056 * @src_value: the source value.
2057 * @dest_format: a pointer to the destination #GstFormat.
2058 * @dest_value: a pointer to the destination value.
2060 * Invokes a conversion on the element.
2061 * If the element doesn't
2062 * implement a convert function, the query will be forwarded
2063 * to a random sink pad.
2065 * Returns: TRUE if the conversion could be performed.
2068 gst_element_convert (GstElement *element,
2069 GstFormat src_format, gint64 src_value,
2070 GstFormat *dest_format, gint64 *dest_value)
2072 GstElementClass *oclass;
2074 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2075 g_return_val_if_fail (dest_format != NULL, FALSE);
2076 g_return_val_if_fail (dest_value != NULL, FALSE);
2078 if (src_format == *dest_format) {
2079 *dest_value = src_value;
2083 oclass = GST_ELEMENT_GET_CLASS (element);
2085 if (oclass->convert)
2086 return oclass->convert (element,
2087 src_format, src_value,
2088 dest_format, dest_value);
2090 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2092 return gst_pad_convert (GST_PAD_PEER (pad),
2093 src_format, src_value,
2094 dest_format, dest_value);
2101 * gst_element_error:
2102 * @element: a #GstElement with the error.
2103 * @error: the printf-style string describing the error.
2104 * @...: the optional arguments for the string.
2106 * signals an error condition on an element.
2107 * This function is used internally by elements.
2108 * It results in the "error" signal.
2111 gst_element_error (GstElement *element, const gchar *error, ...)
2117 g_return_if_fail (GST_IS_ELEMENT (element));
2118 g_return_if_fail (error != NULL);
2120 /* create error message */
2121 va_start (var_args, error);
2122 string = g_strdup_vprintf (error, var_args);
2124 GST_CAT_INFO (GST_CAT_EVENT, "ERROR in %s: %s", GST_ELEMENT_NAME (element), string);
2126 /* if the element was already in error, stop now */
2127 if (GST_FLAG_IS_SET (element, GST_ELEMENT_ERROR)) {
2128 GST_CAT_INFO (GST_CAT_EVENT, "recursive ERROR detected in %s", GST_ELEMENT_NAME (element));
2133 GST_FLAG_SET (element, GST_ELEMENT_ERROR);
2135 /* emit the signal, make sure the element stays available */
2136 gst_object_ref (GST_OBJECT (element));
2137 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element, string);
2139 /* tell the scheduler */
2140 if (element->sched) {
2141 gst_scheduler_error (element->sched, element);
2144 if (GST_STATE (element) == GST_STATE_PLAYING) {
2145 GstElementStateReturn ret;
2147 ret = gst_element_set_state (element, GST_STATE_PAUSED);
2148 if (ret != GST_STATE_SUCCESS) {
2149 g_warning ("could not PAUSE element \"%s\" after error, help!", GST_ELEMENT_NAME (element));
2153 GST_FLAG_UNSET (element, GST_ELEMENT_ERROR);
2156 gst_object_unref (GST_OBJECT (element));
2161 * gst_element_is_locked_state:
2162 * @element: a #GstElement.
2164 * Checks if the state of an element is locked.
2165 * If the state of an element is locked, state changes of the parent don't
2166 * affect the element.
2167 * This way you can leave currently unused elements inside bins. Just lock their
2168 * state before changing the state from #GST_STATE_NULL.
2170 * Returns: TRUE, if the element's state is locked.
2173 gst_element_is_locked_state (GstElement *element)
2175 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2177 return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
2180 * gst_element_set_locked_state:
2181 * @element: a #GstElement
2182 * @locked_state: TRUE to lock the element's state
2184 * Locks the state of an element, so state changes of the parent don't affect
2185 * this element anymore.
2188 gst_element_set_locked_state (GstElement *element, gboolean locked_state)
2192 g_return_if_fail (GST_IS_ELEMENT (element));
2194 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2196 if (old == locked_state)
2200 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2201 GST_ELEMENT_NAME (element));
2202 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2204 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2205 GST_ELEMENT_NAME (element));
2206 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2210 * gst_element_sync_state_with_parent:
2211 * @element: a #GstElement.
2213 * Tries to change the state of the element to the same as its parent.
2214 * If this function returns FALSE, the state of element is undefined.
2216 * Returns: TRUE, if the element's state could be synced to the parent's state.
2219 gst_element_sync_state_with_parent (GstElement *element)
2223 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2224 parent = GST_ELEMENT (GST_ELEMENT_PARENT(element));
2225 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
2227 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
2228 GST_ELEMENT_NAME (element), gst_element_state_get_name (GST_STATE (element)),
2229 GST_ELEMENT_NAME (parent), gst_element_state_get_name (GST_STATE (parent)));
2230 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
2236 * gst_element_get_state:
2237 * @element: a #GstElement to get the state of.
2239 * Gets the state of the element.
2241 * Returns: the #GstElementState of the element.
2244 gst_element_get_state (GstElement *element)
2246 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2248 return GST_STATE (element);
2252 * gst_element_wait_state_change:
2253 * @element: a #GstElement to wait for a state change on.
2255 * Waits and blocks until the element changed its state.
2258 gst_element_wait_state_change (GstElement *element)
2260 g_mutex_lock (element->state_mutex);
2261 g_cond_wait (element->state_cond, element->state_mutex);
2262 g_mutex_unlock (element->state_mutex);
2266 * gst_element_set_state:
2267 * @element: a #GstElement to change state of.
2268 * @state: the element's new #GstElementState.
2270 * Sets the state of the element. This function will try to set the
2271 * requested state by going through all the intermediary states and calling
2272 * the class's state change function for each.
2274 * Returns: TRUE if the state was successfully set.
2275 * (using #GstElementStateReturn).
2277 GstElementStateReturn
2278 gst_element_set_state (GstElement *element, GstElementState state)
2280 GstElementClass *oclass;
2281 GstElementState curpending;
2282 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2284 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2286 /* start with the current state */
2287 curpending = GST_STATE(element);
2289 if (state == curpending)
2291 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2292 "element is already in requested state %s",
2293 gst_element_state_get_name (state));
2294 return (GST_STATE_SUCCESS);
2297 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
2298 gst_element_state_get_name (curpending),
2299 gst_element_state_get_name (state));
2301 /* loop until the final requested state is set */
2302 while (GST_STATE (element) != state
2303 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2304 /* move the curpending state in the correct direction */
2305 if (curpending < state)
2310 /* set the pending state variable */
2311 /* FIXME: should probably check to see that we don't already have one */
2312 GST_STATE_PENDING (element) = curpending;
2314 if (curpending != state) {
2315 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2316 "intermediate: setting state from %s to %s",
2317 gst_element_state_get_name (GST_STATE (element)),
2318 gst_element_state_get_name (curpending));
2321 /* call the state change function so it can set the state */
2322 oclass = GST_ELEMENT_GET_CLASS (element);
2323 if (oclass->change_state)
2324 return_val = (oclass->change_state) (element);
2326 switch (return_val) {
2327 case GST_STATE_FAILURE:
2328 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2329 "have failed change_state return");
2331 case GST_STATE_ASYNC:
2332 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2333 "element will change state async");
2335 case GST_STATE_SUCCESS:
2336 /* Last thing we do is verify that a successful state change really
2337 * did change the state... */
2338 /* if it did not, this is an error - fix the element that does this */
2339 if (GST_STATE (element) != curpending) {
2340 g_warning ("element %s claimed state-change success,"
2341 "but state didn't change to %s. State is %s (%s pending), fix the element",
2342 GST_ELEMENT_NAME (element),
2343 gst_element_state_get_name (curpending),
2344 gst_element_state_get_name (GST_STATE (element)),
2345 gst_element_state_get_name (GST_STATE_PENDING (element)));
2346 return_val = GST_STATE_FAILURE;
2351 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2352 g_assert_not_reached ();
2361 gst_element_negotiate_pads (GstElement *element)
2363 GList *pads = GST_ELEMENT_PADS (element);
2365 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating pads");
2368 GstPad *pad = GST_PAD (pads->data);
2371 pads = g_list_next (pads);
2373 if (!GST_IS_REAL_PAD (pad))
2376 srcpad = GST_PAD_REALIZE (pad);
2378 /* if we have a link on this pad and it doesn't have caps
2379 * allready, try to negotiate */
2380 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2381 GstRealPad *sinkpad;
2382 GstElementState otherstate;
2385 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2387 /* check the parent of the peer pad, if there is no parent do nothing */
2388 parent = GST_PAD_PARENT (sinkpad);
2392 /* skips pads that were already negotiating */
2393 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2394 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2397 otherstate = GST_STATE (parent);
2399 /* swap pads if needed */
2400 if (!GST_PAD_IS_SRC (srcpad)) {
2408 /* only try to negotiate if the peer element is in PAUSED or higher too */
2409 if (otherstate >= GST_STATE_READY) {
2410 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2411 "perform negotiate for %s:%s and %s:%s",
2412 GST_DEBUG_PAD_NAME (srcpad),
2413 GST_DEBUG_PAD_NAME (sinkpad));
2414 if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad)))
2418 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2419 "not negotiating %s:%s and %s:%s, not in READY yet",
2420 GST_DEBUG_PAD_NAME (srcpad),
2421 GST_DEBUG_PAD_NAME (sinkpad));
2430 gst_element_clear_pad_caps (GstElement *element)
2432 GList *pads = GST_ELEMENT_PADS (element);
2434 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "clearing pad caps");
2437 GstRealPad *pad = GST_PAD_REALIZE (pads->data);
2439 gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
2441 pads = g_list_next (pads);
2446 gst_element_pads_activate (GstElement *element, gboolean active)
2448 GList *pads = element->pads;
2451 GstPad *pad = GST_PAD_CAST (pads->data);
2452 pads = g_list_next (pads);
2454 if (!GST_IS_REAL_PAD (pad))
2457 gst_pad_set_active (pad, active);
2461 static GstElementStateReturn
2462 gst_element_change_state (GstElement *element)
2464 GstElementState old_state;
2466 gint old_pending, old_transition;
2468 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2470 old_state = GST_STATE (element);
2471 old_pending = GST_STATE_PENDING (element);
2472 old_transition = GST_STATE_TRANSITION (element);
2474 if (old_pending == GST_STATE_VOID_PENDING ||
2475 old_state == GST_STATE_PENDING (element)) {
2476 GST_CAT_INFO (GST_CAT_STATES,
2477 "no state change needed for element %s (VOID_PENDING)",
2478 GST_ELEMENT_NAME (element));
2479 return GST_STATE_SUCCESS;
2482 GST_CAT_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %04x",
2483 GST_ELEMENT_NAME (element),
2484 gst_element_state_get_name (old_state),
2485 gst_element_state_get_name (old_pending),
2488 /* we set the state change early for the negotiation functions */
2489 GST_STATE (element) = old_pending;
2490 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2492 switch (old_transition) {
2493 case GST_STATE_PLAYING_TO_PAUSED:
2494 gst_element_pads_activate (element, FALSE);
2496 case GST_STATE_PAUSED_TO_PLAYING:
2497 gst_element_pads_activate (element, TRUE);
2499 /* if we are going to paused, we try to negotiate the pads */
2500 case GST_STATE_READY_TO_PAUSED:
2501 if (!gst_element_negotiate_pads (element))
2504 /* going to the READY state clears all pad caps */
2505 case GST_STATE_PAUSED_TO_READY:
2506 gst_element_clear_pad_caps (element);
2512 parent = GST_ELEMENT_PARENT (element);
2514 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2515 "signaling state change from %s to %s",
2516 gst_element_state_get_name (old_state),
2517 gst_element_state_get_name (GST_STATE (element)));
2519 /* tell the scheduler if we have one */
2520 if (element->sched) {
2521 if (gst_scheduler_state_transition (element->sched, element,
2522 old_transition) != GST_STATE_SUCCESS) {
2523 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2524 "scheduler could not change state");
2529 /* tell our parent about the state change */
2530 if (parent && GST_IS_BIN (parent)) {
2531 gst_bin_child_state_change (GST_BIN (parent), old_state,
2532 GST_STATE (element), element);
2534 /* at this point the state of the element could have changed again */
2536 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2537 0, old_state, GST_STATE (element));
2539 /* signal the state change in case somebody is waiting for us */
2540 g_mutex_lock (element->state_mutex);
2541 g_cond_signal (element->state_cond);
2542 g_mutex_unlock (element->state_mutex);
2544 return GST_STATE_SUCCESS;
2547 /* undo the state change */
2548 GST_STATE (element) = old_state;
2549 GST_STATE_PENDING (element) = old_pending;
2551 return GST_STATE_FAILURE;
2555 * gst_element_get_factory:
2556 * @element: a #GstElement to request the element factory of.
2558 * Retrieves the factory that was used to create this element.
2560 * Returns: the #GstElementFactory used for creating this element.
2563 gst_element_get_factory (GstElement *element)
2565 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2567 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2571 gst_element_dispose (GObject *object)
2573 GstElement *element = GST_ELEMENT (object);
2577 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2579 gst_element_set_state (element, GST_STATE_NULL);
2581 /* first we break all our links with the ouside */
2582 if (element->pads) {
2584 orig = pads = g_list_copy (element->pads);
2586 pad = GST_PAD (pads->data);
2588 if (GST_PAD_PEER (pad)) {
2589 GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "unlinking pad '%s'",
2590 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2591 gst_pad_unlink (pad, GST_PAD (GST_PAD_PEER (pad)));
2593 gst_element_remove_pad (element, pad);
2595 pads = g_list_next (pads);
2598 g_list_free (element->pads);
2599 element->pads = NULL;
2602 element->numsrcpads = 0;
2603 element->numsinkpads = 0;
2604 element->numpads = 0;
2605 g_mutex_free (element->state_mutex);
2606 g_cond_free (element->state_cond);
2608 if (element->prop_value_queue)
2609 g_async_queue_unref (element->prop_value_queue);
2610 element->prop_value_queue = NULL;
2611 if (element->property_mutex)
2612 g_mutex_free (element->property_mutex);
2614 gst_object_replace ((GstObject **)&element->sched, NULL);
2615 gst_object_replace ((GstObject **)&element->clock, NULL);
2617 G_OBJECT_CLASS (parent_class)->dispose (object);
2620 #ifndef GST_DISABLE_LOADSAVE
2622 * gst_element_save_thyself:
2623 * @element: a #GstElement to save.
2624 * @parent: the xml parent node.
2626 * Saves the element as part of the given XML structure.
2628 * Returns: the new #xmlNodePtr.
2631 gst_element_save_thyself (GstObject *object,
2635 GstElementClass *oclass;
2636 GParamSpec **specs, *spec;
2638 GValue value = { 0, };
2639 GstElement *element;
2641 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2643 element = GST_ELEMENT (object);
2645 oclass = GST_ELEMENT_GET_CLASS (element);
2647 xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element));
2649 if (oclass->elementfactory != NULL) {
2650 GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory;
2652 xmlNewChild (parent, NULL, "type",
2653 GST_PLUGIN_FEATURE (factory)->name);
2656 /* FIXME: what is this? */
2657 /* if (element->manager) */
2658 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2661 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2663 for (i=0; i<nspecs; i++) {
2665 if (spec->flags & G_PARAM_READABLE) {
2669 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2671 g_object_get_property (G_OBJECT (element), spec->name, &value);
2672 param = xmlNewChild (parent, NULL, "param", NULL);
2673 xmlNewChild (param, NULL, "name", spec->name);
2675 if (G_IS_PARAM_SPEC_STRING (spec))
2676 contents = g_value_dup_string (&value);
2677 else if (G_IS_PARAM_SPEC_ENUM (spec))
2678 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2679 else if (G_IS_PARAM_SPEC_INT64 (spec))
2680 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2681 g_value_get_int64 (&value));
2683 contents = g_strdup_value_contents (&value);
2685 xmlNewChild (param, NULL, "value", contents);
2688 g_value_unset(&value);
2692 pads = GST_ELEMENT_PADS (element);
2695 GstPad *pad = GST_PAD (pads->data);
2696 /* figure out if it's a direct pad or a ghostpad */
2697 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2698 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
2699 gst_object_save_thyself (GST_OBJECT (pad), padtag);
2701 pads = g_list_next (pads);
2708 gst_element_restore_thyself (GstObject *object, xmlNodePtr self)
2710 xmlNodePtr children;
2711 GstElement *element;
2713 gchar *value = NULL;
2715 element = GST_ELEMENT (object);
2716 g_return_if_fail (element != NULL);
2719 children = self->xmlChildrenNode;
2721 if (!strcmp (children->name, "param")) {
2722 xmlNodePtr child = children->xmlChildrenNode;
2725 if (!strcmp (child->name, "name")) {
2726 name = xmlNodeGetContent (child);
2728 else if (!strcmp (child->name, "value")) {
2729 value = xmlNodeGetContent (child);
2731 child = child->next;
2733 /* FIXME: can this just be g_object_set ? */
2734 gst_util_set_object_arg (G_OBJECT (element), name, value);
2735 /* g_object_set (G_OBJECT (element), name, value, NULL); */
2737 children = children->next;
2741 children = self->xmlChildrenNode;
2743 if (!strcmp (children->name, "pad")) {
2744 gst_pad_load_and_link (children, GST_OBJECT (element));
2746 children = children->next;
2749 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2750 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2752 #endif /* GST_DISABLE_LOADSAVE */
2755 * gst_element_yield:
2756 * @element: a #GstElement to yield.
2758 * Requests a yield operation for the element. The scheduler will typically
2759 * give control to another element.
2762 gst_element_yield (GstElement *element)
2764 if (GST_ELEMENT_SCHED (element)) {
2765 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
2770 * gst_element_interrupt:
2771 * @element: a #GstElement to interrupt.
2773 * Requests the scheduler of this element to interrupt the execution of
2774 * this element and scheduler another one.
2776 * Returns: TRUE if the element should exit its chain/loop/get
2777 * function ASAP, depending on the scheduler implementation.
2780 gst_element_interrupt (GstElement *element)
2782 if (GST_ELEMENT_SCHED (element)) {
2783 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
2790 * gst_element_set_scheduler:
2791 * @element: a #GstElement to set the scheduler of.
2792 * @sched: the #GstScheduler to set.
2794 * Sets the scheduler of the element. For internal use only, unless you're
2795 * writing a new bin subclass.
2798 gst_element_set_scheduler (GstElement *element,
2799 GstScheduler *sched)
2801 g_return_if_fail (GST_IS_ELEMENT (element));
2803 GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p", sched);
2805 gst_object_replace ((GstObject **)&GST_ELEMENT_SCHED (element), GST_OBJECT (sched));
2809 * gst_element_get_scheduler:
2810 * @element: a #GstElement to get the scheduler of.
2812 * Returns the scheduler of the element.
2814 * Returns: the element's #GstScheduler.
2817 gst_element_get_scheduler (GstElement *element)
2819 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2821 return GST_ELEMENT_SCHED (element);
2825 * gst_element_set_loop_function:
2826 * @element: a #GstElement to set the loop function of.
2827 * @loop: Pointer to #GstElementLoopFunction.
2829 * This sets the loop function for the element. The function pointed to
2830 * can deviate from the GstElementLoopFunction definition in type of
2833 * NOTE: in order for this to take effect, the current loop function *must*
2834 * exit. Assuming the loop function itself is the only one who will cause
2835 * a new loopfunc to be assigned, this should be no problem.
2838 gst_element_set_loop_function (GstElement *element,
2839 GstElementLoopFunction loop)
2841 gboolean need_notify = FALSE;
2843 g_return_if_fail (GST_IS_ELEMENT (element));
2845 /* if the element changed from loop based to chain/get based
2846 * or vice versa, we need to inform the scheduler about that */
2847 if ((element->loopfunc == NULL && loop != NULL) ||
2848 (element->loopfunc != NULL && loop == NULL))
2853 /* set the loop function */
2854 element->loopfunc = loop;
2857 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
2858 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
2860 if (GST_ELEMENT_SCHED (element)) {
2861 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
2867 gst_element_set_eos_recursive (GstElement *element)
2869 /* this function is only called, when we were in PLAYING before. So every
2870 parent that's PAUSED was PLAYING before. That means it has reached EOS. */
2873 GST_CAT_DEBUG (GST_CAT_EVENT, "setting recursive EOS on %s",
2874 GST_OBJECT_NAME (element));
2875 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
2877 if (!GST_OBJECT_PARENT (element))
2880 parent = GST_ELEMENT (GST_OBJECT_PARENT (element));
2881 if (GST_STATE (parent) == GST_STATE_PAUSED)
2882 gst_element_set_eos_recursive (parent);
2885 * gst_element_set_eos:
2886 * @element: a #GstElement to set to the EOS state.
2888 * Perform the actions needed to bring the element in the EOS state.
2891 gst_element_set_eos (GstElement *element)
2893 g_return_if_fail (GST_IS_ELEMENT (element));
2895 GST_CAT_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
2896 GST_OBJECT_NAME (element));
2898 if (GST_STATE (element) == GST_STATE_PLAYING) {
2899 gst_element_set_state (element, GST_STATE_PAUSED);
2900 gst_element_set_eos_recursive (element);
2902 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
2908 * gst_element_state_get_name:
2909 * @state: a #GstElementState to get the name of.
2911 * Gets a string representing the given state.
2913 * Returns: a string with the name of the state.
2916 gst_element_state_get_name (GstElementState state)
2919 #ifdef GST_DEBUG_COLOR
2920 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2921 case GST_STATE_NULL: return "\033[01;34mNULL\033[00m";break;
2922 case GST_STATE_READY: return "\033[01;31mREADY\033[00m";break;
2923 case GST_STATE_PLAYING: return "\033[01;32mPLAYING\033[00m";break;
2924 case GST_STATE_PAUSED: return "\033[01;33mPAUSED\033[00m";break;
2926 /* This is a memory leak */
2927 return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
2929 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
2930 case GST_STATE_NULL: return "NULL";break;
2931 case GST_STATE_READY: return "READY";break;
2932 case GST_STATE_PLAYING: return "PLAYING";break;
2933 case GST_STATE_PAUSED: return "PAUSED";break;
2934 default: return "UNKNOWN!";
2941 gst_element_populate_std_props (GObjectClass * klass, const gchar *prop_name,
2942 guint arg_id, GParamFlags flags)
2944 GQuark prop_id = g_quark_from_string (prop_name);
2947 static GQuark fd_id = 0;
2948 static GQuark blocksize_id;
2949 static GQuark bytesperread_id;
2950 static GQuark dump_id;
2951 static GQuark filesize_id;
2952 static GQuark mmapsize_id;
2953 static GQuark location_id;
2954 static GQuark offset_id;
2955 static GQuark silent_id;
2956 static GQuark touch_id;
2959 fd_id = g_quark_from_static_string ("fd");
2960 blocksize_id = g_quark_from_static_string ("blocksize");
2961 bytesperread_id = g_quark_from_static_string ("bytesperread");
2962 dump_id = g_quark_from_static_string ("dump");
2963 filesize_id = g_quark_from_static_string ("filesize");
2964 mmapsize_id = g_quark_from_static_string ("mmapsize");
2965 location_id = g_quark_from_static_string ("location");
2966 offset_id = g_quark_from_static_string ("offset");
2967 silent_id = g_quark_from_static_string ("silent");
2968 touch_id = g_quark_from_static_string ("touch");
2971 if (prop_id == fd_id) {
2972 pspec = g_param_spec_int ("fd", "File-descriptor",
2973 "File-descriptor for the file being read",
2974 0, G_MAXINT, 0, flags);
2976 else if (prop_id == blocksize_id) {
2977 pspec = g_param_spec_ulong ("blocksize", "Block Size",
2978 "Block size to read per buffer",
2979 0, G_MAXULONG, 4096, flags);
2982 else if (prop_id == bytesperread_id) {
2983 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
2984 "Number of bytes to read per buffer",
2985 G_MININT, G_MAXINT, 0, flags);
2988 else if (prop_id == dump_id) {
2989 pspec = g_param_spec_boolean ("dump", "Dump",
2990 "Dump bytes to stdout",
2994 else if (prop_id == filesize_id) {
2995 pspec = g_param_spec_int64 ("filesize", "File Size",
2996 "Size of the file being read",
2997 0, G_MAXINT64, 0, flags);
3000 else if (prop_id == mmapsize_id) {
3001 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
3002 "Size in bytes of mmap()d regions",
3003 0, G_MAXULONG, 4 * 1048576, flags);
3006 else if (prop_id == location_id) {
3007 pspec = g_param_spec_string ("location", "File Location",
3008 "Location of the file to read",
3012 else if (prop_id == offset_id) {
3013 pspec = g_param_spec_int64 ("offset", "File Offset",
3014 "Byte offset of current read pointer",
3015 0, G_MAXINT64, 0, flags);
3018 else if (prop_id == silent_id) {
3019 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
3023 else if (prop_id == touch_id) {
3024 pspec = g_param_spec_boolean ("touch", "Touch read data",
3025 "Touch data to force disk read before "
3026 "push ()", TRUE, flags);
3029 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
3030 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
3035 g_object_class_install_property (klass, arg_id, pspec);
3040 * gst_element_class_install_std_props:
3041 * @klass: the #GstElementClass to add the properties to.
3042 * @first_name: the name of the first property.
3043 * in a NULL terminated
3044 * @...: the id and flags of the first property, followed by
3045 * further 'name', 'id', 'flags' triplets and terminated by NULL.
3047 * Adds a list of standardized properties with types to the @klass.
3048 * the id is for the property switch in your get_prop method, and
3049 * the flags determine readability / writeability.
3052 gst_element_class_install_std_props (GstElementClass * klass,
3053 const gchar *first_name, ...)
3059 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
3061 va_start (args, first_name);
3066 int arg_id = va_arg (args, int);
3067 int flags = va_arg (args, int);
3069 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id, flags);
3071 name = va_arg (args, char *);
3078 * gst_element_get_managing_bin:
3079 * @element: a #GstElement to get the managing bin of.
3081 * Gets the managing bin (a pipeline or a thread, for example) of an element.
3083 * Returns: the #GstBin, or NULL on failure.
3086 gst_element_get_managing_bin (GstElement *element)
3090 g_return_val_if_fail (element != NULL, NULL);
3092 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (element)));
3094 while (bin && !GST_FLAG_IS_SET (GST_OBJECT_CAST (bin), GST_BIN_FLAG_MANAGER))
3095 bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (bin)));