From 10fe67f4a6f167d2f3a3f56551a56da3f8c5b5aa Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 15 Jul 2012 16:41:31 -0500 Subject: [PATCH 1/5] FBO tweaks. Release multisample fbo in LLPipeline::releaseScreenBuffers, and fixed LLRenderBuffer::mInternalFormat falling out of sync with LLRenderBuffer::mTex. --- indra/llrender/llrendertarget.cpp | 1 + indra/newview/pipeline.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 6ea20e977..ceb865ad1 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -793,6 +793,7 @@ bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt) } mTex.push_back(tex); + mInternalFormat.push_back(color_fmt); return true; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index bd2424294..f71adc331 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -693,6 +693,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } mSampleBuffer.release(); + mScreen.release(); if (LLPipeline::sRenderDeferred) { @@ -906,6 +907,8 @@ void LLPipeline::releaseScreenBuffers() { mShadow[i].release(); } + + mSampleBuffer.release(); } From 46f7250f087645eb6ea1a1f32213f21ba283dcc5 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 15 Jul 2012 21:12:31 -0500 Subject: [PATCH 2/5] Fixup multisample rbos. Samplecount validation all done in LLMultisampleBuffer::allocate, and falls back to non-multisample safely if multisampled rbos cannot/shouldn't be used. --- indra/llrender/llgl.cpp | 38 ++----------------------- indra/llrender/llgl.h | 5 ---- indra/llrender/llrendertarget.cpp | 44 +++++++++++++++++------------ indra/newview/llviewershadermgr.cpp | 2 +- indra/newview/pipeline.cpp | 7 ----- 5 files changed, 29 insertions(+), 67 deletions(-) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 92d095b80..cf287f98c 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -435,11 +435,7 @@ LLGLManager::LLGLManager() : mHasPointParameters(FALSE), mHasDrawBuffers(FALSE), mHasTextureRectangle(FALSE), - mHasTextureMultisample(FALSE), mHasTransformFeedback(FALSE), - mMaxSampleMaskWords(0), - mMaxColorTextureSamples(0), - mMaxDepthTextureSamples(0), mMaxIntegerSamples(0), mHasAnisotropic(FALSE), @@ -732,12 +728,10 @@ bool LLGLManager::initGL() stop_glerror(); - if (mHasTextureMultisample) + if (mHasFramebufferMultisample) { - glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); - glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); - glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); + glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); } stop_glerror(); @@ -749,24 +743,12 @@ bool LLGLManager::initGL() } #endif stop_glerror(); - mHasTextureMultisample = FALSE; -#if LL_WINDOWS - if (mIsATI) - { //using multisample textures on ATI results in black screen for some reason - mHasTextureMultisample = FALSE; - } -#endif if (mIsIntel && mGLVersion <= 3.f) { //never try to use framebuffer objects on older intel drivers (crashy) mHasFramebufferObject = FALSE; } - if (mHasFramebufferObject) - { - glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); - } - stop_glerror(); setToDebugGPU(); @@ -847,14 +829,6 @@ std::string LLGLManager::getRawGLString() return gl_string; } -U32 LLGLManager::getNumFBOFSAASamples(U32 samples) -{ - samples = llmin(samples, (U32) mMaxColorTextureSamples); - samples = llmin(samples, (U32) mMaxDepthTextureSamples); - samples = llmin(samples, (U32) 4); - return samples; -} - void LLGLManager::shutdownGL() { if (mInited) @@ -960,7 +934,6 @@ void LLGLManager::initExtensions() mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); - mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts); mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts); mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE; #if !LL_DARWIN @@ -1198,13 +1171,6 @@ void LLGLManager::initExtensions() { glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT"); } - if (mHasTextureMultisample) - { - glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample"); - glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample"); - glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv"); - glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski"); - } if (mHasTransformFeedback) { glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback"); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index c7e58aff9..f877834e9 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -104,11 +104,7 @@ public: BOOL mHasDrawBuffers; BOOL mHasDepthClamp; BOOL mHasTextureRectangle; - BOOL mHasTextureMultisample; BOOL mHasTransformFeedback; - S32 mMaxSampleMaskWords; - S32 mMaxColorTextureSamples; - S32 mMaxDepthTextureSamples; S32 mMaxIntegerSamples; // Other extensions. @@ -155,7 +151,6 @@ public: void printGLInfoString(); void getGLInfo(LLSD& info); - U32 getNumFBOFSAASamples(U32 desired_samples = 32); // In ALL CAPS std::string mGLVendor; std::string mGLVendorShort; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index ceb865ad1..589c0dc0d 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -699,6 +699,28 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth release(); stop_glerror(); + if (!gGLManager.mHasFramebufferMultisample || !gGLManager.mHasFramebufferObject || !(sUseFBO || use_fbo)) + return false; + + if(color_fmt != GL_RGBA) + { + llwarns << "Unsupported color format: " << color_fmt << llendl; + return false; + } + + //Restrict to valid sample count + { + mSamples = samples; + mSamples = llmin(mSamples, (U32)4); //Cap to prevent memory bloat. + mSamples = llmin(mSamples, (U32) gGLManager.mMaxIntegerSamples);//GL_RGBA + + if(depth && !stencil) + mSamples = llmin(mSamples, (U32) gGLManager.mMaxSamples); //GL_DEPTH_COMPONENT16_ARB + } + + if (mSamples <= 1) + return false; + mResX = resx; mResY = resy; @@ -706,30 +728,16 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth mUseDepth = depth; mStencil = stencil; - if (!gGLManager.mHasFramebufferMultisample) - { - llerrs << "Attempting to allocate unsupported render target type!" << llendl; - return false; - } - - mSamples = gGLManager.getNumFBOFSAASamples(samples); - - if (mSamples <= 1) - { - llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; - return false; - } - - stop_glerror(); - - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) { if (depth) { stop_glerror(); if(!allocateDepth()) + { + release(); return false; + } stop_glerror(); } glGenFramebuffers(1, (GLuint *) &mFBO); @@ -779,6 +787,7 @@ bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt) if (glGetError() != GL_NO_ERROR) { llwarns << "Unable to allocate color buffer for multisample render target." << llendl; + release(); return false; } @@ -793,7 +802,6 @@ bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt) } mTex.push_back(tex); - mInternalFormat.push_back(color_fmt); return true; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 0eb0b3cc2..6ab2cfd17 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -343,7 +343,7 @@ void LLViewerShaderMgr::setShaders() //setup preprocessor definitions LLShaderMgr::instance()->mDefinitions.clear(); - LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gSavedSettings.getU32("RenderFSAASamples")/*gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"))*/); + LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gSavedSettings.getU32("RenderFSAASamples")); LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits); initAttribsAndUniforms(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f71adc331..27632dcfc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -632,12 +632,6 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) static const LLCachedControl RenderFSAASamples("RenderFSAASamples",0); U32 samples = RenderFSAASamples.get() - RenderFSAASamples.get() % 2; //Must be multipe of 2. - //Don't multisample if not using FXAA, or if fbos are disabled, or if multisampled fbos are not supported. - if(!LLPipeline::sRenderDeferred && (!LLRenderTarget::sUseFBO || !gGLManager.mHasFramebufferMultisample)) - { - samples = 0; - } - //try to allocate screen buffers at requested resolution and samples // - on failure, shrink number of samples and try again // - if not multisampled, shrink resolution and try again (favor X resolution over Y) @@ -791,7 +785,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; if(samples > 1) { - if(mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples)) mScreen.setSampleBuffer(&mSampleBuffer); else From 3cee90fe8b721bb88360ea1df9e763ab48ec7d3b Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 16 Jul 2012 01:00:55 -0500 Subject: [PATCH 3/5] Lets not call glDeleteTextures any more, since the glGenTextures/glDeleteTextures paradigm has gone away. --- indra/llrender/llimagegl.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 1e698adfc..6d7054e7e 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -330,7 +330,6 @@ S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 categ //static void LLImageGL::destroyGL(BOOL save_state) { - deleteDeadTextures(); //Dump unimportant textures. for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++) { gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); @@ -364,7 +363,6 @@ void LLImageGL::destroyGL(BOOL save_state) } llinfos << "Storing " << stored_count << " images..." << llendl; sAllowReadBackRaw = false ; - deleteDeadTextures();//Now, actually call glDeleteTextures for everything. } //static @@ -1528,7 +1526,7 @@ void LLImageGL::deleteDeadTextures() { bool reset = false; - for(U32 i=0;i Date: Wed, 18 Jul 2012 21:04:21 -0500 Subject: [PATCH 4/5] FMODEx diagnostics. SHFMODExStreamBufferSize added. Determines stream buffer size in ms. (stream restart required) SHFMODExDecodeBufferSize added. Determines decode buffer size in ms. (stream restart required) Streams will mute themselves if they are starving, until they are free of starvation for 5 full seconds. Streams that fail to accumulate any buffer progress while starving for 10 full updates will be stopped. Stream buffer progress(buffer percent) is llinfos spewed every update. (temporary) Doubled default stream buffer size Increased default decode buffer size to 1000ms (from 400) Temporarily using FMOD::Memory_Initialize to display raw stream/decode buffer sizes via llinfos. Added llwarns messages for SigmaTel hardware or bad audio acceleration configuration. --- indra/llaudio/llaudioengine_fmodex.cpp | 28 +++++++++ indra/llaudio/llstreamingaudio.h | 3 + indra/llaudio/llstreamingaudio_fmodex.cpp | 68 ++++++++++++++++++++-- indra/llaudio/llstreamingaudio_fmodex.h | 7 +++ indra/newview/app_settings/settings_sh.xml | 22 +++++++ indra/newview/llviewerparcelmedia.cpp | 4 ++ 6 files changed, 126 insertions(+), 6 deletions(-) diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 2b2bd19d5..83ef4c5b4 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -95,6 +95,28 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } +void* __stdcall decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +{ + if(type & FMOD_MEMORY_STREAM_DECODE) + { + llinfos << "Decode buffer size: " << size << llendl; + } + else if(type & FMOD_MEMORY_STREAM_FILE) + { + llinfos << "Strean buffer size: " << size << llendl; + } + return new char[size]; +} +void* __stdcall decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +{ + memset(ptr,0,size); + return ptr; +} +void __stdcall decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) +{ + delete[] ptr; +} + bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) { @@ -108,6 +130,10 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL; + result = FMOD::Memory_Initialize(NULL, NULL, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); + if(Check_FMOD_Error(result, "FMOD::Memory_Initialize")) + return false; + result = FMOD::System_Create(&mSystem); if(Check_FMOD_Error(result, "FMOD::System_Create")) return false; @@ -156,12 +182,14 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) */ result = mSystem->setDSPBufferSize(1024, 10); Check_FMOD_Error(result, "FMOD::System::setDSPBufferSize"); + llwarns << "Windows audio acceleration is disabled. This may introduce latency issues." << llendl; } result = mSystem->getDriverInfo(0, name, 256, 0); Check_FMOD_Error(result, "FMOD::System::getDriverInfo"); if (strstr(name, "SigmaTel")) { + llwarns << "SigmaTel device detected. This may introduce audio quality issues." << llendl; /* Sigmatel sound devices crackle for some reason if the format is PCM 16bit. PCM floating point output seems to solve it. diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h index 0e81cc530..3fb9ad4e3 100644 --- a/indra/llaudio/llstreamingaudio.h +++ b/indra/llaudio/llstreamingaudio.h @@ -58,6 +58,9 @@ class LLStreamingAudioInterface virtual const LLSD *getMetaData() = 0; virtual bool supportsWaveData() = 0; virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) = 0; + + virtual bool supportsAdjustableBufferSizes(){return false;} + virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){}; }; #endif // LL_STREAMINGAUDIO_H diff --git a/indra/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp index 6d97bcc49..c57f7d59b 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ b/indra/llaudio/llstreamingaudio_fmodex.cpp @@ -50,7 +50,7 @@ public: const std::string& getURL() { return mInternetStreamURL; } - FMOD_OPENSTATE getOpenState(); + FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL); protected: FMOD::System* mSystem; FMOD::Channel* mStreamChannel; @@ -70,11 +70,13 @@ LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) : mCurrentInternetStreamp(NULL), mFMODInternetStreamChannelp(NULL), mGain(1.0f), - mMetaData(NULL) + mMetaData(NULL), + mStarvedProgress(0), + mStarvedNoProgressFrames(0) { // Number of milliseconds of audio to buffer for the audio card. // Must be larger than the usual Second Life frame stutter time. - const U32 buffer_seconds = 5; //sec + const U32 buffer_seconds = 10; //sec const U32 estimated_bitrate = 128; //kbit/sec mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); @@ -145,7 +147,10 @@ void LLStreamingAudio_FMODEX::update() return; } - FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(); + unsigned int progress; + bool starving; + bool diskbusy; + FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy); if (open_state == FMOD_OPENSTATE_READY) { @@ -158,6 +163,7 @@ void LLStreamingAudio_FMODEX::update() // Reset volume to previously set volume setGain(getGain()); mFMODInternetStreamChannelp->setPaused(false); + mLastStarved.stop(); } } else if(open_state == FMOD_OPENSTATE_ERROR) @@ -168,6 +174,7 @@ void LLStreamingAudio_FMODEX::update() if(mFMODInternetStreamChannelp) { + llinfos << "progress = " << progress << llendl; if(!mMetaData) mMetaData = new LLSD; @@ -237,12 +244,46 @@ void LLStreamingAudio_FMODEX::update() } } } + if(starving) + { + if(!mLastStarved.getStarted()) + { + llinfos << "Stream starvation detected! Muting stream audio until it clears." << llendl; + llinfos << " (diskbusy="<setMute(true); + mStarvedProgress = progress; + mStarvedNoProgressFrames = 0; + } + else if(mStarvedProgress == progress) + { + if(++mStarvedNoProgressFrames >= 10) + { + //we got 10 consecutive updates of 0 progress made on the stream buffer. It probably stalled. + llinfos << "Stream unable to recover from starvation. Halting." << llendl; + stop(); + return; + } + } + else + { + mStarvedNoProgressFrames = 0; + mStarvedProgress = progress; + } + mLastStarved.start(); + } + else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 5.f) + { + mLastStarved.stop(); + mFMODInternetStreamChannelp->setMute(false); + } } } } void LLStreamingAudio_FMODEX::stop() { + mLastStarved.stop(); if(mMetaData) { delete mMetaData; @@ -341,6 +382,11 @@ void LLStreamingAudio_FMODEX::setGain(F32 vol) if(!mFMODInternetStreamChannelp || !mCurrentInternetStreamp) return false; + bool muted=false; + mFMODInternetStreamChannelp->getMute(&muted); + if(muted) + return false; + static std::vector local_array(count); //Have to have an extra buffer to mix channels. Bleh. if(count > (S32)local_array.size()) //Expand the array if needed. Try to minimize allocation calls, so don't ever shrink. local_array.resize(count); @@ -442,9 +488,19 @@ bool LLAudioStreamManagerFMODEX::stopStream() } } -FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState() +FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy) { FMOD_OPENSTATE state; - mInternetStream->getOpenState(&state,NULL,NULL,NULL); + mInternetStream->getOpenState(&state,percentbuffered,starving,diskbusy); return state; } + +void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime) +{ + mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES); + FMOD_ADVANCEDSETTINGS settings; + memset(&settings,0,sizeof(settings)); + settings.cbsize=sizeof(settings); + settings.defaultDecodeBufferSize = decodebuffertime;//ms + mSystem->setAdvancedSettings(&settings); +} \ No newline at end of file diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h index 064b266e6..46c0ea553 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.h +++ b/indra/llaudio/llstreamingaudio_fmodex.h @@ -37,6 +37,7 @@ #include "stdtypes.h" // from llcommon #include "llstreamingaudio.h" +#include "lltimer.h" //Stubs class LLAudioStreamManagerFMODEX; @@ -66,6 +67,8 @@ class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface /*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not playing. /*virtual*/ bool supportsWaveData(){return true;} /*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1); + /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} + /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); private: FMOD::System *mSystem; @@ -76,6 +79,10 @@ private: std::string mURL; F32 mGain; + LLTimer mLastStarved; + unsigned int mStarvedProgress; + unsigned int mStarvedNoProgressFrames; + LLSD *mMetaData; }; diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 803f7a12e..feae4cb77 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -40,6 +40,28 @@ Boolean Value 0 + + SHFMODExStreamBufferSize + + Comment + Sets the streaming buffer size (in milliseconds) + Persist + 1 + Type + U32 + Value + 7000 + + SHFMODExDecodeBufferSize + + Comment + Sets the streaming decode buffer size (in milliseconds) + Persist + 1 + Type + U32 + Value + 1000 SHAllowScriptCommands diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 9e7df265e..1349429ee 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -54,6 +54,7 @@ #include "llaudioengine.h" #include "lloverlaybar.h" #include "slfloatermediafilter.h" +#include "llstreamingaudio.h" // Static Variables @@ -661,6 +662,9 @@ void LLViewerParcelMedia::playStreamingMusic(LLParcel* parcel, bool filter) else if (gAudiop) { LLStringUtil::trim(music_url); + LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl(); + if(stream && stream->supportsAdjustableBufferSizes()) + stream->setBufferSizes(gSavedSettings.getU32("SHFMODExStreamBufferSize"),gSavedSettings.getU32("SHFMODExDecodeBufferSize")); gAudiop->startInternetStream(music_url); if (music_url.empty()) { From 643844c01d4a96fa56a61f70a03ccdde6c65b24d Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 21:27:02 -0500 Subject: [PATCH 5/5] GCC being GCC-ey. Fix a couple errors and warnings --- indra/llaudio/llaudioengine_fmodex.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 83ef4c5b4..c745dbcd1 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -95,7 +95,7 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } -void* __stdcall decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) { if(type & FMOD_MEMORY_STREAM_DECODE) { @@ -107,14 +107,14 @@ void* __stdcall decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const cha } return new char[size]; } -void* __stdcall decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) { memset(ptr,0,size); return ptr; } -void __stdcall decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) +void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) { - delete[] ptr; + delete[] (char*)ptr; } bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) @@ -130,7 +130,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL; - result = FMOD::Memory_Initialize(NULL, NULL, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); + result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); if(Check_FMOD_Error(result, "FMOD::Memory_Initialize")) return false;