diff options
-rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 321 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc.h | 6 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 8 | ||||
-rw-r--r-- | indra/newview/llimview.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llvoicechannel.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 41 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.h | 6 |
8 files changed, 216 insertions, 180 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 875f233e65..b7501bd0e0 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -84,10 +84,7 @@ void LLAudioDeviceObserver::OnRenderData(const void *audio_samples, { } -LLCustomProcessor::LLCustomProcessor() : - mSampleRateHz(0), - mNumChannels(0), - mMicrophoneEnergy(0.0) +LLCustomProcessor::LLCustomProcessor() : mSampleRateHz(0), mNumChannels(0), mMicrophoneEnergy(0.0) { memset(mSumVector, 0, sizeof(mSumVector)); } @@ -95,7 +92,7 @@ LLCustomProcessor::LLCustomProcessor() : void LLCustomProcessor::Initialize(int sample_rate_hz, int num_channels) { mSampleRateHz = sample_rate_hz; - mNumChannels = num_channels; + mNumChannels = num_channels; memset(mSumVector, 0, sizeof(mSumVector)); } @@ -105,7 +102,7 @@ void LLCustomProcessor::Process(webrtc::AudioBuffer *audio_in) stream_config.set_sample_rate_hz(mSampleRateHz); stream_config.set_num_channels(mNumChannels); std::vector<float *> frame; - std::vector<float> frame_samples; + std::vector<float> frame_samples; if (audio_in->num_channels() < 1 || audio_in->num_frames() < 480) { @@ -123,7 +120,7 @@ void LLCustomProcessor::Process(webrtc::AudioBuffer *audio_in) audio_in->CopyTo(stream_config, &frame[0]); // calculate the energy - float energy = 0; + float energy = 0; for (size_t index = 0; index < stream_config.num_samples(); index++) { float sample = frame_samples[index]; @@ -151,6 +148,7 @@ void LLCustomProcessor::Process(webrtc::AudioBuffer *audio_in) LLWebRTCImpl::LLWebRTCImpl() : mPeerCustomProcessor(nullptr), mMute(true), + mTuningMode(false), mPlayoutDevice(0), mRecordingDevice(0), mTuningAudioDeviceObserver(nullptr) @@ -160,7 +158,7 @@ LLWebRTCImpl::LLWebRTCImpl() : void LLWebRTCImpl::init() { RTC_DCHECK(mPeerConnectionFactory); - mPlayoutDevice = 0; + mPlayoutDevice = 0; mRecordingDevice = 0; rtc::InitializeSSL(); @@ -183,43 +181,41 @@ void LLWebRTCImpl::init() mTuningAudioDeviceObserver = new LLAudioDeviceObserver; mWorkerThread->PostTask( - [this]() - { - // Initialize the audio devices on the Worker Thread - mTuningDeviceModule = webrtc::CreateAudioDeviceWithDataObserver( - webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, - mTaskQueueFactory.get(), - std::unique_ptr<webrtc::AudioDeviceDataObserver>(mTuningAudioDeviceObserver)); - - mTuningDeviceModule->Init(); - mTuningDeviceModule->SetStereoRecording(true); - mTuningDeviceModule->SetStereoPlayout(true); - mTuningDeviceModule->EnableBuiltInAEC(false); - mTuningDeviceModule->SetAudioDeviceSink(this); - updateDevices(); - }); + [this]() + { + // Initialize the audio devices on the Worker Thread + mTuningDeviceModule = + webrtc::CreateAudioDeviceWithDataObserver(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, + mTaskQueueFactory.get(), + std::unique_ptr<webrtc::AudioDeviceDataObserver>(mTuningAudioDeviceObserver)); + + mTuningDeviceModule->Init(); + mTuningDeviceModule->SetStereoRecording(true); + mTuningDeviceModule->SetStereoPlayout(true); + mTuningDeviceModule->EnableBuiltInAEC(false); + mTuningDeviceModule->SetAudioDeviceSink(this); + updateDevices(); + }); mWorkerThread->BlockingCall( - [this]() - { - // the peer device module doesn't need an observer - // as we pull peer data after audio processing. - mPeerDeviceModule = - webrtc::CreateAudioDeviceWithDataObserver( - webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, - mTaskQueueFactory.get(), - nullptr); - mPeerDeviceModule->Init(); - mPeerDeviceModule->SetPlayoutDevice(mPlayoutDevice); - mPeerDeviceModule->SetRecordingDevice(mRecordingDevice); - mPeerDeviceModule->SetStereoRecording(true); - mPeerDeviceModule->SetStereoPlayout(true); - mPeerDeviceModule->EnableBuiltInAEC(false); - mPeerDeviceModule->InitMicrophone(); - mPeerDeviceModule->InitSpeaker(); - mPeerDeviceModule->InitRecording(); - mPeerDeviceModule->InitPlayout(); - }); + [this]() + { + // the peer device module doesn't need an observer + // as we pull peer data after audio processing. + mPeerDeviceModule = webrtc::CreateAudioDeviceWithDataObserver(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, + mTaskQueueFactory.get(), + nullptr); + mPeerDeviceModule->Init(); + mPeerDeviceModule->SetPlayoutDevice(mPlayoutDevice); + mPeerDeviceModule->SetRecordingDevice(mRecordingDevice); + mPeerDeviceModule->SetStereoRecording(true); + mPeerDeviceModule->SetStereoPlayout(true); + mPeerDeviceModule->EnableBuiltInAEC(false); + mPeerDeviceModule->InitMicrophone(); + mPeerDeviceModule->InitSpeaker(); + mPeerDeviceModule->InitRecording(); + mPeerDeviceModule->InitPlayout(); + }); // The custom processor allows us to retrieve audio data (and levels) // from after other audio processing such as AEC, AGC, etc. @@ -230,7 +226,7 @@ void LLWebRTCImpl::init() // TODO: wire some of these to the primary interface and ultimately // to the UI to allow user config. - webrtc::AudioProcessing::Config apm_config; + webrtc::AudioProcessing::Config apm_config; apm_config.echo_canceller.enabled = true; apm_config.echo_canceller.mobile_mode = false; apm_config.gain_controller1.enabled = true; @@ -268,12 +264,7 @@ void LLWebRTCImpl::init() nullptr /* audio_mixer */, apm); - - mWorkerThread->BlockingCall( - [this]() - { - mPeerDeviceModule->StartPlayout(); - }); + mWorkerThread->BlockingCall([this]() { mPeerDeviceModule->StartPlayout(); }); } void LLWebRTCImpl::terminate() @@ -337,128 +328,115 @@ void LLWebRTCImpl::setDevicesObserver(LLWebRTCDevicesObserver *observer) { mVoic void LLWebRTCImpl::unsetDevicesObserver(LLWebRTCDevicesObserver *observer) { std::vector<LLWebRTCDevicesObserver *>::iterator it = - std::find(mVoiceDevicesObserverList.begin(), mVoiceDevicesObserverList.end(), observer); + std::find(mVoiceDevicesObserverList.begin(), mVoiceDevicesObserverList.end(), observer); if (it != mVoiceDevicesObserverList.end()) { mVoiceDevicesObserverList.erase(it); } } -// TODO: There's potential for shared code here as the patterns -// are similar. +static int16_t ll_get_device_module_capture_device(rtc::scoped_refptr<webrtc::AudioDeviceModule> device_module, const std::string &id) +{ + int16_t recordingDevice = 0; + int16_t captureDeviceCount = device_module->RecordingDevices(); + for (int16_t i = 0; i < captureDeviceCount; i++) + { + char name[webrtc::kAdmMaxDeviceNameSize]; + char guid[webrtc::kAdmMaxGuidSize]; + device_module->RecordingDeviceName(i, name, guid); + if (id == guid || id == "Default") // first one in list is default + { + RTC_LOG(LS_INFO) << __FUNCTION__ << "Set recording device to " << name << " " << guid << " " << i; + recordingDevice = i; + break; + } + } + return recordingDevice; +} + +void ll_set_device_module_capture_device(rtc::scoped_refptr<webrtc::AudioDeviceModule> device_module, int16_t device) +{ + device_module->StopRecording(); + device_module->SetRecordingDevice(device); + device_module->InitMicrophone(); + device_module->SetStereoRecording(false); + device_module->InitRecording(); + device_module->StartRecording(); +} + void LLWebRTCImpl::setCaptureDevice(const std::string &id) { + mWorkerThread->PostTask( - [this, id]() - { - int16_t tuningRecordingDevice = 0; - int16_t captureDeviceCount = mTuningDeviceModule->RecordingDevices(); - for (int16_t i = 0; i < captureDeviceCount; i++) - { - char name[webrtc::kAdmMaxDeviceNameSize]; - char guid[webrtc::kAdmMaxGuidSize]; - mTuningDeviceModule->RecordingDeviceName(i, name, guid); - if (id == guid || id == "Default") // first one in list is default - { - RTC_LOG(LS_INFO) << __FUNCTION__ << "Set recording device to " << name << " " << guid << " " << i; - tuningRecordingDevice = i; - break; - } - } - mTuningDeviceModule->StopRecording(); - mTuningDeviceModule->SetRecordingDevice(tuningRecordingDevice); - mTuningDeviceModule->InitMicrophone(); - mTuningDeviceModule->InitRecording(); - mTuningDeviceModule->StartRecording(); - if (mPeerDeviceModule) - { - int16_t captureDeviceCount = mPeerDeviceModule->RecordingDevices(); - for (int16_t i = 0; i < captureDeviceCount; i++) - { - char name[webrtc::kAdmMaxDeviceNameSize]; - char guid[webrtc::kAdmMaxGuidSize]; - mPeerDeviceModule->RecordingDeviceName(i, name, guid); - if (id == guid || id == "Default") // first one in list is default - { - RTC_LOG(LS_INFO) - << __FUNCTION__ << "Set recording device to " << name << " " << guid << " " << i; - mRecordingDevice = i; - break; - } - } - bool was_peer_recording = mPeerDeviceModule->Recording(); - if (was_peer_recording) - { - mPeerDeviceModule->StopRecording(); - } - mPeerDeviceModule->SetRecordingDevice(mRecordingDevice); - mPeerDeviceModule->InitMicrophone(); - mPeerDeviceModule->InitRecording(); - if (was_peer_recording) - { - mPeerDeviceModule->StartRecording(); - } - } - }); + [this, id]() + { + int16_t recordingDevice = ll_get_device_module_capture_device(mTuningDeviceModule, id); + if (recordingDevice != mRecordingDevice) + { + mRecordingDevice = recordingDevice; + if (mTuningMode) + { + ll_set_device_module_capture_device(mTuningDeviceModule, recordingDevice); + } + else + { + ll_set_device_module_capture_device(mPeerDeviceModule, recordingDevice); + } + } + }); +} + +static int16_t ll_get_device_module_render_device( + rtc::scoped_refptr<webrtc::AudioDeviceModule> device_module, + const std::string &id) +{ + int16_t playoutDevice = 0; + int16_t playoutDeviceCount = device_module->PlayoutDevices(); + for (int16_t i = 0; i < playoutDeviceCount; i++) + { + char name[webrtc::kAdmMaxDeviceNameSize]; + char guid[webrtc::kAdmMaxGuidSize]; + device_module->PlayoutDeviceName(i, name, guid); + if (id == guid || id == "Default") // first one in list is default + { + RTC_LOG(LS_INFO) << __FUNCTION__ << "Set recording device to " << name << " " << guid << " " << i; + playoutDevice = i; + break; + } + } + return playoutDevice; +} + + +void ll_set_device_module_render_device(rtc::scoped_refptr<webrtc::AudioDeviceModule> device_module, int16_t device) +{ + device_module->StopPlayout(); + device_module->SetPlayoutDevice(device); + device_module->InitSpeaker(); + device_module->SetStereoPlayout(false); + device_module->InitPlayout(); + device_module->StartPlayout(); } void LLWebRTCImpl::setRenderDevice(const std::string &id) { mWorkerThread->PostTask( - [this, id]() - { - int16_t renderDeviceCount = mTuningDeviceModule->PlayoutDevices(); - int16_t tuningPlayoutDevice = 0; - for (int16_t i = 0; i < renderDeviceCount; i++) - { - char name[webrtc::kAdmMaxDeviceNameSize]; - char guid[webrtc::kAdmMaxGuidSize]; - mTuningDeviceModule->PlayoutDeviceName(i, name, guid); - if (id == guid || id == "Default") - { - RTC_LOG(LS_INFO) << __FUNCTION__ << "Set playout device to " << name << " " << guid << " " << i; - tuningPlayoutDevice = i; - break; - } - } - bool was_tuning_playing = mTuningDeviceModule->Playing(); - if (was_tuning_playing) - { - mTuningDeviceModule->StopPlayout(); - } - - mTuningDeviceModule->SetPlayoutDevice(tuningPlayoutDevice); - mTuningDeviceModule->InitSpeaker(); - mTuningDeviceModule->InitPlayout(); - if (was_tuning_playing) - { - mTuningDeviceModule->StartPlayout(); - } - - if (mPeerDeviceModule) - { - renderDeviceCount = mPeerDeviceModule->PlayoutDevices(); - for (int16_t i = 0; i < renderDeviceCount; i++) - { - char name[webrtc::kAdmMaxDeviceNameSize]; - char guid[webrtc::kAdmMaxGuidSize]; - mPeerDeviceModule->PlayoutDeviceName(i, name, guid); - if (id == guid || id == "Default") - { - RTC_LOG(LS_INFO) - << __FUNCTION__ << "Set playout device to " << name << " " << guid << " " << i; - mPlayoutDevice = i; - break; - } - } - mPeerDeviceModule->StopPlayout(); - mPeerDeviceModule->SetPlayoutDevice(mPlayoutDevice); - mPeerDeviceModule->InitSpeaker(); - mPeerDeviceModule->InitPlayout(); - mPeerDeviceModule->StartPlayout(); - - } - }); + [this, id]() + { + int16_t playoutDevice = ll_get_device_module_render_device(mTuningDeviceModule, id); + if (playoutDevice != mPlayoutDevice) + { + mPlayoutDevice = playoutDevice; + if (mTuningMode) + { + ll_set_device_module_render_device(mTuningDeviceModule, playoutDevice); + } + else + { + ll_set_device_module_render_device(mPeerDeviceModule, playoutDevice); + } + } + }); } // updateDevices needs to happen on the worker thread. @@ -473,7 +451,7 @@ void LLWebRTCImpl::updateDevices() char name[webrtc::kAdmMaxDeviceNameSize]; char guid[webrtc::kAdmMaxGuidSize]; mTuningDeviceModule->PlayoutDeviceName(index, name, guid); - renderDeviceList.emplace_back(name, guid, index == currentRenderDeviceIndex); + renderDeviceList.emplace_back(name, guid); } int16_t captureDeviceCount = mTuningDeviceModule->RecordingDevices(); @@ -485,7 +463,7 @@ void LLWebRTCImpl::updateDevices() char name[webrtc::kAdmMaxDeviceNameSize]; char guid[webrtc::kAdmMaxGuidSize]; mTuningDeviceModule->RecordingDeviceName(index, name, guid); - captureDeviceList.emplace_back(name, guid, index == currentCaptureDeviceIndex); + captureDeviceList.emplace_back(name, guid); } for (auto &observer : mVoiceDevicesObserverList) { @@ -502,6 +480,29 @@ void LLWebRTCImpl::OnDevicesUpdated() void LLWebRTCImpl::setTuningMode(bool enable) { + mTuningMode = enable; + mWorkerThread->PostTask( + [this, enable] { + if (enable) + { + mPeerDeviceModule->StopRecording(); + mPeerDeviceModule->StopPlayout(); + ll_set_device_module_render_device(mTuningDeviceModule, mPlayoutDevice); + ll_set_device_module_capture_device(mTuningDeviceModule, mRecordingDevice); + mTuningDeviceModule->StartRecording(); + mTuningDeviceModule->StartPlayout(); + } + else + { + mTuningDeviceModule->StopRecording(); + mTuningDeviceModule->StopPlayout(); + ll_set_device_module_render_device(mPeerDeviceModule, mPlayoutDevice); + ll_set_device_module_capture_device(mPeerDeviceModule, mRecordingDevice); + mPeerDeviceModule->StartRecording(); + mPeerDeviceModule->StartPlayout(); + } + } + ); mSignalingThread->PostTask( [this, enable] { diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h index 43b48e79ab..dab7774499 100644 --- a/indra/llwebrtc/llwebrtc.h +++ b/indra/llwebrtc/llwebrtc.h @@ -74,12 +74,10 @@ class LLWebRTCVoiceDevice public: std::string mDisplayName; // friendly name for user interface purposes std::string mID; // internal value for selection - bool mCurrent; // current device - LLWebRTCVoiceDevice(const std::string &display_name, const std::string &id, bool current) : + LLWebRTCVoiceDevice(const std::string &display_name, const std::string &id) : mDisplayName(display_name), - mID(id), - mCurrent(current) + mID(id) {}; }; diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index 16afec061e..1f696e8c66 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -40,8 +40,11 @@ #include "llwebrtc.h" // WebRTC Includes #ifdef WEBRTC_WIN -#pragma warning(disable : 4996) -#pragma warning(disable : 4068) +#pragma warning(disable : 4996) // ignore 'deprecated.' We don't use the functions marked + // deprecated in the webrtc headers, but msvc complains anyway. + // Clang doesn't, and that's generally what webrtc uses. +#pragma warning(disable : 4068) // ignore 'invalid pragma.' There are clang pragma's in + // the webrtc headers, which msvc doesn't recognize. #endif // WEBRTC_WIN #include "api/scoped_refptr.h" @@ -236,6 +239,7 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS std::vector<LLWebRTCDevicesObserver *> mVoiceDevicesObserverList; // accessors in native webrtc for devices aren't apparently implemented yet. + bool mTuningMode; int32_t mPlayoutDevice; int32_t mRecordingDevice; bool mMute; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 921e757b58..215cc4103b 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -87,7 +87,10 @@ const S32 XL8_PADDING = 3; // XL8_START_TAG.size() + XL8_END_TAG.size() /** Timeout of outgoing session initialization (in seconds) */ const static U32 SESSION_INITIALIZATION_TIMEOUT = 30; - +// This enum corresponds to the sim's and adds P2P_CHAT_SESSION, +// as webrtc uses the multiagent chat mechanism for p2p calls, +// instead of relying on vivox calling. +// Don't change this without consulting a server developer. enum EMultiAgentChatSessionType { GROUP_CHAT_SESSION = 0, diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 28e895584b..f6658bbaab 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -418,7 +418,7 @@ void LLVoiceChannelGroup::activate() { // we have the channel info, just need to use it now LLVoiceClient::getInstance()->setNonSpatialChannel(mChannelInfo, - mCallDirection == OUTGOING_CALL, + mIsP2P && (mCallDirection == OUTGOING_CALL), mIsP2P); if (mIsP2P) @@ -732,7 +732,7 @@ void LLVoiceChannelProximal::handleError(EStatusType status) LLNotificationsUtil::add(notify, mNotifyArgs); } - LLVoiceChannel::handleError(status); + // proximal voice remains up and the provider will try to reconnect. } void LLVoiceChannelProximal::deactivate() @@ -741,6 +741,7 @@ void LLVoiceChannelProximal::deactivate() { setState(STATE_HUNG_UP); } + LLVoiceClient::getInstance()->activateSpatialChannel(false); } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index b9b8742c41..9dbf469ca8 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -382,14 +382,14 @@ void LLVoiceClient::refreshDeviceLists(bool clearCurrentList) void LLVoiceClient::setCaptureDevice(const std::string& name) { + LLVivoxVoiceClient::getInstance()->setCaptureDevice(name); LLWebRTCVoiceClient::getInstance()->setCaptureDevice(name); - LLVivoxVoiceClient::getInstance()->setCaptureDevice(name); } void LLVoiceClient::setRenderDevice(const std::string& name) { + LLVivoxVoiceClient::getInstance()->setRenderDevice(name); LLWebRTCVoiceClient::getInstance()->setRenderDevice(name); - LLVivoxVoiceClient::getInstance()->setRenderDevice(name); } const LLVoiceDeviceList& LLVoiceClient::getCaptureDevices() diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 2bb16cb336..7be02c1e21 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -92,6 +92,7 @@ namespace { // Don't send positional updates more frequently than this: const F32 UPDATE_THROTTLE_SECONDS = 0.1f; + const F32 MAX_RETRY_WAIT_SECONDS = 10.0f; // Cosine of a "trivially" small angle const F32 FOUR_DEGREES = 4.0f * (F_PI / 180.0f); @@ -590,14 +591,15 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi 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(); bool renderDeviceSet = false; for (auto &device : render_devices) { addRenderDevice(LLVoiceDevice(device.mDisplayName, device.mID)); - if (device.mCurrent && outputDevice == device.mID) + LL_DEBUGS("Voice") << "Checking render device" << "'" << device.mID << "'" << LL_ENDL; + if (outputDevice == device.mID) { - setRenderDevice(outputDevice); renderDeviceSet = true; } } @@ -610,10 +612,11 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi bool captureDeviceSet = false; for (auto &device : capture_devices) { + LL_DEBUGS("Voice") << "Checking capture device:'" << device.mID << "'" << LL_ENDL; + addCaptureDevice(LLVoiceDevice(device.mDisplayName, device.mID)); - if (device.mCurrent && inputDevice == device.mID) + if (inputDevice == device.mID) { - setCaptureDevice(outputDevice); captureDeviceSet = true; } } @@ -1988,8 +1991,13 @@ LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID ®ionID, const s mMicGain(0.0), mOutstandingRequests(0), mChannelID(channelID), - mRegionID(regionID) + mRegionID(regionID), + mRetryWaitPeriod(0) { + // retries wait a short period...randomize it so + // all clients don't try to reconnect at once. + mRetryWaitSecs = ((F32) rand() / (RAND_MAX)) + 0.5; + mWebRTCPeerConnectionInterface = llwebrtc::newPeerConnection(); mWebRTCPeerConnectionInterface->setSignalingObserver(this); } @@ -2404,7 +2412,7 @@ bool LLVoiceWebRTCSpatialConnection::requestVoiceConnection() { body["parcel_local_id"] = mParcelLocalID; } - + body["channel_type"] = "local"; body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( @@ -2567,6 +2575,9 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() case VOICE_STATE_SESSION_UP: { + mRetryWaitPeriod = 0; + mRetryWaitSecs = ((F32) rand() / (RAND_MAX)) + 0.5; + // we'll stay here as long as the session remains up. if (mShutDown) { @@ -2576,9 +2587,21 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() } case VOICE_STATE_SESSION_RETRY: - // something went wrong, so notify that the connection has failed. - LLWebRTCVoiceClient::getInstance()->OnConnectionFailure(mChannelID, mRegionID); - setVoiceConnectionState(VOICE_STATE_DISCONNECT); + // only retry ever 'n' seconds + if (mRetryWaitPeriod++ * UPDATE_THROTTLE_SECONDS > mRetryWaitSecs) + { + // something went wrong, so notify that the connection has failed. + LLWebRTCVoiceClient::getInstance()->OnConnectionFailure(mChannelID, mRegionID); + setVoiceConnectionState(VOICE_STATE_DISCONNECT); + mRetryWaitPeriod = 0; + if (mRetryWaitSecs < MAX_RETRY_WAIT_SECONDS) + { + // back off the retry period, and do it by a small random + // bit so all clients don't reconnect at once. + mRetryWaitSecs += ((F32) rand() / (RAND_MAX)) + 0.5; + mRetryWaitPeriod = 0; + } + } break; case VOICE_STATE_DISCONNECT: diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index 03bbe00162..b26bea27ce 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -694,6 +694,12 @@ class LLVoiceWebRTCConnection : bool mShutDown; S32 mOutstandingRequests; + S32 mRetryWaitPeriod; // number of UPDATE_THROTTLE_SECONDS we've + // waited since our last attempt to connect. + F32 mRetryWaitSecs; // number of seconds to wait before next retry + + + std::vector<llwebrtc::LLWebRTCIceCandidate> mIceCandidates; bool mIceCompleted; bool mTrickling; |