summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llwebrtc/llwebrtc.cpp203
-rw-r--r--indra/newview/llvoicewebrtc.cpp437
-rw-r--r--indra/newview/llvoicewebrtc.h43
3 files changed, 261 insertions, 422 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index e55d94d128..9b3ec2889b 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -86,7 +86,9 @@ void LLWebRTCImpl::init()
mPlayoutDevice = 0;
mRecordingDevice = 0;
rtc::InitializeSSL();
- rtc::LogMessage::LogToDebug(rtc::LS_WARNING);
+ rtc::LogMessage::LogToDebug(rtc::LS_NONE);
+ rtc::LogMessage::SetLogToStderr(true);
+
mTaskQueueFactory = webrtc::CreateDefaultTaskQueueFactory();
mNetworkThread = rtc::Thread::CreateWithSocketServer();
@@ -98,7 +100,7 @@ void LLWebRTCImpl::init()
mSignalingThread = rtc::Thread::Create();
mSignalingThread->SetName("WebRTCSignalingThread", nullptr);
mSignalingThread->Start();
-
+
mWorkerThread->PostTask(
[this]()
{
@@ -466,93 +468,98 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection()
RTC_DCHECK(!mPeerConnection);
mAnswerReceived = false;
- webrtc::PeerConnectionInterface::RTCConfiguration config;
- config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
- webrtc::PeerConnectionInterface::IceServer server;
- server.uri = "stun:roxie-turn.staging.secondlife.io:3478";
- config.servers.push_back(server);
- server.uri = "stun:stun.l.google.com:19302";
- config.servers.push_back(server);
- server.uri = "stun:stun1.l.google.com:19302";
- config.servers.push_back(server);
- server.uri = "stun:stun2.l.google.com:19302";
- config.servers.push_back(server);
- server.uri = "stun:stun3.l.google.com:19302";
- config.servers.push_back(server);
- server.uri = "stun:stun4.l.google.com:19302";
- config.servers.push_back(server);
-
- webrtc::PeerConnectionDependencies pc_dependencies(this);
- auto error_or_peer_connection = mPeerConnectionFactory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
- if (error_or_peer_connection.ok())
- {
- mPeerConnection = std::move(error_or_peer_connection.value());
- }
- else
- {
- RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection: " << error_or_peer_connection.error().message();
- return false;
- }
-
- webrtc::DataChannelInit init;
- init.ordered = true;
-
- auto data_channel_or_error = mPeerConnection->CreateDataChannelOrError("SLData", &init);
- if (data_channel_or_error.ok())
- {
- mDataChannel = std::move(data_channel_or_error.value());
-
- mDataChannel->RegisterObserver(this);
- }
-
- RTC_LOG(LS_INFO) << __FUNCTION__ << " " << mPeerConnection->signaling_state();
-
- cricket::AudioOptions audioOptions;
- audioOptions.auto_gain_control = true;
- audioOptions.echo_cancellation = false; // incompatible with opus stereo
- audioOptions.noise_suppression = true;
-
- mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream");
- rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
- mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(audioOptions).get()));
- audio_track->set_enabled(true);
- mLocalStream->AddTrack(audio_track);
-
- mPeerConnection->AddTrack(audio_track, {"SLStream"});
-
- auto senders = mPeerConnection->GetSenders();
-
- for (auto &sender : senders)
- {
- webrtc::RtpParameters params;
- webrtc::RtpCodecParameters codecparam;
- codecparam.name = "opus";
- codecparam.kind = cricket::MEDIA_TYPE_AUDIO;
- codecparam.clock_rate = 48000;
- codecparam.num_channels = 2;
- codecparam.parameters["stereo"] = "1";
- codecparam.parameters["sprop-stereo"] = "1";
- params.codecs.push_back(codecparam);
- sender->SetParameters(params);
- }
-
- auto receivers = mPeerConnection->GetReceivers();
- for (auto &receiver : receivers)
- {
- webrtc::RtpParameters params;
- webrtc::RtpCodecParameters codecparam;
- codecparam.name = "opus";
- codecparam.kind = cricket::MEDIA_TYPE_AUDIO;
- codecparam.clock_rate = 48000;
- codecparam.num_channels = 2;
- codecparam.parameters["stereo"] = "1";
- codecparam.parameters["sprop-stereo"] = "1";
- params.codecs.push_back(codecparam);
- receiver->SetParameters(params);
- }
-
- webrtc::PeerConnectionInterface::RTCOfferAnswerOptions offerOptions;
- mPeerConnection->CreateOffer(this, offerOptions);
+ mWebRTCImpl->PostSignalingTask(
+ [this]()
+ {
+ webrtc::PeerConnectionInterface::RTCConfiguration config;
+ config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
+ webrtc::PeerConnectionInterface::IceServer server;
+ server.uri = "stun:roxie-turn.staging.secondlife.io:3478";
+ config.servers.push_back(server);
+ server.uri = "stun:stun.l.google.com:19302";
+ config.servers.push_back(server);
+ server.uri = "stun:stun1.l.google.com:19302";
+ config.servers.push_back(server);
+ server.uri = "stun:stun2.l.google.com:19302";
+ config.servers.push_back(server);
+ server.uri = "stun:stun3.l.google.com:19302";
+ config.servers.push_back(server);
+ server.uri = "stun:stun4.l.google.com:19302";
+ config.servers.push_back(server);
+
+ config.set_min_port(60000);
+ config.set_max_port(60100);
+
+ webrtc::PeerConnectionDependencies pc_dependencies(this);
+ auto error_or_peer_connection = mPeerConnectionFactory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
+ if (error_or_peer_connection.ok())
+ {
+ mPeerConnection = std::move(error_or_peer_connection.value());
+ }
+ else
+ {
+ RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection: " << error_or_peer_connection.error().message();
+ return;
+ }
+
+ webrtc::DataChannelInit init;
+ init.ordered = true;
+
+ auto data_channel_or_error = mPeerConnection->CreateDataChannelOrError("SLData", &init);
+ if (data_channel_or_error.ok())
+ {
+ mDataChannel = std::move(data_channel_or_error.value());
+
+ mDataChannel->RegisterObserver(this);
+ }
+
+ cricket::AudioOptions audioOptions;
+ audioOptions.auto_gain_control = true;
+ audioOptions.echo_cancellation = false; // incompatible with opus stereo
+ audioOptions.noise_suppression = true;
+
+ mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream");
+ rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
+ mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(audioOptions).get()));
+ audio_track->set_enabled(true);
+ mLocalStream->AddTrack(audio_track);
+
+ mPeerConnection->AddTrack(audio_track, {"SLStream"});
+
+ auto senders = mPeerConnection->GetSenders();
+
+ for (auto &sender : senders)
+ {
+ webrtc::RtpParameters params;
+ webrtc::RtpCodecParameters codecparam;
+ codecparam.name = "opus";
+ codecparam.kind = cricket::MEDIA_TYPE_AUDIO;
+ codecparam.clock_rate = 48000;
+ codecparam.num_channels = 2;
+ codecparam.parameters["stereo"] = "1";
+ codecparam.parameters["sprop-stereo"] = "1";
+ params.codecs.push_back(codecparam);
+ sender->SetParameters(params);
+ }
+
+ auto receivers = mPeerConnection->GetReceivers();
+ for (auto &receiver : receivers)
+ {
+ webrtc::RtpParameters params;
+ webrtc::RtpCodecParameters codecparam;
+ codecparam.name = "opus";
+ codecparam.kind = cricket::MEDIA_TYPE_AUDIO;
+ codecparam.clock_rate = 48000;
+ codecparam.num_channels = 2;
+ codecparam.parameters["stereo"] = "1";
+ codecparam.parameters["sprop-stereo"] = "1";
+ params.codecs.push_back(codecparam);
+ receiver->SetParameters(params);
+ }
+
+ webrtc::PeerConnectionInterface::RTCOfferAnswerOptions offerOptions;
+ mPeerConnection->CreateOffer(this, offerOptions);
+ });
return true;
}
@@ -839,7 +846,7 @@ void LLWebRTCPeerConnectionImpl::OnIceCandidate(const webrtc::IceCandidateInterf
else
{
mCachedIceCandidates.push_back(
- webrtc::CreateIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(), candidate->candidate()));
+ webrtc::CreateIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(), candidate->candidate()));
}
}
@@ -878,21 +885,16 @@ void LLWebRTCPeerConnectionImpl::OnSuccess(webrtc::SessionDescriptionInterface *
sdp_mangled_stream << sdp_line << "\n";
}
}
-
- webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp_mangled_stream.str());
-
-
-
- mPeerConnection->SetLocalDescription(std::unique_ptr<webrtc::SessionDescriptionInterface>(
- webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp_mangled_stream.str())),
- rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface>(this));
+
RTC_LOG(LS_INFO) << __FUNCTION__ << " Local SDP: " << sdp_mangled_stream.str();
-
-
+
for (auto &observer : mSignalingObserverList)
{
observer->OnOfferAvailable(sdp_mangled_stream.str());
}
+
+ mPeerConnection->SetLocalDescription(std::unique_ptr<webrtc::SessionDescriptionInterface>(webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp_mangled_stream.str())),
+ rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface>(this));
}
void LLWebRTCPeerConnectionImpl::OnFailure(webrtc::RTCError error) { RTC_LOG(LS_ERROR) << ToString(error.type()) << ": " << error.message(); }
@@ -930,7 +932,6 @@ void LLWebRTCPeerConnectionImpl::OnSetRemoteDescriptionComplete(webrtc::RTCError
//
void LLWebRTCPeerConnectionImpl::OnSetLocalDescriptionComplete(webrtc::RTCError error)
{
-
}
//
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index ec1e6a353d..9a1b3525d7 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -455,17 +455,29 @@ void LLWebRTCVoiceClient::idle(void* user_data)
//
//
-void LLWebRTCVoiceClient::predProcessSessionStates(const LLWebRTCVoiceClient::sessionStatePtr_t& session)
+void LLWebRTCVoiceClient::sessionState::processSessionStates()
{
- session->processSessionStates();
+ auto iter = mSessions.begin();
+ while (iter != mSessions.end())
+ {
+ if (!iter->second->processConnectionStates())
+ {
+ iter = mSessions.erase(iter);
+ }
+ else
+ {
+ iter++;
+ }
+ }
}
-void LLWebRTCVoiceClient::sessionState::processSessionStates()
+bool LLWebRTCVoiceClient::sessionState::processConnectionStates()
{
- std::map<std::string, connectionPtr_t>::iterator iter;
- for (iter = mWebRTCConnections.begin(); iter != mWebRTCConnections.end();)
+ std::list<connectionPtr_t>::iterator iter = mWebRTCConnections.begin();
+
+ while (iter != mWebRTCConnections.end())
{
- if (!iter->second->connectionStateMachine())
+ if (!iter->get()->connectionStateMachine())
{
iter = mWebRTCConnections.erase(iter);
}
@@ -474,6 +486,7 @@ void LLWebRTCVoiceClient::sessionState::processSessionStates()
++iter;
}
}
+ return !mWebRTCConnections.empty();
}
void LLWebRTCVoiceClient::voiceConnectionCoro()
@@ -488,33 +501,39 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
// add session for region or parcel voice.
LLViewerRegion *regionp = gAgent.getRegion();
- if (!regionp)
+ if (!regionp || regionp->getRegionID().isNull())
{
continue;
}
- if (regionp->getRegionID().isNull())
- {
- continue;
- }
- if (mVoiceEnabled && (!mAudioSession || mAudioSession->mIsSpatial))
+
+ if (mVoiceEnabled && (!mAudioSession || mAudioSession->isSpatial()) && !mNextAudioSession)
{
// check to see if parcel changed.
std::string channelID = regionp->getRegionID().asString();
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
S32 parcel_local_id = INVALID_PARCEL_ID;
- if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID && !parcel->getParcelFlagUseEstateVoiceChannel())
+ if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID)
{
- parcel_local_id = parcel->getLocalID();
- channelID += "-" + std::to_string(parcel->getLocalID());
+ if (!parcel->getParcelFlagAllowVoice())
+ {
+ channelID.clear();
+ }
+ else if (!parcel->getParcelFlagUseEstateVoiceChannel())
+ {
+ parcel_local_id = parcel->getLocalID();
+ channelID += "-" + std::to_string(parcel->getLocalID());
+ }
}
- if (!mAudioSession || channelID != mAudioSession->mChannelID)
+
+ if ((mNextAudioSession && channelID != mNextAudioSession->mChannelID) ||
+ (!mAudioSession && !channelID.empty()) ||
+ (mAudioSession && channelID != mAudioSession->mChannelID))
{
setSpatialChannel(channelID, "", parcel_local_id);
}
}
- sessionState::for_each(boost::bind(predProcessSessionStates, _1));
- reapEmptySessions();
+ sessionState::processSessionStates();
if (mVoiceEnabled)
{
updatePosition();
@@ -829,7 +848,7 @@ void LLWebRTCVoiceClient::predUpdateOwnVolume(const LLWebRTCVoiceClient::session
void LLWebRTCVoiceClient::predSendData(const LLWebRTCVoiceClient::sessionStatePtr_t& session, const std::string& spatial_data, const std::string& volume_data)
{
- if (session->mIsSpatial && !spatial_data.empty())
+ if (session->isSpatial() && !spatial_data.empty())
{
session->sendData(spatial_data);
}
@@ -843,7 +862,7 @@ void LLWebRTCVoiceClient::sessionState::sendData(const std::string &data)
{
for (auto& connection : mWebRTCConnections)
{
- connection.second->sendData(data);
+ connection->sendData(data);
}
}
@@ -852,7 +871,7 @@ void LLWebRTCVoiceClient::sessionState::setMuteMic(bool muted)
mMuted = muted;
for (auto& connection : mWebRTCConnections)
{
- connection.second->setMuteMic(muted);
+ connection->setMuteMic(muted);
}
}
@@ -861,7 +880,7 @@ void LLWebRTCVoiceClient::sessionState::setMicGain(F32 gain)
mMicGain = gain;
for (auto& connection : mWebRTCConnections)
{
- connection.second->setMicGain(gain);
+ connection->setMicGain(gain);
}
}
@@ -870,7 +889,7 @@ void LLWebRTCVoiceClient::sessionState::setSpeakerVolume(F32 volume)
mSpeakerVolume = volume;
for (auto& connection : mWebRTCConnections)
{
- connection.second->setSpeakerVolume(volume);
+ connection->setSpeakerVolume(volume);
}
}
@@ -878,52 +897,6 @@ void LLWebRTCVoiceClient::sendLocalAudioUpdates()
{
}
-
-void LLWebRTCVoiceClient::joinedAudioSession(const sessionStatePtr_t &session)
-{
- LL_DEBUGS("Voice") << "Joined Audio Session" << LL_ENDL;
- if(mAudioSession != session)
- {
- sessionStatePtr_t oldSession = mAudioSession;
-
- mAudioSession = session;
- mAudioSessionChanged = true;
-
- // The old session may now need to be deleted.
- reapSession(oldSession);
- }
-
- // This is the session we're joining.
- if(mIsJoiningSession)
- {
- LLSD WebRTCevent(LLSDMap("channel", session->mChannelID)
- ("session", "joined"));
-
- mWebRTCPump.post(WebRTCevent);
-
- if(!session->mIsChannel)
- {
- // this is a p2p session. Make sure the other end is added as a participant.
- participantStatePtr_t participant(session->addParticipant(LLUUID(session->mChannelID)));
- if(participant)
- {
- if(participant->mAvatarIDValid)
- {
- lookupName(participant->mAvatarID);
- }
- else if(!session->mName.empty())
- {
- participant->mDisplayName = session->mName;
- avatarNameResolved(participant->mAvatarID, session->mName);
- }
-
- // TODO: Question: Do we need to set up mAvatarID/mAvatarIDValid here?
- LL_INFOS("Voice") << "added caller as participant (" << participant->mAvatarID << ")"<< LL_ENDL;
- }
- }
- }
-}
-
void LLWebRTCVoiceClient::reapSession(const sessionStatePtr_t &session)
{
if(session)
@@ -950,19 +923,6 @@ void LLWebRTCVoiceClient::reapSession(const sessionStatePtr_t &session)
}
-void LLWebRTCVoiceClient::leftAudioSession(const sessionStatePtr_t &session)
-{
- if (mAudioSession == session)
- {
- LLSD WebRTCevent(LLSDMap("channel", session->mChannelID)
- ("session", "removed"));
-
- mWebRTCPump.post(WebRTCevent);
- }
-}
-
-
-
void LLWebRTCVoiceClient::muteListChanged()
{
// The user's mute list has been updated. Go through the current participant list and sync it with the mute list.
@@ -1215,149 +1175,47 @@ void LLWebRTCVoiceClient::removeParticipantByID(const std::string &channelID, co
}
}
-
-// Check for parcel boundary crossing
-bool LLWebRTCVoiceClient::checkParcelChanged(bool update)
-{
- LLViewerRegion *region = gAgent.getRegion();
- LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- if(region && parcel)
- {
- S32 parcelLocalID = parcel->getLocalID();
- std::string regionName = region->getName();
-
- // LL_DEBUGS("Voice") << "Region name = \"" << regionName << "\", parcel local ID = " << parcelLocalID << ", cap URI = \"" << capURI << "\"" << LL_ENDL;
-
- // The region name starts out empty and gets filled in later.
- // Also, the cap gets filled in a short time after the region cross, but a little too late for our purposes.
- // If either is empty, wait for the next time around.
- if(!regionName.empty())
- {
- if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName))
- {
- // We have changed parcels. Initiate a parcel channel lookup.
- if (update)
- {
- mCurrentParcelLocalID = parcelLocalID;
- mCurrentRegionName = regionName;
- }
- return true;
- }
- }
- }
- return false;
-}
-
-bool LLWebRTCVoiceClient::switchChannel(
- const std::string channelID,
- bool spatial,
- bool no_reconnect,
- bool is_p2p,
- std::string hash,
- S32 parcel_local_id)
+bool LLWebRTCVoiceClient::switchChannel(const std::string channelID,
+ sessionState::ESessionType session_type,
+ S32 parcel_local_id)
{
- bool needsSwitch = false;
-
if (mAudioSession)
{
- if (mSessionTerminateRequested)
+ // If we're already in a channel, or if we're joining one, terminate
+ // so we can rejoin with the new session data.
+ sessionTerminate();
+ notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
+ deleteSession(mAudioSession);
+ }
+
+ if (channelID.empty())
+ {
+ // Leave any channel we may be in
+ LL_DEBUGS("Voice") << "leaving channel" << LL_ENDL;
+
+ if (mNextAudioSession)
{
- // If a terminate has been requested, we need to compare against where the URI we're already headed to.
- if(mNextAudioSession)
- {
- if (mNextAudioSession->mChannelID != channelID)
- needsSwitch = true;
- }
- else
- {
- // mNextAudioSession is null -- this probably means we're on our way back to spatial.
- if (!channelID.empty())
- {
- // We do want to process a switch in this case.
- needsSwitch = true;
- }
- }
+ deleteSession(mNextAudioSession);
}
- else
+ // If voice was on, turn it off
+ if (LLVoiceClient::getInstance()->getUserPTTState())
{
- // Otherwise, compare against the URI we're in now.
- if(mAudioSession)
- {
- if (mAudioSession->mChannelID != channelID)
- {
- needsSwitch = true;
- }
- }
- else
- {
- if (!channelID.empty())
- {
- // mAudioSession is null -- it's not clear what case would cause this.
- // For now, log it as a warning and see if it ever crops up.
- LL_WARNS("Voice") << "No current audio session... Forcing switch" << LL_ENDL;
- needsSwitch = true;
- }
- }
+ LLVoiceClient::getInstance()->setUserPTTState(false);
}
+
+ notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED);
}
else
{
- if (!mNextAudioSession || mNextAudioSession->mChannelID != channelID)
+ if (mNextAudioSession)
{
- needsSwitch = true;
+ deleteSession(mNextAudioSession);
}
+ LL_DEBUGS("Voice") << "switching to channel " << channelID << LL_ENDL;
+ mNextAudioSession = addSession(channelID, parcel_local_id);
+ mNextAudioSession->mSessionType = session_type;
}
-
- if(needsSwitch)
- {
- if (mAudioSession)
- {
- // If we're already in a channel, or if we're joining one, terminate
- // so we can rejoin with the new session data.
- sessionTerminate();
- notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
- deleteSession(mAudioSession);
- }
-
- if (channelID.empty())
- {
- // Leave any channel we may be in
- LL_DEBUGS("Voice") << "leaving channel" << LL_ENDL;
-
- if (mNextAudioSession)
- {
- mAudioSession->shutdownAllConnections();
- }
- sessionStatePtr_t oldSession = mNextAudioSession;
- mNextAudioSession.reset();
-
- // The old session may now need to be deleted.
- reapSession(oldSession);
-
- // If voice was on, turn it off
- if (LLVoiceClient::getInstance()->getUserPTTState())
- {
- LLVoiceClient::getInstance()->setUserPTTState(false);
- }
-
- notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED);
- }
- else
- {
- if (mNextAudioSession)
- {
- deleteSession(mNextAudioSession);
- }
- LL_DEBUGS("Voice") << "switching to channel " << channelID << LL_ENDL;
- mNextAudioSession = addSession(channelID, parcel_local_id);
- mNextAudioSession->mIsSpatial = spatial;
- mNextAudioSession->mReconnect = !no_reconnect;
- mNextAudioSession->mIsP2P = is_p2p;
- }
- }
-
- return needsSwitch;
+ return true;
}
void LLWebRTCVoiceClient::joinSession(const sessionStatePtr_t &session)
@@ -1376,7 +1234,7 @@ void LLWebRTCVoiceClient::setNonSpatialChannel(
const std::string &uri,
const std::string &credentials)
{
- switchChannel(uri, false, false, false, credentials);
+ switchChannel(uri, sessionState::SESSION_TYPE_P2P);
}
bool LLWebRTCVoiceClient::setSpatialChannel(
@@ -1386,7 +1244,7 @@ bool LLWebRTCVoiceClient::setSpatialChannel(
LL_DEBUGS("Voice") << "got spatial channel uri: \"" << uri << "\"" << LL_ENDL;
- if((mAudioSession && !(mAudioSession->mIsSpatial)) || (mNextAudioSession && !(mNextAudioSession->mIsSpatial)))
+ if((mAudioSession && !mAudioSession->isSpatial()) || (mNextAudioSession && !mNextAudioSession->isSpatial()))
{
// User is in a non-spatial chat or joining a non-spatial chat. Don't switch channels.
LL_INFOS("Voice") << "in non-spatial chat, not switching channels" << LL_ENDL;
@@ -1394,13 +1252,13 @@ bool LLWebRTCVoiceClient::setSpatialChannel(
}
else
{
- return switchChannel(uri, true, false, false, "", parcel_local_id);
+ return switchChannel(uri, parcel_local_id == INVALID_PARCEL_ID ? sessionState::SESSION_TYPE_ESTATE : sessionState::SESSION_TYPE_PARCEL, parcel_local_id);
}
}
void LLWebRTCVoiceClient::callUser(const LLUUID &uuid)
{
- switchChannel(uuid.asString(), false, true, true);
+ switchChannel(uuid.asString(), sessionState::SESSION_TYPE_P2P);
}
void LLWebRTCVoiceClient::endUserIMSession(const LLUUID &uuid)
@@ -1419,9 +1277,7 @@ bool LLWebRTCVoiceClient::answerInvite(std::string &channelID)
sessionStatePtr_t session(findP2PSession(LLUUID(channelID)));
if(session)
{
- session->mIsSpatial = false;
- session->mReconnect = false;
- session->mIsP2P = true;
+ session->mSessionType = sessionState::ESessionType::SESSION_TYPE_P2P;
joinSession(session);
return true;
@@ -1604,7 +1460,7 @@ bool LLWebRTCVoiceClient::inSpatialChannel(void)
if(mAudioSession)
{
- result = mAudioSession->mIsSpatial;
+ result = mAudioSession->isSpatial();
}
return result;
@@ -2061,34 +1917,12 @@ BOOL LLWebRTCVoiceClient::getAreaVoiceDisabled()
return mAreaVoiceDisabled;
}
-void LLWebRTCVoiceClient::reapEmptySessions()
-{
- sessionState::reapEmptySessions();
-
- // mAudioSession or mNextAudioSession was reaped,
- // so reset them.
- if (mAudioSession && !sessionState::hasSession(mAudioSession->mChannelID))
- {
- mAudioSession.reset();
- }
- if (mNextAudioSession && !sessionState::hasSession(mNextAudioSession->mChannelID))
- {
- mNextAudioSession.reset();
- }
-}
-
//------------------------------------------------------------------------
std::map<std::string, LLWebRTCVoiceClient::sessionState::ptr_t> LLWebRTCVoiceClient::sessionState::mSessions;
LLWebRTCVoiceClient::sessionState::sessionState() :
mErrorStatusCode(0),
- mIsChannel(false),
- mIsSpatial(false),
- mIsP2P(false),
- mIncoming(false),
- mVoiceActive(false),
- mReconnect(false),
mVolumeDirty(false),
mMuteDirty(false),
mParticipantsChanged(false)
@@ -2102,8 +1936,7 @@ LLWebRTCVoiceClient::sessionState::ptr_t LLWebRTCVoiceClient::sessionState::crea
sessionState::ptr_t session(new sessionState());
session->mChannelID = channelID;
- connectionPtr_t connection = connectionPtr_t(new LLVoiceWebRTCConnection(region_id, parcelLocalID, channelID));
- session->mWebRTCConnections[channelID] = connection;
+ session->mWebRTCConnections.emplace_back(new LLVoiceWebRTCConnection(region_id, parcelLocalID, channelID));
session->mPrimaryConnectionID = channelID;
@@ -2202,7 +2035,7 @@ void LLWebRTCVoiceClient::sessionState::for_eachPredicate(const std::pair<std::s
LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::findP2PSession(const LLUUID &agent_id)
{
sessionStatePtr_t result = sessionState::matchSessionByChannelID(agent_id.asString());
- if (result && result->mIsP2P)
+ if (result && result->mSessionType == sessionState::SESSION_TYPE_P2P)
{
return result;
}
@@ -2217,7 +2050,7 @@ void LLWebRTCVoiceClient::sessionState::shutdownAllConnections()
{
for (auto &&connection : mWebRTCConnections)
{
- connection.second->shutDown();
+ connection->shutDown();
}
}
@@ -2277,14 +2110,16 @@ void LLWebRTCVoiceClient::deleteSession(const sessionStatePtr_t &session)
verifySessionState();
session->shutdownAllConnections();
// If this is the current audio session, clean up the pointer which will soon be dangling.
- if(mAudioSession == session)
+ bool deleteAudioSession = mAudioSession == session;
+ bool deleteNextAudioSession = mNextAudioSession == session;
+ if (deleteAudioSession)
{
mAudioSession.reset();
mAudioSessionChanged = true;
}
// ditto for the next audio session
- if(mNextAudioSession == session)
+ if (deleteNextAudioSession)
{
mNextAudioSession.reset();
}
@@ -2696,73 +2531,68 @@ void LLVoiceWebRTCConnection::OnPeerShutDown()
void LLVoiceWebRTCConnection::processIceUpdates()
{
- if (LLWebRTCVoiceClient::isShuttingDown())
- {
- return;
- }
- if (mShutDown)
- {
- return;
- }
- LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
- if (!regionp || !regionp->capabilitiesReceived())
+ if (mShutDown || LLWebRTCVoiceClient::isShuttingDown())
{
- LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL;
return;
}
- std::string url = regionp->getCapability("VoiceSignalingRequest");
- if (url.empty())
- {
- return;
- }
-
- LL_DEBUGS("Voice") << "region ready to complete voice signaling; url=" << url << LL_ENDL;
-
- 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);
-
bool iceCompleted = false;
LLSD body;
{
if (!mTrickling)
{
- if (mIceCandidates.size())
+ if (!mIceCandidates.empty() || mIceCompleted)
{
- LLSD candidates = LLSD::emptyArray();
- for (auto &ice_candidate : mIceCandidates)
+ LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
+ if (!regionp || !regionp->capabilitiesReceived())
{
- LLSD body_candidate;
- body_candidate["sdpMid"] = ice_candidate.sdp_mid;
- body_candidate["sdpMLineIndex"] = ice_candidate.mline_index;
- body_candidate["candidate"] = ice_candidate.candidate;
- candidates.append(body_candidate);
+ LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL;
+ return;
}
- body["candidates"] = candidates;
- mIceCandidates.clear();
- }
- else if (mIceCompleted)
- {
- LLSD body_candidate;
- body_candidate["completed"] = true;
- body["candidate"] = body_candidate;
- iceCompleted = mIceCompleted;
- mIceCompleted = false;
- }
- else
- {
- return;
+
+ std::string url = regionp->getCapability("VoiceSignalingRequest");
+ if (url.empty())
+ {
+ return;
+ }
+
+ 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.sdp_mid;
+ body_candidate["sdpMLineIndex"] = ice_candidate.mline_index;
+ body_candidate["candidate"] = ice_candidate.candidate;
+ 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;
+ }
+
+ 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(&LLVoiceWebRTCConnection::onIceUpdateComplete, this, iceCompleted, _1),
+ boost::bind(&LLVoiceWebRTCConnection::onIceUpdateError, this, 3, url, body, iceCompleted, _1));
+ mOutstandingRequests++;
+ mTrickling = true;
}
- LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(
- url,
- LLCore::HttpRequest::DEFAULT_POLICY_ID,
- body,
- boost::bind(&LLVoiceWebRTCConnection::onIceUpdateComplete, this, iceCompleted, _1),
- boost::bind(&LLVoiceWebRTCConnection::onIceUpdateError, this, 3, url, body, iceCompleted, _1));
- mOutstandingRequests++;
- mTrickling = true;
}
}
}
@@ -2862,7 +2692,7 @@ void LLVoiceWebRTCConnection::OnVoiceConnectionRequestFailure(std::string url, i
}
bool LLVoiceWebRTCConnection::connectionStateMachine()
-{
+{
processIceUpdates();
switch (getVoiceConnectionState())
@@ -2872,6 +2702,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
if (mShutDown)
{
setVoiceConnectionState(VOICE_STATE_DISCONNECT);
+ break;
}
mTrickling = false;
mIceCompleted = false;
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index f311f241dc..1e8ecdf5c2 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -330,7 +330,9 @@ public:
bool isCallBackPossible();
bool isTextIMPossible();
- void processSessionStates();
+ static void processSessionStates();
+
+ bool processConnectionStates();
void OnConnectionEstablished(const std::string &channelID);
void OnConnectionFailure(const std::string &channelID);
@@ -347,6 +349,15 @@ public:
bool isEmpty() { return mWebRTCConnections.empty(); }
+ bool isSpatial() { return mSessionType == SESSION_TYPE_ESTATE || mSessionType == SESSION_TYPE_PARCEL; }
+
+ typedef enum e_session_type
+ {
+ SESSION_TYPE_ESTATE = 1,
+ SESSION_TYPE_PARCEL,
+ SESSION_TYPE_P2P
+ } ESessionType;
+
std::string mHandle;
std::string mGroupHandle;
std::string mChannelID;
@@ -362,9 +373,8 @@ public:
LLUUID mIMSessionID;
LLUUID mCallerID;
int mErrorStatusCode;
- bool mIsChannel; // True for both group and spatial channels (false for p2p, PSTN)
- bool mIsSpatial; // True for spatial channels
- bool mIsP2P;
+ ESessionType mSessionType;
+
bool mIncoming;
bool mVoiceActive;
bool mReconnect; // Whether we should try to reconnect to this session if it's dropped
@@ -381,16 +391,17 @@ public:
LLUUID mVoiceFontID;
static void VerifySessions();
- static bool hasSession(const std::string &sessionID) { return mSessions.find(sessionID) != mSessions.end(); }
+ static bool hasSession(const std::string &sessionID)
+ { return mSessions.find(sessionID) != mSessions.end(); }
private:
- std::map<std::string, connectionPtr_t> mWebRTCConnections;
- std::string mPrimaryConnectionID;
+ std::list<connectionPtr_t> mWebRTCConnections;
+ std::string mPrimaryConnectionID;
+ static std::map<std::string, ptr_t> mSessions; // canonical list of outstanding sessions.
sessionState();
- static std::map<std::string, ptr_t> mSessions; // canonical list of outstanding sessions.
static void for_eachPredicate(const std::pair<std::string, LLWebRTCVoiceClient::sessionState::wptr_t> &a, sessionFunc_t func);
@@ -406,7 +417,6 @@ public:
// Private Member Functions
//////////////////////////////////////////////////////
- static void predProcessSessionStates(const LLWebRTCVoiceClient::sessionStatePtr_t &session);
static void predOnConnectionEstablished(const LLWebRTCVoiceClient::sessionStatePtr_t &session, std::string channelID);
static void predOnConnectionFailure(const LLWebRTCVoiceClient::sessionStatePtr_t &session, std::string channelID);
static void predSendData(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const std::string& spatial_data, const std::string& volume_data);
@@ -415,7 +425,6 @@ public:
static void predSetMicGain(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 volume);
static void predSetSpeakerVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 volume);
static void predShutdownSession(const LLWebRTCVoiceClient::sessionStatePtr_t &session);
- void reapEmptySessions();
//////////////////////////////
/// @name TVC/Server management and communication
@@ -476,9 +485,6 @@ public:
void verifySessionState(void);
- void joinedAudioSession(const sessionStatePtr_t &session);
- void leftAudioSession(const sessionStatePtr_t &session);
-
// This is called in several places where the session _may_ need to be deleted.
// It contains logic for whether to delete the session or keep it around.
void reapSession(const sessionStatePtr_t &session);
@@ -596,12 +602,8 @@ private:
bool mIsInitialized;
bool mShutdownComplete;
- bool checkParcelChanged(bool update = false);
bool switchChannel(const std::string channelID,
- bool spatial = true,
- bool no_reconnect = false,
- bool is_p2p = false,
- std::string hash = "",
+ sessionState::ESessionType sessionType,
S32 parcel_local_id = INVALID_PARCEL_ID);
void joinSession(const sessionStatePtr_t &session);
@@ -808,6 +810,10 @@ protected:
}
EVoiceConnectionState getVoiceConnectionState()
{
+ if (mVoiceStateMutex.isLocked())
+ {
+ LL_WARNS("Voice") << "LOCKED." << LL_ENDL;
+ }
LLMutexLock lock(&mVoiceStateMutex);
return mVoiceConnectionState;
}
@@ -839,6 +845,7 @@ protected:
llwebrtc::LLWebRTCDataInterface *mWebRTCDataInterface;
};
+#define VOICE_ELAPSED LLVoiceTimer(__FUNCTION__);
#endif //LL_WebRTC_VOICE_CLIENT_H