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,625 @@
1
+ #ifndef MS_RTC_BWE_LOSS_BASED_CONTROLLER_HPP
2
+ #define MS_RTC_BWE_LOSS_BASED_CONTROLLER_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/BweTypes.hpp"
6
+ #include <ankerl/unordered_dense.h>
7
+ #include <vector>
8
+
9
+ namespace RTC
10
+ {
11
+ namespace BWE
12
+ {
13
+ /**
14
+ * Tells the loss caused by congestion from the loss a link has by itself.
15
+ *
16
+ * A link can lose packets without being congested at all, which is the normal
17
+ * state of Wi-Fi and mobile links, and reacting to that loss by sending less
18
+ * doesn't reduce it: it just gives away capacity that was there. Telling both
19
+ * apart cannot be done by looking at a loss figure, because the very same
20
+ * figure means different things at different sending rates.
21
+ *
22
+ * So instead of a rule on the reported loss, this is an estimator of two
23
+ * values that together describe the link: how much it loses when it is not
24
+ * congested, and how much it can carry. With those two, the loss to expect
25
+ * from an observation is known: the inherent one while sending below the
26
+ * capacity, plus the share of the excess while sending above it. The pair of
27
+ * values that makes the losses actually observed most likely is the estimate,
28
+ * and the bitrate of that pair is the answer.
29
+ *
30
+ * Candidates slightly above, at and below the current estimate are tried on
31
+ * every update, each refined by a step of Newton's method on the inherent
32
+ * loss, and the most likely one wins. A bias towards higher bitrates keeps
33
+ * the estimate from settling low when the observations cannot tell them
34
+ * apart, and fades away as the observed loss grows.
35
+ *
36
+ * @remarks
37
+ * - This class is a port of the LossBasedBweV2 class in libwebrtc (renamed to
38
+ * a better name).
39
+ */
40
+ class LossBasedController
41
+ {
42
+ public:
43
+ /**
44
+ * @remarks
45
+ * - Every constraint documented below is checked by the constructor and
46
+ * aborts when it doesn't hold. These options are set from C++ alone,
47
+ * never from the network nor from the API, so breaking one of them is a
48
+ * programming error.
49
+ */
50
+ struct LossBasedControllerOptions
51
+ {
52
+ /**
53
+ * Factors applied to the current estimate to build the candidates that
54
+ * are tried on every update.
55
+ *
56
+ * @remarks
57
+ * - Every factor must be positive.
58
+ * - At least one candidate other than the current estimate has to be
59
+ * reachable, so unless `appendAcknowledgedRateCandidate` or
60
+ * `appendDelayBasedEstimateCandidate` is set, one of these factors
61
+ * must differ from 1.
62
+ */
63
+ std::vector<double> candidateFactors{ 1.02, 1.0, 0.95 };
64
+ /**
65
+ * How much the estimate may grow over the acknowledged bitrate while
66
+ * the link is loss limited.
67
+ *
68
+ * @remarks
69
+ * - It must be greater than 1, since it's a bound above that bitrate.
70
+ */
71
+ double bitrateRampupUpperBoundFactor{ 1.5 };
72
+ /**
73
+ * The same while the estimate is being held, which is more conservative
74
+ * because holding means that a higher bitrate already caused loss.
75
+ *
76
+ * @remarks
77
+ * - It must be greater than 1, for the same reason.
78
+ */
79
+ double bitrateRampupUpperBoundFactorInHold{ 1.2 };
80
+ /**
81
+ * How far below the held bitrate the acknowledged one has to be for the
82
+ * factor above to be the one applied.
83
+ *
84
+ * @remarks
85
+ * - It must not be negative.
86
+ */
87
+ double bitrateRampupHoldThreshold{ 1.3 };
88
+ /**
89
+ * How much of the acknowledged bitrate the estimate may grow by on top
90
+ * of its usual bound, the longer the more time has passed since it was
91
+ * last reduced. Zero disables that acceleration.
92
+ *
93
+ * @remarks
94
+ * - It must not be negative.
95
+ */
96
+ double rampupAccelerationMaxFactor{ 0.0 };
97
+ /**
98
+ * Time since the last reduction at which that acceleration is at its
99
+ * fullest.
100
+ *
101
+ * @remarks
102
+ * - It must be positive, since it's what the elapsed time is measured
103
+ * against.
104
+ */
105
+ int64_t rampupAccelerationMaxoutTimeUs{ 60 * 1000 * 1000 };
106
+ /**
107
+ * Weight given to a higher bitrate when choosing among candidates, so
108
+ * that observations which cannot tell them apart don't settle low.
109
+ *
110
+ * @remarks
111
+ * - It must not be negative.
112
+ */
113
+ double higherBitrateBiasFactor{ 0.0002 };
114
+ /**
115
+ * The same, applied to the logarithm of the bitrate, so that the bias
116
+ * doesn't grow without bound.
117
+ */
118
+ double higherLogBitrateBiasFactor{ 0.02 };
119
+ /**
120
+ * Observed loss at which the bias above is gone, since at that much loss
121
+ * preferring a higher bitrate is not defensible anymore.
122
+ *
123
+ * @remarks
124
+ * - Being a loss rate, it must be in [0, 1).
125
+ */
126
+ double lossThresholdOfHighBitratePreference{ 0.2 };
127
+ /**
128
+ * How abruptly that bias fades as the observed loss approaches the
129
+ * threshold above.
130
+ *
131
+ * @remarks
132
+ * - It must be in (0, 1]. Zero is excluded because it divides.
133
+ */
134
+ double bitratePreferenceSmoothingFactor{ 0.002 };
135
+ /**
136
+ * Lowest inherent loss that may be estimated for a link.
137
+ *
138
+ * @remarks
139
+ * - Being a loss rate, it must be in [0, 1).
140
+ */
141
+ double inherentLossLowerBound{ 1.0e-3 };
142
+ /**
143
+ * Inherent loss that may be estimated at an unbounded bitrate, which
144
+ * grows as the bitrate gets lower by the balance below.
145
+ *
146
+ * @remarks
147
+ * - It must be below 1 and never below `inherentLossLowerBound`, since
148
+ * the two of them are the ends of the same range.
149
+ */
150
+ double inherentLossUpperBoundOffset{ 0.05 };
151
+ /**
152
+ * Bitrate at which the inherent loss upper bound grows by one, so that a
153
+ * low bitrate is allowed to be explained by a lossy link.
154
+ *
155
+ * @remarks
156
+ * - It must be positive, since it divides.
157
+ */
158
+ int64_t inherentLossUpperBoundBitrateBalance{ 100000 };
159
+ /**
160
+ * Inherent loss assumed before anything has been observed.
161
+ *
162
+ * @remarks
163
+ * - Being a loss rate, it must be in [0, 1).
164
+ */
165
+ double initialInherentLossEstimate{ 0.01 };
166
+ /**
167
+ * Steps of Newton's method applied to each candidate.
168
+ *
169
+ * @remarks
170
+ * - It must be positive, or no candidate would ever be refined.
171
+ */
172
+ int64_t newtonIterations{ 1 };
173
+ /**
174
+ * Fraction of the step that each of those iterations takes.
175
+ *
176
+ * @remarks
177
+ * - It must be positive, or each iteration would stand still.
178
+ */
179
+ double newtonStepSize{ 0.75 };
180
+ /**
181
+ * Whether the acknowledged bitrate is tried as a candidate of its own.
182
+ *
183
+ * @remarks
184
+ * - See the constraint on `candidateFactors` about there always being a
185
+ * candidate to choose from.
186
+ */
187
+ bool appendAcknowledgedRateCandidate{ true };
188
+ /**
189
+ * Whether the delay based estimate is tried as a candidate of its own
190
+ * while it's above the current one.
191
+ *
192
+ * @remarks
193
+ * - The same constraint as `appendAcknowledgedRateCandidate`.
194
+ */
195
+ bool appendDelayBasedEstimateCandidate{ true };
196
+ /**
197
+ * Whether the bound that the observed loss puts on the estimate is tried
198
+ * as a candidate while not filling the link, which lets the estimate
199
+ * come down to it in one step instead of gradually.
200
+ */
201
+ bool appendUpperBoundCandidateInAlr{ false };
202
+ /**
203
+ * Shortest span of send times that an observation may cover.
204
+ *
205
+ * @remarks
206
+ * - It must be positive, or every packet would close an observation.
207
+ */
208
+ int64_t observationDurationLowerBoundUs{ 250 * 1000 };
209
+ /**
210
+ * Observations kept, which is how far back the estimate looks.
211
+ *
212
+ * @remarks
213
+ * - It must be at least 2. It's also what every observation is indexed
214
+ * modulo, so an empty window would divide by zero.
215
+ */
216
+ int64_t observationWindowSize{ 15 };
217
+ /**
218
+ * Observations needed before this controller may be used at all.
219
+ *
220
+ * @remarks
221
+ * - It must be positive, or the controller would take the estimate over
222
+ * having observed nothing.
223
+ */
224
+ int64_t minNumObservations{ 3 };
225
+ /**
226
+ * How much the sending rate of an observation is smoothed with the one
227
+ * of the previous observation.
228
+ *
229
+ * @remarks
230
+ * - It must be in [0, 1).
231
+ * - Zero means no smoothing at all, which is what libwebrtc does. A
232
+ * sender of a couple of streams has a sending rate that only changes
233
+ * when it decides so, while ours is the sum of many streams whose
234
+ * makeup changes on its own, and those changes are not the network.
235
+ */
236
+ double sendingRateSmoothingFactor{ 0.0 };
237
+ /**
238
+ * How much weight each observation loses per observation of age when
239
+ * looking for the most likely pair of values.
240
+ *
241
+ * @remarks
242
+ * - It must be in (0, 1]. One means that age doesn't weigh at all, and
243
+ * zero is excluded because it would leave every observation but the
244
+ * latest one weightless.
245
+ */
246
+ double temporalWeightFactor{ 0.9 };
247
+ /**
248
+ * The same, for the average observed loss that bounds the estimate right
249
+ * away.
250
+ *
251
+ * @remarks
252
+ * - It must be in (0, 1], for the same reason.
253
+ */
254
+ double immediateUpperBoundTemporalWeightFactor{ 0.9 };
255
+ /**
256
+ * Observed loss under which no immediate upper bound is applied.
257
+ *
258
+ * @remarks
259
+ * - Being a loss rate, it must be in [0, 1).
260
+ */
261
+ double immediateUpperBoundLossOffset{ 0.05 };
262
+ /**
263
+ * Bitrate the immediate upper bound allows per unit of observed loss
264
+ * over the offset above.
265
+ *
266
+ * @remarks
267
+ * - It must be positive, since it multiplies a bound that would
268
+ * otherwise collapse to nothing.
269
+ */
270
+ int64_t immediateUpperBoundBitrateBalance{ 100000 };
271
+ /**
272
+ * How much of the acknowledged bitrate the estimate may never go below.
273
+ *
274
+ * @remarks
275
+ * - It must not be negative.
276
+ */
277
+ double lowerBoundByAckedRateFactor{ 1.0 };
278
+ /**
279
+ * Fraction of the acknowledged bitrate taken as a candidate when backing
280
+ * off.
281
+ *
282
+ * @remarks
283
+ * - It must not be greater than 1, since backing off to more than what
284
+ * is acknowledged is not backing off.
285
+ */
286
+ double bitrateBackoffLowerBoundFactor{ 1.0 };
287
+ /**
288
+ * How much the estimate may grow within the window that follows a
289
+ * decrease.
290
+ *
291
+ * @remarks
292
+ * - It must be positive.
293
+ */
294
+ double maxIncreaseFactor{ 1.3 };
295
+ /**
296
+ * How long that window lasts.
297
+ *
298
+ * @remarks
299
+ * - It must be positive.
300
+ */
301
+ int64_t delayedIncreaseWindowUs{ 300 * 1000 };
302
+ /**
303
+ * Whether the estimate is held back while the loss observed is worse
304
+ * than the one the chosen candidate says the link has by itself, since
305
+ * then the excess is ours to fix.
306
+ */
307
+ bool notIncreaseIfInherentLossLessThanAverageLoss{ true };
308
+ /**
309
+ * Whether the acknowledged bitrate stops being a candidate while not
310
+ * filling the link, since then what it delivers says nothing about what
311
+ * it could deliver.
312
+ */
313
+ bool notUseAckedRateInAlr{ true };
314
+ /**
315
+ * Whether this controller may take the estimate over while the target is
316
+ * still in its start phase.
317
+ */
318
+ bool useInStartPhase{ true };
319
+ /**
320
+ * How much each hold lasts compared to the previous one, which makes
321
+ * repeated failures to increase back off for longer.
322
+ */
323
+ double holdDurationFactor{ 2.0 };
324
+ /**
325
+ * Whether loss is measured in bytes rather than in packets, which tells
326
+ * a lost packet of a full frame apart from a lost one carrying almost
327
+ * nothing.
328
+ */
329
+ bool useByteLossRate{ true };
330
+ /**
331
+ * Whether an estimate that had to be brought down to its bounds stops
332
+ * being kept as a description of the link.
333
+ */
334
+ bool boundBestCandidate{ true };
335
+ /**
336
+ * How much the sending rate of an observation has to exceed the median
337
+ * of the window for its loss to be taken at face value instead of as a
338
+ * spike.
339
+ */
340
+ double medianSendingRateFactor{ 2.0 };
341
+ };
342
+
343
+ /**
344
+ * What this controller is doing with the estimate, which the orchestrator
345
+ * needs in order to decide whether to probe.
346
+ */
347
+ enum class State : uint8_t
348
+ {
349
+ /**
350
+ * The link is loss limited and the estimate is growing back.
351
+ */
352
+ INCREASING,
353
+ /**
354
+ * The link is loss limited and the estimate is being reduced.
355
+ */
356
+ DECREASING,
357
+ /**
358
+ * The link is not loss limited, so the delay based estimate rules.
359
+ */
360
+ DELAY_BASED_ESTIMATE
361
+ };
362
+
363
+ struct Result
364
+ {
365
+ int64_t bitrate{ 0 };
366
+ State state{ State::DELAY_BASED_ESTIMATE };
367
+ };
368
+
369
+ private:
370
+ /**
371
+ * The pair of values that describe a link.
372
+ */
373
+ struct ChannelParameters
374
+ {
375
+ /**
376
+ * Loss the link has while not congested at all.
377
+ */
378
+ double inherentLoss{ 0.0 };
379
+ /**
380
+ * Bitrate the link can carry, or zero while it's not known yet.
381
+ */
382
+ int64_t lossLimitedBitrate{ 0 };
383
+ };
384
+
385
+ /**
386
+ * First and second derivatives of the likelihood with respect to the
387
+ * inherent loss, which is what Newton's method needs.
388
+ */
389
+ struct Derivatives
390
+ {
391
+ double first{ 0.0 };
392
+ double second{ 0.0 };
393
+ };
394
+
395
+ /**
396
+ * What was sent and lost over a span of send times, which is the unit this
397
+ * controller reasons about.
398
+ */
399
+ struct Observation
400
+ {
401
+ bool IsInitialized() const
402
+ {
403
+ return this->id != -1;
404
+ }
405
+
406
+ int64_t numPackets{ 0 };
407
+ int64_t numLostPackets{ 0 };
408
+ int64_t numReceivedPackets{ 0 };
409
+ int64_t sendingRate{ 0 };
410
+ int64_t sizeBytes{ 0 };
411
+ int64_t lostSizeBytes{ 0 };
412
+ int64_t id{ -1 };
413
+ };
414
+
415
+ /**
416
+ * Feedback accumulated so far, which becomes an observation once it covers
417
+ * a long enough span of send times.
418
+ */
419
+ struct PartialObservation
420
+ {
421
+ /**
422
+ * Size of the packets reported as lost, by sequence number, so that a
423
+ * packet reported lost and received later stops counting.
424
+ */
425
+ ankerl::unordered_dense::map<int64_t, int64_t> lostPackets;
426
+ int64_t numPackets{ 0 };
427
+ int64_t sizeBytes{ 0 };
428
+ };
429
+
430
+ /**
431
+ * The bitrate the estimate is not allowed to grow above while holding, and
432
+ * for how long.
433
+ */
434
+ struct HoldInfo
435
+ {
436
+ int64_t atUs{ 0 };
437
+ int64_t durationUs{ 0 };
438
+ int64_t bitrate{ Types::BitrateInfinite };
439
+ };
440
+
441
+ public:
442
+ LossBasedController();
443
+
444
+ explicit LossBasedController(LossBasedControllerOptions options);
445
+
446
+ /**
447
+ * Whether enough has been observed for this controller to say anything.
448
+ */
449
+ bool IsReady() const;
450
+
451
+ /**
452
+ * Whether this controller may take the estimate over while the target is
453
+ * still in its start phase.
454
+ */
455
+ bool IsReadyToUseInStartPhase() const;
456
+
457
+ /**
458
+ * Whether this controller is allowed to be used during the start phase at
459
+ * all, regardless of whether it has observed enough to say anything.
460
+ */
461
+ bool IsUsedInStartPhase() const
462
+ {
463
+ return this->options.useInStartPhase;
464
+ }
465
+
466
+ /**
467
+ * Forget everything observed so far, which is what a link that is not the
468
+ * same one anymore calls for.
469
+ */
470
+ void Reset();
471
+
472
+ /**
473
+ * Latest estimate, or the delay based one while this controller cannot say
474
+ * anything yet.
475
+ */
476
+ Result GetResult() const;
477
+
478
+ void SetAcknowledgedBitrate(int64_t acknowledgedBitrate);
479
+
480
+ void SetBitrateLimits(int64_t minBitrate, int64_t maxBitrate);
481
+
482
+ /**
483
+ * Place the estimate at the given bitrate.
484
+ */
485
+ void SetBitrateEstimate(int64_t bitrate);
486
+
487
+ /**
488
+ * Feed the results of a feedback message.
489
+ *
490
+ * @param delayBasedEstimate - Estimate of the delay based path, which
491
+ * bounds this one, or `Types::BitrateInfinite` if there is none.
492
+ * @param inAlr - Whether the sender is not sending enough to fill the link,
493
+ * in which case the acknowledged bitrate says nothing about its capacity.
494
+ */
495
+ void UpdateBitrateEstimate(
496
+ const std::vector<Types::PacketResult>& packetResults, int64_t delayBasedEstimate, bool inAlr);
497
+
498
+ private:
499
+ /**
500
+ * Add the given results to the observation being accumulated, and close it
501
+ * if it already covers a long enough span of send times.
502
+ *
503
+ * @returns Whether an observation was closed, which is when the estimate
504
+ * can be recalculated.
505
+ */
506
+ bool PushBackObservation(const std::vector<Types::PacketResult>& packetResults);
507
+
508
+ /**
509
+ * Candidates to try on this update, each already within bounds.
510
+ */
511
+ std::vector<ChannelParameters> GetCandidates(bool inAlr) const;
512
+
513
+ /**
514
+ * Highest bitrate a candidate may have.
515
+ */
516
+ int64_t GetCandidateBitrateUpperBound() const;
517
+
518
+ /**
519
+ * How likely the losses observed are if the link were as the given pair of
520
+ * values says, plus the bias towards higher bitrates.
521
+ */
522
+ double GetObjective(const ChannelParameters& channelParameters) const;
523
+
524
+ Derivatives GetDerivatives(const ChannelParameters& channelParameters) const;
525
+
526
+ /**
527
+ * Refine the inherent loss of the given candidate.
528
+ */
529
+ void ApplyNewtonsMethod(ChannelParameters& channelParameters) const;
530
+
531
+ /**
532
+ * Bring the inherent loss of the given candidate within what a link at its
533
+ * bitrate could plausibly have.
534
+ */
535
+ double GetFeasibleInherentLoss(const ChannelParameters& channelParameters) const;
536
+
537
+ double GetInherentLossUpperBound(int64_t bitrate) const;
538
+
539
+ double AdjustBiasFactor(double lossRate, double biasFactor) const;
540
+
541
+ double GetHighBitrateBias(int64_t bitrate) const;
542
+
543
+ /**
544
+ * Sending rate an observation is taken to have, which is its own smoothed
545
+ * with the one of the previous observation.
546
+ */
547
+ int64_t GetSendingRate(int64_t instantSendingRate) const;
548
+
549
+ /**
550
+ * Average loss observed over the window, leaving out the highest and the
551
+ * lowest so that a single spike doesn't drag it.
552
+ */
553
+ void UpdateAverageReportedLossRatio();
554
+
555
+ double CalculateAverageReportedPacketLossRatio() const;
556
+
557
+ /**
558
+ * The same by bytes, which tells a lost packet carrying a full frame apart
559
+ * from one carrying almost nothing.
560
+ */
561
+ double CalculateAverageReportedByteLossRatio() const;
562
+
563
+ int64_t GetMedianSendingRate() const;
564
+
565
+ /**
566
+ * Bound that the observed loss puts on the estimate right away, without
567
+ * waiting for it to converge.
568
+ */
569
+ int64_t GetImmediateUpperBoundBitrate() const;
570
+
571
+ void CalculateImmediateUpperBoundBitrate();
572
+
573
+ int64_t GetImmediateLowerBoundBitrate() const;
574
+
575
+ void CalculateImmediateLowerBoundBitrate();
576
+
577
+ void CalculateTemporalWeights();
578
+
579
+ /**
580
+ * Whether the link is loss limited at all, which is what tells this
581
+ * controller's estimate apart from just following the delay based one.
582
+ */
583
+ bool IsInLossLimitedState() const;
584
+
585
+ bool IsEstimateIncreasingWhenLossLimited(int64_t oldEstimate, int64_t newEstimate) const;
586
+
587
+ private:
588
+ // Passed by argument.
589
+ const LossBasedControllerOptions options;
590
+ // Others.
591
+ // Observations of the window, indexed by their id modulo its size.
592
+ std::vector<Observation> observations;
593
+ // Weight of an observation per observation of age.
594
+ std::vector<double> temporalWeights;
595
+ // The same, for the average observed loss.
596
+ std::vector<double> immediateUpperBoundTemporalWeights;
597
+ struct PartialObservation partialObservation;
598
+ struct ChannelParameters currentBestEstimate;
599
+ struct HoldInfo lastHoldInfo;
600
+ struct Result result;
601
+ // Observations closed so far, which never decreases and hence also gives
602
+ // the id of the next one.
603
+ int64_t numObservations{ 0 };
604
+ // Highest send time of the latest observation, which is the clock this
605
+ // controller runs on. Feedback is the only thing that moves it.
606
+ std::optional<int64_t> lastSendTimeOfLatestObservationUs;
607
+ double averageReportedLossRatio{ 0.0 };
608
+ int64_t acknowledgedBitrate{ Types::BitrateInfinite };
609
+ int64_t delayBasedEstimate{ Types::BitrateInfinite };
610
+ int64_t minBitrate{ 0 };
611
+ int64_t maxBitrate{ Types::BitrateInfinite };
612
+ std::optional<int64_t> immediateUpperBoundBitrate;
613
+ std::optional<int64_t> immediateLowerBoundBitrate;
614
+ // Bitrate the estimate may not grow above until the window that follows a
615
+ // decrease is over.
616
+ int64_t bitrateLimitInCurrentWindow{ Types::BitrateInfinite };
617
+ std::optional<int64_t> recoveringAfterLossAtUs;
618
+ // Instant at which the estimate was last brought down, which is what the
619
+ // rampup acceleration grows from.
620
+ std::optional<int64_t> lastBitrateReducedAtUs;
621
+ };
622
+ } // namespace BWE
623
+ } // namespace RTC
624
+
625
+ #endif
@@ -0,0 +1,71 @@
1
+ #ifndef MS_RTC_BWE_OVERUSE_DETECTOR_HPP
2
+ #define MS_RTC_BWE_OVERUSE_DETECTOR_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/BweTypes.hpp"
6
+
7
+ namespace RTC
8
+ {
9
+ namespace BWE
10
+ {
11
+ /**
12
+ * Decides whether the network is congested from how much the delay between
13
+ * groups of packets is growing.
14
+ *
15
+ * The trend it is given is compared against a threshold that adapts itself
16
+ * to the noise observed, and congestion is only declared once the condition
17
+ * has persisted, which is what keeps an isolated jitter spike from bringing
18
+ * the estimate down.
19
+ *
20
+ * @remarks
21
+ * - This is what the receiving side uses, paired with `OveruseEstimator`.
22
+ * The sending side has `TrendlineEstimator`, which does both jobs at once
23
+ * and shares this very threshold machinery.
24
+ */
25
+ class OveruseDetector
26
+ {
27
+ public:
28
+ OveruseDetector() = default;
29
+
30
+ ~OveruseDetector() = default;
31
+
32
+ OveruseDetector(const OveruseDetector&) = delete;
33
+ OveruseDetector& operator=(const OveruseDetector&) = delete;
34
+
35
+ /**
36
+ * Feed what the estimator makes of the latest pair of groups.
37
+ *
38
+ * @param offsetMs - Part of the delay between both groups that the traffic
39
+ * itself doesn't explain.
40
+ * @param sendDeltaMs - Time between the send times of both groups, which
41
+ * is how long this sample is worth.
42
+ * @param numOfDeltas - Number of samples that offset is based on.
43
+ * @param nowUs - Current time.
44
+ *
45
+ * @returns What the network is taken to be doing after this sample.
46
+ */
47
+ Types::BandwidthUsage Detect(
48
+ double offsetMs, double sendDeltaMs, int64_t numOfDeltas, int64_t nowUs);
49
+
50
+ Types::BandwidthUsage GetState() const
51
+ {
52
+ return this->state;
53
+ }
54
+
55
+ private:
56
+ void UpdateThreshold(double modifiedOffsetMs, int64_t nowUs);
57
+
58
+ private:
59
+ double threshold{ 12.5 };
60
+ std::optional<int64_t> lastThresholdUpdateAtUs;
61
+ double prevOffsetMs{ 0.0 };
62
+ // How long the trend has been above the threshold, or no value while it
63
+ // isn't.
64
+ std::optional<double> timeOverUsingMs;
65
+ int64_t overuseCounter{ 0 };
66
+ Types::BandwidthUsage state{ Types::BandwidthUsage::NORMAL };
67
+ };
68
+ } // namespace BWE
69
+ } // namespace RTC
70
+
71
+ #endif