From 2b4ce13d7ed64907e56ef26ff89b75dc218fc4b7 Mon Sep 17 00:00:00 2001 From: nebojsa Date: Tue, 22 Sep 2009 23:44:24 +0000 Subject: [PATCH] fixed crashes when files are missing. all player errors are now considered as non critical so that app can survive and deliver uninterrupted programming --- .../PlaylistExecutor/AudioPlayerInterface.h | 2 +- .../src/GstreamerPlayContext.h | 10 +++- .../playlistExecutor/src/GstreamerPlayer.cxx | 48 +++++++++---------- .../playlistExecutor/src/GstreamerPlayer.h | 2 +- .../gLiveSupport/src/GLiveSupport.cxx | 8 +++- .../products/gLiveSupport/src/GLiveSupport.h | 2 +- .../gLiveSupport/src/LiveModeWindow.cxx | 6 ++- 7 files changed, 45 insertions(+), 33 deletions(-) diff --git a/campcaster/src/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h b/campcaster/src/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h index 19aa52fc3..9ecac3c39 100644 --- a/campcaster/src/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h +++ b/campcaster/src/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h @@ -152,7 +152,7 @@ class AudioPlayerInterface * @see #close * @see #start */ - virtual void + virtual bool open(const std::string fileUrl) throw (std::invalid_argument, std::runtime_error) = 0; diff --git a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h index 8b88047e6..4cab1b37d 100644 --- a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h +++ b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h @@ -131,7 +131,7 @@ public: delete m_audioDescription; m_audioDescription = NULL; } - } + } void playContext(){ gst_element_set_state (m_pipeline, GST_STATE_PLAYING); @@ -151,6 +151,13 @@ public: void setParentData(gpointer data){ m_data = data; } + + void forceEOS(){ + GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline)); + gst_bus_post (bus, gst_message_new_eos(GST_OBJECT(m_sink))); + gst_object_unref (bus); + } + /*------------------------------------------------------------------------------ * Set the audio device. *----------------------------------------------------------------------------*/ @@ -338,7 +345,6 @@ private: if(m_audioDescription && m_audioDescription->m_animations.size() > 0){ m_ctrl = gst_controller_new (G_OBJECT (m_volume), "volume", NULL); if (m_ctrl == NULL) { - std::cout << "prepareAnimations: element not controllable!" << std::endl; return false; } GValue vol = { 0, }; diff --git a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx index 09174593f..c9be5c8c8 100644 --- a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx +++ b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.cxx @@ -72,31 +72,16 @@ static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data GstreamerPlayer* const player = (GstreamerPlayer*) data; switch (GST_MESSAGE_TYPE (message)) { + //we shall handle errors as non critical events as we should not stop playback in any case case GST_MESSAGE_EOS: + case GST_MESSAGE_ERROR: if(player->playNextSmil()){ break; } player->close(); - // Important: We *must* use an idle function call here, so that the signal handler returns - // before fireOnStopEvent() is executed. - g_idle_add(GstreamerPlayer::fireOnStopEvent, data); - break; - case GST_MESSAGE_ERROR: - // We make sure that we don't send multiple error messages in a row to the GUI - if (!player->m_errorWasRaised) { - GError *gerror; - gchar *debug; - gst_message_parse_error (message, &gerror, &debug); - player->m_errorMessage.reset(new const Glib::ustring(gerror->message)); - player->m_errorWasRaised = true; - - std::cerr << "gstreamer error: " << gerror->message << std::endl; - g_error_free (gerror); - g_free (debug); - // Important: We *must* use an idle function call here, so that the signal handler returns - // before fireOnStopEvent() is executed. - g_idle_add(GstreamerPlayer::fireOnStopEvent, data); - } + // Important: We *must* use an idle function call here, so that the signal handler returns + // before fireOnStopEvent() is executed. + g_idle_add(GstreamerPlayer::fireOnStopEvent, data); break; } } @@ -245,7 +230,7 @@ GstreamerPlayer :: preload(const std::string fileUrl) /*------------------------------------------------------------------------------ * Specify which file to play *----------------------------------------------------------------------------*/ -void +bool GstreamerPlayer :: open(const std::string fileUri) throw (std::invalid_argument, std::runtime_error) @@ -275,16 +260,23 @@ GstreamerPlayer :: open(const std::string fileUri) } if(!m_open){ - m_errorMessage.reset(new const Glib::ustring("GstreamerPlayer :: open failed! Please consult console output for details.")); - m_errorWasRaised = true; - fireOnStopEvent(this); + close(); + deInitialize(); + initialize(); + m_playContext->forceEOS(); + return false; } + return true; } bool GstreamerPlayer :: playNextSmil(void) throw () { DEBUG_BLOCK + if(NULL == m_playContext) + { + return false; + } m_currentPlayLength = m_playContext->getPosition();//this gets the length of the stream that just completed m_playContext->closeContext(); if(m_smilHandler == NULL){ @@ -297,7 +289,13 @@ GstreamerPlayer :: playNextSmil(void) throw ( return false; } if(!m_playContext->openSource(audioDescription)){ - return false; + m_playContext->stopContext(); + m_playContext->closeContext(); + m_open = false; + deInitialize(); + initialize(); + m_playContext->forceEOS(); + return true; } m_smilOffset += m_currentPlayLength; m_playContext->playContext(); diff --git a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h index 6b0e49d43..d0d607f90 100644 --- a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h +++ b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayer.h @@ -285,7 +285,7 @@ public: * @see #close * @see #start */ - virtual void + virtual bool open(const std::string fileUrl) throw (std::invalid_argument, std::runtime_error); diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx index bfe0a669b..4188ae0c7 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx @@ -1288,7 +1288,7 @@ GLiveSupport :: preload(Ptr::Ref playable) /*------------------------------------------------------------------------------ * Play a Playable object using the output audio player. *----------------------------------------------------------------------------*/ -void +bool LiveSupport :: GLiveSupport :: GLiveSupport :: playOutputAudio(Ptr::Ref playable) throw (std::logic_error, @@ -1298,7 +1298,10 @@ GLiveSupport :: playOutputAudio(Ptr::Ref playable) switch (playable->getType()) { case Playable::AudioClipType: outputItemPlayingNow = acquireAudioClip(playable->getId()); - outputPlayer->open(*outputItemPlayingNow->getUri()); + if(false == outputPlayer->open(*outputItemPlayingNow->getUri())) + { + return false; + } outputPlayer->start(); std::cerr << "gLiveSupport: Live Mode playing audio clip '" << *playable->getTitle() @@ -1341,6 +1344,7 @@ GLiveSupport :: playOutputAudio(Ptr::Ref playable) } outputPlayerIsPaused = false; + return true; } diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h index 64d59ad58..ab5972593 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h @@ -990,7 +990,7 @@ class GLiveSupport : public LocalizedConfigurable, * @exception std::logic_error in case of audio player errors. * @exception std::runtime_error in case of audio player errors. */ - virtual void + virtual bool playOutputAudio(Ptr::Ref playable) throw (std::logic_error, std::runtime_error); diff --git a/campcaster/src/products/gLiveSupport/src/LiveModeWindow.cxx b/campcaster/src/products/gLiveSupport/src/LiveModeWindow.cxx index cb42346bd..6d8a7effd 100644 --- a/campcaster/src/products/gLiveSupport/src/LiveModeWindow.cxx +++ b/campcaster/src/products/gLiveSupport/src/LiveModeWindow.cxx @@ -411,7 +411,11 @@ LiveModeWindow :: onOutputPlay(void) throw () if (playable) { try { - gLiveSupport->playOutputAudio(playable); + if(false == gLiveSupport->playOutputAudio(playable)) + { + treeView->removeItem(itemPlayed); + return; + } gLiveSupport->setNowPlaying(playable); treeView->removeItem(itemPlayed);