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.
Files changed (213) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/node/lib/Consumer.d.ts.map +1 -1
  3. package/node/lib/Consumer.js +4 -51
  4. package/node/lib/Producer.d.ts.map +1 -1
  5. package/node/lib/Producer.js +4 -8
  6. package/node/lib/ProducerTypes.d.ts +4 -2
  7. package/node/lib/ProducerTypes.d.ts.map +1 -1
  8. package/node/lib/Router.d.ts.map +1 -1
  9. package/node/lib/Router.js +4 -0
  10. package/node/lib/Transport.d.ts.map +1 -1
  11. package/node/lib/Transport.js +7 -10
  12. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts +3 -4
  13. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts.map +1 -1
  14. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.js +3 -4
  15. package/node/lib/ortc.d.ts +0 -2
  16. package/node/lib/ortc.d.ts.map +1 -1
  17. package/node/lib/ortc.js +11 -21
  18. package/node/lib/rtpMappingFbsUtils.d.ts +6 -0
  19. package/node/lib/rtpMappingFbsUtils.d.ts.map +1 -0
  20. package/node/lib/rtpMappingFbsUtils.js +65 -0
  21. package/node/lib/rtpParametersFbsUtils.d.ts.map +1 -1
  22. package/node/lib/rtpParametersFbsUtils.js +0 -6
  23. package/node/lib/rtpParametersTypes.d.ts +1 -1
  24. package/node/lib/rtpParametersTypes.d.ts.map +1 -1
  25. package/node/lib/rtpStreamFbsUtils.d.ts +4 -0
  26. package/node/lib/rtpStreamFbsUtils.d.ts.map +1 -0
  27. package/node/lib/rtpStreamFbsUtils.js +51 -0
  28. package/node/lib/supportedRtpCapabilities.d.ts.map +1 -1
  29. package/node/lib/supportedRtpCapabilities.js +6 -13
  30. package/node/lib/test/test-Consumer.js +1 -13
  31. package/node/lib/test/test-DataConsumer.js +9 -0
  32. package/node/lib/test/test-DataProducer.js +38 -0
  33. package/node/lib/test/test-PipeTransport.js +27 -29
  34. package/node/lib/test/test-Producer.js +97 -0
  35. package/node/lib/test/test-ortc.js +34 -14
  36. package/package.json +10 -10
  37. package/worker/fbs/FBS/meson.build +25 -0
  38. package/worker/fbs/meson.build +15 -18
  39. package/worker/fbs/rtpParameters.fbs +0 -1
  40. package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
  41. package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
  42. package/worker/include/DepLibUV.hpp +13 -0
  43. package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
  44. package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
  45. package/worker/include/RTC/BWE/BitrateUtils.hpp +39 -0
  46. package/worker/include/RTC/BWE/BweTypes.hpp +171 -3
  47. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
  48. package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
  49. package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
  50. package/worker/include/RTC/BWE/LossBasedController.hpp +625 -0
  51. package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
  52. package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
  53. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
  54. package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
  55. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
  56. package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
  57. package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
  58. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
  59. package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
  60. package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
  61. package/worker/include/RTC/BWE/TargetRateController.hpp +306 -0
  62. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
  63. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +73 -16
  64. package/worker/include/RTC/Consts.hpp +70 -0
  65. package/worker/include/RTC/DataConsumer.hpp +3 -5
  66. package/worker/include/RTC/DirectTransport.hpp +4 -5
  67. package/worker/include/RTC/PipeTransport.hpp +4 -5
  68. package/worker/include/RTC/PlainTransport.hpp +4 -5
  69. package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
  70. package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
  71. package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
  72. package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
  73. package/worker/include/RTC/RTP/Packet.hpp +16 -4
  74. package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
  75. package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
  76. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
  77. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
  78. package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
  79. package/worker/include/RTC/RateCalculator.hpp +103 -24
  80. package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
  81. package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
  82. package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
  83. package/worker/include/RTC/RtpDictionaries.hpp +3 -4
  84. package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
  85. package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +36 -0
  86. package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
  87. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +9 -9
  88. package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
  89. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +11 -1
  90. package/worker/include/RTC/SctpDictionaries.hpp +2 -2
  91. package/worker/include/RTC/TcpConnection.hpp +2 -1
  92. package/worker/include/RTC/Transport.hpp +23 -8
  93. package/worker/include/RTC/TransportTuple.hpp +61 -6
  94. package/worker/include/RTC/WebRtcTransport.hpp +4 -5
  95. package/worker/include/Shared.hpp +5 -0
  96. package/worker/include/SharedInterface.hpp +10 -0
  97. package/worker/include/Utils.hpp +72 -3
  98. package/worker/include/common.hpp +12 -4
  99. package/worker/include/handles/SendCallbacks.hpp +34 -0
  100. package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
  101. package/worker/include/handles/UdpSocketHandle.hpp +4 -8
  102. package/worker/meson.build +45 -1
  103. package/worker/meson_options.txt +1 -0
  104. package/worker/mocks/include/MockShared.hpp +16 -2
  105. package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
  106. package/worker/scripts/package-lock.json +6 -6
  107. package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
  108. package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
  109. package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
  110. package/worker/src/RTC/BWE/BitrateUtils.cpp +54 -0
  111. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
  112. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
  113. package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
  114. package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
  115. package/worker/src/RTC/BWE/LossBasedController.cpp +1194 -0
  116. package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
  117. package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
  118. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
  119. package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
  120. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
  121. package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
  122. package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
  123. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
  124. package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
  125. package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
  126. package/worker/src/RTC/BWE/TargetRateController.cpp +433 -0
  127. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
  128. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +102 -5
  129. package/worker/src/RTC/Consumer.cpp +7 -5
  130. package/worker/src/RTC/DataConsumer.cpp +8 -10
  131. package/worker/src/RTC/DirectTransport.cpp +14 -8
  132. package/worker/src/RTC/DtlsTransport.cpp +8 -8
  133. package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
  134. package/worker/src/RTC/ICE/IceServer.cpp +1 -1
  135. package/worker/src/RTC/PipeTransport.cpp +13 -8
  136. package/worker/src/RTC/PlainTransport.cpp +13 -8
  137. package/worker/src/RTC/Producer.cpp +14 -31
  138. package/worker/src/RTC/RTCP/Bye.cpp +1 -1
  139. package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
  140. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
  141. package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
  142. package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
  143. package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
  144. package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
  145. package/worker/src/RTC/RTP/Packet.cpp +26 -11
  146. package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
  147. package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
  148. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
  149. package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
  150. package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
  151. package/worker/src/RTC/RateCalculator.cpp +133 -28
  152. package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
  153. package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
  154. package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
  155. package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
  156. package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
  157. package/worker/src/RTC/SCTP/association/Association.cpp +16 -2
  158. package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +106 -1
  159. package/worker/src/RTC/SCTP/public/AssociationMetrics.cpp +1 -1
  160. package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
  161. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  162. package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
  163. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
  164. package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
  165. package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
  166. package/worker/src/RTC/SrtpSession.cpp +2 -2
  167. package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
  168. package/worker/src/RTC/TcpConnection.cpp +2 -2
  169. package/worker/src/RTC/Transport.cpp +112 -75
  170. package/worker/src/RTC/TransportTuple.cpp +4 -4
  171. package/worker/src/RTC/WebRtcServer.cpp +4 -3
  172. package/worker/src/RTC/WebRtcTransport.cpp +20 -13
  173. package/worker/src/Utils/BitStream.cpp +24 -0
  174. package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
  175. package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
  176. package/worker/src/handles/UdpSocketHandle.cpp +14 -21
  177. package/worker/tasks.py +43 -18
  178. package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
  179. package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
  180. package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
  181. package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
  182. package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
  183. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
  184. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
  185. package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
  186. package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
  187. package/worker/test/src/RTC/BWE/TestLossBasedController.cpp +1199 -0
  188. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
  189. package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
  190. package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
  191. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
  192. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
  193. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
  194. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
  195. package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
  196. package/worker/test/src/RTC/BWE/TestTargetRateController.cpp +337 -0
  197. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
  198. package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +45 -0
  199. package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
  200. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
  201. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
  202. package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
  203. package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
  204. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
  205. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
  206. package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +111 -0
  207. package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
  208. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
  209. package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
  210. package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
  211. package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
  212. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
  213. package/worker/test/src/Utils/TestTime.cpp +120 -21
@@ -0,0 +1,115 @@
1
+ #ifndef MS_RTC_BWE_OVERUSE_ESTIMATOR_HPP
2
+ #define MS_RTC_BWE_OVERUSE_ESTIMATOR_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/BweTypes.hpp"
6
+ #include <deque>
7
+
8
+ namespace RTC
9
+ {
10
+ namespace BWE
11
+ {
12
+ /**
13
+ * Estimates how much the delay between groups of packets is growing, and how
14
+ * noisy that measure is.
15
+ *
16
+ * It fits a two variable model to what each pair of groups showed: how much
17
+ * of the extra delay is explained by the group being bigger, and how much is
18
+ * left over once that is taken out. The second one is the interesting part,
19
+ * since a delay that grows without the traffic growing is a queue filling up
20
+ * somewhere.
21
+ *
22
+ * Both are tracked with a Kalman filter, which is what lets the estimate
23
+ * follow the network while telling apart a real trend from the jitter that
24
+ * every link has. The noise it measures along the way is what the detector
25
+ * compares the trend against.
26
+ *
27
+ * @remarks
28
+ * - This is what the receiving side uses, where the only thing known about
29
+ * when a packet was sent is the timestamp it carries. The sending side has
30
+ * the real instants, so it uses `TrendlineEstimator` instead, which fits a
31
+ * line rather than filtering.
32
+ */
33
+ class OveruseEstimator
34
+ {
35
+ public:
36
+ OveruseEstimator() = default;
37
+
38
+ ~OveruseEstimator() = default;
39
+
40
+ OveruseEstimator(const OveruseEstimator&) = delete;
41
+ OveruseEstimator& operator=(const OveruseEstimator&) = delete;
42
+
43
+ /**
44
+ * Feed the deltas between two consecutive groups of packets.
45
+ *
46
+ * @param arrivalDeltaMs - Time elapsed between the arrival of both groups.
47
+ * @param sendDeltaMs - Time elapsed between the send times of both groups.
48
+ * @param sizeDelta - Difference of size between both groups (bytes).
49
+ * @param currentHypothesis - What the detector makes of the network right
50
+ * now, which decides whether this sample is used to measure the noise
51
+ * and how much the filter is allowed to move.
52
+ */
53
+ void Update(
54
+ double arrivalDeltaMs,
55
+ double sendDeltaMs,
56
+ int64_t sizeDelta,
57
+ Types::BandwidthUsage currentHypothesis);
58
+
59
+ /**
60
+ * Estimated variance of the noise (ms^2).
61
+ */
62
+ double GetVarNoiseMs2() const
63
+ {
64
+ return this->varNoiseMs2;
65
+ }
66
+
67
+ /**
68
+ * Estimated part of the delay between groups that the traffic itself
69
+ * doesn't explain (ms).
70
+ */
71
+ double GetOffsetMs() const
72
+ {
73
+ return this->offsetMs;
74
+ }
75
+
76
+ /**
77
+ * Number of samples the current estimate is based on.
78
+ */
79
+ int64_t GetNumOfDeltas() const
80
+ {
81
+ return this->numOfDeltas;
82
+ }
83
+
84
+ private:
85
+ /**
86
+ * Shortest send delta of the recent history, which is what the noise
87
+ * estimate is scaled by so that it doesn't depend on how often packets
88
+ * come.
89
+ */
90
+ double UpdateMinFramePeriod(double sendDeltaMs);
91
+
92
+ void UpdateNoiseEstimate(double residual, double minFramePeriodMs, bool stableState);
93
+
94
+ private:
95
+ int64_t numOfDeltas{ 0 };
96
+ // How much of the extra delay a bigger group explains (ms per byte).
97
+ double slopeMsPerByte{ 8.0 / 512.0 };
98
+ // What is left of it once that is taken out (ms).
99
+ double offsetMs{ 0.0 };
100
+ double prevOffsetMs{ 0.0 };
101
+ // Covariance of the two values above, and how much they are allowed to
102
+ // move on their own between samples.
103
+ double e[2][2]{
104
+ { 100.0, 0.0 },
105
+ { 0.0, 1e-1 }
106
+ };
107
+ double processNoise[2]{ 1e-13, 1e-3 };
108
+ double avgNoiseMs{ 0.0 };
109
+ double varNoiseMs2{ 50.0 };
110
+ std::deque<double> sendDeltaHistMs;
111
+ };
112
+ } // namespace BWE
113
+ } // namespace RTC
114
+
115
+ #endif
@@ -0,0 +1,84 @@
1
+ #ifndef MS_RTC_BWE_PROBE_BITRATE_ESTIMATOR_HPP
2
+ #define MS_RTC_BWE_PROBE_BITRATE_ESTIMATOR_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/BweTypes.hpp"
6
+ #include <ankerl/unordered_dense.h>
7
+
8
+ namespace RTC
9
+ {
10
+ namespace BWE
11
+ {
12
+ /**
13
+ * Measures what a probe actually achieved.
14
+ *
15
+ * A probe is a burst of packets sent on purpose above the current estimate,
16
+ * and the point of it is to learn the capacity of the link directly instead
17
+ * of inferring it from the delay. This class gathers the feedback of the
18
+ * packets of each burst and, once enough of the burst has come back, says at
19
+ * what bitrate it was delivered.
20
+ *
21
+ * The answer is the lower of the rate it was sent at and the rate it
22
+ * arrived at, because a burst that arrives faster than it was sent measures
23
+ * the sender and not the link. And when it arrives clearly slower than it
24
+ * was sent, that means the burst found the real capacity, so the answer is
25
+ * taken slightly below what arrived in order not to overuse it right away.
26
+ *
27
+ * A burst that too little of came back, that was sent or received over too
28
+ * long a span, or that arrived far faster than it was sent, is discarded
29
+ * rather than believed.
30
+ */
31
+ class ProbeBitrateEstimator
32
+ {
33
+ private:
34
+ /**
35
+ * What has been gathered so far about a burst.
36
+ */
37
+ struct AggregatedCluster
38
+ {
39
+ int64_t numProbes{ 0 };
40
+ std::optional<int64_t> firstSendTimeUs;
41
+ std::optional<int64_t> lastSendTimeUs;
42
+ std::optional<int64_t> firstReceiveTimeUs;
43
+ std::optional<int64_t> lastReceiveTimeUs;
44
+ // Size of the packet sent last, which the span of send times doesn't
45
+ // cover.
46
+ int64_t sizeLastSend{ 0 };
47
+ // Size of the packet received first, which the span of receive times
48
+ // doesn't cover.
49
+ int64_t sizeFirstReceive{ 0 };
50
+ int64_t sizeTotal{ 0 };
51
+ };
52
+
53
+ public:
54
+ /**
55
+ * Feed the feedback of a packet that belongs to a probe.
56
+ *
57
+ * @returns The bitrate the probe achieved (bps), or no value while its
58
+ * burst cannot be trusted yet or at all.
59
+ */
60
+ std::optional<int64_t> HandleProbeAndEstimateBitrate(const Types::PacketResult& packetResult);
61
+
62
+ /**
63
+ * Take the latest measured bitrate (bps), leaving none behind, so that a
64
+ * probe is never acted upon twice.
65
+ */
66
+ std::optional<int64_t> FetchAndResetLastEstimatedBitrate();
67
+
68
+ private:
69
+ /**
70
+ * Forget the bursts whose last packet arrived long enough ago that they
71
+ * cannot receive anything else.
72
+ */
73
+ void EraseOldClusters(int64_t nowUs);
74
+
75
+ private:
76
+ // Bursts being gathered, by their id. Nothing looks at them in any
77
+ // particular order.
78
+ ankerl::unordered_dense::map<int64_t, AggregatedCluster> clusters;
79
+ std::optional<int64_t> estimatedBitrate;
80
+ };
81
+ } // namespace BWE
82
+ } // namespace RTC
83
+
84
+ #endif
@@ -0,0 +1,379 @@
1
+ #ifndef MS_RTC_BWE_PROBE_CONTROLLER_HPP
2
+ #define MS_RTC_BWE_PROBE_CONTROLLER_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/BweTypes.hpp"
6
+ #include <vector>
7
+
8
+ namespace RTC
9
+ {
10
+ namespace BWE
11
+ {
12
+ /**
13
+ * Decides when to probe and at what bitrate.
14
+ *
15
+ * Probing is the only way to discover capacity that is not being used,
16
+ * because nothing measured while sending below the link's capacity says
17
+ * anything about how much more it could carry. So this asks for bursts: at
18
+ * the start of a connection to climb fast instead of waiting for the slow
19
+ * ramp, periodically while the sender isn't filling the link, when the
20
+ * application asks for more than is being sent, and after a large drop to
21
+ * check whether it was real.
22
+ *
23
+ * It decides nothing else: every method returns the bursts to launch, and
24
+ * emitting them is somebody else's job. And it refuses to probe whenever
25
+ * something is already known to be holding the estimate back, since a burst
26
+ * then measures that limit rather than the link.
27
+ */
28
+ class ProbeController
29
+ {
30
+ public:
31
+ /**
32
+ * Why the estimate is not free to grow, which decides whether probing
33
+ * makes sense at all.
34
+ */
35
+ enum class BandwidthLimitedCause : uint8_t
36
+ {
37
+ /**
38
+ * Loss is what limits the estimate, and it's growing back.
39
+ */
40
+ LOSS_LIMITED_BWE_INCREASING = 0,
41
+ /**
42
+ * Loss is what limits the estimate and it isn't growing.
43
+ */
44
+ LOSS_LIMITED_BWE,
45
+ /**
46
+ * The delay based path is what limits the estimate.
47
+ */
48
+ DELAY_BASED_LIMITED,
49
+ /**
50
+ * The same, with the delay growing right now.
51
+ */
52
+ DELAY_BASED_LIMITED_DELAY_INCREASED,
53
+ /**
54
+ * A round trip time long enough to mean that the queues are full.
55
+ */
56
+ RTT_BASED_BACK_OFF_HIGH_RTT
57
+ };
58
+
59
+ /**
60
+ * @remarks
61
+ * - Every constraint documented below is checked by the constructor and
62
+ * aborts when it doesn't hold. These options are set from C++ alone,
63
+ * never from the network nor from the API, so breaking one of them is a
64
+ * programming error.
65
+ */
66
+ struct ProbeControllerOptions
67
+ {
68
+ /**
69
+ * Factor applied to the start bitrate for the first burst of the
70
+ * connection.
71
+ */
72
+ double firstExponentialProbeScale{ 3.0 };
73
+ /**
74
+ * The same for the second one, or no value to send just one.
75
+ */
76
+ std::optional<double> secondExponentialProbeScale{ 6.0 };
77
+ /**
78
+ * Factor applied to the measured bitrate for each burst that follows one
79
+ * whose result was good enough to keep climbing.
80
+ */
81
+ double furtherExponentialProbeScale{ 2.0 };
82
+ /**
83
+ * Fraction of the bitrate a burst was sent at that its result has to
84
+ * exceed for another one to follow it.
85
+ */
86
+ double furtherProbeThreshold{ 0.7 };
87
+ /**
88
+ * Whether to stop climbing as soon as the measured bitrate is already
89
+ * above what the application asked for.
90
+ */
91
+ bool abortFurtherProbeIfMaxLowerThanCurrent{ false };
92
+ /**
93
+ * How long after the first burst the initial ones keep being repeated,
94
+ * while repeated initial probing is enabled.
95
+ */
96
+ int64_t repeatedInitialProbingTimePeriodUs{ 5 * 1000 * 1000 };
97
+ /**
98
+ * How long each of those initial bursts lasts. It's longer than a usual
99
+ * one because there is no traffic yet to measure against.
100
+ */
101
+ int64_t initialProbeDurationUs{ 100 * 1000 };
102
+ /**
103
+ * Time between two consecutive bursts of packets within one of those
104
+ * initial probes.
105
+ *
106
+ * @remarks
107
+ * - It cannot be zero, since it's what the bitrate of a burst is held
108
+ * over to decide how many bytes each of its shots carries.
109
+ */
110
+ int64_t initialMinProbeDeltaUs{ 20 * 1000 };
111
+ /**
112
+ * How often to probe while the sender is not filling the link.
113
+ */
114
+ int64_t alrProbingIntervalUs{ 5 * 1000 * 1000 };
115
+ /**
116
+ * Factor applied to the estimate for those bursts.
117
+ */
118
+ double alrProbeScale{ 2.0 };
119
+ /**
120
+ * How often to probe while an upper bound of the link capacity is known,
121
+ * or no limit at all to never do it, which is what turns that whole path
122
+ * off.
123
+ */
124
+ int64_t networkStateEstimateProbingIntervalUs{ Types::TimeUsInfinite };
125
+ /**
126
+ * Fraction of that upper bound below which the estimate is low enough to
127
+ * keep probing periodically.
128
+ */
129
+ double probeIfEstimateLowerThanNetworkStateEstimateRatio{ 0.0 };
130
+ /**
131
+ * How often to probe while the estimate is that low.
132
+ */
133
+ int64_t estimateLowerThanNetworkStateEstimateProbingIntervalUs{ 3 * 1000 * 1000 };
134
+ /**
135
+ * Factor applied to that upper bound when it's what bounds the burst.
136
+ */
137
+ double networkStateProbeScale{ 1.0 };
138
+ /**
139
+ * How long a burst lasts when that upper bound is known and is above
140
+ * what the burst aims for.
141
+ */
142
+ int64_t networkStateProbeDurationUs{ 15 * 1000 };
143
+ /**
144
+ * Time between two consecutive bursts of packets in that case.
145
+ *
146
+ * @remarks
147
+ * - It cannot be zero, since it's what the bitrate of a burst is held
148
+ * over to decide how many bytes each of its shots carries.
149
+ */
150
+ int64_t networkStateMinProbeDeltaUs{ 20 * 1000 };
151
+ /**
152
+ * Whether to probe when the application raises how much it wants to
153
+ * send.
154
+ */
155
+ bool probeOnMaxAllocatedBitrateChange{ true };
156
+ /**
157
+ * Whether to do it also while the sender is filling the link.
158
+ */
159
+ bool probeOnMaxAllocatedBitrateChangeWithoutAlr{ true };
160
+ /**
161
+ * Factor applied to what the application asks for, for the first of
162
+ * those bursts, or no value to send none.
163
+ */
164
+ std::optional<double> firstAllocationProbeScale{ 1.0 };
165
+ /**
166
+ * The same for the second one, or no value to send just one.
167
+ */
168
+ std::optional<double> secondAllocationProbeScale{ 2.0 };
169
+ /**
170
+ * Factor applied to the current estimate, which is how far above it
171
+ * those bursts are allowed to aim.
172
+ */
173
+ double allocationProbeLimitByCurrentScale{ 2.0 };
174
+ /**
175
+ * Packets a burst is meant to be made of.
176
+ */
177
+ int64_t minProbePacketsSent{ 5 };
178
+ /**
179
+ * How long a burst lasts.
180
+ */
181
+ int64_t minProbeDurationUs{ 15 * 1000 };
182
+ /**
183
+ * Time between two consecutive bursts of packets within a probe.
184
+ *
185
+ * @remarks
186
+ * - It cannot be zero, since it's what the bitrate of a burst is held
187
+ * over to decide how many bytes each of its shots carries.
188
+ */
189
+ int64_t minProbeDeltaUs{ 2 * 1000 };
190
+ /**
191
+ * Factor applied to the estimate that bounds a burst while loss is what
192
+ * limits it and it's growing back.
193
+ */
194
+ double lossLimitedProbeScale{ 1.5 };
195
+ /**
196
+ * Fraction of the maximum above which the estimate is already high
197
+ * enough for a burst to be pointless. Zero never skips one.
198
+ */
199
+ double skipIfEstimateLargerThanFractionOfMax{ 0.0 };
200
+ /**
201
+ * Factor applied to what the application asks for when deciding that.
202
+ */
203
+ double skipProbeMaxAllocatedScale{ 1.0 };
204
+ /**
205
+ * Whether a large drop may be probed even while the sender is filling
206
+ * the link.
207
+ */
208
+ bool rapidRecoveryExperiment{ false };
209
+ };
210
+
211
+ private:
212
+ /**
213
+ * Where the climbing that follows the first burst of a connection is.
214
+ */
215
+ enum class State : uint8_t
216
+ {
217
+ /**
218
+ * Nothing has been probed yet.
219
+ */
220
+ INIT,
221
+ /**
222
+ * A burst went out and its result decides whether another one follows.
223
+ */
224
+ WAITING_FOR_PROBING_RESULT,
225
+ /**
226
+ * There is nothing left to climb.
227
+ */
228
+ PROBING_COMPLETE
229
+ };
230
+
231
+ public:
232
+ ProbeController();
233
+
234
+ explicit ProbeController(ProbeControllerOptions options);
235
+
236
+ /**
237
+ * Bounds set by the application, plus the bitrate to start from.
238
+ *
239
+ * @param maxBitrate - `Types::BitrateInfinite` for no limit, in which case
240
+ * the highest bitrate that may be probed applies instead.
241
+ */
242
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> SetBitrates(
243
+ int64_t minBitrate, int64_t startBitrate, int64_t maxBitrate, int64_t nowUs);
244
+
245
+ /**
246
+ * Total of what the application wants to send, which is not the same as
247
+ * the maximum it allows: it's the sum over the streams being sent.
248
+ */
249
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> OnMaxTotalAllocatedBitrate(
250
+ int64_t maxTotalAllocatedBitrate, int64_t nowUs);
251
+
252
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> OnNetworkAvailability(
253
+ bool networkAvailable, int64_t nowUs);
254
+
255
+ /**
256
+ * Feed the current estimate and what is holding it back.
257
+ */
258
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> SetEstimatedBitrate(
259
+ int64_t bitrate, BandwidthLimitedCause bandwidthLimitedCause, int64_t nowUs);
260
+
261
+ void EnablePeriodicAlrProbing(bool enable)
262
+ {
263
+ this->enablePeriodicAlrProbing = enable;
264
+ }
265
+
266
+ /**
267
+ * Whether the initial bursts keep being repeated for a while, which only
268
+ * makes sense until there is traffic of its own to measure.
269
+ */
270
+ void EnableRepeatedInitialProbing(bool enable)
271
+ {
272
+ this->repeatedInitialProbingEnabled = enable;
273
+ }
274
+
275
+ void SetAlrStartTimeUs(std::optional<int64_t> alrStartTimeUs)
276
+ {
277
+ this->alrStartTimeUs = alrStartTimeUs;
278
+ }
279
+
280
+ void SetAlrEndedTimeUs(int64_t alrEndedTimeUs)
281
+ {
282
+ this->alrEndedTimeUs = alrEndedTimeUs;
283
+ }
284
+
285
+ /**
286
+ * Ask for a burst after the estimate has come back up from a large drop,
287
+ * to tell a real drop from a passing one.
288
+ */
289
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> RequestProbe(int64_t nowUs);
290
+
291
+ /**
292
+ * Upper bound of the link capacity as measured elsewhere (bps), which
293
+ * bounds what a burst may aim for.
294
+ *
295
+ * @remarks
296
+ * - `Types::BitrateInfinite` means that nothing measured it, which is what
297
+ * the link capacity estimator answers while it has no estimate, and is
298
+ * kept as no bound at all rather than as an enormous one.
299
+ */
300
+ void SetLinkCapacityUpperBound(int64_t linkCapacityUpperBound)
301
+ {
302
+ this->linkCapacityUpperBound = linkCapacityUpperBound != Types::BitrateInfinite
303
+ ? std::optional<int64_t>(linkCapacityUpperBound)
304
+ : std::nullopt;
305
+ }
306
+
307
+ /**
308
+ * Forget what was probed, leaving the settings alone, so that the climbing
309
+ * of a new connection starts over.
310
+ */
311
+ void Reset(int64_t nowUs);
312
+
313
+ /**
314
+ * Reconsider whether a burst is due, which is what drives the periodic
315
+ * ones.
316
+ */
317
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> Process(int64_t nowUs);
318
+
319
+ private:
320
+ void UpdateState(State newState);
321
+
322
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> InitiateExponentialProbing(int64_t nowUs);
323
+
324
+ /**
325
+ * Turn the given bitrates into bursts, bounding them by everything that
326
+ * applies and refusing them altogether while something is known to be
327
+ * holding the estimate back.
328
+ *
329
+ * @param probeFurther - Whether the result of these bursts may lead to
330
+ * another one.
331
+ */
332
+ [[nodiscard]] std::vector<Types::ProbeClusterConfig> InitiateProbing(
333
+ int64_t nowUs, const std::vector<int64_t>& bitratesToProbe, bool probeFurther);
334
+
335
+ bool IsTimeForAlrProbe(int64_t nowUs) const;
336
+
337
+ bool IsTimeForNetworkStateProbe(int64_t nowUs) const;
338
+
339
+ bool IsTimeForNextRepeatedInitialProbe(int64_t nowUs) const;
340
+
341
+ Types::ProbeClusterConfig CreateProbeClusterConfig(int64_t nowUs, int64_t bitrate);
342
+
343
+ private:
344
+ // Passed by argument.
345
+ const ProbeControllerOptions options;
346
+ // Others.
347
+ State state{ State::INIT };
348
+ bool networkAvailable{ false };
349
+ bool repeatedInitialProbingEnabled{ false };
350
+ bool enablePeriodicAlrProbing{ false };
351
+ BandwidthLimitedCause bandwidthLimitedCause{ BandwidthLimitedCause::DELAY_BASED_LIMITED };
352
+ // Instant until which the initial bursts keep being repeated.
353
+ std::optional<int64_t> lastAllowedRepeatedInitialProbeAtUs;
354
+ // Bitrate a burst has to beat for another one to follow it, or
355
+ // `Types::BitrateInfinite` while nothing is to follow.
356
+ int64_t minBitrateToProbeFurther{ Types::BitrateInfinite };
357
+ std::optional<int64_t> lastProbingInitiatedAtUs;
358
+ int64_t estimatedBitrate{ 0 };
359
+ // Upper bound of the link capacity as measured elsewhere, or no value
360
+ // while nothing measured it.
361
+ std::optional<int64_t> linkCapacityUpperBound;
362
+ int64_t startBitrate{ 0 };
363
+ int64_t maxBitrate{ Types::BitrateInfinite };
364
+ std::optional<int64_t> lastBweDropProbingAtUs;
365
+ std::optional<int64_t> alrStartTimeUs;
366
+ std::optional<int64_t> alrEndedTimeUs;
367
+ // Instant of the latest large drop of the estimate, and what it was worth
368
+ // just before it.
369
+ std::optional<int64_t> lastLargeDropAtUs;
370
+ int64_t bitrateBeforeLastLargeDrop{ 0 };
371
+ // Total of what the application wants to send.
372
+ int64_t maxTotalAllocatedBitrate{ 0 };
373
+ // Id given to the next burst, which never repeats.
374
+ int64_t nextProbeClusterId{ 1 };
375
+ };
376
+ } // namespace BWE
377
+ } // namespace RTC
378
+
379
+ #endif
@@ -0,0 +1,130 @@
1
+ #ifndef MS_RTC_BWE_PROBE_PACKET_GENERATOR_HPP
2
+ #define MS_RTC_BWE_PROBE_PACKET_GENERATOR_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/RTP/Packet.hpp"
6
+ #include <array>
7
+
8
+ namespace RTC
9
+ {
10
+ namespace BWE
11
+ {
12
+ /**
13
+ * Makes the RTP packets a probing burst is made of.
14
+ *
15
+ * A burst asks for a number of bytes to be put on the wire over a few
16
+ * milliseconds, and those bytes have to travel as RTP so that the receiver
17
+ * reports when each of them arrived. This turns the bytes into packets and
18
+ * hands them over one by one.
19
+ *
20
+ * What it produces is a stream of its own that carries nothing: a fixed SSRC
21
+ * the receiver has negotiated, a payload of zeroes that nothing decodes, and
22
+ * the header extensions that make the packets reportable. The only thing ever
23
+ * read back from them is when each one arrived.
24
+ */
25
+ class ProbePacketGenerator
26
+ {
27
+ public:
28
+ class Listener
29
+ {
30
+ public:
31
+ virtual ~Listener() = default;
32
+
33
+ public:
34
+ /**
35
+ * A packet of the burst is ready.
36
+ *
37
+ * @returns Whether the rest of the burst is still wanted, so that a
38
+ * packet that couldn't be sent stops the ones behind it.
39
+ *
40
+ * @remarks
41
+ * - The packet must be sent before returning, since the next one is
42
+ * built over the very same instance.
43
+ * - It carries room for the abs-send-time and for the transport wide
44
+ * sequence number but no value for either, so both have to be written
45
+ * here.
46
+ * - Whoever measures the burst has to be told how much of it went out,
47
+ * so the length of the packet is reported from here as well.
48
+ * - This must not destroy the `ProbePacketGenerator`, not even
49
+ * indirectly. It goes on reading its own members after this returns,
50
+ * so returning false is no way out of it either.
51
+ */
52
+ virtual bool OnProbePacketGeneratorSendRtpPacket(
53
+ ProbePacketGenerator* probePacketGenerator, RTC::RTP::Packet* packet) = 0;
54
+ };
55
+
56
+ #ifdef MS_TEST
57
+ public:
58
+ #else
59
+ private:
60
+ #endif
61
+ /**
62
+ * Largest a packet of a burst may be (bytes), which leaves room below the
63
+ * MTU for the overhead that encrypting it adds on the way out.
64
+ */
65
+ static constexpr size_t MaxPacketLength{ 1400 };
66
+
67
+ /**
68
+ * Most bytes a single burst may be asked for (bytes), so 2.5 MB, which is
69
+ * 1 Gbps held for 20 ms.
70
+ *
71
+ * @remarks
72
+ * - A burst larger than this is taken as one that cannot be real, and
73
+ * asking for it would have this handing packets over for a very long
74
+ * while, all within a single iteration of the event loop.
75
+ * - Those two are the highest bitrate the bandwidth estimation deals in
76
+ * and the longest time whoever asks for a burst leaves between two of
77
+ * its shots, neither of which this can enforce.
78
+ */
79
+ static constexpr size_t MaxGeneratePacketsSize{ 2500000 };
80
+
81
+ public:
82
+ explicit ProbePacketGenerator(Listener* listener);
83
+
84
+ ~ProbePacketGenerator() = default;
85
+
86
+ // NOTE: The packet is written over a buffer of this very instance, so one
87
+ // that was copied or moved would keep writing over the buffer of the one
88
+ // it came from.
89
+ ProbePacketGenerator(const ProbePacketGenerator&) = delete;
90
+ ProbePacketGenerator& operator=(const ProbePacketGenerator&) = delete;
91
+
92
+ /**
93
+ * Smallest packet this can make (bytes), which is its header and its
94
+ * extensions and no payload at all.
95
+ */
96
+ size_t GetMinPacketLength() const
97
+ {
98
+ return this->minPacketLength;
99
+ }
100
+
101
+ /**
102
+ * Hand over the packets that carry the given count of bytes.
103
+ *
104
+ * @remarks
105
+ * - What goes out is at least what was asked for, since a burst falling
106
+ * short of the bytes it was meant to carry measures something else, and
107
+ * the last packet can't be smaller than a header.
108
+ */
109
+ void GeneratePackets(size_t size);
110
+
111
+ private:
112
+ // Passed by argument.
113
+ Listener* listener{ nullptr };
114
+ // Others.
115
+ // Bytes the packet is written over. It belongs to this instance rather
116
+ // than being shared, since the packet's header lives in it and the
117
+ // sequence number of the next packet is read back from there. The empty
118
+ // braces zero it, so the payload never carries whatever was in that
119
+ // memory before.
120
+ std::array<uint8_t, MaxPacketLength> packetBuffer{};
121
+ // Allocated by this.
122
+ std::unique_ptr<RTC::RTP::Packet> packet;
123
+ // Length of the packet with no payload at all, so its header and its
124
+ // extensions.
125
+ size_t minPacketLength{ 0 };
126
+ };
127
+ } // namespace BWE
128
+ } // namespace RTC
129
+
130
+ #endif