Merge pull request #4494 from secondlife/roxie/fix-4419

Straighten out muting to prevent echo when crossing from vivox to webrtc regions near a webrtc region boundary.
master
Jonathan "Geenz" Goodman 2025-08-08 18:43:32 -04:00 committed by GitHub
commit 5b1c783be7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 63 additions and 11 deletions

View File

@ -904,12 +904,12 @@ void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable)
// set_enabled shouldn't be done on the worker thread.
if (mPeerConnection)
{
mPeerConnection->SetAudioRecording(enable);
auto senders = mPeerConnection->GetSenders();
for (auto &sender : senders)
{
sender->track()->set_enabled(enable);
}
mPeerConnection->SetAudioRecording(enable);
}
}
@ -964,6 +964,9 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
{
if (mPeerConnection)
{
// SetAudioRecording must be called before enabling/disabling tracks.
mPeerConnection->SetAudioRecording(enable);
auto senders = mPeerConnection->GetSenders();
RTC_LOG(LS_INFO) << __FUNCTION__ << (mMute ? "disabling" : "enabling") << " streams count " << senders.size();
@ -982,7 +985,6 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
track->set_enabled(enable);
}
}
mPeerConnection->SetAudioRecording(enable);
}
});
}

View File

@ -52,6 +52,7 @@
#include "llcachename.h"
#include "llimview.h" // for LLIMMgr
#include "llworld.h"
#include "llviewerregion.h"
#include "llparcel.h"
#include "llviewerparcelmgr.h"
#include "llfirstuse.h"
@ -2004,6 +2005,33 @@ bool LLWebRTCVoiceClient::sessionState::processConnectionStates()
return !mWebRTCConnections.empty();
}
// Helper function to check if a region supports WebRTC voice
bool LLWebRTCVoiceClient::estateSessionState::isRegionWebRTCEnabled(const LLUUID& regionID)
{
LLViewerRegion* region = LLWorld::getInstance()->getRegionFromID(regionID);
if (!region)
{
LL_WARNS("Voice") << "Could not find region " << regionID
<< " for voice server type validation" << LL_ENDL;
return false;
}
LLSD simulatorFeatures;
region->getSimulatorFeatures(simulatorFeatures);
bool isWebRTCEnabled = simulatorFeatures.has("VoiceServerType") &&
simulatorFeatures["VoiceServerType"].asString() == "webrtc";
if (!isWebRTCEnabled)
{
LL_DEBUGS("Voice") << "Region " << regionID << " VoiceServerType is not 'webrtc' (got: "
<< (simulatorFeatures.has("VoiceServerType") ? simulatorFeatures["VoiceServerType"].asString() : "none") << ")"
<< LL_ENDL;
}
return isWebRTCEnabled;
}
// processing of spatial voice connection states requires special handling.
// as neighboring regions need to be started up or shut down depending
// on our location.
@ -2028,6 +2056,13 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
// shut down connections to neighbors that are too far away.
spatialConnection.get()->shutDown();
}
else if (!isRegionWebRTCEnabled(regionID))
{
// shut down connections to neighbors that no longer support WebRTC voice.
LL_DEBUGS("Voice") << "Shutting down connection to neighbor region " << regionID
<< " - no longer supports WebRTC voice" << LL_ENDL;
spatialConnection.get()->shutDown();
}
if (!spatialConnection.get()->isShuttingDown())
{
neighbor_ids.erase(regionID);
@ -2037,11 +2072,20 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
// add new connections for new neighbors
for (auto &neighbor : neighbor_ids)
{
connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID));
// Only connect if the region supports WebRTC voice server type
if (isRegionWebRTCEnabled(neighbor))
{
connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID));
mWebRTCConnections.push_back(connection);
connection->setMuteMic(mMuted);
connection->setSpeakerVolume(mSpeakerVolume);
mWebRTCConnections.push_back(connection);
connection->setMuteMic(mMuted); // mute will be set for primary connection when that connection comes up
connection->setSpeakerVolume(mSpeakerVolume);
}
else
{
LL_DEBUGS("Voice") << "Skipping neighbor region " << neighbor
<< " - does not support WebRTC voice" << LL_ENDL;
}
}
}
return LLWebRTCVoiceClient::sessionState::processConnectionStates();
@ -2391,6 +2435,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac
}
LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL;
mWebRTCAudioInterface = audio_interface;
mWebRTCAudioInterface->setMute(true); // mute will be set appropriately later when we finish setting up.
setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED);
});
}
@ -2750,7 +2795,8 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
}
// update the peer connection with the various characteristics of
// this connection.
mWebRTCAudioInterface->setMute(mMuted);
// this connection will come up as muted, but will be set to the appropriate
// value later on.
mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume);
LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID);
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_DATA_CHANNEL);
@ -2795,6 +2841,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
if (primary != mPrimary)
{
mPrimary = primary;
if (mWebRTCAudioInterface)
{
mWebRTCAudioInterface->setMute(mMuted || !mPrimary);
}
sendJoin();
}
}
@ -3097,10 +3147,7 @@ LLVoiceWebRTCSpatialConnection::LLVoiceWebRTCSpatialConnection(const LLUUID &reg
LLVoiceWebRTCConnection(regionID, channelID),
mParcelLocalID(parcelLocalID)
{
if (gAgent.getRegion())
{
mPrimary = (regionID == gAgent.getRegion()->getRegionID());
}
mPrimary = false; // will be set to primary after connection established
}
LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection()

View File

@ -351,6 +351,9 @@ public:
bool isSpatial() override { return true; }
bool isEstate() override { return true; }
bool isCallbackPossible() override { return false; }
private:
bool isRegionWebRTCEnabled(const LLUUID& regionID);
};
class parcelSessionState : public sessionState