2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wim.taymans@chello.be>
5 * gstscheduler.c: Default scheduling code for most cases
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 #define CLASS(obj) GST_SCHEDULER_CLASS (G_OBJECT_GET_CLASS (obj))
25 #include "gst_private.h"
27 #include "gstscheduler.h"
29 static void gst_scheduler_class_init (GstSchedulerClass *klass);
30 static void gst_scheduler_init (GstScheduler *sched);
32 static GstObjectClass *parent_class = NULL;
34 static gchar *_default_name = NULL;
37 gst_scheduler_get_type (void)
39 static GType _gst_scheduler_type = 0;
41 if (!_gst_scheduler_type) {
42 static const GTypeInfo scheduler_info = {
43 sizeof (GstSchedulerClass),
46 (GClassInitFunc) gst_scheduler_class_init,
49 sizeof (GstScheduler),
51 (GInstanceInitFunc) gst_scheduler_init,
55 _gst_scheduler_type = g_type_register_static (GST_TYPE_OBJECT, "GstScheduler",
56 &scheduler_info, G_TYPE_FLAG_ABSTRACT);
58 return _gst_scheduler_type;
62 gst_scheduler_class_init (GstSchedulerClass *klass)
64 parent_class = g_type_class_ref (GST_TYPE_OBJECT);
68 gst_scheduler_init (GstScheduler *sched)
73 * gst_scheduler_setup:
74 * @sched: the schedulerr
76 * Prepare the scheduler.
79 gst_scheduler_setup (GstScheduler *sched)
81 g_return_if_fail (GST_IS_SCHEDULER (sched));
83 if (CLASS (sched)->setup)
84 CLASS (sched)->setup (sched);
88 * gst_scheduler_reset:
89 * @sched: the schedulerr
94 gst_scheduler_reset (GstScheduler *sched)
96 g_return_if_fail (GST_IS_SCHEDULER (sched));
98 if (CLASS (sched)->reset)
99 CLASS (sched)->reset (sched);
103 * gst_scheduler_pad_connect:
104 * @sched: the schedulerr
105 * @srcpad: the srcpad to connect
106 * @sinkpad: the sinkpad to connect to
108 * Connect the srcpad to the given sinkpad.
111 gst_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad)
113 g_return_if_fail (GST_IS_SCHEDULER (sched));
114 g_return_if_fail (GST_IS_PAD (srcpad));
115 g_return_if_fail (GST_IS_PAD (sinkpad));
117 if (CLASS (sched)->pad_connect)
118 CLASS (sched)->pad_connect (sched, srcpad, sinkpad);
122 * gst_scheduler_pad_disconnect:
123 * @sched: the schedulerr
124 * @srcpad: the srcpad to disconnect
125 * @sinkpad: the sinkpad to disconnect from
127 * Disconnect the srcpad to the given sinkpad.
130 gst_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad)
132 g_return_if_fail (GST_IS_SCHEDULER (sched));
133 g_return_if_fail (GST_IS_PAD (srcpad));
134 g_return_if_fail (GST_IS_PAD (sinkpad));
136 if (CLASS (sched)->pad_disconnect)
137 CLASS (sched)->pad_disconnect (sched, srcpad, sinkpad);
141 * gst_scheduler_pad_select:
142 * @sched: the schedulerr
143 * @padlist: the padlist to select on
145 * register the given padlist for a select operation.
147 * Returns: the pad which received a buffer.
150 gst_scheduler_pad_select (GstScheduler *sched, GList *padlist)
152 g_return_if_fail (GST_IS_SCHEDULER (sched));
153 g_return_if_fail (padlist != NULL);
155 if (CLASS (sched)->pad_select)
156 CLASS (sched)->pad_select (sched, padlist);
160 * gst_scheduler_add_element:
161 * @sched: the schedulerr
162 * @element: the element to add to the schedulerr
164 * Add an element to the schedulerr.
167 gst_scheduler_add_element (GstScheduler *sched, GstElement *element)
169 g_return_if_fail (GST_IS_SCHEDULER (sched));
170 g_return_if_fail (GST_IS_ELEMENT (element));
172 if (CLASS (sched)->add_element)
173 CLASS (sched)->add_element (sched, element);
177 * gst_scheduler_state_transition:
178 * @sched: the schedulerr
179 * @element: the element with the state transition
180 * @transition: the state transition
182 * Tell the scheduler that an element changed its state.
184 * Returns: a GstElementStateReturn indicating success or failure
185 * of the state transition.
187 GstElementStateReturn
188 gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint transition)
190 g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_STATE_FAILURE);
191 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
193 if (CLASS (sched)->state_transition)
194 return CLASS (sched)->state_transition (sched, element, transition);
196 return GST_STATE_SUCCESS;
200 * gst_scheduler_remove_element:
201 * @sched: the schedulerr
202 * @element: the element to remove
204 * Remove an element from the schedulerr.
207 gst_scheduler_remove_element (GstScheduler *sched, GstElement *element)
209 g_return_if_fail (GST_IS_SCHEDULER (sched));
210 g_return_if_fail (GST_IS_ELEMENT (element));
212 if (CLASS (sched)->remove_element)
213 CLASS (sched)->remove_element (sched, element);
217 * gst_scheduler_lock_element:
218 * @sched: the schedulerr
219 * @element: the element to lock
221 * Acquire a lock on the given element in the given scheduler.
224 gst_scheduler_lock_element (GstScheduler *sched, GstElement *element)
226 g_return_if_fail (GST_IS_SCHEDULER (sched));
227 g_return_if_fail (GST_IS_ELEMENT (element));
229 if (CLASS (sched)->lock_element)
230 CLASS (sched)->lock_element (sched, element);
234 * gst_scheduler_unlock_element:
235 * @sched: the schedulerr
236 * @element: the element to unlock
238 * Release the lock on the given element in the given scheduler.
241 gst_scheduler_unlock_element (GstScheduler *sched, GstElement *element)
243 g_return_if_fail (GST_IS_SCHEDULER (sched));
244 g_return_if_fail (GST_IS_ELEMENT (element));
246 if (CLASS (sched)->unlock_element)
247 CLASS (sched)->unlock_element (sched, element);
251 * gst_scheduler_error:
252 * @sched: the schedulerr
253 * @element: the element with the error
255 * Tell the scheduler an element was in error
258 gst_scheduler_error (GstScheduler *sched, GstElement *element)
260 g_return_if_fail (GST_IS_SCHEDULER (sched));
261 g_return_if_fail (GST_IS_ELEMENT (element));
263 if (CLASS (sched)->error)
264 CLASS (sched)->error (sched, element);
268 * gst_scheduler_yield:
269 * @sched: the schedulerr
270 * @element: the element requesting a yield
272 * Tell the scheduler to schedule another element.
275 gst_scheduler_yield (GstScheduler *sched, GstElement *element)
277 g_return_if_fail (GST_IS_SCHEDULER (sched));
278 g_return_if_fail (GST_IS_ELEMENT (element));
280 if (CLASS (sched)->yield)
281 CLASS (sched)->yield (sched, element);
285 * gst_scheduler_interrupt:
286 * @sched: the schedulerr
287 * @element: the element requesting an interrupt
289 * Tell the scheduler to interrupt execution of this element.
291 * Returns: TRUE if the element should return NULL from the chain/get
295 gst_scheduler_interrupt (GstScheduler *sched, GstElement *element)
297 g_return_val_if_fail (GST_IS_SCHEDULER (sched), FALSE);
298 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
300 if (CLASS (sched)->interrupt)
301 return CLASS (sched)->interrupt (sched, element);
307 * gst_scheduler_iterate:
308 * @sched: the schedulerr
310 * Perform one iteration on the schedulerr.
312 * Returns: a boolean indicating something usefull has happened.
315 gst_scheduler_iterate (GstScheduler *sched)
317 g_return_if_fail (GST_IS_SCHEDULER (sched));
319 if (CLASS (sched)->iterate)
320 CLASS (sched)->iterate (sched);
325 * gst_scheduler_show:
326 * @sched: the schedulerr
328 * Dump the state of the schedulerr
331 gst_scheduler_show (GstScheduler *sched)
333 g_return_if_fail (GST_IS_SCHEDULER (sched));
335 if (CLASS (sched)->show)
336 CLASS (sched)->show (sched);
340 * Factory stuff starts here
344 static GList* _gst_schedulerfactories;
346 static void gst_schedulerfactory_class_init (GstSchedulerFactoryClass *klass);
347 static void gst_schedulerfactory_init (GstSchedulerFactory *factory);
349 #ifndef GST_DISABLE_REGISTRY
350 static xmlNodePtr gst_schedulerfactory_save_thyself (GstObject *object, xmlNodePtr parent);
351 static void gst_schedulerfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
354 static GstPluginFeatureClass *factory_parent_class = NULL;
355 /* static guint gst_schedulerfactory_signals[LAST_SIGNAL] = { 0 }; */
358 gst_schedulerfactory_get_type (void)
360 static GType schedulerfactory_type = 0;
362 if (!schedulerfactory_type) {
363 static const GTypeInfo schedulerfactory_info = {
364 sizeof (GstSchedulerFactoryClass),
367 (GClassInitFunc) gst_schedulerfactory_class_init,
370 sizeof(GstSchedulerFactory),
372 (GInstanceInitFunc) gst_schedulerfactory_init,
375 schedulerfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
376 "GstSchedulerFactory", &schedulerfactory_info, 0);
378 return schedulerfactory_type;
382 gst_schedulerfactory_class_init (GstSchedulerFactoryClass *klass)
384 GObjectClass *gobject_class;
385 GstObjectClass *gstobject_class;
386 GstPluginFeatureClass *gstpluginfeature_class;
388 gobject_class = (GObjectClass*)klass;
389 gstobject_class = (GstObjectClass*)klass;
390 gstpluginfeature_class = (GstPluginFeatureClass*) klass;
392 factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
394 #ifndef GST_DISABLE_REGISTRY
395 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_schedulerfactory_save_thyself);
396 gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_schedulerfactory_restore_thyself);
399 _gst_schedulerfactories = NULL;
400 _default_name = g_strdup ("basic");
404 gst_schedulerfactory_init (GstSchedulerFactory *factory)
406 _gst_schedulerfactories = g_list_prepend (_gst_schedulerfactories, factory);
411 * gst_schedulerfactory_new:
412 * @name: name of schedulerfactory to create
413 * @longdesc: long description of schedulerfactory to create
414 * @type: the gtk type of the GstScheduler element of this factory
416 * Create a new schedulerfactory with the given parameters
418 * Returns: a new #GstSchedulerFactory.
421 gst_schedulerfactory_new (const gchar *name, const gchar *longdesc, GType type)
423 GstSchedulerFactory *factory;
425 g_return_val_if_fail(name != NULL, NULL);
426 factory = gst_schedulerfactory_find (name);
428 factory = GST_SCHEDULERFACTORY (g_object_new (GST_TYPE_SCHEDULERFACTORY, NULL));
431 gst_object_set_name (GST_OBJECT (factory), name);
432 if (factory->longdesc)
433 g_free (factory->longdesc);
434 factory->longdesc = g_strdup (longdesc);
435 factory->type = type;
441 * gst_schedulerfactory_destroy:
442 * @factory: factory to destroy
444 * Removes the scheduler from the global list.
447 gst_schedulerfactory_destroy (GstSchedulerFactory *factory)
449 g_return_if_fail (factory != NULL);
451 _gst_schedulerfactories = g_list_remove (_gst_schedulerfactories, factory);
453 /* we don't free the struct bacause someone might have a handle to it.. */
457 * gst_schedulerfactory_find:
458 * @name: name of schedulerfactory to find
460 * Search for an schedulerfactory of the given name.
462 * Returns: #GstSchedulerFactory if found, NULL otherwise
465 gst_schedulerfactory_find (const gchar *name)
468 GstSchedulerFactory *factory;
470 g_return_val_if_fail(name != NULL, NULL);
472 GST_DEBUG (0,"gstscheduler: find \"%s\"\n", name);
474 walk = _gst_schedulerfactories;
476 factory = (GstSchedulerFactory *)(walk->data);
477 if (!strcmp (name, GST_OBJECT_NAME (factory)))
479 walk = g_list_next (walk);
486 * gst_schedulerfactory_get_list:
488 * Get the global list of schedulerfactories.
490 * Returns: GList of type #GstSchedulerFactory
493 gst_schedulerfactory_get_list (void)
495 return _gst_schedulerfactories;
499 * gst_schedulerfactory_create:
500 * @factory: the factory used to create the instance
501 * @parent: the parent element of this scheduler
503 * Create a new #GstScheduler instance from the
504 * given schedulerfactory with the given parent.
506 * Returns: A new #GstScheduler instance.
509 gst_schedulerfactory_create (GstSchedulerFactory *factory, GstElement *parent)
511 GstScheduler *new = NULL;
513 g_return_val_if_fail (factory != NULL, NULL);
515 if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
516 g_return_val_if_fail (factory->type != 0, NULL);
518 new = GST_SCHEDULER (g_object_new (factory->type, NULL));
519 new->parent = parent;
526 * gst_schedulerfactory_make:
527 * @name: the name of the factory used to create the instance
528 * @parent: the parent element of this scheduler
530 * Create a new #GstScheduler instance from the
531 * schedulerfactory with the given name and parent.
533 * Returns: A new #GstScheduler instance.
536 gst_schedulerfactory_make (const gchar *name, GstElement *parent)
538 GstSchedulerFactory *factory;
540 g_return_val_if_fail (name != NULL, NULL);
542 factory = gst_schedulerfactory_find (name);
547 return gst_schedulerfactory_create (factory, parent);
551 gst_schedulerfactory_set_default_name (const gchar* name)
554 g_free (_default_name);
556 _default_name = g_strdup (name);
560 gst_schedulerfactory_get_default_name (void)
562 return _default_name;
565 #ifndef GST_DISABLE_REGISTRY
567 gst_schedulerfactory_save_thyself (GstObject *object, xmlNodePtr parent)
569 GstSchedulerFactory *factory;
571 g_return_val_if_fail (GST_IS_SCHEDULERFACTORY (object), parent);
573 factory = GST_SCHEDULERFACTORY (object);
575 if (GST_OBJECT_CLASS (factory_parent_class)->save_thyself) {
576 GST_OBJECT_CLASS (factory_parent_class)->save_thyself (object, parent);
579 xmlNewChild (parent, NULL, "longdesc", factory->longdesc);
585 * gst_schedulerfactory_load_thyself:
586 * @parent: the parent XML node pointer
588 * Load an schedulerfactory from the given XML parent node.
590 * Returns: A new factory based on the XML node.
593 gst_schedulerfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
595 GstSchedulerFactory *factory = GST_SCHEDULERFACTORY (object);
596 xmlNodePtr children = parent->xmlChildrenNode;
598 if (GST_OBJECT_CLASS (factory_parent_class)->restore_thyself) {
599 GST_OBJECT_CLASS (factory_parent_class)->restore_thyself (object, parent);
603 if (!strcmp(children->name, "name")) {
604 gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent (children));
606 if (!strcmp(children->name, "longdesc")) {
607 factory->longdesc = xmlNodeGetContent (children);
609 children = children->next;
612 #endif /* GST_DISABLE_REGISTRY */