More eos handling, bin in bin is handled correctly now.

Original commit message from CVS:
More eos handling, bin in bin is handled correctly now.
Updated gstreamer-launch to loop while !EOS.
This commit is contained in:
Wim Taymans 2001-01-21 16:06:42 +00:00
parent 3dd77c5107
commit 044c4611af
9 changed files with 136 additions and 95 deletions

View File

@ -136,6 +136,7 @@ gst_bin_init (GstBin *bin)
bin->eos_providers = NULL; bin->eos_providers = NULL;
bin->num_eos_providers = 0; bin->num_eos_providers = 0;
bin->chains = NULL; bin->chains = NULL;
bin->eoscond = g_cond_new ();
// FIXME temporary testing measure // FIXME temporary testing measure
// bin->use_cothreads = TRUE; // bin->use_cothreads = TRUE;
} }
@ -250,6 +251,22 @@ gst_bin_change_state (GstElement *element)
// g_return_val_if_fail(bin->numchildren != 0, GST_STATE_FAILURE); // g_return_val_if_fail(bin->numchildren != 0, GST_STATE_FAILURE);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
{
GstObject *parent;
parent = gst_object_get_parent (GST_OBJECT (element));
if (!parent || !GST_IS_BIN (parent))
gst_bin_create_plan (bin);
break;
}
default:
break;
}
// g_print("-->\n"); // g_print("-->\n");
children = bin->children; children = bin->children;
while (children) { while (children) {
@ -271,21 +288,6 @@ gst_bin_change_state (GstElement *element)
} }
// g_print("<-- \"%s\"\n",gst_object_get_name(GST_OBJECT(bin))); // g_print("<-- \"%s\"\n",gst_object_get_name(GST_OBJECT(bin)));
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
{
GstObject *parent;
parent = gst_object_get_parent (GST_OBJECT (element));
if (!parent || !GST_IS_BIN (parent))
gst_bin_create_plan (bin);
break;
}
default:
break;
}
return gst_bin_change_state_norecurse (bin); return gst_bin_change_state_norecurse (bin);
} }
@ -551,9 +553,12 @@ gst_bin_received_eos (GstElement *element, GstBin *bin)
GST_INFO_ELEMENT (GST_CAT_PLANNING, bin, "child %s fired eos, pending %d\n", gst_element_get_name (element), GST_INFO_ELEMENT (GST_CAT_PLANNING, bin, "child %s fired eos, pending %d\n", gst_element_get_name (element),
bin->num_eos_providers); bin->num_eos_providers);
GST_LOCK (bin);
if (bin->num_eos_providers) { if (bin->num_eos_providers) {
bin->num_eos_providers--; bin->num_eos_providers--;
g_cond_signal (bin->eoscond);
} }
GST_UNLOCK (bin);
} }
/** /**
@ -610,6 +615,7 @@ gst_bin_create_plan_func (GstBin *bin)
} }
GST_DEBUG (0,"setting manager to \"%s\"\n", gst_element_get_name (manager)); GST_DEBUG (0,"setting manager to \"%s\"\n", gst_element_get_name (manager));
} }
gst_element_set_manager (GST_ELEMENT (bin), manager);
// perform the first recursive pass of plan generation // perform the first recursive pass of plan generation
// we set the manager of every element but those who manage themselves // we set the manager of every element but those who manage themselves
@ -635,8 +641,11 @@ gst_bin_create_plan_func (GstBin *bin)
// we do recursion and such for Bins // we do recursion and such for Bins
if (GST_IS_BIN (element)) { if (GST_IS_BIN (element)) {
// recurse into the child Bin // recurse into the child Bin
GST_DEBUG (0,"recursing into child Bin \"%s\"\n",elementname); GST_DEBUG (0,"recursing into child Bin \"%s\" with manager \"%s\"\n",elementname,
gst_element_get_name(element->manager));
gst_bin_create_plan (GST_BIN (element)); gst_bin_create_plan (GST_BIN (element));
GST_DEBUG (0,"after recurse got manager \"%s\"\n",
gst_element_get_name(element->manager));
// check to see if it needs cothreads and isn't self-managing // check to see if it needs cothreads and isn't self-managing
if (((GST_BIN (element))->need_cothreads) && !GST_FLAG_IS_SET(element,GST_BIN_FLAG_MANAGER)) { if (((GST_BIN (element))->need_cothreads) && !GST_FLAG_IS_SET(element,GST_BIN_FLAG_MANAGER)) {
GST_DEBUG (0,"requiring cothreads because child bin \"%s\" does\n",elementname); GST_DEBUG (0,"requiring cothreads because child bin \"%s\" does\n",elementname);
@ -701,10 +710,6 @@ gst_bin_create_plan_func (GstBin *bin)
GST_DEBUG (0,"flattened recurse into \"%s\"\n",elementname); GST_DEBUG (0,"flattened recurse into \"%s\"\n",elementname);
pending = g_slist_prepend (pending, element); pending = g_slist_prepend (pending, element);
gtk_signal_connect (GTK_OBJECT (element), "eos", gst_bin_received_eos, bin);
bin->eos_providers = g_list_prepend (bin->eos_providers, element);
bin->num_eos_providers++;
// otherwise add it to the list of elements // otherwise add it to the list of elements
} else { } else {
GST_DEBUG (0,"found element \"%s\" that I manage\n",elementname); GST_DEBUG (0,"found element \"%s\" that I manage\n",elementname);
@ -712,6 +717,12 @@ gst_bin_create_plan_func (GstBin *bin)
bin->num_managed_elements++; bin->num_managed_elements++;
} }
} }
// else it's not ours and we need to wait for EOS notifications
else {
gtk_signal_connect (GTK_OBJECT (element), "eos", gst_bin_received_eos, bin);
bin->eos_providers = g_list_prepend (bin->eos_providers, element);
bin->num_eos_providers++;
}
} }
} while (pending); } while (pending);
@ -719,6 +730,10 @@ gst_bin_create_plan_func (GstBin *bin)
gst_bin_schedule(bin); gst_bin_schedule(bin);
g_print ("gstbin \"%s\", eos providers:%d\n",
gst_element_get_name (GST_ELEMENT (bin)),
bin->num_eos_providers);
GST_DEBUG_LEAVE("(\"%s\")",gst_element_get_name(GST_ELEMENT(bin))); GST_DEBUG_LEAVE("(\"%s\")",gst_element_get_name(GST_ELEMENT(bin)));
} }
@ -795,15 +810,20 @@ gst_bin_iterate_func (GstBin *bin)
num_scheduled++; num_scheduled++;
} }
/* // check if nothing was scheduled that was ours..
g_print ("bin \"%s\", eos providers:%d, scheduled: %d\n", if (!num_scheduled) {
gst_element_get_name (GST_ELEMENT (bin)), // are there any other elements that are still busy?
bin->num_eos_providers, num_scheduled); if (bin->num_eos_providers) {
*/ GST_LOCK (bin);
GST_DEBUG (0,"waiting for eos providers\n");
if (!num_scheduled && !bin->num_eos_providers) { g_cond_wait (bin->eoscond, GST_OBJECT(bin)->lock);
gst_element_signal_eos (GST_ELEMENT (bin)); GST_DEBUG (0,"num eos providers %d\n", bin->num_eos_providers);
eos = TRUE; GST_UNLOCK (bin);
}
else {
gst_element_signal_eos (GST_ELEMENT (bin));
eos = TRUE;
}
} }
GST_DEBUG_LEAVE("(%s)", gst_element_get_name (GST_ELEMENT (bin))); GST_DEBUG_LEAVE("(%s)", gst_element_get_name (GST_ELEMENT (bin)));

View File

@ -67,6 +67,7 @@ struct _GstBin {
GList *children; GList *children;
gint num_eos_providers; gint num_eos_providers;
GList *eos_providers; GList *eos_providers;
GCond *eoscond;
/* iteration state */ /* iteration state */
gboolean need_cothreads; gboolean need_cothreads;

View File

@ -202,7 +202,7 @@ gst_element_add_ghost_pad (GstElement *element, GstPad *pad, gchar *name)
element->pads = g_list_append (element->pads, ghostpad); element->pads = g_list_append (element->pads, ghostpad);
element->numpads++; element->numpads++;
// set the parent of the ghostpad // set the parent of the ghostpad
gst_pad_set_parent(ghostpad,element); gst_pad_set_parent(ghostpad, GST_OBJECT (element));
GST_DEBUG(0,"added ghostpad %s:%s\n",GST_DEBUG_PAD_NAME(ghostpad)); GST_DEBUG(0,"added ghostpad %s:%s\n",GST_DEBUG_PAD_NAME(ghostpad));

View File

@ -34,7 +34,7 @@ GstElementDetails gst_thread_details = {
"Container that creates/manages a thread", "Container that creates/manages a thread",
VERSION, VERSION,
"Erik Walthinsen <omega@cse.ogi.edu>", "Erik Walthinsen <omega@cse.ogi.edu>",
"(C) 1999", "(C) 1999, 2000",
}; };
@ -50,21 +50,22 @@ enum {
}; };
static void gst_thread_class_init (GstThreadClass *klass); static void gst_thread_class_init (GstThreadClass *klass);
static void gst_thread_init (GstThread *thread); static void gst_thread_init (GstThread *thread);
static void gst_thread_set_arg (GtkObject *object,GtkArg *arg,guint id); static void gst_thread_set_arg (GtkObject *object,GtkArg *arg,guint id);
static void gst_thread_get_arg (GtkObject *object,GtkArg *arg,guint id); static void gst_thread_get_arg (GtkObject *object,GtkArg *arg,guint id);
static GstElementStateReturn gst_thread_change_state (GstElement *element); static GstElementStateReturn gst_thread_change_state (GstElement *element);
static xmlNodePtr gst_thread_save_thyself (GstElement *element,xmlNodePtr parent); static xmlNodePtr gst_thread_save_thyself (GstElement *element,xmlNodePtr parent);
static void gst_thread_restore_thyself (GstElement *element,xmlNodePtr parent, static void gst_thread_restore_thyself (GstElement *element,xmlNodePtr parent,
GHashTable *elements); GHashTable *elements);
static void gst_thread_signal_thread (GstThread *thread); static void gst_thread_signal_thread (GstThread *thread);
static void gst_thread_wait_thread (GstThread *thread); static void gst_thread_wait_thread (GstThread *thread);
static void gst_thread_create_plan_dummy (GstBin *bin); static void gst_thread_create_plan_dummy (GstBin *bin);
static void gst_thread_schedule_dummy (GstBin *bin);
static void* gst_thread_main_loop (void *arg); static void* gst_thread_main_loop (void *arg);
@ -99,21 +100,22 @@ gst_thread_class_init (GstThreadClass *klass)
GstElementClass *gstelement_class; GstElementClass *gstelement_class;
GstBinClass *gstbin_class; GstBinClass *gstbin_class;
gtkobject_class = (GtkObjectClass*)klass; gtkobject_class = (GtkObjectClass*)klass;
gstobject_class = (GstObjectClass*)klass; gstobject_class = (GstObjectClass*)klass;
gstelement_class = (GstElementClass*)klass; gstelement_class = (GstElementClass*)klass;
gstbin_class = (GstBinClass*)klass; gstbin_class = (GstBinClass*)klass;
parent_class = gtk_type_class (GST_TYPE_BIN); parent_class = gtk_type_class (GST_TYPE_BIN);
gtk_object_add_arg_type ("GstThread::create_thread", GTK_TYPE_BOOL, gtk_object_add_arg_type ("GstThread::create_thread", GTK_TYPE_BOOL,
GTK_ARG_READWRITE, ARG_CREATE_THREAD); GTK_ARG_READWRITE, ARG_CREATE_THREAD);
gstelement_class->change_state = gst_thread_change_state; gstelement_class->change_state = gst_thread_change_state;
gstelement_class->save_thyself = gst_thread_save_thyself; gstelement_class->save_thyself = gst_thread_save_thyself;
gstelement_class->restore_thyself = gst_thread_restore_thyself; gstelement_class->restore_thyself = gst_thread_restore_thyself;
gstbin_class->create_plan = gst_thread_create_plan_dummy; //gstbin_class->create_plan = gst_thread_create_plan_dummy;
gstbin_class->schedule = gst_thread_schedule_dummy;
gtkobject_class->set_arg = gst_thread_set_arg; gtkobject_class->set_arg = gst_thread_set_arg;
gtkobject_class->get_arg = gst_thread_get_arg; gtkobject_class->get_arg = gst_thread_get_arg;
@ -136,6 +138,15 @@ gst_thread_init (GstThread *thread)
thread->cond = g_cond_new(); thread->cond = g_cond_new();
} }
static void
gst_thread_schedule_dummy (GstBin *bin)
{
g_return_if_fail (GST_IS_THREAD (bin));
if (!GST_FLAG_IS_SET (GST_THREAD (bin), GST_THREAD_STATE_SPINNING))
GST_INFO (GST_CAT_THREAD,"gstthread: scheduling delayed until thread starts");
}
static void static void
gst_thread_create_plan_dummy (GstBin *bin) gst_thread_create_plan_dummy (GstBin *bin)
{ {
@ -306,8 +317,9 @@ gst_thread_main_loop (void *arg)
gst_element_get_name (GST_ELEMENT (thread)), getpid ()); gst_element_get_name (GST_ELEMENT (thread)), getpid ());
// construct the plan and signal back // construct the plan and signal back
if (GST_BIN_CLASS (parent_class)->create_plan) if (GST_BIN_CLASS (parent_class)->schedule)
GST_BIN_CLASS (parent_class)->create_plan (GST_BIN (thread)); GST_BIN_CLASS (parent_class)->schedule (GST_BIN (thread));
gst_thread_signal_thread (thread); gst_thread_signal_thread (thread);
while (!GST_FLAG_IS_SET (thread, GST_THREAD_STATE_REAPING)) { while (!GST_FLAG_IS_SET (thread, GST_THREAD_STATE_REAPING)) {
@ -323,7 +335,7 @@ gst_thread_main_loop (void *arg)
} }
GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING); GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING);
// pthread_join (thread->thread_id, 0); //pthread_join (thread->thread_id, 0);
GST_INFO (GST_CAT_THREAD, "gstthread: thread \"%s\" is stopped", GST_INFO (GST_CAT_THREAD, "gstthread: thread \"%s\" is stopped",
gst_element_get_name (GST_ELEMENT (thread))); gst_element_get_name (GST_ELEMENT (thread)));

View File

@ -63,6 +63,11 @@ GstVideoScale *gst_videoscale_new(gint sw, gint sh, gint dw, gint dh, GstColorSp
new->scale = gst_videoscale_scale_rgb; new->scale = gst_videoscale_scale_rgb;
scale_bytes = 2; scale_bytes = 2;
break; break;
case GST_COLORSPACE_RGB32:
case GST_COLORSPACE_BGR32:
new->scale = gst_videoscale_scale_rgb;
scale_bytes = 4;
break;
default: default:
g_print("videoscale: unsupported video format %d\n", format); g_print("videoscale: unsupported video format %d\n", format);
g_free(new); g_free(new);

View File

@ -1,4 +1,4 @@
noinst_PROGRAMS = case1 case2 case3 case4 case5 case6 noinst_PROGRAMS = case1 case2 case3 case4 case5 case6 case7
# jsut apps here, this is safe # jsut apps here, this is safe
LIBS += $(GST_LIBS) LIBS += $(GST_LIBS)

View File

@ -19,7 +19,7 @@ eos_signal (GstElement *element)
int int
main(int argc,char *argv[]) main(int argc,char *argv[])
{ {
GstBin *pipeline, *pipeline2; GstBin *pipeline, *bin;
GstElement *src,*identity,*sink; GstElement *src,*identity,*sink;
GstElement *src2,*identity2,*sink2; GstElement *src2,*identity2,*sink2;
@ -38,14 +38,14 @@ main(int argc,char *argv[])
sink = gst_elementfactory_make("fakesink","sink"); sink = gst_elementfactory_make("fakesink","sink");
g_return_val_if_fail(sink != NULL, 4); g_return_val_if_fail(sink != NULL, 4);
pipeline2 = GST_BIN(gst_pipeline_new("pipeline2")); bin = GST_BIN(gst_bin_new("bin"));
g_return_val_if_fail(pipeline2 != NULL, 1); g_return_val_if_fail(bin != NULL, 1);
gst_bin_add(pipeline2,GST_ELEMENT(src)); gst_bin_add(bin,GST_ELEMENT(src));
gst_bin_add(pipeline2,GST_ELEMENT(identity)); gst_bin_add(bin,GST_ELEMENT(identity));
gst_bin_add(pipeline2,GST_ELEMENT(sink)); gst_bin_add(bin,GST_ELEMENT(sink));
gst_bin_add(pipeline,GST_ELEMENT(pipeline2)); gst_bin_add(pipeline,GST_ELEMENT(bin));
gst_element_connect(src,"src",identity,"sink"); gst_element_connect(src,"src",identity,"sink");
gst_element_connect(identity,"src",sink,"sink"); gst_element_connect(identity,"src",sink,"sink");

View File

@ -29,10 +29,11 @@ main(int argc,char *argv[])
g_return_val_if_fail(pipeline != NULL, 1); g_return_val_if_fail(pipeline != NULL, 1);
src = gst_elementfactory_make("fakesrc","src"); src = gst_elementfactory_make("fakesrc","src");
gtk_object_set (GTK_OBJECT (src), "num_buffers", 1, NULL); gtk_object_set (GTK_OBJECT (src), "num_buffers", 4, NULL);
g_return_val_if_fail(src != NULL, 2); g_return_val_if_fail(src != NULL, 2);
identity = gst_elementfactory_make("identity","identity"); identity = gst_elementfactory_make("identity","identity");
gtk_object_set (GTK_OBJECT (identity), "sleep_time", 1000000, NULL);
g_return_val_if_fail(identity != NULL, 3); g_return_val_if_fail(identity != NULL, 3);
sink = gst_elementfactory_make("fakesink","sink"); sink = gst_elementfactory_make("fakesink","sink");
@ -51,7 +52,7 @@ main(int argc,char *argv[])
gst_element_connect(identity,"src",sink,"sink"); gst_element_connect(identity,"src",sink,"sink");
src2 = gst_elementfactory_make("fakesrc","src2"); src2 = gst_elementfactory_make("fakesrc","src2");
gtk_object_set (GTK_OBJECT (src2), "num_buffers", 4, NULL); gtk_object_set (GTK_OBJECT (src2), "num_buffers", 1, NULL);
g_return_val_if_fail(src2 != NULL, 2); g_return_val_if_fail(src2 != NULL, 2);
identity2 = gst_elementfactory_make("identity","identity2"); identity2 = gst_elementfactory_make("identity","identity2");

View File

@ -4,31 +4,33 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
int main(int argc,char *argv[]) { int
main(int argc, char *argv[])
{
GstElement *pipeline; GstElement *pipeline;
char **argvn; char **argvn;
gchar *cmdline; gchar *cmdline;
int i;
gst_init(&argc,&argv); gst_init (&argc, &argv);
pipeline = gst_pipeline_new("launch"); pipeline = gst_pipeline_new ("launch");
// make a null-terminated version of argv // make a null-terminated version of argv
argvn = g_new0(char *,argc); argvn = g_new0 (char *,argc);
memcpy(argvn,argv+1,sizeof(char*)*(argc-1)); memcpy (argvn, argv+1, sizeof (char*) * (argc-1));
// join the argvs together // join the argvs together
cmdline = g_strjoinv(" ",argvn); cmdline = g_strjoinv (" ", argvn);
// free the null-terminated argv // free the null-terminated argv
g_free(argvn); g_free (argvn);
gst_parse_launch(cmdline,pipeline); gst_parse_launch (cmdline, GST_BIN (pipeline));
fprintf(stderr,"RUNNING pipeline\n"); fprintf(stderr,"RUNNING pipeline\n");
gst_element_set_state(pipeline,GST_STATE_PLAYING); gst_element_set_state (pipeline, GST_STATE_PLAYING);
while (1) while (gst_bin_iterate (GST_BIN (pipeline)));
gst_bin_iterate (GST_BIN (pipeline));
gst_element_set_state (pipeline, GST_STATE_NULL);
return 0; return 0;
} }