From 02d3438bc2f305fca699d14bfcc403f092b1fea1 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 7 Nov 2006 19:35:46 +0000 Subject: [PATCH] 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 --- .../playlistExecutor/src/GstreamerPlayer.cxx | 24 ++++++++++++++----- .../playlistExecutor/src/GstreamerPlayer.h | 4 ++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx index 268bd18d3..dae30712b 100644 --- a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx +++ b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx @@ -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(); diff --git a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h index 8bd870a2f..579c25912 100644 --- a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h +++ b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h @@ -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: