summaryrefslogtreecommitdiff
path: root/indra/newview/llvoicewebrtc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvoicewebrtc.cpp')
-rw-r--r--indra/newview/llvoicewebrtc.cpp397
1 files changed, 282 insertions, 115 deletions
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 93c217a7ba..06ccd23670 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -34,7 +34,7 @@
#include "llbufferstream.h"
#include "llfile.h"
#include "llmenugl.h"
-#ifdef LL_USESYSTEMLIBS
+#if 1
# include "expat.h"
#else
# include "expat/expat.h"
@@ -52,6 +52,7 @@
#include "llcachename.h"
#include "llimview.h" // for LLIMMgr
#include "llworld.h"
+#include "llviewerregion.h"
#include "llparcel.h"
#include "llviewerparcelmgr.h"
#include "llfirstuse.h"
@@ -81,9 +82,15 @@ const std::string WEBRTC_VOICE_SERVER_TYPE = "webrtc";
namespace {
- const F32 MAX_AUDIO_DIST = 50.0f;
- const F32 VOLUME_SCALE_WEBRTC = 0.01f;
- const F32 LEVEL_SCALE_WEBRTC = 0.008f;
+ const F32 MAX_AUDIO_DIST = 50.0f;
+ const F32 VOLUME_SCALE_WEBRTC = 0.01f;
+ const F32 TUNING_LEVEL_SCALE = 0.01f;
+ const F32 TUNING_LEVEL_START_POINT = 0.8f;
+ const F32 LEVEL_SCALE = 0.005f;
+ const F32 LEVEL_START_POINT = 0.18f;
+ const uint32_t SET_HIDDEN_RESTORE_DELAY_MS = 200; // 200 ms to unmute again after hiding during teleport
+ const uint32_t MUTE_FADE_DELAY_MS = 500; // 20ms fade followed by 480ms silence gets rid of the click just after unmuting.
+ // This is because the buffers and processing is cleared by the silence.
const F32 SPEAKING_AUDIO_LEVEL = 0.30;
@@ -200,7 +207,6 @@ bool LLWebRTCVoiceClient::sShuttingDown = false;
LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
mHidden(false),
- mTuningMode(false),
mTuningMicGain(0.0),
mTuningSpeakerVolume(50), // Set to 50 so the user can hear themselves when he sets his mic volume
mDevicesListUpdated(false),
@@ -267,6 +273,11 @@ void LLWebRTCVoiceClient::cleanupSingleton()
void LLWebRTCVoiceClient::init(LLPumpIO* pump)
{
// constructor will set up LLVoiceClient::getInstance()
+ initWebRTC();
+}
+
+void LLWebRTCVoiceClient::initWebRTC()
+{
llwebrtc::init(this);
mWebRTCDeviceInterface = llwebrtc::getDeviceInterface();
@@ -282,10 +293,13 @@ void LLWebRTCVoiceClient::terminate()
return;
}
+ LL_INFOS("Voice") << "Terminating WebRTC" << LL_ENDL;
+
mVoiceEnabled = false;
+ sShuttingDown = true; // so that coroutines won't post more work.
llwebrtc::terminate();
- sShuttingDown = true;
+ mWebRTCDeviceInterface = nullptr;
}
//---------------------------------------------------
@@ -336,35 +350,57 @@ void LLWebRTCVoiceClient::updateSettings()
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
setVoiceEnabled(LLVoiceClient::getInstance()->voiceEnabled());
- static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation");
- setEarLocation(sVoiceEarLocation);
-
- static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice");
- setCaptureDevice(sInputDevice);
+ if (mVoiceEnabled)
+ {
+ static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation");
+ setEarLocation(sVoiceEarLocation);
- static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
- setRenderDevice(sOutputDevice);
+ static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice");
+ setCaptureDevice(sInputDevice);
- LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL;
+ static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
+ setRenderDevice(sOutputDevice);
- static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
- setMicGain(sMicLevel);
+ LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice())
+ << LL_ENDL;
- llwebrtc::LLWebRTCDeviceInterface::AudioConfig config;
+ static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
+ setMicGain(sMicLevel);
- static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true);
- config.mEchoCancellation = sEchoCancellation;
+ llwebrtc::LLWebRTCDeviceInterface::AudioConfig config;
- static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true);
- config.mAGC = sAGC;
+ bool audioConfigChanged = false;
- static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings,
- "VoiceNoiseSuppressionLevel",
- llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH);
- config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel) (U32)sNoiseSuppressionLevel;
+ static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true);
+ if (sEchoCancellation != config.mEchoCancellation)
+ {
+ config.mEchoCancellation = sEchoCancellation;
+ audioConfigChanged = true;
+ }
- mWebRTCDeviceInterface->setAudioConfig(config);
+ static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true);
+ if (sAGC != config.mAGC)
+ {
+ config.mAGC = sAGC;
+ audioConfigChanged = true;
+ }
+ static LLCachedControl<U32> sNoiseSuppressionLevel(
+ gSavedSettings,
+ "VoiceNoiseSuppressionLevel",
+ llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH);
+ auto noiseSuppressionLevel =
+ (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel)(U32)sNoiseSuppressionLevel;
+ if (noiseSuppressionLevel != config.mNoiseSuppressionLevel)
+ {
+ config.mNoiseSuppressionLevel = noiseSuppressionLevel;
+ audioConfigChanged = true;
+ }
+ if (audioConfigChanged && mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setAudioConfig(config);
+ }
+ }
}
// Observers
@@ -661,7 +697,11 @@ LLVoiceDeviceList& LLWebRTCVoiceClient::getCaptureDevices()
void LLWebRTCVoiceClient::setCaptureDevice(const std::string& name)
{
- mWebRTCDeviceInterface->setCaptureDevice(name);
+ if (mWebRTCDeviceInterface)
+ {
+ LL_DEBUGS("Voice") << "new capture device is " << name << LL_ENDL;
+ mWebRTCDeviceInterface->setCaptureDevice(name);
+ }
}
void LLWebRTCVoiceClient::setDevicesListUpdated(bool state)
{
@@ -688,25 +728,45 @@ void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDevi
return;
}
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
+
+ LL_DEBUGS("Voice") << "Reiniting " << LL_ENDL;
+
std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
LL_DEBUGS("Voice") << "Setting devices to-input: '" << inputDevice << "' output: '" << outputDevice << "'" << LL_ENDL;
- clearRenderDevices();
- for (auto &device : render_devices)
+
+ // only set the render device if the device list has changed.
+ if (mRenderDevices.size() != render_devices.size() || !std::equal(mRenderDevices.begin(),
+ mRenderDevices.end(),
+ render_devices.begin(),
+ [](const LLVoiceDevice& a, const llwebrtc::LLWebRTCVoiceDevice& b) {
+ return a.display_name == b.mDisplayName && a.full_name == b.mID; }))
{
- addRenderDevice(LLVoiceDevice(device.mDisplayName, device.mID));
+ clearRenderDevices();
+ for (auto& device : render_devices)
+ {
+ addRenderDevice(LLVoiceDevice(device.mDisplayName, device.mID));
+ }
+ setRenderDevice(outputDevice);
}
- setRenderDevice(outputDevice);
- clearCaptureDevices();
- for (auto &device : capture_devices)
+ // only set the capture device if the device list has changed.
+ if (mCaptureDevices.size() != capture_devices.size() ||!std::equal(mCaptureDevices.begin(),
+ mCaptureDevices.end(),
+ capture_devices.begin(),
+ [](const LLVoiceDevice& a, const llwebrtc::LLWebRTCVoiceDevice& b)
+ { return a.display_name == b.mDisplayName && a.full_name == b.mID; }))
{
- LL_DEBUGS("Voice") << "Checking capture device:'" << device.mID << "'" << LL_ENDL;
+ clearCaptureDevices();
+ for (auto& device : capture_devices)
+ {
+ LL_DEBUGS("Voice") << "Checking capture device:'" << device.mID << "'" << LL_ENDL;
- addCaptureDevice(LLVoiceDevice(device.mDisplayName, device.mID));
+ addCaptureDevice(LLVoiceDevice(device.mDisplayName, device.mID));
+ }
+ setCaptureDevice(inputDevice);
}
- setCaptureDevice(inputDevice);
setDevicesListUpdated(true);
}
@@ -731,14 +791,21 @@ LLVoiceDeviceList& LLWebRTCVoiceClient::getRenderDevices()
void LLWebRTCVoiceClient::setRenderDevice(const std::string& name)
{
- mWebRTCDeviceInterface->setRenderDevice(name);
+ if (mWebRTCDeviceInterface)
+ {
+ LL_DEBUGS("Voice") << "new render device is " << name << LL_ENDL;
+ mWebRTCDeviceInterface->setRenderDevice(name);
+ }
}
void LLWebRTCVoiceClient::tuningStart()
{
if (!mIsInTuningMode)
{
- mWebRTCDeviceInterface->setTuningMode(true);
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setTuningMode(true);
+ }
mIsInTuningMode = true;
}
}
@@ -747,7 +814,10 @@ void LLWebRTCVoiceClient::tuningStop()
{
if (mIsInTuningMode)
{
- mWebRTCDeviceInterface->setTuningMode(false);
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setTuningMode(false);
+ }
mIsInTuningMode = false;
}
}
@@ -759,7 +829,14 @@ bool LLWebRTCVoiceClient::inTuningMode()
void LLWebRTCVoiceClient::tuningSetMicVolume(float volume)
{
- mTuningMicGain = volume;
+ if (volume != mTuningMicGain)
+ {
+ mTuningMicGain = volume;
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setTuningMicGain(volume);
+ }
+ }
}
void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
@@ -771,21 +848,14 @@ void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
}
}
-float LLWebRTCVoiceClient::getAudioLevel()
+float LLWebRTCVoiceClient::tuningGetEnergy(void)
{
- if (mIsInTuningMode)
+ if (!mWebRTCDeviceInterface)
{
- return (1.0f - mWebRTCDeviceInterface->getTuningAudioLevel() * LEVEL_SCALE_WEBRTC) * mTuningMicGain / 2.1f;
- }
- else
- {
- return (1.0f - mWebRTCDeviceInterface->getPeerConnectionAudioLevel() * LEVEL_SCALE_WEBRTC) * mMicGain / 2.1f;
+ return 0.f;
}
-}
-
-float LLWebRTCVoiceClient::tuningGetEnergy(void)
-{
- return getAudioLevel();
+ float rms = mWebRTCDeviceInterface->getTuningAudioLevel();
+ return TUNING_LEVEL_START_POINT - TUNING_LEVEL_SCALE * rms;
}
bool LLWebRTCVoiceClient::deviceSettingsAvailable()
@@ -811,7 +881,10 @@ void LLWebRTCVoiceClient::refreshDeviceLists(bool clearCurrentList)
clearCaptureDevices();
clearRenderDevices();
}
- mWebRTCDeviceInterface->refreshDevices();
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->refreshDevices();
+ }
}
@@ -821,6 +894,11 @@ void LLWebRTCVoiceClient::setHidden(bool hidden)
if (inSpatialChannel())
{
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setMute(mHidden || mMuteMic,
+ mHidden ? 0 : SET_HIDDEN_RESTORE_DELAY_MS); // delay 200ms so as to not pile up mutes/unmutes.
+ }
if (mHidden)
{
// get out of the channel entirely
@@ -985,7 +1063,9 @@ void LLWebRTCVoiceClient::updatePosition(void)
LLWebRTCVoiceClient::participantStatePtr_t participant = findParticipantByID("Estate", gAgentID);
if(participant)
{
- participant->mRegion = gAgent.getRegion()->getRegionID();
+ if (participant->mRegion != region->getRegionID()) {
+ participant->mRegion = region->getRegionID();
+ }
}
}
}
@@ -1109,13 +1189,14 @@ void LLWebRTCVoiceClient::sendPositionUpdate(bool force)
// Update our own volume on our participant, so it'll show up
// in the UI. This is done on all sessions, so switching
// sessions retains consistent volume levels.
-void LLWebRTCVoiceClient::updateOwnVolume() {
- F32 audio_level = 0.0;
- if (!mMuteMic && !mTuningMode)
+void LLWebRTCVoiceClient::updateOwnVolume()
+{
+ F32 audio_level = 0.0f;
+ if (!mMuteMic && mWebRTCDeviceInterface)
{
- audio_level = getAudioLevel();
+ float rms = mWebRTCDeviceInterface->getPeerConnectionAudioLevel();
+ audio_level = LEVEL_START_POINT - LEVEL_SCALE * rms;
}
-
sessionState::for_each(boost::bind(predUpdateOwnVolume, _1, audio_level));
}
@@ -1228,7 +1309,7 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::ad
if (!result)
{
// participant isn't already in one list or the other.
- result.reset(new participantState(agent_id, region));
+ result = std::make_shared<participantState>(agent_id, region);
mParticipantsByUUID.insert(participantUUIDMap::value_type(agent_id, result));
result->mAvatarID = agent_id;
}
@@ -1512,6 +1593,17 @@ void LLWebRTCVoiceClient::setMuteMic(bool muted)
}
mMuteMic = muted;
+
+ if (mIsInTuningMode)
+ {
+ return;
+ }
+
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setMute(muted, muted ? MUTE_FADE_DELAY_MS : 0); // delay for 40ms on mute to allow buffers to empty
+ }
+
// when you're hidden, your mic is always muted.
if (!mHidden)
{
@@ -1550,7 +1642,10 @@ void LLWebRTCVoiceClient::setMicGain(F32 gain)
if (gain != mMicGain)
{
mMicGain = gain;
- mWebRTCDeviceInterface->setPeerConnectionGain(gain);
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setMicGain(gain);
+ }
}
}
@@ -1734,6 +1829,15 @@ void LLWebRTCVoiceClient::onChangeDetailed(const LLMute& mute)
}
}
+void LLWebRTCVoiceClient::userAuthorized(const std::string& user_id, const LLUUID& agentID)
+{
+ if (sShuttingDown)
+ {
+ sShuttingDown = false; // was terminated, restart
+ initWebRTC();
+ }
+}
+
void LLWebRTCVoiceClient::predSetUserMute(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const LLUUID &id, bool mute)
{
session->setUserMute(id, mute);
@@ -1999,6 +2103,33 @@ bool LLWebRTCVoiceClient::sessionState::processConnectionStates()
return !mWebRTCConnections.empty();
}
+// Helper function to check if a region supports WebRTC voice
+bool LLWebRTCVoiceClient::estateSessionState::isRegionWebRTCEnabled(const LLUUID& regionID)
+{
+ LLViewerRegion* region = LLWorld::getInstance()->getRegionFromID(regionID);
+ if (!region)
+ {
+ LL_WARNS("Voice") << "Could not find region " << regionID
+ << " for voice server type validation" << LL_ENDL;
+ return false;
+ }
+
+ LLSD simulatorFeatures;
+ region->getSimulatorFeatures(simulatorFeatures);
+
+ bool isWebRTCEnabled = simulatorFeatures.has("VoiceServerType") &&
+ simulatorFeatures["VoiceServerType"].asString() == "webrtc";
+
+ if (!isWebRTCEnabled)
+ {
+ LL_DEBUGS("Voice") << "Region " << regionID << " VoiceServerType is not 'webrtc' (got: "
+ << (simulatorFeatures.has("VoiceServerType") ? simulatorFeatures["VoiceServerType"].asString() : "none") << ")"
+ << LL_ENDL;
+ }
+
+ return isWebRTCEnabled;
+}
+
// processing of spatial voice connection states requires special handling.
// as neighboring regions need to be started up or shut down depending
// on our location.
@@ -2023,6 +2154,13 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
// shut down connections to neighbors that are too far away.
spatialConnection.get()->shutDown();
}
+ else if (!isRegionWebRTCEnabled(regionID))
+ {
+ // shut down connections to neighbors that no longer support WebRTC voice.
+ LL_DEBUGS("Voice") << "Shutting down connection to neighbor region " << regionID
+ << " - no longer supports WebRTC voice" << LL_ENDL;
+ spatialConnection.get()->shutDown();
+ }
if (!spatialConnection.get()->isShuttingDown())
{
neighbor_ids.erase(regionID);
@@ -2032,11 +2170,20 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
// add new connections for new neighbors
for (auto &neighbor : neighbor_ids)
{
- connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID));
+ // Only connect if the region supports WebRTC voice server type
+ if (isRegionWebRTCEnabled(neighbor))
+ {
+ connectionPtr_t connection = std::make_shared<LLVoiceWebRTCSpatialConnection>(neighbor, INVALID_PARCEL_ID, mChannelID);
- mWebRTCConnections.push_back(connection);
- connection->setMuteMic(mMuted);
- connection->setSpeakerVolume(mSpeakerVolume);
+ mWebRTCConnections.push_back(connection);
+ connection->setMuteMic(mMuted); // mute will be set for primary connection when that connection comes up
+ connection->setSpeakerVolume(mSpeakerVolume);
+ }
+ else
+ {
+ LL_DEBUGS("Voice") << "Skipping neighbor region " << neighbor
+ << " - does not support WebRTC voice" << LL_ENDL;
+ }
}
}
return LLWebRTCVoiceClient::sessionState::processConnectionStates();
@@ -2259,7 +2406,6 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
return;
}
- bool iceCompleted = false;
LLSD body;
if (!connection->mIceCandidates.empty() || connection->mIceCompleted)
{
@@ -2298,18 +2444,17 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
LLSD body_candidate;
body_candidate["completed"] = true;
body["candidate"] = body_candidate;
- iceCompleted = connection->mIceCompleted;
connection->mIceCompleted = false;
}
body["viewer_session"] = connection->mViewerSession;
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
- new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::processIceUpdatesCoro",
- LLCore::HttpRequest::DEFAULT_POLICY_ID));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+ std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("LLVoiceWebRTCAdHocConnection::processIceUpdatesCoro",
+ LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setWantHeaders(true);
@@ -2386,6 +2531,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac
}
LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL;
mWebRTCAudioInterface = audio_interface;
+ mWebRTCAudioInterface->setMute(true); // mute will be set appropriately later when we finish setting up.
setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED);
});
}
@@ -2403,10 +2549,7 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
LL::WorkQueue::postMaybe(mMainQueue,
[=, this] {
LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL;
- if (!mShutDown)
- {
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
- }
+ setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
mCurrentStatus = LLVoiceClientStatusObserver::ERROR_UNKNOWN;
});
}
@@ -2518,11 +2661,11 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
body["viewer_session"] = connection->mViewerSession;
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
- new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::breakVoiceConnection",
- LLCore::HttpRequest::DEFAULT_POLICY_ID));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+ std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("LLVoiceWebRTCAdHocConnection::breakVoiceConnection",
+ LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setWantHeaders(true);
@@ -2546,6 +2689,11 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
+ if (LLWebRTCVoiceClient::isShuttingDown())
+ {
+ mOutstandingRequests--;
+ return;
+ }
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
@@ -2582,11 +2730,11 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
}
body["channel_type"] = "local";
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
- new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::requestVoiceConnection",
- LLCore::HttpRequest::DEFAULT_POLICY_ID));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+ std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("LLVoiceWebRTCAdHocConnection::requestVoiceConnection",
+ LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setWantHeaders(true);
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
@@ -2745,7 +2893,13 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
}
// update the peer connection with the various characteristics of
// this connection.
- mWebRTCAudioInterface->setMute(mMuted);
+ // For spatial this connection will come up as muted, but will be set to the appropriate
+ // value later on when we determine the regions we connect to.
+ if (isSpatial())
+ {
+ // we'll determine primary state later and set mute accordinly
+ mPrimary = false;
+ }
mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume);
LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID);
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_DATA_CHANNEL);
@@ -2768,6 +2922,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
LLWebRTCVoiceClient::getInstance()->updatePosition();
LLWebRTCVoiceClient::getInstance()->sendPositionUpdate(true);
}
+ else
+ {
+ mWebRTCAudioInterface->setMute(mMuted);
+ }
}
break;
}
@@ -2790,6 +2948,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
if (primary != mPrimary)
{
mPrimary = primary;
+ if (mWebRTCAudioInterface)
+ {
+ mWebRTCAudioInterface->setMute(mMuted || !mPrimary);
+ }
sendJoin();
}
}
@@ -2843,9 +3005,13 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
}
// else was already posted by llwebrtc::terminate().
break;
+ }
+
case VOICE_STATE_WAIT_FOR_CLOSE:
break;
+
case VOICE_STATE_CLOSED:
+ {
if (!mShutDown)
{
mVoiceConnectionState = VOICE_STATE_START_SESSION;
@@ -2921,7 +3087,6 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
return;
}
boost::json::object voice_data = voice_data_parsed.as_object();
- bool new_participant = false;
boost::json::object mute;
boost::json::object user_gain;
for (auto &participant_elem : voice_data)
@@ -2974,7 +3139,6 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
}
}
- new_participant |= joined;
if (!participant && joined && (primary || !isSpatial()))
{
participant = LLWebRTCVoiceClient::getInstance()->addParticipantByID(mChannelID, agent_id, mRegionID);
@@ -3024,7 +3188,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
{
root["ug"] = user_gain;
}
- if (root.size() > 0)
+ if (root.size() > 0 && mWebRTCDataInterface)
{
std::string json_data = boost::json::serialize(root);
mWebRTCDataInterface->sendData(json_data, false);
@@ -3067,7 +3231,10 @@ void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface
void LLVoiceWebRTCConnection::sendJoin()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
-
+ if (!mWebRTCDataInterface)
+ {
+ return;
+ }
boost::json::object root;
boost::json::object join_obj;
@@ -3089,10 +3256,7 @@ LLVoiceWebRTCSpatialConnection::LLVoiceWebRTCSpatialConnection(const LLUUID &reg
LLVoiceWebRTCConnection(regionID, channelID),
mParcelLocalID(parcelLocalID)
{
- if (gAgent.getRegion())
- {
- mPrimary = (regionID == gAgent.getRegion()->getRegionID());
- }
+ mPrimary = false; // will be set to primary after connection established
}
LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection()
@@ -3101,23 +3265,20 @@ LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection()
void LLVoiceWebRTCSpatialConnection::setMuteMic(bool muted)
{
- if (mMuted != muted)
+ mMuted = muted;
+ if (mWebRTCAudioInterface)
{
- mMuted = muted;
- if (mWebRTCAudioInterface)
+ LLViewerRegion *regionp = gAgent.getRegion();
+ if (regionp && mRegionID == regionp->getRegionID())
{
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp && mRegionID == regionp->getRegionID())
- {
- mWebRTCAudioInterface->setMute(muted);
- }
- else
- {
- // Always mute this agent with respect to neighboring regions.
- // Peers don't want to hear this agent from multiple regions
- // as that'll echo.
- mWebRTCAudioInterface->setMute(true);
- }
+ mWebRTCAudioInterface->setMute(muted);
+ }
+ else
+ {
+ // Always mute this agent with respect to neighboring regions.
+ // Peers don't want to hear this agent from multiple regions
+ // as that'll echo.
+ mWebRTCAudioInterface->setMute(true);
}
}
}
@@ -3145,6 +3306,12 @@ void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
+ if (LLWebRTCVoiceClient::isShuttingDown())
+ {
+ mOutstandingRequests--;
+ return;
+ }
+
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
LL_DEBUGS("Voice") << "Requesting voice connection." << LL_ENDL;
@@ -3178,11 +3345,11 @@ void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
body["channel_type"] = "multiagent";
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
- new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::requestVoiceConnection",
- LLCore::HttpRequest::DEFAULT_POLICY_ID));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+ std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("LLVoiceWebRTCAdHocConnection::requestVoiceConnection",
+ LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setWantHeaders(true);