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.cpp248
1 files changed, 132 insertions, 116 deletions
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 7161f5af5e..6d4f3fe356 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -203,6 +203,7 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
mTuningMode(false),
mTuningMicGain(0.0),
mTuningSpeakerVolume(50), // Set to 50 so the user can hear themselves when he sets his mic volume
+ mDeviceSettingsAvailable(false),
mDevicesListUpdated(false),
mSpatialCoordsDirty(false),
@@ -218,7 +219,7 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
mAvatarNameCacheConnection(),
mIsInTuningMode(false),
mIsProcessingChannels(false),
- mIsCoroutineActive(false),
+ mIsTimerActive(false),
mWebRTCPump("WebRTCClientPump"),
mWebRTCDeviceInterface(nullptr)
{
@@ -295,6 +296,20 @@ void LLWebRTCVoiceClient::cleanUp()
mNeighboringRegions.clear();
sessionState::for_each(boost::bind(predShutdownSession, _1));
LL_DEBUGS("Voice") << "Exiting" << LL_ENDL;
+ stopTimer();
+}
+
+void LLWebRTCVoiceClient::stopTimer()
+{
+ if (mIsTimerActive)
+ {
+ LLMuteList::instanceExists();
+ {
+ LLMuteList::getInstance()->removeObserver(this);
+ }
+ mIsTimerActive = false;
+ LL::Timers::instance().cancel(mVoiceTimerHandle);
+ }
}
void LLWebRTCVoiceClient::LogMessage(llwebrtc::LLWebRTCLogCallback::LogLevel level, const std::string& message)
@@ -443,8 +458,7 @@ void LLWebRTCVoiceClient::removeObserver(LLFriendObserver *observer)
//---------------------------------------------------
// Primary voice loop.
-// This voice loop is called every 100ms plus the time it
-// takes to process the various functions called in the loop
+// This voice loop is called every 100ms
// The loop does the following:
// * gates whether we do channel processing depending on
// whether we're running a WebRTC voice channel or
@@ -456,102 +470,94 @@ void LLWebRTCVoiceClient::removeObserver(LLFriendObserver *observer)
// connection to various voice channels.
// * Sends updates to the voice server when this agent's
// voice levels, or positions have changed.
-void LLWebRTCVoiceClient::voiceConnectionCoro()
+void LLWebRTCVoiceClient::connectionTimer()
{
- LL_DEBUGS("Voice") << "starting" << LL_ENDL;
- mIsCoroutineActive = true;
- LLCoros::set_consuming(true);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
try
{
- LLMuteList::getInstance()->addObserver(this);
- while (!sShuttingDown)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_VOICE("voiceConnectionCoroLoop")
- // TODO: Doing some measurement and calculation here,
- // we could reduce the timeout to take into account the
- // time spent on the previous loop to have the loop
- // cycle at exactly 100ms, instead of 100ms + loop
- // execution time.
- // Could help with voice updates making for smoother
- // voice when we're busy.
- llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
- if (sShuttingDown) return; // 'this' migh already be invalid
- bool voiceEnabled = mVoiceEnabled;
-
- if (!isAgentAvatarValid())
+ bool voiceEnabled = mVoiceEnabled;
+
+ if (!isAgentAvatarValid())
+ {
+ if (sShuttingDown)
{
- continue;
+ cleanUp();
}
+ return;
+ }
- LLViewerRegion *regionp = gAgent.getRegion();
- if (!regionp)
+ LLViewerRegion* regionp = gAgent.getRegion();
+ if (!regionp)
+ {
+ if (sShuttingDown)
{
- continue;
+ cleanUp();
}
+ return;
+ }
- if (!mProcessChannels)
+ if (!mProcessChannels)
+ {
+ // we've switched away from webrtc voice, so shut all channels down.
+ // leave channel can be called again and again without adverse effects.
+ // it merely tells channels to shut down if they're not already doing so.
+ leaveChannel(false);
+ }
+ else if (inSpatialChannel())
+ {
+ bool useEstateVoice = true;
+ // add session for region or parcel voice.
+ if (!regionp || regionp->getRegionID().isNull())
{
- // we've switched away from webrtc voice, so shut all channels down.
- // leave channel can be called again and again without adverse effects.
- // it merely tells channels to shut down if they're not already doing so.
- leaveChannel(false);
+ // no region, no voice.
+ return;
}
- else if (inSpatialChannel())
- {
- bool useEstateVoice = true;
- // add session for region or parcel voice.
- if (!regionp || regionp->getRegionID().isNull())
- {
- // no region, no voice.
- continue;
- }
- voiceEnabled = voiceEnabled && regionp->isVoiceEnabled();
+ voiceEnabled = voiceEnabled && regionp->isVoiceEnabled();
- if (voiceEnabled)
+ if (voiceEnabled)
+ {
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ // check to see if parcel changed.
+ if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID)
{
- LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- // check to see if parcel changed.
- if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID)
+ // parcel voice
+ if (!parcel->getParcelFlagAllowVoice())
{
- // parcel voice
- if (!parcel->getParcelFlagAllowVoice())
- {
- voiceEnabled = false;
- }
- else if (!parcel->getParcelFlagUseEstateVoiceChannel())
- {
- // use the parcel-specific voice channel.
- S32 parcel_local_id = parcel->getLocalID();
- std::string channelID = regionp->getRegionID().asString() + "-" + std::to_string(parcel->getLocalID());
-
- useEstateVoice = false;
- if (!inOrJoiningChannel(channelID))
- {
- startParcelSession(channelID, parcel_local_id);
- }
- }
+ voiceEnabled = false;
}
- if (voiceEnabled && useEstateVoice && !inEstateChannel())
+ else if (!parcel->getParcelFlagUseEstateVoiceChannel())
{
- // estate voice
- startEstateSession();
+ // use the parcel-specific voice channel.
+ S32 parcel_local_id = parcel->getLocalID();
+ std::string channelID = regionp->getRegionID().asString() + "-" + std::to_string(parcel->getLocalID());
+
+ useEstateVoice = false;
+ if (!inOrJoiningChannel(channelID))
+ {
+ startParcelSession(channelID, parcel_local_id);
+ }
}
}
- if (!voiceEnabled)
+ if (voiceEnabled && useEstateVoice && !inEstateChannel())
{
- // voice is disabled, so leave and disable PTT
- leaveChannel(true);
- }
- else
- {
- // we're in spatial voice, and voice is enabled, so determine positions in order
- // to send position updates.
- updatePosition();
+ // estate voice
+ startEstateSession();
}
}
+ if (!voiceEnabled)
+ {
+ // voice is disabled, so leave and disable PTT
+ leaveChannel(true);
+ }
+ else
+ {
+ // we're in spatial voice, and voice is enabled, so determine positions in order
+ // to send position updates.
+ updatePosition();
+ }
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (sShuttingDown)
{
return;
@@ -565,10 +571,6 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
});
}
}
- catch (const LLCoros::Stop&)
- {
- LL_DEBUGS("LLWebRTCVoiceClient") << "Received a shutdown exception" << LL_ENDL;
- }
catch (const LLContinueError&)
{
LOG_UNHANDLED_EXCEPTION("LLWebRTCVoiceClient");
@@ -582,7 +584,10 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
throw;
}
- cleanUp();
+ if (sShuttingDown)
+ {
+ cleanUp();
+ }
}
// For spatial, determine which neighboring regions to connect to
@@ -640,12 +645,14 @@ void LLWebRTCVoiceClient::leaveAudioSession()
void LLWebRTCVoiceClient::clearCaptureDevices()
{
LL_DEBUGS("Voice") << "called" << LL_ENDL;
+ mDeviceSettingsAvailable = false;
mCaptureDevices.clear();
}
void LLWebRTCVoiceClient::addCaptureDevice(const LLVoiceDevice& device)
{
LL_INFOS("Voice") << "Voice Capture Device: '" << device.display_name << "' (" << device.full_name << ")" << LL_ENDL;
+ mDeviceSettingsAvailable = false;
mCaptureDevices.push_back(device);
}
@@ -658,6 +665,7 @@ void LLWebRTCVoiceClient::setCaptureDevice(const std::string& name)
{
mWebRTCDeviceInterface->setCaptureDevice(name);
}
+
void LLWebRTCVoiceClient::setDevicesListUpdated(bool state)
{
mDevicesListUpdated = state;
@@ -669,7 +677,7 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=]
+ [=, this]
{
OnDevicesChangedImpl(render_devices, capture_devices);
});
@@ -703,20 +711,22 @@ void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDevi
}
setCaptureDevice(inputDevice);
+ mDeviceSettingsAvailable = true;
setDevicesListUpdated(true);
}
void LLWebRTCVoiceClient::clearRenderDevices()
{
LL_DEBUGS("Voice") << "called" << LL_ENDL;
+ mDeviceSettingsAvailable = false;
mRenderDevices.clear();
}
void LLWebRTCVoiceClient::addRenderDevice(const LLVoiceDevice& device)
{
LL_INFOS("Voice") << "Voice Render Device: '" << device.display_name << "' (" << device.full_name << ")" << LL_ENDL;
+ mDeviceSettingsAvailable = false;
mRenderDevices.push_back(device);
-
}
LLVoiceDeviceList& LLWebRTCVoiceClient::getRenderDevices()
@@ -729,6 +739,16 @@ void LLWebRTCVoiceClient::setRenderDevice(const std::string& name)
mWebRTCDeviceInterface->setRenderDevice(name);
}
+bool LLWebRTCVoiceClient::isCaptureNoDevice()
+{
+ return mCaptureDevices.empty() || mWebRTCDeviceInterface->isCaptureNoDevice();
+}
+
+bool LLWebRTCVoiceClient::isRenderNoDevice()
+{
+ return mRenderDevices.empty() || mWebRTCDeviceInterface->isRenderNoDevice();
+}
+
void LLWebRTCVoiceClient::tuningStart()
{
if (!mIsInTuningMode)
@@ -754,11 +774,15 @@ bool LLWebRTCVoiceClient::inTuningMode()
void LLWebRTCVoiceClient::tuningSetMicVolume(float volume)
{
- mTuningMicGain = volume;
+ mTuningMicGain = volume;
}
void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
{
+ if (isRenderNoDevice())
+ {
+ volume = 0;
+ }
if (volume != mTuningSpeakerVolume)
{
@@ -768,14 +792,17 @@ void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
float LLWebRTCVoiceClient::getAudioLevel()
{
- if (mIsInTuningMode)
+ if (isCaptureNoDevice())
{
- return (1.0f - mWebRTCDeviceInterface->getTuningAudioLevel() * LEVEL_SCALE_WEBRTC) * mTuningMicGain / 2.1f;
+ return 0;
}
- else
+
+ if (mIsInTuningMode)
{
- return (1.0f - mWebRTCDeviceInterface->getPeerConnectionAudioLevel() * LEVEL_SCALE_WEBRTC) * mMicGain / 2.1f;
+ return (1.0f - mWebRTCDeviceInterface->getTuningAudioLevel() * LEVEL_SCALE_WEBRTC) * mTuningMicGain / 2.1f;
}
+
+ return (1.0f - mWebRTCDeviceInterface->getPeerConnectionAudioLevel() * LEVEL_SCALE_WEBRTC) * mMicGain / 2.1f;
}
float LLWebRTCVoiceClient::tuningGetEnergy(void)
@@ -783,15 +810,6 @@ float LLWebRTCVoiceClient::tuningGetEnergy(void)
return getAudioLevel();
}
-bool LLWebRTCVoiceClient::deviceSettingsAvailable()
-{
- bool result = true;
-
- if(mRenderDevices.empty() || mCaptureDevices.empty())
- result = false;
-
- return result;
-}
bool LLWebRTCVoiceClient::deviceSettingsUpdated()
{
bool updated = mDevicesListUpdated;
@@ -801,7 +819,7 @@ bool LLWebRTCVoiceClient::deviceSettingsUpdated()
void LLWebRTCVoiceClient::refreshDeviceLists(bool clearCurrentList)
{
- if(clearCurrentList)
+ if (clearCurrentList)
{
clearCaptureDevices();
clearRenderDevices();
@@ -809,7 +827,6 @@ void LLWebRTCVoiceClient::refreshDeviceLists(bool clearCurrentList)
mWebRTCDeviceInterface->refreshDevices();
}
-
void LLWebRTCVoiceClient::setHidden(bool hidden)
{
mHidden = hidden;
@@ -1340,7 +1357,7 @@ bool LLWebRTCVoiceClient::isVoiceWorking() const
// webrtc is working if the coroutine is active in the case of
// webrtc. WebRTC doesn't need to connect to a secondary process
// or a login server to become active.
- return mIsCoroutineActive;
+ return mIsTimerActive;
}
// Returns true if calling back the session URI after the session has closed is possible.
@@ -1523,9 +1540,7 @@ void LLWebRTCVoiceClient::setVoiceVolume(F32 volume)
{
if (volume != mSpeakerVolume)
{
- {
- mSpeakerVolume = volume;
- }
+ mSpeakerVolume = volume;
sessionState::for_each(boost::bind(predSetSpeakerVolume, _1, volume));
}
}
@@ -1544,7 +1559,6 @@ void LLWebRTCVoiceClient::setMicGain(F32 gain)
}
}
-
void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
@@ -1552,7 +1566,7 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
LL_DEBUGS("Voice")
<< "( " << (enabled ? "enabled" : "disabled") << " )"
<< " was "<< (mVoiceEnabled ? "enabled" : "disabled")
- << " coro "<< (mIsCoroutineActive ? "active" : "inactive")
+ << " coro "<< (mIsTimerActive ? "active" : "inactive")
<< LL_ENDL;
if (enabled != mVoiceEnabled)
@@ -1569,10 +1583,12 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
status = LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED;
mSpatialCoordsDirty = true;
updatePosition();
- if (!mIsCoroutineActive)
+ if (!mIsTimerActive)
{
- LLCoros::instance().launch("LLWebRTCVoiceClient::voiceConnectionCoro",
- boost::bind(&LLWebRTCVoiceClient::voiceConnectionCoro, LLWebRTCVoiceClient::getInstance()));
+ LL_DEBUGS("Voice") << "Starting" << LL_ENDL;
+ mIsTimerActive = true;
+ LLMuteList::getInstance()->addObserver(this);
+ mVoiceTimerHandle = LL::Timers::instance().scheduleEvery([this]() { connectionTimer(); return false; }, UPDATE_THROTTLE_SECONDS);
}
else
{
@@ -2205,7 +2221,7 @@ LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection()
void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
LL_DEBUGS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL;
switch (state)
@@ -2228,7 +2244,7 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs
// callback from llwebrtc
void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate& candidate)
{
- LL::WorkQueue::postMaybe(mMainQueue, [=] { mIceCandidates.push_back(candidate); });
+ LL::WorkQueue::postMaybe(mMainQueue, [=, this] { mIceCandidates.push_back(candidate); });
}
void LLVoiceWebRTCConnection::processIceUpdates()
@@ -2346,7 +2362,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;
@@ -2373,7 +2389,7 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;
@@ -2395,7 +2411,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac
void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL;
if (!mShutDown)
{
@@ -2409,7 +2425,7 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
void LLVoiceWebRTCConnection::OnPeerConnectionClosed()
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
LL_DEBUGS("Voice") << "Peer connection has closed." << LL_ENDL;
if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_CLOSE)
{
@@ -2881,7 +2897,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
// llwebrtc callback
void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binary)
{
- LL::WorkQueue::postMaybe(mMainQueue, [=] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); });
+ LL::WorkQueue::postMaybe(mMainQueue, [=, this] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); });
}
//
@@ -3037,7 +3053,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;