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 (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 (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 (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 (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 use.
838 gst_element_iterate_pads (GstElement * element)
842 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
845 gst_object_ref (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);
858 direction_filter (gconstpointer pad, gconstpointer direction)
860 if (GST_PAD_DIRECTION (pad) == GPOINTER_TO_INT (direction)) {
861 /* pass the ref through */
865 /* FIXME: this is very stupid */
866 gst_object_unref (GST_OBJECT_CAST (pad));
872 * gst_element_iterate_src_pads:
873 * @element: a #GstElement.
875 * Retrieves an iterator of @element's source pads.
877 * Returns: the #GstIterator of #GstPad. Unref each pad after use.
882 gst_element_iterate_src_pads (GstElement * element)
884 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
886 return gst_iterator_filter (gst_element_iterate_pads (element),
887 direction_filter, GINT_TO_POINTER (GST_PAD_SRC));
891 * gst_element_iterate_sink_pads:
892 * @element: a #GstElement.
894 * Retrieves an iterator of @element's sink pads.
896 * Returns: the #GstIterator of #GstPad. Unref each pad after use.
901 gst_element_iterate_sink_pads (GstElement * element)
903 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
905 return gst_iterator_filter (gst_element_iterate_pads (element),
906 direction_filter, GINT_TO_POINTER (GST_PAD_SINK));
910 * gst_element_class_add_pad_template:
911 * @klass: the #GstElementClass to add the pad template to.
912 * @templ: a #GstPadTemplate to add to the element class.
914 * Adds a padtemplate to an element class. This is mainly used in the _base_init
915 * functions of classes.
918 gst_element_class_add_pad_template (GstElementClass * klass,
919 GstPadTemplate * templ)
921 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
922 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
924 /* avoid registering pad templates with the same name */
925 g_return_if_fail (gst_element_class_get_pad_template (klass,
926 templ->name_template) == NULL);
928 klass->padtemplates = g_list_append (klass->padtemplates,
929 gst_object_ref (templ));
930 klass->numpadtemplates++;
934 * gst_element_class_set_details:
935 * @klass: class to set details for
936 * @details: details to set
938 * Sets the detailed information for a #GstElementClass.
939 * <note>This function is for use in _base_init functions only.</note>
942 gst_element_class_set_details (GstElementClass * klass,
943 const GstElementDetails * details)
945 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
946 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
948 __gst_element_details_copy (&klass->details, details);
952 * gst_element_class_get_pad_template_list:
953 * @element_class: a #GstElementClass to get pad templates of.
955 * Retrieves a list of the pad templates associated with @element_class. The
956 * list must not be modified by the calling code.
957 * <note>If you use this function in the #GInstanceInitFunc of an object class
958 * that has subclasses, make sure to pass the g_class parameter of the
959 * #GInstanceInitFunc here.</note>
961 * Returns: the #GList of padtemplates.
964 gst_element_class_get_pad_template_list (GstElementClass * element_class)
966 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
968 return element_class->padtemplates;
972 * gst_element_class_get_pad_template:
973 * @element_class: a #GstElementClass to get the pad template of.
974 * @name: the name of the #GstPadTemplate to get.
976 * Retrieves a padtemplate from @element_class with the given name.
977 * <note>If you use this function in the #GInstanceInitFunc of an object class
978 * that has subclasses, make sure to pass the g_class parameter of the
979 * #GInstanceInitFunc here.</note>
981 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
982 * No unreferencing is necessary.
985 gst_element_class_get_pad_template (GstElementClass * element_class,
990 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
991 g_return_val_if_fail (name != NULL, NULL);
993 padlist = gst_element_class_get_pad_template_list (element_class);
996 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
998 if (strcmp (padtempl->name_template, name) == 0)
1001 padlist = g_list_next (padlist);
1008 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
1010 GstPad *result = NULL;
1013 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1018 pads = element->srcpads;
1022 pads = element->sinkpads;
1025 goto wrong_direction;
1027 for (; pads; pads = g_list_next (pads)) {
1028 GstPad *pad = GST_PAD (pads->data);
1031 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1032 GST_DEBUG_PAD_NAME (pad));
1034 if (GST_PAD_IS_LINKED (pad)) {
1039 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1040 GST_DEBUG_PAD_NAME (pad));
1045 gst_object_ref (result);
1047 GST_UNLOCK (element);
1051 /* ERROR handling */
1054 g_warning ("unknown pad direction %d", dir);
1060 * gst_element_send_event:
1061 * @element: a #GstElement to send the event to.
1062 * @event: the #GstEvent to send to the element.
1064 * Sends an event to an element. If the element doesn't
1065 * implement an event handler, the event will be forwarded
1066 * to a random sink pad. This function takes owership of the
1067 * provided event so you should _ref it if you want to reuse
1068 * the event after this call.
1070 * Returns: TRUE if the event was handled.
1075 gst_element_send_event (GstElement * element, GstEvent * event)
1077 GstElementClass *oclass;
1078 gboolean result = FALSE;
1080 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1081 g_return_val_if_fail (event != NULL, FALSE);
1083 oclass = GST_ELEMENT_GET_CLASS (element);
1085 if (oclass->send_event) {
1086 result = oclass->send_event (element, event);
1088 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1091 GstPad *peer = gst_pad_get_peer (pad);
1094 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1095 "sending event to random pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1097 result = gst_pad_send_event (peer, event);
1098 gst_object_unref (peer);
1100 gst_object_unref (pad);
1103 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1104 GST_ELEMENT_NAME (element));
1111 * @element: a #GstElement to send the event to.
1112 * @seek_type: the method to use for seeking.
1113 * @offset: the offset to seek to.
1115 * Sends a seek event to an element.
1117 * Returns: TRUE if the event was handled.
1122 gst_element_seek (GstElement * element, GstSeekType seek_type, guint64 offset)
1127 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1129 event = gst_event_new_seek (seek_type, offset);
1130 result = gst_element_send_event (element, event);
1136 * gst_element_get_query_types:
1137 * @element: a #GstElement to query
1139 * Get an array of query types from the element.
1140 * If the element doesn't implement a query types function,
1141 * the query will be forwarded to a random sink pad.
1143 * Returns: An array of #GstQueryType elements that should not
1144 * be freed or modified.
1148 const GstQueryType *
1149 gst_element_get_query_types (GstElement * element)
1151 GstElementClass *oclass;
1152 const GstQueryType *result = NULL;
1154 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1156 oclass = GST_ELEMENT_GET_CLASS (element);
1158 if (oclass->get_query_types) {
1159 result = oclass->get_query_types (element);
1161 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1164 GstPad *peer = gst_pad_get_peer (pad);
1167 result = gst_pad_get_query_types (peer);
1169 gst_object_unref (peer);
1171 gst_object_unref (pad);
1178 * gst_element_query:
1179 * @element: a #GstElement to perform the query on.
1180 * @query: the #GstQuery.
1182 * Performs a query on the given element. If the format is set
1183 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1184 * format pointer will hold the default format.
1185 * For element that don't implement a query handler, this function
1186 * forwards the query to a random usable sinkpad of this element.
1188 * Returns: TRUE if the query could be performed.
1193 gst_element_query (GstElement * element, GstQuery * query)
1195 GstElementClass *oclass;
1196 gboolean result = FALSE;
1198 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1199 g_return_val_if_fail (query != NULL, FALSE);
1201 oclass = GST_ELEMENT_GET_CLASS (element);
1203 if (oclass->query) {
1204 result = oclass->query (element, query);
1206 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
1209 result = gst_pad_query (pad, query);
1211 gst_object_unref (pad);
1213 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1215 GstPad *peer = gst_pad_get_peer (pad);
1218 result = gst_pad_query (peer, query);
1220 gst_object_unref (peer);
1222 gst_object_unref (pad);
1230 * gst_element_post_message:
1231 * @element: a #GstElement posting the message
1232 * @message: a #GstMessage to post
1234 * Post a message on the element's #GstBus.
1236 * Returns: TRUE if the message was successfully posted.
1241 gst_element_post_message (GstElement * element, GstMessage * message)
1244 gboolean result = FALSE;
1246 GST_DEBUG ("posting message %p ...", message);
1248 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1249 g_return_val_if_fail (message != NULL, FALSE);
1254 if (G_UNLIKELY (bus == NULL)) {
1255 GST_DEBUG ("... but I won't because I have no bus");
1256 GST_UNLOCK (element);
1257 gst_message_unref (message);
1260 gst_object_ref (bus);
1261 GST_DEBUG ("... on bus %" GST_PTR_FORMAT, bus);
1262 GST_UNLOCK (element);
1264 result = gst_bus_post (bus, message);
1265 gst_object_unref (bus);
1271 * _gst_element_error_printf:
1272 * @format: the printf-like format to use, or NULL
1274 * This function is only used internally by the #gst_element_error macro.
1276 * Returns: a newly allocated string, or NULL if the format was NULL or ""
1281 _gst_element_error_printf (const gchar * format, ...)
1291 va_start (args, format);
1292 buffer = g_strdup_vprintf (format, args);
1298 * gst_element_message_full:
1299 * @element: a #GstElement to send message from
1300 * @type: the #GstMessageType
1301 * @domain: the GStreamer GError domain this message belongs to
1302 * @code: the GError code belonging to the domain
1303 * @text: an allocated text string to be used as a replacement for the
1304 * default message connected to code, or NULL
1305 * @debug: an allocated debug message to be used as a replacement for the
1306 * default debugging information, or NULL
1307 * @file: the source code file where the error was generated
1308 * @function: the source code function where the error was generated
1309 * @line: the source code line where the error was generated
1311 * Post an error or warning message on the bus from inside an element.
1315 void gst_element_message_full
1316 (GstElement * element, GstMessageType type,
1317 GQuark domain, gint code, gchar * text,
1318 gchar * debug, const gchar * file, const gchar * function, gint line)
1320 GError *gerror = NULL;
1324 GstMessage *message = NULL;
1327 GST_DEBUG ("start");
1328 g_return_if_fail (GST_IS_ELEMENT (element));
1329 g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1330 (type == GST_MESSAGE_WARNING));
1332 /* check if we send the given text or the default error text */
1333 if ((text == NULL) || (text[0] == 0)) {
1334 /* text could have come from g_strdup_printf (""); */
1336 sent_text = gst_error_get_message (domain, code);
1340 /* construct a sent_debug with extra information from source */
1341 if ((debug == NULL) || (debug[0] == 0)) {
1342 /* debug could have come from g_strdup_printf (""); */
1345 name = gst_object_get_path_string (GST_OBJECT (element));
1346 sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
1347 file, line, function, name, debug ? debug : "");
1352 /* create gerror and post message */
1353 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1355 gerror = g_error_new_literal (domain, code, sent_text);
1357 if (type == GST_MESSAGE_ERROR) {
1358 message = gst_message_new_error (GST_OBJECT (element), gerror, sent_debug);
1359 } else if (type == GST_MESSAGE_WARNING) {
1360 message = gst_message_new_warning (GST_OBJECT (element), gerror,
1363 g_assert_not_reached ();
1365 gst_element_post_message (element, message);
1367 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted message: %s",
1371 g_error_free (gerror);
1372 g_free (sent_debug);
1377 * gst_element_is_locked_state:
1378 * @element: a #GstElement.
1380 * Checks if the state of an element is locked.
1381 * If the state of an element is locked, state changes of the parent don't
1382 * affect the element.
1383 * This way you can leave currently unused elements inside bins. Just lock their
1384 * state before changing the state from #GST_STATE_NULL.
1386 * Returns: TRUE, if the element's state is locked.
1391 gst_element_is_locked_state (GstElement * element)
1393 gboolean result = FALSE;
1395 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1398 result = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1399 GST_UNLOCK (element);
1405 * gst_element_set_locked_state:
1406 * @element: a #GstElement
1407 * @locked_state: TRUE to lock the element's state
1409 * Locks the state of an element, so state changes of the parent don't affect
1410 * this element anymore.
1412 * Returns: TRUE if the state was changed, FALSE if bad params were given or
1413 * the element was already in the correct state.
1418 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
1422 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1425 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1427 if (G_UNLIKELY (old == locked_state))
1431 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
1432 GST_ELEMENT_NAME (element));
1433 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
1435 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
1436 GST_ELEMENT_NAME (element));
1437 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
1439 GST_UNLOCK (element);
1444 GST_UNLOCK (element);
1450 * gst_element_sync_state_with_parent:
1451 * @element: a #GstElement.
1453 * Tries to change the state of the element to the same as its parent.
1454 * If this function returns FALSE, the state of element is undefined.
1456 * Returns: TRUE, if the element's state could be synced to the parent's state.
1459 gst_element_sync_state_with_parent (GstElement * element)
1463 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1464 parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
1465 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
1467 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
1468 GST_ELEMENT_NAME (element),
1469 gst_element_state_get_name (GST_STATE (element)),
1470 GST_ELEMENT_NAME (parent),
1471 gst_element_state_get_name (GST_STATE (parent)));
1473 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
1480 static GstElementStateReturn
1481 gst_element_get_state_func (GstElement * element,
1482 GstElementState * state, GstElementState * pending, GTimeVal * timeout)
1484 GstElementStateReturn ret = GST_STATE_FAILURE;
1485 GstElementState old_pending;
1487 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
1489 GST_STATE_LOCK (element);
1490 /* we got an error, report immediatly */
1491 if (GST_STATE_NO_PREROLL (element)) {
1492 ret = GST_STATE_NO_PREROLL;
1496 /* we got an error, report immediatly */
1497 if (GST_STATE_ERROR (element)) {
1498 ret = GST_STATE_FAILURE;
1502 old_pending = GST_STATE_PENDING (element);
1503 if (old_pending != GST_STATE_VOID_PENDING) {
1504 GTimeVal *timeval, abstimeout;
1506 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "wait for pending");
1508 /* make timeout absolute */
1509 g_get_current_time (&abstimeout);
1510 g_time_val_add (&abstimeout,
1511 timeout->tv_sec * G_USEC_PER_SEC + timeout->tv_usec);
1512 timeval = &abstimeout;
1516 /* we have a pending state change, wait for it to complete */
1517 if (!GST_STATE_TIMED_WAIT (element, timeval)) {
1518 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timeout");
1519 /* timeout triggered */
1520 ret = GST_STATE_ASYNC;
1522 /* could be success or failure */
1523 if (old_pending == GST_STATE (element)) {
1524 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got success");
1525 ret = GST_STATE_SUCCESS;
1527 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got failure");
1528 ret = GST_STATE_FAILURE;
1532 /* if nothing is pending anymore we can return SUCCESS */
1533 if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
1534 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
1535 ret = GST_STATE_SUCCESS;
1540 *state = GST_STATE (element);
1542 *pending = GST_STATE_PENDING (element);
1544 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1545 "state current: %s, pending: %s, error: %d, no_preroll: %d, result: %d",
1546 gst_element_state_get_name (GST_STATE (element)),
1547 gst_element_state_get_name (GST_STATE_PENDING (element)),
1548 GST_STATE_ERROR (element), GST_STATE_NO_PREROLL (element), ret);
1550 GST_STATE_UNLOCK (element);
1556 * gst_element_get_state:
1557 * @element: a #GstElement to get the state of.
1558 * @state: a pointer to #GstElementState to hold the state. Can be NULL.
1559 * @pending: a pointer to #GstElementState to hold the pending state.
1561 * @timeout: a #GTimeVal to specify the timeout for an async
1562 * state change or NULL for infinite timeout.
1564 * Gets the state of the element.
1566 * For elements that performed an ASYNC state change, as reported by
1567 * #gst_element_set_state(), this function will block up to the
1568 * specified timeout value for the state change to complete.
1569 * If the element completes the state change or goes into
1570 * an error, this function returns immediatly with a return value of
1571 * GST_STATE_SUCCESS or GST_STATE_FAILURE respectively.
1573 * Returns: GST_STATE_SUCCESS if the element has no more pending state and
1574 * the last state change succeeded, GST_STATE_ASYNC
1575 * if the element is still performing a state change or
1576 * GST_STATE_FAILURE if the last state change failed.
1580 GstElementStateReturn
1581 gst_element_get_state (GstElement * element,
1582 GstElementState * state, GstElementState * pending, GTimeVal * timeout)
1584 GstElementClass *oclass;
1585 GstElementStateReturn result = GST_STATE_FAILURE;
1587 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
1589 oclass = GST_ELEMENT_GET_CLASS (element);
1591 if (oclass->get_state)
1592 result = (oclass->get_state) (element, state, pending, timeout);
1598 * gst_element_abort_state:
1599 * @element: a #GstElement to abort the state of.
1601 * Abort the state change of the element. This function is used
1602 * by elements that do asynchronous state changes and find out
1603 * something is wrong.
1605 * This function should be called with the STATE_LOCK held.
1610 gst_element_abort_state (GstElement * element)
1612 GstElementState pending;
1614 g_return_if_fail (GST_IS_ELEMENT (element));
1616 pending = GST_STATE_PENDING (element);
1618 if (pending != GST_STATE_VOID_PENDING && !GST_STATE_ERROR (element)) {
1619 #ifndef GST_DISABLE_GST_DEBUG
1620 GstElementState old_state = GST_STATE (element);
1623 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1624 "aborting state from %s to %s", gst_element_state_get_name (old_state),
1625 gst_element_state_get_name (pending));
1628 GST_STATE_ERROR (element) = TRUE;
1630 GST_STATE_BROADCAST (element);
1635 * gst_element_commit_state:
1636 * @element: a #GstElement to commit the state of.
1638 * Commit the state change of the element. This function is used
1639 * by elements that do asynchronous state changes.
1641 * This function can only be called with the STATE_LOCK held.
1646 gst_element_commit_state (GstElement * element)
1648 GstElementState pending;
1649 GstMessage *message;
1651 g_return_if_fail (GST_IS_ELEMENT (element));
1653 pending = GST_STATE_PENDING (element);
1655 if (pending != GST_STATE_VOID_PENDING) {
1656 GstElementState old_state = GST_STATE (element);
1658 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1659 "commiting state from %s to %s", gst_element_state_get_name (old_state),
1660 gst_element_state_get_name (pending));
1662 GST_STATE (element) = pending;
1663 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
1664 GST_STATE_ERROR (element) = FALSE;
1666 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
1667 0, old_state, pending);
1668 message = gst_message_new_state_changed (GST_OBJECT (element),
1669 old_state, pending);
1670 gst_element_post_message (element, message);
1671 GST_STATE_BROADCAST (element);
1676 * gst_element_lost_state:
1677 * @element: a #GstElement the state is lost of
1679 * Brings the element to the lost state. The current state of the
1680 * element is copied to the pending state so that any call to
1681 * #gst_element_get_state() will return ASYNC.
1682 * This is mostly used for elements that lost their preroll buffer
1683 * in the PAUSED state after a flush, they become PAUSED again
1684 * if a new preroll buffer is queued.
1685 * This function can only be called when the element is currently
1686 * not in error or an async state change.
1688 * This function can only be called with the STATE_LOCK held.
1693 gst_element_lost_state (GstElement * element)
1695 g_return_if_fail (GST_IS_ELEMENT (element));
1697 if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
1698 !GST_STATE_ERROR (element)) {
1699 GstElementState current_state = GST_STATE (element);
1701 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1702 "lost state of %s", gst_element_state_get_name (current_state));
1704 GST_STATE_PENDING (element) = current_state;
1705 GST_STATE_ERROR (element) = FALSE;
1710 * gst_element_set_state:
1711 * @element: a #GstElement to change state of.
1712 * @state: the element's new #GstElementState.
1714 * Sets the state of the element. This function will try to set the
1715 * requested state by going through all the intermediary states and calling
1716 * the class's state change function for each.
1718 * Returns: Result of the state change using #GstElementStateReturn.
1722 GstElementStateReturn
1723 gst_element_set_state (GstElement * element, GstElementState state)
1725 GstElementClass *oclass;
1726 GstElementState current;
1727 GstElementStateReturn return_val = GST_STATE_SUCCESS;
1728 GstElementStateReturn ret;
1729 GstElementState pending;
1733 /* get current element state, need to call the method so that
1734 * we call the virtual method and subclasses can implement their
1736 GST_TIME_TO_TIMEVAL (0, tv);
1737 ret = gst_element_get_state (element, ¤t, &pending, &tv);
1739 /* get the element state lock */
1740 GST_STATE_LOCK (element);
1741 /* this is the state we should go to */
1742 GST_STATE_FINAL (element) = state;
1743 if (ret == GST_STATE_ASYNC) {
1744 gst_element_commit_state (element);
1747 /* start with the current state */
1748 current = GST_STATE (element);
1750 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
1751 gst_element_state_get_name (current), gst_element_state_get_name (state));
1753 oclass = GST_ELEMENT_GET_CLASS (element);
1755 /* We always perform at least one state change, even if the
1756 * current state is equal to the required state. This is needed
1757 * for bins that sync their children. */
1759 GstElementState pending;
1761 /* calculate the pending state */
1762 if (current < state)
1763 pending = current << 1;
1764 else if (current > state)
1765 pending = current >> 1;
1769 /* set the pending state variable */
1770 GST_STATE_PENDING (element) = pending;
1772 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1773 "%s: setting state from %s to %s",
1774 (pending != state ? "intermediate" : "final"),
1775 gst_element_state_get_name (current),
1776 gst_element_state_get_name (pending));
1778 /* call the state change function so it can set the state */
1779 if (oclass->change_state)
1780 return_val = (oclass->change_state) (element);
1782 return_val = GST_STATE_FAILURE;
1784 /* clear the error and preroll flag, we need to do that after
1785 * calling the virtual change_state function so that it can use the
1786 * old previous value. */
1787 GST_STATE_ERROR (element) = FALSE;
1788 GST_STATE_NO_PREROLL (element) = FALSE;
1790 switch (return_val) {
1791 case GST_STATE_FAILURE:
1792 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1793 "have failed change_state return");
1794 /* state change failure exits the loop */
1795 gst_element_abort_state (element);
1797 case GST_STATE_ASYNC:
1798 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1799 "element will change state async");
1800 /* an async state change exits the loop, we can only
1801 * go to the next state change when this one completes. */
1803 case GST_STATE_SUCCESS:
1804 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1805 "element changed state successfully");
1806 /* we can commit the state now and proceed to the next state */
1807 gst_element_commit_state (element);
1808 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
1810 case GST_STATE_NO_PREROLL:
1811 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1812 "element changed state successfully and can't preroll");
1813 /* we can commit the state now and proceed to the next state */
1814 gst_element_commit_state (element);
1815 GST_STATE_NO_PREROLL (element) = TRUE;
1816 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
1819 goto invalid_return;
1821 /* get the current state of the element and see if we need to do more
1823 current = GST_STATE (element);
1825 while (current != state);
1828 GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1829 GST_STATE_UNLOCK (element);
1831 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change");
1838 GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1839 GST_STATE_UNLOCK (element);
1840 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
1841 g_critical ("unknown return value %d from a state change function",
1843 return GST_STATE_FAILURE;
1847 /* gst_iterator_fold functions for pads_activate */
1850 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
1852 if (!gst_pad_set_active (pad, *active))
1853 g_value_set_boolean (ret, FALSE);
1855 gst_object_unref (pad);
1859 /* returns false on error or early cutout of the fold, true otherwise */
1861 iterator_fold_with_resync (GstIterator * iter, GstIteratorFoldFunction func,
1862 GValue * ret, gpointer user_data)
1864 GstIteratorResult ires;
1865 gboolean res = TRUE;
1868 ires = gst_iterator_fold (iter, func, ret, user_data);
1871 case GST_ITERATOR_RESYNC:
1873 case GST_ITERATOR_DONE:
1886 /* is called with STATE_LOCK
1889 gst_element_pads_activate (GstElement * element, gboolean active)
1891 GValue ret = { 0, };
1895 /* no need to unset this later, it's just a boolean */
1896 g_value_init (&ret, G_TYPE_BOOLEAN);
1897 g_value_set_boolean (&ret, TRUE);
1899 iter = gst_element_iterate_src_pads (element);
1900 fold_ok = iterator_fold_with_resync
1901 (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
1902 gst_iterator_free (iter);
1903 if (!fold_ok || !g_value_get_boolean (&ret))
1906 iter = gst_element_iterate_sink_pads (element);
1907 fold_ok = iterator_fold_with_resync
1908 (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
1909 gst_iterator_free (iter);
1910 if (!fold_ok || !g_value_get_boolean (&ret))
1916 /* is called with STATE_LOCK */
1917 static GstElementStateReturn
1918 gst_element_change_state (GstElement * element)
1920 GstElementState old_state;
1921 gint old_pending, old_transition;
1922 GstElementStateReturn result = GST_STATE_SUCCESS;
1924 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
1926 old_state = GST_STATE (element);
1927 old_pending = GST_STATE_PENDING (element);
1928 old_transition = GST_STATE_TRANSITION (element);
1930 /* if the element already is in the given state, we just return success */
1931 if (old_pending == GST_STATE_VOID_PENDING ||
1932 old_state == GST_STATE_PENDING (element)) {
1933 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1934 "element is already in the %s state",
1935 gst_element_state_get_name (old_state));
1936 if (GST_STATE_NO_PREROLL (element))
1937 return GST_STATE_NO_PREROLL;
1939 return GST_STATE_SUCCESS;
1942 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
1943 "default handler tries setting state from %s to %s (%04x)",
1944 gst_element_state_get_name (old_state),
1945 gst_element_state_get_name (old_pending), old_transition);
1947 switch (old_transition) {
1948 case GST_STATE_NULL_TO_READY:
1950 case GST_STATE_READY_TO_PAUSED:
1951 if (!gst_element_pads_activate (element, TRUE)) {
1952 result = GST_STATE_FAILURE;
1955 case GST_STATE_PAUSED_TO_PLAYING:
1957 if (GST_ELEMENT_MANAGER (element)) {
1958 element->base_time =
1959 GST_ELEMENT_CAST (GST_ELEMENT_MANAGER (element))->base_time;
1961 GST_UNLOCK (element);
1963 case GST_STATE_PLAYING_TO_PAUSED:
1965 case GST_STATE_PAUSED_TO_READY:
1966 case GST_STATE_READY_TO_NULL:
1967 /* deactivate pads in both cases, since they are activated on
1968 ready->paused but the element might not have made it to paused */
1969 if (!gst_element_pads_activate (element, FALSE)) {
1970 result = GST_STATE_FAILURE;
1972 element->base_time = 0;
1976 /* this will catch real but unhandled state changes;
1977 * can only be caused by:
1978 * - a new state was added
1979 * - somehow the element was asked to jump across an intermediate state
1981 g_warning ("Unhandled state change from %s to %s",
1982 gst_element_state_get_name (old_state),
1983 gst_element_state_get_name (old_pending));
1991 * gst_element_get_factory:
1992 * @element: a #GstElement to request the element factory of.
1994 * Retrieves the factory that was used to create this element.
1996 * Returns: the #GstElementFactory used for creating this element.
1999 gst_element_get_factory (GstElement * element)
2001 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2003 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2007 gst_element_dispose (GObject * object)
2009 GstElement *element = GST_ELEMENT (object);
2011 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2013 /* ref so we don't hit 0 again */
2014 gst_object_ref (object);
2016 /* first we break all our links with the outside */
2017 while (element->pads) {
2018 gst_element_remove_pad (element, GST_PAD (element->pads->data));
2020 if (G_UNLIKELY (element->pads != 0)) {
2021 g_critical ("could not remove pads from element %s",
2022 GST_STR_NULL (GST_OBJECT_NAME (object)));
2026 gst_object_replace ((GstObject **) & element->manager, NULL);
2027 gst_object_replace ((GstObject **) & element->clock, NULL);
2028 GST_UNLOCK (element);
2030 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent");
2032 G_OBJECT_CLASS (parent_class)->dispose (object);
2036 gst_element_finalize (GObject * object)
2038 GstElement *element = GST_ELEMENT (object);
2040 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
2042 GST_STATE_LOCK (element);
2043 if (element->state_cond)
2044 g_cond_free (element->state_cond);
2045 element->state_cond = NULL;
2046 GST_STATE_UNLOCK (element);
2047 g_mutex_free (element->state_lock);
2049 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
2051 G_OBJECT_CLASS (parent_class)->finalize (object);
2054 #ifndef GST_DISABLE_LOADSAVE
2056 * gst_element_save_thyself:
2057 * @element: a #GstElement to save.
2058 * @parent: the xml parent node.
2060 * Saves the element as part of the given XML structure.
2062 * Returns: the new #xmlNodePtr.
2065 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
2068 GstElementClass *oclass;
2069 GParamSpec **specs, *spec;
2072 GValue value = { 0, };
2073 GstElement *element;
2075 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2077 element = GST_ELEMENT (object);
2079 oclass = GST_ELEMENT_GET_CLASS (element);
2081 xmlNewChild (parent, NULL, (xmlChar *) "name",
2082 (xmlChar *) GST_ELEMENT_NAME (element));
2084 if (oclass->elementfactory != NULL) {
2085 GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
2087 xmlNewChild (parent, NULL, (xmlChar *) "type",
2088 (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
2091 /* FIXME: what is this? */
2092 /* if (element->manager) */
2093 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2096 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2098 for (i = 0; i < nspecs; i++) {
2100 if (spec->flags & G_PARAM_READABLE) {
2104 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2106 g_object_get_property (G_OBJECT (element), spec->name, &value);
2107 param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
2108 xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
2110 if (G_IS_PARAM_SPEC_STRING (spec))
2111 contents = g_value_dup_string (&value);
2112 else if (G_IS_PARAM_SPEC_ENUM (spec))
2113 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2114 else if (G_IS_PARAM_SPEC_INT64 (spec))
2115 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2116 g_value_get_int64 (&value));
2118 contents = g_strdup_value_contents (&value);
2120 xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
2123 g_value_unset (&value);
2127 pads = GST_ELEMENT_PADS (element);
2130 GstPad *pad = GST_PAD (pads->data);
2132 /* figure out if it's a direct pad or a ghostpad */
2133 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2134 xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
2136 gst_object_save_thyself (GST_OBJECT (pad), padtag);
2138 pads = g_list_next (pads);
2145 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
2147 xmlNodePtr children;
2148 GstElement *element;
2150 gchar *value = NULL;
2152 element = GST_ELEMENT (object);
2153 g_return_if_fail (element != NULL);
2156 children = self->xmlChildrenNode;
2158 if (!strcmp ((char *) children->name, "param")) {
2159 xmlNodePtr child = children->xmlChildrenNode;
2162 if (!strcmp ((char *) child->name, "name")) {
2163 name = (gchar *) xmlNodeGetContent (child);
2164 } else if (!strcmp ((char *) child->name, "value")) {
2165 value = (gchar *) xmlNodeGetContent (child);
2167 child = child->next;
2169 /* FIXME: can this just be g_object_set ? */
2170 gst_util_set_object_arg (G_OBJECT (element), name, value);
2171 /* g_object_set (G_OBJECT (element), name, value, NULL); */
2175 children = children->next;
2179 children = self->xmlChildrenNode;
2181 if (!strcmp ((char *) children->name, "pad")) {
2182 gst_pad_load_and_link (children, GST_OBJECT (element));
2184 children = children->next;
2187 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2188 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2190 #endif /* GST_DISABLE_LOADSAVE */
2193 gst_element_set_manager_func (GstElement * element, GstPipeline * manager)
2195 g_return_if_fail (GST_IS_ELEMENT (element));
2197 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting manager to %p",
2200 /* setting the manager cannot increase the refcount */
2202 GST_ELEMENT_MANAGER (element) = manager;
2203 GST_UNLOCK (element);
2207 gst_element_set_bus_func (GstElement * element, GstBus * bus)
2209 g_return_if_fail (GST_IS_ELEMENT (element));
2211 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
2214 gst_object_replace ((GstObject **) & GST_ELEMENT_BUS (element),
2216 GST_UNLOCK (element);
2220 gst_element_set_scheduler_func (GstElement * element, GstScheduler * scheduler)
2222 g_return_if_fail (GST_IS_ELEMENT (element));
2224 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",
2228 gst_object_replace ((GstObject **) & GST_ELEMENT_SCHEDULER (element),
2229 GST_OBJECT (scheduler));
2230 GST_UNLOCK (element);
2234 * gst_element_set_manager:
2235 * @element: a #GstElement to set the manager of.
2236 * @manager: the #GstManager to set.
2238 * Sets the manager of the element. For internal use only, unless you're
2239 * writing a new bin subclass.
2244 gst_element_set_manager (GstElement * element, GstPipeline * manager)
2246 GstElementClass *oclass;
2248 g_return_if_fail (GST_IS_ELEMENT (element));
2250 oclass = GST_ELEMENT_GET_CLASS (element);
2252 if (oclass->set_manager)
2253 oclass->set_manager (element, manager);
2258 * gst_element_get_manager:
2259 * @element: a #GstElement to get the manager of.
2261 * Returns the manager of the element.
2263 * Returns: the element's #GstPipeline. unref after usage.
2268 gst_element_get_manager (GstElement * element)
2270 GstPipeline *result = NULL;
2272 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2275 result = GST_ELEMENT_MANAGER (element);
2276 gst_object_ref (result);
2277 GST_UNLOCK (element);
2283 * gst_element_set_bus:
2284 * @element: a #GstElement to set the bus of.
2285 * @bus: the #GstBus to set.
2287 * Sets the bus of the element. For internal use only, unless you're
2293 gst_element_set_bus (GstElement * element, GstBus * bus)
2295 GstElementClass *oclass;
2297 g_return_if_fail (GST_IS_ELEMENT (element));
2299 oclass = GST_ELEMENT_GET_CLASS (element);
2301 if (oclass->set_bus)
2302 oclass->set_bus (element, bus);
2306 * gst_element_get_bus:
2307 * @element: a #GstElement to get the bus of.
2309 * Returns the bus of the element.
2311 * Returns: the element's #GstBus. unref after usage.
2316 gst_element_get_bus (GstElement * element)
2318 GstBus *result = NULL;
2320 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2323 result = GST_ELEMENT_BUS (element);
2324 gst_object_ref (result);
2325 GST_UNLOCK (element);
2327 GST_DEBUG_OBJECT (element, "got bus %" GST_PTR_FORMAT, result);
2333 * gst_element_set_scheduler:
2334 * @element: a #GstElement to set the scheduler of.
2335 * @scheduler: the #GstScheduler to set.
2337 * Sets the scheduler of the element. For internal use only, unless you're
2343 gst_element_set_scheduler (GstElement * element, GstScheduler * scheduler)
2345 GstElementClass *oclass;
2347 g_return_if_fail (GST_IS_ELEMENT (element));
2349 oclass = GST_ELEMENT_GET_CLASS (element);
2351 if (oclass->set_scheduler)
2352 oclass->set_scheduler (element, scheduler);
2356 * gst_element_get_scheduler:
2357 * @element: a #GstElement to get the scheduler of.
2359 * Returns the scheduler of the element.
2361 * Returns: the element's #GstScheduler.
2366 gst_element_get_scheduler (GstElement * element)
2368 GstScheduler *result = NULL;
2370 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2373 result = GST_ELEMENT_SCHEDULER (element);
2374 GST_UNLOCK (element);