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,
106 _gst_element_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
107 &element_info, G_TYPE_FLAG_ABSTRACT);
109 return _gst_element_type;
113 gst_element_class_init (GstElementClass * klass)
115 GObjectClass *gobject_class;
116 GstObjectClass *gstobject_class;
118 gobject_class = (GObjectClass *) klass;
119 gstobject_class = (GstObjectClass *) klass;
121 parent_class = g_type_class_ref (GST_TYPE_OBJECT);
123 gst_element_signals[STATE_CHANGE] =
124 g_signal_new ("state-change", G_TYPE_FROM_CLASS (klass),
125 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, state_change), NULL,
126 NULL, gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
127 gst_element_signals[NEW_PAD] =
128 g_signal_new ("new-pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
129 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
130 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
131 gst_element_signals[PAD_REMOVED] =
132 g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
133 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
134 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
135 gst_element_signals[ERROR] =
136 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
137 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
138 gst_marshal_VOID__OBJECT_OBJECT_STRING, G_TYPE_NONE, 3, GST_TYPE_ELEMENT,
139 GST_TYPE_G_ERROR, G_TYPE_STRING);
140 gst_element_signals[EOS] =
141 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
142 G_STRUCT_OFFSET (GstElementClass, eos), NULL, NULL,
143 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
144 gst_element_signals[FOUND_TAG] =
145 g_signal_new ("found-tag", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
146 G_STRUCT_OFFSET (GstElementClass, found_tag), NULL, NULL,
147 gst_marshal_VOID__OBJECT_BOXED, G_TYPE_NONE, 2, GST_TYPE_ELEMENT,
150 gobject_class->set_property =
151 GST_DEBUG_FUNCPTR (gst_element_real_set_property);
152 gobject_class->get_property =
153 GST_DEBUG_FUNCPTR (gst_element_real_get_property);
155 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
157 #ifndef GST_DISABLE_LOADSAVE
158 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
159 gstobject_class->restore_thyself =
160 GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
163 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
164 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
165 klass->found_tag = GST_DEBUG_FUNCPTR (gst_element_found_tag_func);
166 klass->numpadtemplates = 0;
168 klass->elementfactory = NULL;
172 gst_element_base_class_init (gpointer g_class)
174 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
175 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
178 gobject_class->set_property =
179 GST_DEBUG_FUNCPTR (gst_element_real_set_property);
180 gobject_class->get_property =
181 GST_DEBUG_FUNCPTR (gst_element_real_get_property);
183 memset (&element_class->details, 0, sizeof (GstElementDetails));
184 element_class->padtemplates = NULL;
188 gst_element_base_class_finalize (gpointer g_class)
190 GstElementClass *klass = GST_ELEMENT_CLASS (g_class);
192 g_list_foreach (klass->padtemplates, (GFunc) g_object_unref, NULL);
193 g_list_free (klass->padtemplates);
194 __gst_element_details_clear (&klass->details);
198 gst_element_init (GstElement * element)
200 element->current_state = GST_STATE_NULL;
201 element->pending_state = GST_STATE_VOID_PENDING;
202 element->numpads = 0;
203 element->numsrcpads = 0;
204 element->numsinkpads = 0;
205 element->pads = NULL;
206 element->loopfunc = NULL;
207 element->sched = NULL;
208 element->clock = NULL;
209 element->sched_private = NULL;
210 element->state_mutex = g_mutex_new ();
211 element->state_cond = g_cond_new ();
215 gst_element_real_set_property (GObject * object, guint prop_id,
216 const GValue * value, GParamSpec * pspec)
218 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
220 if (oclass->set_property)
221 (oclass->set_property) (object, prop_id, value, pspec);
225 gst_element_real_get_property (GObject * object, guint prop_id, GValue * value,
228 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
230 if (oclass->get_property)
231 (oclass->get_property) (object, prop_id, value, pspec);
235 * gst_element_default_error:
236 * @object: a #GObject that signalled the error.
237 * @orig: the #GstObject that initiated the error.
238 * @error: the GError.
239 * @debug: an additional debug information string, or NULL.
241 * A default error signal callback to attach to an element.
242 * The user data passed to the g_signal_connect is ignored.
244 * The default handler will simply print the error string using g_print.
247 gst_element_default_error (GObject * object, GstObject * source, GError * error,
250 gchar *name = gst_object_get_path_string (source);
252 g_print (_("ERROR: from element %s: %s\n"), name, error->message);
254 g_print (_("Additional debug info:\n%s\n"), debug);
261 const GParamSpec *pspec;
266 element_set_property (GstElement * element, const GParamSpec * pspec,
267 const GValue * value)
269 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
271 prop_value->pspec = pspec;
272 prop_value->value = *value;
274 g_async_queue_push (element->prop_value_queue, prop_value);
278 element_get_property (GstElement * element, const GParamSpec * pspec,
281 g_mutex_lock (element->property_mutex);
282 g_object_get_property ((GObject *) element, pspec->name, value);
283 g_mutex_unlock (element->property_mutex);
287 gst_element_threadsafe_properties_pre_run (GstElement * element)
289 GST_DEBUG ("locking element %s", GST_OBJECT_NAME (element));
290 g_mutex_lock (element->property_mutex);
291 gst_element_set_pending_properties (element);
295 gst_element_threadsafe_properties_post_run (GstElement * element)
297 GST_DEBUG ("unlocking element %s", GST_OBJECT_NAME (element));
298 g_mutex_unlock (element->property_mutex);
302 * gst_element_enable_threadsafe_properties:
303 * @element: a #GstElement to enable threadsafe properties on.
305 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
306 * this element so that properties on the element can be set in a
310 gst_element_enable_threadsafe_properties (GstElement * element)
312 g_return_if_fail (GST_IS_ELEMENT (element));
314 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
315 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
316 element->post_run_func = gst_element_threadsafe_properties_post_run;
317 if (!element->prop_value_queue)
318 element->prop_value_queue = g_async_queue_new ();
319 if (!element->property_mutex)
320 element->property_mutex = g_mutex_new ();
324 * gst_element_disable_threadsafe_properties:
325 * @element: a #GstElement to disable threadsafe properties on.
327 * Removes the threadsafe properties, post- and pre-run locks from
331 gst_element_disable_threadsafe_properties (GstElement * element)
333 g_return_if_fail (GST_IS_ELEMENT (element));
335 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
336 element->pre_run_func = NULL;
337 element->post_run_func = NULL;
338 /* let's keep around that async queue */
342 * gst_element_set_pending_properties:
343 * @element: a #GstElement to set the pending properties on.
345 * Sets all pending properties on the threadsafe properties enabled
349 gst_element_set_pending_properties (GstElement * element)
351 prop_value_t *prop_value;
353 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
354 g_object_set_property ((GObject *) element, prop_value->pspec->name,
356 g_value_unset (&prop_value->value);
361 /* following 6 functions taken mostly from gobject.c */
365 * @element: a #GstElement to set properties on.
366 * @first_property_name: the first property to set.
367 * @...: value of the first property, and more properties to set, ending
370 * Sets properties on an element. If the element uses threadsafe properties,
371 * they will be queued and set on the object when it is scheduled again.
374 gst_element_set (GstElement * element, const gchar * first_property_name, ...)
378 g_return_if_fail (GST_IS_ELEMENT (element));
380 va_start (var_args, first_property_name);
381 gst_element_set_valist (element, first_property_name, var_args);
387 * @element: a #GstElement to get properties of.
388 * @first_property_name: the first property to get.
389 * @...: pointer to a variable to store the first property in, as well as
390 * more properties to get, ending with NULL.
392 * Gets properties from an element. If the element uses threadsafe properties,
393 * the element will be locked before getting the given properties.
396 gst_element_get (GstElement * element, const gchar * first_property_name, ...)
400 g_return_if_fail (GST_IS_ELEMENT (element));
402 va_start (var_args, first_property_name);
403 gst_element_get_valist (element, first_property_name, var_args);
408 * gst_element_set_valist:
409 * @element: a #GstElement to set properties on.
410 * @first_property_name: the first property to set.
411 * @var_args: the var_args list of other properties to get.
413 * Sets properties on an element. If the element uses threadsafe properties,
414 * the property change will be put on the async queue.
417 gst_element_set_valist (GstElement * element, const gchar * first_property_name,
423 g_return_if_fail (GST_IS_ELEMENT (element));
425 object = (GObject *) element;
427 GST_CAT_DEBUG (GST_CAT_PROPERTIES,
428 "setting valist of properties starting with %s on element %s",
429 first_property_name, gst_element_get_name (element));
431 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
432 g_object_set_valist (object, first_property_name, var_args);
436 g_object_ref (object);
438 name = first_property_name;
441 GValue value = { 0, };
445 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
448 g_warning ("%s: object class `%s' has no property named `%s'",
449 G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
452 if (!(pspec->flags & G_PARAM_WRITABLE)) {
453 g_warning ("%s: property `%s' of object class `%s' is not writable",
454 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
458 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
460 G_VALUE_COLLECT (&value, var_args, 0, &error);
462 g_warning ("%s: %s", G_STRLOC, error);
465 /* we purposely leak the value here, it might not be
466 * in a sane state if an error condition occoured
471 element_set_property (element, pspec, &value);
472 g_value_unset (&value);
474 name = va_arg (var_args, gchar *);
477 g_object_unref (object);
481 * gst_element_get_valist:
482 * @element: a #GstElement to get properties of.
483 * @first_property_name: the first property to get.
484 * @var_args: the var_args list of other properties to get.
486 * Gets properties from an element. If the element uses threadsafe properties,
487 * the element will be locked before getting the given properties.
490 gst_element_get_valist (GstElement * element, const gchar * first_property_name,
496 g_return_if_fail (GST_IS_ELEMENT (element));
498 object = (GObject *) element;
500 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
501 g_object_get_valist (object, first_property_name, var_args);
505 g_object_ref (object);
507 name = first_property_name;
510 GValue value = { 0, };
514 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
517 g_warning ("%s: object class `%s' has no property named `%s'",
518 G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
521 if (!(pspec->flags & G_PARAM_READABLE)) {
522 g_warning ("%s: property `%s' of object class `%s' is not readable",
523 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
527 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
529 element_get_property (element, pspec, &value);
531 G_VALUE_LCOPY (&value, var_args, 0, &error);
533 g_warning ("%s: %s", G_STRLOC, error);
535 g_value_unset (&value);
539 g_value_unset (&value);
541 name = va_arg (var_args, gchar *);
544 g_object_unref (object);
548 * gst_element_set_property:
549 * @element: a #GstElement to set properties on.
550 * @property_name: the first property to get.
551 * @value: the #GValue that holds the value to set.
553 * Sets a property on an element. If the element uses threadsafe properties,
554 * the property will be put on the async queue.
557 gst_element_set_property (GstElement * element, const gchar * property_name,
558 const GValue * value)
563 g_return_if_fail (GST_IS_ELEMENT (element));
564 g_return_if_fail (property_name != NULL);
565 g_return_if_fail (G_IS_VALUE (value));
567 object = (GObject *) element;
569 GST_CAT_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
570 property_name, gst_element_get_name (element));
571 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
572 g_object_set_property (object, property_name, value);
576 g_object_ref (object);
578 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
582 g_warning ("%s: object class `%s' has no property named `%s'",
583 G_STRLOC, G_OBJECT_TYPE_NAME (object), property_name);
585 element_set_property (element, pspec, value);
587 g_object_unref (object);
591 * gst_element_get_property:
592 * @element: a #GstElement to get properties of.
593 * @property_name: the first property to get.
594 * @value: the #GValue to store the property value in.
596 * Gets a property from an element. If the element uses threadsafe properties,
597 * the element will be locked before getting the given property.
600 gst_element_get_property (GstElement * element, const gchar * property_name,
606 g_return_if_fail (GST_IS_ELEMENT (element));
607 g_return_if_fail (property_name != NULL);
608 g_return_if_fail (G_IS_VALUE (value));
610 object = (GObject *) element;
612 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
613 g_object_get_property (object, property_name, value);
617 g_object_ref (object);
620 g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
623 g_warning ("%s: object class `%s' has no property named `%s'",
624 G_STRLOC, G_OBJECT_TYPE_NAME (object), property_name);
626 GValue *prop_value, tmp_value = { 0, };
628 /* auto-conversion of the callers value type
630 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec)) {
631 g_value_reset (value);
633 } else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec),
634 G_VALUE_TYPE (value))) {
636 ("can't retrieve property `%s' of type `%s' as value of type `%s'",
637 pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
638 G_VALUE_TYPE_NAME (value));
639 g_object_unref (object);
642 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
643 prop_value = &tmp_value;
645 element_get_property (element, pspec, prop_value);
646 if (prop_value != value) {
647 g_value_transform (prop_value, value);
648 g_value_unset (&tmp_value);
652 g_object_unref (object);
656 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
659 GstPad *newpad = NULL;
660 GstElementClass *oclass;
662 oclass = GST_ELEMENT_GET_CLASS (element);
664 if (oclass->request_new_pad)
665 newpad = (oclass->request_new_pad) (element, templ, name);
671 * gst_element_release_request_pad:
672 * @element: a #GstElement to release the request pad of.
673 * @pad: the #GstPad to release.
675 * Makes the element free the previously requested pad as obtained
676 * with gst_element_get_request_pad().
679 gst_element_release_request_pad (GstElement * element, GstPad * pad)
681 GstElementClass *oclass;
683 g_return_if_fail (GST_IS_ELEMENT (element));
684 g_return_if_fail (GST_IS_PAD (pad));
686 oclass = GST_ELEMENT_GET_CLASS (element);
688 if (oclass->release_pad)
689 (oclass->release_pad) (element, pad);
693 * gst_element_requires_clock:
694 * @element: a #GstElement to query
696 * Query if the element requiresd a clock
698 * Returns: TRUE if the element requires a clock
701 gst_element_requires_clock (GstElement * element)
703 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
705 return (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
709 * gst_element_provides_clock:
710 * @element: a #GstElement to query
712 * Query if the element provides a clock
714 * Returns: TRUE if the element provides a clock
717 gst_element_provides_clock (GstElement * element)
719 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
721 return (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
725 * gst_element_set_clock:
726 * @element: a #GstElement to set the clock for.
727 * @clock: the #GstClock to set for the element.
729 * Sets the clock for the element.
732 gst_element_set_clock (GstElement * element, GstClock * clock)
734 GstElementClass *oclass;
736 g_return_if_fail (GST_IS_ELEMENT (element));
738 oclass = GST_ELEMENT_GET_CLASS (element);
740 if (oclass->set_clock)
741 oclass->set_clock (element, clock);
743 gst_object_replace ((GstObject **) & element->clock, (GstObject *) clock);
747 * gst_element_get_clock:
748 * @element: a #GstElement to get the clock of.
750 * Gets the clock of the element.
752 * Returns: the #GstClock of the element.
755 gst_element_get_clock (GstElement * element)
757 GstElementClass *oclass;
759 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
761 oclass = GST_ELEMENT_GET_CLASS (element);
763 if (oclass->get_clock)
764 return oclass->get_clock (element);
770 * gst_element_clock_wait:
771 * @element: a #GstElement.
772 * @id: the #GstClock to use.
773 * @jitter: the difference between requested time and actual time.
775 * Waits for a specific time on the clock.
777 * Returns: the #GstClockReturn result of the wait operation.
780 gst_element_clock_wait (GstElement * element, GstClockID id,
781 GstClockTimeDiff * jitter)
785 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
787 if (GST_ELEMENT_SCHED (element)) {
788 GST_CAT_DEBUG (GST_CAT_CLOCK, "waiting on scheduler clock");
790 gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id,
793 GST_CAT_DEBUG (GST_CAT_CLOCK, "no scheduler, returning GST_CLOCK_TIMEOUT");
794 res = GST_CLOCK_TIMEOUT;
800 #undef GST_CAT_DEFAULT
801 #define GST_CAT_DEFAULT GST_CAT_CLOCK
803 * gst_element_get_time:
804 * @element: element to query
806 * Query the element's time. The element must use
808 * Returns: the current time of the element or #GST_CLOCK_TIME_NONE when there
809 * is no time available.
812 gst_element_get_time (GstElement * element)
814 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
816 if (element->clock == NULL) {
817 GST_WARNING_OBJECT (element, "element queries time but has no clock");
818 return GST_CLOCK_TIME_NONE;
820 switch (element->current_state) {
822 case GST_STATE_READY:
823 return GST_CLOCK_TIME_NONE;
824 case GST_STATE_PAUSED:
825 return element->base_time;
826 case GST_STATE_PLAYING:
827 return gst_clock_get_time (element->clock) - element->base_time;
829 g_assert_not_reached ();
830 return GST_CLOCK_TIME_NONE;
836 * @element: element that should wait
837 * @timestamp: wait until this time has arrived
839 * Waits until the given time has arrived. When this function returns successfully,
840 * the time specified in the timestamp has passed.
841 * <note>This function can only be called on elements in #GST_STATE_PLAYING</note>
843 * Returns: TRUE on success
846 gst_element_wait (GstElement * element, GstClockTime timestamp)
851 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
852 g_return_val_if_fail (GST_IS_CLOCK (element->clock), FALSE);
853 g_return_val_if_fail (element->current_state == GST_STATE_PLAYING, FALSE);
854 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
856 /* shortcut when we're already late... */
857 if (gst_element_get_time (element) >= timestamp) {
858 GST_INFO_OBJECT (element, "called gst_element_wait and was late");
862 id = gst_clock_new_single_shot_id (element->clock,
863 element->base_time + timestamp);
864 ret = gst_element_clock_wait (element, id, NULL);
865 gst_clock_id_free (id);
867 return ret == GST_CLOCK_STOPPED;
871 * gst_element_set_time:
872 * @element: element to set time on
875 * Sets the current time of the element. This function can be used when handling
876 * discont events. You can only call this function on an element with a clock in
877 * #GST_STATE_PAUSED or #GST_STATE_PLAYING. You might want to have a look at
878 * gst_element_adjust_time(), if you want to adjust by a difference as that is
882 gst_element_set_time (GstElement * element, GstClockTime time)
884 GstClockTime event_time;
886 g_return_if_fail (GST_IS_ELEMENT (element));
887 g_return_if_fail (GST_IS_CLOCK (element->clock));
888 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
890 switch (element->current_state) {
891 case GST_STATE_PAUSED:
892 element->base_time = time;
894 case GST_STATE_PLAYING:
895 event_time = gst_clock_get_event_time (element->clock);
896 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element,
897 "clock time %llu: setting element time to %llu", event_time, time);
898 element->base_time = event_time - time;
901 g_assert_not_reached ();
907 * gst_element_adjust_time:
908 * @element: element to adjust time on
909 * @difference: difference to adjust
911 * Adjusts the current time of the element by the specified difference. This
912 * function can be used when handling discont events. You can only call this
913 * function on an element with a clock in #GST_STATE_PAUSED or
914 * #GST_STATE_PLAYING. It is more accurate than gst_element_set_time().
917 gst_element_adjust_time (GstElement * element, GstClockTimeDiff diff)
921 g_return_if_fail (GST_IS_ELEMENT (element));
922 g_return_if_fail (GST_IS_CLOCK (element->clock));
923 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
925 switch (element->current_state) {
926 case GST_STATE_PAUSED:
927 if (diff < 0 && element->base_time < abs (diff)) {
928 g_warning ("attempted to set the current time of element %s below 0",
929 GST_OBJECT_NAME (element));
930 element->base_time = 0;
932 element->base_time += diff;
935 case GST_STATE_PLAYING:
936 time = gst_clock_get_time (element->clock);
937 if (time < element->base_time - diff) {
938 g_warning ("attempted to set the current time of element %s below 0",
939 GST_OBJECT_NAME (element));
940 element->base_time = time;
942 element->base_time -= diff;
946 g_assert_not_reached ();
951 #undef GST_CAT_DEFAULT
953 #ifndef GST_DISABLE_INDEX
955 * gst_element_is_indexable:
956 * @element: a #GstElement.
958 * Queries if the element can be indexed.
960 * Returns: TRUE if the element can be indexed.
963 gst_element_is_indexable (GstElement * element)
965 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
967 return (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
971 * gst_element_set_index:
972 * @element: a #GstElement.
973 * @index: a #GstIndex.
975 * Set the specified GstIndex on the element.
978 gst_element_set_index (GstElement * element, GstIndex * index)
980 GstElementClass *oclass;
982 g_return_if_fail (GST_IS_ELEMENT (element));
983 g_return_if_fail (GST_IS_INDEX (index));
985 oclass = GST_ELEMENT_GET_CLASS (element);
987 if (oclass->set_index)
988 oclass->set_index (element, index);
992 * gst_element_get_index:
993 * @element: a #GstElement.
995 * Gets the index from the element.
997 * Returns: a #GstIndex or NULL when no index was set on the
1001 gst_element_get_index (GstElement * element)
1003 GstElementClass *oclass;
1005 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1007 oclass = GST_ELEMENT_GET_CLASS (element);
1009 if (oclass->get_index)
1010 return oclass->get_index (element);
1017 * gst_element_release_locks:
1018 * @element: a #GstElement to release all locks on.
1020 * Instruct the element to release all the locks it is holding, such as
1021 * blocking reads, waiting for the clock, ...
1023 * Returns: TRUE if the locks could be released.
1026 gst_element_release_locks (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->release_locks)
1035 return oclass->release_locks (element);
1041 * gst_element_add_pad:
1042 * @element: a #GstElement to add the pad to.
1043 * @pad: the #GstPad to add to the element.
1045 * Adds a pad (link point) to @element. @pad's parent will be set to @element;
1046 * see gst_object_set_parent() for refcounting information.
1048 * Pads are automatically activated when the element is in state PLAYING.
1051 gst_element_add_pad (GstElement * element, GstPad * pad)
1053 g_return_if_fail (GST_IS_ELEMENT (element));
1054 g_return_if_fail (GST_IS_PAD (pad));
1056 /* first check to make sure the pad hasn't already been added to another
1058 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
1060 /* then check to see if there's already a pad by that name here */
1061 g_return_if_fail (gst_object_check_uniqueness (element->pads,
1062 GST_PAD_NAME (pad)) == TRUE);
1064 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
1065 GST_STR_NULL (GST_OBJECT_NAME (pad)));
1067 /* set the pad's parent */
1068 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
1070 /* add it to the list */
1071 element->pads = g_list_append (element->pads, pad);
1074 switch (gst_pad_get_direction (pad)) {
1076 element->numsrcpads++;
1079 element->numsinkpads++;
1082 /* can happen for ghost pads */
1086 /* activate element when we are playing */
1087 if (GST_STATE (element) == GST_STATE_PLAYING)
1088 gst_pad_set_active (pad, TRUE);
1090 /* emit the NEW_PAD signal */
1091 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
1095 * gst_element_add_ghost_pad:
1096 * @element: a #GstElement to add the ghost pad to.
1097 * @pad: the #GstPad from which the new ghost pad will be created.
1098 * @name: the name of the new ghost pad, or NULL to assign a unique name
1101 * Creates a ghost pad from @pad, and adds it to @element via
1102 * gst_element_add_pad().
1104 * Returns: the added ghost #GstPad, or NULL on error.
1107 gst_element_add_ghost_pad (GstElement * element, GstPad * pad,
1112 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1113 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1115 /* then check to see if there's already a pad by that name here */
1116 g_return_val_if_fail (gst_object_check_uniqueness (element->pads,
1117 name) == TRUE, NULL);
1119 ghostpad = gst_ghost_pad_new (name, pad);
1121 gst_element_add_pad (element, ghostpad);
1127 * gst_element_remove_pad:
1128 * @element: a #GstElement to remove pad from.
1129 * @pad: the #GstPad to remove from the element.
1131 * Removes @pad from @element. @pad will be destroyed if it has not been
1132 * referenced elsewhere.
1135 gst_element_remove_pad (GstElement * element, GstPad * pad)
1137 g_return_if_fail (element != NULL);
1138 g_return_if_fail (GST_IS_ELEMENT (element));
1139 g_return_if_fail (pad != NULL);
1140 g_return_if_fail (GST_IS_PAD (pad));
1142 g_return_if_fail (GST_PAD_PARENT (pad) == element);
1144 if (GST_IS_REAL_PAD (pad)) {
1145 /* unlink if necessary */
1146 if (GST_RPAD_PEER (pad) != NULL) {
1147 gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
1149 gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
1150 } else if (GST_IS_GHOST_PAD (pad)) {
1151 g_object_set (pad, "real-pad", NULL, NULL);
1154 /* remove it from the list */
1155 element->pads = g_list_remove (element->pads, pad);
1157 switch (gst_pad_get_direction (pad)) {
1159 element->numsrcpads--;
1162 element->numsinkpads--;
1165 /* can happen for ghost pads */
1169 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
1171 gst_object_unparent (GST_OBJECT (pad));
1175 * gst_element_remove_ghost_pad:
1176 * @element: a #GstElement to remove the ghost pad from.
1177 * @pad: ghost #GstPad to remove.
1179 * Removes a ghost pad from an element. Deprecated, use gst_element_remove_pad()
1183 gst_element_remove_ghost_pad (GstElement * element, GstPad * pad)
1185 g_return_if_fail (GST_IS_ELEMENT (element));
1186 g_return_if_fail (GST_IS_GHOST_PAD (pad));
1188 g_warning ("gst_element_remove_ghost_pad is deprecated.\n"
1189 "Use gst_element_remove_pad instead.");
1191 gst_element_remove_pad (element, pad);
1196 * gst_element_get_pad:
1197 * @element: a #GstElement.
1198 * @name: the name of the pad to retrieve.
1200 * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
1201 * first, then gst_element_get_request_pad().
1203 * Returns: the #GstPad if found, otherwise %NULL.
1206 gst_element_get_pad (GstElement * element, const gchar * name)
1210 g_return_val_if_fail (element != NULL, NULL);
1211 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1212 g_return_val_if_fail (name != NULL, NULL);
1214 pad = gst_element_get_static_pad (element, name);
1216 pad = gst_element_get_request_pad (element, name);
1222 * gst_element_get_static_pad:
1223 * @element: a #GstElement to find a static pad of.
1224 * @name: the name of the static #GstPad to retrieve.
1226 * Retrieves a pad from @element by name. This version only retrieves
1227 * already-existing (i.e. 'static') pads.
1229 * Returns: the requested #GstPad if found, otherwise NULL.
1232 gst_element_get_static_pad (GstElement * element, const gchar * name)
1236 g_return_val_if_fail (element != NULL, NULL);
1237 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1238 g_return_val_if_fail (name != NULL, NULL);
1240 walk = element->pads;
1244 pad = GST_PAD (walk->data);
1245 if (strcmp (GST_PAD_NAME (pad), name) == 0) {
1246 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
1247 GST_DEBUG_PAD_NAME (pad));
1250 walk = g_list_next (walk);
1253 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
1254 name, GST_OBJECT_NAME (element));
1259 * gst_element_get_request_pad:
1260 * @element: a #GstElement to find a request pad of.
1261 * @name: the name of the request #GstPad to retrieve.
1263 * Retrieves a pad from the element by name. This version only retrieves
1266 * Returns: requested #GstPad if found, otherwise NULL.
1269 gst_element_get_request_pad (GstElement * element, const gchar * name)
1271 GstPadTemplate *templ = NULL;
1273 const gchar *req_name = NULL;
1274 gboolean templ_found = FALSE;
1278 gchar *str, *endptr = NULL;
1280 g_return_val_if_fail (element != NULL, NULL);
1281 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1282 g_return_val_if_fail (name != NULL, NULL);
1284 if (strstr (name, "%")) {
1285 templ = gst_element_get_pad_template (element, name);
1290 list = gst_element_get_pad_template_list (element);
1291 while (!templ_found && list) {
1292 templ = (GstPadTemplate *) list->data;
1293 if (templ->presence == GST_PAD_REQUEST) {
1294 /* Because of sanity checks in gst_pad_template_new(), we know that %s
1295 and %d, occurring at the end of the name_template, are the only
1297 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
1298 templ->name_template);
1299 if ((str = strchr (templ->name_template, '%'))
1300 && strncmp (templ->name_template, name,
1301 str - templ->name_template) == 0
1302 && strlen (name) > str - templ->name_template) {
1303 data = name + (str - templ->name_template);
1304 if (*(str + 1) == 'd') {
1306 n = (gint) strtol (data, &endptr, 10);
1307 if (endptr && *endptr == '\0') {
1327 pad = gst_element_request_pad (element, templ, req_name);
1333 * gst_element_get_pad_list:
1334 * @element: a #GstElement to get pads of.
1336 * Retrieves a list of @element's pads. The list must not be modified by the
1339 * Returns: the #GList of pads.
1342 gst_element_get_pad_list (GstElement * element)
1344 g_return_val_if_fail (element != NULL, NULL);
1345 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1347 /* return the list of pads */
1348 return element->pads;
1352 * gst_element_class_add_pad_template:
1353 * @klass: the #GstElementClass to add the pad template to.
1354 * @templ: a #GstPadTemplate to add to the element class.
1356 * Adds a padtemplate to an element class. This is mainly used in the _base_init
1357 * functions of classes.
1360 gst_element_class_add_pad_template (GstElementClass * klass,
1361 GstPadTemplate * templ)
1363 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1364 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1366 /* avoid registering pad templates with the same name */
1367 g_return_if_fail (gst_element_class_get_pad_template (klass,
1368 templ->name_template) == NULL);
1370 klass->padtemplates = g_list_append (klass->padtemplates,
1371 gst_object_ref (GST_OBJECT (templ)));
1372 klass->numpadtemplates++;
1376 * gst_element_class_set_details:
1377 * @klass: class to set details for
1378 * @details: details to set
1380 * Sets the detailed information for a #GstElementClass.
1381 * <note>This function is for use in _base_init functions only.</note>
1384 gst_element_class_set_details (GstElementClass * klass,
1385 const GstElementDetails * details)
1387 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1388 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1390 __gst_element_details_copy (&klass->details, details);
1394 * gst_element_class_get_pad_template_list:
1395 * @element_class: a #GstElementClass to get pad templates of.
1397 * Retrieves a list of the pad templates associated with @element_class. The
1398 * list must not be modified by the calling code.
1400 * Returns: the #GList of padtemplates.
1403 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1405 g_return_val_if_fail (element_class != NULL, NULL);
1406 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1408 return element_class->padtemplates;
1412 * gst_element_class_get_pad_template:
1413 * @element_class: a #GstElementClass to get the pad template of.
1414 * @name: the name of the #GstPadTemplate to get.
1416 * Retrieves a padtemplate from @element_class with the given name.
1418 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1419 * No unreferencing is necessary.
1422 gst_element_class_get_pad_template (GstElementClass * element_class,
1427 g_return_val_if_fail (element_class != NULL, NULL);
1428 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1429 g_return_val_if_fail (name != NULL, NULL);
1431 padlist = gst_element_class_get_pad_template_list (element_class);
1434 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1436 if (strcmp (padtempl->name_template, name) == 0)
1439 padlist = g_list_next (padlist);
1446 * gst_element_get_pad_template_list:
1447 * @element: a #GstElement to get pad templates of.
1449 * Retrieves a list of the pad templates associated with the element.
1450 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template_list).
1452 * Returns: the #GList of padtemplates.
1455 gst_element_get_pad_template_list (GstElement * element)
1457 g_return_val_if_fail (element != NULL, NULL);
1458 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1460 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1464 * gst_element_get_pad_template:
1465 * @element: a #GstElement to get the pad template of.
1466 * @name: the name of the #GstPadTemplate to get.
1468 * Retrieves a padtemplate from this element with the
1470 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template).
1472 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1473 * No unreferencing is necessary.
1476 gst_element_get_pad_template (GstElement * element, const gchar * name)
1478 g_return_val_if_fail (element != NULL, NULL);
1479 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1480 g_return_val_if_fail (name != NULL, NULL);
1482 return gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (element),
1487 * gst_element_get_compatible_pad_template:
1488 * @element: a #GstElement to get a compatible pad template for.
1489 * @compattempl: the #GstPadTemplate to find a compatible template for.
1491 * Retrieves a pad template from @element that is compatible with @compattempl.
1492 * Pads from compatible templates can be linked together.
1494 * Returns: a compatible #GstPadTemplate, or NULL if none was found. No
1495 * unreferencing is necessary.
1498 gst_element_get_compatible_pad_template (GstElement * element,
1499 GstPadTemplate * compattempl)
1501 GstPadTemplate *newtempl = NULL;
1504 g_return_val_if_fail (element != NULL, NULL);
1505 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1506 g_return_val_if_fail (compattempl != NULL, NULL);
1508 padlist = gst_element_get_pad_template_list (element);
1510 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1511 "Looking for a suitable pad template...");
1514 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1515 GstCaps *intersection;
1519 * Check direction (must be opposite)
1522 if (padtempl->direction != compattempl->direction) {
1523 GST_CAT_DEBUG (GST_CAT_CAPS,
1524 "compatible direction: found %s pad template \"%s\"",
1525 padtempl->direction == GST_PAD_SRC ? "src" : "sink",
1526 padtempl->name_template);
1528 intersection = gst_caps_intersect (GST_PAD_TEMPLATE_CAPS (compattempl),
1529 GST_PAD_TEMPLATE_CAPS (padtempl));
1531 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible",
1532 (intersection ? "" : "not "));
1534 if (!gst_caps_is_empty (intersection))
1535 newtempl = padtempl;
1536 gst_caps_free (intersection);
1541 padlist = g_list_next (padlist);
1548 * gst_element_get_pad_from_template:
1549 * @element: a #GstElement.
1550 * @templ: a #GstPadTemplate belonging to @element.
1552 * Gets a pad from @element described by @templ. If the presence of @templ is
1553 * #GST_PAD_REQUEST, requests a new pad. Can return %NULL for #GST_PAD_SOMETIMES
1556 * Returns: the #GstPad, or NULL if one could not be found or created.
1559 gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
1562 GstPadPresence presence;
1564 /* If this function is ever exported, we need check the validity of `element'
1565 * and `templ', and to make sure the template actually belongs to the
1568 presence = GST_PAD_TEMPLATE_PRESENCE (templ);
1571 case GST_PAD_ALWAYS:
1572 case GST_PAD_SOMETIMES:
1573 ret = gst_element_get_static_pad (element, templ->name_template);
1574 if (!ret && presence == GST_PAD_ALWAYS)
1576 ("Element %s has an ALWAYS template %s, but no pad of the same name",
1577 GST_OBJECT_NAME (element), templ->name_template);
1580 case GST_PAD_REQUEST:
1581 ret = gst_element_request_pad (element, templ, NULL);
1589 * gst_element_request_compatible_pad:
1590 * @element: a #GstElement.
1591 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1593 * Requests a pad from @element. The returned pad should be unlinked and
1594 * compatible with @templ. Might return an existing pad, or request a new one.
1596 * Returns: a #GstPad, or %NULL if one could not be found or created.
1599 gst_element_request_compatible_pad (GstElement * element,
1600 GstPadTemplate * templ)
1602 GstPadTemplate *templ_new;
1605 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1606 g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
1608 /* FIXME: should really loop through the templates, testing each for
1609 compatibility and pad availability. */
1610 templ_new = gst_element_get_compatible_pad_template (element, templ);
1612 pad = gst_element_get_pad_from_template (element, templ_new);
1614 /* This can happen for non-request pads. No need to unref. */
1615 if (pad && GST_PAD_PEER (pad))
1622 * gst_element_get_compatible_pad_filtered:
1623 * @element: a #GstElement in which the pad should be found.
1624 * @pad: the #GstPad to find a compatible one for.
1625 * @filtercaps: the #GstCaps to use as a filter.
1627 * Looks for an unlinked pad to which the given pad can link. It is not
1628 * guaranteed that linking the pads will work, though it should work in most
1631 * Returns: the #GstPad to which a link can be made, or %NULL if one cannot be
1635 gst_element_get_compatible_pad_filtered (GstElement * element, GstPad * pad,
1636 const GstCaps * filtercaps)
1639 GstPadTemplate *templ;
1641 GstPad *foundpad = NULL;
1643 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1644 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1646 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1647 "finding pad in %s compatible with %s:%s", GST_ELEMENT_NAME (element),
1648 GST_DEBUG_PAD_NAME (pad));
1650 /* let's use the real pad */
1651 pad = (GstPad *) GST_PAD_REALIZE (pad);
1652 g_return_val_if_fail (pad != NULL, NULL);
1653 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1655 /* try to get an existing unlinked pad */
1656 pads = gst_element_get_pad_list (element);
1658 GstPad *current = GST_PAD (pads->data);
1660 if (GST_PAD_PEER (current) == NULL &&
1661 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1664 pads = g_list_next (pads);
1667 /* try to create a new one */
1668 /* requesting is a little crazy, we need a template. Let's create one */
1669 templcaps = gst_pad_get_caps (pad);
1670 if (filtercaps != NULL) {
1673 temp = gst_caps_intersect (filtercaps, templcaps);
1674 gst_caps_free (templcaps);
1678 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
1679 GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
1680 foundpad = gst_element_request_compatible_pad (element, templ);
1681 gst_object_unref (GST_OBJECT (templ));
1686 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element,
1687 "Could not find a compatible pad to link to %s:%s",
1688 GST_DEBUG_PAD_NAME (pad));
1694 * gst_element_get_compatible_pad:
1695 * @element: a #GstElement in which the pad should be found.
1696 * @pad: the #GstPad to find a compatible one for.
1698 * Looks for an unlinked pad to which the given pad can link to.
1699 * It is not guaranteed that linking the pads will work, though
1700 * it should work in most cases.
1702 * Returns: the #GstPad to which a link can be made, or %NULL if one
1703 * could not be found.
1706 gst_element_get_compatible_pad (GstElement * element, GstPad * pad)
1708 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1712 * gst_element_link_pads_filtered:
1713 * @src: a #GstElement containing the source pad.
1714 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1715 * @dest: the #GstElement containing the destination pad.
1716 * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1717 * @filtercaps: the #GstCaps to use as a filter.
1719 * Links the two named pads of the source and destination elements.
1720 * Side effect is that if one of the pads has no parent, it becomes a
1721 * child of the parent of the other element. If they have different
1722 * parents, the link fails.
1724 * Returns: TRUE if the pads could be linked, FALSE otherwise.
1727 gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
1728 GstElement * dest, const gchar * destpadname, const GstCaps * filtercaps)
1730 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1731 GstPad *srcpad, *destpad;
1732 GstPadTemplate *srctempl, *desttempl;
1735 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1736 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1738 GST_CAT_INFO (GST_CAT_ELEMENT_PADS,
1739 "trying to link element %s:%s to element %s:%s", GST_ELEMENT_NAME (src),
1740 srcpadname ? srcpadname : "(any)", GST_ELEMENT_NAME (dest),
1741 destpadname ? destpadname : "(any)");
1743 /* now get the pads we're trying to link and a list of all remaining pads */
1745 srcpad = gst_element_get_pad (src, srcpadname);
1747 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1748 GST_ELEMENT_NAME (src), srcpadname);
1751 if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1752 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad",
1753 GST_DEBUG_PAD_NAME (srcpad));
1756 if (GST_PAD_PEER (srcpad) != NULL) {
1757 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1758 GST_DEBUG_PAD_NAME (srcpad));
1764 srcpads = gst_element_get_pad_list (src);
1765 srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
1768 destpad = gst_element_get_pad (dest, destpadname);
1770 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1771 GST_ELEMENT_NAME (dest), destpadname);
1774 if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1775 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad",
1776 GST_DEBUG_PAD_NAME (destpad));
1779 if (GST_PAD_PEER (destpad) != NULL) {
1780 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1781 GST_DEBUG_PAD_NAME (destpad));
1787 destpads = gst_element_get_pad_list (dest);
1788 destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
1791 if (srcpadname && destpadname) {
1792 /* two explicitly specified pads */
1793 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1796 /* loop through the allowed pads in the source, trying to find a
1797 * compatible destination pad */
1798 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1799 "looping through allowed src and dest pads");
1801 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1802 GST_DEBUG_PAD_NAME (srcpad));
1803 if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1804 (GST_PAD_PEER (srcpad) == NULL)) {
1805 GstPad *temp = gst_element_get_compatible_pad_filtered (dest, srcpad,
1808 if (temp && gst_pad_link_filtered (srcpad, temp, filtercaps)) {
1809 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1810 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1814 /* find a better way for this mess */
1816 srcpads = g_list_next (srcpads);
1818 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1823 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1824 GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1828 /* loop through the existing pads in the destination */
1830 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1831 GST_DEBUG_PAD_NAME (destpad));
1832 if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1833 (GST_PAD_PEER (destpad) == NULL)) {
1834 GstPad *temp = gst_element_get_compatible_pad_filtered (src, destpad,
1837 if (temp && gst_pad_link_filtered (temp, destpad, filtercaps)) {
1838 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1839 GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1844 destpads = g_list_next (destpads);
1846 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1851 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1852 GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1856 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1857 "we might have request pads on both sides, checking...");
1858 srctempls = gst_element_get_pad_template_list (src);
1859 desttempls = gst_element_get_pad_template_list (dest);
1861 if (srctempls && desttempls) {
1863 srctempl = (GstPadTemplate *) srctempls->data;
1864 if (srctempl->presence == GST_PAD_REQUEST) {
1865 for (l = desttempls; l; l = l->next) {
1866 desttempl = (GstPadTemplate *) l->data;
1867 if (desttempl->presence == GST_PAD_REQUEST &&
1868 desttempl->direction != srctempl->direction) {
1869 if (gst_caps_is_always_compatible (gst_pad_template_get_caps
1870 (srctempl), gst_pad_template_get_caps (desttempl))) {
1872 gst_element_get_request_pad (src, srctempl->name_template);
1874 gst_element_get_request_pad (dest, desttempl->name_template);
1875 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1876 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1877 "linked pad %s:%s to pad %s:%s",
1878 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1881 /* it failed, so we release the request pads */
1882 gst_element_release_request_pad (src, srcpad);
1883 gst_element_release_request_pad (dest, destpad);
1888 srctempls = srctempls->next;
1892 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1893 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1898 * gst_element_link_filtered:
1899 * @src: a #GstElement containing the source pad.
1900 * @dest: the #GstElement containing the destination pad.
1901 * @filtercaps: the #GstCaps to use as a filter.
1903 * Links @src to @dest, filtered by @filtercaps. The link must be from source to
1904 * destination; the other direction will not be tried. The function looks for
1905 * existing pads that aren't linked yet. It will request new pads if necessary.
1906 * If multiple links are possible, only one is established.
1908 * Returns: TRUE if the elements could be linked, FALSE otherwise.
1911 gst_element_link_filtered (GstElement * src, GstElement * dest,
1912 const GstCaps * filtercaps)
1914 return gst_element_link_pads_filtered (src, NULL, dest, NULL, filtercaps);
1918 * gst_element_link_many:
1919 * @element_1: the first #GstElement in the link chain.
1920 * @element_2: the second #GstElement in the link chain.
1921 * @...: the NULL-terminated list of elements to link in order.
1923 * Chain together a series of elements. Uses gst_element_link().
1925 * Returns: TRUE on success, FALSE otherwise.
1928 gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
1932 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1933 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1934 GST_IS_ELEMENT (element_2), FALSE);
1936 va_start (args, element_2);
1939 if (!gst_element_link (element_1, element_2))
1942 element_1 = element_2;
1943 element_2 = va_arg (args, GstElement *);
1953 * @src: a #GstElement containing the source pad.
1954 * @dest: the #GstElement containing the destination pad.
1956 * Links @src to @dest with no filter caps. See gst_element_link_filtered() for
1959 * Returns: TRUE if the elements could be linked, FALSE otherwise.
1962 gst_element_link (GstElement * src, GstElement * dest)
1964 return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1968 * gst_element_link_pads:
1969 * @src: a #GstElement containing the source pad.
1970 * @srcpadname: the name of the #GstPad in the source element.
1971 * @dest: the #GstElement containing the destination pad.
1972 * @destpadname: the name of the #GstPad in destination element.
1974 * Links the two named pads of the source and destination elements.
1975 * Side effect is that if one of the pads has no parent, it becomes a
1976 * child of the parent of the other element. If they have different
1977 * parents, the link fails.
1979 * Returns: TRUE if the pads could be linked, FALSE otherwise.
1982 gst_element_link_pads (GstElement * src, const gchar * srcpadname,
1983 GstElement * dest, const gchar * destpadname)
1985 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname,
1990 * gst_element_unlink_pads:
1991 * @src: a #GstElement containing the source pad.
1992 * @srcpadname: the name of the #GstPad in source element.
1993 * @dest: a #GstElement containing the destination pad.
1994 * @destpadname: the name of the #GstPad in destination element.
1996 * Unlinks the two named pads of the source and destination elements.
1999 gst_element_unlink_pads (GstElement * src, const gchar * srcpadname,
2000 GstElement * dest, const gchar * destpadname)
2002 GstPad *srcpad, *destpad;
2004 g_return_if_fail (src != NULL);
2005 g_return_if_fail (GST_IS_ELEMENT (src));
2006 g_return_if_fail (srcpadname != NULL);
2007 g_return_if_fail (dest != NULL);
2008 g_return_if_fail (GST_IS_ELEMENT (dest));
2009 g_return_if_fail (destpadname != NULL);
2011 /* obtain the pads requested */
2012 srcpad = gst_element_get_pad (src, srcpadname);
2013 if (srcpad == NULL) {
2014 GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
2017 destpad = gst_element_get_pad (dest, destpadname);
2018 if (srcpad == NULL) {
2019 GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"",
2024 /* we're satisified they can be unlinked, let's do it */
2025 gst_pad_unlink (srcpad, destpad);
2029 * gst_element_unlink_many:
2030 * @element_1: the first #GstElement in the link chain.
2031 * @element_2: the second #GstElement in the link chain.
2032 * @...: the NULL-terminated list of elements to unlink in order.
2034 * Unlinks a series of elements. Uses gst_element_unlink().
2037 gst_element_unlink_many (GstElement * element_1, GstElement * element_2, ...)
2041 g_return_if_fail (element_1 != NULL && element_2 != NULL);
2042 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
2044 va_start (args, element_2);
2047 gst_element_unlink (element_1, element_2);
2049 element_1 = element_2;
2050 element_2 = va_arg (args, GstElement *);
2057 * gst_element_unlink:
2058 * @src: the source #GstElement to unlink.
2059 * @dest: the sink #GstElement to unlink.
2061 * Unlinks all source pads of the source element with all sink pads
2062 * of the sink element to which they are linked.
2065 gst_element_unlink (GstElement * src, GstElement * dest)
2067 const GList *srcpads;
2070 g_return_if_fail (GST_IS_ELEMENT (src));
2071 g_return_if_fail (GST_IS_ELEMENT (dest));
2073 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
2074 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
2076 srcpads = gst_element_get_pad_list (src);
2079 pad = GST_PAD (srcpads->data);
2081 /* we only care about real src pads */
2082 if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
2083 GstPad *peerpad = GST_PAD_PEER (pad);
2085 /* see if the pad is connected and is really a pad
2087 if (peerpad && (GST_OBJECT_PARENT (peerpad) == (GstObject *) dest)) {
2088 gst_pad_unlink (pad, peerpad);
2092 srcpads = g_list_next (srcpads);
2097 gst_element_error_func (GstElement * element, GstElement * source,
2098 GError * error, gchar * debug)
2100 /* tell the parent */
2101 if (GST_OBJECT_PARENT (element)) {
2102 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM,
2103 "forwarding error \"%s\" from %s to %s", error->message,
2104 GST_ELEMENT_NAME (element),
2105 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2107 gst_object_ref (GST_OBJECT (element));
2108 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
2109 gst_element_signals[ERROR], 0, source, error, debug);
2110 gst_object_unref (GST_OBJECT (element));
2111 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM, "forwarded error \"%s\" from %s to %s",
2112 error->message, GST_ELEMENT_NAME (element),
2113 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2118 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
2120 GList *pads = element->pads;
2122 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
2124 GstPad *pad = GST_PAD (pads->data);
2126 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
2127 GST_DEBUG_PAD_NAME (pad));
2129 if (GST_PAD_DIRECTION (pad) == dir) {
2130 if (GST_PAD_IS_LINKED (pad)) {
2133 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
2134 GST_DEBUG_PAD_NAME (pad));
2137 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
2138 GST_DEBUG_PAD_NAME (pad));
2141 pads = g_list_next (pads);
2147 * gst_element_get_event_masks:
2148 * @element: a #GstElement to query
2150 * Get an array of event masks from the element.
2151 * If the element doesn't
2152 * implement an event masks function, the query will be forwarded
2153 * to a random linked sink pad.
2155 * Returns: An array of #GstEventMask elements.
2157 const GstEventMask *
2158 gst_element_get_event_masks (GstElement * element)
2160 GstElementClass *oclass;
2162 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2164 oclass = GST_ELEMENT_GET_CLASS (element);
2166 if (oclass->get_event_masks)
2167 return oclass->get_event_masks (element);
2169 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2172 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
2179 * gst_element_send_event:
2180 * @element: a #GstElement to send the event to.
2181 * @event: the #GstEvent to send to the element.
2183 * Sends an event to an element. If the element doesn't
2184 * implement an event handler, the event will be forwarded
2185 * to a random sink pad.
2187 * Returns: TRUE if the event was handled.
2190 gst_element_send_event (GstElement * element, GstEvent * event)
2192 GstElementClass *oclass;
2194 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2195 g_return_val_if_fail (event != NULL, FALSE);
2197 oclass = GST_ELEMENT_GET_CLASS (element);
2199 if (oclass->send_event)
2200 return oclass->send_event (element, event);
2202 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2205 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
2206 GST_DEBUG_PAD_NAME (pad));
2207 return gst_pad_send_event (GST_PAD_PEER (pad), event);
2210 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
2211 GST_ELEMENT_NAME (element));
2217 * @element: a #GstElement to send the event to.
2218 * @seek_type: the method to use for seeking.
2219 * @offset: the offset to seek to.
2221 * Sends a seek event to an element.
2223 * Returns: TRUE if the event was handled.
2226 gst_element_seek (GstElement * element, GstSeekType seek_type, guint64 offset)
2228 GstEvent *event = gst_event_new_seek (seek_type, offset);
2230 return gst_element_send_event (element, event);
2234 * gst_element_get_query_types:
2235 * @element: a #GstElement to query
2237 * Get an array of query types from the element.
2238 * If the element doesn't
2239 * implement a query types function, the query will be forwarded
2240 * to a random sink pad.
2242 * Returns: An array of #GstQueryType elements.
2244 const GstQueryType *
2245 gst_element_get_query_types (GstElement * element)
2247 GstElementClass *oclass;
2249 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2251 oclass = GST_ELEMENT_GET_CLASS (element);
2253 if (oclass->get_query_types)
2254 return oclass->get_query_types (element);
2256 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2259 return gst_pad_get_query_types (GST_PAD_PEER (pad));
2266 * gst_element_query:
2267 * @element: a #GstElement to perform the query on.
2268 * @type: the #GstQueryType.
2269 * @format: the #GstFormat pointer to hold the format of the result.
2270 * @value: the pointer to the value of the result.
2272 * Performs a query on the given element. If the format is set
2273 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
2274 * format pointer will hold the default format.
2275 * For element that don't implement a query handler, this function
2276 * forwards the query to a random usable sinkpad of this element.
2278 * Returns: TRUE if the query could be performed.
2281 gst_element_query (GstElement * element, GstQueryType type,
2282 GstFormat * format, gint64 * value)
2284 GstElementClass *oclass;
2286 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2287 g_return_val_if_fail (format != NULL, FALSE);
2288 g_return_val_if_fail (value != NULL, FALSE);
2290 oclass = GST_ELEMENT_GET_CLASS (element);
2293 return oclass->query (element, type, format, value);
2295 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
2298 return gst_pad_query (pad, type, format, value);
2299 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2301 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
2308 * gst_element_get_formats:
2309 * @element: a #GstElement to query
2311 * Get an array of formst from the element.
2312 * If the element doesn't
2313 * implement a formats function, the query will be forwarded
2314 * to a random sink pad.
2316 * Returns: An array of #GstFormat elements.
2319 gst_element_get_formats (GstElement * element)
2321 GstElementClass *oclass;
2323 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2325 oclass = GST_ELEMENT_GET_CLASS (element);
2327 if (oclass->get_formats)
2328 return oclass->get_formats (element);
2330 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2333 return gst_pad_get_formats (GST_PAD_PEER (pad));
2340 * gst_element_convert:
2341 * @element: a #GstElement to invoke the converter on.
2342 * @src_format: the source #GstFormat.
2343 * @src_value: the source value.
2344 * @dest_format: a pointer to the destination #GstFormat.
2345 * @dest_value: a pointer to the destination value.
2347 * Invokes a conversion on the element.
2348 * If the element doesn't
2349 * implement a convert function, the query will be forwarded
2350 * to a random sink pad.
2352 * Returns: TRUE if the conversion could be performed.
2355 gst_element_convert (GstElement * element,
2356 GstFormat src_format, gint64 src_value,
2357 GstFormat * dest_format, gint64 * dest_value)
2359 GstElementClass *oclass;
2361 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2362 g_return_val_if_fail (dest_format != NULL, FALSE);
2363 g_return_val_if_fail (dest_value != NULL, FALSE);
2365 if (src_format == *dest_format) {
2366 *dest_value = src_value;
2370 oclass = GST_ELEMENT_GET_CLASS (element);
2372 if (oclass->convert)
2373 return oclass->convert (element,
2374 src_format, src_value, dest_format, dest_value);
2376 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2379 return gst_pad_convert (GST_PAD_PEER (pad),
2380 src_format, src_value, dest_format, dest_value);
2387 * _gst_element_error_printf:
2388 * @format: the printf-like format to use, or NULL
2390 * This function is only used internally by the #gst_element_error macro.
2392 * Returns: a newly allocated string, or NULL if the format was NULL or ""
2395 _gst_element_error_printf (const gchar * format, ...)
2405 va_start (args, format);
2406 buffer = g_strdup_vprintf (format, args);
2412 * gst_element_error_full:
2413 * @element: a #GstElement with the error.
2414 * @domain: the GStreamer error domain this error belongs to.
2415 * @code: the error code belonging to the domain
2416 * @message: an allocated message to be used as a replacement for the default
2417 * message connected to code, or NULL
2418 * debug: an allocated debug message to be used as a replacement for the
2419 * default debugging information, or NULL
2421 * Signals an error condition on an element.
2422 * This function is used internally by elements.
2423 * It results in the "error" signal.
2425 void gst_element_error_full
2426 (GstElement * element, GQuark domain, gint code, gchar * message,
2427 gchar * debug, const gchar * file, const gchar * function, gint line)
2429 GError *error = NULL;
2431 gchar *sent_message;
2435 g_return_if_fail (GST_IS_ELEMENT (element));
2437 /* check if we send the given message or the default error message */
2438 if ((message == NULL) || (message[0] == 0)) {
2439 /* we got this message from g_strdup_printf (""); */
2441 sent_message = gst_error_get_message (domain, code);
2443 sent_message = message;
2445 if ((debug == NULL) || (debug[0] == 0)) {
2446 /* we got this debug from g_strdup_printf (""); */
2451 /* create error message */
2452 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signaling error in %s: %s",
2453 GST_ELEMENT_NAME (element), sent_message);
2454 error = g_error_new (domain, code, sent_message);
2456 /* if the element was already in error, stop now */
2457 if (GST_FLAG_IS_SET (element, GST_ELEMENT_IN_ERROR)) {
2458 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "recursive ERROR detected in %s",
2459 GST_ELEMENT_NAME (element));
2460 g_free (sent_message);
2466 GST_FLAG_SET (element, GST_ELEMENT_IN_ERROR);
2468 /* emit the signal, make sure the element stays available */
2469 gst_object_ref (GST_OBJECT (element));
2470 name = gst_object_get_path_string (GST_OBJECT (element));
2472 sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
2473 file, line, function, name, debug ? debug : "");
2478 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element,
2480 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signalled error in %s: %s",
2481 GST_ELEMENT_NAME (element), sent_message);
2483 /* tell the scheduler */
2484 if (element->sched) {
2485 gst_scheduler_error (element->sched, element);
2488 if (GST_STATE (element) == GST_STATE_PLAYING) {
2489 GstElementStateReturn ret;
2491 ret = gst_element_set_state (element, GST_STATE_PAUSED);
2492 if (ret != GST_STATE_SUCCESS) {
2493 g_warning ("could not PAUSE element \"%s\" after error, help!",
2494 GST_ELEMENT_NAME (element));
2498 GST_FLAG_UNSET (element, GST_ELEMENT_IN_ERROR);
2501 gst_object_unref (GST_OBJECT (element));
2502 g_free (sent_message);
2503 g_free (sent_debug);
2504 g_error_free (error);
2508 * gst_element_is_locked_state:
2509 * @element: a #GstElement.
2511 * Checks if the state of an element is locked.
2512 * If the state of an element is locked, state changes of the parent don't
2513 * affect the element.
2514 * This way you can leave currently unused elements inside bins. Just lock their
2515 * state before changing the state from #GST_STATE_NULL.
2517 * Returns: TRUE, if the element's state is locked.
2520 gst_element_is_locked_state (GstElement * element)
2522 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2524 return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
2528 * gst_element_set_locked_state:
2529 * @element: a #GstElement
2530 * @locked_state: TRUE to lock the element's state
2532 * Locks the state of an element, so state changes of the parent don't affect
2533 * this element anymore.
2536 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
2540 g_return_if_fail (GST_IS_ELEMENT (element));
2542 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2544 if (old == locked_state)
2548 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2549 GST_ELEMENT_NAME (element));
2550 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2552 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2553 GST_ELEMENT_NAME (element));
2554 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2559 * gst_element_sync_state_with_parent:
2560 * @element: a #GstElement.
2562 * Tries to change the state of the element to the same as its parent.
2563 * If this function returns FALSE, the state of element is undefined.
2565 * Returns: TRUE, if the element's state could be synced to the parent's state.
2568 gst_element_sync_state_with_parent (GstElement * element)
2572 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2573 parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
2574 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
2576 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
2577 GST_ELEMENT_NAME (element),
2578 gst_element_state_get_name (GST_STATE (element)),
2579 GST_ELEMENT_NAME (parent),
2580 gst_element_state_get_name (GST_STATE (parent)));
2581 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
2588 * gst_element_get_state:
2589 * @element: a #GstElement to get the state of.
2591 * Gets the state of the element.
2593 * Returns: the #GstElementState of the element.
2596 gst_element_get_state (GstElement * element)
2598 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2600 return GST_STATE (element);
2604 * gst_element_wait_state_change:
2605 * @element: a #GstElement to wait for a state change on.
2607 * Waits and blocks until the element changed its state.
2610 gst_element_wait_state_change (GstElement * element)
2612 g_mutex_lock (element->state_mutex);
2613 g_cond_wait (element->state_cond, element->state_mutex);
2614 g_mutex_unlock (element->state_mutex);
2618 * gst_element_set_state:
2619 * @element: a #GstElement to change state of.
2620 * @state: the element's new #GstElementState.
2622 * Sets the state of the element. This function will try to set the
2623 * requested state by going through all the intermediary states and calling
2624 * the class's state change function for each.
2626 * Returns: TRUE if the state was successfully set.
2627 * (using #GstElementStateReturn).
2629 GstElementStateReturn
2630 gst_element_set_state (GstElement * element, GstElementState state)
2632 GstElementClass *oclass;
2633 GstElementState curpending;
2634 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2636 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2638 /* start with the current state */
2639 curpending = GST_STATE (element);
2641 if (state == curpending) {
2642 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2643 "element is already in requested state %s",
2644 gst_element_state_get_name (state));
2645 return (GST_STATE_SUCCESS);
2648 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
2649 gst_element_state_get_name (curpending),
2650 gst_element_state_get_name (state));
2652 /* loop until the final requested state is set */
2653 while (GST_STATE (element) != state
2654 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2655 /* move the curpending state in the correct direction */
2656 if (curpending < state)
2661 /* set the pending state variable */
2662 /* FIXME: should probably check to see that we don't already have one */
2663 GST_STATE_PENDING (element) = curpending;
2665 if (curpending != state) {
2666 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2667 "intermediate: setting state from %s to %s",
2668 gst_element_state_get_name (GST_STATE (element)),
2669 gst_element_state_get_name (curpending));
2672 /* call the state change function so it can set the state */
2673 oclass = GST_ELEMENT_GET_CLASS (element);
2674 if (oclass->change_state)
2675 return_val = (oclass->change_state) (element);
2677 switch (return_val) {
2678 case GST_STATE_FAILURE:
2679 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2680 "have failed change_state return");
2682 case GST_STATE_ASYNC:
2683 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2684 "element will change state async");
2686 case GST_STATE_SUCCESS:
2687 /* Last thing we do is verify that a successful state change really
2688 * did change the state... */
2689 /* if it did not, this is an error - fix the element that does this */
2690 if (GST_STATE (element) != curpending) {
2691 g_warning ("element %s claimed state-change success,"
2692 "but state didn't change to %s. State is %s (%s pending), fix the element",
2693 GST_ELEMENT_NAME (element),
2694 gst_element_state_get_name (curpending),
2695 gst_element_state_get_name (GST_STATE (element)),
2696 gst_element_state_get_name (GST_STATE_PENDING (element)));
2697 return_val = GST_STATE_FAILURE;
2702 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2703 g_assert_not_reached ();
2712 gst_element_negotiate_pads (GstElement * element)
2714 GList *pads = GST_ELEMENT_PADS (element);
2716 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating pads");
2719 GstPad *pad = GST_PAD (pads->data);
2722 pads = g_list_next (pads);
2724 if (!GST_IS_REAL_PAD (pad))
2727 srcpad = GST_PAD_REALIZE (pad);
2729 /* if we have a link on this pad and it doesn't have caps
2730 * allready, try to negotiate */
2731 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2732 GstRealPad *sinkpad;
2733 GstElementState otherstate;
2736 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2738 /* check the parent of the peer pad, if there is no parent do nothing */
2739 parent = GST_PAD_PARENT (sinkpad);
2743 /* skips pads that were already negotiating */
2744 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2745 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2748 otherstate = GST_STATE (parent);
2750 /* swap pads if needed */
2751 if (!GST_PAD_IS_SRC (srcpad)) {
2759 /* only try to negotiate if the peer element is in PAUSED or higher too */
2760 if (otherstate >= GST_STATE_READY) {
2761 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2762 "perform negotiate for %s:%s and %s:%s",
2763 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2764 if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
2767 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2768 "not negotiating %s:%s and %s:%s, not in READY yet",
2769 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2778 gst_element_clear_pad_caps (GstElement * element)
2780 GList *pads = GST_ELEMENT_PADS (element);
2782 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "clearing pad caps");
2785 GstPad *pad = GST_PAD (pads->data);
2787 gst_pad_unnegotiate (pad);
2788 if (GST_IS_REAL_PAD (pad)) {
2789 gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
2792 pads = g_list_next (pads);
2797 gst_element_pads_activate (GstElement * element, gboolean active)
2799 GList *pads = element->pads;
2802 GstPad *pad = GST_PAD (pads->data);
2804 pads = g_list_next (pads);
2806 if (!GST_IS_REAL_PAD (pad))
2809 gst_pad_set_active (pad, active);
2813 static GstElementStateReturn
2814 gst_element_change_state (GstElement * element)
2816 GstElementState old_state;
2818 gint old_pending, old_transition;
2820 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2822 old_state = GST_STATE (element);
2823 old_pending = GST_STATE_PENDING (element);
2824 old_transition = GST_STATE_TRANSITION (element);
2826 if (old_pending == GST_STATE_VOID_PENDING ||
2827 old_state == GST_STATE_PENDING (element)) {
2828 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2829 "element is already in the %s state",
2830 gst_element_state_get_name (old_state));
2831 return GST_STATE_SUCCESS;
2834 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2835 "default handler sets state from %s to %s %04x",
2836 gst_element_state_get_name (old_state),
2837 gst_element_state_get_name (old_pending), old_transition);
2839 /* we set the state change early for the negotiation functions */
2840 GST_STATE (element) = old_pending;
2841 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2843 switch (old_transition) {
2844 case GST_STATE_PLAYING_TO_PAUSED:
2845 if (element->clock) {
2846 GstClockTime time = gst_clock_get_event_time (element->clock);
2848 g_assert (time >= element->base_time);
2849 element->base_time = time - element->base_time;
2850 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2851 G_GINT64_FORMAT, element->base_time);
2853 gst_element_pads_activate (element, FALSE);
2855 case GST_STATE_PAUSED_TO_PLAYING:
2856 gst_element_pads_activate (element, TRUE);
2857 if (element->clock) {
2858 GstClockTime time = gst_clock_get_event_time (element->clock);
2860 element->base_time = time - element->base_time;
2861 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2862 G_GINT64_FORMAT, element->base_time);
2865 /* if we are going to paused, we try to negotiate the pads */
2866 case GST_STATE_READY_TO_PAUSED:
2867 g_assert (element->base_time == 0);
2868 if (!gst_element_negotiate_pads (element))
2871 /* going to the READY state clears all pad caps */
2872 /* FIXME: Why doesn't this happen on READY => NULL? -- Company */
2873 case GST_STATE_PAUSED_TO_READY:
2874 element->base_time = 0;
2875 gst_element_clear_pad_caps (element);
2881 parent = GST_ELEMENT_PARENT (element);
2883 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2884 "signaling state change from %s to %s",
2885 gst_element_state_get_name (old_state),
2886 gst_element_state_get_name (GST_STATE (element)));
2888 /* tell the scheduler if we have one */
2889 if (element->sched) {
2890 if (gst_scheduler_state_transition (element->sched, element,
2891 old_transition) != GST_STATE_SUCCESS) {
2892 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2893 "scheduler could not change state");
2898 /* tell our parent about the state change */
2899 if (parent && GST_IS_BIN (parent)) {
2900 gst_bin_child_state_change (GST_BIN (parent), old_state,
2901 GST_STATE (element), element);
2903 /* at this point the state of the element could have changed again */
2905 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2906 0, old_state, GST_STATE (element));
2908 /* signal the state change in case somebody is waiting for us */
2909 g_mutex_lock (element->state_mutex);
2910 g_cond_signal (element->state_cond);
2911 g_mutex_unlock (element->state_mutex);
2913 return GST_STATE_SUCCESS;
2916 /* undo the state change */
2917 GST_STATE (element) = old_state;
2918 GST_STATE_PENDING (element) = old_pending;
2920 return GST_STATE_FAILURE;
2924 * gst_element_get_factory:
2925 * @element: a #GstElement to request the element factory of.
2927 * Retrieves the factory that was used to create this element.
2929 * Returns: the #GstElementFactory used for creating this element.
2932 gst_element_get_factory (GstElement * element)
2934 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2936 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2940 gst_element_dispose (GObject * object)
2942 GstElement *element = GST_ELEMENT (object);
2946 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2948 gst_element_set_state (element, GST_STATE_NULL);
2950 /* first we break all our links with the ouside */
2951 if (element->pads) {
2954 orig = pads = g_list_copy (element->pads);
2956 pad = GST_PAD (pads->data);
2958 if (GST_PAD_PEER (pad)) {
2959 GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "unlinking pad '%s'",
2960 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2961 gst_pad_unlink (pad, GST_PAD (GST_PAD_PEER (pad)));
2963 gst_element_remove_pad (element, pad);
2965 pads = g_list_next (pads);
2968 g_list_free (element->pads);
2969 element->pads = NULL;
2972 element->numsrcpads = 0;
2973 element->numsinkpads = 0;
2974 element->numpads = 0;
2975 if (element->state_mutex)
2976 g_mutex_free (element->state_mutex);
2977 element->state_mutex = NULL;
2978 if (element->state_cond)
2979 g_cond_free (element->state_cond);
2980 element->state_cond = NULL;
2982 if (element->prop_value_queue)
2983 g_async_queue_unref (element->prop_value_queue);
2984 element->prop_value_queue = NULL;
2985 if (element->property_mutex)
2986 g_mutex_free (element->property_mutex);
2987 element->property_mutex = NULL;
2989 gst_object_replace ((GstObject **) & element->sched, NULL);
2990 gst_object_replace ((GstObject **) & element->clock, NULL);
2992 G_OBJECT_CLASS (parent_class)->dispose (object);
2995 #ifndef GST_DISABLE_LOADSAVE
2997 * gst_element_save_thyself:
2998 * @element: a #GstElement to save.
2999 * @parent: the xml parent node.
3001 * Saves the element as part of the given XML structure.
3003 * Returns: the new #xmlNodePtr.
3006 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
3009 GstElementClass *oclass;
3010 GParamSpec **specs, *spec;
3012 GValue value = { 0, };
3013 GstElement *element;
3015 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
3017 element = GST_ELEMENT (object);
3019 oclass = GST_ELEMENT_GET_CLASS (element);
3021 xmlNewChild (parent, NULL, "name", GST_ELEMENT_NAME (element));
3023 if (oclass->elementfactory != NULL) {
3024 GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
3026 xmlNewChild (parent, NULL, "type", GST_PLUGIN_FEATURE (factory)->name);
3029 /* FIXME: what is this? */
3030 /* if (element->manager) */
3031 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
3034 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
3036 for (i = 0; i < nspecs; i++) {
3038 if (spec->flags & G_PARAM_READABLE) {
3042 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
3044 g_object_get_property (G_OBJECT (element), spec->name, &value);
3045 param = xmlNewChild (parent, NULL, "param", NULL);
3046 xmlNewChild (param, NULL, "name", spec->name);
3048 if (G_IS_PARAM_SPEC_STRING (spec))
3049 contents = g_value_dup_string (&value);
3050 else if (G_IS_PARAM_SPEC_ENUM (spec))
3051 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
3052 else if (G_IS_PARAM_SPEC_INT64 (spec))
3053 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
3054 g_value_get_int64 (&value));
3056 contents = g_strdup_value_contents (&value);
3058 xmlNewChild (param, NULL, "value", contents);
3061 g_value_unset (&value);
3065 pads = GST_ELEMENT_PADS (element);
3068 GstPad *pad = GST_PAD (pads->data);
3070 /* figure out if it's a direct pad or a ghostpad */
3071 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
3072 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
3074 gst_object_save_thyself (GST_OBJECT (pad), padtag);
3076 pads = g_list_next (pads);
3083 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
3085 xmlNodePtr children;
3086 GstElement *element;
3088 gchar *value = NULL;
3090 element = GST_ELEMENT (object);
3091 g_return_if_fail (element != NULL);
3094 children = self->xmlChildrenNode;
3096 if (!strcmp (children->name, "param")) {
3097 xmlNodePtr child = children->xmlChildrenNode;
3100 if (!strcmp (child->name, "name")) {
3101 name = xmlNodeGetContent (child);
3102 } else if (!strcmp (child->name, "value")) {
3103 value = xmlNodeGetContent (child);
3105 child = child->next;
3107 /* FIXME: can this just be g_object_set ? */
3108 gst_util_set_object_arg (G_OBJECT (element), name, value);
3109 /* g_object_set (G_OBJECT (element), name, value, NULL); */
3111 children = children->next;
3115 children = self->xmlChildrenNode;
3117 if (!strcmp (children->name, "pad")) {
3118 gst_pad_load_and_link (children, GST_OBJECT (element));
3120 children = children->next;
3123 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3124 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3126 #endif /* GST_DISABLE_LOADSAVE */
3129 * gst_element_yield:
3130 * @element: a #GstElement to yield.
3132 * Requests a yield operation for the element. The scheduler will typically
3133 * give control to another element.
3136 gst_element_yield (GstElement * element)
3138 if (GST_ELEMENT_SCHED (element)) {
3139 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
3144 * gst_element_interrupt:
3145 * @element: a #GstElement to interrupt.
3147 * Requests the scheduler of this element to interrupt the execution of
3148 * this element and scheduler another one.
3150 * Returns: TRUE if the element should exit its chain/loop/get
3151 * function ASAP, depending on the scheduler implementation.
3154 gst_element_interrupt (GstElement * element)
3156 if (GST_ELEMENT_SCHED (element)) {
3157 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
3163 * gst_element_set_scheduler:
3164 * @element: a #GstElement to set the scheduler of.
3165 * @sched: the #GstScheduler to set.
3167 * Sets the scheduler of the element. For internal use only, unless you're
3168 * writing a new bin subclass.
3171 gst_element_set_scheduler (GstElement * element, GstScheduler * sched)
3173 g_return_if_fail (GST_IS_ELEMENT (element));
3175 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",
3178 gst_object_replace ((GstObject **) & GST_ELEMENT_SCHED (element),
3179 GST_OBJECT (sched));
3183 * gst_element_get_scheduler:
3184 * @element: a #GstElement to get the scheduler of.
3186 * Returns the scheduler of the element.
3188 * Returns: the element's #GstScheduler.
3191 gst_element_get_scheduler (GstElement * element)
3193 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3195 return GST_ELEMENT_SCHED (element);
3199 * gst_element_set_loop_function:
3200 * @element: a #GstElement to set the loop function of.
3201 * @loop: Pointer to #GstElementLoopFunction.
3203 * This sets the loop function for the element. The function pointed to
3204 * can deviate from the GstElementLoopFunction definition in type of
3207 * NOTE: in order for this to take effect, the current loop function *must*
3208 * exit. Assuming the loop function itself is the only one who will cause
3209 * a new loopfunc to be assigned, this should be no problem.
3212 gst_element_set_loop_function (GstElement * element,
3213 GstElementLoopFunction loop)
3215 gboolean need_notify = FALSE;
3217 g_return_if_fail (GST_IS_ELEMENT (element));
3219 /* if the element changed from loop based to chain/get based
3220 * or vice versa, we need to inform the scheduler about that */
3221 if ((element->loopfunc == NULL && loop != NULL) ||
3222 (element->loopfunc != NULL && loop == NULL)) {
3226 /* set the loop function */
3227 element->loopfunc = loop;
3230 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
3231 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
3233 if (GST_ELEMENT_SCHED (element)) {
3234 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
3239 gst_element_emit_found_tag (GstElement * element, GstElement * source,
3240 const GstTagList * tag_list)
3242 gst_object_ref (GST_OBJECT (element));
3243 g_signal_emit (element, gst_element_signals[FOUND_TAG], 0, source, tag_list);
3244 gst_object_unref (GST_OBJECT (element));
3247 gst_element_found_tag_func (GstElement * element, GstElement * source,
3248 const GstTagList * tag_list)
3250 /* tell the parent */
3251 if (GST_OBJECT_PARENT (element)) {
3252 GST_CAT_LOG_OBJECT (GST_CAT_EVENT, element, "forwarding tag event to %s",
3253 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
3254 gst_element_emit_found_tag (GST_ELEMENT (GST_OBJECT_PARENT (element)),
3260 * gst_element_found_tags:
3261 * @element: the element that found the tags
3262 * @tag_list: the found tags
3264 * This function emits the found_tags signal. This is a recursive signal, so
3265 * every parent will emit that signal, too, before this function returns.
3266 * Only emit this signal, when you extracted these tags out of the data stream,
3267 * not when you handle an event.
3270 gst_element_found_tags (GstElement * element, const GstTagList * tag_list)
3272 gst_element_emit_found_tag (element, element, tag_list);
3276 * gst_element_found_tags_for_pad:
3277 * @element: element that found the tag
3278 * @pad: src pad the tags correspond to
3279 * @timestamp: time the tags were found
3280 * @list: the taglist
3282 * This is a convenience routine for tag finding. Most of the time you only
3283 * want to push the found tags down one pad, in that case this function is for
3284 * you. It takes ownership of the taglist, emits the found-tag signal and pushes
3285 * a tag event down the pad.
3286 * <note>This function may not be used in a #GstPadGetFunction, because it calls
3287 * gst_pad_push(). In those functions, call gst_element_found_tags(), create a
3288 * tag event with gst_event_new_tag() and return that from your
3289 * #GstPadGetFunction.</note>
3292 gst_element_found_tags_for_pad (GstElement * element, GstPad * pad,
3293 GstClockTime timestamp, GstTagList * list)
3295 GstEvent *tag_event;
3297 g_return_if_fail (GST_IS_ELEMENT (element));
3298 g_return_if_fail (GST_IS_REAL_PAD (pad));
3299 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
3300 g_return_if_fail (element == GST_PAD_PARENT (pad));
3301 g_return_if_fail (list != NULL);
3303 tag_event = gst_event_new_tag (list);
3304 GST_EVENT_TIMESTAMP (tag_event) = timestamp;
3305 gst_element_found_tags (element, gst_event_tag_get_list (tag_event));
3306 if (GST_PAD_IS_USABLE (pad)) {
3307 gst_pad_push (pad, GST_DATA (tag_event));
3309 gst_data_unref (GST_DATA (tag_event));
3314 gst_element_set_eos_recursive (GstElement * element)
3316 /* this function is only called, when we were in PLAYING before. So every
3317 parent that's PAUSED was PLAYING before. That means it has reached EOS. */
3320 GST_CAT_DEBUG (GST_CAT_EVENT, "setting recursive EOS on %s",
3321 GST_OBJECT_NAME (element));
3322 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3324 if (!GST_OBJECT_PARENT (element))
3327 parent = GST_ELEMENT (GST_OBJECT_PARENT (element));
3328 if (GST_STATE (parent) == GST_STATE_PAUSED)
3329 gst_element_set_eos_recursive (parent);
3333 * gst_element_set_eos:
3334 * @element: a #GstElement to set to the EOS state.
3336 * Perform the actions needed to bring the element in the EOS state.
3339 gst_element_set_eos (GstElement * element)
3341 g_return_if_fail (GST_IS_ELEMENT (element));
3343 GST_CAT_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
3344 GST_OBJECT_NAME (element));
3346 if (GST_STATE (element) == GST_STATE_PLAYING) {
3347 gst_element_set_state (element, GST_STATE_PAUSED);
3348 gst_element_set_eos_recursive (element);
3350 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3356 * gst_element_state_get_name:
3357 * @state: a #GstElementState to get the name of.
3359 * Gets a string representing the given state.
3361 * Returns: a string with the name of the state.
3364 gst_element_state_get_name (GstElementState state)
3367 #ifdef GST_DEBUG_COLOR
3368 case GST_STATE_VOID_PENDING:
3369 return "NONE_PENDING";
3371 case GST_STATE_NULL:
3372 return "\033[01;34mNULL\033[00m";
3374 case GST_STATE_READY:
3375 return "\033[01;31mREADY\033[00m";
3377 case GST_STATE_PLAYING:
3378 return "\033[01;32mPLAYING\033[00m";
3380 case GST_STATE_PAUSED:
3381 return "\033[01;33mPAUSED\033[00m";
3384 /* This is a memory leak */
3385 return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
3387 case GST_STATE_VOID_PENDING:
3388 return "NONE_PENDING";
3390 case GST_STATE_NULL:
3393 case GST_STATE_READY:
3396 case GST_STATE_PLAYING:
3399 case GST_STATE_PAUSED:
3410 gst_element_populate_std_props (GObjectClass * klass, const gchar * prop_name,
3411 guint arg_id, GParamFlags flags)
3413 GQuark prop_id = g_quark_from_string (prop_name);
3416 static GQuark fd_id = 0;
3417 static GQuark blocksize_id;
3418 static GQuark bytesperread_id;
3419 static GQuark dump_id;
3420 static GQuark filesize_id;
3421 static GQuark mmapsize_id;
3422 static GQuark location_id;
3423 static GQuark offset_id;
3424 static GQuark silent_id;
3425 static GQuark touch_id;
3428 fd_id = g_quark_from_static_string ("fd");
3429 blocksize_id = g_quark_from_static_string ("blocksize");
3430 bytesperread_id = g_quark_from_static_string ("bytesperread");
3431 dump_id = g_quark_from_static_string ("dump");
3432 filesize_id = g_quark_from_static_string ("filesize");
3433 mmapsize_id = g_quark_from_static_string ("mmapsize");
3434 location_id = g_quark_from_static_string ("location");
3435 offset_id = g_quark_from_static_string ("offset");
3436 silent_id = g_quark_from_static_string ("silent");
3437 touch_id = g_quark_from_static_string ("touch");
3440 if (prop_id == fd_id) {
3441 pspec = g_param_spec_int ("fd", "File-descriptor",
3442 "File-descriptor for the file being read", 0, G_MAXINT, 0, flags);
3443 } else if (prop_id == blocksize_id) {
3444 pspec = g_param_spec_ulong ("blocksize", "Block Size",
3445 "Block size to read per buffer", 0, G_MAXULONG, 4096, flags);
3447 } else if (prop_id == bytesperread_id) {
3448 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
3449 "Number of bytes to read per buffer", G_MININT, G_MAXINT, 0, flags);
3451 } else if (prop_id == dump_id) {
3452 pspec = g_param_spec_boolean ("dump", "Dump",
3453 "Dump bytes to stdout", FALSE, flags);
3455 } else if (prop_id == filesize_id) {
3456 pspec = g_param_spec_int64 ("filesize", "File Size",
3457 "Size of the file being read", 0, G_MAXINT64, 0, flags);
3459 } else if (prop_id == mmapsize_id) {
3460 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
3461 "Size in bytes of mmap()d regions", 0, G_MAXULONG, 4 * 1048576, flags);
3463 } else if (prop_id == location_id) {
3464 pspec = g_param_spec_string ("location", "File Location",
3465 "Location of the file to read", NULL, flags);
3467 } else if (prop_id == offset_id) {
3468 pspec = g_param_spec_int64 ("offset", "File Offset",
3469 "Byte offset of current read pointer", 0, G_MAXINT64, 0, flags);
3471 } else if (prop_id == silent_id) {
3472 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
3475 } else if (prop_id == touch_id) {
3476 pspec = g_param_spec_boolean ("touch", "Touch read data",
3477 "Touch data to force disk read before " "push ()", TRUE, flags);
3479 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
3480 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
3485 g_object_class_install_property (klass, arg_id, pspec);
3490 * gst_element_class_install_std_props:
3491 * @klass: the #GstElementClass to add the properties to.
3492 * @first_name: the name of the first property.
3493 * in a NULL terminated
3494 * @...: the id and flags of the first property, followed by
3495 * further 'name', 'id', 'flags' triplets and terminated by NULL.
3497 * Adds a list of standardized properties with types to the @klass.
3498 * the id is for the property switch in your get_prop method, and
3499 * the flags determine readability / writeability.
3502 gst_element_class_install_std_props (GstElementClass * klass,
3503 const gchar * first_name, ...)
3509 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
3511 va_start (args, first_name);
3516 int arg_id = va_arg (args, int);
3517 int flags = va_arg (args, int);
3519 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id,
3522 name = va_arg (args, char *);
3529 * gst_element_get_managing_bin:
3530 * @element: a #GstElement to get the managing bin of.
3532 * Gets the managing bin (a pipeline or a thread, for example) of an element.
3534 * Returns: the #GstBin, or NULL on failure.
3537 gst_element_get_managing_bin (GstElement * element)
3541 g_return_val_if_fail (element != NULL, NULL);
3543 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (element)));
3545 while (bin && !GST_FLAG_IS_SET (GST_OBJECT (bin), GST_BIN_FLAG_MANAGER))
3546 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (bin)));