mediasoup 3.27.0 → 3.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/node/lib/Consumer.d.ts.map +1 -1
- package/node/lib/Consumer.js +4 -51
- package/node/lib/Producer.d.ts.map +1 -1
- package/node/lib/Producer.js +4 -8
- package/node/lib/ProducerTypes.d.ts +4 -2
- package/node/lib/ProducerTypes.d.ts.map +1 -1
- package/node/lib/Router.d.ts.map +1 -1
- package/node/lib/Router.js +4 -0
- package/node/lib/Transport.d.ts.map +1 -1
- package/node/lib/Transport.js +7 -10
- package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts +3 -4
- package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts.map +1 -1
- package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.js +3 -4
- package/node/lib/ortc.d.ts +0 -2
- package/node/lib/ortc.d.ts.map +1 -1
- package/node/lib/ortc.js +11 -21
- package/node/lib/rtpMappingFbsUtils.d.ts +6 -0
- package/node/lib/rtpMappingFbsUtils.d.ts.map +1 -0
- package/node/lib/rtpMappingFbsUtils.js +65 -0
- package/node/lib/rtpParametersFbsUtils.d.ts.map +1 -1
- package/node/lib/rtpParametersFbsUtils.js +0 -6
- package/node/lib/rtpParametersTypes.d.ts +1 -1
- package/node/lib/rtpParametersTypes.d.ts.map +1 -1
- package/node/lib/rtpStreamFbsUtils.d.ts +4 -0
- package/node/lib/rtpStreamFbsUtils.d.ts.map +1 -0
- package/node/lib/rtpStreamFbsUtils.js +51 -0
- package/node/lib/supportedRtpCapabilities.d.ts.map +1 -1
- package/node/lib/supportedRtpCapabilities.js +6 -13
- package/node/lib/test/test-Consumer.js +1 -13
- package/node/lib/test/test-DataConsumer.js +9 -0
- package/node/lib/test/test-DataProducer.js +38 -0
- package/node/lib/test/test-PipeTransport.js +27 -29
- package/node/lib/test/test-Producer.js +97 -0
- package/node/lib/test/test-ortc.js +34 -14
- package/package.json +10 -10
- package/worker/fbs/FBS/meson.build +25 -0
- package/worker/fbs/meson.build +15 -18
- package/worker/fbs/rtpParameters.fbs +0 -1
- package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
- package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
- package/worker/include/DepLibUV.hpp +13 -0
- package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
- package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
- package/worker/include/RTC/BWE/BitrateUtils.hpp +39 -0
- package/worker/include/RTC/BWE/BweTypes.hpp +171 -3
- package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
- package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
- package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
- package/worker/include/RTC/BWE/LossBasedController.hpp +625 -0
- package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
- package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
- package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
- package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
- package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
- package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
- package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
- package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
- package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
- package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
- package/worker/include/RTC/BWE/TargetRateController.hpp +306 -0
- package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
- package/worker/include/RTC/BWE/TrendlineEstimator.hpp +73 -16
- package/worker/include/RTC/Consts.hpp +70 -0
- package/worker/include/RTC/DataConsumer.hpp +3 -5
- package/worker/include/RTC/DirectTransport.hpp +4 -5
- package/worker/include/RTC/PipeTransport.hpp +4 -5
- package/worker/include/RTC/PlainTransport.hpp +4 -5
- package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
- package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
- package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
- package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
- package/worker/include/RTC/RTP/Packet.hpp +16 -4
- package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
- package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
- package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
- package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
- package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
- package/worker/include/RTC/RateCalculator.hpp +103 -24
- package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
- package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
- package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
- package/worker/include/RTC/RtpDictionaries.hpp +3 -4
- package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
- package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +36 -0
- package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
- package/worker/include/RTC/SCTP/public/SctpTypes.hpp +9 -9
- package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
- package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +11 -1
- package/worker/include/RTC/SctpDictionaries.hpp +2 -2
- package/worker/include/RTC/TcpConnection.hpp +2 -1
- package/worker/include/RTC/Transport.hpp +23 -8
- package/worker/include/RTC/TransportTuple.hpp +61 -6
- package/worker/include/RTC/WebRtcTransport.hpp +4 -5
- package/worker/include/Shared.hpp +5 -0
- package/worker/include/SharedInterface.hpp +10 -0
- package/worker/include/Utils.hpp +72 -3
- package/worker/include/common.hpp +12 -4
- package/worker/include/handles/SendCallbacks.hpp +34 -0
- package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
- package/worker/include/handles/UdpSocketHandle.hpp +4 -8
- package/worker/meson.build +45 -1
- package/worker/meson_options.txt +1 -0
- package/worker/mocks/include/MockShared.hpp +16 -2
- package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
- package/worker/scripts/package-lock.json +6 -6
- package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
- package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
- package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
- package/worker/src/RTC/BWE/BitrateUtils.cpp +54 -0
- package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
- package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
- package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
- package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
- package/worker/src/RTC/BWE/LossBasedController.cpp +1194 -0
- package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
- package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
- package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
- package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
- package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
- package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
- package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
- package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
- package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
- package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
- package/worker/src/RTC/BWE/TargetRateController.cpp +433 -0
- package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
- package/worker/src/RTC/BWE/TrendlineEstimator.cpp +102 -5
- package/worker/src/RTC/Consumer.cpp +7 -5
- package/worker/src/RTC/DataConsumer.cpp +8 -10
- package/worker/src/RTC/DirectTransport.cpp +14 -8
- package/worker/src/RTC/DtlsTransport.cpp +8 -8
- package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
- package/worker/src/RTC/ICE/IceServer.cpp +1 -1
- package/worker/src/RTC/PipeTransport.cpp +13 -8
- package/worker/src/RTC/PlainTransport.cpp +13 -8
- package/worker/src/RTC/Producer.cpp +14 -31
- package/worker/src/RTC/RTCP/Bye.cpp +1 -1
- package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
- package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
- package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
- package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
- package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
- package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
- package/worker/src/RTC/RTP/Packet.cpp +26 -11
- package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
- package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
- package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
- package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
- package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
- package/worker/src/RTC/RateCalculator.cpp +133 -28
- package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
- package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
- package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
- package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
- package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
- package/worker/src/RTC/SCTP/association/Association.cpp +16 -2
- package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +106 -1
- package/worker/src/RTC/SCTP/public/AssociationMetrics.cpp +1 -1
- package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
- package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
- package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
- package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
- package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
- package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
- package/worker/src/RTC/SrtpSession.cpp +2 -2
- package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
- package/worker/src/RTC/TcpConnection.cpp +2 -2
- package/worker/src/RTC/Transport.cpp +112 -75
- package/worker/src/RTC/TransportTuple.cpp +4 -4
- package/worker/src/RTC/WebRtcServer.cpp +4 -3
- package/worker/src/RTC/WebRtcTransport.cpp +20 -13
- package/worker/src/Utils/BitStream.cpp +24 -0
- package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
- package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
- package/worker/src/handles/UdpSocketHandle.cpp +14 -21
- package/worker/tasks.py +43 -18
- package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
- package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
- package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
- package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
- package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
- package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
- package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
- package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
- package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
- package/worker/test/src/RTC/BWE/TestLossBasedController.cpp +1199 -0
- package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
- package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
- package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
- package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
- package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
- package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
- package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
- package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
- package/worker/test/src/RTC/BWE/TestTargetRateController.cpp +337 -0
- package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
- package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +45 -0
- package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
- package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
- package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
- package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
- package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
- package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
- package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
- package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +111 -0
- package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
- package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
- package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
- package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
- package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
- package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
- package/worker/test/src/Utils/TestTime.cpp +120 -21
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
#include "RTC/BWE/AimdRateControl.hpp"
|
|
5
5
|
#include "Logger.hpp"
|
|
6
|
+
#include "RTC/Consts.hpp"
|
|
6
7
|
#include <cmath>
|
|
7
8
|
|
|
8
9
|
namespace RTC
|
|
@@ -21,8 +22,6 @@ namespace RTC
|
|
|
21
22
|
// Bounds of how often the bitrate may be reduced, derived from the RTT.
|
|
22
23
|
static constexpr int64_t MinBitrateReductionIntervalUs{ 10 * 1000 };
|
|
23
24
|
static constexpr int64_t MaxBitrateReductionIntervalUs{ 200 * 1000 };
|
|
24
|
-
// Bitrate the target is never taken below unless configured otherwise (bps).
|
|
25
|
-
static constexpr int64_t CongestionControllerMinBitrate{ 5000 };
|
|
26
25
|
// Bitrate the target starts from before anything has been measured (bps).
|
|
27
26
|
static constexpr int64_t MaxConfiguredBitrate{ 30000 * 1000 };
|
|
28
27
|
// Headroom allowed on top of the measured throughput when increasing (bps).
|
|
@@ -64,7 +63,7 @@ namespace RTC
|
|
|
64
63
|
|
|
65
64
|
AimdRateControl::AimdRateControl(AimdRateControlOptions options)
|
|
66
65
|
: options(options),
|
|
67
|
-
minConfiguredBitrate(
|
|
66
|
+
minConfiguredBitrate(Consts::BweMinBitrate),
|
|
68
67
|
maxConfiguredBitrate(MaxConfiguredBitrate),
|
|
69
68
|
currentBitrate(this->maxConfiguredBitrate),
|
|
70
69
|
latestEstimatedThroughput(this->currentBitrate),
|
|
@@ -358,7 +357,7 @@ namespace RTC
|
|
|
358
357
|
break;
|
|
359
358
|
}
|
|
360
359
|
|
|
361
|
-
|
|
360
|
+
NO_DEFAULT();
|
|
362
361
|
}
|
|
363
362
|
|
|
364
363
|
this->currentBitrate = ClampBitrate(newBitrate.value_or(this->currentBitrate));
|
|
@@ -398,7 +397,7 @@ namespace RTC
|
|
|
398
397
|
break;
|
|
399
398
|
}
|
|
400
399
|
|
|
401
|
-
|
|
400
|
+
NO_DEFAULT();
|
|
402
401
|
}
|
|
403
402
|
}
|
|
404
403
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#define MS_CLASS "RTC::BWE::AlrDetector"
|
|
2
|
+
// #define MS_LOG_DEV_LEVEL 3
|
|
3
|
+
|
|
4
|
+
#include "RTC/BWE/AlrDetector.hpp"
|
|
5
|
+
#include "Logger.hpp"
|
|
6
|
+
#include "RTC/BWE/BitrateUtils.hpp"
|
|
7
|
+
|
|
8
|
+
namespace RTC
|
|
9
|
+
{
|
|
10
|
+
namespace BWE
|
|
11
|
+
{
|
|
12
|
+
/* Instance methods. */
|
|
13
|
+
|
|
14
|
+
AlrDetector::AlrDetector(SharedInterface* shared) : AlrDetector(shared, AlrDetectorOptions{})
|
|
15
|
+
{
|
|
16
|
+
MS_TRACE();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
AlrDetector::AlrDetector(SharedInterface* shared, AlrDetectorOptions options)
|
|
20
|
+
: shared(shared),
|
|
21
|
+
options(options),
|
|
22
|
+
// What an interval leaves unspent builds up, since not filling the link
|
|
23
|
+
// is precisely a state that has to accumulate to be noticed.
|
|
24
|
+
alrBudget(/*initialTargetBitrate*/ 0, /*canBuildUpUnderuse*/ true)
|
|
25
|
+
{
|
|
26
|
+
MS_TRACE();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
void AlrDetector::OnBytesSent(int64_t bytesSent, int64_t sentAtUs)
|
|
30
|
+
{
|
|
31
|
+
MS_TRACE();
|
|
32
|
+
|
|
33
|
+
// How long those bytes took to go out is unknown until there is a previous
|
|
34
|
+
// send to measure them against.
|
|
35
|
+
if (!this->lastSentAtUs.has_value())
|
|
36
|
+
{
|
|
37
|
+
this->lastSentAtUs = sentAtUs;
|
|
38
|
+
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const int64_t deltaTimeUs = sentAtUs - this->lastSentAtUs.value();
|
|
43
|
+
|
|
44
|
+
this->lastSentAtUs = sentAtUs;
|
|
45
|
+
|
|
46
|
+
this->alrBudget.UseBudget(bytesSent);
|
|
47
|
+
this->alrBudget.IncreaseBudget(deltaTimeUs);
|
|
48
|
+
|
|
49
|
+
const double budgetRatio = this->alrBudget.GetBudgetRatio();
|
|
50
|
+
|
|
51
|
+
if (budgetRatio > this->options.startBudgetLevelRatio && !this->alrStartTimeUs.has_value())
|
|
52
|
+
{
|
|
53
|
+
// The instant this state began is what the rest of the module reasons
|
|
54
|
+
// about, so it's the current one and not that of the send that revealed
|
|
55
|
+
// it.
|
|
56
|
+
this->alrStartTimeUs = this->shared->GetTimeUs();
|
|
57
|
+
|
|
58
|
+
MS_DEBUG_DEV("sender is not filling the link [budgetRatio:%f]", budgetRatio);
|
|
59
|
+
}
|
|
60
|
+
else if (budgetRatio < this->options.stopBudgetLevelRatio && this->alrStartTimeUs.has_value())
|
|
61
|
+
{
|
|
62
|
+
this->alrStartTimeUs.reset();
|
|
63
|
+
|
|
64
|
+
MS_DEBUG_DEV("sender is filling the link again [budgetRatio:%f]", budgetRatio);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void AlrDetector::SetEstimatedBitrate(int64_t bitrate)
|
|
69
|
+
{
|
|
70
|
+
MS_TRACE();
|
|
71
|
+
|
|
72
|
+
// NOTE: The target this comes from is clamped to the minimum bitrate of
|
|
73
|
+
// the congestion controller, so anything else is a programming error.
|
|
74
|
+
MS_ASSERT(bitrate > 0, "bitrate must be positive [bitrate:%" PRIi64 "]", bitrate);
|
|
75
|
+
|
|
76
|
+
this->alrBudget.SetTargetBitrate(
|
|
77
|
+
BitrateUtils::ApplyBitrateFactor(bitrate, this->options.bandwidthUsageRatio));
|
|
78
|
+
}
|
|
79
|
+
} // namespace BWE
|
|
80
|
+
} // namespace RTC
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
#define MS_CLASS "RTC::BWE::BitrateProber"
|
|
2
|
+
// #define MS_LOG_DEV_LEVEL 3
|
|
3
|
+
|
|
4
|
+
#include "RTC/BWE/BitrateProber.hpp"
|
|
5
|
+
#include "Logger.hpp"
|
|
6
|
+
|
|
7
|
+
namespace RTC
|
|
8
|
+
{
|
|
9
|
+
namespace BWE
|
|
10
|
+
{
|
|
11
|
+
/* Static. */
|
|
12
|
+
|
|
13
|
+
// How long a burst that was asked for but never started is worth keeping.
|
|
14
|
+
static constexpr int64_t ProbeClusterTimeoutUs{ 5 * 1000 * 1000 };
|
|
15
|
+
// How many bursts may be waiting at once.
|
|
16
|
+
static constexpr size_t MaxPendingProbeClusters{ 5 };
|
|
17
|
+
|
|
18
|
+
/* Instance methods. */
|
|
19
|
+
|
|
20
|
+
BitrateProber::BitrateProber() : BitrateProber(BitrateProberOptions{})
|
|
21
|
+
{
|
|
22
|
+
MS_TRACE();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
BitrateProber::BitrateProber(BitrateProberOptions options) : options(options)
|
|
26
|
+
{
|
|
27
|
+
MS_TRACE();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void BitrateProber::CreateProbeCluster(const Types::ProbeClusterConfig& clusterConfig)
|
|
31
|
+
{
|
|
32
|
+
MS_TRACE();
|
|
33
|
+
|
|
34
|
+
// NOTE: Whoever puts a burst configuration together already refuses a zero
|
|
35
|
+
// there, since it is what the bitrate of the burst is held over to decide
|
|
36
|
+
// how many bytes each of its shots carries.
|
|
37
|
+
MS_ASSERT(clusterConfig.minProbeDeltaUs > 0, "no time between packets of the burst");
|
|
38
|
+
|
|
39
|
+
// Whatever was asked for long ago is not worth sending anymore, and only so
|
|
40
|
+
// many may be waiting at once.
|
|
41
|
+
while (!this->clusters.empty() &&
|
|
42
|
+
(clusterConfig.atUs - this->clusters.front().requestedAtUs > ProbeClusterTimeoutUs ||
|
|
43
|
+
this->clusters.size() > MaxPendingProbeClusters))
|
|
44
|
+
{
|
|
45
|
+
this->clusters.pop();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
Cluster cluster;
|
|
49
|
+
|
|
50
|
+
cluster.probeCluster.id = clusterConfig.id;
|
|
51
|
+
cluster.probeCluster.minProbes = clusterConfig.targetProbeCount;
|
|
52
|
+
// The bytes the burst is meant to carry are its bitrate held for as long as
|
|
53
|
+
// it is meant to last, rounded to the nearest byte.
|
|
54
|
+
cluster.probeCluster.minBytes =
|
|
55
|
+
((clusterConfig.targetBitrate * clusterConfig.targetDurationUs) + 4000000) / (8 * 1000000);
|
|
56
|
+
cluster.sendBitrate = clusterConfig.targetBitrate;
|
|
57
|
+
cluster.minProbeDeltaUs = clusterConfig.minProbeDeltaUs;
|
|
58
|
+
cluster.requestedAtUs = clusterConfig.atUs;
|
|
59
|
+
|
|
60
|
+
MS_ASSERT(cluster.probeCluster.minBytes >= 0, "burst of a negative count of bytes");
|
|
61
|
+
|
|
62
|
+
this->clusters.push(cluster);
|
|
63
|
+
|
|
64
|
+
MaybeSetActiveState(/*packetSize*/ 0);
|
|
65
|
+
|
|
66
|
+
MS_DEBUG_DEV(
|
|
67
|
+
"probe cluster created [id:%" PRIi64 ", bitrate:%" PRIi64 ", minBytes:%" PRIi64
|
|
68
|
+
", minProbes:%" PRIi64 ", active:%s]",
|
|
69
|
+
cluster.probeCluster.id,
|
|
70
|
+
cluster.sendBitrate,
|
|
71
|
+
cluster.probeCluster.minBytes,
|
|
72
|
+
cluster.probeCluster.minProbes,
|
|
73
|
+
this->state == State::ACTIVE ? "true" : "false");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
std::optional<int64_t> BitrateProber::GetNextProbeTimeUs(int64_t nowUs) const
|
|
77
|
+
{
|
|
78
|
+
MS_TRACE();
|
|
79
|
+
|
|
80
|
+
// Nothing is being emitted, or everything asked for is already done.
|
|
81
|
+
if (this->state != State::ACTIVE || this->clusters.empty())
|
|
82
|
+
{
|
|
83
|
+
return std::nullopt;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// A burst that hasn't started goes out at the first chance there is.
|
|
87
|
+
return this->nextProbeTimeUs.value_or(nowUs);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
std::optional<BitrateProber::CurrentCluster> BitrateProber::GetCurrentCluster(int64_t nowUs)
|
|
91
|
+
{
|
|
92
|
+
MS_TRACE();
|
|
93
|
+
|
|
94
|
+
if (this->clusters.empty() || this->state != State::ACTIVE)
|
|
95
|
+
{
|
|
96
|
+
return std::nullopt;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// A packet that goes out long after it was due no longer measures the
|
|
100
|
+
// bitrate the burst was meant to be sent at, so the whole burst is dropped
|
|
101
|
+
// rather than believed.
|
|
102
|
+
if (this->nextProbeTimeUs.has_value() && nowUs - this->nextProbeTimeUs.value() > this->options.maxProbeDelayUs)
|
|
103
|
+
{
|
|
104
|
+
MS_DEBUG_DEV(
|
|
105
|
+
"probe delayed too much, discarding the cluster [dueAt:%" PRIi64 ", now:%" PRIi64 "]",
|
|
106
|
+
this->nextProbeTimeUs.value(),
|
|
107
|
+
nowUs);
|
|
108
|
+
|
|
109
|
+
this->clusters.pop();
|
|
110
|
+
|
|
111
|
+
if (this->clusters.empty())
|
|
112
|
+
{
|
|
113
|
+
this->state = State::INACTIVE;
|
|
114
|
+
|
|
115
|
+
return std::nullopt;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const auto& cluster = this->clusters.front();
|
|
120
|
+
|
|
121
|
+
return CurrentCluster{ .probeCluster = cluster.probeCluster, .sentBytes = cluster.sentBytes };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
size_t BitrateProber::GetRecommendedMinProbeSize() const
|
|
125
|
+
{
|
|
126
|
+
MS_TRACE();
|
|
127
|
+
|
|
128
|
+
if (this->clusters.empty())
|
|
129
|
+
{
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const auto& cluster = this->clusters.front();
|
|
134
|
+
|
|
135
|
+
// What the burst's bitrate carries over the time between two of its shots,
|
|
136
|
+
// rounded to the nearest byte.
|
|
137
|
+
return static_cast<size_t>(
|
|
138
|
+
((cluster.sendBitrate * cluster.minProbeDeltaUs) + 4000000) / (8 * 1000000));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void BitrateProber::ProbeSent(int64_t nowUs, size_t size)
|
|
142
|
+
{
|
|
143
|
+
MS_TRACE();
|
|
144
|
+
|
|
145
|
+
// NOTE: Reporting a shot means one was asked for with GetCurrentCluster(),
|
|
146
|
+
// which only answers while a burst is being emitted, and that state is
|
|
147
|
+
// only left from within this class.
|
|
148
|
+
MS_ASSERT(this->state == State::ACTIVE, "no burst is being emitted");
|
|
149
|
+
// NOTE: A shot out of which no byte left is not reported at all, since
|
|
150
|
+
// there would be nothing to measure the burst with.
|
|
151
|
+
MS_ASSERT(size != 0, "a packet of no bytes was sent");
|
|
152
|
+
|
|
153
|
+
if (this->clusters.empty())
|
|
154
|
+
{
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
auto& cluster = this->clusters.front();
|
|
159
|
+
|
|
160
|
+
if (cluster.sentProbes == 0)
|
|
161
|
+
{
|
|
162
|
+
MS_ASSERT(!cluster.startedAtUs.has_value(), "burst already started");
|
|
163
|
+
|
|
164
|
+
cluster.startedAtUs = nowUs;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
cluster.sentBytes += static_cast<int64_t>(size);
|
|
168
|
+
cluster.sentProbes += 1;
|
|
169
|
+
|
|
170
|
+
this->nextProbeTimeUs = CalculateNextProbeTimeUs(cluster);
|
|
171
|
+
|
|
172
|
+
// Both counts have to be reached, since a burst of too few packets says
|
|
173
|
+
// nothing however many bytes it carried, and the other way round.
|
|
174
|
+
if (
|
|
175
|
+
cluster.sentBytes >= cluster.probeCluster.minBytes &&
|
|
176
|
+
cluster.sentProbes >= cluster.probeCluster.minProbes)
|
|
177
|
+
{
|
|
178
|
+
this->clusters.pop();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (this->clusters.empty())
|
|
182
|
+
{
|
|
183
|
+
this->state = State::INACTIVE;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
void BitrateProber::OnIncomingPacket(size_t packetSize)
|
|
188
|
+
{
|
|
189
|
+
MS_TRACE();
|
|
190
|
+
|
|
191
|
+
MaybeSetActiveState(packetSize);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
void BitrateProber::MaybeSetActiveState(size_t packetSize)
|
|
195
|
+
{
|
|
196
|
+
MS_TRACE();
|
|
197
|
+
|
|
198
|
+
if (IsReadyToSetActiveState(packetSize))
|
|
199
|
+
{
|
|
200
|
+
this->nextProbeTimeUs.reset();
|
|
201
|
+
this->state = State::ACTIVE;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
bool BitrateProber::IsReadyToSetActiveState(size_t packetSize) const
|
|
206
|
+
{
|
|
207
|
+
MS_TRACE();
|
|
208
|
+
|
|
209
|
+
if (this->clusters.empty())
|
|
210
|
+
{
|
|
211
|
+
MS_ASSERT(this->state == State::INACTIVE, "emitting a burst with none to emit");
|
|
212
|
+
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
switch (this->state)
|
|
217
|
+
{
|
|
218
|
+
case State::ACTIVE:
|
|
219
|
+
{
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
case State::INACTIVE:
|
|
224
|
+
{
|
|
225
|
+
if (this->options.allowStartProbingImmediately)
|
|
226
|
+
{
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// A burst that begins on a tiny packet starts measuring from an instant
|
|
231
|
+
// that says nothing, so a big enough one has to go out first. What
|
|
232
|
+
// counts as big enough is never more than a whole shot of the burst.
|
|
233
|
+
return packetSize >= std::min(GetRecommendedMinProbeSize(), this->options.minPacketSize);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
int64_t BitrateProber::CalculateNextProbeTimeUs(const Cluster& cluster) const
|
|
241
|
+
{
|
|
242
|
+
MS_TRACE();
|
|
243
|
+
|
|
244
|
+
MS_ASSERT(cluster.sendBitrate > 0, "burst at no bitrate");
|
|
245
|
+
MS_ASSERT(cluster.startedAtUs.has_value(), "burst has not started");
|
|
246
|
+
|
|
247
|
+
// Measured from the start of the burst rather than from the previous packet,
|
|
248
|
+
// so that a packet going out late is made up for by the ones after it
|
|
249
|
+
// instead of dragging the whole burst below the bitrate asked for.
|
|
250
|
+
const int64_t deltaUs = (cluster.sentBytes * 8 * 1000000) / cluster.sendBitrate;
|
|
251
|
+
|
|
252
|
+
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
253
|
+
return cluster.startedAtUs.value() + deltaUs;
|
|
254
|
+
}
|
|
255
|
+
} // namespace BWE
|
|
256
|
+
} // namespace RTC
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#define MS_CLASS "RTC::BWE::BitrateUtils"
|
|
2
|
+
// #define MS_LOG_DEV_LEVEL 3
|
|
3
|
+
|
|
4
|
+
#include "RTC/BWE/BitrateUtils.hpp"
|
|
5
|
+
#include "Logger.hpp"
|
|
6
|
+
#include "RTC/BWE/BweTypes.hpp"
|
|
7
|
+
#include <cmath> // std::llround()
|
|
8
|
+
|
|
9
|
+
namespace RTC
|
|
10
|
+
{
|
|
11
|
+
namespace BWE
|
|
12
|
+
{
|
|
13
|
+
/* Class methods. */
|
|
14
|
+
|
|
15
|
+
int64_t BitrateUtils::ApplyBitrateFactor(int64_t bitrate, double factor)
|
|
16
|
+
{
|
|
17
|
+
MS_TRACE();
|
|
18
|
+
|
|
19
|
+
const double result = static_cast<double>(bitrate) * factor;
|
|
20
|
+
|
|
21
|
+
// NOTE: Converting a value that the type cannot hold is undefined
|
|
22
|
+
// behaviour, and the maximum bitrate is chosen by the application, so
|
|
23
|
+
// nothing keeps this product within range.
|
|
24
|
+
if (result >= static_cast<double>(Types::BitrateInfinite))
|
|
25
|
+
{
|
|
26
|
+
return Types::BitrateInfinite;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (result <= 0.0)
|
|
30
|
+
{
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The result is rounded rather than truncated, since a factor is applied
|
|
35
|
+
// over and over to a bitrate that keeps being derived from the previous
|
|
36
|
+
// one and always losing the fraction drifts it downwards.
|
|
37
|
+
return std::llround(result);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
int64_t BitrateUtils::AddBitrates(int64_t bitrate, int64_t otherBitrate)
|
|
41
|
+
{
|
|
42
|
+
MS_TRACE();
|
|
43
|
+
|
|
44
|
+
// NOTE: Signed overflow is undefined behaviour, and both operands can be
|
|
45
|
+
// as high as the application allows.
|
|
46
|
+
if (bitrate > Types::BitrateInfinite - otherBitrate)
|
|
47
|
+
{
|
|
48
|
+
return Types::BitrateInfinite;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return bitrate + otherBitrate;
|
|
52
|
+
}
|
|
53
|
+
} // namespace BWE
|
|
54
|
+
} // namespace RTC
|
|
@@ -110,7 +110,7 @@ namespace RTC
|
|
|
110
110
|
|
|
111
111
|
if (this->options.separateAudioPackets)
|
|
112
112
|
{
|
|
113
|
-
if (packetResult.sentPacket.
|
|
113
|
+
if (packetResult.sentPacket.isAudio)
|
|
114
114
|
{
|
|
115
115
|
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
116
116
|
delayDetectorForPacket = std::addressof(this->audioDelayDetector.value());
|
|
@@ -141,7 +141,7 @@ namespace RTC
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
auto& interArrivalForPacket =
|
|
144
|
-
(this->options.separateAudioPackets && packetResult.sentPacket.
|
|
144
|
+
(this->options.separateAudioPackets && packetResult.sentPacket.isAudio)
|
|
145
145
|
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
146
146
|
? this->audioInterArrivalDelta.value()
|
|
147
147
|
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
@@ -28,17 +28,6 @@ namespace RTC
|
|
|
28
28
|
return std::nullopt;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const auto lastSequenceNumber = this->sendPacketHistory->GetLastSequenceNumber();
|
|
32
|
-
|
|
33
|
-
if (!lastSequenceNumber.has_value())
|
|
34
|
-
{
|
|
35
|
-
MS_DEBUG_TAG(bwe, "feedback received before any packet was sent");
|
|
36
|
-
|
|
37
|
-
return std::nullopt;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const int64_t lastSentSequenceNumber = lastSequenceNumber.value();
|
|
41
|
-
|
|
42
31
|
const int64_t baseTimeUs = feedback->GetReferenceTimestampUs();
|
|
43
32
|
|
|
44
33
|
if (!this->lastFeedbackBaseTimeUs.has_value())
|
|
@@ -47,6 +36,10 @@ namespace RTC
|
|
|
47
36
|
}
|
|
48
37
|
else
|
|
49
38
|
{
|
|
39
|
+
// NOTE: Taken in microseconds and not quantized any further. The groups
|
|
40
|
+
// whose arrival times the delay detector compares are only a few
|
|
41
|
+
// milliseconds apart, so rounding them to whole milliseconds would be
|
|
42
|
+
// noise of the same order as the slope being measured.
|
|
50
43
|
const int64_t baseDeltaUs = feedback->GetBaseDeltaUs(this->lastFeedbackBaseTimeUs.value());
|
|
51
44
|
|
|
52
45
|
if (baseDeltaUs < -this->currentOffsetUs)
|
|
@@ -76,30 +69,35 @@ namespace RTC
|
|
|
76
69
|
|
|
77
70
|
size_t failedLookups{ 0 };
|
|
78
71
|
|
|
79
|
-
// Each packet is resolved against the one reported before it, since the
|
|
80
|
-
// packets being sent may be far ahead of the ones the feedbacks report on.
|
|
81
|
-
// The latest packet sent seeds it, and bounds it as well, since no report
|
|
82
|
-
// can stand for a packet that was never sent.
|
|
83
|
-
int64_t sequenceNumber = std::min(
|
|
84
|
-
this->lastUnwrappedSequenceNumber.value_or(lastSentSequenceNumber), lastSentSequenceNumber);
|
|
85
|
-
|
|
86
72
|
for (const auto& packetStatus : packetStatuses)
|
|
87
73
|
{
|
|
88
|
-
|
|
74
|
+
// The wire carries the sequence number of the transport truncated to 16
|
|
75
|
+
// bits, so it's the history, which handed it out, the one that knows
|
|
76
|
+
// which of its packets it stands for.
|
|
77
|
+
const int64_t sequenceNumber =
|
|
78
|
+
this->sendPacketHistory->UnwrapSequenceNumber(packetStatus.sequenceNumber);
|
|
89
79
|
|
|
90
|
-
const auto
|
|
80
|
+
const auto retrievedEntry =
|
|
91
81
|
this->sendPacketHistory->RetrievePacket(sequenceNumber, packetStatus.received);
|
|
92
82
|
|
|
93
|
-
if (!
|
|
83
|
+
if (!retrievedEntry.has_value())
|
|
94
84
|
{
|
|
95
85
|
++failedLookups;
|
|
96
86
|
|
|
97
87
|
continue;
|
|
98
88
|
}
|
|
99
89
|
|
|
90
|
+
const auto& entry = retrievedEntry.value();
|
|
91
|
+
|
|
100
92
|
Types::PacketResult packetResult;
|
|
101
93
|
|
|
102
|
-
packetResult.sentPacket = sentPacket
|
|
94
|
+
packetResult.sentPacket = entry.sentPacket;
|
|
95
|
+
packetResult.rtpPacketInfo =
|
|
96
|
+
Types::PacketResult::RtpPacketInfo{ .ssrc = entry.ssrc,
|
|
97
|
+
.rtpSequenceNumber = entry.seq,
|
|
98
|
+
.isRetransmission = entry.isRetransmission };
|
|
99
|
+
packetResult.ambiguousReceiveTime = entry.ambiguousReceiveTime;
|
|
100
|
+
packetResult.sentWithEct1 = entry.sentWithEct1;
|
|
103
101
|
|
|
104
102
|
if (packetStatus.received)
|
|
105
103
|
{
|
|
@@ -110,8 +108,6 @@ namespace RTC
|
|
|
110
108
|
transportPacketsFeedback.packetFeedbacks.push_back(packetResult);
|
|
111
109
|
}
|
|
112
110
|
|
|
113
|
-
this->lastUnwrappedSequenceNumber = sequenceNumber;
|
|
114
|
-
|
|
115
111
|
if (failedLookups > 0)
|
|
116
112
|
{
|
|
117
113
|
MS_DEBUG_TAG(
|
|
@@ -131,18 +127,5 @@ namespace RTC
|
|
|
131
127
|
return transportPacketsFeedback;
|
|
132
128
|
}
|
|
133
129
|
|
|
134
|
-
int64_t FeedbackAdapter::UnwrapSequenceNumber(
|
|
135
|
-
uint16_t wideSequenceNumber, int64_t previousSequenceNumber)
|
|
136
|
-
{
|
|
137
|
-
MS_TRACE();
|
|
138
|
-
|
|
139
|
-
// The wire carries the sequence number of the history truncated to 16 bits,
|
|
140
|
-
// so the closest value to the previous one ending in those very same bits
|
|
141
|
-
// is the one it stands for.
|
|
142
|
-
const auto deltaSequenceNumber = static_cast<int16_t>(
|
|
143
|
-
static_cast<uint16_t>(wideSequenceNumber - static_cast<uint16_t>(previousSequenceNumber)));
|
|
144
|
-
|
|
145
|
-
return previousSequenceNumber + deltaSequenceNumber;
|
|
146
|
-
}
|
|
147
130
|
} // namespace BWE
|
|
148
131
|
} // namespace RTC
|