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,110 @@
1
+ #include "common.hpp"
2
+ #include "RTC/BWE/AlrDetector.hpp"
3
+ #include "mocks/include/MockShared.hpp"
4
+ #include <catch2/catch_test_macros.hpp>
5
+ #include <memory>
6
+
7
+ SCENARIO("BWE AlrDetector", "[bwe][alrdetector]")
8
+ {
9
+ constexpr int64_t InitialTimeUs{ 1000 * 1000 };
10
+ constexpr int64_t EstimatedBitrate{ 300000 };
11
+ // Span each step of the simulated traffic covers.
12
+ constexpr int64_t StepUs{ 10 * 1000 };
13
+
14
+ int64_t nowUs{ InitialTimeUs };
15
+
16
+ mocks::MockShared shared(/*getTimeUs*/
17
+ [&nowUs]() -> int64_t
18
+ {
19
+ return nowUs;
20
+ });
21
+
22
+ // Send traffic at the given percentage of the estimated bitrate for the given
23
+ // span of time, in steps so that the detector sees a steady pace rather than
24
+ // one huge send.
25
+ const auto sendTraffic =
26
+ [&nowUs](RTC::BWE::AlrDetector& alrDetector, int64_t usagePercentage, int64_t durationUs) -> void
27
+ {
28
+ for (int64_t elapsedUs{ 0 }; elapsedUs < durationUs; elapsedUs += StepUs)
29
+ {
30
+ nowUs += StepUs;
31
+
32
+ const int64_t bytesSent = (EstimatedBitrate * usagePercentage * StepUs) / (100 * 8 * 1000000);
33
+
34
+ alrDetector.OnBytesSent(bytesSent, nowUs);
35
+ }
36
+ };
37
+
38
+ SECTION("the link stops being filled and starts being filled again")
39
+ {
40
+ RTC::BWE::AlrDetector alrDetector(std::addressof(shared));
41
+
42
+ alrDetector.SetEstimatedBitrate(EstimatedBitrate);
43
+
44
+ REQUIRE(!alrDetector.GetAlrStartTimeUs().has_value());
45
+
46
+ // Sending close to what the estimate allows is filling the link.
47
+ sendTraffic(alrDetector, /*usagePercentage*/ 90, /*durationUs*/ 1000 * 1000);
48
+
49
+ REQUIRE(!alrDetector.GetAlrStartTimeUs().has_value());
50
+
51
+ // Dropping to a fifth of it is not.
52
+ sendTraffic(alrDetector, /*usagePercentage*/ 20, /*durationUs*/ 1500 * 1000);
53
+
54
+ REQUIRE(alrDetector.GetAlrStartTimeUs().has_value());
55
+
56
+ // And going back to using the whole estimate ends it.
57
+ sendTraffic(alrDetector, /*usagePercentage*/ 100, /*durationUs*/ 4000 * 1000);
58
+
59
+ REQUIRE(!alrDetector.GetAlrStartTimeUs().has_value());
60
+ }
61
+
62
+ SECTION("a short burst doesn't end the state")
63
+ {
64
+ RTC::BWE::AlrDetector alrDetector(std::addressof(shared));
65
+
66
+ alrDetector.SetEstimatedBitrate(EstimatedBitrate);
67
+
68
+ REQUIRE(!alrDetector.GetAlrStartTimeUs().has_value());
69
+
70
+ sendTraffic(alrDetector, /*usagePercentage*/ 20, /*durationUs*/ 1000 * 1000);
71
+
72
+ REQUIRE(alrDetector.GetAlrStartTimeUs().has_value());
73
+
74
+ // Sending half again as much as the estimate allows, but only briefly, eats
75
+ // into the budget without emptying it.
76
+ sendTraffic(alrDetector, /*usagePercentage*/ 150, /*durationUs*/ 100 * 1000);
77
+
78
+ REQUIRE(alrDetector.GetAlrStartTimeUs().has_value());
79
+
80
+ // Sustained traffic is what ends it.
81
+ sendTraffic(alrDetector, /*usagePercentage*/ 100, /*durationUs*/ 3000 * 1000);
82
+
83
+ REQUIRE(!alrDetector.GetAlrStartTimeUs().has_value());
84
+ }
85
+
86
+ SECTION("a lower estimate keeps the state until the same traffic fills the link")
87
+ {
88
+ RTC::BWE::AlrDetector alrDetector(std::addressof(shared));
89
+
90
+ alrDetector.SetEstimatedBitrate(EstimatedBitrate);
91
+
92
+ REQUIRE(!alrDetector.GetAlrStartTimeUs().has_value());
93
+
94
+ sendTraffic(alrDetector, /*usagePercentage*/ 20, /*durationUs*/ 1000 * 1000);
95
+
96
+ REQUIRE(alrDetector.GetAlrStartTimeUs().has_value());
97
+
98
+ // An estimate falling doesn't end the state by itself, so that whoever
99
+ // decides to probe still sees it and can react to the drop.
100
+ alrDetector.SetEstimatedBitrate(EstimatedBitrate / 5);
101
+
102
+ REQUIRE(alrDetector.GetAlrStartTimeUs().has_value());
103
+
104
+ // It ends shortly after, because the very same traffic now fills a link
105
+ // that is believed to be five times smaller.
106
+ sendTraffic(alrDetector, /*usagePercentage*/ 50, /*durationUs*/ 1000 * 1000);
107
+
108
+ REQUIRE(!alrDetector.GetAlrStartTimeUs().has_value());
109
+ }
110
+ }
@@ -0,0 +1,418 @@
1
+ #include "common.hpp"
2
+ #include "RTC/BWE/BitrateProber.hpp"
3
+ #include "RTC/BWE/BweTypes.hpp"
4
+ #include <catch2/catch_test_macros.hpp>
5
+
6
+ SCENARIO("BWE BitrateProber", "[bwe][bitrateprober]")
7
+ {
8
+ // The clock starts well away from zero so that a mistake taking a time for a
9
+ // duration doesn't go unnoticed.
10
+ constexpr int64_t InitialTimeUs{ 100000000 };
11
+ constexpr size_t ProbeSize{ 1000 };
12
+
13
+ int64_t nowUs{ InitialTimeUs };
14
+
15
+ // What a bitrate held for the given time carries, rounded rather than
16
+ // truncated, which is what decides the bytes a burst is meant to be made of.
17
+ const auto bytesFor = [](int64_t bitrate, int64_t durationUs) -> size_t
18
+ {
19
+ return static_cast<size_t>(((bitrate * durationUs) + 4000000) / (8 * 1000000));
20
+ };
21
+
22
+ const auto makeClusterConfig = [](
23
+ int64_t id,
24
+ int64_t atUs,
25
+ int64_t targetBitrate,
26
+ int64_t minProbeDeltaUs) -> RTC::BWE::Types::ProbeClusterConfig
27
+ {
28
+ return RTC::BWE::Types::ProbeClusterConfig{ .id = id,
29
+ .atUs = atUs,
30
+ .targetBitrate = targetBitrate,
31
+ .targetDurationUs = 15 * 1000,
32
+ .minProbeDeltaUs = minProbeDeltaUs,
33
+ .targetProbeCount = 5 };
34
+ };
35
+
36
+ SECTION("a burst goes out at the bitrate it was asked for, and then the next one")
37
+ {
38
+ constexpr int64_t TestBitrate1{ 900000 };
39
+ constexpr int64_t TestBitrate2{ 1800000 };
40
+ constexpr int64_t ClusterSize{ 5 };
41
+ constexpr int64_t MinProbeDurationUs{ 15 * 1000 };
42
+
43
+ RTC::BWE::BitrateProber prober;
44
+
45
+ REQUIRE(!prober.IsProbing());
46
+
47
+ const int64_t startTimeUs = nowUs;
48
+
49
+ REQUIRE(!prober.GetNextProbeTimeUs(nowUs).has_value());
50
+
51
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, TestBitrate1, 2 * 1000));
52
+ prober.CreateProbeCluster(makeClusterConfig(1, nowUs, TestBitrate2, 2 * 1000));
53
+
54
+ REQUIRE(!prober.IsProbing());
55
+
56
+ prober.OnIncomingPacket(ProbeSize);
57
+
58
+ REQUIRE(prober.IsProbing());
59
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
60
+ REQUIRE(prober.GetCurrentCluster(nowUs).value().probeCluster.id == 0);
61
+
62
+ // The first packet goes out at the first chance there is.
63
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
64
+ REQUIRE(prober.GetNextProbeTimeUs(nowUs).value() == nowUs);
65
+
66
+ for (int64_t i{ 0 }; i < ClusterSize; ++i)
67
+ {
68
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
69
+ nowUs = std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value());
70
+
71
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
72
+ REQUIRE(nowUs == std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value()));
73
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
74
+ REQUIRE(prober.GetCurrentCluster(nowUs).value().probeCluster.id == 0);
75
+
76
+ prober.ProbeSent(nowUs, ProbeSize);
77
+ }
78
+
79
+ REQUIRE(nowUs - startTimeUs >= MinProbeDurationUs);
80
+
81
+ // The bitrate it went out at is within 10% of the one asked for.
82
+ int64_t bitrate =
83
+ (static_cast<int64_t>(ProbeSize) * (ClusterSize - 1) * 8 * 1000000) / (nowUs - startTimeUs);
84
+
85
+ REQUIRE(bitrate > (TestBitrate1 * 9) / 10);
86
+ REQUIRE(bitrate < (TestBitrate1 * 11) / 10);
87
+
88
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
89
+ nowUs = std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value());
90
+
91
+ const int64_t probe2StartedUs = nowUs;
92
+
93
+ for (int64_t i{ 0 }; i < ClusterSize; ++i)
94
+ {
95
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
96
+ nowUs = std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value());
97
+
98
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
99
+ REQUIRE(nowUs == std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value()));
100
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
101
+ REQUIRE(prober.GetCurrentCluster(nowUs).value().probeCluster.id == 1);
102
+
103
+ prober.ProbeSent(nowUs, ProbeSize);
104
+ }
105
+
106
+ const int64_t durationUs = nowUs - probe2StartedUs;
107
+
108
+ REQUIRE(durationUs >= MinProbeDurationUs);
109
+
110
+ bitrate = (static_cast<int64_t>(ProbeSize) * (ClusterSize - 1) * 8 * 1000000) / durationUs;
111
+
112
+ REQUIRE(bitrate > (TestBitrate2 * 9) / 10);
113
+ REQUIRE(bitrate < (TestBitrate2 * 11) / 10);
114
+
115
+ REQUIRE(!prober.GetNextProbeTimeUs(nowUs).has_value());
116
+ REQUIRE(!prober.IsProbing());
117
+ }
118
+
119
+ SECTION("nothing goes out until a packet of somebody else's does")
120
+ {
121
+ RTC::BWE::BitrateProber prober;
122
+
123
+ REQUIRE(!prober.GetNextProbeTimeUs(nowUs).has_value());
124
+
125
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, 900000, 2 * 1000));
126
+
127
+ REQUIRE(!prober.IsProbing());
128
+
129
+ prober.OnIncomingPacket(ProbeSize);
130
+
131
+ REQUIRE(prober.IsProbing());
132
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
133
+ REQUIRE(nowUs == std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value()));
134
+
135
+ prober.ProbeSent(nowUs, ProbeSize);
136
+ }
137
+
138
+ SECTION("a packet that goes out long after it was due throws its burst away")
139
+ {
140
+ constexpr int64_t MaxProbeDelayUs{ 3 * 1000 };
141
+
142
+ const RTC::BWE::BitrateProber::BitrateProberOptions options{ .maxProbeDelayUs = MaxProbeDelayUs };
143
+
144
+ RTC::BWE::BitrateProber prober(options);
145
+
146
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, 900000, 2 * 1000));
147
+
148
+ prober.OnIncomingPacket(ProbeSize);
149
+
150
+ REQUIRE(prober.IsProbing());
151
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
152
+ REQUIRE(prober.GetCurrentCluster(nowUs).value().probeCluster.id == 0);
153
+
154
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
155
+ nowUs = std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value());
156
+
157
+ prober.ProbeSent(nowUs, ProbeSize);
158
+
159
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
160
+ const int64_t nextProbeTimeUs = prober.GetNextProbeTimeUs(nowUs).value();
161
+
162
+ REQUIRE(nextProbeTimeUs > nowUs);
163
+
164
+ nowUs += (nextProbeTimeUs - nowUs) + MaxProbeDelayUs + 1000;
165
+
166
+ // It still says the instant it wanted to go out at.
167
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
168
+ REQUIRE(prober.GetNextProbeTimeUs(nowUs).value() == nextProbeTimeUs);
169
+ // And the only burst there was is gone.
170
+ REQUIRE(!prober.GetCurrentCluster(nowUs).has_value());
171
+ }
172
+
173
+ SECTION("only so many bursts may be waiting at once")
174
+ {
175
+ RTC::BWE::BitrateProber prober;
176
+
177
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, 900000, 2 * 1000));
178
+ prober.OnIncomingPacket(ProbeSize);
179
+
180
+ REQUIRE(prober.IsProbing());
181
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
182
+ REQUIRE(prober.GetCurrentCluster(nowUs).value().probeCluster.id == 0);
183
+
184
+ for (int64_t i{ 1 }; i < 11; ++i)
185
+ {
186
+ prober.CreateProbeCluster(makeClusterConfig(i, nowUs, 900000, 2 * 1000));
187
+ prober.OnIncomingPacket(ProbeSize);
188
+ }
189
+
190
+ // Some of them have been dropped.
191
+ REQUIRE(prober.IsProbing());
192
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
193
+ REQUIRE(prober.GetCurrentCluster(nowUs).value().probeCluster.id >= 5);
194
+
195
+ const int64_t maxExpectedProbeTimeUs = nowUs + (1000 * 1000);
196
+
197
+ while (prober.IsProbing() && nowUs < maxExpectedProbeTimeUs)
198
+ {
199
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
200
+ nowUs = std::max(nowUs, prober.GetNextProbeTimeUs(nowUs).value());
201
+
202
+ prober.ProbeSent(nowUs, ProbeSize);
203
+ }
204
+
205
+ REQUIRE(!prober.IsProbing());
206
+ }
207
+
208
+ SECTION("a packet too small to measure from doesn't start a burst")
209
+ {
210
+ RTC::BWE::BitrateProber prober;
211
+
212
+ REQUIRE(!prober.IsProbing());
213
+
214
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, 1000000, 2 * 1000));
215
+ prober.OnIncomingPacket(100);
216
+
217
+ REQUIRE(!prober.IsProbing());
218
+ }
219
+
220
+ SECTION("unless any packet is said to do")
221
+ {
222
+ const RTC::BWE::BitrateProber::BitrateProberOptions options{ .minPacketSize = 0 };
223
+
224
+ RTC::BWE::BitrateProber prober(options);
225
+
226
+ REQUIRE(!prober.IsProbing());
227
+
228
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, 1000000, 2 * 1000));
229
+ prober.OnIncomingPacket(10);
230
+
231
+ REQUIRE(prober.IsProbing());
232
+ }
233
+
234
+ SECTION("the shot of a fast burst carries more than a millisecond of it")
235
+ {
236
+ constexpr int64_t HighBitrate{ 10000000 };
237
+
238
+ RTC::BWE::BitrateProber prober;
239
+
240
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, HighBitrate, 2 * 1000));
241
+
242
+ REQUIRE(prober.GetRecommendedMinProbeSize() > bytesFor(HighBitrate, 1000));
243
+ }
244
+
245
+ SECTION("and how much it carries is the time between shots that was asked for")
246
+ {
247
+ constexpr int64_t HighBitrate{ 10000000 };
248
+
249
+ RTC::BWE::BitrateProber prober;
250
+
251
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, HighBitrate, 20 * 1000));
252
+
253
+ REQUIRE(prober.GetRecommendedMinProbeSize() == bytesFor(HighBitrate, 20 * 1000));
254
+
255
+ prober.OnIncomingPacket(ProbeSize);
256
+
257
+ // Having sent what a shot should carry, the next one is due a whole time
258
+ // between shots later.
259
+ prober.ProbeSent(nowUs, prober.GetRecommendedMinProbeSize());
260
+
261
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
262
+ REQUIRE(prober.GetNextProbeTimeUs(nowUs).value() == nowUs + (20 * 1000));
263
+ }
264
+
265
+ SECTION("a slow burst still takes the count of packets it asked for")
266
+ {
267
+ constexpr int64_t Bitrate{ 100000 };
268
+ constexpr size_t PacketSize{ 1000 };
269
+
270
+ RTC::BWE::BitrateProber prober;
271
+
272
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, Bitrate, 2 * 1000));
273
+ prober.OnIncomingPacket(PacketSize);
274
+
275
+ for (int64_t i{ 0 }; i < 5; ++i)
276
+ {
277
+ REQUIRE(prober.IsProbing());
278
+
279
+ prober.ProbeSent(nowUs, PacketSize);
280
+ }
281
+
282
+ REQUIRE(!prober.IsProbing());
283
+ }
284
+
285
+ SECTION("and a fast one takes the bytes it asked for")
286
+ {
287
+ constexpr int64_t Bitrate{ 10000000 };
288
+ constexpr size_t PacketSize{ 1000 };
289
+
290
+ const size_t expectedDataSent = bytesFor(Bitrate, 15 * 1000);
291
+
292
+ RTC::BWE::BitrateProber prober;
293
+
294
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, Bitrate, 2 * 1000));
295
+ prober.OnIncomingPacket(PacketSize);
296
+
297
+ size_t dataSent{ 0 };
298
+
299
+ while (dataSent < expectedDataSent)
300
+ {
301
+ REQUIRE(prober.IsProbing());
302
+
303
+ prober.ProbeSent(nowUs, PacketSize);
304
+
305
+ dataSent += PacketSize;
306
+ }
307
+
308
+ REQUIRE(!prober.IsProbing());
309
+ }
310
+
311
+ SECTION("however fast it is")
312
+ {
313
+ constexpr int64_t Bitrate{ 1000000000 };
314
+ constexpr size_t PacketSize{ 1000 };
315
+
316
+ const size_t expectedDataSent = bytesFor(Bitrate, 15 * 1000);
317
+
318
+ RTC::BWE::BitrateProber prober;
319
+
320
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, Bitrate, 2 * 1000));
321
+ prober.OnIncomingPacket(PacketSize);
322
+
323
+ size_t dataSent{ 0 };
324
+
325
+ while (dataSent < expectedDataSent)
326
+ {
327
+ REQUIRE(prober.IsProbing());
328
+
329
+ prober.ProbeSent(nowUs, PacketSize);
330
+
331
+ dataSent += PacketSize;
332
+ }
333
+
334
+ REQUIRE(!prober.IsProbing());
335
+ }
336
+
337
+ SECTION("a burst that never started goes stale")
338
+ {
339
+ constexpr int64_t Bitrate{ 300000 };
340
+ constexpr size_t SmallPacketSize{ 20 };
341
+ // Two bursts of five packets each.
342
+ constexpr size_t ExpectedDataSent{ SmallPacketSize * 2 * 5 };
343
+ constexpr int64_t TimeoutUs{ 5000 * 1000 };
344
+
345
+ RTC::BWE::BitrateProber prober;
346
+
347
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, Bitrate, 2 * 1000));
348
+ prober.OnIncomingPacket(SmallPacketSize);
349
+
350
+ REQUIRE(!prober.IsProbing());
351
+
352
+ nowUs += TimeoutUs;
353
+
354
+ prober.CreateProbeCluster(makeClusterConfig(1, nowUs, Bitrate / 10, 2 * 1000));
355
+ prober.OnIncomingPacket(SmallPacketSize);
356
+
357
+ REQUIRE(!prober.IsProbing());
358
+
359
+ nowUs += 1000;
360
+
361
+ prober.CreateProbeCluster(makeClusterConfig(2, nowUs, Bitrate / 10, 2 * 1000));
362
+ prober.OnIncomingPacket(SmallPacketSize);
363
+
364
+ REQUIRE(prober.IsProbing());
365
+
366
+ size_t dataSent{ 0 };
367
+
368
+ while (dataSent < ExpectedDataSent)
369
+ {
370
+ REQUIRE(prober.IsProbing());
371
+
372
+ prober.ProbeSent(nowUs, SmallPacketSize);
373
+
374
+ dataSent += SmallPacketSize;
375
+ }
376
+
377
+ REQUIRE(!prober.IsProbing());
378
+ }
379
+
380
+ SECTION("a burst may start with no packet of somebody else's at all")
381
+ {
382
+ const RTC::BWE::BitrateProber::BitrateProberOptions options{ .minPacketSize = 0 };
383
+
384
+ RTC::BWE::BitrateProber prober(options);
385
+
386
+ prober.CreateProbeCluster(makeClusterConfig(0, nowUs, 300000, 2 * 1000));
387
+
388
+ REQUIRE(prober.IsProbing());
389
+ }
390
+
391
+ SECTION("and so may the one after it")
392
+ {
393
+ constexpr int64_t Bitrate{ 300000 };
394
+
395
+ const RTC::BWE::BitrateProber::BitrateProberOptions options{ .minPacketSize = 0 };
396
+
397
+ RTC::BWE::BitrateProber prober(options);
398
+
399
+ auto clusterConfig = makeClusterConfig(0, nowUs, Bitrate, 2 * 1000);
400
+
401
+ clusterConfig.targetProbeCount = 1;
402
+
403
+ prober.CreateProbeCluster(clusterConfig);
404
+
405
+ REQUIRE(prober.IsProbing());
406
+
407
+ prober.ProbeSent(nowUs + 1000, bytesFor(Bitrate, 15 * 1000));
408
+
409
+ REQUIRE(!prober.IsProbing());
410
+
411
+ clusterConfig.id = 2;
412
+ clusterConfig.atUs = nowUs + (100 * 1000);
413
+
414
+ prober.CreateProbeCluster(clusterConfig);
415
+
416
+ REQUIRE(prober.IsProbing());
417
+ }
418
+ }
@@ -0,0 +1,61 @@
1
+ #include "common.hpp"
2
+ #include "RTC/BWE/BitrateUtils.hpp"
3
+ #include "RTC/BWE/BweTypes.hpp"
4
+ #include <catch2/catch_test_macros.hpp>
5
+
6
+ SCENARIO("BWE BitrateUtils", "[bwe][bitrateutils]")
7
+ {
8
+ SECTION("ApplyBitrateFactor() gives the bitrate times the factor")
9
+ {
10
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(600000, 1.02) == 612000);
11
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(600000, 0.95) == 570000);
12
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(600000, 1.0) == 600000);
13
+ }
14
+
15
+ SECTION("ApplyBitrateFactor() rounds to the nearest bitrate, away from zero on a tie")
16
+ {
17
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(3, 0.4) == 1);
18
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(3, 0.5) == 2);
19
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(7, 0.5) == 4);
20
+ }
21
+
22
+ SECTION("ApplyBitrateFactor() gives no bitrate at all beyond what the type holds")
23
+ {
24
+ // Anything over the maximum means no limit, which is what its own value
25
+ // already means.
26
+ REQUIRE(
27
+ RTC::BWE::BitrateUtils::ApplyBitrateFactor(RTC::BWE::Types::BitrateInfinite, 1.3) ==
28
+ RTC::BWE::Types::BitrateInfinite);
29
+ REQUIRE(
30
+ RTC::BWE::BitrateUtils::ApplyBitrateFactor(RTC::BWE::Types::BitrateInfinite / 2, 4.0) ==
31
+ RTC::BWE::Types::BitrateInfinite);
32
+ REQUIRE(
33
+ RTC::BWE::BitrateUtils::ApplyBitrateFactor(RTC::BWE::Types::BitrateInfinite, 1.0) ==
34
+ RTC::BWE::Types::BitrateInfinite);
35
+ }
36
+
37
+ SECTION("ApplyBitrateFactor() never gives a negative bitrate")
38
+ {
39
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(600000, -1.0) == 0);
40
+ REQUIRE(RTC::BWE::BitrateUtils::ApplyBitrateFactor(0, 1.5) == 0);
41
+ }
42
+
43
+ SECTION("AddBitrates() gives the sum")
44
+ {
45
+ REQUIRE(RTC::BWE::BitrateUtils::AddBitrates(600000, 1000) == 601000);
46
+ REQUIRE(RTC::BWE::BitrateUtils::AddBitrates(600000, 0) == 600000);
47
+ }
48
+
49
+ SECTION("AddBitrates() gives no bitrate at all beyond what the type holds")
50
+ {
51
+ REQUIRE(
52
+ RTC::BWE::BitrateUtils::AddBitrates(RTC::BWE::Types::BitrateInfinite, 1000) ==
53
+ RTC::BWE::Types::BitrateInfinite);
54
+ REQUIRE(
55
+ RTC::BWE::BitrateUtils::AddBitrates(RTC::BWE::Types::BitrateInfinite - 1000, 1001) ==
56
+ RTC::BWE::Types::BitrateInfinite);
57
+ REQUIRE(
58
+ RTC::BWE::BitrateUtils::AddBitrates(RTC::BWE::Types::BitrateInfinite - 1000, 1000) ==
59
+ RTC::BWE::Types::BitrateInfinite);
60
+ }
61
+ }
@@ -4,7 +4,7 @@
4
4
  #include "RTC/BWE/RobustThroughputEstimator.hpp"
5
5
  #include "test/include/RTC/BWE/helpers/LinkSimulator.hpp"
6
6
  #include <catch2/catch_test_macros.hpp>
7
- #include <cmath>
7
+ #include <cstdlib> // std::abs()
8
8
 
9
9
  SCENARIO("BWE DelayBasedBwe", "[bwe][delaybasedbwe]")
10
10
  {
@@ -354,9 +354,9 @@ SCENARIO("BWE DelayBasedBwe", "[bwe][delaybasedbwe]")
354
354
  SimulatedTransport simulatedTransport;
355
355
 
356
356
  // The very same scenario as the first capacity drop, expected against a
357
- // margin shifted by 33 ms. Upstream keeps both because the measured value
358
- // falls inside the two, and the parameter that used to tell them apart is
359
- // no longer read by anything.
357
+ // margin shifted by 33 ms. Both are kept because the measured value falls
358
+ // inside the two, and the parameter that used to tell them apart is no longer
359
+ // read by anything.
360
360
  capacityDropTestHelper(
361
361
  simulatedTransport,
362
362
  /*numberOfStreams*/ 1,