diff --git a/.hgtags b/.hgtags
index 02f7525b3aefa024165adccd0b6ea173aa0bbbdf..9b5b8b7022e1498bb3c0d8f0bd34c14b203e7e73 100755
--- a/.hgtags
+++ b/.hgtags
@@ -441,3 +441,5 @@ adc360e6bf21390d2665380951d85937cd29a604 3.5.0-release
 9d8726eca785acad694564516f16dd639faf45c0 3.5.1-beta2
 78a8fe6abf331944d6b6bb1ce1024a6bc08141f4 DRTVWR-298
 50ccc12f38c3c99f03b374e32429cb043b73e2a6 DRTVWR-294
+4b7fa963b80e2056ab648f83a4d61310b3cedb3d DRTVWR-314
+65ae89aeb7ea674a555e439e963f17949322ac94 3.5.1-beta3
diff --git a/autobuild.xml b/autobuild.xml
index abf3e22ea1166597ab2d8f78250b6702f90f5bc8..b12bb5a94b8d828605ba15b09958769f507e597c 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -498,9 +498,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-	      <string>89a3df89da75444877cf3197416fed67</string>
+	      <string>10352aab979c333a52dbad21b6e6fba9</string>
               <key>url</key>
-	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/270029/arch/Darwin/installer/fmodex-4.44-darwin-20130205.tar.bz2</string>
+	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274403/arch/Darwin/installer/fmodex-4.44-darwin-20130419.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -510,9 +510,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-          <string>fd787931f49ece9bf99f4d1d1596f04b</string>
+          <string>79e45527aa9fb90b813599dff5ce01a7</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/269984/arch/Linux/installer/fmodex-4.44-linux-20130205.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274378/arch/Linux/installer/fmodex-4.44-linux-20130419.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -522,9 +522,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-	      <string>9e0f62be63e74af18f670f864cac93da</string>
+	      <string>0980cdf98a322a780ba739e324d0b955</string>
               <key>url</key>
-	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/270026/arch/CYGWIN/installer/fmodex-4.44-windows-20130205.tar.bz2</string>
+	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274401/arch/CYGWIN/installer/fmodex-4.44-windows-20130419.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 9f2f51f248a9f2dcd8425e740fdbc55b0a426a54..09c0d01b116bd9fb0d6d5bf1cd4dc9011bd7d701 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -899,6 +899,7 @@ NickyD
 Nicky Dasmijn
 	VWR-29228
 	MAINT-873
+	SUN-72
 Nicky Perian
 	OPEN-1
 	STORM-1087
diff --git a/indra/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp
index 4a74267650bcc30b95476cb2901b2b233d214f3c..266fa2f57b27ea5106f448c73c6b181e78cb680b 100644
--- a/indra/llaudio/llstreamingaudio_fmodex.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodex.cpp
@@ -153,7 +153,6 @@ 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,21 +167,43 @@ void LLStreamingAudio_FMODEX::update()
 
 		if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound)
 		{
+			FMOD_TAG tag;
+			S32 tagcount, dirtytagcount;
+
+			if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount)
+			{
+				for(S32 i = 0; i < tagcount; ++i)
+				{
+					if(sound->getTag(NULL, i, &tag)!=FMOD_OK)
+						continue;
+
+					if (tag.type == FMOD_TAGTYPE_FMOD)
+					{
+						if (!strcmp(tag.name, "Sample Rate Change"))
+						{
+							llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl;
+							mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
+						}
+						continue;
+					}
+				}
+			}
+
 			if(starving)
 			{
-				if(!mLastStarved.getStarted())
+				bool paused = false;
+				mFMODInternetStreamChannelp->getPaused(&paused);
+				if(!paused)
 				{
-					llinfos << "Stream starvation detected! Muting stream audio until it clears." << llendl;
+					llinfos << "Stream starvation detected! Pausing stream until buffer nearly full." << llendl;
 					llinfos << "  (diskbusy="<<diskbusy<<")" << llendl;
 					llinfos << "  (progress="<<progress<<")" << llendl;
-					mFMODInternetStreamChannelp->setMute(true);
+					mFMODInternetStreamChannelp->setPaused(true);
 				}
-				mLastStarved.start();
 			}
-			else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 1.f)
+			else if(progress > 80)
 			{
-				mLastStarved.stop();
-				mFMODInternetStreamChannelp->setMute(false);
+				mFMODInternetStreamChannelp->setPaused(false);
 			}
 		}
 	}
@@ -190,8 +211,6 @@ void LLStreamingAudio_FMODEX::update()
 
 void LLStreamingAudio_FMODEX::stop()
 {
-	mLastStarved.stop();
-
 	if (mFMODInternetStreamChannelp)
 	{
 		mFMODInternetStreamChannelp->setPaused(true);
diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h
index 42b6b3aaa8ffa4e43265ea9b9de7f1c16471d7b0..1dee18ae7dab520cea4295bdd254dc14a4da21d2 100644
--- a/indra/llaudio/llstreamingaudio_fmodex.h
+++ b/indra/llaudio/llstreamingaudio_fmodex.h
@@ -67,8 +67,6 @@ class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface
 
 	std::string mURL;
 	F32 mGain;
-
-	LLTimer mLastStarved;
 };
 
 
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index bc615ed39ec593de0cda0d2bd3caa1639d7dad06..864b6e6975632d099f217ececae9a54841e6d116 100755
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -853,7 +853,8 @@ llifstream::llifstream(const std::string& _Filename,
 #if LL_WINDOWS
 	std::istream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -872,7 +873,8 @@ llifstream::llifstream(const char* _Filename,
 #if LL_WINDOWS
 	std::istream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -917,8 +919,10 @@ bool llifstream::is_open() const
 
 void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
 {	// open a C stream with specified mode
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+
 #if LL_WINDOWS
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -927,6 +931,7 @@ void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
 		_Myios::clear();
 	}
 #else
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
 	{
 		this->setstate(ios_base::failbit);
 	}
@@ -969,7 +974,8 @@ llofstream::llofstream(const std::string& _Filename,
 #if LL_WINDOWS
 	std::ostream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -988,7 +994,8 @@ llofstream::llofstream(const char* _Filename,
 #if LL_WINDOWS
 	std::ostream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -1032,8 +1039,9 @@ bool llofstream::is_open() const
 
 void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
 {	// open a C stream with specified mode
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
 #if LL_WINDOWS
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -1042,6 +1050,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
 		_Myios::clear();
 	}
 #else
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
 	{
 		this->setstate(ios_base::failbit);
 	}