![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /usr/local/lib/node_modules/mediasoup/worker/src/RTC/ |
Upload File : |
#define MS_CLASS "RTC::SenderBandwidthEstimator" // #define MS_LOG_DEV_LEVEL 3 #include "RTC/SenderBandwidthEstimator.hpp" #include "DepLibUV.hpp" #include "Logger.hpp" #include <limits> namespace RTC { /* Static. */ // static constexpr uint64_t AvailableBitrateEventInterval{ 2000u }; // In ms. static constexpr uint16_t MaxSentInfoAge{ 2000u }; // TODO: Let's see. static constexpr float DefaultRtt{ 100 }; /* Instance methods. */ SenderBandwidthEstimator::SenderBandwidthEstimator( RTC::SenderBandwidthEstimator::Listener* listener, uint32_t initialAvailableBitrate) : listener(listener), initialAvailableBitrate(initialAvailableBitrate), rtt(DefaultRtt), sendTransmission(1000u), sendTransmissionTrend(0.15f) { MS_TRACE(); } SenderBandwidthEstimator::~SenderBandwidthEstimator() { MS_TRACE(); } void SenderBandwidthEstimator::TransportConnected() { MS_TRACE(); this->availableBitrate = this->initialAvailableBitrate; this->lastAvailableBitrateEventAtMs = DepLibUV::GetTimeMs(); } void SenderBandwidthEstimator::TransportDisconnected() { MS_TRACE(); this->availableBitrate = 0u; this->sentInfos.clear(); this->cummulativeResult.Reset(); } void SenderBandwidthEstimator::RtpPacketSent(SentInfo& sentInfo) { MS_TRACE(); auto nowMs = sentInfo.sentAtMs; // Remove old sent infos. auto it = this->sentInfos.lower_bound(sentInfo.wideSeq - MaxSentInfoAge + 1); this->sentInfos.erase(this->sentInfos.begin(), it); // Insert the sent info into the map. this->sentInfos[sentInfo.wideSeq] = sentInfo; // Fill the send transmission counter. this->sendTransmission.Update(sentInfo.size, nowMs); // Update the send transmission trend. auto sendBitrate = this->sendTransmission.GetRate(nowMs); this->sendTransmissionTrend.Update(sendBitrate, nowMs); // TODO: Remove. // MS_DEBUG_DEV( // "[wideSeq:%" PRIu16 ", size:%zu, isProbation:%s, bitrate:%" PRIu32 "]", // sentInfo.wideSeq, // sentInfo.size, // sentInfo.isProbation ? "true" : "false", // sendBitrate); } void SenderBandwidthEstimator::ReceiveRtcpTransportFeedback( const RTC::RTCP::FeedbackRtpTransportPacket* feedback) { MS_TRACE(); auto nowMs = DepLibUV::GetTimeMs(); uint64_t elapsedMs = nowMs - this->cummulativeResult.GetStartedAtMs(); // Drop ongoing cummulative result if too old. if (elapsedMs > 1000u) this->cummulativeResult.Reset(); for (auto& result : feedback->GetPacketResults()) { if (!result.received) continue; uint16_t wideSeq = result.sequenceNumber; auto it = this->sentInfos.find(wideSeq); if (it == this->sentInfos.end()) { MS_WARN_DEV("received packet not present in sent infos [wideSeq:%" PRIu16 "]", wideSeq); continue; } auto& sentInfo = it->second; if (!sentInfo.isProbation) { this->cummulativeResult.AddPacket( sentInfo.size, static_cast<int64_t>(sentInfo.sentAtMs), result.receivedAtMs); } else { this->probationCummulativeResult.AddPacket( sentInfo.size, static_cast<int64_t>(sentInfo.sentAtMs), result.receivedAtMs); } } // Handle probation packets separately. if (this->probationCummulativeResult.GetNumPackets() >= 2u) { // MS_DEBUG_DEV( // "probation [packets:%zu, size:%zu] " // "[send bps:%" PRIu32 ", recv bps:%" PRIu32 "] ", // this->probationCummulativeResult.GetNumPackets(), // this->probationCummulativeResult.GetTotalSize(), // this->probationCummulativeResult.GetSendBitrate(), // this->probationCummulativeResult.GetReceiveBitrate()); EstimateAvailableBitrate(this->probationCummulativeResult); // Reset probation cummulative result. this->probationCummulativeResult.Reset(); } else { // Reset probation cummulative result. this->probationCummulativeResult.Reset(); } // Handle real and probation packets all together. if (elapsedMs >= 100u && this->cummulativeResult.GetNumPackets() >= 20u) { // auto sendBitrate = this->sendTransmission.GetRate(nowMs); // auto sendBitrateTrend = this->sendTransmissionTrend.GetValue(); // MS_DEBUG_DEV( // "real+prob [packets:%zu, size:%zu] " // "[send bps:%" PRIu32 ", recv bps:%" PRIu32 // "] " // "[real bps:%" PRIu32 ", trend bps:%" PRIu32 "]", // this->cummulativeResult.GetNumPackets(), // this->cummulativeResult.GetTotalSize(), // this->cummulativeResult.GetSendBitrate(), // this->cummulativeResult.GetReceiveBitrate(), // sendBitrate, // sendBitrateTrend); EstimateAvailableBitrate(this->cummulativeResult); // Reset cummulative result. this->cummulativeResult.Reset(); } } void SenderBandwidthEstimator::EstimateAvailableBitrate(CummulativeResult& cummulativeResult) { MS_TRACE(); auto previousAvailableBitrate = this->availableBitrate; double ratio = static_cast<double>(cummulativeResult.GetReceiveBitrate()) / static_cast<double>(cummulativeResult.GetSendBitrate()); auto bitrate = std::min<uint32_t>(cummulativeResult.GetReceiveBitrate(), cummulativeResult.GetSendBitrate()); if (0.75f <= ratio && ratio <= 1.25f) { if (bitrate > this->availableBitrate) { this->availableBitrate = bitrate; MS_DEBUG_DEV("BWE UP [ratio:%f, availableBitrate:%" PRIu32 "]", ratio, this->availableBitrate); } } else { if (bitrate < this->availableBitrate) { this->availableBitrate = bitrate; MS_DEBUG_DEV( "BWE DOWN [ratio:%f, availableBitrate:%" PRIu32 "]", ratio, this->availableBitrate); } } // TODO: No, should wait for AvailableBitrateEventInterval and so on. this->listener->OnSenderBandwidthEstimatorAvailableBitrate( this, this->availableBitrate, previousAvailableBitrate); } void SenderBandwidthEstimator::UpdateRtt(float rtt) { MS_TRACE(); this->rtt = rtt; } uint32_t SenderBandwidthEstimator::GetAvailableBitrate() const { MS_TRACE(); return this->availableBitrate; } void SenderBandwidthEstimator::RescheduleNextAvailableBitrateEvent() { MS_TRACE(); this->lastAvailableBitrateEventAtMs = DepLibUV::GetTimeMs(); } void SenderBandwidthEstimator::CummulativeResult::AddPacket( size_t size, int64_t sentAtMs, int64_t receivedAtMs) { MS_TRACE(); if (this->numPackets == 0u) { this->firstPacketSentAtMs = sentAtMs; this->firstPacketReceivedAtMs = receivedAtMs; this->lastPacketSentAtMs = sentAtMs; this->lastPacketReceivedAtMs = receivedAtMs; } else { if (sentAtMs < this->firstPacketSentAtMs) this->firstPacketSentAtMs = sentAtMs; if (receivedAtMs < this->firstPacketReceivedAtMs) this->firstPacketReceivedAtMs = receivedAtMs; if (sentAtMs > this->lastPacketSentAtMs) this->lastPacketSentAtMs = sentAtMs; if (receivedAtMs > this->lastPacketReceivedAtMs) this->lastPacketReceivedAtMs = receivedAtMs; } this->numPackets++; this->totalSize += size; } void SenderBandwidthEstimator::CummulativeResult::Reset() { MS_TRACE(); this->numPackets = 0u; this->totalSize = 0u; this->firstPacketSentAtMs = 0u; this->lastPacketSentAtMs = 0u; this->firstPacketReceivedAtMs = 0u; this->lastPacketReceivedAtMs = 0u; } } // namespace RTC