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
@@ -1,7 +1,8 @@
1
1
  #include "common.hpp"
2
2
  #include "RTC/RateCalculator.hpp"
3
3
  #include <catch2/catch_test_macros.hpp>
4
- #include <limits> // std::numeric_limits
4
+ #include <cstdlib> // std::abs()
5
+ #include <limits> // std::numeric_limits
5
6
  #include <vector>
6
7
 
7
8
  SCENARIO("RateCalculator", "[rate-calculator]")
@@ -10,7 +11,7 @@ SCENARIO("RateCalculator", "[rate-calculator]")
10
11
  {
11
12
  int64_t offset;
12
13
  uint32_t size;
13
- uint32_t rate;
14
+ std::optional<int64_t> rate;
14
15
  };
15
16
 
16
17
  auto validate =
@@ -23,23 +24,249 @@ SCENARIO("RateCalculator", "[rate-calculator]")
23
24
  REQUIRE(rate.GetRate(timeBaseMs + item.offset) == item.rate);
24
25
  }
25
26
 
26
- // Repeat asking for the rate at a time older than the whole window, which
27
- // must leave it untouched.
27
+ // Repeat asking for the rate at a time older than the whole window. There is
28
+ // no period between the samples and a time that precedes all of them, so
29
+ // there is nothing to measure.
28
30
  rate.Reset();
29
31
 
30
32
  for (const auto& item : input)
31
33
  {
32
34
  rate.Update(item.size, timeBaseMs + item.offset);
33
35
 
34
- REQUIRE(rate.GetRate(item.offset) == item.rate);
36
+ REQUIRE(rate.GetRate(item.offset) == std::nullopt);
35
37
  }
36
38
 
39
+ // The reads above left the data untouched, so the rate at the time of the
40
+ // latest sample is still the one that was reported for it.
41
+ REQUIRE(rate.GetRate(timeBaseMs + input.back().offset) == input.back().rate);
42
+
37
43
  // Asking for the rate far in the future expires every item.
38
- REQUIRE(rate.GetRate(std::numeric_limits<int64_t>::max()) == 0);
44
+ REQUIRE(rate.GetRate(std::numeric_limits<int64_t>::max()) == std::nullopt);
39
45
  };
40
46
 
41
47
  const int64_t nowMs = 12345678;
42
48
 
49
+ // NOTE: This pins the three states in which there is nothing to measure, and
50
+ // that a lone sample does become a measurement once the window has filled
51
+ // around it.
52
+ SECTION("no rate until there is something to measure")
53
+ {
54
+ RTC::RateCalculator rate(1000, 8000, 100);
55
+
56
+ // Not a single sample.
57
+ REQUIRE(rate.GetRate(nowMs) == std::nullopt);
58
+
59
+ rate.Update(5, nowMs);
60
+
61
+ // A single sample taken at an instant says how much data there was, not how
62
+ // fast it is flowing.
63
+ REQUIRE(rate.GetRate(nowMs) == std::nullopt);
64
+ REQUIRE(rate.GetRate(nowMs + 500) == std::nullopt);
65
+
66
+ // Once the window has filled, that lone sample is all the data there was
67
+ // during a whole window, which is a rate.
68
+ REQUIRE(rate.GetRate(nowMs + 999) == 40);
69
+
70
+ // And one more item later it has expired, leaving nothing again.
71
+ REQUIRE(rate.GetRate(nowMs + 1000) == std::nullopt);
72
+ }
73
+
74
+ // NOTE: This pins the headline of the whole thing: the divisor is the period
75
+ // the samples span, not the window they sit in. Dividing by the window here
76
+ // would report 32 bps for a link carrying 16 kbps.
77
+ SECTION("rate is measured over the period the samples span")
78
+ {
79
+ RTC::RateCalculator rate(1000, 8000, 100);
80
+
81
+ rate.Update(1000, nowMs);
82
+ rate.Update(1000, nowMs + 999);
83
+
84
+ // The period is the whole window, so both samples count: 2000 * 8000 / 1000.
85
+ REQUIRE(rate.GetRate(nowMs + 999) == 16000);
86
+ }
87
+
88
+ // NOTE: The five sections below use a window of 500 ms split into items of a
89
+ // single millisecond, so that expiration happens sample by sample and every
90
+ // expected value can be worked out by hand.
91
+
92
+ SECTION("a lone sample is measured once the window has filled around it")
93
+ {
94
+ // window: 500ms, items: 500 (granularity: 1ms)
95
+ RTC::RateCalculator rate(500, 8000, 500);
96
+
97
+ REQUIRE(rate.GetRate(nowMs) == std::nullopt);
98
+
99
+ // One byte per millisecond, given as a single sample.
100
+ rate.Update(500, nowMs);
101
+
102
+ // Only one sample, and the window has not filled.
103
+ REQUIRE(rate.GetRate(nowMs + 498) == std::nullopt);
104
+
105
+ // Now it has, so the single sample is all the data of a whole window.
106
+ REQUIRE(rate.GetRate(nowMs + 499) == 1000 * 8);
107
+
108
+ // Another one on top doubles it.
109
+ rate.Update(500, nowMs + 499);
110
+
111
+ REQUIRE(rate.GetRate(nowMs + 499) == 2 * 1000 * 8);
112
+
113
+ // And now the first one drops out.
114
+ REQUIRE(rate.GetRate(nowMs + 500) == 1000 * 8);
115
+ }
116
+
117
+ SECTION("samples of size zero are measured as no data rather than no rate")
118
+ {
119
+ // window: 500ms, items: 500 (granularity: 1ms)
120
+ RTC::RateCalculator rate(500, 8000, 500);
121
+
122
+ REQUIRE(rate.GetRate(nowMs) == std::nullopt);
123
+
124
+ rate.Update(500, nowMs);
125
+ rate.Update(0, nowMs + 499);
126
+
127
+ REQUIRE(rate.GetRate(nowMs + 499) == 1000 * 8);
128
+
129
+ // The first sample drops out, leaving the empty one, which is a rate of
130
+ // zero rather than no rate at all.
131
+ REQUIRE(rate.GetRate(nowMs + 500) == 0);
132
+
133
+ // And now the empty one drops out too.
134
+ REQUIRE(rate.GetRate(nowMs + 1000) == std::nullopt);
135
+ }
136
+
137
+ SECTION("a quiet period is measured as no data until it empties the window")
138
+ {
139
+ // window: 500ms, items: 500 (granularity: 1ms)
140
+ RTC::RateCalculator rate(500, 8000, 500);
141
+
142
+ REQUIRE(rate.GetRate(nowMs) == std::nullopt);
143
+
144
+ rate.Update(0, nowMs);
145
+
146
+ REQUIRE(rate.GetRate(nowMs + 499) == 0);
147
+
148
+ // Move the window along so that the sample falls out.
149
+ REQUIRE(rate.GetRate(nowMs + 500) == std::nullopt);
150
+
151
+ // Move it a long way out, which makes the next sample start a new period.
152
+ rate.Update(0, nowMs + 1500);
153
+
154
+ REQUIRE(rate.GetRate(nowMs + 1500) == std::nullopt);
155
+
156
+ // The second one gives a period to measure over.
157
+ rate.Update(0, nowMs + 1501);
158
+
159
+ REQUIRE(rate.GetRate(nowMs + 1501) == 0);
160
+ }
161
+
162
+ SECTION("silence longer than the window starts a new period")
163
+ {
164
+ // window: 500ms, items: 500 (granularity: 1ms)
165
+ RTC::RateCalculator rate(500, 8000, 500);
166
+
167
+ // 1000 bytes per millisecond until the window has filled, which must not make
168
+ // the estimation error grow as the measured period is extended.
169
+ int64_t prevError{ 8000000 };
170
+ std::optional<int64_t> bitrate;
171
+
172
+ for (int64_t i{ 1 }; i < 10000; ++i)
173
+ {
174
+ rate.Update(1000, nowMs + i);
175
+
176
+ bitrate = rate.GetRate(nowMs + i);
177
+
178
+ if (bitrate.has_value())
179
+ {
180
+ const int64_t error = std::abs(8000000 - bitrate.value());
181
+
182
+ REQUIRE(error <= prevError + 1);
183
+
184
+ prevError = error;
185
+ }
186
+ }
187
+
188
+ REQUIRE(bitrate == 8000000);
189
+
190
+ // Silence over the window size, read during the silence.
191
+ REQUIRE(rate.GetRate(nowMs + 10500) == std::nullopt);
192
+
193
+ // So the samples that come next are measured over their own period, which is
194
+ // the 2ms they span, leaving out the one that starts it: 1000 * 8000 / 2.
195
+ rate.Update(1000, nowMs + 10500);
196
+ rate.Update(1000, nowMs + 10501);
197
+
198
+ REQUIRE(rate.GetRate(nowMs + 10501) == 4000000);
199
+
200
+ // A manual reset does the same.
201
+ rate.Reset();
202
+
203
+ REQUIRE(rate.GetRate(nowMs + 10501) == std::nullopt);
204
+
205
+ rate.Update(1000, nowMs + 10501);
206
+ rate.Update(1000, nowMs + 10502);
207
+
208
+ REQUIRE(rate.GetRate(nowMs + 10502) == 4000000);
209
+ }
210
+
211
+ // NOTE: This pins that data given with an instant that precedes the whole
212
+ // window is not lost. It is taken as if it had been given at the instant the
213
+ // newest item starts at, so it counts towards both the rate and the total.
214
+ SECTION("a sample older than the whole window still counts")
215
+ {
216
+ // window: 1000ms, items: 1000 (granularity: 1ms)
217
+ RTC::RateCalculator rate(1000, 8000, 1000);
218
+
219
+ rate.Update(1000, nowMs);
220
+ rate.Update(1000, nowMs + 500);
221
+
222
+ // 1000 * 8000 / 501, without the sample that starts the period.
223
+ REQUIRE(rate.GetRate(nowMs + 500) == 15968);
224
+ REQUIRE(rate.GetBytes() == 2000);
225
+
226
+ // Five seconds before the window, which spans one.
227
+ rate.Update(1000, nowMs - 5000);
228
+
229
+ REQUIRE(rate.GetBytes() == 3000);
230
+ // 2000 * 8000 / 501.
231
+ REQUIRE(rate.GetRate(nowMs + 500) == 31936);
232
+ }
233
+
234
+ // NOTE: This is what the margin exists for: the samples come a whole window
235
+ // apart, so without it each of them would find the window empty, restart the
236
+ // measured period and never be measured at all.
237
+ SECTION("a stream sending as often as the window is still measured")
238
+ {
239
+ // window: 1000ms, items: 1000 (granularity: 1ms), counting frames
240
+ RTC::RateCalculator rate(1000, 1000, 1000);
241
+
242
+ REQUIRE(rate.GetRate(nowMs) == std::nullopt);
243
+
244
+ // One frame per second for ten seconds.
245
+ for (int64_t i{ 0 }; i < 10000; i += 1000)
246
+ {
247
+ rate.Update(1, nowMs + i);
248
+
249
+ if (i > 0)
250
+ {
251
+ REQUIRE(rate.GetRate(nowMs + i) == 1);
252
+ }
253
+ }
254
+ }
255
+
256
+ // NOTE: The overflow is provoked through the scale rather than through the size
257
+ // of the samples, since Update() takes a size_t and on a 32 bit build no amount
258
+ // of samples of that size makes the result overflow.
259
+ SECTION("a rate that does not fit is no rate at all")
260
+ {
261
+ // window: 1000ms, items: 1000 (granularity: 1ms)
262
+ RTC::RateCalculator rate(1000, 1e30F, 1000);
263
+
264
+ rate.Update(1000, nowMs);
265
+ rate.Update(1000, nowMs + 1);
266
+
267
+ REQUIRE(rate.GetRate(nowMs + 1) == std::nullopt);
268
+ }
269
+
43
270
  SECTION("receive single item per 1000 ms")
44
271
  {
45
272
  RTC::RateCalculator rate;
@@ -47,7 +274,7 @@ SCENARIO("RateCalculator", "[rate-calculator]")
47
274
  // clang-format off
48
275
  const std::vector<TestRateCalculatorData> input =
49
276
  {
50
- { .offset=0, .size=5, .rate=40 }
277
+ { .offset=0, .size=5, .rate=std::nullopt }
51
278
  };
52
279
  // clang-format on
53
280
 
@@ -61,10 +288,15 @@ SCENARIO("RateCalculator", "[rate-calculator]")
61
288
  // clang-format off
62
289
  const std::vector<TestRateCalculatorData> input =
63
290
  {
64
- { .offset=0, .size=5, .rate=40 },
65
- { .offset=100, .size=2, .rate=56 },
66
- { .offset=300, .size=2, .rate=72 },
67
- { .offset=999, .size=4, .rate=104 }
291
+ // A lone sample with the window unfilled.
292
+ { .offset=0, .size=5, .rate=std::nullopt },
293
+ // 2 * 8000 / 101, the first sample being the one that starts the period.
294
+ { .offset=100, .size=2, .rate=158 },
295
+ // (2 + 2) * 8000 / 301.
296
+ { .offset=300, .size=2, .rate=106 },
297
+ // The period is the whole window now, so every sample counts:
298
+ // (5 + 2 + 2 + 4) * 8000 / 1000.
299
+ { .offset=999, .size=4, .rate=104 }
68
300
  };
69
301
  // clang-format on
70
302
 
@@ -75,12 +307,15 @@ SCENARIO("RateCalculator", "[rate-calculator]")
75
307
  {
76
308
  RTC::RateCalculator rate(1000, 8000, 100);
77
309
 
310
+ // Each sample expires the previous one, but they come close enough together
311
+ // for the measured period to be kept, so each of them is measured over the
312
+ // window instead of over the instant it was taken in.
78
313
  // clang-format off
79
314
  const std::vector<TestRateCalculatorData> input =
80
315
  {
81
- { .offset=0, .size=5, .rate=40 },
82
- { .offset=1000, .size=5, .rate=40 },
83
- { .offset=2000, .size=5, .rate=40 }
316
+ { .offset=0, .size=5, .rate=std::nullopt },
317
+ { .offset=1000, .size=5, .rate=40 },
318
+ { .offset=2000, .size=5, .rate=40 }
84
319
  };
85
320
  // clang-format on
86
321
 
@@ -91,20 +326,22 @@ SCENARIO("RateCalculator", "[rate-calculator]")
91
326
  {
92
327
  RTC::RateCalculator rate(1000, 8000, 1000);
93
328
 
329
+ // From the second sample on the period is already the whole window, so every
330
+ // rate below is the bytes left within it times 8.
94
331
  // clang-format off
95
332
  const std::vector<TestRateCalculatorData> input =
96
333
  {
97
- { .offset=0, .size=5, .rate=40 },
98
- { .offset=999, .size=2, .rate=56 },
99
- { .offset=1001, .size=1, .rate=24 },
100
- { .offset=1001, .size=1, .rate=32 },
101
- { .offset=2000, .size=1, .rate=24 }
334
+ { .offset=0, .size=5, .rate=std::nullopt },
335
+ { .offset=999, .size=2, .rate=56 },
336
+ { .offset=1001, .size=1, .rate=24 },
337
+ { .offset=1001, .size=1, .rate=32 },
338
+ { .offset=2000, .size=1, .rate=24 }
102
339
  };
103
340
  // clang-format on
104
341
 
105
342
  validate(rate, nowMs, input);
106
343
 
107
- REQUIRE(rate.GetRate(nowMs + 3001) == 0);
344
+ REQUIRE(rate.GetRate(nowMs + 3001) == std::nullopt);
108
345
  }
109
346
 
110
347
  SECTION("slide with 100 items")
@@ -114,19 +351,21 @@ SCENARIO("RateCalculator", "[rate-calculator]")
114
351
  // clang-format off
115
352
  const std::vector<TestRateCalculatorData> input =
116
353
  {
117
- { .offset=0, .size=5, .rate=40 },
118
- { .offset=999, .size=2, .rate=56 },
119
- { .offset=1001, .size=1, .rate=24 }, // merged inside 999
120
- { .offset=1001, .size=1, .rate=32 }, // merged inside 999
121
- { .offset=2000, .size=1, .rate=8 } // it will erase the item with
122
- // timestamp=999, removing also the next two samples. The
123
- // end estimation will include only the last sample.
354
+ { .offset=0, .size=5, .rate=std::nullopt },
355
+ { .offset=999, .size=2, .rate=56 },
356
+ { .offset=1001, .size=1, .rate=24 }, // merged inside 999
357
+ { .offset=1001, .size=1, .rate=32 }, // merged inside 999
358
+ { .offset=2000, .size=1, .rate=8 } // it will erase the item
359
+ // with timestamp=999, removing also the next two samples.
360
+ // Only the last sample is left, and it comes close enough
361
+ // to the previous one to keep being measured over the
362
+ // window.
124
363
  };
125
364
  // clang-format on
126
365
 
127
366
  validate(rate, nowMs, input);
128
367
 
129
- REQUIRE(rate.GetRate(nowMs + 3001) == 0);
368
+ REQUIRE(rate.GetRate(nowMs + 3001) == std::nullopt);
130
369
  }
131
370
 
132
371
  SECTION("wrap")
@@ -134,19 +373,22 @@ SCENARIO("RateCalculator", "[rate-calculator]")
134
373
  // window: 1000ms, items: 5 (granularity: 200ms)
135
374
  RTC::RateCalculator rate(1000, 8000, 5);
136
375
 
376
+ // A byte every 200ms is 40 bps, and that is what comes out from the second
377
+ // sample on: leaving out the one that starts the period is what makes the
378
+ // samples and the gaps between them match while the window fills.
137
379
  // clang-format off
138
380
  const std::vector<TestRateCalculatorData> input =
139
381
  {
140
- { .offset=1000, .size=1, .rate=1*8 },
141
- { .offset=1200, .size=1, .rate=(1*8) + (1*8) },
142
- { .offset=1400, .size=1, .rate=(1*8) + (2*8) },
143
- { .offset=1600, .size=1, .rate=(1*8) + (3*8) },
144
- { .offset=1800, .size=1, .rate=(1*8) + (4*8) },
145
- { .offset=2000, .size=1, .rate=(1*8) + ((5-1)*8) }, // starts wrap here
146
- { .offset=2200, .size=1, .rate=(1*8) + ((6-2)*8) },
147
- { .offset=2400, .size=1, .rate=(1*8) + ((7-3)*8) },
148
- { .offset=2600, .size=1, .rate=(1*8) + ((8-4)*8) },
149
- { .offset=2800, .size=1, .rate=(1*8) + ((9-5)*8) },
382
+ { .offset=1000, .size=1, .rate=std::nullopt },
383
+ { .offset=1200, .size=1, .rate=40 },
384
+ { .offset=1400, .size=1, .rate=40 },
385
+ { .offset=1600, .size=1, .rate=40 },
386
+ { .offset=1800, .size=1, .rate=40 },
387
+ { .offset=2000, .size=1, .rate=(1*8) + ((5-1)*8) }, // starts wrap here
388
+ { .offset=2200, .size=1, .rate=(1*8) + ((6-2)*8) },
389
+ { .offset=2400, .size=1, .rate=(1*8) + ((7-3)*8) },
390
+ { .offset=2600, .size=1, .rate=(1*8) + ((8-4)*8) },
391
+ { .offset=2800, .size=1, .rate=(1*8) + ((9-5)*8) },
150
392
  };
151
393
  // clang-format on
152
394
 
@@ -163,10 +405,13 @@ SCENARIO("RateCalculator", "[rate-calculator]")
163
405
  // clang-format off
164
406
  const std::vector<TestRateCalculatorData> input =
165
407
  {
166
- { .offset=0, .size=1, .rate=8 },
167
- { .offset=333, .size=1, .rate=16 },
168
- { .offset=666, .size=1, .rate=24 },
169
- { .offset=999, .size=1, .rate=32 },
408
+ { .offset=0, .size=1, .rate=std::nullopt },
409
+ // 1 * 8000 / 334, without the sample that starts the period.
410
+ { .offset=333, .size=1, .rate=24 },
411
+ // 2 * 8000 / 667.
412
+ { .offset=666, .size=1, .rate=24 },
413
+ // The period is the whole window now: 4 * 8000 / 1000.
414
+ { .offset=999, .size=1, .rate=32 },
170
415
  };
171
416
  // clang-format on
172
417
 
@@ -194,27 +439,33 @@ SCENARIO("RateCalculator", "[rate-calculator]")
194
439
  REQUIRE(rate.GetRate(nowMs + 1100) == 91 * 8);
195
440
  }
196
441
 
197
- // NOTE: This pins the GetRate() memoization key, which is both nowMs and the
198
- // total count. Keying it on nowMs alone would return a stale rate.
442
+ // NOTE: This pins the GetRate() memoization key, which is the time plus both
443
+ // totals. Keying it on the time alone would return a stale rate.
199
444
  SECTION("rate is recalculated after Update() with the same now")
200
445
  {
201
446
  RTC::RateCalculator rate(1000, 8000, 100);
202
447
 
448
+ // Two samples apart in time, so that there is a period to measure over and
449
+ // the reads below are not rejected for lack of one.
203
450
  rate.Update(5, nowMs);
451
+ rate.Update(5, nowMs + 500);
204
452
 
205
- REQUIRE(rate.GetRate(nowMs) == 40);
453
+ // 5 * 8000 / 501, without the sample that starts the period.
454
+ REQUIRE(rate.GetRate(nowMs + 500) == 80);
206
455
 
207
- rate.Update(5, nowMs);
456
+ rate.Update(5, nowMs + 500);
208
457
 
209
- REQUIRE(rate.GetRate(nowMs) == 80);
458
+ // 10 * 8000 / 501.
459
+ REQUIRE(rate.GetRate(nowMs + 500) == 160);
210
460
 
211
- rate.Update(5, nowMs);
461
+ rate.Update(5, nowMs + 500);
212
462
 
213
- REQUIRE(rate.GetRate(nowMs) == 120);
463
+ // 15 * 8000 / 501.
464
+ REQUIRE(rate.GetRate(nowMs + 500) == 240);
214
465
 
215
466
  // Repeated reads with no Update() in between must be stable.
216
- REQUIRE(rate.GetRate(nowMs) == 120);
217
- REQUIRE(rate.GetRate(nowMs) == 120);
467
+ REQUIRE(rate.GetRate(nowMs + 500) == 240);
468
+ REQUIRE(rate.GetRate(nowMs + 500) == 240);
218
469
  }
219
470
 
220
471
  // NOTE: This pins the item size rounding for a window size which is not a
@@ -237,24 +488,28 @@ SCENARIO("RateCalculator", "[rate-calculator]")
237
488
 
238
489
  // NOTE: This pins that the GetRate() memoization needs no "not calculated yet"
239
490
  // mark. Its zeroed initial state is a valid entry, so a read at time 0 must be
240
- // neither a stale hit nor a miss returning something else than 0.
491
+ // neither a stale hit nor a miss returning something else than no rate at all.
241
492
  SECTION("rate at time 0 on a fresh and on a reset calculator")
242
493
  {
243
494
  RTC::RateCalculator rate(1000, 8000, 100);
244
495
 
245
- REQUIRE(rate.GetRate(0) == 0);
496
+ REQUIRE(rate.GetRate(0) == std::nullopt);
246
497
 
247
498
  rate.Update(5, 0);
499
+ rate.Update(5, 500);
248
500
 
249
- REQUIRE(rate.GetRate(0) == 40);
501
+ // 5 * 8000 / 501, without the sample that starts the period.
502
+ REQUIRE(rate.GetRate(500) == 80);
250
503
 
251
504
  rate.Reset();
252
505
 
253
- REQUIRE(rate.GetRate(0) == 0);
506
+ REQUIRE(rate.GetRate(0) == std::nullopt);
254
507
 
255
508
  rate.Update(5, 0);
509
+ rate.Update(5, 500);
256
510
 
257
- REQUIRE(rate.GetRate(0) == 40);
511
+ // The same as before the reset.
512
+ REQUIRE(rate.GetRate(500) == 80);
258
513
  }
259
514
 
260
515
  // NOTE: This pins the constructor clamping. A zero number of items used to
@@ -269,9 +524,16 @@ SCENARIO("RateCalculator", "[rate-calculator]")
269
524
  oneItem.Update(5, nowMs);
270
525
  noWindow.Update(5, nowMs);
271
526
 
272
- REQUIRE(noItems.GetRate(nowMs) == 40);
273
- REQUIRE(oneItem.GetRate(nowMs) == 40);
274
- // The window size is clamped to 1ms.
275
- REQUIRE(noWindow.GetRate(nowMs) == 40000);
527
+ noItems.Update(5, nowMs + 500);
528
+ oneItem.Update(5, nowMs + 500);
529
+ noWindow.Update(5, nowMs + 500);
530
+
531
+ // Two samples 500ms apart, of which the one that starts the period is left
532
+ // out: 5 * 8000 / 501.
533
+ REQUIRE(noItems.GetRate(nowMs + 500) == 80);
534
+ REQUIRE(oneItem.GetRate(nowMs + 500) == 80);
535
+ // The window size is clamped to 1ms, which leaves every sample alone in a
536
+ // period of a single millisecond, so such a window can never measure a rate.
537
+ REQUIRE(noWindow.GetRate(nowMs + 500) == std::nullopt);
276
538
  }
277
539
  }
@@ -2,6 +2,9 @@
2
2
  #include "RTC/RTCP/SenderReport.hpp"
3
3
  #include "RTC/RTP/RtpStreamRecv.hpp"
4
4
  #include "RTC/RemoteCaptureTimeEstimator.hpp"
5
+ #include "RTC/RtpDictionaries.hpp"
6
+ #include "Utils.hpp"
7
+ #include "test/include/RTC/RTP/rtpCommon.hpp"
5
8
  #include "mocks/include/MockShared.hpp"
6
9
  #include <catch2/catch_test_macros.hpp>
7
10
 
@@ -81,10 +84,49 @@ SCENARIO("RemoteCaptureTimeEstimator", "[rtp][rtcp][remotecapturetimeestimator]"
81
84
  estimator.SenderReportReceived(std::addressof(rtpStream));
82
85
  };
83
86
 
87
+ // Makes a packet carrying the 'abs-capture-time' extension reach the stream, which
88
+ // is what tells a sender that does send it from one that only announced it.
89
+ auto receiveAbsCaptureTimePacket = [&nowUs, &rtpStream]() -> void
90
+ {
91
+ // Id the extension is given, which only has to match between what is written
92
+ // and what is read back.
93
+ constexpr uint8_t AbsCaptureTimeId{ 1 };
94
+
95
+ std::unique_ptr<RTC::RTP::Packet> packet(
96
+ RTC::RTP::Packet::Factory(rtpCommon::FactoryBuffer, sizeof(rtpCommon::FactoryBuffer)));
97
+
98
+ REQUIRE(packet);
99
+
100
+ packet->SetSsrc(Ssrc);
101
+ packet->SetTimestamp(RemoteBaseTs);
102
+
103
+ const std::vector<RTC::RTP::Packet::Extension> extensions{
104
+ { RTC::RtpHeaderExtensionUri::Type::ABS_CAPTURE_TIME,
105
+ AbsCaptureTimeId, /*len*/ 8,
106
+ rtpCommon::DataBuffer }
107
+ };
108
+
109
+ packet->SetExtensions(RTC::RTP::Packet::ExtensionsType::OneByte, extensions);
110
+
111
+ RTC::RTP::HeaderExtensionIds headerExtensionIds;
112
+
113
+ headerExtensionIds.absCaptureTime = AbsCaptureTimeId;
114
+
115
+ packet->AssignExtensionIds(headerExtensionIds);
116
+
117
+ const auto ntp = Utils::Time::TimeUsToNtp(static_cast<int64_t>(RemoteBaseNtpSec) * 1000000);
118
+
119
+ REQUIRE(packet->UpdateAbsCaptureTime(
120
+ (static_cast<uint64_t>(ntp.seconds) << 32) | static_cast<uint64_t>(ntp.fractions)));
121
+
122
+ rtpStream.ReceivePacket(packet.get(), nowUs);
123
+ };
124
+
84
125
  SECTION("no source until the first Producer has been taken into account")
85
126
  {
86
127
  REQUIRE_FALSE(estimator.GetSource().has_value());
87
- REQUIRE_FALSE(estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs).has_value());
128
+ REQUIRE_FALSE(
129
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs, nowUs).has_value());
88
130
  }
89
131
 
90
132
  SECTION("the first Producer chooses abs-capture-time when it negotiated it")
@@ -118,6 +160,50 @@ SCENARIO("RemoteCaptureTimeEstimator", "[rtp][rtcp][remotecapturetimeestimator]"
118
160
  REQUIRE(estimator.GetSource() == RTC::RemoteCaptureTimeEstimator::Source::SENDER_REPORT);
119
161
  }
120
162
 
163
+ SECTION("abs-capture-time negotiated but never received moves the source to Sender Report")
164
+ {
165
+ estimator.UpdateSource(/*absCaptureTimeNegotiated*/ true);
166
+
167
+ // The first packet is what the wait is measured against, so nothing happens on
168
+ // it however long this sender has been around.
169
+ nowUs += 60 * 1000000;
170
+
171
+ REQUIRE_FALSE(
172
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs, nowUs).has_value());
173
+ REQUIRE(estimator.GetSource() == RTC::RemoteCaptureTimeEstimator::Source::ABS_CAPTURE_TIME);
174
+
175
+ // Still within the wait, since the extension travels on some packets rather
176
+ // than on every one and may simply not have arrived yet.
177
+ nowUs += 4 * 1000000;
178
+
179
+ REQUIRE_FALSE(
180
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs, nowUs).has_value());
181
+ REQUIRE(estimator.GetSource() == RTC::RemoteCaptureTimeEstimator::Source::ABS_CAPTURE_TIME);
182
+
183
+ // Long enough without a single packet carrying it.
184
+ nowUs += 1 * 1000000;
185
+
186
+ REQUIRE_FALSE(
187
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs, nowUs).has_value());
188
+ REQUIRE(estimator.GetSource() == RTC::RemoteCaptureTimeEstimator::Source::SENDER_REPORT);
189
+ }
190
+
191
+ SECTION("abs-capture-time received keeps the source whatever the sender does later")
192
+ {
193
+ estimator.UpdateSource(/*absCaptureTimeNegotiated*/ true);
194
+
195
+ receiveAbsCaptureTimePacket();
196
+
197
+ REQUIRE(rtpStream.HasAbsCaptureTime());
198
+
199
+ // Way past the wait, which is not armed at all once the extension has been seen.
200
+ nowUs += 60 * 1000000;
201
+
202
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs, nowUs);
203
+
204
+ REQUIRE(estimator.GetSource() == RTC::RemoteCaptureTimeEstimator::Source::ABS_CAPTURE_TIME);
205
+ }
206
+
121
207
  SECTION("the capture instant is translated into our clock")
122
208
  {
123
209
  estimator.UpdateSource(/*absCaptureTimeNegotiated*/ false);
@@ -125,7 +211,8 @@ SCENARIO("RemoteCaptureTimeEstimator", "[rtp][rtcp][remotecapturetimeestimator]"
125
211
  // A single Sender Report is not enough for the clock offset to be estimated.
126
212
  receiveSenderReport(0);
127
213
 
128
- REQUIRE_FALSE(estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs).has_value());
214
+ REQUIRE_FALSE(
215
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs, nowUs).has_value());
129
216
 
130
217
  for (uint32_t idx{ 1 }; idx < RTC::RemoteClockOffsetEstimator::MinSampleCount; ++idx)
131
218
  {
@@ -137,19 +224,19 @@ SCENARIO("RemoteCaptureTimeEstimator", "[rtp][rtcp][remotecapturetimeestimator]"
137
224
  const auto lastIdx = RTC::RemoteClockOffsetEstimator::MinSampleCount - 1;
138
225
  const auto lastTs = static_cast<uint32_t>(RemoteBaseTs + (lastIdx * ClockRate));
139
226
 
140
- REQUIRE(estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), lastTs).has_value());
227
+ REQUIRE(estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), lastTs, nowUs).has_value());
141
228
  REQUIRE(
142
229
  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
143
- estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), lastTs).value() ==
230
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), lastTs, nowUs).value() ==
144
231
  LocalBaseUs + (lastIdx * 1000000));
145
232
 
146
233
  // One second of media later maps one second later in our clock too.
147
234
  const auto nextTs = static_cast<uint32_t>(RemoteBaseTs + ((lastIdx + 1) * ClockRate));
148
235
 
149
- REQUIRE(estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), nextTs).has_value());
236
+ REQUIRE(estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), nextTs, nowUs).has_value());
150
237
  REQUIRE(
151
238
  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
152
- estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), nextTs).value() ==
239
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), nextTs, nowUs).value() ==
153
240
  LocalBaseUs + ((lastIdx + 1) * 1000000));
154
241
  }
155
242
 
@@ -164,6 +251,7 @@ SCENARIO("RemoteCaptureTimeEstimator", "[rtp][rtcp][remotecapturetimeestimator]"
164
251
 
165
252
  // Sender Reports have been received, but the source in use is not allowed to
166
253
  // fall back to them.
167
- REQUIRE_FALSE(estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs).has_value());
254
+ REQUIRE_FALSE(
255
+ estimator.GetLocalCaptureAtUs(std::addressof(rtpStream), RemoteBaseTs, nowUs).has_value());
168
256
  }
169
257
  }