From ac2135a459f65cf9fdeb7715bcc5b4a6f1c47990 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 28 Oct 2021 23:42:38 +0300
Subject: [PATCH] SL-16235 Restart music in case of an error

Additional logging
---
 indra/llaudio/llstreamingaudio_fmodstudio.cpp | 53 ++++++++++++++-----
 indra/llaudio/llstreamingaudio_fmodstudio.h   |  1 +
 indra/newview/llappviewer.cpp                 |  2 +
 indra/newview/llvieweraudio.cpp               |  5 ++
 4 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
index 08d19209aad..6439095cee7 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
@@ -63,7 +63,8 @@ LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
 mSystem(system),
 mCurrentInternetStreamp(NULL),
 mFMODInternetStreamChannelp(NULL),
-mGain(1.0f)
+mGain(1.0f),
+mRetryCount(0)
 {
     // Number of milliseconds of audio to buffer for the audio card.
     // Must be larger than the usual Second Life frame stutter time.
@@ -100,15 +101,17 @@ void LLStreamingAudio_FMODSTUDIO::start(const std::string& url)
 
     if (!url.empty())
     {
-        LL_INFOS() << "Starting internet stream: " << url << LL_ENDL;
+        LL_INFOS("FMOD") << "Starting internet stream: " << url << LL_ENDL;
         mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url);
         mURL = url;
     }
     else
     {
-        LL_INFOS() << "Set internet stream to null" << LL_ENDL;
+        LL_INFOS("FMOD") << "Set internet stream to null" << LL_ENDL;
         mURL.clear();
     }
+
+    mRetryCount = 0;
 }
 
 
@@ -121,7 +124,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
         LLAudioStreamManagerFMODSTUDIO *streamp = *iter;
         if (streamp->stopStream())
         {
-            LL_INFOS() << "Closed dead stream" << LL_ENDL;
+            LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL;
             delete streamp;
             mDeadStreams.erase(iter++);
         }
@@ -154,10 +157,33 @@ void LLStreamingAudio_FMODSTUDIO::update()
             setGain(getGain());
             mFMODInternetStreamChannelp->setPaused(false);
         }
+        mRetryCount = 0;
     }
     else if (open_state == FMOD_OPENSTATE_ERROR)
     {
-        stop();
+        LL_INFOS("FMOD") << "State: FMOD_OPENSTATE_ERROR"
+            << " Progress: " << U32(progress)
+            << " Starving: " << S32(starving)
+            << " Diskbusy: " << S32(diskbusy) << LL_ENDL;
+        if (mRetryCount < 2)
+        {
+            // Retry
+            std::string url = mURL;
+            stop(); // might drop mURL, drops mCurrentInternetStreamp
+
+            mRetryCount++;
+
+            if (!url.empty())
+            {
+                LL_INFOS("FMOD") << "Restarting internet stream: " << url  << ", attempt " << (mRetryCount + 1) << LL_ENDL;
+                mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url);
+                mURL = url;
+            }
+        }
+        else
+        {
+            stop();
+        }
         return;
     }
 
@@ -181,7 +207,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
                     {
                         if (!strcmp(tag.name, "Sample Rate Change"))
                         {
-                            LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL;
+                            LL_INFOS("FMOD") << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL;
                             mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
                         }
                         continue;
@@ -195,9 +221,9 @@ void LLStreamingAudio_FMODSTUDIO::update()
                 mFMODInternetStreamChannelp->getPaused(&paused);
                 if (!paused)
                 {
-                    LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL;
-                    LL_INFOS() << "  (diskbusy=" << diskbusy << ")" << LL_ENDL;
-                    LL_INFOS() << "  (progress=" << progress << ")" << LL_ENDL;
+                    LL_INFOS("FMOD") << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL;
+                    LL_INFOS("FMOD") << "  (diskbusy=" << diskbusy << ")" << LL_ENDL;
+                    LL_INFOS("FMOD") << "  (progress=" << progress << ")" << LL_ENDL;
                     mFMODInternetStreamChannelp->setPaused(true);
                 }
             }
@@ -220,14 +246,14 @@ void LLStreamingAudio_FMODSTUDIO::stop()
 
     if (mCurrentInternetStreamp)
     {
-        LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
+        LL_INFOS("FMOD") << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
         if (mCurrentInternetStreamp->stopStream())
         {
             delete mCurrentInternetStreamp;
         }
         else
         {
-            LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
+            LL_WARNS("FMOD") << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
             mDeadStreams.push_back(mCurrentInternetStreamp);
         }
         mCurrentInternetStreamp = NULL;
@@ -246,6 +272,7 @@ void LLStreamingAudio_FMODSTUDIO::pause(int pauseopt)
     {
         if (mCurrentInternetStreamp)
         {
+            LL_INFOS("FMOD") << "Pausing internet stream" << LL_ENDL;
             stop();
         }
     }
@@ -314,7 +341,7 @@ mReady(false)
 
     if (result != FMOD_OK)
     {
-        LL_WARNS() << "Couldn't open fmod stream, error "
+        LL_WARNS("FMOD") << "Couldn't open fmod stream, error "
             << FMOD_ErrorString(result)
             << LL_ENDL;
         mReady = false;
@@ -329,7 +356,7 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
     // We need a live and opened stream before we try and play it.
     if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY)
     {
-        LL_WARNS() << "No internet stream to start playing!" << LL_ENDL;
+        LL_WARNS("FMOD") << "No internet stream to start playing!" << LL_ENDL;
         return NULL;
     }
 
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h
index 1fc3c54d79b..ea451bc9b55 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.h
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.h
@@ -67,6 +67,7 @@ class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface
 
     std::string mURL;
     F32 mGain;
+    S32 mRetryCount;
 };
 
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3ce325cd4b9..c4ba7540842 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1841,6 +1841,8 @@ bool LLAppViewer::cleanup()
 
 	if (gAudiop)
 	{
+        LL_INFOS() << "Shutting down audio" << LL_ENDL;
+
         // be sure to stop the internet stream cleanly BEFORE destroying the interface to stop it.
         gAudiop->stopInternetStream();
         // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index f97ba0930e2..f810e5f4ef6 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -83,6 +83,8 @@ void LLViewerAudio::registerIdleListener()
 
 void LLViewerAudio::startInternetStreamWithAutoFade(const std::string &streamURI)
 {
+    LL_DEBUGS("AudioEngine") << "Start with outo fade: " << streamURI << LL_ENDL;
+
 	// Old and new stream are identical
 	if (mNextStreamURI == streamURI)
 	{
@@ -166,6 +168,7 @@ bool LLViewerAudio::onIdleUpdate()
 			if (gAudiop)
 			{
 				// Clear URI
+                LL_DEBUGS("AudioEngine") << "Done with audio fade" << LL_ENDL;
 				gAudiop->startInternetStream(LLStringUtil::null);
 				gAudiop->stopInternetStream();
 			}
@@ -176,6 +179,7 @@ bool LLViewerAudio::onIdleUpdate()
 
 				if (gAudiop)
 				{
+                    LL_DEBUGS("AudioEngine") << "Audio fade in: " << mNextStreamURI << LL_ENDL;
 					LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl();
 					if(stream && stream->supportsAdjustableBufferSizes())
 						stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize"));
@@ -219,6 +223,7 @@ void LLViewerAudio::stopInternetStreamWithAutoFade()
 	
 	if (gAudiop)
 	{
+        LL_DEBUGS("AudioEngine") << "Stop audio fade" << LL_ENDL;
 		gAudiop->startInternetStream(LLStringUtil::null);
 		gAudiop->stopInternetStream();
 	}
-- 
GitLab