SL-20543 - voice over region boundaries.

This commit includes code to allow the llwebrtc.dll/dylib to allow
multiple connections at once.
meow-7.2.2
Roxie Linden 2023-11-08 10:13:15 -08:00
parent 459de5087e
commit 85aea763d1
5 changed files with 537 additions and 466 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/**
* @file llaccordionctrl.cpp
* @brief Accordion panel implementation
* @file llwebrtc.h
* @brief WebRTC interface
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
@ -17,7 +17,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* License along with this library; if not, write to the Free tSoftware
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
@ -44,8 +44,6 @@
namespace llwebrtc
{
LLSYMEXPORT void init();
LLSYMEXPORT void terminate();
struct LLWebRTCIceCandidate
{
@ -87,6 +85,10 @@ class LLWebRTCDeviceInterface
virtual void setTuningMode(bool enable) = 0;
virtual float getTuningAudioLevel() = 0;
virtual void setSpeakerVolume(float volume) = 0; // volume between 0.0 and 1.0
virtual void setMicrophoneVolume(float volume) = 0; // volume between 0.0 and 1.0
virtual float getPeerAudioLevel() = 0;
};
class LLWebRTCAudioObserver
@ -100,15 +102,12 @@ class LLWebRTCAudioInterface
virtual void setAudioObserver(LLWebRTCAudioObserver *observer) = 0;
virtual void unsetAudioObserver(LLWebRTCAudioObserver *observer) = 0;
virtual void setMute(bool mute) = 0;
virtual void setSpeakerVolume(float volume) = 0; // volume between 0.0 and 1.0
virtual float getAudioLevel() = 0;
};
class LLWebRTCDataObserver
{
public:
virtual void OnDataReceived(const std::string& data, bool binary) = 0;
virtual void OnDataChannelReady() = 0;
};
class LLWebRTCDataInterface
@ -133,9 +132,10 @@ class LLWebRTCSignalingObserver
virtual void OnOfferAvailable(const std::string& sdp) = 0;
virtual void OnRenegotiationNeeded() = 0;
virtual void OnAudioEstablished(LLWebRTCAudioInterface *audio_interface) = 0;
virtual void OnDataChannelReady(LLWebRTCDataInterface *data_interface) = 0;
};
class LLWebRTCSignalInterface
class LLWebRTCPeerConnection
{
public:
virtual void setSignalingObserver(LLWebRTCSignalingObserver* observer) = 0;
@ -146,9 +146,11 @@ class LLWebRTCSignalInterface
virtual void AnswerAvailable(const std::string &sdp) = 0;
};
LLSYMEXPORT void init();
LLSYMEXPORT void terminate();
LLSYMEXPORT LLWebRTCDeviceInterface* getDeviceInterface();
LLSYMEXPORT LLWebRTCSignalInterface* getSignalingInterface();
LLSYMEXPORT LLWebRTCDataInterface* getDataInterface();
LLSYMEXPORT LLWebRTCPeerConnection* newPeerConnection();
LLSYMEXPORT void freePeerConnection(LLWebRTCPeerConnection *connection);
}
#endif // LLWEBRTC_H

View File

@ -1,6 +1,6 @@
/**
* @file llaccordionctrl.cpp
* @brief Accordion panel implementation
* @file llwebrtc_impl.h
* @brief WebRTC Interface implementation.
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
@ -63,6 +63,8 @@
namespace llwebrtc
{
class LLWebRTCPeerConnectionImpl;
class LLAudioDeviceObserver : public webrtc::AudioDeviceDataObserver
{
public:
@ -87,16 +89,7 @@ class LLAudioDeviceObserver : public webrtc::AudioDeviceDataObserver
float mMicrophoneEnergy;
};
class LLWebRTCImpl : public LLWebRTCDeviceInterface,
public LLWebRTCSignalInterface,
public LLWebRTCAudioInterface,
public LLWebRTCDataInterface,
public webrtc::PeerConnectionObserver,
public webrtc::CreateSessionDescriptionObserver,
public webrtc::SetRemoteDescriptionObserverInterface,
public webrtc::SetLocalDescriptionObserverInterface,
public webrtc::DataChannelObserver
class LLWebRTCImpl : public LLWebRTCDeviceInterface
{
public:
LLWebRTCImpl() :
@ -116,15 +109,112 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface,
void setDevicesObserver(LLWebRTCDevicesObserver *observer) override;
void unsetDevicesObserver(LLWebRTCDevicesObserver *observer) override;
void setCaptureDevice(const std::string& id) override;
void setCaptureDevice(const std::string& id) override;
void setRenderDevice(const std::string& id) override;
void setTuningMode(bool enable) override;
float getTuningAudioLevel() override;
float getPeerAudioLevel() override;
void setSpeakerVolume(float volume) override; // range 0.0-1.0
void setMicrophoneVolume(float volume) override; // range 0.0-1.0
//
// LLWebRTCSignalInterface
// Helpers
//
void PostWorkerTask(absl::AnyInvocable<void() &&> task,
const webrtc::Location& location = webrtc::Location::Current())
{
mWorkerThread->PostTask(std::move(task), location);
}
void PostSignalingTask(absl::AnyInvocable<void() &&> task,
const webrtc::Location& location = webrtc::Location::Current())
{
mSignalingThread->PostTask(std::move(task), location);
}
void PostNetworkTask(absl::AnyInvocable<void() &&> task,
const webrtc::Location& location = webrtc::Location::Current())
{
mNetworkThread->PostTask(std::move(task), location);
}
void WorkerBlockingCall(rtc::FunctionView<void()> functor,
const webrtc::Location& location = webrtc::Location::Current())
{
mWorkerThread->BlockingCall(std::move(functor), location);
}
void SignalingBlockingCall(rtc::FunctionView<void()> functor,
const webrtc::Location& location = webrtc::Location::Current())
{
mSignalingThread->BlockingCall(std::move(functor), location);
}
void NetworkBlockingCall(rtc::FunctionView<void()> functor,
const webrtc::Location& location = webrtc::Location::Current())
{
mNetworkThread->BlockingCall(std::move(functor), location);
}
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> getPeerConnectionFactory() { return mPeerConnectionFactory; }
LLWebRTCPeerConnection * newPeerConnection();
void freePeerConnection(LLWebRTCPeerConnection * peer_connection);
protected:
std::unique_ptr<rtc::Thread> mNetworkThread;
std::unique_ptr<rtc::Thread> mWorkerThread;
std::unique_ptr<rtc::Thread> mSignalingThread;
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
webrtc::PeerConnectionInterface::RTCConfiguration mConfiguration;
std::unique_ptr<webrtc::TaskQueueFactory> mTaskQueueFactory;
// Devices
void updateDevices();
rtc::scoped_refptr<webrtc::AudioDeviceModule> mTuningDeviceModule;
rtc::scoped_refptr<webrtc::AudioDeviceModule> mPeerDeviceModule;
std::vector<LLWebRTCDevicesObserver *> mVoiceDevicesObserverList;
// accessors in webrtc aren't apparently implemented yet.
int32_t mPlayoutDevice;
int32_t mRecordingDevice;
bool mMute;
LLAudioDeviceObserver * mTuningAudioDeviceObserver;
LLAudioDeviceObserver * mPeerAudioDeviceObserver;
// peer connections
std::vector<rtc::scoped_refptr<LLWebRTCPeerConnectionImpl>> mPeerConnections;
};
class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnection,
public LLWebRTCAudioInterface,
public LLWebRTCDataInterface,
public webrtc::PeerConnectionObserver,
public webrtc::CreateSessionDescriptionObserver,
public webrtc::SetRemoteDescriptionObserverInterface,
public webrtc::SetLocalDescriptionObserverInterface,
public webrtc::DataChannelObserver
{
public:
LLWebRTCPeerConnectionImpl() {}
~LLWebRTCPeerConnectionImpl() {}
void init(LLWebRTCImpl * webrtc_impl);
void terminate();
virtual void AddRef() const override = 0;
virtual rtc::RefCountReleaseStatus Release() const override = 0;
//
// LLWebRTCPeerConnection
//
void setSignalingObserver(LLWebRTCSignalingObserver *observer) override;
@ -140,8 +230,6 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface,
void setAudioObserver(LLWebRTCAudioObserver *observer) override;
void unsetAudioObserver(LLWebRTCAudioObserver *observer) override;
void setMute(bool mute) override;
void setSpeakerVolume(float folume) override; // range 0.0-1.0
float getAudioLevel() override;
//
// LLWebRTCDataInterface
@ -187,31 +275,17 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface,
//
void OnStateChange() override;
void OnMessage(const webrtc::DataBuffer& buffer) override;
// Helpers
void enableTracks(bool enable);
protected:
std::unique_ptr<rtc::Thread> mNetworkThread;
std::unique_ptr<rtc::Thread> mWorkerThread;
std::unique_ptr<rtc::Thread> mSignalingThread;
LLWebRTCImpl * mWebRTCImpl;
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
webrtc::PeerConnectionInterface::RTCConfiguration mConfiguration;
std::unique_ptr<webrtc::TaskQueueFactory> mTaskQueueFactory;
// Devices
void updateDevices();
rtc::scoped_refptr<webrtc::AudioDeviceModule> mTuningDeviceModule;
rtc::scoped_refptr<webrtc::AudioDeviceModule> mPeerDeviceModule;
std::vector<LLWebRTCDevicesObserver *> mVoiceDevicesObserverList;
// accessors in webrtc aren't apparently implemented yet.
int32_t mPlayoutDevice;
int32_t mRecordingDevice;
bool mMute;
LLAudioDeviceObserver * mTuningAudioDeviceObserver;
LLAudioDeviceObserver * mPeerAudioDeviceObserver;
// signaling
std::vector<LLWebRTCSignalingObserver *> mSignalingObserverList;
std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> mCachedIceCandidates;

View File

@ -307,7 +307,7 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
mIsCoroutineActive(false),
mWebRTCPump("WebRTCClientPump"),
mWebRTCDeviceInterface(nullptr),
mWebRTCSignalingInterface(nullptr),
mWebRTCPeerConnection(nullptr),
mWebRTCAudioInterface(nullptr)
{
sShuttingDown = false;
@ -364,11 +364,8 @@ void LLWebRTCVoiceClient::init(LLPumpIO *pump)
mWebRTCDeviceInterface = llwebrtc::getDeviceInterface();
mWebRTCDeviceInterface->setDevicesObserver(this);
mWebRTCSignalingInterface = llwebrtc::getSignalingInterface();
mWebRTCSignalingInterface->setSignalingObserver(this);
mWebRTCDataInterface = llwebrtc::getDataInterface();
mWebRTCDataInterface->setDataObserver(this);
mWebRTCPeerConnection = llwebrtc::newPeerConnection();
mWebRTCPeerConnection->setSignalingObserver(this);
}
void LLWebRTCVoiceClient::terminate()
@ -500,7 +497,7 @@ void LLWebRTCVoiceClient::setLoginInfo(
const std::string& channel_sdp)
{
mRemoteChannelSDP = channel_sdp;
mWebRTCSignalingInterface->AnswerAvailable(channel_sdp);
mWebRTCPeerConnection->AnswerAvailable(channel_sdp);
if(mAccountLoggedIn)
{
@ -862,7 +859,7 @@ bool LLWebRTCVoiceClient::establishVoiceConnection()
{
return false;
}
return mWebRTCSignalingInterface->initializeConnection();
return mWebRTCPeerConnection->initializeConnection();
}
bool LLWebRTCVoiceClient::breakVoiceConnection(bool corowait)
@ -896,7 +893,7 @@ bool LLWebRTCVoiceClient::breakVoiceConnection(bool corowait)
LLSD body;
body["logout"] = TRUE;
httpAdapter->postAndSuspend(httpRequest, url, body);
mWebRTCSignalingInterface->shutdownConnection();
mWebRTCPeerConnection->shutdownConnection();
return true;
}
@ -1136,11 +1133,14 @@ bool LLWebRTCVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession
addParticipantByID(gAgent.getID());
// tell peers that this participant has joined.
Json::FastWriter writer;
Json::Value root = getPositionAndVolumeUpdateJson(true);
root["j"] = true;
std::string json_data = writer.write(root);
mWebRTCDataInterface->sendData(json_data, false);
if (mWebRTCDataInterface)
{
Json::FastWriter writer;
Json::Value root = getPositionAndVolumeUpdateJson(true);
root["j"] = true;
std::string json_data = writer.write(root);
mWebRTCDataInterface->sendData(json_data, false);
}
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED);
@ -2235,7 +2235,7 @@ Json::Value LLWebRTCVoiceClient::getPositionAndVolumeUpdateJson(bool force)
if (!mMuteMic)
{
audio_level = (F32) mWebRTCAudioInterface->getAudioLevel();
audio_level = (F32) mWebRTCDeviceInterface->getPeerAudioLevel();
}
uint32_t uint_audio_level = mMuteMic ? 0 : (uint32_t) (audio_level * 128);
if (force || (uint_audio_level != mAudioLevel))
@ -2451,7 +2451,6 @@ void LLWebRTCVoiceClient::processIceUpdates()
if (mIceCandidates.size())
{
LLSD candidates = LLSD::emptyArray();
body["candidates"] = LLSD::emptyArray();
for (auto &ice_candidate : mIceCandidates)
{
LLSD body_candidate;
@ -2532,7 +2531,7 @@ void LLWebRTCVoiceClient::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *
LLMutexLock lock(&mVoiceStateMutex);
speaker_volume = mSpeakerVolume;
}
audio_interface->setSpeakerVolume(mSpeakerVolume);
mWebRTCDeviceInterface->setSpeakerVolume(mSpeakerVolume);
setVoiceControlStateUnless(VOICE_STATE_SESSION_ESTABLISHED, VOICE_STATE_SESSION_RETRY);
}
@ -2597,9 +2596,10 @@ void LLWebRTCVoiceClient::OnDataReceived(const std::string& data, bool binary)
}
}
void LLWebRTCVoiceClient::OnDataChannelReady()
void LLWebRTCVoiceClient::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface)
{
mWebRTCDataInterface = data_interface;
mWebRTCDataInterface->setDataObserver(this);
}
@ -4470,7 +4470,7 @@ void LLWebRTCVoiceClient::setVoiceVolume(F32 volume)
}
if (mWebRTCAudioInterface)
{
mWebRTCAudioInterface->setSpeakerVolume(volume);
mWebRTCDeviceInterface->setSpeakerVolume(volume);
}
}
}

View File

@ -271,7 +271,7 @@ public:
/// LLWebRTCDataObserver
//@{
void OnDataReceived(const std::string& data, bool binary) override;
void OnDataChannelReady() override;
void OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface) override;
//@}
void processIceUpdates();
@ -778,7 +778,7 @@ private:
buddyListMap mBuddyListMap;
llwebrtc::LLWebRTCDeviceInterface *mWebRTCDeviceInterface;
llwebrtc::LLWebRTCSignalInterface *mWebRTCSignalingInterface;
llwebrtc::LLWebRTCPeerConnection *mWebRTCPeerConnection;
llwebrtc::LLWebRTCAudioInterface *mWebRTCAudioInterface;
llwebrtc::LLWebRTCDataInterface *mWebRTCDataInterface;