mediasoup 3.27.1 → 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 (203) hide show
  1. package/CHANGELOG.md +14 -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/rtpParameters.fbs +0 -1
  38. package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
  39. package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
  40. package/worker/include/DepLibUV.hpp +13 -0
  41. package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
  42. package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
  43. package/worker/include/RTC/BWE/{Utils.hpp → BitrateUtils.hpp} +3 -3
  44. package/worker/include/RTC/BWE/BweTypes.hpp +170 -2
  45. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
  46. package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
  47. package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
  48. package/worker/include/RTC/BWE/LossBasedController.hpp +105 -0
  49. package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
  50. package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
  51. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
  52. package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
  53. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
  54. package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
  55. package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
  56. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
  57. package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
  58. package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
  59. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
  60. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +15 -0
  61. package/worker/include/RTC/Consts.hpp +70 -0
  62. package/worker/include/RTC/DataConsumer.hpp +3 -5
  63. package/worker/include/RTC/DirectTransport.hpp +4 -5
  64. package/worker/include/RTC/PipeTransport.hpp +4 -5
  65. package/worker/include/RTC/PlainTransport.hpp +4 -5
  66. package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
  67. package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
  68. package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
  69. package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
  70. package/worker/include/RTC/RTP/Packet.hpp +16 -4
  71. package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
  72. package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
  73. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
  74. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
  75. package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
  76. package/worker/include/RTC/RateCalculator.hpp +103 -24
  77. package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
  78. package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
  79. package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
  80. package/worker/include/RTC/RtpDictionaries.hpp +3 -4
  81. package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
  82. package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
  83. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +4 -4
  84. package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
  85. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +1 -1
  86. package/worker/include/RTC/SctpDictionaries.hpp +2 -2
  87. package/worker/include/RTC/TcpConnection.hpp +2 -1
  88. package/worker/include/RTC/Transport.hpp +23 -8
  89. package/worker/include/RTC/TransportTuple.hpp +61 -6
  90. package/worker/include/RTC/WebRtcTransport.hpp +4 -5
  91. package/worker/include/Shared.hpp +5 -0
  92. package/worker/include/SharedInterface.hpp +10 -0
  93. package/worker/include/Utils.hpp +72 -3
  94. package/worker/include/common.hpp +12 -4
  95. package/worker/include/handles/SendCallbacks.hpp +34 -0
  96. package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
  97. package/worker/include/handles/UdpSocketHandle.hpp +4 -8
  98. package/worker/meson.build +41 -3
  99. package/worker/meson_options.txt +1 -0
  100. package/worker/mocks/include/MockShared.hpp +16 -2
  101. package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
  102. package/worker/scripts/package-lock.json +6 -6
  103. package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
  104. package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
  105. package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
  106. package/worker/src/RTC/BWE/{Utils.cpp → BitrateUtils.cpp} +4 -4
  107. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
  108. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
  109. package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
  110. package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
  111. package/worker/src/RTC/BWE/LossBasedController.cpp +189 -41
  112. package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
  113. package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
  114. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
  115. package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
  116. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
  117. package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
  118. package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
  119. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
  120. package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
  121. package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
  122. package/worker/src/RTC/BWE/TargetRateController.cpp +12 -14
  123. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
  124. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +19 -0
  125. package/worker/src/RTC/Consumer.cpp +7 -5
  126. package/worker/src/RTC/DataConsumer.cpp +8 -10
  127. package/worker/src/RTC/DirectTransport.cpp +14 -8
  128. package/worker/src/RTC/DtlsTransport.cpp +8 -8
  129. package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
  130. package/worker/src/RTC/ICE/IceServer.cpp +1 -1
  131. package/worker/src/RTC/PipeTransport.cpp +13 -8
  132. package/worker/src/RTC/PlainTransport.cpp +13 -8
  133. package/worker/src/RTC/Producer.cpp +14 -31
  134. package/worker/src/RTC/RTCP/Bye.cpp +1 -1
  135. package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
  136. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
  137. package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
  138. package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
  139. package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
  140. package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
  141. package/worker/src/RTC/RTP/Packet.cpp +26 -11
  142. package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
  143. package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
  144. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
  145. package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
  146. package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
  147. package/worker/src/RTC/RateCalculator.cpp +133 -28
  148. package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
  149. package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
  150. package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
  151. package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
  152. package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
  153. package/worker/src/RTC/SCTP/association/Association.cpp +1 -1
  154. package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
  155. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  156. package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
  157. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
  158. package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
  159. package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
  160. package/worker/src/RTC/SrtpSession.cpp +2 -2
  161. package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
  162. package/worker/src/RTC/TcpConnection.cpp +2 -2
  163. package/worker/src/RTC/Transport.cpp +111 -93
  164. package/worker/src/RTC/TransportTuple.cpp +4 -4
  165. package/worker/src/RTC/WebRtcServer.cpp +4 -3
  166. package/worker/src/RTC/WebRtcTransport.cpp +20 -13
  167. package/worker/src/Utils/BitStream.cpp +24 -0
  168. package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
  169. package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
  170. package/worker/src/handles/UdpSocketHandle.cpp +14 -21
  171. package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
  172. package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
  173. package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
  174. package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
  175. package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
  176. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
  177. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
  178. package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
  179. package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
  180. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
  181. package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
  182. package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
  183. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
  184. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
  185. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
  186. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
  187. package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
  188. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
  189. package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
  190. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
  191. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
  192. package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
  193. package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
  194. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
  195. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
  196. package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
  197. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
  198. package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
  199. package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
  200. package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
  201. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
  202. package/worker/test/src/Utils/TestTime.cpp +120 -21
  203. package/worker/test/src/RTC/BWE/TestUtils.cpp +0 -61
@@ -36,6 +36,19 @@ public:
36
36
  return static_cast<int64_t>(uv_hrtime() / 1000);
37
37
  }
38
38
 
39
+ /**
40
+ * Time at which the current iteration of the event loop began (ms).
41
+ *
42
+ * @remarks
43
+ * - It is taken once per iteration and cached, so every caller within the same one
44
+ * gets the very same value no matter how long the iteration takes. That is what
45
+ * tells two iterations apart, which the clocks above cannot do.
46
+ */
47
+ static uint64_t GetLoopTimeMs()
48
+ {
49
+ return uv_now(DepLibUV::GetLoop());
50
+ }
51
+
39
52
  /**
40
53
  * Offset between our own monotonic clock and the NTP epoch (us).
41
54
  *
@@ -0,0 +1,97 @@
1
+ #ifndef MS_RTC_BWE_ALR_DETECTOR_HPP
2
+ #define MS_RTC_BWE_ALR_DETECTOR_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/IntervalBudget.hpp"
6
+ #include "SharedInterface.hpp"
7
+
8
+ namespace RTC
9
+ {
10
+ namespace BWE
11
+ {
12
+ /**
13
+ * Tells whether the sender is not sending enough to fill the link.
14
+ *
15
+ * While that is the case nothing measured says anything about the capacity
16
+ * of the link, because what arrives is only what was sent: the delay doesn't
17
+ * grow, no packet is lost, and the bitrate that gets acknowledged is the one
18
+ * chosen rather than the one the link can carry. So the estimate cannot grow
19
+ * on its own, and the only way out is to probe.
20
+ *
21
+ * The question is answered by giving the sender a budget that refills at a
22
+ * fraction of the estimated bitrate and is spent as bytes go out. A budget
23
+ * that keeps growing means the sender is not using what it was given.
24
+ *
25
+ * @remarks
26
+ * - For a browser this is an odd situation, but for an SFU whose consumers
27
+ * sit on low layers it is the normal state.
28
+ */
29
+ class AlrDetector
30
+ {
31
+ public:
32
+ struct AlrDetectorOptions
33
+ {
34
+ /**
35
+ * Fraction of the estimated bitrate the sender is expected to be using.
36
+ * The budget refills at that fraction rather than at the whole estimate,
37
+ * so that staying somewhat below it doesn't count as not filling the
38
+ * link.
39
+ */
40
+ double bandwidthUsageRatio{ 0.65 };
41
+ /**
42
+ * Level the budget has to grow past for the sender to be taken as not
43
+ * filling the link.
44
+ */
45
+ double startBudgetLevelRatio{ 0.80 };
46
+ /**
47
+ * Level the budget has to fall back below for it to stop being taken as
48
+ * such. It is lower than the one above so that a short burst doesn't end
49
+ * the state.
50
+ */
51
+ double stopBudgetLevelRatio{ 0.50 };
52
+ };
53
+
54
+ public:
55
+ explicit AlrDetector(SharedInterface* shared);
56
+
57
+ AlrDetector(SharedInterface* shared, AlrDetectorOptions options);
58
+
59
+ /**
60
+ * Feed bytes that have just left towards the network.
61
+ *
62
+ * @param sentAtUs - Instant at which they left, which is what the span of
63
+ * time they were sent over is measured with.
64
+ */
65
+ void OnBytesSent(int64_t bytesSent, int64_t sentAtUs);
66
+
67
+ /**
68
+ * Bitrate the sender is expected to be able to use (bps).
69
+ */
70
+ void SetEstimatedBitrate(int64_t bitrate);
71
+
72
+ /**
73
+ * Instant at which the sender started not filling the link, or no value
74
+ * while it is filling it.
75
+ */
76
+ std::optional<int64_t> GetAlrStartTimeUs() const
77
+ {
78
+ return this->alrStartTimeUs;
79
+ }
80
+
81
+ private:
82
+ // Passed by argument.
83
+ SharedInterface* shared{ nullptr };
84
+ const AlrDetectorOptions options;
85
+ // Others.
86
+ // Budget of what the sender was expected to use, whose level is the whole
87
+ // signal this produces.
88
+ IntervalBudget alrBudget;
89
+ // Instant of the latest send, which is what the span of the next one is
90
+ // measured against.
91
+ std::optional<int64_t> lastSentAtUs;
92
+ std::optional<int64_t> alrStartTimeUs;
93
+ };
94
+ } // namespace BWE
95
+ } // namespace RTC
96
+
97
+ #endif
@@ -0,0 +1,217 @@
1
+ #ifndef MS_RTC_BWE_BITRATE_PROBER_HPP
2
+ #define MS_RTC_BWE_BITRATE_PROBER_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/BweTypes.hpp"
6
+ #include <queue>
7
+
8
+ namespace RTC
9
+ {
10
+ namespace BWE
11
+ {
12
+ /**
13
+ * Paces out the bursts that somebody else decided to send.
14
+ *
15
+ * It takes the bursts asked for, keeps them in the order they were asked for,
16
+ * and answers a single question over and over: at what instant may the next
17
+ * packet of the current one go out, and how many bytes should it carry. It
18
+ * sends nothing itself.
19
+ *
20
+ * The spacing is what makes a burst worth anything. A burst is a bitrate held
21
+ * for a few milliseconds, so letting the packets go as fast as the socket
22
+ * takes them measures the queue of whoever is in the way rather than the link.
23
+ * So each instant is computed from the start of the burst and the bytes gone
24
+ * out so far, which keeps the whole of it close to the bitrate asked for even
25
+ * when a packet leaves late.
26
+ */
27
+ class BitrateProber
28
+ {
29
+ private:
30
+ /**
31
+ * Whether bursts are being emitted, and why not when they are not.
32
+ */
33
+ enum class State : uint8_t
34
+ {
35
+ /**
36
+ * There may be bursts waiting, but none of them has started.
37
+ */
38
+ INACTIVE,
39
+ /**
40
+ * A burst is being emitted.
41
+ */
42
+ ACTIVE
43
+ };
44
+
45
+ /**
46
+ * A burst that was asked for, and how much of it has gone out.
47
+ */
48
+ struct Cluster
49
+ {
50
+ /**
51
+ * What travels with each of its packets, and what makes its result
52
+ * trustworthy.
53
+ */
54
+ Types::ProbeCluster probeCluster;
55
+ /**
56
+ * Bitrate it is meant to be sent at (bps).
57
+ */
58
+ int64_t sendBitrate{ 0 };
59
+ /**
60
+ * Time between two consecutive bursts of packets within it.
61
+ */
62
+ int64_t minProbeDeltaUs{ 0 };
63
+ /**
64
+ * Instant at which it was asked for, which is what makes it go stale.
65
+ */
66
+ int64_t requestedAtUs{ 0 };
67
+ /**
68
+ * Instant at which its first packet went out, or no value while none
69
+ * has.
70
+ */
71
+ std::optional<int64_t> startedAtUs;
72
+ int64_t sentProbes{ 0 };
73
+ int64_t sentBytes{ 0 };
74
+ };
75
+
76
+ public:
77
+ struct BitrateProberOptions
78
+ {
79
+ /**
80
+ * How late a packet of a burst may go out before the whole burst is
81
+ * given up on, since one sent too slowly no longer measures the bitrate
82
+ * it was meant to.
83
+ */
84
+ int64_t maxProbeDelayUs{ 10 * 1000 };
85
+ /**
86
+ * Size a packet has to reach for a burst to start on it (bytes).
87
+ *
88
+ * @remarks
89
+ * - It only applies while the bursts are made of traffic that somebody
90
+ * else produces, since a burst that begins on a tiny packet starts
91
+ * measuring from an instant that says nothing.
92
+ */
93
+ size_t minPacketSize{ 200 };
94
+ /**
95
+ * Whether a burst may start without waiting for a packet of that size.
96
+ */
97
+ bool allowStartProbingImmediately{ false };
98
+ };
99
+
100
+ /**
101
+ * The burst being emitted, together with how much of it has gone out.
102
+ */
103
+ struct CurrentCluster
104
+ {
105
+ /**
106
+ * What travels with each of its packets.
107
+ */
108
+ Types::ProbeCluster probeCluster;
109
+ /**
110
+ * Bytes of the burst that have already gone out (bytes).
111
+ *
112
+ * @remarks
113
+ * - It doesn't belong in `Types::ProbeCluster` because that one travels
114
+ * attached to every packet until its feedback comes back, and by then
115
+ * this count means nothing.
116
+ */
117
+ int64_t sentBytes{ 0 };
118
+ };
119
+
120
+ public:
121
+ BitrateProber();
122
+
123
+ explicit BitrateProber(BitrateProberOptions options);
124
+
125
+ ~BitrateProber() = default;
126
+
127
+ /**
128
+ * Whether a burst is being emitted right now.
129
+ */
130
+ bool IsProbing() const
131
+ {
132
+ return this->state == State::ACTIVE;
133
+ }
134
+
135
+ /**
136
+ * Take a burst that has been asked for.
137
+ */
138
+ void CreateProbeCluster(const Types::ProbeClusterConfig& clusterConfig);
139
+
140
+ /**
141
+ * Instant at which the next packet of the current burst may go out, or no
142
+ * value if there is nothing to send.
143
+ *
144
+ * @remarks
145
+ * - The instant given is `nowUs` itself when the packet may go out right
146
+ * away, so that the answer is always an instant that can be operated
147
+ * with rather than a value meaning "as soon as possible".
148
+ */
149
+ [[nodiscard]] std::optional<int64_t> GetNextProbeTimeUs(int64_t nowUs) const;
150
+
151
+ /**
152
+ * The burst being emitted, or no value if there is none.
153
+ *
154
+ * @remarks
155
+ * - It gives up on the burst, and may leave none being emitted, when the
156
+ * instant it was due at is too far behind.
157
+ */
158
+ [[nodiscard]] std::optional<CurrentCluster> GetCurrentCluster(int64_t nowUs);
159
+
160
+ /**
161
+ * Bytes the next packet of the current burst should carry, or zero if there
162
+ * is no burst.
163
+ *
164
+ * @remarks
165
+ * - Packets are allowed to be grouped into a single shot as long as they
166
+ * add up to this, which is what keeps a burst from needing a packet every
167
+ * couple of milliseconds.
168
+ */
169
+ size_t GetRecommendedMinProbeSize() const;
170
+
171
+ /**
172
+ * Report that the given bytes of the current burst have gone out.
173
+ */
174
+ void ProbeSent(int64_t nowUs, size_t size);
175
+
176
+ /**
177
+ * Feed a packet that somebody else is sending, which is what may start a
178
+ * burst that is waiting for one.
179
+ *
180
+ * @remarks
181
+ * - Only the tests call it today, because the bursts are made of packets
182
+ * fabricated for them and there is no traffic of somebody else's to wait
183
+ * for. This is the way in for the day a burst rides on real traffic
184
+ * instead, and with it `minPacketSize` starts meaning something.
185
+ */
186
+ void OnIncomingPacket(size_t packetSize);
187
+
188
+ private:
189
+ /**
190
+ * Start emitting if there is a burst waiting and the given packet is enough
191
+ * to begin on.
192
+ */
193
+ void MaybeSetActiveState(size_t packetSize);
194
+
195
+ bool IsReadyToSetActiveState(size_t packetSize) const;
196
+
197
+ /**
198
+ * Instant at which the next packet of the given burst is due, computed from
199
+ * the start of the burst so that it stays close to its bitrate.
200
+ */
201
+ int64_t CalculateNextProbeTimeUs(const Cluster& cluster) const;
202
+
203
+ private:
204
+ // Passed by argument.
205
+ BitrateProberOptions options;
206
+ // Others.
207
+ State state{ State::INACTIVE };
208
+ // The bursts asked for, the first one being the one being emitted.
209
+ std::queue<Cluster> clusters;
210
+ // Instant at which the next packet is due, or no value while it is due
211
+ // right away.
212
+ std::optional<int64_t> nextProbeTimeUs;
213
+ };
214
+ } // namespace BWE
215
+ } // namespace RTC
216
+
217
+ #endif
@@ -1,5 +1,5 @@
1
- #ifndef MS_RTC_BWE_UTILS_HPP
2
- #define MS_RTC_BWE_UTILS_HPP
1
+ #ifndef MS_RTC_BWE_BITRATE_UTILS_HPP
2
+ #define MS_RTC_BWE_BITRATE_UTILS_HPP
3
3
 
4
4
  #include "common.hpp"
5
5
 
@@ -7,7 +7,7 @@ namespace RTC
7
7
  {
8
8
  namespace BWE
9
9
  {
10
- class Utils
10
+ class BitrateUtils
11
11
  {
12
12
  public:
13
13
  /**
@@ -22,6 +22,32 @@ namespace RTC
22
22
  */
23
23
  constexpr int64_t TimeUsInfinite{ std::numeric_limits<int64_t>::max() };
24
24
 
25
+ /**
26
+ * The two bits of the IP header with which the network tells that it is
27
+ * congested instead of dropping the packet.
28
+ *
29
+ * @see https://www.rfc-editor.org/rfc/rfc9331.html
30
+ */
31
+ enum class EcnMarking : uint8_t
32
+ {
33
+ /**
34
+ * Not ECN capable transport.
35
+ */
36
+ NOT_ECT = 0b00,
37
+ /**
38
+ * ECN capable transport, which is the one L4S uses.
39
+ */
40
+ ECT1 = 0b01,
41
+ /**
42
+ * ECN capable transport, not used by L4S.
43
+ */
44
+ ECT0 = 0b10,
45
+ /**
46
+ * Congestion experienced, which is what the network sets on the way.
47
+ */
48
+ CE = 0b11
49
+ };
50
+
25
51
  /**
26
52
  * How the network is behaving according to the delay based detector.
27
53
  */
@@ -60,7 +86,7 @@ namespace RTC
60
86
  return "OVERUSING";
61
87
  }
62
88
 
63
- NO_DEFAULT_GCC();
89
+ NO_DEFAULT();
64
90
  }
65
91
  }
66
92
 
@@ -95,6 +121,67 @@ namespace RTC
95
121
  std::optional<int64_t> estimatedThroughput;
96
122
  };
97
123
 
124
+ /**
125
+ * The burst of packets a probe is sent as, and what makes its result
126
+ * trustworthy.
127
+ *
128
+ * A probe is only worth believing once enough of what was sent has come
129
+ * back, so the burst carries how many packets and how many bytes it was
130
+ * meant to be. Whoever measures it compares those against what actually
131
+ * arrived, and discards the cluster if too little of it did.
132
+ */
133
+ struct ProbeCluster
134
+ {
135
+ /**
136
+ * Identifies the burst, so that the packets of one probe are not mixed
137
+ * with those of another.
138
+ */
139
+ int64_t id{ 0 };
140
+ /**
141
+ * Packets the burst was meant to be made of.
142
+ */
143
+ int64_t minProbes{ 0 };
144
+ /**
145
+ * Bytes the burst was meant to carry.
146
+ */
147
+ int64_t minBytes{ 0 };
148
+ };
149
+
150
+ /**
151
+ * A burst that has been asked for but not sent yet.
152
+ *
153
+ * It's what whoever decides to probe hands over to whoever emits the
154
+ * packets: at what bitrate, for how long and in how many packets. What
155
+ * travels with each of those packets afterwards is a `ProbeCluster`.
156
+ */
157
+ struct ProbeClusterConfig
158
+ {
159
+ /**
160
+ * Identifies the burst, and is what each of its packets carries.
161
+ */
162
+ int64_t id{ 0 };
163
+ /**
164
+ * Instant at which the burst was asked for.
165
+ */
166
+ int64_t atUs{ 0 };
167
+ /**
168
+ * Bitrate the burst is meant to be sent at (bps).
169
+ */
170
+ int64_t targetBitrate{ 0 };
171
+ /**
172
+ * How long the burst is meant to last.
173
+ */
174
+ int64_t targetDurationUs{ 0 };
175
+ /**
176
+ * Time between two consecutive bursts of packets within the probe.
177
+ */
178
+ int64_t minProbeDeltaUs{ 2 * 1000 };
179
+ /**
180
+ * Packets the burst is meant to be made of.
181
+ */
182
+ int64_t targetProbeCount{ 0 };
183
+ };
184
+
98
185
  /**
99
186
  * A packet that was sent and is being tracked until its feedback arrives.
100
187
  */
@@ -133,7 +220,12 @@ namespace RTC
133
220
  /**
134
221
  * Whether it's an audio packet. False for video, padding and RTX.
135
222
  */
136
- bool audio{ false };
223
+ bool isAudio{ false };
224
+ /**
225
+ * The probe cluster the packet belongs to, or no value if it isn't a
226
+ * probe.
227
+ */
228
+ std::optional<ProbeCluster> probeCluster;
137
229
  };
138
230
 
139
231
  /**
@@ -154,6 +246,16 @@ namespace RTC
154
246
  bool operator()(const PacketResult& lhs, const PacketResult& rhs) const;
155
247
  };
156
248
 
249
+ /**
250
+ * What identifies the packet on the wire.
251
+ */
252
+ struct RtpPacketInfo
253
+ {
254
+ uint32_t ssrc{ 0 };
255
+ uint16_t rtpSequenceNumber{ 0 };
256
+ bool isRetransmission{ false };
257
+ };
258
+
157
259
  /**
158
260
  * Whether the packet reached the receiver at all.
159
261
  */
@@ -168,6 +270,72 @@ namespace RTC
168
270
  * value if it was reported as lost.
169
271
  */
170
272
  std::optional<int64_t> receiveTimeUs;
273
+ /**
274
+ * What identifies the packet on the wire, or no value when the feedback
275
+ * doesn't report on an RTP packet.
276
+ */
277
+ std::optional<RtpPacketInfo> rtpPacketInfo;
278
+ /**
279
+ * How long the receiver held the packet before sending the feedback
280
+ * that reports it, which is what allows a round trip time per packet.
281
+ *
282
+ * @remark
283
+ * - Only a feedback that carries it per packet has it, which is the one
284
+ * of RFC 8888 and not the transport-cc one.
285
+ *
286
+ * @see https://datatracker.ietf.org/doc/html/rfc8888
287
+ */
288
+ std::optional<int64_t> arrivalTimeOffsetUs;
289
+ /**
290
+ * The marking the packet carried when it arrived, which is how the
291
+ * network reports being congested without dropping it.
292
+ *
293
+ * @remark
294
+ * - Only a feedback that reports it has it, which is the one of RFC
295
+ * 8888 and not the transport-cc one.
296
+ *
297
+ * @see https://datatracker.ietf.org/doc/html/rfc8888
298
+ */
299
+ EcnMarking ecn{ EcnMarking::NOT_ECT };
300
+ /**
301
+ * Whether the arrival time reported for this packet cannot be told from
302
+ * that of another one, so it says nothing about the delay.
303
+ *
304
+ * @remark
305
+ * - Nothing in this estimator reads it. It is only of use to SCReAM,
306
+ * another way of estimating the bandwidth.
307
+ *
308
+ * @link https://datatracker.ietf.org/doc/draft-johansson-ccwg-rfc8298bis-screamv2
309
+ */
310
+ bool ambiguousReceiveTime{ false };
311
+ /**
312
+ * Whether the packet was sent marked as ECT(1), which asks the network
313
+ * to report congestion instead of dropping the packet.
314
+ *
315
+ * @see https://www.rfc-editor.org/rfc/rfc9331.html
316
+ */
317
+ bool sentWithEct1{ false };
318
+ /**
319
+ * Whether this is the first feedback to report the packet as lost.
320
+ *
321
+ * @remark
322
+ * - Only a feedback that reports on a whole range of packets can tell,
323
+ * which is the one of RFC 8888 and not the transport-cc one.
324
+ *
325
+ * @see https://datatracker.ietf.org/doc/html/rfc8888
326
+ */
327
+ bool reportedLostForTheFirstTime{ false };
328
+ /**
329
+ * Whether this feedback reports as received a packet that an earlier
330
+ * one had reported as lost.
331
+ *
332
+ * @remark
333
+ * - Only a feedback that reports on a whole range of packets can tell,
334
+ * which is the one of RFC 8888 and not the transport-cc one.
335
+ *
336
+ * @see https://datatracker.ietf.org/doc/html/rfc8888
337
+ */
338
+ bool reportedRecoveredForTheFirstTime{ false };
171
339
  };
172
340
 
173
341
  /**
@@ -43,17 +43,6 @@ namespace RTC
43
43
  std::optional<Types::TransportPacketsFeedback> ProcessTransportFeedback(
44
44
  const RTCP::FeedbackRtpTransportPacket* feedback, int64_t receivedAtUs);
45
45
 
46
- private:
47
- /**
48
- * Recover the sequence number the history gave to a packet out of the
49
- * lowest bits of it that the wire carries.
50
- *
51
- * @param previousSequenceNumber - Sequence number the previous packet the
52
- * feedback reported on resolved into, which the returned one is the
53
- * closest to.
54
- */
55
- static int64_t UnwrapSequenceNumber(uint16_t wideSequenceNumber, int64_t previousSequenceNumber);
56
-
57
46
  private:
58
47
  SendPacketHistory* const sendPacketHistory;
59
48
  // Our own time the arrival times of the current feedback are given
@@ -62,9 +51,6 @@ namespace RTC
62
51
  // Base time of the latest feedback processed, in the remote clock, or no
63
52
  // value if no feedback was ever processed.
64
53
  std::optional<int64_t> lastFeedbackBaseTimeUs;
65
- // Sequence number the latest packet reported on resolved into, or no
66
- // value if no feedback was ever processed.
67
- std::optional<int64_t> lastUnwrappedSequenceNumber;
68
54
  };
69
55
  } // namespace BWE
70
56
  } // namespace RTC
@@ -0,0 +1,117 @@
1
+ #ifndef MS_RTC_BWE_INTER_ARRIVAL_HPP
2
+ #define MS_RTC_BWE_INTER_ARRIVAL_HPP
3
+
4
+ #include "common.hpp"
5
+
6
+ namespace RTC
7
+ {
8
+ namespace BWE
9
+ {
10
+ /**
11
+ * Groups received packets into send bursts and computes the deltas between
12
+ * two consecutive bursts.
13
+ *
14
+ * It does the same job as `InterArrivalDelta` but on the receiving side,
15
+ * where the instant a packet was sent is not known: all there is is a
16
+ * timestamp of the sender's own, carried by the packet, which wraps around
17
+ * and whose tick is whatever the sender decided. So groups are formed by
18
+ * that timestamp instead of by a real instant, and telling which of two
19
+ * timestamps is the later one has to account for the wrap.
20
+ *
21
+ * The computed deltas are the input of the overuse estimator: if the arrival
22
+ * delta grows faster than the send delta then queues are building up
23
+ * somewhere in the network.
24
+ */
25
+ class InterArrival
26
+ {
27
+ public:
28
+ /**
29
+ * Deltas between two consecutive groups of packets sent in a burst.
30
+ */
31
+ struct Deltas
32
+ {
33
+ /**
34
+ * Ticks elapsed between the send timestamps of both groups.
35
+ */
36
+ uint32_t timestampDelta;
37
+
38
+ /**
39
+ * Time elapsed between the arrival times of both groups (us).
40
+ */
41
+ int64_t arrivalDeltaUs;
42
+
43
+ /**
44
+ * Difference of size between both groups (bytes).
45
+ */
46
+ int64_t sizeDelta;
47
+ };
48
+
49
+ private:
50
+ struct TimestampGroup
51
+ {
52
+ bool IsFirstPacket() const
53
+ {
54
+ return !this->completeTimeUs.has_value();
55
+ }
56
+
57
+ size_t size{ 0 };
58
+ uint32_t firstTimestamp{ 0 };
59
+ uint32_t timestamp{ 0 };
60
+ int64_t firstArrivalTimeUs{ 0 };
61
+ std::optional<int64_t> completeTimeUs;
62
+ int64_t lastSystemTimeUs{ 0 };
63
+ };
64
+
65
+ public:
66
+ /**
67
+ * @param timestampGroupLengthTicks - Every packet whose timestamp is
68
+ * within this many ticks of the first packet of a group belongs to that
69
+ * group.
70
+ * @param timestampToUsCoeff - Microseconds a single tick of those
71
+ * timestamps is worth.
72
+ */
73
+ InterArrival(uint32_t timestampGroupLengthTicks, double timestampToUsCoeff);
74
+
75
+ /**
76
+ * Feed a received packet.
77
+ *
78
+ * @param timestamp - Timestamp the packet carries, in the sender's own
79
+ * units, which wraps around.
80
+ * @param arrivalTimeUs - Time at which the packet arrived.
81
+ * @param systemTimeUs - Time, in our own clock reference, at which the
82
+ * packet is being fed. It's used to detect that the timestamps have
83
+ * jumped by comparing how much they advanced against how much our clock
84
+ * did.
85
+ * @param packetSize - Size of the packet (bytes).
86
+ *
87
+ * @returns The deltas between the two latest complete groups, or no value
88
+ * if they cannot be computed yet.
89
+ */
90
+ std::optional<Deltas> ComputeDeltas(
91
+ uint32_t timestamp, int64_t arrivalTimeUs, int64_t systemTimeUs, size_t packetSize);
92
+
93
+ private:
94
+ /**
95
+ * Whether the given timestamp is not older than the first one of the
96
+ * current group, so that a packet that got reordered on its way here
97
+ * doesn't close a group it doesn't belong to.
98
+ */
99
+ bool IsPacketInOrder(uint32_t timestamp) const;
100
+
101
+ bool IsNewTimestampGroup(int64_t arrivalTimeUs, uint32_t timestamp) const;
102
+
103
+ bool BelongsToBurst(int64_t arrivalTimeUs, uint32_t timestamp) const;
104
+
105
+ void Reset();
106
+
107
+ private:
108
+ const uint32_t timestampGroupLengthTicks;
109
+ const double timestampToUsCoeff;
110
+ TimestampGroup currentGroup;
111
+ TimestampGroup prevGroup;
112
+ size_t numConsecutiveReorderedGroups{ 0 };
113
+ };
114
+ } // namespace BWE
115
+ } // namespace RTC
116
+
117
+ #endif