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. * Send the onStop event to all attached listeners.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void gboolean
GstreamerPlayer :: fireOnStopEvent(void) throw () GstreamerPlayer :: fireOnStopEvent(gpointer self) throw ()
{ {
ListenerVector::iterator it = listeners.begin(); DEBUG_BLOCK
ListenerVector::iterator end = listeners.end();
GstreamerPlayer * player = (GstreamerPlayer*) self;
ListenerVector::iterator it = player->listeners.begin();
ListenerVector::iterator end = player->listeners.end();
while (it != end) { while (it != end) {
(*it)->onStop(); (*it)->onStop();
++it; ++it;
} }
// false == Don't call this idle function again
return false;
} }
@ -231,10 +238,15 @@ GstreamerPlayer :: eosEventHandler(GstElement * element,
gpointer self) gpointer self)
throw () throw ()
{ {
DEBUG_BLOCK
GstreamerPlayer * player = (GstreamerPlayer*) self; GstreamerPlayer * player = (GstreamerPlayer*) self;
gst_element_set_eos(player->pipeline); 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 void
GstreamerPlayer :: close(void) throw (std::logic_error) GstreamerPlayer :: close(void) throw (std::logic_error)
{ {
DEBUG_FUNC_INFO DEBUG_BLOCK
if (isPlaying()) { if (isPlaying()) {
stop(); stop();

View File

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