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;
35 gst_scheduler_get_type (void)
37 static GType _gst_scheduler_type = 0;
39 if (!_gst_scheduler_type) {
40 static const GTypeInfo scheduler_info = {
41 sizeof (GstSchedulerClass),
44 (GClassInitFunc) gst_scheduler_class_init,
47 sizeof (GstScheduler),
49 (GInstanceInitFunc) gst_scheduler_init,
53 _gst_scheduler_type = g_type_register_static (GST_TYPE_OBJECT, "GstScheduler",
54 &scheduler_info, G_TYPE_FLAG_ABSTRACT);
56 return _gst_scheduler_type;
60 gst_scheduler_class_init (GstSchedulerClass *klass)
62 parent_class = g_type_class_ref (GST_TYPE_OBJECT);
66 gst_scheduler_init (GstScheduler *sched)
71 * gst_scheduler_setup:
72 * @sched: the schedulerr
74 * Prepare the scheduler.
77 gst_scheduler_setup (GstScheduler *sched)
79 g_return_if_fail (GST_IS_SCHEDULER (sched));
81 if (CLASS (sched)->setup)
82 CLASS (sched)->setup (sched);
86 * gst_scheduler_reset:
87 * @sched: the schedulerr
92 gst_scheduler_reset (GstScheduler *sched)
94 g_return_if_fail (GST_IS_SCHEDULER (sched));
96 if (CLASS (sched)->reset)
97 CLASS (sched)->reset (sched);
101 * gst_scheduler_pad_connect:
102 * @sched: the schedulerr
103 * @srcpad: the srcpad to connect
104 * @sinkpad: the sinkpad to connect to
106 * Connect the srcpad to the given sinkpad.
109 gst_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad)
111 g_return_if_fail (GST_IS_SCHEDULER (sched));
112 g_return_if_fail (GST_IS_PAD (srcpad));
113 g_return_if_fail (GST_IS_PAD (sinkpad));
115 if (CLASS (sched)->pad_connect)
116 CLASS (sched)->pad_connect (sched, srcpad, sinkpad);
120 * gst_scheduler_pad_disconnect:
121 * @sched: the schedulerr
122 * @srcpad: the srcpad to disconnect
123 * @sinkpad: the sinkpad to disconnect from
125 * Disconnect the srcpad to the given sinkpad.
128 gst_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad)
130 g_return_if_fail (GST_IS_SCHEDULER (sched));
131 g_return_if_fail (GST_IS_PAD (srcpad));
132 g_return_if_fail (GST_IS_PAD (sinkpad));
134 if (CLASS (sched)->pad_disconnect)
135 CLASS (sched)->pad_disconnect (sched, srcpad, sinkpad);
139 * gst_scheduler_pad_select:
140 * @sched: the schedulerr
141 * @padlist: the padlist to select on
143 * register the given padlist for a select operation.
145 * Returns: the pad which received a buffer.
148 gst_scheduler_pad_select (GstScheduler *sched, GList *padlist)
150 g_return_if_fail (GST_IS_SCHEDULER (sched));
151 g_return_if_fail (padlist != NULL);
153 if (CLASS (sched)->pad_select)
154 CLASS (sched)->pad_select (sched, padlist);
158 * gst_scheduler_add_element:
159 * @sched: the schedulerr
160 * @element: the element to add to the schedulerr
162 * Add an element to the schedulerr.
165 gst_scheduler_add_element (GstScheduler *sched, GstElement *element)
167 g_return_if_fail (GST_IS_SCHEDULER (sched));
168 g_return_if_fail (GST_IS_ELEMENT (element));
170 if (CLASS (sched)->add_element)
171 CLASS (sched)->add_element (sched, element);
175 * gst_scheduler_state_transition:
176 * @sched: the schedulerr
177 * @element: the element with the state transition
178 * @transition: the state transition
180 * Tell the scheduler that an element changed its state.
182 GstElementStateReturn
183 gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint transition)
185 g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_STATE_FAILURE);
186 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
188 if (CLASS (sched)->state_transition)
189 return CLASS (sched)->state_transition (sched, element, transition);
191 return GST_STATE_SUCCESS;
195 * gst_scheduler_remove_element:
196 * @sched: the schedulerr
197 * @element: the element to remove
199 * Remove an element from the schedulerr.
202 gst_scheduler_remove_element (GstScheduler *sched, GstElement *element)
204 g_return_if_fail (GST_IS_SCHEDULER (sched));
205 g_return_if_fail (GST_IS_ELEMENT (element));
207 if (CLASS (sched)->remove_element)
208 CLASS (sched)->remove_element (sched, element);
212 * gst_scheduler_lock_element:
213 * @sched: the schedulerr
214 * @element: the element to lock
216 * Acquire a lock on the given element in the given scheduler.
219 gst_scheduler_lock_element (GstScheduler *sched, GstElement *element)
221 g_return_if_fail (GST_IS_SCHEDULER (sched));
222 g_return_if_fail (GST_IS_ELEMENT (element));
224 if (CLASS (sched)->lock_element)
225 CLASS (sched)->lock_element (sched, element);
229 * gst_scheduler_unlock_element:
230 * @sched: the schedulerr
231 * @element: the element to unlock
233 * Release the lock on the given element in the given scheduler.
236 gst_scheduler_unlock_element (GstScheduler *sched, GstElement *element)
238 g_return_if_fail (GST_IS_SCHEDULER (sched));
239 g_return_if_fail (GST_IS_ELEMENT (element));
241 if (CLASS (sched)->unlock_element)
242 CLASS (sched)->unlock_element (sched, element);
246 * gst_scheduler_error:
247 * @sched: the schedulerr
248 * @element: the element with the error
250 * Tell the scheduler an element was in error
253 gst_scheduler_error (GstScheduler *sched, GstElement *element)
255 g_return_if_fail (GST_IS_SCHEDULER (sched));
256 g_return_if_fail (GST_IS_ELEMENT (element));
258 if (CLASS (sched)->error)
259 CLASS (sched)->error (sched, element);
263 * gst_scheduler_yield:
264 * @sched: the schedulerr
265 * @element: the element requesting a yield
267 * Tell the scheduler to schedule another element.
270 gst_scheduler_yield (GstScheduler *sched, GstElement *element)
272 g_return_if_fail (GST_IS_SCHEDULER (sched));
273 g_return_if_fail (GST_IS_ELEMENT (element));
275 if (CLASS (sched)->yield)
276 CLASS (sched)->yield (sched, element);
280 * gst_scheduler_interrupt:
281 * @sched: the schedulerr
282 * @element: the element requesting an interrupt
284 * Tell the scheduler to interrupt execution of this element.
287 gst_scheduler_interrupt (GstScheduler *sched, GstElement *element)
289 g_return_if_fail (GST_IS_SCHEDULER (sched));
290 g_return_if_fail (GST_IS_ELEMENT (element));
292 if (CLASS (sched)->interrupt)
293 CLASS (sched)->interrupt (sched, element);
297 * gst_scheduler_iterate:
298 * @sched: the schedulerr
300 * Perform one iteration on the schedulerr.
302 * Returns: a boolean indicating something usefull has happened.
305 gst_scheduler_iterate (GstScheduler *sched)
307 g_return_if_fail (GST_IS_SCHEDULER (sched));
309 if (CLASS (sched)->iterate)
310 CLASS (sched)->iterate (sched);
315 * gst_scheduler_show:
316 * @sched: the schedulerr
318 * Dump the state of the schedulerr
321 gst_scheduler_show (GstScheduler *sched)
323 g_return_if_fail (GST_IS_SCHEDULER (sched));
325 if (CLASS (sched)->show)
326 CLASS (sched)->show (sched);
330 * Factory stuff starts here
334 static GList* _gst_schedulerfactories;
336 static void gst_schedulerfactory_class_init (GstSchedulerFactoryClass *klass);
337 static void gst_schedulerfactory_init (GstSchedulerFactory *factory);
339 #ifndef GST_DISABLE_REGISTRY
340 static xmlNodePtr gst_schedulerfactory_save_thyself (GstObject *object, xmlNodePtr parent);
341 static void gst_schedulerfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
344 static GstPluginFeatureClass *factory_parent_class = NULL;
345 /* static guint gst_schedulerfactory_signals[LAST_SIGNAL] = { 0 }; */
348 gst_schedulerfactory_get_type (void)
350 static GType schedulerfactory_type = 0;
352 if (!schedulerfactory_type) {
353 static const GTypeInfo schedulerfactory_info = {
354 sizeof (GstSchedulerFactoryClass),
357 (GClassInitFunc) gst_schedulerfactory_class_init,
360 sizeof(GstSchedulerFactory),
362 (GInstanceInitFunc) gst_schedulerfactory_init,
365 schedulerfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
366 "GstSchedulerFactory", &schedulerfactory_info, 0);
368 return schedulerfactory_type;
372 gst_schedulerfactory_class_init (GstSchedulerFactoryClass *klass)
374 GObjectClass *gobject_class;
375 GstObjectClass *gstobject_class;
376 GstPluginFeatureClass *gstpluginfeature_class;
378 gobject_class = (GObjectClass*)klass;
379 gstobject_class = (GstObjectClass*)klass;
380 gstpluginfeature_class = (GstPluginFeatureClass*) klass;
382 factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
384 #ifndef GST_DISABLE_REGISTRY
385 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_schedulerfactory_save_thyself);
386 gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_schedulerfactory_restore_thyself);
389 _gst_schedulerfactories = NULL;
393 gst_schedulerfactory_init (GstSchedulerFactory *factory)
395 _gst_schedulerfactories = g_list_prepend (_gst_schedulerfactories, factory);
400 * gst_schedulerfactory_new:
401 * @name: name of schedulerfactory to create
402 * @longdesc: long description of schedulerfactory to create
403 * @type: the gtk type of the GstScheduler element of this factory
405 * Create a new schedulerfactory with the given parameters
407 * Returns: a new #GstSchedulerFactory.
410 gst_schedulerfactory_new (const gchar *name, const gchar *longdesc, GType type)
412 GstSchedulerFactory *factory;
414 g_return_val_if_fail(name != NULL, NULL);
415 factory = gst_schedulerfactory_find (name);
417 factory = GST_SCHEDULERFACTORY (g_object_new (GST_TYPE_SCHEDULERFACTORY, NULL));
420 gst_object_set_name (GST_OBJECT (factory), name);
421 if (factory->longdesc)
422 g_free (factory->longdesc);
423 factory->longdesc = g_strdup (longdesc);
424 factory->type = type;
430 * gst_schedulerfactory_destroy:
431 * @factory: factory to destroy
433 * Removes the scheduler from the global list.
436 gst_schedulerfactory_destroy (GstSchedulerFactory *factory)
438 g_return_if_fail (factory != NULL);
440 _gst_schedulerfactories = g_list_remove (_gst_schedulerfactories, factory);
442 /* we don't free the struct bacause someone might have a handle to it.. */
446 * gst_schedulerfactory_find:
447 * @name: name of schedulerfactory to find
449 * Search for an schedulerfactory of the given name.
451 * Returns: #GstSchedulerFactory if found, NULL otherwise
454 gst_schedulerfactory_find (const gchar *name)
457 GstSchedulerFactory *factory;
459 g_return_val_if_fail(name != NULL, NULL);
461 GST_DEBUG (0,"gstscheduler: find \"%s\"\n", name);
463 walk = _gst_schedulerfactories;
465 factory = (GstSchedulerFactory *)(walk->data);
466 if (!strcmp (name, GST_OBJECT_NAME (factory)))
468 walk = g_list_next (walk);
475 * gst_schedulerfactory_get_list:
477 * Get the global list of schedulerfactories.
479 * Returns: GList of type #GstSchedulerFactory
482 gst_schedulerfactory_get_list (void)
484 return _gst_schedulerfactories;
488 * gst_schedulerfactory_create:
489 * @factory: the factory used to create the instance
490 * @parent: the parent element of this scheduler
492 * Create a new #GstScheduler instance from the
493 * given schedulerfactory with the given parent.
495 * Returns: A new #GstScheduler instance.
498 gst_schedulerfactory_create (GstSchedulerFactory *factory, GstElement *parent)
500 GstScheduler *new = NULL;
502 g_return_val_if_fail (factory != NULL, NULL);
504 if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
505 g_return_val_if_fail (factory->type != 0, NULL);
507 new = GST_SCHEDULER (g_object_new (factory->type, NULL));
508 new->parent = parent;
515 * gst_schedulerfactory_make:
516 * @name: the name of the factory used to create the instance
517 * @parent: the parent element of this scheduler
519 * Create a new #GstScheduler instance from the
520 * schedulerfactory with the given name and parent.
522 * Returns: A new #GstScheduler instance.
525 gst_schedulerfactory_make (const gchar *name, GstElement *parent)
527 GstSchedulerFactory *factory;
529 g_return_val_if_fail (name != NULL, NULL);
531 factory = gst_schedulerfactory_find (name);
536 return gst_schedulerfactory_create (factory, parent);
539 #ifndef GST_DISABLE_REGISTRY
541 gst_schedulerfactory_save_thyself (GstObject *object, xmlNodePtr parent)
543 GstSchedulerFactory *factory;
545 g_return_val_if_fail (GST_IS_SCHEDULERFACTORY (object), parent);
547 factory = GST_SCHEDULERFACTORY (object);
549 if (GST_OBJECT_CLASS (factory_parent_class)->save_thyself) {
550 GST_OBJECT_CLASS (factory_parent_class)->save_thyself (object, parent);
553 xmlNewChild (parent, NULL, "longdesc", factory->longdesc);
559 * gst_schedulerfactory_load_thyself:
560 * @parent: the parent XML node pointer
562 * Load an schedulerfactory from the given XML parent node.
564 * Returns: A new factory based on the XML node.
567 gst_schedulerfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
569 GstSchedulerFactory *factory = GST_SCHEDULERFACTORY (object);
570 xmlNodePtr children = parent->xmlChildrenNode;
572 if (GST_OBJECT_CLASS (factory_parent_class)->restore_thyself) {
573 GST_OBJECT_CLASS (factory_parent_class)->restore_thyself (object, parent);
577 if (!strcmp(children->name, "name")) {
578 gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent (children));
580 if (!strcmp(children->name, "longdesc")) {
581 factory->longdesc = xmlNodeGetContent (children);
583 children = children->next;
586 #endif /* GST_DISABLE_REGISTRY */