Fix GStreamer warnings that would sometime occur on trackend. The root of this problem was a rather rather serious bug in the player: In some cases we called other methods from inside of the EOS handler, which would modify the pipeline, start new tracks, etc. I have fixed this problem by using an idle function, so that the calls are relayed via the event loop.

Please note: The new code causes some tests to fail. This is *not* a bug in the player, but in fact a known problem with the testrunner.

Fixes #1941
This commit is contained in:
mark 2006-11-07 19:35:46 +00:00
parent a94d747628
commit 02d3438bc2
2 changed files with 20 additions and 8 deletions

View File

@ -210,16 +210,23 @@ GstreamerPlayer :: detachListener(AudioPlayerEventListener* eventListener)
/*------------------------------------------------------------------------------
* Send the onStop event to all attached listeners.
*----------------------------------------------------------------------------*/
void
GstreamerPlayer :: fireOnStopEvent(void) throw ()
gboolean
GstreamerPlayer :: fireOnStopEvent(gpointer self) throw ()
{
ListenerVector::iterator it = listeners.begin();
ListenerVector::iterator end = listeners.end();
DEBUG_BLOCK
GstreamerPlayer * player = (GstreamerPlayer*) self;
ListenerVector::iterator it = player->listeners.begin();
ListenerVector::iterator end = player->listeners.end();
while (it != end) {
(*it)->onStop();
++it;
}
// false == Don't call this idle function again
return false;
}
@ -231,10 +238,15 @@ GstreamerPlayer :: eosEventHandler(GstElement * element,
gpointer self)
throw ()
{
DEBUG_BLOCK
GstreamerPlayer * player = (GstreamerPlayer*) self;
gst_element_set_eos(player->pipeline);
player->fireOnStopEvent();
// Important: We *must* use an idle function call here, so that the signal handler returns
// before fireOnStopEvent() is executed.
g_idle_add(fireOnStopEvent, player);
}
@ -470,7 +482,7 @@ GstreamerPlayer :: stop(void) throw (std::logic_error)
void
GstreamerPlayer :: close(void) throw (std::logic_error)
{
DEBUG_FUNC_INFO
DEBUG_BLOCK
if (isPlaying()) {
stop();

View File

@ -202,8 +202,8 @@ class GstreamerPlayer : virtual public Configurable,
/**
* Send the onStop event to all attached listeners.
*/
virtual void
fireOnStopEvent(void) throw ();
static gboolean
fireOnStopEvent(gpointer self) throw ();
public: