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
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
#define MS_CLASS "RTC::BWE::ProbeController"
|
|
2
|
+
// #define MS_LOG_DEV_LEVEL 3
|
|
3
|
+
|
|
4
|
+
#include "RTC/BWE/ProbeController.hpp"
|
|
5
|
+
#include "Logger.hpp"
|
|
6
|
+
#include "RTC/BWE/BitrateUtils.hpp"
|
|
7
|
+
|
|
8
|
+
namespace RTC
|
|
9
|
+
{
|
|
10
|
+
namespace BWE
|
|
11
|
+
{
|
|
12
|
+
/* Static. */
|
|
13
|
+
|
|
14
|
+
// How long to wait for the result of a burst before giving up on it.
|
|
15
|
+
static constexpr int64_t MaxWaitingTimeForProbingResultUs{ 1000 * 1000 };
|
|
16
|
+
// Highest bitrate a burst may aim for while the application sets no maximum.
|
|
17
|
+
//
|
|
18
|
+
// NOTE: libwebrtc uses 5 Mbps here, which is a sensible ceiling for a browser
|
|
19
|
+
// sending a couple of streams and a low one for a transport that carries many.
|
|
20
|
+
static constexpr int64_t DefaultMaxProbingBitrate{ 10000000 };
|
|
21
|
+
// Fraction of the previous estimate below which a new one counts as a large
|
|
22
|
+
// drop rather than as the estimate moving.
|
|
23
|
+
static constexpr double BitrateDropThreshold{ 0.66 };
|
|
24
|
+
// How long after a large drop it's still worth probing to find out whether it
|
|
25
|
+
// was real.
|
|
26
|
+
static constexpr int64_t BitrateDropTimeoutUs{ 5 * 1000 * 1000 };
|
|
27
|
+
// Fraction of what the estimate was worth before a large drop that the burst
|
|
28
|
+
// checking it aims for.
|
|
29
|
+
static constexpr double ProbeFractionAfterDrop{ 0.85 };
|
|
30
|
+
// How long after the sender goes back to filling the link a burst is still
|
|
31
|
+
// taken as one sent while it wasn't.
|
|
32
|
+
static constexpr int64_t AlrEndedTimeoutUs{ 3 * 1000 * 1000 };
|
|
33
|
+
// Shortest time between two bursts caused by a large drop.
|
|
34
|
+
static constexpr int64_t MinTimeBetweenAlrProbesUs{ 5 * 1000 * 1000 };
|
|
35
|
+
// How far below what a burst aims for its result may land and still be worth
|
|
36
|
+
// acting upon.
|
|
37
|
+
static constexpr double ProbeUncertainty{ 0.05 };
|
|
38
|
+
|
|
39
|
+
/* Instance methods. */
|
|
40
|
+
|
|
41
|
+
ProbeController::ProbeController() : ProbeController(ProbeControllerOptions{})
|
|
42
|
+
{
|
|
43
|
+
MS_TRACE();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
ProbeController::ProbeController(ProbeControllerOptions options) : options(options)
|
|
47
|
+
{
|
|
48
|
+
MS_TRACE();
|
|
49
|
+
|
|
50
|
+
// The time between two shots of a burst is what its bitrate is held over to
|
|
51
|
+
// decide how many bytes each shot carries, so none of them may be zero.
|
|
52
|
+
MS_ASSERT(this->options.minProbeDeltaUs > 0, "minProbeDeltaUs cannot be zero");
|
|
53
|
+
MS_ASSERT(this->options.initialMinProbeDeltaUs > 0, "initialMinProbeDeltaUs cannot be zero");
|
|
54
|
+
MS_ASSERT(
|
|
55
|
+
this->options.networkStateMinProbeDeltaUs > 0, "networkStateMinProbeDeltaUs cannot be zero");
|
|
56
|
+
|
|
57
|
+
// Until the application sets one, this is what bounds a burst.
|
|
58
|
+
this->maxBitrate = DefaultMaxProbingBitrate;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::SetBitrates(
|
|
62
|
+
int64_t minBitrate, int64_t startBitrate, int64_t maxBitrate, int64_t nowUs)
|
|
63
|
+
{
|
|
64
|
+
MS_TRACE();
|
|
65
|
+
|
|
66
|
+
if (startBitrate > 0)
|
|
67
|
+
{
|
|
68
|
+
this->startBitrate = startBitrate;
|
|
69
|
+
this->estimatedBitrate = startBitrate;
|
|
70
|
+
}
|
|
71
|
+
else if (this->startBitrate == 0)
|
|
72
|
+
{
|
|
73
|
+
this->startBitrate = minBitrate;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// NOTE: Kept because the new maximum has to be in place before probing,
|
|
77
|
+
// and the comparison below needs the old one.
|
|
78
|
+
const int64_t oldMaxBitrate = this->maxBitrate;
|
|
79
|
+
|
|
80
|
+
this->maxBitrate = maxBitrate != Types::BitrateInfinite ? maxBitrate : DefaultMaxProbingBitrate;
|
|
81
|
+
|
|
82
|
+
switch (this->state)
|
|
83
|
+
{
|
|
84
|
+
case State::INIT:
|
|
85
|
+
{
|
|
86
|
+
if (this->networkAvailable)
|
|
87
|
+
{
|
|
88
|
+
return InitiateExponentialProbing(nowUs);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
case State::WAITING_FOR_PROBING_RESULT:
|
|
95
|
+
{
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
case State::PROBING_COMPLETE:
|
|
100
|
+
{
|
|
101
|
+
// A maximum above both the previous one and the estimate is room that
|
|
102
|
+
// hasn't been looked for yet.
|
|
103
|
+
if (
|
|
104
|
+
this->estimatedBitrate != 0 && oldMaxBitrate < this->maxBitrate &&
|
|
105
|
+
this->estimatedBitrate < this->maxBitrate)
|
|
106
|
+
{
|
|
107
|
+
return InitiateProbing(nowUs, { this->maxBitrate }, /*probeFurther*/ false);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::OnMaxTotalAllocatedBitrate(
|
|
118
|
+
int64_t maxTotalAllocatedBitrate, int64_t nowUs)
|
|
119
|
+
{
|
|
120
|
+
MS_TRACE();
|
|
121
|
+
|
|
122
|
+
const bool inAlr = this->alrStartTimeUs.has_value();
|
|
123
|
+
const bool allowAllocationProbe =
|
|
124
|
+
inAlr || this->options.probeOnMaxAllocatedBitrateChangeWithoutAlr;
|
|
125
|
+
|
|
126
|
+
if (
|
|
127
|
+
this->options.probeOnMaxAllocatedBitrateChange && this->state == State::PROBING_COMPLETE &&
|
|
128
|
+
maxTotalAllocatedBitrate > this->maxTotalAllocatedBitrate &&
|
|
129
|
+
this->estimatedBitrate < this->maxBitrate &&
|
|
130
|
+
this->estimatedBitrate < maxTotalAllocatedBitrate && allowAllocationProbe)
|
|
131
|
+
{
|
|
132
|
+
this->maxTotalAllocatedBitrate = maxTotalAllocatedBitrate;
|
|
133
|
+
|
|
134
|
+
if (!this->options.firstAllocationProbeScale.has_value())
|
|
135
|
+
{
|
|
136
|
+
return {};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
int64_t firstProbeBitrate = BitrateUtils::ApplyBitrateFactor(
|
|
140
|
+
maxTotalAllocatedBitrate, this->options.firstAllocationProbeScale.value());
|
|
141
|
+
const int64_t currentBweLimit = BitrateUtils::ApplyBitrateFactor(
|
|
142
|
+
this->estimatedBitrate, this->options.allocationProbeLimitByCurrentScale);
|
|
143
|
+
|
|
144
|
+
bool limitedByCurrentBwe = currentBweLimit < firstProbeBitrate;
|
|
145
|
+
|
|
146
|
+
if (limitedByCurrentBwe)
|
|
147
|
+
{
|
|
148
|
+
firstProbeBitrate = currentBweLimit;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
std::vector<int64_t> probes{ firstProbeBitrate };
|
|
152
|
+
|
|
153
|
+
if (!limitedByCurrentBwe && this->options.secondAllocationProbeScale.has_value())
|
|
154
|
+
{
|
|
155
|
+
int64_t secondProbeBitrate = BitrateUtils::ApplyBitrateFactor(
|
|
156
|
+
maxTotalAllocatedBitrate, this->options.secondAllocationProbeScale.value());
|
|
157
|
+
|
|
158
|
+
limitedByCurrentBwe = currentBweLimit < secondProbeBitrate;
|
|
159
|
+
|
|
160
|
+
if (limitedByCurrentBwe)
|
|
161
|
+
{
|
|
162
|
+
secondProbeBitrate = currentBweLimit;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (secondProbeBitrate > firstProbeBitrate)
|
|
166
|
+
{
|
|
167
|
+
probes.push_back(secondProbeBitrate);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return InitiateProbing(nowUs, probes, /*probeFurther*/ limitedByCurrentBwe);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Having something to send is what ends the repeated initial probing, since
|
|
175
|
+
// from then on there is traffic of its own to measure.
|
|
176
|
+
if (maxTotalAllocatedBitrate != 0)
|
|
177
|
+
{
|
|
178
|
+
this->lastAllowedRepeatedInitialProbeAtUs = nowUs;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
this->maxTotalAllocatedBitrate = maxTotalAllocatedBitrate;
|
|
182
|
+
|
|
183
|
+
return {};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::OnNetworkAvailability(
|
|
187
|
+
bool networkAvailable, int64_t nowUs)
|
|
188
|
+
{
|
|
189
|
+
MS_TRACE();
|
|
190
|
+
|
|
191
|
+
this->networkAvailable = networkAvailable;
|
|
192
|
+
|
|
193
|
+
if (!this->networkAvailable && this->state == State::WAITING_FOR_PROBING_RESULT)
|
|
194
|
+
{
|
|
195
|
+
this->state = State::PROBING_COMPLETE;
|
|
196
|
+
this->minBitrateToProbeFurther = Types::BitrateInfinite;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (this->networkAvailable && this->state == State::INIT && this->startBitrate != 0)
|
|
200
|
+
{
|
|
201
|
+
return InitiateExponentialProbing(nowUs);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return {};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::SetEstimatedBitrate(
|
|
208
|
+
int64_t bitrate, BandwidthLimitedCause bandwidthLimitedCause, int64_t nowUs)
|
|
209
|
+
{
|
|
210
|
+
MS_TRACE();
|
|
211
|
+
|
|
212
|
+
this->bandwidthLimitedCause = bandwidthLimitedCause;
|
|
213
|
+
|
|
214
|
+
if (bitrate < BitrateUtils::ApplyBitrateFactor(this->estimatedBitrate, BitrateDropThreshold))
|
|
215
|
+
{
|
|
216
|
+
this->lastLargeDropAtUs = nowUs;
|
|
217
|
+
this->bitrateBeforeLastLargeDrop = this->estimatedBitrate;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this->estimatedBitrate = bitrate;
|
|
221
|
+
|
|
222
|
+
if (this->state == State::WAITING_FOR_PROBING_RESULT)
|
|
223
|
+
{
|
|
224
|
+
// Reaching what was asked for leaves nothing to keep climbing towards.
|
|
225
|
+
if (
|
|
226
|
+
this->options.abortFurtherProbeIfMaxLowerThanCurrent &&
|
|
227
|
+
(bitrate > this->maxBitrate ||
|
|
228
|
+
(this->maxTotalAllocatedBitrate != 0 &&
|
|
229
|
+
bitrate > BitrateUtils::ApplyBitrateFactor(this->maxTotalAllocatedBitrate, 2.0))))
|
|
230
|
+
{
|
|
231
|
+
this->minBitrateToProbeFurther = Types::BitrateInfinite;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const int64_t networkStateProbeFurtherLimit =
|
|
235
|
+
this->options.networkStateEstimateProbingIntervalUs != Types::TimeUsInfinite &&
|
|
236
|
+
this->linkCapacityUpperBound.has_value()
|
|
237
|
+
? BitrateUtils::ApplyBitrateFactor(
|
|
238
|
+
this->linkCapacityUpperBound.value(), this->options.furtherProbeThreshold)
|
|
239
|
+
: Types::BitrateInfinite;
|
|
240
|
+
|
|
241
|
+
if (bitrate > this->minBitrateToProbeFurther && bitrate <= networkStateProbeFurtherLimit)
|
|
242
|
+
{
|
|
243
|
+
return InitiateProbing(
|
|
244
|
+
nowUs,
|
|
245
|
+
{ BitrateUtils::ApplyBitrateFactor(bitrate, this->options.furtherExponentialProbeScale) },
|
|
246
|
+
/*probeFurther*/ true);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::RequestProbe(int64_t nowUs)
|
|
254
|
+
{
|
|
255
|
+
MS_TRACE();
|
|
256
|
+
|
|
257
|
+
// Asked for once the estimate has come back to normal after a large drop.
|
|
258
|
+
// A single burst at what it was worth before tells a drop caused by a
|
|
259
|
+
// competing flow or by the network changing from a passing one.
|
|
260
|
+
const bool inAlr = this->alrStartTimeUs.has_value();
|
|
261
|
+
const bool alrEndedRecently = this->alrEndedTimeUs.has_value() &&
|
|
262
|
+
nowUs - this->alrEndedTimeUs.value() < AlrEndedTimeoutUs;
|
|
263
|
+
|
|
264
|
+
if (!inAlr && !alrEndedRecently && !this->options.rapidRecoveryExperiment)
|
|
265
|
+
{
|
|
266
|
+
return {};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (this->state != State::PROBING_COMPLETE)
|
|
270
|
+
{
|
|
271
|
+
return {};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const int64_t suggestedProbe =
|
|
275
|
+
BitrateUtils::ApplyBitrateFactor(this->bitrateBeforeLastLargeDrop, ProbeFractionAfterDrop);
|
|
276
|
+
const int64_t minExpectedProbeResult =
|
|
277
|
+
BitrateUtils::ApplyBitrateFactor(suggestedProbe, 1.0 - ProbeUncertainty);
|
|
278
|
+
|
|
279
|
+
// NOTE: Never having dropped nor probed is not a reason to hold the burst
|
|
280
|
+
// back, so a missing instant counts as long ago.
|
|
281
|
+
const bool droppedRecently = this->lastLargeDropAtUs.has_value() &&
|
|
282
|
+
nowUs - this->lastLargeDropAtUs.value() < BitrateDropTimeoutUs;
|
|
283
|
+
const bool probedRecently =
|
|
284
|
+
this->lastBweDropProbingAtUs.has_value() &&
|
|
285
|
+
nowUs - this->lastBweDropProbingAtUs.value() <= MinTimeBetweenAlrProbesUs;
|
|
286
|
+
|
|
287
|
+
if (minExpectedProbeResult > this->estimatedBitrate && droppedRecently && !probedRecently)
|
|
288
|
+
{
|
|
289
|
+
MS_DEBUG_DEV("large drop detected, probing [suggestedProbe:%" PRIi64 "]", suggestedProbe);
|
|
290
|
+
|
|
291
|
+
this->lastBweDropProbingAtUs = nowUs;
|
|
292
|
+
|
|
293
|
+
return InitiateProbing(nowUs, { suggestedProbe }, /*probeFurther*/ false);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return {};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
void ProbeController::Reset(int64_t nowUs)
|
|
300
|
+
{
|
|
301
|
+
MS_TRACE();
|
|
302
|
+
|
|
303
|
+
this->bandwidthLimitedCause = BandwidthLimitedCause::DELAY_BASED_LIMITED;
|
|
304
|
+
this->state = State::INIT;
|
|
305
|
+
this->minBitrateToProbeFurther = Types::BitrateInfinite;
|
|
306
|
+
this->lastProbingInitiatedAtUs.reset();
|
|
307
|
+
this->estimatedBitrate = 0;
|
|
308
|
+
this->linkCapacityUpperBound.reset();
|
|
309
|
+
this->startBitrate = 0;
|
|
310
|
+
this->maxBitrate = DefaultMaxProbingBitrate;
|
|
311
|
+
this->alrEndedTimeUs.reset();
|
|
312
|
+
this->lastBweDropProbingAtUs = nowUs;
|
|
313
|
+
this->lastLargeDropAtUs = nowUs;
|
|
314
|
+
this->bitrateBeforeLastLargeDrop = 0;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::Process(int64_t nowUs)
|
|
318
|
+
{
|
|
319
|
+
MS_TRACE();
|
|
320
|
+
|
|
321
|
+
// NOTE: Never having probed counts as having waited long enough.
|
|
322
|
+
if (!this->lastProbingInitiatedAtUs.has_value() || nowUs - this->lastProbingInitiatedAtUs.value() > MaxWaitingTimeForProbingResultUs)
|
|
323
|
+
{
|
|
324
|
+
if (this->state == State::WAITING_FOR_PROBING_RESULT)
|
|
325
|
+
{
|
|
326
|
+
MS_DEBUG_DEV("gave up waiting for the result of a probe");
|
|
327
|
+
|
|
328
|
+
UpdateState(State::PROBING_COMPLETE);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (this->estimatedBitrate == 0 || this->state != State::PROBING_COMPLETE)
|
|
333
|
+
{
|
|
334
|
+
return {};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (IsTimeForNextRepeatedInitialProbe(nowUs))
|
|
338
|
+
{
|
|
339
|
+
return InitiateProbing(
|
|
340
|
+
nowUs,
|
|
341
|
+
{ BitrateUtils::ApplyBitrateFactor(
|
|
342
|
+
this->estimatedBitrate, this->options.firstExponentialProbeScale) },
|
|
343
|
+
/*probeFurther*/ true);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (IsTimeForAlrProbe(nowUs) || IsTimeForNetworkStateProbe(nowUs))
|
|
347
|
+
{
|
|
348
|
+
return InitiateProbing(
|
|
349
|
+
nowUs,
|
|
350
|
+
{ BitrateUtils::ApplyBitrateFactor(this->estimatedBitrate, this->options.alrProbeScale) },
|
|
351
|
+
/*probeFurther*/ true);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return {};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
void ProbeController::UpdateState(State newState)
|
|
358
|
+
{
|
|
359
|
+
MS_TRACE();
|
|
360
|
+
|
|
361
|
+
this->state = newState;
|
|
362
|
+
|
|
363
|
+
// Nothing left to climb towards means no bitrate can be worth following up.
|
|
364
|
+
if (newState == State::PROBING_COMPLETE)
|
|
365
|
+
{
|
|
366
|
+
this->minBitrateToProbeFurther = Types::BitrateInfinite;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::InitiateExponentialProbing(int64_t nowUs)
|
|
371
|
+
{
|
|
372
|
+
MS_TRACE();
|
|
373
|
+
|
|
374
|
+
// NOTE: The three of them are guaranteed by every caller, which only gets
|
|
375
|
+
// here with a network and a bitrate to start from and nothing probed yet.
|
|
376
|
+
MS_ASSERT(this->networkAvailable, "network is not available");
|
|
377
|
+
MS_ASSERT(this->state == State::INIT, "probing already started");
|
|
378
|
+
MS_ASSERT(this->startBitrate > 0, "no bitrate to start from");
|
|
379
|
+
|
|
380
|
+
std::vector<int64_t> probes{ BitrateUtils::ApplyBitrateFactor(
|
|
381
|
+
this->startBitrate, this->options.firstExponentialProbeScale) };
|
|
382
|
+
|
|
383
|
+
if (
|
|
384
|
+
this->options.secondExponentialProbeScale.has_value() &&
|
|
385
|
+
this->options.secondExponentialProbeScale.value() > 0)
|
|
386
|
+
{
|
|
387
|
+
probes.push_back(
|
|
388
|
+
BitrateUtils::ApplyBitrateFactor(
|
|
389
|
+
this->startBitrate, this->options.secondExponentialProbeScale.value()));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Repeating the initial bursts only makes sense while there is nothing of
|
|
393
|
+
// our own being sent to measure instead.
|
|
394
|
+
if (this->repeatedInitialProbingEnabled && this->maxTotalAllocatedBitrate == 0)
|
|
395
|
+
{
|
|
396
|
+
this->lastAllowedRepeatedInitialProbeAtUs =
|
|
397
|
+
nowUs + this->options.repeatedInitialProbingTimePeriodUs;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return InitiateProbing(nowUs, probes, /*probeFurther*/ true);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
std::vector<Types::ProbeClusterConfig> ProbeController::InitiateProbing(
|
|
404
|
+
int64_t nowUs, const std::vector<int64_t>& bitratesToProbe, bool probeFurther)
|
|
405
|
+
{
|
|
406
|
+
MS_TRACE();
|
|
407
|
+
|
|
408
|
+
if (this->options.skipIfEstimateLargerThanFractionOfMax > 0)
|
|
409
|
+
{
|
|
410
|
+
const int64_t linkCapacityUpperBound =
|
|
411
|
+
this->linkCapacityUpperBound.value_or(Types::BitrateInfinite);
|
|
412
|
+
const int64_t maxProbeBitrate =
|
|
413
|
+
this->maxTotalAllocatedBitrate == 0
|
|
414
|
+
? this->maxBitrate
|
|
415
|
+
: std::min(
|
|
416
|
+
BitrateUtils::ApplyBitrateFactor(
|
|
417
|
+
this->maxTotalAllocatedBitrate, this->options.skipProbeMaxAllocatedScale),
|
|
418
|
+
this->maxBitrate);
|
|
419
|
+
|
|
420
|
+
if (
|
|
421
|
+
std::min(linkCapacityUpperBound, this->estimatedBitrate) >
|
|
422
|
+
BitrateUtils::ApplyBitrateFactor(
|
|
423
|
+
maxProbeBitrate, this->options.skipIfEstimateLargerThanFractionOfMax))
|
|
424
|
+
{
|
|
425
|
+
UpdateState(State::PROBING_COMPLETE);
|
|
426
|
+
|
|
427
|
+
return {};
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
int64_t maxProbeBitrate = this->maxBitrate;
|
|
432
|
+
|
|
433
|
+
// Aiming above what the application wants to send is allowed, since a
|
|
434
|
+
// stream that bursts would otherwise have to climb once it's already
|
|
435
|
+
// overshooting, and a burst tends to be received slightly below what it
|
|
436
|
+
// aimed for.
|
|
437
|
+
if (this->maxTotalAllocatedBitrate > 0)
|
|
438
|
+
{
|
|
439
|
+
maxProbeBitrate = std::min(
|
|
440
|
+
maxProbeBitrate, BitrateUtils::ApplyBitrateFactor(this->maxTotalAllocatedBitrate, 2.0));
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
switch (this->bandwidthLimitedCause)
|
|
444
|
+
{
|
|
445
|
+
case BandwidthLimitedCause::RTT_BASED_BACK_OFF_HIGH_RTT:
|
|
446
|
+
case BandwidthLimitedCause::DELAY_BASED_LIMITED_DELAY_INCREASED:
|
|
447
|
+
case BandwidthLimitedCause::LOSS_LIMITED_BWE:
|
|
448
|
+
{
|
|
449
|
+
// Something is already holding the estimate back, so a burst would
|
|
450
|
+
// measure that and not the link.
|
|
451
|
+
MS_DEBUG_DEV("not probing while the estimate is limited");
|
|
452
|
+
|
|
453
|
+
return {};
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
case BandwidthLimitedCause::LOSS_LIMITED_BWE_INCREASING:
|
|
457
|
+
{
|
|
458
|
+
maxProbeBitrate = std::min(
|
|
459
|
+
maxProbeBitrate,
|
|
460
|
+
BitrateUtils::ApplyBitrateFactor(
|
|
461
|
+
this->estimatedBitrate, this->options.lossLimitedProbeScale));
|
|
462
|
+
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
case BandwidthLimitedCause::DELAY_BASED_LIMITED:
|
|
467
|
+
{
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (
|
|
473
|
+
this->options.networkStateEstimateProbingIntervalUs != Types::TimeUsInfinite &&
|
|
474
|
+
this->linkCapacityUpperBound.has_value())
|
|
475
|
+
{
|
|
476
|
+
if (this->linkCapacityUpperBound.value() == 0)
|
|
477
|
+
{
|
|
478
|
+
MS_DEBUG_DEV("not probing, the link is known to carry nothing");
|
|
479
|
+
|
|
480
|
+
return {};
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
maxProbeBitrate = std::min(
|
|
484
|
+
maxProbeBitrate,
|
|
485
|
+
std::max(
|
|
486
|
+
this->estimatedBitrate,
|
|
487
|
+
BitrateUtils::ApplyBitrateFactor(
|
|
488
|
+
this->linkCapacityUpperBound.value(), this->options.networkStateProbeScale)));
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
std::vector<Types::ProbeClusterConfig> pendingProbes;
|
|
492
|
+
|
|
493
|
+
pendingProbes.reserve(bitratesToProbe.size());
|
|
494
|
+
|
|
495
|
+
for (int64_t bitrate : bitratesToProbe)
|
|
496
|
+
{
|
|
497
|
+
// A burst at no bitrate is not a burst. It comes up when what bounds it
|
|
498
|
+
// is an estimate that doesn't exist yet, and then there is nothing to
|
|
499
|
+
// look for.
|
|
500
|
+
if (bitrate == 0)
|
|
501
|
+
{
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (bitrate >= maxProbeBitrate)
|
|
506
|
+
{
|
|
507
|
+
bitrate = maxProbeBitrate;
|
|
508
|
+
probeFurther = false;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
pendingProbes.push_back(CreateProbeClusterConfig(nowUs, bitrate));
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
this->lastProbingInitiatedAtUs = nowUs;
|
|
515
|
+
|
|
516
|
+
// Nothing was asked for, so there is no result to wait for either.
|
|
517
|
+
if (probeFurther && !pendingProbes.empty())
|
|
518
|
+
{
|
|
519
|
+
UpdateState(State::WAITING_FOR_PROBING_RESULT);
|
|
520
|
+
|
|
521
|
+
// A burst is not expected to be received at the whole bitrate it was
|
|
522
|
+
// sent at, so what has to be beaten is a fraction of it.
|
|
523
|
+
this->minBitrateToProbeFurther = BitrateUtils::ApplyBitrateFactor(
|
|
524
|
+
pendingProbes.back().targetBitrate, this->options.furtherProbeThreshold);
|
|
525
|
+
}
|
|
526
|
+
else
|
|
527
|
+
{
|
|
528
|
+
UpdateState(State::PROBING_COMPLETE);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return pendingProbes;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
bool ProbeController::IsTimeForAlrProbe(int64_t nowUs) const
|
|
535
|
+
{
|
|
536
|
+
MS_TRACE();
|
|
537
|
+
|
|
538
|
+
if (!this->enablePeriodicAlrProbing || !this->alrStartTimeUs.has_value())
|
|
539
|
+
{
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// NOTE: Never having probed makes the start of the state the only instant
|
|
544
|
+
// to measure from.
|
|
545
|
+
const int64_t sinceUs = std::max(
|
|
546
|
+
this->alrStartTimeUs.value(),
|
|
547
|
+
this->lastProbingInitiatedAtUs.value_or(this->alrStartTimeUs.value()));
|
|
548
|
+
|
|
549
|
+
return nowUs >= sinceUs + this->options.alrProbingIntervalUs;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
bool ProbeController::IsTimeForNetworkStateProbe(int64_t nowUs) const
|
|
553
|
+
{
|
|
554
|
+
MS_TRACE();
|
|
555
|
+
|
|
556
|
+
if (!this->linkCapacityUpperBound.has_value())
|
|
557
|
+
{
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const bool probeDueToLowEstimate =
|
|
562
|
+
this->bandwidthLimitedCause == BandwidthLimitedCause::DELAY_BASED_LIMITED &&
|
|
563
|
+
this->estimatedBitrate < BitrateUtils::ApplyBitrateFactor(
|
|
564
|
+
this->linkCapacityUpperBound.value(),
|
|
565
|
+
this->options.probeIfEstimateLowerThanNetworkStateEstimateRatio);
|
|
566
|
+
|
|
567
|
+
// NOTE: Never having probed means that whichever interval applies has
|
|
568
|
+
// already gone by.
|
|
569
|
+
if (probeDueToLowEstimate && this->options.estimateLowerThanNetworkStateEstimateProbingIntervalUs != Types::TimeUsInfinite)
|
|
570
|
+
{
|
|
571
|
+
return !this->lastProbingInitiatedAtUs.has_value() ||
|
|
572
|
+
nowUs >= this->lastProbingInitiatedAtUs.value() +
|
|
573
|
+
this->options.estimateLowerThanNetworkStateEstimateProbingIntervalUs;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const bool periodicProbe = this->estimatedBitrate < this->linkCapacityUpperBound.value();
|
|
577
|
+
|
|
578
|
+
if (periodicProbe && this->options.networkStateEstimateProbingIntervalUs != Types::TimeUsInfinite)
|
|
579
|
+
{
|
|
580
|
+
return !this->lastProbingInitiatedAtUs.has_value() ||
|
|
581
|
+
nowUs >= this->lastProbingInitiatedAtUs.value() +
|
|
582
|
+
this->options.networkStateEstimateProbingIntervalUs;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return false;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
bool ProbeController::IsTimeForNextRepeatedInitialProbe(int64_t nowUs) const
|
|
589
|
+
{
|
|
590
|
+
MS_TRACE();
|
|
591
|
+
|
|
592
|
+
if (
|
|
593
|
+
this->state == State::WAITING_FOR_PROBING_RESULT ||
|
|
594
|
+
!this->lastAllowedRepeatedInitialProbeAtUs.has_value() ||
|
|
595
|
+
this->lastAllowedRepeatedInitialProbeAtUs.value() <= nowUs)
|
|
596
|
+
{
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// NOTE: Never having probed means that the wait is already over.
|
|
601
|
+
return !this->lastProbingInitiatedAtUs.has_value() ||
|
|
602
|
+
nowUs >= this->lastProbingInitiatedAtUs.value() + MaxWaitingTimeForProbingResultUs;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
Types::ProbeClusterConfig ProbeController::CreateProbeClusterConfig(int64_t nowUs, int64_t bitrate)
|
|
606
|
+
{
|
|
607
|
+
MS_TRACE();
|
|
608
|
+
|
|
609
|
+
Types::ProbeClusterConfig config;
|
|
610
|
+
|
|
611
|
+
config.atUs = nowUs;
|
|
612
|
+
config.targetBitrate = bitrate;
|
|
613
|
+
|
|
614
|
+
// A burst aiming no higher than what the link is known to carry can be
|
|
615
|
+
// shorter, since it isn't looking for room that may not be there.
|
|
616
|
+
if (
|
|
617
|
+
this->linkCapacityUpperBound.has_value() &&
|
|
618
|
+
this->options.networkStateEstimateProbingIntervalUs != Types::TimeUsInfinite &&
|
|
619
|
+
this->linkCapacityUpperBound.value() >= bitrate)
|
|
620
|
+
{
|
|
621
|
+
config.targetDurationUs = this->options.networkStateProbeDurationUs;
|
|
622
|
+
config.minProbeDeltaUs = this->options.networkStateMinProbeDeltaUs;
|
|
623
|
+
}
|
|
624
|
+
else if (
|
|
625
|
+
this->lastAllowedRepeatedInitialProbeAtUs.has_value() &&
|
|
626
|
+
nowUs < this->lastAllowedRepeatedInitialProbeAtUs.value())
|
|
627
|
+
{
|
|
628
|
+
config.targetDurationUs = this->options.initialProbeDurationUs;
|
|
629
|
+
config.minProbeDeltaUs = this->options.initialMinProbeDeltaUs;
|
|
630
|
+
}
|
|
631
|
+
else
|
|
632
|
+
{
|
|
633
|
+
config.targetDurationUs = this->options.minProbeDurationUs;
|
|
634
|
+
config.minProbeDeltaUs = this->options.minProbeDeltaUs;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
config.targetProbeCount = this->options.minProbePacketsSent;
|
|
638
|
+
config.id = this->nextProbeClusterId;
|
|
639
|
+
|
|
640
|
+
this->nextProbeClusterId++;
|
|
641
|
+
|
|
642
|
+
return config;
|
|
643
|
+
}
|
|
644
|
+
} // namespace BWE
|
|
645
|
+
} // namespace RTC
|