mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-12 03:16:33 +00:00
snapshot for matth to work with while I fly over to Europe....
Original commit message from CVS: snapshot for matth to work with while I fly over to Europe....
This commit is contained in:
parent
8a10800420
commit
f75bb0f38b
13 changed files with 186 additions and 184 deletions
1
AUTHORS
1
AUTHORS
|
@ -2,3 +2,4 @@ Erik Walthinsen <omega@cse.ogi.edu>
|
|||
Wim Taymans <wim.taymans@tvd.be>
|
||||
Richard Boulton <richard@tartarus.org>
|
||||
Chris Emerson (PPC port)
|
||||
Zaheer Merali <zaheer@grid9.net> (thread synchronization rework)
|
||||
|
|
|
@ -19,7 +19,11 @@ bin_SCRIPTS = gstreamer-config
|
|||
m4datadir = $(datadir)/aclocal
|
||||
m4data_DATA = gstreamer.m4
|
||||
|
||||
EXTRA_DIST = gstreamer.spec.in gstreamer-config.in gstreamer.m4 LICENSE REQUIREMENTS ABOUT-NLS
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = gstreamer.pc
|
||||
|
||||
EXTRA_DIST = gstreamer.spec.in gstreamer-config.in gstreamer.m4 gstreamer.pc.in \
|
||||
LICENSE REQUIREMENTS ABOUT-NLS
|
||||
|
||||
dist-hook:
|
||||
cp gstreamer.spec $(distdir)
|
||||
|
|
|
@ -757,5 +757,6 @@ docs/manual/Makefile
|
|||
docs/fwg/Makefile
|
||||
stamp.h
|
||||
gstreamer-config
|
||||
gstreamer.spec])
|
||||
gstreamer.spec
|
||||
gstreamer.pc])
|
||||
AC_OUTPUT_COMMANDS([chmod +x gstreamer-config])
|
||||
|
|
13
gst/gstbin.c
13
gst/gstbin.c
|
@ -210,7 +210,7 @@ gst_bin_set_element_sched (GstElement *element,GstSchedule *sched)
|
|||
|
||||
// otherwise, if it's just a regular old element
|
||||
} else {
|
||||
g_print("calling schedule_add_element (%p, \"%s\")\n",sched, GST_ELEMENT_NAME(element));
|
||||
//g_print("calling schedule_add_element (%p, \"%s\")\n",sched, GST_ELEMENT_NAME(element));
|
||||
GST_SCHEDULE_ADD_ELEMENT (sched, element);
|
||||
}
|
||||
}
|
||||
|
@ -264,10 +264,8 @@ gst_bin_add (GstBin *bin,
|
|||
|
||||
GST_DEBUG_ENTER ("");
|
||||
|
||||
// must be NULL or PAUSED state in order to modify bin
|
||||
// FIXME this isn't right any more
|
||||
g_return_if_fail ((GST_STATE (bin) == GST_STATE_NULL) ||
|
||||
(GST_STATE (bin) == GST_STATE_PAUSED));
|
||||
// must be not be in PLAYING state in order to modify bin
|
||||
g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING);
|
||||
|
||||
// the element must not already have a parent
|
||||
g_return_if_fail (GST_ELEMENT_PARENT(element) == NULL);
|
||||
|
@ -311,9 +309,8 @@ gst_bin_remove (GstBin *bin,
|
|||
g_return_if_fail (GST_IS_ELEMENT (element));
|
||||
g_return_if_fail (bin->children != NULL);
|
||||
|
||||
// must be NULL or PAUSED state in order to modify bin
|
||||
g_return_if_fail ((GST_STATE (bin) == GST_STATE_NULL) ||
|
||||
(GST_STATE (bin) == GST_STATE_PAUSED));
|
||||
// must not be in PLAYING state in order to modify bin
|
||||
g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING);
|
||||
|
||||
// the element must have its parent set to the current bin
|
||||
g_return_if_fail (GST_ELEMENT_PARENT(element) == (GstElement *)bin);
|
||||
|
|
|
@ -700,6 +700,9 @@ gst_element_set_state (GstElement *element, GstElementState state)
|
|||
g_return_val_if_fail (element != NULL, GST_STATE_FAILURE);
|
||||
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
|
||||
|
||||
GST_DEBUG (GST_CAT_STATES,"setting element '%s' to state %s\n",GST_ELEMENT_NAME (element),
|
||||
_gst_print_statename(state));
|
||||
|
||||
/* start with the current state */
|
||||
curpending = GST_STATE(element);
|
||||
|
||||
|
@ -712,6 +715,8 @@ gst_element_set_state (GstElement *element, GstElementState state)
|
|||
/* set the pending state variable */
|
||||
// FIXME: should probably check to see that we don't already have one
|
||||
GST_STATE_PENDING (element) = curpending;
|
||||
GST_DEBUG (GST_CAT_STATES,"intermediate: setting element '%s' to state %s\n",
|
||||
GST_ELEMENT_NAME (element),_gst_print_statename(curpending));
|
||||
|
||||
/* call the state change function so it can set the state */
|
||||
oclass = GST_ELEMENT_CLASS (GTK_OBJECT (element)->klass);
|
||||
|
@ -767,8 +772,8 @@ gst_element_change_state (GstElement *element)
|
|||
g_return_val_if_fail (element != NULL, GST_STATE_FAILURE);
|
||||
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
|
||||
|
||||
// g_print("gst_element_change_state(\"%s\",%d)\n",
|
||||
// element->name,state);
|
||||
GST_DEBUG (GST_CAT_STATES, "default handler sets '%s' state to %s\n",
|
||||
GST_ELEMENT_NAME (element), _gst_print_statename(GST_STATE_PENDING(element)));
|
||||
|
||||
if (GST_STATE_TRANSITION(element) == GST_STATE_READY_TO_PLAYING)
|
||||
GST_SCHEDULE_ENABLE_ELEMENT (element->sched,element);
|
||||
|
|
|
@ -574,8 +574,11 @@ gst_pad_connect (GstPad *srcpad,
|
|||
gtk_signal_emit(GTK_OBJECT(realsrc), gst_real_pad_signals[REAL_CONNECTED], realsink);
|
||||
gtk_signal_emit(GTK_OBJECT(realsink), gst_real_pad_signals[REAL_CONNECTED], realsrc);
|
||||
|
||||
// now tell the scheduler
|
||||
GST_SCHEDULE_PAD_CONNECT (realsrc->sched, realsrc, realsink);
|
||||
// now tell the scheduler(s)
|
||||
if (realsrc->sched)
|
||||
GST_SCHEDULE_PAD_CONNECT (realsrc->sched, realsrc, realsink);
|
||||
else if (realsink->sched)
|
||||
GST_SCHEDULE_PAD_CONNECT (realsink->sched, realsrc, realsink);
|
||||
|
||||
GST_INFO (GST_CAT_ELEMENT_PADS, "connected %s:%s and %s:%s",
|
||||
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
|
||||
|
|
|
@ -862,6 +862,7 @@ gst_schedule_chain_new (GstSchedule *sched)
|
|||
{
|
||||
GstScheduleChain *chain = g_new (GstScheduleChain, 1);
|
||||
|
||||
// initialize the chain with sane values
|
||||
chain->sched = sched;
|
||||
chain->disabled = NULL;
|
||||
chain->elements = NULL;
|
||||
|
@ -870,6 +871,7 @@ gst_schedule_chain_new (GstSchedule *sched)
|
|||
chain->cothreaded_elements = 0;
|
||||
chain->schedule = FALSE;
|
||||
|
||||
// add the chain to the schedules' list of chains
|
||||
sched->chains = g_list_prepend (sched->chains, chain);
|
||||
sched->num_chains++;
|
||||
|
||||
|
@ -881,11 +883,13 @@ gst_schedule_chain_new (GstSchedule *sched)
|
|||
void
|
||||
gst_schedule_chain_destroy (GstScheduleChain *chain)
|
||||
{
|
||||
// remove the chain from the schedules' list of chains
|
||||
chain->sched->chains = g_list_remove (chain->sched->chains, chain);
|
||||
chain->sched->num_chains--;
|
||||
|
||||
g_list_free (chain->disabled);
|
||||
g_list_free (chain->elements);
|
||||
// destroy the chain
|
||||
g_list_free (chain->disabled); // should be empty...
|
||||
g_list_free (chain->elements); // ditto
|
||||
g_free (chain);
|
||||
}
|
||||
|
||||
|
@ -925,7 +929,8 @@ gst_schedule_chain_disable_element (GstScheduleChain *chain, GstElement *element
|
|||
chain->disabled = g_list_prepend (chain->disabled, element);
|
||||
|
||||
// reschedule the chain
|
||||
gst_schedule_cothreaded_chain(GST_BIN(chain->sched->parent),chain);
|
||||
// FIXME this should be done only if manager state != NULL
|
||||
// gst_schedule_cothreaded_chain(GST_BIN(chain->sched->parent),chain);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -938,8 +943,13 @@ gst_schedule_chain_remove_element (GstScheduleChain *chain, GstElement *element)
|
|||
gst_schedule_chain_disable_element (chain, element);
|
||||
}
|
||||
|
||||
// remove the element from the list of elements
|
||||
chain->disabled = g_list_remove (chain->disabled, element);
|
||||
chain->num_elements--;
|
||||
|
||||
// if there are no more elements in the chain, destroy the chain
|
||||
if (chain->num_elements == 0)
|
||||
gst_schedule_chain_destroy(chain);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1015,7 +1025,7 @@ gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad)
|
|||
GST_INFO (GST_CAT_SCHEDULING, "have pad connected callback on %s:%s",GST_DEBUG_PAD_NAME(srcpad));
|
||||
|
||||
if ((peerelement = gst_schedule_check_pad(sched,srcpad))) {
|
||||
GST_INFO (GST_CAT_SCHEDULING, "peer is in same schedule, chaining together");
|
||||
GST_INFO (GST_CAT_SCHEDULING, "peer %s:%s is in same schedule, chaining together",GST_DEBUG_PAD_NAME(sinkpad));
|
||||
gst_schedule_chain_elements (sched, GST_ELEMENT(GST_PAD_PARENT(srcpad)), peerelement);
|
||||
}
|
||||
}
|
||||
|
@ -1097,18 +1107,12 @@ gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad
|
|||
// now create a new chain to hold element1 and build it from scratch
|
||||
chain1 = gst_schedule_chain_new (sched);
|
||||
gst_schedule_chain_recursive_add (chain1, element1);
|
||||
// this is an ugly hack to handle elements left over
|
||||
if (chain1->num_elements == 1)
|
||||
gst_schedule_chain_destroy(chain1);
|
||||
|
||||
// check the other element to see if it landed in the newly created chain
|
||||
if (gst_schedule_find_chain (sched, element2) == NULL) {
|
||||
// if not in chain, create chain and build from scratch
|
||||
chain2 = gst_schedule_chain_new (sched);
|
||||
gst_schedule_chain_recursive_add (chain2, element2);
|
||||
// this is an ugly hack to handle elements left over
|
||||
if (chain2->num_elements == 1)
|
||||
gst_schedule_chain_destroy(chain2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1119,6 +1123,7 @@ gst_schedule_add_element (GstSchedule *sched, GstElement *element)
|
|||
GList *pads;
|
||||
GstPad *pad;
|
||||
GstElement *peerelement;
|
||||
GstScheduleChain *chain;
|
||||
|
||||
g_return_if_fail (element != NULL);
|
||||
g_return_if_fail (GST_IS_ELEMENT(element));
|
||||
|
@ -1126,12 +1131,19 @@ gst_schedule_add_element (GstSchedule *sched, GstElement *element)
|
|||
GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to schedule",
|
||||
GST_ELEMENT_NAME(element));
|
||||
|
||||
// set the sched pointer in the element itself
|
||||
gst_element_set_sched (element, sched);
|
||||
|
||||
// only deal with elements after this point, not bins
|
||||
if (GST_IS_BIN (element)) return;
|
||||
|
||||
// first add it to the list of elements that are to be scheduled
|
||||
sched->elements = g_list_prepend (sched->elements, element);
|
||||
sched->num_elements++;
|
||||
|
||||
// set the sched pointer in the element itself
|
||||
gst_element_set_sched (element, sched);
|
||||
// create a chain to hold it, and add
|
||||
chain = gst_schedule_chain_new (sched);
|
||||
gst_schedule_chain_add_element (chain, element);
|
||||
|
||||
// set the sched pointer in all the pads
|
||||
pads = element->pads;
|
||||
|
@ -1185,6 +1197,8 @@ gst_schedule_disable_element (GstSchedule *sched, GstElement *element)
|
|||
void
|
||||
gst_schedule_remove_element (GstSchedule *sched, GstElement *element)
|
||||
{
|
||||
GstScheduleChain *chain;
|
||||
|
||||
g_return_if_fail (element != NULL);
|
||||
g_return_if_fail (GST_IS_ELEMENT(element));
|
||||
|
||||
|
@ -1192,15 +1206,21 @@ gst_schedule_remove_element (GstSchedule *sched, GstElement *element)
|
|||
GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from schedule",
|
||||
GST_ELEMENT_NAME(element));
|
||||
|
||||
// disable the element, i.e. remove from chain
|
||||
gst_schedule_disable_element (sched, element);
|
||||
// find what chain the element is in
|
||||
chain = gst_schedule_find_chain(sched, element);
|
||||
|
||||
// unset the scheduler
|
||||
gst_element_set_sched (element, NULL);
|
||||
// disable the element, i.e. remove from chain's active list
|
||||
gst_schedule_chain_disable_element (chain, element);
|
||||
|
||||
// remove it from its chain
|
||||
gst_schedule_chain_remove_element (chain, element);
|
||||
|
||||
// remove it from the list of elements
|
||||
sched->elements = g_list_remove (sched->elements, element);
|
||||
sched->num_elements--;
|
||||
|
||||
// unset the scheduler pointer in the element
|
||||
gst_element_set_sched (element, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1213,6 +1233,7 @@ gst_schedule_iterate (GstSchedule *sched)
|
|||
GstElement *entry;
|
||||
gint num_scheduled = 0;
|
||||
gboolean eos = FALSE;
|
||||
GList *elements;
|
||||
|
||||
GST_DEBUG_ENTER("(\"%s\")", GST_ELEMENT_NAME (bin));
|
||||
|
||||
|
@ -1222,7 +1243,8 @@ gst_schedule_iterate (GstSchedule *sched)
|
|||
|
||||
// step through all the chains
|
||||
chains = sched->chains;
|
||||
if (chains == NULL) return FALSE;
|
||||
// if (chains == NULL) return FALSE;
|
||||
g_return_val_if_fail (chains != NULL, FALSE);
|
||||
while (chains) {
|
||||
chain = (GstScheduleChain *)(chains->data);
|
||||
chains = g_list_next (chains);
|
||||
|
@ -1235,8 +1257,17 @@ gst_schedule_iterate (GstSchedule *sched)
|
|||
GST_DEBUG (GST_CAT_DATAFLOW,"starting iteration via cothreads\n");
|
||||
|
||||
if (chain->elements) {
|
||||
elements = chain->elements;
|
||||
//printf("searching for non-decoupled element\n");
|
||||
while (elements) {
|
||||
entry = GST_ELEMENT(elements->data);
|
||||
elements = g_list_next(elements);
|
||||
//printf("checking %s\n",GST_ELEMENT_NAME(entry));
|
||||
if (!GST_FLAG_IS_SET(entry,GST_ELEMENT_DECOUPLED)) break;
|
||||
}
|
||||
//printf("found non-decoupled element\n");
|
||||
// FIXME FIXME FIXME need to not use a DECOUPLED element as entry
|
||||
entry = GST_ELEMENT (chain->elements->data);
|
||||
// entry = GST_ELEMENT (chain->elements->data);
|
||||
if (entry) {
|
||||
GST_FLAG_SET (entry, GST_ELEMENT_COTHREAD_STOPPING);
|
||||
GST_DEBUG (GST_CAT_DATAFLOW,"set COTHREAD_STOPPING flag on \"%s\"(@%p)\n",
|
||||
|
|
|
@ -118,9 +118,9 @@ 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);
|
||||
gboolean gst_schedule_iterate (GstSchedule *sched);
|
||||
|
||||
void gst_schedule_show (GstSchedule *sched);
|
||||
gboolean gst_schedule_iterate (GstSchedule *sched);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
206
gst/gstthread.c
206
gst/gstthread.c
|
@ -68,8 +68,7 @@ static GstElementStateReturn gst_thread_change_state (GstElement *element);
|
|||
static xmlNodePtr gst_thread_save_thyself (GstObject *object, xmlNodePtr parent);
|
||||
static void gst_thread_restore_thyself (GstObject *object, xmlNodePtr self);
|
||||
|
||||
static void gst_thread_signal_thread (GstThread *thread, guint syncflag,gboolean set);
|
||||
static void gst_thread_wait_thread (GstThread *thread, guint syncflag,gboolean set);
|
||||
static void gst_thread_signal_thread (GstThread *thread, gboolean spinning);
|
||||
static void
|
||||
gst_thread_wait_two_thread (GstThread *thread, guint syncflag, gboolean set,guint syncflag2, gboolean set2);
|
||||
static void gst_thread_schedule_dummy (GstBin *bin);
|
||||
|
@ -255,13 +254,16 @@ gst_thread_change_state (GstElement *element)
|
|||
GST_DEBUG (GST_CAT_THREAD, "creating thread \"%s\"\n",
|
||||
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
||||
|
||||
g_mutex_lock(thread->lock);
|
||||
|
||||
// create the thread
|
||||
pthread_create (&thread->thread_id, NULL,
|
||||
gst_thread_main_loop, thread);
|
||||
|
||||
// wait for it to 'spin up'
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: waiting for spinup\n");
|
||||
gst_thread_wait_thread (thread,GST_THREAD_STATE_STARTED,TRUE);
|
||||
g_cond_wait(thread->cond,thread->lock);
|
||||
g_mutex_unlock(thread->lock);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: thread claims to be up\n");
|
||||
} else {
|
||||
GST_INFO (GST_CAT_THREAD, "NOT starting thread \"%s\"",
|
||||
|
@ -279,38 +281,23 @@ gst_thread_change_state (GstElement *element)
|
|||
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
||||
|
||||
GST_DEBUG(0,"sync: telling thread to start spinning\n");
|
||||
gst_thread_signal_thread (thread,GST_THREAD_STATE_SPINNING,TRUE);
|
||||
GST_DEBUG(0,"sync: done telling thread to start spinning\n");
|
||||
GST_INFO(GST_CAT_THREAD, "waiting for thread to start up");
|
||||
gst_thread_wait_thread (thread,GST_THREAD_STATE_ELEMENT_CHANGED,TRUE);
|
||||
g_mutex_lock(thread->lock);
|
||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_ELEMENT_CHANGED);
|
||||
g_mutex_unlock(thread->lock);
|
||||
gst_thread_signal_thread(thread,TRUE);
|
||||
break;
|
||||
case GST_STATE_PLAYING_TO_PAUSED:
|
||||
GST_INFO (GST_CAT_THREAD,"pausing thread \"%s\"",
|
||||
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
||||
|
||||
//GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
|
||||
gst_thread_signal_thread (thread,GST_THREAD_STATE_SPINNING,FALSE);
|
||||
gst_thread_wait_thread (thread,GST_THREAD_STATE_ELEMENT_CHANGED,TRUE);
|
||||
g_mutex_lock(thread->lock);
|
||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_ELEMENT_CHANGED);
|
||||
g_mutex_unlock(thread->lock);
|
||||
gst_thread_signal_thread(thread,FALSE);
|
||||
break;
|
||||
case GST_STATE_PLAYING_TO_READY:
|
||||
gst_thread_signal_thread (thread,GST_THREAD_STATE_SPINNING,FALSE);
|
||||
gst_thread_wait_thread (thread,GST_THREAD_STATE_ELEMENT_CHANGED,TRUE);
|
||||
g_mutex_lock(thread->lock);
|
||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_ELEMENT_CHANGED);
|
||||
g_mutex_unlock(thread->lock);
|
||||
gst_thread_signal_thread(thread,FALSE);
|
||||
break;
|
||||
case GST_STATE_READY_TO_NULL:
|
||||
GST_INFO (GST_CAT_THREAD,"stopping thread \"%s\"",
|
||||
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
||||
|
||||
//GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING);
|
||||
gst_thread_signal_thread (thread,GST_THREAD_STATE_REAPING,TRUE);
|
||||
GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING);
|
||||
gst_thread_signal_thread(thread,FALSE);
|
||||
|
||||
pthread_join(thread->thread_id,NULL);
|
||||
|
||||
|
@ -320,7 +307,7 @@ gst_thread_change_state (GstElement *element)
|
|||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_ELEMENT_CHANGED);
|
||||
|
||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||
stateset = GST_ELEMENT_CLASS (parent_class)->change_state (thread);
|
||||
stateset = GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT(thread));
|
||||
|
||||
break;
|
||||
default:
|
||||
|
@ -330,6 +317,16 @@ gst_thread_change_state (GstElement *element)
|
|||
return stateset;
|
||||
}
|
||||
|
||||
static void gst_thread_update_state (GstThread *thread)
|
||||
{
|
||||
// check for state change
|
||||
if (GST_STATE_PENDING(thread) != GST_STATE_NONE_PENDING) {
|
||||
// punt and change state on all the children
|
||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||
GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT(thread));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_thread_main_loop:
|
||||
* @arg: the thread to start
|
||||
|
@ -341,8 +338,8 @@ static void *
|
|||
gst_thread_main_loop (void *arg)
|
||||
{
|
||||
GstThread *thread = GST_THREAD (arg);
|
||||
gboolean first = 1;
|
||||
gint stateset;
|
||||
gboolean isSpinning = FALSE;
|
||||
|
||||
GST_INFO (GST_CAT_THREAD,"thread \"%s\" is running with PID %d",
|
||||
GST_ELEMENT_NAME (GST_ELEMENT (thread)), getpid ());
|
||||
|
@ -357,58 +354,48 @@ gst_thread_main_loop (void *arg)
|
|||
if (GST_BIN_CLASS (parent_class)->schedule)
|
||||
GST_BIN_CLASS (parent_class)->schedule (GST_BIN (thread));
|
||||
|
||||
GST_DEBUG(0, "sync: indicating spinup\n");
|
||||
gst_thread_signal_thread (thread,GST_THREAD_STATE_STARTED,TRUE);
|
||||
GST_DEBUG(0, "sync: done indicating spinup\n");
|
||||
|
||||
GST_INFO (GST_CAT_THREAD,"sync: thread has signaled to parent at startup");
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: indicating spinup\n");
|
||||
g_mutex_lock (thread->lock);
|
||||
g_cond_signal (thread->cond);
|
||||
// don't unlock the mutex because we hold it into the top of the while loop
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: thread has indicated spinup to main process\n");
|
||||
|
||||
while (!GST_FLAG_IS_SET (thread, GST_THREAD_STATE_REAPING)) {
|
||||
if (GST_FLAG_IS_SET (thread, GST_THREAD_STATE_SPINNING)) {
|
||||
isSpinning=TRUE;
|
||||
// start out by waiting for a state change into spinning
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: waiting at top of while for signal from main process\n");
|
||||
g_cond_wait (thread->cond,thread->lock);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: main process has signaled at top of while\n");
|
||||
// now is a good time to change the state of the children and the thread itself
|
||||
gst_thread_update_state (thread);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: done changing state, signaling back\n");
|
||||
g_cond_signal (thread->cond);
|
||||
g_mutex_unlock (thread->lock);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: done syncing with main thread at top of while\n");
|
||||
|
||||
while (GST_FLAG_IS_SET (thread, GST_THREAD_STATE_SPINNING)) {
|
||||
if (!gst_bin_iterate (GST_BIN (thread))) {
|
||||
/*g_mutex_lock(thread->lock);
|
||||
GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
|
||||
GST_DEBUG(0,"sync: removed spinning state due to failed iteration\n");
|
||||
g_mutex_unlock(thread->lock);*/
|
||||
gst_thread_wait_two_thread(thread,GST_THREAD_STATE_REAPING,TRUE,
|
||||
GST_THREAD_STATE_SPINNING,FALSE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isSpinning==TRUE) {
|
||||
GST_DEBUG(0,"sync: got a pause or playing to ready transition");
|
||||
isSpinning=FALSE;
|
||||
// check for state change
|
||||
if (GST_STATE_PENDING(thread)) {
|
||||
// punt and change state on all the children
|
||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||
stateset = GST_ELEMENT_CLASS (parent_class)->change_state (thread);
|
||||
}
|
||||
gst_thread_signal_thread (thread,GST_THREAD_STATE_ELEMENT_CHANGED,TRUE);
|
||||
}
|
||||
|
||||
GST_DEBUG (0, "sync: thread \"%s\" waiting\n", GST_ELEMENT_NAME (GST_ELEMENT (thread)));
|
||||
gst_thread_wait_two_thread (thread,GST_THREAD_STATE_SPINNING,TRUE,
|
||||
GST_THREAD_STATE_REAPING,TRUE);
|
||||
GST_DEBUG (0, "sync: done waiting\n");
|
||||
isSpinning=TRUE;
|
||||
// if reaping was returned, break outof while loop
|
||||
if (GST_FLAG_IS_SET(thread,GST_THREAD_STATE_REAPING)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check for state change
|
||||
if (GST_STATE_PENDING(thread)) {
|
||||
// punt and change state on all the children
|
||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||
stateset = GST_ELEMENT_CLASS (parent_class)->change_state (thread);
|
||||
}
|
||||
|
||||
gst_thread_signal_thread (thread,GST_THREAD_STATE_ELEMENT_CHANGED,TRUE);
|
||||
}
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: waiting at bottom of while for signal from main process\n");
|
||||
g_mutex_lock (thread->lock);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: signaling that the thread is out of the SPINNING loop\n");
|
||||
g_cond_signal (thread->cond);
|
||||
g_cond_wait (thread->cond, thread->lock);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: main process has signaled at bottom of while\n");
|
||||
// now change the children's and thread's state
|
||||
gst_thread_update_state (thread);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: done changing state, signaling back\n");
|
||||
g_cond_signal (thread->cond);
|
||||
// don't release the mutex, we hold that into the top of the loop
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync: done syncning with main thread at bottom of while\n");
|
||||
}
|
||||
|
||||
// since we don't unlock at the end of the while loop, do it here
|
||||
g_mutex_unlock (thread->lock);
|
||||
|
||||
GST_INFO (GST_CAT_THREAD, "gstthread: thread \"%s\" is stopped",
|
||||
GST_ELEMENT_NAME (thread));
|
||||
return NULL;
|
||||
|
@ -416,76 +403,27 @@ gst_thread_main_loop (void *arg)
|
|||
|
||||
// the set flag is to say whether it should set TRUE or FALSE
|
||||
static void
|
||||
gst_thread_signal_thread (GstThread *thread, guint syncflag, gboolean set)
|
||||
gst_thread_signal_thread (GstThread *thread, gboolean spinning)
|
||||
{
|
||||
g_mutex_lock (thread->lock);
|
||||
GST_DEBUG (0,"sync: signaling thread setting %u to %d\n",syncflag,set);
|
||||
if (set)
|
||||
GST_FLAG_SET(thread,syncflag);
|
||||
else
|
||||
GST_FLAG_UNSET(thread,syncflag);
|
||||
// set the spinning state
|
||||
if (spinning) GST_FLAG_SET(thread,GST_THREAD_STATE_SPINNING);
|
||||
else GST_FLAG_SET (thread, GST_THREAD_STATE_SPINNING);
|
||||
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: locking\n");
|
||||
g_mutex_lock(thread->lock);
|
||||
|
||||
if (!spinning) {
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: waiting for spindown\n");
|
||||
g_cond_wait (thread->cond, thread->lock);
|
||||
}
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: signaling\n");
|
||||
g_cond_signal (thread->cond);
|
||||
g_mutex_unlock (thread->lock);
|
||||
GST_DEBUG (0,"sync: done signaling thread with %u set to %u..should be %d\n",syncflag,
|
||||
GST_FLAG_IS_SET(thread,syncflag),set);
|
||||
}
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: waiting for ack\n");
|
||||
g_cond_wait (thread->cond,thread->lock);
|
||||
|
||||
// the set flag is to see what flag to wait for
|
||||
static void
|
||||
gst_thread_wait_thread (GstThread *thread, guint syncflag, gboolean set)
|
||||
{
|
||||
// if (!thread->signaling) {
|
||||
GTimeVal finaltime;
|
||||
g_mutex_lock (thread->lock);
|
||||
GST_DEBUG (0,"sync: waiting for thread for %u to be set %d\n",
|
||||
syncflag,set);
|
||||
while ((!GST_FLAG_IS_SET(thread,syncflag) && set==TRUE) ||
|
||||
(GST_FLAG_IS_SET(thread,syncflag) && set==FALSE)) {
|
||||
g_get_current_time(&finaltime);
|
||||
if (finaltime.tv_usec>995000) {
|
||||
finaltime.tv_sec++;
|
||||
finaltime.tv_usec=5000-(1000000-finaltime.tv_usec);
|
||||
}
|
||||
else {
|
||||
finaltime.tv_usec+=5000;
|
||||
}
|
||||
g_cond_timed_wait (thread->cond, thread->lock,&finaltime);
|
||||
}
|
||||
g_mutex_unlock (thread->lock);
|
||||
GST_DEBUG (0, "sync: done waiting for thread for %u to be set %d\n",
|
||||
syncflag,set);
|
||||
// }
|
||||
}
|
||||
|
||||
// the set flag is to see what flag to wait for
|
||||
static void
|
||||
gst_thread_wait_two_thread (GstThread *thread, guint syncflag, gboolean set,
|
||||
guint syncflag2, gboolean set2)
|
||||
{
|
||||
// if (!thread->signaling) {
|
||||
GTimeVal finaltime;
|
||||
g_mutex_lock (thread->lock);
|
||||
GST_DEBUG (0,"sync: waiting for thread for %u to be set %d or %u to be set %d\n",
|
||||
syncflag,set,syncflag2,set);
|
||||
while (((!GST_FLAG_IS_SET(thread,syncflag) && set==TRUE) ||
|
||||
(GST_FLAG_IS_SET(thread,syncflag) && set==FALSE)) &&
|
||||
((!GST_FLAG_IS_SET(thread,syncflag2) && set2==TRUE) ||
|
||||
(GST_FLAG_IS_SET(thread,syncflag2) && set==FALSE)))
|
||||
{
|
||||
g_get_current_time(&finaltime);
|
||||
if (finaltime.tv_usec>995000) {
|
||||
finaltime.tv_sec++;
|
||||
finaltime.tv_usec=5000-(1000000-finaltime.tv_usec);
|
||||
}
|
||||
else {
|
||||
finaltime.tv_usec+=5000;
|
||||
}
|
||||
g_cond_timed_wait (thread->cond, thread->lock,&finaltime);
|
||||
}
|
||||
g_mutex_unlock (thread->lock);
|
||||
GST_DEBUG (0, "sync: done waiting for thread for %u to be set %d or %u to be set %d\n",
|
||||
syncflag,set,syncflag2,set2);
|
||||
// }
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: unlocking\n");
|
||||
g_mutex_unlock(thread->lock);
|
||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: unlocked\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -83,3 +83,4 @@ make prefix=$RPM_BUILD_ROOT%{prefix} install
|
|||
%{prefix}/include/*
|
||||
%{prefix}/lib/lib*.a
|
||||
%{prefix}/lib/lib*.so
|
||||
%{prefix}/lib/pkgconfig/*
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
<<<<<<< incsched.c
|
||||
<<<<<<< incsched.c
|
||||
#include <stdlib.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
@ -49,11 +47,11 @@ int main(int argc,char *argv[]) {
|
|||
|
||||
g_print("\nAdding sink to bin:\n");
|
||||
gst_bin_add(bin,sink);
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(bin));
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(thread));
|
||||
|
||||
g_print("\nAdding bin to thread:\n");
|
||||
gst_bin_add(thread, GST_ELEMENT(bin));
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(bin));
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(thread));
|
||||
|
||||
g_print("\nConnecting identity to sink:\n");
|
||||
gst_element_connect(identity,"src",sink,"sink");
|
||||
|
@ -113,6 +111,13 @@ int main(int argc,char *argv[]) {
|
|||
gst_element_connect(identity,"src",sink,"sink");
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(thread));
|
||||
|
||||
g_print("\n\nNow setting identity2 to NULL:\n");
|
||||
gst_element_set_state(identity2,GST_STATE_NULL);
|
||||
|
||||
g_print("\nRemoving identity2 from bin:\n");
|
||||
gst_bin_remove(bin, identity2);
|
||||
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));
|
||||
|
|
|
@ -12,23 +12,34 @@ int main(int argc,char *argv[]) {
|
|||
pipeline = gst_pipeline_new("pipeline");
|
||||
thread = gst_thread_new("thread");
|
||||
src = gst_elementfactory_make("fakesrc","src");
|
||||
queue1 = gst_elementfactory_make("queue","queue");
|
||||
sink = gst_elementfactory_make("fakesink","sink");
|
||||
|
||||
gst_bin_add(pipeline,src);
|
||||
gst_bin_add(pipeline,queue1);
|
||||
gst_bin_add(pipeline,GST_ELEMENT(thread));
|
||||
fprintf(stderr,"ADDING src\n");
|
||||
gst_bin_add(thread,src);
|
||||
fprintf(stderr,"ADDING sink\n");
|
||||
gst_bin_add(thread,sink);
|
||||
fprintf(stderr,"ADDING thread\n");
|
||||
gst_bin_add(pipeline,GST_ELEMENT(thread));
|
||||
|
||||
gst_element_add_ghost_pad(GST_ELEMENT(thread),gst_element_get_pad(sink,"sink"),"sink");
|
||||
// gst_element_add_ghost_pad(GST_ELEMENT(thread),gst_element_get_pad(sink,"sink"),"sink");
|
||||
|
||||
gst_element_connect (src,"src",queue1,"sink");
|
||||
gst_element_connect (queue1, "src", thread, "sink");
|
||||
fprintf(stderr,"CONNECTING src to sink\n");
|
||||
gst_element_connect (src, "src", sink, "sink");
|
||||
|
||||
while (1) {
|
||||
fprintf(stderr,"SWITCHING TO READY:\n");
|
||||
gst_element_set_state (pipeline, GST_STATE_READY);
|
||||
fprintf(stderr,"SWITCHING TO NULL:\n");
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
}
|
||||
fprintf(stderr,"\nSWITCHING to READY:\n");
|
||||
gst_element_set_state (thread, GST_STATE_READY);
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(pipeline));
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(thread));
|
||||
|
||||
/*
|
||||
fprintf(stderr,"\nSWITCHING to PLAYING:\n");
|
||||
gst_element_set_state (thread, GST_STATE_PLAYING);
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(pipeline));
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(thread));
|
||||
|
||||
fprintf(stderr,"\nSWITCHING to READY:\n");
|
||||
gst_element_set_state (thread, GST_STATE_READY);
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(pipeline));
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(thread));
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ main(int argc, char *argv[])
|
|||
|
||||
gst_parse_launch (cmdline, GST_BIN (pipeline));
|
||||
|
||||
xmlSaveFile("launch.gst", gst_xml_write(GST_ELEMENT(pipeline)));
|
||||
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(pipeline));
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(gst_bin_get_by_name(pipeline,"thread0")));
|
||||
|
||||
fprintf(stderr,"RUNNING pipeline\n");
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
|
|
Loading…
Reference in a new issue