summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llprofilercategories.h13
-rw-r--r--indra/llwebrtc/llwebrtc.cpp27
-rw-r--r--indra/newview/llvoicewebrtc.cpp266
-rw-r--r--indra/newview/llvoicewebrtc.h15
4 files changed, 200 insertions, 121 deletions
diff --git a/indra/llcommon/llprofilercategories.h b/indra/llcommon/llprofilercategories.h
index 617431f629..0de343d020 100644
--- a/indra/llcommon/llprofilercategories.h
+++ b/indra/llcommon/llprofilercategories.h
@@ -1,5 +1,5 @@
/**
- * @file llprofiler_ategories.h
+ * @file llprofilercategories.h
* @brief Profiling categories to minimize Tracy memory usage when viewing captures.
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
@@ -33,7 +33,7 @@
// LL_PROFILER_CATEGORY_ENABLE_DRAWPOOL
// LL_PROFILER_CATEGORY_ENABLE_LLSD
// LL_PROFILER_CATEGORY_ENABLE_MEMORY
-// LL_PROFILER_CATEGORY_ENABLE_SHADERS
+// LL_PROFILER_CATEGORY_ENABLE_SHADER
//
// NOTE: You can still manually use:
// LL_PROFILE_ZONE_SCOPED();
@@ -67,6 +67,7 @@
#define LL_PROFILER_CATEGORY_ENABLE_VERTEX 1
#define LL_PROFILER_CATEGORY_ENABLE_VOLUME 1
#define LL_PROFILER_CATEGORY_ENABLE_WIN32 1
+#define LL_PROFILER_CATEGORY_ENABLE_VOICE 1
#if LL_PROFILER_CATEGORY_ENABLE_APP
#define LL_PROFILE_ZONE_NAMED_CATEGORY_APP LL_PROFILE_ZONE_NAMED
@@ -276,5 +277,13 @@
#define LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32
#endif
+#if LL_PROFILER_CATEGORY_ENABLE_VOICE
+#define LL_PROFILE_ZONE_NAMED_CATEGORY_VOICE LL_PROFILE_ZONE_NAMED
+#define LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE LL_PROFILE_ZONE_SCOPED
+#else
+#define LL_PROFILE_ZONE_NAMED_CATEGORY_VOICE(name)
+#define LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+#endif
+
#endif // LL_PROFILER_CATEGORIES_H
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index c51bcfcdd5..a1e125a8f2 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -629,6 +629,9 @@ void LLWebRTCPeerConnectionImpl::terminate()
rtc::scoped_refptr<webrtc::MediaStreamInterface> localStream;
mLocalStream.swap(localStream);
+ mSignalingObserverList.clear();
+ mDataObserverList.clear();
+
mWebRTCImpl->PostSignalingTask(
[=]()
{
@@ -1114,6 +1117,10 @@ void LLWebRTCPeerConnectionImpl::OnSuccess(webrtc::SessionDescriptionInterface *
void LLWebRTCPeerConnectionImpl::OnFailure(webrtc::RTCError error)
{
RTC_LOG(LS_ERROR) << ToString(error.type()) << ": " << error.message();
+ for (auto &observer : mSignalingObserverList)
+ {
+ observer->OnRenegotiationNeeded();
+ }
}
//
@@ -1127,6 +1134,10 @@ void LLWebRTCPeerConnectionImpl::OnSetRemoteDescriptionComplete(webrtc::RTCError
if (!error.ok())
{
RTC_LOG(LS_ERROR) << ToString(error.type()) << ": " << error.message();
+ for (auto &observer : mSignalingObserverList)
+ {
+ observer->OnRenegotiationNeeded();
+ }
return;
}
mAnswerReceived = true;
@@ -1144,7 +1155,10 @@ void LLWebRTCPeerConnectionImpl::OnSetRemoteDescriptionComplete(webrtc::RTCError
}
}
mCachedIceCandidates.clear();
- OnIceGatheringChange(mPeerConnection->ice_gathering_state());
+ if (mPeerConnection)
+ {
+ OnIceGatheringChange(mPeerConnection->ice_gathering_state());
+ }
}
@@ -1161,6 +1175,10 @@ void LLWebRTCPeerConnectionImpl::OnSetLocalDescriptionComplete(webrtc::RTCError
void LLWebRTCPeerConnectionImpl::OnStateChange()
{
+ if (!mDataChannel)
+ {
+ return;
+ }
RTC_LOG(LS_INFO) << __FUNCTION__ << " Data Channel State: " << webrtc::DataChannelInterface::DataStateString(mDataChannel->state());
switch (mDataChannel->state())
{
@@ -1204,7 +1222,12 @@ void LLWebRTCPeerConnectionImpl::sendData(const std::string& data, bool binary)
{
rtc::CopyOnWriteBuffer cowBuffer(data.data(), data.length());
webrtc::DataBuffer buffer(cowBuffer, binary);
- mDataChannel->Send(buffer);
+ mWebRTCImpl->PostNetworkTask([this, buffer]() {
+ if (mDataChannel)
+ {
+ mDataChannel->Send(buffer);
+ }
+ });
}
}
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index bb5b386e7c..f3d3460022 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -291,6 +291,8 @@ const LLVoiceVersionInfo& LLWebRTCVoiceClient::getVersion()
void LLWebRTCVoiceClient::updateSettings()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
setVoiceEnabled(LLVoiceClient::getInstance()->voiceEnabled());
setEarLocation(gSavedSettings.getS32("VoiceEarLocation"));
@@ -322,6 +324,7 @@ void LLWebRTCVoiceClient::removeObserver(LLVoiceClientParticipantObserver *obser
void LLWebRTCVoiceClient::notifyParticipantObservers()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
for (observer_set_t::iterator it = mParticipantObservers.begin(); it != mParticipantObservers.end();)
{
LLVoiceClientParticipantObserver *observer = *it;
@@ -343,6 +346,8 @@ void LLWebRTCVoiceClient::removeObserver(LLVoiceClientStatusObserver *observer)
void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
LL_DEBUGS("Voice") << "( " << LLVoiceClientStatusObserver::status2string(status) << " )"
<< " mSession=" << mSession << LL_ENDL;
@@ -409,6 +414,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
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
@@ -495,7 +501,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
sessionState::processSessionStates();
if (mProcessChannels && voiceEnabled && !mHidden)
{
- sendPositionUpdate(true);
+ sendPositionUpdate(false);
updateOwnVolume();
}
}
@@ -524,6 +530,8 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
// for cross-region voice.
void LLWebRTCVoiceClient::updateNeighboringRegions()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
static const std::vector<LLVector3d> neighbors {LLVector3d(0.0f, 1.0f, 0.0f), LLVector3d(0.707f, 0.707f, 0.0f),
LLVector3d(1.0f, 0.0f, 0.0f), LLVector3d(0.707f, -0.707f, 0.0f),
LLVector3d(0.0f, -1.0f, 0.0f), LLVector3d(-0.707f, -0.707f, 0.0f),
@@ -554,6 +562,8 @@ void LLWebRTCVoiceClient::updateNeighboringRegions()
// shut down the current audio session to make room for the next one.
void LLWebRTCVoiceClient::leaveAudioSession()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
if(mSession)
{
LL_DEBUGS("Voice") << "leaving session: " << mSession->mChannelID << LL_ENDL;
@@ -607,6 +617,8 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi
void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices,
const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
@@ -790,6 +802,8 @@ void LLWebRTCVoiceClient::setHidden(bool hidden)
// notify the observers.
void LLWebRTCVoiceClient::OnConnectionEstablished(const std::string &channelID, const LLUUID &regionID)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
if (gAgent.getRegion()->getRegionID() == regionID)
{
if (mNextSession && mNextSession->mChannelID == channelID)
@@ -831,18 +845,20 @@ void LLWebRTCVoiceClient::OnConnectionShutDown(const std::string &channelID, con
}
}
}
-void LLWebRTCVoiceClient::OnConnectionFailure(const std::string &channelID, const LLUUID &regionID)
+void LLWebRTCVoiceClient::OnConnectionFailure(const std::string &channelID,
+ const LLUUID &regionID,
+ LLVoiceClientStatusObserver::EStatusType status_type)
{
LL_DEBUGS("Voice") << "A connection failed. channel:" << channelID << LL_ENDL;
if (gAgent.getRegion()->getRegionID() == regionID)
{
if (mNextSession && mNextSession->mChannelID == channelID)
{
- LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
+ LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(status_type);
}
else if (mSession && mSession->mChannelID == channelID)
{
- LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
+ LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(status_type);
}
}
}
@@ -862,6 +878,8 @@ void LLWebRTCVoiceClient::setEarLocation(S32 loc)
void LLWebRTCVoiceClient::updatePosition(void)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
LLViewerRegion *region = gAgent.getRegion();
if (region && isAgentAvatarValid())
{
@@ -982,6 +1000,8 @@ void LLWebRTCVoiceClient::enforceTether()
// standard 50m
void LLWebRTCVoiceClient::sendPositionUpdate(bool force)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
Json::FastWriter writer;
std::string spatial_data;
@@ -1093,6 +1113,8 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::addParticipantBy
void LLWebRTCVoiceClient::removeParticipantByID(const std::string &channelID, const LLUUID &id)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
participantStatePtr_t result;
LLWebRTCVoiceClient::sessionState::ptr_t session = sessionState::matchSessionByChannelID(channelID);
if (session)
@@ -1123,6 +1145,9 @@ LLWebRTCVoiceClient::participantState::participantState(const LLUUID& agent_id)
LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::addParticipant(const LLUUID& agent_id)
{
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
participantStatePtr_t result;
participantUUIDMap::iterator iter = mParticipantsByUUID.find(agent_id);
@@ -1158,6 +1183,8 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::ad
LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::findParticipantByID(const LLUUID& id)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
participantStatePtr_t result;
participantUUIDMap::iterator iter = mParticipantsByUUID.find(id);
@@ -1171,6 +1198,8 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::fi
void LLWebRTCVoiceClient::sessionState::removeParticipant(const LLWebRTCVoiceClient::participantStatePtr_t &participant)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
if (participant)
{
participantUUIDMap::iterator iter = mParticipantsByUUID.find(participant->mAvatarID);
@@ -1409,6 +1438,8 @@ void LLWebRTCVoiceClient::predSetMicGain(const LLWebRTCVoiceClient::sessionState
void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
LL_DEBUGS("Voice")
<< "( " << (enabled ? "enabled" : "disabled") << " )"
<< " was "<< (mVoiceEnabled ? "enabled" : "disabled")
@@ -1811,6 +1842,8 @@ void LLWebRTCVoiceClient::sessionState::revive()
void LLWebRTCVoiceClient::sessionState::processSessionStates()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
auto iter = mSessions.begin();
while (iter != mSessions.end())
{
@@ -1830,6 +1863,8 @@ void LLWebRTCVoiceClient::sessionState::processSessionStates()
// process the states on each connection associated with a session.
bool LLWebRTCVoiceClient::sessionState::processConnectionStates()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
std::list<connectionPtr_t>::iterator iter = mWebRTCConnections.begin();
while (iter != mWebRTCConnections.end())
{
@@ -1852,6 +1887,8 @@ bool LLWebRTCVoiceClient::sessionState::processConnectionStates()
// on our location.
bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
if (!mShuttingDown)
{
// Estate voice requires connection to neighboring regions.
@@ -2003,9 +2040,9 @@ LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID &regionID, const s
mWebRTCAudioInterface(nullptr),
mWebRTCDataInterface(nullptr),
mVoiceConnectionState(VOICE_STATE_START_SESSION),
+ mCurrentStatus(LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED),
mMuted(true),
mShutDown(false),
- mTrickling(false),
mIceCompleted(false),
mSpeakerVolume(0.0),
mMicGain(0.0),
@@ -2078,123 +2115,98 @@ void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidat
LL::WorkQueue::postMaybe(mMainQueue, [=] { mIceCandidates.push_back(candidate); });
}
-void LLVoiceWebRTCConnection::onIceUpdateComplete(bool ice_completed, const LLSD &result)
-{
- mOutstandingRequests--;
- if (LLWebRTCVoiceClient::isShuttingDown())
- {
- return;
- }
- mTrickling = false;
-}
-
-void LLVoiceWebRTCConnection::onIceUpdateError(int retries, std::string url, LLSD body, bool ice_completed, const LLSD &result)
+void LLVoiceWebRTCConnection::processIceUpdates()
{
- if (LLWebRTCVoiceClient::isShuttingDown())
- {
- mOutstandingRequests--;
- return;
- }
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceAccountProvision", httpPolicy));
-
- if (retries >= 0)
- {
- LL_WARNS("Voice") << "Unable to complete ice trickling voice account, retrying. " << result << LL_ENDL;
- LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(
- url,
- LLCore::HttpRequest::DEFAULT_POLICY_ID,
- body,
- boost::bind(&LLVoiceWebRTCConnection::onIceUpdateComplete, this, ice_completed, _1),
- boost::bind(&LLVoiceWebRTCConnection::onIceUpdateError, this, retries - 1, url, body, ice_completed, _1));
- return;
- }
-
- LL_WARNS("Voice") << "Unable to complete ice trickling voice account, restarting connection. " << result << LL_ENDL;
- if (!mShutDown)
- {
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
- }
- mTrickling = false;
-
- mOutstandingRequests--;
+ mOutstandingRequests++;
+ LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::requestVoiceConnectionCoro",
+ boost::bind(&LLVoiceWebRTCConnection::processIceUpdatesCoro, this));
}
-
// Ice candidates may be streamed in before or after the SDP offer is available (see below)
// This function determines whether candidates are available to send to the Secondlife WebRTC
// server via the simulator. If so, and there are no more candidates, this code
// will make the cap call to the server sending up the ICE candidates.
-void LLVoiceWebRTCConnection::processIceUpdates()
+void LLVoiceWebRTCConnection::processIceUpdatesCoro()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
if (mShutDown || LLWebRTCVoiceClient::isShuttingDown())
{
+ mOutstandingRequests--;
return;
}
bool iceCompleted = false;
LLSD body;
+ if (!mIceCandidates.empty() || mIceCompleted)
{
- if (!mTrickling)
+ LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
+ if (!regionp || !regionp->capabilitiesReceived())
+ {
+ LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL;
+ mOutstandingRequests--;
+ return;
+ }
+
+ std::string url = regionp->getCapability("VoiceSignalingRequest");
+ if (url.empty())
+ {
+ mOutstandingRequests--;
+ return;
+ }
+
+ LL_DEBUGS("Voice") << "region ready to complete voice signaling; url=" << url << LL_ENDL;
+ if (!mIceCandidates.empty())
{
- if (!mIceCandidates.empty() || mIceCompleted)
+ LLSD candidates = LLSD::emptyArray();
+ for (auto &ice_candidate : mIceCandidates)
{
- LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
- if (!regionp || !regionp->capabilitiesReceived())
- {
- LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL;
- return;
- }
+ LLSD body_candidate;
+ body_candidate["sdpMid"] = ice_candidate.mSdpMid;
+ body_candidate["sdpMLineIndex"] = ice_candidate.mMLineIndex;
+ body_candidate["candidate"] = ice_candidate.mCandidate;
+ candidates.append(body_candidate);
+ }
+ body["candidates"] = candidates;
+ mIceCandidates.clear();
+ }
+ else if (mIceCompleted)
+ {
+ LLSD body_candidate;
+ body_candidate["completed"] = true;
+ body["candidate"] = body_candidate;
+ iceCompleted = mIceCompleted;
+ mIceCompleted = false;
+ }
- std::string url = regionp->getCapability("VoiceSignalingRequest");
- if (url.empty())
- {
- return;
- }
+ body["viewer_session"] = mViewerSession;
+ body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
- LL_DEBUGS("Voice") << "region ready to complete voice signaling; url=" << url << LL_ENDL;
- if (!mIceCandidates.empty())
- {
- LLSD candidates = LLSD::emptyArray();
- for (auto &ice_candidate : mIceCandidates)
- {
- LLSD body_candidate;
- body_candidate["sdpMid"] = ice_candidate.mSdpMid;
- body_candidate["sdpMLineIndex"] = ice_candidate.mMLineIndex;
- body_candidate["candidate"] = ice_candidate.mCandidate;
- candidates.append(body_candidate);
- }
- body["candidates"] = candidates;
- mIceCandidates.clear();
- }
- else if (mIceCompleted)
- {
- LLSD body_candidate;
- body_candidate["completed"] = true;
- body["candidate"] = body_candidate;
- iceCompleted = mIceCompleted;
- mIceCompleted = false;
- }
+ 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);
- body["viewer_session"] = mViewerSession;
- body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
-
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
- new LLCoreHttpUtil::HttpCoroutineAdapter("voiceAccountProvision", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
- LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(
- url,
- LLCore::HttpRequest::DEFAULT_POLICY_ID,
- body,
- boost::bind(&LLVoiceWebRTCSpatialConnection::onIceUpdateComplete, this, iceCompleted, _1),
- boost::bind(&LLVoiceWebRTCSpatialConnection::onIceUpdateError, this, 3, url, body, iceCompleted, _1));
- mOutstandingRequests++;
- mTrickling = true;
- }
+ httpOpts->setWantHeaders(true);
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
+
+ if (LLWebRTCVoiceClient::isShuttingDown())
+ {
+ return;
+ }
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ // couldn't trickle the candidates, so restart the session.
+ setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
}
}
+ mOutstandingRequests--;
}
@@ -2343,8 +2355,10 @@ void LLVoiceWebRTCConnection::sendData(const std::string &data)
// Tell the simulator that we're shutting down a voice connection.
// The simulator will pass this on to the Secondlife WebRTC server.
-void LLVoiceWebRTCConnection::breakVoiceConnection()
+void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL;
if (mWebRTCDataInterface)
{
@@ -2389,6 +2403,11 @@ void LLVoiceWebRTCConnection::breakVoiceConnection()
// also shut things down.
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
+ if (LLWebRTCVoiceClient::isShuttingDown())
+ {
+ return;
+ }
+
if (mWebRTCPeerConnectionInterface)
{
mWebRTCPeerConnectionInterface->shutdownConnection();
@@ -2404,6 +2423,8 @@ void LLVoiceWebRTCConnection::breakVoiceConnection()
// will use the offer and answer to negotiate the session.
void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
LL_DEBUGS("Voice") << "Requesting voice connection." << LL_ENDL;
@@ -2445,22 +2466,36 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
mOutstandingRequests++;
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (!status)
+ if (status)
{
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ OnVoiceConnectionRequestSuccess(result);
}
else
{
- OnVoiceConnectionRequestSuccess(result);
+ switch (status.getType())
+ {
+ case HTTP_CONFLICT:
+ mCurrentStatus = LLVoiceClientStatusObserver::ERROR_CHANNEL_FULL;
+ break;
+ case HTTP_UNAUTHORIZED:
+ mCurrentStatus = LLVoiceClientStatusObserver::ERROR_CHANNEL_LOCKED;
+ break;
+ default:
+ mCurrentStatus = LLVoiceClientStatusObserver::ERROR_UNKNOWN;
+ break;
+ }
+ setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
}
mOutstandingRequests--;
}
void LLVoiceWebRTCConnection::OnVoiceConnectionRequestSuccess(const LLSD &result)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
if (LLWebRTCVoiceClient::isShuttingDown())
{
return;
@@ -2514,18 +2549,20 @@ static llwebrtc::LLWebRTCPeerConnectionInterface::InitOptions getConnectionOptio
// Secondlife WebRTC server.
bool LLVoiceWebRTCConnection::connectionStateMachine()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
processIceUpdates();
switch (getVoiceConnectionState())
{
case VOICE_STATE_START_SESSION:
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VOICE("VOICE_STATE_START_SESSION")
if (mShutDown)
{
setVoiceConnectionState(VOICE_STATE_DISCONNECT);
break;
}
- mTrickling = false;
mIceCompleted = false;
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_SESSION_START);
@@ -2597,6 +2634,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
{
sendJoin(); // tell the Secondlife WebRTC server that we're here via the data channel.
setVoiceConnectionState(VOICE_STATE_SESSION_UP);
+ LLWebRTCVoiceClient::getInstance()->sendPositionUpdate(true);
}
break;
}
@@ -2619,7 +2657,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
if (mRetryWaitPeriod++ * UPDATE_THROTTLE_SECONDS > mRetryWaitSecs)
{
// something went wrong, so notify that the connection has failed.
- LLWebRTCVoiceClient::getInstance()->OnConnectionFailure(mChannelID, mRegionID);
+ LLWebRTCVoiceClient::getInstance()->OnConnectionFailure(mChannelID, mRegionID, mCurrentStatus);
setVoiceConnectionState(VOICE_STATE_DISCONNECT);
mRetryWaitPeriod = 0;
if (mRetryWaitSecs < MAX_RETRY_WAIT_SECONDS)
@@ -2633,8 +2671,8 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
break;
case VOICE_STATE_DISCONNECT:
- LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnection",
- boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnection, this));
+ LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro",
+ boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this));
break;
case VOICE_STATE_WAIT_FOR_EXIT:
@@ -2696,6 +2734,8 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binar
// this pointer.
void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool binary)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
if (mShutDown)
{
return;
@@ -2724,8 +2764,8 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
LLUUID agent_id(participant_id);
if (agent_id.isNull())
{
- LL_WARNS("Voice") << "Bad participant ID from data channel (" << participant_id << "):" << data << LL_ENDL;
- continue;
+ // probably a test client.
+ continue;
}
LLWebRTCVoiceClient::participantStatePtr_t participant =
@@ -2841,6 +2881,8 @@ void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface
// to peers.
void LLVoiceWebRTCConnection::sendJoin()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
Json::FastWriter writer;
Json::Value root = Json::objectValue;
Json::Value join_obj = Json::objectValue;
@@ -2929,6 +2971,8 @@ LLVoiceWebRTCAdHocConnection::~LLVoiceWebRTCAdHocConnection()
// So, we have a separate requestVoiceConnection call.
void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
+
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
LL_DEBUGS("Voice") << "Requesting voice connection." << LL_ENDL;
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index 96d39f3928..aa3298ec1b 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -203,7 +203,9 @@ public:
void OnConnectionEstablished(const std::string& channelID, const LLUUID& regionID);
void OnConnectionShutDown(const std::string &channelID, const LLUUID &regionID);
- void OnConnectionFailure(const std::string &channelID, const LLUUID& regionID);
+ void OnConnectionFailure(const std::string &channelID,
+ const LLUUID &regionID,
+ LLVoiceClientStatusObserver::EStatusType status_type = LLVoiceClientStatusObserver::ERROR_UNKNOWN);
void sendPositionUpdate(bool force);
void updateOwnVolume();
@@ -603,10 +605,10 @@ class LLVoiceWebRTCConnection :
void sendJoin();
void sendData(const std::string &data);
- virtual void processIceUpdates();
- virtual void onIceUpdateComplete(bool ice_completed, const LLSD &result);
- virtual void onIceUpdateError(int retries, std::string url, LLSD body, bool ice_completed, const LLSD &result);
+ void processIceUpdates();
+ void processIceUpdatesCoro();
+
virtual void setMuteMic(bool muted);
virtual void setMicGain(F32 volume);
virtual void setSpeakerVolume(F32 volume);
@@ -673,7 +675,9 @@ class LLVoiceWebRTCConnection :
virtual void requestVoiceConnection() = 0;
void requestVoiceConnectionCoro() { requestVoiceConnection(); }
- void breakVoiceConnection();
+ void breakVoiceConnectionCoro();
+
+ LLVoiceClientStatusObserver::EStatusType mCurrentStatus;
LLUUID mRegionID;
LLUUID mViewerSession;
@@ -697,7 +701,6 @@ class LLVoiceWebRTCConnection :
std::vector<llwebrtc::LLWebRTCIceCandidate> mIceCandidates;
bool mIceCompleted;
- bool mTrickling;
llwebrtc::LLWebRTCPeerConnectionInterface *mWebRTCPeerConnectionInterface;
llwebrtc::LLWebRTCAudioInterface *mWebRTCAudioInterface;