2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2004 Wim Taymans <wim@fluendo.com>
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 #include "gst_private.h"
26 #include <gobject/gvaluecollector.h>
28 #include "gstelement.h"
30 #include "gstmarshal.h"
32 #include "gstscheduler.h"
36 #include "gst-i18n-lib.h"
38 /* Element signals and args */
55 extern void __gst_element_details_clear (GstElementDetails * dp);
56 extern void __gst_element_details_copy (GstElementDetails * dest,
57 const GstElementDetails * src);
59 static void gst_element_class_init (GstElementClass * klass);
60 static void gst_element_init (GstElement * element);
61 static void gst_element_base_class_init (gpointer g_class);
62 static void gst_element_base_class_finalize (gpointer g_class);
64 static void gst_element_dispose (GObject * object);
65 static void gst_element_finalize (GObject * object);
67 static GstElementStateReturn gst_element_change_state (GstElement * element);
68 static GstElementStateReturn gst_element_get_state_func (GstElement * element,
69 GstElementState * state, GstElementState * pending, GTimeVal * timeout);
70 static void gst_element_set_manager_func (GstElement * element,
71 GstPipeline * manager);
72 static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
73 static void gst_element_set_scheduler_func (GstElement * element,
74 GstScheduler * scheduler);
76 #ifndef GST_DISABLE_LOADSAVE
77 static xmlNodePtr gst_element_save_thyself (GstObject * object,
79 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self);
82 GType _gst_element_type = 0;
84 static GstObjectClass *parent_class = NULL;
85 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
88 gst_element_get_type (void)
90 if (!_gst_element_type) {
91 static const GTypeInfo element_info = {
92 sizeof (GstElementClass),
93 gst_element_base_class_init,
94 gst_element_base_class_finalize,
95 (GClassInitFunc) gst_element_class_init,
100 (GInstanceInitFunc) gst_element_init,
104 _gst_element_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
105 &element_info, G_TYPE_FLAG_ABSTRACT);
107 return _gst_element_type;
111 gst_element_class_init (GstElementClass * klass)
113 GObjectClass *gobject_class;
114 GstObjectClass *gstobject_class;
116 gobject_class = (GObjectClass *) klass;
117 gstobject_class = (GstObjectClass *) klass;
119 parent_class = g_type_class_ref (GST_TYPE_OBJECT);
122 * GstElement::state-change:
123 * @gstelement: the object which received the signal
127 * the #GstElementState of the element has been changed
129 gst_element_signals[STATE_CHANGE] =
130 g_signal_new ("state-change", G_TYPE_FROM_CLASS (klass),
131 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, state_change), NULL,
132 NULL, gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
134 * GstElement::new-pad:
135 * @gstelement: the object which received the signal
138 * a new #GstPad has been added to the element
140 gst_element_signals[NEW_PAD] =
141 g_signal_new ("new-pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
142 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
143 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
145 * GstElement::pad-removed:
146 * @gstelement: the object which received the signal
149 * a #GstPad has been removed from the element
151 gst_element_signals[PAD_REMOVED] =
152 g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
153 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
154 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
156 * GstElement::no-more-pads:
157 * @gstelement: the object which received the signal
161 gst_element_signals[NO_MORE_PADS] =
162 g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
163 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
164 NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
166 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
167 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_element_finalize);
169 #ifndef GST_DISABLE_LOADSAVE
170 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
171 gstobject_class->restore_thyself =
172 GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
175 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
176 klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
177 klass->set_manager = GST_DEBUG_FUNCPTR (gst_element_set_manager_func);
178 klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
179 klass->set_scheduler = GST_DEBUG_FUNCPTR (gst_element_set_scheduler_func);
180 klass->numpadtemplates = 0;
182 klass->elementfactory = NULL;
186 gst_element_base_class_init (gpointer g_class)
188 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
190 memset (&element_class->details, 0, sizeof (GstElementDetails));
191 element_class->padtemplates = NULL;
195 gst_element_base_class_finalize (gpointer g_class)
197 GstElementClass *klass = GST_ELEMENT_CLASS (g_class);
199 g_list_foreach (klass->padtemplates, (GFunc) gst_object_unref, NULL);
200 g_list_free (klass->padtemplates);
201 __gst_element_details_clear (&klass->details);
205 gst_element_init (GstElement * element)
207 element->current_state = GST_STATE_NULL;
208 element->pending_state = GST_STATE_VOID_PENDING;
209 element->state_lock = g_mutex_new ();
210 element->state_cond = g_cond_new ();
214 * gst_element_default_error:
215 * @object: a #GObject that signalled the error.
216 * @orig: the #GstObject that initiated the error.
217 * @error: the GError.
218 * @debug: an additional debug information string, or NULL.
220 * A default error signal callback to attach to an element.
221 * The user data passed to the g_signal_connect is ignored.
223 * The default handler will simply print the error string using g_print.
228 gst_element_default_error (GObject * object, GstObject * source, GError * error,
231 gchar *name = gst_object_get_path_string (source);
233 g_print (_("ERROR: from element %s: %s\n"), name, error->message);
235 g_print (_("Additional debug info:\n%s\n"), debug);
241 * gst_element_release_request_pad:
242 * @element: a #GstElement to release the request pad of.
243 * @pad: the #GstPad to release.
245 * Makes the element free the previously requested pad as obtained
246 * with gst_element_get_request_pad().
251 gst_element_release_request_pad (GstElement * element, GstPad * pad)
253 GstElementClass *oclass;
255 g_return_if_fail (GST_IS_ELEMENT (element));
256 g_return_if_fail (GST_IS_PAD (pad));
258 oclass = GST_ELEMENT_GET_CLASS (element);
260 if (oclass->release_pad)
261 (oclass->release_pad) (element, pad);
263 gst_element_remove_pad (element, pad);
267 * gst_element_requires_clock:
268 * @element: a #GstElement to query
270 * Query if the element requires a clock.
272 * Returns: TRUE if the element requires a clock
277 gst_element_requires_clock (GstElement * element)
279 gboolean result = FALSE;
281 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
283 result = (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
289 * gst_element_provides_clock:
290 * @element: a #GstElement to query
292 * Query if the element provides a clock.
294 * Returns: TRUE if the element provides a clock
299 gst_element_provides_clock (GstElement * element)
301 gboolean result = FALSE;
303 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
305 result = (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
311 * gst_element_set_clock:
312 * @element: a #GstElement to set the clock for.
313 * @clock: the #GstClock to set for the element.
315 * Sets the clock for the element. This function increases the
316 * refcount on the clock. Any previously set clock on the object
322 gst_element_set_clock (GstElement * element, GstClock * clock)
324 GstElementClass *oclass;
326 g_return_if_fail (GST_IS_ELEMENT (element));
328 oclass = GST_ELEMENT_GET_CLASS (element);
330 if (oclass->set_clock)
331 oclass->set_clock (element, clock);
334 gst_object_replace ((GstObject **) & element->clock, (GstObject *) clock);
335 GST_UNLOCK (element);
339 * gst_element_get_clock:
340 * @element: a #GstElement to get the clock of.
342 * Gets the clock of the element. If the element provides a clock,
343 * this function will return this clock. For elements that do not
344 * provide a clock, this function returns NULL.
346 * Returns: the #GstClock of the element. unref after usage.
351 gst_element_get_clock (GstElement * element)
353 GstElementClass *oclass;
355 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
357 oclass = GST_ELEMENT_GET_CLASS (element);
359 if (oclass->get_clock)
360 return oclass->get_clock (element);
365 #ifndef GST_DISABLE_INDEX
367 * gst_element_is_indexable:
368 * @element: a #GstElement.
370 * Queries if the element can be indexed.
372 * Returns: TRUE if the element can be indexed.
377 gst_element_is_indexable (GstElement * element)
379 gboolean result = FALSE;
381 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
383 result = (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
389 * gst_element_set_index:
390 * @element: a #GstElement.
391 * @index: a #GstIndex.
393 * Set the specified GstIndex on the element.
398 gst_element_set_index (GstElement * element, GstIndex * index)
400 GstElementClass *oclass;
402 g_return_if_fail (GST_IS_ELEMENT (element));
403 g_return_if_fail (GST_IS_INDEX (index));
405 oclass = GST_ELEMENT_GET_CLASS (element);
407 if (oclass->set_index)
408 oclass->set_index (element, index);
412 * gst_element_get_index:
413 * @element: a #GstElement.
415 * Gets the index from the element.
417 * Returns: a #GstIndex or NULL when no index was set on the
418 * element. unref after usage.
423 gst_element_get_index (GstElement * element)
425 GstElementClass *oclass;
427 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
429 oclass = GST_ELEMENT_GET_CLASS (element);
431 if (oclass->get_index)
432 return oclass->get_index (element);
439 * gst_element_add_pad:
440 * @element: a #GstElement to add the pad to.
441 * @pad: the #GstPad to add to the element.
443 * Adds a pad (link point) to @element. @pad's parent will be set to @element;
444 * see gst_object_set_parent() for refcounting information.
446 * Pads are not automatically activated so elements should perform the needed
447 * steps to activate the pad.
449 * The pad and the element should be unlocked when calling this function.
451 * Returns: TRUE if the pad could be added. This function can fail when
452 * passing bad arguments or when a pad with the same name already existed.
457 gst_element_add_pad (GstElement * element, GstPad * pad)
461 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
462 g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
464 /* locking pad to look at the name */
466 pad_name = g_strdup (GST_PAD_NAME (pad));
467 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
468 GST_STR_NULL (pad_name));
471 /* then check to see if there's already a pad by that name here */
473 if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, pad_name)))
476 /* try to set the pad's parent */
477 if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (pad),
478 GST_OBJECT_CAST (element))))
483 /* add it to the list */
484 switch (gst_pad_get_direction (pad)) {
486 element->srcpads = g_list_prepend (element->srcpads, pad);
487 element->numsrcpads++;
490 element->sinkpads = g_list_prepend (element->sinkpads, pad);
491 element->numsinkpads++;
496 element->pads = g_list_prepend (element->pads, pad);
498 element->pads_cookie++;
499 GST_UNLOCK (element);
501 /* emit the NEW_PAD signal */
502 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
509 g_critical ("Padname %s is not unique in element %s, not adding",
510 pad_name, GST_ELEMENT_NAME (element));
511 GST_UNLOCK (element);
518 ("Pad %s already has parent when trying to add to element %s",
519 pad_name, GST_ELEMENT_NAME (element));
520 GST_UNLOCK (element);
528 ("Trying to add pad %s to element %s, but it has no direction",
529 GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
531 GST_UNLOCK (element);
537 * gst_element_remove_pad:
538 * @element: a #GstElement to remove pad from.
539 * @pad: the #GstPad to remove from the element.
541 * Removes @pad from @element. @pad will be destroyed if it has not been
542 * referenced elsewhere.
544 * Returns: TRUE if the pad could be removed. Can return FALSE if the
545 * pad is not belonging to the provided element or when wrong parameters
546 * are passed to this function.
551 gst_element_remove_pad (GstElement * element, GstPad * pad)
556 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
557 g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
559 /* locking pad to look at the name and parent */
561 pad_name = g_strdup (GST_PAD_NAME (pad));
563 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'",
564 GST_STR_NULL (pad_name));
566 if (G_UNLIKELY (GST_PAD_PARENT (pad) != element))
572 peer = gst_pad_get_peer (pad);
576 /* window for MT unsafeness, someone else could unlink here
577 * and then we call unlink with wrong pads. The unlink
578 * function would catch this and safely return failed. */
579 if (GST_PAD_IS_SRC (pad))
580 gst_pad_unlink (pad, GST_PAD_CAST (peer));
582 gst_pad_unlink (GST_PAD_CAST (peer), pad);
584 gst_object_unref (GST_OBJECT (peer));
588 /* remove it from the list */
589 switch (gst_pad_get_direction (pad)) {
591 element->srcpads = g_list_remove (element->srcpads, pad);
592 element->numsrcpads--;
595 element->sinkpads = g_list_remove (element->sinkpads, pad);
596 element->numsinkpads--;
599 g_critical ("Removing pad without direction???");
602 element->pads = g_list_remove (element->pads, pad);
604 element->pads_cookie++;
605 GST_UNLOCK (element);
607 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
609 gst_object_unparent (GST_OBJECT (pad));
615 /* FIXME, locking order? */
617 g_critical ("Padname %s:%s does not belong to element %s when removing",
618 GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
619 GST_ELEMENT_NAME (element));
620 GST_UNLOCK (element);
628 * gst_element_no_more_pads:
629 * @element: a #GstElement
631 * Use this function to signal that the element does not expect any more pads
632 * to show up in the current pipeline. This function should be called whenever
633 * pads have been added by the element itself. Elements with GST_PAD_SOMETIMES
634 * pad templates use this in combination with autopluggers to figure out that
635 * the element is done initializing its pads.
640 gst_element_no_more_pads (GstElement * element)
642 g_return_if_fail (GST_IS_ELEMENT (element));
644 g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
648 pad_compare_name (GstPad * pad1, const gchar * name)
653 result = strcmp (GST_PAD_NAME (pad1), name);
660 * gst_element_get_static_pad:
661 * @element: a #GstElement to find a static pad of.
662 * @name: the name of the static #GstPad to retrieve.
664 * Retrieves a pad from @element by name. This version only retrieves
665 * already-existing (i.e. 'static') pads.
667 * Returns: the requested #GstPad if found, otherwise NULL. unref after
673 gst_element_get_static_pad (GstElement * element, const gchar * name)
676 GstPad *result = NULL;
678 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
679 g_return_val_if_fail (name != NULL, NULL);
683 g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
685 result = GST_PAD_CAST (find->data);
686 gst_object_ref (GST_OBJECT_CAST (result));
689 if (result == NULL) {
690 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
691 name, GST_ELEMENT_NAME (element));
693 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
694 GST_ELEMENT_NAME (element), name);
696 GST_UNLOCK (element);
702 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
705 GstPad *newpad = NULL;
706 GstElementClass *oclass;
708 oclass = GST_ELEMENT_GET_CLASS (element);
710 if (oclass->request_new_pad)
711 newpad = (oclass->request_new_pad) (element, templ, name);
714 gst_object_ref (GST_OBJECT (newpad));
720 * gst_element_get_request_pad:
721 * @element: a #GstElement to find a request pad of.
722 * @name: the name of the request #GstPad to retrieve.
724 * Retrieves a pad from the element by name. This version only retrieves
727 * Returns: requested #GstPad if found, otherwise NULL. Unref after usage.
730 gst_element_get_request_pad (GstElement * element, const gchar * name)
732 GstPadTemplate *templ = NULL;
734 const gchar *req_name = NULL;
735 gboolean templ_found = FALSE;
739 gchar *str, *endptr = NULL;
740 GstElementClass *class;
742 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
743 g_return_val_if_fail (name != NULL, NULL);
745 class = GST_ELEMENT_GET_CLASS (element);
747 if (strstr (name, "%")) {
748 templ = gst_element_class_get_pad_template (class, name);
753 list = gst_element_class_get_pad_template_list (class);
754 while (!templ_found && list) {
755 templ = (GstPadTemplate *) list->data;
756 if (templ->presence == GST_PAD_REQUEST) {
757 /* Because of sanity checks in gst_pad_template_new(), we know that %s
758 and %d, occurring at the end of the name_template, are the only
760 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
761 templ->name_template);
762 if ((str = strchr (templ->name_template, '%'))
763 && strncmp (templ->name_template, name,
764 str - templ->name_template) == 0
765 && strlen (name) > str - templ->name_template) {
766 data = name + (str - templ->name_template);
767 if (*(str + 1) == 'd') {
769 n = (gint) strtol (data, &endptr, 10);
770 if (endptr && *endptr == '\0') {
790 pad = gst_element_request_pad (element, templ, req_name);
796 * gst_element_get_pad:
797 * @element: a #GstElement.
798 * @name: the name of the pad to retrieve.
800 * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
801 * first, then gst_element_get_request_pad().
803 * Returns: the #GstPad if found, otherwise %NULL. Unref after usage.
806 gst_element_get_pad (GstElement * element, const gchar * name)
810 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
811 g_return_val_if_fail (name != NULL, NULL);
813 pad = gst_element_get_static_pad (element, name);
815 pad = gst_element_get_request_pad (element, name);
821 iterate_pad (GstIterator * it, GstPad * pad)
823 gst_object_ref (GST_OBJECT_CAST (pad));
824 return GST_ITERATOR_ITEM_PASS;
828 * gst_element_iterate_pads:
829 * @element: a #GstElement to iterate pads of.
831 * Retrieves an iterattor of @element's pads.
833 * Returns: the #GstIterator of #GstPad. unref each pad after usage.
838 gst_element_iterate_pads (GstElement * element)
842 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
845 gst_object_ref (GST_OBJECT (element));
846 result = gst_iterator_new_list (GST_GET_LOCK (element),
847 &element->pads_cookie,
850 (GstIteratorItemFunction) iterate_pad,
851 (GstIteratorDisposeFunction) gst_object_unref);
852 GST_UNLOCK (element);
859 * gst_element_class_add_pad_template:
860 * @klass: the #GstElementClass to add the pad template to.
861 * @templ: a #GstPadTemplate to add to the element class.
863 * Adds a padtemplate to an element class. This is mainly used in the _base_init
864 * functions of classes.
867 gst_element_class_add_pad_template (GstElementClass * klass,
868 GstPadTemplate * templ)
870 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
871 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
873 /* avoid registering pad templates with the same name */
874 g_return_if_fail (gst_element_class_get_pad_template (klass,
875 templ->name_template) == NULL);
877 klass->padtemplates = g_list_append (klass->padtemplates,
878 gst_object_ref (GST_OBJECT (templ)));
879 klass->numpadtemplates++;
883 * gst_element_class_set_details:
884 * @klass: class to set details for
885 * @details: details to set
887 * Sets the detailed information for a #GstElementClass.
888 * <note>This function is for use in _base_init functions only.</note>
891 gst_element_class_set_details (GstElementClass * klass,
892 const GstElementDetails * details)
894 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
895 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
897 __gst_element_details_copy (&klass->details, details);
901 * gst_element_class_get_pad_template_list:
902 * @element_class: a #GstElementClass to get pad templates of.
904 * Retrieves a list of the pad templates associated with @element_class. The
905 * list must not be modified by the calling code.
906 * <note>If you use this function in the #GInstanceInitFunc of an object class
907 * that has subclasses, make sure to pass the g_class parameter of the
908 * #GInstanceInitFunc here.</note>
910 * Returns: the #GList of padtemplates.
913 gst_element_class_get_pad_template_list (GstElementClass * element_class)
915 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
917 return element_class->padtemplates;
921 * gst_element_class_get_pad_template:
922 * @element_class: a #GstElementClass to get the pad template of.
923 * @name: the name of the #GstPadTemplate to get.
925 * Retrieves a padtemplate from @element_class with the given name.
926 * <note>If you use this function in the #GInstanceInitFunc of an object class
927 * that has subclasses, make sure to pass the g_class parameter of the
928 * #GInstanceInitFunc here.</note>
930 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
931 * No unreferencing is necessary.
934 gst_element_class_get_pad_template (GstElementClass * element_class,
939 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
940 g_return_val_if_fail (name != NULL, NULL);
942 padlist = gst_element_class_get_pad_template_list (element_class);
945 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
947 if (strcmp (padtempl->name_template, name) == 0)
950 padlist = g_list_next (padlist);
957 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
959 GstPad *result = NULL;
962 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
967 pads = element->srcpads;
971 pads = element->sinkpads;
974 goto wrong_direction;
976 for (; pads; pads = g_list_next (pads)) {
977 GstPad *pad = GST_PAD (pads->data);
980 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
981 GST_DEBUG_PAD_NAME (pad));
983 if (GST_PAD_IS_LINKED (pad)) {
988 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
989 GST_DEBUG_PAD_NAME (pad));
994 gst_object_ref (GST_OBJECT (result));
996 GST_UNLOCK (element);
1000 /* ERROR handling */
1003 g_warning ("unknown pad direction %d", dir);
1009 * gst_element_send_event:
1010 * @element: a #GstElement to send the event to.
1011 * @event: the #GstEvent to send to the element.
1013 * Sends an event to an element. If the element doesn't
1014 * implement an event handler, the event will be forwarded
1015 * to a random sink pad. This function takes owership of the
1016 * provided event so you should _ref it if you want to reuse
1017 * the event after this call.
1019 * Returns: TRUE if the event was handled.
1024 gst_element_send_event (GstElement * element, GstEvent * event)
1026 GstElementClass *oclass;
1027 gboolean result = FALSE;
1029 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1030 g_return_val_if_fail (event != NULL, FALSE);
1032 oclass = GST_ELEMENT_GET_CLASS (element);
1034 if (oclass->send_event) {
1035 result = oclass->send_event (element, event);
1037 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1040 GstPad *peer = gst_pad_get_peer (pad);
1043 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1044 "sending event to random pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1046 result = gst_pad_send_event (peer, event);
1047 gst_object_unref (GST_OBJECT (peer));
1049 gst_object_unref (GST_OBJECT (pad));
1052 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1053 GST_ELEMENT_NAME (element));
1060 * @element: a #GstElement to send the event to.
1061 * @seek_type: the method to use for seeking.
1062 * @offset: the offset to seek to.
1064 * Sends a seek event to an element.
1066 * Returns: TRUE if the event was handled.
1071 gst_element_seek (GstElement * element, GstSeekType seek_type, guint64 offset)
1076 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1078 event = gst_event_new_seek (seek_type, offset);
1079 result = gst_element_send_event (element, event);
1085 * gst_element_get_query_types:
1086 * @element: a #GstElement to query
1088 * Get an array of query types from the element.
1089 * If the element doesn't implement a query types function,
1090 * the query will be forwarded to a random sink pad.
1092 * Returns: An array of #GstQueryType elements that should not
1093 * be freed or modified.
1097 const GstQueryType *
1098 gst_element_get_query_types (GstElement * element)
1100 GstElementClass *oclass;
1101 const GstQueryType *result = NULL;
1103 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1105 oclass = GST_ELEMENT_GET_CLASS (element);
1107 if (oclass->get_query_types) {
1108 result = oclass->get_query_types (element);
1110 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1113 GstPad *peer = gst_pad_get_peer (pad);
1116 result = gst_pad_get_query_types (peer);
1118 gst_object_unref (GST_OBJECT (peer));
1120 gst_object_unref (GST_OBJECT (pad));
1127 * gst_element_query:
1128 * @element: a #GstElement to perform the query on.
1129 * @type: the #GstQueryType.
1130 * @format: the #GstFormat pointer to hold the format of the result.
1131 * @value: the pointer to the value of the result.
1133 * Performs a query on the given element. If the format is set
1134 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1135 * format pointer will hold the default format.
1136 * For element that don't implement a query handler, this function
1137 * forwards the query to a random usable sinkpad of this element.
1139 * Returns: TRUE if the query could be performed.
1144 gst_element_query (GstElement * element, GstQuery * query)
1146 GstElementClass *oclass;
1147 gboolean result = FALSE;
1149 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1150 g_return_val_if_fail (query != NULL, FALSE);
1152 oclass = GST_ELEMENT_GET_CLASS (element);
1154 if (oclass->query) {
1155 result = oclass->query (element, query);
1157 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
1160 result = gst_pad_query (pad, query);
1162 gst_object_unref (GST_OBJECT (pad));
1164 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1166 GstPad *peer = gst_pad_get_peer (pad);
1169 result = gst_pad_query (peer, query);
1171 gst_object_unref (GST_OBJECT (peer));
1173 gst_object_unref (GST_OBJECT (pad));
1181 * gst_element_post_message:
1182 * @element: a #GstElement posting the message
1183 * @message: a #GstMessage to post
1185 * Post a message on the elements #GstBus.
1187 * Returns: TRUE if the message was successfuly posted.
1192 gst_element_post_message (GstElement * element, GstMessage * message)
1195 gboolean result = FALSE;
1197 GST_DEBUG ("posting message %p ...", message);
1199 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1200 g_return_val_if_fail (message != NULL, FALSE);
1205 if (G_UNLIKELY (bus == NULL)) {
1206 GST_DEBUG ("... but I won't because I have no bus");
1207 GST_UNLOCK (element);
1208 gst_message_unref (message);
1211 gst_object_ref (GST_OBJECT (bus));
1212 GST_DEBUG ("... on bus %p", bus);
1213 GST_UNLOCK (element);
1215 result = gst_bus_post (bus, message);
1216 gst_object_unref (GST_OBJECT (bus));
1222 * _gst_element_error_printf:
1223 * @format: the printf-like format to use, or NULL
1225 * This function is only used internally by the #gst_element_error macro.
1227 * Returns: a newly allocated string, or NULL if the format was NULL or ""
1232 _gst_element_error_printf (const gchar * format, ...)
1242 va_start (args, format);
1243 buffer = g_strdup_vprintf (format, args);
1249 * gst_element_message_full:
1250 * @element: a #GstElement to send message from
1251 * @type: the #GstMessageType
1252 * @domain: the GStreamer GError domain this message belongs to
1253 * @code: the GError code belonging to the domain
1254 * @text: an allocated text string to be used as a replacement for the
1255 * default message connected to code, or NULL
1256 * @debug: an allocated debug message to be used as a replacement for the
1257 * default debugging information, or NULL
1258 * @file: the source code file where the error was generated
1259 * @function: the source code function where the error was generated
1260 * @line: the source code line where the error was generated
1262 * Post an error or warning message on the bus from inside an element.
1266 void gst_element_message_full
1267 (GstElement * element, GstMessageType type,
1268 GQuark domain, gint code, gchar * text,
1269 gchar * debug, const gchar * file, const gchar * function, gint line)
1271 GError *gerror = NULL;
1275 GstMessage *message = NULL;
1278 GST_DEBUG ("start");
1279 g_return_if_fail (GST_IS_ELEMENT (element));
1280 g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1281 (type == GST_MESSAGE_WARNING));
1283 /* check if we send the given text or the default error text */
1284 if ((text == NULL) || (text[0] == 0)) {
1285 /* text could have come from g_strdup_printf (""); */
1287 sent_text = gst_error_get_message (domain, code);
1291 /* construct a sent_debug with extra information from source */
1292 if ((debug == NULL) || (debug[0] == 0)) {
1293 /* debug could have come from g_strdup_printf (""); */
1296 name = gst_object_get_path_string (GST_OBJECT (element));
1297 sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
1298 file, line, function, name, debug ? debug : "");
1303 /* create gerror and post message */
1304 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1306 gerror = g_error_new_literal (domain, code, sent_text);
1308 if (type == GST_MESSAGE_ERROR) {
1309 message = gst_message_new_error (GST_OBJECT (element), gerror, sent_debug);
1311 message = gst_message_new_warning (GST_OBJECT (element), gerror,
1314 gst_element_post_message (element, message);
1316 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted message: %s",
1321 /* sent_debug is not part of the gerror, so don't free it here */
1325 * gst_element_is_locked_state:
1326 * @element: a #GstElement.
1328 * Checks if the state of an element is locked.
1329 * If the state of an element is locked, state changes of the parent don't
1330 * affect the element.
1331 * This way you can leave currently unused elements inside bins. Just lock their
1332 * state before changing the state from #GST_STATE_NULL.
1334 * Returns: TRUE, if the element's state is locked.
1339 gst_element_is_locked_state (GstElement * element)
1341 gboolean result = FALSE;
1343 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1346 result = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1347 GST_UNLOCK (element);
1353 * gst_element_set_locked_state:
1354 * @element: a #GstElement
1355 * @locked_state: TRUE to lock the element's state
1357 * Locks the state of an element, so state changes of the parent don't affect
1358 * this element anymore.
1360 * Returns: TRUE if the state was changed, FALSE if bad params were given or
1361 * the element was already in the correct state.
1366 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
1370 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1373 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1375 if (G_UNLIKELY (old == locked_state))
1379 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
1380 GST_ELEMENT_NAME (element));
1381 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
1383 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
1384 GST_ELEMENT_NAME (element));
1385 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
1387 GST_UNLOCK (element);
1392 GST_UNLOCK (element);
1398 * gst_element_sync_state_with_parent:
1399 * @element: a #GstElement.
1401 * Tries to change the state of the element to the same as its parent.
1402 * If this function returns FALSE, the state of element is undefined.
1404 * Returns: TRUE, if the element's state could be synced to the parent's state.
1407 gst_element_sync_state_with_parent (GstElement * element)
1411 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1412 parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
1413 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
1415 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
1416 GST_ELEMENT_NAME (element),
1417 gst_element_state_get_name (GST_STATE (element)),
1418 GST_ELEMENT_NAME (parent),
1419 gst_element_state_get_name (GST_STATE (parent)));
1421 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
1428 static GstElementStateReturn
1429 gst_element_get_state_func (GstElement * element,
1430 GstElementState * state, GstElementState * pending, GTimeVal * timeout)
1432 GstElementStateReturn ret = GST_STATE_FAILURE;
1433 GstElementState old_pending;
1435 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
1437 GST_STATE_LOCK (element);
1438 /* we got an error, report immediatly */
1439 if (GST_STATE_NO_PREROLL (element)) {
1440 ret = GST_STATE_NO_PREROLL;
1444 /* we got an error, report immediatly */
1445 if (GST_STATE_ERROR (element)) {
1446 ret = GST_STATE_FAILURE;
1450 old_pending = GST_STATE_PENDING (element);
1451 if (old_pending != GST_STATE_VOID_PENDING) {
1452 GTimeVal *timeval, abstimeout;
1454 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "wait for pending");
1456 /* make timeout absolute */
1457 g_get_current_time (&abstimeout);
1458 g_time_val_add (&abstimeout,
1459 timeout->tv_sec * G_USEC_PER_SEC + timeout->tv_usec);
1460 timeval = &abstimeout;
1464 /* we have a pending state change, wait for it to complete */
1465 if (!GST_STATE_TIMED_WAIT (element, timeval)) {
1466 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timeout");
1467 /* timeout triggered */
1468 ret = GST_STATE_ASYNC;
1470 /* could be success or failure */
1471 if (old_pending == GST_STATE (element)) {
1472 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got success");
1473 ret = GST_STATE_SUCCESS;
1475 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got failure");
1476 ret = GST_STATE_FAILURE;
1480 /* if nothing is pending anymore we can return SUCCESS */
1481 if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
1482 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
1483 ret = GST_STATE_SUCCESS;
1488 *state = GST_STATE (element);
1490 *pending = GST_STATE_PENDING (element);
1492 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1493 "state current: %s, pending: %s, error: %d, no_preroll: %d, result: %d",
1494 gst_element_state_get_name (GST_STATE (element)),
1495 gst_element_state_get_name (GST_STATE_PENDING (element)),
1496 GST_STATE_ERROR (element), GST_STATE_NO_PREROLL (element), ret);
1498 GST_STATE_UNLOCK (element);
1504 * gst_element_get_state:
1505 * @element: a #GstElement to get the state of.
1506 * @state: a pointer to #GstElementState to hold the state. Can be NULL.
1507 * @pending: a pointer to #GstElementState to hold the pending state.
1509 * @timeout: a #GTimeVal to specify the timeout for an async
1510 * state change or NULL for infinite timeout.
1512 * Gets the state of the element.
1514 * For elements that performed an ASYNC state change, as reported by
1515 * #gst_element_set_state(), this function will block up to the
1516 * specified timeout value for the state change to complete.
1517 * If the element completes the state change or goes into
1518 * an error, this function returns immediatly with a return value of
1519 * GST_STATE_SUCCESS or GST_STATE_FAILURE respectively.
1521 * Returns: GST_STATE_SUCCESS if the element has no more pending state and
1522 * the last state change succeeded, GST_STATE_ASYNC
1523 * if the element is still performing a state change or
1524 * GST_STATE_FAILURE if the last state change failed.
1528 GstElementStateReturn
1529 gst_element_get_state (GstElement * element,
1530 GstElementState * state, GstElementState * pending, GTimeVal * timeout)
1532 GstElementClass *oclass;
1533 GstElementStateReturn result = GST_STATE_FAILURE;
1535 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
1537 oclass = GST_ELEMENT_GET_CLASS (element);
1539 if (oclass->get_state)
1540 result = (oclass->get_state) (element, state, pending, timeout);
1546 * gst_element_abort_state:
1547 * @element: a #GstElement to abort the state of.
1549 * Abort the state change of the element. This function is used
1550 * by elements that do asynchronous state changes and find out
1551 * something is wrong.
1553 * This function should be called with the STATE_LOCK held.
1558 gst_element_abort_state (GstElement * element)
1560 GstElementState pending;
1562 g_return_if_fail (GST_IS_ELEMENT (element));
1564 pending = GST_STATE_PENDING (element);
1566 if (pending != GST_STATE_VOID_PENDING && !GST_STATE_ERROR (element)) {
1567 #ifndef GST_DISABLE_GST_DEBUG
1568 GstElementState old_state = GST_STATE (element);
1571 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1572 "aborting state from %s to %s", gst_element_state_get_name (old_state),
1573 gst_element_state_get_name (pending));
1576 GST_STATE_ERROR (element) = TRUE;
1578 GST_STATE_BROADCAST (element);
1583 * gst_element_commit_state:
1584 * @element: a #GstElement to commit the state of.
1586 * Commit the state change of the element. This function is used
1587 * by elements that do asynchronous state changes.
1589 * This function can only be called with the STATE_LOCK held.
1594 gst_element_commit_state (GstElement * element)
1596 GstElementState pending;
1597 GstMessage *message;
1599 g_return_if_fail (GST_IS_ELEMENT (element));
1601 pending = GST_STATE_PENDING (element);
1603 if (pending != GST_STATE_VOID_PENDING) {
1604 GstElementState old_state = GST_STATE (element);
1606 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1607 "commiting state from %s to %s", gst_element_state_get_name (old_state),
1608 gst_element_state_get_name (pending));
1610 GST_STATE (element) = pending;
1611 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
1612 GST_STATE_ERROR (element) = FALSE;
1614 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
1615 0, old_state, pending);
1616 message = gst_message_new_state_changed (GST_OBJECT (element),
1617 old_state, pending);
1618 gst_element_post_message (element, message);
1619 GST_STATE_BROADCAST (element);
1624 * gst_element_lost_state:
1625 * @element: a #GstElement the state is lost of
1627 * Brings the element to the lost state. The current state of the
1628 * element is copied to the pending state so that any call to
1629 * #gst_element_get_state() will return ASYNC.
1630 * This is mostly used for elements that lost their preroll buffer
1631 * in the PAUSED state after a flush, they become PAUSED again
1632 * if a new preroll buffer is queued.
1633 * This function can only be called when the element is currently
1634 * not in error or an async state change.
1636 * This function can only be called with the STATE_LOCK held.
1641 gst_element_lost_state (GstElement * element)
1643 g_return_if_fail (GST_IS_ELEMENT (element));
1645 if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
1646 !GST_STATE_ERROR (element)) {
1647 GstElementState current_state = GST_STATE (element);
1649 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1650 "lost state of %s", gst_element_state_get_name (current_state));
1652 GST_STATE_PENDING (element) = current_state;
1653 GST_STATE_ERROR (element) = FALSE;
1658 * gst_element_set_state:
1659 * @element: a #GstElement to change state of.
1660 * @state: the element's new #GstElementState.
1662 * Sets the state of the element. This function will try to set the
1663 * requested state by going through all the intermediary states and calling
1664 * the class's state change function for each.
1666 * Returns: Result of the state change using #GstElementStateReturn.
1670 GstElementStateReturn
1671 gst_element_set_state (GstElement * element, GstElementState state)
1673 GstElementClass *oclass;
1674 GstElementState current;
1675 GstElementStateReturn return_val = GST_STATE_SUCCESS;
1676 GstElementStateReturn ret;
1677 GstElementState pending;
1681 /* get current element state, need to call the method so that
1682 * we call the virtual method and subclasses can implement their
1684 GST_TIME_TO_TIMEVAL (0, tv);
1685 ret = gst_element_get_state (element, ¤t, &pending, &tv);
1687 /* get the element state lock */
1688 GST_STATE_LOCK (element);
1689 /* this is the state we should go to */
1690 GST_STATE_FINAL (element) = state;
1691 if (ret == GST_STATE_ASYNC) {
1692 gst_element_commit_state (element);
1695 /* start with the current state */
1696 current = GST_STATE (element);
1698 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
1699 gst_element_state_get_name (current), gst_element_state_get_name (state));
1701 oclass = GST_ELEMENT_GET_CLASS (element);
1703 /* We always perform at least one state change, even if the
1704 * current state is equal to the required state. This is needed
1705 * for bins that sync their children. */
1707 GstElementState pending;
1709 /* calculate the pending state */
1710 if (current < state)
1711 pending = current << 1;
1712 else if (current > state)
1713 pending = current >> 1;
1717 /* set the pending state variable */
1718 GST_STATE_PENDING (element) = pending;
1720 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1721 "%s: setting state from %s to %s",
1722 (pending != state ? "intermediate" : "final"),
1723 gst_element_state_get_name (current),
1724 gst_element_state_get_name (pending));
1726 /* call the state change function so it can set the state */
1727 if (oclass->change_state)
1728 return_val = (oclass->change_state) (element);
1730 return_val = GST_STATE_FAILURE;
1732 /* clear the error and preroll flag, we need to do that after
1733 * calling the virtual change_state function so that it can use the
1734 * old previous value. */
1735 GST_STATE_ERROR (element) = FALSE;
1736 GST_STATE_NO_PREROLL (element) = FALSE;
1738 switch (return_val) {
1739 case GST_STATE_FAILURE:
1740 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1741 "have failed change_state return");
1742 /* state change failure exits the loop */
1743 gst_element_abort_state (element);
1745 case GST_STATE_ASYNC:
1746 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1747 "element will change state async");
1748 /* an async state change exits the loop, we can only
1749 * go to the next state change when this one completes. */
1751 case GST_STATE_SUCCESS:
1752 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1753 "element changed state successfuly");
1754 /* we can commit the state now and proceed to the next state */
1755 gst_element_commit_state (element);
1756 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
1758 case GST_STATE_NO_PREROLL:
1759 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1760 "element changed state successfuly and can't preroll");
1761 /* we can commit the state now and proceed to the next state */
1762 gst_element_commit_state (element);
1763 GST_STATE_NO_PREROLL (element) = TRUE;
1764 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
1767 goto invalid_return;
1769 /* get the current state of the element and see if we need to do more
1771 current = GST_STATE (element);
1773 while (current != state);
1776 GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1777 GST_STATE_UNLOCK (element);
1779 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change");
1786 GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1787 GST_STATE_UNLOCK (element);
1788 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
1789 g_critical ("unknown return value %d from a state change function",
1791 return GST_STATE_FAILURE;
1795 /* is called with STATE_LOCK
1797 * This function activates the pads of a given element.
1799 * TODO: activate pads from src to sinks?
1800 * move pad activate logic to GstPad because we also need this
1801 * when pads are added to elements?
1804 gst_element_pads_activate (GstElement * element, gboolean active)
1813 pads = element->pads;
1814 cookie = element->pads_cookie;
1815 for (; pads && result; pads = g_list_next (pads)) {
1817 gboolean pad_loop, pad_get;
1818 gboolean done = FALSE;
1820 pad = GST_PAD (pads->data);
1821 gst_object_ref (GST_OBJECT (pad));
1822 GST_UNLOCK (element);
1825 pad_get = GST_PAD_IS_SINK (pad) && gst_pad_check_pull_range (pad);
1827 /* see if the pad has a loop function and grab
1830 pad_loop = GST_PAD_LOOPFUNC (pad) != NULL;
1831 peer = GST_PAD_PEER (pad);
1833 gst_object_ref (GST_OBJECT_CAST (peer));
1836 GST_DEBUG ("pad %s:%s: get: %d, loop: %d",
1837 GST_DEBUG_PAD_NAME (pad), pad_get, pad_loop);
1840 gboolean peer_loop, peer_get;
1842 /* see if the peer has a getrange function */
1843 peer_get = GST_PAD_IS_SINK (peer)
1844 && gst_pad_check_pull_range (GST_PAD_CAST (peer));
1845 /* see if the peer has a loop function */
1846 peer_loop = GST_PAD_LOOPFUNC (peer) != NULL;
1848 GST_DEBUG ("peer %s:%s: get: %d, loop: %d",
1849 GST_DEBUG_PAD_NAME (peer), peer_get, peer_loop);
1851 /* If the pad is a sink with loop and the peer has a get function,
1852 * we can activate the sinkpad, FIXME, logic is reversed as
1853 * check_pull_range() checks the peer of the given pad. */
1854 if ((pad_get && pad_loop) || (peer_get && peer_loop)) {
1855 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1856 "activating pad %s in pull mode", GST_OBJECT_NAME (pad));
1858 result &= gst_pad_set_active (pad, GST_ACTIVATE_PULL);
1861 gst_object_unref (GST_OBJECT_CAST (peer));
1865 /* all other conditions are just push based pads */
1866 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1867 "activating pad %s in push mode", GST_OBJECT_NAME (pad));
1869 result &= gst_pad_set_active (pad, GST_ACTIVATE_PUSH);
1872 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1873 "deactivating pad %s", GST_OBJECT_NAME (pad));
1875 result &= gst_pad_set_active (pad, GST_ACTIVATE_NONE);
1878 gst_object_unref (GST_OBJECT_CAST (pad));
1880 if (cookie != element->pads_cookie)
1883 GST_UNLOCK (element);
1888 /* is called with STATE_LOCK */
1889 static GstElementStateReturn
1890 gst_element_change_state (GstElement * element)
1892 GstElementState old_state;
1893 gint old_pending, old_transition;
1894 GstElementStateReturn result = GST_STATE_SUCCESS;
1896 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
1898 old_state = GST_STATE (element);
1899 old_pending = GST_STATE_PENDING (element);
1900 old_transition = GST_STATE_TRANSITION (element);
1902 /* if the element already is in the given state, we just return success */
1903 if (old_pending == GST_STATE_VOID_PENDING ||
1904 old_state == GST_STATE_PENDING (element)) {
1905 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1906 "element is already in the %s state",
1907 gst_element_state_get_name (old_state));
1908 if (GST_STATE_NO_PREROLL (element))
1909 return GST_STATE_NO_PREROLL;
1911 return GST_STATE_SUCCESS;
1914 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
1915 "default handler tries setting state from %s to %s (%04x)",
1916 gst_element_state_get_name (old_state),
1917 gst_element_state_get_name (old_pending), old_transition);
1919 switch (old_transition) {
1920 case GST_STATE_NULL_TO_READY:
1922 case GST_STATE_READY_TO_PAUSED:
1923 if (!gst_element_pads_activate (element, TRUE)) {
1924 result = GST_STATE_FAILURE;
1927 case GST_STATE_PAUSED_TO_PLAYING:
1929 if (GST_ELEMENT_MANAGER (element)) {
1930 element->base_time =
1931 GST_ELEMENT_CAST (GST_ELEMENT_MANAGER (element))->base_time;
1933 GST_UNLOCK (element);
1935 case GST_STATE_PLAYING_TO_PAUSED:
1937 case GST_STATE_PAUSED_TO_READY:
1938 case GST_STATE_READY_TO_NULL:
1939 /* deactivate pads in both cases, since they are activated on
1940 ready->paused but the element might not have made it to paused */
1941 if (!gst_element_pads_activate (element, FALSE)) {
1942 result = GST_STATE_FAILURE;
1944 element->base_time = 0;
1948 /* this will catch real but unhandled state changes;
1949 * can only be caused by:
1950 * - a new state was added
1951 * - somehow the element was asked to jump across an intermediate state
1953 g_warning ("Unhandled state change from %s to %s",
1954 gst_element_state_get_name (old_state),
1955 gst_element_state_get_name (old_pending));
1963 * gst_element_get_factory:
1964 * @element: a #GstElement to request the element factory of.
1966 * Retrieves the factory that was used to create this element.
1968 * Returns: the #GstElementFactory used for creating this element.
1971 gst_element_get_factory (GstElement * element)
1973 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1975 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
1979 gst_element_dispose (GObject * object)
1981 GstElement *element = GST_ELEMENT (object);
1983 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
1985 /* ref so we don't hit 0 again */
1986 gst_object_ref (GST_OBJECT (object));
1988 /* first we break all our links with the ouside */
1989 while (element->pads) {
1990 gst_element_remove_pad (element, GST_PAD (element->pads->data));
1992 if (G_UNLIKELY (element->pads != 0)) {
1993 g_critical ("could not remove pads from element %s",
1994 GST_STR_NULL (GST_OBJECT_NAME (object)));
1998 gst_object_replace ((GstObject **) & element->manager, NULL);
1999 gst_object_replace ((GstObject **) & element->clock, NULL);
2000 GST_UNLOCK (element);
2002 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent");
2004 G_OBJECT_CLASS (parent_class)->dispose (object);
2008 gst_element_finalize (GObject * object)
2010 GstElement *element = GST_ELEMENT (object);
2012 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
2014 GST_STATE_LOCK (element);
2015 if (element->state_cond)
2016 g_cond_free (element->state_cond);
2017 element->state_cond = NULL;
2018 GST_STATE_UNLOCK (element);
2019 g_mutex_free (element->state_lock);
2021 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
2023 G_OBJECT_CLASS (parent_class)->finalize (object);
2026 #ifndef GST_DISABLE_LOADSAVE
2028 * gst_element_save_thyself:
2029 * @element: a #GstElement to save.
2030 * @parent: the xml parent node.
2032 * Saves the element as part of the given XML structure.
2034 * Returns: the new #xmlNodePtr.
2037 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
2040 GstElementClass *oclass;
2041 GParamSpec **specs, *spec;
2044 GValue value = { 0, };
2045 GstElement *element;
2047 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2049 element = GST_ELEMENT (object);
2051 oclass = GST_ELEMENT_GET_CLASS (element);
2053 xmlNewChild (parent, NULL, (xmlChar *) "name",
2054 (xmlChar *) GST_ELEMENT_NAME (element));
2056 if (oclass->elementfactory != NULL) {
2057 GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
2059 xmlNewChild (parent, NULL, (xmlChar *) "type",
2060 (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
2063 /* FIXME: what is this? */
2064 /* if (element->manager) */
2065 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2068 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2070 for (i = 0; i < nspecs; i++) {
2072 if (spec->flags & G_PARAM_READABLE) {
2076 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2078 g_object_get_property (G_OBJECT (element), spec->name, &value);
2079 param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
2080 xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
2082 if (G_IS_PARAM_SPEC_STRING (spec))
2083 contents = g_value_dup_string (&value);
2084 else if (G_IS_PARAM_SPEC_ENUM (spec))
2085 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2086 else if (G_IS_PARAM_SPEC_INT64 (spec))
2087 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2088 g_value_get_int64 (&value));
2090 contents = g_strdup_value_contents (&value);
2092 xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
2095 g_value_unset (&value);
2099 pads = GST_ELEMENT_PADS (element);
2102 GstPad *pad = GST_PAD (pads->data);
2104 /* figure out if it's a direct pad or a ghostpad */
2105 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2106 xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
2108 gst_object_save_thyself (GST_OBJECT (pad), padtag);
2110 pads = g_list_next (pads);
2117 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
2119 xmlNodePtr children;
2120 GstElement *element;
2122 gchar *value = NULL;
2124 element = GST_ELEMENT (object);
2125 g_return_if_fail (element != NULL);
2128 children = self->xmlChildrenNode;
2130 if (!strcmp ((char *) children->name, "param")) {
2131 xmlNodePtr child = children->xmlChildrenNode;
2134 if (!strcmp ((char *) child->name, "name")) {
2135 name = (gchar *) xmlNodeGetContent (child);
2136 } else if (!strcmp ((char *) child->name, "value")) {
2137 value = (gchar *) xmlNodeGetContent (child);
2139 child = child->next;
2141 /* FIXME: can this just be g_object_set ? */
2142 gst_util_set_object_arg (G_OBJECT (element), name, value);
2143 /* g_object_set (G_OBJECT (element), name, value, NULL); */
2147 children = children->next;
2151 children = self->xmlChildrenNode;
2153 if (!strcmp ((char *) children->name, "pad")) {
2154 gst_pad_load_and_link (children, GST_OBJECT (element));
2156 children = children->next;
2159 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2160 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2162 #endif /* GST_DISABLE_LOADSAVE */
2165 gst_element_set_manager_func (GstElement * element, GstPipeline * manager)
2167 g_return_if_fail (GST_IS_ELEMENT (element));
2169 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting manager to %p",
2172 /* setting the manager cannot increase the refcount */
2174 GST_ELEMENT_MANAGER (element) = manager;
2175 GST_UNLOCK (element);
2179 gst_element_set_bus_func (GstElement * element, GstBus * bus)
2181 g_return_if_fail (GST_IS_ELEMENT (element));
2183 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
2186 gst_object_replace ((GstObject **) & GST_ELEMENT_BUS (element),
2188 GST_UNLOCK (element);
2192 gst_element_set_scheduler_func (GstElement * element, GstScheduler * scheduler)
2194 g_return_if_fail (GST_IS_ELEMENT (element));
2196 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",
2200 gst_object_replace ((GstObject **) & GST_ELEMENT_SCHEDULER (element),
2201 GST_OBJECT (scheduler));
2202 GST_UNLOCK (element);
2206 * gst_element_set_manager:
2207 * @element: a #GstElement to set the manager of.
2208 * @manager: the #GstManager to set.
2210 * Sets the manager of the element. For internal use only, unless you're
2211 * writing a new bin subclass.
2216 gst_element_set_manager (GstElement * element, GstPipeline * manager)
2218 GstElementClass *oclass;
2220 g_return_if_fail (GST_IS_ELEMENT (element));
2222 oclass = GST_ELEMENT_GET_CLASS (element);
2224 if (oclass->set_manager)
2225 oclass->set_manager (element, manager);
2230 * gst_element_get_manager:
2231 * @element: a #GstElement to get the manager of.
2233 * Returns the manager of the element.
2235 * Returns: the element's #GstPipeline. unref after usage.
2240 gst_element_get_manager (GstElement * element)
2242 GstPipeline *result = NULL;
2244 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2247 result = GST_ELEMENT_MANAGER (element);
2248 gst_object_ref (GST_OBJECT (result));
2249 GST_UNLOCK (element);
2255 * gst_element_set_bus:
2256 * @element: a #GstElement to set the bus of.
2257 * @bus: the #GstBus to set.
2259 * Sets the bus of the element. For internal use only, unless you're
2265 gst_element_set_bus (GstElement * element, GstBus * bus)
2267 GstElementClass *oclass;
2269 g_return_if_fail (GST_IS_ELEMENT (element));
2271 oclass = GST_ELEMENT_GET_CLASS (element);
2273 if (oclass->set_bus)
2274 oclass->set_bus (element, bus);
2278 * gst_element_get_bus:
2279 * @element: a #GstElement to get the bus of.
2281 * Returns the bus of the element.
2283 * Returns: the element's #GstBus.
2288 gst_element_get_bus (GstElement * element)
2290 GstBus *result = NULL;
2292 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2295 result = GST_ELEMENT_BUS (element);
2296 GST_UNLOCK (element);
2302 * gst_element_set_scheduler:
2303 * @element: a #GstElement to set the scheduler of.
2304 * @scheduler: the #GstScheduler to set.
2306 * Sets the scheduler of the element. For internal use only, unless you're
2312 gst_element_set_scheduler (GstElement * element, GstScheduler * scheduler)
2314 GstElementClass *oclass;
2316 g_return_if_fail (GST_IS_ELEMENT (element));
2318 oclass = GST_ELEMENT_GET_CLASS (element);
2320 if (oclass->set_scheduler)
2321 oclass->set_scheduler (element, scheduler);
2325 * gst_element_get_scheduler:
2326 * @element: a #GstElement to get the scheduler of.
2328 * Returns the scheduler of the element.
2330 * Returns: the element's #GstScheduler.
2335 gst_element_get_scheduler (GstElement * element)
2337 GstScheduler *result = NULL;
2339 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2342 result = GST_ELEMENT_SCHEDULER (element);
2343 GST_UNLOCK (element);