diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index 480b3934c3..cc60417982 100644
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -645,6 +645,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path);
if (!mCurrentDecodep->initDecode())
{
+ gAudiop->markSoundCorrupt( uuid );
mCurrentDecodep = NULL;
}
}
@@ -671,6 +672,11 @@ void LLAudioDecodeMgr::processQueue(const F32 num_secs)
BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
{
+ // Protect against corrupted sounds. Just do a quit exit instead of trying to decode over and over.
+ if( gAudiop->isCorruptSound( uuid ) )
+ return FALSE;
+ //
+
if (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 f89b61c30f..aef5bb3f1e 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -676,6 +676,11 @@ void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
bool LLAudioEngine::preloadSound(const LLUUID &uuid)
{
+ // Protect against corrupted sounds. Just do a quick exit instead of trying to preload over and over again.
+ if( gAudiop->isCorruptSound( uuid ) )
+ return false;
+ //
+
gAudiop->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
@@ -955,6 +960,11 @@ LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id)
LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid)
{
+ // Protect against corrupted sounds. Just do a quick exit instead of trying to decode over and over again.
+ if( isCorruptSound( audio_uuid ) )
+ return 0;
+ //
+
data_map::iterator iter;
iter = mAllData.find(audio_uuid);
if (iter == mAllData.end())
@@ -1292,61 +1302,73 @@ std::map gSoundHistory;
// static
void LLAudioSource::logSoundPlay(LLUUID id, LLAudioSource* audio_source, LLVector3d position, S32 type, LLUUID assetid, LLUUID ownerid, LLUUID sourceid, bool is_trigger, bool is_looped)
{
- LLSoundHistoryItem item;
- item.mID = id;
- item.mAudioSource = audio_source;
- item.mPosition = position;
- item.mType = type;
- item.mAssetID = assetid;
- item.mOwnerID = ownerid;
- item.mSourceID = sourceid;
- item.mPlaying = true;
- item.mTimeStarted = LLTimer::getElapsedSeconds();
- item.mTimeStopped = F64_MAX;
- item.mIsTrigger = is_trigger;
- item.mIsLooped = is_looped;
+ // Corrupt asset, do not bother
+ if( gAudiop->isCorruptSound( assetid ) )
+ return;
+ //
- item.mReviewed = false;
- item.mReviewedCollision = false;
+ // Do not overflow our log here.
+ if( gSoundHistory.size() > 2048 )
+ pruneSoundLog();
+ if( gSoundHistory.size() > 2048 )
+ return; // Might clear out oldest entries before giving up?
+ //
- gSoundHistory[id] = item;
+ LLSoundHistoryItem item;
+ item.mID = id;
+ item.mAudioSource = audio_source;
+ item.mPosition = position;
+ item.mType = type;
+ item.mAssetID = assetid;
+ item.mOwnerID = ownerid;
+ item.mSourceID = sourceid;
+ item.mPlaying = true;
+ item.mTimeStarted = LLTimer::getElapsedSeconds();
+ item.mTimeStopped = F64_MAX;
+ item.mIsTrigger = is_trigger;
+ item.mIsLooped = is_looped;
+
+ item.mReviewed = false;
+ item.mReviewedCollision = false;
+
+ gSoundHistory[id] = item;
}
// static
void LLAudioSource::logSoundStop(LLUUID id)
{
- if(gSoundHistory.find(id) != gSoundHistory.end())
- {
- gSoundHistory[id].mPlaying = false;
- gSoundHistory[id].mTimeStopped = LLTimer::getElapsedSeconds();
- gSoundHistory[id].mAudioSource = NULL; // just in case
- pruneSoundLog();
- }
+ if(gSoundHistory.find(id) != gSoundHistory.end())
+ {
+ gSoundHistory[id].mPlaying = false;
+ gSoundHistory[id].mTimeStopped = LLTimer::getElapsedSeconds();
+ gSoundHistory[id].mAudioSource = NULL; // just in case
+ pruneSoundLog();
+ }
}
// static
void LLAudioSource::pruneSoundLog()
{
- if(++gSoundHistoryPruneCounter >= 64)
- {
- gSoundHistoryPruneCounter = 0;
- while(gSoundHistory.size() > 256)
- {
- std::map::iterator iter = gSoundHistory.begin();
- std::map::iterator end = gSoundHistory.end();
- U64 lowest_time = (*iter).second.mTimeStopped;
- LLUUID lowest_id = (*iter).first;
- for( ; iter != end; ++iter)
- {
- if((*iter).second.mTimeStopped < lowest_time)
- {
- lowest_time = (*iter).second.mTimeStopped;
- lowest_id = (*iter).first;
- }
- }
- gSoundHistory.erase(lowest_id);
- }
- }
+ if(++gSoundHistoryPruneCounter >= 64)
+ {
+ gSoundHistoryPruneCounter = 0;
+ while(gSoundHistory.size() > 256)
+ {
+ std::map::iterator iter = gSoundHistory.begin();
+ std::map::iterator end = gSoundHistory.end();
+ U64 lowest_time = (*iter).second.mTimeStopped;
+ LLUUID lowest_id = (*iter).first;
+ for( ; iter != end; ++iter)
+ {
+ if((*iter).second.mTimeStopped < lowest_time)
+ {
+ lowest_time = (*iter).second.mTimeStopped;
+ lowest_id = (*iter).first;
+ }
+ }
+ gSoundHistory.erase(lowest_id);
+ }
+ }
}
// NaCl End
@@ -1399,6 +1421,7 @@ void LLAudioSource::update()
{
llwarns << "Marking LLAudioSource corrupted for " << adp->getID() << llendl;
mCorrupted = true ;
+ gAudiop->markSoundCorrupt( adp->getID() );
}
}
}
@@ -1488,6 +1511,8 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
mAgeTimer.reset();
LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
+ if( !adp )
+ return false;
addAudioData(adp);
if (isMuted())
@@ -1879,3 +1904,26 @@ bool LLAudioData::load()
mBufferp->mAudioDatap = this;
return true;
}
+
+// Protect against corrupted sounds
+
+const U32 ND_MAX_SOUNDRETRIES = 25;
+
+void LLAudioEngine::markSoundCorrupt( LLUUID const &aId )
+{
+ std::map::iterator itr = mCorruptData.find( aId );
+ if( mCorruptData.end() == itr )
+ mCorruptData[ aId ] = 1;
+ else if( itr->second != ND_MAX_SOUNDRETRIES )
+ itr->second += 1;
+}
+
+bool LLAudioEngine::isCorruptSound( LLUUID const &aId ) const
+{
+ std::map::const_iterator itr = mCorruptData.find( aId );
+ if( mCorruptData.end() == itr )
+ return false;
+
+ return itr->second == ND_MAX_SOUNDRETRIES;
+}
+//
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index b03e27aff3..b1117a9c47 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -253,6 +253,16 @@ protected:
private:
void setDefaults();
LLStreamingAudioInterface *mStreamingAudioImpl;
+
+ // Protect against corrupted sounds
+
+ std::map mCorruptData;
+
+public:
+ void markSoundCorrupt( LLUUID const & );
+ bool isCorruptSound( LLUUID const& ) const;
+
+ //
};
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp
index 0c2d4b823d..f199eb602f 100644
--- a/indra/llmessage/llcircuit.cpp
+++ b/indra/llmessage/llcircuit.cpp
@@ -120,6 +120,11 @@ LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id,
mPeriodTime = mt_sec;
mLocalEndPointID.generate();
+
+ // Throttle to prevent log spam.
+ mLastPacketLog = 0;
+ mLogMessagesSkipped = 0;
+ //
}
@@ -750,7 +755,22 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
}
else
{
- llinfos << "packet_out_of_order - got packet " << id << " expecting " << index << " from " << mHost << llendl;
+ // Throttle to prevent log spam.
+
+ // llinfos << "packet_out_of_order - got packet " << id << " expecting " << index << " from " << mHost << llendl;
+
+ if( (LLTimer::getTotalSeconds() - mLastPacketLog ) > 15 )
+ {
+ llinfos << "packet_out_of_order - got packet " << id << " expecting " << index << " from " << mHost << llendl;
+ llinfos << mLogMessagesSkipped << " since last log entry" << llendl;
+ mLastPacketLog = LLTimer::getTotalSeconds();
+ mLogMessagesSkipped = 0;
+ }
+ else
+ ++mLogMessagesSkipped;
+
+ //
+
if(gMessageSystem->mVerboseLog)
{
std::ostringstream str;
diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h
index 430d6358f7..11ce777656 100644
--- a/indra/llmessage/llcircuit.h
+++ b/indra/llmessage/llcircuit.h
@@ -276,6 +276,11 @@ protected:
const F32 mHeartbeatInterval;
const F32 mHeartbeatTimeout;
+
+ // Throttle to prevent log spam.
+ F64 mLastPacketLog;
+ U32 mLogMessagesSkipped;
+ //
};
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 5ecef9c004..0787535866 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5466,6 +5466,11 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id);
msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id);
+ // Protect against corrupted sounds
+ if( gAudiop->isCorruptSound( sound_id ) )
+ return;
+ //
+
if(FSWSAssetBlacklist::getInstance()->isBlacklisted(sound_id,LLAssetType::AT_SOUND)){
return;
}
@@ -5579,6 +5584,11 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
return;
// NaCl End
+ // Protect against corrupted sounds
+ if( gAudiop->isCorruptSound( sound_id ) )
+ return;
+ //
+
LLViewerObject *objectp = gObjectList.findObject(object_id);
if (!objectp) return;