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"
31 #include "gstscheduler.h"
35 #include "gst-i18n-lib.h"
37 /* Element signals and args */
54 extern void __gst_element_details_clear (GstElementDetails *dp);
55 extern void __gst_element_details_set (GstElementDetails *dest,
56 const GstElementDetails *src);
58 static void gst_element_class_init (GstElementClass *klass);
59 static void gst_element_init (GstElement *element);
60 static void gst_element_base_class_init (gpointer g_class);
61 static void gst_element_base_class_finalize (gpointer g_class);
63 static void gst_element_real_set_property (GObject *object, guint prop_id,
64 const GValue *value, GParamSpec *pspec);
65 static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value,
68 static void gst_element_dispose (GObject *object);
70 static GstElementStateReturn gst_element_change_state (GstElement *element);
71 static void gst_element_error_func (GstElement* element, GstElement *source, GError *error, gchar *debug);
72 static void gst_element_found_tag_func (GstElement* element, GstElement *source, const GstTagList *tag_list);
74 #ifndef GST_DISABLE_LOADSAVE
75 static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent);
76 static void gst_element_restore_thyself (GstObject *parent, xmlNodePtr self);
79 GType _gst_element_type = 0;
81 static GstObjectClass *parent_class = NULL;
82 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
84 GType gst_element_get_type (void)
86 if (!_gst_element_type) {
87 static const GTypeInfo element_info = {
88 sizeof(GstElementClass),
89 gst_element_base_class_init,
90 gst_element_base_class_finalize,
91 (GClassInitFunc)gst_element_class_init,
96 (GInstanceInitFunc)gst_element_init,
99 _gst_element_type = g_type_register_static(GST_TYPE_OBJECT, "GstElement",
100 &element_info, G_TYPE_FLAG_ABSTRACT);
102 return _gst_element_type;
106 gst_element_class_init (GstElementClass *klass)
108 GObjectClass *gobject_class;
109 GstObjectClass *gstobject_class;
111 gobject_class = (GObjectClass*) klass;
112 gstobject_class = (GstObjectClass*) klass;
114 parent_class = g_type_class_ref(GST_TYPE_OBJECT);
116 gst_element_signals[STATE_CHANGE] =
117 g_signal_new ("state_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
118 G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL,
119 gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
120 G_TYPE_INT, G_TYPE_INT);
121 gst_element_signals[NEW_PAD] =
122 g_signal_new ("new_pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
123 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
124 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
126 gst_element_signals[PAD_REMOVED] =
127 g_signal_new ("pad_removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
128 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
129 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
131 gst_element_signals[ERROR] =
132 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
133 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
134 gst_marshal_VOID__OBJECT_POINTER_STRING, G_TYPE_NONE, 3,
135 GST_TYPE_ELEMENT, G_TYPE_POINTER, G_TYPE_STRING);
136 gst_element_signals[EOS] =
137 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
138 G_STRUCT_OFFSET (GstElementClass, eos), NULL, NULL,
139 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
140 gst_element_signals[FOUND_TAG] =
141 g_signal_new ("found-tag", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
142 G_STRUCT_OFFSET (GstElementClass, found_tag), NULL, NULL,
143 gst_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
144 GST_TYPE_ELEMENT, G_TYPE_POINTER);
146 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property);
147 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_property);
149 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
151 #ifndef GST_DISABLE_LOADSAVE
152 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
153 gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
156 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
157 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
158 klass->found_tag = GST_DEBUG_FUNCPTR (gst_element_found_tag_func);
159 klass->numpadtemplates = 0;
161 klass->elementfactory = NULL;
165 gst_element_base_class_init (gpointer g_class)
167 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
168 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
171 gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_element_real_set_property);
172 gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_element_real_get_property);
174 element_class->padtemplates = NULL;
178 gst_element_base_class_finalize (gpointer g_class)
180 GstElementClass *klass = GST_ELEMENT_CLASS (klass);
182 g_list_foreach (klass->padtemplates, (GFunc) g_object_unref, NULL);
183 g_list_free (klass->padtemplates);
184 __gst_element_details_clear (&klass->details);
188 gst_element_init (GstElement *element)
190 element->current_state = GST_STATE_NULL;
191 element->pending_state = GST_STATE_VOID_PENDING;
192 element->numpads = 0;
193 element->numsrcpads = 0;
194 element->numsinkpads = 0;
195 element->pads = NULL;
196 element->loopfunc = NULL;
197 element->sched = NULL;
198 element->clock = NULL;
199 element->sched_private = NULL;
200 element->state_mutex = g_mutex_new ();
201 element->state_cond = g_cond_new ();
205 gst_element_real_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
207 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
209 if (oclass->set_property)
210 (oclass->set_property) (object, prop_id, value, pspec);
214 gst_element_real_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
216 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
218 if (oclass->get_property)
219 (oclass->get_property) (object, prop_id, value, pspec);
223 * gst_element_default_error:
224 * @object: a #GObject that signalled the error.
225 * @orig: the #GstObject that initiated the error.
226 * @error: the GError.
227 * @debug: an additional debug information string, or NULL.
229 * A default error signal callback to attach to an element.
230 * The user data passed to the g_signal_connect is ignored.
232 * The default handler will simply print the error string using g_print.
235 gst_element_default_error (GObject *object, GstObject *source, GError *error, gchar *debug)
237 gchar *name = gst_object_get_path_string (source);
239 g_print (_("ERROR: from element %s: %s.\n"), name, error->message);
241 g_print (_("Additional debug info:\n%s\n"), debug);
247 const GParamSpec *pspec;
252 element_set_property (GstElement *element, const GParamSpec *pspec, const GValue *value)
254 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
256 prop_value->pspec = pspec;
257 prop_value->value = *value;
259 g_async_queue_push (element->prop_value_queue, prop_value);
263 element_get_property (GstElement *element, const GParamSpec *pspec, GValue *value)
265 g_mutex_lock (element->property_mutex);
266 g_object_get_property ((GObject*)element, pspec->name, value);
267 g_mutex_unlock (element->property_mutex);
271 gst_element_threadsafe_properties_pre_run (GstElement *element)
273 GST_DEBUG ("locking element %s", GST_OBJECT_NAME (element));
274 g_mutex_lock (element->property_mutex);
275 gst_element_set_pending_properties (element);
279 gst_element_threadsafe_properties_post_run (GstElement *element)
281 GST_DEBUG ("unlocking element %s", GST_OBJECT_NAME (element));
282 g_mutex_unlock (element->property_mutex);
286 * gst_element_enable_threadsafe_properties:
287 * @element: a #GstElement to enable threadsafe properties on.
289 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
290 * this element so that properties on the element can be set in a
294 gst_element_enable_threadsafe_properties (GstElement *element)
296 g_return_if_fail (GST_IS_ELEMENT (element));
298 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
299 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
300 element->post_run_func = gst_element_threadsafe_properties_post_run;
301 if (!element->prop_value_queue)
302 element->prop_value_queue = g_async_queue_new ();
303 if (!element->property_mutex)
304 element->property_mutex = g_mutex_new ();
308 * gst_element_disable_threadsafe_properties:
309 * @element: a #GstElement to disable threadsafe properties on.
311 * Removes the threadsafe properties, post- and pre-run locks from
315 gst_element_disable_threadsafe_properties (GstElement *element)
317 g_return_if_fail (GST_IS_ELEMENT (element));
319 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
320 element->pre_run_func = NULL;
321 element->post_run_func = NULL;
322 /* let's keep around that async queue */
326 * gst_element_set_pending_properties:
327 * @element: a #GstElement to set the pending properties on.
329 * Sets all pending properties on the threadsafe properties enabled
333 gst_element_set_pending_properties (GstElement *element)
335 prop_value_t *prop_value;
337 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
338 g_object_set_property ((GObject*)element, prop_value->pspec->name, &prop_value->value);
339 g_value_unset (&prop_value->value);
344 /* following 6 functions taken mostly from gobject.c */
348 * @element: a #GstElement to set properties on.
349 * @first_property_name: the first property to set.
350 * @...: value of the first property, and more properties to set, ending
353 * Sets properties on an element. If the element uses threadsafe properties,
354 * they will be queued and set on the object when it is scheduled again.
357 gst_element_set (GstElement *element, const gchar *first_property_name, ...)
361 g_return_if_fail (GST_IS_ELEMENT (element));
363 va_start (var_args, first_property_name);
364 gst_element_set_valist (element, first_property_name, var_args);
370 * @element: a #GstElement to get properties of.
371 * @first_property_name: the first property to get.
372 * @...: pointer to a variable to store the first property in, as well as
373 * more properties to get, ending with NULL.
375 * Gets properties from an element. If the element uses threadsafe properties,
376 * the element will be locked before getting the given properties.
379 gst_element_get (GstElement *element, const gchar *first_property_name, ...)
383 g_return_if_fail (GST_IS_ELEMENT (element));
385 va_start (var_args, first_property_name);
386 gst_element_get_valist (element, first_property_name, var_args);
391 * gst_element_set_valist:
392 * @element: a #GstElement to set properties on.
393 * @first_property_name: the first property to set.
394 * @var_args: the var_args list of other properties to get.
396 * Sets properties on an element. If the element uses threadsafe properties,
397 * the property change will be put on the async queue.
400 gst_element_set_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
405 g_return_if_fail (GST_IS_ELEMENT (element));
407 object = (GObject *) element;
409 GST_CAT_DEBUG (GST_CAT_PROPERTIES,
410 "setting valist of properties starting with %s on element %s",
411 first_property_name, gst_element_get_name (element));
413 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
414 g_object_set_valist (object, first_property_name, var_args);
418 g_object_ref (object);
420 name = first_property_name;
424 GValue value = { 0, };
428 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
432 g_warning ("%s: object class `%s' has no property named `%s'",
434 G_OBJECT_TYPE_NAME (object),
438 if (!(pspec->flags & G_PARAM_WRITABLE))
440 g_warning ("%s: property `%s' of object class `%s' is not writable",
443 G_OBJECT_TYPE_NAME (object));
447 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
449 G_VALUE_COLLECT (&value, var_args, 0, &error);
452 g_warning ("%s: %s", G_STRLOC, error);
455 /* we purposely leak the value here, it might not be
456 * in a sane state if an error condition occoured
461 element_set_property (element, pspec, &value);
462 g_value_unset (&value);
464 name = va_arg (var_args, gchar*);
467 g_object_unref (object);
471 * gst_element_get_valist:
472 * @element: a #GstElement to get properties of.
473 * @first_property_name: the first property to get.
474 * @var_args: the var_args list of other properties to get.
476 * Gets properties from an element. If the element uses threadsafe properties,
477 * the element will be locked before getting the given properties.
480 gst_element_get_valist (GstElement *element, const gchar *first_property_name, va_list var_args)
485 g_return_if_fail (GST_IS_ELEMENT (element));
487 object = (GObject*)element;
489 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
490 g_object_get_valist (object, first_property_name, var_args);
494 g_object_ref (object);
496 name = first_property_name;
500 GValue value = { 0, };
504 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
508 g_warning ("%s: object class `%s' has no property named `%s'",
510 G_OBJECT_TYPE_NAME (object),
514 if (!(pspec->flags & G_PARAM_READABLE))
516 g_warning ("%s: property `%s' of object class `%s' is not readable",
519 G_OBJECT_TYPE_NAME (object));
523 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
525 element_get_property (element, pspec, &value);
527 G_VALUE_LCOPY (&value, var_args, 0, &error);
530 g_warning ("%s: %s", G_STRLOC, error);
532 g_value_unset (&value);
536 g_value_unset (&value);
538 name = va_arg (var_args, gchar*);
541 g_object_unref (object);
545 * gst_element_set_property:
546 * @element: a #GstElement to set properties on.
547 * @property_name: the first property to get.
548 * @value: the #GValue that holds the value to set.
550 * Sets a property on an element. If the element uses threadsafe properties,
551 * the property will be put on the async queue.
554 gst_element_set_property (GstElement *element, const gchar *property_name,
560 g_return_if_fail (GST_IS_ELEMENT (element));
561 g_return_if_fail (property_name != NULL);
562 g_return_if_fail (G_IS_VALUE (value));
564 object = (GObject*) element;
566 GST_CAT_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
567 property_name, gst_element_get_name (element));
568 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
569 g_object_set_property (object, property_name, value);
573 g_object_ref (object);
575 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
579 g_warning ("%s: object class `%s' has no property named `%s'",
581 G_OBJECT_TYPE_NAME (object),
584 element_set_property (element, pspec, value);
586 g_object_unref (object);
590 * gst_element_get_property:
591 * @element: a #GstElement to get properties of.
592 * @property_name: the first property to get.
593 * @value: the #GValue to store the property value in.
595 * Gets a property from an element. If the element uses threadsafe properties,
596 * the element will be locked before getting the given property.
599 gst_element_get_property (GstElement *element, const gchar *property_name, GValue *value)
604 g_return_if_fail (GST_IS_ELEMENT (element));
605 g_return_if_fail (property_name != NULL);
606 g_return_if_fail (G_IS_VALUE (value));
608 object = (GObject*)element;
610 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
611 g_object_get_property (object, property_name, value);
615 g_object_ref (object);
617 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
620 g_warning ("%s: object class `%s' has no property named `%s'",
622 G_OBJECT_TYPE_NAME (object),
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))
632 g_value_reset (value);
635 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
637 g_warning ("can't retrieve property `%s' of type `%s' as value of type `%s'",
639 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
640 G_VALUE_TYPE_NAME (value));
641 g_object_unref (object);
646 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
647 prop_value = &tmp_value;
649 element_get_property (element, pspec, prop_value);
650 if (prop_value != value)
652 g_value_transform (prop_value, value);
653 g_value_unset (&tmp_value);
657 g_object_unref (object);
661 gst_element_request_pad (GstElement *element, GstPadTemplate *templ, const gchar* name)
663 GstPad *newpad = NULL;
664 GstElementClass *oclass;
666 oclass = GST_ELEMENT_GET_CLASS (element);
668 if (oclass->request_new_pad)
669 newpad = (oclass->request_new_pad)(element, templ, name);
675 * gst_element_release_request_pad:
676 * @element: a #GstElement to release the request pad of.
677 * @pad: the #GstPad to release.
679 * Makes the element free the previously requested pad as obtained
680 * with gst_element_get_request_pad().
683 gst_element_release_request_pad (GstElement *element, GstPad *pad)
685 GstElementClass *oclass;
687 g_return_if_fail (GST_IS_ELEMENT (element));
688 g_return_if_fail (GST_IS_PAD (pad));
690 oclass = GST_ELEMENT_GET_CLASS (element);
692 if (oclass->release_pad)
693 (oclass->release_pad) (element, pad);
697 * gst_element_requires_clock:
698 * @element: a #GstElement to query
700 * Query if the element requiresd a clock
702 * Returns: TRUE if the element requires a clock
705 gst_element_requires_clock (GstElement *element)
707 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
709 return (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
713 * gst_element_provides_clock:
714 * @element: a #GstElement to query
716 * Query if the element provides a clock
718 * Returns: TRUE if the element provides a clock
721 gst_element_provides_clock (GstElement *element)
723 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
725 return (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
729 * gst_element_set_clock:
730 * @element: a #GstElement to set the clock for.
731 * @clock: the #GstClock to set for the element.
733 * Sets the clock for the element.
736 gst_element_set_clock (GstElement *element, GstClock *clock)
738 GstElementClass *oclass;
740 g_return_if_fail (GST_IS_ELEMENT (element));
742 oclass = GST_ELEMENT_GET_CLASS (element);
744 if (oclass->set_clock)
745 oclass->set_clock (element, clock);
747 gst_object_replace ((GstObject **)&element->clock, (GstObject *)clock);
751 * gst_element_get_clock:
752 * @element: a #GstElement to get the clock of.
754 * Gets the clock of the element.
756 * Returns: the #GstClock of the element.
759 gst_element_get_clock (GstElement *element)
761 GstElementClass *oclass;
763 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
765 oclass = GST_ELEMENT_GET_CLASS (element);
767 if (oclass->get_clock)
768 return oclass->get_clock (element);
774 * gst_element_clock_wait:
775 * @element: a #GstElement.
776 * @id: the #GstClock to use.
777 * @jitter: the difference between requested time and actual time.
779 * Waits for a specific time on the clock.
781 * Returns: the #GstClockReturn result of the wait operation.
784 gst_element_clock_wait (GstElement *element, GstClockID id, GstClockTimeDiff *jitter)
788 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
790 if (GST_ELEMENT_SCHED (element)) {
791 GST_CAT_DEBUG (GST_CAT_CLOCK, "waiting on scheduler clock");
792 res = gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id, jitter);
795 GST_CAT_DEBUG (GST_CAT_CLOCK, "no scheduler, returning GST_CLOCK_TIMEOUT");
796 res = GST_CLOCK_TIMEOUT;
801 #undef GST_CAT_DEFAULT
802 #define GST_CAT_DEFAULT GST_CAT_CLOCK
804 * gst_element_get_time:
805 * @element: element to query
807 * Query the element's time. The element must use
809 * Returns: the current time of the element or #GST_CLOCK_TIME_NONE when there
810 * is no time available.
813 gst_element_get_time (GstElement *element)
815 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
817 if (element->clock == NULL) {
818 GST_WARNING_OBJECT (element, "element queries time but has no clock");
819 return GST_CLOCK_TIME_NONE;
821 switch (element->current_state) {
823 case GST_STATE_READY:
824 return GST_CLOCK_TIME_NONE;
825 case GST_STATE_PAUSED:
826 return element->base_time;
827 case GST_STATE_PLAYING:
828 return gst_clock_get_time (element->clock) - element->base_time;
830 g_assert_not_reached ();
831 return GST_CLOCK_TIME_NONE;
835 GstClockID gst_clock_new_single_shot_id (GstClock *clock,
837 void gst_clock_id_free (GstClockID id);
840 * @element: element that should wait
841 * @timestamp: wait until this time has arrived
843 * Waits until the given time has arrived. When this function returns successfully,
844 * the time specified in the timestamp has passed.
845 * <note>This function can only be called on elements in #GST_STATE_PLAYING</note>
847 * Returns: TRUE on success
850 gst_element_wait (GstElement *element, GstClockTime timestamp)
855 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
856 g_return_val_if_fail (GST_IS_CLOCK (element->clock), FALSE);
857 g_return_val_if_fail (element->current_state == GST_STATE_PLAYING, FALSE);
858 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
860 /* shortcut when we're already late... */
861 if (gst_element_get_time (element) >= timestamp) {
862 GST_INFO_OBJECT (element, "called gst_element_wait and was late");
866 id = gst_clock_new_single_shot_id (element->clock, element->base_time + timestamp);
867 ret = gst_element_clock_wait (element, id, NULL);
868 gst_clock_id_free (id);
870 return ret == GST_CLOCK_STOPPED;
874 * gst_element_set_time:
875 * @element: element to set time on
878 * Sets the current time of the element. This function can be used when handling
879 * discont events. You can only call this function on an element with a clock in
880 * #GST_STATE_PAUSED or #GST_STATE_PLAYING. You might want to have a look at
881 * gst_element_adjust_time(), if you want to adjust by a difference as that is
885 gst_element_set_time (GstElement *element, GstClockTime time)
887 GstClockTime event_time;
889 g_return_if_fail (GST_IS_ELEMENT (element));
890 g_return_if_fail (GST_IS_CLOCK (element->clock));
891 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
893 switch (element->current_state) {
894 case GST_STATE_PAUSED:
895 element->base_time = time;
897 case GST_STATE_PLAYING:
898 event_time = gst_clock_get_event_time (element->clock);
899 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element,
900 "clock time %llu: setting element time to %llu", event_time, time);
901 element->base_time = event_time - time;
904 g_assert_not_reached ();
910 * gst_element_adjust_time:
911 * @element: element to adjust time on
912 * @difference: difference to adjust
914 * Adjusts the current time of the element by the specified difference. This
915 * function can be used when handling discont events. You can only call this
916 * function on an element with a clock in #GST_STATE_PAUSED or
917 * #GST_STATE_PLAYING. It is more accurate than gst_element_set_time().
920 gst_element_adjust_time (GstElement *element, GstClockTimeDiff diff)
924 g_return_if_fail (GST_IS_ELEMENT (element));
925 g_return_if_fail (GST_IS_CLOCK (element->clock));
926 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
928 switch (element->current_state) {
929 case GST_STATE_PAUSED:
930 if (diff < 0 && element->base_time < abs (diff)) {
931 g_warning ("attempted to set the current time of element %s below 0",
932 GST_OBJECT_NAME (element));
933 element->base_time = 0;
935 element->base_time += diff;
938 case GST_STATE_PLAYING:
939 time = gst_clock_get_time (element->clock);
940 if (time < element->base_time - diff) {
941 g_warning ("attempted to set the current time of element %s below 0",
942 GST_OBJECT_NAME (element));
943 element->base_time = time;
945 element->base_time -= diff;
949 g_assert_not_reached ();
954 #undef GST_CAT_DEFAULT
956 #ifndef GST_DISABLE_INDEX
958 * gst_element_is_indexable:
959 * @element: a #GstElement.
961 * Queries if the element can be indexed.
963 * Returns: TRUE if the element can be indexed.
966 gst_element_is_indexable (GstElement *element)
968 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
970 return (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
974 * gst_element_set_index:
975 * @element: a #GstElement.
976 * @index: a #GstIndex.
978 * Set the specified GstIndex on the element.
981 gst_element_set_index (GstElement *element, GstIndex *index)
983 GstElementClass *oclass;
985 g_return_if_fail (GST_IS_ELEMENT (element));
986 g_return_if_fail (GST_IS_INDEX (index));
988 oclass = GST_ELEMENT_GET_CLASS (element);
990 if (oclass->set_index)
991 oclass->set_index (element, index);
995 * gst_element_get_index:
996 * @element: a #GstElement.
998 * Gets the index from the element.
1000 * Returns: a #GstIndex or NULL when no index was set on the
1004 gst_element_get_index (GstElement *element)
1006 GstElementClass *oclass;
1008 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1010 oclass = GST_ELEMENT_GET_CLASS (element);
1012 if (oclass->get_index)
1013 return oclass->get_index (element);
1020 * gst_element_release_locks:
1021 * @element: a #GstElement to release all locks on.
1023 * Instruct the element to release all the locks it is holding, such as
1024 * blocking reads, waiting for the clock, ...
1026 * Returns: TRUE if the locks could be released.
1029 gst_element_release_locks (GstElement *element)
1031 GstElementClass *oclass;
1033 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1035 oclass = GST_ELEMENT_GET_CLASS (element);
1037 if (oclass->release_locks)
1038 return oclass->release_locks (element);
1044 * gst_element_add_pad:
1045 * @element: a #GstElement to add the pad to.
1046 * @pad: the #GstPad to add to the element.
1048 * Add a pad (link point) to the element, setting the parent of the
1049 * pad to the element (and thus adding a reference).
1050 * Pads are automatically activated when the element is in state PLAYING.
1053 gst_element_add_pad (GstElement *element, GstPad *pad)
1055 g_return_if_fail (GST_IS_ELEMENT (element));
1056 g_return_if_fail (GST_IS_PAD (pad));
1058 /* first check to make sure the pad's parent is already set */
1059 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
1061 /* then check to see if there's already a pad by that name here */
1062 g_return_if_fail (gst_object_check_uniqueness (element->pads, GST_PAD_NAME(pad)) == TRUE);
1064 /* set the pad's parent */
1065 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"setting parent of pad '%s' to '%s'",
1066 GST_PAD_NAME (pad), GST_STR_NULL (GST_ELEMENT_NAME (element)));
1067 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
1069 /* add it to the list */
1070 element->pads = g_list_append (element->pads, pad);
1072 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
1073 element->numsrcpads++;
1075 element->numsinkpads++;
1077 /* activate element when we are playing */
1078 if (GST_STATE (element) == GST_STATE_PLAYING)
1079 gst_pad_set_active (pad, TRUE);
1081 /* emit the NEW_PAD signal */
1082 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
1086 * gst_element_remove_pad:
1087 * @element: a #GstElement to remove pad from.
1088 * @pad: the #GstPad to remove from the element.
1090 * Remove a pad (link point) from the element.
1093 gst_element_remove_pad (GstElement *element, GstPad *pad)
1095 g_return_if_fail (element != NULL);
1096 g_return_if_fail (GST_IS_ELEMENT (element));
1097 g_return_if_fail (pad != NULL);
1098 g_return_if_fail (GST_IS_PAD (pad));
1100 g_return_if_fail (GST_PAD_PARENT (pad) == element);
1102 /* check to see if the pad is still linked */
1103 /* FIXME: what if someone calls _remove_pad instead of
1104 _remove_ghost_pad? */
1105 if (GST_IS_REAL_PAD (pad)) {
1106 if (GST_RPAD_PEER (pad) != NULL) {
1107 gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
1111 /* remove it from the list */
1112 element->pads = g_list_remove (element->pads, pad);
1114 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
1115 element->numsrcpads--;
1117 element->numsinkpads--;
1119 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
1121 gst_object_unparent (GST_OBJECT (pad));
1125 * gst_element_add_ghost_pad:
1126 * @element: a #GstElement to add the ghost pad to.
1127 * @pad: the #GstPad from which the new ghost pad will be created.
1128 * @name: the name of the new ghost pad.
1130 * Creates a ghost pad from the given pad, and adds it to the list of pads
1133 * Returns: the added ghost #GstPad, or NULL, if no ghost pad was created.
1136 gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
1140 g_return_val_if_fail (element != NULL, NULL);
1141 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1142 g_return_val_if_fail (pad != NULL, NULL);
1143 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1145 /* then check to see if there's already a pad by that name here */
1146 g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
1148 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1149 "creating new ghost pad called %s, from pad %s:%s",
1150 name, GST_DEBUG_PAD_NAME(pad));
1151 ghostpad = gst_ghost_pad_new (name, pad);
1153 /* add it to the list */
1154 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"adding ghost pad %s to element %s",
1155 name, GST_ELEMENT_NAME (element));
1156 element->pads = g_list_append (element->pads, ghostpad);
1158 /* set the parent of the ghostpad */
1159 gst_object_set_parent (GST_OBJECT (ghostpad), GST_OBJECT (element));
1161 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s",GST_DEBUG_PAD_NAME(ghostpad));
1163 /* emit the NEW_GHOST_PAD signal */
1164 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
1170 * gst_element_remove_ghost_pad:
1171 * @element: a #GstElement to remove the ghost pad from.
1172 * @pad: ghost #GstPad to remove.
1174 * Removes a ghost pad from an element.
1177 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
1179 g_return_if_fail (GST_IS_ELEMENT (element));
1180 g_return_if_fail (GST_IS_GHOST_PAD (pad));
1182 /* FIXME this is redundant?
1183 * wingo 10-july-2001: I don't think so, you have to actually remove the pad
1184 * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
1185 * the real pad's ghost pad list
1187 gst_object_ref (GST_OBJECT (pad));
1188 gst_element_remove_pad (element, pad);
1189 gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
1190 gst_object_unref (GST_OBJECT (pad));
1195 * gst_element_get_pad:
1196 * @element: a #GstElement to find pad of.
1197 * @name: the name of the pad to retrieve.
1199 * Retrieves a pad from the element by name.
1201 * Returns: requested #GstPad if found, otherwise NULL.
1204 gst_element_get_pad (GstElement *element, const gchar *name)
1208 g_return_val_if_fail (element != NULL, NULL);
1209 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1210 g_return_val_if_fail (name != NULL, NULL);
1212 pad = gst_element_get_static_pad (element, name);
1214 pad = gst_element_get_request_pad (element, name);
1220 * gst_element_get_static_pad:
1221 * @element: a #GstElement to find a static pad of.
1222 * @name: the name of the static #GstPad to retrieve.
1224 * Retrieves a pad from the element by name. This version only retrieves
1225 * already-existing (i.e. 'static') pads.
1227 * Returns: the requested #GstPad if found, otherwise NULL.
1230 gst_element_get_static_pad (GstElement *element, const gchar *name)
1234 g_return_val_if_fail (element != NULL, NULL);
1235 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1236 g_return_val_if_fail (name != NULL, NULL);
1238 walk = element->pads;
1242 pad = GST_PAD(walk->data);
1243 if (strcmp (GST_PAD_NAME(pad), name) == 0) {
1244 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1247 walk = g_list_next (walk);
1250 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"", name, GST_OBJECT_NAME (element));
1255 * gst_element_get_request_pad:
1256 * @element: a #GstElement to find a request pad of.
1257 * @name: the name of the request #GstPad to retrieve.
1259 * Retrieves a pad from the element by name. This version only retrieves
1262 * Returns: requested #GstPad if found, otherwise NULL.
1265 gst_element_get_request_pad (GstElement *element, const gchar *name)
1267 GstPadTemplate *templ = NULL;
1269 const gchar *req_name = NULL;
1270 gboolean templ_found = FALSE;
1274 gchar *str, *endptr = NULL;
1276 g_return_val_if_fail (element != NULL, NULL);
1277 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1278 g_return_val_if_fail (name != NULL, NULL);
1280 if (strstr (name, "%")) {
1281 templ = gst_element_get_pad_template (element, name);
1286 list = gst_element_get_pad_template_list(element);
1287 while (!templ_found && list) {
1288 templ = (GstPadTemplate*) list->data;
1289 if (templ->presence == GST_PAD_REQUEST) {
1290 /* we know that %s and %d are the only possibilities because of sanity
1291 checks in gst_pad_template_new */
1292 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name, templ->name_template);
1293 if ((str = strchr (templ->name_template, '%')) &&
1294 strncmp (templ->name_template, name, str - templ->name_template) == 0 &&
1295 strlen (name) > str - templ->name_template) {
1296 data = name + (str - templ->name_template);
1297 if (*(str+1) == 'd') {
1299 n = (gint) strtol (data, &endptr, 10);
1300 if (endptr && *endptr == '\0') {
1320 pad = gst_element_request_pad (element, templ, req_name);
1326 * gst_element_get_pad_list:
1327 * @element: a #GstElement to get pads of.
1329 * Retrieves a list of the pads associated with the element.
1331 * Returns: the #GList of pads.
1334 gst_element_get_pad_list (GstElement *element)
1336 g_return_val_if_fail (element != NULL, NULL);
1337 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1339 /* return the list of pads */
1340 return element->pads;
1344 * gst_element_class_add_pad_template:
1345 * @klass: the #GstElementClass to add the pad template to.
1346 * @templ: a #GstPadTemplate to add to the element class.
1348 * Adds a padtemplate to an element class. This is mainly used in the _base_init
1349 * functions of classes.
1352 gst_element_class_add_pad_template (GstElementClass *klass,
1353 GstPadTemplate *templ)
1355 GstPadTemplate *templ_copy;
1357 g_return_if_fail (klass != NULL);
1358 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1359 g_return_if_fail (templ != NULL);
1360 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1361 /* avoid registering pad templates with the same name */
1362 g_return_if_fail (gst_element_class_get_pad_template (klass, templ->name_template) == NULL);
1364 templ_copy = g_memdup(templ, sizeof(GstPadTemplate));
1366 klass->padtemplates = g_list_append (klass->padtemplates, templ_copy);
1367 klass->numpadtemplates++;
1371 * gst_element_class_set_details:
1372 * @klass: class to set details for
1373 * @details: details to set
1375 * Sets the detailed information for a #GstElementClass.
1376 * <note>This function is for use in _base_init functions only.</note>
1379 gst_element_class_set_details (GstElementClass *klass, const GstElementDetails *details)
1381 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1382 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1384 __gst_element_details_set (&klass->details, details);
1388 * gst_element_class_get_pad_template_list:
1389 * @element: a #GstElementClass to get pad templates of.
1391 * Retrieves a list of the pad templates associated with the element.
1393 * Returns: the #GList of padtemplates.
1396 gst_element_class_get_pad_template_list (GstElementClass *element_class)
1398 g_return_val_if_fail (element_class != NULL, NULL);
1399 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1401 return element_class->padtemplates;
1405 * gst_element_class_get_pad_template:
1406 * @element: a #GstElementClass to get the pad template of.
1407 * @name: the name of the #GstPadTemplate to get.
1409 * Retrieves a padtemplate from this element with the
1412 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1413 * No unreferencing is necessary.
1416 gst_element_class_get_pad_template (GstElementClass *element_class, const gchar *name)
1420 g_return_val_if_fail (element_class != NULL, NULL);
1421 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1422 g_return_val_if_fail (name != NULL, NULL);
1424 padlist = gst_element_class_get_pad_template_list (element_class);
1427 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1429 if (strcmp (padtempl->name_template, name) == 0)
1432 padlist = g_list_next (padlist);
1439 * gst_element_get_pad_template_list:
1440 * @element: a #GstElement to get pad templates of.
1442 * Retrieves a list of the pad templates associated with the element.
1443 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template_list).
1445 * Returns: the #GList of padtemplates.
1448 gst_element_get_pad_template_list (GstElement *element)
1450 g_return_val_if_fail (element != NULL, NULL);
1451 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1453 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1457 * gst_element_get_pad_template:
1458 * @element: a #GstElement to get the pad template of.
1459 * @name: the name of the #GstPadTemplate to get.
1461 * Retrieves a padtemplate from this element with the
1463 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template).
1465 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1466 * No unreferencing is necessary.
1469 gst_element_get_pad_template (GstElement *element, const gchar *name)
1473 g_return_val_if_fail (element != NULL, NULL);
1474 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1475 g_return_val_if_fail (name != NULL, NULL);
1477 padlist = gst_element_get_pad_template_list (element);
1480 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1482 if (!strcmp (padtempl->name_template, name))
1485 padlist = g_list_next (padlist);
1492 * gst_element_get_compatible_pad_template:
1493 * @element: a #GstElement to get a compatible pad template for.
1494 * @compattempl: the #GstPadTemplate to find a compatible template for.
1496 * Generates a pad template for this element compatible with the given
1497 * template (meaning it is able to link with it).
1499 * Returns: the #GstPadTemplate of the element that is compatible with
1500 * the given GstPadTemplate, or NULL if none was found. No unreferencing
1504 gst_element_get_compatible_pad_template (GstElement *element,
1505 GstPadTemplate *compattempl)
1507 GstPadTemplate *newtempl = NULL;
1510 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "gst_element_get_compatible_pad_template()");
1512 g_return_val_if_fail (element != NULL, NULL);
1513 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1514 g_return_val_if_fail (compattempl != NULL, NULL);
1516 padlist = gst_element_get_pad_template_list (element);
1519 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1520 gboolean comp = FALSE;
1524 * Check direction (must be opposite)
1527 GST_CAT_DEBUG (GST_CAT_CAPS, "checking direction and caps");
1528 if (padtempl->direction == GST_PAD_SRC &&
1529 compattempl->direction == GST_PAD_SINK) {
1530 GST_CAT_DEBUG (GST_CAT_CAPS, "compatible direction: found src pad template");
1531 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1532 GST_PAD_TEMPLATE_CAPS (padtempl));
1533 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1534 } else if (padtempl->direction == GST_PAD_SINK &&
1535 compattempl->direction == GST_PAD_SRC) {
1536 GST_CAT_DEBUG (GST_CAT_CAPS, "compatible direction: found sink pad template");
1537 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1538 GST_PAD_TEMPLATE_CAPS (padtempl));
1539 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1543 newtempl = padtempl;
1547 padlist = g_list_next (padlist);
1554 * gst_element_request_compatible_pad:
1555 * @element: a #GstElement to request a new pad from.
1556 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1558 * Requests a new pad from the element. The template will
1559 * be used to decide what type of pad to create. This function
1560 * is typically used for elements with a padtemplate with presence
1563 * Returns: the new #GstPad that was created, or NULL if none could be created.
1566 gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
1568 GstPadTemplate *templ_new;
1571 g_return_val_if_fail (element != NULL, NULL);
1572 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1573 g_return_val_if_fail (templ != NULL, NULL);
1575 templ_new = gst_element_get_compatible_pad_template (element, templ);
1576 if (templ_new != NULL)
1577 pad = gst_element_request_pad (element, templ_new, NULL);
1584 * gst_element_get_compatible_pad_filtered:
1585 * @element: a #GstElement in which the pad should be found.
1586 * @pad: the #GstPad to find a compatible one for.
1587 * @filtercaps: the #GstCaps to use as a filter.
1589 * Looks for an unlinked pad to which the given pad can link to.
1590 * It is not guaranteed that linking the pads will work, though
1591 * it should work in most cases.
1593 * Returns: the #GstPad to which a link can be made.
1596 gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
1597 const GstCaps *filtercaps)
1600 GstPadTemplate *templ;
1602 GstPad *foundpad = NULL;
1605 g_return_val_if_fail (element != NULL, NULL);
1606 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1607 g_return_val_if_fail (pad != NULL, NULL);
1608 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1610 GST_DEBUG ("finding pad in %s compatible with %s:%s",
1611 GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad));
1613 /* let's use the real pad */
1614 pad = (GstPad *) GST_PAD_REALIZE (pad);
1615 g_return_val_if_fail (pad != NULL, NULL);
1616 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1618 /* try to get an existing unlinked pad */
1619 pads = gst_element_get_pad_list (element);
1621 GstPad *current = GST_PAD (pads->data);
1622 if ((GST_PAD_PEER (GST_PAD_REALIZE (current)) == NULL) &&
1623 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1626 pads = g_list_next (pads);
1629 /* try to create a new one */
1630 /* requesting is a little crazy, we need a template. Let's create one */
1631 templcaps = gst_pad_get_caps (pad);
1632 if (filtercaps != NULL) {
1634 temp = gst_caps_intersect (filtercaps, templcaps);
1635 gst_caps_free (templcaps);
1639 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
1640 GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
1641 foundpad = gst_element_request_compatible_pad (element, templ);
1642 gst_object_unref (GST_OBJECT (templ));
1644 if (foundpad) return foundpad;
1646 /* FIXME: this is broken, but it's in here so autoplugging elements
1647 * that don't have caps on their source padtemplates (spider) can
1649 //g_warning("got here");
1650 //if (filtercaps == NULL) {
1651 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
1652 GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, gst_caps_new_any());
1653 foundpad = gst_element_request_compatible_pad (element, templ);
1654 gst_object_unref (GST_OBJECT (templ));
1656 if (foundpad) return foundpad;
1659 GST_DEBUG_OBJECT (element, "Could not find a compatible pad to link to %s:%s",
1660 GST_DEBUG_PAD_NAME (pad));
1666 * gst_element_get_compatible_pad:
1667 * @element: a #GstElement in which the pad should be found.
1668 * @pad: the #GstPad to find a compatible one for.
1670 * Looks for an unlinked pad to which the given pad can link to.
1671 * It is not guaranteed that linking the pads will work, though
1672 * it should work in most cases.
1674 * Returns: the #GstPad to which a link can be made, or NULL if none
1678 gst_element_get_compatible_pad (GstElement *element, GstPad *pad)
1680 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1684 * gst_element_link_pads_filtered:
1685 * @src: a #GstElement containing the source pad.
1686 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1687 * @dest: the #GstElement containing the destination pad.
1688 * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1689 * @filtercaps: the #GstCaps to use as a filter.
1691 * Links the two named pads of the source and destination elements.
1692 * Side effect is that if one of the pads has no parent, it becomes a
1693 * child of the parent of the other element. If they have different
1694 * parents, the link fails.
1696 * Returns: TRUE if the pads could be linked.
1699 gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
1700 GstElement *dest, const gchar *destpadname,
1701 const GstCaps *filtercaps)
1703 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1704 GstPad *srcpad, *destpad;
1705 GstPadTemplate *srctempl, *desttempl;
1708 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1709 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1711 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "trying to link element %s:%s to element %s:%s",
1712 GST_ELEMENT_NAME (src), srcpadname ? srcpadname : "(any)",
1713 GST_ELEMENT_NAME (dest), destpadname ? destpadname : "(any)");
1715 /* now get the pads we're trying to link and a list of all remaining pads */
1717 srcpad = gst_element_get_pad (src, srcpadname);
1719 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (src), srcpadname);
1722 if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1723 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad", GST_DEBUG_PAD_NAME (srcpad));
1726 if (GST_PAD_PEER (srcpad) != NULL) {
1727 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (srcpad));
1733 srcpads = gst_element_get_pad_list (src);
1734 srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
1737 destpad = gst_element_get_pad (dest, destpadname);
1739 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (dest), destpadname);
1742 if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1743 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad", GST_DEBUG_PAD_NAME (destpad));
1746 if (GST_PAD_PEER (destpad) != NULL) {
1747 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (destpad));
1753 destpads = gst_element_get_pad_list (dest);
1754 destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
1757 if (srcpadname && destpadname) {
1758 /* two explicitly specified pads */
1759 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1762 /* loop through the allowed pads in the source, trying to find a
1763 * compatible destination pad */
1764 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "looping through allowed src and dest pads");
1766 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1767 GST_DEBUG_PAD_NAME (srcpad));
1768 if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1769 (GST_PAD_PEER (srcpad) == NULL)) {
1770 GstPad *temp = gst_element_get_compatible_pad_filtered (dest, srcpad,
1772 if (temp && gst_pad_link_filtered (srcpad, temp, filtercaps)) {
1773 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1774 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1778 /* find a better way for this mess */
1780 srcpads = g_list_next (srcpads);
1782 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1787 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1788 GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1792 /* loop through the existing pads in the destination */
1794 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1795 GST_DEBUG_PAD_NAME (destpad));
1796 if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1797 (GST_PAD_PEER (destpad) == NULL)) {
1798 GstPad *temp = gst_element_get_compatible_pad_filtered (src, destpad,
1800 if (temp && gst_pad_link_filtered (temp, destpad, filtercaps)) {
1801 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1802 GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1807 destpads = g_list_next (destpads);
1809 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1814 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1815 GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1819 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1820 "we might have request pads on both sides, checking...");
1821 srctempls = gst_element_get_pad_template_list (src);
1822 desttempls = gst_element_get_pad_template_list (dest);
1824 if (srctempls && desttempls) {
1826 srctempl = (GstPadTemplate*) srctempls->data;
1827 if (srctempl->presence == GST_PAD_REQUEST) {
1828 for (l=desttempls; l; l=l->next) {
1829 desttempl = (GstPadTemplate*) l->data;
1830 if (desttempl->presence == GST_PAD_REQUEST &&
1831 desttempl->direction != srctempl->direction) {
1832 if (gst_caps_is_always_compatible (gst_pad_template_get_caps (srctempl),
1833 gst_pad_template_get_caps (desttempl))) {
1834 srcpad = gst_element_get_request_pad (src,
1835 srctempl->name_template);
1836 destpad = gst_element_get_request_pad (dest,
1837 desttempl->name_template);
1838 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1839 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1840 "linked pad %s:%s to pad %s:%s",
1841 GST_DEBUG_PAD_NAME (srcpad),
1842 GST_DEBUG_PAD_NAME (destpad));
1845 /* it failed, so we release the request pads */
1846 gst_element_release_request_pad (src, srcpad);
1847 gst_element_release_request_pad (dest, destpad);
1852 srctempls = srctempls->next;
1856 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1857 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1861 * gst_element_link_filtered:
1862 * @src: a #GstElement containing the source pad.
1863 * @dest: the #GstElement containing the destination pad.
1864 * @filtercaps: the #GstCaps to use as a filter.
1866 * Links the source to the destination element using the filtercaps.
1867 * The link must be from source to destination, the other
1868 * direction will not be tried.
1869 * The functions looks for existing pads that aren't linked yet.
1870 * It will use request pads if possible. But both pads will not be requested.
1871 * If multiple links are possible, only one is established.
1873 * Returns: TRUE if the elements could be linked.
1876 gst_element_link_filtered (GstElement *src, GstElement *dest,
1877 const GstCaps *filtercaps)
1879 return gst_element_link_pads_filtered (src, NULL, dest, NULL, filtercaps);
1883 * gst_element_link_many:
1884 * @element_1: the first #GstElement in the link chain.
1885 * @element_2: the second #GstElement in the link chain.
1886 * @...: the NULL-terminated list of elements to link in order.
1888 * Chain together a series of elements. Uses #gst_element_link.
1890 * Returns: TRUE on success, FALSE otherwise.
1893 gst_element_link_many (GstElement *element_1, GstElement *element_2, ...)
1897 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1898 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1899 GST_IS_ELEMENT (element_2), FALSE);
1901 va_start (args, element_2);
1904 if (!gst_element_link (element_1, element_2))
1907 element_1 = element_2;
1908 element_2 = va_arg (args, GstElement*);
1918 * @src: a #GstElement containing the source pad.
1919 * @dest: the #GstElement containing the destination pad.
1921 * Links the source to the destination element.
1922 * The link must be from source to destination, the other
1923 * direction will not be tried.
1924 * The functions looks for existing pads and request pads that aren't
1925 * linked yet. If multiple links are possible, only one is
1928 * Returns: TRUE if the elements could be linked.
1931 gst_element_link (GstElement *src, GstElement *dest)
1933 return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1937 * gst_element_link_pads:
1938 * @src: a #GstElement containing the source pad.
1939 * @srcpadname: the name of the #GstPad in the source element.
1940 * @dest: the #GstElement containing the destination pad.
1941 * @destpadname: the name of the #GstPad in destination element.
1943 * Links the two named pads of the source and destination elements.
1944 * Side effect is that if one of the pads has no parent, it becomes a
1945 * child of the parent of the other element. If they have different
1946 * parents, the link fails.
1948 * Returns: TRUE if the pads could be linked.
1951 gst_element_link_pads (GstElement *src, const gchar *srcpadname,
1952 GstElement *dest, const gchar *destpadname)
1954 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname, NULL);
1958 * gst_element_unlink_pads:
1959 * @src: a #GstElement containing the source pad.
1960 * @srcpadname: the name of the #GstPad in source element.
1961 * @dest: a #GstElement containing the destination pad.
1962 * @destpadname: the name of the #GstPad in destination element.
1964 * Unlinks the two named pads of the source and destination elements.
1967 gst_element_unlink_pads (GstElement *src, const gchar *srcpadname,
1968 GstElement *dest, const gchar *destpadname)
1970 GstPad *srcpad,*destpad;
1972 g_return_if_fail (src != NULL);
1973 g_return_if_fail (GST_IS_ELEMENT(src));
1974 g_return_if_fail (srcpadname != NULL);
1975 g_return_if_fail (dest != NULL);
1976 g_return_if_fail (GST_IS_ELEMENT(dest));
1977 g_return_if_fail (destpadname != NULL);
1979 /* obtain the pads requested */
1980 srcpad = gst_element_get_pad (src, srcpadname);
1981 if (srcpad == NULL) {
1982 GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
1985 destpad = gst_element_get_pad (dest, destpadname);
1986 if (srcpad == NULL) {
1987 GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"", destpadname);
1991 /* we're satisified they can be unlinked, let's do it */
1992 gst_pad_unlink (srcpad,destpad);
1996 * gst_element_unlink_many:
1997 * @element_1: the first #GstElement in the link chain.
1998 * @element_2: the second #GstElement in the link chain.
1999 * @...: the NULL-terminated list of elements to unlink in order.
2001 * Unlinks a series of elements. Uses #gst_element_unlink.
2004 gst_element_unlink_many (GstElement *element_1, GstElement *element_2, ...)
2008 g_return_if_fail (element_1 != NULL && element_2 != NULL);
2009 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
2011 va_start (args, element_2);
2014 gst_element_unlink (element_1, element_2);
2016 element_1 = element_2;
2017 element_2 = va_arg (args, GstElement*);
2024 * gst_element_unlink:
2025 * @src: the source #GstElement to unlink.
2026 * @dest: the sink #GstElement to unlink.
2028 * Unlinks all source pads of the source element with all sink pads
2029 * of the sink element to which they are linked.
2032 gst_element_unlink (GstElement *src, GstElement *dest)
2034 const GList *srcpads;
2037 g_return_if_fail (GST_IS_ELEMENT (src));
2038 g_return_if_fail (GST_IS_ELEMENT (dest));
2040 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
2041 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
2043 srcpads = gst_element_get_pad_list (src);
2046 pad = GST_PAD (srcpads->data);
2048 /* we only care about real src pads */
2049 if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
2050 GstPad *peerpad = GST_PAD_PEER (pad);
2052 /* see if the pad is connected and is really a pad
2055 (GST_OBJECT_PARENT (peerpad) == (GstObject*) dest))
2057 gst_pad_unlink (pad, peerpad);
2061 srcpads = g_list_next (srcpads);
2066 gst_element_error_func (GstElement* element, GstElement *source,
2067 GError *error, gchar *debug)
2069 /* tell the parent */
2070 if (GST_OBJECT_PARENT (element)) {
2071 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM, "forwarding error \"%s\" from %s to %s",
2072 error->message, GST_ELEMENT_NAME (element),
2073 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2075 gst_object_ref (GST_OBJECT (element));
2076 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
2077 gst_element_signals[ERROR], 0, source, error, debug);
2078 gst_object_unref (GST_OBJECT (element));
2079 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM, "forwarded error \"%s\" from %s to %s",
2080 error->message, GST_ELEMENT_NAME (element),
2081 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2086 gst_element_get_random_pad (GstElement *element, GstPadDirection dir)
2088 GList *pads = element->pads;
2089 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
2091 GstPad *pad = GST_PAD (pads->data);
2093 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
2094 GST_DEBUG_PAD_NAME (pad));
2096 if (GST_PAD_DIRECTION (pad) == dir) {
2097 if (GST_PAD_IS_LINKED (pad)) {
2101 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
2102 GST_DEBUG_PAD_NAME (pad));
2106 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
2107 GST_DEBUG_PAD_NAME (pad));
2110 pads = g_list_next (pads);
2116 * gst_element_get_event_masks:
2117 * @element: a #GstElement to query
2119 * Get an array of event masks from the element.
2120 * If the element doesn't
2121 * implement an event masks function, the query will be forwarded
2122 * to a random linked sink pad.
2124 * Returns: An array of #GstEventMask elements.
2127 gst_element_get_event_masks (GstElement *element)
2129 GstElementClass *oclass;
2131 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2133 oclass = GST_ELEMENT_GET_CLASS (element);
2135 if (oclass->get_event_masks)
2136 return oclass->get_event_masks (element);
2138 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2140 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
2147 * gst_element_send_event:
2148 * @element: a #GstElement to send the event to.
2149 * @event: the #GstEvent to send to the element.
2151 * Sends an event to an element. If the element doesn't
2152 * implement an event handler, the event will be forwarded
2153 * to a random sink pad.
2155 * Returns: TRUE if the event was handled.
2158 gst_element_send_event (GstElement *element, GstEvent *event)
2160 GstElementClass *oclass;
2162 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2163 g_return_val_if_fail (event != NULL, FALSE);
2165 oclass = GST_ELEMENT_GET_CLASS (element);
2167 if (oclass->send_event)
2168 return oclass->send_event (element, event);
2170 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2172 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
2173 GST_DEBUG_PAD_NAME (pad));
2174 return gst_pad_send_event (GST_PAD_PEER (pad), event);
2177 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
2178 GST_ELEMENT_NAME (element));
2184 * @element: a #GstElement to send the event to.
2185 * @seek_type: the method to use for seeking.
2186 * @offset: the offset to seek to.
2188 * Sends a seek event to an element.
2190 * Returns: TRUE if the event was handled.
2193 gst_element_seek (GstElement *element,
2194 GstSeekType seek_type,
2197 GstEvent *event = gst_event_new_seek (seek_type, offset);
2199 return gst_element_send_event (element, event);
2203 * gst_element_get_query_types:
2204 * @element: a #GstElement to query
2206 * Get an array of query types from the element.
2207 * If the element doesn't
2208 * implement a query types function, the query will be forwarded
2209 * to a random sink pad.
2211 * Returns: An array of #GstQueryType elements.
2214 gst_element_get_query_types (GstElement *element)
2216 GstElementClass *oclass;
2218 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2220 oclass = GST_ELEMENT_GET_CLASS (element);
2222 if (oclass->get_query_types)
2223 return oclass->get_query_types (element);
2225 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2227 return gst_pad_get_query_types (GST_PAD_PEER (pad));
2234 * gst_element_query:
2235 * @element: a #GstElement to perform the query on.
2236 * @type: the #GstQueryType.
2237 * @format: the #GstFormat pointer to hold the format of the result.
2238 * @value: the pointer to the value of the result.
2240 * Performs a query on the given element. If the format is set
2241 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
2242 * format pointer will hold the default format.
2243 * For element that don't implement a query handler, this function
2244 * forwards the query to a random usable sinkpad of this element.
2246 * Returns: TRUE if the query could be performed.
2249 gst_element_query (GstElement *element, GstQueryType type,
2250 GstFormat *format, gint64 *value)
2252 GstElementClass *oclass;
2254 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2255 g_return_val_if_fail (format != NULL, FALSE);
2256 g_return_val_if_fail (value != NULL, FALSE);
2258 oclass = GST_ELEMENT_GET_CLASS (element);
2261 return oclass->query (element, type, format, value);
2263 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
2265 return gst_pad_query (pad, type, format, value);
2266 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2268 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
2275 * gst_element_get_formats:
2276 * @element: a #GstElement to query
2278 * Get an array of formst from the element.
2279 * If the element doesn't
2280 * implement a formats function, the query will be forwarded
2281 * to a random sink pad.
2283 * Returns: An array of #GstFormat elements.
2286 gst_element_get_formats (GstElement *element)
2288 GstElementClass *oclass;
2290 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2292 oclass = GST_ELEMENT_GET_CLASS (element);
2294 if (oclass->get_formats)
2295 return oclass->get_formats (element);
2297 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2299 return gst_pad_get_formats (GST_PAD_PEER (pad));
2306 * gst_element_convert:
2307 * @element: a #GstElement to invoke the converter on.
2308 * @src_format: the source #GstFormat.
2309 * @src_value: the source value.
2310 * @dest_format: a pointer to the destination #GstFormat.
2311 * @dest_value: a pointer to the destination value.
2313 * Invokes a conversion on the element.
2314 * If the element doesn't
2315 * implement a convert function, the query will be forwarded
2316 * to a random sink pad.
2318 * Returns: TRUE if the conversion could be performed.
2321 gst_element_convert (GstElement *element,
2322 GstFormat src_format, gint64 src_value,
2323 GstFormat *dest_format, gint64 *dest_value)
2325 GstElementClass *oclass;
2327 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2328 g_return_val_if_fail (dest_format != NULL, FALSE);
2329 g_return_val_if_fail (dest_value != NULL, FALSE);
2331 if (src_format == *dest_format) {
2332 *dest_value = src_value;
2336 oclass = GST_ELEMENT_GET_CLASS (element);
2338 if (oclass->convert)
2339 return oclass->convert (element,
2340 src_format, src_value,
2341 dest_format, dest_value);
2343 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2345 return gst_pad_convert (GST_PAD_PEER (pad),
2346 src_format, src_value,
2347 dest_format, dest_value);
2354 * _gst_element_error_printf:
2355 * @format: the printf-like format to use, or NULL
2357 * This function is only used internally by the #gst_element_error macro.
2359 * Returns: a newly allocated string, or NULL if the format was NULL or ""
2362 _gst_element_error_printf (const gchar *format, ...)
2367 if (format == NULL) return NULL;
2368 if (format[0] == 0) return NULL;
2370 va_start (args, format);
2371 buffer = g_strdup_vprintf (format, args);
2377 * gst_element_error_full:
2378 * @element: a #GstElement with the error.
2379 * @domain: the GStreamer error domain this error belongs to.
2380 * @code: the error code belonging to the domain
2381 * @message: an allocated message to be used as a replacement for the default
2382 * message connected to code, or NULL
2383 * debug: an allocated debug message to be used as a replacement for the
2384 * default debugging information, or NULL
2386 * Signals an error condition on an element.
2387 * This function is used internally by elements.
2388 * It results in the "error" signal.
2391 gst_element_error_full
2392 (GstElement *element, GQuark domain, gint code, gchar *message, gchar *debug,
2393 const gchar *file, const gchar *function, gint line)
2395 GError *error = NULL;
2396 gchar *sent_message;
2400 g_return_if_fail (GST_IS_ELEMENT (element));
2402 /* check if we send the given message or the default error message */
2403 if ((message == NULL) || (message[0] == 0))
2405 /* we got this message from g_strdup_printf (""); */
2407 sent_message = gst_error_get_message (domain, code);
2410 sent_message = message;
2412 if ((debug == NULL) || (debug[0] == 0))
2414 /* we got this debug from g_strdup_printf (""); */
2419 /* create error message */
2420 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signaling error in %s: %s",
2421 GST_ELEMENT_NAME (element),
2423 error = g_error_new (domain, code, sent_message);
2425 /* if the element was already in error, stop now */
2426 if (GST_FLAG_IS_SET (element, GST_ELEMENT_IN_ERROR)) {
2427 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "recursive ERROR detected in %s",
2428 GST_ELEMENT_NAME (element));
2429 g_free (sent_message);
2430 if (debug) g_free (debug);
2434 GST_FLAG_SET (element, GST_ELEMENT_IN_ERROR);
2436 /* emit the signal, make sure the element stays available */
2437 gst_object_ref (GST_OBJECT (element));
2439 sent_debug = g_strdup_printf ("%s(%d):%s:\n%s",
2440 file, line, function,
2441 debug ? debug : "");
2445 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element,
2447 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signalled error in %s: %s",
2448 GST_ELEMENT_NAME (element),
2451 /* tell the scheduler */
2452 if (element->sched) {
2453 gst_scheduler_error (element->sched, element);
2456 if (GST_STATE (element) == GST_STATE_PLAYING) {
2457 GstElementStateReturn ret;
2459 ret = gst_element_set_state (element, GST_STATE_PAUSED);
2460 if (ret != GST_STATE_SUCCESS) {
2461 g_warning ("could not PAUSE element \"%s\" after error, help!",
2462 GST_ELEMENT_NAME (element));
2466 GST_FLAG_UNSET (element, GST_ELEMENT_IN_ERROR);
2469 gst_object_unref (GST_OBJECT (element));
2470 g_free (sent_message);
2471 g_free (sent_debug);
2472 g_error_free (error);
2476 * gst_element_is_locked_state:
2477 * @element: a #GstElement.
2479 * Checks if the state of an element is locked.
2480 * If the state of an element is locked, state changes of the parent don't
2481 * affect the element.
2482 * This way you can leave currently unused elements inside bins. Just lock their
2483 * state before changing the state from #GST_STATE_NULL.
2485 * Returns: TRUE, if the element's state is locked.
2488 gst_element_is_locked_state (GstElement *element)
2490 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2492 return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
2495 * gst_element_set_locked_state:
2496 * @element: a #GstElement
2497 * @locked_state: TRUE to lock the element's state
2499 * Locks the state of an element, so state changes of the parent don't affect
2500 * this element anymore.
2503 gst_element_set_locked_state (GstElement *element, gboolean locked_state)
2507 g_return_if_fail (GST_IS_ELEMENT (element));
2509 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2511 if (old == locked_state)
2515 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2516 GST_ELEMENT_NAME (element));
2517 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2519 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2520 GST_ELEMENT_NAME (element));
2521 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2525 * gst_element_sync_state_with_parent:
2526 * @element: a #GstElement.
2528 * Tries to change the state of the element to the same as its parent.
2529 * If this function returns FALSE, the state of element is undefined.
2531 * Returns: TRUE, if the element's state could be synced to the parent's state.
2534 gst_element_sync_state_with_parent (GstElement *element)
2538 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2539 parent = GST_ELEMENT (GST_ELEMENT_PARENT(element));
2540 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
2542 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
2543 GST_ELEMENT_NAME (element), gst_element_state_get_name (GST_STATE (element)),
2544 GST_ELEMENT_NAME (parent), gst_element_state_get_name (GST_STATE (parent)));
2545 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
2551 * gst_element_get_state:
2552 * @element: a #GstElement to get the state of.
2554 * Gets the state of the element.
2556 * Returns: the #GstElementState of the element.
2559 gst_element_get_state (GstElement *element)
2561 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2563 return GST_STATE (element);
2567 * gst_element_wait_state_change:
2568 * @element: a #GstElement to wait for a state change on.
2570 * Waits and blocks until the element changed its state.
2573 gst_element_wait_state_change (GstElement *element)
2575 g_mutex_lock (element->state_mutex);
2576 g_cond_wait (element->state_cond, element->state_mutex);
2577 g_mutex_unlock (element->state_mutex);
2581 * gst_element_set_state:
2582 * @element: a #GstElement to change state of.
2583 * @state: the element's new #GstElementState.
2585 * Sets the state of the element. This function will try to set the
2586 * requested state by going through all the intermediary states and calling
2587 * the class's state change function for each.
2589 * Returns: TRUE if the state was successfully set.
2590 * (using #GstElementStateReturn).
2592 GstElementStateReturn
2593 gst_element_set_state (GstElement *element, GstElementState state)
2595 GstElementClass *oclass;
2596 GstElementState curpending;
2597 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2599 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2601 /* start with the current state */
2602 curpending = GST_STATE(element);
2604 if (state == curpending)
2606 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2607 "element is already in requested state %s",
2608 gst_element_state_get_name (state));
2609 return (GST_STATE_SUCCESS);
2612 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
2613 gst_element_state_get_name (curpending),
2614 gst_element_state_get_name (state));
2616 /* loop until the final requested state is set */
2617 while (GST_STATE (element) != state
2618 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2619 /* move the curpending state in the correct direction */
2620 if (curpending < state)
2625 /* set the pending state variable */
2626 /* FIXME: should probably check to see that we don't already have one */
2627 GST_STATE_PENDING (element) = curpending;
2629 if (curpending != state) {
2630 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2631 "intermediate: setting state from %s to %s",
2632 gst_element_state_get_name (GST_STATE (element)),
2633 gst_element_state_get_name (curpending));
2636 /* call the state change function so it can set the state */
2637 oclass = GST_ELEMENT_GET_CLASS (element);
2638 if (oclass->change_state)
2639 return_val = (oclass->change_state) (element);
2641 switch (return_val) {
2642 case GST_STATE_FAILURE:
2643 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2644 "have failed change_state return");
2646 case GST_STATE_ASYNC:
2647 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2648 "element will change state async");
2650 case GST_STATE_SUCCESS:
2651 /* Last thing we do is verify that a successful state change really
2652 * did change the state... */
2653 /* if it did not, this is an error - fix the element that does this */
2654 if (GST_STATE (element) != curpending) {
2655 g_warning ("element %s claimed state-change success,"
2656 "but state didn't change to %s. State is %s (%s pending), fix the element",
2657 GST_ELEMENT_NAME (element),
2658 gst_element_state_get_name (curpending),
2659 gst_element_state_get_name (GST_STATE (element)),
2660 gst_element_state_get_name (GST_STATE_PENDING (element)));
2661 return_val = GST_STATE_FAILURE;
2666 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2667 g_assert_not_reached ();
2676 gst_element_negotiate_pads (GstElement *element)
2678 GList *pads = GST_ELEMENT_PADS (element);
2680 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating pads");
2683 GstPad *pad = GST_PAD (pads->data);
2686 pads = g_list_next (pads);
2688 if (!GST_IS_REAL_PAD (pad))
2691 srcpad = GST_PAD_REALIZE (pad);
2693 /* if we have a link on this pad and it doesn't have caps
2694 * allready, try to negotiate */
2695 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2696 GstRealPad *sinkpad;
2697 GstElementState otherstate;
2700 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2702 /* check the parent of the peer pad, if there is no parent do nothing */
2703 parent = GST_PAD_PARENT (sinkpad);
2707 /* skips pads that were already negotiating */
2708 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2709 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2712 otherstate = GST_STATE (parent);
2714 /* swap pads if needed */
2715 if (!GST_PAD_IS_SRC (srcpad)) {
2723 /* only try to negotiate if the peer element is in PAUSED or higher too */
2724 if (otherstate >= GST_STATE_READY) {
2725 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2726 "perform negotiate for %s:%s and %s:%s",
2727 GST_DEBUG_PAD_NAME (srcpad),
2728 GST_DEBUG_PAD_NAME (sinkpad));
2729 if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
2733 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2734 "not negotiating %s:%s and %s:%s, not in READY yet",
2735 GST_DEBUG_PAD_NAME (srcpad),
2736 GST_DEBUG_PAD_NAME (sinkpad));
2745 gst_element_clear_pad_caps (GstElement *element)
2747 GList *pads = GST_ELEMENT_PADS (element);
2749 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "clearing pad caps");
2752 GstPad *pad = GST_PAD (pads->data);
2754 gst_pad_unnegotiate (pad);
2756 pads = g_list_next (pads);
2761 gst_element_pads_activate (GstElement *element, gboolean active)
2763 GList *pads = element->pads;
2766 GstPad *pad = GST_PAD (pads->data);
2767 pads = g_list_next (pads);
2769 if (!GST_IS_REAL_PAD (pad))
2772 gst_pad_set_active (pad, active);
2776 static GstElementStateReturn
2777 gst_element_change_state (GstElement *element)
2779 GstElementState old_state;
2781 gint old_pending, old_transition;
2783 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2785 old_state = GST_STATE (element);
2786 old_pending = GST_STATE_PENDING (element);
2787 old_transition = GST_STATE_TRANSITION (element);
2789 if (old_pending == GST_STATE_VOID_PENDING ||
2790 old_state == GST_STATE_PENDING (element)) {
2791 GST_CAT_INFO (GST_CAT_STATES,
2792 "no state change needed for element %s (VOID_PENDING)",
2793 GST_ELEMENT_NAME (element));
2794 return GST_STATE_SUCCESS;
2797 GST_CAT_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %04x",
2798 GST_ELEMENT_NAME (element),
2799 gst_element_state_get_name (old_state),
2800 gst_element_state_get_name (old_pending),
2803 /* we set the state change early for the negotiation functions */
2804 GST_STATE (element) = old_pending;
2805 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2807 switch (old_transition) {
2808 case GST_STATE_PLAYING_TO_PAUSED:
2809 if (element->clock) {
2810 GstClockTime time = gst_clock_get_event_time (element->clock);
2811 g_assert (time >= element->base_time);
2812 element->base_time = time - element->base_time;
2813 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2814 G_GINT64_FORMAT, element->base_time);
2816 gst_element_pads_activate (element, FALSE);
2818 case GST_STATE_PAUSED_TO_PLAYING:
2819 gst_element_pads_activate (element, TRUE);
2820 if (element->clock) {
2821 GstClockTime time = gst_clock_get_event_time (element->clock);
2822 element->base_time = time - element->base_time;
2823 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2824 G_GINT64_FORMAT, element->base_time);
2827 /* if we are going to paused, we try to negotiate the pads */
2828 case GST_STATE_READY_TO_PAUSED:
2829 g_assert (element->base_time == 0);
2830 if (!gst_element_negotiate_pads (element))
2833 /* going to the READY state clears all pad caps */
2834 /* FIXME: Why doesn't this happen on READY => NULL? -- Company */
2835 case GST_STATE_PAUSED_TO_READY:
2836 element->base_time = 0;
2837 gst_element_clear_pad_caps (element);
2843 parent = GST_ELEMENT_PARENT (element);
2845 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2846 "signaling state change from %s to %s",
2847 gst_element_state_get_name (old_state),
2848 gst_element_state_get_name (GST_STATE (element)));
2850 /* tell the scheduler if we have one */
2851 if (element->sched) {
2852 if (gst_scheduler_state_transition (element->sched, element,
2853 old_transition) != GST_STATE_SUCCESS) {
2854 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2855 "scheduler could not change state");
2860 /* tell our parent about the state change */
2861 if (parent && GST_IS_BIN (parent)) {
2862 gst_bin_child_state_change (GST_BIN (parent), old_state,
2863 GST_STATE (element), element);
2865 /* at this point the state of the element could have changed again */
2867 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2868 0, old_state, GST_STATE (element));
2870 /* signal the state change in case somebody is waiting for us */
2871 g_mutex_lock (element->state_mutex);
2872 g_cond_signal (element->state_cond);
2873 g_mutex_unlock (element->state_mutex);
2875 return GST_STATE_SUCCESS;
2878 /* undo the state change */
2879 GST_STATE (element) = old_state;
2880 GST_STATE_PENDING (element) = old_pending;
2882 return GST_STATE_FAILURE;
2886 * gst_element_get_factory:
2887 * @element: a #GstElement to request the element factory of.
2889 * Retrieves the factory that was used to create this element.
2891 * Returns: the #GstElementFactory used for creating this element.
2894 gst_element_get_factory (GstElement *element)
2896 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2898 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2902 gst_element_dispose (GObject *object)
2904 GstElement *element = GST_ELEMENT (object);
2908 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2910 gst_element_set_state (element, GST_STATE_NULL);
2912 /* first we break all our links with the ouside */
2913 if (element->pads) {
2915 orig = pads = g_list_copy (element->pads);
2917 pad = GST_PAD (pads->data);
2919 if (GST_PAD_PEER (pad)) {
2920 GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "unlinking pad '%s'",
2921 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2922 gst_pad_unlink (pad, GST_PAD (GST_PAD_PEER (pad)));
2924 gst_element_remove_pad (element, pad);
2926 pads = g_list_next (pads);
2929 g_list_free (element->pads);
2930 element->pads = NULL;
2933 element->numsrcpads = 0;
2934 element->numsinkpads = 0;
2935 element->numpads = 0;
2936 g_mutex_free (element->state_mutex);
2937 g_cond_free (element->state_cond);
2939 if (element->prop_value_queue)
2940 g_async_queue_unref (element->prop_value_queue);
2941 element->prop_value_queue = NULL;
2942 if (element->property_mutex)
2943 g_mutex_free (element->property_mutex);
2945 gst_object_replace ((GstObject **)&element->sched, NULL);
2946 gst_object_replace ((GstObject **)&element->clock, NULL);
2948 G_OBJECT_CLASS (parent_class)->dispose (object);
2951 #ifndef GST_DISABLE_LOADSAVE
2953 * gst_element_save_thyself:
2954 * @element: a #GstElement to save.
2955 * @parent: the xml parent node.
2957 * Saves the element as part of the given XML structure.
2959 * Returns: the new #xmlNodePtr.
2962 gst_element_save_thyself (GstObject *object,
2966 GstElementClass *oclass;
2967 GParamSpec **specs, *spec;
2969 GValue value = { 0, };
2970 GstElement *element;
2972 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2974 element = GST_ELEMENT (object);
2976 oclass = GST_ELEMENT_GET_CLASS (element);
2978 xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element));
2980 if (oclass->elementfactory != NULL) {
2981 GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory;
2983 xmlNewChild (parent, NULL, "type",
2984 GST_PLUGIN_FEATURE (factory)->name);
2987 /* FIXME: what is this? */
2988 /* if (element->manager) */
2989 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2992 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2994 for (i=0; i<nspecs; i++) {
2996 if (spec->flags & G_PARAM_READABLE) {
3000 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
3002 g_object_get_property (G_OBJECT (element), spec->name, &value);
3003 param = xmlNewChild (parent, NULL, "param", NULL);
3004 xmlNewChild (param, NULL, "name", spec->name);
3006 if (G_IS_PARAM_SPEC_STRING (spec))
3007 contents = g_value_dup_string (&value);
3008 else if (G_IS_PARAM_SPEC_ENUM (spec))
3009 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
3010 else if (G_IS_PARAM_SPEC_INT64 (spec))
3011 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
3012 g_value_get_int64 (&value));
3014 contents = g_strdup_value_contents (&value);
3016 xmlNewChild (param, NULL, "value", contents);
3019 g_value_unset(&value);
3023 pads = GST_ELEMENT_PADS (element);
3026 GstPad *pad = GST_PAD (pads->data);
3027 /* figure out if it's a direct pad or a ghostpad */
3028 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
3029 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
3030 gst_object_save_thyself (GST_OBJECT (pad), padtag);
3032 pads = g_list_next (pads);
3039 gst_element_restore_thyself (GstObject *object, xmlNodePtr self)
3041 xmlNodePtr children;
3042 GstElement *element;
3044 gchar *value = NULL;
3046 element = GST_ELEMENT (object);
3047 g_return_if_fail (element != NULL);
3050 children = self->xmlChildrenNode;
3052 if (!strcmp (children->name, "param")) {
3053 xmlNodePtr child = children->xmlChildrenNode;
3056 if (!strcmp (child->name, "name")) {
3057 name = xmlNodeGetContent (child);
3059 else if (!strcmp (child->name, "value")) {
3060 value = xmlNodeGetContent (child);
3062 child = child->next;
3064 /* FIXME: can this just be g_object_set ? */
3065 gst_util_set_object_arg (G_OBJECT (element), name, value);
3066 /* g_object_set (G_OBJECT (element), name, value, NULL); */
3068 children = children->next;
3072 children = self->xmlChildrenNode;
3074 if (!strcmp (children->name, "pad")) {
3075 gst_pad_load_and_link (children, GST_OBJECT (element));
3077 children = children->next;
3080 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3081 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3083 #endif /* GST_DISABLE_LOADSAVE */
3086 * gst_element_yield:
3087 * @element: a #GstElement to yield.
3089 * Requests a yield operation for the element. The scheduler will typically
3090 * give control to another element.
3093 gst_element_yield (GstElement *element)
3095 if (GST_ELEMENT_SCHED (element)) {
3096 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
3101 * gst_element_interrupt:
3102 * @element: a #GstElement to interrupt.
3104 * Requests the scheduler of this element to interrupt the execution of
3105 * this element and scheduler another one.
3107 * Returns: TRUE if the element should exit its chain/loop/get
3108 * function ASAP, depending on the scheduler implementation.
3111 gst_element_interrupt (GstElement *element)
3113 if (GST_ELEMENT_SCHED (element)) {
3114 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
3121 * gst_element_set_scheduler:
3122 * @element: a #GstElement to set the scheduler of.
3123 * @sched: the #GstScheduler to set.
3125 * Sets the scheduler of the element. For internal use only, unless you're
3126 * writing a new bin subclass.
3129 gst_element_set_scheduler (GstElement *element,
3130 GstScheduler *sched)
3132 g_return_if_fail (GST_IS_ELEMENT (element));
3134 GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p", sched);
3136 gst_object_replace ((GstObject **)&GST_ELEMENT_SCHED (element), GST_OBJECT (sched));
3140 * gst_element_get_scheduler:
3141 * @element: a #GstElement to get the scheduler of.
3143 * Returns the scheduler of the element.
3145 * Returns: the element's #GstScheduler.
3148 gst_element_get_scheduler (GstElement *element)
3150 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3152 return GST_ELEMENT_SCHED (element);
3156 * gst_element_set_loop_function:
3157 * @element: a #GstElement to set the loop function of.
3158 * @loop: Pointer to #GstElementLoopFunction.
3160 * This sets the loop function for the element. The function pointed to
3161 * can deviate from the GstElementLoopFunction definition in type of
3164 * NOTE: in order for this to take effect, the current loop function *must*
3165 * exit. Assuming the loop function itself is the only one who will cause
3166 * a new loopfunc to be assigned, this should be no problem.
3169 gst_element_set_loop_function (GstElement *element,
3170 GstElementLoopFunction loop)
3172 gboolean need_notify = FALSE;
3174 g_return_if_fail (GST_IS_ELEMENT (element));
3176 /* if the element changed from loop based to chain/get based
3177 * or vice versa, we need to inform the scheduler about that */
3178 if ((element->loopfunc == NULL && loop != NULL) ||
3179 (element->loopfunc != NULL && loop == NULL))
3184 /* set the loop function */
3185 element->loopfunc = loop;
3188 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
3189 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
3191 if (GST_ELEMENT_SCHED (element)) {
3192 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
3197 gst_element_emit_found_tag (GstElement* element, GstElement *source, const GstTagList *tag_list)
3199 gst_object_ref (GST_OBJECT (element));
3200 g_signal_emit (element, gst_element_signals[FOUND_TAG], 0, source, tag_list);
3201 gst_object_unref (GST_OBJECT (element));
3204 gst_element_found_tag_func (GstElement* element, GstElement *source, const GstTagList *tag_list)
3206 /* tell the parent */
3207 if (GST_OBJECT_PARENT (element)) {
3208 GST_CAT_LOG_OBJECT (GST_CAT_EVENT, element, "forwarding tag event to %s",
3209 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
3210 gst_element_emit_found_tag (GST_ELEMENT (GST_OBJECT_PARENT (element)), source, tag_list);
3214 * gst_element_found_tags:
3215 * @element: the element that found the tags
3216 * @tag_list: the found tags
3218 * This function emits the found_tags signal. This is a recursive signal, so
3219 * every parent will emit that signal, too, before this function returns.
3220 * Only emit this signal, when you extracted these tags out of the data stream,
3221 * not when you handle an event.
3224 gst_element_found_tags (GstElement *element, const GstTagList *tag_list)
3226 gst_element_emit_found_tag (element, element, tag_list);
3229 * gst_element_found_tags_for_pad:
3230 * @element: element that found the tag
3231 * @pad: src pad the tags correspond to
3232 * @timestamp: time the tags were found
3233 * @list: the taglist
3235 * This is a convenience routine for tag finding. Most of the time you only
3236 * want to push the found tags down one pad, in that case this function is for
3237 * you. It takes ownership of the taglist, emits the found-tag signal and pushes
3238 * a tag event down the pad.
3241 gst_element_found_tags_for_pad (GstElement *element, GstPad *pad, GstClockTime timestamp,
3244 GstEvent *tag_event;
3246 g_return_if_fail (GST_IS_ELEMENT (element));
3247 g_return_if_fail (GST_IS_REAL_PAD (pad));
3248 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
3249 g_return_if_fail (element == GST_PAD_PARENT (pad));
3250 g_return_if_fail (list != NULL);
3252 tag_event = gst_event_new_tag (list);
3253 GST_EVENT_TIMESTAMP (tag_event) = timestamp;
3254 gst_element_found_tags (element, gst_event_tag_get_list (tag_event));
3255 if (GST_PAD_IS_USABLE (pad)) {
3256 gst_pad_push (pad, GST_DATA (tag_event));
3258 gst_data_unref (GST_DATA (tag_event));
3263 gst_element_set_eos_recursive (GstElement *element)
3265 /* this function is only called, when we were in PLAYING before. So every
3266 parent that's PAUSED was PLAYING before. That means it has reached EOS. */
3269 GST_CAT_DEBUG (GST_CAT_EVENT, "setting recursive EOS on %s",
3270 GST_OBJECT_NAME (element));
3271 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3273 if (!GST_OBJECT_PARENT (element))
3276 parent = GST_ELEMENT (GST_OBJECT_PARENT (element));
3277 if (GST_STATE (parent) == GST_STATE_PAUSED)
3278 gst_element_set_eos_recursive (parent);
3281 * gst_element_set_eos:
3282 * @element: a #GstElement to set to the EOS state.
3284 * Perform the actions needed to bring the element in the EOS state.
3287 gst_element_set_eos (GstElement *element)
3289 g_return_if_fail (GST_IS_ELEMENT (element));
3291 GST_CAT_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
3292 GST_OBJECT_NAME (element));
3294 if (GST_STATE (element) == GST_STATE_PLAYING) {
3295 gst_element_set_state (element, GST_STATE_PAUSED);
3296 gst_element_set_eos_recursive (element);
3298 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3304 * gst_element_state_get_name:
3305 * @state: a #GstElementState to get the name of.
3307 * Gets a string representing the given state.
3309 * Returns: a string with the name of the state.
3312 gst_element_state_get_name (GstElementState state)
3315 #ifdef GST_DEBUG_COLOR
3316 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
3317 case GST_STATE_NULL: return "\033[01;34mNULL\033[00m";break;
3318 case GST_STATE_READY: return "\033[01;31mREADY\033[00m";break;
3319 case GST_STATE_PLAYING: return "\033[01;32mPLAYING\033[00m";break;
3320 case GST_STATE_PAUSED: return "\033[01;33mPAUSED\033[00m";break;
3322 /* This is a memory leak */
3323 return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
3325 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
3326 case GST_STATE_NULL: return "NULL";break;
3327 case GST_STATE_READY: return "READY";break;
3328 case GST_STATE_PLAYING: return "PLAYING";break;
3329 case GST_STATE_PAUSED: return "PAUSED";break;
3330 default: return "UNKNOWN!";
3337 gst_element_populate_std_props (GObjectClass * klass, const gchar *prop_name,
3338 guint arg_id, GParamFlags flags)
3340 GQuark prop_id = g_quark_from_string (prop_name);
3343 static GQuark fd_id = 0;
3344 static GQuark blocksize_id;
3345 static GQuark bytesperread_id;
3346 static GQuark dump_id;
3347 static GQuark filesize_id;
3348 static GQuark mmapsize_id;
3349 static GQuark location_id;
3350 static GQuark offset_id;
3351 static GQuark silent_id;
3352 static GQuark touch_id;
3355 fd_id = g_quark_from_static_string ("fd");
3356 blocksize_id = g_quark_from_static_string ("blocksize");
3357 bytesperread_id = g_quark_from_static_string ("bytesperread");
3358 dump_id = g_quark_from_static_string ("dump");
3359 filesize_id = g_quark_from_static_string ("filesize");
3360 mmapsize_id = g_quark_from_static_string ("mmapsize");
3361 location_id = g_quark_from_static_string ("location");
3362 offset_id = g_quark_from_static_string ("offset");
3363 silent_id = g_quark_from_static_string ("silent");
3364 touch_id = g_quark_from_static_string ("touch");
3367 if (prop_id == fd_id) {
3368 pspec = g_param_spec_int ("fd", "File-descriptor",
3369 "File-descriptor for the file being read",
3370 0, G_MAXINT, 0, flags);
3372 else if (prop_id == blocksize_id) {
3373 pspec = g_param_spec_ulong ("blocksize", "Block Size",
3374 "Block size to read per buffer",
3375 0, G_MAXULONG, 4096, flags);
3378 else if (prop_id == bytesperread_id) {
3379 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
3380 "Number of bytes to read per buffer",
3381 G_MININT, G_MAXINT, 0, flags);
3384 else if (prop_id == dump_id) {
3385 pspec = g_param_spec_boolean ("dump", "Dump",
3386 "Dump bytes to stdout",
3390 else if (prop_id == filesize_id) {
3391 pspec = g_param_spec_int64 ("filesize", "File Size",
3392 "Size of the file being read",
3393 0, G_MAXINT64, 0, flags);
3396 else if (prop_id == mmapsize_id) {
3397 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
3398 "Size in bytes of mmap()d regions",
3399 0, G_MAXULONG, 4 * 1048576, flags);
3402 else if (prop_id == location_id) {
3403 pspec = g_param_spec_string ("location", "File Location",
3404 "Location of the file to read",
3408 else if (prop_id == offset_id) {
3409 pspec = g_param_spec_int64 ("offset", "File Offset",
3410 "Byte offset of current read pointer",
3411 0, G_MAXINT64, 0, flags);
3414 else if (prop_id == silent_id) {
3415 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
3419 else if (prop_id == touch_id) {
3420 pspec = g_param_spec_boolean ("touch", "Touch read data",
3421 "Touch data to force disk read before "
3422 "push ()", TRUE, flags);
3425 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
3426 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
3431 g_object_class_install_property (klass, arg_id, pspec);
3436 * gst_element_class_install_std_props:
3437 * @klass: the #GstElementClass to add the properties to.
3438 * @first_name: the name of the first property.
3439 * in a NULL terminated
3440 * @...: the id and flags of the first property, followed by
3441 * further 'name', 'id', 'flags' triplets and terminated by NULL.
3443 * Adds a list of standardized properties with types to the @klass.
3444 * the id is for the property switch in your get_prop method, and
3445 * the flags determine readability / writeability.
3448 gst_element_class_install_std_props (GstElementClass * klass,
3449 const gchar *first_name, ...)
3455 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
3457 va_start (args, first_name);
3462 int arg_id = va_arg (args, int);
3463 int flags = va_arg (args, int);
3465 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id, flags);
3467 name = va_arg (args, char *);
3474 * gst_element_get_managing_bin:
3475 * @element: a #GstElement to get the managing bin of.
3477 * Gets the managing bin (a pipeline or a thread, for example) of an element.
3479 * Returns: the #GstBin, or NULL on failure.
3482 gst_element_get_managing_bin (GstElement *element)
3486 g_return_val_if_fail (element != NULL, NULL);
3488 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (element)));
3490 while (bin && !GST_FLAG_IS_SET (GST_OBJECT (bin), GST_BIN_FLAG_MANAGER))
3491 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (bin)));