diff options
Diffstat (limited to 'indra/llwebrtc')
| -rw-r--r-- | indra/llwebrtc/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 93 | ||||
| -rw-r--r-- | indra/llwebrtc/llwebrtc.h | 6 | ||||
| -rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 14 |
4 files changed, 120 insertions, 9 deletions
diff --git a/indra/llwebrtc/CMakeLists.txt b/indra/llwebrtc/CMakeLists.txt index a01d9fc632..6fb4616087 100644 --- a/indra/llwebrtc/CMakeLists.txt +++ b/indra/llwebrtc/CMakeLists.txt @@ -69,6 +69,14 @@ ADD_CUSTOM_COMMAND(TARGET llwebrtc POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:llwebrtc> ${SHARED_LIB_STAGING_DIR}) + +if (CMAKE_BUILD_TYPE MATCHES Release AND (CMAKE_CXX_COMPILER_ID STREQUAL Clang OR CMAKE_CXX_COMPILER_ID MATCHES GNU)) + add_custom_command( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_STRIP} lib${PROJECT_NAME}.so + ) +endif () + # Add tests if (LL_TESTS) endif (LL_TESTS) @@ -76,12 +84,14 @@ endif (LL_TESTS) if (INSTALL) if (DARWIN) set(_LIB ../Frameworks) + elseif (USE_FLATPAK) + set(_LIB lib) elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) - set(_LIB lib/${ARCH}-linux-gnu) + set(_LIB lib/${ARCH}-linux-gnu/${VIEWER_BINARY_NAME}) elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) - set(_LIB lib${ADDRESS_SIZE}) + set(_LIB lib${ADDRESS_SIZE}/${VIEWER_BINARY_NAME}) else () - set(_LIB lib) + set(_LIB lib/${VIEWER_BINARY_NAME}) endif () if (WINDOWS) diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index d780b1d606..589934fcce 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -749,12 +749,17 @@ void LLWebRTCImpl::intSetMute(bool mute, int delay_ms) { mPeerCustomProcessor->setGain(mMute ? 0.0f : mGain); } + + // Sequence counter to prevent race conditions from rapid requests to mute/unmute + static std::atomic<uint32_t> mute_sequence(0); + uint32_t current_sequence = ++mute_sequence; + if (mMute) { mWorkerThread->PostDelayedTask( - [this] + [this, current_sequence] { - if (mDeviceModule) + if (mDeviceModule && (current_sequence == mute_sequence.load())) { mDeviceModule->ForceStopRecording(); } @@ -764,9 +769,9 @@ void LLWebRTCImpl::intSetMute(bool mute, int delay_ms) else { mWorkerThread->PostTask( - [this] + [this, current_sequence] { - if (mDeviceModule) + if (mDeviceModule && (current_sequence == mute_sequence.load())) { mDeviceModule->InitRecording(); mDeviceModule->ForceStartRecording(); @@ -822,6 +827,8 @@ LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() : mPeerConnection(nullptr), mMute(MUTE_INITIAL), mAnswerReceived(false), + mPeerConnectionState(webrtc::PeerConnectionInterface::PeerConnectionState::kNew), + mDisconnectCount(0), mPendingJobs(0) { } @@ -1248,11 +1255,15 @@ void LLWebRTCPeerConnectionImpl::OnIceGatheringChange(webrtc::PeerConnectionInte } } +static const webrtc::TimeDelta DISCONNECT_RENEGOTIATE_DELAY = webrtc::TimeDelta::Millis(10000); + // Called any time the PeerConnectionState changes. void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterface::PeerConnectionState new_state) { RTC_LOG(LS_ERROR) << __FUNCTION__ << " Peer Connection State Change " << new_state; + mPeerConnectionState = new_state; + switch (new_state) { case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected: @@ -1268,13 +1279,32 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf break; } case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed: - case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected: { for (auto &observer : mSignalingObserverList) { observer->OnRenegotiationNeeded(); } - + break; + } + case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected: + { + // Wait 10 seconds before renegotiating in case the connection recovers on its own. + // Use a sequence count so that only the most recent disconnect transition can trigger + // a renegotiation, avoiding stale delayed tasks from earlier disconnect/reconnect cycles. + uint32_t disconnect_count = ++mDisconnectCount; + mWebRTCImpl->PostDelayedSignalingTask( + [this, disconnect_count]() + { + if (disconnect_count == mDisconnectCount + && mPeerConnectionState == webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected) + { + for (auto &observer : mSignalingObserverList) + { + observer->OnRenegotiationNeeded(); + } + } + }, + DISCONNECT_RENEGOTIATE_DELAY); break; } default: @@ -1547,6 +1577,57 @@ void LLWebRTCPeerConnectionImpl::unsetDataObserver(LLWebRTCDataObserver* observe } } +class LLStatsCollectorCallback : public webrtc::RTCStatsCollectorCallback +{ +public: + typedef std::function<void(const LLWebRTCStatsMap&)> StatsCallback; + + LLStatsCollectorCallback(StatsCallback callback) : callback_(callback) {} + + void OnStatsDelivered(const webrtc::scoped_refptr<const webrtc::RTCStatsReport>& report) override + { + if (callback_) + { + // Transform RTCStatsReport stats to simple map + LLWebRTCStatsMap stats_map; + for (const auto& stats : *report) + { + std::map<std::string, std::string> stat_attributes; + + // Convert each attribute to string format + for (const auto& attribute : stats.Attributes()) + { + stat_attributes[attribute.name()] = attribute.ToString(); + } + stats_map[stats.id()] = stat_attributes; + } + callback_(stats_map); + } + } + +private: + StatsCallback callback_; +}; + +void LLWebRTCPeerConnectionImpl::gatherConnectionStats() +{ + if (!mPeerConnection) + { + return; + } + + auto stats_callback = webrtc::make_ref_counted<LLStatsCollectorCallback>( + [this](const LLWebRTCStatsMap& generic_stats) + { + for (auto& observer : mSignalingObserverList) + { + observer->OnStatsDelivered(generic_stats); + } + }); + + mPeerConnection->GetStats(stats_callback.get()); +} + LLWebRTCImpl * gWebRTCImpl = nullptr; LLWebRTCDeviceInterface * getDeviceInterface() { diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h index 7d06b7d2b4..e76e708f0c 100644 --- a/indra/llwebrtc/llwebrtc.h +++ b/indra/llwebrtc/llwebrtc.h @@ -38,6 +38,7 @@ #ifndef LLWEBRTC_H #define LLWEBRTC_H +#include <map> #include <string> #include <vector> @@ -55,6 +56,7 @@ namespace llwebrtc { +typedef std::map<std::string, std::map<std::string, std::string>> LLWebRTCStatsMap; class LLWebRTCLogCallback { @@ -240,6 +242,8 @@ class LLWebRTCSignalingObserver // Called when the data channel has been established and data // transfer can begin. virtual void OnDataChannelReady(LLWebRTCDataInterface *data_interface) = 0; + + virtual void OnStatsDelivered(const LLWebRTCStatsMap& stats_data) {} }; // LLWebRTCPeerConnectionInterface representsd a connection to a peer, @@ -273,6 +277,8 @@ class LLWebRTCPeerConnectionInterface virtual void unsetSignalingObserver(LLWebRTCSignalingObserver* observer) = 0; virtual void AnswerAvailable(const std::string &sdp) = 0; + + virtual void gatherConnectionStats() = 0; }; // The following define the dynamic linked library diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index 9d3af985ef..2fd11b9b4f 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -345,6 +345,7 @@ public: inner_->InitRecording(); inner_->StartRecording(); } + inner_->InitPlayout(); inner_->StartPlayout(); } } @@ -489,6 +490,13 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO mSignalingThread->PostTask(std::move(task), location); } + void PostDelayedSignalingTask(absl::AnyInvocable<void() &&> task, + webrtc::TimeDelta delay, + const webrtc::Location& location = webrtc::Location::Current()) + { + mSignalingThread->PostDelayedTask(std::move(task), delay, location); + } + void PostNetworkTask(absl::AnyInvocable<void() &&> task, const webrtc::Location& location = webrtc::Location::Current()) { @@ -658,6 +666,8 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, void enableSenderTracks(bool enable); void enableReceiverTracks(bool enable); + void gatherConnectionStats() override; + protected: LLWebRTCImpl * mWebRTCImpl; @@ -683,6 +693,10 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, std::vector<LLWebRTCDataObserver *> mDataObserverList; webrtc::scoped_refptr<webrtc::DataChannelInterface> mDataChannel; + // connection state tracking for delayed renegotiation on disconnect + webrtc::PeerConnectionInterface::PeerConnectionState mPeerConnectionState; + uint32_t mDisconnectCount; + std::atomic<int> mPendingJobs; }; |
