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:
parent
a94d747628
commit
02d3438bc2
|
@ -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();
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue