mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
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:
parent
3dd77c5107
commit
044c4611af
9 changed files with 136 additions and 95 deletions
74
gst/gstbin.c
74
gst/gstbin.c
|
@ -136,6 +136,7 @@ gst_bin_init (GstBin *bin)
|
|||
bin->eos_providers = NULL;
|
||||
bin->num_eos_providers = 0;
|
||||
bin->chains = NULL;
|
||||
bin->eoscond = g_cond_new ();
|
||||
// FIXME temporary testing measure
|
||||
// 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);
|
||||
|
||||
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");
|
||||
children = bin->children;
|
||||
while (children) {
|
||||
|
@ -271,21 +288,6 @@ gst_bin_change_state (GstElement *element)
|
|||
}
|
||||
// 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);
|
||||
}
|
||||
|
@ -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),
|
||||
bin->num_eos_providers);
|
||||
|
||||
GST_LOCK (bin);
|
||||
if (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_element_set_manager (GST_ELEMENT (bin), manager);
|
||||
|
||||
// perform the first recursive pass of plan generation
|
||||
// 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
|
||||
if (GST_IS_BIN (element)) {
|
||||
// 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_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
|
||||
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);
|
||||
|
@ -701,10 +710,6 @@ gst_bin_create_plan_func (GstBin *bin)
|
|||
GST_DEBUG (0,"flattened recurse into \"%s\"\n",elementname);
|
||||
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
|
||||
} else {
|
||||
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++;
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
|
||||
|
@ -719,6 +730,10 @@ gst_bin_create_plan_func (GstBin *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)));
|
||||
}
|
||||
|
||||
|
@ -795,16 +810,21 @@ gst_bin_iterate_func (GstBin *bin)
|
|||
num_scheduled++;
|
||||
}
|
||||
|
||||
/*
|
||||
g_print ("bin \"%s\", eos providers:%d, scheduled: %d\n",
|
||||
gst_element_get_name (GST_ELEMENT (bin)),
|
||||
bin->num_eos_providers, num_scheduled);
|
||||
*/
|
||||
|
||||
if (!num_scheduled && !bin->num_eos_providers) {
|
||||
// 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_LEAVE("(%s)", gst_element_get_name (GST_ELEMENT (bin)));
|
||||
return !eos;
|
||||
|
|
|
@ -67,6 +67,7 @@ struct _GstBin {
|
|||
GList *children;
|
||||
gint num_eos_providers;
|
||||
GList *eos_providers;
|
||||
GCond *eoscond;
|
||||
|
||||
/* iteration state */
|
||||
gboolean need_cothreads;
|
||||
|
|
|
@ -202,7 +202,7 @@ gst_element_add_ghost_pad (GstElement *element, GstPad *pad, gchar *name)
|
|||
element->pads = g_list_append (element->pads, ghostpad);
|
||||
element->numpads++;
|
||||
// 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));
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ GstElementDetails gst_thread_details = {
|
|||
"Container that creates/manages a thread",
|
||||
VERSION,
|
||||
"Erik Walthinsen <omega@cse.ogi.edu>",
|
||||
"(C) 1999",
|
||||
"(C) 1999, 2000",
|
||||
};
|
||||
|
||||
|
||||
|
@ -65,6 +65,7 @@ static void gst_thread_restore_thyself (GstElement *element,xmlNodePtr parent
|
|||
static void gst_thread_signal_thread (GstThread *thread);
|
||||
static void gst_thread_wait_thread (GstThread *thread);
|
||||
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);
|
||||
|
||||
|
@ -113,7 +114,8 @@ gst_thread_class_init (GstThreadClass *klass)
|
|||
gstelement_class->save_thyself = gst_thread_save_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->get_arg = gst_thread_get_arg;
|
||||
|
@ -136,6 +138,15 @@ gst_thread_init (GstThread *thread)
|
|||
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
|
||||
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 ());
|
||||
|
||||
// construct the plan and signal back
|
||||
if (GST_BIN_CLASS (parent_class)->create_plan)
|
||||
GST_BIN_CLASS (parent_class)->create_plan (GST_BIN (thread));
|
||||
if (GST_BIN_CLASS (parent_class)->schedule)
|
||||
GST_BIN_CLASS (parent_class)->schedule (GST_BIN (thread));
|
||||
|
||||
gst_thread_signal_thread (thread);
|
||||
|
||||
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);
|
||||
// pthread_join (thread->thread_id, 0);
|
||||
//pthread_join (thread->thread_id, 0);
|
||||
|
||||
GST_INFO (GST_CAT_THREAD, "gstthread: thread \"%s\" is stopped",
|
||||
gst_element_get_name (GST_ELEMENT (thread)));
|
||||
|
|
|
@ -63,6 +63,11 @@ GstVideoScale *gst_videoscale_new(gint sw, gint sh, gint dw, gint dh, GstColorSp
|
|||
new->scale = gst_videoscale_scale_rgb;
|
||||
scale_bytes = 2;
|
||||
break;
|
||||
case GST_COLORSPACE_RGB32:
|
||||
case GST_COLORSPACE_BGR32:
|
||||
new->scale = gst_videoscale_scale_rgb;
|
||||
scale_bytes = 4;
|
||||
break;
|
||||
default:
|
||||
g_print("videoscale: unsupported video format %d\n", format);
|
||||
g_free(new);
|
||||
|
|
|
@ -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
|
||||
LIBS += $(GST_LIBS)
|
||||
|
|
|
@ -19,7 +19,7 @@ eos_signal (GstElement *element)
|
|||
int
|
||||
main(int argc,char *argv[])
|
||||
{
|
||||
GstBin *pipeline, *pipeline2;
|
||||
GstBin *pipeline, *bin;
|
||||
GstElement *src,*identity,*sink;
|
||||
GstElement *src2,*identity2,*sink2;
|
||||
|
||||
|
@ -38,14 +38,14 @@ main(int argc,char *argv[])
|
|||
sink = gst_elementfactory_make("fakesink","sink");
|
||||
g_return_val_if_fail(sink != NULL, 4);
|
||||
|
||||
pipeline2 = GST_BIN(gst_pipeline_new("pipeline2"));
|
||||
g_return_val_if_fail(pipeline2 != NULL, 1);
|
||||
bin = GST_BIN(gst_bin_new("bin"));
|
||||
g_return_val_if_fail(bin != NULL, 1);
|
||||
|
||||
gst_bin_add(pipeline2,GST_ELEMENT(src));
|
||||
gst_bin_add(pipeline2,GST_ELEMENT(identity));
|
||||
gst_bin_add(pipeline2,GST_ELEMENT(sink));
|
||||
gst_bin_add(bin,GST_ELEMENT(src));
|
||||
gst_bin_add(bin,GST_ELEMENT(identity));
|
||||
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(identity,"src",sink,"sink");
|
||||
|
|
|
@ -29,10 +29,11 @@ main(int argc,char *argv[])
|
|||
g_return_val_if_fail(pipeline != NULL, 1);
|
||||
|
||||
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);
|
||||
|
||||
identity = gst_elementfactory_make("identity","identity");
|
||||
gtk_object_set (GTK_OBJECT (identity), "sleep_time", 1000000, NULL);
|
||||
g_return_val_if_fail(identity != NULL, 3);
|
||||
|
||||
sink = gst_elementfactory_make("fakesink","sink");
|
||||
|
@ -51,7 +52,7 @@ main(int argc,char *argv[])
|
|||
gst_element_connect(identity,"src",sink,"sink");
|
||||
|
||||
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);
|
||||
|
||||
identity2 = gst_elementfactory_make("identity","identity2");
|
||||
|
|
|
@ -4,31 +4,33 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
GstElement *pipeline;
|
||||
char **argvn;
|
||||
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
|
||||
argvn = g_new0(char *,argc);
|
||||
memcpy(argvn,argv+1,sizeof(char*)*(argc-1));
|
||||
argvn = g_new0 (char *,argc);
|
||||
memcpy (argvn, argv+1, sizeof (char*) * (argc-1));
|
||||
// join the argvs together
|
||||
cmdline = g_strjoinv(" ",argvn);
|
||||
cmdline = g_strjoinv (" ", argvn);
|
||||
// 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");
|
||||
gst_element_set_state(pipeline,GST_STATE_PLAYING);
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
while (1)
|
||||
gst_bin_iterate (GST_BIN (pipeline));
|
||||
while (gst_bin_iterate (GST_BIN (pipeline)));
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue