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;