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.
23 #include "gst_private.h"
26 #include <gobject/gvaluecollector.h>
28 #include "gstelement.h"
30 #include "gstmarshal.h"
32 #include "gstscheduler.h"
36 #include "gst-i18n-lib.h"
38 /* Element signals and args */
58 extern void __gst_element_details_clear (GstElementDetails * dp);
59 extern void __gst_element_details_copy (GstElementDetails * dest,
60 const GstElementDetails * src);
62 static void gst_element_class_init (GstElementClass * klass);
63 static void gst_element_init (GstElement * element);
64 static void gst_element_base_class_init (gpointer g_class);
65 static void gst_element_base_class_finalize (gpointer g_class);
67 static void gst_element_real_set_property (GObject * object, guint prop_id,
68 const GValue * value, GParamSpec * pspec);
69 static void gst_element_real_get_property (GObject * object, guint prop_id,
70 GValue * value, GParamSpec * pspec);
72 static void gst_element_dispose (GObject * object);
74 static GstElementStateReturn gst_element_change_state (GstElement * element);
75 static void gst_element_error_func (GstElement * element, GstElement * source,
76 GError * error, gchar * debug);
77 static void gst_element_found_tag_func (GstElement * element,
78 GstElement * source, const GstTagList * tag_list);
79 static GstElementStateReturn gst_element_set_state_func (GstElement * element,
80 GstElementState state);
82 #ifndef GST_DISABLE_LOADSAVE
83 static xmlNodePtr gst_element_save_thyself (GstObject * object,
85 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self);
88 GType _gst_element_type = 0;
90 static GstObjectClass *parent_class = NULL;
91 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
94 gst_element_get_type (void)
96 if (!_gst_element_type) {
97 static const GTypeInfo element_info = {
98 sizeof (GstElementClass),
99 gst_element_base_class_init,
100 gst_element_base_class_finalize,
101 (GClassInitFunc) gst_element_class_init,
106 (GInstanceInitFunc) gst_element_init,
110 _gst_element_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
111 &element_info, G_TYPE_FLAG_ABSTRACT);
113 return _gst_element_type;
117 gst_element_class_init (GstElementClass * klass)
119 GObjectClass *gobject_class;
120 GstObjectClass *gstobject_class;
122 gobject_class = (GObjectClass *) klass;
123 gstobject_class = (GstObjectClass *) klass;
125 parent_class = g_type_class_ref (GST_TYPE_OBJECT);
127 gst_element_signals[STATE_CHANGE] =
128 g_signal_new ("state-change", G_TYPE_FROM_CLASS (klass),
129 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, state_change), NULL,
130 NULL, gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
131 gst_element_signals[NEW_PAD] =
132 g_signal_new ("new-pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
133 G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
134 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
135 gst_element_signals[PAD_REMOVED] =
136 g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
137 G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
138 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
139 gst_element_signals[ERROR] =
140 g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
141 G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
142 gst_marshal_VOID__OBJECT_BOXED_STRING, G_TYPE_NONE, 3, GST_TYPE_ELEMENT,
143 GST_TYPE_G_ERROR, G_TYPE_STRING);
144 gst_element_signals[EOS] =
145 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
146 G_STRUCT_OFFSET (GstElementClass, eos), NULL, NULL,
147 gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
148 gst_element_signals[FOUND_TAG] =
149 g_signal_new ("found-tag", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
150 G_STRUCT_OFFSET (GstElementClass, found_tag), NULL, NULL,
151 gst_marshal_VOID__OBJECT_BOXED, G_TYPE_NONE, 2, GST_TYPE_ELEMENT,
153 gst_element_signals[NO_MORE_PADS] =
154 g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
155 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
156 NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
158 gobject_class->set_property =
159 GST_DEBUG_FUNCPTR (gst_element_real_set_property);
160 gobject_class->get_property =
161 GST_DEBUG_FUNCPTR (gst_element_real_get_property);
163 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
165 #ifndef GST_DISABLE_LOADSAVE
166 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
167 gstobject_class->restore_thyself =
168 GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
171 klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
172 klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
173 klass->found_tag = GST_DEBUG_FUNCPTR (gst_element_found_tag_func);
174 klass->numpadtemplates = 0;
175 klass->set_state = GST_DEBUG_FUNCPTR (gst_element_set_state_func);
177 klass->elementfactory = NULL;
181 gst_element_base_class_init (gpointer g_class)
183 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
184 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
187 gobject_class->set_property =
188 GST_DEBUG_FUNCPTR (gst_element_real_set_property);
189 gobject_class->get_property =
190 GST_DEBUG_FUNCPTR (gst_element_real_get_property);
192 memset (&element_class->details, 0, sizeof (GstElementDetails));
193 element_class->padtemplates = NULL;
197 gst_element_base_class_finalize (gpointer g_class)
199 GstElementClass *klass = GST_ELEMENT_CLASS (g_class);
201 g_list_foreach (klass->padtemplates, (GFunc) gst_object_unref, NULL);
202 g_list_free (klass->padtemplates);
203 __gst_element_details_clear (&klass->details);
207 gst_element_init (GstElement * element)
209 element->current_state = GST_STATE_NULL;
210 element->pending_state = GST_STATE_VOID_PENDING;
211 element->numpads = 0;
212 element->numsrcpads = 0;
213 element->numsinkpads = 0;
214 element->pads = NULL;
215 element->loopfunc = NULL;
216 element->sched = NULL;
217 element->clock = NULL;
218 element->sched_private = NULL;
219 element->state_mutex = g_mutex_new ();
220 element->state_cond = g_cond_new ();
224 gst_element_real_set_property (GObject * object, guint prop_id,
225 const GValue * value, GParamSpec * pspec)
227 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
229 if (oclass->set_property)
230 (oclass->set_property) (object, prop_id, value, pspec);
234 gst_element_real_get_property (GObject * object, guint prop_id, GValue * value,
237 GstElementClass *oclass = GST_ELEMENT_GET_CLASS (object);
239 if (oclass->get_property)
240 (oclass->get_property) (object, prop_id, value, pspec);
244 * gst_element_default_error:
245 * @object: a #GObject that signalled the error.
246 * @orig: the #GstObject that initiated the error.
247 * @error: the GError.
248 * @debug: an additional debug information string, or NULL.
250 * A default error signal callback to attach to an element.
251 * The user data passed to the g_signal_connect is ignored.
253 * The default handler will simply print the error string using g_print.
256 gst_element_default_error (GObject * object, GstObject * source, GError * error,
259 gchar *name = gst_object_get_path_string (source);
261 g_print (_("ERROR: from element %s: %s\n"), name, error->message);
263 g_print (_("Additional debug info:\n%s\n"), debug);
270 const GParamSpec *pspec;
276 element_set_property (GstElement * element, const GParamSpec * pspec,
277 const GValue * value)
279 prop_value_t *prop_value = g_new0 (prop_value_t, 1);
281 prop_value->pspec = pspec;
282 prop_value->value = *value;
284 g_async_queue_push (element->prop_value_queue, prop_value);
288 element_get_property (GstElement * element, const GParamSpec * pspec,
291 g_mutex_lock (element->property_mutex);
292 g_object_get_property ((GObject *) element, pspec->name, value);
293 g_mutex_unlock (element->property_mutex);
297 gst_element_threadsafe_properties_pre_run (GstElement * element)
299 GST_DEBUG ("locking element %s", GST_OBJECT_NAME (element));
300 g_mutex_lock (element->property_mutex);
301 gst_element_set_pending_properties (element);
305 gst_element_threadsafe_properties_post_run (GstElement * element)
307 GST_DEBUG ("unlocking element %s", GST_OBJECT_NAME (element));
308 g_mutex_unlock (element->property_mutex);
312 * gst_element_enable_threadsafe_properties:
313 * @element: a #GstElement to enable threadsafe properties on.
315 * Installs an asynchronous queue, a mutex and pre- and post-run functions on
316 * this element so that properties on the element can be set in a
320 gst_element_enable_threadsafe_properties (GstElement * element)
322 g_return_if_fail (GST_IS_ELEMENT (element));
324 GST_FLAG_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
325 element->pre_run_func = gst_element_threadsafe_properties_pre_run;
326 element->post_run_func = gst_element_threadsafe_properties_post_run;
327 if (!element->prop_value_queue)
328 element->prop_value_queue = g_async_queue_new ();
329 if (!element->property_mutex)
330 element->property_mutex = g_mutex_new ();
334 * gst_element_disable_threadsafe_properties:
335 * @element: a #GstElement to disable threadsafe properties on.
337 * Removes the threadsafe properties, post- and pre-run locks from
341 gst_element_disable_threadsafe_properties (GstElement * element)
343 g_return_if_fail (GST_IS_ELEMENT (element));
345 GST_FLAG_UNSET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES);
346 element->pre_run_func = NULL;
347 element->post_run_func = NULL;
348 /* let's keep around that async queue */
352 * gst_element_set_pending_properties:
353 * @element: a #GstElement to set the pending properties on.
355 * Sets all pending properties on the threadsafe properties enabled
359 gst_element_set_pending_properties (GstElement * element)
361 prop_value_t *prop_value;
363 while ((prop_value = g_async_queue_try_pop (element->prop_value_queue))) {
364 g_object_set_property ((GObject *) element, prop_value->pspec->name,
366 g_value_unset (&prop_value->value);
371 /* following 6 functions taken mostly from gobject.c */
375 * @element: a #GstElement to set properties on.
376 * @first_property_name: the first property to set.
377 * @...: value of the first property, and more properties to set, ending
380 * Sets properties on an element. If the element uses threadsafe properties,
381 * they will be queued and set on the object when it is scheduled again.
384 gst_element_set (GstElement * element, const gchar * first_property_name, ...)
388 g_return_if_fail (GST_IS_ELEMENT (element));
390 va_start (var_args, first_property_name);
391 gst_element_set_valist (element, first_property_name, var_args);
397 * @element: a #GstElement to get properties of.
398 * @first_property_name: the first property to get.
399 * @...: pointer to a variable to store the first property in, as well as
400 * more properties to get, ending with NULL.
402 * Gets properties from an element. If the element uses threadsafe properties,
403 * the element will be locked before getting the given properties.
406 gst_element_get (GstElement * element, const gchar * first_property_name, ...)
410 g_return_if_fail (GST_IS_ELEMENT (element));
412 va_start (var_args, first_property_name);
413 gst_element_get_valist (element, first_property_name, var_args);
418 * gst_element_set_valist:
419 * @element: a #GstElement to set properties on.
420 * @first_property_name: the first property to set.
421 * @var_args: the var_args list of other properties to get.
423 * Sets properties on an element. If the element uses threadsafe properties,
424 * the property change will be put on the async queue.
427 gst_element_set_valist (GstElement * element, const gchar * first_property_name,
433 g_return_if_fail (GST_IS_ELEMENT (element));
435 object = (GObject *) element;
437 GST_CAT_DEBUG (GST_CAT_PROPERTIES,
438 "setting valist of properties starting with %s on element %s",
439 first_property_name, gst_element_get_name (element));
441 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
442 g_object_set_valist (object, first_property_name, var_args);
446 g_object_ref (object);
448 name = first_property_name;
451 GValue value = { 0, };
455 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
458 g_warning ("%s: object class `%s' has no property named `%s'",
459 G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
462 if (!(pspec->flags & G_PARAM_WRITABLE)) {
463 g_warning ("%s: property `%s' of object class `%s' is not writable",
464 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
468 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
470 G_VALUE_COLLECT (&value, var_args, 0, &error);
472 g_warning ("%s: %s", G_STRLOC, error);
475 /* we purposely leak the value here, it might not be
476 * in a sane state if an error condition occoured
481 element_set_property (element, pspec, &value);
482 g_value_unset (&value);
484 name = va_arg (var_args, gchar *);
487 g_object_unref (object);
491 * gst_element_get_valist:
492 * @element: a #GstElement to get properties of.
493 * @first_property_name: the first property to get.
494 * @var_args: the var_args list of other properties to get.
496 * Gets properties from an element. If the element uses threadsafe properties,
497 * the element will be locked before getting the given properties.
500 gst_element_get_valist (GstElement * element, const gchar * first_property_name,
506 g_return_if_fail (GST_IS_ELEMENT (element));
508 object = (GObject *) element;
510 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
511 g_object_get_valist (object, first_property_name, var_args);
515 g_object_ref (object);
517 name = first_property_name;
520 GValue value = { 0, };
524 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
527 g_warning ("%s: object class `%s' has no property named `%s'",
528 G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
531 if (!(pspec->flags & G_PARAM_READABLE)) {
532 g_warning ("%s: property `%s' of object class `%s' is not readable",
533 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
537 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
539 element_get_property (element, pspec, &value);
541 G_VALUE_LCOPY (&value, var_args, 0, &error);
543 g_warning ("%s: %s", G_STRLOC, error);
545 g_value_unset (&value);
549 g_value_unset (&value);
551 name = va_arg (var_args, gchar *);
554 g_object_unref (object);
558 * gst_element_set_property:
559 * @element: a #GstElement to set properties on.
560 * @property_name: the first property to get.
561 * @value: the #GValue that holds the value to set.
563 * Sets a property on an element. If the element uses threadsafe properties,
564 * the property will be put on the async queue.
567 gst_element_set_property (GstElement * element, const gchar * property_name,
568 const GValue * value)
573 g_return_if_fail (GST_IS_ELEMENT (element));
574 g_return_if_fail (property_name != NULL);
575 g_return_if_fail (G_IS_VALUE (value));
577 object = (GObject *) element;
579 GST_CAT_DEBUG (GST_CAT_PROPERTIES, "setting property %s on element %s",
580 property_name, gst_element_get_name (element));
581 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
582 g_object_set_property (object, property_name, value);
586 g_object_ref (object);
588 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
592 g_warning ("%s: object class `%s' has no property named `%s'",
593 G_STRLOC, G_OBJECT_TYPE_NAME (object), property_name);
595 element_set_property (element, pspec, value);
597 g_object_unref (object);
601 * gst_element_get_property:
602 * @element: a #GstElement to get properties of.
603 * @property_name: the first property to get.
604 * @value: the #GValue to store the property value in.
606 * Gets a property from an element. If the element uses threadsafe properties,
607 * the element will be locked before getting the given property.
610 gst_element_get_property (GstElement * element, const gchar * property_name,
616 g_return_if_fail (GST_IS_ELEMENT (element));
617 g_return_if_fail (property_name != NULL);
618 g_return_if_fail (G_IS_VALUE (value));
620 object = (GObject *) element;
622 if (!GST_FLAG_IS_SET (element, GST_ELEMENT_USE_THREADSAFE_PROPERTIES)) {
623 g_object_get_property (object, property_name, value);
627 g_object_ref (object);
630 g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
633 g_warning ("%s: object class `%s' has no property named `%s'",
634 G_STRLOC, G_OBJECT_TYPE_NAME (object), property_name);
636 GValue *prop_value, tmp_value = { 0, };
638 /* auto-conversion of the callers value type
640 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec)) {
641 g_value_reset (value);
643 } else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec),
644 G_VALUE_TYPE (value))) {
646 ("can't retrieve property `%s' of type `%s' as value of type `%s'",
647 pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
648 G_VALUE_TYPE_NAME (value));
649 g_object_unref (object);
652 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
653 prop_value = &tmp_value;
655 element_get_property (element, pspec, prop_value);
656 if (prop_value != value) {
657 g_value_transform (prop_value, value);
658 g_value_unset (&tmp_value);
662 g_object_unref (object);
666 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
669 GstPad *newpad = NULL;
670 GstElementClass *oclass;
672 oclass = GST_ELEMENT_GET_CLASS (element);
674 if (oclass->request_new_pad)
675 newpad = (oclass->request_new_pad) (element, templ, name);
681 * gst_element_release_request_pad:
682 * @element: a #GstElement to release the request pad of.
683 * @pad: the #GstPad to release.
685 * Makes the element free the previously requested pad as obtained
686 * with gst_element_get_request_pad().
689 gst_element_release_request_pad (GstElement * element, GstPad * pad)
691 GstElementClass *oclass;
693 g_return_if_fail (GST_IS_ELEMENT (element));
694 g_return_if_fail (GST_IS_PAD (pad));
696 oclass = GST_ELEMENT_GET_CLASS (element);
698 if (oclass->release_pad)
699 (oclass->release_pad) (element, pad);
703 * gst_element_requires_clock:
704 * @element: a #GstElement to query
706 * Query if the element requiresd a clock
708 * Returns: TRUE if the element requires a clock
711 gst_element_requires_clock (GstElement * element)
713 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
715 return (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
719 * gst_element_provides_clock:
720 * @element: a #GstElement to query
722 * Query if the element provides a clock
724 * Returns: TRUE if the element provides a clock
727 gst_element_provides_clock (GstElement * element)
729 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
731 return (GST_ELEMENT_GET_CLASS (element)->get_clock != NULL);
735 * gst_element_set_clock:
736 * @element: a #GstElement to set the clock for.
737 * @clock: the #GstClock to set for the element.
739 * Sets the clock for the element.
742 gst_element_set_clock (GstElement * element, GstClock * clock)
744 GstElementClass *oclass;
746 g_return_if_fail (GST_IS_ELEMENT (element));
748 oclass = GST_ELEMENT_GET_CLASS (element);
750 if (oclass->set_clock)
751 oclass->set_clock (element, clock);
753 gst_object_replace ((GstObject **) & element->clock, (GstObject *) clock);
757 * gst_element_get_clock:
758 * @element: a #GstElement to get the clock of.
760 * Gets the clock of the element.
762 * Returns: the #GstClock of the element.
765 gst_element_get_clock (GstElement * element)
767 GstElementClass *oclass;
769 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
771 oclass = GST_ELEMENT_GET_CLASS (element);
773 if (oclass->get_clock)
774 return oclass->get_clock (element);
780 * gst_element_clock_wait:
781 * @element: a #GstElement.
782 * @id: the #GstClock to use.
783 * @jitter: the difference between requested time and actual time.
785 * Waits for a specific time on the clock.
787 * Returns: the #GstClockReturn result of the wait operation.
790 gst_element_clock_wait (GstElement * element, GstClockID id,
791 GstClockTimeDiff * jitter)
795 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR);
797 if (GST_ELEMENT_SCHED (element)) {
798 GST_CAT_DEBUG (GST_CAT_CLOCK, "waiting on scheduler clock with id %d");
800 gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id,
803 GST_CAT_DEBUG (GST_CAT_CLOCK, "no scheduler, returning GST_CLOCK_TIMEOUT");
804 res = GST_CLOCK_TIMEOUT;
810 #undef GST_CAT_DEFAULT
811 #define GST_CAT_DEFAULT GST_CAT_CLOCK
813 * gst_element_get_time:
814 * @element: element to query
816 * Query the element's time. FIXME: The element must use
818 * Returns: the current stream time in #GST_STATE_PLAYING,
819 * the element base time in #GST_STATE_PAUSED,
820 * or #GST_CLOCK_TIME_NONE otherwise.
822 /* FIXME: this should always return time on the same scale. Now it returns
823 * the (absolute) base_time in PAUSED and the (current running) time in
825 * Solution: have a get_base_time and make the element subtract if it needs
826 * to. In PAUSED return the same as PLAYING, ie. the current timestamp where
827 * the element is at according to the provided clock.
830 gst_element_get_time (GstElement * element)
832 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
834 if (element->clock == NULL) {
835 GST_WARNING_OBJECT (element, "element queries time but has no clock");
836 return GST_CLOCK_TIME_NONE;
838 switch (element->current_state) {
840 case GST_STATE_READY:
841 return GST_CLOCK_TIME_NONE;
842 case GST_STATE_PAUSED:
843 return element->base_time;
844 case GST_STATE_PLAYING:
845 return gst_clock_get_time (element->clock) - element->base_time;
847 g_assert_not_reached ();
848 return GST_CLOCK_TIME_NONE;
854 * @element: element that should wait
855 * @timestamp: what timestamp to wait on
857 * Waits until the given relative time stamp for the element has arrived.
858 * When this function returns successfully, the relative time point specified
859 * in the timestamp has passed for this element.
860 * <note>This function can only be called on elements in
861 * #GST_STATE_PLAYING</note>
863 * Returns: TRUE on success.
866 gst_element_wait (GstElement * element, GstClockTime timestamp)
872 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
873 g_return_val_if_fail (GST_IS_CLOCK (element->clock), FALSE);
874 g_return_val_if_fail (element->current_state == GST_STATE_PLAYING, FALSE);
875 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
877 /* shortcut when we're already late... */
878 time = gst_element_get_time (element);
879 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "element time %" GST_TIME_FORMAT,
880 GST_TIME_ARGS (time));
881 if (time >= timestamp) {
882 GST_CAT_INFO_OBJECT (GST_CAT_CLOCK, element,
883 "called gst_element_wait (% " GST_TIME_FORMAT ") and was late (%"
884 GST_TIME_FORMAT, GST_TIME_ARGS (timestamp),
885 GST_TIME_ARGS (gst_element_get_time (element)));
889 id = gst_clock_new_single_shot_id (element->clock,
890 element->base_time + timestamp);
891 ret = gst_element_clock_wait (element, id, NULL);
892 gst_clock_id_free (id);
894 return ret == GST_CLOCK_STOPPED;
898 * gst_element_set_time:
899 * @element: element to set time on
902 * Sets the current time of the element. This function can be used when handling
903 * discont events. You can only call this function on an element with a clock in
904 * #GST_STATE_PAUSED or #GST_STATE_PLAYING. You might want to have a look at
905 * gst_element_adjust_time(), if you want to adjust by a difference as that is
909 gst_element_set_time (GstElement * element, GstClockTime time)
911 gst_element_set_time_delay (element, time, 0);
915 * gst_element_set_time_delay:
916 * @element: element to set time on
918 * @delay: a delay to discount from the given time
920 * Sets the current time of the element to time - delay. This function can be
921 * used when handling discont events in elements writing to an external buffer,
922 * i. e., an audio sink that writes to a sound card that buffers the sound
923 * before playing it. The delay should be the current buffering delay.
925 * You can only call this function on an element with a clock in
926 * #GST_STATE_PAUSED or #GST_STATE_PLAYING. You might want to have a look at
927 * gst_element_adjust_time(), if you want to adjust by a difference as that is
931 gst_element_set_time_delay (GstElement * element, GstClockTime time,
934 GstClockTime event_time;
936 g_return_if_fail (GST_IS_ELEMENT (element));
937 g_return_if_fail (GST_IS_CLOCK (element->clock));
938 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
939 g_return_if_fail (time >= delay);
941 switch (element->current_state) {
942 case GST_STATE_PAUSED:
943 element->base_time = time - delay;
945 case GST_STATE_PLAYING:
946 event_time = gst_clock_get_event_time_delay (element->clock, delay);
947 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element,
948 "clock time %" GST_TIME_FORMAT ": setting element time to %"
949 GST_TIME_FORMAT, GST_TIME_ARGS (event_time), GST_TIME_ARGS (time));
950 element->base_time = event_time - time;
953 g_assert_not_reached ();
959 * gst_element_adjust_time:
960 * @element: element to adjust time on
961 * @diff: difference to adjust
963 * Adjusts the current time of the element by the specified difference. This
964 * function can be used when handling discont events. You can only call this
965 * function on an element with a clock in #GST_STATE_PAUSED or
966 * #GST_STATE_PLAYING. It is more accurate than gst_element_set_time().
969 gst_element_adjust_time (GstElement * element, GstClockTimeDiff diff)
973 g_return_if_fail (GST_IS_ELEMENT (element));
974 g_return_if_fail (GST_IS_CLOCK (element->clock));
975 g_return_if_fail (element->current_state >= GST_STATE_PAUSED);
977 switch (element->current_state) {
978 case GST_STATE_PAUSED:
979 if (diff < 0 && element->base_time < abs (diff)) {
980 g_warning ("attempted to set the current time of element %s below 0",
981 GST_OBJECT_NAME (element));
982 element->base_time = 0;
984 element->base_time += diff;
987 case GST_STATE_PLAYING:
988 time = gst_clock_get_time (element->clock);
989 if (time < element->base_time - diff) {
990 g_warning ("attempted to set the current time of element %s below 0",
991 GST_OBJECT_NAME (element));
992 element->base_time = time;
994 element->base_time -= diff;
998 g_assert_not_reached ();
1003 #undef GST_CAT_DEFAULT
1005 #ifndef GST_DISABLE_INDEX
1007 * gst_element_is_indexable:
1008 * @element: a #GstElement.
1010 * Queries if the element can be indexed.
1012 * Returns: TRUE if the element can be indexed.
1015 gst_element_is_indexable (GstElement * element)
1017 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1019 return (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
1023 * gst_element_set_index:
1024 * @element: a #GstElement.
1025 * @index: a #GstIndex.
1027 * Set the specified GstIndex on the element.
1030 gst_element_set_index (GstElement * element, GstIndex * index)
1032 GstElementClass *oclass;
1034 g_return_if_fail (GST_IS_ELEMENT (element));
1035 g_return_if_fail (GST_IS_INDEX (index));
1037 oclass = GST_ELEMENT_GET_CLASS (element);
1039 if (oclass->set_index)
1040 oclass->set_index (element, index);
1044 * gst_element_get_index:
1045 * @element: a #GstElement.
1047 * Gets the index from the element.
1049 * Returns: a #GstIndex or NULL when no index was set on the
1053 gst_element_get_index (GstElement * element)
1055 GstElementClass *oclass;
1057 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1059 oclass = GST_ELEMENT_GET_CLASS (element);
1061 if (oclass->get_index)
1062 return oclass->get_index (element);
1069 * gst_element_release_locks:
1070 * @element: a #GstElement to release all locks on.
1072 * Instruct the element to release all the locks it is holding, such as
1073 * blocking reads, waiting for the clock, ...
1075 * Returns: TRUE if the locks could be released.
1078 gst_element_release_locks (GstElement * element)
1080 GstElementClass *oclass;
1082 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1084 oclass = GST_ELEMENT_GET_CLASS (element);
1086 if (oclass->release_locks)
1087 return oclass->release_locks (element);
1093 * gst_element_add_pad:
1094 * @element: a #GstElement to add the pad to.
1095 * @pad: the #GstPad to add to the element.
1097 * Adds a pad (link point) to @element. @pad's parent will be set to @element;
1098 * see gst_object_set_parent() for refcounting information.
1100 * Pads are automatically activated when the element is in state PLAYING.
1103 gst_element_add_pad (GstElement * element, GstPad * pad)
1105 g_return_if_fail (GST_IS_ELEMENT (element));
1106 g_return_if_fail (GST_IS_PAD (pad));
1108 /* first check to make sure the pad hasn't already been added to another
1110 g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
1112 /* then check to see if there's already a pad by that name here */
1113 g_return_if_fail (gst_object_check_uniqueness (element->pads,
1114 GST_PAD_NAME (pad)) == TRUE);
1116 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
1117 GST_STR_NULL (GST_OBJECT_NAME (pad)));
1119 /* set the pad's parent */
1120 gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element));
1122 /* add it to the list */
1123 element->pads = g_list_append (element->pads, pad);
1126 switch (gst_pad_get_direction (pad)) {
1128 element->numsrcpads++;
1131 element->numsinkpads++;
1134 /* can happen for ghost pads */
1138 /* activate element when we are playing */
1139 if (GST_STATE (element) == GST_STATE_PLAYING)
1140 gst_pad_set_active (pad, TRUE);
1142 /* emit the NEW_PAD signal */
1143 g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
1147 * gst_element_add_ghost_pad:
1148 * @element: a #GstElement to add the ghost pad to.
1149 * @pad: the #GstPad from which the new ghost pad will be created.
1150 * @name: the name of the new ghost pad, or NULL to assign a unique name
1153 * Creates a ghost pad from @pad, and adds it to @element via
1154 * gst_element_add_pad().
1156 * Returns: the added ghost #GstPad, or NULL on error.
1159 gst_element_add_ghost_pad (GstElement * element, GstPad * pad,
1164 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1165 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1167 /* then check to see if there's already a pad by that name here */
1168 g_return_val_if_fail (gst_object_check_uniqueness (element->pads,
1169 name) == TRUE, NULL);
1171 ghostpad = gst_ghost_pad_new (name, pad);
1173 gst_element_add_pad (element, ghostpad);
1179 * gst_element_remove_pad:
1180 * @element: a #GstElement to remove pad from.
1181 * @pad: the #GstPad to remove from the element.
1183 * Removes @pad from @element. @pad will be destroyed if it has not been
1184 * referenced elsewhere.
1187 gst_element_remove_pad (GstElement * element, GstPad * pad)
1189 g_return_if_fail (element != NULL);
1190 g_return_if_fail (GST_IS_ELEMENT (element));
1191 g_return_if_fail (pad != NULL);
1192 g_return_if_fail (GST_IS_PAD (pad));
1194 g_return_if_fail (GST_PAD_PARENT (pad) == element);
1196 if (GST_IS_REAL_PAD (pad)) {
1197 /* unlink if necessary */
1198 if (GST_RPAD_PEER (pad) != NULL) {
1199 gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
1201 gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
1202 } else if (GST_IS_GHOST_PAD (pad)) {
1203 g_object_set (pad, "real-pad", NULL, NULL);
1206 /* remove it from the list */
1207 element->pads = g_list_remove (element->pads, pad);
1209 switch (gst_pad_get_direction (pad)) {
1211 element->numsrcpads--;
1214 element->numsinkpads--;
1217 /* can happen for ghost pads */
1221 g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
1223 gst_object_unparent (GST_OBJECT (pad));
1227 * gst_element_remove_ghost_pad:
1228 * @element: a #GstElement to remove the ghost pad from.
1229 * @pad: ghost #GstPad to remove.
1231 * Removes a ghost pad from an element. Deprecated, use gst_element_remove_pad()
1235 gst_element_remove_ghost_pad (GstElement * element, GstPad * pad)
1237 g_return_if_fail (GST_IS_ELEMENT (element));
1238 g_return_if_fail (GST_IS_GHOST_PAD (pad));
1240 g_warning ("gst_element_remove_ghost_pad is deprecated.\n"
1241 "Use gst_element_remove_pad instead.");
1243 gst_element_remove_pad (element, pad);
1247 * gst_element_no_more_pads:
1248 * @element: a #GstElement
1250 * Use this function to signal that the element does not expect any more pads
1251 * to show up in the current pipeline. This function should be called whenever
1252 * pads have been added by the element itself. Elements with GST_PAD_SOMETIMES
1253 * pad templates use this in combination with autopluggers to figure out that
1254 * the element is done initializing its pads.
1257 gst_element_no_more_pads (GstElement * element)
1259 g_return_if_fail (GST_IS_ELEMENT (element));
1261 g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
1265 * gst_element_get_pad:
1266 * @element: a #GstElement.
1267 * @name: the name of the pad to retrieve.
1269 * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
1270 * first, then gst_element_get_request_pad().
1272 * Returns: the #GstPad if found, otherwise %NULL.
1275 gst_element_get_pad (GstElement * element, const gchar * name)
1279 g_return_val_if_fail (element != NULL, NULL);
1280 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1281 g_return_val_if_fail (name != NULL, NULL);
1283 pad = gst_element_get_static_pad (element, name);
1285 pad = gst_element_get_request_pad (element, name);
1291 * gst_element_get_static_pad:
1292 * @element: a #GstElement to find a static pad of.
1293 * @name: the name of the static #GstPad to retrieve.
1295 * Retrieves a pad from @element by name. This version only retrieves
1296 * already-existing (i.e. 'static') pads.
1298 * Returns: the requested #GstPad if found, otherwise NULL.
1301 gst_element_get_static_pad (GstElement * element, const gchar * name)
1305 g_return_val_if_fail (element != NULL, NULL);
1306 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1307 g_return_val_if_fail (name != NULL, NULL);
1309 walk = element->pads;
1313 pad = GST_PAD (walk->data);
1314 if (strcmp (GST_PAD_NAME (pad), name) == 0) {
1315 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
1316 GST_DEBUG_PAD_NAME (pad));
1319 walk = g_list_next (walk);
1322 GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
1323 name, GST_OBJECT_NAME (element));
1328 * gst_element_get_request_pad:
1329 * @element: a #GstElement to find a request pad of.
1330 * @name: the name of the request #GstPad to retrieve.
1332 * Retrieves a pad from the element by name. This version only retrieves
1335 * Returns: requested #GstPad if found, otherwise NULL.
1338 gst_element_get_request_pad (GstElement * element, const gchar * name)
1340 GstPadTemplate *templ = NULL;
1342 const gchar *req_name = NULL;
1343 gboolean templ_found = FALSE;
1347 gchar *str, *endptr = NULL;
1349 g_return_val_if_fail (element != NULL, NULL);
1350 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1351 g_return_val_if_fail (name != NULL, NULL);
1353 if (strstr (name, "%")) {
1354 templ = gst_element_get_pad_template (element, name);
1359 list = gst_element_get_pad_template_list (element);
1360 while (!templ_found && list) {
1361 templ = (GstPadTemplate *) list->data;
1362 if (templ->presence == GST_PAD_REQUEST) {
1363 /* Because of sanity checks in gst_pad_template_new(), we know that %s
1364 and %d, occurring at the end of the name_template, are the only
1366 GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
1367 templ->name_template);
1368 if ((str = strchr (templ->name_template, '%'))
1369 && strncmp (templ->name_template, name,
1370 str - templ->name_template) == 0
1371 && strlen (name) > str - templ->name_template) {
1372 data = name + (str - templ->name_template);
1373 if (*(str + 1) == 'd') {
1375 n = (gint) strtol (data, &endptr, 10);
1376 if (endptr && *endptr == '\0') {
1396 pad = gst_element_request_pad (element, templ, req_name);
1402 * gst_element_get_pad_list:
1403 * @element: a #GstElement to get pads of.
1405 * Retrieves a list of @element's pads. The list must not be modified by the
1408 * Returns: the #GList of pads.
1411 gst_element_get_pad_list (GstElement * element)
1413 g_return_val_if_fail (element != NULL, NULL);
1414 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1416 /* return the list of pads */
1417 return element->pads;
1421 * gst_element_class_add_pad_template:
1422 * @klass: the #GstElementClass to add the pad template to.
1423 * @templ: a #GstPadTemplate to add to the element class.
1425 * Adds a padtemplate to an element class. This is mainly used in the _base_init
1426 * functions of classes.
1429 gst_element_class_add_pad_template (GstElementClass * klass,
1430 GstPadTemplate * templ)
1432 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1433 g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1435 /* avoid registering pad templates with the same name */
1436 g_return_if_fail (gst_element_class_get_pad_template (klass,
1437 templ->name_template) == NULL);
1439 klass->padtemplates = g_list_append (klass->padtemplates,
1440 gst_object_ref (GST_OBJECT (templ)));
1441 klass->numpadtemplates++;
1445 * gst_element_class_set_details:
1446 * @klass: class to set details for
1447 * @details: details to set
1449 * Sets the detailed information for a #GstElementClass.
1450 * <note>This function is for use in _base_init functions only.</note>
1453 gst_element_class_set_details (GstElementClass * klass,
1454 const GstElementDetails * details)
1456 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1457 g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1459 __gst_element_details_copy (&klass->details, details);
1463 * gst_element_class_get_pad_template_list:
1464 * @element_class: a #GstElementClass to get pad templates of.
1466 * Retrieves a list of the pad templates associated with @element_class. The
1467 * list must not be modified by the calling code.
1468 * <note>If you use this function in the #GInstanceInitFunc of an object class
1469 * that has subclasses, make sure to pass the g_class parameter of the
1470 * #GInstanceInitFunc here.</note>
1472 * Returns: the #GList of padtemplates.
1475 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1477 g_return_val_if_fail (element_class != NULL, NULL);
1478 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1480 return element_class->padtemplates;
1484 * gst_element_class_get_pad_template:
1485 * @element_class: a #GstElementClass to get the pad template of.
1486 * @name: the name of the #GstPadTemplate to get.
1488 * Retrieves a padtemplate from @element_class with the given name.
1489 * <note>If you use this function in the #GInstanceInitFunc of an object class
1490 * that has subclasses, make sure to pass the g_class parameter of the
1491 * #GInstanceInitFunc here.</note>
1493 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1494 * No unreferencing is necessary.
1497 gst_element_class_get_pad_template (GstElementClass * element_class,
1502 g_return_val_if_fail (element_class != NULL, NULL);
1503 g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1504 g_return_val_if_fail (name != NULL, NULL);
1506 padlist = gst_element_class_get_pad_template_list (element_class);
1509 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1511 if (strcmp (padtempl->name_template, name) == 0)
1514 padlist = g_list_next (padlist);
1521 * gst_element_get_pad_template_list:
1522 * @element: a #GstElement to get pad templates of.
1524 * Retrieves a list of the pad templates associated with the element.
1525 * (FIXME: Should be deprecated in favor of
1526 * gst_element_class_get_pad_template_list).
1528 * Returns: the #GList of padtemplates.
1531 gst_element_get_pad_template_list (GstElement * element)
1533 g_return_val_if_fail (element != NULL, NULL);
1534 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1536 return GST_ELEMENT_GET_CLASS (element)->padtemplates;
1540 * gst_element_get_pad_template:
1541 * @element: a #GstElement to get the pad template of.
1542 * @name: the name of the #GstPadTemplate to get.
1544 * Retrieves a padtemplate from this element with the
1546 * (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template).
1548 * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1549 * No unreferencing is necessary.
1552 gst_element_get_pad_template (GstElement * element, const gchar * name)
1554 g_return_val_if_fail (element != NULL, NULL);
1555 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1556 g_return_val_if_fail (name != NULL, NULL);
1558 return gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (element),
1563 * gst_element_get_compatible_pad_template:
1564 * @element: a #GstElement to get a compatible pad template for.
1565 * @compattempl: the #GstPadTemplate to find a compatible template for.
1567 * Retrieves a pad template from @element that is compatible with @compattempl.
1568 * Pads from compatible templates can be linked together.
1570 * Returns: a compatible #GstPadTemplate, or NULL if none was found. No
1571 * unreferencing is necessary.
1574 gst_element_get_compatible_pad_template (GstElement * element,
1575 GstPadTemplate * compattempl)
1577 GstPadTemplate *newtempl = NULL;
1580 g_return_val_if_fail (element != NULL, NULL);
1581 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1582 g_return_val_if_fail (compattempl != NULL, NULL);
1584 padlist = gst_element_get_pad_template_list (element);
1586 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1587 "Looking for a suitable pad template in %s out of %d templates...",
1588 GST_ELEMENT_NAME (element), g_list_length (padlist));
1591 GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1592 GstCaps *intersection;
1596 * Check direction (must be opposite)
1599 GST_CAT_LOG (GST_CAT_CAPS,
1600 "checking pad template %s", padtempl->name_template);
1601 if (padtempl->direction != compattempl->direction) {
1602 GST_CAT_DEBUG (GST_CAT_CAPS,
1603 "compatible direction: found %s pad template \"%s\"",
1604 padtempl->direction == GST_PAD_SRC ? "src" : "sink",
1605 padtempl->name_template);
1607 intersection = gst_caps_intersect (GST_PAD_TEMPLATE_CAPS (compattempl),
1608 GST_PAD_TEMPLATE_CAPS (padtempl));
1610 GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible",
1611 (intersection ? "" : "not "));
1613 if (!gst_caps_is_empty (intersection))
1614 newtempl = padtempl;
1615 gst_caps_free (intersection);
1620 padlist = g_list_next (padlist);
1623 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1624 "Returning new pad template %p", newtempl);
1626 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "No compatible pad template found");
1632 * gst_element_get_pad_from_template:
1633 * @element: a #GstElement.
1634 * @templ: a #GstPadTemplate belonging to @element.
1636 * Gets a pad from @element described by @templ. If the presence of @templ is
1637 * #GST_PAD_REQUEST, requests a new pad. Can return %NULL for #GST_PAD_SOMETIMES
1640 * Returns: the #GstPad, or NULL if one could not be found or created.
1643 gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
1646 GstPadPresence presence;
1648 /* If this function is ever exported, we need check the validity of `element'
1649 * and `templ', and to make sure the template actually belongs to the
1652 presence = GST_PAD_TEMPLATE_PRESENCE (templ);
1655 case GST_PAD_ALWAYS:
1656 case GST_PAD_SOMETIMES:
1657 ret = gst_element_get_static_pad (element, templ->name_template);
1658 if (!ret && presence == GST_PAD_ALWAYS)
1660 ("Element %s has an ALWAYS template %s, but no pad of the same name",
1661 GST_OBJECT_NAME (element), templ->name_template);
1664 case GST_PAD_REQUEST:
1665 ret = gst_element_request_pad (element, templ, NULL);
1673 * gst_element_request_compatible_pad:
1674 * @element: a #GstElement.
1675 * @templ: the #GstPadTemplate to which the new pad should be able to link.
1677 * Requests a pad from @element. The returned pad should be unlinked and
1678 * compatible with @templ. Might return an existing pad, or request a new one.
1680 * Returns: a #GstPad, or %NULL if one could not be found or created.
1683 gst_element_request_compatible_pad (GstElement * element,
1684 GstPadTemplate * templ)
1686 GstPadTemplate *templ_new;
1689 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1690 g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
1692 /* FIXME: should really loop through the templates, testing each for
1693 compatibility and pad availability. */
1694 templ_new = gst_element_get_compatible_pad_template (element, templ);
1696 pad = gst_element_get_pad_from_template (element, templ_new);
1698 /* This can happen for non-request pads. No need to unref. */
1699 if (pad && GST_PAD_PEER (pad))
1706 * gst_element_get_compatible_pad_filtered:
1707 * @element: a #GstElement in which the pad should be found.
1708 * @pad: the #GstPad to find a compatible one for.
1709 * @filtercaps: the #GstCaps to use as a filter.
1711 * Looks for an unlinked pad to which the given pad can link. It is not
1712 * guaranteed that linking the pads will work, though it should work in most
1715 * Returns: the #GstPad to which a link can be made, or %NULL if one cannot be
1719 gst_element_get_compatible_pad_filtered (GstElement * element, GstPad * pad,
1720 const GstCaps * filtercaps)
1723 GstPadTemplate *templ;
1725 GstPad *foundpad = NULL;
1727 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1728 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1730 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1731 "finding pad in %s compatible with %s:%s and filter %" GST_PTR_FORMAT,
1732 GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad), filtercaps);
1734 /* let's use the real pad */
1735 pad = (GstPad *) GST_PAD_REALIZE (pad);
1736 g_return_val_if_fail (pad != NULL, NULL);
1737 g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
1739 /* try to get an existing unlinked pad */
1740 pads = gst_element_get_pad_list (element);
1742 GstPad *current = GST_PAD (pads->data);
1744 GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examing pad %s:%s",
1745 GST_DEBUG_PAD_NAME (current));
1746 if (GST_PAD_PEER (current) == NULL &&
1747 gst_pad_can_link_filtered (pad, current, filtercaps)) {
1748 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1749 "found existing unlinked pad %s:%s", GST_DEBUG_PAD_NAME (current));
1752 pads = g_list_next (pads);
1755 /* try to create a new one */
1756 /* requesting is a little crazy, we need a template. Let's create one */
1757 templcaps = gst_pad_get_caps (pad);
1758 if (filtercaps != NULL) {
1761 temp = gst_caps_intersect (filtercaps, templcaps);
1762 gst_caps_free (templcaps);
1766 templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
1767 GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
1768 foundpad = gst_element_request_compatible_pad (element, templ);
1769 gst_object_unref (GST_OBJECT (templ));
1772 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1773 "found existing request pad %s:%s", GST_DEBUG_PAD_NAME (foundpad));
1777 GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element,
1778 "Could not find a compatible pad to link to %s:%s",
1779 GST_DEBUG_PAD_NAME (pad));
1784 * gst_element_get_compatible_pad:
1785 * @element: a #GstElement in which the pad should be found.
1786 * @pad: the #GstPad to find a compatible one for.
1788 * Looks for an unlinked pad to which the given pad can link to.
1789 * It is not guaranteed that linking the pads will work, though
1790 * it should work in most cases.
1792 * Returns: the #GstPad to which a link can be made, or %NULL if one
1793 * could not be found.
1796 gst_element_get_compatible_pad (GstElement * element, GstPad * pad)
1798 return gst_element_get_compatible_pad_filtered (element, pad, NULL);
1802 * gst_element_link_pads_filtered:
1803 * @src: a #GstElement containing the source pad.
1804 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1805 * @dest: the #GstElement containing the destination pad.
1806 * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1807 * @filtercaps: the #GstCaps to use as a filter.
1809 * Links the two named pads of the source and destination elements.
1810 * Side effect is that if one of the pads has no parent, it becomes a
1811 * child of the parent of the other element. If they have different
1812 * parents, the link fails.
1814 * Returns: TRUE if the pads could be linked, FALSE otherwise.
1817 gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
1818 GstElement * dest, const gchar * destpadname, const GstCaps * filtercaps)
1820 const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1821 GstPad *srcpad, *destpad;
1822 GstPadTemplate *srctempl, *desttempl;
1825 g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1826 g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1828 GST_CAT_INFO (GST_CAT_ELEMENT_PADS,
1829 "trying to link element %s:%s to element %s:%s", GST_ELEMENT_NAME (src),
1830 srcpadname ? srcpadname : "(any)", GST_ELEMENT_NAME (dest),
1831 destpadname ? destpadname : "(any)");
1833 /* now get the pads we're trying to link and a list of all remaining pads */
1835 srcpad = gst_element_get_pad (src, srcpadname);
1837 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1838 GST_ELEMENT_NAME (src), srcpadname);
1841 if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1842 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad",
1843 GST_DEBUG_PAD_NAME (srcpad));
1846 if (GST_PAD_PEER (srcpad) != NULL) {
1847 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1848 GST_DEBUG_PAD_NAME (srcpad));
1854 srcpads = gst_element_get_pad_list (src);
1855 srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
1858 destpad = gst_element_get_pad (dest, destpadname);
1860 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1861 GST_ELEMENT_NAME (dest), destpadname);
1864 if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1865 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad",
1866 GST_DEBUG_PAD_NAME (destpad));
1869 if (GST_PAD_PEER (destpad) != NULL) {
1870 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1871 GST_DEBUG_PAD_NAME (destpad));
1877 destpads = gst_element_get_pad_list (dest);
1878 destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
1881 if (srcpadname && destpadname) {
1882 /* two explicitly specified pads */
1883 return gst_pad_link_filtered (srcpad, destpad, filtercaps);
1886 /* loop through the allowed pads in the source, trying to find a
1887 * compatible destination pad */
1888 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1889 "looping through allowed src and dest pads");
1891 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1892 GST_DEBUG_PAD_NAME (srcpad));
1893 if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1894 (GST_PAD_PEER (srcpad) == NULL)) {
1895 GstPad *temp = destpadname ? destpad :
1896 gst_element_get_compatible_pad_filtered (dest, srcpad,
1899 if (temp && gst_pad_link_filtered (srcpad, temp, filtercaps)) {
1900 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1901 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1905 /* find a better way for this mess */
1907 srcpads = g_list_next (srcpads);
1909 srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
1914 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1915 GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1919 /* loop through the existing pads in the destination */
1921 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1922 GST_DEBUG_PAD_NAME (destpad));
1923 if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1924 (GST_PAD_PEER (destpad) == NULL)) {
1925 GstPad *temp = gst_element_get_compatible_pad_filtered (src, destpad,
1928 if (temp && gst_pad_link_filtered (temp, destpad, filtercaps)) {
1929 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1930 GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1935 destpads = g_list_next (destpads);
1937 destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
1942 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1943 GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1947 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1948 "we might have request pads on both sides, checking...");
1949 srctempls = gst_element_get_pad_template_list (src);
1950 desttempls = gst_element_get_pad_template_list (dest);
1952 if (srctempls && desttempls) {
1954 srctempl = (GstPadTemplate *) srctempls->data;
1955 if (srctempl->presence == GST_PAD_REQUEST) {
1956 for (l = desttempls; l; l = l->next) {
1957 desttempl = (GstPadTemplate *) l->data;
1958 if (desttempl->presence == GST_PAD_REQUEST &&
1959 desttempl->direction != srctempl->direction) {
1960 if (gst_caps_is_always_compatible (gst_pad_template_get_caps
1961 (srctempl), gst_pad_template_get_caps (desttempl))) {
1963 gst_element_get_request_pad (src, srctempl->name_template);
1965 gst_element_get_request_pad (dest, desttempl->name_template);
1966 if (gst_pad_link_filtered (srcpad, destpad, filtercaps)) {
1967 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1968 "linked pad %s:%s to pad %s:%s",
1969 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1972 /* it failed, so we release the request pads */
1973 gst_element_release_request_pad (src, srcpad);
1974 gst_element_release_request_pad (dest, destpad);
1979 srctempls = srctempls->next;
1983 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1984 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1989 * gst_element_link_filtered:
1990 * @src: a #GstElement containing the source pad.
1991 * @dest: the #GstElement containing the destination pad.
1992 * @filtercaps: the #GstCaps to use as a filter.
1994 * Links @src to @dest, filtered by @filtercaps. The link must be from source to
1995 * destination; the other direction will not be tried. The function looks for
1996 * existing pads that aren't linked yet. It will request new pads if necessary.
1997 * If multiple links are possible, only one is established.
1999 * Returns: TRUE if the elements could be linked, FALSE otherwise.
2002 gst_element_link_filtered (GstElement * src, GstElement * dest,
2003 const GstCaps * filtercaps)
2005 return gst_element_link_pads_filtered (src, NULL, dest, NULL, filtercaps);
2009 * gst_element_link_many:
2010 * @element_1: the first #GstElement in the link chain.
2011 * @element_2: the second #GstElement in the link chain.
2012 * @...: the NULL-terminated list of elements to link in order.
2014 * Chain together a series of elements. Uses gst_element_link().
2016 * Returns: TRUE on success, FALSE otherwise.
2019 gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
2023 g_return_val_if_fail (element_1 != NULL && element_2 != NULL, FALSE);
2024 g_return_val_if_fail (GST_IS_ELEMENT (element_1) &&
2025 GST_IS_ELEMENT (element_2), FALSE);
2027 va_start (args, element_2);
2030 if (!gst_element_link (element_1, element_2))
2033 element_1 = element_2;
2034 element_2 = va_arg (args, GstElement *);
2044 * @src: a #GstElement containing the source pad.
2045 * @dest: the #GstElement containing the destination pad.
2047 * Links @src to @dest with no filter caps. See gst_element_link_filtered() for
2050 * Returns: TRUE if the elements could be linked, FALSE otherwise.
2053 gst_element_link (GstElement * src, GstElement * dest)
2055 return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
2059 * gst_element_link_pads:
2060 * @src: a #GstElement containing the source pad.
2061 * @srcpadname: the name of the #GstPad in the source element.
2062 * @dest: the #GstElement containing the destination pad.
2063 * @destpadname: the name of the #GstPad in destination element.
2065 * Links the two named pads of the source and destination elements.
2066 * Side effect is that if one of the pads has no parent, it becomes a
2067 * child of the parent of the other element. If they have different
2068 * parents, the link fails.
2070 * Returns: TRUE if the pads could be linked, FALSE otherwise.
2073 gst_element_link_pads (GstElement * src, const gchar * srcpadname,
2074 GstElement * dest, const gchar * destpadname)
2076 return gst_element_link_pads_filtered (src, srcpadname, dest, destpadname,
2081 * gst_element_unlink_pads:
2082 * @src: a #GstElement containing the source pad.
2083 * @srcpadname: the name of the #GstPad in source element.
2084 * @dest: a #GstElement containing the destination pad.
2085 * @destpadname: the name of the #GstPad in destination element.
2087 * Unlinks the two named pads of the source and destination elements.
2090 gst_element_unlink_pads (GstElement * src, const gchar * srcpadname,
2091 GstElement * dest, const gchar * destpadname)
2093 GstPad *srcpad, *destpad;
2095 g_return_if_fail (src != NULL);
2096 g_return_if_fail (GST_IS_ELEMENT (src));
2097 g_return_if_fail (srcpadname != NULL);
2098 g_return_if_fail (dest != NULL);
2099 g_return_if_fail (GST_IS_ELEMENT (dest));
2100 g_return_if_fail (destpadname != NULL);
2102 /* obtain the pads requested */
2103 srcpad = gst_element_get_pad (src, srcpadname);
2104 if (srcpad == NULL) {
2105 GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
2108 destpad = gst_element_get_pad (dest, destpadname);
2109 if (srcpad == NULL) {
2110 GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"",
2115 /* we're satisified they can be unlinked, let's do it */
2116 gst_pad_unlink (srcpad, destpad);
2120 * gst_element_unlink_many:
2121 * @element_1: the first #GstElement in the link chain.
2122 * @element_2: the second #GstElement in the link chain.
2123 * @...: the NULL-terminated list of elements to unlink in order.
2125 * Unlinks a series of elements. Uses gst_element_unlink().
2128 gst_element_unlink_many (GstElement * element_1, GstElement * element_2, ...)
2132 g_return_if_fail (element_1 != NULL && element_2 != NULL);
2133 g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
2135 va_start (args, element_2);
2138 gst_element_unlink (element_1, element_2);
2140 element_1 = element_2;
2141 element_2 = va_arg (args, GstElement *);
2148 * gst_element_unlink:
2149 * @src: the source #GstElement to unlink.
2150 * @dest: the sink #GstElement to unlink.
2152 * Unlinks all source pads of the source element with all sink pads
2153 * of the sink element to which they are linked.
2156 gst_element_unlink (GstElement * src, GstElement * dest)
2158 const GList *srcpads;
2161 g_return_if_fail (GST_IS_ELEMENT (src));
2162 g_return_if_fail (GST_IS_ELEMENT (dest));
2164 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
2165 GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
2167 srcpads = gst_element_get_pad_list (src);
2170 pad = GST_PAD (srcpads->data);
2172 /* we only care about real src pads */
2173 if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
2174 GstPad *peerpad = GST_PAD_PEER (pad);
2176 /* see if the pad is connected and is really a pad
2178 if (peerpad && (GST_OBJECT_PARENT (peerpad) == (GstObject *) dest)) {
2179 gst_pad_unlink (pad, peerpad);
2183 srcpads = g_list_next (srcpads);
2188 gst_element_error_func (GstElement * element, GstElement * source,
2189 GError * error, gchar * debug)
2191 GstObject *parent = GST_OBJECT_PARENT (element);
2193 /* tell the parent */
2195 gst_object_ref (GST_OBJECT (element));
2196 gst_object_ref (parent);
2197 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM,
2198 "forwarding error \"%s\" from %s to %s", error->message,
2199 GST_ELEMENT_NAME (element), GST_OBJECT_NAME (parent));
2201 g_signal_emit (G_OBJECT (parent),
2202 gst_element_signals[ERROR], 0, source, error, debug);
2203 GST_CAT_DEBUG (GST_CAT_ERROR_SYSTEM, "forwarded error \"%s\" from %s to %s",
2204 error->message, GST_ELEMENT_NAME (element), GST_OBJECT_NAME (parent));
2205 gst_object_unref (GST_OBJECT (element));
2206 gst_object_unref (GST_OBJECT (parent));
2211 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
2213 GList *pads = element->pads;
2215 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
2217 GstPad *pad = GST_PAD (pads->data);
2219 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
2220 GST_DEBUG_PAD_NAME (pad));
2222 if (GST_PAD_DIRECTION (pad) == dir) {
2223 if (GST_PAD_IS_LINKED (pad)) {
2226 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
2227 GST_DEBUG_PAD_NAME (pad));
2230 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is in wrong direction",
2231 GST_DEBUG_PAD_NAME (pad));
2234 pads = g_list_next (pads);
2240 * gst_element_get_event_masks:
2241 * @element: a #GstElement to query
2243 * Get an array of event masks from the element.
2244 * If the element doesn't implement an event masks function,
2245 * the query will be forwarded to a random linked sink pad.
2247 * Returns: An array of #GstEventMask elements.
2249 const GstEventMask *
2250 gst_element_get_event_masks (GstElement * element)
2252 GstElementClass *oclass;
2254 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2256 oclass = GST_ELEMENT_GET_CLASS (element);
2258 if (oclass->get_event_masks)
2259 return oclass->get_event_masks (element);
2261 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2264 return gst_pad_get_event_masks (GST_PAD_PEER (pad));
2271 * gst_element_send_event:
2272 * @element: a #GstElement to send the event to.
2273 * @event: the #GstEvent to send to the element.
2275 * Sends an event to an element. If the element doesn't
2276 * implement an event handler, the event will be forwarded
2277 * to a random sink pad.
2279 * Returns: TRUE if the event was handled.
2282 gst_element_send_event (GstElement * element, GstEvent * event)
2284 GstElementClass *oclass;
2286 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2287 g_return_val_if_fail (event != NULL, FALSE);
2289 oclass = GST_ELEMENT_GET_CLASS (element);
2291 if (oclass->send_event)
2292 return oclass->send_event (element, event);
2294 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2297 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "sending event to random pad %s:%s",
2298 GST_DEBUG_PAD_NAME (pad));
2299 return gst_pad_send_event (GST_PAD_PEER (pad), event);
2302 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
2303 GST_ELEMENT_NAME (element));
2309 * @element: a #GstElement to send the event to.
2310 * @seek_type: the method to use for seeking.
2311 * @offset: the offset to seek to.
2313 * Sends a seek event to an element.
2315 * Returns: TRUE if the event was handled.
2318 gst_element_seek (GstElement * element, GstSeekType seek_type, guint64 offset)
2320 GstEvent *event = gst_event_new_seek (seek_type, offset);
2322 return gst_element_send_event (element, event);
2326 * gst_element_get_query_types:
2327 * @element: a #GstElement to query
2329 * Get an array of query types from the element.
2330 * If the element doesn't implement a query types function,
2331 * the query will be forwarded to a random sink pad.
2333 * Returns: An array of #GstQueryType elements.
2335 const GstQueryType *
2336 gst_element_get_query_types (GstElement * element)
2338 GstElementClass *oclass;
2340 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2342 oclass = GST_ELEMENT_GET_CLASS (element);
2344 if (oclass->get_query_types)
2345 return oclass->get_query_types (element);
2347 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2350 return gst_pad_get_query_types (GST_PAD_PEER (pad));
2357 * gst_element_query:
2358 * @element: a #GstElement to perform the query on.
2359 * @type: the #GstQueryType.
2360 * @format: the #GstFormat pointer to hold the format of the result.
2361 * @value: the pointer to the value of the result.
2363 * Performs a query on the given element. If the format is set
2364 * to GST_FORMAT_DEFAULT and this function returns TRUE, the
2365 * format pointer will hold the default format.
2366 * For element that don't implement a query handler, this function
2367 * forwards the query to a random usable sinkpad of this element.
2369 * Returns: TRUE if the query could be performed.
2372 gst_element_query (GstElement * element, GstQueryType type,
2373 GstFormat * format, gint64 * value)
2375 GstElementClass *oclass;
2377 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2378 g_return_val_if_fail (format != NULL, FALSE);
2379 g_return_val_if_fail (value != NULL, FALSE);
2381 oclass = GST_ELEMENT_GET_CLASS (element);
2384 return oclass->query (element, type, format, value);
2386 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
2389 return gst_pad_query (pad, type, format, value);
2390 pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2392 return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
2399 * gst_element_get_formats:
2400 * @element: a #GstElement to query
2402 * Get an array of formats from the element.
2403 * If the element doesn't implement a formats function,
2404 * the query will be forwarded to a random sink pad.
2406 * Returns: An array of #GstFormat elements.
2409 gst_element_get_formats (GstElement * element)
2411 GstElementClass *oclass;
2413 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2415 oclass = GST_ELEMENT_GET_CLASS (element);
2417 if (oclass->get_formats)
2418 return oclass->get_formats (element);
2420 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2423 return gst_pad_get_formats (GST_PAD_PEER (pad));
2430 * gst_element_convert:
2431 * @element: a #GstElement to invoke the converter on.
2432 * @src_format: the source #GstFormat.
2433 * @src_value: the source value.
2434 * @dest_format: a pointer to the destination #GstFormat.
2435 * @dest_value: a pointer to the destination value.
2437 * Invokes a conversion on the element.
2438 * If the element doesn't implement a convert function,
2439 * the query will be forwarded to a random sink pad.
2441 * Returns: TRUE if the conversion could be performed.
2444 gst_element_convert (GstElement * element,
2445 GstFormat src_format, gint64 src_value,
2446 GstFormat * dest_format, gint64 * dest_value)
2448 GstElementClass *oclass;
2450 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2451 g_return_val_if_fail (dest_format != NULL, FALSE);
2452 g_return_val_if_fail (dest_value != NULL, FALSE);
2454 if (src_format == *dest_format) {
2455 *dest_value = src_value;
2459 oclass = GST_ELEMENT_GET_CLASS (element);
2461 if (oclass->convert)
2462 return oclass->convert (element,
2463 src_format, src_value, dest_format, dest_value);
2465 GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
2468 return gst_pad_convert (GST_PAD_PEER (pad),
2469 src_format, src_value, dest_format, dest_value);
2476 * _gst_element_error_printf:
2477 * @format: the printf-like format to use, or NULL
2479 * This function is only used internally by the #gst_element_error macro.
2481 * Returns: a newly allocated string, or NULL if the format was NULL or ""
2484 _gst_element_error_printf (const gchar * format, ...)
2494 va_start (args, format);
2495 buffer = g_strdup_vprintf (format, args);
2501 * gst_element_error_full:
2502 * @element: a #GstElement with the error.
2503 * @domain: the GStreamer error domain this error belongs to.
2504 * @code: the error code belonging to the domain
2505 * @message: an allocated message to be used as a replacement for the default
2506 * message connected to code, or NULL
2507 * @debug: an allocated debug message to be used as a replacement for the
2508 * default debugging information, or NULL
2509 * @file: the source code file where the error was generated
2510 * @function: the source code function where the error was generated
2511 * @line: the source code line where the error was generated
2513 * Signals an error condition on an element.
2514 * This function is used internally by elements.
2515 * It results in the "error" signal.
2517 void gst_element_error_full
2518 (GstElement * element, GQuark domain, gint code, gchar * message,
2519 gchar * debug, const gchar * file, const gchar * function, gint line)
2521 GError *error = NULL;
2523 gchar *sent_message;
2527 g_return_if_fail (GST_IS_ELEMENT (element));
2529 /* check if we send the given message or the default error message */
2530 if ((message == NULL) || (message[0] == 0)) {
2531 /* we got this message from g_strdup_printf (""); */
2533 sent_message = gst_error_get_message (domain, code);
2535 sent_message = message;
2537 if ((debug == NULL) || (debug[0] == 0)) {
2538 /* we got this debug from g_strdup_printf (""); */
2543 /* create error message */
2544 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signaling error in %s: %s",
2545 GST_ELEMENT_NAME (element), sent_message);
2546 error = g_error_new (domain, code, sent_message);
2548 /* if the element was already in error, stop now */
2549 if (GST_FLAG_IS_SET (element, GST_ELEMENT_IN_ERROR)) {
2550 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "recursive ERROR detected in %s",
2551 GST_ELEMENT_NAME (element));
2552 g_free (sent_message);
2558 GST_FLAG_SET (element, GST_ELEMENT_IN_ERROR);
2560 /* emit the signal, make sure the element stays available */
2561 gst_object_ref (GST_OBJECT (element));
2562 name = gst_object_get_path_string (GST_OBJECT (element));
2564 sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
2565 file, line, function, name, debug ? debug : "");
2570 g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, element,
2572 GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signalled error in %s: %s",
2573 GST_ELEMENT_NAME (element), sent_message);
2575 /* tell the scheduler */
2576 if (element->sched) {
2577 gst_scheduler_error (element->sched, element);
2580 if (GST_STATE (element) == GST_STATE_PLAYING) {
2581 GstElementStateReturn ret;
2583 ret = gst_element_set_state (element, GST_STATE_PAUSED);
2584 if (ret != GST_STATE_SUCCESS) {
2585 g_warning ("could not PAUSE element \"%s\" after error, help!",
2586 GST_ELEMENT_NAME (element));
2590 GST_FLAG_UNSET (element, GST_ELEMENT_IN_ERROR);
2593 gst_object_unref (GST_OBJECT (element));
2594 g_free (sent_message);
2595 g_free (sent_debug);
2596 g_error_free (error);
2600 * gst_element_is_locked_state:
2601 * @element: a #GstElement.
2603 * Checks if the state of an element is locked.
2604 * If the state of an element is locked, state changes of the parent don't
2605 * affect the element.
2606 * This way you can leave currently unused elements inside bins. Just lock their
2607 * state before changing the state from #GST_STATE_NULL.
2609 * Returns: TRUE, if the element's state is locked.
2612 gst_element_is_locked_state (GstElement * element)
2614 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2616 return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
2620 * gst_element_set_locked_state:
2621 * @element: a #GstElement
2622 * @locked_state: TRUE to lock the element's state
2624 * Locks the state of an element, so state changes of the parent don't affect
2625 * this element anymore.
2628 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
2632 g_return_if_fail (GST_IS_ELEMENT (element));
2634 old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2636 if (old == locked_state)
2640 GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2641 GST_ELEMENT_NAME (element));
2642 GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2644 GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2645 GST_ELEMENT_NAME (element));
2646 GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2651 * gst_element_sync_state_with_parent:
2652 * @element: a #GstElement.
2654 * Tries to change the state of the element to the same as its parent.
2655 * If this function returns FALSE, the state of element is undefined.
2657 * Returns: TRUE, if the element's state could be synced to the parent's state.
2660 gst_element_sync_state_with_parent (GstElement * element)
2664 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2665 parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
2666 g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
2668 GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
2669 GST_ELEMENT_NAME (element),
2670 gst_element_state_get_name (GST_STATE (element)),
2671 GST_ELEMENT_NAME (parent),
2672 gst_element_state_get_name (GST_STATE (parent)));
2673 if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
2680 * gst_element_get_state:
2681 * @element: a #GstElement to get the state of.
2683 * Gets the state of the element.
2685 * Returns: the #GstElementState of the element.
2688 gst_element_get_state (GstElement * element)
2690 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_VOID_PENDING);
2692 return GST_STATE (element);
2696 * gst_element_wait_state_change:
2697 * @element: a #GstElement to wait for a state change on.
2699 * Waits and blocks until the element changed its state.
2702 gst_element_wait_state_change (GstElement * element)
2704 g_mutex_lock (element->state_mutex);
2705 g_cond_wait (element->state_cond, element->state_mutex);
2706 g_mutex_unlock (element->state_mutex);
2710 * gst_element_set_state:
2711 * @element: a #GstElement to change state of.
2712 * @state: the element's new #GstElementState.
2714 * Sets the state of the element. This function will try to set the
2715 * requested state by going through all the intermediary states and calling
2716 * the class's state change function for each.
2718 * Returns: TRUE if the state was successfully set.
2719 * (using #GstElementStateReturn).
2721 GstElementStateReturn
2722 gst_element_set_state (GstElement * element, GstElementState state)
2724 GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
2726 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2727 GST_DEBUG_OBJECT (element, "setting state to %s",
2728 gst_element_state_get_name (state));
2729 klass = GST_ELEMENT_GET_CLASS (element);
2730 /* a set_state function is mandatory */
2731 g_return_val_if_fail (klass->set_state, GST_STATE_FAILURE);
2732 return klass->set_state (element, state);
2735 static GstElementStateReturn
2736 gst_element_set_state_func (GstElement * element, GstElementState state)
2738 GstElementClass *oclass;
2739 GstElementState curpending;
2740 GstElementStateReturn return_val = GST_STATE_SUCCESS;
2742 oclass = GST_ELEMENT_GET_CLASS (element);
2744 /* start with the current state */
2745 curpending = GST_STATE (element);
2747 if (state == curpending) {
2748 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2749 "element is already in requested state %s, returning",
2750 gst_element_state_get_name (state));
2751 return GST_STATE_SUCCESS;
2754 /* reentrancy issues with signals in change_state) */
2755 gst_object_ref (GST_OBJECT (element));
2756 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
2757 gst_element_state_get_name (curpending),
2758 gst_element_state_get_name (state));
2760 /* loop until the final requested state is set */
2762 while (GST_STATE (element) != state
2763 && GST_STATE (element) != GST_STATE_VOID_PENDING) {
2764 /* move the curpending state in the correct direction */
2765 if (curpending < state)
2770 /* set the pending state variable */
2771 GST_STATE_PENDING (element) = curpending;
2773 if (curpending != state) {
2774 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2775 "intermediate: setting state from %s to %s",
2776 gst_element_state_get_name (GST_STATE (element)),
2777 gst_element_state_get_name (curpending));
2779 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2780 "start: setting current state %s again",
2781 gst_element_state_get_name (GST_STATE (element)));
2784 /* call the state change function so it can set the state */
2785 if (oclass->change_state)
2786 return_val = (oclass->change_state) (element);
2788 switch (return_val) {
2789 case GST_STATE_FAILURE:
2790 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2791 "have failed change_state return");
2793 case GST_STATE_ASYNC:
2794 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2795 "element will change state async");
2797 case GST_STATE_SUCCESS:
2798 /* Last thing we do is verify that a successful state change really
2799 * did change the state... */
2800 /* if it did not, this is an error - fix the element that does this */
2801 if (GST_STATE (element) != curpending) {
2802 g_warning ("element %s claimed state-change success,"
2803 "but state didn't change to %s. State is %s (%s pending), "
2805 GST_ELEMENT_NAME (element),
2806 gst_element_state_get_name (curpending),
2807 gst_element_state_get_name (GST_STATE (element)),
2808 gst_element_state_get_name (GST_STATE_PENDING (element)));
2809 return_val = GST_STATE_FAILURE;
2814 /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2815 g_assert_not_reached ();
2820 gst_object_unref (GST_OBJECT (element));
2826 gst_element_negotiate_pads (GstElement * element)
2828 GList *pads = GST_ELEMENT_PADS (element);
2830 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating pads");
2833 GstPad *pad = GST_PAD (pads->data);
2836 pads = g_list_next (pads);
2838 if (!GST_IS_REAL_PAD (pad))
2841 srcpad = GST_PAD_REALIZE (pad);
2843 /* if we have a link on this pad and it doesn't have caps
2844 * allready, try to negotiate */
2845 if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
2846 GstRealPad *sinkpad;
2847 GstElementState otherstate;
2850 sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
2852 /* check the parent of the peer pad, if there is no parent do nothing */
2853 parent = GST_PAD_PARENT (sinkpad);
2857 /* skips pads that were already negotiating */
2858 if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
2859 GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
2862 otherstate = GST_STATE (parent);
2864 /* swap pads if needed */
2865 if (!GST_PAD_IS_SRC (srcpad)) {
2873 /* only try to negotiate if the peer element is in PAUSED or higher too */
2874 if (otherstate >= GST_STATE_READY) {
2875 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2876 "perform negotiate for %s:%s and %s:%s",
2877 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2878 if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
2881 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
2882 "not negotiating %s:%s and %s:%s, not in READY yet",
2883 GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2892 gst_element_clear_pad_caps (GstElement * element)
2894 GList *pads = GST_ELEMENT_PADS (element);
2896 GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "clearing pad caps");
2899 GstPad *pad = GST_PAD (pads->data);
2901 gst_pad_unnegotiate (pad);
2902 if (GST_IS_REAL_PAD (pad)) {
2903 gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
2906 pads = g_list_next (pads);
2911 gst_element_pads_activate (GstElement * element, gboolean active)
2913 GList *pads = element->pads;
2916 GstPad *pad = GST_PAD (pads->data);
2918 pads = g_list_next (pads);
2920 if (!GST_IS_REAL_PAD (pad))
2923 gst_pad_set_active (pad, active);
2927 static GstElementStateReturn
2928 gst_element_change_state (GstElement * element)
2930 GstElementState old_state, old_pending;
2932 gint old_transition;
2934 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
2936 old_state = GST_STATE (element);
2937 old_pending = GST_STATE_PENDING (element);
2938 old_transition = GST_STATE_TRANSITION (element);
2940 /* if the element already is in the given state, we just return success */
2941 if (old_pending == GST_STATE_VOID_PENDING ||
2942 old_state == GST_STATE_PENDING (element)) {
2943 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2944 "element is already in the %s state",
2945 gst_element_state_get_name (old_state));
2946 return GST_STATE_SUCCESS;
2949 /* we need to ref the object because of reentrancy issues with the signal
2950 * handlers (including those in pads and gst_bin_child_state_change */
2951 gst_object_ref (GST_OBJECT (element));
2952 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2953 "default handler tries setting state from %s to %s (%04x)",
2954 gst_element_state_get_name (old_state),
2955 gst_element_state_get_name (old_pending), old_transition);
2957 /* we set the state change early for the negotiation functions */
2958 GST_STATE (element) = old_pending;
2959 GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2961 switch (old_transition) {
2962 case GST_STATE_PLAYING_TO_PAUSED:
2963 if (element->clock) {
2964 GstClockTimeDiff time = gst_clock_get_event_time (element->clock);
2966 g_assert (time >= element->base_time);
2967 element->base_time = time - element->base_time;
2968 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2969 G_GINT64_FORMAT, element->base_time);
2971 gst_element_pads_activate (element, FALSE);
2973 case GST_STATE_PAUSED_TO_PLAYING:
2974 gst_element_pads_activate (element, TRUE);
2975 if (element->clock) {
2976 GstClockTime time = gst_clock_get_event_time (element->clock);
2978 element->base_time = time - element->base_time;
2979 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %"
2980 GST_TIME_FORMAT, GST_TIME_ARGS (element->base_time));
2983 /* if we are going to paused, we try to negotiate the pads */
2984 case GST_STATE_READY_TO_PAUSED:
2985 g_assert (element->base_time == 0);
2986 if (!gst_element_negotiate_pads (element)) {
2987 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2988 "failed state change, could not negotiate pads");
2992 /* going to the READY state clears all pad caps */
2993 /* FIXME: Why doesn't this happen on READY => NULL? -- Company */
2994 case GST_STATE_PAUSED_TO_READY:
2995 element->base_time = 0;
2996 gst_element_clear_pad_caps (element);
2998 case GST_STATE_NULL_TO_READY:
2999 case GST_STATE_READY_TO_NULL:
3002 /* this will catch real but unhandled state changes;
3003 * can only be caused by:
3004 * - a new state was added
3005 * - somehow the element was asked to jump across an intermediate state
3007 g_assert_not_reached ();
3011 parent = GST_ELEMENT_PARENT (element);
3013 GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
3014 "signaling state change from %s to %s",
3015 gst_element_state_get_name (old_state),
3016 gst_element_state_get_name (GST_STATE (element)));
3018 /* tell the scheduler if we have one */
3019 if (element->sched) {
3020 if (gst_scheduler_state_transition (element->sched, element,
3021 old_transition) != GST_STATE_SUCCESS) {
3022 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
3023 "scheduler could not change state");
3028 /* tell our parent about the state change */
3029 if (parent && GST_IS_BIN (parent)) {
3030 gst_bin_child_state_change (GST_BIN (parent), old_state,
3031 GST_STATE (element), element);
3033 /* at this point the state of the element could have changed again */
3035 g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
3036 0, old_state, GST_STATE (element));
3038 /* signal the state change in case somebody is waiting for us */
3039 g_mutex_lock (element->state_mutex);
3040 g_cond_signal (element->state_cond);
3041 g_mutex_unlock (element->state_mutex);
3043 gst_object_unref (GST_OBJECT (element));
3044 return GST_STATE_SUCCESS;
3047 /* undo the state change */
3048 GST_STATE (element) = old_state;
3049 GST_STATE_PENDING (element) = old_pending;
3050 gst_object_unref (GST_OBJECT (element));
3052 return GST_STATE_FAILURE;
3056 * gst_element_get_factory:
3057 * @element: a #GstElement to request the element factory of.
3059 * Retrieves the factory that was used to create this element.
3061 * Returns: the #GstElementFactory used for creating this element.
3064 gst_element_get_factory (GstElement * element)
3066 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3068 return GST_ELEMENT_GET_CLASS (element)->elementfactory;
3072 gst_element_dispose (GObject * object)
3074 GstElement *element = GST_ELEMENT (object);
3076 GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
3078 gst_element_set_state (element, GST_STATE_NULL);
3080 /* first we break all our links with the ouside */
3081 while (element->pads) {
3082 gst_element_remove_pad (element, GST_PAD (element->pads->data));
3085 element->numsrcpads = 0;
3086 element->numsinkpads = 0;
3087 element->numpads = 0;
3088 if (element->state_mutex)
3089 g_mutex_free (element->state_mutex);
3090 element->state_mutex = NULL;
3091 if (element->state_cond)
3092 g_cond_free (element->state_cond);
3093 element->state_cond = NULL;
3095 if (element->prop_value_queue)
3096 g_async_queue_unref (element->prop_value_queue);
3097 element->prop_value_queue = NULL;
3098 if (element->property_mutex)
3099 g_mutex_free (element->property_mutex);
3100 element->property_mutex = NULL;
3102 gst_object_replace ((GstObject **) & element->sched, NULL);
3103 gst_object_replace ((GstObject **) & element->clock, NULL);
3105 G_OBJECT_CLASS (parent_class)->dispose (object);
3108 #ifndef GST_DISABLE_LOADSAVE
3110 * gst_element_save_thyself:
3111 * @element: a #GstElement to save.
3112 * @parent: the xml parent node.
3114 * Saves the element as part of the given XML structure.
3116 * Returns: the new #xmlNodePtr.
3119 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
3122 GstElementClass *oclass;
3123 GParamSpec **specs, *spec;
3125 GValue value = { 0, };
3126 GstElement *element;
3128 g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
3130 element = GST_ELEMENT (object);
3132 oclass = GST_ELEMENT_GET_CLASS (element);
3134 xmlNewChild (parent, NULL, "name", GST_ELEMENT_NAME (element));
3136 if (oclass->elementfactory != NULL) {
3137 GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
3139 xmlNewChild (parent, NULL, "type", GST_PLUGIN_FEATURE (factory)->name);
3142 /* FIXME: what is this? */
3143 /* if (element->manager) */
3144 /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
3147 specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
3149 for (i = 0; i < nspecs; i++) {
3151 if (spec->flags & G_PARAM_READABLE) {
3155 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
3157 g_object_get_property (G_OBJECT (element), spec->name, &value);
3158 param = xmlNewChild (parent, NULL, "param", NULL);
3159 xmlNewChild (param, NULL, "name", spec->name);
3161 if (G_IS_PARAM_SPEC_STRING (spec))
3162 contents = g_value_dup_string (&value);
3163 else if (G_IS_PARAM_SPEC_ENUM (spec))
3164 contents = g_strdup_printf ("%d", g_value_get_enum (&value));
3165 else if (G_IS_PARAM_SPEC_INT64 (spec))
3166 contents = g_strdup_printf ("%" G_GINT64_FORMAT,
3167 g_value_get_int64 (&value));
3169 contents = g_strdup_value_contents (&value);
3171 xmlNewChild (param, NULL, "value", contents);
3174 g_value_unset (&value);
3178 pads = GST_ELEMENT_PADS (element);
3181 GstPad *pad = GST_PAD (pads->data);
3183 /* figure out if it's a direct pad or a ghostpad */
3184 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
3185 xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
3187 gst_object_save_thyself (GST_OBJECT (pad), padtag);
3189 pads = g_list_next (pads);
3196 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
3198 xmlNodePtr children;
3199 GstElement *element;
3201 gchar *value = NULL;
3203 element = GST_ELEMENT (object);
3204 g_return_if_fail (element != NULL);
3207 children = self->xmlChildrenNode;
3209 if (!strcmp (children->name, "param")) {
3210 xmlNodePtr child = children->xmlChildrenNode;
3213 if (!strcmp (child->name, "name")) {
3214 name = xmlNodeGetContent (child);
3215 } else if (!strcmp (child->name, "value")) {
3216 value = xmlNodeGetContent (child);
3218 child = child->next;
3220 /* FIXME: can this just be g_object_set ? */
3221 gst_util_set_object_arg (G_OBJECT (element), name, value);
3222 /* g_object_set (G_OBJECT (element), name, value, NULL); */
3224 children = children->next;
3228 children = self->xmlChildrenNode;
3230 if (!strcmp (children->name, "pad")) {
3231 gst_pad_load_and_link (children, GST_OBJECT (element));
3233 children = children->next;
3236 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3237 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3239 #endif /* GST_DISABLE_LOADSAVE */
3242 * gst_element_yield:
3243 * @element: a #GstElement to yield.
3245 * Requests a yield operation for the element. The scheduler will typically
3246 * give control to another element.
3249 gst_element_yield (GstElement * element)
3251 if (GST_ELEMENT_SCHED (element)) {
3252 gst_scheduler_yield (GST_ELEMENT_SCHED (element), element);
3257 * gst_element_interrupt:
3258 * @element: a #GstElement to interrupt.
3260 * Requests the scheduler of this element to interrupt the execution of
3261 * this element and scheduler another one.
3263 * Returns: TRUE if the element should exit its chain/loop/get
3264 * function ASAP, depending on the scheduler implementation.
3267 gst_element_interrupt (GstElement * element)
3269 if (GST_ELEMENT_SCHED (element)) {
3270 return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element);
3276 * gst_element_set_scheduler:
3277 * @element: a #GstElement to set the scheduler of.
3278 * @sched: the #GstScheduler to set.
3280 * Sets the scheduler of the element. For internal use only, unless you're
3281 * writing a new bin subclass.
3284 gst_element_set_scheduler (GstElement * element, GstScheduler * sched)
3286 g_return_if_fail (GST_IS_ELEMENT (element));
3288 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",
3291 gst_object_replace ((GstObject **) & GST_ELEMENT_SCHED (element),
3292 GST_OBJECT (sched));
3296 * gst_element_get_scheduler:
3297 * @element: a #GstElement to get the scheduler of.
3299 * Returns the scheduler of the element.
3301 * Returns: the element's #GstScheduler.
3304 gst_element_get_scheduler (GstElement * element)
3306 g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3308 return GST_ELEMENT_SCHED (element);
3312 * gst_element_set_loop_function:
3313 * @element: a #GstElement to set the loop function of.
3314 * @loop: Pointer to #GstElementLoopFunction.
3316 * This sets the loop function for the element. The function pointed to
3317 * can deviate from the GstElementLoopFunction definition in type of
3320 * NOTE: in order for this to take effect, the current loop function *must*
3321 * exit. Assuming the loop function itself is the only one who will cause
3322 * a new loopfunc to be assigned, this should be no problem.
3325 gst_element_set_loop_function (GstElement * element,
3326 GstElementLoopFunction loop)
3328 gboolean need_notify = FALSE;
3330 g_return_if_fail (GST_IS_ELEMENT (element));
3332 /* if the element changed from loop based to chain/get based
3333 * or vice versa, we need to inform the scheduler about that */
3334 if ((element->loopfunc == NULL && loop != NULL) ||
3335 (element->loopfunc != NULL && loop == NULL)) {
3339 /* set the loop function */
3340 element->loopfunc = loop;
3343 /* set the NEW_LOOPFUNC flag so everyone knows to go try again */
3344 GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
3346 if (GST_ELEMENT_SCHED (element)) {
3347 gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
3352 gst_element_emit_found_tag (GstElement * element, GstElement * source,
3353 const GstTagList * tag_list)
3355 gst_object_ref (GST_OBJECT (element));
3356 g_signal_emit (element, gst_element_signals[FOUND_TAG], 0, source, tag_list);
3357 gst_object_unref (GST_OBJECT (element));
3360 gst_element_found_tag_func (GstElement * element, GstElement * source,
3361 const GstTagList * tag_list)
3363 /* tell the parent */
3364 if (GST_OBJECT_PARENT (element)) {
3365 GST_CAT_LOG_OBJECT (GST_CAT_EVENT, element, "forwarding tag event to %s",
3366 GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
3367 gst_element_emit_found_tag (GST_ELEMENT (GST_OBJECT_PARENT (element)),
3373 * gst_element_found_tags:
3374 * @element: the element that found the tags
3375 * @tag_list: the found tags
3377 * This function emits the found_tags signal. This is a recursive signal, so
3378 * every parent will emit that signal, too, before this function returns.
3379 * Only emit this signal, when you extracted these tags out of the data stream,
3380 * not when you handle an event.
3383 gst_element_found_tags (GstElement * element, const GstTagList * tag_list)
3385 gst_element_emit_found_tag (element, element, tag_list);
3389 * gst_element_found_tags_for_pad:
3390 * @element: element that found the tag
3391 * @pad: src pad the tags correspond to
3392 * @timestamp: time the tags were found
3393 * @list: the taglist
3395 * This is a convenience routine for tag finding. Most of the time you only
3396 * want to push the found tags down one pad, in that case this function is for
3397 * you. It takes ownership of the taglist, emits the found-tag signal and
3398 * pushes a tag event down the pad.
3399 * <note>This function may not be used in a #GstPadGetFunction, because it calls
3400 * gst_pad_push(). In those functions, call gst_element_found_tags(), create a
3401 * tag event with gst_event_new_tag() and return that from your
3402 * #GstPadGetFunction.</note>
3405 gst_element_found_tags_for_pad (GstElement * element, GstPad * pad,
3406 GstClockTime timestamp, GstTagList * list)
3408 GstEvent *tag_event;
3410 g_return_if_fail (GST_IS_ELEMENT (element));
3411 g_return_if_fail (GST_IS_REAL_PAD (pad));
3412 g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
3413 g_return_if_fail (element == GST_PAD_PARENT (pad));
3414 g_return_if_fail (list != NULL);
3416 tag_event = gst_event_new_tag (list);
3417 GST_EVENT_TIMESTAMP (tag_event) = timestamp;
3418 gst_element_found_tags (element, gst_event_tag_get_list (tag_event));
3419 if (GST_PAD_IS_USABLE (pad)) {
3420 gst_pad_push (pad, GST_DATA (tag_event));
3422 gst_data_unref (GST_DATA (tag_event));
3427 gst_element_set_eos_recursive (GstElement * element)
3429 /* this function is only called, when we were in PLAYING before. So every
3430 parent that's PAUSED was PLAYING before. That means it has reached EOS. */
3433 GST_CAT_DEBUG (GST_CAT_EVENT, "setting recursive EOS on %s",
3434 GST_OBJECT_NAME (element));
3435 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3437 if (!GST_OBJECT_PARENT (element))
3440 parent = GST_ELEMENT (GST_OBJECT_PARENT (element));
3441 if (GST_STATE (parent) == GST_STATE_PAUSED)
3442 gst_element_set_eos_recursive (parent);
3446 * gst_element_set_eos:
3447 * @element: a #GstElement to set to the EOS state.
3449 * Perform the actions needed to bring the element in the EOS state.
3452 gst_element_set_eos (GstElement * element)
3454 g_return_if_fail (GST_IS_ELEMENT (element));
3456 GST_CAT_DEBUG (GST_CAT_EVENT, "setting EOS on element %s",
3457 GST_OBJECT_NAME (element));
3459 if (GST_STATE (element) == GST_STATE_PLAYING) {
3460 gst_element_set_state (element, GST_STATE_PAUSED);
3461 gst_element_set_eos_recursive (element);
3463 g_signal_emit (G_OBJECT (element), gst_element_signals[EOS], 0);
3469 * gst_element_state_get_name:
3470 * @state: a #GstElementState to get the name of.
3472 * Gets a string representing the given state.
3474 * Returns: a string with the name of the state.
3477 gst_element_state_get_name (GstElementState state)
3480 #ifdef GST_DEBUG_COLOR
3481 case GST_STATE_VOID_PENDING:
3482 return "NONE_PENDING";
3484 case GST_STATE_NULL:
3485 return "\033[01;34mNULL\033[00m";
3487 case GST_STATE_READY:
3488 return "\033[01;31mREADY\033[00m";
3490 case GST_STATE_PLAYING:
3491 return "\033[01;32mPLAYING\033[00m";
3493 case GST_STATE_PAUSED:
3494 return "\033[01;33mPAUSED\033[00m";
3497 /* This is a memory leak */
3498 return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
3500 case GST_STATE_VOID_PENDING:
3501 return "NONE_PENDING";
3503 case GST_STATE_NULL:
3506 case GST_STATE_READY:
3509 case GST_STATE_PLAYING:
3512 case GST_STATE_PAUSED:
3523 gst_element_populate_std_props (GObjectClass * klass, const gchar * prop_name,
3524 guint arg_id, GParamFlags flags)
3526 GQuark prop_id = g_quark_from_string (prop_name);
3529 static GQuark fd_id = 0;
3530 static GQuark blocksize_id;
3531 static GQuark bytesperread_id;
3532 static GQuark dump_id;
3533 static GQuark filesize_id;
3534 static GQuark mmapsize_id;
3535 static GQuark location_id;
3536 static GQuark offset_id;
3537 static GQuark silent_id;
3538 static GQuark touch_id;
3541 fd_id = g_quark_from_static_string ("fd");
3542 blocksize_id = g_quark_from_static_string ("blocksize");
3543 bytesperread_id = g_quark_from_static_string ("bytesperread");
3544 dump_id = g_quark_from_static_string ("dump");
3545 filesize_id = g_quark_from_static_string ("filesize");
3546 mmapsize_id = g_quark_from_static_string ("mmapsize");
3547 location_id = g_quark_from_static_string ("location");
3548 offset_id = g_quark_from_static_string ("offset");
3549 silent_id = g_quark_from_static_string ("silent");
3550 touch_id = g_quark_from_static_string ("touch");
3553 if (prop_id == fd_id) {
3554 pspec = g_param_spec_int ("fd", "File-descriptor",
3555 "File-descriptor for the file being read", 0, G_MAXINT, 0, flags);
3556 } else if (prop_id == blocksize_id) {
3557 pspec = g_param_spec_ulong ("blocksize", "Block Size",
3558 "Block size to read per buffer", 0, G_MAXULONG, 4096, flags);
3560 } else if (prop_id == bytesperread_id) {
3561 pspec = g_param_spec_int ("bytesperread", "Bytes per read",
3562 "Number of bytes to read per buffer", G_MININT, G_MAXINT, 0, flags);
3564 } else if (prop_id == dump_id) {
3565 pspec = g_param_spec_boolean ("dump", "Dump",
3566 "Dump bytes to stdout", FALSE, flags);
3568 } else if (prop_id == filesize_id) {
3569 pspec = g_param_spec_int64 ("filesize", "File Size",
3570 "Size of the file being read", 0, G_MAXINT64, 0, flags);
3572 } else if (prop_id == mmapsize_id) {
3573 pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
3574 "Size in bytes of mmap()d regions", 0, G_MAXULONG, 4 * 1048576, flags);
3576 } else if (prop_id == location_id) {
3577 pspec = g_param_spec_string ("location", "File Location",
3578 "Location of the file to read", NULL, flags);
3580 } else if (prop_id == offset_id) {
3581 pspec = g_param_spec_int64 ("offset", "File Offset",
3582 "Byte offset of current read pointer", 0, G_MAXINT64, 0, flags);
3584 } else if (prop_id == silent_id) {
3585 pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
3588 } else if (prop_id == touch_id) {
3589 pspec = g_param_spec_boolean ("touch", "Touch read data",
3590 "Touch data to force disk read before " "push ()", TRUE, flags);
3592 g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
3593 prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
3598 g_object_class_install_property (klass, arg_id, pspec);
3603 * gst_element_class_install_std_props:
3604 * @klass: the #GstElementClass to add the properties to.
3605 * @first_name: the name of the first property.
3606 * in a NULL terminated
3607 * @...: the id and flags of the first property, followed by
3608 * further 'name', 'id', 'flags' triplets and terminated by NULL.
3610 * Adds a list of standardized properties with types to the @klass.
3611 * the id is for the property switch in your get_prop method, and
3612 * the flags determine readability / writeability.
3615 gst_element_class_install_std_props (GstElementClass * klass,
3616 const gchar * first_name, ...)
3622 g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
3624 va_start (args, first_name);
3629 int arg_id = va_arg (args, int);
3630 int flags = va_arg (args, int);
3632 gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id,
3635 name = va_arg (args, char *);
3642 * gst_element_get_managing_bin:
3643 * @element: a #GstElement to get the managing bin of.
3645 * Gets the managing bin (a pipeline or a thread, for example) of an element.
3647 * Returns: the #GstBin, or NULL on failure.
3650 gst_element_get_managing_bin (GstElement * element)
3654 g_return_val_if_fail (element != NULL, NULL);
3656 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (element)));
3658 while (bin && !GST_FLAG_IS_SET (GST_OBJECT (bin), GST_BIN_FLAG_MANAGER))
3659 bin = GST_BIN (gst_object_get_parent (GST_OBJECT (bin)));