From 4dc45cf901c32817ef5a41eec28e5921b514cb19 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Thu, 16 Nov 2023 02:19:16 -0500
Subject: [PATCH] Port in Nicky's corrupt sound blacklisting

---
 indra/llaudio/llaudiodecodemgr.cpp |  8 ++++++++
 indra/llaudio/llaudioengine.cpp    | 23 +++++++++++++++++++++++
 indra/llaudio/llaudioengine.h      |  9 ++++++++-
 indra/newview/llviewermessage.cpp  |  7 +++++++
 4 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index 906f19203cf..5282900f9fc 100644
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -533,6 +533,9 @@ void LLVorbisDecodeState::flushBadFile()
 	{
 		LL_WARNS("AudioEngine") << "Flushing bad vorbis file from cache for " << mUUID << LL_ENDL;
 		mInFilep->remove();
+
+		delete mInFilep;
+		mInFilep = NULL;
 	}
 }
 
@@ -623,6 +626,9 @@ void LLAudioDecodeMgr::Impl::startMoreDecodes()
 
                 if (!decode_state)
                 {
+                    if (gAudiop)
+                        gAudiop->markSoundCorrupt(decode_id);
+
                     // Audio decode has errored
                     return decode_state;
                 }
@@ -789,6 +795,8 @@ void LLAudioDecodeMgr::processQueue()
 
 BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
 {
+	if (gAudiop && gAudiop->isCorruptSound(uuid))
+		return FALSE;
 	if (gAudiop && gAudiop->hasDecodedFile(uuid))
 	{
 		// Already have a decoded version, don't need to decode it.
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 0fa3de28008..7d647d54e41 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -642,6 +642,9 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid)
 {
 	LL_DEBUGS("AudioEngine")<<"( "<<uuid<<" )"<<LL_ENDL;
 
+	if (isCorruptSound(uuid))
+		return false;
+
 	getAudioData(uuid);	// We don't care about the return value, this is just to make sure
 									// that we have an entry, which will mean that the audio engine knows about this
 
@@ -1925,3 +1928,23 @@ bool LLAudioData::load()
 	mBufferp->mAudioDatap = this;
 	return true;
 }
+
+const U32 MAX_SOUND_RETRIES = 25;
+
+void LLAudioEngine::markSoundCorrupt(const LLUUID& sound_id)
+{
+	auto itr = mCorruptData.find(sound_id);
+	if (mCorruptData.end() == itr)
+		mCorruptData[sound_id] = 1;
+	else if (itr->second != MAX_SOUND_RETRIES)
+		itr->second += 1;
+}
+
+bool LLAudioEngine::isCorruptSound(const LLUUID& sound_id) const
+{
+	auto itr = mCorruptData.find(sound_id);
+	if (mCorruptData.end() == itr)
+		return false;
+
+	return itr->second == MAX_SOUND_RETRIES;
+}
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index d1c3dab9b3f..1f61cadb4b2 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -51,7 +51,7 @@ const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
 const F32 DEFAULT_MIN_DISTANCE = 2.0f;
 
 #define LL_MAX_AUDIO_CHANNELS 30
-#define LL_MAX_AUDIO_BUFFERS 40 // Some extra for preloading, maybe?
+#define LL_MAX_AUDIO_BUFFERS 60 // Some extra for preloading, maybe?
 
 class LLAudioSource;
 class LLAudioData;
@@ -258,6 +258,13 @@ class LLAudioEngine
 private:
 	void setDefaults();
 	LLStreamingAudioInterface *mStreamingAudioImpl;
+
+	boost::unordered_map<LLUUID,U32> mCorruptData;
+
+public:
+	void markSoundCorrupt(LLUUID const&);
+	bool isCorruptSound(LLUUID const&) const;
+
 };
 
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e3339d215b9..564c7efbb43 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4202,6 +4202,10 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
 	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id);
 	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id);
 	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id);
+
+	if (gAudiop->isCorruptSound(sound_id))
+		return;
+
 	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ParentID, parent_id);
 	msg->getU64Fast(_PREHASH_SoundData, _PREHASH_Handle, region_handle);
 	msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local);
@@ -4273,6 +4277,9 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
 	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
 	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
 
+	if (gAudiop->isCorruptSound(sound_id))
+		return;
+
 	LLViewerObject *objectp = gObjectList.findObject(object_id);
 	if (!objectp) return;
 
-- 
GitLab