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
@@ -8,6 +8,7 @@
8
8
  #include "RTC/RTCP/FeedbackRtpNack.hpp"
9
9
  #include "RTC/RTP/Codecs/Tools.hpp"
10
10
  #include "Utils.hpp"
11
+ #include <cmath> // std::round()
11
12
 
12
13
  namespace RTC
13
14
  {
@@ -72,7 +73,7 @@ namespace RTC
72
73
  {
73
74
  for (auto& temporalLayerCounter : spatialLayerCounter)
74
75
  {
75
- rate += temporalLayerCounter.GetBitrate(nowMs);
76
+ rate += temporalLayerCounter.GetBitrate(nowMs).value_or(0);
76
77
  }
77
78
  }
78
79
 
@@ -91,7 +92,7 @@ namespace RTC
91
92
  // Return 0 if specified layers are not being received.
92
93
  auto& counter = this->spatialLayerCounters[spatialLayer][temporalLayer];
93
94
 
94
- if (counter.GetBitrate(nowMs) <= 0)
95
+ if (counter.GetBitrate(nowMs).value_or(0) <= 0)
95
96
  {
96
97
  return 0;
97
98
  }
@@ -105,7 +106,7 @@ namespace RTC
105
106
  {
106
107
  auto& temporalLayerCounter = this->spatialLayerCounters[sIdx][tIdx];
107
108
 
108
- rate += temporalLayerCounter.GetBitrate(nowMs);
109
+ rate += temporalLayerCounter.GetBitrate(nowMs).value_or(0);
109
110
  }
110
111
  }
111
112
 
@@ -114,7 +115,7 @@ namespace RTC
114
115
  {
115
116
  auto& temporalLayerCounter = this->spatialLayerCounters[spatialLayer][tIdx];
116
117
 
117
- rate += temporalLayerCounter.GetBitrate(nowMs);
118
+ rate += temporalLayerCounter.GetBitrate(nowMs).value_or(0);
118
119
  }
119
120
 
120
121
  return rate;
@@ -132,7 +133,7 @@ namespace RTC
132
133
  {
133
134
  auto& temporalLayerCounter = this->spatialLayerCounters[spatialLayer][tIdx];
134
135
 
135
- rate += temporalLayerCounter.GetBitrate(nowMs);
136
+ rate += temporalLayerCounter.GetBitrate(nowMs).value_or(0);
136
137
  }
137
138
 
138
139
  return rate;
@@ -149,14 +150,14 @@ namespace RTC
149
150
 
150
151
  auto& counter = this->spatialLayerCounters[spatialLayer][temporalLayer];
151
152
 
152
- return counter.GetBitrate(nowMs);
153
+ return counter.GetBitrate(nowMs).value_or(0);
153
154
  }
154
155
 
155
- size_t RtpStreamRecv::TransmissionCounter::GetPacketCount() const
156
+ uint64_t RtpStreamRecv::TransmissionCounter::GetPacketCount() const
156
157
  {
157
158
  MS_TRACE();
158
159
 
159
- size_t packetCount{ 0 };
160
+ uint64_t packetCount{ 0 };
160
161
 
161
162
  for (const auto& spatialLayerCounter : this->spatialLayerCounters)
162
163
  {
@@ -169,11 +170,11 @@ namespace RTC
169
170
  return packetCount;
170
171
  }
171
172
 
172
- size_t RtpStreamRecv::TransmissionCounter::GetBytes() const
173
+ uint64_t RtpStreamRecv::TransmissionCounter::GetBytes() const
173
174
  {
174
175
  MS_TRACE();
175
176
 
176
- size_t bytes{ 0 };
177
+ uint64_t bytes{ 0 };
177
178
 
178
179
  for (const auto& spatialLayerCounter : this->spatialLayerCounters)
179
180
  {
@@ -281,7 +282,7 @@ namespace RTC
281
282
  this->transmissionCounter.GetPacketCount(),
282
283
  this->transmissionCounter.GetBytes(),
283
284
  static_cast<uint64_t>(this->transmissionCounter.GetBitrate(nowMs)),
284
- &bitrateByLayer);
285
+ std::addressof(bitrateByLayer));
285
286
 
286
287
  return FBS::RtpStream::CreateStats(builder, FBS::RtpStream::StatsData::RecvStats, stats.Union());
287
288
  }
@@ -345,7 +346,7 @@ namespace RTC
345
346
  //
346
347
  // capture NTP clock = sender NTP clock + capture clock offset
347
348
  const auto captureAtUs =
348
- Utils::Time::Ntp2TimeUs(ntp) - Utils::Time::Q32x32ToTimeUs(estimatedCaptureClockOffset);
349
+ Utils::Time::NtpToTimeUs(ntp) - Utils::Time::Q32x32ToTimeUs(estimatedCaptureClockOffset);
349
350
 
350
351
  // NOTE: A capture instant that is not positive means a capture clock offset
351
352
  // that cannot be true, so there is nothing to store.
@@ -532,9 +533,16 @@ namespace RTC
532
533
  // Calculate packets expected and lost.
533
534
  auto expected = GetExpectedPackets();
534
535
 
535
- if (expected > this->mediaTransmissionCounter.GetPacketCount())
536
+ // NOTE: The expected count is the extended sequence number arithmetic of RFC
537
+ // 3550, so it wraps at 32 bits, whereas the received one does not wrap at
538
+ // all. Each subtraction below is therefore made in the width that keeps it
539
+ // right: this one truncates the received count so that both wrap together,
540
+ // and the interval further down is taken in full width, where it is exact.
541
+ const auto received = static_cast<uint32_t>(this->mediaTransmissionCounter.GetPacketCount());
542
+
543
+ if (expected > received)
536
544
  {
537
- this->packetsLost = expected - this->mediaTransmissionCounter.GetPacketCount();
545
+ this->packetsLost = static_cast<int32_t>(expected - received);
538
546
  }
539
547
  else
540
548
  {
@@ -542,24 +550,31 @@ namespace RTC
542
550
  }
543
551
 
544
552
  // Calculate fraction lost.
545
- const uint32_t expectedInterval = expected - this->expectedPrior;
553
+ //
554
+ // NOTE: Reading the difference of the expected count as signed makes a
555
+ // sequence number re-sync, which restarts the count, come out negative.
556
+ const int64_t expectedInterval = static_cast<int32_t>(expected - this->expectedPrior);
546
557
 
547
558
  this->expectedPrior = expected;
548
559
 
549
- const uint32_t receivedInterval =
550
- this->mediaTransmissionCounter.GetPacketCount() - this->receivedPrior;
560
+ const auto receivedInterval =
561
+ static_cast<int64_t>(this->mediaTransmissionCounter.GetPacketCount() - this->receivedPrior);
551
562
 
552
563
  this->receivedPrior = this->mediaTransmissionCounter.GetPacketCount();
553
564
 
554
- const int32_t lostInterval = expectedInterval - receivedInterval;
565
+ const int64_t lostInterval = expectedInterval - receivedInterval;
555
566
 
556
- if (expectedInterval == 0 || lostInterval <= 0)
567
+ if (expectedInterval <= 0 || lostInterval <= 0)
557
568
  {
558
569
  this->fractionLost = 0;
559
570
  }
560
571
  else
561
572
  {
562
- this->fractionLost = std::round((static_cast<double>(lostInterval << 8) / expectedInterval));
573
+ // A fixed point number with 8 bits of fraction, so a whole interval lost
574
+ // gives 256, one more than the field can hold.
575
+ const double fraction = std::round(static_cast<double>(lostInterval << 8) / expectedInterval);
576
+
577
+ this->fractionLost = static_cast<uint8_t>(std::min(fraction, 255.0));
563
578
  }
564
579
 
565
580
  // Worst remote fraction lost is not worse than local one.
@@ -573,7 +588,11 @@ namespace RTC
573
588
  else
574
589
  {
575
590
  // Recalculate packetsLost.
576
- const uint32_t newLostInterval = (worstRemoteFractionLost * expectedInterval) >> 8;
591
+ //
592
+ // NOTE: The expected interval is not positive when a sequence number
593
+ // re-sync restarted the count, and then nothing was expected to be lost.
594
+ const auto newLostInterval = static_cast<uint32_t>(
595
+ (worstRemoteFractionLost * std::max<int64_t>(expectedInterval, 0)) >> 8);
577
596
 
578
597
  this->reportedPacketsLost += newLostInterval;
579
598
 
@@ -644,7 +663,7 @@ namespace RTC
644
663
  ntp.fractions = report->GetNtpFrac();
645
664
 
646
665
  this->lastSenderReportMapping = RTP::RtpStream::SenderReportMapping{
647
- .ntpUs = Utils::Time::Ntp2TimeUs(ntp),
666
+ .ntpUs = Utils::Time::NtpToTimeUs(ntp),
648
667
  .ts = report->GetRtpTs(),
649
668
  };
650
669
  }
@@ -672,7 +691,7 @@ namespace RTC
672
691
 
673
692
  // Get the NTP representation of the time at which the report arrived, which
674
693
  // is what the round trip is measured against.
675
- auto ntp = Utils::Time::TimeUs2Ntp(receivedAtUs + this->shared->GetNtpOffsetUs());
694
+ auto ntp = Utils::Time::TimeUsToNtp(receivedAtUs + this->shared->GetNtpOffsetUs());
676
695
 
677
696
  // Get the compact NTP representation of the arrival time.
678
697
  uint32_t compactNtp = (ntp.seconds & 0x0000FFFF) << 16;
@@ -682,21 +701,17 @@ namespace RTC
682
701
  const uint32_t lastRr = ssrcInfo->GetLastReceiverReport();
683
702
  const uint32_t dlrr = ssrcInfo->GetDelaySinceLastReceiverReport();
684
703
 
685
- // RTT in 1/2^16 second fractions.
686
- uint32_t rttCompactNtp{ 0 };
687
-
688
704
  // If no Receiver Extended Report was received by the remote endpoint yet,
689
- // ignore lastRr and dlrr values in the Sender Extended Report.
690
- if (lastRr && dlrr && (compactNtp > dlrr + lastRr))
705
+ // the Sender Extended Report carries no RTT, so the last one is kept.
706
+ if (lastRr == 0)
691
707
  {
692
- rttCompactNtp = compactNtp - dlrr - lastRr;
708
+ return;
693
709
  }
694
710
 
695
- this->rttMs = static_cast<float>(rttCompactNtp >> 16) * 1000;
696
- this->rttMs += (static_cast<float>(rttCompactNtp & 0x0000FFFF) / 65536) * 1000;
697
-
698
- // Avoid negative RTT value since it doesn't make sense.
699
- this->rttMs = std::max(this->rttMs, 0.0f);
711
+ // NOTE: The subtraction wraps around along with the compact NTP
712
+ // representation, which is what the conversion expects.
713
+ this->rttMs =
714
+ static_cast<float>(Utils::Time::CompactNtpRttToTimeUs(compactNtp - dlrr - lastRr)) / 1000;
700
715
 
701
716
  // Tell it to the NackGenerator.
702
717
  if (this->params.useNack)
@@ -798,7 +813,7 @@ namespace RTC
798
813
 
799
814
  // Notify the listener.
800
815
  static_cast<RTP::RtpStreamRecv::Listener*>(this->listener)
801
- ->OnRtpStreamSendRtcpPacket(this, &packet);
816
+ ->OnRtpStreamSendRtcpPacket(this, std::addressof(packet));
802
817
  }
803
818
  else if (this->params.useFir)
804
819
  {
@@ -816,7 +831,7 @@ namespace RTC
816
831
 
817
832
  // Notify the listener.
818
833
  static_cast<RTP::RtpStreamRecv::Listener*>(this->listener)
819
- ->OnRtpStreamSendRtcpPacket(this, &packet);
834
+ ->OnRtpStreamSendRtcpPacket(this, std::addressof(packet));
820
835
  }
821
836
  }
822
837
 
@@ -869,8 +884,10 @@ namespace RTC
869
884
  static_cast<uint32_t>(((receivedAtUs % 1000000) * GetClockRate()) / 1000000);
870
885
 
871
886
  // NOTE: Based on https://github.com/versatica/mediasoup/issues/1018.
872
- auto transit = static_cast<int>(arrivalTs - rtpTimestamp);
873
- int d = transit - this->transit;
887
+ const auto transit = static_cast<int32_t>(arrivalTs - rtpTimestamp);
888
+ // NOTE: Wider than its operands because the difference of two int32_t does
889
+ // not fit in an int32_t, and neither would negating its lowest value.
890
+ int64_t d = static_cast<int64_t>(transit) - this->transit;
874
891
 
875
892
  // First transit calculation, save and return.
876
893
  if (this->transit == 0)
@@ -902,12 +919,12 @@ namespace RTC
902
919
 
903
920
  // Calculate number of packets received in this interval.
904
921
  const auto totalReceived = this->mediaTransmissionCounter.GetPacketCount();
905
- const uint32_t received = totalReceived - this->receivedPriorScore;
922
+ const auto received = totalReceived - this->receivedPriorScore;
906
923
 
907
924
  this->receivedPriorScore = totalReceived;
908
925
 
909
926
  // Calculate number of packets lost in this interval.
910
- uint32_t lost;
927
+ uint64_t lost;
911
928
 
912
929
  if (expected < received)
913
930
  {
@@ -920,13 +937,15 @@ namespace RTC
920
937
 
921
938
  // Calculate number of packets repaired in this interval.
922
939
  const auto totalRepaired = this->packetsRepaired;
923
- uint32_t repaired = totalRepaired - this->repairedPriorScore;
940
+
941
+ auto repaired = totalRepaired - this->repairedPriorScore;
924
942
 
925
943
  this->repairedPriorScore = totalRepaired;
926
944
 
927
945
  // Calculate number of packets retransmitted in this interval.
928
946
  const auto totatRetransmitted = this->packetsRetransmitted;
929
- uint32_t retransmitted = totatRetransmitted - this->retransmittedPriorScore;
947
+
948
+ auto retransmitted = totatRetransmitted - this->retransmittedPriorScore;
930
949
 
931
950
  this->retransmittedPriorScore = totatRetransmitted;
932
951
 
@@ -958,8 +977,10 @@ namespace RTC
958
977
  {
959
978
  if (HasRtx())
960
979
  {
961
- repaired = lost;
980
+ // NOTE: The excess has to be discounted before clamping, since once
981
+ // `repaired` has been clamped there is no excess left to tell.
962
982
  retransmitted -= repaired - lost;
983
+ repaired = lost;
963
984
  }
964
985
  else
965
986
  {
@@ -970,15 +991,15 @@ namespace RTC
970
991
  #if MS_LOG_DEV_LEVEL == 3
971
992
  MS_DEBUG_TAG(
972
993
  score,
973
- "[totalExpected:%" PRIu32 ", totalReceived:%zu, totalRepaired:%zu",
994
+ "[totalExpected:%" PRIu32 ", totalReceived:%" PRIu64 ", totalRepaired:%" PRIu64,
974
995
  totalExpected,
975
996
  totalReceived,
976
997
  totalRepaired);
977
998
 
978
999
  MS_DEBUG_TAG(
979
1000
  score,
980
- "fixed values [expected:%" PRIu32 ", received:%" PRIu32 ", lost:%" PRIu32
981
- ", repaired:%" PRIu32 ", retransmitted:%" PRIu32,
1001
+ "fixed values [expected:%" PRIu32 ", received:%" PRIu64 ", lost:%" PRIu64
1002
+ ", repaired:%" PRIu64 ", retransmitted:%" PRIu64,
982
1003
  expected,
983
1004
  received,
984
1005
  lost,
@@ -996,7 +1017,7 @@ namespace RTC
996
1017
  repairedWeight *= static_cast<float>(repaired) / retransmitted;
997
1018
  }
998
1019
 
999
- lost -= repaired * repairedWeight;
1020
+ lost = static_cast<uint64_t>(lost - (repaired * repairedWeight));
1000
1021
 
1001
1022
  auto deliveredRatio = static_cast<float>(received - lost) / static_cast<float>(received);
1002
1023
  auto score = static_cast<uint8_t>(std::round(std::pow(deliveredRatio, 4) * 10));
@@ -1004,7 +1025,7 @@ namespace RTC
1004
1025
  #if MS_LOG_DEV_LEVEL == 3
1005
1026
  MS_DEBUG_TAG(
1006
1027
  score,
1007
- "[deliveredRatio:%f, repairedRatio:%f, repairedWeight:%f, new lost:%" PRIu32
1028
+ "[deliveredRatio:%f, repairedRatio:%f, repairedWeight:%f, new lost:%" PRIu64
1008
1029
  ", score:%" PRIu8 "]",
1009
1030
  deliveredRatio,
1010
1031
  repairedRatio,
@@ -84,7 +84,7 @@ namespace RTC
84
84
  baseStats,
85
85
  this->transmissionCounter.GetPacketCount(),
86
86
  this->transmissionCounter.GetBytes(),
87
- static_cast<uint64_t>(this->transmissionCounter.GetBitrate(nowMs)));
87
+ static_cast<uint64_t>(this->transmissionCounter.GetBitrate(nowMs).value_or(0)));
88
88
 
89
89
  return FBS::RtpStream::CreateStats(builder, FBS::RtpStream::StatsData::SendStats, stats.Union());
90
90
  }
@@ -280,7 +280,7 @@ namespace RTC
280
280
 
281
281
  // Get the NTP representation of the time at which the Receiver Report
282
282
  // arrived, which is what the round trip is measured against.
283
- auto ntp = Utils::Time::TimeUs2Ntp(receivedAtUs + this->shared->GetNtpOffsetUs());
283
+ auto ntp = Utils::Time::TimeUsToNtp(receivedAtUs + this->shared->GetNtpOffsetUs());
284
284
 
285
285
  // Get the compact NTP representation of the arrival time.
286
286
  uint32_t compactNtp = (ntp.seconds & 0x0000FFFF) << 16;
@@ -290,22 +290,17 @@ namespace RTC
290
290
  const uint32_t lastSr = report->GetLastSenderReport();
291
291
  const uint32_t dlsr = report->GetDelaySinceLastSenderReport();
292
292
 
293
- // RTT in 1/2^16 second fractions.
294
- uint32_t rttCompactNtp{ 0 };
295
-
296
- // If no Sender Report was received by the remote endpoint yet, ignore lastSr
297
- // and dlsr values in the Receiver Report.
298
- if (lastSr && dlsr && (compactNtp > dlsr + lastSr))
293
+ // If no Sender Report was received by the remote endpoint yet, the Receiver
294
+ // Report carries no RTT, so the last one is kept.
295
+ //
296
+ // NOTE: The subtraction wraps around along with the compact NTP
297
+ // representation, which is what the conversion expects.
298
+ if (lastSr != 0)
299
299
  {
300
- rttCompactNtp = compactNtp - dlsr - lastSr;
300
+ this->rttMs =
301
+ static_cast<float>(Utils::Time::CompactNtpRttToTimeUs(compactNtp - dlsr - lastSr)) / 1000;
301
302
  }
302
303
 
303
- this->rttMs = static_cast<float>(rttCompactNtp >> 16) * 1000;
304
- this->rttMs += (static_cast<float>(rttCompactNtp & 0x0000FFFF) / 65536) * 1000;
305
-
306
- // Avoid negative RTT value since it doesn't make sense.
307
- this->rttMs = std::max(this->rttMs, 0.0f);
308
-
309
304
  this->packetsLost = report->GetTotalLost();
310
305
  this->fractionLost = report->GetFractionLost();
311
306
  this->jitter = static_cast<float>(report->GetJitter());
@@ -345,7 +340,7 @@ namespace RTC
345
340
  return nullptr;
346
341
  }
347
342
 
348
- auto ntp = Utils::Time::TimeUs2Ntp(nowUs + this->shared->GetNtpOffsetUs());
343
+ auto ntp = Utils::Time::TimeUsToNtp(nowUs + this->shared->GetNtpOffsetUs());
349
344
  auto* report = new RTC::RTCP::SenderReport();
350
345
 
351
346
  // Calculate TS difference between now and the instant at which the media in the
@@ -358,8 +353,10 @@ namespace RTC
358
353
  const auto rtpTs = static_cast<uint32_t>(this->maxPacketTs + diffTs);
359
354
 
360
355
  report->SetSsrc(GetSsrc());
361
- report->SetPacketCount(this->transmissionCounter.GetPacketCount());
362
- report->SetOctetCount(this->transmissionCounter.GetBytes());
356
+ // NOTE: Both fields are 32 bits wide and are meant to wrap, so the counters
357
+ // are truncated into them on purpose.
358
+ report->SetPacketCount(static_cast<uint32_t>(this->transmissionCounter.GetPacketCount()));
359
+ report->SetOctetCount(static_cast<uint32_t>(this->transmissionCounter.GetBytes()));
363
360
  report->SetNtpSec(ntp.seconds);
364
361
  report->SetNtpFrac(ntp.fractions);
365
362
  report->SetRtpTs(rtpTs);
@@ -486,7 +483,7 @@ namespace RTC
486
483
 
487
484
  // Look for each requested packet.
488
485
  const int64_t nowMs = this->shared->GetTimeMs();
489
- const int64_t rttMs = (this->rttMs > 0.0f ? this->rttMs : DefaultRttMs);
486
+ const int64_t rttMs = (this->rttMs > 0.0f ? static_cast<int64_t>(this->rttMs) : DefaultRttMs);
490
487
  uint16_t currentSeq = seq;
491
488
  bool requested{ true };
492
489
  size_t containerIdx{ 0 };
@@ -586,14 +583,15 @@ namespace RTC
586
583
  MS_TRACE();
587
584
 
588
585
  // Calculate number of packets sent in this interval.
589
- auto totalSent = this->transmissionCounter.GetPacketCount();
590
- auto sent = totalSent - this->sentPriorScore;
586
+ const auto totalSent = this->transmissionCounter.GetPacketCount();
587
+ const auto sent = totalSent - this->sentPriorScore;
591
588
 
592
589
  this->sentPriorScore = totalSent;
593
590
 
594
591
  // Calculate number of packets lost in this interval.
595
592
  const int32_t totalLost = report->GetTotalLost() > 0 ? report->GetTotalLost() : 0;
596
- uint32_t lost;
593
+
594
+ uint64_t lost;
597
595
 
598
596
  if (totalLost < this->lostPriorScore)
599
597
  {
@@ -607,14 +605,15 @@ namespace RTC
607
605
  this->lostPriorScore = totalLost;
608
606
 
609
607
  // Calculate number of packets repaired in this interval.
610
- auto totalRepaired = this->packetsRepaired;
611
- uint32_t repaired = totalRepaired - this->repairedPriorScore;
608
+ const auto totalRepaired = this->packetsRepaired;
609
+
610
+ auto repaired = totalRepaired - this->repairedPriorScore;
612
611
 
613
612
  this->repairedPriorScore = totalRepaired;
614
613
 
615
614
  // Calculate number of packets retransmitted in this interval.
616
- auto totatRetransmitted = this->packetsRetransmitted;
617
- const uint32_t retransmitted = totatRetransmitted - this->retransmittedPriorScore;
615
+ const auto totatRetransmitted = this->packetsRetransmitted;
616
+ const auto retransmitted = totatRetransmitted - this->retransmittedPriorScore;
618
617
 
619
618
  this->retransmittedPriorScore = totatRetransmitted;
620
619
 
@@ -626,20 +625,21 @@ namespace RTC
626
625
  return;
627
626
  }
628
627
 
629
- lost = std::min<size_t>(lost, sent);
628
+ lost = std::min(lost, sent);
630
629
  repaired = std::min(repaired, lost);
631
630
 
632
631
  #if MS_LOG_DEV_LEVEL == 3
633
632
  MS_DEBUG_TAG(
634
633
  score,
635
- "[totalSent:%zu, totalLost:%" PRIi32 ", totalRepaired:%zu",
634
+ "[totalSent:%" PRIu64 ", totalLost:%" PRIi32 ", totalRepaired:%" PRIu64,
636
635
  totalSent,
637
636
  totalLost,
638
637
  totalRepaired);
639
638
 
640
639
  MS_DEBUG_TAG(
641
640
  score,
642
- "fixed values [sent:%zu, lost:%" PRIu32 ", repaired:%" PRIu32 ", retransmitted:%" PRIu32,
641
+ "fixed values [sent:%" PRIu64 ", lost:%" PRIu64 ", repaired:%" PRIu64
642
+ ", retransmitted:%" PRIu64,
643
643
  sent,
644
644
  lost,
645
645
  repaired,
@@ -656,7 +656,7 @@ namespace RTC
656
656
  repairedWeight *= static_cast<float>(repaired) / retransmitted;
657
657
  }
658
658
 
659
- lost -= repaired * repairedWeight;
659
+ lost = static_cast<uint64_t>(lost - (repaired * repairedWeight));
660
660
 
661
661
  auto deliveredRatio = static_cast<float>(sent - lost) / static_cast<float>(sent);
662
662
  auto score = static_cast<uint8_t>(std::round(std::pow(deliveredRatio, 4) * 10));
@@ -664,7 +664,7 @@ namespace RTC
664
664
  #if MS_LOG_DEV_LEVEL == 3
665
665
  MS_DEBUG_TAG(
666
666
  score,
667
- "[deliveredRatio:%f, repairedRatio:%f, repairedWeight:%f, new lost:%" PRIu32
667
+ "[deliveredRatio:%f, repairedRatio:%f, repairedWeight:%f, new lost:%" PRIu64
668
668
  ", score:%" PRIu8 "]",
669
669
  deliveredRatio,
670
670
  repairedRatio,
@@ -4,6 +4,7 @@
4
4
  #include "RTC/RTP/RtxStream.hpp"
5
5
  #include "Logger.hpp"
6
6
  #include "Utils.hpp"
7
+ #include <cmath> // std::round()
7
8
 
8
9
  namespace RTC
9
10
  {
@@ -96,9 +97,16 @@ namespace RTC
96
97
  // Calculate packets xxpected and lost.
97
98
  auto expected = GetExpectedPackets();
98
99
 
99
- if (expected > this->packetsCount)
100
+ // NOTE: The expected count is the extended sequence number arithmetic of RFC
101
+ // 3550, so it wraps at 32 bits, whereas the received one does not wrap at
102
+ // all. Each subtraction below is therefore made in the width that keeps it
103
+ // right: this one truncates the received count so that both wrap together,
104
+ // and the interval further down is taken in full width, where it is exact.
105
+ const auto received = static_cast<uint32_t>(this->packetsCount);
106
+
107
+ if (expected > received)
100
108
  {
101
- this->packetsLost = expected - this->packetsCount;
109
+ this->packetsLost = static_cast<int32_t>(expected - received);
102
110
  }
103
111
  else
104
112
  {
@@ -106,23 +114,30 @@ namespace RTC
106
114
  }
107
115
 
108
116
  // Calculate fraction lost.
109
- const uint32_t expectedInterval = expected - this->expectedPrior;
117
+ //
118
+ // NOTE: Reading the difference of the expected count as signed makes a
119
+ // sequence number re-sync, which restarts the count, come out negative.
120
+ const int64_t expectedInterval = static_cast<int32_t>(expected - this->expectedPrior);
110
121
 
111
122
  this->expectedPrior = expected;
112
123
 
113
- const uint32_t receivedInterval = this->packetsCount - this->receivedPrior;
124
+ const auto receivedInterval = static_cast<int64_t>(this->packetsCount - this->receivedPrior);
114
125
 
115
126
  this->receivedPrior = this->packetsCount;
116
127
 
117
- const int32_t lostInterval = expectedInterval - receivedInterval;
128
+ const int64_t lostInterval = expectedInterval - receivedInterval;
118
129
 
119
- if (expectedInterval == 0 || lostInterval <= 0)
130
+ if (expectedInterval <= 0 || lostInterval <= 0)
120
131
  {
121
132
  this->fractionLost = 0;
122
133
  }
123
134
  else
124
135
  {
125
- this->fractionLost = std::round((static_cast<double>(lostInterval << 8) / expectedInterval));
136
+ // A fixed point number with 8 bits of fraction, so a whole interval lost
137
+ // gives 256, one more than the field can hold.
138
+ const double fraction = std::round(static_cast<double>(lostInterval << 8) / expectedInterval);
139
+
140
+ this->fractionLost = static_cast<uint8_t>(std::min(fraction, 255.0));
126
141
  }
127
142
 
128
143
  this->reportedPacketsLost += (this->packetsLost - prevPacketsLost);