diff options
Diffstat (limited to 'indra/llwebrtc')
| -rw-r--r-- | indra/llwebrtc/CMakeLists.txt | 22 | ||||
| -rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 109 | ||||
| -rw-r--r-- | indra/llwebrtc/llwebrtc.h | 6 | ||||
| -rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 24 |
4 files changed, 153 insertions, 8 deletions
diff --git a/indra/llwebrtc/CMakeLists.txt b/indra/llwebrtc/CMakeLists.txt index eb10f4eee4..85d40b2c5b 100644 --- a/indra/llwebrtc/CMakeLists.txt +++ b/indra/llwebrtc/CMakeLists.txt @@ -24,7 +24,7 @@ list(APPEND llwebrtc_SOURCE_FILES ${llwebrtc_HEADER_FILES}) add_library (llwebrtc SHARED ${llwebrtc_SOURCE_FILES}) -set_target_properties(llwebrtc PROPERTIES PUBLIC_HEADER llwebrtc.h) +#set_target_properties(llwebrtc PROPERTIES PUBLIC_HEADER llwebrtc.h) if (WINDOWS) cmake_policy(SET CMP0091 NEW) @@ -52,7 +52,7 @@ elseif (DARWIN) set_target_properties(llwebrtc PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym" XCODE_ATTRIBUTE_DWARF_DSYM_FOLDER_PATH "${SYMBOLS_STAGING_DIR}/dSYMs") endif (USE_BUGSPLAT) -elseif (LINUX) +elseif (NOT CMAKE_SYSTEM_NAME MATCHES FreeBSD) target_link_libraries(llwebrtc PRIVATE ll::webrtc) endif (WINDOWS) @@ -72,3 +72,21 @@ ADD_CUSTOM_COMMAND(TARGET llwebrtc POST_BUILD # Add tests if (LL_TESTS) endif (LL_TESTS) + +if (INSTALL) + if (DARWIN) + set(_LIB ../Frameworks) + elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) + set(_LIB lib${ADDRESS_SIZE}) + else () + set(_LIB lib) + endif () + + if (WINDOWS) + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${PROJECT_NAME}.dll DESTINATION .) + else () + install(TARGETS ${PROJECT_NAME} DESTINATION ${_LIB}/${VIEWER_BINARY_NAME}) + endif () +endif () diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 8e08239ee6..589934fcce 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -39,6 +39,20 @@ #include "modules/audio_mixer/audio_mixer_impl.h" #include "api/environment/environment_factory.h" +#if CM_WEBRTC + +#include "modules/congestion_controller/goog_cc/loss_based_bwe_v2.h" + +webrtc::RtpStreamConfig::Rtx::Rtx() +{ +} + +webrtc::LossBasedBweV2::Config::Config() +{ +} + +#endif + namespace llwebrtc { #if WEBRTC_WIN @@ -292,7 +306,9 @@ void LLWebRTCImpl::init() webrtc::scoped_refptr<webrtc::AudioDeviceModule> realADM = webrtc::AudioDeviceModule::Create(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, mTaskQueueFactory.get()); mDeviceModule = webrtc::make_ref_counted<LLWebRTCAudioDeviceModule>(realADM); +#if !CM_WEBRTC mDeviceModule->SetObserver(this); +#endif }); // The custom processor allows us to retrieve audio data (and levels) @@ -733,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(); } @@ -748,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(); @@ -806,6 +827,8 @@ LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() : mPeerConnection(nullptr), mMute(MUTE_INITIAL), mAnswerReceived(false), + mPeerConnectionState(webrtc::PeerConnectionInterface::PeerConnectionState::kNew), + mDisconnectCount(0), mPendingJobs(0) { } @@ -1232,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: @@ -1252,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: @@ -1531,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 01cfb17ced..2fd11b9b4f 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -316,9 +316,11 @@ public: virtual int GetRecordAudioParameters(AudioParameters* params) override { return inner_->GetRecordAudioParameters(params); } #endif // WEBRTC_IOS +#if !CM_WEBRTC virtual int32_t GetPlayoutDevice() const override { return inner_->GetPlayoutDevice(); } virtual int32_t GetRecordingDevice() const override { return inner_->GetRecordingDevice(); } virtual int32_t SetObserver(webrtc::AudioDeviceObserver* observer) override { return inner_->SetObserver(observer); } +#endif // tuning microphone energy calculations float GetMicrophoneEnergy() { return audio_transport_.GetMicrophoneEnergy(); } @@ -343,6 +345,7 @@ public: inner_->InitRecording(); inner_->StartRecording(); } + inner_->InitPlayout(); inner_->StartPlayout(); } } @@ -415,7 +418,11 @@ protected: // Primary singleton implementation for interfacing // with the native webrtc library. +#if CM_WEBRTC +class LLWebRTCImpl : public LLWebRTCDeviceInterface +#else class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceObserver +#endif { public: LLWebRTCImpl(LLWebRTCLogCallback* logCallback); @@ -458,7 +465,11 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO // // AudioDeviceObserver // +#if CM_WEBRTC + void OnDevicesUpdated(); +#else void OnDevicesUpdated() override; +#endif // // Helpers @@ -479,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()) { @@ -648,6 +666,8 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, void enableSenderTracks(bool enable); void enableReceiverTracks(bool enable); + void gatherConnectionStats() override; + protected: LLWebRTCImpl * mWebRTCImpl; @@ -673,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; }; |
