mediasoup 3.27.0 → 3.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/node/lib/Consumer.d.ts.map +1 -1
  3. package/node/lib/Consumer.js +4 -51
  4. package/node/lib/Producer.d.ts.map +1 -1
  5. package/node/lib/Producer.js +4 -8
  6. package/node/lib/ProducerTypes.d.ts +4 -2
  7. package/node/lib/ProducerTypes.d.ts.map +1 -1
  8. package/node/lib/Router.d.ts.map +1 -1
  9. package/node/lib/Router.js +4 -0
  10. package/node/lib/Transport.d.ts.map +1 -1
  11. package/node/lib/Transport.js +7 -10
  12. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts +3 -4
  13. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts.map +1 -1
  14. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.js +3 -4
  15. package/node/lib/ortc.d.ts +0 -2
  16. package/node/lib/ortc.d.ts.map +1 -1
  17. package/node/lib/ortc.js +11 -21
  18. package/node/lib/rtpMappingFbsUtils.d.ts +6 -0
  19. package/node/lib/rtpMappingFbsUtils.d.ts.map +1 -0
  20. package/node/lib/rtpMappingFbsUtils.js +65 -0
  21. package/node/lib/rtpParametersFbsUtils.d.ts.map +1 -1
  22. package/node/lib/rtpParametersFbsUtils.js +0 -6
  23. package/node/lib/rtpParametersTypes.d.ts +1 -1
  24. package/node/lib/rtpParametersTypes.d.ts.map +1 -1
  25. package/node/lib/rtpStreamFbsUtils.d.ts +4 -0
  26. package/node/lib/rtpStreamFbsUtils.d.ts.map +1 -0
  27. package/node/lib/rtpStreamFbsUtils.js +51 -0
  28. package/node/lib/supportedRtpCapabilities.d.ts.map +1 -1
  29. package/node/lib/supportedRtpCapabilities.js +6 -13
  30. package/node/lib/test/test-Consumer.js +1 -13
  31. package/node/lib/test/test-DataConsumer.js +9 -0
  32. package/node/lib/test/test-DataProducer.js +38 -0
  33. package/node/lib/test/test-PipeTransport.js +27 -29
  34. package/node/lib/test/test-Producer.js +97 -0
  35. package/node/lib/test/test-ortc.js +34 -14
  36. package/package.json +10 -10
  37. package/worker/fbs/FBS/meson.build +25 -0
  38. package/worker/fbs/meson.build +15 -18
  39. package/worker/fbs/rtpParameters.fbs +0 -1
  40. package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
  41. package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
  42. package/worker/include/DepLibUV.hpp +13 -0
  43. package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
  44. package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
  45. package/worker/include/RTC/BWE/BitrateUtils.hpp +39 -0
  46. package/worker/include/RTC/BWE/BweTypes.hpp +171 -3
  47. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
  48. package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
  49. package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
  50. package/worker/include/RTC/BWE/LossBasedController.hpp +625 -0
  51. package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
  52. package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
  53. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
  54. package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
  55. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
  56. package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
  57. package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
  58. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
  59. package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
  60. package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
  61. package/worker/include/RTC/BWE/TargetRateController.hpp +306 -0
  62. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
  63. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +73 -16
  64. package/worker/include/RTC/Consts.hpp +70 -0
  65. package/worker/include/RTC/DataConsumer.hpp +3 -5
  66. package/worker/include/RTC/DirectTransport.hpp +4 -5
  67. package/worker/include/RTC/PipeTransport.hpp +4 -5
  68. package/worker/include/RTC/PlainTransport.hpp +4 -5
  69. package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
  70. package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
  71. package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
  72. package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
  73. package/worker/include/RTC/RTP/Packet.hpp +16 -4
  74. package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
  75. package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
  76. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
  77. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
  78. package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
  79. package/worker/include/RTC/RateCalculator.hpp +103 -24
  80. package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
  81. package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
  82. package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
  83. package/worker/include/RTC/RtpDictionaries.hpp +3 -4
  84. package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
  85. package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +36 -0
  86. package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
  87. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +9 -9
  88. package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
  89. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +11 -1
  90. package/worker/include/RTC/SctpDictionaries.hpp +2 -2
  91. package/worker/include/RTC/TcpConnection.hpp +2 -1
  92. package/worker/include/RTC/Transport.hpp +23 -8
  93. package/worker/include/RTC/TransportTuple.hpp +61 -6
  94. package/worker/include/RTC/WebRtcTransport.hpp +4 -5
  95. package/worker/include/Shared.hpp +5 -0
  96. package/worker/include/SharedInterface.hpp +10 -0
  97. package/worker/include/Utils.hpp +72 -3
  98. package/worker/include/common.hpp +12 -4
  99. package/worker/include/handles/SendCallbacks.hpp +34 -0
  100. package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
  101. package/worker/include/handles/UdpSocketHandle.hpp +4 -8
  102. package/worker/meson.build +45 -1
  103. package/worker/meson_options.txt +1 -0
  104. package/worker/mocks/include/MockShared.hpp +16 -2
  105. package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
  106. package/worker/scripts/package-lock.json +6 -6
  107. package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
  108. package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
  109. package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
  110. package/worker/src/RTC/BWE/BitrateUtils.cpp +54 -0
  111. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
  112. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
  113. package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
  114. package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
  115. package/worker/src/RTC/BWE/LossBasedController.cpp +1194 -0
  116. package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
  117. package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
  118. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
  119. package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
  120. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
  121. package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
  122. package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
  123. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
  124. package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
  125. package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
  126. package/worker/src/RTC/BWE/TargetRateController.cpp +433 -0
  127. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
  128. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +102 -5
  129. package/worker/src/RTC/Consumer.cpp +7 -5
  130. package/worker/src/RTC/DataConsumer.cpp +8 -10
  131. package/worker/src/RTC/DirectTransport.cpp +14 -8
  132. package/worker/src/RTC/DtlsTransport.cpp +8 -8
  133. package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
  134. package/worker/src/RTC/ICE/IceServer.cpp +1 -1
  135. package/worker/src/RTC/PipeTransport.cpp +13 -8
  136. package/worker/src/RTC/PlainTransport.cpp +13 -8
  137. package/worker/src/RTC/Producer.cpp +14 -31
  138. package/worker/src/RTC/RTCP/Bye.cpp +1 -1
  139. package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
  140. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
  141. package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
  142. package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
  143. package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
  144. package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
  145. package/worker/src/RTC/RTP/Packet.cpp +26 -11
  146. package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
  147. package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
  148. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
  149. package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
  150. package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
  151. package/worker/src/RTC/RateCalculator.cpp +133 -28
  152. package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
  153. package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
  154. package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
  155. package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
  156. package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
  157. package/worker/src/RTC/SCTP/association/Association.cpp +16 -2
  158. package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +106 -1
  159. package/worker/src/RTC/SCTP/public/AssociationMetrics.cpp +1 -1
  160. package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
  161. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  162. package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
  163. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
  164. package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
  165. package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
  166. package/worker/src/RTC/SrtpSession.cpp +2 -2
  167. package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
  168. package/worker/src/RTC/TcpConnection.cpp +2 -2
  169. package/worker/src/RTC/Transport.cpp +112 -75
  170. package/worker/src/RTC/TransportTuple.cpp +4 -4
  171. package/worker/src/RTC/WebRtcServer.cpp +4 -3
  172. package/worker/src/RTC/WebRtcTransport.cpp +20 -13
  173. package/worker/src/Utils/BitStream.cpp +24 -0
  174. package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
  175. package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
  176. package/worker/src/handles/UdpSocketHandle.cpp +14 -21
  177. package/worker/tasks.py +43 -18
  178. package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
  179. package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
  180. package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
  181. package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
  182. package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
  183. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
  184. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
  185. package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
  186. package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
  187. package/worker/test/src/RTC/BWE/TestLossBasedController.cpp +1199 -0
  188. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
  189. package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
  190. package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
  191. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
  192. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
  193. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
  194. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
  195. package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
  196. package/worker/test/src/RTC/BWE/TestTargetRateController.cpp +337 -0
  197. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
  198. package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +45 -0
  199. package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
  200. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
  201. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
  202. package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
  203. package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
  204. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
  205. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
  206. package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +111 -0
  207. package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
  208. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
  209. package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
  210. package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
  211. package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
  212. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
  213. package/worker/test/src/Utils/TestTime.cpp +120 -21
@@ -0,0 +1,643 @@
1
+ #include "common.hpp"
2
+ #include "RTC/BWE/InterArrival.hpp"
3
+ #include <catch2/catch_test_macros.hpp>
4
+
5
+ SCENARIO("BWE InterArrival", "[bwe][interarrival]")
6
+ {
7
+ constexpr int64_t TimestampGroupLengthUs{ 5000 };
8
+ constexpr int64_t MinStepUs{ 20 };
9
+ constexpr int64_t TriggerNewGroupUs{ TimestampGroupLengthUs + MinStepUs };
10
+ constexpr int64_t BurstThresholdMs{ 5 };
11
+ constexpr int AbsSendTimeFraction{ 18 };
12
+ constexpr int AbsSendTimeInterArrivalUpshift{ 8 };
13
+ constexpr int InterArrivalShift{ AbsSendTimeFraction + AbsSendTimeInterArrivalUpshift };
14
+ constexpr double RtpTimestampToUs{ 1000.0 / 90.0 };
15
+ constexpr double AbsSendTimeToUs{ 1000000.0 / static_cast<double>(1 << InterArrivalShift) };
16
+ // NOTE: Both are private to the class, so they are repeated here.
17
+ constexpr int64_t ArrivalTimeOffsetThresholdMs{ 3000 };
18
+ constexpr size_t ReorderedResetThreshold{ 3 };
19
+
20
+ // The given instant, expressed as an RTP timestamp of a 90 kHz clock.
21
+ const auto makeRtpTimestamp = [](int64_t us) -> uint32_t
22
+ {
23
+ return static_cast<uint32_t>(static_cast<uint64_t>((us * 90) + 500) / 1000);
24
+ };
25
+
26
+ // The same, as the abs-send-time the estimator works with: 24 bits of a 6.18
27
+ // fixed point value, shifted up to use the whole 32 bits.
28
+ const auto makeAbsSendTime = [](int64_t us) -> uint32_t
29
+ {
30
+ const uint32_t absSendTime =
31
+ static_cast<uint32_t>(((static_cast<uint64_t>(us) << 18) + 500000) / 1000000) & 0x00FFFFFF;
32
+
33
+ return absSendTime << 8;
34
+ };
35
+
36
+ // The two instances that every case drives at once, one on each kind of
37
+ // timestamp, so that what is asserted holds however the sender counts time.
38
+ RTC::BWE::InterArrival interArrivalRtp(makeRtpTimestamp(TimestampGroupLengthUs), RtpTimestampToUs);
39
+ RTC::BWE::InterArrival interArrivalAst(makeAbsSendTime(TimestampGroupLengthUs), AbsSendTimeToUs);
40
+ // And one whose timestamps are plain milliseconds, for the cases that don't
41
+ // care about how they are encoded.
42
+ RTC::BWE::InterArrival interArrival(TimestampGroupLengthUs / 1000, 1000.0);
43
+
44
+ // Neither instance closes a group with the given packet.
45
+ const auto expectFalse = [&interArrivalRtp, &interArrivalAst, &makeRtpTimestamp, &makeAbsSendTime](
46
+ int64_t timestampUs, int64_t arrivalTimeMs, size_t packetSize) -> void
47
+ {
48
+ REQUIRE(!interArrivalRtp
49
+ .ComputeDeltas(
50
+ makeRtpTimestamp(timestampUs), arrivalTimeMs * 1000, arrivalTimeMs * 1000, packetSize)
51
+ .has_value());
52
+ REQUIRE(!interArrivalAst
53
+ .ComputeDeltas(
54
+ makeAbsSendTime(timestampUs), arrivalTimeMs * 1000, arrivalTimeMs * 1000, packetSize)
55
+ .has_value());
56
+ };
57
+
58
+ // Both instances close a group with the given packet, and its deltas are the
59
+ // expected ones.
60
+ //
61
+ // NOTE: The timestamp delta is compared within a tolerance because rounding
62
+ // the very same instant into each kind of timestamp lands on different ticks.
63
+ const auto expectTrue = [&interArrivalRtp, &interArrivalAst, &makeRtpTimestamp, &makeAbsSendTime](
64
+ int64_t timestampUs,
65
+ int64_t arrivalTimeMs,
66
+ size_t packetSize,
67
+ int64_t expectedTimestampDeltaUs,
68
+ int64_t expectedArrivalDeltaMs,
69
+ int64_t expectedSizeDelta,
70
+ uint32_t timestampNear) -> void
71
+ {
72
+ const auto expectDeltas = [](
73
+ const std::optional<RTC::BWE::InterArrival::Deltas>& deltas,
74
+ uint32_t expectedTimestampDelta,
75
+ int64_t expectedArrivalDeltaUs,
76
+ int64_t expectedSizeDelta,
77
+ uint32_t timestampNear) -> void
78
+ {
79
+ REQUIRE(deltas.has_value());
80
+
81
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
82
+ const auto& value = deltas.value();
83
+ const uint32_t timestampDiff = value.timestampDelta > expectedTimestampDelta
84
+ ? value.timestampDelta - expectedTimestampDelta
85
+ : expectedTimestampDelta - value.timestampDelta;
86
+
87
+ REQUIRE(timestampDiff <= timestampNear);
88
+ REQUIRE(value.arrivalDeltaUs == expectedArrivalDeltaUs);
89
+ REQUIRE(value.sizeDelta == expectedSizeDelta);
90
+ };
91
+
92
+ expectDeltas(
93
+ interArrivalRtp.ComputeDeltas(
94
+ makeRtpTimestamp(timestampUs), arrivalTimeMs * 1000, arrivalTimeMs * 1000, packetSize),
95
+ makeRtpTimestamp(expectedTimestampDeltaUs),
96
+ expectedArrivalDeltaMs * 1000,
97
+ expectedSizeDelta,
98
+ timestampNear);
99
+ expectDeltas(
100
+ interArrivalAst.ComputeDeltas(
101
+ makeAbsSendTime(timestampUs), arrivalTimeMs * 1000, arrivalTimeMs * 1000, packetSize),
102
+ makeAbsSendTime(expectedTimestampDeltaUs),
103
+ expectedArrivalDeltaMs * 1000,
104
+ expectedSizeDelta,
105
+ timestampNear << 8);
106
+ };
107
+
108
+ // Walk the timestamps across the point where they wrap around, a quarter of
109
+ // their range at a time so that no packet is taken as reordered just for
110
+ // being near it.
111
+ const auto wrapTestHelper =
112
+ [&expectFalse,
113
+ &expectTrue](int64_t wrapStartUs, uint32_t timestampNear, bool unorderlyWithinGroup) -> void
114
+ {
115
+ // G1.
116
+ int64_t arrivalTime = 17;
117
+
118
+ expectFalse(0, arrivalTime, 1);
119
+
120
+ // G2.
121
+ arrivalTime += BurstThresholdMs + 1;
122
+
123
+ expectFalse(wrapStartUs / 4, arrivalTime, 1);
124
+
125
+ // G3.
126
+ arrivalTime += BurstThresholdMs + 1;
127
+
128
+ // Delta G2-G1.
129
+ expectTrue(wrapStartUs / 2, arrivalTime, 1, wrapStartUs / 4, 6, 0, 0);
130
+
131
+ // G4.
132
+ arrivalTime += BurstThresholdMs + 1;
133
+
134
+ const int64_t g4ArrivalTime = arrivalTime;
135
+
136
+ // Delta G3-G2.
137
+ expectTrue(
138
+ (wrapStartUs / 2) + (wrapStartUs / 4), arrivalTime, 1, wrapStartUs / 4, 6, 0, timestampNear);
139
+
140
+ // G5.
141
+ arrivalTime += BurstThresholdMs + 1;
142
+
143
+ // Delta G4-G3.
144
+ expectTrue(wrapStartUs, arrivalTime, 2, wrapStartUs / 4, 6, 0, timestampNear);
145
+
146
+ for (int64_t i{ 0 }; i < 10; ++i)
147
+ {
148
+ // Slowly step across the wrap point.
149
+ arrivalTime += BurstThresholdMs + 1;
150
+
151
+ if (unorderlyWithinGroup)
152
+ {
153
+ // These packets arrive with timestamps in decreasing order but are
154
+ // accumulated into the group anyway, because they are still higher than
155
+ // the one the group began with.
156
+ expectFalse(wrapStartUs + (MinStepUs * (9 - i)), arrivalTime, 1);
157
+ }
158
+ else
159
+ {
160
+ expectFalse(wrapStartUs + (MinStepUs * i), arrivalTime, 1);
161
+ }
162
+ }
163
+
164
+ const int64_t g5ArrivalTime = arrivalTime;
165
+
166
+ // This packet is out of order and is dropped.
167
+ arrivalTime += BurstThresholdMs + 1;
168
+
169
+ expectFalse(wrapStartUs - 100, arrivalTime, 100);
170
+
171
+ // G6.
172
+ arrivalTime += BurstThresholdMs + 1;
173
+
174
+ const int64_t g6ArrivalTime = arrivalTime;
175
+
176
+ // Delta G5-G4.
177
+ expectTrue(
178
+ wrapStartUs + TriggerNewGroupUs,
179
+ arrivalTime,
180
+ 10,
181
+ (wrapStartUs / 4) + (9 * MinStepUs),
182
+ g5ArrivalTime - g4ArrivalTime,
183
+ (2 + 10) - 1,
184
+ timestampNear);
185
+
186
+ // This packet is out of order and is dropped.
187
+ arrivalTime += BurstThresholdMs + 1;
188
+
189
+ expectFalse(wrapStartUs + TimestampGroupLengthUs, arrivalTime, 100);
190
+
191
+ // G7.
192
+ arrivalTime += BurstThresholdMs + 1;
193
+
194
+ // Delta G6-G5.
195
+ expectTrue(
196
+ wrapStartUs + (2 * TriggerNewGroupUs),
197
+ arrivalTime,
198
+ 100,
199
+ TriggerNewGroupUs - (9 * MinStepUs),
200
+ g6ArrivalTime - g5ArrivalTime,
201
+ 10 - (2 + 10),
202
+ timestampNear);
203
+ };
204
+
205
+ SECTION("the very first packet closes no group")
206
+ {
207
+ expectFalse(0, 17, 1);
208
+ }
209
+
210
+ SECTION("the first group is only closed by the packet that starts the third one")
211
+ {
212
+ // G1.
213
+ int64_t arrivalTime = 17;
214
+
215
+ const int64_t g1ArrivalTime = arrivalTime;
216
+
217
+ expectFalse(0, arrivalTime, 1);
218
+
219
+ // G2.
220
+ arrivalTime += BurstThresholdMs + 1;
221
+
222
+ const int64_t g2ArrivalTime = arrivalTime;
223
+
224
+ expectFalse(TriggerNewGroupUs, arrivalTime, 2);
225
+
226
+ // G3. Only once the first packet of the third group arrives do the deltas
227
+ // between the first two show up.
228
+ arrivalTime += BurstThresholdMs + 1;
229
+
230
+ expectTrue(
231
+ 2 * TriggerNewGroupUs, arrivalTime, 1, TriggerNewGroupUs, g2ArrivalTime - g1ArrivalTime, 1, 0);
232
+ }
233
+
234
+ SECTION("each group is closed by the one that follows it")
235
+ {
236
+ // G1.
237
+ int64_t arrivalTime = 17;
238
+
239
+ const int64_t g1ArrivalTime = arrivalTime;
240
+
241
+ expectFalse(0, arrivalTime, 1);
242
+
243
+ // G2.
244
+ arrivalTime += BurstThresholdMs + 1;
245
+
246
+ const int64_t g2ArrivalTime = arrivalTime;
247
+
248
+ expectFalse(TriggerNewGroupUs, arrivalTime, 2);
249
+
250
+ // G3.
251
+ arrivalTime += BurstThresholdMs + 1;
252
+
253
+ const int64_t g3ArrivalTime = arrivalTime;
254
+
255
+ expectTrue(
256
+ 2 * TriggerNewGroupUs, arrivalTime, 1, TriggerNewGroupUs, g2ArrivalTime - g1ArrivalTime, 1, 0);
257
+
258
+ // G4. The first packet of the fourth group yields the deltas between the
259
+ // second and the third.
260
+ arrivalTime += BurstThresholdMs + 1;
261
+
262
+ expectTrue(
263
+ 3 * TriggerNewGroupUs, arrivalTime, 2, TriggerNewGroupUs, g3ArrivalTime - g2ArrivalTime, -1, 0);
264
+ }
265
+
266
+ SECTION("a group accumulates every packet whose timestamp falls within it")
267
+ {
268
+ // G1.
269
+ int64_t arrivalTime = 17;
270
+
271
+ const int64_t g1ArrivalTime = arrivalTime;
272
+
273
+ expectFalse(0, arrivalTime, 1);
274
+
275
+ // G2.
276
+ arrivalTime += BurstThresholdMs + 1;
277
+
278
+ expectFalse(TriggerNewGroupUs, 28, 2);
279
+
280
+ int64_t timestamp = TriggerNewGroupUs;
281
+
282
+ for (int64_t i{ 0 }; i < 10; ++i)
283
+ {
284
+ // A bunch of packets arriving within the same group.
285
+ arrivalTime += BurstThresholdMs + 1;
286
+ timestamp += MinStepUs;
287
+
288
+ expectFalse(timestamp, arrivalTime, 1);
289
+ }
290
+
291
+ const int64_t g2ArrivalTime = arrivalTime;
292
+ const int64_t g2Timestamp = timestamp;
293
+
294
+ // G3.
295
+ arrivalTime = 500;
296
+
297
+ // Delta G2-G1.
298
+ expectTrue(
299
+ 2 * TriggerNewGroupUs,
300
+ arrivalTime,
301
+ 100,
302
+ g2Timestamp,
303
+ g2ArrivalTime - g1ArrivalTime,
304
+ (2 + 10) - 1,
305
+ 0);
306
+ }
307
+
308
+ SECTION("a packet older than the group it arrives into is dropped")
309
+ {
310
+ // G1.
311
+ int64_t arrivalTime = 17;
312
+ int64_t timestamp = 0;
313
+
314
+ expectFalse(timestamp, arrivalTime, 1);
315
+
316
+ const int64_t g1Timestamp = timestamp;
317
+ const int64_t g1ArrivalTime = arrivalTime;
318
+
319
+ // G2.
320
+ arrivalTime += 11;
321
+ timestamp += TriggerNewGroupUs;
322
+
323
+ expectFalse(timestamp, 28, 2);
324
+
325
+ for (int64_t i{ 0 }; i < 10; ++i)
326
+ {
327
+ arrivalTime += BurstThresholdMs + 1;
328
+ timestamp += MinStepUs;
329
+
330
+ expectFalse(timestamp, arrivalTime, 1);
331
+ }
332
+
333
+ const int64_t g2Timestamp = timestamp;
334
+ const int64_t g2ArrivalTime = arrivalTime;
335
+
336
+ // This packet is out of order and is dropped.
337
+ arrivalTime = 281;
338
+
339
+ expectFalse(g1Timestamp, arrivalTime, 100);
340
+
341
+ // G3.
342
+ arrivalTime = 500;
343
+ timestamp = 2 * TriggerNewGroupUs;
344
+
345
+ // Delta G2-G1.
346
+ expectTrue(
347
+ timestamp,
348
+ arrivalTime,
349
+ 100,
350
+ g2Timestamp - g1Timestamp,
351
+ g2ArrivalTime - g1ArrivalTime,
352
+ (2 + 10) - 1,
353
+ 0);
354
+ }
355
+
356
+ SECTION("packets whose timestamps go backwards still join the group they belong to")
357
+ {
358
+ // G1.
359
+ int64_t arrivalTime = 17;
360
+ int64_t timestamp = 0;
361
+
362
+ expectFalse(timestamp, arrivalTime, 1);
363
+
364
+ const int64_t g1Timestamp = timestamp;
365
+ const int64_t g1ArrivalTime = arrivalTime;
366
+
367
+ // G2.
368
+ timestamp += TriggerNewGroupUs;
369
+ arrivalTime += 11;
370
+
371
+ expectFalse(TriggerNewGroupUs, 28, 2);
372
+
373
+ timestamp += 10 * MinStepUs;
374
+
375
+ const int64_t g2Timestamp = timestamp;
376
+
377
+ for (int64_t i{ 0 }; i < 10; ++i)
378
+ {
379
+ // These arrive with timestamps in decreasing order but are accumulated
380
+ // into the group anyway, because they are still higher than the one it
381
+ // began with.
382
+ arrivalTime += BurstThresholdMs + 1;
383
+
384
+ expectFalse(timestamp, arrivalTime, 1);
385
+
386
+ timestamp -= MinStepUs;
387
+ }
388
+
389
+ const int64_t g2ArrivalTime = arrivalTime;
390
+
391
+ // This one, however, is older than the group and is dropped.
392
+ arrivalTime = 281;
393
+ timestamp = g1Timestamp;
394
+
395
+ expectFalse(timestamp, arrivalTime, 100);
396
+
397
+ // G3.
398
+ timestamp = 2 * TriggerNewGroupUs;
399
+ arrivalTime = 500;
400
+
401
+ expectTrue(
402
+ timestamp,
403
+ arrivalTime,
404
+ 100,
405
+ g2Timestamp - g1Timestamp,
406
+ g2ArrivalTime - g1ArrivalTime,
407
+ (2 + 10) - 1,
408
+ 0);
409
+ }
410
+
411
+ SECTION("packets arriving in a burst make up a single group")
412
+ {
413
+ // G1.
414
+ const int64_t g1ArrivalTime = 17;
415
+
416
+ expectFalse(0, g1ArrivalTime, 1);
417
+
418
+ // G2.
419
+ int64_t timestamp = TriggerNewGroupUs;
420
+ // Simulate no packets arriving for 100 ms.
421
+ int64_t arrivalTime = 100;
422
+
423
+ for (int64_t i{ 0 }; i < 10; ++i)
424
+ {
425
+ // A bunch of packets arriving in one burst, within 5 ms of each other.
426
+ timestamp += 30000;
427
+ arrivalTime += BurstThresholdMs;
428
+
429
+ expectFalse(timestamp, arrivalTime, 1);
430
+ }
431
+
432
+ const int64_t g2ArrivalTime = arrivalTime;
433
+ const int64_t g2Timestamp = timestamp;
434
+
435
+ // G3.
436
+ timestamp += 30000;
437
+ arrivalTime += BurstThresholdMs + 1;
438
+
439
+ // Delta G2-G1.
440
+ expectTrue(timestamp, arrivalTime, 100, g2Timestamp, g2ArrivalTime - g1ArrivalTime, 10 - 1, 0);
441
+ }
442
+
443
+ SECTION("packets spaced further apart than the burst threshold make up their own groups")
444
+ {
445
+ // G1.
446
+ expectFalse(0, 17, 1);
447
+
448
+ // G2.
449
+ const int64_t timestamp = TriggerNewGroupUs;
450
+ const int64_t arrivalTime = 28;
451
+
452
+ expectFalse(timestamp, arrivalTime, 2);
453
+
454
+ // G3. Delta G2-G1.
455
+ expectTrue(
456
+ TriggerNewGroupUs + 30000,
457
+ arrivalTime + BurstThresholdMs + 1,
458
+ 100,
459
+ timestamp - 0,
460
+ arrivalTime - 17,
461
+ 2 - 1,
462
+ 0);
463
+ }
464
+
465
+ // NOTE: Each of these instants lands on 0xfffffffe once turned into its kind
466
+ // of timestamp, so the walk below crosses the wrap around.
467
+ constexpr int64_t StartRtpTimestampWrapUs{ 47721858827 };
468
+ constexpr int64_t StartAbsSendTimeWrapUs{ 63999995 };
469
+
470
+ SECTION("RTP timestamps wrapping around")
471
+ {
472
+ wrapTestHelper(StartRtpTimestampWrapUs, 1, false);
473
+ }
474
+
475
+ SECTION("abs-send-time wrapping around")
476
+ {
477
+ wrapTestHelper(StartAbsSendTimeWrapUs, 1, false);
478
+ }
479
+
480
+ SECTION("RTP timestamps wrapping around with a group whose timestamps go backwards")
481
+ {
482
+ wrapTestHelper(StartRtpTimestampWrapUs, 1, true);
483
+ }
484
+
485
+ SECTION("abs-send-time wrapping around with a group whose timestamps go backwards")
486
+ {
487
+ wrapTestHelper(StartAbsSendTimeWrapUs, 1, true);
488
+ }
489
+
490
+ SECTION("the arrival times jumping forward resets everything")
491
+ {
492
+ constexpr size_t PacketSize{ 1000 };
493
+ constexpr int64_t TimeDeltaMs{ 30 };
494
+
495
+ int64_t sendTimeMs = 10000;
496
+ int64_t arrivalTimeMs = 20000;
497
+ int64_t systemTimeMs = 30000;
498
+
499
+ REQUIRE(
500
+ !interArrival
501
+ .ComputeDeltas(
502
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize)
503
+ .has_value());
504
+
505
+ sendTimeMs += TimeDeltaMs;
506
+ arrivalTimeMs += TimeDeltaMs;
507
+ systemTimeMs += TimeDeltaMs;
508
+
509
+ REQUIRE(
510
+ !interArrival
511
+ .ComputeDeltas(
512
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize)
513
+ .has_value());
514
+
515
+ sendTimeMs += TimeDeltaMs;
516
+ arrivalTimeMs += TimeDeltaMs + ArrivalTimeOffsetThresholdMs;
517
+ systemTimeMs += TimeDeltaMs;
518
+
519
+ auto deltas = interArrival.ComputeDeltas(
520
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize);
521
+
522
+ REQUIRE(deltas.has_value());
523
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
524
+ REQUIRE(deltas.value().timestampDelta == TimeDeltaMs);
525
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
526
+ REQUIRE(deltas.value().arrivalDeltaUs == TimeDeltaMs * 1000);
527
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
528
+ REQUIRE(deltas.value().sizeDelta == 0);
529
+
530
+ sendTimeMs += TimeDeltaMs;
531
+ arrivalTimeMs += TimeDeltaMs;
532
+ systemTimeMs += TimeDeltaMs;
533
+
534
+ // The jump of the previous arrival time is detected now and causes a reset.
535
+ REQUIRE(
536
+ !interArrival
537
+ .ComputeDeltas(
538
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize)
539
+ .has_value());
540
+
541
+ // The two packets that follow give no deltas, since everything starts over.
542
+ for (int64_t i{ 0 }; i < 2; ++i)
543
+ {
544
+ sendTimeMs += TimeDeltaMs;
545
+ arrivalTimeMs += TimeDeltaMs;
546
+ systemTimeMs += TimeDeltaMs;
547
+
548
+ REQUIRE(
549
+ !interArrival
550
+ .ComputeDeltas(
551
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize)
552
+ .has_value());
553
+ }
554
+
555
+ sendTimeMs += TimeDeltaMs;
556
+ arrivalTimeMs += TimeDeltaMs;
557
+ systemTimeMs += TimeDeltaMs;
558
+
559
+ deltas = interArrival.ComputeDeltas(
560
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize);
561
+
562
+ REQUIRE(deltas.has_value());
563
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
564
+ REQUIRE(deltas.value().timestampDelta == TimeDeltaMs);
565
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
566
+ REQUIRE(deltas.value().arrivalDeltaUs == TimeDeltaMs * 1000);
567
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
568
+ REQUIRE(deltas.value().sizeDelta == 0);
569
+ }
570
+
571
+ SECTION("the arrival times jumping backwards resets everything")
572
+ {
573
+ constexpr size_t PacketSize{ 1000 };
574
+ constexpr int64_t TimeDeltaMs{ 30 };
575
+
576
+ int64_t sendTimeMs = 10000;
577
+ int64_t arrivalTimeMs = 20000;
578
+ int64_t systemTimeMs = 30000;
579
+
580
+ REQUIRE(
581
+ !interArrival
582
+ .ComputeDeltas(
583
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize)
584
+ .has_value());
585
+
586
+ sendTimeMs += TimeDeltaMs;
587
+ arrivalTimeMs += TimeDeltaMs;
588
+ systemTimeMs += TimeDeltaMs;
589
+
590
+ REQUIRE(
591
+ !interArrival
592
+ .ComputeDeltas(
593
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize)
594
+ .has_value());
595
+
596
+ sendTimeMs += TimeDeltaMs;
597
+ arrivalTimeMs += TimeDeltaMs;
598
+ systemTimeMs += TimeDeltaMs;
599
+
600
+ auto deltas = interArrival.ComputeDeltas(
601
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize);
602
+
603
+ REQUIRE(deltas.has_value());
604
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
605
+ REQUIRE(deltas.value().timestampDelta == TimeDeltaMs);
606
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
607
+ REQUIRE(deltas.value().arrivalDeltaUs == TimeDeltaMs * 1000);
608
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
609
+ REQUIRE(deltas.value().sizeDelta == 0);
610
+
611
+ // Three groups arriving out of order give nothing, and after the reset two
612
+ // more are needed before the first valid deltas show up again.
613
+ arrivalTimeMs -= 1000;
614
+
615
+ for (size_t i{ 0 }; i < ReorderedResetThreshold + 3; ++i)
616
+ {
617
+ sendTimeMs += TimeDeltaMs;
618
+ arrivalTimeMs += TimeDeltaMs;
619
+ systemTimeMs += TimeDeltaMs;
620
+
621
+ REQUIRE(
622
+ !interArrival
623
+ .ComputeDeltas(
624
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize)
625
+ .has_value());
626
+ }
627
+
628
+ sendTimeMs += TimeDeltaMs;
629
+ arrivalTimeMs += TimeDeltaMs;
630
+ systemTimeMs += TimeDeltaMs;
631
+
632
+ deltas = interArrival.ComputeDeltas(
633
+ static_cast<uint32_t>(sendTimeMs), arrivalTimeMs * 1000, systemTimeMs * 1000, PacketSize);
634
+
635
+ REQUIRE(deltas.has_value());
636
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
637
+ REQUIRE(deltas.value().timestampDelta == TimeDeltaMs);
638
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
639
+ REQUIRE(deltas.value().arrivalDeltaUs == TimeDeltaMs * 1000);
640
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
641
+ REQUIRE(deltas.value().sizeDelta == 0);
642
+ }
643
+ }