summaryrefslogtreecommitdiff
path: root/indra/newview/llvoicevivox.cpp
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2016-05-06 10:28:42 -0400
committerOz Linden <oz@lindenlab.com>2016-05-06 10:28:42 -0400
commit950c41d184b340a7a3370c2cbda5d1eed9a17b0b (patch)
tree373912394af6834d7d56258becf46954244b8423 /indra/newview/llvoicevivox.cpp
parent20198b750d02c769ab6845226f98ce6e5dd1f20b (diff)
parent7f5e6cea124e1193b199a3eabd50bdab96340c13 (diff)
merge 4.0.4-release and MAINT-5974
Diffstat (limited to 'indra/newview/llvoicevivox.cpp')
-rw-r--r--indra/newview/llvoicevivox.cpp195
1 files changed, 94 insertions, 101 deletions
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index c9661dfb11..07427e0377 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -80,39 +80,49 @@
extern LLMenuBarGL* gMenuBarView;
extern void handle_voice_morphing_subscribe();
-const F32 VOLUME_SCALE_VIVOX = 0.01f;
+namespace {
+ const F32 VOLUME_SCALE_VIVOX = 0.01f;
-const F32 SPEAKING_TIMEOUT = 1.f;
+ const F32 SPEAKING_TIMEOUT = 1.f;
-static const std::string VOICE_SERVER_TYPE = "Vivox";
+ static const std::string VOICE_SERVER_TYPE = "Vivox";
-// Don't retry connecting to the daemon more frequently than this:
-const F32 CONNECT_THROTTLE_SECONDS = 1.0f;
+ // Don't retry connecting to the daemon more frequently than this:
+ const F32 CONNECT_THROTTLE_SECONDS = 1.0f;
-// Don't send positional updates more frequently than this:
-const F32 UPDATE_THROTTLE_SECONDS = 0.5f;
+ // Don't send positional updates more frequently than this:
+ const F32 UPDATE_THROTTLE_SECONDS = 0.5f;
-const F32 LOGIN_RETRY_SECONDS = 10.0f;
-const int MAX_LOGIN_RETRIES = 12;
+ const F32 LOGIN_ATTEMPT_TIMEOUT = 5.0f;
+ const int LOGIN_RETRY_MAX = 5;
+ const F32 LOGIN_RETRY_TIMEOUT = 4.0f;
-// Cosine of a "trivially" small angle
-const F32 MINUSCULE_ANGLE_COS = 0.999f;
+ const int PROVISION_RETRY_MAX = 5;
+ const F32 PROVISION_RETRY_TIMEOUT = 2.0;
-// Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine()
-// which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed
-// from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process
-// backs up processing join requests. There is a log statement that records when channel joins take longer than 100 frames.
-const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500;
+ // Cosine of a "trivially" small angle
+ const F32 MINUSCULE_ANGLE_COS = 0.999f;
-// How often to check for expired voice fonts in seconds
-const F32 VOICE_FONT_EXPIRY_INTERVAL = 10.f;
-// Time of day at which Vivox expires voice font subscriptions.
-// Used to replace the time portion of received expiry timestamps.
-static const std::string VOICE_FONT_EXPIRY_TIME = "T05:00:00Z";
+ const F32 SESSION_JOIN_TIMEOUT = 10.0f;
-// Maximum length of capture buffer recordings in seconds.
-const F32 CAPTURE_BUFFER_MAX_TIME = 10.f;
+ // Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine()
+ // which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed
+ // from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process
+ // backs up processing join requests. There is a log statement that records when channel joins take longer than 100 frames.
+ const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500;
+ // How often to check for expired voice fonts in seconds
+ const F32 VOICE_FONT_EXPIRY_INTERVAL = 10.f;
+ // Time of day at which Vivox expires voice font subscriptions.
+ // Used to replace the time portion of received expiry timestamps.
+ static const std::string VOICE_FONT_EXPIRY_TIME = "T05:00:00Z";
+
+ // Maximum length of capture buffer recordings in seconds.
+ const F32 CAPTURE_BUFFER_MAX_TIME = 10.f;
+
+ const int ERROR_VIVOX_OBJECT_NOT_FOUND = 1001;
+ const int ERROR_VIVOX_NOT_LOGGED_IN = 1007;
+}
static int scale_mic_volume(float volume)
{
@@ -129,8 +139,6 @@ static int scale_speaker_volume(float volume)
}
-const int ERROR_VIVOX_OBJECT_NOT_FOUND = 1001;
-const int ERROR_VIVOX_NOT_LOGGED_IN = 1007;
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -546,7 +554,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
// if we hit this and mRelogRequested is true, that indicates
// that we attempted to relog into Vivox and were rejected.
// Rather than just quit out of voice, we will tear it down (above)
- // and then reconstruct the voice connecino from scratch.
+ // and then reconstruct the voice connecion from scratch.
if (mRelogRequested)
{
while (isGatewayRunning())
@@ -784,13 +792,15 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
if (status == LLCore::HttpStatus(404))
{
- if (++retryCount > 5)
+ if (++retryCount > PROVISION_RETRY_MAX)
{
- LL_WARNS("Voice") << "Could not access voice provision cap after 5 attempts." << LL_ENDL;
+ LL_WARNS("Voice") << "Could not access voice provision cap after " << PROVISION_RETRY_MAX << " attempts." << LL_ENDL;
return false;
}
- LL_WARNS("Voice") << "Provision CAP 404. Retrying in 1.0" << LL_ENDL;
- llcoro::suspendUntilTimeout(1.0);
+
+ F32 timeout = pow(PROVISION_RETRY_TIMEOUT, static_cast<float>(retryCount));
+ LL_WARNS("Voice") << "Provision CAP 404. Retrying in " << timeout << " seconds." << LL_ENDL;
+ llcoro::suspendUntilTimeout(timeout);
continue;
}
@@ -888,38 +898,42 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
bool LLVivoxVoiceClient::loginToVivox()
{
- int loginRetryCount(0);
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
+ LLSD timeoutResult(LLSDMap("login", "timeout"));
+
+ int loginRetryCount(0);
+
bool response_ok(false);
bool account_login(false);
bool send_login(true);
do
{
+
mIsLoggingIn = true;
if (send_login)
loginSendMessage();
send_login = false;
- LLSD result = llcoro::suspendUntilEventOn(voicePump);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
if (result.has("login"))
{
std::string loginresp = result["login"];
- if (loginresp == "retry")
+ if ((loginresp == "retry") || (loginresp == "timeout"))
{
- if (!loginRetryCount)
+ if ((!loginRetryCount) && (loginresp != "timeout"))
{ // on first retry notify user
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGIN_RETRY);
}
- if ((++loginRetryCount > MAX_LOGIN_RETRIES) || (!result["login_retry"]))
+ if ((++loginRetryCount > LOGIN_RETRY_MAX) || (loginresp == "timeout"))
{
- LL_WARNS("Voice") << "too many login retries, giving up." << LL_ENDL;
+ LL_WARNS("Voice") << "too many login retries or timeout connecting, giving up." << LL_ENDL;
LLSD args;
std::stringstream errs;
errs << mVoiceAccountServerURI << "\n:UDP: 3478, 3479, 5060, 5062, 12000-17000";
@@ -942,8 +956,10 @@ bool LLVivoxVoiceClient::loginToVivox()
account_login = false;
send_login = true;
- LL_INFOS("Voice") << "will retry login in " << LOGIN_RETRY_SECONDS << " seconds." << LL_ENDL;
- llcoro::suspendUntilTimeout(LOGIN_RETRY_SECONDS);
+ F32 timeout = pow(LOGIN_RETRY_TIMEOUT, static_cast<float>(loginRetryCount)) - 1.0f;
+
+ LL_INFOS("Voice") << "will retry login in " << timeout << " seconds." << LL_ENDL;
+ llcoro::suspendUntilTimeout(timeout);
}
else if (loginresp == "failed")
{
@@ -982,7 +998,6 @@ bool LLVivoxVoiceClient::loginToVivox()
void LLVivoxVoiceClient::logoutOfVivox(bool wait)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
if (!mIsLoggedIn)
return;
@@ -995,7 +1010,10 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
if (wait)
{
- LLSD result = llcoro::suspendUntilEventOn(voicePump);
+ LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
+ LLSD timeoutResult(LLSDMap("lougout", "timeout"));
+
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
@@ -1169,6 +1187,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
if (!mVoiceEnabled && mIsInitialized)
{
+ LL_DEBUGS("Voice") << "Voice no longer enabled. Exiting." << LL_ENDL;
mIsJoiningSession = false;
// User bailed out during connect -- jump straight to teardown.
terminateAudioSession(true);
@@ -1177,6 +1196,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
}
else if (mSessionTerminateRequested)
{
+ LL_DEBUGS("Voice") << "Terminate requested" << LL_ENDL;
if (mAudioSession && !mAudioSession->mHandle.empty())
{
// Only allow direct exits from this state in p2p calls (for cancelling an invite).
@@ -1194,15 +1214,17 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
bool added(true);
bool joined(false);
+ LLSD timeoutResult(LLSDMap("session", "timeout"));
+
// It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4
// before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck.
// For now, the SessionGroup.AddSession response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined.
// This is a cheap way to make sure both have happened before proceeding.
do
{
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOnWithTimeout(voicePump, SESSION_JOIN_TIMEOUT, timeoutResult);
- LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
+ LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
if (result.has("session"))
{
if (result.has("handle"))
@@ -1215,14 +1237,15 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
}
std::string message = result["session"].asString();
+
if ((message == "added") || (message == "created"))
added = true;
else if (message == "joined")
joined = true;
- else if ((message == "failed") || (message == "removed"))
+ else if ((message == "failed") || (message == "removed") || (message == "timeout"))
{ // we will get a removed message if a voice call is declined.
- if (message == "failed")
+ if (message == "failed")
{
int reason = result["reason"].asInteger();
LL_WARNS("Voice") << "Add and join failed for reason " << reason << LL_ENDL;
@@ -1230,7 +1253,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
if ((reason == ERROR_VIVOX_NOT_LOGGED_IN) ||
(reason == ERROR_VIVOX_OBJECT_NOT_FOUND))
{
- LL_INFOS("Voice") << "Requesting reprovision and login." << LL_ENDL;
+ LL_DEBUGS("Voice") << "Requesting reprovision and login." << LL_ENDL;
requestRelog();
}
@@ -1472,11 +1495,9 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
notifyParticipantObservers();
notifyVoiceFontObservers();
- LLSD timeoutEvent = LLSD::emptyMap();
- timeoutEvent["timeout"] = LLSD::Boolean(true);
+ LLSD timeoutEvent(LLSDMap("timeout", LLSD::Boolean(true)));
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
- LLEventTimeout timeout(voicePump);
mIsInChannel = true;
mMuteMicDirty = true;
@@ -1528,8 +1549,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
sendLocalAudioUpdates();
mIsInitialized = true;
- timeout.eventAfter(UPDATE_THROTTLE_SECONDS, timeoutEvent);
- LLSD result = llcoro::suspendUntilEventOn(timeout);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
if (!result.has("timeout")) // logging the timeout event spams the log
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
if (result.has("session"))
@@ -1627,22 +1647,19 @@ void LLVivoxVoiceClient::recordingAndPlaybackMode()
int LLVivoxVoiceClient::voiceRecordBuffer()
{
- LLSD timeoutResult;
- timeoutResult["recplay"] = LLSD::String("stop");
+ LLSD timeoutResult(LLSDMap("recplay", "stop"));
LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL;
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
- LLEventTimeout timeout(voicePump);
- timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LLSD result;
captureBufferRecordStartSendMessage();
-
notifyVoiceFontObservers();
+
do
{
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -1660,14 +1677,11 @@ int LLVivoxVoiceClient::voiceRecordBuffer()
int LLVivoxVoiceClient::voicePlaybackBuffer()
{
- LLSD timeoutResult;
- timeoutResult["recplay"] = LLSD::String("stop");
+ LLSD timeoutResult(LLSDMap("recplay", "stop"));
LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL;
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
- LLEventTimeout timeout(voicePump);
- timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LLSD result;
do
@@ -1682,7 +1696,7 @@ int LLVivoxVoiceClient::voicePlaybackBuffer()
// Update UI, should really use a separate callback.
notifyVoiceFontObservers();
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -2902,11 +2916,9 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
session->mErrorStatusString = statusString;
if(session == mAudioSession)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("failed");
- vivoxevent["reason"] = LLSD::Integer(statusCode);
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "failed")
+ ("reason", LLSD::Integer(statusCode)));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -2923,10 +2935,8 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
{
setSessionHandle(session, sessionHandle);
}
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("created");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "created"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -2950,10 +2960,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
session->mErrorStatusString = statusString;
if(session == mAudioSession)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("failed");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "failed"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -2971,10 +2979,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
setSessionHandle(session, sessionHandle);
}
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("added");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "added"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3019,9 +3025,7 @@ void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusStrin
LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL;
// Should this ever fail? do we care if it does?
}
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["logout"] = LLSD::Boolean(true);
+ LLSD vivoxevent(LLSDMap("logout", LLSD::Boolean(true)));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -3036,9 +3040,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
mConnected = false;
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["connector"] = LLSD::Boolean(false);
+ LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -3146,10 +3148,8 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session)
// This is the session we're joining.
if(mIsJoiningSession)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(session->mHandle);
- vivoxevent["session"] = LLSD::String("joined");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
+ ("session", "joined"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3292,10 +3292,8 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session)
{
if (mAudioSession == session)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(session->mHandle);
- vivoxevent["session"] = LLSD::String("removed");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
+ ("session", "removed"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -6150,9 +6148,7 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st
{
// *TODO: We seem to get multiple events of this type. Should figure a way to advance only after
// receiving the last one.
- LLSD result = LLSD::emptyMap();
-
- result["voice_fonts"] = LLSD::Boolean(true);
+ LLSD result(LLSDMap("voice_fonts", LLSD::Boolean(true)));
LLEventPumps::instance().post("vivoxClientPump", result);
}
@@ -6325,8 +6321,7 @@ void LLVivoxVoiceClient::recordPreviewBuffer()
mCaptureBufferRecording = true;
- LLSD result;
- result["recplay"] = "record";
+ LLSD result(LLSDMap("recplay", "record"));
LLEventPumps::instance().post("vivoxClientPump", result);
}
@@ -6349,8 +6344,7 @@ void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id)
mPreviewVoiceFont = effect_id;
mCaptureBufferPlaying = true;
- LLSD result;
- result["recplay"] = "playback";
+ LLSD result(LLSDMap("recplay", "playback"));
LLEventPumps::instance().post("vivoxClientPump", result);
}
@@ -6359,8 +6353,7 @@ void LLVivoxVoiceClient::stopPreviewBuffer()
mCaptureBufferRecording = false;
mCaptureBufferPlaying = false;
- LLSD result;
- result["recplay"] = "quit";
+ LLSD result(LLSDMap("recplay", "quit"));
LLEventPumps::instance().post("vivoxClientPump", result);
}