diff --git a/gst/elements/gstfakesrc.c b/gst/elements/gstfakesrc.c index 56bc217bd0..5a0f1f809a 100644 --- a/gst/elements/gstfakesrc.c +++ b/gst/elements/gstfakesrc.c @@ -49,6 +49,7 @@ enum { ARG_OUTPUT, ARG_PATTERN, ARG_NUM_BUFFERS, + ARG_EOS, }; #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_object_add_arg_type ("GstFakeSrc::num_buffers", GTK_TYPE_INT, 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->get_arg = gst_fakesrc_get_arg; @@ -217,6 +220,10 @@ gst_fakesrc_set_arg (GtkObject *object, GtkArg *arg, guint id) case ARG_NUM_BUFFERS: src->num_buffers = GTK_VALUE_INT (*arg); break; + case ARG_EOS: + src->eos = GTK_VALUE_BOOL (*arg); +GST_INFO (0, "will EOS on next buffer"); + break; default: break; } @@ -248,6 +255,8 @@ gst_fakesrc_get_arg (GtkObject *object, GtkArg *arg, guint id) case ARG_NUM_BUFFERS: GTK_VALUE_INT (*arg) = src->num_buffers; break; + case ARG_EOS: + GTK_VALUE_BOOL (*arg) = src->eos; default: arg->type = GTK_TYPE_INVALID; break; @@ -284,6 +293,12 @@ gst_fakesrc_get(GstPad *pad) 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)); buf = gst_buffer_new(); @@ -327,6 +342,12 @@ gst_fakesrc_loop(GstElement *element) 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(); g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad)); diff --git a/gst/elements/gstfakesrc.h b/gst/elements/gstfakesrc.h index f03a0fdca9..58bcfc4af6 100644 --- a/gst/elements/gstfakesrc.h +++ b/gst/elements/gstfakesrc.h @@ -65,6 +65,7 @@ struct _GstFakeSrc { GstElement element; gboolean loop_based; + gboolean eos; gint numsrcpads; GSList *srcpads; GstFakeSrcOutputType output; diff --git a/gst/gstbin.c b/gst/gstbin.c index 106ecb7c6b..da6f12dfeb 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -901,6 +901,18 @@ gst_bin_create_plan_func (GstBin *bin) static gboolean 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; _GstBinChain *chain; @@ -991,4 +1003,4 @@ gst_bin_iterate_func (GstBin *bin) GST_DEBUG_LEAVE("(%s)", GST_ELEMENT_NAME (bin)); return !eos; } - +*/ diff --git a/gst/gstelement.c b/gst/gstelement.c index 49193e7a7c..b3d0fadf61 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -26,6 +26,7 @@ #include "gstelement.h" #include "gstextratypes.h" #include "gstbin.h" +#include "gstscheduler.h" /* Element signals and args */ @@ -769,6 +770,11 @@ gst_element_change_state (GstElement *element) // g_print("gst_element_change_state(\"%s\",%d)\n", // 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_PENDING (element) = GST_STATE_NONE_PENDING; diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index 49402bb6b2..6a39693b1e 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -204,8 +204,7 @@ gst_schedule_cothreaded_chain (GstBin *bin, GstScheduleChain *chain) { GList *pads; GstPad *pad; -printf("\n"); - GST_DEBUG (0,"chain is using cothreads\n"); + GST_DEBUG (0,"chain is using COTHREADS\n"); // first create thread context if (bin->threadcontext == NULL) { @@ -251,7 +250,7 @@ printf("\n"); // if the element is DECOUPLED or outside the manager, we have to chain if ((wrapper_function == NULL) || (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 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->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_disconnect = GST_DEBUG_FUNCPTR(gst_schedule_pad_disconnect); + schedule->iterate = GST_DEBUG_FUNCPTR(gst_schedule_iterate); } GstSchedule* @@ -835,6 +837,7 @@ gst_schedule_chain_new (GstSchedule *sched) GstScheduleChain *chain = g_new (GstScheduleChain, 1); chain->sched = sched; + chain->disabled = NULL; chain->elements = NULL; chain->num_elements = 0; 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->num_chains--; + g_list_free (chain->disabled); g_list_free (chain->elements); g_free (chain); } @@ -863,11 +867,53 @@ void gst_schedule_chain_add_element (GstScheduleChain *chain, GstElement *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 -// gst_schedule_cothreaded_chain(chain->sched->parent,chain); + chain->disabled = g_list_prepend (chain->disabled, element); + 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 @@ -884,9 +930,14 @@ gst_schedule_chain_elements (GstSchedule *sched, GstElement *element1, GstElemen chain = (GstScheduleChain *)(chains->data); chains = g_list_next(chains); - if (g_list_find (chain->elements,element1)) + if (g_list_find (chain->disabled,element1)) 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; } @@ -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, element2); // 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 } else if ((chain1 != NULL) && (chain2 != NULL)) { GST_INFO (GST_CAT_SCHEDULING, "joining two existing chains together"); // 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->num_elements += chain2->num_elements; // 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); @@ -925,12 +977,12 @@ gst_schedule_chain_elements (GstSchedule *sched, GstElement *element1, GstElemen GST_INFO (GST_CAT_SCHEDULING, "adding element to existing chain"); gst_schedule_chain_add_element (chain, element); // FIXME chain changed here - gst_schedule_cothreaded_chain(chain->sched->parent,chain); +// gst_schedule_cothreaded_chain(chain->sched->parent,chain); } } void -gst_schedule_pad_connect_callback (GstPad *srcpad, GstPad *sinkpad, GstSchedule *sched) +gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad) { 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 GstScheduleChain * 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)) return chain; + if (g_list_find (chain->disabled, element)) + return chain; } return NULL; @@ -994,17 +1044,17 @@ gst_schedule_chain_recursive_add (GstScheduleChain *chain, GstElement *element) } void -gst_schedule_pad_disconnect_callback (GstPad *pad, GstPad *peer, GstSchedule *sched) +gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad) { GstScheduleChain *chain; GstElement *element1, *element2; 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 - element1 = GST_PAD_PARENT(pad); - element2 = GST_PAD_PARENT(peer); + element1 = GST_PAD_PARENT(srcpad); + element2 = GST_PAD_PARENT(sinkpad); GST_INFO (GST_CAT_SCHEDULING, "disconnecting elements \"%s\" and \"%s\"", 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 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 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; while (pads) { 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 gst_schedule_chain_elements (sched,element,peerelement); } + } +} - // now we have to attach a signal to each pad - // FIXME this is stupid -// 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); +void +gst_schedule_enable_element (GstSchedule *sched, GstElement *element) +{ + 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,28 +1169,116 @@ gst_schedule_remove_element (GstSchedule *sched, GstElement *element) GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from schedule", GST_ELEMENT_NAME(element)); - // find which chain it's in and remove it from that chain - chains = sched->chains; - while (chains) { - chain = (GstScheduleChain *)(chains->data); - chains = g_list_next(chains); - - if (g_list_find (chain->elements, element)) { - GST_INFO (GST_CAT_SCHEDULING, "removing element from chain"); - chain->elements = g_list_remove (chain->elements, element); - // FIXME chain changed here - break; - } - } + // 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; + while (chains) { + chain = (GstScheduleChain *)(chains->data); + chains = g_list_next (chains); + +// if (!chain->need_scheduling) continue; + +// if (chain->need_cothreads) { + // all we really have to do is switch to the first child + // 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++; + } + +/* + // 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; + } + } +*/ + + GST_DEBUG (0, "leaving (%s)\n", GST_ELEMENT_NAME (bin)); + return !eos; +} + + void gst_schedule_show (GstSchedule *sched) @@ -1129,7 +1287,11 @@ gst_schedule_show (GstSchedule *sched) GstElement *element; 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_print("schedule has %d elements in it: ",sched->num_elements); @@ -1148,6 +1310,14 @@ gst_schedule_show (GstSchedule *sched) chain = (GstScheduleChain *)(chains->data); 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; while (elements) { element = GST_ELEMENT(elements->data); diff --git a/gst/gstscheduler.h b/gst/gstscheduler.h index dd82b79724..6345124e91 100644 --- a/gst/gstscheduler.h +++ b/gst/gstscheduler.h @@ -62,28 +62,41 @@ struct _GstSchedule { void (*add_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_disconnect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad); + gboolean (*iterate) (GstSchedule *sched); }; struct _GstScheduleClass { GstObjectClass parent_class; }; +//#define GST_SCHEDULE_SAFETY if (sched) +#define GST_SCHEDULE_SAFETY #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) \ - ((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) \ - ((sched)->pad_connect((sched),(srcpad),(sinkpad))) + GST_SCHEDULE_SAFETY ((sched)->pad_connect((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 { GstSchedule *sched; + GList *disabled; + GList *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_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_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad); void gst_schedule_show (GstSchedule *sched); +gboolean gst_schedule_iterate (GstSchedule *sched); #ifdef __cplusplus diff --git a/plugins/elements/gstfakesrc.c b/plugins/elements/gstfakesrc.c index 56bc217bd0..5a0f1f809a 100644 --- a/plugins/elements/gstfakesrc.c +++ b/plugins/elements/gstfakesrc.c @@ -49,6 +49,7 @@ enum { ARG_OUTPUT, ARG_PATTERN, ARG_NUM_BUFFERS, + ARG_EOS, }; #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_object_add_arg_type ("GstFakeSrc::num_buffers", GTK_TYPE_INT, 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->get_arg = gst_fakesrc_get_arg; @@ -217,6 +220,10 @@ gst_fakesrc_set_arg (GtkObject *object, GtkArg *arg, guint id) case ARG_NUM_BUFFERS: src->num_buffers = GTK_VALUE_INT (*arg); break; + case ARG_EOS: + src->eos = GTK_VALUE_BOOL (*arg); +GST_INFO (0, "will EOS on next buffer"); + break; default: break; } @@ -248,6 +255,8 @@ gst_fakesrc_get_arg (GtkObject *object, GtkArg *arg, guint id) case ARG_NUM_BUFFERS: GTK_VALUE_INT (*arg) = src->num_buffers; break; + case ARG_EOS: + GTK_VALUE_BOOL (*arg) = src->eos; default: arg->type = GTK_TYPE_INVALID; break; @@ -284,6 +293,12 @@ gst_fakesrc_get(GstPad *pad) 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)); buf = gst_buffer_new(); @@ -327,6 +342,12 @@ gst_fakesrc_loop(GstElement *element) 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(); g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad)); diff --git a/plugins/elements/gstfakesrc.h b/plugins/elements/gstfakesrc.h index f03a0fdca9..58bcfc4af6 100644 --- a/plugins/elements/gstfakesrc.h +++ b/plugins/elements/gstfakesrc.h @@ -65,6 +65,7 @@ struct _GstFakeSrc { GstElement element; gboolean loop_based; + gboolean eos; gint numsrcpads; GSList *srcpads; GstFakeSrcOutputType output; diff --git a/tests/incsched.c b/tests/incsched.c index 665a146630..fce7ed911d 100644 --- a/tests/incsched.c +++ b/tests/incsched.c @@ -37,7 +37,6 @@ int main(int argc,char *argv[]) { gst_element_connect(src,"src",identity,"sink"); gst_schedule_show(GST_ELEMENT_SCHED(thread)); -//return; g_print("\nDisconnecting src from identity:\n"); gst_element_disconnect(src,"src",identity,"sink"); gst_schedule_show(GST_ELEMENT_SCHED(thread)); @@ -52,7 +51,7 @@ int main(int argc,char *argv[]) { g_print("\nAdding bin to thread:\n"); 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"); 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_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_schedule_show(GST_ELEMENT_SCHED(thread)); - g_print("\n\nNow setting state from NULL to READY:\n"); - gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY); + g_print("\nDisconnecting identity2 from sink:\n"); + 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); }