Significant progress. Now able to do most operations live, without any failure. tests/incsched.c currently faults a...

Original commit message from CVS:
Significant progress.  Now able to do most operations live, without any
failure.  tests/incsched.c currently faults at the last iteration, not
yet sure why.
This commit is contained in:
Erik Walthinsen 2001-02-20 08:19:05 +00:00
parent 0871fad29b
commit 999f30ff02
9 changed files with 343 additions and 53 deletions

View file

@ -49,6 +49,7 @@ enum {
ARG_OUTPUT, ARG_OUTPUT,
ARG_PATTERN, ARG_PATTERN,
ARG_NUM_BUFFERS, ARG_NUM_BUFFERS,
ARG_EOS,
}; };
#define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type()) #define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type())
@ -124,6 +125,8 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
GTK_ARG_READWRITE, ARG_PATTERN); GTK_ARG_READWRITE, ARG_PATTERN);
gtk_object_add_arg_type ("GstFakeSrc::num_buffers", GTK_TYPE_INT, gtk_object_add_arg_type ("GstFakeSrc::num_buffers", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_NUM_BUFFERS); GTK_ARG_READWRITE, ARG_NUM_BUFFERS);
gtk_object_add_arg_type ("GstFakeSrc::eos", GTK_TYPE_BOOL,
GTK_ARG_READWRITE, ARG_EOS);
gtkobject_class->set_arg = gst_fakesrc_set_arg; gtkobject_class->set_arg = gst_fakesrc_set_arg;
gtkobject_class->get_arg = gst_fakesrc_get_arg; gtkobject_class->get_arg = gst_fakesrc_get_arg;
@ -217,6 +220,10 @@ gst_fakesrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
case ARG_NUM_BUFFERS: case ARG_NUM_BUFFERS:
src->num_buffers = GTK_VALUE_INT (*arg); src->num_buffers = GTK_VALUE_INT (*arg);
break; break;
case ARG_EOS:
src->eos = GTK_VALUE_BOOL (*arg);
GST_INFO (0, "will EOS on next buffer");
break;
default: default:
break; break;
} }
@ -248,6 +255,8 @@ gst_fakesrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
case ARG_NUM_BUFFERS: case ARG_NUM_BUFFERS:
GTK_VALUE_INT (*arg) = src->num_buffers; GTK_VALUE_INT (*arg) = src->num_buffers;
break; break;
case ARG_EOS:
GTK_VALUE_BOOL (*arg) = src->eos;
default: default:
arg->type = GTK_TYPE_INVALID; arg->type = GTK_TYPE_INVALID;
break; break;
@ -284,6 +293,12 @@ gst_fakesrc_get(GstPad *pad)
src->num_buffers--; src->num_buffers--;
} }
if (src->eos) {
GST_INFO (0, "fakesrc is setting eos on pad");
gst_pad_set_eos (pad);
return NULL;
}
g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad)); g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad));
buf = gst_buffer_new(); buf = gst_buffer_new();
@ -327,6 +342,12 @@ gst_fakesrc_loop(GstElement *element)
src->num_buffers--; src->num_buffers--;
} }
if (src->eos) {
GST_INFO (0, "fakesrc is setting eos on pad");
gst_pad_set_eos (pad);
return NULL;
}
buf = gst_buffer_new(); buf = gst_buffer_new();
g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad)); g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad));

View file

@ -65,6 +65,7 @@ struct _GstFakeSrc {
GstElement element; GstElement element;
gboolean loop_based; gboolean loop_based;
gboolean eos;
gint numsrcpads; gint numsrcpads;
GSList *srcpads; GSList *srcpads;
GstFakeSrcOutputType output; GstFakeSrcOutputType output;

View file

@ -901,6 +901,18 @@ gst_bin_create_plan_func (GstBin *bin)
static gboolean static gboolean
gst_bin_iterate_func (GstBin *bin) gst_bin_iterate_func (GstBin *bin)
{
// only iterate if this is the manager bin
if (GST_ELEMENT_SCHED(bin)->parent == bin) {
return GST_SCHEDULE_ITERATE(GST_ELEMENT_SCHED(bin));
} else {
GST_DEBUG (GST_CAT_SCHEDULING, "this bin can't be iterated on!\n");
}
return FALSE;
}
/*
{ {
GList *chains; GList *chains;
_GstBinChain *chain; _GstBinChain *chain;
@ -991,4 +1003,4 @@ gst_bin_iterate_func (GstBin *bin)
GST_DEBUG_LEAVE("(%s)", GST_ELEMENT_NAME (bin)); GST_DEBUG_LEAVE("(%s)", GST_ELEMENT_NAME (bin));
return !eos; return !eos;
} }
*/

View file

@ -26,6 +26,7 @@
#include "gstelement.h" #include "gstelement.h"
#include "gstextratypes.h" #include "gstextratypes.h"
#include "gstbin.h" #include "gstbin.h"
#include "gstscheduler.h"
/* Element signals and args */ /* Element signals and args */
@ -769,6 +770,11 @@ gst_element_change_state (GstElement *element)
// g_print("gst_element_change_state(\"%s\",%d)\n", // g_print("gst_element_change_state(\"%s\",%d)\n",
// element->name,state); // element->name,state);
if (GST_STATE_TRANSITION(element) == GST_STATE_READY_TO_PLAYING)
GST_SCHEDULE_ENABLE_ELEMENT (element->sched,element);
else if (GST_STATE_TRANSITION(element) == GST_STATE_PLAYING_TO_READY)
GST_SCHEDULE_DISABLE_ELEMENT (element->sched,element);
GST_STATE (element) = GST_STATE_PENDING (element); GST_STATE (element) = GST_STATE_PENDING (element);
GST_STATE_PENDING (element) = GST_STATE_NONE_PENDING; GST_STATE_PENDING (element) = GST_STATE_NONE_PENDING;

View file

@ -204,8 +204,7 @@ gst_schedule_cothreaded_chain (GstBin *bin, GstScheduleChain *chain) {
GList *pads; GList *pads;
GstPad *pad; GstPad *pad;
printf("\n"); GST_DEBUG (0,"chain is using COTHREADS\n");
GST_DEBUG (0,"chain is using cothreads\n");
// first create thread context // first create thread context
if (bin->threadcontext == NULL) { if (bin->threadcontext == NULL) {
@ -251,7 +250,7 @@ printf("\n");
// if the element is DECOUPLED or outside the manager, we have to chain // if the element is DECOUPLED or outside the manager, we have to chain
if ((wrapper_function == NULL) || if ((wrapper_function == NULL) ||
(GST_RPAD_PEER(pad) && (GST_RPAD_PEER(pad) &&
(GST_ELEMENT (GST_PAD_PARENT (GST_PAD (GST_RPAD_PEER (pad))))->manager != GST_ELEMENT(bin))) (GST_ELEMENT (GST_PAD_PARENT (GST_PAD (GST_RPAD_PEER (pad))))->sched != chain->sched))
) { ) {
// set the chain proxies // set the chain proxies
if (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK) { if (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK) {
@ -789,8 +788,11 @@ gst_schedule_init (GstSchedule *schedule)
{ {
schedule->add_element = GST_DEBUG_FUNCPTR(gst_schedule_add_element); schedule->add_element = GST_DEBUG_FUNCPTR(gst_schedule_add_element);
schedule->remove_element = GST_DEBUG_FUNCPTR(gst_schedule_remove_element); schedule->remove_element = GST_DEBUG_FUNCPTR(gst_schedule_remove_element);
schedule->enable_element = GST_DEBUG_FUNCPTR(gst_schedule_enable_element);
schedule->disable_element = GST_DEBUG_FUNCPTR(gst_schedule_disable_element);
schedule->pad_connect = GST_DEBUG_FUNCPTR(gst_schedule_pad_connect); schedule->pad_connect = GST_DEBUG_FUNCPTR(gst_schedule_pad_connect);
schedule->pad_disconnect = GST_DEBUG_FUNCPTR(gst_schedule_pad_disconnect); schedule->pad_disconnect = GST_DEBUG_FUNCPTR(gst_schedule_pad_disconnect);
schedule->iterate = GST_DEBUG_FUNCPTR(gst_schedule_iterate);
} }
GstSchedule* GstSchedule*
@ -835,6 +837,7 @@ gst_schedule_chain_new (GstSchedule *sched)
GstScheduleChain *chain = g_new (GstScheduleChain, 1); GstScheduleChain *chain = g_new (GstScheduleChain, 1);
chain->sched = sched; chain->sched = sched;
chain->disabled = NULL;
chain->elements = NULL; chain->elements = NULL;
chain->num_elements = 0; chain->num_elements = 0;
chain->entry = NULL; chain->entry = NULL;
@ -855,6 +858,7 @@ gst_schedule_chain_destroy (GstScheduleChain *chain)
chain->sched->chains = g_list_remove (chain->sched->chains, chain); chain->sched->chains = g_list_remove (chain->sched->chains, chain);
chain->sched->num_chains--; chain->sched->num_chains--;
g_list_free (chain->disabled);
g_list_free (chain->elements); g_list_free (chain->elements);
g_free (chain); g_free (chain);
} }
@ -863,11 +867,53 @@ void
gst_schedule_chain_add_element (GstScheduleChain *chain, GstElement *element) gst_schedule_chain_add_element (GstScheduleChain *chain, GstElement *element)
{ {
GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to chain", GST_ELEMENT_NAME (element)); GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to chain", GST_ELEMENT_NAME (element));
chain->elements = g_list_prepend (chain->elements, element);
chain->num_elements++;
// FIXME need to update chain schedule here, or not chain->disabled = g_list_prepend (chain->disabled, element);
// gst_schedule_cothreaded_chain(chain->sched->parent,chain); chain->num_elements++;
}
void
gst_schedule_chain_enable_element (GstScheduleChain *chain, GstElement *element)
{
GST_INFO (GST_CAT_SCHEDULING, "enabling element \"%s\" in chain", GST_ELEMENT_NAME (element));
// 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
gst_schedule_cothreaded_chain(chain->sched->parent,chain);
}
void
gst_schedule_chain_disable_element (GstScheduleChain *chain, GstElement *element)
{
GST_INFO (GST_CAT_SCHEDULING, "disabling element \"%s\" in chain", GST_ELEMENT_NAME (element));
// remove from elements list
chain->elements = g_list_remove (chain->elements, element);
// add to disabled list
chain->disabled = g_list_prepend (chain->disabled, element);
// reschedule the chain
gst_schedule_cothreaded_chain(chain->sched->parent,chain);
}
void
gst_schedule_chain_remove_element (GstScheduleChain *chain, GstElement *element)
{
GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from chain", GST_ELEMENT_NAME (element));
// if it's active, deactivate it
if (g_list_find (chain->elements, element)) {
gst_schedule_chain_disable_element (chain, element);
}
chain->disabled = g_list_remove (chain->disabled, element);
chain->num_elements--;
} }
void void
@ -884,9 +930,14 @@ gst_schedule_chain_elements (GstSchedule *sched, GstElement *element1, GstElemen
chain = (GstScheduleChain *)(chains->data); chain = (GstScheduleChain *)(chains->data);
chains = g_list_next(chains); chains = g_list_next(chains);
if (g_list_find (chain->elements,element1)) if (g_list_find (chain->disabled,element1))
chain1 = chain; chain1 = chain;
if (g_list_find (chain->elements,element2)) 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; chain2 = chain;
} }
@ -903,16 +954,17 @@ gst_schedule_chain_elements (GstSchedule *sched, GstElement *element1, GstElemen
gst_schedule_chain_add_element (chain, element1); gst_schedule_chain_add_element (chain, element1);
gst_schedule_chain_add_element (chain, element2); gst_schedule_chain_add_element (chain, element2);
// FIXME chain changed here // FIXME chain changed here
gst_schedule_cothreaded_chain(chain->sched->parent,chain); // gst_schedule_cothreaded_chain(chain->sched->parent,chain);
// otherwise if both have chains already, join them // otherwise if both have chains already, join them
} else if ((chain1 != NULL) && (chain2 != NULL)) { } else if ((chain1 != NULL) && (chain2 != NULL)) {
GST_INFO (GST_CAT_SCHEDULING, "joining two existing chains together"); GST_INFO (GST_CAT_SCHEDULING, "joining two existing chains together");
// take the contents of chain2 and merge them into 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->elements = g_list_concat (chain1->elements, g_list_copy(chain2->elements));
chain1->num_elements += chain2->num_elements; chain1->num_elements += chain2->num_elements;
// FIXME chain changed here // FIXME chain changed here
gst_schedule_cothreaded_chain(chain->sched->parent,chain); // gst_schedule_cothreaded_chain(chain->sched->parent,chain);
gst_schedule_chain_destroy(chain2); gst_schedule_chain_destroy(chain2);
@ -925,12 +977,12 @@ gst_schedule_chain_elements (GstSchedule *sched, GstElement *element1, GstElemen
GST_INFO (GST_CAT_SCHEDULING, "adding element to existing chain"); GST_INFO (GST_CAT_SCHEDULING, "adding element to existing chain");
gst_schedule_chain_add_element (chain, element); gst_schedule_chain_add_element (chain, element);
// FIXME chain changed here // FIXME chain changed here
gst_schedule_cothreaded_chain(chain->sched->parent,chain); // gst_schedule_cothreaded_chain(chain->sched->parent,chain);
} }
} }
void void
gst_schedule_pad_connect_callback (GstPad *srcpad, GstPad *sinkpad, GstSchedule *sched) gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad)
{ {
GstElement *peerelement; GstElement *peerelement;
@ -942,10 +994,6 @@ gst_schedule_pad_connect_callback (GstPad *srcpad, GstPad *sinkpad, GstSchedule
} }
} }
void gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad) {
gst_schedule_pad_connect_callback(srcpad,sinkpad,sched);
}
// find the chain within the schedule that holds the element, if any // find the chain within the schedule that holds the element, if any
GstScheduleChain * GstScheduleChain *
gst_schedule_find_chain (GstSchedule *sched, GstElement *element) gst_schedule_find_chain (GstSchedule *sched, GstElement *element)
@ -962,6 +1010,8 @@ gst_schedule_find_chain (GstSchedule *sched, GstElement *element)
if (g_list_find (chain->elements, element)) if (g_list_find (chain->elements, element))
return chain; return chain;
if (g_list_find (chain->disabled, element))
return chain;
} }
return NULL; return NULL;
@ -994,17 +1044,17 @@ gst_schedule_chain_recursive_add (GstScheduleChain *chain, GstElement *element)
} }
void void
gst_schedule_pad_disconnect_callback (GstPad *pad, GstPad *peer, GstSchedule *sched) gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad)
{ {
GstScheduleChain *chain; GstScheduleChain *chain;
GstElement *element1, *element2; GstElement *element1, *element2;
GstScheduleChain *chain1, *chain2; GstScheduleChain *chain1, *chain2;
GST_INFO (GST_CAT_SCHEDULING, "have pad disconnected callback on %s:%s",GST_DEBUG_PAD_NAME(pad)); GST_INFO (GST_CAT_SCHEDULING, "have pad disconnected callback on %s:%s",GST_DEBUG_PAD_NAME(srcpad));
// we need to have the parent elements of each pad // we need to have the parent elements of each pad
element1 = GST_PAD_PARENT(pad); element1 = GST_PAD_PARENT(srcpad);
element2 = GST_PAD_PARENT(peer); element2 = GST_PAD_PARENT(sinkpad);
GST_INFO (GST_CAT_SCHEDULING, "disconnecting elements \"%s\" and \"%s\"", GST_INFO (GST_CAT_SCHEDULING, "disconnecting elements \"%s\" and \"%s\"",
GST_ELEMENT_NAME(element1), GST_ELEMENT_NAME(element2)); GST_ELEMENT_NAME(element1), GST_ELEMENT_NAME(element2));
@ -1036,9 +1086,6 @@ gst_schedule_pad_disconnect_callback (GstPad *pad, GstPad *peer, GstSchedule *sc
} }
} }
void gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad) {
gst_schedule_pad_disconnect_callback(srcpad,sinkpad,sched);
}
void void
gst_schedule_add_element (GstSchedule *sched, GstElement *element) gst_schedule_add_element (GstSchedule *sched, GstElement *element)
@ -1060,7 +1107,7 @@ gst_schedule_add_element (GstSchedule *sched, GstElement *element)
// set the sched pointer in the element itself // set the sched pointer in the element itself
gst_element_set_sched (element, sched); gst_element_set_sched (element, sched);
// now look through the pads and see what we need to do // set the sched pointer in all the pads
pads = element->pads; pads = element->pads;
while (pads) { while (pads) {
pad = GST_PAD(pads->data); pad = GST_PAD(pads->data);
@ -1078,11 +1125,34 @@ gst_schedule_add_element (GstSchedule *sched, GstElement *element)
// make sure that the two elements are in the same chain // make sure that the two elements are in the same chain
gst_schedule_chain_elements (sched,element,peerelement); gst_schedule_chain_elements (sched,element,peerelement);
} }
}
}
// now we have to attach a signal to each pad void
// FIXME this is stupid gst_schedule_enable_element (GstSchedule *sched, GstElement *element)
// gtk_signal_connect(pad,"connected",GTK_SIGNAL_FUNC(gst_schedule_pad_connect_callback),sched); {
// gtk_signal_connect(pad,"disconnected",GTK_SIGNAL_FUNC(gst_schedule_pad_disconnect_callback),sched); GstScheduleChain *chain;
// find the chain the element's in
chain = gst_schedule_find_chain (sched, element);
if (chain)
gst_schedule_chain_enable_element (chain, element);
else
GST_INFO (GST_CAT_SCHEDULING, "element not found in any chain, not enabling");
}
void
gst_schedule_disable_element (GstSchedule *sched, GstElement *element)
{
GstScheduleChain *chain;
// find the chain the element is in
chain = gst_schedule_find_chain (sched, element);
// remove it from the chain
if (chain) {
gst_schedule_chain_disable_element(chain,element);
} }
} }
@ -1099,29 +1169,117 @@ gst_schedule_remove_element (GstSchedule *sched, GstElement *element)
GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from schedule", GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from schedule",
GST_ELEMENT_NAME(element)); GST_ELEMENT_NAME(element));
// find which chain it's in and remove it from that chain // disable the element, i.e. remove from chain
gst_schedule_disable_element (sched, element);
// unset the scheduler
gst_element_set_sched (element, NULL);
// remove it from the list of elements
sched->elements = g_list_remove (sched->elements, element);
sched->num_elements--;
}
}
gboolean
gst_schedule_iterate (GstSchedule *sched)
{
GstBin *bin = sched->parent;
GList *chains;
GstScheduleChain *chain;
GList *entries;
GstElement *entry;
GList *pads;
GstPad *pad;
GstBuffer *buf = NULL;
gint num_scheduled = 0;
gboolean eos = FALSE;
GST_DEBUG_ENTER("(\"%s\")", GST_ELEMENT_NAME (bin));
g_return_val_if_fail (bin != NULL, TRUE);
g_return_val_if_fail (GST_IS_BIN (bin), TRUE);
// g_return_val_if_fail (GST_STATE (bin) == GST_STATE_PLAYING, TRUE);
// step through all the chains
chains = sched->chains; chains = sched->chains;
while (chains) { while (chains) {
chain = (GstScheduleChain *)(chains->data); chain = (GstScheduleChain *)(chains->data);
chains = g_list_next (chains); chains = g_list_next (chains);
if (g_list_find (chain->elements, element)) { // if (!chain->need_scheduling) continue;
GST_INFO (GST_CAT_SCHEDULING, "removing element from chain");
chain->elements = g_list_remove (chain->elements, element); // if (chain->need_cothreads) {
// FIXME chain changed here // all we really have to do is switch to the first child
break; // FIXME this should be lots more intelligent about where to start
GST_DEBUG (0,"starting iteration via cothreads\n");
entry = GST_ELEMENT (chain->elements->data);
GST_FLAG_SET (entry, GST_ELEMENT_COTHREAD_STOPPING);
GST_DEBUG (0,"set COTHREAD_STOPPING flag on \"%s\"(@%p)\n",
GST_ELEMENT_NAME (entry),entry);
cothread_switch (entry->threadstate);
/*
} else {
GST_DEBUG (0,"starting iteration via chain-functions\n");
entries = chain->entries;
g_assert (entries != NULL);
while (entries) {
entry = GST_ELEMENT (entries->data);
entries = g_list_next (entries);
GST_DEBUG (0,"have entry \"%s\"\n",GST_ELEMENT_NAME (entry));
if (GST_IS_BIN (entry)) {
gst_bin_iterate (GST_BIN (entry));
} else {
pads = entry->pads;
while (pads) {
pad = GST_PAD (pads->data);
if (GST_RPAD_DIRECTION(pad) == GST_PAD_SRC) {
GST_DEBUG (0,"calling getfunc of %s:%s\n",GST_DEBUG_PAD_NAME(pad));
if (GST_REAL_PAD(pad)->getfunc == NULL)
fprintf(stderr, "error, no getfunc in \"%s\"\n", GST_ELEMENT_NAME (entry));
else
buf = (GST_REAL_PAD(pad)->getfunc)(pad);
if (buf) gst_pad_push(pad,buf);
} }
pads = g_list_next (pads);
}
}
}
}*/
num_scheduled++;
} }
// unset the scheduler /*
gst_element_set_sched (element, NULL); // check if nothing was scheduled that was ours..
if (!num_scheduled) {
// are there any other elements that are still busy?
if (bin->num_eos_providers) {
GST_LOCK (bin);
GST_DEBUG (0,"waiting for eos providers\n");
g_cond_wait (bin->eoscond, GST_OBJECT(bin)->lock);
GST_DEBUG (0,"num eos providers %d\n", bin->num_eos_providers);
GST_UNLOCK (bin);
}
else {
gst_element_signal_eos (GST_ELEMENT (bin));
eos = TRUE;
}
}
*/
sched->elements = g_list_remove (sched->elements, element); GST_DEBUG (0, "leaving (%s)\n", GST_ELEMENT_NAME (bin));
sched->num_elements--; return !eos;
}
} }
void void
gst_schedule_show (GstSchedule *sched) gst_schedule_show (GstSchedule *sched)
{ {
@ -1129,7 +1287,11 @@ gst_schedule_show (GstSchedule *sched)
GstElement *element; GstElement *element;
GstScheduleChain *chain; GstScheduleChain *chain;
g_return_if_fail(sched != NULL); if (sched == NULL) {
g_print("schedule doesn't exist for this element\n");
return;
}
g_return_if_fail(GST_IS_SCHEDULE(sched)); g_return_if_fail(GST_IS_SCHEDULE(sched));
g_print("schedule has %d elements in it: ",sched->num_elements); g_print("schedule has %d elements in it: ",sched->num_elements);
@ -1148,6 +1310,14 @@ gst_schedule_show (GstSchedule *sched)
chain = (GstScheduleChain *)(chains->data); chain = (GstScheduleChain *)(chains->data);
chains = g_list_next(chains); chains = g_list_next(chains);
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; elements = chain->elements;
while (elements) { while (elements) {
element = GST_ELEMENT(elements->data); element = GST_ELEMENT(elements->data);

View file

@ -62,28 +62,41 @@ struct _GstSchedule {
void (*add_element) (GstSchedule *sched, GstElement *element); void (*add_element) (GstSchedule *sched, GstElement *element);
void (*remove_element) (GstSchedule *sched, GstElement *element); void (*remove_element) (GstSchedule *sched, GstElement *element);
void (*enable_element) (GstSchedule *sched, GstElement *element);
void (*disable_element) (GstSchedule *sched, GstElement *element);
void (*pad_connect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad); void (*pad_connect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
void (*pad_disconnect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad); void (*pad_disconnect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
gboolean (*iterate) (GstSchedule *sched);
}; };
struct _GstScheduleClass { struct _GstScheduleClass {
GstObjectClass parent_class; GstObjectClass parent_class;
}; };
//#define GST_SCHEDULE_SAFETY if (sched)
#define GST_SCHEDULE_SAFETY
#define GST_SCHEDULE_ADD_ELEMENT(sched,element) \ #define GST_SCHEDULE_ADD_ELEMENT(sched,element) \
((sched)->add_element((sched),(element))) GST_SCHEDULE_SAFETY ((sched)->add_element((sched),(element)))
#define GST_SCHEDULE_REMOVE_ELEMENT(sched,element) \ #define GST_SCHEDULE_REMOVE_ELEMENT(sched,element) \
((sched)->remove_element((sched),(element))) GST_SCHEDULE_SAFETY ((sched)->remove_element((sched),(element)))
#define GST_SCHEDULE_ENABLE_ELEMENT(sched,element) \
GST_SCHEDULE_SAFETY ((sched)->enable_element((sched),(element)))
#define GST_SCHEDULE_DISABLE_ELEMENT(sched,element) \
GST_SCHEDULE_SAFETY ((sched)->disable_element((sched),(element)))
#define GST_SCHEDULE_PAD_CONNECT(sched,srcpad,sinkpad) \ #define GST_SCHEDULE_PAD_CONNECT(sched,srcpad,sinkpad) \
((sched)->pad_connect((sched),(srcpad),(sinkpad))) GST_SCHEDULE_SAFETY ((sched)->pad_connect((sched),(srcpad),(sinkpad)))
#define GST_SCHEDULE_PAD_DISCONNECT(sched,srcpad,sinkpad) \ #define GST_SCHEDULE_PAD_DISCONNECT(sched,srcpad,sinkpad) \
((sched)->pad_disconnect((sched),(srcpad),(sinkpad))) GST_SCHEDULE_SAFETY ((sched)->pad_disconnect((sched),(srcpad),(sinkpad)))
#define GST_SCHEDULE_ITERATE(sched) \
((sched)->iterate((sched)))
struct _GstScheduleChain { struct _GstScheduleChain {
GstSchedule *sched; GstSchedule *sched;
GList *disabled;
GList *elements; GList *elements;
gint num_elements; gint num_elements;
@ -101,10 +114,13 @@ GstSchedule * gst_schedule_new (GstElement *parent);
void gst_schedule_add_element (GstSchedule *sched, GstElement *element); void gst_schedule_add_element (GstSchedule *sched, GstElement *element);
void gst_schedule_remove_element (GstSchedule *sched, GstElement *element); void gst_schedule_remove_element (GstSchedule *sched, GstElement *element);
void gst_schedule_enable_element (GstSchedule *sched, GstElement *element);
void gst_schedule_disable_element (GstSchedule *sched, GstElement *element);
void gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad); void gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
void gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad); void gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
void gst_schedule_show (GstSchedule *sched); void gst_schedule_show (GstSchedule *sched);
gboolean gst_schedule_iterate (GstSchedule *sched);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -49,6 +49,7 @@ enum {
ARG_OUTPUT, ARG_OUTPUT,
ARG_PATTERN, ARG_PATTERN,
ARG_NUM_BUFFERS, ARG_NUM_BUFFERS,
ARG_EOS,
}; };
#define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type()) #define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type())
@ -124,6 +125,8 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
GTK_ARG_READWRITE, ARG_PATTERN); GTK_ARG_READWRITE, ARG_PATTERN);
gtk_object_add_arg_type ("GstFakeSrc::num_buffers", GTK_TYPE_INT, gtk_object_add_arg_type ("GstFakeSrc::num_buffers", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_NUM_BUFFERS); GTK_ARG_READWRITE, ARG_NUM_BUFFERS);
gtk_object_add_arg_type ("GstFakeSrc::eos", GTK_TYPE_BOOL,
GTK_ARG_READWRITE, ARG_EOS);
gtkobject_class->set_arg = gst_fakesrc_set_arg; gtkobject_class->set_arg = gst_fakesrc_set_arg;
gtkobject_class->get_arg = gst_fakesrc_get_arg; gtkobject_class->get_arg = gst_fakesrc_get_arg;
@ -217,6 +220,10 @@ gst_fakesrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
case ARG_NUM_BUFFERS: case ARG_NUM_BUFFERS:
src->num_buffers = GTK_VALUE_INT (*arg); src->num_buffers = GTK_VALUE_INT (*arg);
break; break;
case ARG_EOS:
src->eos = GTK_VALUE_BOOL (*arg);
GST_INFO (0, "will EOS on next buffer");
break;
default: default:
break; break;
} }
@ -248,6 +255,8 @@ gst_fakesrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
case ARG_NUM_BUFFERS: case ARG_NUM_BUFFERS:
GTK_VALUE_INT (*arg) = src->num_buffers; GTK_VALUE_INT (*arg) = src->num_buffers;
break; break;
case ARG_EOS:
GTK_VALUE_BOOL (*arg) = src->eos;
default: default:
arg->type = GTK_TYPE_INVALID; arg->type = GTK_TYPE_INVALID;
break; break;
@ -284,6 +293,12 @@ gst_fakesrc_get(GstPad *pad)
src->num_buffers--; src->num_buffers--;
} }
if (src->eos) {
GST_INFO (0, "fakesrc is setting eos on pad");
gst_pad_set_eos (pad);
return NULL;
}
g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad)); g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad));
buf = gst_buffer_new(); buf = gst_buffer_new();
@ -327,6 +342,12 @@ gst_fakesrc_loop(GstElement *element)
src->num_buffers--; src->num_buffers--;
} }
if (src->eos) {
GST_INFO (0, "fakesrc is setting eos on pad");
gst_pad_set_eos (pad);
return NULL;
}
buf = gst_buffer_new(); buf = gst_buffer_new();
g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad)); g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad));

View file

@ -65,6 +65,7 @@ struct _GstFakeSrc {
GstElement element; GstElement element;
gboolean loop_based; gboolean loop_based;
gboolean eos;
gint numsrcpads; gint numsrcpads;
GSList *srcpads; GSList *srcpads;
GstFakeSrcOutputType output; GstFakeSrcOutputType output;

View file

@ -37,7 +37,6 @@ int main(int argc,char *argv[]) {
gst_element_connect(src,"src",identity,"sink"); gst_element_connect(src,"src",identity,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread)); gst_schedule_show(GST_ELEMENT_SCHED(thread));
//return;
g_print("\nDisconnecting src from identity:\n"); g_print("\nDisconnecting src from identity:\n");
gst_element_disconnect(src,"src",identity,"sink"); gst_element_disconnect(src,"src",identity,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread)); gst_schedule_show(GST_ELEMENT_SCHED(thread));
@ -52,7 +51,7 @@ int main(int argc,char *argv[]) {
g_print("\nAdding bin to thread:\n"); g_print("\nAdding bin to thread:\n");
gst_bin_add(thread, GST_ELEMENT(bin)); gst_bin_add(thread, GST_ELEMENT(bin));
gst_schedule_show(GST_ELEMENT_SCHED(thread)); gst_schedule_show(GST_ELEMENT_SCHED(bin));
g_print("\nConnecting identity to sink:\n"); g_print("\nConnecting identity to sink:\n");
gst_element_connect(identity,"src",sink,"sink"); gst_element_connect(identity,"src",sink,"sink");
@ -74,10 +73,53 @@ int main(int argc,char *argv[]) {
gst_element_connect(identity,"src",identity2,"sink"); gst_element_connect(identity,"src",identity2,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread)); gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nDisconnecting identity from identity2\n"); g_print("\n\nNow setting state from NULL to READY:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from READY to PLAYING:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_PLAYING);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nIterating:\n");
gst_bin_iterate(thread);
g_print("\n\nNow setting state from PLAYING to READY:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from READY to PLAYING:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_PLAYING);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nIterating:\n");
gst_bin_iterate(thread);
g_print("\n\nNow setting state from PLAYING to READY:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nDisconnecting identity from identity2:\n");
gst_element_disconnect(identity,"src",identity2,"sink"); gst_element_disconnect(identity,"src",identity2,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread)); gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from NULL to READY:\n"); g_print("\nDisconnecting identity2 from sink:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY); gst_element_disconnect(identity2,"src",sink,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting identity to sink:\n");
gst_element_connect(identity,"src",sink,"sink");
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from READY to PLAYING:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_PLAYING);
gst_schedule_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nIterating:\n");
gst_bin_iterate(thread);
return;
g_print("\n\nSetting EOS on fakesrc and iterating again:\n");
gtk_object_set(GTK_OBJECT(src),"eos",TRUE,NULL);
gst_bin_iterate(thread);
} }