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., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
25 * @short_description: Abstract base class for all pipeline elements
26 * @see_also: #GstElementFactory, #GstPad
28 * GstElement is the abstract base class needed to construct an element that
29 * can be used in a GStreamer pipeline. Please refer to the plugin writers
30 * guide for more information on creating #GstElement subclasses.
32 * The name of a #GstElement can be get with gst_element_get_name() and set with
33 * gst_element_set_name(). For speed, GST_ELEMENT_NAME() can be used in the
34 * core when using the appropriate locking. Do not use this in plug-ins or
35 * applications in order to retain ABI compatibility.
37 * Elements can have pads (of the type #GstPad). These pads link to pads on
38 * other elements. #GstBuffer flow between these linked pads.
39 * A #GstElement has a #GList of #GstPad structures for all their input (or sink)
40 * and output (or source) pads.
41 * Core and plug-in writers can add and remove pads with gst_element_add_pad()
42 * and gst_element_remove_pad().
44 * An existing pad of an element can be retrieved by name with
45 * gst_element_get_static_pad(). A new dynamic pad can be created using
46 * gst_element_request_pad() with a #GstPadTemplate.
47 * An iterator of all pads can be retrieved with gst_element_iterate_pads().
49 * Elements can be linked through their pads.
50 * If the link is straightforward, use the gst_element_link()
51 * convenience function to link two elements, or gst_element_link_many()
52 * for more elements in a row.
53 * Use gst_element_link_filtered() to link two elements constrained by
54 * a specified set of #GstCaps.
55 * For finer control, use gst_element_link_pads() and
56 * gst_element_link_pads_filtered() to specify the pads to link on
57 * each element by name.
59 * Each element has a state (see #GstState). You can get and set the state
60 * of an element with gst_element_get_state() and gst_element_set_state().
61 * Setting a state triggers a #GstStateChange. To get a string representation
62 * of a #GstState, use gst_element_state_get_name().
64 * You can get and set a #GstClock on an element using gst_element_get_clock()
65 * and gst_element_set_clock().
66 * Some elements can provide a clock for the pipeline if
67 * the #GST_ELEMENT_FLAG_PROVIDE_CLOCK flag is set. With the
68 * gst_element_provide_clock() method one can retrieve the clock provided by
70 * Not all elements require a clock to operate correctly. If the
71 * #GST_ELEMENT_FLAG_REQUIRE_CLOCK() flag is set, a clock should be set on the
72 * element with gst_element_set_clock().
74 * Note that clock selection and distribution is normally handled by the
75 * toplevel #GstPipeline so the clock functions are only to be used in very
76 * specific situations.
79 #include "gst_private.h"
82 #include <gobject/gvaluecollector.h>
84 #include "gstelement.h"
85 #include "gstelementmetadata.h"
86 #include "gstenumtypes.h"
93 #include "gsttracerutils.h"
95 #include "gst-i18n-lib.h"
96 #include "glib-compat-private.h"
98 #ifndef GST_DISABLE_GST_DEBUG
99 #include "printf/printf.h"
102 /* Element signals and args */
118 static void gst_element_class_init (GstElementClass * klass);
119 static void gst_element_init (GstElement * element);
120 static void gst_element_base_class_init (gpointer g_class);
122 static void gst_element_constructed (GObject * object);
123 static void gst_element_dispose (GObject * object);
124 static void gst_element_finalize (GObject * object);
126 static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
127 GstStateChange transition);
128 static GstStateChangeReturn gst_element_get_state_func (GstElement * element,
129 GstState * state, GstState * pending, GstClockTime timeout);
130 static GstStateChangeReturn gst_element_set_state_func (GstElement * element,
132 static gboolean gst_element_set_clock_func (GstElement * element,
134 static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
135 static gboolean gst_element_post_message_default (GstElement * element,
136 GstMessage * message);
137 static void gst_element_set_context_default (GstElement * element,
138 GstContext * context);
140 static gboolean gst_element_default_send_event (GstElement * element,
142 static gboolean gst_element_default_query (GstElement * element,
145 static GstPadTemplate
146 * gst_element_class_get_request_pad_template (GstElementClass *
147 element_class, const gchar * name);
149 static void gst_element_call_async_func (gpointer data, gpointer user_data);
151 static GstObjectClass *parent_class = NULL;
152 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
154 static GThreadPool *gst_element_pool = NULL;
156 /* this is used in gstelementfactory.c:gst_element_register() */
157 GQuark __gst_elementclass_factory = 0;
160 gst_element_get_type (void)
162 static volatile gsize gst_element_type = 0;
164 if (g_once_init_enter (&gst_element_type)) {
166 static const GTypeInfo element_info = {
167 sizeof (GstElementClass),
168 gst_element_base_class_init,
169 NULL, /* base_class_finalize */
170 (GClassInitFunc) gst_element_class_init,
175 (GInstanceInitFunc) gst_element_init,
179 _type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
180 &element_info, G_TYPE_FLAG_ABSTRACT);
182 __gst_elementclass_factory =
183 g_quark_from_static_string ("GST_ELEMENTCLASS_FACTORY");
184 g_once_init_leave (&gst_element_type, _type);
186 return gst_element_type;
190 gst_element_class_init (GstElementClass * klass)
192 GObjectClass *gobject_class;
195 gobject_class = (GObjectClass *) klass;
197 parent_class = g_type_class_peek_parent (klass);
200 * GstElement::pad-added:
201 * @gstelement: the object which received the signal
202 * @new_pad: the pad that has been added
204 * a new #GstPad has been added to the element. Note that this signal will
205 * usually be emitted from the context of the streaming thread. Also keep in
206 * mind that if you add new elements to the pipeline in the signal handler
207 * you will need to set them to the desired target state with
208 * gst_element_set_state() or gst_element_sync_state_with_parent().
210 gst_element_signals[PAD_ADDED] =
211 g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
212 G_STRUCT_OFFSET (GstElementClass, pad_added), NULL, NULL,
213 g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
215 * GstElement::pad-removed:
216 * @gstelement: the object which received the signal
217 * @old_pad: the pad that has been removed
219 * a #GstPad has been removed from the element
221 gst_element_signals[PAD_REMOVED] =
222 g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
223 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
224 g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
226 * GstElement::no-more-pads:
227 * @gstelement: the object which received the signal
229 * This signals that the element will not generate more dynamic pads.
230 * Note that this signal will usually be emitted from the context of
231 * the streaming thread.
233 gst_element_signals[NO_MORE_PADS] =
234 g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
235 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
236 NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0);
238 gobject_class->dispose = gst_element_dispose;
239 gobject_class->finalize = gst_element_finalize;
240 gobject_class->constructed = gst_element_constructed;
242 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
243 klass->set_state = GST_DEBUG_FUNCPTR (gst_element_set_state_func);
244 klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
245 klass->set_clock = GST_DEBUG_FUNCPTR (gst_element_set_clock_func);
246 klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
247 klass->query = GST_DEBUG_FUNCPTR (gst_element_default_query);
248 klass->send_event = GST_DEBUG_FUNCPTR (gst_element_default_send_event);
249 klass->numpadtemplates = 0;
250 klass->post_message = GST_DEBUG_FUNCPTR (gst_element_post_message_default);
251 klass->set_context = GST_DEBUG_FUNCPTR (gst_element_set_context_default);
253 klass->elementfactory = NULL;
255 GST_DEBUG ("creating element thread pool");
257 g_thread_pool_new ((GFunc) gst_element_call_async_func, NULL, -1, FALSE,
260 g_critical ("could not alloc threadpool %s", err->message);
261 g_clear_error (&err);
266 gst_element_base_class_init (gpointer g_class)
268 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
269 GList *node, *padtemplates;
271 /* Copy the element details here so elements can inherit the
272 * details from their base class and classes only need to set
273 * the details in class_init instead of base_init */
274 element_class->metadata =
275 element_class->metadata ? gst_structure_copy (element_class->metadata) :
276 gst_structure_new_empty ("metadata");
278 /* Copy the pad templates so elements inherit them
279 * from their base class but elements can add pad templates in class_init
280 * instead of base_init.
282 padtemplates = g_list_copy (element_class->padtemplates);
283 for (node = padtemplates; node != NULL; node = node->next) {
284 GstPadTemplate *tmpl = (GstPadTemplate *) node->data;
285 gst_object_ref (tmpl);
287 element_class->padtemplates = padtemplates;
289 /* set the factory, see gst_element_register() */
290 element_class->elementfactory =
291 g_type_get_qdata (G_TYPE_FROM_CLASS (element_class),
292 __gst_elementclass_factory);
293 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "type %s : factory %p",
294 G_OBJECT_CLASS_NAME (element_class), element_class->elementfactory);
298 gst_element_init (GstElement * element)
300 GST_STATE (element) = GST_STATE_NULL;
301 GST_STATE_TARGET (element) = GST_STATE_NULL;
302 GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
303 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
304 GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
306 g_rec_mutex_init (&element->state_lock);
307 g_cond_init (&element->state_cond);
311 gst_element_constructed (GObject * object)
313 GST_TRACER_ELEMENT_NEW (GST_ELEMENT_CAST (object));
314 G_OBJECT_CLASS (parent_class)->constructed (object);
318 * gst_element_release_request_pad:
319 * @element: a #GstElement to release the request pad of.
320 * @pad: the #GstPad to release.
322 * Makes the element free the previously requested pad as obtained
323 * with gst_element_request_pad().
325 * This does not unref the pad. If the pad was created by using
326 * gst_element_request_pad(), gst_element_release_request_pad() needs to be
327 * followed by gst_object_unref() to free the @pad.
332 gst_element_release_request_pad (GstElement * element, GstPad * pad)
334 GstElementClass *oclass;
336 g_return_if_fail (GST_IS_ELEMENT (element));
337 g_return_if_fail (GST_IS_PAD (pad));
338 g_return_if_fail (GST_PAD_PAD_TEMPLATE (pad) == NULL ||
339 GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad)) ==
342 oclass = GST_ELEMENT_GET_CLASS (element);
344 /* if the element implements a custom release function we call that, else we
345 * simply remove the pad from the element */
346 if (oclass->release_pad)
347 oclass->release_pad (element, pad);
349 gst_element_remove_pad (element, pad);
353 * gst_element_provide_clock:
354 * @element: a #GstElement to query
356 * Get the clock provided by the given element.
357 * <note>An element is only required to provide a clock in the PAUSED
358 * state. Some elements can provide a clock in other states.</note>
360 * Returns: (transfer full) (nullable): the GstClock provided by the
361 * element or %NULL if no clock could be provided. Unref after usage.
366 gst_element_provide_clock (GstElement * element)
368 GstClock *result = NULL;
369 GstElementClass *oclass;
371 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
373 oclass = GST_ELEMENT_GET_CLASS (element);
375 if (oclass->provide_clock)
376 result = oclass->provide_clock (element);
382 gst_element_set_clock_func (GstElement * element, GstClock * clock)
386 GST_OBJECT_LOCK (element);
387 clock_p = &element->clock;
388 gst_object_replace ((GstObject **) clock_p, (GstObject *) clock);
389 GST_OBJECT_UNLOCK (element);
395 * gst_element_set_clock:
396 * @element: a #GstElement to set the clock for.
397 * @clock: the #GstClock to set for the element.
399 * Sets the clock for the element. This function increases the
400 * refcount on the clock. Any previously set clock on the object
403 * Returns: %TRUE if the element accepted the clock. An element can refuse a
404 * clock when it, for example, is not able to slave its internal clock to the
405 * @clock or when it requires a specific clock to operate.
410 gst_element_set_clock (GstElement * element, GstClock * clock)
412 GstElementClass *oclass;
413 gboolean res = FALSE;
415 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
416 g_return_val_if_fail (clock == NULL || GST_IS_CLOCK (clock), FALSE);
418 oclass = GST_ELEMENT_GET_CLASS (element);
420 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element, "setting clock %p", clock);
422 if (oclass->set_clock)
423 res = oclass->set_clock (element, clock);
429 * gst_element_get_clock:
430 * @element: a #GstElement to get the clock of.
432 * Gets the currently configured clock of the element. This is the clock as was
433 * last set with gst_element_set_clock().
435 * Elements in a pipeline will only have their clock set when the
436 * pipeline is in the PLAYING state.
438 * Returns: (transfer full): the #GstClock of the element. unref after usage.
443 gst_element_get_clock (GstElement * element)
447 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
449 GST_OBJECT_LOCK (element);
450 if ((result = element->clock))
451 gst_object_ref (result);
452 GST_OBJECT_UNLOCK (element);
458 * gst_element_set_base_time:
459 * @element: a #GstElement.
460 * @time: the base time to set.
462 * Set the base time of an element. See gst_element_get_base_time().
467 gst_element_set_base_time (GstElement * element, GstClockTime time)
471 g_return_if_fail (GST_IS_ELEMENT (element));
473 GST_OBJECT_LOCK (element);
474 old = element->base_time;
475 element->base_time = time;
476 GST_OBJECT_UNLOCK (element);
478 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
479 "set base_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
480 GST_TIME_ARGS (time), GST_TIME_ARGS (old));
484 * gst_element_get_base_time:
485 * @element: a #GstElement.
487 * Returns the base time of the element. The base time is the
488 * absolute time of the clock when this element was last put to
489 * PLAYING. Subtracting the base time from the clock time gives
490 * the running time of the element.
492 * Returns: the base time of the element.
497 gst_element_get_base_time (GstElement * element)
501 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
503 GST_OBJECT_LOCK (element);
504 result = element->base_time;
505 GST_OBJECT_UNLOCK (element);
511 * gst_element_set_start_time:
512 * @element: a #GstElement.
513 * @time: the base time to set.
515 * Set the start time of an element. The start time of the element is the
516 * running time of the element when it last went to the PAUSED state. In READY
517 * or after a flushing seek, it is set to 0.
519 * Toplevel elements like #GstPipeline will manage the start_time and
520 * base_time on its children. Setting the start_time to #GST_CLOCK_TIME_NONE
521 * on such a toplevel element will disable the distribution of the base_time to
522 * the children and can be useful if the application manages the base_time
523 * itself, for example if you want to synchronize capture from multiple
524 * pipelines, and you can also ensure that the pipelines have the same clock.
529 gst_element_set_start_time (GstElement * element, GstClockTime time)
533 g_return_if_fail (GST_IS_ELEMENT (element));
535 GST_OBJECT_LOCK (element);
536 old = GST_ELEMENT_START_TIME (element);
537 GST_ELEMENT_START_TIME (element) = time;
538 GST_OBJECT_UNLOCK (element);
540 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
541 "set start_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
542 GST_TIME_ARGS (time), GST_TIME_ARGS (old));
546 * gst_element_get_start_time:
547 * @element: a #GstElement.
549 * Returns the start time of the element. The start time is the
550 * running time of the clock when this element was last put to PAUSED.
552 * Usually the start_time is managed by a toplevel element such as
557 * Returns: the start time of the element.
560 gst_element_get_start_time (GstElement * element)
564 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
566 GST_OBJECT_LOCK (element);
567 result = GST_ELEMENT_START_TIME (element);
568 GST_OBJECT_UNLOCK (element);
575 * gst_element_set_index:
576 * @element: a #GstElement.
577 * @index: (transfer none): a #GstIndex.
579 * Set @index on the element. The refcount of the index
580 * will be increased, any previously set index is unreffed.
585 gst_element_set_index (GstElement * element, GstIndex * index)
587 GstElementClass *oclass;
589 g_return_if_fail (GST_IS_ELEMENT (element));
590 g_return_if_fail (index == NULL || GST_IS_INDEX (index));
592 oclass = GST_ELEMENT_GET_CLASS (element);
594 if (oclass->set_index)
595 oclass->set_index (element, index);
599 * gst_element_get_index:
600 * @element: a #GstElement.
602 * Gets the index from the element.
604 * Returns: (transfer full) (nullable): a #GstIndex or %NULL when no
605 * index was set on the element. unref after usage.
610 gst_element_get_index (GstElement * element)
612 GstElementClass *oclass;
613 GstIndex *result = NULL;
615 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
617 oclass = GST_ELEMENT_GET_CLASS (element);
619 if (oclass->get_index)
620 result = oclass->get_index (element);
627 * gst_element_add_pad:
628 * @element: a #GstElement to add the pad to.
629 * @pad: (transfer full): the #GstPad to add to the element.
631 * Adds a pad (link point) to @element. @pad's parent will be set to @element;
632 * see gst_object_set_parent() for refcounting information.
634 * Pads are not automatically activated so elements should perform the needed
635 * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
636 * state. See gst_pad_set_active() for more information about activating pads.
638 * The pad and the element should be unlocked when calling this function.
640 * This function will emit the #GstElement::pad-added signal on the element.
642 * Returns: %TRUE if the pad could be added. This function can fail when
643 * a pad with the same name already existed or the pad already had another
649 gst_element_add_pad (GstElement * element, GstPad * pad)
654 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
655 g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
657 /* locking pad to look at the name */
658 GST_OBJECT_LOCK (pad);
659 pad_name = g_strdup (GST_PAD_NAME (pad));
660 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
661 GST_STR_NULL (pad_name));
662 active = GST_PAD_IS_ACTIVE (pad);
663 GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_PARENT);
664 GST_OBJECT_UNLOCK (pad);
666 /* then check to see if there's already a pad by that name here */
667 GST_OBJECT_LOCK (element);
668 if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, pad_name)))
671 /* try to set the pad's parent */
672 if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (pad),
673 GST_OBJECT_CAST (element))))
676 /* check for active pads */
677 if (!active && (GST_STATE (element) > GST_STATE_READY ||
678 GST_STATE_NEXT (element) == GST_STATE_PAUSED)) {
679 g_warning ("adding inactive pad '%s' to running element '%s', you need to "
680 "use gst_pad_set_active(pad,TRUE) before adding it.",
681 GST_STR_NULL (pad_name), GST_ELEMENT_NAME (element));
682 gst_pad_set_active (pad, TRUE);
687 /* add it to the list */
688 switch (gst_pad_get_direction (pad)) {
690 element->srcpads = g_list_append (element->srcpads, pad);
691 element->numsrcpads++;
694 element->sinkpads = g_list_append (element->sinkpads, pad);
695 element->numsinkpads++;
700 element->pads = g_list_append (element->pads, pad);
702 element->pads_cookie++;
703 GST_OBJECT_UNLOCK (element);
705 /* emit the PAD_ADDED signal */
706 g_signal_emit (element, gst_element_signals[PAD_ADDED], 0, pad);
707 GST_TRACER_ELEMENT_ADD_PAD (element, pad);
713 g_critical ("Padname %s is not unique in element %s, not adding",
714 pad_name, GST_ELEMENT_NAME (element));
715 GST_OBJECT_UNLOCK (element);
722 ("Pad %s already has parent when trying to add to element %s",
723 pad_name, GST_ELEMENT_NAME (element));
724 GST_OBJECT_UNLOCK (element);
730 GST_OBJECT_LOCK (pad);
732 ("Trying to add pad %s to element %s, but it has no direction",
733 GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
734 GST_OBJECT_UNLOCK (pad);
735 GST_OBJECT_UNLOCK (element);
741 * gst_element_remove_pad:
742 * @element: a #GstElement to remove pad from.
743 * @pad: (transfer full): the #GstPad to remove from the element.
745 * Removes @pad from @element. @pad will be destroyed if it has not been
746 * referenced elsewhere using gst_object_unparent().
748 * This function is used by plugin developers and should not be used
749 * by applications. Pads that were dynamically requested from elements
750 * with gst_element_request_pad() should be released with the
751 * gst_element_release_request_pad() function instead.
753 * Pads are not automatically deactivated so elements should perform the needed
754 * steps to deactivate the pad in case this pad is removed in the PAUSED or
755 * PLAYING state. See gst_pad_set_active() for more information about
758 * The pad and the element should be unlocked when calling this function.
760 * This function will emit the #GstElement::pad-removed signal on the element.
762 * Returns: %TRUE if the pad could be removed. Can return %FALSE if the
763 * pad does not belong to the provided element.
768 gst_element_remove_pad (GstElement * element, GstPad * pad)
772 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
773 g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
775 /* locking pad to look at the name and parent */
776 GST_OBJECT_LOCK (pad);
777 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'",
778 GST_STR_NULL (GST_PAD_NAME (pad)));
780 if (G_UNLIKELY (GST_PAD_PARENT (pad) != element))
782 GST_OBJECT_UNLOCK (pad);
785 if ((peer = gst_pad_get_peer (pad))) {
786 /* window for MT unsafeness, someone else could unlink here
787 * and then we call unlink with wrong pads. The unlink
788 * function would catch this and safely return failed. */
789 if (GST_PAD_IS_SRC (pad))
790 gst_pad_unlink (pad, peer);
792 gst_pad_unlink (peer, pad);
794 gst_object_unref (peer);
797 GST_OBJECT_LOCK (element);
798 /* remove it from the list */
799 switch (gst_pad_get_direction (pad)) {
801 element->srcpads = g_list_remove (element->srcpads, pad);
802 element->numsrcpads--;
805 element->sinkpads = g_list_remove (element->sinkpads, pad);
806 element->numsinkpads--;
809 g_critical ("Removing pad without direction???");
812 element->pads = g_list_remove (element->pads, pad);
814 element->pads_cookie++;
815 GST_OBJECT_UNLOCK (element);
817 /* emit the PAD_REMOVED signal before unparenting and losing the last ref. */
818 g_signal_emit (element, gst_element_signals[PAD_REMOVED], 0, pad);
819 GST_TRACER_ELEMENT_REMOVE_PAD (element, pad);
820 gst_object_unparent (GST_OBJECT_CAST (pad));
827 /* locking order is element > pad */
828 GST_OBJECT_UNLOCK (pad);
830 GST_OBJECT_LOCK (element);
831 GST_OBJECT_LOCK (pad);
832 g_critical ("Padname %s:%s does not belong to element %s when removing",
833 GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
834 GST_OBJECT_UNLOCK (pad);
835 GST_OBJECT_UNLOCK (element);
841 * gst_element_no_more_pads:
842 * @element: a #GstElement
844 * Use this function to signal that the element does not expect any more pads
845 * to show up in the current pipeline. This function should be called whenever
846 * pads have been added by the element itself. Elements with #GST_PAD_SOMETIMES
847 * pad templates use this in combination with autopluggers to figure out that
848 * the element is done initializing its pads.
850 * This function emits the #GstElement::no-more-pads signal.
855 gst_element_no_more_pads (GstElement * element)
857 g_return_if_fail (GST_IS_ELEMENT (element));
859 g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
863 pad_compare_name (GstPad * pad1, const gchar * name)
867 GST_OBJECT_LOCK (pad1);
868 result = strcmp (GST_PAD_NAME (pad1), name);
869 GST_OBJECT_UNLOCK (pad1);
875 * gst_element_get_static_pad:
876 * @element: a #GstElement to find a static pad of.
877 * @name: the name of the static #GstPad to retrieve.
879 * Retrieves a pad from @element by name. This version only retrieves
880 * already-existing (i.e. 'static') pads.
882 * Returns: (transfer full) (nullable): the requested #GstPad if
883 * found, otherwise %NULL. unref after usage.
888 gst_element_get_static_pad (GstElement * element, const gchar * name)
891 GstPad *result = NULL;
893 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
894 g_return_val_if_fail (name != NULL, NULL);
896 GST_OBJECT_LOCK (element);
898 g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
900 result = GST_PAD_CAST (find->data);
901 gst_object_ref (result);
904 if (result == NULL) {
905 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
906 name, GST_ELEMENT_NAME (element));
908 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
909 GST_ELEMENT_NAME (element), name);
911 GST_OBJECT_UNLOCK (element);
917 _gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
918 const gchar * name, const GstCaps * caps)
920 GstPad *newpad = NULL;
921 GstElementClass *oclass;
923 oclass = GST_ELEMENT_GET_CLASS (element);
925 #ifndef G_DISABLE_CHECKS
926 /* Some sanity checking here */
930 /* Is this the template name? */
931 if (strstr (name, "%") || !strchr (templ->name_template, '%')) {
932 g_return_val_if_fail (strcmp (name, templ->name_template) == 0, NULL);
934 const gchar *str, *data;
937 /* Otherwise check if it's a valid name for the name template */
938 str = strchr (templ->name_template, '%');
939 g_return_val_if_fail (str != NULL, NULL);
940 g_return_val_if_fail (strncmp (templ->name_template, name,
941 str - templ->name_template) == 0, NULL);
942 g_return_val_if_fail (strlen (name) > str - templ->name_template, NULL);
944 data = name + (str - templ->name_template);
946 /* Can either be %s or %d or %u, do sanity checking for %d */
947 if (*(str + 1) == 'd') {
951 tmp = g_ascii_strtoll (data, &endptr, 10);
952 g_return_val_if_fail (tmp >= G_MININT && tmp <= G_MAXINT
953 && *endptr == '\0', NULL);
954 } else if (*(str + 1) == 'u') {
958 tmp = g_ascii_strtoull (data, &endptr, 10);
959 g_return_val_if_fail (tmp <= G_MAXUINT && *endptr == '\0', NULL);
963 pad = gst_element_get_static_pad (element, name);
965 gst_object_unref (pad);
966 /* FIXME 2.0: Change this to g_return_val_if_fail() */
967 g_critical ("Element %s already has a pad named %s, the behaviour of "
968 " gst_element_get_request_pad() for existing pads is undefined!",
969 GST_ELEMENT_NAME (element), name);
974 if (oclass->request_new_pad)
975 newpad = (oclass->request_new_pad) (element, templ, name, caps);
978 gst_object_ref (newpad);
984 * gst_element_get_request_pad:
985 * @element: a #GstElement to find a request pad of.
986 * @name: the name of the request #GstPad to retrieve.
988 * Retrieves a pad from the element by name (e.g. "src_\%d"). This version only
989 * retrieves request pads. The pad should be released with
990 * gst_element_release_request_pad().
992 * This method is slower than manually getting the pad template and calling
993 * gst_element_request_pad() if the pads should have a specific name (e.g.
994 * @name is "src_1" instead of "src_\%u").
996 * Returns: (transfer full) (nullable): requested #GstPad if found,
997 * otherwise %NULL. Release after usage.
1000 gst_element_get_request_pad (GstElement * element, const gchar * name)
1002 GstPadTemplate *templ = NULL;
1004 const gchar *req_name = NULL;
1005 gboolean templ_found = FALSE;
1008 gchar *str, *endptr = NULL;
1009 GstElementClass *class;
1011 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1012 g_return_val_if_fail (name != NULL, NULL);
1014 class = GST_ELEMENT_GET_CLASS (element);
1016 /* if the name contains a %, we assume it's the complete template name. Get
1017 * the template and try to get a pad */
1018 if (strstr (name, "%")) {
1019 templ = gst_element_class_get_request_pad_template (class, name);
1024 /* there is no % in the name, try to find a matching template */
1025 list = class->padtemplates;
1026 while (!templ_found && list) {
1027 templ = (GstPadTemplate *) list->data;
1028 if (templ->presence == GST_PAD_REQUEST) {
1029 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
1030 templ->name_template);
1031 /* see if we find an exact match */
1032 if (strcmp (name, templ->name_template) == 0) {
1037 /* Because of sanity checks in gst_pad_template_new(), we know that %s
1038 and %d and %u, occurring at the end of the name_template, are the only
1040 else if ((str = strchr (templ->name_template, '%'))
1041 && strncmp (templ->name_template, name,
1042 str - templ->name_template) == 0
1043 && strlen (name) > str - templ->name_template) {
1044 data = name + (str - templ->name_template);
1045 if (*(str + 1) == 'd') {
1049 tmp = strtol (data, &endptr, 10);
1050 if (tmp != G_MINLONG && tmp != G_MAXLONG && endptr &&
1056 } else if (*(str + 1) == 'u') {
1060 tmp = strtoul (data, &endptr, 10);
1061 if (tmp != G_MAXULONG && endptr && *endptr == '\0') {
1081 pad = _gst_element_request_pad (element, templ, req_name, NULL);
1087 * gst_element_request_pad: (virtual request_new_pad)
1088 * @element: a #GstElement to find a request pad of.
1089 * @templ: a #GstPadTemplate of which we want a pad of.
1090 * @name: (transfer none) (allow-none): the name of the request #GstPad
1091 * to retrieve. Can be %NULL.
1092 * @caps: (transfer none) (allow-none): the caps of the pad we want to
1093 * request. Can be %NULL.
1095 * Retrieves a request pad from the element according to the provided template.
1096 * Pad templates can be looked up using
1097 * gst_element_factory_get_static_pad_templates().
1099 * The pad should be released with gst_element_release_request_pad().
1101 * Returns: (transfer full) (nullable): requested #GstPad if found,
1102 * otherwise %NULL. Release after usage.
1105 gst_element_request_pad (GstElement * element,
1106 GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
1108 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1109 g_return_val_if_fail (templ != NULL, NULL);
1110 g_return_val_if_fail (templ->presence == GST_PAD_REQUEST, NULL);
1112 return _gst_element_request_pad (element, templ, name, caps);
1115 static GstIterator *
1116 gst_element_iterate_pad_list (GstElement * element, GList ** padlist)
1118 GstIterator *result;
1120 GST_OBJECT_LOCK (element);
1121 result = gst_iterator_new_list (GST_TYPE_PAD,
1122 GST_OBJECT_GET_LOCK (element),
1123 &element->pads_cookie, padlist, (GObject *) element, NULL);
1124 GST_OBJECT_UNLOCK (element);
1130 * gst_element_iterate_pads:
1131 * @element: a #GstElement to iterate pads of.
1133 * Retrieves an iterator of @element's pads. The iterator should
1134 * be freed after usage. Also more specialized iterators exists such as
1135 * gst_element_iterate_src_pads() or gst_element_iterate_sink_pads().
1137 * The order of pads returned by the iterator will be the order in which
1138 * the pads were added to the element.
1140 * Returns: (transfer full): the #GstIterator of #GstPad.
1145 gst_element_iterate_pads (GstElement * element)
1147 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1149 return gst_element_iterate_pad_list (element, &element->pads);
1153 * gst_element_iterate_src_pads:
1154 * @element: a #GstElement.
1156 * Retrieves an iterator of @element's source pads.
1158 * The order of pads returned by the iterator will be the order in which
1159 * the pads were added to the element.
1161 * Returns: (transfer full): the #GstIterator of #GstPad.
1166 gst_element_iterate_src_pads (GstElement * element)
1168 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1170 return gst_element_iterate_pad_list (element, &element->srcpads);
1174 * gst_element_iterate_sink_pads:
1175 * @element: a #GstElement.
1177 * Retrieves an iterator of @element's sink pads.
1179 * The order of pads returned by the iterator will be the order in which
1180 * the pads were added to the element.
1182 * Returns: (transfer full): the #GstIterator of #GstPad.
1187 gst_element_iterate_sink_pads (GstElement * element)
1189 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1191 return gst_element_iterate_pad_list (element, &element->sinkpads);
1195 * gst_element_class_add_pad_template:
1196 * @klass: the #GstElementClass to add the pad template to.
1197 * @templ: (transfer full): a #GstPadTemplate to add to the element class.
1199 * Adds a padtemplate to an element class. This is mainly used in the _class_init
1200 * functions of classes. If a pad template with the same name as an already
1201 * existing one is added the old one is replaced by the new one.
1205 gst_element_class_add_pad_template (GstElementClass * klass,
1206 GstPadTemplate * templ)
1208 GList *template_list = klass->padtemplates;
1210 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1211 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1213 /* If we already have a pad template with the same name replace the
1215 while (template_list) {
1216 GstPadTemplate *padtempl = (GstPadTemplate *) template_list->data;
1218 /* Found pad with the same name, replace and return */
1219 if (strcmp (templ->name_template, padtempl->name_template) == 0) {
1220 gst_object_unref (padtempl);
1221 template_list->data = templ;
1224 template_list = g_list_next (template_list);
1227 /* Take ownership of the floating ref */
1228 gst_object_ref_sink (templ);
1230 klass->padtemplates = g_list_append (klass->padtemplates, templ);
1231 klass->numpadtemplates++;
1235 * gst_element_class_add_static_pad_template:
1236 * @klass: the #GstElementClass to add the pad template to.
1237 * @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
1239 * Adds a pad template to an element class based on the static pad template
1240 * @templ. This is mainly used in the _class_init functions of element
1241 * implementations. If a pad template with the same name already exists,
1242 * the old one is replaced by the new one.
1247 gst_element_class_add_static_pad_template (GstElementClass * klass,
1248 GstStaticPadTemplate * static_templ)
1250 gst_element_class_add_pad_template (klass,
1251 gst_static_pad_template_get (static_templ));
1255 * gst_element_class_add_metadata:
1256 * @klass: class to set metadata for
1257 * @key: the key to set
1258 * @value: the value to set
1260 * Set @key with @value as metadata in @klass.
1263 gst_element_class_add_metadata (GstElementClass * klass,
1264 const gchar * key, const gchar * value)
1266 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1267 g_return_if_fail (key != NULL);
1268 g_return_if_fail (value != NULL);
1270 gst_structure_set ((GstStructure *) klass->metadata,
1271 key, G_TYPE_STRING, value, NULL);
1275 * gst_element_class_add_static_metadata:
1276 * @klass: class to set metadata for
1277 * @key: the key to set
1278 * @value: the value to set
1280 * Set @key with @value as metadata in @klass.
1282 * Same as gst_element_class_add_metadata(), but @value must be a static string
1283 * or an inlined string, as it will not be copied. (GStreamer plugins will
1284 * be made resident once loaded, so this function can be used even from
1285 * dynamically loaded plugins.)
1288 gst_element_class_add_static_metadata (GstElementClass * klass,
1289 const gchar * key, const gchar * value)
1291 GValue val = G_VALUE_INIT;
1293 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1294 g_return_if_fail (key != NULL);
1295 g_return_if_fail (value != NULL);
1297 g_value_init (&val, G_TYPE_STRING);
1298 g_value_set_static_string (&val, value);
1299 gst_structure_take_value ((GstStructure *) klass->metadata, key, &val);
1303 * gst_element_class_set_metadata:
1304 * @klass: class to set metadata for
1305 * @longname: The long English name of the element. E.g. "File Sink"
1306 * @classification: String describing the type of element, as an unordered list
1307 * separated with slashes ('/'). See draft-klass.txt of the design docs
1308 * for more details and common types. E.g: "Sink/File"
1309 * @description: Sentence describing the purpose of the element.
1310 * E.g: "Write stream to a file"
1311 * @author: Name and contact details of the author(s). Use \n to separate
1312 * multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
1314 * Sets the detailed information for a #GstElementClass.
1315 * <note>This function is for use in _class_init functions only.</note>
1318 gst_element_class_set_metadata (GstElementClass * klass,
1319 const gchar * longname, const gchar * classification,
1320 const gchar * description, const gchar * author)
1322 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1323 g_return_if_fail (longname != NULL && *longname != '\0');
1324 g_return_if_fail (classification != NULL && *classification != '\0');
1325 g_return_if_fail (description != NULL && *description != '\0');
1326 g_return_if_fail (author != NULL && *author != '\0');
1328 gst_structure_id_set ((GstStructure *) klass->metadata,
1329 GST_QUARK (ELEMENT_METADATA_LONGNAME), G_TYPE_STRING, longname,
1330 GST_QUARK (ELEMENT_METADATA_KLASS), G_TYPE_STRING, classification,
1331 GST_QUARK (ELEMENT_METADATA_DESCRIPTION), G_TYPE_STRING, description,
1332 GST_QUARK (ELEMENT_METADATA_AUTHOR), G_TYPE_STRING, author, NULL);
1336 * gst_element_class_set_static_metadata:
1337 * @klass: class to set metadata for
1338 * @longname: The long English name of the element. E.g. "File Sink"
1339 * @classification: String describing the type of element, as an unordered list
1340 * separated with slashes ('/'). See draft-klass.txt of the design docs
1341 * for more details and common types. E.g: "Sink/File"
1342 * @description: Sentence describing the purpose of the element.
1343 * E.g: "Write stream to a file"
1344 * @author: Name and contact details of the author(s). Use \n to separate
1345 * multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
1347 * Sets the detailed information for a #GstElementClass.
1348 * <note>This function is for use in _class_init functions only.</note>
1350 * Same as gst_element_class_set_metadata(), but @longname, @classification,
1351 * @description, and @author must be static strings or inlined strings, as
1352 * they will not be copied. (GStreamer plugins will be made resident once
1353 * loaded, so this function can be used even from dynamically loaded plugins.)
1356 gst_element_class_set_static_metadata (GstElementClass * klass,
1357 const gchar * longname, const gchar * classification,
1358 const gchar * description, const gchar * author)
1360 GstStructure *s = (GstStructure *) klass->metadata;
1361 GValue val = G_VALUE_INIT;
1363 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1364 g_return_if_fail (longname != NULL && *longname != '\0');
1365 g_return_if_fail (classification != NULL && *classification != '\0');
1366 g_return_if_fail (description != NULL && *description != '\0');
1367 g_return_if_fail (author != NULL && *author != '\0');
1369 g_value_init (&val, G_TYPE_STRING);
1371 g_value_set_static_string (&val, longname);
1372 gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_LONGNAME), &val);
1374 g_value_set_static_string (&val, classification);
1375 gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_KLASS), &val);
1377 g_value_set_static_string (&val, description);
1378 gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_DESCRIPTION),
1381 g_value_set_static_string (&val, author);
1382 gst_structure_id_take_value (s, GST_QUARK (ELEMENT_METADATA_AUTHOR), &val);
1386 * gst_element_class_get_metadata:
1387 * @klass: class to get metadata for
1388 * @key: the key to get
1390 * Get metadata with @key in @klass.
1392 * Returns: the metadata for @key.
1395 gst_element_class_get_metadata (GstElementClass * klass, const gchar * key)
1397 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (klass), NULL);
1398 g_return_val_if_fail (key != NULL, NULL);
1400 return gst_structure_get_string ((GstStructure *) klass->metadata, key);
1404 * gst_element_class_get_pad_template_list:
1405 * @element_class: a #GstElementClass to get pad templates of.
1407 * Retrieves a list of the pad templates associated with @element_class. The
1408 * list must not be modified by the calling code.
1409 * <note>If you use this function in the #GInstanceInitFunc of an object class
1410 * that has subclasses, make sure to pass the g_class parameter of the
1411 * #GInstanceInitFunc here.</note>
1413 * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
1417 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1419 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1421 return element_class->padtemplates;
1425 * gst_element_class_get_pad_template:
1426 * @element_class: a #GstElementClass to get the pad template of.
1427 * @name: the name of the #GstPadTemplate to get.
1429 * Retrieves a padtemplate from @element_class with the given name.
1430 * <note>If you use this function in the #GInstanceInitFunc of an object class
1431 * that has subclasses, make sure to pass the g_class parameter of the
1432 * #GInstanceInitFunc here.</note>
1434 * Returns: (transfer none) (nullable): the #GstPadTemplate with the
1435 * given name, or %NULL if none was found. No unreferencing is
1439 gst_element_class_get_pad_template (GstElementClass *
1440 element_class, const gchar * name)
1444 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1445 g_return_val_if_fail (name != NULL, NULL);
1447 padlist = element_class->padtemplates;
1450 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1452 if (strcmp (padtempl->name_template, name) == 0)
1455 padlist = g_list_next (padlist);
1461 static GstPadTemplate *
1462 gst_element_class_get_request_pad_template (GstElementClass *
1463 element_class, const gchar * name)
1465 GstPadTemplate *tmpl;
1467 tmpl = gst_element_class_get_pad_template (element_class, name);
1468 if (tmpl != NULL && tmpl->presence == GST_PAD_REQUEST)
1474 /* get a random pad on element of the given direction.
1475 * The pad is random in a sense that it is the first pad that is (optionaly) linked.
1478 gst_element_get_random_pad (GstElement * element,
1479 gboolean need_linked, GstPadDirection dir)
1481 GstPad *result = NULL;
1484 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1488 GST_OBJECT_LOCK (element);
1489 pads = element->srcpads;
1492 GST_OBJECT_LOCK (element);
1493 pads = element->sinkpads;
1496 goto wrong_direction;
1498 for (; pads; pads = g_list_next (pads)) {
1499 GstPad *pad = GST_PAD_CAST (pads->data);
1501 GST_OBJECT_LOCK (pad);
1502 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1503 GST_DEBUG_PAD_NAME (pad));
1505 if (need_linked && !GST_PAD_IS_LINKED (pad)) {
1506 /* if we require a linked pad, and it is not linked, continue the
1508 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1509 GST_DEBUG_PAD_NAME (pad));
1510 GST_OBJECT_UNLOCK (pad);
1513 /* found a pad, stop search */
1514 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
1515 GST_DEBUG_PAD_NAME (pad));
1516 GST_OBJECT_UNLOCK (pad);
1522 gst_object_ref (result);
1524 GST_OBJECT_UNLOCK (element);
1528 /* ERROR handling */
1531 g_warning ("unknown pad direction %d", dir);
1537 gst_element_default_send_event (GstElement * element, GstEvent * event)
1539 gboolean result = FALSE;
1542 pad = GST_EVENT_IS_DOWNSTREAM (event) ?
1543 gst_element_get_random_pad (element, TRUE, GST_PAD_SINK) :
1544 gst_element_get_random_pad (element, TRUE, GST_PAD_SRC);
1547 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1548 "pushing %s event to random %s pad %s:%s",
1549 GST_EVENT_TYPE_NAME (event),
1550 (GST_PAD_DIRECTION (pad) == GST_PAD_SRC ? "src" : "sink"),
1551 GST_DEBUG_PAD_NAME (pad));
1553 result = gst_pad_send_event (pad, event);
1554 gst_object_unref (pad);
1556 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send %s event on element %s",
1557 GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1558 gst_event_unref (event);
1564 * gst_element_send_event:
1565 * @element: a #GstElement to send the event to.
1566 * @event: (transfer full): the #GstEvent to send to the element.
1568 * Sends an event to an element. If the element doesn't implement an
1569 * event handler, the event will be pushed on a random linked sink pad for
1570 * downstream events or a random linked source pad for upstream events.
1572 * This function takes ownership of the provided event so you should
1573 * gst_event_ref() it if you want to reuse the event after this call.
1577 * Returns: %TRUE if the event was handled. Events that trigger a preroll (such
1578 * as flushing seeks and steps) will emit %GST_MESSAGE_ASYNC_DONE.
1581 gst_element_send_event (GstElement * element, GstEvent * event)
1583 GstElementClass *oclass;
1584 gboolean result = FALSE;
1586 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1587 g_return_val_if_fail (event != NULL, FALSE);
1589 oclass = GST_ELEMENT_GET_CLASS (element);
1591 GST_STATE_LOCK (element);
1592 if (oclass->send_event) {
1593 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send %s event on element %s",
1594 GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1595 result = oclass->send_event (element, event);
1597 gst_event_unref (event);
1599 GST_STATE_UNLOCK (element);
1606 * @element: a #GstElement to send the event to.
1607 * @rate: The new playback rate
1608 * @format: The format of the seek values
1609 * @flags: The optional seek flags.
1610 * @start_type: The type and flags for the new start position
1611 * @start: The value of the new start position
1612 * @stop_type: The type and flags for the new stop position
1613 * @stop: The value of the new stop position
1615 * Sends a seek event to an element. See gst_event_new_seek() for the details of
1616 * the parameters. The seek event is sent to the element using
1617 * gst_element_send_event().
1621 * Returns: %TRUE if the event was handled. Flushing seeks will trigger a
1622 * preroll, which will emit %GST_MESSAGE_ASYNC_DONE.
1625 gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
1626 GstSeekFlags flags, GstSeekType start_type, gint64 start,
1627 GstSeekType stop_type, gint64 stop)
1632 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1635 gst_event_new_seek (rate, format, flags, start_type, start, stop_type,
1637 result = gst_element_send_event (element, event);
1643 gst_element_default_query (GstElement * element, GstQuery * query)
1645 gboolean result = FALSE;
1648 pad = gst_element_get_random_pad (element, FALSE, GST_PAD_SRC);
1650 result = gst_pad_query (pad, query);
1652 gst_object_unref (pad);
1654 pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1656 GstPad *peer = gst_pad_get_peer (pad);
1659 result = gst_pad_query (peer, query);
1661 gst_object_unref (peer);
1663 gst_object_unref (pad);
1670 * gst_element_query:
1671 * @element: a #GstElement to perform the query on.
1672 * @query: (transfer none): the #GstQuery.
1674 * Performs a query on the given element.
1676 * For elements that don't implement a query handler, this function
1677 * forwards the query to a random srcpad or to the peer of a
1678 * random linked sinkpad of this element.
1680 * Please note that some queries might need a running pipeline to work.
1682 * Returns: %TRUE if the query could be performed.
1687 gst_element_query (GstElement * element, GstQuery * query)
1689 GstElementClass *klass;
1690 gboolean res = FALSE;
1692 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1693 g_return_val_if_fail (query != NULL, FALSE);
1695 GST_TRACER_ELEMENT_QUERY_PRE (element, query);
1697 klass = GST_ELEMENT_GET_CLASS (element);
1699 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
1700 GST_ELEMENT_NAME (element));
1701 res = klass->query (element, query);
1704 GST_TRACER_ELEMENT_QUERY_POST (element, query, res);
1709 gst_element_post_message_default (GstElement * element, GstMessage * message)
1712 gboolean result = FALSE;
1714 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1715 g_return_val_if_fail (message != NULL, FALSE);
1717 GST_OBJECT_LOCK (element);
1720 if (G_UNLIKELY (bus == NULL))
1723 gst_object_ref (bus);
1724 GST_OBJECT_UNLOCK (element);
1726 /* we release the element lock when posting the message so that any
1727 * (synchronous) message handlers can operate on the element */
1728 result = gst_bus_post (bus, message);
1729 gst_object_unref (bus);
1736 GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element,
1737 "not posting message %p: no bus", message);
1738 GST_OBJECT_UNLOCK (element);
1739 gst_message_unref (message);
1745 * gst_element_post_message:
1746 * @element: a #GstElement posting the message
1747 * @message: (transfer full): a #GstMessage to post
1749 * Post a message on the element's #GstBus. This function takes ownership of the
1750 * message; if you want to access the message after this call, you should add an
1751 * additional reference before calling.
1753 * Returns: %TRUE if the message was successfully posted. The function returns
1754 * %FALSE if the element did not have a bus.
1759 gst_element_post_message (GstElement * element, GstMessage * message)
1761 GstElementClass *klass;
1762 gboolean res = FALSE;
1764 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1765 g_return_val_if_fail (message != NULL, FALSE);
1767 GST_TRACER_ELEMENT_POST_MESSAGE_PRE (element, message);
1769 klass = GST_ELEMENT_GET_CLASS (element);
1770 if (klass->post_message)
1771 res = klass->post_message (element, message);
1773 gst_message_unref (message);
1775 GST_TRACER_ELEMENT_POST_MESSAGE_POST (element, res);
1780 * _gst_element_error_printf:
1781 * @format: (allow-none): the printf-like format to use, or %NULL
1783 * This function is only used internally by the gst_element_error() macro.
1785 * Returns: (transfer full) (nullable): a newly allocated string, or
1786 * %NULL if the format was %NULL or ""
1791 _gst_element_error_printf (const gchar * format, ...)
1802 va_start (args, format);
1804 len = __gst_vasprintf (&buffer, format, args);
1815 * gst_element_message_full:
1816 * @element: a #GstElement to send message from
1817 * @type: the #GstMessageType
1818 * @domain: the GStreamer GError domain this message belongs to
1819 * @code: the GError code belonging to the domain
1820 * @text: (allow-none) (transfer full): an allocated text string to be used
1821 * as a replacement for the default message connected to code,
1823 * @debug: (allow-none) (transfer full): an allocated debug message to be
1824 * used as a replacement for the default debugging information,
1826 * @file: the source code file where the error was generated
1827 * @function: the source code function where the error was generated
1828 * @line: the source code line where the error was generated
1830 * Post an error, warning or info message on the bus from inside an element.
1832 * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
1833 * #GST_MESSAGE_INFO.
1837 void gst_element_message_full
1838 (GstElement * element, GstMessageType type,
1839 GQuark domain, gint code, gchar * text,
1840 gchar * debug, const gchar * file, const gchar * function, gint line)
1842 GError *gerror = NULL;
1846 gboolean has_debug = TRUE;
1847 GstMessage *message = NULL;
1850 GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start");
1851 g_return_if_fail (GST_IS_ELEMENT (element));
1852 g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1853 (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO));
1855 /* check if we send the given text or the default error text */
1856 if ((text == NULL) || (text[0] == 0)) {
1857 /* text could have come from g_strdup_printf (""); */
1859 sent_text = gst_error_get_message (domain, code);
1863 /* construct a sent_debug with extra information from source */
1864 if ((debug == NULL) || (debug[0] == 0)) {
1865 /* debug could have come from g_strdup_printf (""); */
1869 name = gst_object_get_path_string (GST_OBJECT_CAST (element));
1871 sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
1872 file, line, function, name, debug);
1874 sent_debug = g_strdup_printf ("%s(%d): %s (): %s",
1875 file, line, function, name);
1879 /* create gerror and post message */
1880 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1882 gerror = g_error_new_literal (domain, code, sent_text);
1885 case GST_MESSAGE_ERROR:
1887 gst_message_new_error (GST_OBJECT_CAST (element), gerror, sent_debug);
1889 case GST_MESSAGE_WARNING:
1890 message = gst_message_new_warning (GST_OBJECT_CAST (element), gerror,
1893 case GST_MESSAGE_INFO:
1894 message = gst_message_new_info (GST_OBJECT_CAST (element), gerror,
1898 g_assert_not_reached ();
1901 gst_element_post_message (element, message);
1903 GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
1904 (type == GST_MESSAGE_ERROR ? "error" : "warning"), sent_text);
1907 g_error_free (gerror);
1908 g_free (sent_debug);
1913 * gst_element_is_locked_state:
1914 * @element: a #GstElement.
1916 * Checks if the state of an element is locked.
1917 * If the state of an element is locked, state changes of the parent don't
1918 * affect the element.
1919 * This way you can leave currently unused elements inside bins. Just lock their
1920 * state before changing the state from #GST_STATE_NULL.
1924 * Returns: %TRUE, if the element's state is locked.
1927 gst_element_is_locked_state (GstElement * element)
1931 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1933 GST_OBJECT_LOCK (element);
1934 result = GST_ELEMENT_IS_LOCKED_STATE (element);
1935 GST_OBJECT_UNLOCK (element);
1941 * gst_element_set_locked_state:
1942 * @element: a #GstElement
1943 * @locked_state: %TRUE to lock the element's state
1945 * Locks the state of an element, so state changes of the parent don't affect
1946 * this element anymore.
1950 * Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
1951 * or the elements state-locking needed no change.
1954 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
1958 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1960 GST_OBJECT_LOCK (element);
1961 old = GST_ELEMENT_IS_LOCKED_STATE (element);
1963 if (G_UNLIKELY (old == locked_state))
1967 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
1968 GST_ELEMENT_NAME (element));
1969 GST_OBJECT_FLAG_SET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
1971 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
1972 GST_ELEMENT_NAME (element));
1973 GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
1975 GST_OBJECT_UNLOCK (element);
1981 GST_CAT_DEBUG (GST_CAT_STATES,
1982 "elements %s was already in locked state %d",
1983 GST_ELEMENT_NAME (element), old);
1984 GST_OBJECT_UNLOCK (element);
1991 * gst_element_sync_state_with_parent:
1992 * @element: a #GstElement.
1994 * Tries to change the state of the element to the same as its parent.
1995 * If this function returns %FALSE, the state of element is undefined.
1997 * Returns: %TRUE, if the element's state could be synced to the parent's state.
2002 gst_element_sync_state_with_parent (GstElement * element)
2006 GstStateChangeReturn ret;
2008 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2010 if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
2011 GstState parent_current, parent_pending;
2013 GST_OBJECT_LOCK (parent);
2014 parent_current = GST_STATE (parent);
2015 parent_pending = GST_STATE_PENDING (parent);
2016 GST_OBJECT_UNLOCK (parent);
2018 /* set to pending if there is one, else we set it to the current state of
2020 if (parent_pending != GST_STATE_VOID_PENDING)
2021 target = parent_pending;
2023 target = parent_current;
2025 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2026 "syncing state (%s) to parent %s %s (%s, %s)",
2027 gst_element_state_get_name (GST_STATE (element)),
2028 GST_ELEMENT_NAME (parent), gst_element_state_get_name (target),
2029 gst_element_state_get_name (parent_current),
2030 gst_element_state_get_name (parent_pending));
2032 ret = gst_element_set_state (element, target);
2033 if (ret == GST_STATE_CHANGE_FAILURE)
2036 gst_object_unref (parent);
2040 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "element has no parent");
2047 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2048 "syncing state failed (%s)",
2049 gst_element_state_change_return_get_name (ret));
2050 gst_object_unref (parent);
2056 static GstStateChangeReturn
2057 gst_element_get_state_func (GstElement * element,
2058 GstState * state, GstState * pending, GstClockTime timeout)
2060 GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
2061 GstState old_pending;
2063 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
2064 GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
2066 GST_OBJECT_LOCK (element);
2067 ret = GST_STATE_RETURN (element);
2068 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
2069 gst_element_state_change_return_get_name (ret));
2071 /* we got an error, report immediately */
2072 if (ret == GST_STATE_CHANGE_FAILURE)
2075 /* we got no_preroll, report immediately */
2076 if (ret == GST_STATE_CHANGE_NO_PREROLL)
2079 /* no need to wait async if we are not async */
2080 if (ret != GST_STATE_CHANGE_ASYNC)
2083 old_pending = GST_STATE_PENDING (element);
2084 if (old_pending != GST_STATE_VOID_PENDING) {
2088 /* get cookie to detect state changes during waiting */
2089 cookie = element->state_cookie;
2091 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2092 "waiting for element to commit state");
2094 /* we have a pending state change, wait for it to complete */
2095 if (timeout != GST_CLOCK_TIME_NONE) {
2097 /* make timeout absolute */
2098 end_time = g_get_monotonic_time () + (timeout / 1000);
2099 signaled = GST_STATE_WAIT_UNTIL (element, end_time);
2101 GST_STATE_WAIT (element);
2106 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
2107 /* timeout triggered */
2108 ret = GST_STATE_CHANGE_ASYNC;
2110 if (cookie != element->state_cookie)
2113 /* could be success or failure */
2114 if (old_pending == GST_STATE (element)) {
2115 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
2116 ret = GST_STATE_CHANGE_SUCCESS;
2118 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
2119 ret = GST_STATE_CHANGE_FAILURE;
2122 /* if nothing is pending anymore we can return SUCCESS */
2123 if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
2124 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
2125 ret = GST_STATE_CHANGE_SUCCESS;
2131 *state = GST_STATE (element);
2133 *pending = GST_STATE_PENDING (element);
2135 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2136 "state current: %s, pending: %s, result: %s",
2137 gst_element_state_get_name (GST_STATE (element)),
2138 gst_element_state_get_name (GST_STATE_PENDING (element)),
2139 gst_element_state_change_return_get_name (ret));
2140 GST_OBJECT_UNLOCK (element);
2147 *state = GST_STATE_VOID_PENDING;
2149 *pending = GST_STATE_VOID_PENDING;
2151 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
2153 GST_OBJECT_UNLOCK (element);
2155 return GST_STATE_CHANGE_FAILURE;
2160 * gst_element_get_state:
2161 * @element: a #GstElement to get the state of.
2162 * @state: (out) (allow-none): a pointer to #GstState to hold the state.
2164 * @pending: (out) (allow-none): a pointer to #GstState to hold the pending
2165 * state. Can be %NULL.
2166 * @timeout: a #GstClockTime to specify the timeout for an async
2167 * state change or %GST_CLOCK_TIME_NONE for infinite timeout.
2169 * Gets the state of the element.
2171 * For elements that performed an ASYNC state change, as reported by
2172 * gst_element_set_state(), this function will block up to the
2173 * specified timeout value for the state change to complete.
2174 * If the element completes the state change or goes into
2175 * an error, this function returns immediately with a return value of
2176 * %GST_STATE_CHANGE_SUCCESS or %GST_STATE_CHANGE_FAILURE respectively.
2178 * For elements that did not return %GST_STATE_CHANGE_ASYNC, this function
2179 * returns the current and pending state immediately.
2181 * This function returns %GST_STATE_CHANGE_NO_PREROLL if the element
2182 * successfully changed its state but is not able to provide data yet.
2183 * This mostly happens for live sources that only produce data in
2184 * %GST_STATE_PLAYING. While the state change return is equivalent to
2185 * %GST_STATE_CHANGE_SUCCESS, it is returned to the application to signal that
2186 * some sink elements might not be able to complete their state change because
2187 * an element is not producing data to complete the preroll. When setting the
2188 * element to playing, the preroll will complete and playback will start.
2190 * Returns: %GST_STATE_CHANGE_SUCCESS if the element has no more pending state
2191 * and the last state change succeeded, %GST_STATE_CHANGE_ASYNC if the
2192 * element is still performing a state change or
2193 * %GST_STATE_CHANGE_FAILURE if the last state change failed.
2197 GstStateChangeReturn
2198 gst_element_get_state (GstElement * element,
2199 GstState * state, GstState * pending, GstClockTime timeout)
2201 GstElementClass *oclass;
2202 GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2204 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2206 oclass = GST_ELEMENT_GET_CLASS (element);
2208 if (oclass->get_state)
2209 result = (oclass->get_state) (element, state, pending, timeout);
2215 * gst_element_abort_state:
2216 * @element: a #GstElement to abort the state of.
2218 * Abort the state change of the element. This function is used
2219 * by elements that do asynchronous state changes and find out
2220 * something is wrong.
2222 * This function should be called with the STATE_LOCK held.
2227 gst_element_abort_state (GstElement * element)
2231 #ifndef GST_DISABLE_GST_DEBUG
2235 g_return_if_fail (GST_IS_ELEMENT (element));
2237 GST_OBJECT_LOCK (element);
2238 pending = GST_STATE_PENDING (element);
2240 if (pending == GST_STATE_VOID_PENDING ||
2241 GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2242 goto nothing_aborted;
2244 #ifndef GST_DISABLE_GST_DEBUG
2245 old_state = GST_STATE (element);
2247 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2248 "aborting state from %s to %s", gst_element_state_get_name (old_state),
2249 gst_element_state_get_name (pending));
2253 GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
2255 GST_STATE_BROADCAST (element);
2256 GST_OBJECT_UNLOCK (element);
2262 GST_OBJECT_UNLOCK (element);
2267 /* Not static because GstBin has manual state handling too */
2269 _priv_gst_element_state_changed (GstElement * element, GstState oldstate,
2270 GstState newstate, GstState pending)
2272 GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
2273 GstMessage *message;
2275 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2276 "notifying about state-changed %s to %s (%s pending)",
2277 gst_element_state_get_name (oldstate),
2278 gst_element_state_get_name (newstate),
2279 gst_element_state_get_name (pending));
2281 if (klass->state_changed)
2282 klass->state_changed (element, oldstate, newstate, pending);
2284 message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
2285 oldstate, newstate, pending);
2286 gst_element_post_message (element, message);
2290 * gst_element_continue_state:
2291 * @element: a #GstElement to continue the state change of.
2292 * @ret: The previous state return value
2294 * Commit the state change of the element and proceed to the next
2295 * pending state if any. This function is used
2296 * by elements that do asynchronous state changes.
2297 * The core will normally call this method automatically when an
2298 * element returned %GST_STATE_CHANGE_SUCCESS from the state change function.
2300 * If after calling this method the element still has not reached
2301 * the pending state, the next state change is performed.
2303 * This method is used internally and should normally not be called by plugins
2306 * Returns: The result of the commit state change.
2310 GstStateChangeReturn
2311 gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
2313 GstStateChangeReturn old_ret;
2314 GstState old_state, old_next;
2315 GstState current, next, pending;
2316 GstStateChange transition;
2318 GST_OBJECT_LOCK (element);
2319 old_ret = GST_STATE_RETURN (element);
2320 GST_STATE_RETURN (element) = ret;
2321 pending = GST_STATE_PENDING (element);
2323 /* check if there is something to commit */
2324 if (pending == GST_STATE_VOID_PENDING)
2325 goto nothing_pending;
2327 old_state = GST_STATE (element);
2328 /* this is the state we should go to next */
2329 old_next = GST_STATE_NEXT (element);
2330 /* update current state */
2331 current = GST_STATE (element) = old_next;
2333 /* see if we reached the final state */
2334 if (pending == current)
2337 next = GST_STATE_GET_NEXT (current, pending);
2338 transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2340 GST_STATE_NEXT (element) = next;
2342 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2343 GST_OBJECT_UNLOCK (element);
2345 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2346 "committing state from %s to %s, pending %s, next %s",
2347 gst_element_state_get_name (old_state),
2348 gst_element_state_get_name (old_next),
2349 gst_element_state_get_name (pending), gst_element_state_get_name (next));
2351 _priv_gst_element_state_changed (element, old_state, old_next, pending);
2353 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2354 "continue state change %s to %s, final %s",
2355 gst_element_state_get_name (current),
2356 gst_element_state_get_name (next), gst_element_state_get_name (pending));
2358 ret = gst_element_change_state (element, transition);
2364 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
2365 GST_OBJECT_UNLOCK (element);
2370 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2371 GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2373 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2374 "completed state change to %s", gst_element_state_get_name (pending));
2375 GST_OBJECT_UNLOCK (element);
2377 /* don't post silly messages with the same state. This can happen
2378 * when an element state is changed to what it already was. For bins
2379 * this can be the result of a lost state, which we check with the
2380 * previous return value.
2381 * We do signal the cond though as a _get_state() might be blocking
2383 if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
2384 _priv_gst_element_state_changed (element, old_state, old_next,
2385 GST_STATE_VOID_PENDING);
2387 GST_STATE_BROADCAST (element);
2394 * gst_element_lost_state:
2395 * @element: a #GstElement the state is lost of
2397 * Brings the element to the lost state. The current state of the
2398 * element is copied to the pending state so that any call to
2399 * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
2401 * An ASYNC_START message is posted. If the element was PLAYING, it will
2402 * go to PAUSED. The element will be restored to its PLAYING state by
2403 * the parent pipeline when it prerolls again.
2405 * This is mostly used for elements that lost their preroll buffer
2406 * in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
2407 * they will go to their pending state again when a new preroll buffer is
2408 * queued. This function can only be called when the element is currently
2409 * not in error or an async state change.
2411 * This function is used internally and should normally not be called from
2412 * plugins or applications.
2415 gst_element_lost_state (GstElement * element)
2417 GstState old_state, new_state;
2418 GstMessage *message;
2420 g_return_if_fail (GST_IS_ELEMENT (element));
2422 GST_OBJECT_LOCK (element);
2423 if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2426 if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING)
2427 goto only_async_start;
2429 old_state = GST_STATE (element);
2431 /* when we were PLAYING, the new state is PAUSED. We will also not
2432 * automatically go to PLAYING but let the parent bin(s) set us to PLAYING
2433 * when we preroll. */
2434 if (old_state > GST_STATE_PAUSED)
2435 new_state = GST_STATE_PAUSED;
2437 new_state = old_state;
2439 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2440 "lost state of %s to %s", gst_element_state_get_name (old_state),
2441 gst_element_state_get_name (new_state));
2443 GST_STATE (element) = new_state;
2444 GST_STATE_NEXT (element) = new_state;
2445 GST_STATE_PENDING (element) = new_state;
2446 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2447 GST_OBJECT_UNLOCK (element);
2449 _priv_gst_element_state_changed (element, new_state, new_state, new_state);
2451 message = gst_message_new_async_start (GST_OBJECT_CAST (element));
2452 gst_element_post_message (element, message);
2458 GST_OBJECT_UNLOCK (element);
2463 GST_OBJECT_UNLOCK (element);
2465 message = gst_message_new_async_start (GST_OBJECT_CAST (element));
2466 gst_element_post_message (element, message);
2472 * gst_element_set_state:
2473 * @element: a #GstElement to change state of.
2474 * @state: the element's new #GstState.
2476 * Sets the state of the element. This function will try to set the
2477 * requested state by going through all the intermediary states and calling
2478 * the class's state change function for each.
2480 * This function can return #GST_STATE_CHANGE_ASYNC, in which case the
2481 * element will perform the remainder of the state change asynchronously in
2483 * An application can use gst_element_get_state() to wait for the completion
2484 * of the state change or it can wait for a %GST_MESSAGE_ASYNC_DONE or
2485 * %GST_MESSAGE_STATE_CHANGED on the bus.
2487 * State changes to %GST_STATE_READY or %GST_STATE_NULL never return
2488 * #GST_STATE_CHANGE_ASYNC.
2490 * Returns: Result of the state change using #GstStateChangeReturn.
2494 GstStateChangeReturn
2495 gst_element_set_state (GstElement * element, GstState state)
2497 GstElementClass *oclass;
2498 GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2500 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2502 oclass = GST_ELEMENT_GET_CLASS (element);
2504 if (oclass->set_state)
2505 result = (oclass->set_state) (element, state);
2511 * default set state function, calculates the next state based
2512 * on current state and calls the change_state function
2514 static GstStateChangeReturn
2515 gst_element_set_state_func (GstElement * element, GstState state)
2517 GstState current, next, old_pending;
2518 GstStateChangeReturn ret;
2519 GstStateChange transition;
2520 GstStateChangeReturn old_ret;
2522 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2524 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
2525 gst_element_state_get_name (state));
2527 /* state lock is taken to protect the set_state() and get_state()
2528 * procedures, it does not lock any variables. */
2529 GST_STATE_LOCK (element);
2531 /* now calculate how to get to the new state */
2532 GST_OBJECT_LOCK (element);
2533 old_ret = GST_STATE_RETURN (element);
2534 /* previous state change returned an error, remove all pending
2535 * and next states */
2536 if (old_ret == GST_STATE_CHANGE_FAILURE) {
2537 GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2538 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2539 GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
2542 current = GST_STATE (element);
2543 next = GST_STATE_NEXT (element);
2544 old_pending = GST_STATE_PENDING (element);
2546 /* this is the (new) state we should go to. TARGET is the last state we set on
2548 if (state != GST_STATE_TARGET (element)) {
2549 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2550 "setting target state to %s", gst_element_state_get_name (state));
2551 GST_STATE_TARGET (element) = state;
2552 /* increment state cookie so that we can track each state change. We only do
2553 * this if this is actually a new state change. */
2554 element->state_cookie++;
2556 GST_STATE_PENDING (element) = state;
2558 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2559 "current %s, old_pending %s, next %s, old return %s",
2560 gst_element_state_get_name (current),
2561 gst_element_state_get_name (old_pending),
2562 gst_element_state_get_name (next),
2563 gst_element_state_change_return_get_name (old_ret));
2565 /* if the element was busy doing a state change, we just update the
2566 * target state, it'll get to it async then. */
2567 if (old_pending != GST_STATE_VOID_PENDING) {
2568 /* upwards state change will happen ASYNC */
2569 if (old_pending <= state)
2571 /* element is going to this state already */
2572 else if (next == state)
2574 /* element was performing an ASYNC upward state change and
2575 * we request to go downward again. Start from the next pending
2577 else if (next > state
2578 && GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
2582 next = GST_STATE_GET_NEXT (current, state);
2583 /* now we store the next state */
2584 GST_STATE_NEXT (element) = next;
2585 /* mark busy, we need to check that there is actually a state change
2586 * to be done else we could accidentally override SUCCESS/NO_PREROLL and
2587 * the default element change_state function has no way to know what the
2588 * old value was... could consider this a FIXME...*/
2589 if (current != next)
2590 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2592 transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2594 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2595 "%s: setting state from %s to %s",
2596 (next != state ? "intermediate" : "final"),
2597 gst_element_state_get_name (current), gst_element_state_get_name (next));
2599 /* now signal any waiters, they will error since the cookie was incremented */
2600 GST_STATE_BROADCAST (element);
2602 GST_OBJECT_UNLOCK (element);
2604 ret = gst_element_change_state (element, transition);
2606 GST_STATE_UNLOCK (element);
2608 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "returned %s",
2609 gst_element_state_change_return_get_name (ret));
2615 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2616 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2617 "element was busy with async state change");
2618 GST_OBJECT_UNLOCK (element);
2620 GST_STATE_UNLOCK (element);
2622 return GST_STATE_CHANGE_ASYNC;
2627 * gst_element_change_state:
2628 * @element: a #GstElement
2629 * @transition: the requested transition
2631 * Perform @transition on @element.
2633 * This function must be called with STATE_LOCK held and is mainly used
2636 * Returns: the #GstStateChangeReturn of the state transition.
2638 GstStateChangeReturn
2639 gst_element_change_state (GstElement * element, GstStateChange transition)
2641 GstElementClass *oclass;
2642 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2644 oclass = GST_ELEMENT_GET_CLASS (element);
2646 GST_TRACER_ELEMENT_CHANGE_STATE_PRE (element, transition);
2648 /* call the state change function so it can set the state */
2649 if (oclass->change_state)
2650 ret = (oclass->change_state) (element, transition);
2652 ret = GST_STATE_CHANGE_FAILURE;
2654 GST_TRACER_ELEMENT_CHANGE_STATE_POST (element, transition, ret);
2657 case GST_STATE_CHANGE_FAILURE:
2658 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2659 "have FAILURE change_state return");
2660 /* state change failure */
2661 gst_element_abort_state (element);
2663 case GST_STATE_CHANGE_ASYNC:
2667 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2668 "element will change state ASYNC");
2670 target = GST_STATE_TARGET (element);
2672 if (target > GST_STATE_READY)
2675 /* else we just continue the state change downwards */
2676 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2677 "forcing commit state %s <= %s",
2678 gst_element_state_get_name (target),
2679 gst_element_state_get_name (GST_STATE_READY));
2681 ret = gst_element_continue_state (element, GST_STATE_CHANGE_SUCCESS);
2684 case GST_STATE_CHANGE_SUCCESS:
2685 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2686 "element changed state SUCCESS");
2687 /* we can commit the state now which will proceeed to
2689 ret = gst_element_continue_state (element, ret);
2691 case GST_STATE_CHANGE_NO_PREROLL:
2692 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2693 "element changed state NO_PREROLL");
2694 /* we can commit the state now which will proceeed to
2696 ret = gst_element_continue_state (element, ret);
2699 goto invalid_return;
2702 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
2707 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit async state change %d",
2715 GST_OBJECT_LOCK (element);
2716 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2717 g_critical ("%s: unknown return value %d from a state change function",
2718 GST_ELEMENT_NAME (element), ret);
2720 /* we are in error now */
2721 ret = GST_STATE_CHANGE_FAILURE;
2722 GST_STATE_RETURN (element) = ret;
2723 GST_OBJECT_UNLOCK (element);
2729 /* gst_iterator_fold functions for pads_activate
2730 * Stop the iterator if activating one pad failed, but only if that pad
2731 * has not been removed from the element. */
2733 activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
2735 GstPad *pad = g_value_get_object (vpad);
2736 gboolean cont = TRUE;
2738 if (!gst_pad_set_active (pad, *active)) {
2739 if (GST_PAD_PARENT (pad) != NULL) {
2741 g_value_set_boolean (ret, FALSE);
2748 /* returns false on error or early cutout of the fold, true if all
2749 * pads in @iter were (de)activated successfully. */
2751 iterator_activate_fold_with_resync (GstIterator * iter,
2752 GstIteratorFoldFunction func, gpointer user_data)
2754 GstIteratorResult ires;
2757 /* no need to unset this later, it's just a boolean */
2758 g_value_init (&ret, G_TYPE_BOOLEAN);
2759 g_value_set_boolean (&ret, TRUE);
2762 ires = gst_iterator_fold (iter, func, &ret, user_data);
2764 case GST_ITERATOR_RESYNC:
2765 /* need to reset the result again */
2766 g_value_set_boolean (&ret, TRUE);
2767 gst_iterator_resync (iter);
2769 case GST_ITERATOR_DONE:
2770 /* all pads iterated, return collected value */
2773 /* iterator returned _ERROR or premature end with _OK,
2774 * mark an error and exit */
2775 g_value_set_boolean (&ret, FALSE);
2780 /* return collected value */
2781 return g_value_get_boolean (&ret);
2784 /* is called with STATE_LOCK
2786 * Pads are activated from source pads to sinkpads.
2789 gst_element_pads_activate (GstElement * element, gboolean active)
2794 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2795 "%s pads", active ? "activate" : "deactivate");
2797 iter = gst_element_iterate_src_pads (element);
2799 iterator_activate_fold_with_resync (iter,
2800 (GstIteratorFoldFunction) activate_pads, &active);
2801 gst_iterator_free (iter);
2802 if (G_UNLIKELY (!res))
2805 iter = gst_element_iterate_sink_pads (element);
2807 iterator_activate_fold_with_resync (iter,
2808 (GstIteratorFoldFunction) activate_pads, &active);
2809 gst_iterator_free (iter);
2810 if (G_UNLIKELY (!res))
2813 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2814 "pad %sactivation successful", active ? "" : "de");
2821 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2822 "pad %sactivation failed", active ? "" : "de");
2827 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2828 "sink pads_activate failed");
2833 /* is called with STATE_LOCK */
2834 static GstStateChangeReturn
2835 gst_element_change_state_func (GstElement * element, GstStateChange transition)
2837 GstState state, next;
2838 GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2840 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2842 state = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
2843 next = GST_STATE_TRANSITION_NEXT (transition);
2845 /* if the element already is in the given state, we just return success */
2846 if (next == GST_STATE_VOID_PENDING || state == next)
2849 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2850 "default handler tries setting state from %s to %s (%04x)",
2851 gst_element_state_get_name (state),
2852 gst_element_state_get_name (next), transition);
2854 switch (transition) {
2855 case GST_STATE_CHANGE_NULL_TO_READY:
2857 case GST_STATE_CHANGE_READY_TO_PAUSED:
2858 if (!gst_element_pads_activate (element, TRUE)) {
2859 result = GST_STATE_CHANGE_FAILURE;
2862 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2864 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2866 case GST_STATE_CHANGE_PAUSED_TO_READY:
2867 case GST_STATE_CHANGE_READY_TO_NULL:{
2870 /* deactivate pads in both cases, since they are activated on
2871 ready->paused but the element might not have made it to paused */
2872 if (!gst_element_pads_activate (element, FALSE)) {
2873 result = GST_STATE_CHANGE_FAILURE;
2876 /* Remove all non-persistent contexts */
2877 GST_OBJECT_LOCK (element);
2878 for (l = element->contexts; l;) {
2879 GstContext *context = l->data;
2881 if (!gst_context_is_persistent (context)) {
2884 gst_context_unref (context);
2886 element->contexts = g_list_delete_link (element->contexts, l);
2892 GST_OBJECT_UNLOCK (element);
2896 /* this will catch real but unhandled state changes;
2897 * can only be caused by:
2898 * - a new state was added
2899 * - somehow the element was asked to jump across an intermediate state
2901 g_warning ("Unhandled state change from %s to %s",
2902 gst_element_state_get_name (state),
2903 gst_element_state_get_name (next));
2910 GST_OBJECT_LOCK (element);
2911 result = GST_STATE_RETURN (element);
2912 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2913 "element is already in the %s state",
2914 gst_element_state_get_name (state));
2915 GST_OBJECT_UNLOCK (element);
2922 * gst_element_get_factory:
2923 * @element: a #GstElement to request the element factory of.
2925 * Retrieves the factory that was used to create this element.
2927 * Returns: (transfer none): the #GstElementFactory used for creating this
2928 * element. no refcounting is needed.
2931 gst_element_get_factory (GstElement * element)
2933 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2935 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2939 gst_element_dispose (GObject * object)
2941 GstElement *element = GST_ELEMENT_CAST (object);
2944 GstElementClass *oclass;
2947 oclass = GST_ELEMENT_GET_CLASS (element);
2949 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p dispose", element);
2951 if (GST_STATE (element) != GST_STATE_NULL)
2954 /* start by releasing all request pads, this might also remove some dynamic
2956 walk = element->pads;
2958 GstPad *pad = GST_PAD_CAST (walk->data);
2962 if (oclass->release_pad && GST_PAD_PAD_TEMPLATE (pad) &&
2963 GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad))
2964 == GST_PAD_REQUEST) {
2965 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2966 "removing request pad %s:%s", GST_DEBUG_PAD_NAME (pad));
2967 oclass->release_pad (element, pad);
2969 /* in case the release_pad function removed the next pad too */
2970 if (walk && g_list_position (element->pads, walk) == -1)
2971 walk = element->pads;
2974 /* remove the remaining pads */
2975 while (element->pads) {
2976 GstPad *pad = GST_PAD_CAST (element->pads->data);
2977 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2978 "removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
2979 if (!gst_element_remove_pad (element, pad)) {
2980 /* only happens when someone unparented our pad.. */
2981 g_critical ("failed to remove pad %s:%s", GST_DEBUG_PAD_NAME (pad));
2986 GST_OBJECT_LOCK (element);
2987 clock_p = &element->clock;
2988 bus_p = &element->bus;
2989 gst_object_replace ((GstObject **) clock_p, NULL);
2990 gst_object_replace ((GstObject **) bus_p, NULL);
2991 g_list_free_full (element->contexts, (GDestroyNotify) gst_context_unref);
2992 GST_OBJECT_UNLOCK (element);
2994 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p parent class dispose",
2997 G_OBJECT_CLASS (parent_class)->dispose (object);
3006 is_locked = GST_ELEMENT_IS_LOCKED_STATE (element);
3008 ("\nTrying to dispose element %s, but it is in %s%s instead of the NULL"
3010 "You need to explicitly set elements to the NULL state before\n"
3011 "dropping the final reference, to allow them to clean up.\n"
3012 "This problem may also be caused by a refcounting bug in the\n"
3013 "application or some element.\n",
3014 GST_OBJECT_NAME (element),
3015 gst_element_state_get_name (GST_STATE (element)),
3016 is_locked ? " (locked)" : "");
3022 gst_element_finalize (GObject * object)
3024 GstElement *element = GST_ELEMENT_CAST (object);
3026 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize", element);
3028 g_cond_clear (&element->state_cond);
3029 g_rec_mutex_clear (&element->state_lock);
3031 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize parent",
3034 G_OBJECT_CLASS (parent_class)->finalize (object);
3038 gst_element_set_bus_func (GstElement * element, GstBus * bus)
3042 g_return_if_fail (GST_IS_ELEMENT (element));
3044 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
3046 GST_OBJECT_LOCK (element);
3047 bus_p = &GST_ELEMENT_BUS (element);
3048 gst_object_replace ((GstObject **) bus_p, GST_OBJECT_CAST (bus));
3049 GST_OBJECT_UNLOCK (element);
3053 * gst_element_set_bus:
3054 * @element: a #GstElement to set the bus of.
3055 * @bus: (transfer none): the #GstBus to set.
3057 * Sets the bus of the element. Increases the refcount on the bus.
3058 * For internal use only, unless you're testing elements.
3063 gst_element_set_bus (GstElement * element, GstBus * bus)
3065 GstElementClass *oclass;
3067 g_return_if_fail (GST_IS_ELEMENT (element));
3069 oclass = GST_ELEMENT_GET_CLASS (element);
3071 if (oclass->set_bus)
3072 oclass->set_bus (element, bus);
3076 * gst_element_get_bus:
3077 * @element: a #GstElement to get the bus of.
3079 * Returns the bus of the element. Note that only a #GstPipeline will provide a
3080 * bus for the application.
3082 * Returns: (transfer full): the element's #GstBus. unref after usage.
3087 gst_element_get_bus (GstElement * element)
3089 GstBus *result = NULL;
3091 g_return_val_if_fail (GST_IS_ELEMENT (element), result);
3093 GST_OBJECT_LOCK (element);
3094 if ((result = GST_ELEMENT_BUS (element)))
3095 gst_object_ref (result);
3096 GST_OBJECT_UNLOCK (element);
3098 GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
3105 gst_element_set_context_default (GstElement * element, GstContext * context)
3107 const gchar *context_type;
3110 GST_OBJECT_LOCK (element);
3111 context_type = gst_context_get_context_type (context);
3112 for (l = element->contexts; l; l = l->next) {
3113 GstContext *tmp = l->data;
3114 const gchar *tmp_type = gst_context_get_context_type (tmp);
3116 /* Always store newest context but never replace
3117 * a persistent one by a non-persistent one */
3118 if (strcmp (context_type, tmp_type) == 0 &&
3119 (gst_context_is_persistent (context) ||
3120 !gst_context_is_persistent (tmp))) {
3121 gst_context_replace ((GstContext **) & l->data, context);
3125 /* Not found? Add */
3128 g_list_prepend (element->contexts, gst_context_ref (context));
3130 GST_OBJECT_UNLOCK (element);
3134 * gst_element_set_context:
3135 * @element: a #GstElement to set the context of.
3136 * @context: (transfer none): the #GstContext to set.
3138 * Sets the context of the element. Increases the refcount of the context.
3143 gst_element_set_context (GstElement * element, GstContext * context)
3145 GstElementClass *oclass;
3147 g_return_if_fail (GST_IS_ELEMENT (element));
3149 oclass = GST_ELEMENT_GET_CLASS (element);
3151 GST_CAT_DEBUG_OBJECT (GST_CAT_CONTEXT, element,
3152 "set context %p %" GST_PTR_FORMAT, context,
3153 gst_context_get_structure (context));
3155 if (oclass->set_context)
3156 oclass->set_context (element, context);
3160 * gst_element_get_contexts:
3161 * @element: a #GstElement to set the context of.
3163 * Gets the contexts set on the element.
3167 * Returns: (element-type Gst.Context) (transfer full): List of #GstContext
3172 gst_element_get_contexts (GstElement * element)
3176 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3178 GST_OBJECT_LOCK (element);
3179 ret = g_list_copy_deep (element->contexts, (GCopyFunc) gst_context_ref, NULL);
3180 GST_OBJECT_UNLOCK (element);
3186 _match_context_type (GstContext * c1, const gchar * context_type)
3188 const gchar *c1_type;
3190 c1_type = gst_context_get_context_type (c1);
3192 return g_strcmp0 (c1_type, context_type);
3196 * gst_element_get_context_unlocked:
3197 * @element: a #GstElement to get the context of.
3198 * @context_type: a name of a context to retrieve
3200 * Gets the context with @context_type set on the element or NULL.
3202 * Returns: (transfer full): A #GstContext or NULL
3207 gst_element_get_context_unlocked (GstElement * element,
3208 const gchar * context_type)
3210 GstContext *ret = NULL;
3213 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3216 g_list_find_custom (element->contexts, context_type,
3217 (GCompareFunc) _match_context_type);
3218 if (node && node->data)
3219 ret = gst_context_ref (node->data);
3225 * gst_element_get_context:
3226 * @element: a #GstElement to get the context of.
3227 * @context_type: a name of a context to retrieve
3229 * Gets the context with @context_type set on the element or NULL.
3233 * Returns: (transfer full): A #GstContext or NULL
3238 gst_element_get_context (GstElement * element, const gchar * context_type)
3240 GstContext *ret = NULL;
3242 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3244 GST_OBJECT_LOCK (element);
3245 ret = gst_element_get_context_unlocked (element, context_type);
3246 GST_OBJECT_UNLOCK (element);
3252 gst_element_property_post_notify_msg (GstElement * element, GObject * obj,
3253 GParamSpec * pspec, gboolean include_value)
3255 GValue val = G_VALUE_INIT;
3258 GST_LOG_OBJECT (element, "property '%s' of object %" GST_PTR_FORMAT " has "
3259 "changed, posting message with%s value", pspec->name, obj,
3260 include_value ? "" : "out");
3262 if (include_value && (pspec->flags & G_PARAM_READABLE) != 0) {
3263 g_value_init (&val, pspec->value_type);
3264 g_object_get_property (obj, pspec->name, &val);
3269 gst_element_post_message (element,
3270 gst_message_new_property_notify (GST_OBJECT_CAST (obj), pspec->name, v));
3274 gst_element_property_deep_notify_cb (GstElement * element, GObject * prop_obj,
3275 GParamSpec * pspec, gpointer user_data)
3277 gboolean include_value = GPOINTER_TO_INT (user_data);
3279 gst_element_property_post_notify_msg (element, prop_obj, pspec,
3284 gst_element_property_notify_cb (GObject * obj, GParamSpec * pspec,
3287 gboolean include_value = GPOINTER_TO_INT (user_data);
3289 gst_element_property_post_notify_msg (GST_ELEMENT_CAST (obj), obj, pspec,
3294 * gst_element_add_property_notify_watch:
3295 * @element: a #GstElement to watch for property changes
3296 * @property_name: (allow-none): name of property to watch for changes, or
3297 * NULL to watch all properties
3298 * @include_value: whether to include the new property value in the message
3300 * Returns: a watch id, which can be used in connection with
3301 * gst_element_remove_property_notify_watch() to remove the watch again.
3306 gst_element_add_property_notify_watch (GstElement * element,
3307 const gchar * property_name, gboolean include_value)
3313 g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
3315 sep = (property_name != NULL) ? "::" : NULL;
3316 signal_name = g_strconcat ("notify", sep, property_name, NULL);
3317 id = g_signal_connect (element, signal_name,
3318 G_CALLBACK (gst_element_property_notify_cb),
3319 GINT_TO_POINTER (include_value));
3320 g_free (signal_name);
3326 * gst_element_add_property_deep_notify_watch:
3327 * @element: a #GstElement to watch (recursively) for property changes
3328 * @property_name: (allow-none): name of property to watch for changes, or
3329 * NULL to watch all properties
3330 * @include_value: whether to include the new property value in the message
3332 * Returns: a watch id, which can be used in connection with
3333 * gst_element_remove_property_notify_watch() to remove the watch again.
3338 gst_element_add_property_deep_notify_watch (GstElement * element,
3339 const gchar * property_name, gboolean include_value)
3345 g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
3347 sep = (property_name != NULL) ? "::" : NULL;
3348 signal_name = g_strconcat ("deep-notify", sep, property_name, NULL);
3349 id = g_signal_connect (element, signal_name,
3350 G_CALLBACK (gst_element_property_deep_notify_cb),
3351 GINT_TO_POINTER (include_value));
3352 g_free (signal_name);
3358 * gst_element_remove_property_notify_watch:
3359 * @element: a #GstElement being watched for property changes
3360 * @watch_id: watch id to remove
3365 gst_element_remove_property_notify_watch (GstElement * element, gulong watch_id)
3367 g_signal_handler_disconnect (element, watch_id);
3372 GstElement *element;
3373 GstElementCallAsyncFunc func;
3375 GDestroyNotify destroy_notify;
3376 } GstElementCallAsyncData;
3379 gst_element_call_async_func (gpointer data, gpointer user_data)
3381 GstElementCallAsyncData *async_data = data;
3383 async_data->func (async_data->element, async_data->user_data);
3384 if (async_data->destroy_notify)
3385 async_data->destroy_notify (async_data->user_data);
3386 gst_object_unref (async_data->element);
3387 g_free (async_data);
3391 * gst_element_call_async:
3392 * @element: a #GstElement
3393 * @func: Function to call asynchronously from another thread
3394 * @user_data: Data to pass to @func
3395 * @destroy_notify: GDestroyNotify for @user_data
3397 * Calls @func from another thread and passes @user_data to it. This is to be
3398 * used for cases when a state change has to be performed from a streaming
3399 * thread, directly via gst_element_set_state() or indirectly e.g. via SEEK
3402 * Calling those functions directly from the streaming thread will cause
3403 * deadlocks in many situations, as they might involve waiting for the
3404 * streaming thread to shut down from this very streaming thread.
3411 gst_element_call_async (GstElement * element, GstElementCallAsyncFunc func,
3412 gpointer user_data, GDestroyNotify destroy_notify)
3414 GstElementCallAsyncData *async_data;
3416 g_return_if_fail (GST_IS_ELEMENT (element));
3418 async_data = g_new0 (GstElementCallAsyncData, 1);
3419 async_data->element = gst_object_ref (element);
3420 async_data->func = func;
3421 async_data->user_data = user_data;
3422 async_data->destroy_notify = destroy_notify;
3424 g_thread_pool_push (gst_element_pool, async_data, NULL);
3428 _priv_gst_element_cleanup (void)
3430 if (gst_element_pool) {
3431 g_thread_pool_free (gst_element_pool, FALSE, TRUE);
3432 gst_element_pool = NULL;