From 8f06b55c38a22883c4b55a72c730ab7223ba0c63 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 15 Dec 2002 18:21:43 +0000 Subject: [PATCH] - Removed old deprecated fastscheduler Original commit message from CVS: - Removed old deprecated fastscheduler - ifdef out cothread specific code in optimalscheduler - added more g_asserts to optimalscheduler - create separate scheduler called "opt", removed property from scheduler - fixed iterations property --- gst/schedulers/Makefile.am | 22 +- gst/schedulers/gstfastscheduler.c | 1087 -------------------------- gst/schedulers/gstoptimalscheduler.c | 141 ++-- 3 files changed, 82 insertions(+), 1168 deletions(-) delete mode 100644 gst/schedulers/gstfastscheduler.c diff --git a/gst/schedulers/Makefile.am b/gst/schedulers/Makefile.am index bc12181402..11c5ff0dde 100644 --- a/gst/schedulers/Makefile.am +++ b/gst/schedulers/Makefile.am @@ -3,8 +3,7 @@ plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@ plugin_LTLIBRARIES = \ libgstbasicomegascheduler.la \ libgstbasicwingoscheduler.la \ - libgstfastomegascheduler.la \ - libgstfastwingoscheduler.la \ + libgstoptscheduler.la \ libgstoptomegascheduler.la \ libgstoptwingoscheduler.la @@ -20,29 +19,20 @@ libgstbasicwingoscheduler_la_SOURCES = gstbasicscheduler.c libgstbasicwingoscheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_WINGO libgstbasicwingoscheduler_la_CFLAGS += -I$(top_builddir)/libs/ext/cothreads libgstbasicwingoscheduler_la_CFLAGS += -I$(top_srcdir)/libs/ext/cothreads - libgstbasicwingoscheduler_la_LIBADD = $(top_builddir)/libs/ext/cothreads/cothreads/libcothreads-gthreads.la libgstbasicwingoscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstfastomegascheduler_la_SOURCES = gstfastscheduler.c -libgstfastomegascheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_OMEGA -libgstfastomegascheduler_la_LIBADD = ../libcothreads.la -libgstfastomegascheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -libgstfastwingoscheduler_la_SOURCES = gstfastscheduler.c -libgstfastwingoscheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_WINGO -libgstfastwingoscheduler_la_CFLAGS += -I$(top_builddir)/libs/ext/cothreads -libgstfastwingoscheduler_la_CFLAGS += -I$(top_srcdir)/libs/ext/cothreads -libgstfastwingoscheduler_la_LIBADD = $(top_builddir)/libs/ext/cothreads/cothreads/libcothreads-gthreads.la -libgstfastwingoscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstoptscheduler_la_SOURCES = gstoptimalscheduler.c +libgstoptscheduler_la_CFLAGS = $(GST_CFLAGS) +libgstoptscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstoptomegascheduler_la_SOURCES = gstoptimalscheduler.c -libgstoptomegascheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_OMEGA +libgstoptomegascheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_OMEGA -DUSE_COTHREADS libgstoptomegascheduler_la_LIBADD = ../libcothreads.la libgstoptomegascheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstoptwingoscheduler_la_SOURCES = gstoptimalscheduler.c -libgstoptwingoscheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_WINGO +libgstoptwingoscheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_WINGO -DUSE_COTHREADS libgstoptwingoscheduler_la_CFLAGS += -I$(top_builddir)/libs/ext/cothreads libgstoptwingoscheduler_la_CFLAGS += -I$(top_srcdir)/libs/ext/cothreads libgstoptwingoscheduler_la_LIBADD = $(top_builddir)/libs/ext/cothreads/cothreads/libcothreads-gthreads.la diff --git a/gst/schedulers/gstfastscheduler.c b/gst/schedulers/gstfastscheduler.c deleted file mode 100644 index c74387d0c6..0000000000 --- a/gst/schedulers/gstfastscheduler.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstscheduler.c: Default scheduling code for most cases - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/*#define GST_DEBUG_ENABLED */ -#include - -#include "cothreads_compat.h" - -typedef struct _GstSchedulerChain GstSchedulerChain; - -#define GST_ELEMENT_THREADSTATE(elem) (cothread*) (GST_ELEMENT_CAST (elem)->sched_private) -#define GST_RPAD_BUFPEN(pad) (GstBuffer*) (GST_REAL_PAD_CAST(pad)->sched_private) - -#define GST_ELEMENT_COTHREAD_STOPPING GST_ELEMENT_SCHEDULER_PRIVATE1 -#define GST_ELEMENT_IS_COTHREAD_STOPPING(element) GST_FLAG_IS_SET((element), GST_ELEMENT_COTHREAD_STOPPING) -#define GST_ELEMENT_INTERRUPTED GST_ELEMENT_SCHEDULER_PRIVATE2 -#define GST_ELEMENT_IS_INTERRUPTED(element) GST_FLAG_IS_SET((element), GST_ELEMENT_INTERRUPTED) - -typedef struct _GstFastScheduler GstFastScheduler; -typedef struct _GstFastSchedulerClass GstFastSchedulerClass; - -struct _GstSchedulerChain { - GstFastScheduler *sched; - - GList *disabled; - - GList *elements; - gint num_elements; - - GstElement *entry; - - GList *cothreaded_elements; - gint num_cothreaded; - - gboolean schedule; -}; - -#define GST_TYPE_FAST_SCHEDULER \ - (gst_fast_scheduler_get_type()) -#define GST_FAST_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FAST_SCHEDULER,GstFastScheduler)) -#define GST_FAST_SCHEDULER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FAST_SCHEDULER,GstFastSchedulerClass)) -#define GST_IS_FAST_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FAST_SCHEDULER)) -#define GST_IS_FAST_SCHEDULER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FAST_SCHEDULER)) - -#define GST_FAST_SCHEDULER_CAST(sched) ((GstFastScheduler *)(sched)) - -typedef enum { - GST_FAST_SCHEDULER_STATE_NONE, - GST_FAST_SCHEDULER_STATE_STOPPED, - GST_FAST_SCHEDULER_STATE_ERROR, - GST_FAST_SCHEDULER_STATE_RUNNING, -} GstFastSchedulerState; - -struct _GstFastScheduler { - GstScheduler parent; - - GList *elements; - gint num_elements; - - GList *chains; - gint num_chains; - - GstFastSchedulerState state; - - cothread_context *context; -}; - -struct _GstFastSchedulerClass { - GstSchedulerClass parent_class; -}; - -static GType _gst_fast_scheduler_type = 0; - -static void gst_fast_scheduler_class_init (GstFastSchedulerClass * klass); -static void gst_fast_scheduler_init (GstFastScheduler * scheduler); - -static void gst_fast_scheduler_dispose (GObject *object); - -static void gst_fast_scheduler_setup (GstScheduler *sched); -static void gst_fast_scheduler_reset (GstScheduler *sched); -static void gst_fast_scheduler_add_element (GstScheduler *sched, GstElement *element); -static void gst_fast_scheduler_remove_element (GstScheduler *sched, GstElement *element); -static GstElementStateReturn - gst_fast_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint transition); -static void gst_fast_scheduler_lock_element (GstScheduler *sched, GstElement *element); -static void gst_fast_scheduler_unlock_element (GstScheduler *sched, GstElement *element); -static void gst_fast_scheduler_yield (GstScheduler *sched, GstElement *element); -static gboolean gst_fast_scheduler_interrupt (GstScheduler *sched, GstElement *element); -static void gst_fast_scheduler_error (GstScheduler *sched, GstElement *element); -static void gst_fast_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); -static void gst_fast_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); -static GstPad* gst_fast_scheduler_pad_select (GstScheduler *sched, GList *padlist); -static GstSchedulerState - gst_fast_scheduler_iterate (GstScheduler *sched); -/* defined but not used -static void gst_fast_scheduler_show (GstScheduler *sched); -*/ -static GstSchedulerClass *parent_class = NULL; - -static GType -gst_fast_scheduler_get_type (void) -{ - if (!_gst_fast_scheduler_type) { - static const GTypeInfo scheduler_info = { - sizeof (GstFastSchedulerClass), - NULL, - NULL, - (GClassInitFunc) gst_fast_scheduler_class_init, - NULL, - NULL, - sizeof (GstFastScheduler), - 0, - (GInstanceInitFunc) gst_fast_scheduler_init, - NULL - }; - - _gst_fast_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, "GstFast"COTHREADS_NAME_CAPITAL"Scheduler", &scheduler_info, 0); - } - return _gst_fast_scheduler_type; -} - -static void -gst_fast_scheduler_class_init (GstFastSchedulerClass * klass) -{ - GObjectClass *gobject_class; - GstObjectClass *gstobject_class; - GstSchedulerClass *gstscheduler_class; - - gobject_class = (GObjectClass*)klass; - gstobject_class = (GstObjectClass*)klass; - gstscheduler_class = (GstSchedulerClass*)klass; - - parent_class = g_type_class_ref (GST_TYPE_SCHEDULER); - - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_fast_scheduler_dispose); - - gstscheduler_class->setup = GST_DEBUG_FUNCPTR (gst_fast_scheduler_setup); - gstscheduler_class->reset = GST_DEBUG_FUNCPTR (gst_fast_scheduler_reset); - gstscheduler_class->add_element = GST_DEBUG_FUNCPTR (gst_fast_scheduler_add_element); - gstscheduler_class->remove_element = GST_DEBUG_FUNCPTR (gst_fast_scheduler_remove_element); - gstscheduler_class->state_transition = GST_DEBUG_FUNCPTR (gst_fast_scheduler_state_transition); - gstscheduler_class->lock_element = GST_DEBUG_FUNCPTR (gst_fast_scheduler_lock_element); - gstscheduler_class->unlock_element = GST_DEBUG_FUNCPTR (gst_fast_scheduler_unlock_element); - gstscheduler_class->yield = GST_DEBUG_FUNCPTR (gst_fast_scheduler_yield); - gstscheduler_class->interrupt = GST_DEBUG_FUNCPTR (gst_fast_scheduler_interrupt); - gstscheduler_class->error = GST_DEBUG_FUNCPTR (gst_fast_scheduler_error); - gstscheduler_class->pad_connect = GST_DEBUG_FUNCPTR (gst_fast_scheduler_pad_connect); - gstscheduler_class->pad_disconnect = GST_DEBUG_FUNCPTR (gst_fast_scheduler_pad_disconnect); - gstscheduler_class->pad_select = GST_DEBUG_FUNCPTR (gst_fast_scheduler_pad_select); - gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_fast_scheduler_iterate); - - do_cothreads_init(NULL); -} - -static void -gst_fast_scheduler_init (GstFastScheduler *scheduler) -{ - scheduler->elements = NULL; - scheduler->num_elements = 0; - scheduler->chains = NULL; - scheduler->num_chains = 0; -} - -static void -gst_fast_scheduler_dispose (GObject *object) -{ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static gboolean -plugin_init (GModule *module, GstPlugin *plugin) -{ - GstSchedulerFactory *factory; - - gst_plugin_set_longname (plugin, "A fast scheduler"); - - factory = gst_scheduler_factory_new ("fast"COTHREADS_NAME, - "A fast scheduler using "COTHREADS_NAME" cothreads", - gst_fast_scheduler_get_type()); - - if (factory != NULL) { - gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); - } - else { - g_warning ("could not register scheduler: fast"); - } - return TRUE; -} - -GstPluginDesc plugin_desc = { - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "gstfast"COTHREADS_NAME"scheduler", - plugin_init -}; - -static int -gst_fast_scheduler_loopfunc_wrapper (int argc, char *argv[]) -{ - GstElement *element = GST_ELEMENT_CAST (argv); - G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element); - - GST_DEBUG_ENTER ("(%d,'%s')", argc, name); - - do { - GST_DEBUG (GST_CAT_DATAFLOW, "calling loopfunc %s for element %s", - GST_DEBUG_FUNCPTR_NAME (element->loopfunc), name); - (element->loopfunc) (element); - GST_DEBUG (GST_CAT_DATAFLOW, "element %s ended loop function", name); - - } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); - GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING); - - GST_DEBUG_LEAVE ("(%d,'%s')", argc, name); - return 0; -} - -static void -gst_fast_scheduler_chainfunc_proxy (GstPad *pad, GstBuffer *buffer) -{ - GstElement *element = GST_PAD_PARENT (pad); - - GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad)); - - GST_RPAD_BUFPEN (pad) = buffer; - - while (GST_RPAD_BUFPEN (pad) != NULL) { - if (GST_ELEMENT_THREADSTATE (element)) { - do_cothread_switch (GST_ELEMENT_THREADSTATE (element)); - } - else { - g_assert_not_reached(); - } - } - GST_DEBUG_LEAVE ("(%s:%s)", GST_DEBUG_PAD_NAME (pad)); -} - -static GstBuffer* -gst_fast_scheduler_getfunc_proxy (GstPad *pad) -{ - GstElement *element = GST_PAD_PARENT (pad); - GstPad *peer = GST_PAD_CAST (GST_RPAD_PEER (pad)); - GstBuffer *buf; - - GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad)); - - while (GST_RPAD_BUFPEN (peer) == NULL) { - if (GST_ELEMENT_THREADSTATE (element)) { - do_cothread_switch (GST_ELEMENT_THREADSTATE (element)); - } - else { - g_assert_not_reached(); - } - } - - GST_DEBUG_LEAVE ("(%s:%s)", GST_DEBUG_PAD_NAME (pad)); - buf = GST_RPAD_BUFPEN (peer); - GST_RPAD_BUFPEN (peer) = NULL; - - return buf; -} - -static gboolean -gst_fast_scheduler_cothreaded_element (GstBin * bin, GstElement *element) -{ - cothread_func wrapper_function; - const GList *pads; - GstFastScheduler *sched; - - GST_DEBUG (GST_CAT_SCHEDULING, "element is using COTHREADS"); - - sched = (GstFastScheduler *) GST_ELEMENT_SCHED (bin); - g_assert (GST_IS_FAST_SCHEDULER (sched)); - - wrapper_function = GST_DEBUG_FUNCPTR (gst_fast_scheduler_loopfunc_wrapper); - - if (GST_ELEMENT_THREADSTATE (element) == NULL) { - do_cothread_create (GST_ELEMENT_THREADSTATE (element), sched->context, wrapper_function, 0, (char **) element); - if (GST_ELEMENT_THREADSTATE (element) == NULL) { - gst_element_error (element, "could not create cothread for \"%s\"", - GST_ELEMENT_NAME (element), NULL); - return FALSE; - GST_DEBUG (GST_CAT_SCHEDULING, "created cothread %p for '%s' with wrapper function &%s", - GST_ELEMENT_THREADSTATE (element), - GST_ELEMENT_NAME (element), GST_DEBUG_FUNCPTR_NAME (wrapper_function)); - } - } else { - do_cothread_setfunc (GST_ELEMENT_THREADSTATE (element), sched->context, wrapper_function, 0, (char **) element); - GST_DEBUG (GST_CAT_SCHEDULING, "set wrapper function for '%s' to &%s", - GST_ELEMENT_NAME (element), GST_DEBUG_FUNCPTR_NAME (wrapper_function)); - } - - pads = gst_element_get_pad_list (element); - - while (pads) { - GstPad *pad = GST_PAD_CAST (pads->data); - pads = g_list_next (pads); - - if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) { - GST_DEBUG (GST_CAT_SCHEDULING, "setting gethandler to getfunc_proxy for %s:%s", GST_DEBUG_PAD_NAME (pad)); - GST_RPAD_GETHANDLER (pad) = gst_fast_scheduler_getfunc_proxy; - } - else { - GST_DEBUG (GST_CAT_SCHEDULING, "setting chainhandler to chainfunc_proxy for %s:%s", GST_DEBUG_PAD_NAME (pad)); - GST_RPAD_CHAINHANDLER (pad) = gst_fast_scheduler_chainfunc_proxy; - } - } - - return TRUE; -} - -static void -gst_fast_scheduler_event_proxy (GstPad *pad, GstBuffer *buf) -{ - if (GST_IS_EVENT (buf)) - GST_RPAD_EVENTFUNC (pad) (pad, GST_EVENT (buf)); - else - GST_RPAD_CHAINFUNC (pad) (pad, buf); -} - - -static gboolean -gst_fast_scheduler_chained_element (GstBin *bin, GstElement *element) { - const GList *pads; - GstPad *pad; - - GST_DEBUG (GST_CAT_SCHEDULING,"chain entered"); - - /* walk through all the pads */ - pads = gst_element_get_pad_list (element); - while (pads) { - pad = GST_PAD (pads->data); - pads = g_list_next (pads); - if (!GST_IS_REAL_PAD (pad)) - continue; - - if (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK) { - GST_DEBUG (GST_CAT_SCHEDULING,"copying chain function into chain handler for %s:%s",GST_DEBUG_PAD_NAME (pad)); - if (!GST_FLAG_IS_SET (element, GST_ELEMENT_EVENT_AWARE)) - GST_RPAD_CHAINHANDLER (pad) = gst_fast_scheduler_event_proxy; - else - GST_RPAD_CHAINHANDLER (pad) = GST_RPAD_CHAINFUNC (pad); - } else { - GST_DEBUG (GST_CAT_SCHEDULING,"copying get function into get handler for %s:%s",GST_DEBUG_PAD_NAME (pad)); - if (!GST_RPAD_GETFUNC (pad)) - GST_RPAD_GETHANDLER (pad) = gst_fast_scheduler_getfunc_proxy; - else - GST_RPAD_GETHANDLER (pad) = GST_RPAD_GETFUNC (pad); - } - } - - return TRUE; -} - - -static GstSchedulerChain * -gst_fast_scheduler_chain_new (GstFastScheduler * sched) -{ - GstSchedulerChain *chain = g_new (GstSchedulerChain, 1); - - /* initialize the chain with sane values */ - chain->sched = sched; - chain->disabled = NULL; - chain->elements = NULL; - chain->num_elements = 0; - chain->entry = NULL; - chain->cothreaded_elements = NULL; - chain->num_cothreaded = 0; - chain->schedule = FALSE; - - /* add the chain to the schedulers' list of chains */ - sched->chains = g_list_prepend (sched->chains, chain); - sched->num_chains++; - - GST_INFO (GST_CAT_SCHEDULING, "created new chain %p, now are %d chains in sched %p", - chain, sched->num_chains, sched); - - return chain; -} - -static void -gst_fast_scheduler_chain_destroy (GstSchedulerChain * chain) -{ - GstFastScheduler *sched = chain->sched; - - - /* remove the chain from the schedulers' list of chains */ - sched->chains = g_list_remove (sched->chains, chain); - sched->num_chains--; - - /* destroy the chain */ - g_list_free (chain->disabled); /* should be empty... */ - g_list_free (chain->elements); /* ditto */ - - GST_INFO (GST_CAT_SCHEDULING, "destroyed chain %p, now are %d chains in sched %p", chain, - sched->num_chains, sched); - - g_free (chain); -} - -static gboolean -gst_fast_scheduler_chain_enable_element (GstSchedulerChain * chain, GstElement * element) -{ - GST_INFO (GST_CAT_SCHEDULING, "enabling element \"%s\" in chain %p, %d cothreaded elements", - GST_ELEMENT_NAME (element), chain, chain->num_cothreaded); - - /* remove from disabled list */ - chain->disabled = g_list_remove (chain->disabled, element); - - /* add to elements list */ - chain->elements = g_list_prepend (chain->elements, element); - - /* reschedule the chain */ - if (element->loopfunc) { - chain->cothreaded_elements = g_list_prepend (chain->cothreaded_elements, element); - chain->num_cothreaded++; - - return gst_fast_scheduler_cothreaded_element (GST_BIN (GST_SCHEDULER (chain->sched)->parent), element); - } - else { - if (element->numsinkpads == 0 || GST_ELEMENT_IS_DECOUPLED (element)) { - chain->entry = element; - } - - return gst_fast_scheduler_chained_element (GST_BIN (GST_SCHEDULER (chain->sched)->parent), element); - } -} - -static void -gst_fast_scheduler_chain_disable_element (GstSchedulerChain * chain, GstElement * element) -{ - GST_INFO (GST_CAT_SCHEDULING, "disabling element \"%s\" in chain %p", GST_ELEMENT_NAME (element), - chain); - - /* remove from elements list */ - chain->elements = g_list_remove (chain->elements, element); - - /* add to disabled list */ - chain->disabled = g_list_prepend (chain->disabled, element); - - if (element->loopfunc) { - chain->cothreaded_elements = g_list_remove (chain->cothreaded_elements, element); - chain->num_cothreaded--; - } - else { - if (chain->entry == element) - chain->entry = NULL; - } -} - -static void -gst_fast_scheduler_chain_add_element (GstSchedulerChain * chain, GstElement * element) -{ - GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to chain %p", GST_ELEMENT_NAME (element), - chain); - - /* set the sched pointer for the element */ - element->sched = GST_SCHEDULER (chain->sched); - - /* add the element to the list of 'disabled' elements */ - chain->disabled = g_list_prepend (chain->disabled, element); - chain->num_elements++; -} - -static void -gst_fast_scheduler_chain_remove_element (GstSchedulerChain * chain, GstElement * element) -{ - GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from chain %p", GST_ELEMENT_NAME (element), - chain); - - /* if it's active, deactivate it */ - if (g_list_find (chain->elements, element)) { - gst_fast_scheduler_chain_disable_element (chain, element); - } - /* we have to check for a threadstate here because a queue doesn't have one */ - if (GST_ELEMENT_THREADSTATE (element)) { - do_cothread_destroy (GST_ELEMENT_THREADSTATE (element)); - GST_ELEMENT_THREADSTATE (element) = NULL; - } - - /* remove the element from the list of elements */ - chain->disabled = g_list_remove (chain->disabled, element); - chain->num_elements--; - - /* if there are no more elements in the chain, destroy the chain */ - if (chain->num_elements == 0) - gst_fast_scheduler_chain_destroy (chain); -} - -static void -gst_fast_scheduler_chain_elements (GstFastScheduler * sched, GstElement * element1, GstElement * element2) -{ - GList *chains; - GstSchedulerChain *chain; - GstSchedulerChain *chain1 = NULL, *chain2 = NULL; - GstElement *element; - - /* first find the chains that hold the two */ - chains = sched->chains; - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - if (g_list_find (chain->disabled, element1)) - chain1 = chain; - else if (g_list_find (chain->elements, element1)) - chain1 = chain; - - if (g_list_find (chain->disabled, element2)) - chain2 = chain; - else if (g_list_find (chain->elements, element2)) - chain2 = chain; - } - - /* first check to see if they're in the same chain, we're done if that's the case */ - if ((chain1 != NULL) && (chain1 == chain2)) { - GST_INFO (GST_CAT_SCHEDULING, "elements are already in the same chain"); - return; - } - - /* now, if neither element has a chain, create one */ - if ((chain1 == NULL) && (chain2 == NULL)) { - GST_INFO (GST_CAT_SCHEDULING, "creating new chain to hold two new elements"); - chain = gst_fast_scheduler_chain_new (sched); - gst_fast_scheduler_chain_add_element (chain, element1); - gst_fast_scheduler_chain_add_element (chain, element2); - - /* otherwise if both have chains already, join them */ - } - else if ((chain1 != NULL) && (chain2 != NULL)) { - GST_INFO (GST_CAT_SCHEDULING, "merging chain %p into chain %p", chain2, chain1); - /* take the contents of chain2 and merge them into chain1 */ - chain1->disabled = g_list_concat (chain1->disabled, g_list_copy (chain2->disabled)); - chain1->elements = g_list_concat (chain1->elements, g_list_copy (chain2->elements)); - /* chain1->cothreaded_elements = g_list_concat (chain1->cothreaded_elements, g_list_copy (chain2->cothreaded_elements)); */ - chain1->num_elements += chain2->num_elements; - /* chain1->num_cothreaded += chain2->num_cothreaded; */ - - gst_fast_scheduler_chain_destroy (chain2); - - /* otherwise one has a chain already, the other doesn't */ - } - else { - /* pick out which one has the chain, and which doesn't */ - if (chain1 != NULL) - chain = chain1, element = element2; - else - chain = chain2, element = element1; - - GST_INFO (GST_CAT_SCHEDULING, "adding element to existing chain"); - gst_fast_scheduler_chain_add_element (chain, element); - } -} - - -/* find the chain within the scheduler that holds the element, if any */ -static GstSchedulerChain * -gst_fast_scheduler_find_chain (GstFastScheduler * sched, GstElement * element) -{ - GList *chains; - GstSchedulerChain *chain; - - GST_INFO (GST_CAT_SCHEDULING, "searching for element \"%s\" in chains", - GST_ELEMENT_NAME (element)); - - chains = sched->chains; - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - if (g_list_find (chain->elements, element)) - return chain; - if (g_list_find (chain->disabled, element)) - return chain; - } - - return NULL; -} - -static void -gst_fast_scheduler_chain_recursive_add (GstSchedulerChain * chain, GstElement * element) -{ - GList *pads; - GstPad *pad; - GstElement *peerelement; - - /* add the element to the chain */ - gst_fast_scheduler_chain_add_element (chain, element); - - GST_DEBUG (GST_CAT_SCHEDULING, "recursing on element \"%s\"", GST_ELEMENT_NAME (element)); - /* now go through all the pads and see which peers can be added */ - pads = element->pads; - while (pads) { - pad = GST_PAD (pads->data); - pads = g_list_next (pads); - - GST_DEBUG (GST_CAT_SCHEDULING, "have pad %s:%s, checking for valid peer", - GST_DEBUG_PAD_NAME (pad)); - /* if the peer exists and could be in the same chain */ - if (GST_PAD_PEER (pad)) { - GST_DEBUG (GST_CAT_SCHEDULING, "has peer %s:%s", GST_DEBUG_PAD_NAME (GST_PAD_PEER (pad))); - peerelement = GST_PAD_PARENT (GST_PAD_PEER (pad)); - if (GST_ELEMENT_SCHED (GST_PAD_PARENT (pad)) == GST_ELEMENT_SCHED (peerelement)) { - GST_DEBUG (GST_CAT_SCHEDULING, "peer \"%s\" is valid for same chain", - GST_ELEMENT_NAME (peerelement)); - /* if it's not already in a chain, add it to this one */ - if (gst_fast_scheduler_find_chain (chain->sched, peerelement) == NULL) { - gst_fast_scheduler_chain_recursive_add (chain, peerelement); - } - } - } - } -} - -/* - * Entry points for this scheduler. - */ -static void -gst_fast_scheduler_setup (GstScheduler *sched) -{ - GstFastScheduler *fast = GST_FAST_SCHEDULER_CAST (sched); - - /* first create thread context */ - if (fast->context == NULL) { - GST_DEBUG (GST_CAT_SCHEDULING, "initializing cothread context"); - fast->context = do_cothread_context_init (); - } -} - -static void -gst_fast_scheduler_reset (GstScheduler *sched) -{ - GstFastScheduler *fast = GST_FAST_SCHEDULER_CAST (sched); - GList *elements = fast->elements; - - while (elements) { - GST_ELEMENT_THREADSTATE (elements->data) = NULL; - elements = g_list_next (elements); - } - - do_cothread_context_destroy (fast->context); - - fast->context = NULL; -} - -static void -gst_fast_scheduler_add_element (GstScheduler * sched, GstElement * element) -{ - GList *pads; - GstPad *pad; - GstElement *peerelement; - GstSchedulerChain *chain; - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - - GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to scheduler", GST_ELEMENT_NAME (element)); - - /* only deal with elements after this point, not bins */ - /* exception is made for Bin's that are schedulable, like the autoplugger */ - if (GST_IS_BIN (element) && !GST_FLAG_IS_SET (element, GST_BIN_SELF_SCHEDULABLE)) - return; - - /* first add it to the list of elements that are to be scheduled */ - bsched->elements = g_list_prepend (bsched->elements, element); - bsched->num_elements++; - - /* create a chain to hold it, and add */ - chain = gst_fast_scheduler_chain_new (bsched); - gst_fast_scheduler_chain_add_element (chain, element); - - /* set the sched pointer in all the pads */ - pads = element->pads; - while (pads) { - pad = GST_PAD (pads->data); - pads = g_list_next (pads); - - /* we only operate on real pads */ - if (!GST_IS_REAL_PAD (pad)) - continue; - - /* if the peer element exists and is a candidate */ - if (GST_PAD_PEER (pad)) { - peerelement = GST_PAD_PARENT (GST_PAD_PEER (pad)); - if (GST_ELEMENT_SCHED (element) == GST_ELEMENT_SCHED (peerelement)) { - GST_INFO (GST_CAT_SCHEDULING, "peer is in same scheduler, chaining together"); - /* make sure that the two elements are in the same chain */ - gst_fast_scheduler_chain_elements (bsched, element, peerelement); - } - } - } -} - -static void -gst_fast_scheduler_remove_element (GstScheduler * sched, GstElement * element) -{ - GstSchedulerChain *chain; - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - - if (g_list_find (bsched->elements, element)) { - GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from scheduler", - GST_ELEMENT_NAME (element)); - - /* find what chain the element is in */ - chain = gst_fast_scheduler_find_chain (bsched, element); - - /* remove it from its chain */ - gst_fast_scheduler_chain_remove_element (chain, element); - - /* remove it from the list of elements */ - bsched->elements = g_list_remove (bsched->elements, element); - bsched->num_elements--; - } -} - -static GstElementStateReturn -gst_fast_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint transition) -{ - GstSchedulerChain *chain; - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - - /* check if our parent changed state */ - if (GST_SCHEDULER_PARENT (sched) == element) { - GST_INFO (GST_CAT_SCHEDULING, "parent \"%s\" changed state", GST_ELEMENT_NAME (element)); - if (transition == GST_STATE_PLAYING_TO_PAUSED) { - GST_INFO (GST_CAT_SCHEDULING, "setting scheduler state to stopped"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_STOPPED; - } - else if (transition == GST_STATE_PAUSED_TO_PLAYING) { - GST_INFO (GST_CAT_SCHEDULING, "setting scheduler state to running"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_RUNNING; - } - else { - GST_INFO (GST_CAT_SCHEDULING, "no interesting state change, doing nothing"); - } - } - else if (transition == GST_STATE_PLAYING_TO_PAUSED || - transition == GST_STATE_PAUSED_TO_PLAYING) { - /* find the chain the element is in */ - chain = gst_fast_scheduler_find_chain (bsched, element); - - /* remove it from the chain */ - if (chain) { - if (transition == GST_STATE_PLAYING_TO_PAUSED) { - gst_fast_scheduler_chain_disable_element (chain, element); - } - else if (transition == GST_STATE_PAUSED_TO_PLAYING) { - if (!gst_fast_scheduler_chain_enable_element (chain, element)) { - GST_INFO (GST_CAT_SCHEDULING, "could not enable element \"%s\"", GST_ELEMENT_NAME (element)); - return GST_STATE_FAILURE; - } - } - } - else { - GST_INFO (GST_CAT_SCHEDULING, "element \"%s\" not found in any chain, no state change", GST_ELEMENT_NAME (element)); - } - } - - return GST_STATE_SUCCESS; -} - -static void -gst_fast_scheduler_lock_element (GstScheduler * sched, GstElement * element) -{ - if (GST_ELEMENT_THREADSTATE (element)) - do_cothread_lock (GST_ELEMENT_THREADSTATE (element)); -} - -static void -gst_fast_scheduler_unlock_element (GstScheduler * sched, GstElement * element) -{ - if (GST_ELEMENT_THREADSTATE (element)) - do_cothread_unlock (GST_ELEMENT_THREADSTATE (element)); -} - -static void -gst_fast_scheduler_yield (GstScheduler *sched, GstElement *element) -{ - if (GST_ELEMENT_IS_COTHREAD_STOPPING (element)) { - do_cothread_switch (do_cothread_get_main (GST_FAST_SCHEDULER_CAST (sched)->context)); - } -} - -static gboolean -gst_fast_scheduler_interrupt (GstScheduler *sched, GstElement *element) -{ - if (do_cothread_get_current () != do_cothread_get_main (GST_FAST_SCHEDULER_CAST (sched)->context)) { - do_cothread_switch (do_cothread_get_main (GST_FAST_SCHEDULER_CAST (sched)->context)); - return FALSE; - } - GST_FLAG_SET (element, GST_ELEMENT_INTERRUPTED); - return TRUE; -} - -static void -gst_fast_scheduler_error (GstScheduler *sched, GstElement *element) -{ - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - GstSchedulerChain *chain; - - chain = gst_fast_scheduler_find_chain (bsched, element); - if (chain) - gst_fast_scheduler_chain_disable_element (chain, element); - - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_ERROR; - - gst_fast_scheduler_interrupt (sched, element); -} - -static void -gst_fast_scheduler_pad_connect (GstScheduler * sched, GstPad *srcpad, GstPad *sinkpad) -{ - GstElement *srcelement, *sinkelement; - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - - srcelement = GST_PAD_PARENT (srcpad); - g_return_if_fail (srcelement != NULL); - sinkelement = GST_PAD_PARENT (sinkpad); - g_return_if_fail (sinkelement != NULL); - - GST_INFO (GST_CAT_SCHEDULING, "have pad connected callback on %s:%s to %s:%s", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - GST_DEBUG (GST_CAT_SCHEDULING, "srcpad sched is %p, sinkpad sched is %p", - GST_ELEMENT_SCHED (srcelement), GST_ELEMENT_SCHED (sinkelement)); - - if (GST_ELEMENT_SCHED (srcelement) == GST_ELEMENT_SCHED (sinkelement)) { - GST_INFO (GST_CAT_SCHEDULING, "peer %s:%s is in same scheduler, chaining together", - GST_DEBUG_PAD_NAME (sinkpad)); - gst_fast_scheduler_chain_elements (bsched, srcelement, sinkelement); - } -} - -static void -gst_fast_scheduler_pad_disconnect (GstScheduler * sched, GstPad * srcpad, GstPad * sinkpad) -{ - GstElement *element1, *element2; - GstSchedulerChain *chain1, *chain2; - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - - GST_INFO (GST_CAT_SCHEDULING, "disconnecting pads %s:%s and %s:%s", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - - /* we need to have the parent elements of each pad */ - element1 = GST_ELEMENT_CAST (GST_PAD_PARENT (srcpad)); - element2 = GST_ELEMENT_CAST (GST_PAD_PARENT (sinkpad)); - - /* first task is to remove the old chain they belonged to. - * this can be accomplished by taking either of the elements, - * since they are guaranteed to be in the same chain - * FIXME is it potentially better to make an attempt at splitting cleaner?? - */ - chain1 = gst_fast_scheduler_find_chain (bsched, element1); - chain2 = gst_fast_scheduler_find_chain (bsched, element2); - - if (chain1 != chain2) { - /* elements not in the same chain don't need to be separated */ - GST_INFO (GST_CAT_SCHEDULING, "elements not in the same chain"); - return; - } - - if (chain1) { - GST_INFO (GST_CAT_SCHEDULING, "destroying chain"); - gst_fast_scheduler_chain_destroy (chain1); - - /* now create a new chain to hold element1 and build it from scratch */ - chain1 = gst_fast_scheduler_chain_new (bsched); - gst_fast_scheduler_chain_recursive_add (chain1, element1); - } - - /* check the other element to see if it landed in the newly created chain */ - if (gst_fast_scheduler_find_chain (bsched, element2) == NULL) { - /* if not in chain, create chain and build from scratch */ - chain2 = gst_fast_scheduler_chain_new (bsched); - gst_fast_scheduler_chain_recursive_add (chain2, element2); - } -} - -static GstPad * -gst_fast_scheduler_pad_select (GstScheduler * sched, GList * padlist) -{ - GstPad *pad = NULL; - - GST_INFO (GST_CAT_SCHEDULING, "imlement me!!"); - - return pad; -} - -static GstSchedulerState -gst_fast_scheduler_iterate (GstScheduler * sched) -{ - GstBin *bin = GST_BIN (sched->parent); - GList *chains; - GstSchedulerChain *chain; - gint scheduled = 0; - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - GstSchedulerState state; - - GST_DEBUG_ENTER ("(\"%s\")", GST_ELEMENT_NAME (bin)); - - /* step through all the chains */ - chains = bsched->chains; - - if (chains == NULL) { - GST_DEBUG (GST_CAT_DATAFLOW, "no chains!"); - - state = GST_SCHEDULER_STATE_STOPPED; - - goto exit; - } - - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - if (chain->elements == NULL) { - continue; - } - - if (chain->num_cothreaded > 1) { - g_warning ("this scheduler can only deal with 1 cothreaded element in a chain"); - - state = GST_SCHEDULER_STATE_ERROR; - - goto exit; - } - else if (chain->num_cothreaded != 0) { - /* we just pick the first cothreaded element */ - GstElement *entry = GST_ELEMENT (chain->cothreaded_elements->data); - - GST_DEBUG (GST_CAT_DATAFLOW, "starting iteration via cothreads"); - - GST_FLAG_SET (entry, GST_ELEMENT_COTHREAD_STOPPING); - - GST_DEBUG (GST_CAT_DATAFLOW, "set COTHREAD_STOPPING flag on \"%s\"(@%p)", - GST_ELEMENT_NAME (entry), entry); - - if (GST_ELEMENT_THREADSTATE (entry)) { - do_cothread_switch (GST_ELEMENT_THREADSTATE (entry)); - } - else { - GST_DEBUG (GST_CAT_DATAFLOW, "cothread switch not possible, element has no threadstate"); - - GST_DEBUG (GST_CAT_DATAFLOW, "leaving (%s)", GST_ELEMENT_NAME (bin)); - - state = GST_SCHEDULER_STATE_ERROR; - - goto exit; - } - - GST_DEBUG (GST_CAT_SCHEDULING, "loopfunc of element %s ended", GST_ELEMENT_NAME (entry)); - - scheduled++; - } - else { - GstElement *entry = chain->entry; - if (entry) { - const GList *pads = gst_element_get_pad_list (entry); - - GST_DEBUG (GST_CAT_DATAFLOW, "starting chained iteration"); - - while (pads) { - GstPad *pad = GST_PAD_CAST (pads->data); - pads = g_list_next (pads); - - if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) { - GstBuffer *buf; - - buf = GST_RPAD_GETFUNC (pad) (pad); - if (GST_ELEMENT_IS_INTERRUPTED (entry)) { - GST_FLAG_UNSET (entry, GST_ELEMENT_INTERRUPTED); - break; - } - gst_pad_push (pad, buf); - scheduled++; - } - } - } - else { - GST_INFO (GST_CAT_DATAFLOW, "no entry found!!"); - - state = GST_SCHEDULER_STATE_ERROR; - goto exit; - } - } - - state = GST_SCHEDULER_STATE (sched); - - if (state != GST_SCHEDULER_STATE_RUNNING) { - GST_INFO (GST_CAT_DATAFLOW, "scheduler is not running, in state %d", state); - - goto exit; - } - } - - GST_DEBUG (GST_CAT_DATAFLOW, "leaving (%s)", GST_ELEMENT_NAME (bin)); - - if (scheduled == 0) { - GST_INFO (GST_CAT_DATAFLOW, "nothing was scheduled, return STOPPED"); - state = GST_SCHEDULER_STATE_STOPPED; - } - else { - GST_INFO (GST_CAT_DATAFLOW, "scheduler still running, return RUNNING"); - state = GST_SCHEDULER_STATE_RUNNING; - } - -exit: - GST_DEBUG (GST_CAT_DATAFLOW, "leaving (%s) %d", GST_ELEMENT_NAME (bin), state); - - return state; -} - -/* defined but not used -static void -gst_fast_scheduler_show (GstScheduler * sched) -{ - GList *chains, *elements; - GstElement *element; - GstSchedulerChain *chain; - GstFastScheduler *bsched = GST_FAST_SCHEDULER (sched); - - if (sched == NULL) { - g_print ("scheduler doesn't exist for this element"); - return; - } - - g_return_if_fail (GST_IS_SCHEDULER (sched)); - - g_print ("SCHEDULER DUMP FOR MANAGING BIN \"%s\"\n", GST_ELEMENT_NAME (sched->parent)); - - g_print ("scheduler has %d elements in it: ", bsched->num_elements); - elements = bsched->elements; - while (elements) { - element = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - - g_print ("%s, ", GST_ELEMENT_NAME (element)); - } - g_print ("\n"); - - g_print ("scheduler has %d chains in it\n", bsched->num_chains); - chains = bsched->chains; - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - g_print ("%p: ", chain); - - elements = chain->disabled; - while (elements) { - element = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - - g_print ("!%s, ", GST_ELEMENT_NAME (element)); - } - - elements = chain->elements; - while (elements) { - element = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - - g_print ("%s, ", GST_ELEMENT_NAME (element)); - } - g_print ("\n"); - } -} -*/ diff --git a/gst/schedulers/gstoptimalscheduler.c b/gst/schedulers/gstoptimalscheduler.c index 182be79625..2300c93ac4 100644 --- a/gst/schedulers/gstoptimalscheduler.c +++ b/gst/schedulers/gstoptimalscheduler.c @@ -23,8 +23,12 @@ /*#define GST_DEBUG_ENABLED */ #include -#include "cothreads_compat.h" - +#ifdef USE_COTHREADS +# include "cothreads_compat.h" +#else +# define COTHREADS_NAME_CAPITAL "" +# define COTHREADS_NAME "" +#endif #define GST_ELEMENT_SCHED_CONTEXT(elem) ((GstOptSchedulerCtx*) (GST_ELEMENT_CAST (elem)->sched_private)) #define GST_ELEMENT_SCHED_GROUP(elem) (GST_ELEMENT_SCHED_CONTEXT (elem)->group) @@ -63,8 +67,9 @@ struct _GstOptScheduler { GstOptSchedulerState state; +#ifdef USE_COTHREADS cothread_context *context; - gboolean use_cothreads; +#endif gint iterations; GSList *elements; @@ -140,7 +145,9 @@ struct _GstOptSchedulerGroup { GSList *providers; /* other groups that provide data for this group */ +#ifdef USE_COTHREADS cothread *cothread; /* the cothread of this group */ +#endif GroupScheduleFunction schedulefunc; int argc; char **argv; @@ -164,7 +171,6 @@ struct _GstOptSchedulerCtx { enum { ARG_0, - ARG_USE_COTHREADS, ARG_ITERATIONS, }; @@ -243,10 +249,7 @@ gst_opt_scheduler_class_init (GstOptSchedulerClass *klass) gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_opt_scheduler_get_property); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_opt_scheduler_dispose); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_USE_COTHREADS, - g_param_spec_boolean ("use_cothreads", "Use cothreads", "Should this scheduler use cothreads", - TRUE, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_USE_COTHREADS, + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ITERATIONS, g_param_spec_int ("iterations", "Iterations", "Number of groups to schedule in one iteration (-1 == until EOS/error)", -1, G_MAXINT, 1, G_PARAM_READWRITE)); @@ -273,8 +276,6 @@ static void gst_opt_scheduler_init (GstOptScheduler *scheduler) { scheduler->elements = NULL; - scheduler->use_cothreads = FALSE; - //scheduler->use_cothreads = TRUE; scheduler->iterations = 1; } @@ -328,6 +329,7 @@ delete_chain (GstOptSchedulerChain *chain) while (groups) { GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) groups->data; + /* clear all group's chain pointers, so they can never reference us again */ if (group->chain == chain) group->chain = NULL; @@ -375,6 +377,7 @@ remove_from_chain (GstOptSchedulerChain *chain, GstOptSchedulerGroup *group) if (!chain) return NULL; + g_assert (group); g_assert (group->chain == chain); chain->groups = g_slist_remove (chain->groups, group); @@ -483,13 +486,18 @@ create_group (GstOptSchedulerChain *chain, GstElement *element) static void destroy_group_scheduler (GstOptSchedulerGroup *group) { + g_assert (group); + if (group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING) g_warning ("removing running element"); +#ifdef USE_COTHREADS if (group->cothread) { do_cothread_destroy (group->cothread); } - else { + else +#endif + { group->schedulefunc = NULL; group->argc = 0; group->argv = NULL; @@ -505,6 +513,7 @@ delete_group (GstOptSchedulerGroup *group) GST_INFO (GST_CAT_SCHEDULING, "delete group %p", group); + g_assert (group != NULL); g_assert (group->chain == NULL); if (group->flags & GST_OPT_SCHEDULER_GROUP_SCHEDULABLE) @@ -560,6 +569,9 @@ remove_from_group (GstOptSchedulerGroup *group, GstElement *element) { GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from group %p", GST_ELEMENT_NAME (element), group); + g_assert (group != NULL); + g_assert (element != NULL); + group->elements = g_slist_remove (group->elements, element); group->num_elements--; @@ -578,6 +590,9 @@ remove_from_group (GstOptSchedulerGroup *group, GstElement *element) static void group_element_set_enabled (GstOptSchedulerGroup *group, GstElement *element, gboolean enabled) { + g_assert (group != NULL); + g_assert (element != NULL); + if (enabled) { group->num_enabled++; GST_INFO (GST_CAT_SCHEDULING, "enable element %s in group %p, now %d elements enabled out of %d", @@ -607,18 +622,17 @@ group_element_set_enabled (GstOptSchedulerGroup *group, GstElement *element, gbo static gboolean schedule_group (GstOptSchedulerGroup *group) { - if (group->chain->sched->use_cothreads) { - if (group->cothread) - do_cothread_switch (group->cothread); - return TRUE; - } - else { - group->schedulefunc (group->argc, group->argv); - return TRUE; - } - return FALSE; +#ifdef USE_COTHREADS + if (group->cothread) + do_cothread_switch (group->cothread); + return TRUE; +#else + group->schedulefunc (group->argc, group->argv); + return TRUE; +#endif } +#ifndef USE_COTHREADS static void gst_opt_scheduler_schedule_run_queue (GstOptScheduler *osched) { @@ -643,6 +657,7 @@ gst_opt_scheduler_schedule_run_queue (GstOptScheduler *osched) osched->recursion--; } +#endif /* a chain is scheduled by picking the first active group and scheduling it */ static void @@ -663,14 +678,13 @@ schedule_chain (GstOptSchedulerChain *chain) GST_INFO (GST_CAT_SCHEDULING, "scheduling group %p in chain %p", group, chain); - if (osched->use_cothreads) { - schedule_group (group); - } - else { - osched->recursion = 0; - osched->runqueue = g_list_append (osched->runqueue, group); - gst_opt_scheduler_schedule_run_queue (osched); - } +#ifdef USE_COTHREADS + schedule_group (group); +#else + osched->recursion = 0; + osched->runqueue = g_list_append (osched->runqueue, group); + gst_opt_scheduler_schedule_run_queue (osched); +#endif GST_INFO (GST_CAT_SCHEDULING, "done scheduling group %p in chain %p", group, chain); @@ -768,23 +782,22 @@ gst_opt_scheduler_loop_wrapper (GstPad *sinkpad, GstBuffer *buffer) osched = group->chain->sched; - if (osched->use_cothreads) { - if (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad))) { - g_warning ("deadlock detected, disabling group %p", group); - chain_group_set_enabled (group->chain, group, FALSE); - group->chain->sched->state = GST_OPT_SCHEDULER_STATE_ERROR; - } - else { - GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)) = g_list_append (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)), buffer); - schedule_group (group); - } +#ifdef USE_COTHREADS + if (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad))) { + g_warning ("deadlock detected, disabling group %p", group); + chain_group_set_enabled (group->chain, group, FALSE); + group->chain->sched->state = GST_OPT_SCHEDULER_STATE_ERROR; } else { GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)) = g_list_append (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)), buffer); - if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { - osched->runqueue = g_list_append (osched->runqueue, group); - } + schedule_group (group); } +#else + GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)) = g_list_append (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)), buffer); + if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { + osched->runqueue = g_list_append (osched->runqueue, group); + } +#endif GST_INFO (GST_CAT_SCHEDULING, "after loop wrapper buflist %d", g_list_length (GST_PAD_BUFLIST (GST_RPAD_PEER (sinkpad)))); @@ -810,10 +823,10 @@ gst_opt_scheduler_get_wrapper (GstPad *srcpad) group = GST_ELEMENT_SCHED_GROUP (GST_PAD_PARENT (srcpad)); osched = group->chain->sched; - if (osched->use_cothreads) { - schedule_group (group); - } - else if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { +#ifdef USE_COTHREADS + schedule_group (group); +#else + if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { osched->runqueue = g_list_append (osched->runqueue, group); gst_opt_scheduler_schedule_run_queue (osched); } @@ -823,6 +836,7 @@ gst_opt_scheduler_get_wrapper (GstPad *srcpad) group->chain->sched->state = GST_OPT_SCHEDULER_STATE_ERROR; return NULL; } +#endif if (GST_PAD_BUFLIST (srcpad)) { buffer = (GstBuffer *) GST_PAD_BUFLIST (srcpad)->data; @@ -865,21 +879,20 @@ setup_group_scheduler (GstOptScheduler *osched, GstOptSchedulerGroup *group) else if (group->type == GST_OPT_SCHEDULER_GROUP_LOOP) wrapper = loop_group_schedule_function; - if (osched->use_cothreads) { - if (!(group->flags & GST_OPT_SCHEDULER_GROUP_SCHEDULABLE)) { - do_cothread_create (group->cothread, osched->context, +#ifdef USE_COTHREADS + if (!(group->flags & GST_OPT_SCHEDULER_GROUP_SCHEDULABLE)) { + do_cothread_create (group->cothread, osched->context, (cothread_func) wrapper, 0, (char **) group); - } - else { - do_cothread_setfunc (group->cothread, osched->context, - (cothread_func) wrapper, 0, (char **) group); - } } else { - group->schedulefunc = wrapper; - group->argc = 0; - group->argv = (char **) group; + do_cothread_setfunc (group->cothread, osched->context, + (cothread_func) wrapper, 0, (char **) group); } +#else + group->schedulefunc = wrapper; + group->argc = 0; + group->argv = (char **) group; +#endif group->flags |= GST_OPT_SCHEDULER_GROUP_SCHEDULABLE; } @@ -1033,24 +1046,28 @@ typedef enum { static void gst_opt_scheduler_setup (GstScheduler *sched) { +#ifdef USE_COTHREADS GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); /* first create thread context */ - if (osched->context == NULL && osched->use_cothreads) { + if (osched->context == NULL) { GST_DEBUG (GST_CAT_SCHEDULING, "initializing cothread context"); osched->context = do_cothread_context_init (); } +#endif } static void gst_opt_scheduler_reset (GstScheduler *sched) { +#ifdef USE_COTHREADS GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); - if (osched->context && osched->use_cothreads) { + if (osched->context) { do_cothread_context_destroy (osched->context); osched->context = NULL; } +#endif } static void gst_opt_scheduler_add_element (GstScheduler *sched, GstElement *element) @@ -1512,9 +1529,6 @@ gst_opt_scheduler_get_property (GObject *object, guint prop_id, osched = GST_OPT_SCHEDULER_CAST (object); switch (prop_id) { - case ARG_USE_COTHREADS: - g_value_set_boolean (value, osched->use_cothreads); - break; case ARG_ITERATIONS: g_value_set_int (value, osched->iterations); break; @@ -1535,9 +1549,6 @@ gst_opt_scheduler_set_property (GObject *object, guint prop_id, osched = GST_OPT_SCHEDULER_CAST (object); switch (prop_id) { - case ARG_USE_COTHREADS: - osched->use_cothreads = g_value_get_boolean (value); - break; case ARG_ITERATIONS: osched->iterations = g_value_get_int (value); break;