2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstelement.c: The base element, all elements derive from this
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 #include <gobject/gvaluecollector.h>
26 #include "gst_private.h"
28 #include "gstelement.h"
30 #include "gstmarshal.h"
32 #include "gstscheduler.h"
36 #include "gst-i18n-lib.h"
38 /* Element signals and args */
57 extern void __gst_element_details_clear (GstElementDetails * dp);
58 extern void __gst_element_details_copy (GstElementDetails * dest,
59 const GstElementDetails * src);
61 static void gst_element_class_init (GstElementClass * klass);
62 static void gst_element_init (GstElement * element);
63 static void gst_element_base_class_init (gpointer g_class);
64 static void gst_element_base_class_finalize (gpointer g_class);
66 static void gst_element_real_set_property (GObject * object, guint prop_id,
67 const GValue * value, GParamSpec * pspec);
68 static void gst_element_real_get_property (GObject * object, guint prop_id,
69 GValue * value, GParamSpec * pspec);
71 static void gst_element_dispose (GObject * object);
73 static GstElementStateReturn gst_element_change_state (GstElement * element);
74 static void gst_element_error_func (GstElement * element, GstElement * source,
75 GError * error, gchar * debug);
76 static void gst_element_found_tag_func (GstElement * element,
77 GstElement * source, const GstTagList * tag_list);
79 #ifndef GST_DISABLE_LOADSAVE
80 static xmlNodePtr gst_element_save_thyself (GstObject * object,
82 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self);
85 GType _gst_element_type = 0;
87 static GstObjectClass *parent_class = NULL;
88 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
91 gst_element_get_type (void)
93 if (!_gst_element_type) {
94 static const GTypeInfo element_info = {
95 sizeof (GstElementClass),
96 gst_element_base_class_init,
97 gst_element_base_class_finalize,
98 (GClassInitFunc) gst_element_class_init,
103 (GInstanceInitFunc) gst_element_init,
107 _gst_element_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
108 &element_info, G_TYPE_FLAG_ABSTRACT);
110 return _gst_element_type;
114 gst_element_class_init (GstElementClass * klass)
116 GObjectClass *gobject_class;
117 GstObjectClass *gstobject_class;
119 gobject_class = (GObjectClass *) klass;
120 gstobject_class = (GstObjectClass *) klass;
122 parent_class = g_type_class_ref (GST_TYPE_OBJECT);
124 gst_element_signals[STATE_CHANGE] =
125 g_signal_new ("state-change", G_TYPE_FROM_CLASS (klass),
126 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, state_change), NULL,
127 NULL, gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
128 gst_element_signals[NEW_PAD] =
129 g_signal_new ("new-pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
130 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
131 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
132 gst_element_signals[PAD_REMOVED] =
133 g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
134 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
135 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
136 gst_element_signals[ERROR] =
137 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
138 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
139 gst_marshal_VOID__OBJECT_OBJECT_STRING, G_TYPE_NONE, 3, GST_TYPE_ELEMENT,
140 GST_TYPE_G_ERROR, G_TYPE_STRING);
141 gst_element_signals[EOS] =
142 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
143 G_STRUCT_OFFSET (GstElementClass, eos), NULL, NULL,
144 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
145 gst_element_signals[FOUND_TAG] =
146 g_signal_new ("found-tag", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
147 G_STRUCT_OFFSET (GstElementClass, found_tag), NULL, NULL,
148 gst_marshal_VOID__OBJECT_BOXED, G_TYPE_NONE, 2, GST_TYPE_ELEMENT,
151 gobject_class->set_property =
152 GST_DEBUG_FUNCPTR (gst_element_real_set_property);
153 gobject_class->get_property =
154 GST_DEBUG_FUNCPTR (gst_element_real_get_property);
156 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
158 #ifndef GST_DISABLE_LOADSAVE
159 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
160 gstobject_class->restore_thyself =
161 GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
164 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
165 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
166 klass->found_tag = GST_DEBUG_FUNCPTR (gst_element_found_tag_func);
167 klass->numpadtemplates = 0;
169 klass->elementfactory = NULL;
173 gst_element_base_class_init (gpointer g_class)
175 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
176 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
179 gobject_class->set_property =
180 GST_DEBUG_FUNCPTR (gst_element_real_set_property);
181 gobject_class->get_property =
182 GST_DEBUG_FUNCPTR (gst_element_real_get_property);
184 memset (&element_class->details, 0, sizeof (GstElementDetails));
185 element_class->padtemplates = NULL;
189 gst_element_base_class_finalize (gpointer g_class)
191 GstElementClass *klass = GST_ELEMENT_CLASS (g_class);
193 g_list_foreach (klass->padtemplates, (GFunc) g_object_unref, NULL);
194 g_list_free (klass->padtemplates);
195 __gst_element_details_clear (&klass->details);
199 gst_element_init (GstElement * element)
201 element->current_state = GST_STATE_NULL;
202 element->pending_state = GST_STATE_VOID_PENDING;
203 element->numpads = 0;
204 element->numsrcpads = 0;
205 element->numsinkpads = 0;
206 element->pads = NULL;
207 element->loopfunc = NULL;
208 element->sched = NULL;
209 element->clock = NULL;
210 element->sched_private = NULL;
211 element->state_mutex = g_mutex_new ();
212 element->state_cond = g_cond_new ();
216 gst_element_real_set_property (GObject * object, guint prop_id,
217 const GValue * value, GParamSpec * pspec)
219 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
221 if (oclass->set_property)
222 (oclass->set_property) (object, prop_id, value, pspec);
226 gst_element_real_get_property (GObject * object, guint prop_id, GValue * value,
229 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
231 if (oclass->get_property)
232 (oclass->get_property) (object, prop_id, value, pspec);
236 * gst_element_default_error:
237 * @object: a #GObject that signalled the error.
238 * @orig: the #GstObject that initiated the error.
239 * @error: the GError.
240 * @debug: an additional debug information string, or NULL.
242 * A default error signal callback to attach to an element.
243 * The user data passed to the g_signal_connect is ignored.
245 * The default handler will simply print the error string using g_print.
248 gst_element_default_error (GObject * object, GstObject * source, GError * error,
251 gchar *name = gst_object_get_path_string (source);
253 g_print (_("ERROR: from element %s: %s\n"), name, error->message);
255 g_print (_("Additional debug info:\n%s\n"), debug);
262 const GParamSpec *pspec;
268 element_set_property (GstElement * element, const GParamSpec * pspec,
269 const GValue * value)
271 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
273 prop_value->pspec = pspec;
274 prop_value->value = *value;
276 g_async_queue_push (element->prop_value_queue, prop_value);
280 element_get_property (GstElement * element, const GParamSpec * pspec,
283 g_mutex_lock (element->property_mutex);
284 g_object_get_property ((GObject *) element, pspec->name, value);
285 g_mutex_unlock (element->property_mutex);
289 gst_element_threadsafe_properties_pre_run (GstElement * element)
291 GST_DEBUG ("locking element %s", GST_OBJECT_NAME (element));
292 g_mutex_lock (element->property_mutex);
293 gst_element_set_pending_properties (element);
297 gst_element_threadsafe_properties_post_run (GstElement * element)
299 GST_DEBUG ("unlocking element %s", GST_OBJECT_NAME (element));
300 g_mutex_unlock (element->property_mutex);
304 * gst_element_enable_threadsafe_properties:
305 * @element: a #GstElement to enable threadsafe properties on.
307 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
308 * this element so that properties on the element can be set in a
312 gst_element_enable_threadsafe_properties (GstElement * element)
314 g_return_if_fail (GST_IS_ELEMENT (element));
316 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
317 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
318 element->post_run_func = gst_element_threadsafe_properties_post_run;
319 if (!element->prop_value_queue)
320 element->prop_value_queue = g_async_queue_new ();
321 if (!element->property_mutex)
322 element->property_mutex = g_mutex_new ();
326 * gst_element_disable_threadsafe_properties:
327 * @element: a #GstElement to disable threadsafe properties on.
329 * Removes the threadsafe properties, post- and pre-run locks from
333 gst_element_disable_threadsafe_properties (GstElement * element)
335 g_return_if_fail (GST_IS_ELEMENT (element));
337 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
338 element->pre_run_func = NULL;
339 element->post_run_func = NULL;
340 /* let's keep around that async queue */
344 * gst_element_set_pending_properties:
345 * @element: a #GstElement to set the pending properties on.
347 * Sets all pending properties on the threadsafe properties enabled
351 gst_element_set_pending_properties (GstElement * element)
353 prop_value_t *prop_value;
355 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
356 g_object_set_property ((GObject *) element, prop_value->pspec->name,
358 g_value_unset (&prop_value->value);
363 /* following 6 functions taken mostly from gobject.c */
367 * @element: a #GstElement to set properties on.
368 * @first_property_name: the first property to set.
369 * @...: value of the first property, and more properties to set, ending
372 * Sets properties on an element. If the element uses threadsafe properties,
373 * they will be queued and set on the object when it is scheduled again.
376 gst_element_set (GstElement * element, const gchar * first_property_name, ...)
380 g_return_if_fail (GST_IS_ELEMENT (element));
382 va_start (var_args, first_property_name);
383 gst_element_set_valist (element, first_property_name, var_args);
389 * @element: a #GstElement to get properties of.
390 * @first_property_name: the first property to get.
391 * @...: pointer to a variable to store the first property in, as well as
392 * more properties to get, ending with NULL.
394 * Gets properties from an element. If the element uses threadsafe properties,
395 * the element will be locked before getting the given properties.
398 gst_element_get (GstElement * element, const gchar * first_property_name, ...)
402 g_return_if_fail (GST_IS_ELEMENT (element));
404 va_start (var_args, first_property_name);
405 gst_element_get_valist (element, first_property_name, var_args);
410 * gst_element_set_valist:
411 * @element: a #GstElement to set properties on.
412 * @first_property_name: the first property to set.
413 * @var_args: the var_args list of other properties to get.
415 * Sets properties on an element. If the element uses threadsafe properties,
416 * the property change will be put on the async queue.
419 gst_element_set_valist (GstElement * element, const gchar * first_property_name,
425 g_return_if_fail (GST_IS_ELEMENT (element));
427 object = (GObject *) element;
429 GST_CAT_DEBUG (GST_CAT_PROPERTIES,
430 "setting valist of properties starting with %s on element %s",
431 first_property_name, gst_element_get_name (element));
433 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
434 g_object_set_valist (object, first_property_name, var_args);
438 g_object_ref (object);
440 name = first_property_name;
443 GValue value = { 0, };
447 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
450 g_warning ("%s: object class `%s' has no property named `%s'",
451 G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
454 if (!(pspec->flags & G_PARAM_WRITABLE)) {
455 g_warning ("%s: property `%s' of object class `%s' is not writable",
456 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
460 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
462 G_VALUE_COLLECT (&value, var_args, 0, &error);
464 g_warning ("%s: %s", G_STRLOC, error);
467 /* we purposely leak the value here, it might not be
468 * in a sane state if an error condition occoured
473 element_set_property (element, pspec, &value);
474 g_value_unset (&value);
476 name = va_arg (var_args, gchar *);
479 g_object_unref (object);
483 * gst_element_get_valist:
484 * @element: a #GstElement to get properties of.
485 * @first_property_name: the first property to get.
486 * @var_args: the var_args list of other properties to get.
488 * Gets properties from an element. If the element uses threadsafe properties,
489 * the element will be locked before getting the given properties.
492 gst_element_get_valist (GstElement * element, const gchar * first_property_name,
498 g_return_if_fail (GST_IS_ELEMENT (element));
500 object = (GObject *) element;
502 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
503 g_object_get_valist (object, first_property_name, var_args);
507 g_object_ref (object);
509 name = first_property_name;
512 GValue value = { 0, };
516 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
519 g_warning ("%s: object class `%s' has no property named `%s'",
520 G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
523 if (!(pspec->flags & G_PARAM_READABLE)) {
524 g_warning ("%s: property `%s' of object class `%s' is not readable",
525 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
529 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
531 element_get_property (element, pspec, &value);
533 G_VALUE_LCOPY (&value, var_args, 0, &error);
535 g_warning ("%s: %s", G_STRLOC, error);
537 g_value_unset (&value);
541 g_value_unset (&value);
543 name = va_arg (var_args, gchar *);
546 g_object_unref (object);
550 * gst_element_set_property:
551 * @element: a #GstElement to set properties on.
552 * @property_name: the first property to get.
553 * @value: the #GValue that holds the value to set.
555 * Sets a property on an element. If the element uses threadsafe properties,
556 * the property will be put on the async queue.
559 gst_element_set_property (GstElement * element, const gchar * property_name,
560 const GValue * value)
565 g_return_if_fail (GST_IS_ELEMENT (element));
566 g_return_if_fail (property_name != NULL);
567 g_return_if_fail (G_IS_VALUE (value));
569 object = (GObject *) element;
571 GST_CAT_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
572 property_name, gst_element_get_name (element));
573 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
574 g_object_set_property (object, property_name, value);
578 g_object_ref (object);
580 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
584 g_warning ("%s: object class `%s' has no property named `%s'",
585 G_STRLOC, G_OBJECT_TYPE_NAME (object), property_name);
587 element_set_property (element, pspec, value);
589 g_object_unref (object);
593 * gst_element_get_property:
594 * @element: a #GstElement to get properties of.
595 * @property_name: the first property to get.
596 * @value: the #GValue to store the property value in.
598 * Gets a property from an element. If the element uses threadsafe properties,
599 * the element will be locked before getting the given property.
602 gst_element_get_property (GstElement * element, const gchar * property_name,
608 g_return_if_fail (GST_IS_ELEMENT (element));
609 g_return_if_fail (property_name != NULL);
610 g_return_if_fail (G_IS_VALUE (value));
612 object = (GObject *) element;
614 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
615 g_object_get_property (object, property_name, value);
619 g_object_ref (object);
622 g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
625 g_warning ("%s: object class `%s' has no property named `%s'",
626 G_STRLOC, G_OBJECT_TYPE_NAME (object), property_name);
628 GValue *prop_value, tmp_value = { 0, };
630 /* auto-conversion of the callers value type
632 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec)) {
633 g_value_reset (value);
635 } else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec),
636 G_VALUE_TYPE (value))) {
638 ("can't retrieve property `%s' of type `%s' as value of type `%s'",
639 pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
640 G_VALUE_TYPE_NAME (value));
641 g_object_unref (object);
644 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
645 prop_value = &tmp_value;
647 element_get_property (element, pspec, prop_value);
648 if (prop_value != value) {
649 g_value_transform (prop_value, value);
650 g_value_unset (&tmp_value);
654 g_object_unref (object);
658 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
661 GstPad *newpad = NULL;
662 GstElementClass *oclass;
664 oclass = GST_ELEMENT_GET_CLASS (element);
666 if (oclass->request_new_pad)
667 newpad = (oclass->request_new_pad) (element, templ, name);
673 * gst_element_release_request_pad:
674 * @element: a #GstElement to release the request pad of.
675 * @pad: the #GstPad to release.
677 * Makes the element free the previously requested pad as obtained
678 * with gst_element_get_request_pad().
681 gst_element_release_request_pad (GstElement * element, GstPad * pad)
683 GstElementClass *oclass;
685 g_return_if_fail (GST_IS_ELEMENT (element));
686 g_return_if_fail (GST_IS_PAD (pad));
688 oclass = GST_ELEMENT_GET_CLASS (element);
690 if (oclass->release_pad)
691 (oclass->release_pad) (element, pad);
695 * gst_element_requires_clock:
696 * @element: a #GstElement to query
698 * Query if the element requiresd a clock
700 * Returns: TRUE if the element requires a clock
703 gst_element_requires_clock (GstElement * element)
705 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
707 return (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
711 * gst_element_provides_clock:
712 * @element: a #GstElement to query
714 * Query if the element provides a clock
716 * Returns: TRUE if the element provides a clock
719 gst_element_provides_clock (GstElement * element)
721 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
723 return (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
727 * gst_element_set_clock:
728 * @element: a #GstElement to set the clock for.
729 * @clock: the #GstClock to set for the element.
731 * Sets the clock for the element.
734 gst_element_set_clock (GstElement * element, GstClock * clock)
736 GstElementClass *oclass;
738 g_return_if_fail (GST_IS_ELEMENT (element));
740 oclass = GST_ELEMENT_GET_CLASS (element);
742 if (oclass->set_clock)
743 oclass->set_clock (element, clock);
745 gst_object_replace ((GstObject **) & element->clock, (GstObject *) clock);
749 * gst_element_get_clock:
750 * @element: a #GstElement to get the clock of.
752 * Gets the clock of the element.
754 * Returns: the #GstClock of the element.
757 gst_element_get_clock (GstElement * element)
759 GstElementClass *oclass;
761 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
763 oclass = GST_ELEMENT_GET_CLASS (element);
765 if (oclass->get_clock)
766 return oclass->get_clock (element);
772 * gst_element_clock_wait:
773 * @element: a #GstElement.
774 * @id: the #GstClock to use.
775 * @jitter: the difference between requested time and actual time.
777 * Waits for a specific time on the clock.
779 * Returns: the #GstClockReturn result of the wait operation.
782 gst_element_clock_wait (GstElement * element, GstClockID id,
783 GstClockTimeDiff * jitter)
787 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
789 if (GST_ELEMENT_SCHED (element)) {
790 GST_CAT_DEBUG (GST_CAT_CLOCK, "waiting on scheduler clock");
792 gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id,
795 GST_CAT_DEBUG (GST_CAT_CLOCK, "no scheduler, returning GST_CLOCK_TIMEOUT");
796 res = GST_CLOCK_TIMEOUT;
802 #undef GST_CAT_DEFAULT
803 #define GST_CAT_DEFAULT GST_CAT_CLOCK
805 * gst_element_get_time:
806 * @element: element to query
808 * Query the element's time. The element must use
810 * Returns: the current time of the element or #GST_CLOCK_TIME_NONE when there
811 * is no time available.
814 gst_element_get_time (GstElement * element)
816 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
818 if (element->clock == NULL) {
819 GST_WARNING_OBJECT (element, "element queries time but has no clock");
820 return GST_CLOCK_TIME_NONE;
822 switch (element->current_state) {
824 case GST_STATE_READY:
825 return GST_CLOCK_TIME_NONE;
826 case GST_STATE_PAUSED:
827 return element->base_time;
828 case GST_STATE_PLAYING:
829 return gst_clock_get_time (element->clock) - element->base_time;
831 g_assert_not_reached ();
832 return GST_CLOCK_TIME_NONE;
838 * @element: element that should wait
839 * @timestamp: wait until this time has arrived
841 * Waits until the given time has arrived. When this function returns successfully,
842 * the time specified in the timestamp has passed.
843 * <note>This function can only be called on elements in #GST_STATE_PLAYING</note>
845 * Returns: TRUE on success
848 gst_element_wait (GstElement * element, GstClockTime timestamp)
853 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
854 g_return_val_if_fail (GST_IS_CLOCK (element->clock), FALSE);
855 g_return_val_if_fail (element->current_state == GST_STATE_PLAYING, FALSE);
856 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
858 /* shortcut when we're already late... */
859 if (gst_element_get_time (element) >= timestamp) {
860 GST_INFO_OBJECT (element, "called gst_element_wait and was late");
864 id = gst_clock_new_single_shot_id (element->clock,
865 element->base_time + timestamp);
866 ret = gst_element_clock_wait (element, id, NULL);
867 gst_clock_id_free (id);
869 return ret == GST_CLOCK_STOPPED;
873 * gst_element_set_time:
874 * @element: element to set time on
877 * Sets the current time of the element. This function can be used when handling
878 * discont events. You can only call this function on an element with a clock in
879 * #GST_STATE_PAUSED or #GST_STATE_PLAYING. You might want to have a look at
880 * gst_element_adjust_time(), if you want to adjust by a difference as that is
884 gst_element_set_time (GstElement * element, GstClockTime time)
886 gst_element_set_time_delay (element, time, 0);
890 * gst_element_set_time_delay:
891 * @element: element to set time on
893 * @delay: a delay to discount from the given time
895 * Sets the current time of the element to time - delay. This function can be
896 * used when handling discont events in elements writing to an external buffer,
897 * i. e., an audio sink that writes to a sound card that buffers the sound
898 * before playing it. The delay should be the current buffering delay.
900 * You can only call this function on an element with a clock in
901 * #GST_STATE_PAUSED or #GST_STATE_PLAYING. You might want to have a look at
902 * gst_element_adjust_time(), if you want to adjust by a difference as that is
906 gst_element_set_time_delay (GstElement * element, GstClockTime time,
909 GstClockTime event_time;
911 g_return_if_fail (GST_IS_ELEMENT (element));
912 g_return_if_fail (GST_IS_CLOCK (element->clock));
913 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
915 switch (element->current_state) {
916 case GST_STATE_PAUSED:
917 element->base_time = time - delay;
919 case GST_STATE_PLAYING:
920 event_time = gst_clock_get_event_time_delay (element->clock, delay);
921 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element,
922 "clock time %llu: setting element time to %llu", event_time, time);
923 element->base_time = event_time - time;
926 g_assert_not_reached ();
932 * gst_element_adjust_time:
933 * @element: element to adjust time on
934 * @diff: difference to adjust
936 * Adjusts the current time of the element by the specified difference. This
937 * function can be used when handling discont events. You can only call this
938 * function on an element with a clock in #GST_STATE_PAUSED or
939 * #GST_STATE_PLAYING. It is more accurate than gst_element_set_time().
942 gst_element_adjust_time (GstElement * element, GstClockTimeDiff diff)
946 g_return_if_fail (GST_IS_ELEMENT (element));
947 g_return_if_fail (GST_IS_CLOCK (element->clock));
948 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
950 switch (element->current_state) {
951 case GST_STATE_PAUSED:
952 if (diff < 0 && element->base_time < abs (diff)) {
953 g_warning ("attempted to set the current time of element %s below 0",
954 GST_OBJECT_NAME (element));
955 element->base_time = 0;
957 element->base_time += diff;
960 case GST_STATE_PLAYING:
961 time = gst_clock_get_time (element->clock);
962 if (time < element->base_time - diff) {
963 g_warning ("attempted to set the current time of element %s below 0",
964 GST_OBJECT_NAME (element));
965 element->base_time = time;
967 element->base_time -= diff;
971 g_assert_not_reached ();
976 #undef GST_CAT_DEFAULT
978 #ifndef GST_DISABLE_INDEX
980 * gst_element_is_indexable:
981 * @element: a #GstElement.
983 * Queries if the element can be indexed.
985 * Returns: TRUE if the element can be indexed.
988 gst_element_is_indexable (GstElement * element)
990 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
992 return (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
996 * gst_element_set_index:
997 * @element: a #GstElement.
998 * @index: a #GstIndex.
1000 * Set the specified GstIndex on the element.
1003 gst_element_set_index (GstElement * element, GstIndex * index)
1005 GstElementClass *oclass;
1007 g_return_if_fail (GST_IS_ELEMENT (element));
1008 g_return_if_fail (GST_IS_INDEX (index));
1010 oclass = GST_ELEMENT_GET_CLASS (element);
1012 if (oclass->set_index)
1013 oclass->set_index (element, index);
1017 * gst_element_get_index:
1018 * @element: a #GstElement.
1020 * Gets the index from the element.
1022 * Returns: a #GstIndex or NULL when no index was set on the
1026 gst_element_get_index (GstElement * element)
1028 GstElementClass *oclass;
1030 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1032 oclass = GST_ELEMENT_GET_CLASS (element);
1034 if (oclass->get_index)
1035 return oclass->get_index (element);
1042 * gst_element_release_locks:
1043 * @element: a #GstElement to release all locks on.
1045 * Instruct the element to release all the locks it is holding, such as
1046 * blocking reads, waiting for the clock, ...
1048 * Returns: TRUE if the locks could be released.
1051 gst_element_release_locks (GstElement * element)
1053 GstElementClass *oclass;
1055 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1057 oclass = GST_ELEMENT_GET_CLASS (element);
1059 if (oclass->release_locks)
1060 return oclass->release_locks (element);
1066 * gst_element_add_pad:
1067 * @element: a #GstElement to add the pad to.
1068 * @pad: the #GstPad to add to the element.
1070 * Adds a pad (link point) to @element. @pad's parent will be set to @element;
1071 * see gst_object_set_parent() for refcounting information.
1073 * Pads are automatically activated when the element is in state PLAYING.
1076 gst_element_add_pad (GstElement * element, GstPad * pad)
1078 g_return_if_fail (GST_IS_ELEMENT (element));
1079 g_return_if_fail (GST_IS_PAD (pad));
1081 /* first check to make sure the pad hasn't already been added to another
1083 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
1085 /* then check to see if there's already a pad by that name here */
1086 g_return_if_fail (gst_object_check_uniqueness (element->pads,
1087 GST_PAD_NAME (pad)) == TRUE);
1089 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
1090 GST_STR_NULL (GST_OBJECT_NAME (pad)));
1092 /* set the pad's parent */
1093 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
1095 /* add it to the list */
1096 element->pads = g_list_append (element->pads, pad);
1099 switch (gst_pad_get_direction (pad)) {
1101 element->numsrcpads++;
1104 element->numsinkpads++;
1107 /* can happen for ghost pads */
1111 /* activate element when we are playing */
1112 if (GST_STATE (element) == GST_STATE_PLAYING)
1113 gst_pad_set_active (pad, TRUE);
1115 /* emit the NEW_PAD signal */
1116 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
1120 * gst_element_add_ghost_pad:
1121 * @element: a #GstElement to add the ghost pad to.
1122 * @pad: the #GstPad from which the new ghost pad will be created.
1123 * @name: the name of the new ghost pad, or NULL to assign a unique name
1126 * Creates a ghost pad from @pad, and adds it to @element via
1127 * gst_element_add_pad().
1129 * Returns: the added ghost #GstPad, or NULL on error.
1132 gst_element_add_ghost_pad (GstElement * element, GstPad * pad,
1137 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1138 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1140 /* then check to see if there's already a pad by that name here */
1141 g_return_val_if_fail (gst_object_check_uniqueness (element->pads,
1142 name) == TRUE, NULL);
1144 ghostpad = gst_ghost_pad_new (name, pad);
1146 gst_element_add_pad (element, ghostpad);
1152 * gst_element_remove_pad:
1153 * @element: a #GstElement to remove pad from.
1154 * @pad: the #GstPad to remove from the element.
1156 * Removes @pad from @element. @pad will be destroyed if it has not been
1157 * referenced elsewhere.
1160 gst_element_remove_pad (GstElement * element, GstPad * pad)
1162 g_return_if_fail (element != NULL);
1163 g_return_if_fail (GST_IS_ELEMENT (element));
1164 g_return_if_fail (pad != NULL);
1165 g_return_if_fail (GST_IS_PAD (pad));
1167 g_return_if_fail (GST_PAD_PARENT (pad) == element);
1169 if (GST_IS_REAL_PAD (pad)) {
1170 /* unlink if necessary */
1171 if (GST_RPAD_PEER (pad) != NULL) {
1172 gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
1174 gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
1175 } else if (GST_IS_GHOST_PAD (pad)) {
1176 g_object_set (pad, "real-pad", NULL, NULL);
1179 /* remove it from the list */
1180 element->pads = g_list_remove (element->pads, pad);
1182 switch (gst_pad_get_direction (pad)) {
1184 element->numsrcpads--;
1187 element->numsinkpads--;
1190 /* can happen for ghost pads */
1194 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
1196 gst_object_unparent (GST_OBJECT (pad));
1200 * gst_element_remove_ghost_pad:
1201 * @element: a #GstElement to remove the ghost pad from.
1202 * @pad: ghost #GstPad to remove.
1204 * Removes a ghost pad from an element. Deprecated, use gst_element_remove_pad()
1208 gst_element_remove_ghost_pad (GstElement * element, GstPad * pad)
1210 g_return_if_fail (GST_IS_ELEMENT (element));
1211 g_return_if_fail (GST_IS_GHOST_PAD (pad));
1213 g_warning ("gst_element_remove_ghost_pad is deprecated.\n"
1214 "Use gst_element_remove_pad instead.");
1216 gst_element_remove_pad (element, pad);
1221 * gst_element_get_pad:
1222 * @element: a #GstElement.
1223 * @name: the name of the pad to retrieve.
1225 * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
1226 * first, then gst_element_get_request_pad().
1228 * Returns: the #GstPad if found, otherwise %NULL.
1231 gst_element_get_pad (GstElement * element, const gchar * name)
1235 g_return_val_if_fail (element != NULL, NULL);
1236 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1237 g_return_val_if_fail (name != NULL, NULL);
1239 pad = gst_element_get_static_pad (element, name);
1241 pad = gst_element_get_request_pad (element, name);
1247 * gst_element_get_static_pad:
1248 * @element: a #GstElement to find a static pad of.
1249 * @name: the name of the static #GstPad to retrieve.
1251 * Retrieves a pad from @element by name. This version only retrieves
1252 * already-existing (i.e. 'static') pads.
1254 * Returns: the requested #GstPad if found, otherwise NULL.
1257 gst_element_get_static_pad (GstElement * element, const gchar * name)
1261 g_return_val_if_fail (element != NULL, NULL);
1262 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1263 g_return_val_if_fail (name != NULL, NULL);
1265 walk = element->pads;
1269 pad = GST_PAD (walk->data);
1270 if (strcmp (GST_PAD_NAME (pad), name) == 0) {
1271 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
1272 GST_DEBUG_PAD_NAME (pad));
1275 walk = g_list_next (walk);
1278 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
1279 name, GST_OBJECT_NAME (element));
1284 * gst_element_get_request_pad:
1285 * @element: a #GstElement to find a request pad of.
1286 * @name: the name of the request #GstPad to retrieve.
1288 * Retrieves a pad from the element by name. This version only retrieves
1291 * Returns: requested #GstPad if found, otherwise NULL.
1294 gst_element_get_request_pad (GstElement * element, const gchar * name)
1296 GstPadTemplate *templ = NULL;
1298 const gchar *req_name = NULL;
1299 gboolean templ_found = FALSE;
1303 gchar *str, *endptr = NULL;
1305 g_return_val_if_fail (element != NULL, NULL);
1306 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1307 g_return_val_if_fail (name != NULL, NULL);
1309 if (strstr (name, "%")) {
1310 templ = gst_element_get_pad_template (element, name);
1315 list = gst_element_get_pad_template_list (element);
1316 while (!templ_found && list) {
1317 templ = (GstPadTemplate *) list->data;
1318 if (templ->presence == GST_PAD_REQUEST) {
1319 /* Because of sanity checks in gst_pad_template_new(), we know that %s
1320 and %d, occurring at the end of the name_template, are the only
1322 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
1323 templ->name_template);
1324 if ((str = strchr (templ->name_template, '%'))
1325 && strncmp (templ->name_template, name,
1326 str - templ->name_template) == 0
1327 && strlen (name) > str - templ->name_template) {
1328 data = name + (str - templ->name_template);
1329 if (*(str + 1) == 'd') {
1331 n = (gint) strtol (data, &endptr, 10);
1332 if (endptr && *endptr == '\0') {
1352 pad = gst_element_request_pad (element, templ, req_name);
1358 * gst_element_get_pad_list:
1359 * @element: a #GstElement to get pads of.
1361 * Retrieves a list of @element's pads. The list must not be modified by the
1364 * Returns: the #GList of pads.
1367 gst_element_get_pad_list (GstElement * element)
1369 g_return_val_if_fail (element != NULL, NULL);
1370 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1372 /* return the list of pads */
1373 return element->pads;
1377 * gst_element_class_add_pad_template:
1378 * @klass: the #GstElementClass to add the pad template to.
1379 * @templ: a #GstPadTemplate to add to the element class.
1381 * Adds a padtemplate to an element class. This is mainly used in the _base_init
1382 * functions of classes.
1385 gst_element_class_add_pad_template (GstElementClass * klass,
1386 GstPadTemplate * templ)
1388 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1389 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1391 /* avoid registering pad templates with the same name */
1392 g_return_if_fail (gst_element_class_get_pad_template (klass,
1393 templ->name_template) == NULL);
1395 klass->padtemplates = g_list_append (klass->padtemplates,
1396 gst_object_ref (GST_OBJECT (templ)));
1397 klass->numpadtemplates++;
1401 * gst_element_class_set_details:
1402 * @klass: class to set details for
1403 * @details: details to set
1405 * Sets the detailed information for a #GstElementClass.
1406 * <note>This function is for use in _base_init functions only.</note>
1409 gst_element_class_set_details (GstElementClass * klass,
1410 const GstElementDetails * details)
1412 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1413 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1415 __gst_element_details_copy (&klass->details, details);
1419 * gst_element_class_get_pad_template_list:
1420 * @element_class: a #GstElementClass to get pad templates of.
1422 * Retrieves a list of the pad templates associated with @element_class. The
1423 * list must not be modified by the calling code.
1424 * <note>If you use this function in the #GInstanceInitFunc of an object class
1425 * that has subclasses, make sure to pass the g_class parameter of the
1426 * #GInstanceInitFunc here.</note>
1428 * Returns: the #GList of padtemplates.
1431 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1433 g_return_val_if_fail (element_class != NULL, NULL);
1434 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1436 return element_class->padtemplates;
1440 * gst_element_class_get_pad_template:
1441 * @element_class: a #GstElementClass to get the pad template of.
1442 * @name: the name of the #GstPadTemplate to get.
1444 * Retrieves a padtemplate from @element_class with the given name.
1445 * <note>If you use this function in the #GInstanceInitFunc of an object class
1446 * that has subclasses, make sure to pass the g_class parameter of the
1447 * #GInstanceInitFunc here.</note>
1449 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1450 * No unreferencing is necessary.
1453 gst_element_class_get_pad_template (GstElementClass * element_class,
1458 g_return_val_if_fail (element_class != NULL, NULL);
1459 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1460 g_return_val_if_fail (name != NULL, NULL);
1462 padlist = gst_element_class_get_pad_template_list (element_class);
1465 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1467 if (strcmp (padtempl->name_template, name) == 0)
1470 padlist = g_list_next (padlist);
1477 * gst_element_get_pad_template_list:
1478 * @element: a #GstElement to get pad templates of.
1480 * Retrieves a list of the pad templates associated with the element.
1481 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template_list).
1483 * Returns: the #GList of padtemplates.
1486 gst_element_get_pad_template_list (GstElement * element)
1488 g_return_val_if_fail (element != NULL, NULL);
1489 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1491 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1495 * gst_element_get_pad_template:
1496 * @element: a #GstElement to get the pad template of.
1497 * @name: the name of the #GstPadTemplate to get.
1499 * Retrieves a padtemplate from this element with the
1501 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template).
1503 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1504 * No unreferencing is necessary.
1507 gst_element_get_pad_template (GstElement * element, const gchar * name)
1509 g_return_val_if_fail (element != NULL, NULL);
1510 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1511 g_return_val_if_fail (name != NULL, NULL);
1513 return gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (element),
1518 * gst_element_get_compatible_pad_template:
1519 * @element: a #GstElement to get a compatible pad template for.
1520 * @compattempl: the #GstPadTemplate to find a compatible template for.
1522 * Retrieves a pad template from @element that is compatible with @compattempl.
1523 * Pads from compatible templates can be linked together.
1525 * Returns: a compatible #GstPadTemplate, or NULL if none was found. No
1526 * unreferencing is necessary.
1529 gst_element_get_compatible_pad_template (GstElement * element,
1530 GstPadTemplate * compattempl)
1532 GstPadTemplate *newtempl = NULL;
1535 g_return_val_if_fail (element != NULL, NULL);
1536 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1537 g_return_val_if_fail (compattempl != NULL, NULL);
1539 padlist = gst_element_get_pad_template_list (element);
1541 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1542 "Looking for a suitable pad template...");
1545 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1546 GstCaps *intersection;
1550 * Check direction (must be opposite)
1553 if (padtempl->direction != compattempl->direction) {
1554 GST_CAT_DEBUG (GST_CAT_CAPS,
1555 "compatible direction: found %s pad template \"%s\"",
1556 padtempl->direction == GST_PAD_SRC ? "src" : "sink",
1557 padtempl->name_template);
1559 intersection = gst_caps_intersect (GST_PAD_TEMPLATE_CAPS (compattempl),
1560 GST_PAD_TEMPLATE_CAPS (padtempl));
1562 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible",
1563 (intersection ? "" : "not "));
1565 if (!gst_caps_is_empty (intersection))
1566 newtempl = padtempl;
1567 gst_caps_free (intersection);
1572 padlist = g_list_next (padlist);
1579 * gst_element_get_pad_from_template:
1580 * @element: a #GstElement.
1581 * @templ: a #GstPadTemplate belonging to @element.
1583 * Gets a pad from @element described by @templ. If the presence of @templ is
1584 * #GST_PAD_REQUEST, requests a new pad. Can return %NULL for #GST_PAD_SOMETIMES
1587 * Returns: the #GstPad, or NULL if one could not be found or created.
1590 gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
1593 GstPadPresence presence;
1595 /* If this function is ever exported, we need check the validity of `element'
1596 * and `templ', and to make sure the template actually belongs to the
1599 presence = GST_PAD_TEMPLATE_PRESENCE (templ);
1602 case GST_PAD_ALWAYS:
1603 case GST_PAD_SOMETIMES:
1604 ret = gst_element_get_static_pad (element, templ->name_template);
1605 if (!ret && presence == GST_PAD_ALWAYS)
1607 ("Element %s has an ALWAYS template %s, but no pad of the same name",
1608 GST_OBJECT_NAME (element), templ->name_template);
1611 case GST_PAD_REQUEST:
1612 ret = gst_element_request_pad (element, templ, NULL);
1620 * gst_element_request_compatible_pad:
1621 * @element: a #GstElement.
1622 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1624 * Requests a pad from @element. The returned pad should be unlinked and
1625 * compatible with @templ. Might return an existing pad, or request a new one.
1627 * Returns: a #GstPad, or %NULL if one could not be found or created.
1630 gst_element_request_compatible_pad (GstElement * element,
1631 GstPadTemplate * templ)
1633 GstPadTemplate *templ_new;
1636 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1637 g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
1639 /* FIXME: should really loop through the templates, testing each for
1640 compatibility and pad availability. */
1641 templ_new = gst_element_get_compatible_pad_template (element, templ);
1643 pad = gst_element_get_pad_from_template (element, templ_new);
1645 /* This can happen for non-request pads. No need to unref. */
1646 if (pad && GST_PAD_PEER (pad))
1653 * gst_element_get_compatible_pad_filtered:
1654 * @element: a #GstElement in which the pad should be found.
1655 * @pad: the #GstPad to find a compatible one for.
1656 * @filtercaps: the #GstCaps to use as a filter.
1658 * Looks for an unlinked pad to which the given pad can link. It is not
1659 * guaranteed that linking the pads will work, though it should work in most
1662 * Returns: the #GstPad to which a link can be made, or %NULL if one cannot be
1666 gst_element_get_compatible_pad_filtered (GstElement * element, GstPad * pad,
1667 const GstCaps * filtercaps)
1670 GstPadTemplate *templ;
1672 GstPad *foundpad = NULL;
1674 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1675 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1677 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1678 "finding pad in %s compatible with %s:%s", GST_ELEMENT_NAME (element),
1679 GST_DEBUG_PAD_NAME (pad));
1681 /* let's use the real pad */
1682 pad = (GstPad *) GST_PAD_REALIZE (pad);
1683 g_return_val_if_fail (pad != NULL, NULL);
1684 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1686 /* try to get an existing unlinked pad */
1687 pads = gst_element_get_pad_list (element);
1689 GstPad *current = GST_PAD (pads->data);
1691 if (GST_PAD_PEER (current) == NULL &&
1692 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1695 pads = g_list_next (pads);
1698 /* try to create a new one */
1699 /* requesting is a little crazy, we need a template. Let's create one */
1700 templcaps = gst_pad_get_caps (pad);
1701 if (filtercaps != NULL) {
1704 temp = gst_caps_intersect (filtercaps, templcaps);
1705 gst_caps_free (templcaps);
1709 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
1710 GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
1711 foundpad = gst_element_request_compatible_pad (element, templ);
1712 gst_object_unref (GST_OBJECT (templ));
1717 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element,
1718 "Could not find a compatible pad to link to %s:%s",
1719 GST_DEBUG_PAD_NAME (pad));
1725 * gst_element_get_compatible_pad:
1726 * @element: a #GstElement in which the pad should be found.
1727 * @pad: the #GstPad to find a compatible one for.
1729 * Looks for an unlinked pad to which the given pad can link to.
1730 * It is not guaranteed that linking the pads will work, though
1731 * it should work in most cases.
1733 * Returns: the #GstPad to which a link can be made, or %NULL if one
1734 * could not be found.
1737 gst_element_get_compatible_pad (GstElement * element, GstPad * pad)
1739 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1743 * gst_element_link_pads_filtered:
1744 * @src: a #GstElement containing the source pad.
1745 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1746 * @dest: the #GstElement containing the destination pad.
1747 * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1748 * @filtercaps: the #GstCaps to use as a filter.
1750 * Links the two named pads of the source and destination elements.
1751 * Side effect is that if one of the pads has no parent, it becomes a
1752 * child of the parent of the other element. If they have different
1753 * parents, the link fails.
1755 * Returns: TRUE if the pads could be linked, FALSE otherwise.
1758 gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
1759 GstElement * dest, const gchar * destpadname, const GstCaps * filtercaps)
1761 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1762 GstPad *srcpad, *destpad;
1763 GstPadTemplate *srctempl, *desttempl;
1766 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1767 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1769 GST_CAT_INFO (GST_CAT_ELEMENT_PADS,
1770 "trying to link element %s:%s to element %s:%s", GST_ELEMENT_NAME (src),
1771 srcpadname ? srcpadname : "(any)", GST_ELEMENT_NAME (dest),
1772 destpadname ? destpadname : "(any)");
1774 /* now get the pads we're trying to link and a list of all remaining pads */
1776 srcpad = gst_element_get_pad (src, srcpadname);
1778 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1779 GST_ELEMENT_NAME (src), srcpadname);
1782 if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1783 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad",
1784 GST_DEBUG_PAD_NAME (srcpad));
1787 if (GST_PAD_PEER (srcpad) != NULL) {
1788 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1789 GST_DEBUG_PAD_NAME (srcpad));
1795 srcpads = gst_element_get_pad_list (src);
1796 srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
1799 destpad = gst_element_get_pad (dest, destpadname);
1801 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1802 GST_ELEMENT_NAME (dest), destpadname);
1805 if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1806 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad",
1807 GST_DEBUG_PAD_NAME (destpad));
1810 if (GST_PAD_PEER (destpad) != NULL) {
1811 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1812 GST_DEBUG_PAD_NAME (destpad));
1818 destpads = gst_element_get_pad_list (dest);
1819 destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
1822 if (srcpadname && destpadname) {
1823 /* two explicitly specified pads */
1824 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1827 /* loop through the allowed pads in the source, trying to find a
1828 * compatible destination pad */
1829 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1830 "looping through allowed src and dest pads");
1832 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1833 GST_DEBUG_PAD_NAME (srcpad));
1834 if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1835 (GST_PAD_PEER (srcpad) == NULL)) {
1836 GstPad *temp = gst_element_get_compatible_pad_filtered (dest, srcpad,
1839 if (temp && gst_pad_link_filtered (srcpad, temp, filtercaps)) {
1840 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1841 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1845 /* find a better way for this mess */
1847 srcpads = g_list_next (srcpads);
1849 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1854 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1855 GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1859 /* loop through the existing pads in the destination */
1861 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1862 GST_DEBUG_PAD_NAME (destpad));
1863 if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1864 (GST_PAD_PEER (destpad) == NULL)) {
1865 GstPad *temp = gst_element_get_compatible_pad_filtered (src, destpad,
1868 if (temp && gst_pad_link_filtered (temp, destpad, filtercaps)) {
1869 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1870 GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1875 destpads = g_list_next (destpads);
1877 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1882 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1883 GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1887 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1888 "we might have request pads on both sides, checking...");
1889 srctempls = gst_element_get_pad_template_list (src);
1890 desttempls = gst_element_get_pad_template_list (dest);
1892 if (srctempls && desttempls) {
1894 srctempl = (GstPadTemplate *) srctempls->data;
1895 if (srctempl->presence == GST_PAD_REQUEST) {
1896 for (l = desttempls; l; l = l->next) {
1897 desttempl = (GstPadTemplate *) l->data;
1898 if (desttempl->presence == GST_PAD_REQUEST &&
1899 desttempl->direction != srctempl->direction) {
1900 if (gst_caps_is_always_compatible (gst_pad_template_get_caps
1901 (srctempl), gst_pad_template_get_caps (desttempl))) {
1903 gst_element_get_request_pad (src, srctempl->name_template);
1905 gst_element_get_request_pad (dest, desttempl->name_template);
1906 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1907 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1908 "linked pad %s:%s to pad %s:%s",
1909 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1912 /* it failed, so we release the request pads */
1913 gst_element_release_request_pad (src, srcpad);
1914 gst_element_release_request_pad (dest, destpad);
1919 srctempls = srctempls->next;
1923 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1924 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1929 * gst_element_link_filtered:
1930 * @src: a #GstElement containing the source pad.
1931 * @dest: the #GstElement containing the destination pad.
1932 * @filtercaps: the #GstCaps to use as a filter.
1934 * Links @src to @dest, filtered by @filtercaps. The link must be from source to
1935 * destination; the other direction will not be tried. The function looks for
1936 * existing pads that aren't linked yet. It will request new pads if necessary.
1937 * If multiple links are possible, only one is established.
1939 * Returns: TRUE if the elements could be linked, FALSE otherwise.
1942 gst_element_link_filtered (GstElement * src, GstElement * dest,
1943 const GstCaps * filtercaps)
1945 return gst_element_link_pads_filtered (src, NULL, dest, NULL, filtercaps);
1949 * gst_element_link_many:
1950 * @element_1: the first #GstElement in the link chain.
1951 * @element_2: the second #GstElement in the link chain.
1952 * @...: the NULL-terminated list of elements to link in order.
1954 * Chain together a series of elements. Uses gst_element_link().
1956 * Returns: TRUE on success, FALSE otherwise.
1959 gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
1963 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1964 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1965 GST_IS_ELEMENT (element_2), FALSE);
1967 va_start (args, element_2);
1970 if (!gst_element_link (element_1, element_2))
1973 element_1 = element_2;
1974 element_2 = va_arg (args, GstElement *);
1984 * @src: a #GstElement containing the source pad.
1985 * @dest: the #GstElement containing the destination pad.
1987 * Links @src to @dest with no filter caps. See gst_element_link_filtered() for
1990 * Returns: TRUE if the elements could be linked, FALSE otherwise.
1993 gst_element_link (GstElement * src, GstElement * dest)
1995 return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1999 * gst_element_link_pads:
2000 * @src: a #GstElement containing the source pad.
2001 * @srcpadname: the name of the #GstPad in the source element.
2002 * @dest: the #GstElement containing the destination pad.
2003 * @destpadname: the name of the #GstPad in destination element.
2005 * Links the two named pads of the source and destination elements.
2006 * Side effect is that if one of the pads has no parent, it becomes a
2007 * child of the parent of the other element. If they have different
2008 * parents, the link fails.
2010 * Returns: TRUE if the pads could be linked, FALSE otherwise.
2013 gst_element_link_pads (GstElement * src, const gchar * srcpadname,
2014 GstElement * dest, const gchar * destpadname)
2016 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname,
2021 * gst_element_unlink_pads:
2022 * @src: a #GstElement containing the source pad.
2023 * @srcpadname: the name of the #GstPad in source element.
2024 * @dest: a #GstElement containing the destination pad.
2025 * @destpadname: the name of the #GstPad in destination element.
2027 * Unlinks the two named pads of the source and destination elements.
2030 gst_element_unlink_pads (GstElement * src, const gchar * srcpadname,
2031 GstElement * dest, const gchar * destpadname)
2033 GstPad *srcpad, *destpad;
2035 g_return_if_fail (src != NULL);
2036 g_return_if_fail (GST_IS_ELEMENT (src));
2037 g_return_if_fail (srcpadname != NULL);
2038 g_return_if_fail (dest != NULL);
2039 g_return_if_fail (GST_IS_ELEMENT (dest));
2040 g_return_if_fail (destpadname != NULL);
2042 /* obtain the pads requested */
2043 srcpad = gst_element_get_pad (src, srcpadname);
2044 if (srcpad == NULL) {
2045 GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
2048 destpad = gst_element_get_pad (dest, destpadname);
2049 if (srcpad == NULL) {
2050 GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"",
2055 /* we're satisified they can be unlinked, let's do it */
2056 gst_pad_unlink (srcpad, destpad);
2060 * gst_element_unlink_many:
2061 * @element_1: the first #GstElement in the link chain.
2062 * @element_2: the second #GstElement in the link chain.
2063 * @...: the NULL-terminated list of elements to unlink in order.
2065 * Unlinks a series of elements. Uses gst_element_unlink().
2068 gst_element_unlink_many (GstElement * element_1, GstElement * element_2, ...)
2072 g_return_if_fail (element_1 != NULL && element_2 != NULL);
2073 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
2075 va_start (args, element_2);
2078 gst_element_unlink (element_1, element_2);
2080 element_1 = element_2;
2081 element_2 = va_arg (args, GstElement *);
2088 * gst_element_unlink:
2089 * @src: the source #GstElement to unlink.
2090 * @dest: the sink #GstElement to unlink.
2092 * Unlinks all source pads of the source element with all sink pads
2093 * of the sink element to which they are linked.
2096 gst_element_unlink (GstElement * src, GstElement * dest)
2098 const GList *srcpads;
2101 g_return_if_fail (GST_IS_ELEMENT (src));
2102 g_return_if_fail (GST_IS_ELEMENT (dest));
2104 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
2105 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
2107 srcpads = gst_element_get_pad_list (src);
2110 pad = GST_PAD (srcpads->data);
2112 /* we only care about real src pads */
2113 if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
2114 GstPad *peerpad = GST_PAD_PEER (pad);
2116 /* see if the pad is connected and is really a pad
2118 if (peerpad && (GST_OBJECT_PARENT (peerpad) == (GstObject *) dest)) {
2119 gst_pad_unlink (pad, peerpad);
2123 srcpads = g_list_next (srcpads);
2128 gst_element_error_func (GstElement * element, GstElement * source,
2129 GError * error, gchar * debug)
2131 /* tell the parent */
2132 if (GST_OBJECT_PARENT (element)) {
2133 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM,
2134 "forwarding error \"%s\" from %s to %s", error->message,
2135 GST_ELEMENT_NAME (element),
2136 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2138 gst_object_ref (GST_OBJECT (element));
2139 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
2140 gst_element_signals[ERROR], 0, source, error, debug);
2141 gst_object_unref (GST_OBJECT (element));
2142 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM, "forwarded error \"%s\" from %s to %s",
2143 error->message, GST_ELEMENT_NAME (element),
2144 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2149 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
2151 GList *pads = element->pads;
2153 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
2155 GstPad *pad = GST_PAD (pads->data);
2157 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
2158 GST_DEBUG_PAD_NAME (pad));
2160 if (GST_PAD_DIRECTION (pad) == dir) {
2161 if (GST_PAD_IS_LINKED (pad)) {
2164 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
2165 GST_DEBUG_PAD_NAME (pad));
2168 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
2169 GST_DEBUG_PAD_NAME (pad));
2172 pads = g_list_next (pads);
2178 * gst_element_get_event_masks:
2179 * @element: a #GstElement to query
2181 * Get an array of event masks from the element.
2182 * If the element doesn't
2183 * implement an event masks function, the query will be forwarded
2184 * to a random linked sink pad.
2186 * Returns: An array of #GstEventMask elements.
2188 const GstEventMask *
2189 gst_element_get_event_masks (GstElement * element)
2191 GstElementClass *oclass;
2193 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2195 oclass = GST_ELEMENT_GET_CLASS (element);
2197 if (oclass->get_event_masks)
2198 return oclass->get_event_masks (element);
2200 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2203 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
2210 * gst_element_send_event:
2211 * @element: a #GstElement to send the event to.
2212 * @event: the #GstEvent to send to the element.
2214 * Sends an event to an element. If the element doesn't
2215 * implement an event handler, the event will be forwarded
2216 * to a random sink pad.
2218 * Returns: TRUE if the event was handled.
2221 gst_element_send_event (GstElement * element, GstEvent * event)
2223 GstElementClass *oclass;
2225 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2226 g_return_val_if_fail (event != NULL, FALSE);
2228 oclass = GST_ELEMENT_GET_CLASS (element);
2230 if (oclass->send_event)
2231 return oclass->send_event (element, event);
2233 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2236 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
2237 GST_DEBUG_PAD_NAME (pad));
2238 return gst_pad_send_event (GST_PAD_PEER (pad), event);
2241 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
2242 GST_ELEMENT_NAME (element));
2248 * @element: a #GstElement to send the event to.
2249 * @seek_type: the method to use for seeking.
2250 * @offset: the offset to seek to.
2252 * Sends a seek event to an element.
2254 * Returns: TRUE if the event was handled.
2257 gst_element_seek (GstElement * element, GstSeekType seek_type, guint64 offset)
2259 GstEvent *event = gst_event_new_seek (seek_type, offset);
2261 return gst_element_send_event (element, event);
2265 * gst_element_get_query_types:
2266 * @element: a #GstElement to query
2268 * Get an array of query types from the element.
2269 * If the element doesn't
2270 * implement a query types function, the query will be forwarded
2271 * to a random sink pad.
2273 * Returns: An array of #GstQueryType elements.
2275 const GstQueryType *
2276 gst_element_get_query_types (GstElement * element)
2278 GstElementClass *oclass;
2280 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2282 oclass = GST_ELEMENT_GET_CLASS (element);
2284 if (oclass->get_query_types)
2285 return oclass->get_query_types (element);
2287 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2290 return gst_pad_get_query_types (GST_PAD_PEER (pad));
2297 * gst_element_query:
2298 * @element: a #GstElement to perform the query on.
2299 * @type: the #GstQueryType.
2300 * @format: the #GstFormat pointer to hold the format of the result.
2301 * @value: the pointer to the value of the result.
2303 * Performs a query on the given element. If the format is set
2304 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
2305 * format pointer will hold the default format.
2306 * For element that don't implement a query handler, this function
2307 * forwards the query to a random usable sinkpad of this element.
2309 * Returns: TRUE if the query could be performed.
2312 gst_element_query (GstElement * element, GstQueryType type,
2313 GstFormat * format, gint64 * value)
2315 GstElementClass *oclass;
2317 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2318 g_return_val_if_fail (format != NULL, FALSE);
2319 g_return_val_if_fail (value != NULL, FALSE);
2321 oclass = GST_ELEMENT_GET_CLASS (element);
2324 return oclass->query (element, type, format, value);
2326 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
2329 return gst_pad_query (pad, type, format, value);
2330 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2332 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
2339 * gst_element_get_formats:
2340 * @element: a #GstElement to query
2342 * Get an array of formst from the element.
2343 * If the element doesn't
2344 * implement a formats function, the query will be forwarded
2345 * to a random sink pad.
2347 * Returns: An array of #GstFormat elements.
2350 gst_element_get_formats (GstElement * element)
2352 GstElementClass *oclass;
2354 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2356 oclass = GST_ELEMENT_GET_CLASS (element);
2358 if (oclass->get_formats)
2359 return oclass->get_formats (element);
2361 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2364 return gst_pad_get_formats (GST_PAD_PEER (pad));
2371 * gst_element_convert:
2372 * @element: a #GstElement to invoke the converter on.
2373 * @src_format: the source #GstFormat.
2374 * @src_value: the source value.
2375 * @dest_format: a pointer to the destination #GstFormat.
2376 * @dest_value: a pointer to the destination value.
2378 * Invokes a conversion on the element.
2379 * If the element doesn't
2380 * implement a convert function, the query will be forwarded
2381 * to a random sink pad.
2383 * Returns: TRUE if the conversion could be performed.
2386 gst_element_convert (GstElement * element,
2387 GstFormat src_format, gint64 src_value,
2388 GstFormat * dest_format, gint64 * dest_value)
2390 GstElementClass *oclass;
2392 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2393 g_return_val_if_fail (dest_format != NULL, FALSE);
2394 g_return_val_if_fail (dest_value != NULL, FALSE);
2396 if (src_format == *dest_format) {
2397 *dest_value = src_value;
2401 oclass = GST_ELEMENT_GET_CLASS (element);
2403 if (oclass->convert)
2404 return oclass->convert (element,
2405 src_format, src_value, dest_format, dest_value);
2407 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2410 return gst_pad_convert (GST_PAD_PEER (pad),
2411 src_format, src_value, dest_format, dest_value);
2418 * _gst_element_error_printf:
2419 * @format: the printf-like format to use, or NULL
2421 * This function is only used internally by the #gst_element_error macro.
2423 * Returns: a newly allocated string, or NULL if the format was NULL or ""
2426 _gst_element_error_printf (const gchar * format, ...)
2436 va_start (args, format);
2437 buffer = g_strdup_vprintf (format, args);
2443 * gst_element_error_full:
2444 * @element: a #GstElement with the error.
2445 * @domain: the GStreamer error domain this error belongs to.
2446 * @code: the error code belonging to the domain
2447 * @message: an allocated message to be used as a replacement for the default
2448 * message connected to code, or NULL
2449 * @debug: an allocated debug message to be used as a replacement for the
2450 * default debugging information, or NULL
2451 * @file: source filename
2452 * @function: source function
2453 * @line: source line
2455 * Signals an error condition on an element.
2456 * This function is used internally by elements.
2457 * It results in the "error" signal.
2459 void gst_element_error_full
2460 (GstElement * element, GQuark domain, gint code, gchar * message,
2461 gchar * debug, const gchar * file, const gchar * function, gint line)
2463 GError *error = NULL;
2465 gchar *sent_message;
2469 g_return_if_fail (GST_IS_ELEMENT (element));
2471 /* check if we send the given message or the default error message */
2472 if ((message == NULL) || (message[0] == 0)) {
2473 /* we got this message from g_strdup_printf (""); */
2475 sent_message = gst_error_get_message (domain, code);
2477 sent_message = message;
2479 if ((debug == NULL) || (debug[0] == 0)) {
2480 /* we got this debug from g_strdup_printf (""); */
2485 /* create error message */
2486 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signaling error in %s: %s",
2487 GST_ELEMENT_NAME (element), sent_message);
2488 error = g_error_new (domain, code, sent_message);
2490 /* if the element was already in error, stop now */
2491 if (GST_FLAG_IS_SET (element, GST_ELEMENT_IN_ERROR)) {
2492 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "recursive ERROR detected in %s",
2493 GST_ELEMENT_NAME (element));
2494 g_free (sent_message);
2500 GST_FLAG_SET (element, GST_ELEMENT_IN_ERROR);
2502 /* emit the signal, make sure the element stays available */
2503 gst_object_ref (GST_OBJECT (element));
2504 name = gst_object_get_path_string (GST_OBJECT (element));
2506 sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
2507 file, line, function, name, debug ? debug : "");
2512 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element,
2514 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signalled error in %s: %s",
2515 GST_ELEMENT_NAME (element), sent_message);
2517 /* tell the scheduler */
2518 if (element->sched) {
2519 gst_scheduler_error (element->sched, element);
2522 if (GST_STATE (element) == GST_STATE_PLAYING) {
2523 GstElementStateReturn ret;
2525 ret = gst_element_set_state (element, GST_STATE_PAUSED);
2526 if (ret != GST_STATE_SUCCESS) {
2527 g_warning ("could not PAUSE element \"%s\" after error, help!",
2528 GST_ELEMENT_NAME (element));
2532 GST_FLAG_UNSET (element, GST_ELEMENT_IN_ERROR);
2535 gst_object_unref (GST_OBJECT (element));
2536 g_free (sent_message);
2537 g_free (sent_debug);
2538 g_error_free (error);
2542 * gst_element_is_locked_state:
2543 * @element: a #GstElement.
2545 * Checks if the state of an element is locked.
2546 * If the state of an element is locked, state changes of the parent don't
2547 * affect the element.
2548 * This way you can leave currently unused elements inside bins. Just lock their
2549 * state before changing the state from #GST_STATE_NULL.
2551 * Returns: TRUE, if the element's state is locked.
2554 gst_element_is_locked_state (GstElement * element)
2556 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2558 return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
2562 * gst_element_set_locked_state:
2563 * @element: a #GstElement
2564 * @locked_state: TRUE to lock the element's state
2566 * Locks the state of an element, so state changes of the parent don't affect
2567 * this element anymore.
2570 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
2574 g_return_if_fail (GST_IS_ELEMENT (element));
2576 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2578 if (old == locked_state)
2582 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2583 GST_ELEMENT_NAME (element));
2584 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2586 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2587 GST_ELEMENT_NAME (element));
2588 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2593 * gst_element_sync_state_with_parent:
2594 * @element: a #GstElement.
2596 * Tries to change the state of the element to the same as its parent.
2597 * If this function returns FALSE, the state of element is undefined.
2599 * Returns: TRUE, if the element's state could be synced to the parent's state.
2602 gst_element_sync_state_with_parent (GstElement * element)
2606 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2607 parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
2608 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
2610 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
2611 GST_ELEMENT_NAME (element),
2612 gst_element_state_get_name (GST_STATE (element)),
2613 GST_ELEMENT_NAME (parent),
2614 gst_element_state_get_name (GST_STATE (parent)));
2615 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
2622 * gst_element_get_state:
2623 * @element: a #GstElement to get the state of.
2625 * Gets the state of the element.
2627 * Returns: the #GstElementState of the element.
2630 gst_element_get_state (GstElement * element)
2632 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2634 return GST_STATE (element);
2638 * gst_element_wait_state_change:
2639 * @element: a #GstElement to wait for a state change on.
2641 * Waits and blocks until the element changed its state.
2644 gst_element_wait_state_change (GstElement * element)
2646 g_mutex_lock (element->state_mutex);
2647 g_cond_wait (element->state_cond, element->state_mutex);
2648 g_mutex_unlock (element->state_mutex);
2652 * gst_element_set_state:
2653 * @element: a #GstElement to change state of.
2654 * @state: the element's new #GstElementState.
2656 * Sets the state of the element. This function will try to set the
2657 * requested state by going through all the intermediary states and calling
2658 * the class's state change function for each.
2660 * Returns: TRUE if the state was successfully set.
2661 * (using #GstElementStateReturn).
2663 GstElementStateReturn
2664 gst_element_set_state (GstElement * element, GstElementState state)
2666 GstElementClass *oclass;
2667 GstElementState curpending;
2668 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2670 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2672 /* start with the current state */
2673 curpending = GST_STATE (element);
2675 if (state == curpending) {
2676 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2677 "element is already in requested state %s",
2678 gst_element_state_get_name (state));
2679 return (GST_STATE_SUCCESS);
2682 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
2683 gst_element_state_get_name (curpending),
2684 gst_element_state_get_name (state));
2686 /* loop until the final requested state is set */
2687 while (GST_STATE (element) != state
2688 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2689 /* move the curpending state in the correct direction */
2690 if (curpending < state)
2695 /* set the pending state variable */
2696 /* FIXME: should probably check to see that we don't already have one */
2697 GST_STATE_PENDING (element) = curpending;
2699 if (curpending != state) {
2700 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2701 "intermediate: setting state from %s to %s",
2702 gst_element_state_get_name (GST_STATE (element)),
2703 gst_element_state_get_name (curpending));
2706 /* call the state change function so it can set the state */
2707 oclass = GST_ELEMENT_GET_CLASS (element);
2708 if (oclass->change_state)
2709 return_val = (oclass->change_state) (element);
2711 switch (return_val) {
2712 case GST_STATE_FAILURE:
2713 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2714 "have failed change_state return");
2716 case GST_STATE_ASYNC:
2717 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2718 "element will change state async");
2720 case GST_STATE_SUCCESS:
2721 /* Last thing we do is verify that a successful state change really
2722 * did change the state... */
2723 /* if it did not, this is an error - fix the element that does this */
2724 if (GST_STATE (element) != curpending) {
2725 g_warning ("element %s claimed state-change success,"
2726 "but state didn't change to %s. State is %s (%s pending), fix the element",
2727 GST_ELEMENT_NAME (element),
2728 gst_element_state_get_name (curpending),
2729 gst_element_state_get_name (GST_STATE (element)),
2730 gst_element_state_get_name (GST_STATE_PENDING (element)));
2731 return_val = GST_STATE_FAILURE;
2736 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2737 g_assert_not_reached ();
2746 gst_element_negotiate_pads (GstElement * element)
2748 GList *pads = GST_ELEMENT_PADS (element);
2750 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating pads");
2753 GstPad *pad = GST_PAD (pads->data);
2756 pads = g_list_next (pads);
2758 if (!GST_IS_REAL_PAD (pad))
2761 srcpad = GST_PAD_REALIZE (pad);
2763 /* if we have a link on this pad and it doesn't have caps
2764 * allready, try to negotiate */
2765 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2766 GstRealPad *sinkpad;
2767 GstElementState otherstate;
2770 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2772 /* check the parent of the peer pad, if there is no parent do nothing */
2773 parent = GST_PAD_PARENT (sinkpad);
2777 /* skips pads that were already negotiating */
2778 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2779 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2782 otherstate = GST_STATE (parent);
2784 /* swap pads if needed */
2785 if (!GST_PAD_IS_SRC (srcpad)) {
2793 /* only try to negotiate if the peer element is in PAUSED or higher too */
2794 if (otherstate >= GST_STATE_READY) {
2795 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2796 "perform negotiate for %s:%s and %s:%s",
2797 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2798 if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
2801 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2802 "not negotiating %s:%s and %s:%s, not in READY yet",
2803 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2812 gst_element_clear_pad_caps (GstElement * element)
2814 GList *pads = GST_ELEMENT_PADS (element);
2816 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "clearing pad caps");
2819 GstPad *pad = GST_PAD (pads->data);
2821 gst_pad_unnegotiate (pad);
2822 if (GST_IS_REAL_PAD (pad)) {
2823 gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
2826 pads = g_list_next (pads);
2831 gst_element_pads_activate (GstElement * element, gboolean active)
2833 GList *pads = element->pads;
2836 GstPad *pad = GST_PAD (pads->data);
2838 pads = g_list_next (pads);
2840 if (!GST_IS_REAL_PAD (pad))
2843 gst_pad_set_active (pad, active);
2847 static GstElementStateReturn
2848 gst_element_change_state (GstElement * element)
2850 GstElementState old_state;
2852 gint old_pending, old_transition;
2854 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2856 old_state = GST_STATE (element);
2857 old_pending = GST_STATE_PENDING (element);
2858 old_transition = GST_STATE_TRANSITION (element);
2860 if (old_pending == GST_STATE_VOID_PENDING ||
2861 old_state == GST_STATE_PENDING (element)) {
2862 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2863 "element is already in the %s state",
2864 gst_element_state_get_name (old_state));
2865 return GST_STATE_SUCCESS;
2868 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2869 "default handler sets state from %s to %s %04x",
2870 gst_element_state_get_name (old_state),
2871 gst_element_state_get_name (old_pending), old_transition);
2873 /* we set the state change early for the negotiation functions */
2874 GST_STATE (element) = old_pending;
2875 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2877 switch (old_transition) {
2878 case GST_STATE_PLAYING_TO_PAUSED:
2879 if (element->clock) {
2880 GstClockTime time = gst_clock_get_event_time (element->clock);
2882 g_assert (time >= element->base_time);
2883 element->base_time = time - element->base_time;
2884 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2885 G_GINT64_FORMAT, element->base_time);
2887 gst_element_pads_activate (element, FALSE);
2889 case GST_STATE_PAUSED_TO_PLAYING:
2890 gst_element_pads_activate (element, TRUE);
2891 if (element->clock) {
2892 GstClockTime time = gst_clock_get_event_time (element->clock);
2894 element->base_time = time - element->base_time;
2895 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2896 G_GINT64_FORMAT, element->base_time);
2899 /* if we are going to paused, we try to negotiate the pads */
2900 case GST_STATE_READY_TO_PAUSED:
2901 g_assert (element->base_time == 0);
2902 if (!gst_element_negotiate_pads (element))
2905 /* going to the READY state clears all pad caps */
2906 /* FIXME: Why doesn't this happen on READY => NULL? -- Company */
2907 case GST_STATE_PAUSED_TO_READY:
2908 element->base_time = 0;
2909 gst_element_clear_pad_caps (element);
2915 parent = GST_ELEMENT_PARENT (element);
2917 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2918 "signaling state change from %s to %s",
2919 gst_element_state_get_name (old_state),
2920 gst_element_state_get_name (GST_STATE (element)));
2922 /* tell the scheduler if we have one */
2923 if (element->sched) {
2924 if (gst_scheduler_state_transition (element->sched, element,
2925 old_transition) != GST_STATE_SUCCESS) {
2926 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2927 "scheduler could not change state");
2932 /* tell our parent about the state change */
2933 if (parent && GST_IS_BIN (parent)) {
2934 gst_bin_child_state_change (GST_BIN (parent), old_state,
2935 GST_STATE (element), element);
2937 /* at this point the state of the element could have changed again */
2939 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2940 0, old_state, GST_STATE (element));
2942 /* signal the state change in case somebody is waiting for us */
2943 g_mutex_lock (element->state_mutex);
2944 g_cond_signal (element->state_cond);
2945 g_mutex_unlock (element->state_mutex);
2947 return GST_STATE_SUCCESS;
2950 /* undo the state change */
2951 GST_STATE (element) = old_state;
2952 GST_STATE_PENDING (element) = old_pending;
2954 return GST_STATE_FAILURE;
2958 * gst_element_get_factory:
2959 * @element: a #GstElement to request the element factory of.
2961 * Retrieves the factory that was used to create this element.
2963 * Returns: the #GstElementFactory used for creating this element.
2966 gst_element_get_factory (GstElement * element)
2968 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2970 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2974 gst_element_dispose (GObject * object)
2976 GstElement *element = GST_ELEMENT (object);
2980 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2982 gst_element_set_state (element, GST_STATE_NULL);
2984 /* first we break all our links with the ouside */
2985 if (element->pads) {
2988 orig = pads = g_list_copy (element->pads);
2990 pad = GST_PAD (pads->data);
2992 if (GST_PAD_PEER (pad)) {
2993 GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "unlinking pad '%s'",
2994 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2995 gst_pad_unlink (pad, GST_PAD (GST_PAD_PEER (pad)));
2997 gst_element_remove_pad (element, pad);
2999 pads = g_list_next (pads);
3002 g_list_free (element->pads);
3003 element->pads = NULL;
3006 element->numsrcpads = 0;
3007 element->numsinkpads = 0;
3008 element->numpads = 0;
3009 if (element->state_mutex)
3010 g_mutex_free (element->state_mutex);
3011 element->state_mutex = NULL;
3012 if (element->state_cond)
3013 g_cond_free (element->state_cond);
3014 element->state_cond = NULL;
3016 if (element->prop_value_queue)
3017 g_async_queue_unref (element->prop_value_queue);
3018 element->prop_value_queue = NULL;
3019 if (element->property_mutex)
3020 g_mutex_free (element->property_mutex);
3021 element->property_mutex = NULL;
3023 gst_object_replace ((GstObject **) & element->sched, NULL);
3024 gst_object_replace ((GstObject **) & element->clock, NULL);
3026 G_OBJECT_CLASS (parent_class)->dispose (object);
3029 #ifndef GST_DISABLE_LOADSAVE
3031 * gst_element_save_thyself:
3032 * @element: a #GstElement to save.
3033 * @parent: the xml parent node.
3035 * Saves the element as part of the given XML structure.
3037 * Returns: the new #xmlNodePtr.
3040 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
3043 GstElementClass *oclass;
3044 GParamSpec **specs, *spec;
3046 GValue value = { 0, };
3047 GstElement *element;
3049 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
3051 element = GST_ELEMENT (object);
3053 oclass = GST_ELEMENT_GET_CLASS (element);
3055 xmlNewChild (parent, NULL, "name", GST_ELEMENT_NAME (element));
3057 if (oclass->elementfactory != NULL) {
3058 GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
3060 xmlNewChild (parent, NULL, "type", GST_PLUGIN_FEATURE (factory)->name);
3063 /* FIXME: what is this? */
3064 /* if (element->manager) */
3065 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
3068 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
3070 for (i = 0; i < nspecs; i++) {
3072 if (spec->flags & G_PARAM_READABLE) {
3076 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
3078 g_object_get_property (G_OBJECT (element), spec->name, &value);
3079 param = xmlNewChild (parent, NULL, "param", NULL);
3080 xmlNewChild (param, NULL, "name", spec->name);
3082 if (G_IS_PARAM_SPEC_STRING (spec))
3083 contents = g_value_dup_string (&value);
3084 else if (G_IS_PARAM_SPEC_ENUM (spec))
3085 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
3086 else if (G_IS_PARAM_SPEC_INT64 (spec))
3087 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
3088 g_value_get_int64 (&value));
3090 contents = g_strdup_value_contents (&value);
3092 xmlNewChild (param, NULL, "value", contents);
3095 g_value_unset (&value);
3099 pads = GST_ELEMENT_PADS (element);
3102 GstPad *pad = GST_PAD (pads->data);
3104 /* figure out if it's a direct pad or a ghostpad */
3105 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
3106 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
3108 gst_object_save_thyself (GST_OBJECT (pad), padtag);
3110 pads = g_list_next (pads);
3117 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
3119 xmlNodePtr children;
3120 GstElement *element;
3122 gchar *value = NULL;
3124 element = GST_ELEMENT (object);
3125 g_return_if_fail (element != NULL);
3128 children = self->xmlChildrenNode;
3130 if (!strcmp (children->name, "param")) {
3131 xmlNodePtr child = children->xmlChildrenNode;
3134 if (!strcmp (child->name, "name")) {
3135 name = xmlNodeGetContent (child);
3136 } else if (!strcmp (child->name, "value")) {
3137 value = xmlNodeGetContent (child);
3139 child = child->next;
3141 /* FIXME: can this just be g_object_set ? */
3142 gst_util_set_object_arg (G_OBJECT (element), name, value);
3143 /* g_object_set (G_OBJECT (element), name, value, NULL); */
3145 children = children->next;
3149 children = self->xmlChildrenNode;
3151 if (!strcmp (children->name, "pad")) {
3152 gst_pad_load_and_link (children, GST_OBJECT (element));
3154 children = children->next;
3157 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3158 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3160 #endif /* GST_DISABLE_LOADSAVE */
3163 * gst_element_yield:
3164 * @element: a #GstElement to yield.
3166 * Requests a yield operation for the element. The scheduler will typically
3167 * give control to another element.
3170 gst_element_yield (GstElement * element)
3172 if (GST_ELEMENT_SCHED (element)) {
3173 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
3178 * gst_element_interrupt:
3179 * @element: a #GstElement to interrupt.
3181 * Requests the scheduler of this element to interrupt the execution of
3182 * this element and scheduler another one.
3184 * Returns: TRUE if the element should exit its chain/loop/get
3185 * function ASAP, depending on the scheduler implementation.
3188 gst_element_interrupt (GstElement * element)
3190 if (GST_ELEMENT_SCHED (element)) {
3191 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
3197 * gst_element_set_scheduler:
3198 * @element: a #GstElement to set the scheduler of.
3199 * @sched: the #GstScheduler to set.
3201 * Sets the scheduler of the element. For internal use only, unless you're
3202 * writing a new bin subclass.
3205 gst_element_set_scheduler (GstElement * element, GstScheduler * sched)
3207 g_return_if_fail (GST_IS_ELEMENT (element));
3209 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",
3212 gst_object_replace ((GstObject **) & GST_ELEMENT_SCHED (element),
3213 GST_OBJECT (sched));
3217 * gst_element_get_scheduler:
3218 * @element: a #GstElement to get the scheduler of.
3220 * Returns the scheduler of the element.
3222 * Returns: the element's #GstScheduler.
3225 gst_element_get_scheduler (GstElement * element)
3227 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3229 return GST_ELEMENT_SCHED (element);
3233 * gst_element_set_loop_function:
3234 * @element: a #GstElement to set the loop function of.
3235 * @loop: Pointer to #GstElementLoopFunction.
3237 * This sets the loop function for the element. The function pointed to
3238 * can deviate from the GstElementLoopFunction definition in type of
3241 * NOTE: in order for this to take effect, the current loop function *must*
3242 * exit. Assuming the loop function itself is the only one who will cause
3243 * a new loopfunc to be assigned, this should be no problem.
3246 gst_element_set_loop_function (GstElement * element,
3247 GstElementLoopFunction loop)
3249 gboolean need_notify = FALSE;
3251 g_return_if_fail (GST_IS_ELEMENT (element));
3253 /* if the element changed from loop based to chain/get based
3254 * or vice versa, we need to inform the scheduler about that */
3255 if ((element->loopfunc == NULL && loop != NULL) ||
3256 (element->loopfunc != NULL && loop == NULL)) {
3260 /* set the loop function */
3261 element->loopfunc = loop;
3264 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
3265 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
3267 if (GST_ELEMENT_SCHED (element)) {
3268 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
3273 gst_element_emit_found_tag (GstElement * element, GstElement * source,
3274 const GstTagList * tag_list)
3276 gst_object_ref (GST_OBJECT (element));
3277 g_signal_emit (element, gst_element_signals[FOUND_TAG], 0, source, tag_list);
3278 gst_object_unref (GST_OBJECT (element));
3281 gst_element_found_tag_func (GstElement * element, GstElement * source,
3282 const GstTagList * tag_list)
3284 /* tell the parent */
3285 if (GST_OBJECT_PARENT (element)) {
3286 GST_CAT_LOG_OBJECT (GST_CAT_EVENT, element, "forwarding tag event to %s",
3287 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
3288 gst_element_emit_found_tag (GST_ELEMENT (GST_OBJECT_PARENT (element)),
3294 * gst_element_found_tags:
3295 * @element: the element that found the tags
3296 * @tag_list: the found tags
3298 * This function emits the found_tags signal. This is a recursive signal, so
3299 * every parent will emit that signal, too, before this function returns.
3300 * Only emit this signal, when you extracted these tags out of the data stream,
3301 * not when you handle an event.
3304 gst_element_found_tags (GstElement * element, const GstTagList * tag_list)
3306 gst_element_emit_found_tag (element, element, tag_list);
3310 * gst_element_found_tags_for_pad:
3311 * @element: element that found the tag
3312 * @pad: src pad the tags correspond to
3313 * @timestamp: time the tags were found
3314 * @list: the taglist
3316 * This is a convenience routine for tag finding. Most of the time you only
3317 * want to push the found tags down one pad, in that case this function is for
3318 * you. It takes ownership of the taglist, emits the found-tag signal and pushes
3319 * a tag event down the pad.
3320 * <note>This function may not be used in a #GstPadGetFunction, because it calls
3321 * gst_pad_push(). In those functions, call gst_element_found_tags(), create a
3322 * tag event with gst_event_new_tag() and return that from your
3323 * #GstPadGetFunction.</note>
3326 gst_element_found_tags_for_pad (GstElement * element, GstPad * pad,
3327 GstClockTime timestamp, GstTagList * list)
3329 GstEvent *tag_event;
3331 g_return_if_fail (GST_IS_ELEMENT (element));
3332 g_return_if_fail (GST_IS_REAL_PAD (pad));
3333 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
3334 g_return_if_fail (element == GST_PAD_PARENT (pad));
3335 g_return_if_fail (list != NULL);
3337 tag_event = gst_event_new_tag (list);
3338 GST_EVENT_TIMESTAMP (tag_event) = timestamp;
3339 gst_element_found_tags (element, gst_event_tag_get_list (tag_event));
3340 if (GST_PAD_IS_USABLE (pad)) {
3341 gst_pad_push (pad, GST_DATA (tag_event));
3343 gst_data_unref (GST_DATA (tag_event));
3348 gst_element_set_eos_recursive (GstElement * element)
3350 /* this function is only called, when we were in PLAYING before. So every
3351 parent that's PAUSED was PLAYING before. That means it has reached EOS. */
3354 GST_CAT_DEBUG (GST_CAT_EVENT, "setting recursive EOS on %s",
3355 GST_OBJECT_NAME (element));
3356 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3358 if (!GST_OBJECT_PARENT (element))
3361 parent = GST_ELEMENT (GST_OBJECT_PARENT (element));
3362 if (GST_STATE (parent) == GST_STATE_PAUSED)
3363 gst_element_set_eos_recursive (parent);
3367 * gst_element_set_eos:
3368 * @element: a #GstElement to set to the EOS state.
3370 * Perform the actions needed to bring the element in the EOS state.
3373 gst_element_set_eos (GstElement * element)
3375 g_return_if_fail (GST_IS_ELEMENT (element));
3377 GST_CAT_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
3378 GST_OBJECT_NAME (element));
3380 if (GST_STATE (element) == GST_STATE_PLAYING) {
3381 gst_element_set_state (element, GST_STATE_PAUSED);
3382 gst_element_set_eos_recursive (element);
3384 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3390 * gst_element_state_get_name:
3391 * @state: a #GstElementState to get the name of.
3393 * Gets a string representing the given state.
3395 * Returns: a string with the name of the state.
3398 gst_element_state_get_name (GstElementState state)
3401 #ifdef GST_DEBUG_COLOR
3402 case GST_STATE_VOID_PENDING:
3403 return "NONE_PENDING";
3405 case GST_STATE_NULL:
3406 return "\033[01;34mNULL\033[00m";
3408 case GST_STATE_READY:
3409 return "\033[01;31mREADY\033[00m";
3411 case GST_STATE_PLAYING:
3412 return "\033[01;32mPLAYING\033[00m";
3414 case GST_STATE_PAUSED:
3415 return "\033[01;33mPAUSED\033[00m";
3418 /* This is a memory leak */
3419 return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
3421 case GST_STATE_VOID_PENDING:
3422 return "NONE_PENDING";
3424 case GST_STATE_NULL:
3427 case GST_STATE_READY:
3430 case GST_STATE_PLAYING:
3433 case GST_STATE_PAUSED:
3444 gst_element_populate_std_props (GObjectClass * klass, const gchar * prop_name,
3445 guint arg_id, GParamFlags flags)
3447 GQuark prop_id = g_quark_from_string (prop_name);
3450 static GQuark fd_id = 0;
3451 static GQuark blocksize_id;
3452 static GQuark bytesperread_id;
3453 static GQuark dump_id;
3454 static GQuark filesize_id;
3455 static GQuark mmapsize_id;
3456 static GQuark location_id;
3457 static GQuark offset_id;
3458 static GQuark silent_id;
3459 static GQuark touch_id;
3462 fd_id = g_quark_from_static_string ("fd");
3463 blocksize_id = g_quark_from_static_string ("blocksize");
3464 bytesperread_id = g_quark_from_static_string ("bytesperread");
3465 dump_id = g_quark_from_static_string ("dump");
3466 filesize_id = g_quark_from_static_string ("filesize");
3467 mmapsize_id = g_quark_from_static_string ("mmapsize");
3468 location_id = g_quark_from_static_string ("location");
3469 offset_id = g_quark_from_static_string ("offset");
3470 silent_id = g_quark_from_static_string ("silent");
3471 touch_id = g_quark_from_static_string ("touch");
3474 if (prop_id == fd_id) {
3475 pspec = g_param_spec_int ("fd", "File-descriptor",
3476 "File-descriptor for the file being read", 0, G_MAXINT, 0, flags);
3477 } else if (prop_id == blocksize_id) {
3478 pspec = g_param_spec_ulong ("blocksize", "Block Size",
3479 "Block size to read per buffer", 0, G_MAXULONG, 4096, flags);
3481 } else if (prop_id == bytesperread_id) {
3482 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
3483 "Number of bytes to read per buffer", G_MININT, G_MAXINT, 0, flags);
3485 } else if (prop_id == dump_id) {
3486 pspec = g_param_spec_boolean ("dump", "Dump",
3487 "Dump bytes to stdout", FALSE, flags);
3489 } else if (prop_id == filesize_id) {
3490 pspec = g_param_spec_int64 ("filesize", "File Size",
3491 "Size of the file being read", 0, G_MAXINT64, 0, flags);
3493 } else if (prop_id == mmapsize_id) {
3494 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
3495 "Size in bytes of mmap()d regions", 0, G_MAXULONG, 4 * 1048576, flags);
3497 } else if (prop_id == location_id) {
3498 pspec = g_param_spec_string ("location", "File Location",
3499 "Location of the file to read", NULL, flags);
3501 } else if (prop_id == offset_id) {
3502 pspec = g_param_spec_int64 ("offset", "File Offset",
3503 "Byte offset of current read pointer", 0, G_MAXINT64, 0, flags);
3505 } else if (prop_id == silent_id) {
3506 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
3509 } else if (prop_id == touch_id) {
3510 pspec = g_param_spec_boolean ("touch", "Touch read data",
3511 "Touch data to force disk read before " "push ()", TRUE, flags);
3513 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
3514 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
3519 g_object_class_install_property (klass, arg_id, pspec);
3524 * gst_element_class_install_std_props:
3525 * @klass: the #GstElementClass to add the properties to.
3526 * @first_name: the name of the first property.
3527 * in a NULL terminated
3528 * @...: the id and flags of the first property, followed by
3529 * further 'name', 'id', 'flags' triplets and terminated by NULL.
3531 * Adds a list of standardized properties with types to the @klass.
3532 * the id is for the property switch in your get_prop method, and
3533 * the flags determine readability / writeability.
3536 gst_element_class_install_std_props (GstElementClass * klass,
3537 const gchar * first_name, ...)
3543 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
3545 va_start (args, first_name);
3550 int arg_id = va_arg (args, int);
3551 int flags = va_arg (args, int);
3553 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id,
3556 name = va_arg (args, char *);
3563 * gst_element_get_managing_bin:
3564 * @element: a #GstElement to get the managing bin of.
3566 * Gets the managing bin (a pipeline or a thread, for example) of an element.
3568 * Returns: the #GstBin, or NULL on failure.
3571 gst_element_get_managing_bin (GstElement * element)
3575 g_return_val_if_fail (element != NULL, NULL);
3577 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (element)));
3579 while (bin && !GST_FLAG_IS_SET (GST_OBJECT (bin), GST_BIN_FLAG_MANAGER))
3580 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (bin)));