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.cpp156
1 files changed, 90 insertions, 66 deletions
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 22b53c0b85..facda1d876 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"
@@ -87,6 +87,8 @@ namespace {
const F32 SPEAKING_AUDIO_LEVEL = 0.30;
+ const uint32_t PEER_GAIN_CONVERSION_FACTOR = 220;
+
static const std::string REPORTED_VOICE_SERVER_TYPE = "Secondlife WebRTC Gateway";
// Don't send positional updates more frequently than this:
@@ -256,6 +258,8 @@ void LLWebRTCVoiceClient::cleanupSingleton()
}
cleanUp();
sessionState::clearSessions();
+
+ mStatusObservers.clear();
}
//---------------------------------------------------
@@ -341,6 +345,8 @@ void LLWebRTCVoiceClient::updateSettings()
static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
setRenderDevice(sOutputDevice);
+ LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL;
+
static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
setMicGain(sMicLevel);
@@ -401,8 +407,9 @@ void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESt
LL_DEBUGS("Voice") << "( " << LLVoiceClientStatusObserver::status2string(status) << " )"
<< " mSession=" << mSession << LL_ENDL;
+ bool in_spatial_channel = inSpatialChannel();
LL_DEBUGS("Voice") << " " << LLVoiceClientStatusObserver::status2string(status) << ", session channelInfo "
- << getAudioSessionChannelInfo() << ", proximal is " << inSpatialChannel() << LL_ENDL;
+ << getAudioSessionChannelInfo() << ", proximal is " << in_spatial_channel << LL_ENDL;
mIsProcessingChannels = status == LLVoiceClientStatusObserver::STATUS_JOINED;
@@ -410,7 +417,7 @@ void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESt
for (status_observer_set_t::iterator it = mStatusObservers.begin(); it != mStatusObservers.end();)
{
LLVoiceClientStatusObserver *observer = *it;
- observer->onChange(status, channelInfo, inSpatialChannel());
+ observer->onChange(status, channelInfo, in_spatial_channel);
// In case onError() deleted an entry.
it = mStatusObservers.upper_bound(observer);
}
@@ -420,7 +427,7 @@ void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESt
status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL &&
status != LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED)
{
- bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
+ bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && mIsProcessingChannels;
gAgent.setVoiceConnected(voice_status);
@@ -549,7 +556,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
}
}
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (sShuttingDown)
{
return;
@@ -667,7 +674,7 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=]
+ [=, this]
{
OnDevicesChangedImpl(render_devices, capture_devices);
});
@@ -891,7 +898,7 @@ void LLWebRTCVoiceClient::OnConnectionShutDown(const std::string &channelID, con
{
if (mSession && mSession->mChannelID == channelID)
{
- LL_DEBUGS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
+ LL_INFOS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
}
}
mSession->removeAllParticipants(regionID);
@@ -978,7 +985,10 @@ 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();
+ setMuteMic(mMuteMic);
+ }
}
}
}
@@ -1335,7 +1345,10 @@ bool LLWebRTCVoiceClient::startAdHocSession(const LLSD& channelInfo, bool notify
bool LLWebRTCVoiceClient::isVoiceWorking() const
{
- return mIsProcessingChannels;
+ // 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;
}
// Returns true if calling back the session URI after the session has closed is possible.
@@ -1496,6 +1509,11 @@ bool LLWebRTCVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &
// we're muting the mic, so tell each session such
void LLWebRTCVoiceClient::setMuteMic(bool muted)
{
+ if (mMuteMic != muted)
+ {
+ LL_INFOS("Voice") << "( " << (muted ? "true" : "false") << " )" << LL_ENDL;
+ }
+
mMuteMic = muted;
// when you're hidden, your mic is always muted.
if (!mHidden)
@@ -1544,14 +1562,10 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- LL_DEBUGS("Voice")
- << "( " << (enabled ? "enabled" : "disabled") << " )"
- << " was "<< (mVoiceEnabled ? "enabled" : "disabled")
- << " coro "<< (mIsCoroutineActive ? "active" : "inactive")
- << LL_ENDL;
-
if (enabled != mVoiceEnabled)
{
+ LL_INFOS("Voice") << "( " << (enabled ? "enabled" : "disabled") << " )"
+ << ", coro: " << (mIsCoroutineActive ? "active" : "inactive") << LL_ENDL;
// TODO: Refactor this so we don't call into LLVoiceChannel, but simply
// use the status observer
mVoiceEnabled = enabled;
@@ -2012,7 +2026,10 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
// shut down connections to neighbors that are too far away.
spatialConnection.get()->shutDown();
}
- neighbor_ids.erase(regionID);
+ if (!spatialConnection.get()->isShuttingDown())
+ {
+ neighbor_ids.erase(regionID);
+ }
}
// add new connections for new neighbors
@@ -2197,7 +2214,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)
@@ -2220,7 +2237,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()
@@ -2338,7 +2355,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;
@@ -2365,7 +2382,7 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;
@@ -2387,7 +2404,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)
{
@@ -2401,7 +2418,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)
{
@@ -2437,7 +2454,7 @@ void LLVoiceWebRTCConnection::setSpeakerVolume(F32 volume)
void LLVoiceWebRTCConnection::setUserVolume(const LLUUID& id, F32 volume)
{
- boost::json::object root = {{"ug", {id.asString(), (uint32_t) (volume * 200)}}};
+ boost::json::object root = { { "ug", { { id.asString(), (uint32_t)(volume * PEER_GAIN_CONVERSION_FACTOR) } } } };
std::string json_data = boost::json::serialize(root);
if (mWebRTCDataInterface)
{
@@ -2447,7 +2464,7 @@ void LLVoiceWebRTCConnection::setUserVolume(const LLUUID& id, F32 volume)
void LLVoiceWebRTCConnection::setUserMute(const LLUUID& id, bool mute)
{
- boost::json::object root = {{"m", {id.asString(), mute}}};
+ boost::json::object root = { { "m", { { id.asString(), mute } } } };
std::string json_data = boost::json::serialize(root);
if (mWebRTCDataInterface)
{
@@ -2472,7 +2489,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL;
+ LL_INFOS("Voice") << "Disconnecting voice." << LL_ENDL;
if (connection->mWebRTCDataInterface)
{
connection->mWebRTCDataInterface->unsetDataObserver(connection.get());
@@ -2512,8 +2529,6 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
httpOpts->setWantHeaders(true);
- connection->mOutstandingRequests++;
-
// tell the server to shut down the connection as a courtesy.
// shutdownConnection will drop the WebRTC connection which will
// also shut things down.
@@ -2544,6 +2559,7 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
// try again.
setVoiceConnectionState(VOICE_STATE_REQUEST_CONNECTION);
+ mOutstandingRequests--;
return;
}
@@ -2551,6 +2567,7 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
if (url.empty())
{
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ mOutstandingRequests--;
return;
}
@@ -2575,12 +2592,12 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
- mOutstandingRequests++;
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ LL_INFOS("Voice") << "Voice connection request: " << (status ? "Success" : status.toString()) << LL_ENDL;
if (status)
{
OnVoiceConnectionRequestSuccess(result);
@@ -2663,7 +2680,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- processIceUpdates();
+ if (!mShutDown)
+ {
+ processIceUpdates();
+ }
switch (getVoiceConnectionState())
{
@@ -2707,6 +2727,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
// a given voice channel. On completion, we'll move on to the
// VOICE_STATE_SESSION_ESTABLISHED via a callback on a webrtc thread.
setVoiceConnectionState(VOICE_STATE_CONNECTION_WAIT);
+ mOutstandingRequests++;
LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::requestVoiceConnectionCoro",
boost::bind(&LLVoiceWebRTCConnection::requestVoiceConnectionCoro, this->shared_from_this()));
break;
@@ -2757,24 +2778,25 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
case VOICE_STATE_SESSION_UP:
{
mRetryWaitPeriod = 0;
- mRetryWaitSecs = (F32)((F32) rand() / (RAND_MAX)) + 0.5f;
- LLUUID agentRegionID;
- if (isSpatial() && gAgent.getRegion())
- {
-
- bool primary = (mRegionID == gAgent.getRegion()->getRegionID());
- if (primary != mPrimary)
- {
- mPrimary = primary;
- sendJoin();
- }
- }
+ mRetryWaitSecs = (F32)((F32)rand() / (RAND_MAX)) + 0.5f;
// we'll stay here as long as the session remains up.
if (mShutDown)
{
setVoiceConnectionState(VOICE_STATE_DISCONNECT);
}
+ else
+ {
+ if (isSpatial() && gAgent.getRegion())
+ {
+ bool primary = (mRegionID == gAgent.getRegion()->getRegionID());
+ if (primary != mPrimary)
+ {
+ mPrimary = primary;
+ sendJoin();
+ }
+ }
+ }
break;
}
@@ -2799,6 +2821,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
case VOICE_STATE_DISCONNECT:
if (!LLWebRTCVoiceClient::isShuttingDown())
{
+ mOutstandingRequests++;
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT);
LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro",
boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this->shared_from_this()));
@@ -2807,7 +2830,6 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
{
// llwebrtc::terminate() is already shuting down the connection.
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_CLOSE);
- mOutstandingRequests++;
}
break;
@@ -2869,7 +2891,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); });
}
//
@@ -2976,7 +2998,9 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
// we got a 'power' update.
if (participant_obj.contains("p") && participant_obj["p"].is_number())
{
- participant->mLevel = (F32)participant_obj["p"].as_int64();
+ // server sends up power as an integer which is level * 128 to save
+ // character count.
+ participant->mLevel = (F32)participant_obj["p"].as_int64()/128.0f;
}
if (participant_obj.contains("v") && participant_obj["v"].is_bool())
@@ -2984,10 +3008,9 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
participant->mIsSpeaking = participant_obj["v"].as_bool();
}
- if (participant_obj.contains("v") && participant_obj["m"].is_bool())
+ if (participant_obj.contains("m") && participant_obj["m"].is_bool())
{
participant->mIsModeratorMuted = participant_obj["m"].as_bool();
- ;
}
}
}
@@ -3004,7 +3027,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);
@@ -3024,7 +3047,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;
@@ -3047,11 +3070,13 @@ 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;
- LLUUID regionID = gAgent.getRegion()->getRegionID();
if (mPrimary)
{
join_obj["p"] = true;
@@ -3082,23 +3107,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);
}
}
}
@@ -3134,6 +3156,7 @@ void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; retrying " << LL_ENDL;
// try again.
setVoiceConnectionState(VOICE_STATE_REQUEST_CONNECTION);
+ mOutstandingRequests--;
return;
}
@@ -3141,6 +3164,7 @@ void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
if (url.empty())
{
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ mOutstandingRequests--;
return;
}
@@ -3164,7 +3188,7 @@ void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
- mOutstandingRequests++;
+
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];