Use LL::WorkQueue to handle transitions from llwebrtc threads to the main thread
parent
3794e3275c
commit
e4dee511ca
|
|
@ -580,7 +580,7 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl)
|
|||
}
|
||||
void LLWebRTCPeerConnectionImpl::terminate()
|
||||
{
|
||||
mWebRTCImpl->SignalingBlockingCall(
|
||||
mWebRTCImpl->PostSignalingTask(
|
||||
[this]()
|
||||
{
|
||||
if (mPeerConnection)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file LLWebRTCVoiceClient.cpp
|
||||
* @file llvoicewebrtc.cpp
|
||||
* @brief Implementation of LLWebRTCVoiceClient class which is the interface to the voice client process.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
|
|
@ -585,8 +585,19 @@ void LLWebRTCVoiceClient::setDevicesListUpdated(bool state)
|
|||
mDevicesListUpdated = state;
|
||||
}
|
||||
|
||||
void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices,
|
||||
const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices)
|
||||
// the singleton 'this' pointer will outlive the work queue.
|
||||
void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceList& render_devices,
|
||||
const llwebrtc::LLWebRTCVoiceDeviceList& capture_devices)
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue,
|
||||
[=]
|
||||
{
|
||||
OnDevicesChangedImpl(render_devices, capture_devices);
|
||||
});
|
||||
}
|
||||
|
||||
void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices,
|
||||
const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices)
|
||||
{
|
||||
std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
|
||||
std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
|
||||
|
|
@ -1412,6 +1423,7 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
|
|||
updatePosition();
|
||||
if (!mIsCoroutineActive)
|
||||
{
|
||||
mMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
LLCoros::instance().launch("LLWebRTCVoiceClient::voiceConnectionCoro",
|
||||
boost::bind(&LLWebRTCVoiceClient::voiceConnectionCoro, LLWebRTCVoiceClient::getInstance()));
|
||||
}
|
||||
|
|
@ -2000,6 +2012,7 @@ LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID ®ionID, const s
|
|||
|
||||
mWebRTCPeerConnectionInterface = llwebrtc::newPeerConnection();
|
||||
mWebRTCPeerConnectionInterface->setSignalingObserver(this);
|
||||
mMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
}
|
||||
|
||||
LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection()
|
||||
|
|
@ -2026,7 +2039,14 @@ LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection()
|
|||
// negotiated, updates about the best connectivity paths may trickle in. These need to be
|
||||
// sent to the Secondlife WebRTC server via the simulator so that both sides have a clear
|
||||
// view of the network environment.
|
||||
|
||||
// callback from llwebrtc
|
||||
void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state)
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnIceGatheringStateImpl(state); });
|
||||
}
|
||||
|
||||
void LLVoiceWebRTCConnection::OnIceGatheringStateImpl(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL;
|
||||
|
||||
|
|
@ -2034,13 +2054,11 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs
|
|||
{
|
||||
case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_COMPLETE:
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
mIceCompleted = true;
|
||||
break;
|
||||
}
|
||||
case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_NEW:
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
mIceCompleted = false;
|
||||
}
|
||||
default:
|
||||
|
|
@ -2048,9 +2066,14 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs
|
|||
}
|
||||
}
|
||||
|
||||
void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate &candidate)
|
||||
// callback from llwebrtc
|
||||
void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate& candidate)
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnIceCandidateImpl(candidate); });
|
||||
}
|
||||
|
||||
void LLVoiceWebRTCConnection::OnIceCandidateImpl(const llwebrtc::LLWebRTCIceCandidate &candidate)
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
mIceCandidates.push_back(candidate);
|
||||
}
|
||||
|
||||
|
|
@ -2182,10 +2205,24 @@ void LLVoiceWebRTCConnection::processIceUpdates()
|
|||
// and is passed to the simulator via a CAP, which then passes
|
||||
// it on to the Secondlife WebRTC server.
|
||||
|
||||
// callback from llwebrtc
|
||||
void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnOfferAvailableImpl(sdp); });
|
||||
}
|
||||
|
||||
//
|
||||
// The LLWebRTCVoiceConnection object will not be deleted
|
||||
// before the webrtc connection itself is shut down, so
|
||||
// we shouldn't be getting this callback on a nonexistant
|
||||
// this pointer.
|
||||
void LLVoiceWebRTCConnection::OnOfferAvailableImpl(const std::string &sdp)
|
||||
{
|
||||
if (mShutDown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LL_DEBUGS("Voice") << "On Offer Available." << LL_ENDL;
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
mChannelSDP = sdp;
|
||||
if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_SESSION_START)
|
||||
{
|
||||
|
|
@ -2193,15 +2230,42 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
|
|||
}
|
||||
}
|
||||
|
||||
// Notifications from the webrtc library.
|
||||
void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *audio_interface)
|
||||
// callback from llwebrtc
|
||||
void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface)
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnAudioEstablishedImpl(audio_interface); });
|
||||
}
|
||||
|
||||
//
|
||||
// The LLWebRTCVoiceConnection object will not be deleted
|
||||
// before the webrtc connection itself is shut down, so
|
||||
// we shouldn't be getting this callback on a nonexistant
|
||||
// this pointer.
|
||||
// nor should audio_interface be invalid if the LLWebRTCVoiceConnection
|
||||
// is shut down.
|
||||
void LLVoiceWebRTCConnection::OnAudioEstablishedImpl(llwebrtc::LLWebRTCAudioInterface *audio_interface)
|
||||
{
|
||||
if (mShutDown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL;
|
||||
mWebRTCAudioInterface = audio_interface;
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED);
|
||||
}
|
||||
|
||||
// callback from llwebrtc
|
||||
void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnRenegotiationNeededImpl(); });
|
||||
}
|
||||
|
||||
//
|
||||
// The LLWebRTCVoiceConnection object will not be deleted
|
||||
// before the webrtc connection itself is shut down, so
|
||||
// we shouldn't be getting this callback on a nonexistant
|
||||
// this pointer.
|
||||
void LLVoiceWebRTCConnection::OnRenegotiationNeededImpl()
|
||||
{
|
||||
LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL;
|
||||
if (!mShutDown)
|
||||
|
|
@ -2210,7 +2274,13 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
|
|||
}
|
||||
}
|
||||
|
||||
// callback from llwebrtc
|
||||
void LLVoiceWebRTCConnection::OnPeerConnectionShutdown()
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnPeerConnectionShutdownImpl(); });
|
||||
}
|
||||
|
||||
void LLVoiceWebRTCConnection::OnPeerConnectionShutdownImpl()
|
||||
{
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
|
||||
mOutstandingRequests--; // shut down is an async call which is handled on a webrtc thread.
|
||||
|
|
@ -2410,7 +2480,6 @@ bool LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
|
|||
LLSD jsep;
|
||||
jsep["type"] = "offer";
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
jsep["sdp"] = mChannelSDP;
|
||||
}
|
||||
body["jsep"] = jsep;
|
||||
|
|
@ -2620,7 +2689,6 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
|
|||
case VOICE_STATE_SESSION_EXIT:
|
||||
{
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
if (!mShutDown)
|
||||
{
|
||||
mVoiceConnectionState = VOICE_STATE_START_SESSION;
|
||||
|
|
@ -2649,19 +2717,35 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
|
|||
}
|
||||
|
||||
// Data has been received on the webrtc data channel
|
||||
void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binary)
|
||||
// incoming data will be a json structure (if it's not binary.) We may pack
|
||||
// binary for size reasons. Most of the keys in the json objects are
|
||||
// single or double characters for size reasons.
|
||||
// The primary element is:
|
||||
// An object where each key is an agent id. (in the future, we may allow
|
||||
// integer indices into an agentid list, populated on join commands. For size.
|
||||
// Each key will point to a json object with keys identifying what's updated.
|
||||
// 'p' - audio source power (level/volume) (int8 as int)
|
||||
// 'j' - object of join data (currently only a boolean 'p' marking a primary participant)
|
||||
// 'l' - boolean, always true if exists.
|
||||
// 'v' - boolean - voice activity has been detected.
|
||||
|
||||
// llwebrtc callback
|
||||
void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binary)
|
||||
{
|
||||
// incoming data will be a json structure (if it's not binary.) We may pack
|
||||
// binary for size reasons. Most of the keys in the json objects are
|
||||
// single or double characters for size reasons.
|
||||
// The primary element is:
|
||||
// An object where each key is an agent id. (in the future, we may allow
|
||||
// integer indices into an agentid list, populated on join commands. For size.
|
||||
// Each key will point to a json object with keys identifying what's updated.
|
||||
// 'p' - audio source power (level/volume) (int8 as int)
|
||||
// 'j' - object of join data (currently only a boolean 'p' marking a primary participant)
|
||||
// 'l' - boolean, always true if exists.
|
||||
// 'v' - boolean - voice activity has been detected.
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnDataReceivedImpl(data, binary); });
|
||||
}
|
||||
|
||||
//
|
||||
// The LLWebRTCVoiceConnection object will not be deleted
|
||||
// before the webrtc connection itself is shut down, so
|
||||
// we shouldn't be getting this callback on a nonexistant
|
||||
// this pointer.
|
||||
void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool binary)
|
||||
{
|
||||
if (mShutDown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (binary)
|
||||
{
|
||||
|
|
@ -2769,8 +2853,26 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binar
|
|||
}
|
||||
}
|
||||
|
||||
// llwebrtc callback
|
||||
void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface)
|
||||
{
|
||||
LL::WorkQueue::postMaybe(mMainQueue, [=] { OnDataChannelReadyImpl(data_interface); });
|
||||
}
|
||||
|
||||
//
|
||||
// The LLWebRTCVoiceConnection object will not be deleted
|
||||
// before the webrtc connection itself is shut down, so
|
||||
// we shouldn't be getting this callback on a nonexistant
|
||||
// this pointer.
|
||||
// nor should data_interface be invalid if the LLWebRTCVoiceConnection
|
||||
// is shut down.
|
||||
void LLVoiceWebRTCConnection::OnDataChannelReadyImpl(llwebrtc::LLWebRTCDataInterface *data_interface)
|
||||
{
|
||||
if (mShutDown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_interface)
|
||||
{
|
||||
mWebRTCDataInterface = data_interface;
|
||||
|
|
@ -2894,7 +2996,6 @@ bool LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
|
|||
LLSD jsep;
|
||||
jsep["type"] = "offer";
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
jsep["sdp"] = mChannelSDP;
|
||||
}
|
||||
body["jsep"] = jsep;
|
||||
|
|
|
|||
|
|
@ -225,7 +225,8 @@ public:
|
|||
void OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices,
|
||||
const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices) override;
|
||||
//@}
|
||||
|
||||
void OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices,
|
||||
const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices);
|
||||
|
||||
struct participantState
|
||||
{
|
||||
|
|
@ -445,6 +446,8 @@ private:
|
|||
/// Clean up objects created during a voice session.
|
||||
void cleanUp();
|
||||
|
||||
LL::WorkQueue::weak_t mMainQueue;
|
||||
|
||||
bool mTuningMode;
|
||||
F32 mTuningMicGain;
|
||||
int mTuningSpeakerVolume;
|
||||
|
|
@ -588,6 +591,13 @@ class LLVoiceWebRTCConnection :
|
|||
void OnPeerConnectionShutdown() override;
|
||||
//@}
|
||||
|
||||
void OnIceGatheringStateImpl(EIceGatheringState state);
|
||||
void OnIceCandidateImpl(const llwebrtc::LLWebRTCIceCandidate &candidate);
|
||||
void OnOfferAvailableImpl(const std::string &sdp);
|
||||
void OnRenegotiationNeededImpl();
|
||||
void OnAudioEstablishedImpl(llwebrtc::LLWebRTCAudioInterface *audio_interface);
|
||||
void OnPeerConnectionShutdownImpl();
|
||||
|
||||
/////////////////////////
|
||||
/// @name Data Notification
|
||||
/// LLWebRTCDataObserver
|
||||
|
|
@ -596,6 +606,9 @@ class LLVoiceWebRTCConnection :
|
|||
void OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface) override;
|
||||
//@}
|
||||
|
||||
void OnDataReceivedImpl(const std::string &data, bool binary);
|
||||
void OnDataChannelReadyImpl(llwebrtc::LLWebRTCDataInterface *data_interface);
|
||||
|
||||
void sendJoin();
|
||||
void sendData(const std::string &data);
|
||||
|
||||
|
|
@ -618,7 +631,6 @@ class LLVoiceWebRTCConnection :
|
|||
|
||||
void shutDown()
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
mShutDown = true;
|
||||
}
|
||||
|
||||
|
|
@ -644,11 +656,10 @@ class LLVoiceWebRTCConnection :
|
|||
} EVoiceConnectionState;
|
||||
|
||||
EVoiceConnectionState mVoiceConnectionState;
|
||||
LLMutex mVoiceStateMutex;
|
||||
LL::WorkQueue::weak_t mMainQueue;
|
||||
|
||||
void setVoiceConnectionState(EVoiceConnectionState new_voice_connection_state)
|
||||
{
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
|
||||
if (new_voice_connection_state & VOICE_STATE_SESSION_STOPPING)
|
||||
{
|
||||
// the new state is shutdown or restart.
|
||||
|
|
@ -666,11 +677,6 @@ class LLVoiceWebRTCConnection :
|
|||
}
|
||||
EVoiceConnectionState getVoiceConnectionState()
|
||||
{
|
||||
if (mVoiceStateMutex.isLocked())
|
||||
{
|
||||
LL_WARNS("Voice") << "LOCKED." << LL_ENDL;
|
||||
}
|
||||
LLMutexLock lock(&mVoiceStateMutex);
|
||||
return mVoiceConnectionState;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue