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, 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_LOG_OBJECT (element, "clock time %llu: setting element time to %llu", event_time, time);
900 element->base_time = event_time - time;
903 g_assert_not_reached ();
909 * gst_element_adjust_time:
910 * @element: element to adjust time on
911 * @difference: difference to adjust
913 * Adjusts the current time of the element by the specified difference. This
914 * function can be used when handling discont events. You can only call this
915 * function on an element with a clock in #GST_STATE_PAUSED or
916 * #GST_STATE_PLAYING. It is more accurate than gst_element_set_time().
919 gst_element_adjust_time (GstElement *element, GstClockTimeDiff diff)
923 g_return_if_fail (GST_IS_ELEMENT (element));
924 g_return_if_fail (GST_IS_CLOCK (element->clock));
925 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
927 switch (element->current_state) {
928 case GST_STATE_PAUSED:
929 if (diff < 0 && element->base_time < abs (diff)) {
930 g_warning ("attempted to set the current time of element %s below 0",
931 GST_OBJECT_NAME (element));
932 element->base_time = 0;
934 element->base_time += diff;
937 case GST_STATE_PLAYING:
938 time = gst_clock_get_time (element->clock);
939 if (time < element->base_time - diff) {
940 g_warning ("attempted to set the current time of element %s below 0",
941 GST_OBJECT_NAME (element));
942 element->base_time = time;
944 element->base_time -= diff;
948 g_assert_not_reached ();
953 #undef GST_CAT_DEFAULT
955 #ifndef GST_DISABLE_INDEX
957 * gst_element_is_indexable:
958 * @element: a #GstElement.
960 * Queries if the element can be indexed.
962 * Returns: TRUE if the element can be indexed.
965 gst_element_is_indexable (GstElement *element)
967 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
969 return (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
973 * gst_element_set_index:
974 * @element: a #GstElement.
975 * @index: a #GstIndex.
977 * Set the specified GstIndex on the element.
980 gst_element_set_index (GstElement *element, GstIndex *index)
982 GstElementClass *oclass;
984 g_return_if_fail (GST_IS_ELEMENT (element));
985 g_return_if_fail (GST_IS_INDEX (index));
987 oclass = GST_ELEMENT_GET_CLASS (element);
989 if (oclass->set_index)
990 oclass->set_index (element, index);
994 * gst_element_get_index:
995 * @element: a #GstElement.
997 * Gets the index from the element.
999 * Returns: a #GstIndex or NULL when no index was set on the
1003 gst_element_get_index (GstElement *element)
1005 GstElementClass *oclass;
1007 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1009 oclass = GST_ELEMENT_GET_CLASS (element);
1011 if (oclass->get_index)
1012 return oclass->get_index (element);
1019 * gst_element_release_locks:
1020 * @element: a #GstElement to release all locks on.
1022 * Instruct the element to release all the locks it is holding, such as
1023 * blocking reads, waiting for the clock, ...
1025 * Returns: TRUE if the locks could be released.
1028 gst_element_release_locks (GstElement *element)
1030 GstElementClass *oclass;
1032 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1034 oclass = GST_ELEMENT_GET_CLASS (element);
1036 if (oclass->release_locks)
1037 return oclass->release_locks (element);
1043 * gst_element_add_pad:
1044 * @element: a #GstElement to add the pad to.
1045 * @pad: the #GstPad to add to the element.
1047 * Add a pad (link point) to the element, setting the parent of the
1048 * pad to the element (and thus adding a reference).
1049 * Pads are automatically activated when the element is in state PLAYING.
1052 gst_element_add_pad (GstElement *element, GstPad *pad)
1054 g_return_if_fail (GST_IS_ELEMENT (element));
1055 g_return_if_fail (GST_IS_PAD (pad));
1057 /* first check to make sure the pad's parent is already set */
1058 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
1060 /* then check to see if there's already a pad by that name here */
1061 g_return_if_fail (gst_object_check_uniqueness (element->pads, GST_PAD_NAME(pad)) == TRUE);
1063 /* set the pad's parent */
1064 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"setting parent of pad '%s' to '%s'",
1065 GST_PAD_NAME (pad), GST_STR_NULL (GST_ELEMENT_NAME (element)));
1066 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
1068 /* add it to the list */
1069 element->pads = g_list_append (element->pads, pad);
1071 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
1072 element->numsrcpads++;
1074 element->numsinkpads++;
1076 /* activate element when we are playing */
1077 if (GST_STATE (element) == GST_STATE_PLAYING)
1078 gst_pad_set_active (pad, TRUE);
1080 /* emit the NEW_PAD signal */
1081 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
1085 * gst_element_remove_pad:
1086 * @element: a #GstElement to remove pad from.
1087 * @pad: the #GstPad to remove from the element.
1089 * Remove a pad (link point) from the element.
1092 gst_element_remove_pad (GstElement *element, GstPad *pad)
1094 g_return_if_fail (element != NULL);
1095 g_return_if_fail (GST_IS_ELEMENT (element));
1096 g_return_if_fail (pad != NULL);
1097 g_return_if_fail (GST_IS_PAD (pad));
1099 g_return_if_fail (GST_PAD_PARENT (pad) == element);
1101 /* check to see if the pad is still linked */
1102 /* FIXME: what if someone calls _remove_pad instead of
1103 _remove_ghost_pad? */
1104 if (GST_IS_REAL_PAD (pad)) {
1105 if (GST_RPAD_PEER (pad) != NULL) {
1106 gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
1110 /* remove it from the list */
1111 element->pads = g_list_remove (element->pads, pad);
1113 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
1114 element->numsrcpads--;
1116 element->numsinkpads--;
1118 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
1120 gst_object_unparent (GST_OBJECT (pad));
1124 * gst_element_add_ghost_pad:
1125 * @element: a #GstElement to add the ghost pad to.
1126 * @pad: the #GstPad from which the new ghost pad will be created.
1127 * @name: the name of the new ghost pad.
1129 * Creates a ghost pad from the given pad, and adds it to the list of pads
1132 * Returns: the added ghost #GstPad, or NULL, if no ghost pad was created.
1135 gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
1139 g_return_val_if_fail (element != NULL, NULL);
1140 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1141 g_return_val_if_fail (pad != NULL, NULL);
1142 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1144 /* then check to see if there's already a pad by that name here */
1145 g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
1147 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1148 "creating new ghost pad called %s, from pad %s:%s",
1149 name, GST_DEBUG_PAD_NAME(pad));
1150 ghostpad = gst_ghost_pad_new (name, pad);
1152 /* add it to the list */
1153 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"adding ghost pad %s to element %s",
1154 name, GST_ELEMENT_NAME (element));
1155 element->pads = g_list_append (element->pads, ghostpad);
1157 /* set the parent of the ghostpad */
1158 gst_object_set_parent (GST_OBJECT (ghostpad), GST_OBJECT (element));
1160 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s",GST_DEBUG_PAD_NAME(ghostpad));
1162 /* emit the NEW_GHOST_PAD signal */
1163 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
1169 * gst_element_remove_ghost_pad:
1170 * @element: a #GstElement to remove the ghost pad from.
1171 * @pad: ghost #GstPad to remove.
1173 * Removes a ghost pad from an element.
1176 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
1178 g_return_if_fail (GST_IS_ELEMENT (element));
1179 g_return_if_fail (GST_IS_GHOST_PAD (pad));
1181 /* FIXME this is redundant?
1182 * wingo 10-july-2001: I don't think so, you have to actually remove the pad
1183 * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
1184 * the real pad's ghost pad list
1186 gst_object_ref (GST_OBJECT (pad));
1187 gst_element_remove_pad (element, pad);
1188 gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
1189 gst_object_unref (GST_OBJECT (pad));
1194 * gst_element_get_pad:
1195 * @element: a #GstElement to find pad of.
1196 * @name: the name of the pad to retrieve.
1198 * Retrieves a pad from the element by name.
1200 * Returns: requested #GstPad if found, otherwise NULL.
1203 gst_element_get_pad (GstElement *element, const gchar *name)
1207 g_return_val_if_fail (element != NULL, NULL);
1208 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1209 g_return_val_if_fail (name != NULL, NULL);
1211 pad = gst_element_get_static_pad (element, name);
1213 pad = gst_element_get_request_pad (element, name);
1219 * gst_element_get_static_pad:
1220 * @element: a #GstElement to find a static pad of.
1221 * @name: the name of the static #GstPad to retrieve.
1223 * Retrieves a pad from the element by name. This version only retrieves
1224 * already-existing (i.e. 'static') pads.
1226 * Returns: the requested #GstPad if found, otherwise NULL.
1229 gst_element_get_static_pad (GstElement *element, const gchar *name)
1233 g_return_val_if_fail (element != NULL, NULL);
1234 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1235 g_return_val_if_fail (name != NULL, NULL);
1237 walk = element->pads;
1241 pad = GST_PAD(walk->data);
1242 if (strcmp (GST_PAD_NAME(pad), name) == 0) {
1243 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1246 walk = g_list_next (walk);
1249 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"", name, GST_OBJECT_NAME (element));
1254 * gst_element_get_request_pad:
1255 * @element: a #GstElement to find a request pad of.
1256 * @name: the name of the request #GstPad to retrieve.
1258 * Retrieves a pad from the element by name. This version only retrieves
1261 * Returns: requested #GstPad if found, otherwise NULL.
1264 gst_element_get_request_pad (GstElement *element, const gchar *name)
1266 GstPadTemplate *templ = NULL;
1268 const gchar *req_name = NULL;
1269 gboolean templ_found = FALSE;
1273 gchar *str, *endptr = NULL;
1275 g_return_val_if_fail (element != NULL, NULL);
1276 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1277 g_return_val_if_fail (name != NULL, NULL);
1279 if (strstr (name, "%")) {
1280 templ = gst_element_get_pad_template (element, name);
1285 list = gst_element_get_pad_template_list(element);
1286 while (!templ_found && list) {
1287 templ = (GstPadTemplate*) list->data;
1288 if (templ->presence == GST_PAD_REQUEST) {
1289 /* we know that %s and %d are the only possibilities because of sanity
1290 checks in gst_pad_template_new */
1291 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name, templ->name_template);
1292 if ((str = strchr (templ->name_template, '%')) &&
1293 strncmp (templ->name_template, name, str - templ->name_template) == 0 &&
1294 strlen (name) > str - templ->name_template) {
1295 data = name + (str - templ->name_template);
1296 if (*(str+1) == 'd') {
1298 n = (gint) strtol (data, &endptr, 10);
1299 if (endptr && *endptr == '\0') {
1319 pad = gst_element_request_pad (element, templ, req_name);
1325 * gst_element_get_pad_list:
1326 * @element: a #GstElement to get pads of.
1328 * Retrieves a list of the pads associated with the element.
1330 * Returns: the #GList of pads.
1333 gst_element_get_pad_list (GstElement *element)
1335 g_return_val_if_fail (element != NULL, NULL);
1336 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1338 /* return the list of pads */
1339 return element->pads;
1343 * gst_element_class_add_pad_template:
1344 * @klass: the #GstElementClass to add the pad template to.
1345 * @templ: a #GstPadTemplate to add to the element class.
1347 * Adds a padtemplate to an element class. This is mainly used in the _base_init
1348 * functions of classes.
1351 gst_element_class_add_pad_template (GstElementClass *klass,
1352 GstPadTemplate *templ)
1354 GstPadTemplate *templ_copy;
1356 g_return_if_fail (klass != NULL);
1357 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1358 g_return_if_fail (templ != NULL);
1359 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1360 /* avoid registering pad templates with the same name */
1361 g_return_if_fail (gst_element_class_get_pad_template (klass, templ->name_template) == NULL);
1363 templ_copy = g_memdup(templ, sizeof(GstPadTemplate));
1365 klass->padtemplates = g_list_append (klass->padtemplates, templ_copy);
1366 klass->numpadtemplates++;
1370 * gst_element_class_set_details:
1371 * @klass: class to set details for
1372 * @details: details to set
1374 * Sets the detailed information for a #GstElementClass.
1375 * <note>This function is for use in _base_init functions only.</note>
1378 gst_element_class_set_details (GstElementClass *klass, const GstElementDetails *details)
1380 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1381 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1383 __gst_element_details_set (&klass->details, details);
1387 * gst_element_class_get_pad_template_list:
1388 * @element: a #GstElementClass to get pad templates of.
1390 * Retrieves a list of the pad templates associated with the element.
1392 * Returns: the #GList of padtemplates.
1395 gst_element_class_get_pad_template_list (GstElementClass *element_class)
1397 g_return_val_if_fail (element_class != NULL, NULL);
1398 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1400 return element_class->padtemplates;
1404 * gst_element_class_get_pad_template:
1405 * @element: a #GstElementClass to get the pad template of.
1406 * @name: the name of the #GstPadTemplate to get.
1408 * Retrieves a padtemplate from this element with the
1411 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1412 * No unreferencing is necessary.
1415 gst_element_class_get_pad_template (GstElementClass *element_class, const gchar *name)
1419 g_return_val_if_fail (element_class != NULL, NULL);
1420 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1421 g_return_val_if_fail (name != NULL, NULL);
1423 padlist = gst_element_class_get_pad_template_list (element_class);
1426 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1428 if (strcmp (padtempl->name_template, name) == 0)
1431 padlist = g_list_next (padlist);
1438 * gst_element_get_pad_template_list:
1439 * @element: a #GstElement to get pad templates of.
1441 * Retrieves a list of the pad templates associated with the element.
1442 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template_list).
1444 * Returns: the #GList of padtemplates.
1447 gst_element_get_pad_template_list (GstElement *element)
1449 g_return_val_if_fail (element != NULL, NULL);
1450 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1452 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1456 * gst_element_get_pad_template:
1457 * @element: a #GstElement to get the pad template of.
1458 * @name: the name of the #GstPadTemplate to get.
1460 * Retrieves a padtemplate from this element with the
1462 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template).
1464 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1465 * No unreferencing is necessary.
1468 gst_element_get_pad_template (GstElement *element, const gchar *name)
1472 g_return_val_if_fail (element != NULL, NULL);
1473 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1474 g_return_val_if_fail (name != NULL, NULL);
1476 padlist = gst_element_get_pad_template_list (element);
1479 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1481 if (!strcmp (padtempl->name_template, name))
1484 padlist = g_list_next (padlist);
1491 * gst_element_get_compatible_pad_template:
1492 * @element: a #GstElement to get a compatible pad template for.
1493 * @compattempl: the #GstPadTemplate to find a compatible template for.
1495 * Generates a pad template for this element compatible with the given
1496 * template (meaning it is able to link with it).
1498 * Returns: the #GstPadTemplate of the element that is compatible with
1499 * the given GstPadTemplate, or NULL if none was found. No unreferencing
1503 gst_element_get_compatible_pad_template (GstElement *element,
1504 GstPadTemplate *compattempl)
1506 GstPadTemplate *newtempl = NULL;
1509 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "gst_element_get_compatible_pad_template()");
1511 g_return_val_if_fail (element != NULL, NULL);
1512 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1513 g_return_val_if_fail (compattempl != NULL, NULL);
1515 padlist = gst_element_get_pad_template_list (element);
1518 GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
1519 gboolean comp = FALSE;
1523 * Check direction (must be opposite)
1526 GST_CAT_DEBUG (GST_CAT_CAPS, "checking direction and caps");
1527 if (padtempl->direction == GST_PAD_SRC &&
1528 compattempl->direction == GST_PAD_SINK) {
1529 GST_CAT_DEBUG (GST_CAT_CAPS, "compatible direction: found src pad template");
1530 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1531 GST_PAD_TEMPLATE_CAPS (padtempl));
1532 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1533 } else if (padtempl->direction == GST_PAD_SINK &&
1534 compattempl->direction == GST_PAD_SRC) {
1535 GST_CAT_DEBUG (GST_CAT_CAPS, "compatible direction: found sink pad template");
1536 comp = gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (compattempl),
1537 GST_PAD_TEMPLATE_CAPS (padtempl));
1538 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible", (comp ? "" : "not "));
1542 newtempl = padtempl;
1546 padlist = g_list_next (padlist);
1553 * gst_element_request_compatible_pad:
1554 * @element: a #GstElement to request a new pad from.
1555 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1557 * Requests a new pad from the element. The template will
1558 * be used to decide what type of pad to create. This function
1559 * is typically used for elements with a padtemplate with presence
1562 * Returns: the new #GstPad that was created, or NULL if none could be created.
1565 gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
1567 GstPadTemplate *templ_new;
1570 g_return_val_if_fail (element != NULL, NULL);
1571 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1572 g_return_val_if_fail (templ != NULL, NULL);
1574 templ_new = gst_element_get_compatible_pad_template (element, templ);
1575 if (templ_new != NULL)
1576 pad = gst_element_request_pad (element, templ_new, NULL);
1583 * gst_element_get_compatible_pad_filtered:
1584 * @element: a #GstElement in which the pad should be found.
1585 * @pad: the #GstPad to find a compatible one for.
1586 * @filtercaps: the #GstCaps to use as a filter.
1588 * Looks for an unlinked pad to which the given pad can link to.
1589 * It is not guaranteed that linking the pads will work, though
1590 * it should work in most cases.
1592 * Returns: the #GstPad to which a link can be made.
1595 gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
1596 const GstCaps *filtercaps)
1599 GstPadTemplate *templ;
1601 GstPad *foundpad = NULL;
1604 g_return_val_if_fail (element != NULL, NULL);
1605 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1606 g_return_val_if_fail (pad != NULL, NULL);
1607 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1609 GST_DEBUG ("finding pad in %s compatible with %s:%s",
1610 GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad));
1612 /* let's use the real pad */
1613 pad = (GstPad *) GST_PAD_REALIZE (pad);
1614 g_return_val_if_fail (pad != NULL, NULL);
1615 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1617 /* try to get an existing unlinked pad */
1618 pads = gst_element_get_pad_list (element);
1620 GstPad *current = GST_PAD (pads->data);
1621 if ((GST_PAD_PEER (GST_PAD_REALIZE (current)) == NULL) &&
1622 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1625 pads = g_list_next (pads);
1628 /* try to create a new one */
1629 /* requesting is a little crazy, we need a template. Let's create one */
1630 templcaps = gst_pad_get_caps (pad);
1631 if (filtercaps != NULL) {
1633 temp = gst_caps_intersect (filtercaps, templcaps);
1634 gst_caps_free (templcaps);
1638 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
1639 GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
1640 foundpad = gst_element_request_compatible_pad (element, templ);
1641 gst_object_unref (GST_OBJECT (templ));
1643 if (foundpad) return foundpad;
1645 /* FIXME: this is broken, but it's in here so autoplugging elements
1646 * that don't have caps on their source padtemplates (spider) can
1648 //g_warning("got here");
1649 //if (filtercaps == NULL) {
1650 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
1651 GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, gst_caps_new_any());
1652 foundpad = gst_element_request_compatible_pad (element, templ);
1653 gst_object_unref (GST_OBJECT (templ));
1655 if (foundpad) return foundpad;
1658 GST_DEBUG_OBJECT (element, "Could not find a compatible pad to link to %s:%s",
1659 GST_DEBUG_PAD_NAME (pad));
1665 * gst_element_get_compatible_pad:
1666 * @element: a #GstElement in which the pad should be found.
1667 * @pad: the #GstPad to find a compatible one for.
1669 * Looks for an unlinked pad to which the given pad can link to.
1670 * It is not guaranteed that linking the pads will work, though
1671 * it should work in most cases.
1673 * Returns: the #GstPad to which a link can be made, or NULL if none
1677 gst_element_get_compatible_pad (GstElement *element, GstPad *pad)
1679 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1683 * gst_element_link_pads_filtered:
1684 * @src: a #GstElement containing the source pad.
1685 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1686 * @dest: the #GstElement containing the destination pad.
1687 * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1688 * @filtercaps: the #GstCaps to use as a filter.
1690 * Links the two named pads of the source and destination elements.
1691 * Side effect is that if one of the pads has no parent, it becomes a
1692 * child of the parent of the other element. If they have different
1693 * parents, the link fails.
1695 * Returns: TRUE if the pads could be linked.
1698 gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
1699 GstElement *dest, const gchar *destpadname,
1700 const GstCaps *filtercaps)
1702 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1703 GstPad *srcpad, *destpad;
1704 GstPadTemplate *srctempl, *desttempl;
1707 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1708 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1710 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "trying to link element %s:%s to element %s:%s",
1711 GST_ELEMENT_NAME (src), srcpadname ? srcpadname : "(any)",
1712 GST_ELEMENT_NAME (dest), destpadname ? destpadname : "(any)");
1714 /* now get the pads we're trying to link and a list of all remaining pads */
1716 srcpad = gst_element_get_pad (src, srcpadname);
1718 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (src), srcpadname);
1721 if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1722 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad", GST_DEBUG_PAD_NAME (srcpad));
1725 if (GST_PAD_PEER (srcpad) != NULL) {
1726 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (srcpad));
1732 srcpads = gst_element_get_pad_list (src);
1733 srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
1736 destpad = gst_element_get_pad (dest, destpadname);
1738 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (dest), destpadname);
1741 if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1742 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad", GST_DEBUG_PAD_NAME (destpad));
1745 if (GST_PAD_PEER (destpad) != NULL) {
1746 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked", GST_DEBUG_PAD_NAME (destpad));
1752 destpads = gst_element_get_pad_list (dest);
1753 destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
1756 if (srcpadname && destpadname) {
1757 /* two explicitly specified pads */
1758 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1761 /* loop through the allowed pads in the source, trying to find a
1762 * compatible destination pad */
1763 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "looping through allowed src and dest pads");
1765 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1766 GST_DEBUG_PAD_NAME (srcpad));
1767 if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1768 (GST_PAD_PEER (srcpad) == NULL)) {
1769 GstPad *temp = gst_element_get_compatible_pad_filtered (dest, srcpad,
1771 if (temp && gst_pad_link_filtered (srcpad, temp, filtercaps)) {
1772 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1773 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1777 /* find a better way for this mess */
1779 srcpads = g_list_next (srcpads);
1781 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1786 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1787 GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1791 /* loop through the existing pads in the destination */
1793 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1794 GST_DEBUG_PAD_NAME (destpad));
1795 if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1796 (GST_PAD_PEER (destpad) == NULL)) {
1797 GstPad *temp = gst_element_get_compatible_pad_filtered (src, destpad,
1799 if (temp && gst_pad_link_filtered (temp, destpad, filtercaps)) {
1800 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1801 GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1806 destpads = g_list_next (destpads);
1808 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1813 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1814 GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1818 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1819 "we might have request pads on both sides, checking...");
1820 srctempls = gst_element_get_pad_template_list (src);
1821 desttempls = gst_element_get_pad_template_list (dest);
1823 if (srctempls && desttempls) {
1825 srctempl = (GstPadTemplate*) srctempls->data;
1826 if (srctempl->presence == GST_PAD_REQUEST) {
1827 for (l=desttempls; l; l=l->next) {
1828 desttempl = (GstPadTemplate*) l->data;
1829 if (desttempl->presence == GST_PAD_REQUEST &&
1830 desttempl->direction != srctempl->direction) {
1831 if (gst_caps_is_always_compatible (gst_pad_template_get_caps (srctempl),
1832 gst_pad_template_get_caps (desttempl))) {
1833 srcpad = gst_element_get_request_pad (src,
1834 srctempl->name_template);
1835 destpad = gst_element_get_request_pad (dest,
1836 desttempl->name_template);
1837 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1838 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1839 "linked pad %s:%s to pad %s:%s",
1840 GST_DEBUG_PAD_NAME (srcpad),
1841 GST_DEBUG_PAD_NAME (destpad));
1844 /* it failed, so we release the request pads */
1845 gst_element_release_request_pad (src, srcpad);
1846 gst_element_release_request_pad (dest, destpad);
1851 srctempls = srctempls->next;
1855 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1856 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1860 * gst_element_link_filtered:
1861 * @src: a #GstElement containing the source pad.
1862 * @dest: the #GstElement containing the destination pad.
1863 * @filtercaps: the #GstCaps to use as a filter.
1865 * Links the source to the destination element using the filtercaps.
1866 * The link must be from source to destination, the other
1867 * direction will not be tried.
1868 * The functions looks for existing pads that aren't linked yet.
1869 * It will use request pads if possible. But both pads will not be requested.
1870 * If multiple links are possible, only one is established.
1872 * Returns: TRUE if the elements could be linked.
1875 gst_element_link_filtered (GstElement *src, GstElement *dest,
1876 const GstCaps *filtercaps)
1878 return gst_element_link_pads_filtered (src, NULL, dest, NULL, filtercaps);
1882 * gst_element_link_many:
1883 * @element_1: the first #GstElement in the link chain.
1884 * @element_2: the second #GstElement in the link chain.
1885 * @...: the NULL-terminated list of elements to link in order.
1887 * Chain together a series of elements. Uses #gst_element_link.
1889 * Returns: TRUE on success, FALSE otherwise.
1892 gst_element_link_many (GstElement *element_1, GstElement *element_2, ...)
1896 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
1897 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
1898 GST_IS_ELEMENT (element_2), FALSE);
1900 va_start (args, element_2);
1903 if (!gst_element_link (element_1, element_2))
1906 element_1 = element_2;
1907 element_2 = va_arg (args, GstElement*);
1917 * @src: a #GstElement containing the source pad.
1918 * @dest: the #GstElement containing the destination pad.
1920 * Links the source to the destination element.
1921 * The link must be from source to destination, the other
1922 * direction will not be tried.
1923 * The functions looks for existing pads and request pads that aren't
1924 * linked yet. If multiple links are possible, only one is
1927 * Returns: TRUE if the elements could be linked.
1930 gst_element_link (GstElement *src, GstElement *dest)
1932 return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1936 * gst_element_link_pads:
1937 * @src: a #GstElement containing the source pad.
1938 * @srcpadname: the name of the #GstPad in the source element.
1939 * @dest: the #GstElement containing the destination pad.
1940 * @destpadname: the name of the #GstPad in destination element.
1942 * Links the two named pads of the source and destination elements.
1943 * Side effect is that if one of the pads has no parent, it becomes a
1944 * child of the parent of the other element. If they have different
1945 * parents, the link fails.
1947 * Returns: TRUE if the pads could be linked.
1950 gst_element_link_pads (GstElement *src, const gchar *srcpadname,
1951 GstElement *dest, const gchar *destpadname)
1953 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname, NULL);
1957 * gst_element_unlink_pads:
1958 * @src: a #GstElement containing the source pad.
1959 * @srcpadname: the name of the #GstPad in source element.
1960 * @dest: a #GstElement containing the destination pad.
1961 * @destpadname: the name of the #GstPad in destination element.
1963 * Unlinks the two named pads of the source and destination elements.
1966 gst_element_unlink_pads (GstElement *src, const gchar *srcpadname,
1967 GstElement *dest, const gchar *destpadname)
1969 GstPad *srcpad,*destpad;
1971 g_return_if_fail (src != NULL);
1972 g_return_if_fail (GST_IS_ELEMENT(src));
1973 g_return_if_fail (srcpadname != NULL);
1974 g_return_if_fail (dest != NULL);
1975 g_return_if_fail (GST_IS_ELEMENT(dest));
1976 g_return_if_fail (destpadname != NULL);
1978 /* obtain the pads requested */
1979 srcpad = gst_element_get_pad (src, srcpadname);
1980 if (srcpad == NULL) {
1981 GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
1984 destpad = gst_element_get_pad (dest, destpadname);
1985 if (srcpad == NULL) {
1986 GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"", destpadname);
1990 /* we're satisified they can be unlinked, let's do it */
1991 gst_pad_unlink (srcpad,destpad);
1995 * gst_element_unlink_many:
1996 * @element_1: the first #GstElement in the link chain.
1997 * @element_2: the second #GstElement in the link chain.
1998 * @...: the NULL-terminated list of elements to unlink in order.
2000 * Unlinks a series of elements. Uses #gst_element_unlink.
2003 gst_element_unlink_many (GstElement *element_1, GstElement *element_2, ...)
2007 g_return_if_fail (element_1 != NULL && element_2 != NULL);
2008 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
2010 va_start (args, element_2);
2013 gst_element_unlink (element_1, element_2);
2015 element_1 = element_2;
2016 element_2 = va_arg (args, GstElement*);
2023 * gst_element_unlink:
2024 * @src: the source #GstElement to unlink.
2025 * @dest: the sink #GstElement to unlink.
2027 * Unlinks all source pads of the source element with all sink pads
2028 * of the sink element to which they are linked.
2031 gst_element_unlink (GstElement *src, GstElement *dest)
2033 const GList *srcpads;
2036 g_return_if_fail (GST_IS_ELEMENT (src));
2037 g_return_if_fail (GST_IS_ELEMENT (dest));
2039 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
2040 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
2042 srcpads = gst_element_get_pad_list (src);
2045 pad = GST_PAD (srcpads->data);
2047 /* we only care about real src pads */
2048 if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
2049 GstPad *peerpad = GST_PAD_PEER (pad);
2051 /* see if the pad is connected and is really a pad
2054 (GST_OBJECT_PARENT (peerpad) == (GstObject*) dest))
2056 gst_pad_unlink (pad, peerpad);
2060 srcpads = g_list_next (srcpads);
2065 gst_element_error_func (GstElement* element, GstElement *source,
2066 GError *error, gchar *debug)
2068 /* tell the parent */
2069 if (GST_OBJECT_PARENT (element)) {
2070 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM, "forwarding error \"%s\" from %s to %s",
2071 error->message, GST_ELEMENT_NAME (element),
2072 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2074 gst_object_ref (GST_OBJECT (element));
2075 g_signal_emit (G_OBJECT (GST_OBJECT_PARENT (element)),
2076 gst_element_signals[ERROR], 0, source, error, debug);
2077 gst_object_unref (GST_OBJECT (element));
2078 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM, "forwarded error \"%s\" from %s to %s",
2079 error->message, GST_ELEMENT_NAME (element),
2080 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
2085 gst_element_get_random_pad (GstElement *element, GstPadDirection dir)
2087 GList *pads = element->pads;
2088 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
2090 GstPad *pad = GST_PAD (pads->data);
2092 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
2093 GST_DEBUG_PAD_NAME (pad));
2095 if (GST_PAD_DIRECTION (pad) == dir) {
2096 if (GST_PAD_IS_LINKED (pad)) {
2100 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
2101 GST_DEBUG_PAD_NAME (pad));
2105 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
2106 GST_DEBUG_PAD_NAME (pad));
2109 pads = g_list_next (pads);
2115 * gst_element_get_event_masks:
2116 * @element: a #GstElement to query
2118 * Get an array of event masks from the element.
2119 * If the element doesn't
2120 * implement an event masks function, the query will be forwarded
2121 * to a random linked sink pad.
2123 * Returns: An array of #GstEventMask elements.
2126 gst_element_get_event_masks (GstElement *element)
2128 GstElementClass *oclass;
2130 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2132 oclass = GST_ELEMENT_GET_CLASS (element);
2134 if (oclass->get_event_masks)
2135 return oclass->get_event_masks (element);
2137 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2139 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
2146 * gst_element_send_event:
2147 * @element: a #GstElement to send the event to.
2148 * @event: the #GstEvent to send to the element.
2150 * Sends an event to an element. If the element doesn't
2151 * implement an event handler, the event will be forwarded
2152 * to a random sink pad.
2154 * Returns: TRUE if the event was handled.
2157 gst_element_send_event (GstElement *element, GstEvent *event)
2159 GstElementClass *oclass;
2161 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2162 g_return_val_if_fail (event != NULL, FALSE);
2164 oclass = GST_ELEMENT_GET_CLASS (element);
2166 if (oclass->send_event)
2167 return oclass->send_event (element, event);
2169 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2171 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
2172 GST_DEBUG_PAD_NAME (pad));
2173 return gst_pad_send_event (GST_PAD_PEER (pad), event);
2176 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
2177 GST_ELEMENT_NAME (element));
2183 * @element: a #GstElement to send the event to.
2184 * @seek_type: the method to use for seeking.
2185 * @offset: the offset to seek to.
2187 * Sends a seek event to an element.
2189 * Returns: TRUE if the event was handled.
2192 gst_element_seek (GstElement *element,
2193 GstSeekType seek_type,
2196 GstEvent *event = gst_event_new_seek (seek_type, offset);
2198 return gst_element_send_event (element, event);
2202 * gst_element_get_query_types:
2203 * @element: a #GstElement to query
2205 * Get an array of query types from the element.
2206 * If the element doesn't
2207 * implement a query types function, the query will be forwarded
2208 * to a random sink pad.
2210 * Returns: An array of #GstQueryType elements.
2213 gst_element_get_query_types (GstElement *element)
2215 GstElementClass *oclass;
2217 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2219 oclass = GST_ELEMENT_GET_CLASS (element);
2221 if (oclass->get_query_types)
2222 return oclass->get_query_types (element);
2224 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2226 return gst_pad_get_query_types (GST_PAD_PEER (pad));
2233 * gst_element_query:
2234 * @element: a #GstElement to perform the query on.
2235 * @type: the #GstQueryType.
2236 * @format: the #GstFormat pointer to hold the format of the result.
2237 * @value: the pointer to the value of the result.
2239 * Performs a query on the given element. If the format is set
2240 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
2241 * format pointer will hold the default format.
2242 * For element that don't implement a query handler, this function
2243 * forwards the query to a random usable sinkpad of this element.
2245 * Returns: TRUE if the query could be performed.
2248 gst_element_query (GstElement *element, GstQueryType type,
2249 GstFormat *format, gint64 *value)
2251 GstElementClass *oclass;
2253 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2254 g_return_val_if_fail (format != NULL, FALSE);
2255 g_return_val_if_fail (value != NULL, FALSE);
2257 oclass = GST_ELEMENT_GET_CLASS (element);
2260 return oclass->query (element, type, format, value);
2262 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
2264 return gst_pad_query (pad, type, format, value);
2265 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2267 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
2274 * gst_element_get_formats:
2275 * @element: a #GstElement to query
2277 * Get an array of formst from the element.
2278 * If the element doesn't
2279 * implement a formats function, the query will be forwarded
2280 * to a random sink pad.
2282 * Returns: An array of #GstFormat elements.
2285 gst_element_get_formats (GstElement *element)
2287 GstElementClass *oclass;
2289 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2291 oclass = GST_ELEMENT_GET_CLASS (element);
2293 if (oclass->get_formats)
2294 return oclass->get_formats (element);
2296 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2298 return gst_pad_get_formats (GST_PAD_PEER (pad));
2305 * gst_element_convert:
2306 * @element: a #GstElement to invoke the converter on.
2307 * @src_format: the source #GstFormat.
2308 * @src_value: the source value.
2309 * @dest_format: a pointer to the destination #GstFormat.
2310 * @dest_value: a pointer to the destination value.
2312 * Invokes a conversion on the element.
2313 * If the element doesn't
2314 * implement a convert function, the query will be forwarded
2315 * to a random sink pad.
2317 * Returns: TRUE if the conversion could be performed.
2320 gst_element_convert (GstElement *element,
2321 GstFormat src_format, gint64 src_value,
2322 GstFormat *dest_format, gint64 *dest_value)
2324 GstElementClass *oclass;
2326 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2327 g_return_val_if_fail (dest_format != NULL, FALSE);
2328 g_return_val_if_fail (dest_value != NULL, FALSE);
2330 if (src_format == *dest_format) {
2331 *dest_value = src_value;
2335 oclass = GST_ELEMENT_GET_CLASS (element);
2337 if (oclass->convert)
2338 return oclass->convert (element,
2339 src_format, src_value,
2340 dest_format, dest_value);
2342 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2344 return gst_pad_convert (GST_PAD_PEER (pad),
2345 src_format, src_value,
2346 dest_format, dest_value);
2353 * _gst_element_error_printf:
2354 * @format: the printf-like format to use, or NULL
2356 * This function is only used internally by the #gst_element_error macro.
2358 * Returns: a newly allocated string, or NULL if the format was NULL or ""
2361 _gst_element_error_printf (const gchar *format, ...)
2366 if (format == NULL) return NULL;
2367 if (format[0] == 0) return NULL;
2369 va_start (args, format);
2370 buffer = g_strdup_vprintf (format, args);
2376 * gst_element_error_full:
2377 * @element: a #GstElement with the error.
2378 * @domain: the GStreamer error domain this error belongs to.
2379 * @code: the error code belonging to the domain
2380 * @message: an allocated message to be used as a replacement for the default
2381 * message connected to code, or NULL
2382 * debug: an allocated debug message to be used as a replacement for the
2383 * default debugging information, or NULL
2385 * Signals an error condition on an element.
2386 * This function is used internally by elements.
2387 * It results in the "error" signal.
2390 gst_element_error_full
2391 (GstElement *element, GQuark domain, gint code, gchar *message, gchar *debug,
2392 const gchar *file, const gchar *function, gint line)
2394 GError *error = NULL;
2395 gchar *sent_message;
2399 g_return_if_fail (GST_IS_ELEMENT (element));
2401 /* check if we send the given message or the default error message */
2402 if ((message == NULL) || (message[0] == 0))
2404 /* we got this message from g_strdup_printf (""); */
2406 sent_message = gst_error_get_message (domain, code);
2409 sent_message = message;
2411 if ((debug == NULL) || (debug[0] == 0))
2413 /* we got this debug from g_strdup_printf (""); */
2418 /* create error message */
2419 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signaling error in %s: %s",
2420 GST_ELEMENT_NAME (element),
2422 error = g_error_new (domain, code, sent_message);
2424 /* if the element was already in error, stop now */
2425 if (GST_FLAG_IS_SET (element, GST_ELEMENT_ERROR)) {
2426 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "recursive ERROR detected in %s",
2427 GST_ELEMENT_NAME (element));
2428 g_free (sent_message);
2429 if (debug) g_free (debug);
2433 GST_FLAG_SET (element, GST_ELEMENT_ERROR);
2435 /* emit the signal, make sure the element stays available */
2436 gst_object_ref (GST_OBJECT (element));
2438 sent_debug = g_strdup_printf ("%s(%d):%s:\n%s",
2439 file, line, function,
2440 debug ? debug : "");
2444 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element,
2446 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signalled error in %s: %s",
2447 GST_ELEMENT_NAME (element),
2450 /* tell the scheduler */
2451 if (element->sched) {
2452 gst_scheduler_error (element->sched, element);
2455 if (GST_STATE (element) == GST_STATE_PLAYING) {
2456 GstElementStateReturn ret;
2458 ret = gst_element_set_state (element, GST_STATE_PAUSED);
2459 if (ret != GST_STATE_SUCCESS) {
2460 g_warning ("could not PAUSE element \"%s\" after error, help!",
2461 GST_ELEMENT_NAME (element));
2465 GST_FLAG_UNSET (element, GST_ELEMENT_ERROR);
2468 gst_object_unref (GST_OBJECT (element));
2469 g_free (sent_message);
2470 g_free (sent_debug);
2471 g_error_free (error);
2475 * gst_element_is_locked_state:
2476 * @element: a #GstElement.
2478 * Checks if the state of an element is locked.
2479 * If the state of an element is locked, state changes of the parent don't
2480 * affect the element.
2481 * This way you can leave currently unused elements inside bins. Just lock their
2482 * state before changing the state from #GST_STATE_NULL.
2484 * Returns: TRUE, if the element's state is locked.
2487 gst_element_is_locked_state (GstElement *element)
2489 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2491 return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
2494 * gst_element_set_locked_state:
2495 * @element: a #GstElement
2496 * @locked_state: TRUE to lock the element's state
2498 * Locks the state of an element, so state changes of the parent don't affect
2499 * this element anymore.
2502 gst_element_set_locked_state (GstElement *element, gboolean locked_state)
2506 g_return_if_fail (GST_IS_ELEMENT (element));
2508 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2510 if (old == locked_state)
2514 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2515 GST_ELEMENT_NAME (element));
2516 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2518 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2519 GST_ELEMENT_NAME (element));
2520 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2524 * gst_element_sync_state_with_parent:
2525 * @element: a #GstElement.
2527 * Tries to change the state of the element to the same as its parent.
2528 * If this function returns FALSE, the state of element is undefined.
2530 * Returns: TRUE, if the element's state could be synced to the parent's state.
2533 gst_element_sync_state_with_parent (GstElement *element)
2537 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2538 parent = GST_ELEMENT (GST_ELEMENT_PARENT(element));
2539 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
2541 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
2542 GST_ELEMENT_NAME (element), gst_element_state_get_name (GST_STATE (element)),
2543 GST_ELEMENT_NAME (parent), gst_element_state_get_name (GST_STATE (parent)));
2544 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
2550 * gst_element_get_state:
2551 * @element: a #GstElement to get the state of.
2553 * Gets the state of the element.
2555 * Returns: the #GstElementState of the element.
2558 gst_element_get_state (GstElement *element)
2560 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2562 return GST_STATE (element);
2566 * gst_element_wait_state_change:
2567 * @element: a #GstElement to wait for a state change on.
2569 * Waits and blocks until the element changed its state.
2572 gst_element_wait_state_change (GstElement *element)
2574 g_mutex_lock (element->state_mutex);
2575 g_cond_wait (element->state_cond, element->state_mutex);
2576 g_mutex_unlock (element->state_mutex);
2580 * gst_element_set_state:
2581 * @element: a #GstElement to change state of.
2582 * @state: the element's new #GstElementState.
2584 * Sets the state of the element. This function will try to set the
2585 * requested state by going through all the intermediary states and calling
2586 * the class's state change function for each.
2588 * Returns: TRUE if the state was successfully set.
2589 * (using #GstElementStateReturn).
2591 GstElementStateReturn
2592 gst_element_set_state (GstElement *element, GstElementState state)
2594 GstElementClass *oclass;
2595 GstElementState curpending;
2596 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2598 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2600 /* start with the current state */
2601 curpending = GST_STATE(element);
2603 if (state == curpending)
2605 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2606 "element is already in requested state %s",
2607 gst_element_state_get_name (state));
2608 return (GST_STATE_SUCCESS);
2611 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
2612 gst_element_state_get_name (curpending),
2613 gst_element_state_get_name (state));
2615 /* loop until the final requested state is set */
2616 while (GST_STATE (element) != state
2617 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2618 /* move the curpending state in the correct direction */
2619 if (curpending < state)
2624 /* set the pending state variable */
2625 /* FIXME: should probably check to see that we don't already have one */
2626 GST_STATE_PENDING (element) = curpending;
2628 if (curpending != state) {
2629 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2630 "intermediate: setting state from %s to %s",
2631 gst_element_state_get_name (GST_STATE (element)),
2632 gst_element_state_get_name (curpending));
2635 /* call the state change function so it can set the state */
2636 oclass = GST_ELEMENT_GET_CLASS (element);
2637 if (oclass->change_state)
2638 return_val = (oclass->change_state) (element);
2640 switch (return_val) {
2641 case GST_STATE_FAILURE:
2642 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2643 "have failed change_state return");
2645 case GST_STATE_ASYNC:
2646 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2647 "element will change state async");
2649 case GST_STATE_SUCCESS:
2650 /* Last thing we do is verify that a successful state change really
2651 * did change the state... */
2652 /* if it did not, this is an error - fix the element that does this */
2653 if (GST_STATE (element) != curpending) {
2654 g_warning ("element %s claimed state-change success,"
2655 "but state didn't change to %s. State is %s (%s pending), fix the element",
2656 GST_ELEMENT_NAME (element),
2657 gst_element_state_get_name (curpending),
2658 gst_element_state_get_name (GST_STATE (element)),
2659 gst_element_state_get_name (GST_STATE_PENDING (element)));
2660 return_val = GST_STATE_FAILURE;
2665 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2666 g_assert_not_reached ();
2675 gst_element_negotiate_pads (GstElement *element)
2677 GList *pads = GST_ELEMENT_PADS (element);
2679 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating pads");
2682 GstPad *pad = GST_PAD (pads->data);
2685 pads = g_list_next (pads);
2687 if (!GST_IS_REAL_PAD (pad))
2690 srcpad = GST_PAD_REALIZE (pad);
2692 /* if we have a link on this pad and it doesn't have caps
2693 * allready, try to negotiate */
2694 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2695 GstRealPad *sinkpad;
2696 GstElementState otherstate;
2699 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2701 /* check the parent of the peer pad, if there is no parent do nothing */
2702 parent = GST_PAD_PARENT (sinkpad);
2706 /* skips pads that were already negotiating */
2707 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2708 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2711 otherstate = GST_STATE (parent);
2713 /* swap pads if needed */
2714 if (!GST_PAD_IS_SRC (srcpad)) {
2722 /* only try to negotiate if the peer element is in PAUSED or higher too */
2723 if (otherstate >= GST_STATE_READY) {
2724 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2725 "perform negotiate for %s:%s and %s:%s",
2726 GST_DEBUG_PAD_NAME (srcpad),
2727 GST_DEBUG_PAD_NAME (sinkpad));
2728 if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
2732 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2733 "not negotiating %s:%s and %s:%s, not in READY yet",
2734 GST_DEBUG_PAD_NAME (srcpad),
2735 GST_DEBUG_PAD_NAME (sinkpad));
2744 gst_element_clear_pad_caps (GstElement *element)
2746 GList *pads = GST_ELEMENT_PADS (element);
2748 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "clearing pad caps");
2751 GstPad *pad = GST_PAD (pads->data);
2753 gst_pad_unnegotiate (pad);
2755 pads = g_list_next (pads);
2760 gst_element_pads_activate (GstElement *element, gboolean active)
2762 GList *pads = element->pads;
2765 GstPad *pad = GST_PAD (pads->data);
2766 pads = g_list_next (pads);
2768 if (!GST_IS_REAL_PAD (pad))
2771 gst_pad_set_active (pad, active);
2775 static GstElementStateReturn
2776 gst_element_change_state (GstElement *element)
2778 GstElementState old_state;
2780 gint old_pending, old_transition;
2782 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2784 old_state = GST_STATE (element);
2785 old_pending = GST_STATE_PENDING (element);
2786 old_transition = GST_STATE_TRANSITION (element);
2788 if (old_pending == GST_STATE_VOID_PENDING ||
2789 old_state == GST_STATE_PENDING (element)) {
2790 GST_CAT_INFO (GST_CAT_STATES,
2791 "no state change needed for element %s (VOID_PENDING)",
2792 GST_ELEMENT_NAME (element));
2793 return GST_STATE_SUCCESS;
2796 GST_CAT_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %04x",
2797 GST_ELEMENT_NAME (element),
2798 gst_element_state_get_name (old_state),
2799 gst_element_state_get_name (old_pending),
2802 /* we set the state change early for the negotiation functions */
2803 GST_STATE (element) = old_pending;
2804 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2806 switch (old_transition) {
2807 case GST_STATE_PLAYING_TO_PAUSED:
2808 if (element->clock) {
2809 GstClockTime time = gst_clock_get_event_time (element->clock);
2810 g_assert (time >= element->base_time);
2811 element->base_time = time - element->base_time;
2812 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2813 G_GINT64_FORMAT, element->base_time);
2815 gst_element_pads_activate (element, FALSE);
2817 case GST_STATE_PAUSED_TO_PLAYING:
2818 gst_element_pads_activate (element, TRUE);
2819 if (element->clock) {
2820 GstClockTime time = gst_clock_get_event_time (element->clock);
2821 element->base_time = time - element->base_time;
2822 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2823 G_GINT64_FORMAT, element->base_time);
2826 /* if we are going to paused, we try to negotiate the pads */
2827 case GST_STATE_READY_TO_PAUSED:
2828 g_assert (element->base_time == 0);
2829 if (!gst_element_negotiate_pads (element))
2832 /* going to the READY state clears all pad caps */
2833 /* FIXME: Why doesn't this happen on READY => NULL? -- Company */
2834 case GST_STATE_PAUSED_TO_READY:
2835 element->base_time = 0;
2836 gst_element_clear_pad_caps (element);
2842 parent = GST_ELEMENT_PARENT (element);
2844 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2845 "signaling state change from %s to %s",
2846 gst_element_state_get_name (old_state),
2847 gst_element_state_get_name (GST_STATE (element)));
2849 /* tell the scheduler if we have one */
2850 if (element->sched) {
2851 if (gst_scheduler_state_transition (element->sched, element,
2852 old_transition) != GST_STATE_SUCCESS) {
2853 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2854 "scheduler could not change state");
2859 /* tell our parent about the state change */
2860 if (parent && GST_IS_BIN (parent)) {
2861 gst_bin_child_state_change (GST_BIN (parent), old_state,
2862 GST_STATE (element), element);
2864 /* at this point the state of the element could have changed again */
2866 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
2867 0, old_state, GST_STATE (element));
2869 /* signal the state change in case somebody is waiting for us */
2870 g_mutex_lock (element->state_mutex);
2871 g_cond_signal (element->state_cond);
2872 g_mutex_unlock (element->state_mutex);
2874 return GST_STATE_SUCCESS;
2877 /* undo the state change */
2878 GST_STATE (element) = old_state;
2879 GST_STATE_PENDING (element) = old_pending;
2881 return GST_STATE_FAILURE;
2885 * gst_element_get_factory:
2886 * @element: a #GstElement to request the element factory of.
2888 * Retrieves the factory that was used to create this element.
2890 * Returns: the #GstElementFactory used for creating this element.
2893 gst_element_get_factory (GstElement *element)
2895 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2897 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2901 gst_element_dispose (GObject *object)
2903 GstElement *element = GST_ELEMENT (object);
2907 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2909 gst_element_set_state (element, GST_STATE_NULL);
2911 /* first we break all our links with the ouside */
2912 if (element->pads) {
2914 orig = pads = g_list_copy (element->pads);
2916 pad = GST_PAD (pads->data);
2918 if (GST_PAD_PEER (pad)) {
2919 GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "unlinking pad '%s'",
2920 GST_OBJECT_NAME (GST_OBJECT (GST_PAD (GST_PAD_PEER (pad)))));
2921 gst_pad_unlink (pad, GST_PAD (GST_PAD_PEER (pad)));
2923 gst_element_remove_pad (element, pad);
2925 pads = g_list_next (pads);
2928 g_list_free (element->pads);
2929 element->pads = NULL;
2932 element->numsrcpads = 0;
2933 element->numsinkpads = 0;
2934 element->numpads = 0;
2935 g_mutex_free (element->state_mutex);
2936 g_cond_free (element->state_cond);
2938 if (element->prop_value_queue)
2939 g_async_queue_unref (element->prop_value_queue);
2940 element->prop_value_queue = NULL;
2941 if (element->property_mutex)
2942 g_mutex_free (element->property_mutex);
2944 gst_object_replace ((GstObject **)&element->sched, NULL);
2945 gst_object_replace ((GstObject **)&element->clock, NULL);
2947 G_OBJECT_CLASS (parent_class)->dispose (object);
2950 #ifndef GST_DISABLE_LOADSAVE
2952 * gst_element_save_thyself:
2953 * @element: a #GstElement to save.
2954 * @parent: the xml parent node.
2956 * Saves the element as part of the given XML structure.
2958 * Returns: the new #xmlNodePtr.
2961 gst_element_save_thyself (GstObject *object,
2965 GstElementClass *oclass;
2966 GParamSpec **specs, *spec;
2968 GValue value = { 0, };
2969 GstElement *element;
2971 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2973 element = GST_ELEMENT (object);
2975 oclass = GST_ELEMENT_GET_CLASS (element);
2977 xmlNewChild(parent, NULL, "name", GST_ELEMENT_NAME(element));
2979 if (oclass->elementfactory != NULL) {
2980 GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory;
2982 xmlNewChild (parent, NULL, "type",
2983 GST_PLUGIN_FEATURE (factory)->name);
2986 /* FIXME: what is this? */
2987 /* if (element->manager) */
2988 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
2991 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2993 for (i=0; i<nspecs; i++) {
2995 if (spec->flags & G_PARAM_READABLE) {
2999 g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
3001 g_object_get_property (G_OBJECT (element), spec->name, &value);
3002 param = xmlNewChild (parent, NULL, "param", NULL);
3003 xmlNewChild (param, NULL, "name", spec->name);
3005 if (G_IS_PARAM_SPEC_STRING (spec))
3006 contents = g_value_dup_string (&value);
3007 else if (G_IS_PARAM_SPEC_ENUM (spec))
3008 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
3009 else if (G_IS_PARAM_SPEC_INT64 (spec))
3010 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
3011 g_value_get_int64 (&value));
3013 contents = g_strdup_value_contents (&value);
3015 xmlNewChild (param, NULL, "value", contents);
3018 g_value_unset(&value);
3022 pads = GST_ELEMENT_PADS (element);
3025 GstPad *pad = GST_PAD (pads->data);
3026 /* figure out if it's a direct pad or a ghostpad */
3027 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
3028 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
3029 gst_object_save_thyself (GST_OBJECT (pad), padtag);
3031 pads = g_list_next (pads);
3038 gst_element_restore_thyself (GstObject *object, xmlNodePtr self)
3040 xmlNodePtr children;
3041 GstElement *element;
3043 gchar *value = NULL;
3045 element = GST_ELEMENT (object);
3046 g_return_if_fail (element != NULL);
3049 children = self->xmlChildrenNode;
3051 if (!strcmp (children->name, "param")) {
3052 xmlNodePtr child = children->xmlChildrenNode;
3055 if (!strcmp (child->name, "name")) {
3056 name = xmlNodeGetContent (child);
3058 else if (!strcmp (child->name, "value")) {
3059 value = xmlNodeGetContent (child);
3061 child = child->next;
3063 /* FIXME: can this just be g_object_set ? */
3064 gst_util_set_object_arg (G_OBJECT (element), name, value);
3065 /* g_object_set (G_OBJECT (element), name, value, NULL); */
3067 children = children->next;
3071 children = self->xmlChildrenNode;
3073 if (!strcmp (children->name, "pad")) {
3074 gst_pad_load_and_link (children, GST_OBJECT (element));
3076 children = children->next;
3079 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3080 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3082 #endif /* GST_DISABLE_LOADSAVE */
3085 * gst_element_yield:
3086 * @element: a #GstElement to yield.
3088 * Requests a yield operation for the element. The scheduler will typically
3089 * give control to another element.
3092 gst_element_yield (GstElement *element)
3094 if (GST_ELEMENT_SCHED (element)) {
3095 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
3100 * gst_element_interrupt:
3101 * @element: a #GstElement to interrupt.
3103 * Requests the scheduler of this element to interrupt the execution of
3104 * this element and scheduler another one.
3106 * Returns: TRUE if the element should exit its chain/loop/get
3107 * function ASAP, depending on the scheduler implementation.
3110 gst_element_interrupt (GstElement *element)
3112 if (GST_ELEMENT_SCHED (element)) {
3113 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
3120 * gst_element_set_scheduler:
3121 * @element: a #GstElement to set the scheduler of.
3122 * @sched: the #GstScheduler to set.
3124 * Sets the scheduler of the element. For internal use only, unless you're
3125 * writing a new bin subclass.
3128 gst_element_set_scheduler (GstElement *element,
3129 GstScheduler *sched)
3131 g_return_if_fail (GST_IS_ELEMENT (element));
3133 GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p", sched);
3135 gst_object_replace ((GstObject **)&GST_ELEMENT_SCHED (element), GST_OBJECT (sched));
3139 * gst_element_get_scheduler:
3140 * @element: a #GstElement to get the scheduler of.
3142 * Returns the scheduler of the element.
3144 * Returns: the element's #GstScheduler.
3147 gst_element_get_scheduler (GstElement *element)
3149 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3151 return GST_ELEMENT_SCHED (element);
3155 * gst_element_set_loop_function:
3156 * @element: a #GstElement to set the loop function of.
3157 * @loop: Pointer to #GstElementLoopFunction.
3159 * This sets the loop function for the element. The function pointed to
3160 * can deviate from the GstElementLoopFunction definition in type of
3163 * NOTE: in order for this to take effect, the current loop function *must*
3164 * exit. Assuming the loop function itself is the only one who will cause
3165 * a new loopfunc to be assigned, this should be no problem.
3168 gst_element_set_loop_function (GstElement *element,
3169 GstElementLoopFunction loop)
3171 gboolean need_notify = FALSE;
3173 g_return_if_fail (GST_IS_ELEMENT (element));
3175 /* if the element changed from loop based to chain/get based
3176 * or vice versa, we need to inform the scheduler about that */
3177 if ((element->loopfunc == NULL && loop != NULL) ||
3178 (element->loopfunc != NULL && loop == NULL))
3183 /* set the loop function */
3184 element->loopfunc = loop;
3187 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
3188 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
3190 if (GST_ELEMENT_SCHED (element)) {
3191 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
3196 gst_element_emit_found_tag (GstElement* element, GstElement *source, GstTagList *tag_list)
3198 gst_object_ref (GST_OBJECT (element));
3199 g_signal_emit (element, gst_element_signals[FOUND_TAG], 0, source, tag_list);
3200 gst_object_unref (GST_OBJECT (element));
3203 gst_element_found_tag_func (GstElement* element, GstElement *source, GstTagList *tag_list)
3205 /* tell the parent */
3206 if (GST_OBJECT_PARENT (element)) {
3207 GST_CAT_LOG_OBJECT (GST_CAT_EVENT, element, "forwarding tag event to %s",
3208 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
3209 gst_element_emit_found_tag (GST_ELEMENT (GST_OBJECT_PARENT (element)), source, tag_list);
3213 * gst_element_found_tags:
3214 * @element: the element that found the tags
3215 * @tag_list: the found tags
3217 * This function emits the found_tags signal. This is a recursive signal, so
3218 * every parent will emit that signal, too, before this function returns.
3219 * Only emit this signal, when you extracted these tags out of the data stream,
3220 * not when you handle an event.
3223 gst_element_found_tags (GstElement *element, GstTagList *tag_list)
3225 gst_element_emit_found_tag (element, element, tag_list);
3228 * gst_element_found_tags_for_pad:
3229 * @element: element that found the tag
3230 * @pad: src pad the tags correspond to
3231 * @timestamp: time the tags were found
3232 * @list: the taglist
3234 * This is a convenience routine for tag finding. Most of the time you only
3235 * want to push the found tags down one pad, in that case this function is for
3236 * you. It takes ownership of the taglist, emits the found-tag signal and pushes
3237 * a tag event down the pad.
3240 gst_element_found_tags_for_pad (GstElement *element, GstPad *pad, GstClockTime timestamp,
3243 GstEvent *tag_event;
3245 g_return_if_fail (GST_IS_ELEMENT (element));
3246 g_return_if_fail (GST_IS_REAL_PAD (pad));
3247 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
3248 g_return_if_fail (element == GST_PAD_PARENT (pad));
3249 g_return_if_fail (list != NULL);
3251 tag_event = gst_event_new_tag (list);
3252 GST_EVENT_TIMESTAMP (tag_event) = timestamp;
3253 gst_element_found_tags (element, gst_event_tag_get_list (tag_event));
3254 if (GST_PAD_IS_USABLE (pad)) {
3255 gst_pad_push (pad, GST_DATA (tag_event));
3257 gst_data_unref (GST_DATA (tag_event));
3262 gst_element_set_eos_recursive (GstElement *element)
3264 /* this function is only called, when we were in PLAYING before. So every
3265 parent that's PAUSED was PLAYING before. That means it has reached EOS. */
3268 GST_CAT_DEBUG (GST_CAT_EVENT, "setting recursive EOS on %s",
3269 GST_OBJECT_NAME (element));
3270 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3272 if (!GST_OBJECT_PARENT (element))
3275 parent = GST_ELEMENT (GST_OBJECT_PARENT (element));
3276 if (GST_STATE (parent) == GST_STATE_PAUSED)
3277 gst_element_set_eos_recursive (parent);
3280 * gst_element_set_eos:
3281 * @element: a #GstElement to set to the EOS state.
3283 * Perform the actions needed to bring the element in the EOS state.
3286 gst_element_set_eos (GstElement *element)
3288 g_return_if_fail (GST_IS_ELEMENT (element));
3290 GST_CAT_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
3291 GST_OBJECT_NAME (element));
3293 if (GST_STATE (element) == GST_STATE_PLAYING) {
3294 gst_element_set_state (element, GST_STATE_PAUSED);
3295 gst_element_set_eos_recursive (element);
3297 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3303 * gst_element_state_get_name:
3304 * @state: a #GstElementState to get the name of.
3306 * Gets a string representing the given state.
3308 * Returns: a string with the name of the state.
3311 gst_element_state_get_name (GstElementState state)
3314 #ifdef GST_DEBUG_COLOR
3315 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
3316 case GST_STATE_NULL: return "\033[01;34mNULL\033[00m";break;
3317 case GST_STATE_READY: return "\033[01;31mREADY\033[00m";break;
3318 case GST_STATE_PLAYING: return "\033[01;32mPLAYING\033[00m";break;
3319 case GST_STATE_PAUSED: return "\033[01;33mPAUSED\033[00m";break;
3321 /* This is a memory leak */
3322 return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
3324 case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
3325 case GST_STATE_NULL: return "NULL";break;
3326 case GST_STATE_READY: return "READY";break;
3327 case GST_STATE_PLAYING: return "PLAYING";break;
3328 case GST_STATE_PAUSED: return "PAUSED";break;
3329 default: return "UNKNOWN!";
3336 gst_element_populate_std_props (GObjectClass * klass, const gchar *prop_name,
3337 guint arg_id, GParamFlags flags)
3339 GQuark prop_id = g_quark_from_string (prop_name);
3342 static GQuark fd_id = 0;
3343 static GQuark blocksize_id;
3344 static GQuark bytesperread_id;
3345 static GQuark dump_id;
3346 static GQuark filesize_id;
3347 static GQuark mmapsize_id;
3348 static GQuark location_id;
3349 static GQuark offset_id;
3350 static GQuark silent_id;
3351 static GQuark touch_id;
3354 fd_id = g_quark_from_static_string ("fd");
3355 blocksize_id = g_quark_from_static_string ("blocksize");
3356 bytesperread_id = g_quark_from_static_string ("bytesperread");
3357 dump_id = g_quark_from_static_string ("dump");
3358 filesize_id = g_quark_from_static_string ("filesize");
3359 mmapsize_id = g_quark_from_static_string ("mmapsize");
3360 location_id = g_quark_from_static_string ("location");
3361 offset_id = g_quark_from_static_string ("offset");
3362 silent_id = g_quark_from_static_string ("silent");
3363 touch_id = g_quark_from_static_string ("touch");
3366 if (prop_id == fd_id) {
3367 pspec = g_param_spec_int ("fd", "File-descriptor",
3368 "File-descriptor for the file being read",
3369 0, G_MAXINT, 0, flags);
3371 else if (prop_id == blocksize_id) {
3372 pspec = g_param_spec_ulong ("blocksize", "Block Size",
3373 "Block size to read per buffer",
3374 0, G_MAXULONG, 4096, flags);
3377 else if (prop_id == bytesperread_id) {
3378 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
3379 "Number of bytes to read per buffer",
3380 G_MININT, G_MAXINT, 0, flags);
3383 else if (prop_id == dump_id) {
3384 pspec = g_param_spec_boolean ("dump", "Dump",
3385 "Dump bytes to stdout",
3389 else if (prop_id == filesize_id) {
3390 pspec = g_param_spec_int64 ("filesize", "File Size",
3391 "Size of the file being read",
3392 0, G_MAXINT64, 0, flags);
3395 else if (prop_id == mmapsize_id) {
3396 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
3397 "Size in bytes of mmap()d regions",
3398 0, G_MAXULONG, 4 * 1048576, flags);
3401 else if (prop_id == location_id) {
3402 pspec = g_param_spec_string ("location", "File Location",
3403 "Location of the file to read",
3407 else if (prop_id == offset_id) {
3408 pspec = g_param_spec_int64 ("offset", "File Offset",
3409 "Byte offset of current read pointer",
3410 0, G_MAXINT64, 0, flags);
3413 else if (prop_id == silent_id) {
3414 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
3418 else if (prop_id == touch_id) {
3419 pspec = g_param_spec_boolean ("touch", "Touch read data",
3420 "Touch data to force disk read before "
3421 "push ()", TRUE, flags);
3424 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
3425 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
3430 g_object_class_install_property (klass, arg_id, pspec);
3435 * gst_element_class_install_std_props:
3436 * @klass: the #GstElementClass to add the properties to.
3437 * @first_name: the name of the first property.
3438 * in a NULL terminated
3439 * @...: the id and flags of the first property, followed by
3440 * further 'name', 'id', 'flags' triplets and terminated by NULL.
3442 * Adds a list of standardized properties with types to the @klass.
3443 * the id is for the property switch in your get_prop method, and
3444 * the flags determine readability / writeability.
3447 gst_element_class_install_std_props (GstElementClass * klass,
3448 const gchar *first_name, ...)
3454 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
3456 va_start (args, first_name);
3461 int arg_id = va_arg (args, int);
3462 int flags = va_arg (args, int);
3464 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id, flags);
3466 name = va_arg (args, char *);
3473 * gst_element_get_managing_bin:
3474 * @element: a #GstElement to get the managing bin of.
3476 * Gets the managing bin (a pipeline or a thread, for example) of an element.
3478 * Returns: the #GstBin, or NULL on failure.
3481 gst_element_get_managing_bin (GstElement *element)
3485 g_return_val_if_fail (element != NULL, NULL);
3487 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (element)));
3489 while (bin && !GST_FLAG_IS_SET (GST_OBJECT (bin), GST_BIN_FLAG_MANAGER))
3490 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (bin)));