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
74
gst/gstbin.c
74
gst/gstbin.c
@ -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,16 +810,21 @@ 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_DEBUG (0,"num eos providers %d\n", bin->num_eos_providers);
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
}
|
||||||
|
else {
|
||||||
gst_element_signal_eos (GST_ELEMENT (bin));
|
gst_element_signal_eos (GST_ELEMENT (bin));
|
||||||
eos = TRUE;
|
eos = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG_LEAVE("(%s)", gst_element_get_name (GST_ELEMENT (bin)));
|
GST_DEBUG_LEAVE("(%s)", gst_element_get_name (GST_ELEMENT (bin)));
|
||||||
return !eos;
|
return !eos;
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -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_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);
|
||||||
|
|
||||||
@ -113,7 +114,8 @@ gst_thread_class_init (GstThreadClass *klass)
|
|||||||
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)));
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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");
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user