fixed crashes when files are missing. all player errors are now considered as non critical so that app can survive and deliver uninterrupted programming

This commit is contained in:
nebojsa 2009-09-22 23:44:24 +00:00
parent cb32ca774e
commit 2b4ce13d7e
7 changed files with 45 additions and 33 deletions

View file

@ -152,7 +152,7 @@ class AudioPlayerInterface
* @see #close * @see #close
* @see #start * @see #start
*/ */
virtual void virtual bool
open(const std::string fileUrl) throw (std::invalid_argument, open(const std::string fileUrl) throw (std::invalid_argument,
std::runtime_error) std::runtime_error)
= 0; = 0;

View file

@ -131,7 +131,7 @@ public:
delete m_audioDescription; delete m_audioDescription;
m_audioDescription = NULL; m_audioDescription = NULL;
} }
} }
void playContext(){ void playContext(){
gst_element_set_state (m_pipeline, GST_STATE_PLAYING); gst_element_set_state (m_pipeline, GST_STATE_PLAYING);
@ -151,6 +151,13 @@ public:
void setParentData(gpointer data){ void setParentData(gpointer data){
m_data = 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. * Set the audio device.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
@ -338,7 +345,6 @@ private:
if(m_audioDescription && m_audioDescription->m_animations.size() > 0){ if(m_audioDescription && m_audioDescription->m_animations.size() > 0){
m_ctrl = gst_controller_new (G_OBJECT (m_volume), "volume", NULL); m_ctrl = gst_controller_new (G_OBJECT (m_volume), "volume", NULL);
if (m_ctrl == NULL) { if (m_ctrl == NULL) {
std::cout << "prepareAnimations: element not controllable!" << std::endl;
return false; return false;
} }
GValue vol = { 0, }; GValue vol = { 0, };

View file

@ -72,31 +72,16 @@ static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data
GstreamerPlayer* const player = (GstreamerPlayer*) data; GstreamerPlayer* const player = (GstreamerPlayer*) data;
switch (GST_MESSAGE_TYPE (message)) { 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_EOS:
case GST_MESSAGE_ERROR:
if(player->playNextSmil()){ if(player->playNextSmil()){
break; break;
} }
player->close(); player->close();
// Important: We *must* use an idle function call here, so that the signal handler returns // Important: We *must* use an idle function call here, so that the signal handler returns
// before fireOnStopEvent() is executed. // before fireOnStopEvent() is executed.
g_idle_add(GstreamerPlayer::fireOnStopEvent, data); 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);
}
break; break;
} }
} }
@ -245,7 +230,7 @@ GstreamerPlayer :: preload(const std::string fileUrl)
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Specify which file to play * Specify which file to play
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void bool
GstreamerPlayer :: open(const std::string fileUri) GstreamerPlayer :: open(const std::string fileUri)
throw (std::invalid_argument, throw (std::invalid_argument,
std::runtime_error) std::runtime_error)
@ -275,16 +260,23 @@ GstreamerPlayer :: open(const std::string fileUri)
} }
if(!m_open){ if(!m_open){
m_errorMessage.reset(new const Glib::ustring("GstreamerPlayer :: open failed! Please consult console output for details.")); close();
m_errorWasRaised = true; deInitialize();
fireOnStopEvent(this); initialize();
m_playContext->forceEOS();
return false;
} }
return true;
} }
bool bool
GstreamerPlayer :: playNextSmil(void) throw () GstreamerPlayer :: playNextSmil(void) throw ()
{ {
DEBUG_BLOCK DEBUG_BLOCK
if(NULL == m_playContext)
{
return false;
}
m_currentPlayLength = m_playContext->getPosition();//this gets the length of the stream that just completed m_currentPlayLength = m_playContext->getPosition();//this gets the length of the stream that just completed
m_playContext->closeContext(); m_playContext->closeContext();
if(m_smilHandler == NULL){ if(m_smilHandler == NULL){
@ -297,7 +289,13 @@ GstreamerPlayer :: playNextSmil(void) throw (
return false; return false;
} }
if(!m_playContext->openSource(audioDescription)){ 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_smilOffset += m_currentPlayLength;
m_playContext->playContext(); m_playContext->playContext();

View file

@ -285,7 +285,7 @@ public:
* @see #close * @see #close
* @see #start * @see #start
*/ */
virtual void virtual bool
open(const std::string fileUrl) throw (std::invalid_argument, open(const std::string fileUrl) throw (std::invalid_argument,
std::runtime_error); std::runtime_error);

View file

@ -1288,7 +1288,7 @@ GLiveSupport :: preload(Ptr<const Playable>::Ref playable)
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Play a Playable object using the output audio player. * Play a Playable object using the output audio player.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void bool
LiveSupport :: GLiveSupport :: LiveSupport :: GLiveSupport ::
GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable) GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
throw (std::logic_error, throw (std::logic_error,
@ -1298,7 +1298,10 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
switch (playable->getType()) { switch (playable->getType()) {
case Playable::AudioClipType: case Playable::AudioClipType:
outputItemPlayingNow = acquireAudioClip(playable->getId()); outputItemPlayingNow = acquireAudioClip(playable->getId());
outputPlayer->open(*outputItemPlayingNow->getUri()); if(false == outputPlayer->open(*outputItemPlayingNow->getUri()))
{
return false;
}
outputPlayer->start(); outputPlayer->start();
std::cerr << "gLiveSupport: Live Mode playing audio clip '" std::cerr << "gLiveSupport: Live Mode playing audio clip '"
<< *playable->getTitle() << *playable->getTitle()
@ -1341,6 +1344,7 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
} }
outputPlayerIsPaused = false; outputPlayerIsPaused = false;
return true;
} }

View file

@ -990,7 +990,7 @@ class GLiveSupport : public LocalizedConfigurable,
* @exception std::logic_error in case of audio player errors. * @exception std::logic_error in case of audio player errors.
* @exception std::runtime_error in case of audio player errors. * @exception std::runtime_error in case of audio player errors.
*/ */
virtual void virtual bool
playOutputAudio(Ptr<Playable>::Ref playable) playOutputAudio(Ptr<Playable>::Ref playable)
throw (std::logic_error, throw (std::logic_error,
std::runtime_error); std::runtime_error);

View file

@ -411,7 +411,11 @@ LiveModeWindow :: onOutputPlay(void) throw ()
if (playable) { if (playable) {
try { try {
gLiveSupport->playOutputAudio(playable); if(false == gLiveSupport->playOutputAudio(playable))
{
treeView->removeItem(itemPlayed);
return;
}
gLiveSupport->setNowPlaying(playable); gLiveSupport->setNowPlaying(playable);
treeView->removeItem(itemPlayed); treeView->removeItem(itemPlayed);