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
@@ -11,6 +11,15 @@ namespace Utils
11
11
  {
12
12
  MS_TRACE();
13
13
 
14
+ // NOTE: Whatever comes from the network is the value of an RTP header
15
+ // extension, whose length field is a single byte, so it always fits. This
16
+ // only catches a caller handing over a longer buffer.
17
+ MS_ASSERT(
18
+ len <= sizeof(this->data),
19
+ "given length exceeds the buffer [len:%zu, buffer:%zu]",
20
+ len,
21
+ sizeof(this->data));
22
+
14
23
  std::memcpy(this->data, data, len);
15
24
  }
16
25
 
@@ -49,6 +58,15 @@ namespace Utils
49
58
  {
50
59
  MS_TRACE();
51
60
 
61
+ // There is nothing left to read, so stay where the data ended rather than
62
+ // read past it. Callers are expected to check GetLeftBits() themselves, and
63
+ // a zero cannot be told apart from a real one, so this is the last resort
64
+ // and not the way to know that the data is over.
65
+ if (GetLeftBits() == 0)
66
+ {
67
+ return 0;
68
+ }
69
+
52
70
  auto bit = ((*(data + (this->offset >> 0x3))) >> (0x7 - (this->offset & 0x7))) & 0x1;
53
71
 
54
72
  this->offset++;
@@ -178,6 +196,12 @@ namespace Utils
178
196
  // Retrieve the current byte position.
179
197
  const size_t byteOffset = offset >> 0x3;
180
198
 
199
+ MS_ASSERT(
200
+ byteOffset < sizeof(this->data),
201
+ "given offset is past the buffer [offset:%" PRIu32 ", buffer:%zu]",
202
+ offset,
203
+ sizeof(this->data));
204
+
181
205
  // Calculate the bitmask for the target bit within the current byte.
182
206
  const auto bitmask = (1u << (0x7 - (offset & 0x7)));
183
207
 
@@ -128,7 +128,7 @@ int64_t BackoffTimerHandle::ComputeNextTimeoutMs() const
128
128
  return std::min<int64_t>(timeoutMs, BackoffTimerHandleInterface::MaxTimeoutMs);
129
129
  }
130
130
 
131
- NO_DEFAULT_GCC();
131
+ NO_DEFAULT();
132
132
  }
133
133
  }
134
134
 
@@ -41,14 +41,13 @@ inline static void onWrite(uv_write_t* req, int status)
41
41
  auto* writeData = static_cast<TcpConnectionHandle::UvWriteData*>(req->data);
42
42
  auto* handle = req->handle;
43
43
  auto* connection = static_cast<TcpConnectionHandle*>(handle->data);
44
- const auto* cb = writeData->cb;
45
44
 
46
45
  if (connection)
47
46
  {
48
- connection->OnUvWrite(status, cb);
47
+ connection->OnUvWrite(status, writeData->cb);
49
48
  }
50
49
 
51
- // Delete the UvWriteData struct and the cb.
50
+ // Delete the UvWriteData struct (it will delete the store too).
52
51
  delete writeData;
53
52
  }
54
53
 
@@ -182,11 +181,7 @@ bool TcpConnectionHandle::Start() noexcept
182
181
  }
183
182
 
184
183
  void TcpConnectionHandle::Write(
185
- const uint8_t* data1,
186
- size_t len1,
187
- const uint8_t* data2,
188
- size_t len2,
189
- TcpConnectionHandle::onSendCallback* cb)
184
+ const uint8_t* data1, size_t len1, const uint8_t* data2, size_t len2, onSendCallback cb)
190
185
  {
191
186
  MS_TRACE();
192
187
 
@@ -194,8 +189,7 @@ void TcpConnectionHandle::Write(
194
189
  {
195
190
  if (cb)
196
191
  {
197
- (*cb)(false);
198
- delete cb;
192
+ cb(false);
199
193
  }
200
194
 
201
195
  return;
@@ -205,8 +199,7 @@ void TcpConnectionHandle::Write(
205
199
  {
206
200
  if (cb)
207
201
  {
208
- (*cb)(false);
209
- delete cb;
202
+ cb(false);
210
203
  }
211
204
 
212
205
  return;
@@ -232,8 +225,7 @@ void TcpConnectionHandle::Write(
232
225
 
233
226
  if (cb)
234
227
  {
235
- (*cb)(true);
236
- delete cb;
228
+ cb(true);
237
229
  }
238
230
 
239
231
  return;
@@ -274,7 +266,7 @@ void TcpConnectionHandle::Write(
274
266
  len2 - (static_cast<size_t>(written) - len1));
275
267
  }
276
268
 
277
- writeData->cb = cb;
269
+ writeData->cb = std::move(cb);
278
270
 
279
271
  const uv_buf_t buffer = uv_buf_init(reinterpret_cast<char*>(writeData->store), pendingLen);
280
272
 
@@ -289,12 +281,12 @@ void TcpConnectionHandle::Write(
289
281
  {
290
282
  MS_WARN_DEV("uv_write() failed: %s", uv_strerror(err));
291
283
 
292
- if (cb)
284
+ if (writeData->cb)
293
285
  {
294
- (*cb)(false);
286
+ writeData->cb(false);
295
287
  }
296
288
 
297
- // Delete the UvWriteData struct (it will delete the store and cb too).
289
+ // Delete the UvWriteData struct (it will delete the store too).
298
290
  delete writeData;
299
291
  }
300
292
  else
@@ -483,17 +475,15 @@ inline void TcpConnectionHandle::OnUvRead(ssize_t nread, const uv_buf_t* /*buf*/
483
475
  }
484
476
  }
485
477
 
486
- inline void TcpConnectionHandle::OnUvWrite(int status, TcpConnectionHandle::onSendCallback* cb)
478
+ inline void TcpConnectionHandle::OnUvWrite(int status, const onSendCallback& cb)
487
479
  {
488
480
  MS_TRACE();
489
481
 
490
- // NOTE: Do not delete cb here since it will be delete in onWrite() above.
491
-
492
482
  if (status == 0)
493
483
  {
494
484
  if (cb)
495
485
  {
496
- (*cb)(true);
486
+ cb(true);
497
487
  }
498
488
  }
499
489
  else
@@ -507,7 +497,7 @@ inline void TcpConnectionHandle::OnUvWrite(int status, TcpConnectionHandle::onSe
507
497
 
508
498
  if (cb)
509
499
  {
510
- (*cb)(false);
500
+ cb(false);
511
501
  }
512
502
 
513
503
  InternalClose();
@@ -50,14 +50,13 @@ inline static void onSend(uv_udp_send_t* req, int status)
50
50
  auto* sendData = static_cast<UdpSocketHandle::UvSendData*>(req->data);
51
51
  auto* handle = req->handle;
52
52
  auto* socket = static_cast<UdpSocketHandle*>(handle->data);
53
- const auto* cb = sendData->cb;
54
53
 
55
54
  if (socket)
56
55
  {
57
- socket->OnUvSend(status, cb);
56
+ socket->OnUvSend(status, sendData->cb);
58
57
  }
59
58
 
60
- // Delete the UvSendData struct (it will delete the store and cb too).
59
+ // Delete the UvSendData struct (it will delete the store too).
61
60
  delete sendData;
62
61
  }
63
62
 
@@ -126,7 +125,7 @@ void UdpSocketHandle::Dump(int indentation) const
126
125
  }
127
126
 
128
127
  void UdpSocketHandle::Send(
129
- const uint8_t* data, size_t len, const struct sockaddr* addr, UdpSocketHandle::onSendCallback* cb)
128
+ const uint8_t* data, size_t len, const struct sockaddr* addr, onSendCallback cb)
130
129
  {
131
130
  MS_TRACE();
132
131
 
@@ -134,8 +133,7 @@ void UdpSocketHandle::Send(
134
133
  {
135
134
  if (cb)
136
135
  {
137
- (*cb)(false);
138
- delete cb;
136
+ cb(false);
139
137
  }
140
138
 
141
139
  return;
@@ -145,8 +143,7 @@ void UdpSocketHandle::Send(
145
143
  {
146
144
  if (cb)
147
145
  {
148
- (*cb)(false);
149
- delete cb;
146
+ cb(false);
150
147
  }
151
148
 
152
149
  return;
@@ -166,8 +163,7 @@ void UdpSocketHandle::Send(
166
163
 
167
164
  if (cb)
168
165
  {
169
- (*cb)(true);
170
- delete cb;
166
+ cb(true);
171
167
  }
172
168
 
173
169
  return;
@@ -181,8 +177,7 @@ void UdpSocketHandle::Send(
181
177
 
182
178
  if (cb)
183
179
  {
184
- (*cb)(false);
185
- delete cb;
180
+ cb(false);
186
181
  }
187
182
 
188
183
  return;
@@ -197,7 +192,7 @@ void UdpSocketHandle::Send(
197
192
 
198
193
  sendData->req.data = static_cast<void*>(sendData);
199
194
  std::memcpy(sendData->store, data, len);
200
- sendData->cb = cb;
195
+ sendData->cb = std::move(cb);
201
196
 
202
197
  buffer = uv_buf_init(reinterpret_cast<char*>(sendData->store), len);
203
198
 
@@ -215,12 +210,12 @@ void UdpSocketHandle::Send(
215
210
  // (IPv6 destination on a IPv4 binded socket), so be ready.
216
211
  MS_WARN_DEV("uv_udp_send() failed: %s", uv_strerror(err));
217
212
 
218
- if (cb)
213
+ if (sendData->cb)
219
214
  {
220
- (*cb)(false);
215
+ sendData->cb(false);
221
216
  }
222
217
 
223
- // Delete the UvSendData struct (it will delete the store and cb too).
218
+ // Delete the UvSendData struct (it will delete the store too).
224
219
  delete sendData;
225
220
  }
226
221
  else
@@ -402,17 +397,15 @@ inline void UdpSocketHandle::OnUvRecv(
402
397
  }
403
398
  }
404
399
 
405
- inline void UdpSocketHandle::OnUvSend(int status, UdpSocketHandle::onSendCallback* cb)
400
+ inline void UdpSocketHandle::OnUvSend(int status, const onSendCallback& cb)
406
401
  {
407
402
  MS_TRACE();
408
403
 
409
- // NOTE: Do not delete cb here since it will be delete in onSend() above.
410
-
411
404
  if (status == 0)
412
405
  {
413
406
  if (cb)
414
407
  {
415
- (*cb)(true);
408
+ cb(true);
416
409
  }
417
410
  }
418
411
  else
@@ -423,7 +416,7 @@ inline void UdpSocketHandle::OnUvSend(int status, UdpSocketHandle::onSendCallbac
423
416
 
424
417
  if (cb)
425
418
  {
426
- (*cb)(false);
419
+ cb(false);
427
420
  }
428
421
  }
429
422
  }
package/worker/tasks.py CHANGED
@@ -10,6 +10,7 @@ Usage:
10
10
 
11
11
  import glob
12
12
  import inspect
13
+ import json
13
14
  import os
14
15
  import re
15
16
  import shutil
@@ -172,21 +173,33 @@ def meson_ninja(ctx):
172
173
 
173
174
  def default_meson_options():
174
175
  """
175
- Return every option in meson_options.txt set to its default value
176
+ Return every option in meson_options.txt mapped to its default value
176
177
  """
177
178
 
178
- options = []
179
+ options = {}
179
180
 
180
181
  with open(f"{WORKER_DIR}/meson_options.txt", encoding="utf-8") as options_file:
181
182
  for line in options_file:
182
183
  match = re.match(r"\s*option\('([^']+)'.*value:\s*([^,)]+)", line)
183
184
 
184
185
  if match:
185
- options.append(
186
- f"-D{match.group(1)}={match.group(2).strip().strip(chr(39))}"
187
- )
186
+ options[match.group(1)] = match.group(2).strip().strip(chr(39))
188
187
 
189
- return " ".join(options)
188
+ return options
189
+
190
+
191
+ def configured_meson_options(build_dir):
192
+ """
193
+ Return the name of every option the given build directory is configured with
194
+ """
195
+
196
+ try:
197
+ with open(
198
+ f"{build_dir}/meson-info/intro-buildoptions.json", encoding="utf-8"
199
+ ) as options_file:
200
+ return {option["name"] for option in json.load(options_file)}
201
+ except (OSError, ValueError):
202
+ return set()
190
203
 
191
204
 
192
205
  @task(pre=[meson_ninja])
@@ -195,23 +208,36 @@ def setup(ctx, meson_args=MESON_ARGS, build_dir=BUILD_DIR):
195
208
  Run meson setup
196
209
  """
197
210
 
211
+ # NOTE: Meson keeps every option of an already configured build directory
212
+ # that is not given again, so all of them are passed with their default
213
+ # value before meson_args, which comes later and hence wins. Without this,
214
+ # removing an option from MESON_ARGS would silently keep the value it was
215
+ # given the previous time.
216
+ default_options = default_meson_options()
217
+ default_options_args = " ".join(
218
+ f"-D{name}={value}" for name, value in default_options.items()
219
+ )
220
+
198
221
  # NOTE: Given an already configured build directory, "meson setup" just
199
222
  # prints "Directory already configured" and exits successfully, silently
200
223
  # ignoring the given options. So it must be told to reconfigure it or
201
224
  # changing MESON_ARGS would have no effect until the directory is removed.
202
- reconfigure = "--reconfigure" if os.path.isdir(f"{build_dir}/meson-info") else ""
203
-
204
- # NOTE: Meson also keeps every option of an already configured build
205
- # directory that is not given again, so all of them are passed with their
206
- # default value before meson_args, which comes later and hence wins. Without
207
- # this, removing an option from MESON_ARGS would silently keep the value it
208
- # was given the previous time.
209
- default_options = default_meson_options()
225
+ reconfigure = ""
226
+
227
+ if os.path.isdir(f"{build_dir}/meson-info"):
228
+ # NOTE: Meson validates the given options against the ones it has cached
229
+ # before reading meson_options.txt again, so a build directory configured
230
+ # back when an option didn't exist yet cannot be reconfigured with it.
231
+ # There is nothing to preserve in that case, so it's built from scratch.
232
+ if default_options.keys() <= configured_meson_options(build_dir):
233
+ reconfigure = "--reconfigure"
234
+ else:
235
+ shutil.rmtree(build_dir, ignore_errors=True)
210
236
 
211
237
  if MEDIASOUP_BUILDTYPE == "Release":
212
238
  with cd_worker():
213
239
  ctx.run(
214
- f'"{MESON}" setup {reconfigure} --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype release -Db_ndebug=true {default_options} {meson_args} "{build_dir}"',
240
+ f'"{MESON}" setup {reconfigure} --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype release -Db_ndebug=true {default_options_args} {meson_args} "{build_dir}"',
215
241
  echo=True,
216
242
  pty=PTY_SUPPORTED,
217
243
  shell=SHELL,
@@ -219,7 +245,7 @@ def setup(ctx, meson_args=MESON_ARGS, build_dir=BUILD_DIR):
219
245
  elif MEDIASOUP_BUILDTYPE == "Debug":
220
246
  with cd_worker():
221
247
  ctx.run(
222
- f'"{MESON}" setup {reconfigure} --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype debug {default_options} {meson_args} "{build_dir}"',
248
+ f'"{MESON}" setup {reconfigure} --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype debug {default_options_args} {meson_args} "{build_dir}"',
223
249
  echo=True,
224
250
  pty=PTY_SUPPORTED,
225
251
  shell=SHELL,
@@ -227,7 +253,7 @@ def setup(ctx, meson_args=MESON_ARGS, build_dir=BUILD_DIR):
227
253
  else:
228
254
  with cd_worker():
229
255
  ctx.run(
230
- f'"{MESON}" setup {reconfigure} --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype {MEDIASOUP_BUILDTYPE} -Db_ndebug=if-release {default_options} {meson_args} "{build_dir}"',
256
+ f'"{MESON}" setup {reconfigure} --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype {MEDIASOUP_BUILDTYPE} -Db_ndebug=if-release {default_options_args} {meson_args} "{build_dir}"',
231
257
  echo=True,
232
258
  pty=PTY_SUPPORTED,
233
259
  shell=SHELL,
@@ -310,7 +336,6 @@ def clean_all(ctx):
310
336
  )
311
337
 
312
338
  shutil.rmtree(MEDIASOUP_OUT_DIR, ignore_errors=True)
313
- shutil.rmtree("include/FBS", ignore_errors=True)
314
339
 
315
340
 
316
341
  @task(pre=[meson_ninja])
@@ -3,9 +3,26 @@
3
3
 
4
4
  #include "common.hpp"
5
5
  #include "RTC/BWE/BweTypes.hpp"
6
+ #include <vector>
6
7
 
7
8
  namespace bweHelpers
8
9
  {
10
+ // Largest packet a frame is split into (bytes).
11
+ constexpr size_t Mtu{ 1200 };
12
+
13
+ /**
14
+ * A packet as it left a stream and as it arrived, for whoever needs to know
15
+ * which stream it belongs to rather than just its feedback.
16
+ */
17
+ struct Packet
18
+ {
19
+ uint32_t ssrc;
20
+ uint32_t rtpTimestamp;
21
+ int64_t sendTimeUs;
22
+ int64_t arrivalTimeUs;
23
+ size_t size;
24
+ };
25
+
9
26
  /**
10
27
  * A stream that produces frames at a given frame rate and bitrate, split into
11
28
  * packets of at most one MTU.
@@ -13,19 +30,27 @@ namespace bweHelpers
13
30
  class RtpStream
14
31
  {
15
32
  public:
16
- /**
17
- * Offset added to the send times so that they don't share the origin with
18
- * the arrival ones, which would hide a mistake mixing both references.
19
- */
20
- static constexpr int64_t SendSideOffsetUs{ 1000 * 1000 };
21
-
22
- public:
23
- RtpStream(int fps, int64_t bitrateBps);
33
+ RtpStream(
34
+ int fps,
35
+ int64_t bitrateBps,
36
+ uint32_t ssrc = 0,
37
+ uint32_t frequency = 90000,
38
+ uint32_t rtpTimestampOffset = 0);
24
39
 
25
40
  RtpStream& operator=(const RtpStream&) = delete;
26
41
 
27
42
  RtpStream(const RtpStream&) = delete;
28
43
 
44
+ uint32_t GetSsrc() const
45
+ {
46
+ return this->ssrc;
47
+ }
48
+
49
+ void SetRtpTimestampOffset(uint32_t rtpTimestampOffset)
50
+ {
51
+ this->rtpTimestampOffset = rtpTimestampOffset;
52
+ }
53
+
29
54
  /**
30
55
  * Generate a frame and split it into packets, appending them to
31
56
  * `packetResults`. Nothing is generated if it's called before the next frame
@@ -38,6 +63,13 @@ namespace bweHelpers
38
63
  int64_t& nextSequenceNumber,
39
64
  std::vector<RTC::BWE::Types::PacketResult>& packetResults);
40
65
 
66
+ int64_t GetBitrateBps() const
67
+ {
68
+ return this->bitrateBps;
69
+ }
70
+
71
+ void SetBitrateBps(int64_t bitrateBps);
72
+
41
73
  /**
42
74
  * Send time at which the next frame can be generated.
43
75
  */
@@ -46,12 +78,12 @@ namespace bweHelpers
46
78
  return this->nextRtpTimeUs;
47
79
  }
48
80
 
49
- int64_t GetBitrateBps() const
50
- {
51
- return this->bitrateBps;
52
- }
53
-
54
- void SetBitrateBps(int64_t bitrateBps);
81
+ /**
82
+ * Generate a frame as the other overload does, for whoever needs the packets
83
+ * themselves rather than the feedback they would produce. The arrival time
84
+ * is left for the link to fill in.
85
+ */
86
+ int64_t GenerateFrame(int64_t timeNowUs, std::vector<Packet>& packets);
55
87
 
56
88
  /**
57
89
  * Orders streams by which one is due to produce a frame first.
@@ -60,6 +92,9 @@ namespace bweHelpers
60
92
 
61
93
  private:
62
94
  const int fps;
95
+ const uint32_t ssrc;
96
+ const uint32_t frequency;
97
+ uint32_t rtpTimestampOffset;
63
98
  int64_t bitrateBps;
64
99
  int64_t nextRtpTimeUs{ 0 };
65
100
  };
@@ -88,6 +123,12 @@ namespace bweHelpers
88
123
 
89
124
  void SetCapacityBps(int64_t capacityBps);
90
125
 
126
+ /**
127
+ * Set the RTP timestamp offset of the stream with the given SSRC, which
128
+ * does nothing if no stream has it.
129
+ */
130
+ void SetRtpTimestampOffset(uint32_t ssrc, uint32_t rtpTimestampOffset);
131
+
91
132
  /**
92
133
  * Divide `bitrateBps` among the streams, keeping the ratios they had.
93
134
  */
@@ -105,6 +146,19 @@ namespace bweHelpers
105
146
  int64_t& nextSequenceNumber,
106
147
  std::vector<RTC::BWE::Types::PacketResult>& packetResults);
107
148
 
149
+ /**
150
+ * Generate a frame as the other overload does, for whoever needs the packets
151
+ * themselves rather than the feedback they would produce.
152
+ */
153
+ int64_t GenerateFrame(int64_t timeNowUs, std::vector<Packet>& packets);
154
+
155
+ private:
156
+ /**
157
+ * Time the link needs to put a packet of the given size on the wire, which
158
+ * is also how long the next one waits behind it.
159
+ */
160
+ int64_t GetRequiredNetworkTimeUs(size_t size) const;
161
+
108
162
  private:
109
163
  // Capacity of the simulated link (bps).
110
164
  int64_t capacityBps;
@@ -0,0 +1,125 @@
1
+ #ifndef MS_TEST_RTC_BWE_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_TEST_HELPER_HPP
2
+ #define MS_TEST_RTC_BWE_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_TEST_HELPER_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp"
6
+ #include "test/include/RTC/BWE/helpers/LinkSimulator.hpp"
7
+ #include <vector>
8
+
9
+ namespace bweHelpers
10
+ {
11
+ /**
12
+ * Drives a `RTC::BWE::RemoteBitrateEstimatorAbsSendTime` through the scenarios
13
+ * its tests are written around: it owns the estimator, feeds it the packets a
14
+ * simulated link delivers, and keeps the latest estimation it reported.
15
+ */
16
+ class RemoteBitrateEstimatorAbsSendTimeTestHelper
17
+ : public RTC::BWE::RemoteBitrateEstimatorAbsSendTime::Listener
18
+ {
19
+ public:
20
+ /**
21
+ * SSRC of the stream `AddDefaultStream()` adds.
22
+ */
23
+ static constexpr uint32_t DefaultSsrc{ 1 };
24
+
25
+ public:
26
+ RemoteBitrateEstimatorAbsSendTimeTestHelper();
27
+
28
+ ~RemoteBitrateEstimatorAbsSendTimeTestHelper() override = default;
29
+
30
+ RemoteBitrateEstimatorAbsSendTimeTestHelper(const RemoteBitrateEstimatorAbsSendTimeTestHelper&) =
31
+ delete;
32
+ RemoteBitrateEstimatorAbsSendTimeTestHelper& operator=(
33
+ const RemoteBitrateEstimatorAbsSendTimeTestHelper&) = delete;
34
+
35
+ /**
36
+ * Turn an instant into the 24 bits of the 'abs-send-time' extension,
37
+ * rounded upwards.
38
+ *
39
+ * @param denom - What to divide the instant by to get whole seconds, so
40
+ * 1000 for milliseconds.
41
+ */
42
+ static uint32_t AbsSendTime(int64_t t, int64_t denom);
43
+
44
+ /**
45
+ * Add two of those values together, keeping the result within 24 bits.
46
+ */
47
+ static uint32_t AddAbsSendTime(uint32_t t1, uint32_t t2);
48
+
49
+ void AddDefaultStream();
50
+
51
+ /**
52
+ * Build a packet with the given 'abs-send-time' and feed it to the
53
+ * estimator as having arrived at `arrivalTimeMs`.
54
+ */
55
+ void IncomingPacket(
56
+ uint32_t ssrc,
57
+ size_t payloadSize,
58
+ int64_t arrivalTimeMs,
59
+ uint32_t rtpTimestamp,
60
+ uint32_t absSendTime);
61
+
62
+ /**
63
+ * Generate a frame at the given bitrate, push it through the link and give
64
+ * every packet to the estimator.
65
+ *
66
+ * @returns Whether the estimation came out below what was being sent, which
67
+ * is what an overuse looks like from here.
68
+ */
69
+ bool GenerateAndProcessFrame(uint32_t ssrc, int64_t bitrateBps);
70
+
71
+ /**
72
+ * Feed frames until the estimation settles above `targetBitrate` or until
73
+ * `maxNumberOfFrames` have gone by, which is how a scenario gets the
74
+ * estimator into a steady state before doing anything to it.
75
+ *
76
+ * @returns The bitrate reached.
77
+ */
78
+ int64_t SteadyStateRun(
79
+ uint32_t ssrc,
80
+ int maxNumberOfFrames,
81
+ int64_t startBitrate,
82
+ int64_t minBitrate,
83
+ int64_t maxBitrate,
84
+ int64_t targetBitrate);
85
+
86
+ void InitialBehaviorTestHelper(int64_t expectedConvergeBitrate);
87
+
88
+ void RateIncreaseReorderingTestHelper(int64_t expectedBitrate);
89
+
90
+ void RateIncreaseRtpTimestampsTestHelper(int expectedIterations);
91
+
92
+ void CapacityDropTestHelper(
93
+ int numberOfStreams,
94
+ bool wrapTimestamp,
95
+ int64_t expectedBitrateDropDeltaMs,
96
+ int64_t receiverClockOffsetChangeMs);
97
+
98
+ void TestTimestampGroupingTestHelper();
99
+
100
+ void TestWrappingHelper(int silenceTimeS);
101
+
102
+ /* Pure virtual methods inherited from RemoteBitrateEstimatorAbsSendTime::Listener. */
103
+ public:
104
+ void OnRemoteBitrateEstimatorAbsSendTimeBitrateChanged(
105
+ RTC::BWE::RemoteBitrateEstimatorAbsSendTime* remoteBitrateEstimator,
106
+ const std::vector<uint32_t>& ssrcs,
107
+ int64_t bitrate) override;
108
+
109
+ private:
110
+ // Current instant, which the scenarios move forward themselves since no
111
+ // class of the module reads a clock.
112
+ int64_t nowUs;
113
+ // Added to the arrival time of every packet, so that a scenario can move
114
+ // the receiver's clock mid-run.
115
+ int64_t arrivalTimeOffsetMs{ 0 };
116
+ // Whether the estimation was reported since the latest reset.
117
+ bool updated{ false };
118
+ // Latest estimation reported (bps).
119
+ int64_t latestBitrate{ 0 };
120
+ LinkSimulator linkSimulator;
121
+ RTC::BWE::RemoteBitrateEstimatorAbsSendTime remoteBitrateEstimator;
122
+ };
123
+ } // namespace bweHelpers
124
+
125
+ #endif