summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Linden <brad@lindenlab.com>2024-08-20 09:44:14 -0700
committerBrad Linden <brad@lindenlab.com>2024-08-20 09:44:14 -0700
commit68f712615f6858d66aef1d030fb18debb1a2dae4 (patch)
tree08a0b93af46ca152d72238dffd9543af1b19ce2c
parent9f7dd0177201fe080c287144b99a70125be1fb2b (diff)
parent1d017b76292cf8c7afad34ec54d7401e2f1795e5 (diff)
Merge remote-tracking branch 'origin/release/2024.06-atlasaurus' into develop
# Conflicts: # autobuild.xml # indra/newview/llvoicewebrtc.cpp
-rw-r--r--autobuild.xml82
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp45
-rw-r--r--indra/llmessage/message_string_table.cpp1
-rw-r--r--indra/llui/llfloater.cpp8
-rw-r--r--indra/llui/llfloater.h1
-rw-r--r--indra/llwebrtc/CMakeLists.txt6
-rw-r--r--indra/llwebrtc/llwebrtc.cpp86
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h2
-rw-r--r--indra/newview/llconversationview.cpp14
-rw-r--r--indra/newview/llflexibleobject.cpp2
-rw-r--r--indra/newview/llfloaterimcontainer.cpp6
-rw-r--r--indra/newview/llfloaterimcontainer.h2
-rw-r--r--indra/newview/llfloaterimsession.cpp17
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp6
-rw-r--r--indra/newview/llfloaterimsessiontab.h1
-rw-r--r--indra/newview/llimview.cpp5
-rw-r--r--indra/newview/llpanelgroup.cpp7
-rw-r--r--indra/newview/llpanelpeople.cpp15
-rw-r--r--indra/newview/llpanelprofile.cpp53
-rw-r--r--indra/newview/llspeakingindicatormanager.cpp7
-rw-r--r--indra/newview/llviewermedia.cpp4
-rw-r--r--indra/newview/llviewertexture.cpp2
-rw-r--r--indra/newview/llvoicechannel.cpp23
-rw-r--r--indra/newview/llvoicechannel.h4
-rw-r--r--indra/newview/llvoiceclient.cpp30
-rw-r--r--indra/newview/llvoiceclient.h12
-rw-r--r--indra/newview/llvoicewebrtc.cpp107
-rw-r--r--indra/newview/llvoicewebrtc.h9
28 files changed, 356 insertions, 201 deletions
diff --git a/autobuild.xml b/autobuild.xml
index e4dc2da201..02dfde7520 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -749,18 +749,6 @@
</map>
<key>glm</key>
<map>
- <key>canonical_repo</key>
- <string>https://github.com/secondlife/3p-glm</string>
- <key>copyright</key>
- <string>Copyright (c) 2005 - G-Truc Creation</string>
- <key>description</key>
- <string>OpenGL Mathematics</string>
- <key>license</key>
- <string>MIT</string>
- <key>license_file</key>
- <string>LICENSES/glm_license.txt</string>
- <key>name</key>
- <string>glm</string>
<key>platforms</key>
<map>
<key>common</key>
@@ -778,16 +766,28 @@
<string>common</string>
</map>
</map>
- <key>source_type</key>
- <string>git</string>
+ <key>license</key>
+ <string>MIT</string>
+ <key>license_file</key>
+ <string>LICENSES/glm_license.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2005 - G-Truc Creation</string>
+ <key>version</key>
+ <string>v1.0.1</string>
+ <key>name</key>
+ <string>glm</string>
<key>vcs_branch</key>
<string>refs/tags/v1.0.1-r1</string>
<key>vcs_revision</key>
<string>399cd5ba57a9267a560ce07e50a0f8c5fe3dc66f</string>
<key>vcs_url</key>
<string>git://github.com/secondlife/3p-glm.git</string>
- <key>version</key>
- <string>v1.0.1</string>
+ <key>canonical_repo</key>
+ <string>https://github.com/secondlife/3p-glm</string>
+ <key>description</key>
+ <string>OpenGL Mathematics</string>
+ <key>source_type</key>
+ <string>git</string>
</map>
<key>gstreamer</key>
<map>
@@ -1426,14 +1426,6 @@
</map>
<key>llphysicsextensions_source</key>
<map>
- <key>copyright</key>
- <string>Copyright (c) 2010, Linden Research, Inc.</string>
- <key>license</key>
- <string>internal</string>
- <key>license_file</key>
- <string>LICENSES/llphysicsextensions.txt</string>
- <key>name</key>
- <string>llphysicsextensions_source</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -1485,8 +1477,16 @@
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>internal</string>
+ <key>license_file</key>
+ <string>LICENSES/llphysicsextensions.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2010, Linden Research, Inc.</string>
<key>version</key>
<string>1.0.66e6919</string>
+ <key>name</key>
+ <string>llphysicsextensions_source</string>
</map>
<key>llphysicsextensions_stub</key>
<map>
@@ -2032,16 +2032,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
</map>
<key>openal</key>
<map>
- <key>copyright</key>
- <string>Copyright (C) 1999-2007 by authors.</string>
- <key>description</key>
- <string>OpenAL Soft is a software implementation of the OpenAL 3D audio API.</string>
- <key>license</key>
- <string>LGPL2</string>
- <key>license_file</key>
- <string>LICENSES/openal-soft.txt</string>
- <key>name</key>
- <string>openal</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -2087,8 +2077,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>LGPL2</string>
+ <key>license_file</key>
+ <string>LICENSES/openal-soft.txt</string>
+ <key>copyright</key>
+ <string>Copyright (C) 1999-2007 by authors.</string>
<key>version</key>
<string>1.23.1</string>
+ <key>name</key>
+ <string>openal</string>
+ <key>description</key>
+ <string>OpenAL Soft is a software implementation of the OpenAL 3D audio API.</string>
</map>
<key>openjpeg</key>
<map>
@@ -2643,11 +2643,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>baabb11f324be350253b1fb58cf262c1aa19fa70</string>
+ <string>3570b6442d472cd97bad8622c2ec2571d72218a0</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.67-debug/webrtc-m114.5735.08.67-debug.10190042668-darwin64-10190042668.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.72-test/webrtc-m114.5735.08.72-test.10444682919-darwin64-10444682919.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2657,11 +2657,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>a13776c8f99f8975665be66ff8b51a80ba46c718</string>
+ <string>eadf6aa99313940ded11801d42c11375669f1628</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.67-debug/webrtc-m114.5735.08.67-debug.10190042668-linux64-10190042668.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.72-test/webrtc-m114.5735.08.72-test.10444682919-linux64-10444682919.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2671,11 +2671,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>965ef5d65a14191a52ee9ec6a9a8a1d2ce3f2ffb</string>
+ <string>0081fd35290adbc8e66dd366535fb6cd8a966f1e</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.67-debug/webrtc-m114.5735.08.67-debug.10190042668-windows64-10190042668.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.72-test/webrtc-m114.5735.08.72-test.10444682919-windows64-10444682919.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2688,7 +2688,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (c) 2011, The WebRTC project authors. All rights reserved.</string>
<key>version</key>
- <string>m114.5735.08.67-debug.10190042668</string>
+ <string>m114.5735.08.72-test.10444682919</string>
<key>name</key>
<string>webrtc</string>
<key>vcs_branch</key>
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index be3e585ef8..375cb050cc 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -159,7 +159,8 @@ AccumulatorBufferGroup* ThreadRecorder::activate( AccumulatorBufferGroup* record
ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording )
{
#if LL_TRACE_ENABLED
- if (mActiveRecordings.empty()) return mActiveRecordings.end();
+ if (mActiveRecordings.empty())
+ return mActiveRecordings.end();
mActiveRecordings.back()->mPartialRecording.sync();
BlockTimer::updateTimes();
@@ -202,7 +203,7 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate(
#endif
}
-void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording )
+void ThreadRecorder::deactivate(AccumulatorBufferGroup* recording)
{
#if LL_TRACE_ENABLED
active_recording_list_t::iterator recording_it = bringUpToDate(recording);
@@ -228,9 +229,10 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording )
#endif
}
-ThreadRecorder::ActiveRecording::ActiveRecording( AccumulatorBufferGroup* target )
+ThreadRecorder::ActiveRecording::ActiveRecording(AccumulatorBufferGroup* target)
: mTargetRecording(target)
-{}
+{
+}
void ThreadRecorder::ActiveRecording::movePartialToTarget()
{
@@ -243,30 +245,30 @@ void ThreadRecorder::ActiveRecording::movePartialToTarget()
// called by child thread
-void ThreadRecorder::addChildRecorder( class ThreadRecorder* child )
+void ThreadRecorder::addChildRecorder(ThreadRecorder* child)
{
#if LL_TRACE_ENABLED
- { LLMutexLock lock(&mChildListMutex);
- mChildThreadRecorders.push_back(child);
- }
+ LLMutexLock lock(&mChildListMutex);
+ mChildThreadRecorders.push_back(child);
#endif
}
// called by child thread
-void ThreadRecorder::removeChildRecorder( class ThreadRecorder* child )
+void ThreadRecorder::removeChildRecorder(ThreadRecorder* child)
{
#if LL_TRACE_ENABLED
- { LLMutexLock lock(&mChildListMutex);
- mChildThreadRecorders.remove(child);
- }
+ LLMutexLock lock(&mChildListMutex);
+ mChildThreadRecorders.remove(child);
#endif
}
void ThreadRecorder::pushToParent()
{
#if LL_TRACE_ENABLED
- { LLMutexLock lock(&mSharedRecordingMutex);
- LLTrace::get_thread_recorder()->bringUpToDate(&mThreadRecordingBuffers);
+ if (ThreadRecorder* recorder = LLTrace::get_thread_recorder())
+ {
+ LLMutexLock lock(&mSharedRecordingMutex);
+ recorder->bringUpToDate(&mThreadRecordingBuffers);
mSharedRecordingBuffers.append(mThreadRecordingBuffers);
mThreadRecordingBuffers.reset();
}
@@ -278,15 +280,14 @@ void ThreadRecorder::pullFromChildren()
{
#if LL_TRACE_ENABLED
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
- if (mActiveRecordings.empty()) return;
-
- { LLMutexLock lock(&mChildListMutex);
-
+ if (!mActiveRecordings.empty())
+ {
+ LLMutexLock lock(&mChildListMutex);
AccumulatorBufferGroup& target_recording_buffers = mActiveRecordings.back()->mPartialRecording;
target_recording_buffers.sync();
for (LLTrace::ThreadRecorder* rec : mChildThreadRecorders)
- { LLMutexLock lock(&(rec->mSharedRecordingMutex));
-
+ {
+ LLMutexLock lock(&(rec->mSharedRecordingMutex));
target_recording_buffers.merge(rec->mSharedRecordingBuffers);
rec->mSharedRecordingBuffers.reset();
}
@@ -294,13 +295,11 @@ void ThreadRecorder::pullFromChildren()
#endif
}
-
-void set_master_thread_recorder( ThreadRecorder* recorder )
+void set_master_thread_recorder(ThreadRecorder* recorder)
{
sMasterThreadRecorder = recorder;
}
-
ThreadRecorder* get_master_thread_recorder()
{
return sMasterThreadRecorder;
diff --git a/indra/llmessage/message_string_table.cpp b/indra/llmessage/message_string_table.cpp
index 6d2157eec9..084c373265 100644
--- a/indra/llmessage/message_string_table.cpp
+++ b/indra/llmessage/message_string_table.cpp
@@ -88,4 +88,3 @@ char* LLMessageStringTable::getString(const char *str)
}
return mString[hash_value];
}
-
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 12d5c41de1..ff174d8470 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1966,6 +1966,14 @@ void LLFloater::onClickClose( LLFloater* self )
self->onClickCloseBtn();
}
+// static
+void LLFloater::onClickClose(LLFloater* self, bool app_quitting)
+{
+ if (!self)
+ return;
+ self->onClickCloseBtn(app_quitting);
+}
+
void LLFloater::onClickCloseBtn(bool app_quitting)
{
closeFloater(false);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 3d75c42f60..9be2240f6f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -363,6 +363,7 @@ public:
// }
static void onClickClose(LLFloater* floater);
+ static void onClickClose(LLFloater* floater, bool app_quitting);
static void onClickMinimize(LLFloater* floater);
static void onClickTearOff(LLFloater* floater);
static void onClickDock(LLFloater* floater);
diff --git a/indra/llwebrtc/CMakeLists.txt b/indra/llwebrtc/CMakeLists.txt
index 30aaec1265..a18b716003 100644
--- a/indra/llwebrtc/CMakeLists.txt
+++ b/indra/llwebrtc/CMakeLists.txt
@@ -31,6 +31,7 @@ add_library (llwebrtc SHARED ${llwebrtc_SOURCE_FILES})
set_target_properties(llwebrtc PROPERTIES PUBLIC_HEADER llwebrtc.h)
if (WINDOWS)
+ cmake_policy(SET CMP0091 NEW)
set_target_properties(llwebrtc
PROPERTIES
LINK_FLAGS "/debug /LARGEADDRESSAWARE"
@@ -42,7 +43,10 @@ if (WINDOWS)
wmcodecdspuuid
msdmo
strmiids
- iphlpapi)
+ iphlpapi
+ libcmt)
+ # as the webrtc libraries are release, build this binary as release as well.
+ target_compile_options(llwebrtc PRIVATE "/MT")
if (USE_BUGSPLAT)
set_target_properties(llwebrtc PROPERTIES PDB_OUTPUT_DIRECTORY "${SYMBOLS_STAGING_DIR}")
endif (USE_BUGSPLAT)
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index 2c890acbdb..0daa767766 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -206,10 +206,10 @@ void LLWebRTCImpl::init()
mTuningDeviceModule->SetAudioDeviceSink(this);
mTuningDeviceModule->InitMicrophone();
mTuningDeviceModule->InitSpeaker();
+ mTuningDeviceModule->SetStereoRecording(false);
+ mTuningDeviceModule->SetStereoPlayout(true);
mTuningDeviceModule->InitRecording();
mTuningDeviceModule->InitPlayout();
- mTuningDeviceModule->SetStereoRecording(true);
- mTuningDeviceModule->SetStereoPlayout(true);
updateDevices();
});
@@ -227,10 +227,6 @@ void LLWebRTCImpl::init()
mPeerDeviceModule->EnableBuiltInAEC(false);
mPeerDeviceModule->InitMicrophone();
mPeerDeviceModule->InitSpeaker();
- mPeerDeviceModule->InitRecording();
- mPeerDeviceModule->InitPlayout();
- mPeerDeviceModule->SetStereoRecording(true);
- mPeerDeviceModule->SetStereoPlayout(true);
});
// The custom processor allows us to retrieve audio data (and levels)
@@ -251,8 +247,9 @@ void LLWebRTCImpl::init()
apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh;
apm_config.transient_suppression.enabled = true;
apm_config.pipeline.multi_channel_render = true;
- apm_config.pipeline.multi_channel_capture = true;
- apm_config.pipeline.multi_channel_capture = true;
+ apm_config.pipeline.multi_channel_capture = false;
+
+ mAudioProcessingModule->ApplyConfig(apm_config);
webrtc::ProcessingConfig processing_config;
processing_config.input_stream().set_num_channels(2);
@@ -264,10 +261,8 @@ void LLWebRTCImpl::init()
processing_config.reverse_output_stream().set_num_channels(2);
processing_config.reverse_output_stream().set_sample_rate_hz(48000);
- mAudioProcessingModule->ApplyConfig(apm_config);
mAudioProcessingModule->Initialize(processing_config);
-
mPeerConnectionFactory = webrtc::CreatePeerConnectionFactory(mNetworkThread.get(),
mWorkerThread.get(),
mSignalingThread.get(),
@@ -279,7 +274,6 @@ void LLWebRTCImpl::init()
nullptr /* audio_mixer */,
mAudioProcessingModule);
- mWorkerThread->BlockingCall([this]() { mPeerDeviceModule->StartPlayout(); });
}
void LLWebRTCImpl::terminate()
@@ -331,6 +325,8 @@ void LLWebRTCImpl::setRecording(bool recording)
{
if (recording)
{
+ mPeerDeviceModule->SetStereoRecording(false);
+ mPeerDeviceModule->InitRecording();
mPeerDeviceModule->StartRecording();
}
else
@@ -340,6 +336,24 @@ void LLWebRTCImpl::setRecording(bool recording)
});
}
+void LLWebRTCImpl::setPlayout(bool playing)
+{
+ mWorkerThread->PostTask(
+ [this, playing]()
+ {
+ if (playing)
+ {
+ mPeerDeviceModule->SetStereoPlayout(true);
+ mPeerDeviceModule->InitPlayout();
+ mPeerDeviceModule->StartPlayout();
+ }
+ else
+ {
+ mPeerDeviceModule->StopPlayout();
+ }
+ });
+}
+
void LLWebRTCImpl::setAudioConfig(LLWebRTCDeviceInterface::AudioConfig config)
{
webrtc::AudioProcessing::Config apm_config;
@@ -402,7 +416,6 @@ void LLWebRTCImpl::unsetDevicesObserver(LLWebRTCDevicesObserver *observer)
void ll_set_device_module_capture_device(rtc::scoped_refptr<webrtc::AudioDeviceModule> device_module, int16_t device)
{
- device_module->StopRecording();
#if WEBRTC_WIN
if (device < 0)
{
@@ -417,10 +430,9 @@ void ll_set_device_module_capture_device(rtc::scoped_refptr<webrtc::AudioDeviceM
// has it at 0
device_module->SetRecordingDevice(device + 1);
#endif
+ device_module->SetStereoRecording(false);
device_module->InitMicrophone();
device_module->InitRecording();
- device_module->SetStereoRecording(false);
- device_module->StartRecording();
}
void LLWebRTCImpl::setCaptureDevice(const std::string &id)
@@ -444,18 +456,32 @@ void LLWebRTCImpl::setCaptureDevice(const std::string &id)
mRecordingDevice = recordingDevice;
if (mTuningMode)
{
- mWorkerThread->PostTask([this, recordingDevice]() { ll_set_device_module_capture_device(mTuningDeviceModule, recordingDevice); });
+ mWorkerThread->PostTask([this, recordingDevice]()
+ {
+ ll_set_device_module_capture_device(mTuningDeviceModule, recordingDevice);
+ });
}
else
{
- mWorkerThread->PostTask([this, recordingDevice]() { ll_set_device_module_capture_device(mPeerDeviceModule, recordingDevice); });
+ mWorkerThread->PostTask([this, recordingDevice]()
+ {
+ bool recording = mPeerDeviceModule->Recording();
+ if (recording)
+ {
+ mPeerDeviceModule->StopRecording();
+ }
+ ll_set_device_module_capture_device(mPeerDeviceModule, recordingDevice);
+ if (recording)
+ {
+ mPeerDeviceModule->StartRecording();
+ }
+ });
}
}
void ll_set_device_module_render_device(rtc::scoped_refptr<webrtc::AudioDeviceModule> device_module, int16_t device)
{
- device_module->StopPlayout();
#if WEBRTC_WIN
if (device < 0)
{
@@ -468,9 +494,9 @@ void ll_set_device_module_render_device(rtc::scoped_refptr<webrtc::AudioDeviceMo
#else
device_module->SetPlayoutDevice(device + 1);
#endif
+ device_module->SetStereoPlayout(true);
device_module->InitSpeaker();
device_module->InitPlayout();
- device_module->SetStereoPlayout(true);
}
void LLWebRTCImpl::setRenderDevice(const std::string &id)
@@ -506,8 +532,16 @@ void LLWebRTCImpl::setRenderDevice(const std::string &id)
mWorkerThread->PostTask(
[this, playoutDevice]()
{
+ bool playing = mPeerDeviceModule->Playing();
+ if (playing)
+ {
+ mPeerDeviceModule->StopPlayout();
+ }
ll_set_device_module_render_device(mPeerDeviceModule, playoutDevice);
- mPeerDeviceModule->StartPlayout();
+ if (playing)
+ {
+ mPeerDeviceModule->StartPlayout();
+ }
});
}
}
@@ -592,6 +626,8 @@ void LLWebRTCImpl::setTuningMode(bool enable)
//mTuningDeviceModule->StopPlayout();
ll_set_device_module_render_device(mPeerDeviceModule, mPlayoutDevice);
ll_set_device_module_capture_device(mPeerDeviceModule, mRecordingDevice);
+ mPeerDeviceModule->SetStereoPlayout(true);
+ mPeerDeviceModule->SetStereoRecording(false);
mPeerDeviceModule->InitPlayout();
mPeerDeviceModule->InitRecording();
mPeerDeviceModule->StartPlayout();
@@ -635,6 +671,11 @@ LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection()
mPeerConnections.emplace_back(peerConnection);
peerConnection->enableSenderTracks(!mMute);
+ if (mPeerConnections.empty())
+ {
+ setRecording(true);
+ setPlayout(true);
+ }
return peerConnection.get();
}
@@ -649,6 +690,7 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
if (mPeerConnections.empty())
{
setRecording(false);
+ setPlayout(false);
}
}
@@ -662,7 +704,7 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :
mWebRTCImpl(nullptr),
mPeerConnection(nullptr),
- mMute(false),
+ mMute(true),
mAnswerReceived(false)
{
}
@@ -684,8 +726,8 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl)
}
void LLWebRTCPeerConnectionImpl::terminate()
{
- mWebRTCImpl->PostSignalingTask(
- [=]()
+ mWebRTCImpl->SignalingBlockingCall(
+ [this]()
{
if (mPeerConnection)
{
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index 9504e6573b..b93a1fdb01 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -278,6 +278,8 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS
// enables/disables capture via the capture device
void setRecording(bool recording);
+ void setPlayout(bool playing);
+
protected:
LLWebRTCLogSink* mLogSink;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index cb2370f413..b19b6f8dec 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -98,10 +98,7 @@ LLConversationViewSession::~LLConversationViewSession()
if (mVoiceClientObserver)
{
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
- }
+ LLVoiceClient::removeObserver(mVoiceClientObserver);
delete mVoiceClientObserver;
}
@@ -259,16 +256,15 @@ bool LLConversationViewSession::postBuild()
icon->setVisible(true);
mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true);
mIsInActiveVoiceChannel = true;
- if(LLVoiceClient::instanceExists())
- {
+
if (mVoiceClientObserver)
{
- LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
+ LLVoiceClient::removeObserver(mVoiceClientObserver);
delete mVoiceClientObserver;
}
mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
- LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver);
- }
+ LLVoiceClient::addObserver(mVoiceClientObserver);
+
break;
}
default:
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index b6f1eea802..7d098b2676 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -775,7 +775,7 @@ bool LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
}
}
- if (volume->mDrawable.isNull())
+ if (volume->mDrawable.isNull() || volume->mDrawable->isDead())
{
return true; // No update to complete
}
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index f43f403755..abf15ea9cf 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -2444,7 +2444,7 @@ void LLFloaterIMContainer::closeHostedFloater()
onClickCloseBtn();
}
-void LLFloaterIMContainer::closeAllConversations()
+void LLFloaterIMContainer::closeAllConversations(bool app_quitting)
{
std::vector<LLUUID> ids;
for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
@@ -2459,7 +2459,7 @@ void LLFloaterIMContainer::closeAllConversations()
for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(*it);
- LLFloater::onClickClose(conversationFloater);
+ LLFloater::onClickClose(conversationFloater, app_quitting);
}
}
@@ -2482,7 +2482,7 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
{
if(app_quitting)
{
- closeAllConversations();
+ closeAllConversations(app_quitting);
onClickCloseBtn(app_quitting);
}
else
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index e11445d779..d1cfd3442c 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -117,7 +117,7 @@ public:
void assignResizeLimits();
virtual bool handleKeyHere(KEY key, MASK mask );
/*virtual*/ void closeFloater(bool app_quitting = false);
- void closeAllConversations();
+ void closeAllConversations(bool app_quitting);
void closeSelectedConversations(const uuid_vec_t& ids);
/*virtual*/ bool isFrontmost();
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 5dd78fe1db..557b3f27c5 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -138,8 +138,14 @@ void LLFloaterIMSession::onTearOffClicked()
}
// virtual
-void LLFloaterIMSession::onClickCloseBtn(bool)
+void LLFloaterIMSession::onClickCloseBtn(bool app_qutting)
{
+ if (app_qutting)
+ {
+ LLFloaterIMSessionTab::onClickCloseBtn();
+ return;
+ }
+
LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
if (session != NULL)
@@ -287,10 +293,8 @@ void LLFloaterIMSession::sendMsg(const std::string& msg)
LLFloaterIMSession::~LLFloaterIMSession()
{
mVoiceChannelStateChangeConnection.disconnect();
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
+
+ LLVoiceClient::removeObserver(this);
LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
@@ -366,7 +370,7 @@ bool LLFloaterIMSession::postBuild()
childSetAction("voice_call_btn", boost::bind(&LLFloaterIMSession::onCallButtonClicked, this));
- LLVoiceClient::getInstance()->addObserver(this);
+ LLVoiceClient::addObserver(this);
//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
//see LLFloaterIMPanel for how it is done (IB)
@@ -537,6 +541,7 @@ void LLFloaterIMSession::boundVoiceChannel()
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
if(voice_channel)
{
+ mVoiceChannelStateChangeConnection.disconnect();
mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(
boost::bind(&LLFloaterIMSession::onVoiceChannelStateChanged, this, _1, _2));
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 2eebb6cc64..2621ce576c 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -547,6 +547,12 @@ void LLFloaterIMSessionTab::closeFloater(bool app_quitting)
super::closeFloater(app_quitting);
}
+void LLFloaterIMSessionTab::deleteAllChildren()
+{
+ super::deleteAllChildren();
+ mVoiceButton = NULL;
+}
+
std::string LLFloaterIMSessionTab::appendTime()
{
std::string timeStr = "[" + LLTrans::getString("TimeHour") + "]:"
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 29e10184b1..6dd8e62482 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -82,6 +82,7 @@ public:
/*virtual*/ void setVisible(bool visible);
/*virtual*/ void setFocus(bool focus);
/*virtual*/ void closeFloater(bool app_quitting = false);
+ /*virtual*/ void deleteAllChildren();
// Handle the left hand participant list widgets
void addConversationViewParticipant(LLConversationItem* item, bool update_view = true);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 33e6d2d1b2..136b59f3a6 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -3861,6 +3861,11 @@ bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection dir
{
voice_channel->setChannelInfo(voice_channel_info);
}
+ else if (voice_channel->getState() < LLVoiceChannel::STATE_READY)
+ {
+ // restart if there wa an error or it was hang up
+ voice_channel->resetChannelInfo();
+ }
voice_channel->setCallDirection(direction);
voice_channel->activate();
return true;
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 079a5583d4..65aa1876b0 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -98,10 +98,7 @@ LLPanelGroup::LLPanelGroup()
LLPanelGroup::~LLPanelGroup()
{
LLGroupMgr::getInstance()->removeObserver(this);
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
+ LLVoiceClient::removeObserver(this);
}
void LLPanelGroup::onOpen(const LLSD& key)
@@ -196,7 +193,7 @@ bool LLPanelGroup::postBuild()
mJoinText = panel_general->getChild<LLUICtrl>("join_cost_text");
}
- LLVoiceClient::getInstance()->addObserver(this);
+ LLVoiceClient::addObserver(this);
return true;
}
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 107b1cf6cd..25672db318 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -336,7 +336,7 @@ public:
LLAvatarTracker::instance().addObserver(this);
// For notification when SIP online status changes.
- LLVoiceClient::getInstance()->addObserver(this);
+ LLVoiceClient::addObserver(this);
mInvObserver = new LLInventoryFriendCardObserver(this);
}
@@ -344,10 +344,7 @@ public:
{
// will be deleted by ~LLInventoryModel
//delete mInvObserver;
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
+ LLVoiceClient::removeObserver(this);
LLAvatarTracker::instance().removeObserver(this);
}
@@ -575,15 +572,13 @@ LLPanelPeople::~LLPanelPeople()
delete mFriendListUpdater;
delete mRecentListUpdater;
+ LLVoiceClient::removeObserver(this);
+
mNearbyFilterCommitConnection.disconnect();
mFriedsFilterCommitConnection.disconnect();
mGroupsFilterCommitConnection.disconnect();
mRecentFilterCommitConnection.disconnect();
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
}
void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list)
@@ -740,7 +735,7 @@ bool LLPanelPeople::postBuild()
// Must go after setting commit callback and initializing all pointers to children.
mTabContainer->selectTabByName(NEARBY_TAB_NAME);
- LLVoiceClient::getInstance()->addObserver(this);
+ LLVoiceClient::addObserver(this);
// call this method in case some list is empty and buttons can be in inconsistent state
updateButtons();
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 8f44b28ebe..9711729498 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -703,10 +703,7 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife()
LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
}
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
- }
+ LLVoiceClient::removeObserver((LLVoiceClientStatusObserver*)this);
if (mAvatarNameCacheConnection.connected())
{
@@ -1020,7 +1017,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)
setDescriptionText(avatar_data->about_text);
- mSecondLifePic->setValue(avatar_data->image_id);
+ mSecondLifePic->setValue(avatar_data->image_id);
if (getSelfProfile())
{
@@ -1168,10 +1165,10 @@ void LLPanelProfileSecondLife::fillAgeData(const LLAvatarData* avatar_data)
}
else
{
- std::string register_date = getString("age_format");
- LLSD args_age;
+ std::string register_date = getString("age_format");
+ LLSD args_age;
args_age["[AGE]"] = LLDateUtil::ageFromDate(avatar_data->born_on, LLDate::now());
- LLStringUtil::format(register_date, args_age);
+ LLStringUtil::format(register_date, args_age);
userAgeCtrl->setValue(register_date);
}
@@ -1614,12 +1611,12 @@ void LLPanelProfileSecondLife::onShowInSearchCallback()
if (value == mAllowPublish)
return;
- mAllowPublish = value;
+ mAllowPublish = value;
saveAgentUserInfoCoro("allow_publish", value);
-}
+ }
void LLPanelProfileSecondLife::onHideAgeCallback()
-{
+ {
bool value = mHideAgeCombo->getValue().asInteger();
if (value == mHideAge)
return;
@@ -1768,35 +1765,35 @@ void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id)
if (mSecondLifePic->getImageAssetId() == id)
return;
- std::function<void(bool)> callback = [id](bool result)
- {
- if (result)
+ std::function<void(bool)> callback = [id](bool result)
{
- LLAvatarIconIDCache::getInstance()->add(gAgentID, id);
+ if (result)
+ {
+ LLAvatarIconIDCache::getInstance()->add(gAgentID, id);
// Should trigger callbacks in icon controls (or request Legacy)
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID);
- }
- };
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID);
+ }
+ };
if (!saveAgentUserInfoCoro("sl_image_id", id, callback))
return;
mSecondLifePic->setValue(id);
- LLFloater *floater = mFloaterProfileTextureHandle.get();
- if (floater)
- {
- LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
- if (id == LLUUID::null)
- {
- texture_view->resetAsset();
- }
- else
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
{
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (id == LLUUID::null)
+ {
+ texture_view->resetAsset();
+ }
+ else
+ {
texture_view->loadAsset(id);
+ }
}
}
-}
//////////////////////////////////////////////////////////////////////////
// LLPanelProfileWeb
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index ca99d351bb..a9ef5e244d 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -182,7 +182,7 @@ void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker
SpeakingIndicatorManager::SpeakingIndicatorManager()
{
LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&SpeakingIndicatorManager::sOnCurrentChannelChanged, this, _1));
- LLVoiceClient::getInstance()->addObserver(this);
+ LLVoiceClient::addObserver(this);
}
SpeakingIndicatorManager::~SpeakingIndicatorManager()
@@ -193,10 +193,7 @@ void SpeakingIndicatorManager::cleanupSingleton()
{
// Don't use LLVoiceClient::getInstance() here without a check,
// singleton MAY have already been destroyed.
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
+ LLVoiceClient::removeObserver(this);
}
void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 6fc9f2a6f0..9739cac311 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1758,9 +1758,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
bool javascript_enabled = gSavedSettings.getBOOL("BrowserJavascriptEnabled");
media_source->setJavascriptEnabled(javascript_enabled || clean_browser);
- // collect 'web security disabled' (see Chrome --web-security-disabled) setting from prefs and send to embedded browser
- bool web_security_disabled = gSavedSettings.getBOOL("BrowserWebSecurityDisabled");
- media_source->setWebSecurityDisabled(web_security_disabled || clean_browser);
+ media_source->setWebSecurityDisabled(clean_browser);
// collect setting indicates if local file access from file URLs is allowed from prefs and send to embedded browser
bool file_access_from_file_urls = gSavedSettings.getBOOL("BrowserFileAccessFromFileUrls");
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 5974625dfa..eab564a856 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -846,7 +846,7 @@ S32 LLViewerTexture::getTotalNumFaces() const
S32 LLViewerTexture::getNumFaces(U32 ch) const
{
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
- return mNumFaces[ch];
+ return ch < LLRender::NUM_TEXTURE_CHANNELS ? mNumFaces[ch] : 0;
}
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 5914303e80..eb1cd00940 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -81,10 +81,7 @@ LLVoiceChannel::~LLVoiceChannel()
{
sCurrentVoiceChannel = NULL;
// Must check instance exists here, the singleton MAY have already been destroyed.
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
+ LLVoiceClient::removeObserver(this);
}
sVoiceChannelMap.erase(mSessionID);
@@ -118,6 +115,12 @@ void LLVoiceChannel::setChannelInfo(const LLSD &channelInfo)
}
}
+void LLVoiceChannel::resetChannelInfo()
+{
+ mChannelInfo = LLSD();
+ mState = STATE_NO_CHANNEL_INFO;
+}
+
void LLVoiceChannel::onChange(EStatusType type, const LLSD& channelInfo, bool proximal)
{
LL_DEBUGS("Voice") << "Incoming channel info: " << channelInfo << LL_ENDL;
@@ -219,7 +222,7 @@ void LLVoiceChannel::deactivate()
LLVoiceClient::getInstance()->setUserPTTState(false);
}
}
- LLVoiceClient::getInstance()->removeObserver(this);
+ LLVoiceClient::removeObserver(this);
if (sCurrentVoiceChannel == this)
{
@@ -259,7 +262,7 @@ void LLVoiceChannel::activate()
setState(STATE_CALL_STARTED);
}
- LLVoiceClient::getInstance()->addObserver(this);
+ LLVoiceClient::addObserver(this);
//do not send earlier, channel should be initialized, should not be in STATE_NO_CHANNEL_INFO state
sCurrentVoiceChannelChangedSignal(this->mSessionID);
@@ -751,7 +754,7 @@ void LLVoiceChannelProximal::deactivate()
{
setState(STATE_HUNG_UP);
}
- LLVoiceClient::getInstance()->removeObserver(this);
+ LLVoiceClient::removeObserver(this);
LLVoiceClient::getInstance()->activateSpatialChannel(false);
}
@@ -918,6 +921,12 @@ void LLVoiceChannelP2P::setChannelInfo(const LLSD& channel_info)
}
}
+void LLVoiceChannelP2P::resetChannelInfo()
+{
+ mChannelInfo = LLVoiceClient::getInstance()->getP2PChannelInfoTemplate(mOtherUserID);
+ mState = STATE_NO_CHANNEL_INFO; // we have template, not full info
+}
+
void LLVoiceChannelP2P::setState(EState state)
{
LL_INFOS("Voice") << "P2P CALL STATE CHANGE: incoming=" << int(mReceivedCall) << " oldstate=" << mState << " newstate=" << state << LL_ENDL;
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index d50a6f589a..4d7bf551e1 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -72,7 +72,8 @@ public:
virtual void handleError(EStatusType status);
virtual void deactivate();
virtual void activate();
- virtual void setChannelInfo(const LLSD &channelInfo);
+ virtual void setChannelInfo(const LLSD& channelInfo);
+ virtual void resetChannelInfo();
virtual void requestChannelInfo();
virtual bool isActive() const;
virtual bool callStarted() const;
@@ -189,6 +190,7 @@ class LLVoiceChannelP2P : public LLVoiceChannelGroup
void requestChannelInfo() override;
void deactivate() override;
void setChannelInfo(const LLSD& channel_info) override;
+ void resetChannelInfo() override;
protected:
void setState(EState state) override;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 21f469abb3..5af7528ada 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -796,8 +796,14 @@ void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer)
void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer)
{
- LLVivoxVoiceClient::getInstance()->removeObserver(observer);
- LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
+ if (LLVivoxVoiceClient::instanceExists())
+ {
+ LLVivoxVoiceClient::getInstance()->removeObserver(observer);
+ }
+ if (LLWebRTCVoiceClient::instanceExists())
+ {
+ LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
+ }
}
void LLVoiceClient::addObserver(LLFriendObserver* observer)
@@ -808,8 +814,14 @@ void LLVoiceClient::addObserver(LLFriendObserver* observer)
void LLVoiceClient::removeObserver(LLFriendObserver* observer)
{
- LLVivoxVoiceClient::getInstance()->removeObserver(observer);
- LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
+ if (LLVivoxVoiceClient::instanceExists())
+ {
+ LLVivoxVoiceClient::getInstance()->removeObserver(observer);
+ }
+ if (LLWebRTCVoiceClient::instanceExists())
+ {
+ LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
+ }
}
void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
@@ -820,8 +832,14 @@ void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer)
{
- LLVivoxVoiceClient::getInstance()->removeObserver(observer);
- LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
+ if (LLVivoxVoiceClient::instanceExists())
+ {
+ LLVivoxVoiceClient::getInstance()->removeObserver(observer);
+ }
+ if (LLWebRTCVoiceClient::instanceExists())
+ {
+ LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
+ }
}
std::string LLVoiceClient::sipURIFromID(const LLUUID &id) const
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 3476571ca4..d53f512d82 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -481,12 +481,12 @@ public:
void onRegionChanged();
- void addObserver(LLVoiceClientStatusObserver* observer);
- void removeObserver(LLVoiceClientStatusObserver* observer);
- void addObserver(LLFriendObserver* observer);
- void removeObserver(LLFriendObserver* observer);
- void addObserver(LLVoiceClientParticipantObserver* observer);
- void removeObserver(LLVoiceClientParticipantObserver* observer);
+ static void addObserver(LLVoiceClientStatusObserver* observer);
+ static void removeObserver(LLVoiceClientStatusObserver* observer);
+ static void addObserver(LLFriendObserver* observer);
+ static void removeObserver(LLFriendObserver* observer);
+ static void addObserver(LLVoiceClientParticipantObserver* observer);
+ static void removeObserver(LLVoiceClientParticipantObserver* observer);
std::string sipURIFromID(const LLUUID &id) const;
LLSD getP2PChannelInfoTemplate(const LLUUID& id) const;
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 35ba75138c..a651a22a01 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -236,11 +236,26 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
LLWebRTCVoiceClient::~LLWebRTCVoiceClient()
{
+}
+
+void LLWebRTCVoiceClient::cleanupSingleton()
+{
if (mAvatarNameCacheConnection.connected())
{
mAvatarNameCacheConnection.disconnect();
}
+
sShuttingDown = true;
+ if (mSession)
+ {
+ mSession->shutdownAllConnections();
+ }
+ if (mNextSession)
+ {
+ mNextSession->shutdownAllConnections();
+ }
+ cleanUp();
+ sessionState::clearSessions();
}
//---------------------------------------------------
@@ -253,6 +268,7 @@ void LLWebRTCVoiceClient::init(LLPumpIO* pump)
mWebRTCDeviceInterface = llwebrtc::getDeviceInterface();
mWebRTCDeviceInterface->setDevicesObserver(this);
mMainQueue = LL::WorkQueue::getInstance("mainloop");
+ refreshDeviceLists();
}
void LLWebRTCVoiceClient::terminate()
@@ -621,7 +637,7 @@ void LLWebRTCVoiceClient::clearCaptureDevices()
void LLWebRTCVoiceClient::addCaptureDevice(const LLVoiceDevice& device)
{
- LL_DEBUGS("Voice") << "display: '" << device.display_name << "' device: '" << device.full_name << "'" << LL_ENDL;
+ LL_INFOS("Voice") << "Voice Capture Device: '" << device.display_name << "' (" << device.full_name << ")" << LL_ENDL;
mCaptureDevices.push_back(device);
}
@@ -654,6 +670,10 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi
void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices,
const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices)
{
+ if (sShuttingDown)
+ {
+ return;
+ }
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
@@ -686,7 +706,7 @@ void LLWebRTCVoiceClient::clearRenderDevices()
void LLWebRTCVoiceClient::addRenderDevice(const LLVoiceDevice& device)
{
- LL_DEBUGS("Voice") << "display: '" << device.display_name << "' device: '" << device.full_name << "'" << LL_ENDL;
+ LL_INFOS("Voice") << "Voice Render Device: '" << device.display_name << "' (" << device.full_name << ")" << LL_ENDL;
mRenderDevices.push_back(device);
}
@@ -1705,7 +1725,7 @@ void LLWebRTCVoiceClient::predSetUserMute(const LLWebRTCVoiceClient::sessionStat
//------------------------------------------------------------------------
// Sessions
-std::map<std::string, LLWebRTCVoiceClient::sessionState::ptr_t> LLWebRTCVoiceClient::sessionState::mSessions;
+std::map<std::string, LLWebRTCVoiceClient::sessionState::ptr_t> LLWebRTCVoiceClient::sessionState::sSessions;
LLWebRTCVoiceClient::sessionState::sessionState() :
@@ -1792,13 +1812,19 @@ void LLWebRTCVoiceClient::sessionState::addSession(
const std::string & channelID,
LLWebRTCVoiceClient::sessionState::ptr_t& session)
{
- mSessions[channelID] = session;
+ sSessions[channelID] = session;
}
LLWebRTCVoiceClient::sessionState::~sessionState()
{
LL_DEBUGS("Voice") << "Destroying session CHANNEL=" << mChannelID << LL_ENDL;
+ if (!mShuttingDown)
+ {
+ shutdownAllConnections();
+ }
+ mWebRTCConnections.clear();
+
removeAllParticipants();
}
@@ -1808,8 +1834,8 @@ LLWebRTCVoiceClient::sessionState::ptr_t LLWebRTCVoiceClient::sessionState::matc
sessionStatePtr_t result;
// *TODO: My kingdom for a lambda!
- std::map<std::string, ptr_t>::iterator it = mSessions.find(channel_id);
- if (it != mSessions.end())
+ std::map<std::string, ptr_t>::iterator it = sSessions.find(channel_id);
+ if (it != sSessions.end())
{
result = (*it).second;
}
@@ -1818,17 +1844,17 @@ LLWebRTCVoiceClient::sessionState::ptr_t LLWebRTCVoiceClient::sessionState::matc
void LLWebRTCVoiceClient::sessionState::for_each(sessionFunc_t func)
{
- std::for_each(mSessions.begin(), mSessions.end(), boost::bind(for_eachPredicate, _1, func));
+ std::for_each(sSessions.begin(), sSessions.end(), boost::bind(for_eachPredicate, _1, func));
}
void LLWebRTCVoiceClient::sessionState::reapEmptySessions()
{
std::map<std::string, ptr_t>::iterator iter;
- for (iter = mSessions.begin(); iter != mSessions.end();)
+ for (iter = sSessions.begin(); iter != sSessions.end();)
{
if (iter->second->isEmpty())
{
- iter = mSessions.erase(iter);
+ iter = sSessions.erase(iter);
}
else
{
@@ -1874,6 +1900,11 @@ LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::addSession(const std
}
}
+void LLWebRTCVoiceClient::sessionState::clearSessions()
+{
+ sSessions.clear();
+}
+
LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::findP2PSession(const LLUUID &agent_id)
{
sessionStatePtr_t result = sessionState::matchSessionByChannelID(agent_id.asString());
@@ -1913,14 +1944,14 @@ void LLWebRTCVoiceClient::sessionState::processSessionStates()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- auto iter = mSessions.begin();
- while (iter != mSessions.end())
+ auto iter = sSessions.begin();
+ while (iter != sSessions.end())
{
if (!iter->second->processConnectionStates() && iter->second->mShuttingDown)
{
// if the connections associated with a session are gone,
// and this session is shutting down, remove it.
- iter = mSessions.erase(iter);
+ iter = sSessions.erase(iter);
}
else
{
@@ -2121,8 +2152,10 @@ LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID &regionID, const s
mOutstandingRequests(0),
mChannelID(channelID),
mRegionID(regionID),
+ mPrimary(true),
mRetryWaitPeriod(0)
{
+
// retries wait a short period...randomize it so
// all clients don't try to reconnect at once.
mRetryWaitSecs = (F32)((F32) rand() / (RAND_MAX)) + 0.5f;
@@ -2368,6 +2401,12 @@ void LLVoiceWebRTCConnection::OnPeerConnectionClosed()
setVoiceConnectionState(VOICE_STATE_CLOSED);
mOutstandingRequests--;
}
+ else if (LLWebRTCVoiceClient::isShuttingDown())
+ {
+ // disconnect was initialized by llwebrtc::terminate() instead of connectionStateMachine
+ LL_INFOS("Voice") << "Peer connection has closed, but state is " << mVoiceConnectionState << LL_ENDL;
+ setVoiceConnectionState(VOICE_STATE_CLOSED);
+ }
});
}
@@ -2474,7 +2513,11 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
connection->mOutstandingRequests--;
- connection->setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
+
+ if (connection->getVoiceConnectionState() == VOICE_STATE_WAIT_FOR_EXIT)
+ {
+ connection->setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
+ }
}
// Tell the simulator to tell the Secondlife WebRTC server that we want a voice
@@ -2708,6 +2751,17 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
{
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();
+ }
+ }
// we'll stay here as long as the session remains up.
if (mShutDown)
@@ -2736,9 +2790,18 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
break;
case VOICE_STATE_DISCONNECT:
- setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT);
- LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro",
- boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this->shared_from_this()));
+ if (!LLWebRTCVoiceClient::isShuttingDown())
+ {
+ setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT);
+ LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro",
+ boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this->shared_from_this()));
+ }
+ else
+ {
+ // llwebrtc::terminate() is already shuting down the connection.
+ setVoiceConnectionState(VOICE_STATE_WAIT_FOR_CLOSE);
+ mOutstandingRequests++;
+ }
break;
case VOICE_STATE_WAIT_FOR_EXIT:
@@ -2748,7 +2811,11 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
{
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_CLOSE);
mOutstandingRequests++;
- mWebRTCPeerConnectionInterface->shutdownConnection();
+ if (!LLWebRTCVoiceClient::isShuttingDown())
+ {
+ mWebRTCPeerConnectionInterface->shutdownConnection();
+ }
+ // else was already posted by llwebrtc::terminate().
break;
case VOICE_STATE_WAIT_FOR_CLOSE:
break;
@@ -2978,7 +3045,7 @@ void LLVoiceWebRTCConnection::sendJoin()
boost::json::object root;
boost::json::object join_obj;
LLUUID regionID = gAgent.getRegion()->getRegionID();
- if ((regionID == mRegionID) || !isSpatial())
+ if (mPrimary)
{
join_obj["p"] = true;
}
@@ -2996,6 +3063,10 @@ LLVoiceWebRTCSpatialConnection::LLVoiceWebRTCSpatialConnection(const LLUUID &reg
LLVoiceWebRTCConnection(regionID, channelID),
mParcelLocalID(parcelLocalID)
{
+ if (gAgent.getRegion())
+ {
+ mPrimary = (regionID == gAgent.getRegion()->getRegionID());
+ }
}
LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection()
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index c8dbb64574..32127f9b17 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -70,6 +70,7 @@ class LLWebRTCVoiceClient : public LLSingleton<LLWebRTCVoiceClient>,
virtual ~LLWebRTCVoiceClient();
public:
+ void cleanupSingleton() override;
/// @name LLVoiceModuleInterface virtual implementations
/// @see LLVoiceModuleInterface
//@{
@@ -300,6 +301,7 @@ public:
static void for_each(sessionFunc_t func);
static void reapEmptySessions();
+ static void clearSessions();
bool isEmpty() { return mWebRTCConnections.empty(); }
@@ -319,7 +321,7 @@ public:
participantUUIDMap mParticipantsByUUID;
static bool hasSession(const std::string &sessionID)
- { return mSessions.find(sessionID) != mSessions.end(); }
+ { return sSessions.find(sessionID) != sSessions.end(); }
bool mHangupOnLastLeave; // notify observers after the session becomes empty.
bool mNotifyOnFirstJoin; // notify observers when the first peer joins.
@@ -330,7 +332,7 @@ public:
private:
- static std::map<std::string, ptr_t> mSessions; // canonical list of outstanding sessions.
+ static std::map<std::string, ptr_t> sSessions; // canonical list of outstanding sessions.
static void for_eachPredicate(const std::pair<std::string,
LLWebRTCVoiceClient::sessionState::wptr_t> &a,
@@ -620,7 +622,7 @@ class LLVoiceWebRTCConnection :
bool connectionStateMachine();
- virtual bool isSpatial() = 0;
+ virtual bool isSpatial() { return false; }
LLUUID getRegionID() { return mRegionID; }
@@ -684,6 +686,7 @@ class LLVoiceWebRTCConnection :
LLVoiceClientStatusObserver::EStatusType mCurrentStatus;
LLUUID mRegionID;
+ bool mPrimary;
LLUUID mViewerSession;
std::string mChannelID;