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
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include "RTC/BWE/AimdRateControl.hpp"
5
5
  #include "Logger.hpp"
6
+ #include "RTC/Consts.hpp"
6
7
  #include <cmath>
7
8
 
8
9
  namespace RTC
@@ -21,8 +22,6 @@ namespace RTC
21
22
  // Bounds of how often the bitrate may be reduced, derived from the RTT.
22
23
  static constexpr int64_t MinBitrateReductionIntervalUs{ 10 * 1000 };
23
24
  static constexpr int64_t MaxBitrateReductionIntervalUs{ 200 * 1000 };
24
- // Bitrate the target is never taken below unless configured otherwise (bps).
25
- static constexpr int64_t CongestionControllerMinBitrate{ 5000 };
26
25
  // Bitrate the target starts from before anything has been measured (bps).
27
26
  static constexpr int64_t MaxConfiguredBitrate{ 30000 * 1000 };
28
27
  // Headroom allowed on top of the measured throughput when increasing (bps).
@@ -64,7 +63,7 @@ namespace RTC
64
63
 
65
64
  AimdRateControl::AimdRateControl(AimdRateControlOptions options)
66
65
  : options(options),
67
- minConfiguredBitrate(CongestionControllerMinBitrate),
66
+ minConfiguredBitrate(Consts::BweMinBitrate),
68
67
  maxConfiguredBitrate(MaxConfiguredBitrate),
69
68
  currentBitrate(this->maxConfiguredBitrate),
70
69
  latestEstimatedThroughput(this->currentBitrate),
@@ -358,7 +357,7 @@ namespace RTC
358
357
  break;
359
358
  }
360
359
 
361
- NO_DEFAULT_GCC();
360
+ NO_DEFAULT();
362
361
  }
363
362
 
364
363
  this->currentBitrate = ClampBitrate(newBitrate.value_or(this->currentBitrate));
@@ -398,7 +397,7 @@ namespace RTC
398
397
  break;
399
398
  }
400
399
 
401
- NO_DEFAULT_GCC();
400
+ NO_DEFAULT();
402
401
  }
403
402
  }
404
403
 
@@ -0,0 +1,80 @@
1
+ #define MS_CLASS "RTC::BWE::AlrDetector"
2
+ // #define MS_LOG_DEV_LEVEL 3
3
+
4
+ #include "RTC/BWE/AlrDetector.hpp"
5
+ #include "Logger.hpp"
6
+ #include "RTC/BWE/BitrateUtils.hpp"
7
+
8
+ namespace RTC
9
+ {
10
+ namespace BWE
11
+ {
12
+ /* Instance methods. */
13
+
14
+ AlrDetector::AlrDetector(SharedInterface* shared) : AlrDetector(shared, AlrDetectorOptions{})
15
+ {
16
+ MS_TRACE();
17
+ }
18
+
19
+ AlrDetector::AlrDetector(SharedInterface* shared, AlrDetectorOptions options)
20
+ : shared(shared),
21
+ options(options),
22
+ // What an interval leaves unspent builds up, since not filling the link
23
+ // is precisely a state that has to accumulate to be noticed.
24
+ alrBudget(/*initialTargetBitrate*/ 0, /*canBuildUpUnderuse*/ true)
25
+ {
26
+ MS_TRACE();
27
+ }
28
+
29
+ void AlrDetector::OnBytesSent(int64_t bytesSent, int64_t sentAtUs)
30
+ {
31
+ MS_TRACE();
32
+
33
+ // How long those bytes took to go out is unknown until there is a previous
34
+ // send to measure them against.
35
+ if (!this->lastSentAtUs.has_value())
36
+ {
37
+ this->lastSentAtUs = sentAtUs;
38
+
39
+ return;
40
+ }
41
+
42
+ const int64_t deltaTimeUs = sentAtUs - this->lastSentAtUs.value();
43
+
44
+ this->lastSentAtUs = sentAtUs;
45
+
46
+ this->alrBudget.UseBudget(bytesSent);
47
+ this->alrBudget.IncreaseBudget(deltaTimeUs);
48
+
49
+ const double budgetRatio = this->alrBudget.GetBudgetRatio();
50
+
51
+ if (budgetRatio > this->options.startBudgetLevelRatio && !this->alrStartTimeUs.has_value())
52
+ {
53
+ // The instant this state began is what the rest of the module reasons
54
+ // about, so it's the current one and not that of the send that revealed
55
+ // it.
56
+ this->alrStartTimeUs = this->shared->GetTimeUs();
57
+
58
+ MS_DEBUG_DEV("sender is not filling the link [budgetRatio:%f]", budgetRatio);
59
+ }
60
+ else if (budgetRatio < this->options.stopBudgetLevelRatio && this->alrStartTimeUs.has_value())
61
+ {
62
+ this->alrStartTimeUs.reset();
63
+
64
+ MS_DEBUG_DEV("sender is filling the link again [budgetRatio:%f]", budgetRatio);
65
+ }
66
+ }
67
+
68
+ void AlrDetector::SetEstimatedBitrate(int64_t bitrate)
69
+ {
70
+ MS_TRACE();
71
+
72
+ // NOTE: The target this comes from is clamped to the minimum bitrate of
73
+ // the congestion controller, so anything else is a programming error.
74
+ MS_ASSERT(bitrate > 0, "bitrate must be positive [bitrate:%" PRIi64 "]", bitrate);
75
+
76
+ this->alrBudget.SetTargetBitrate(
77
+ BitrateUtils::ApplyBitrateFactor(bitrate, this->options.bandwidthUsageRatio));
78
+ }
79
+ } // namespace BWE
80
+ } // namespace RTC
@@ -0,0 +1,256 @@
1
+ #define MS_CLASS "RTC::BWE::BitrateProber"
2
+ // #define MS_LOG_DEV_LEVEL 3
3
+
4
+ #include "RTC/BWE/BitrateProber.hpp"
5
+ #include "Logger.hpp"
6
+
7
+ namespace RTC
8
+ {
9
+ namespace BWE
10
+ {
11
+ /* Static. */
12
+
13
+ // How long a burst that was asked for but never started is worth keeping.
14
+ static constexpr int64_t ProbeClusterTimeoutUs{ 5 * 1000 * 1000 };
15
+ // How many bursts may be waiting at once.
16
+ static constexpr size_t MaxPendingProbeClusters{ 5 };
17
+
18
+ /* Instance methods. */
19
+
20
+ BitrateProber::BitrateProber() : BitrateProber(BitrateProberOptions{})
21
+ {
22
+ MS_TRACE();
23
+ }
24
+
25
+ BitrateProber::BitrateProber(BitrateProberOptions options) : options(options)
26
+ {
27
+ MS_TRACE();
28
+ }
29
+
30
+ void BitrateProber::CreateProbeCluster(const Types::ProbeClusterConfig& clusterConfig)
31
+ {
32
+ MS_TRACE();
33
+
34
+ // NOTE: Whoever puts a burst configuration together already refuses a zero
35
+ // there, since it is what the bitrate of the burst is held over to decide
36
+ // how many bytes each of its shots carries.
37
+ MS_ASSERT(clusterConfig.minProbeDeltaUs > 0, "no time between packets of the burst");
38
+
39
+ // Whatever was asked for long ago is not worth sending anymore, and only so
40
+ // many may be waiting at once.
41
+ while (!this->clusters.empty() &&
42
+ (clusterConfig.atUs - this->clusters.front().requestedAtUs > ProbeClusterTimeoutUs ||
43
+ this->clusters.size() > MaxPendingProbeClusters))
44
+ {
45
+ this->clusters.pop();
46
+ }
47
+
48
+ Cluster cluster;
49
+
50
+ cluster.probeCluster.id = clusterConfig.id;
51
+ cluster.probeCluster.minProbes = clusterConfig.targetProbeCount;
52
+ // The bytes the burst is meant to carry are its bitrate held for as long as
53
+ // it is meant to last, rounded to the nearest byte.
54
+ cluster.probeCluster.minBytes =
55
+ ((clusterConfig.targetBitrate * clusterConfig.targetDurationUs) + 4000000) / (8 * 1000000);
56
+ cluster.sendBitrate = clusterConfig.targetBitrate;
57
+ cluster.minProbeDeltaUs = clusterConfig.minProbeDeltaUs;
58
+ cluster.requestedAtUs = clusterConfig.atUs;
59
+
60
+ MS_ASSERT(cluster.probeCluster.minBytes >= 0, "burst of a negative count of bytes");
61
+
62
+ this->clusters.push(cluster);
63
+
64
+ MaybeSetActiveState(/*packetSize*/ 0);
65
+
66
+ MS_DEBUG_DEV(
67
+ "probe cluster created [id:%" PRIi64 ", bitrate:%" PRIi64 ", minBytes:%" PRIi64
68
+ ", minProbes:%" PRIi64 ", active:%s]",
69
+ cluster.probeCluster.id,
70
+ cluster.sendBitrate,
71
+ cluster.probeCluster.minBytes,
72
+ cluster.probeCluster.minProbes,
73
+ this->state == State::ACTIVE ? "true" : "false");
74
+ }
75
+
76
+ std::optional<int64_t> BitrateProber::GetNextProbeTimeUs(int64_t nowUs) const
77
+ {
78
+ MS_TRACE();
79
+
80
+ // Nothing is being emitted, or everything asked for is already done.
81
+ if (this->state != State::ACTIVE || this->clusters.empty())
82
+ {
83
+ return std::nullopt;
84
+ }
85
+
86
+ // A burst that hasn't started goes out at the first chance there is.
87
+ return this->nextProbeTimeUs.value_or(nowUs);
88
+ }
89
+
90
+ std::optional<BitrateProber::CurrentCluster> BitrateProber::GetCurrentCluster(int64_t nowUs)
91
+ {
92
+ MS_TRACE();
93
+
94
+ if (this->clusters.empty() || this->state != State::ACTIVE)
95
+ {
96
+ return std::nullopt;
97
+ }
98
+
99
+ // A packet that goes out long after it was due no longer measures the
100
+ // bitrate the burst was meant to be sent at, so the whole burst is dropped
101
+ // rather than believed.
102
+ if (this->nextProbeTimeUs.has_value() && nowUs - this->nextProbeTimeUs.value() > this->options.maxProbeDelayUs)
103
+ {
104
+ MS_DEBUG_DEV(
105
+ "probe delayed too much, discarding the cluster [dueAt:%" PRIi64 ", now:%" PRIi64 "]",
106
+ this->nextProbeTimeUs.value(),
107
+ nowUs);
108
+
109
+ this->clusters.pop();
110
+
111
+ if (this->clusters.empty())
112
+ {
113
+ this->state = State::INACTIVE;
114
+
115
+ return std::nullopt;
116
+ }
117
+ }
118
+
119
+ const auto& cluster = this->clusters.front();
120
+
121
+ return CurrentCluster{ .probeCluster = cluster.probeCluster, .sentBytes = cluster.sentBytes };
122
+ }
123
+
124
+ size_t BitrateProber::GetRecommendedMinProbeSize() const
125
+ {
126
+ MS_TRACE();
127
+
128
+ if (this->clusters.empty())
129
+ {
130
+ return 0;
131
+ }
132
+
133
+ const auto& cluster = this->clusters.front();
134
+
135
+ // What the burst's bitrate carries over the time between two of its shots,
136
+ // rounded to the nearest byte.
137
+ return static_cast<size_t>(
138
+ ((cluster.sendBitrate * cluster.minProbeDeltaUs) + 4000000) / (8 * 1000000));
139
+ }
140
+
141
+ void BitrateProber::ProbeSent(int64_t nowUs, size_t size)
142
+ {
143
+ MS_TRACE();
144
+
145
+ // NOTE: Reporting a shot means one was asked for with GetCurrentCluster(),
146
+ // which only answers while a burst is being emitted, and that state is
147
+ // only left from within this class.
148
+ MS_ASSERT(this->state == State::ACTIVE, "no burst is being emitted");
149
+ // NOTE: A shot out of which no byte left is not reported at all, since
150
+ // there would be nothing to measure the burst with.
151
+ MS_ASSERT(size != 0, "a packet of no bytes was sent");
152
+
153
+ if (this->clusters.empty())
154
+ {
155
+ return;
156
+ }
157
+
158
+ auto& cluster = this->clusters.front();
159
+
160
+ if (cluster.sentProbes == 0)
161
+ {
162
+ MS_ASSERT(!cluster.startedAtUs.has_value(), "burst already started");
163
+
164
+ cluster.startedAtUs = nowUs;
165
+ }
166
+
167
+ cluster.sentBytes += static_cast<int64_t>(size);
168
+ cluster.sentProbes += 1;
169
+
170
+ this->nextProbeTimeUs = CalculateNextProbeTimeUs(cluster);
171
+
172
+ // Both counts have to be reached, since a burst of too few packets says
173
+ // nothing however many bytes it carried, and the other way round.
174
+ if (
175
+ cluster.sentBytes >= cluster.probeCluster.minBytes &&
176
+ cluster.sentProbes >= cluster.probeCluster.minProbes)
177
+ {
178
+ this->clusters.pop();
179
+ }
180
+
181
+ if (this->clusters.empty())
182
+ {
183
+ this->state = State::INACTIVE;
184
+ }
185
+ }
186
+
187
+ void BitrateProber::OnIncomingPacket(size_t packetSize)
188
+ {
189
+ MS_TRACE();
190
+
191
+ MaybeSetActiveState(packetSize);
192
+ }
193
+
194
+ void BitrateProber::MaybeSetActiveState(size_t packetSize)
195
+ {
196
+ MS_TRACE();
197
+
198
+ if (IsReadyToSetActiveState(packetSize))
199
+ {
200
+ this->nextProbeTimeUs.reset();
201
+ this->state = State::ACTIVE;
202
+ }
203
+ }
204
+
205
+ bool BitrateProber::IsReadyToSetActiveState(size_t packetSize) const
206
+ {
207
+ MS_TRACE();
208
+
209
+ if (this->clusters.empty())
210
+ {
211
+ MS_ASSERT(this->state == State::INACTIVE, "emitting a burst with none to emit");
212
+
213
+ return false;
214
+ }
215
+
216
+ switch (this->state)
217
+ {
218
+ case State::ACTIVE:
219
+ {
220
+ return false;
221
+ }
222
+
223
+ case State::INACTIVE:
224
+ {
225
+ if (this->options.allowStartProbingImmediately)
226
+ {
227
+ return true;
228
+ }
229
+
230
+ // A burst that begins on a tiny packet starts measuring from an instant
231
+ // that says nothing, so a big enough one has to go out first. What
232
+ // counts as big enough is never more than a whole shot of the burst.
233
+ return packetSize >= std::min(GetRecommendedMinProbeSize(), this->options.minPacketSize);
234
+ }
235
+ }
236
+
237
+ return false;
238
+ }
239
+
240
+ int64_t BitrateProber::CalculateNextProbeTimeUs(const Cluster& cluster) const
241
+ {
242
+ MS_TRACE();
243
+
244
+ MS_ASSERT(cluster.sendBitrate > 0, "burst at no bitrate");
245
+ MS_ASSERT(cluster.startedAtUs.has_value(), "burst has not started");
246
+
247
+ // Measured from the start of the burst rather than from the previous packet,
248
+ // so that a packet going out late is made up for by the ones after it
249
+ // instead of dragging the whole burst below the bitrate asked for.
250
+ const int64_t deltaUs = (cluster.sentBytes * 8 * 1000000) / cluster.sendBitrate;
251
+
252
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
253
+ return cluster.startedAtUs.value() + deltaUs;
254
+ }
255
+ } // namespace BWE
256
+ } // namespace RTC
@@ -0,0 +1,54 @@
1
+ #define MS_CLASS "RTC::BWE::BitrateUtils"
2
+ // #define MS_LOG_DEV_LEVEL 3
3
+
4
+ #include "RTC/BWE/BitrateUtils.hpp"
5
+ #include "Logger.hpp"
6
+ #include "RTC/BWE/BweTypes.hpp"
7
+ #include <cmath> // std::llround()
8
+
9
+ namespace RTC
10
+ {
11
+ namespace BWE
12
+ {
13
+ /* Class methods. */
14
+
15
+ int64_t BitrateUtils::ApplyBitrateFactor(int64_t bitrate, double factor)
16
+ {
17
+ MS_TRACE();
18
+
19
+ const double result = static_cast<double>(bitrate) * factor;
20
+
21
+ // NOTE: Converting a value that the type cannot hold is undefined
22
+ // behaviour, and the maximum bitrate is chosen by the application, so
23
+ // nothing keeps this product within range.
24
+ if (result >= static_cast<double>(Types::BitrateInfinite))
25
+ {
26
+ return Types::BitrateInfinite;
27
+ }
28
+
29
+ if (result <= 0.0)
30
+ {
31
+ return 0;
32
+ }
33
+
34
+ // The result is rounded rather than truncated, since a factor is applied
35
+ // over and over to a bitrate that keeps being derived from the previous
36
+ // one and always losing the fraction drifts it downwards.
37
+ return std::llround(result);
38
+ }
39
+
40
+ int64_t BitrateUtils::AddBitrates(int64_t bitrate, int64_t otherBitrate)
41
+ {
42
+ MS_TRACE();
43
+
44
+ // NOTE: Signed overflow is undefined behaviour, and both operands can be
45
+ // as high as the application allows.
46
+ if (bitrate > Types::BitrateInfinite - otherBitrate)
47
+ {
48
+ return Types::BitrateInfinite;
49
+ }
50
+
51
+ return bitrate + otherBitrate;
52
+ }
53
+ } // namespace BWE
54
+ } // namespace RTC
@@ -110,7 +110,7 @@ namespace RTC
110
110
 
111
111
  if (this->options.separateAudioPackets)
112
112
  {
113
- if (packetResult.sentPacket.audio)
113
+ if (packetResult.sentPacket.isAudio)
114
114
  {
115
115
  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
116
116
  delayDetectorForPacket = std::addressof(this->audioDelayDetector.value());
@@ -141,7 +141,7 @@ namespace RTC
141
141
  }
142
142
 
143
143
  auto& interArrivalForPacket =
144
- (this->options.separateAudioPackets && packetResult.sentPacket.audio)
144
+ (this->options.separateAudioPackets && packetResult.sentPacket.isAudio)
145
145
  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
146
146
  ? this->audioInterArrivalDelta.value()
147
147
  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
@@ -28,17 +28,6 @@ namespace RTC
28
28
  return std::nullopt;
29
29
  }
30
30
 
31
- const auto lastSequenceNumber = this->sendPacketHistory->GetLastSequenceNumber();
32
-
33
- if (!lastSequenceNumber.has_value())
34
- {
35
- MS_DEBUG_TAG(bwe, "feedback received before any packet was sent");
36
-
37
- return std::nullopt;
38
- }
39
-
40
- const int64_t lastSentSequenceNumber = lastSequenceNumber.value();
41
-
42
31
  const int64_t baseTimeUs = feedback->GetReferenceTimestampUs();
43
32
 
44
33
  if (!this->lastFeedbackBaseTimeUs.has_value())
@@ -47,6 +36,10 @@ namespace RTC
47
36
  }
48
37
  else
49
38
  {
39
+ // NOTE: Taken in microseconds and not quantized any further. The groups
40
+ // whose arrival times the delay detector compares are only a few
41
+ // milliseconds apart, so rounding them to whole milliseconds would be
42
+ // noise of the same order as the slope being measured.
50
43
  const int64_t baseDeltaUs = feedback->GetBaseDeltaUs(this->lastFeedbackBaseTimeUs.value());
51
44
 
52
45
  if (baseDeltaUs < -this->currentOffsetUs)
@@ -76,30 +69,35 @@ namespace RTC
76
69
 
77
70
  size_t failedLookups{ 0 };
78
71
 
79
- // Each packet is resolved against the one reported before it, since the
80
- // packets being sent may be far ahead of the ones the feedbacks report on.
81
- // The latest packet sent seeds it, and bounds it as well, since no report
82
- // can stand for a packet that was never sent.
83
- int64_t sequenceNumber = std::min(
84
- this->lastUnwrappedSequenceNumber.value_or(lastSentSequenceNumber), lastSentSequenceNumber);
85
-
86
72
  for (const auto& packetStatus : packetStatuses)
87
73
  {
88
- sequenceNumber = UnwrapSequenceNumber(packetStatus.sequenceNumber, sequenceNumber);
74
+ // The wire carries the sequence number of the transport truncated to 16
75
+ // bits, so it's the history, which handed it out, the one that knows
76
+ // which of its packets it stands for.
77
+ const int64_t sequenceNumber =
78
+ this->sendPacketHistory->UnwrapSequenceNumber(packetStatus.sequenceNumber);
89
79
 
90
- const auto sentPacket =
80
+ const auto retrievedEntry =
91
81
  this->sendPacketHistory->RetrievePacket(sequenceNumber, packetStatus.received);
92
82
 
93
- if (!sentPacket.has_value())
83
+ if (!retrievedEntry.has_value())
94
84
  {
95
85
  ++failedLookups;
96
86
 
97
87
  continue;
98
88
  }
99
89
 
90
+ const auto& entry = retrievedEntry.value();
91
+
100
92
  Types::PacketResult packetResult;
101
93
 
102
- packetResult.sentPacket = sentPacket.value();
94
+ packetResult.sentPacket = entry.sentPacket;
95
+ packetResult.rtpPacketInfo =
96
+ Types::PacketResult::RtpPacketInfo{ .ssrc = entry.ssrc,
97
+ .rtpSequenceNumber = entry.seq,
98
+ .isRetransmission = entry.isRetransmission };
99
+ packetResult.ambiguousReceiveTime = entry.ambiguousReceiveTime;
100
+ packetResult.sentWithEct1 = entry.sentWithEct1;
103
101
 
104
102
  if (packetStatus.received)
105
103
  {
@@ -110,8 +108,6 @@ namespace RTC
110
108
  transportPacketsFeedback.packetFeedbacks.push_back(packetResult);
111
109
  }
112
110
 
113
- this->lastUnwrappedSequenceNumber = sequenceNumber;
114
-
115
111
  if (failedLookups > 0)
116
112
  {
117
113
  MS_DEBUG_TAG(
@@ -131,18 +127,5 @@ namespace RTC
131
127
  return transportPacketsFeedback;
132
128
  }
133
129
 
134
- int64_t FeedbackAdapter::UnwrapSequenceNumber(
135
- uint16_t wideSequenceNumber, int64_t previousSequenceNumber)
136
- {
137
- MS_TRACE();
138
-
139
- // The wire carries the sequence number of the history truncated to 16 bits,
140
- // so the closest value to the previous one ending in those very same bits
141
- // is the one it stands for.
142
- const auto deltaSequenceNumber = static_cast<int16_t>(
143
- static_cast<uint16_t>(wideSequenceNumber - static_cast<uint16_t>(previousSequenceNumber)));
144
-
145
- return previousSequenceNumber + deltaSequenceNumber;
146
- }
147
130
  } // namespace BWE
148
131
  } // namespace RTC