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 * @type: the #GstQueryType.
1181 * @format: the #GstFormat pointer to hold the format of the result.
1182 * @value: the pointer to the value of the result.
1184 * Performs a query on the given element. If the format is set
1185 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1186 * format pointer will hold the default format.
1187 * For element that don't implement a query handler, this function
1188 * forwards the query to a random usable sinkpad of this element.
1190 * Returns: TRUE if the query could be performed.
1195 gst_element_query (GstElement * element, GstQuery * query)
1197 GstElementClass *oclass;
1198 gboolean result = FALSE;
1200 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1201 g_return_val_if_fail (query != NULL, FALSE);
1203 oclass = GST_ELEMENT_GET_CLASS (element);
1205 if (oclass->query) {
1206 result = oclass->query (element, query);
1208 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
1211 result = gst_pad_query (pad, query);
1213 gst_object_unref (pad);
1215 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1217 GstPad *peer = gst_pad_get_peer (pad);
1220 result = gst_pad_query (peer, query);
1222 gst_object_unref (peer);
1224 gst_object_unref (pad);
1232 * gst_element_post_message:
1233 * @element: a #GstElement posting the message
1234 * @message: a #GstMessage to post
1236 * Post a message on the elements #GstBus.
1238 * Returns: TRUE if the message was successfuly posted.
1243 gst_element_post_message (GstElement * element, GstMessage * message)
1246 gboolean result = FALSE;
1248 GST_DEBUG ("posting message %p ...", message);
1250 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1251 g_return_val_if_fail (message != NULL, FALSE);
1256 if (G_UNLIKELY (bus == NULL)) {
1257 GST_DEBUG ("... but I won't because I have no bus");
1258 GST_UNLOCK (element);
1259 gst_message_unref (message);
1262 gst_object_ref (bus);
1263 GST_DEBUG ("... on bus %p", bus);
1264 GST_UNLOCK (element);
1266 result = gst_bus_post (bus, message);
1267 gst_object_unref (bus);
1273 * _gst_element_error_printf:
1274 * @format: the printf-like format to use, or NULL
1276 * This function is only used internally by the #gst_element_error macro.
1278 * Returns: a newly allocated string, or NULL if the format was NULL or ""
1283 _gst_element_error_printf (const gchar * format, ...)
1293 va_start (args, format);
1294 buffer = g_strdup_vprintf (format, args);
1300 * gst_element_message_full:
1301 * @element: a #GstElement to send message from
1302 * @type: the #GstMessageType
1303 * @domain: the GStreamer GError domain this message belongs to
1304 * @code: the GError code belonging to the domain
1305 * @text: an allocated text string to be used as a replacement for the
1306 * default message connected to code, or NULL
1307 * @debug: an allocated debug message to be used as a replacement for the
1308 * default debugging information, or NULL
1309 * @file: the source code file where the error was generated
1310 * @function: the source code function where the error was generated
1311 * @line: the source code line where the error was generated
1313 * Post an error or warning message on the bus from inside an element.
1317 void gst_element_message_full
1318 (GstElement * element, GstMessageType type,
1319 GQuark domain, gint code, gchar * text,
1320 gchar * debug, const gchar * file, const gchar * function, gint line)
1322 GError *gerror = NULL;
1326 GstMessage *message = NULL;
1329 GST_DEBUG ("start");
1330 g_return_if_fail (GST_IS_ELEMENT (element));
1331 g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1332 (type == GST_MESSAGE_WARNING));
1334 /* check if we send the given text or the default error text */
1335 if ((text == NULL) || (text[0] == 0)) {
1336 /* text could have come from g_strdup_printf (""); */
1338 sent_text = gst_error_get_message (domain, code);
1342 /* construct a sent_debug with extra information from source */
1343 if ((debug == NULL) || (debug[0] == 0)) {
1344 /* debug could have come from g_strdup_printf (""); */
1347 name = gst_object_get_path_string (GST_OBJECT (element));
1348 sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
1349 file, line, function, name, debug ? debug : "");
1354 /* create gerror and post message */
1355 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1357 gerror = g_error_new_literal (domain, code, sent_text);
1359 if (type == GST_MESSAGE_ERROR) {
1360 message = gst_message_new_error (GST_OBJECT (element), gerror, sent_debug);
1362 message = gst_message_new_warning (GST_OBJECT (element), gerror,
1365 gst_element_post_message (element, message);
1367 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted message: %s",
1372 /* sent_debug is not part of the gerror, so don't free it here */
1376 * gst_element_is_locked_state:
1377 * @element: a #GstElement.
1379 * Checks if the state of an element is locked.
1380 * If the state of an element is locked, state changes of the parent don't
1381 * affect the element.
1382 * This way you can leave currently unused elements inside bins. Just lock their
1383 * state before changing the state from #GST_STATE_NULL.
1385 * Returns: TRUE, if the element's state is locked.
1390 gst_element_is_locked_state (GstElement * element)
1392 gboolean result = FALSE;
1394 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1397 result = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1398 GST_UNLOCK (element);
1404 * gst_element_set_locked_state:
1405 * @element: a #GstElement
1406 * @locked_state: TRUE to lock the element's state
1408 * Locks the state of an element, so state changes of the parent don't affect
1409 * this element anymore.
1411 * Returns: TRUE if the state was changed, FALSE if bad params were given or
1412 * the element was already in the correct state.
1417 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
1421 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1424 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1426 if (G_UNLIKELY (old == locked_state))
1430 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
1431 GST_ELEMENT_NAME (element));
1432 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
1434 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
1435 GST_ELEMENT_NAME (element));
1436 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
1438 GST_UNLOCK (element);
1443 GST_UNLOCK (element);
1449 * gst_element_sync_state_with_parent:
1450 * @element: a #GstElement.
1452 * Tries to change the state of the element to the same as its parent.
1453 * If this function returns FALSE, the state of element is undefined.
1455 * Returns: TRUE, if the element's state could be synced to the parent's state.
1458 gst_element_sync_state_with_parent (GstElement * element)
1462 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1463 parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
1464 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
1466 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
1467 GST_ELEMENT_NAME (element),
1468 gst_element_state_get_name (GST_STATE (element)),
1469 GST_ELEMENT_NAME (parent),
1470 gst_element_state_get_name (GST_STATE (parent)));
1472 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
1479 static GstElementStateReturn
1480 gst_element_get_state_func (GstElement * element,
1481 GstElementState * state, GstElementState * pending, GTimeVal * timeout)
1483 GstElementStateReturn ret = GST_STATE_FAILURE;
1484 GstElementState old_pending;
1486 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
1488 GST_STATE_LOCK (element);
1489 /* we got an error, report immediatly */
1490 if (GST_STATE_NO_PREROLL (element)) {
1491 ret = GST_STATE_NO_PREROLL;
1495 /* we got an error, report immediatly */
1496 if (GST_STATE_ERROR (element)) {
1497 ret = GST_STATE_FAILURE;
1501 old_pending = GST_STATE_PENDING (element);
1502 if (old_pending != GST_STATE_VOID_PENDING) {
1503 GTimeVal *timeval, abstimeout;
1505 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "wait for pending");
1507 /* make timeout absolute */
1508 g_get_current_time (&abstimeout);
1509 g_time_val_add (&abstimeout,
1510 timeout->tv_sec * G_USEC_PER_SEC + timeout->tv_usec);
1511 timeval = &abstimeout;
1515 /* we have a pending state change, wait for it to complete */
1516 if (!GST_STATE_TIMED_WAIT (element, timeval)) {
1517 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timeout");
1518 /* timeout triggered */
1519 ret = GST_STATE_ASYNC;
1521 /* could be success or failure */
1522 if (old_pending == GST_STATE (element)) {
1523 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got success");
1524 ret = GST_STATE_SUCCESS;
1526 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got failure");
1527 ret = GST_STATE_FAILURE;
1531 /* if nothing is pending anymore we can return SUCCESS */
1532 if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
1533 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
1534 ret = GST_STATE_SUCCESS;
1539 *state = GST_STATE (element);
1541 *pending = GST_STATE_PENDING (element);
1543 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1544 "state current: %s, pending: %s, error: %d, no_preroll: %d, result: %d",
1545 gst_element_state_get_name (GST_STATE (element)),
1546 gst_element_state_get_name (GST_STATE_PENDING (element)),
1547 GST_STATE_ERROR (element), GST_STATE_NO_PREROLL (element), ret);
1549 GST_STATE_UNLOCK (element);
1555 * gst_element_get_state:
1556 * @element: a #GstElement to get the state of.
1557 * @state: a pointer to #GstElementState to hold the state. Can be NULL.
1558 * @pending: a pointer to #GstElementState to hold the pending state.
1560 * @timeout: a #GTimeVal to specify the timeout for an async
1561 * state change or NULL for infinite timeout.
1563 * Gets the state of the element.
1565 * For elements that performed an ASYNC state change, as reported by
1566 * #gst_element_set_state(), this function will block up to the
1567 * specified timeout value for the state change to complete.
1568 * If the element completes the state change or goes into
1569 * an error, this function returns immediatly with a return value of
1570 * GST_STATE_SUCCESS or GST_STATE_FAILURE respectively.
1572 * Returns: GST_STATE_SUCCESS if the element has no more pending state and
1573 * the last state change succeeded, GST_STATE_ASYNC
1574 * if the element is still performing a state change or
1575 * GST_STATE_FAILURE if the last state change failed.
1579 GstElementStateReturn
1580 gst_element_get_state (GstElement * element,
1581 GstElementState * state, GstElementState * pending, GTimeVal * timeout)
1583 GstElementClass *oclass;
1584 GstElementStateReturn result = GST_STATE_FAILURE;
1586 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
1588 oclass = GST_ELEMENT_GET_CLASS (element);
1590 if (oclass->get_state)
1591 result = (oclass->get_state) (element, state, pending, timeout);
1597 * gst_element_abort_state:
1598 * @element: a #GstElement to abort the state of.
1600 * Abort the state change of the element. This function is used
1601 * by elements that do asynchronous state changes and find out
1602 * something is wrong.
1604 * This function should be called with the STATE_LOCK held.
1609 gst_element_abort_state (GstElement * element)
1611 GstElementState pending;
1613 g_return_if_fail (GST_IS_ELEMENT (element));
1615 pending = GST_STATE_PENDING (element);
1617 if (pending != GST_STATE_VOID_PENDING && !GST_STATE_ERROR (element)) {
1618 #ifndef GST_DISABLE_GST_DEBUG
1619 GstElementState old_state = GST_STATE (element);
1622 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1623 "aborting state from %s to %s", gst_element_state_get_name (old_state),
1624 gst_element_state_get_name (pending));
1627 GST_STATE_ERROR (element) = TRUE;
1629 GST_STATE_BROADCAST (element);
1634 * gst_element_commit_state:
1635 * @element: a #GstElement to commit the state of.
1637 * Commit the state change of the element. This function is used
1638 * by elements that do asynchronous state changes.
1640 * This function can only be called with the STATE_LOCK held.
1645 gst_element_commit_state (GstElement * element)
1647 GstElementState pending;
1648 GstMessage *message;
1650 g_return_if_fail (GST_IS_ELEMENT (element));
1652 pending = GST_STATE_PENDING (element);
1654 if (pending != GST_STATE_VOID_PENDING) {
1655 GstElementState old_state = GST_STATE (element);
1657 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1658 "commiting state from %s to %s", gst_element_state_get_name (old_state),
1659 gst_element_state_get_name (pending));
1661 GST_STATE (element) = pending;
1662 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
1663 GST_STATE_ERROR (element) = FALSE;
1665 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
1666 0, old_state, pending);
1667 message = gst_message_new_state_changed (GST_OBJECT (element),
1668 old_state, pending);
1669 gst_element_post_message (element, message);
1670 GST_STATE_BROADCAST (element);
1675 * gst_element_lost_state:
1676 * @element: a #GstElement the state is lost of
1678 * Brings the element to the lost state. The current state of the
1679 * element is copied to the pending state so that any call to
1680 * #gst_element_get_state() will return ASYNC.
1681 * This is mostly used for elements that lost their preroll buffer
1682 * in the PAUSED state after a flush, they become PAUSED again
1683 * if a new preroll buffer is queued.
1684 * This function can only be called when the element is currently
1685 * not in error or an async state change.
1687 * This function can only be called with the STATE_LOCK held.
1692 gst_element_lost_state (GstElement * element)
1694 g_return_if_fail (GST_IS_ELEMENT (element));
1696 if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
1697 !GST_STATE_ERROR (element)) {
1698 GstElementState current_state = GST_STATE (element);
1700 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1701 "lost state of %s", gst_element_state_get_name (current_state));
1703 GST_STATE_PENDING (element) = current_state;
1704 GST_STATE_ERROR (element) = FALSE;
1709 * gst_element_set_state:
1710 * @element: a #GstElement to change state of.
1711 * @state: the element's new #GstElementState.
1713 * Sets the state of the element. This function will try to set the
1714 * requested state by going through all the intermediary states and calling
1715 * the class's state change function for each.
1717 * Returns: Result of the state change using #GstElementStateReturn.
1721 GstElementStateReturn
1722 gst_element_set_state (GstElement * element, GstElementState state)
1724 GstElementClass *oclass;
1725 GstElementState current;
1726 GstElementStateReturn return_val = GST_STATE_SUCCESS;
1727 GstElementStateReturn ret;
1728 GstElementState pending;
1732 /* get current element state, need to call the method so that
1733 * we call the virtual method and subclasses can implement their
1735 GST_TIME_TO_TIMEVAL (0, tv);
1736 ret = gst_element_get_state (element, ¤t, &pending, &tv);
1738 /* get the element state lock */
1739 GST_STATE_LOCK (element);
1740 /* this is the state we should go to */
1741 GST_STATE_FINAL (element) = state;
1742 if (ret == GST_STATE_ASYNC) {
1743 gst_element_commit_state (element);
1746 /* start with the current state */
1747 current = GST_STATE (element);
1749 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
1750 gst_element_state_get_name (current), gst_element_state_get_name (state));
1752 oclass = GST_ELEMENT_GET_CLASS (element);
1754 /* We always perform at least one state change, even if the
1755 * current state is equal to the required state. This is needed
1756 * for bins that sync their children. */
1758 GstElementState pending;
1760 /* calculate the pending state */
1761 if (current < state)
1762 pending = current << 1;
1763 else if (current > state)
1764 pending = current >> 1;
1768 /* set the pending state variable */
1769 GST_STATE_PENDING (element) = pending;
1771 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1772 "%s: setting state from %s to %s",
1773 (pending != state ? "intermediate" : "final"),
1774 gst_element_state_get_name (current),
1775 gst_element_state_get_name (pending));
1777 /* call the state change function so it can set the state */
1778 if (oclass->change_state)
1779 return_val = (oclass->change_state) (element);
1781 return_val = GST_STATE_FAILURE;
1783 /* clear the error and preroll flag, we need to do that after
1784 * calling the virtual change_state function so that it can use the
1785 * old previous value. */
1786 GST_STATE_ERROR (element) = FALSE;
1787 GST_STATE_NO_PREROLL (element) = FALSE;
1789 switch (return_val) {
1790 case GST_STATE_FAILURE:
1791 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1792 "have failed change_state return");
1793 /* state change failure exits the loop */
1794 gst_element_abort_state (element);
1796 case GST_STATE_ASYNC:
1797 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1798 "element will change state async");
1799 /* an async state change exits the loop, we can only
1800 * go to the next state change when this one completes. */
1802 case GST_STATE_SUCCESS:
1803 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1804 "element changed state successfuly");
1805 /* we can commit the state now and proceed to the next state */
1806 gst_element_commit_state (element);
1807 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
1809 case GST_STATE_NO_PREROLL:
1810 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1811 "element changed state successfuly and can't preroll");
1812 /* we can commit the state now and proceed to the next state */
1813 gst_element_commit_state (element);
1814 GST_STATE_NO_PREROLL (element) = TRUE;
1815 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
1818 goto invalid_return;
1820 /* get the current state of the element and see if we need to do more
1822 current = GST_STATE (element);
1824 while (current != state);
1827 GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1828 GST_STATE_UNLOCK (element);
1830 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change");
1837 GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1838 GST_STATE_UNLOCK (element);
1839 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
1840 g_critical ("unknown return value %d from a state change function",
1842 return GST_STATE_FAILURE;
1846 /* gst_iterator_fold functions for pads_activate */
1849 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
1851 if (!gst_pad_set_active (pad, *active))
1852 g_value_set_boolean (ret, FALSE);
1854 gst_object_unref (pad);
1858 /* returns false on error or early cutout of the fold, true otherwise */
1860 iterator_fold_with_resync (GstIterator * iter, GstIteratorFoldFunction func,
1861 GValue * ret, gpointer user_data)
1863 GstIteratorResult ires;
1864 gboolean res = TRUE;
1867 ires = gst_iterator_fold (iter, func, ret, user_data);
1870 case GST_ITERATOR_RESYNC:
1872 case GST_ITERATOR_DONE:
1885 /* is called with STATE_LOCK
1888 gst_element_pads_activate (GstElement * element, gboolean active)
1890 GValue ret = { 0, };
1894 /* no need to unset this later, it's just a boolean */
1895 g_value_init (&ret, G_TYPE_BOOLEAN);
1896 g_value_set_boolean (&ret, TRUE);
1898 iter = gst_element_iterate_src_pads (element);
1899 fold_ok = iterator_fold_with_resync
1900 (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
1901 gst_iterator_free (iter);
1902 if (!fold_ok || !g_value_get_boolean (&ret))
1905 iter = gst_element_iterate_sink_pads (element);
1906 fold_ok = iterator_fold_with_resync
1907 (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
1908 gst_iterator_free (iter);
1909 if (!fold_ok || !g_value_get_boolean (&ret))
1915 /* is called with STATE_LOCK */
1916 static GstElementStateReturn
1917 gst_element_change_state (GstElement * element)
1919 GstElementState old_state;
1920 gint old_pending, old_transition;
1921 GstElementStateReturn result = GST_STATE_SUCCESS;
1923 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
1925 old_state = GST_STATE (element);
1926 old_pending = GST_STATE_PENDING (element);
1927 old_transition = GST_STATE_TRANSITION (element);
1929 /* if the element already is in the given state, we just return success */
1930 if (old_pending == GST_STATE_VOID_PENDING ||
1931 old_state == GST_STATE_PENDING (element)) {
1932 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1933 "element is already in the %s state",
1934 gst_element_state_get_name (old_state));
1935 if (GST_STATE_NO_PREROLL (element))
1936 return GST_STATE_NO_PREROLL;
1938 return GST_STATE_SUCCESS;
1941 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
1942 "default handler tries setting state from %s to %s (%04x)",
1943 gst_element_state_get_name (old_state),
1944 gst_element_state_get_name (old_pending), old_transition);
1946 switch (old_transition) {
1947 case GST_STATE_NULL_TO_READY:
1949 case GST_STATE_READY_TO_PAUSED:
1950 if (!gst_element_pads_activate (element, TRUE)) {
1951 result = GST_STATE_FAILURE;
1954 case GST_STATE_PAUSED_TO_PLAYING:
1956 if (GST_ELEMENT_MANAGER (element)) {
1957 element->base_time =
1958 GST_ELEMENT_CAST (GST_ELEMENT_MANAGER (element))->base_time;
1960 GST_UNLOCK (element);
1962 case GST_STATE_PLAYING_TO_PAUSED:
1964 case GST_STATE_PAUSED_TO_READY:
1965 case GST_STATE_READY_TO_NULL:
1966 /* deactivate pads in both cases, since they are activated on
1967 ready->paused but the element might not have made it to paused */
1968 if (!gst_element_pads_activate (element, FALSE)) {
1969 result = GST_STATE_FAILURE;
1971 element->base_time = 0;
1975 /* this will catch real but unhandled state changes;
1976 * can only be caused by:
1977 * - a new state was added
1978 * - somehow the element was asked to jump across an intermediate state
1980 g_warning ("Unhandled state change from %s to %s",
1981 gst_element_state_get_name (old_state),
1982 gst_element_state_get_name (old_pending));
1990 * gst_element_get_factory:
1991 * @element: a #GstElement to request the element factory of.
1993 * Retrieves the factory that was used to create this element.
1995 * Returns: the #GstElementFactory used for creating this element.
1998 gst_element_get_factory (GstElement * element)
2000 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2002 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2006 gst_element_dispose (GObject * object)
2008 GstElement *element = GST_ELEMENT (object);
2010 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2012 /* ref so we don't hit 0 again */
2013 gst_object_ref (object);
2015 /* first we break all our links with the ouside */
2016 while (element->pads) {
2017 gst_element_remove_pad (element, GST_PAD (element->pads->data));
2019 if (G_UNLIKELY (element->pads != 0)) {
2020 g_critical ("could not remove pads from element %s",
2021 GST_STR_NULL (GST_OBJECT_NAME (object)));
2025 gst_object_replace ((GstObject **) & element->manager, NULL);
2026 gst_object_replace ((GstObject **) & element->clock, NULL);
2027 GST_UNLOCK (element);
2029 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent");
2031 G_OBJECT_CLASS (parent_class)->dispose (object);
2035 gst_element_finalize (GObject * object)
2037 GstElement *element = GST_ELEMENT (object);
2039 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
2041 GST_STATE_LOCK (element);
2042 if (element->state_cond)
2043 g_cond_free (element->state_cond);
2044 element->state_cond = NULL;
2045 GST_STATE_UNLOCK (element);
2046 g_mutex_free (element->state_lock);
2048 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
2050 G_OBJECT_CLASS (parent_class)->finalize (object);
2053 #ifndef GST_DISABLE_LOADSAVE
2055 * gst_element_save_thyself:
2056 * @element: a #GstElement to save.
2057 * @parent: the xml parent node.
2059 * Saves the element as part of the given XML structure.
2061 * Returns: the new #xmlNodePtr.
2064 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
2067 GstElementClass *oclass;
2068 GParamSpec **specs, *spec;
2071 GValue value = { 0, };
2072 GstElement *element;
2074 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2076 element = GST_ELEMENT (object);
2078 oclass = GST_ELEMENT_GET_CLASS (element);
2080 xmlNewChild (parent, NULL, (xmlChar *) "name",
2081 (xmlChar *) GST_ELEMENT_NAME (element));
2083 if (oclass->elementfactory != NULL) {
2084 GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
2086 xmlNewChild (parent, NULL, (xmlChar *) "type",
2087 (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
2090 /* FIXME: what is this? */
2091 /* if (element->manager) */
2092 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2095 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2097 for (i = 0; i < nspecs; i++) {
2099 if (spec->flags & G_PARAM_READABLE) {
2103 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2105 g_object_get_property (G_OBJECT (element), spec->name, &value);
2106 param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
2107 xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
2109 if (G_IS_PARAM_SPEC_STRING (spec))
2110 contents = g_value_dup_string (&value);
2111 else if (G_IS_PARAM_SPEC_ENUM (spec))
2112 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2113 else if (G_IS_PARAM_SPEC_INT64 (spec))
2114 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2115 g_value_get_int64 (&value));
2117 contents = g_strdup_value_contents (&value);
2119 xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
2122 g_value_unset (&value);
2126 pads = GST_ELEMENT_PADS (element);
2129 GstPad *pad = GST_PAD (pads->data);
2131 /* figure out if it's a direct pad or a ghostpad */
2132 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2133 xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
2135 gst_object_save_thyself (GST_OBJECT (pad), padtag);
2137 pads = g_list_next (pads);
2144 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
2146 xmlNodePtr children;
2147 GstElement *element;
2149 gchar *value = NULL;
2151 element = GST_ELEMENT (object);
2152 g_return_if_fail (element != NULL);
2155 children = self->xmlChildrenNode;
2157 if (!strcmp ((char *) children->name, "param")) {
2158 xmlNodePtr child = children->xmlChildrenNode;
2161 if (!strcmp ((char *) child->name, "name")) {
2162 name = (gchar *) xmlNodeGetContent (child);
2163 } else if (!strcmp ((char *) child->name, "value")) {
2164 value = (gchar *) xmlNodeGetContent (child);
2166 child = child->next;
2168 /* FIXME: can this just be g_object_set ? */
2169 gst_util_set_object_arg (G_OBJECT (element), name, value);
2170 /* g_object_set (G_OBJECT (element), name, value, NULL); */
2174 children = children->next;
2178 children = self->xmlChildrenNode;
2180 if (!strcmp ((char *) children->name, "pad")) {
2181 gst_pad_load_and_link (children, GST_OBJECT (element));
2183 children = children->next;
2186 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2187 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2189 #endif /* GST_DISABLE_LOADSAVE */
2192 gst_element_set_manager_func (GstElement * element, GstPipeline * manager)
2194 g_return_if_fail (GST_IS_ELEMENT (element));
2196 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting manager to %p",
2199 /* setting the manager cannot increase the refcount */
2201 GST_ELEMENT_MANAGER (element) = manager;
2202 GST_UNLOCK (element);
2206 gst_element_set_bus_func (GstElement * element, GstBus * bus)
2208 g_return_if_fail (GST_IS_ELEMENT (element));
2210 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
2213 gst_object_replace ((GstObject **) & GST_ELEMENT_BUS (element),
2215 GST_UNLOCK (element);
2219 gst_element_set_scheduler_func (GstElement * element, GstScheduler * scheduler)
2221 g_return_if_fail (GST_IS_ELEMENT (element));
2223 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",
2227 gst_object_replace ((GstObject **) & GST_ELEMENT_SCHEDULER (element),
2228 GST_OBJECT (scheduler));
2229 GST_UNLOCK (element);
2233 * gst_element_set_manager:
2234 * @element: a #GstElement to set the manager of.
2235 * @manager: the #GstManager to set.
2237 * Sets the manager of the element. For internal use only, unless you're
2238 * writing a new bin subclass.
2243 gst_element_set_manager (GstElement * element, GstPipeline * manager)
2245 GstElementClass *oclass;
2247 g_return_if_fail (GST_IS_ELEMENT (element));
2249 oclass = GST_ELEMENT_GET_CLASS (element);
2251 if (oclass->set_manager)
2252 oclass->set_manager (element, manager);
2257 * gst_element_get_manager:
2258 * @element: a #GstElement to get the manager of.
2260 * Returns the manager of the element.
2262 * Returns: the element's #GstPipeline. unref after usage.
2267 gst_element_get_manager (GstElement * element)
2269 GstPipeline *result = NULL;
2271 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2274 result = GST_ELEMENT_MANAGER (element);
2275 gst_object_ref (result);
2276 GST_UNLOCK (element);
2282 * gst_element_set_bus:
2283 * @element: a #GstElement to set the bus of.
2284 * @bus: the #GstBus to set.
2286 * Sets the bus of the element. For internal use only, unless you're
2292 gst_element_set_bus (GstElement * element, GstBus * bus)
2294 GstElementClass *oclass;
2296 g_return_if_fail (GST_IS_ELEMENT (element));
2298 oclass = GST_ELEMENT_GET_CLASS (element);
2300 if (oclass->set_bus)
2301 oclass->set_bus (element, bus);
2305 * gst_element_get_bus:
2306 * @element: a #GstElement to get the bus of.
2308 * Returns the bus of the element.
2310 * Returns: the element's #GstBus.
2315 gst_element_get_bus (GstElement * element)
2317 GstBus *result = NULL;
2319 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2322 result = GST_ELEMENT_BUS (element);
2323 GST_UNLOCK (element);
2329 * gst_element_set_scheduler:
2330 * @element: a #GstElement to set the scheduler of.
2331 * @scheduler: the #GstScheduler to set.
2333 * Sets the scheduler of the element. For internal use only, unless you're
2339 gst_element_set_scheduler (GstElement * element, GstScheduler * scheduler)
2341 GstElementClass *oclass;
2343 g_return_if_fail (GST_IS_ELEMENT (element));
2345 oclass = GST_ELEMENT_GET_CLASS (element);
2347 if (oclass->set_scheduler)
2348 oclass->set_scheduler (element, scheduler);
2352 * gst_element_get_scheduler:
2353 * @element: a #GstElement to get the scheduler of.
2355 * Returns the scheduler of the element.
2357 * Returns: the element's #GstScheduler.
2362 gst_element_get_scheduler (GstElement * element)
2364 GstScheduler *result = NULL;
2366 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2369 result = GST_ELEMENT_SCHEDULER (element);
2370 GST_UNLOCK (element);