mediasoup 3.27.1 → 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 (203) hide show
  1. package/CHANGELOG.md +14 -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/rtpParameters.fbs +0 -1
  38. package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
  39. package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
  40. package/worker/include/DepLibUV.hpp +13 -0
  41. package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
  42. package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
  43. package/worker/include/RTC/BWE/{Utils.hpp → BitrateUtils.hpp} +3 -3
  44. package/worker/include/RTC/BWE/BweTypes.hpp +170 -2
  45. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
  46. package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
  47. package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
  48. package/worker/include/RTC/BWE/LossBasedController.hpp +105 -0
  49. package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
  50. package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
  51. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
  52. package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
  53. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
  54. package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
  55. package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
  56. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
  57. package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
  58. package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
  59. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
  60. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +15 -0
  61. package/worker/include/RTC/Consts.hpp +70 -0
  62. package/worker/include/RTC/DataConsumer.hpp +3 -5
  63. package/worker/include/RTC/DirectTransport.hpp +4 -5
  64. package/worker/include/RTC/PipeTransport.hpp +4 -5
  65. package/worker/include/RTC/PlainTransport.hpp +4 -5
  66. package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
  67. package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
  68. package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
  69. package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
  70. package/worker/include/RTC/RTP/Packet.hpp +16 -4
  71. package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
  72. package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
  73. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
  74. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
  75. package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
  76. package/worker/include/RTC/RateCalculator.hpp +103 -24
  77. package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
  78. package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
  79. package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
  80. package/worker/include/RTC/RtpDictionaries.hpp +3 -4
  81. package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
  82. package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
  83. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +4 -4
  84. package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
  85. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +1 -1
  86. package/worker/include/RTC/SctpDictionaries.hpp +2 -2
  87. package/worker/include/RTC/TcpConnection.hpp +2 -1
  88. package/worker/include/RTC/Transport.hpp +23 -8
  89. package/worker/include/RTC/TransportTuple.hpp +61 -6
  90. package/worker/include/RTC/WebRtcTransport.hpp +4 -5
  91. package/worker/include/Shared.hpp +5 -0
  92. package/worker/include/SharedInterface.hpp +10 -0
  93. package/worker/include/Utils.hpp +72 -3
  94. package/worker/include/common.hpp +12 -4
  95. package/worker/include/handles/SendCallbacks.hpp +34 -0
  96. package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
  97. package/worker/include/handles/UdpSocketHandle.hpp +4 -8
  98. package/worker/meson.build +41 -3
  99. package/worker/meson_options.txt +1 -0
  100. package/worker/mocks/include/MockShared.hpp +16 -2
  101. package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
  102. package/worker/scripts/package-lock.json +6 -6
  103. package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
  104. package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
  105. package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
  106. package/worker/src/RTC/BWE/{Utils.cpp → BitrateUtils.cpp} +4 -4
  107. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
  108. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
  109. package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
  110. package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
  111. package/worker/src/RTC/BWE/LossBasedController.cpp +189 -41
  112. package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
  113. package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
  114. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
  115. package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
  116. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
  117. package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
  118. package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
  119. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
  120. package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
  121. package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
  122. package/worker/src/RTC/BWE/TargetRateController.cpp +12 -14
  123. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
  124. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +19 -0
  125. package/worker/src/RTC/Consumer.cpp +7 -5
  126. package/worker/src/RTC/DataConsumer.cpp +8 -10
  127. package/worker/src/RTC/DirectTransport.cpp +14 -8
  128. package/worker/src/RTC/DtlsTransport.cpp +8 -8
  129. package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
  130. package/worker/src/RTC/ICE/IceServer.cpp +1 -1
  131. package/worker/src/RTC/PipeTransport.cpp +13 -8
  132. package/worker/src/RTC/PlainTransport.cpp +13 -8
  133. package/worker/src/RTC/Producer.cpp +14 -31
  134. package/worker/src/RTC/RTCP/Bye.cpp +1 -1
  135. package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
  136. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
  137. package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
  138. package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
  139. package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
  140. package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
  141. package/worker/src/RTC/RTP/Packet.cpp +26 -11
  142. package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
  143. package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
  144. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
  145. package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
  146. package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
  147. package/worker/src/RTC/RateCalculator.cpp +133 -28
  148. package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
  149. package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
  150. package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
  151. package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
  152. package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
  153. package/worker/src/RTC/SCTP/association/Association.cpp +1 -1
  154. package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
  155. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  156. package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
  157. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
  158. package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
  159. package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
  160. package/worker/src/RTC/SrtpSession.cpp +2 -2
  161. package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
  162. package/worker/src/RTC/TcpConnection.cpp +2 -2
  163. package/worker/src/RTC/Transport.cpp +111 -93
  164. package/worker/src/RTC/TransportTuple.cpp +4 -4
  165. package/worker/src/RTC/WebRtcServer.cpp +4 -3
  166. package/worker/src/RTC/WebRtcTransport.cpp +20 -13
  167. package/worker/src/Utils/BitStream.cpp +24 -0
  168. package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
  169. package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
  170. package/worker/src/handles/UdpSocketHandle.cpp +14 -21
  171. package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
  172. package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
  173. package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
  174. package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
  175. package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
  176. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
  177. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
  178. package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
  179. package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
  180. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
  181. package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
  182. package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
  183. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
  184. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
  185. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
  186. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
  187. package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
  188. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
  189. package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
  190. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
  191. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
  192. package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
  193. package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
  194. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
  195. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
  196. package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
  197. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
  198. package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
  199. package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
  200. package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
  201. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
  202. package/worker/test/src/Utils/TestTime.cpp +120 -21
  203. package/worker/test/src/RTC/BWE/TestUtils.cpp +0 -61
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseRtpStream = parseRtpStream;
4
+ function parseRtpStream(data) {
5
+ const params = parseRtpStreamParameters(data.params());
6
+ let rtxStream;
7
+ if (data.rtxStream()) {
8
+ rtxStream = parseRtxStream(data.rtxStream());
9
+ }
10
+ return {
11
+ params,
12
+ score: data.score(),
13
+ rtxStream,
14
+ };
15
+ }
16
+ function parseRtpStreamParameters(data) {
17
+ return {
18
+ encodingIdx: data.encodingIdx(),
19
+ ssrc: data.ssrc(),
20
+ payloadType: data.payloadType(),
21
+ mimeType: data.mimeType(),
22
+ clockRate: data.clockRate(),
23
+ rid: data.rid().length > 0 ? data.rid() : undefined,
24
+ cname: data.cname(),
25
+ rtxSsrc: data.rtxSsrc() !== null ? data.rtxSsrc() : undefined,
26
+ rtxPayloadType: data.rtxPayloadType() !== null ? data.rtxPayloadType() : undefined,
27
+ useNack: data.useNack(),
28
+ usePli: data.usePli(),
29
+ useFir: data.useFir(),
30
+ useInBandFec: data.useInBandFec(),
31
+ useDtx: data.useDtx(),
32
+ spatialLayers: data.spatialLayers(),
33
+ temporalLayers: data.temporalLayers(),
34
+ };
35
+ }
36
+ function parseRtxStream(data) {
37
+ const params = parseRtxStreamParameters(data.params());
38
+ return {
39
+ params,
40
+ };
41
+ }
42
+ function parseRtxStreamParameters(data) {
43
+ return {
44
+ ssrc: data.ssrc(),
45
+ payloadType: data.payloadType(),
46
+ mimeType: data.mimeType(),
47
+ clockRate: data.clockRate(),
48
+ rrid: data.rrid().length > 0 ? data.rrid() : undefined,
49
+ cname: data.cname(),
50
+ };
51
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"supportedRtpCapabilities.d.ts","sourceRoot":"","sources":["../src/supportedRtpCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,QAAA,MAAM,wBAAwB,EAAE,qBA4U/B,CAAC;AAEF,OAAO,EAAE,wBAAwB,EAAE,CAAC"}
1
+ {"version":3,"file":"supportedRtpCapabilities.d.ts","sourceRoot":"","sources":["../src/supportedRtpCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,QAAA,MAAM,wBAAwB,EAAE,qBAqU/B,CAAC;AAEF,OAAO,EAAE,wBAAwB,EAAE,CAAC"}
@@ -282,52 +282,45 @@ const supportedRtpCapabilities = {
282
282
  preferredEncrypt: false,
283
283
  direction: 'sendrecv',
284
284
  },
285
- {
286
- kind: 'video',
287
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
288
- preferredId: 9,
289
- preferredEncrypt: false,
290
- direction: 'sendrecv',
291
- },
292
285
  {
293
286
  kind: 'audio',
294
287
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
295
- preferredId: 10,
288
+ preferredId: 9,
296
289
  preferredEncrypt: false,
297
290
  direction: 'sendrecv',
298
291
  },
299
292
  {
300
293
  kind: 'video',
301
294
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
302
- preferredId: 10,
295
+ preferredId: 9,
303
296
  preferredEncrypt: false,
304
297
  direction: 'sendrecv',
305
298
  },
306
299
  {
307
300
  kind: 'audio',
308
301
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
309
- preferredId: 11,
302
+ preferredId: 10,
310
303
  preferredEncrypt: false,
311
304
  direction: 'sendrecv',
312
305
  },
313
306
  {
314
307
  kind: 'video',
315
308
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
316
- preferredId: 11,
309
+ preferredId: 10,
317
310
  preferredEncrypt: false,
318
311
  direction: 'sendrecv',
319
312
  },
320
313
  {
321
314
  kind: 'audio',
322
315
  uri: 'urn:mediasoup:params:rtp-hdrext:packet-id',
323
- preferredId: 12,
316
+ preferredId: 11,
324
317
  preferredEncrypt: false,
325
318
  direction: 'sendrecv',
326
319
  },
327
320
  {
328
321
  kind: 'video',
329
322
  uri: 'urn:mediasoup:params:rtp-hdrext:packet-id',
330
- preferredId: 12,
323
+ preferredId: 11,
331
324
  preferredEncrypt: false,
332
325
  direction: 'sendrecv',
333
326
  },
@@ -233,12 +233,6 @@ const ctx = {
233
233
  preferredId: 8,
234
234
  preferredEncrypt: false,
235
235
  },
236
- {
237
- kind: 'video',
238
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
239
- preferredId: 9,
240
- preferredEncrypt: false,
241
- },
242
236
  ],
243
237
  }),
244
238
  vpxMediaCodecs: utils.deepFreeze([
@@ -745,7 +739,7 @@ test('consumer.dump() succeeds', async () => {
745
739
  { type: 'goog-remb' },
746
740
  ]);
747
741
  expect(Array.isArray(dump2.rtpParameters.headerExtensions)).toBe(true);
748
- expect(dump2.rtpParameters.headerExtensions.length).toBe(4);
742
+ expect(dump2.rtpParameters.headerExtensions.length).toBe(3);
749
743
  expect(dump2.rtpParameters.headerExtensions).toEqual([
750
744
  {
751
745
  uri: 'urn:ietf:params:rtp-hdrext:sdes:mid',
@@ -765,12 +759,6 @@ test('consumer.dump() succeeds', async () => {
765
759
  parameters: {},
766
760
  encrypt: false,
767
761
  },
768
- {
769
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
770
- id: 9,
771
- parameters: {},
772
- encrypt: false,
773
- },
774
762
  ]);
775
763
  expect(Array.isArray(dump2.rtpParameters.encodings)).toBe(true);
776
764
  expect(dump2.rtpParameters.encodings.length).toBe(1);
@@ -114,6 +114,15 @@ test('transport.consumeData() with unknown dataProducerId fails', async () => {
114
114
  dataProducerId: '12345678',
115
115
  })).rejects.toThrow(errors_1.NotFoundError);
116
116
  }, 2000);
117
+ test('transport.consumeData() with maxRetransmits replaces DataProducer maxPacketLifeTime', async () => {
118
+ const dataConsumer = await ctx.webRtcTransport2.consumeData({
119
+ dataProducerId: ctx.sctpDataProducer.id,
120
+ maxRetransmits: 2,
121
+ });
122
+ expect(dataConsumer.sctpStreamParameters.ordered).toBe(false);
123
+ expect(dataConsumer.sctpStreamParameters.maxPacketLifeTime).toBeUndefined();
124
+ expect(dataConsumer.sctpStreamParameters.maxRetransmits).toBe(2);
125
+ }, 2000);
117
126
  test('dataConsumer.dump() succeeds', async () => {
118
127
  const dataConsumer = await ctx.webRtcTransport2.consumeData({
119
128
  dataProducerId: ctx.sctpDataProducer.id,
@@ -154,6 +154,44 @@ test('transport.produceData() with ordered and maxPacketLifeTime rejects with Ty
154
154
  },
155
155
  })).rejects.toThrow(TypeError);
156
156
  }, 2000);
157
+ test('transport.produceData() with maxRetransmits 0 or maxPacketLifeTime 0 creates an unordered DataProducer', async () => {
158
+ const dataProducer1 = await ctx.webRtcTransport1.produceData({
159
+ sctpStreamParameters: {
160
+ streamId: 888,
161
+ maxRetransmits: 0,
162
+ },
163
+ });
164
+ expect(dataProducer1.sctpStreamParameters?.ordered).toBe(false);
165
+ expect(dataProducer1.sctpStreamParameters?.maxPacketLifeTime).toBeUndefined();
166
+ expect(dataProducer1.sctpStreamParameters?.maxRetransmits).toBe(0);
167
+ const dataProducer2 = await ctx.webRtcTransport1.produceData({
168
+ sctpStreamParameters: {
169
+ streamId: 999,
170
+ maxPacketLifeTime: 0,
171
+ },
172
+ });
173
+ expect(dataProducer2.sctpStreamParameters?.ordered).toBe(false);
174
+ expect(dataProducer2.sctpStreamParameters?.maxPacketLifeTime).toBe(0);
175
+ expect(dataProducer2.sctpStreamParameters?.maxRetransmits).toBeUndefined();
176
+ }, 2000);
177
+ test('transport.produceData() with ordered and maxRetransmits 0 rejects with TypeError', async () => {
178
+ await expect(ctx.webRtcTransport1.produceData({
179
+ sctpStreamParameters: {
180
+ streamId: 999,
181
+ ordered: true,
182
+ maxRetransmits: 0,
183
+ },
184
+ })).rejects.toThrow(TypeError);
185
+ }, 2000);
186
+ test('transport.produceData() with maxPacketLifeTime 0 and maxRetransmits rejects with TypeError', async () => {
187
+ await expect(ctx.webRtcTransport1.produceData({
188
+ sctpStreamParameters: {
189
+ streamId: 999,
190
+ maxPacketLifeTime: 0,
191
+ maxRetransmits: 5,
192
+ },
193
+ })).rejects.toThrow(TypeError);
194
+ }, 2000);
157
195
  test('dataProducer.dump() succeeds', async () => {
158
196
  const dataProducer1 = await ctx.webRtcTransport1.produceData(ctx.dataProducerOptions1);
159
197
  const dump1 = await dataProducer1.dump();
@@ -262,13 +262,13 @@ test('router.pipeToRouter() succeeds with audio', async () => {
262
262
  },
263
263
  {
264
264
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
265
- id: 11,
265
+ id: 10,
266
266
  encrypt: false,
267
267
  parameters: {},
268
268
  },
269
269
  {
270
270
  uri: 'urn:mediasoup:params:rtp-hdrext:packet-id',
271
- id: 12,
271
+ id: 11,
272
272
  encrypt: false,
273
273
  parameters: {},
274
274
  },
@@ -315,13 +315,13 @@ test('router.pipeToRouter() succeeds with audio', async () => {
315
315
  },
316
316
  {
317
317
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
318
- id: 11,
318
+ id: 10,
319
319
  encrypt: false,
320
320
  parameters: {},
321
321
  },
322
322
  {
323
323
  uri: 'urn:mediasoup:params:rtp-hdrext:packet-id',
324
- id: 12,
324
+ id: 11,
325
325
  encrypt: false,
326
326
  parameters: {},
327
327
  },
@@ -370,21 +370,15 @@ test('router.pipeToRouter() succeeds with video', async () => {
370
370
  encrypt: false,
371
371
  parameters: {},
372
372
  },
373
- {
374
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
375
- id: 9,
376
- encrypt: false,
377
- parameters: {},
378
- },
379
373
  {
380
374
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
381
- id: 11,
375
+ id: 10,
382
376
  encrypt: false,
383
377
  parameters: {},
384
378
  },
385
379
  {
386
380
  uri: 'urn:mediasoup:params:rtp-hdrext:packet-id',
387
- id: 12,
381
+ id: 11,
388
382
  encrypt: false,
389
383
  parameters: {},
390
384
  },
@@ -428,21 +422,15 @@ test('router.pipeToRouter() succeeds with video', async () => {
428
422
  encrypt: false,
429
423
  parameters: {},
430
424
  },
431
- {
432
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
433
- id: 9,
434
- encrypt: false,
435
- parameters: {},
436
- },
437
425
  {
438
426
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
439
- id: 11,
427
+ id: 10,
440
428
  encrypt: false,
441
429
  parameters: {},
442
430
  },
443
431
  {
444
432
  uri: 'urn:mediasoup:params:rtp-hdrext:packet-id',
445
- id: 12,
433
+ id: 11,
446
434
  encrypt: false,
447
435
  parameters: {},
448
436
  },
@@ -479,7 +467,7 @@ test('router.pipeToRouter() gives abs-capture-time to the pipe Consumer if the P
479
467
  }));
480
468
  expect(pipeConsumer.rtpParameters.headerExtensions).toContainEqual({
481
469
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
482
- id: 10,
470
+ id: 9,
483
471
  encrypt: false,
484
472
  parameters: {},
485
473
  });
@@ -502,6 +490,22 @@ test('router.pipeToRouter() with unknown router, producerId or dataProducerId fa
502
490
  dataProducerId: '12345678',
503
491
  })).rejects.toThrow(errors_1.NotFoundError);
504
492
  }, 2000);
493
+ test('router.pipeToRouter() can be retried after failing to create the PipeTransport pair', async () => {
494
+ // Fails because the IP is not assigned to any local network interface.
495
+ await expect(ctx.router1.pipeToRouter({
496
+ router: ctx.router2,
497
+ producerId: ctx.videoProducer.id,
498
+ listenInfo: { protocol: 'udp', ip: '203.0.113.1' },
499
+ })).rejects.toThrow();
500
+ const { pipeConsumer, pipeProducer } = await ctx.router1.pipeToRouter({
501
+ router: ctx.router2,
502
+ producerId: ctx.videoProducer.id,
503
+ listenInfo: { protocol: 'udp', ip: '127.0.0.1' },
504
+ });
505
+ expect(pipeConsumer).toBeDefined();
506
+ expect(pipeProducer).toBeDefined();
507
+ expect(pipeProducer.id).toBe(ctx.videoProducer.id);
508
+ }, 5000);
505
509
  test('router.createPipeTransport() with wrong arguments rejects with TypeError', async () => {
506
510
  // @ts-expect-error --- Testing purposes.
507
511
  await expect(ctx.router1.createPipeTransport({})).rejects.toThrow(TypeError);
@@ -576,21 +580,15 @@ test('router.createPipeTransport() with enableRtx succeeds', async () => {
576
580
  encrypt: false,
577
581
  parameters: {},
578
582
  },
579
- {
580
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
581
- id: 9,
582
- encrypt: false,
583
- parameters: {},
584
- },
585
583
  {
586
584
  uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
587
- id: 11,
585
+ id: 10,
588
586
  encrypt: false,
589
587
  parameters: {},
590
588
  },
591
589
  {
592
590
  uri: 'urn:mediasoup:params:rtp-hdrext:packet-id',
593
- id: 12,
591
+ id: 11,
594
592
  encrypt: false,
595
593
  parameters: {},
596
594
  },
@@ -536,6 +536,8 @@ test('producer.dump() succeeds', async () => {
536
536
  expect(dump1.rtpParameters.encodings[0]).toEqual(expect.objectContaining({
537
537
  codecPayloadType: 0,
538
538
  }));
539
+ // No RTP has been received yet, so there are no RTP streams.
540
+ expect(dump1.rtpStreams).toEqual([]);
539
541
  expect(dump1.type).toBe('simple');
540
542
  const videoProducer = await ctx.webRtcTransport2.produce(ctx.videoProducerOptions);
541
543
  const dump2 = await videoProducer.dump();
@@ -592,8 +594,103 @@ test('producer.dump() succeeds', async () => {
592
594
  { codecPayloadType: 112, ssrc: 22222226, rtx: { ssrc: 22222227 } },
593
595
  { codecPayloadType: 112, ssrc: 22222228, rtx: { ssrc: 22222229 } },
594
596
  ]);
597
+ // These encodings have no rid, so it must be undefined in rtpMapping.
598
+ expect(dump2.rtpMapping).toMatchObject({
599
+ encodings: [
600
+ { rid: undefined, ssrc: 22222222 },
601
+ { rid: undefined, ssrc: 22222224 },
602
+ { rid: undefined, ssrc: 22222226 },
603
+ { rid: undefined, ssrc: 22222228 },
604
+ ],
605
+ });
606
+ expect(dump2.rtpStreams).toEqual([]);
595
607
  expect(dump2.type).toBe('simulcast');
596
608
  }, 2000);
609
+ test('producer.dump() exposes rid in rtpMapping.encodings', async () => {
610
+ const videoProducer = await ctx.webRtcTransport1.produce({
611
+ kind: 'video',
612
+ rtpParameters: {
613
+ mid: 'VIDEO',
614
+ codecs: [
615
+ {
616
+ mimeType: 'video/VP8',
617
+ payloadType: 96,
618
+ clockRate: 90000,
619
+ },
620
+ ],
621
+ headerExtensions: [
622
+ {
623
+ uri: 'urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id',
624
+ id: 11,
625
+ },
626
+ ],
627
+ encodings: [{ rid: 'r0' }, { rid: 'r1' }, { rid: 'r2' }],
628
+ rtcp: { cname: 'video-rid' },
629
+ },
630
+ });
631
+ const dump = await videoProducer.dump();
632
+ expect(dump.type).toBe('simulcast');
633
+ expect(dump.rtpMapping).toMatchObject({
634
+ encodings: [
635
+ { rid: 'r0', ssrc: undefined },
636
+ { rid: 'r1', ssrc: undefined },
637
+ { rid: 'r2', ssrc: undefined },
638
+ ],
639
+ });
640
+ }, 2000);
641
+ test('producer.dump() exposes rtpStreams once RTP is received', async () => {
642
+ // RTP packet without extensions or payload.
643
+ // payloadType: 1, seqNumber: 8, timestamp: 4, ssrc: 5.
644
+ // prettier-ignore
645
+ const rtpPacket = Buffer.from([
646
+ 0x80, 0x01, 0x00, 0x08,
647
+ 0x00, 0x00, 0x00, 0x04,
648
+ 0x00, 0x00, 0x00, 0x05,
649
+ ]);
650
+ // A DirectTransport is needed since it's the only one that allows injecting
651
+ // RTP packets via producer.send().
652
+ const directTransport = await ctx.router.createDirectTransport();
653
+ const audioProducer = await directTransport.produce({
654
+ kind: 'audio',
655
+ rtpParameters: {
656
+ mid: 'AUDIO',
657
+ codecs: [
658
+ {
659
+ mimeType: 'audio/opus',
660
+ payloadType: 1,
661
+ clockRate: 48000,
662
+ channels: 2,
663
+ },
664
+ ],
665
+ encodings: [{ ssrc: 5 }],
666
+ rtcp: { cname: 'audio-rtp' },
667
+ },
668
+ });
669
+ // No RTP has been received yet, so there are no RTP streams.
670
+ await expect(audioProducer.dump()).resolves.toMatchObject({
671
+ rtpStreams: [],
672
+ });
673
+ // The worker emits a first 'score' event as soon as it creates the
674
+ // RtpStreamRecv, which happens upon reception of the first RTP packet.
675
+ const onScore = (0, enhancedEvents_1.enhancedOnce)(audioProducer, 'score');
676
+ audioProducer.send(rtpPacket);
677
+ await onScore;
678
+ const dump = await audioProducer.dump();
679
+ expect(dump.rtpStreams.length).toBe(1);
680
+ expect(typeof dump.rtpStreams[0].score).toBe('number');
681
+ expect(dump.rtpStreams[0].rtxStream).toBeUndefined();
682
+ expect(dump.rtpStreams[0].params).toMatchObject({
683
+ encodingIdx: 0,
684
+ ssrc: 5,
685
+ payloadType: 1,
686
+ mimeType: 'audio/opus',
687
+ clockRate: 48000,
688
+ cname: 'audio-rtp',
689
+ rid: undefined,
690
+ rtxSsrc: undefined,
691
+ rtxPayloadType: undefined,
692
+ });
693
+ }, 2000);
597
694
  test('producer.getStats() succeeds', async () => {
598
695
  const audioProducer = await ctx.webRtcTransport1.produce(ctx.audioProducerOptions);
599
696
  const videoProducer = await ctx.webRtcTransport2.produce(ctx.videoProducerOptions);
@@ -174,7 +174,7 @@ test('generateRouterRtpCapabilities() with too many codecs throws', () => {
174
174
  channels: 2,
175
175
  });
176
176
  }
177
- expect(() => ortc.generateRouterRtpCapabilities(mediaCodecs)).toThrow('cannot allocate');
177
+ expect(() => ortc.generateRouterRtpCapabilities(mediaCodecs)).toThrow();
178
178
  });
179
179
  test('getProducerRtpParametersMapping(), getConsumableRtpParameters(), getConsumerRtpParameters() and getPipeConsumerRtpParameters() succeed', () => {
180
180
  const mediaCodecs = [
@@ -377,13 +377,6 @@ test('getProducerRtpParametersMapping(), getConsumableRtpParameters(), getConsum
377
377
  preferredEncrypt: false,
378
378
  direction: 'sendrecv',
379
379
  },
380
- {
381
- kind: 'video',
382
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
383
- preferredId: 9,
384
- preferredEncrypt: false,
385
- direction: 'sendrecv',
386
- },
387
380
  ],
388
381
  };
389
382
  const consumerRtpParameters = ortc.getConsumerRtpParameters({
@@ -436,12 +429,6 @@ test('getProducerRtpParametersMapping(), getConsumableRtpParameters(), getConsum
436
429
  encrypt: false,
437
430
  parameters: {},
438
431
  },
439
- {
440
- uri: 'urn:ietf:params:rtp-hdrext:toffset',
441
- id: 9,
442
- encrypt: false,
443
- parameters: {},
444
- },
445
432
  ]);
446
433
  expect(consumerRtpParameters.rtcp).toEqual({
447
434
  cname: rtpParameters.rtcp?.cname,
@@ -523,3 +510,36 @@ test('getProducerRtpParametersMapping() with incompatible params throws Unsuppor
523
510
  };
524
511
  expect(() => ortc.getProducerRtpParametersMapping(rtpParameters, routerRtpCapabilities)).toThrow(errors_1.UnsupportedError);
525
512
  });
513
+ test('getProducerRtpParametersMapping() with RTX apt pointing to a non media codec throws', () => {
514
+ const mediaCodecs = [
515
+ {
516
+ kind: 'video',
517
+ mimeType: 'video/VP8',
518
+ clockRate: 90000,
519
+ },
520
+ ];
521
+ const routerRtpCapabilities = ortc.generateRouterRtpCapabilities(mediaCodecs);
522
+ // The apt parameter of the RTX codec is its own payload type, which is not a
523
+ // media codec.
524
+ const rtpParameters = {
525
+ codecs: [
526
+ {
527
+ mimeType: 'video/VP8',
528
+ payloadType: 111,
529
+ clockRate: 90000,
530
+ },
531
+ {
532
+ mimeType: 'video/rtx',
533
+ payloadType: 112,
534
+ clockRate: 90000,
535
+ parameters: { apt: 112 },
536
+ },
537
+ ],
538
+ headerExtensions: [],
539
+ encodings: [{ ssrc: 11111111 }],
540
+ rtcp: {
541
+ cname: 'qwerty1234',
542
+ },
543
+ };
544
+ expect(() => ortc.getProducerRtpParametersMapping(rtpParameters, routerRtpCapabilities)).toThrow(TypeError);
545
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup",
3
- "version": "3.27.1",
3
+ "version": "3.28.0",
4
4
  "description": "Cutting Edge WebRTC Video Conferencing",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -121,22 +121,22 @@
121
121
  "@types/debug": "^4.1.13",
122
122
  "@types/ini": "^4.1.1",
123
123
  "@types/jest": "^30.0.0",
124
- "@types/node": "^26.5.1",
125
- "eslint": "^10.10.0",
124
+ "@types/node": "^26.6.3",
125
+ "eslint": "^10.11.0",
126
126
  "eslint-config-prettier": "^10.1.8",
127
127
  "eslint-plugin-jest": "^29.16.6",
128
128
  "eslint-plugin-prettier": "^5.5.6",
129
- "globals": "^17.12.0",
129
+ "globals": "^17.13.0",
130
130
  "ini": "^7.0.0",
131
- "jest": "^30.5.1",
132
- "knip": "^6.35.1",
133
- "marked": "^18.0.13",
131
+ "jest": "^30.5.2",
132
+ "knip": "^6.39.0",
133
+ "marked": "^18.0.14",
134
134
  "open-cli": "^9.0.0",
135
135
  "pick-port": "^2.2.1",
136
- "prettier": "^3.9.6",
137
- "ts-jest": "^29.4.12",
136
+ "prettier": "^3.9.9",
137
+ "ts-jest": "^29.4.14",
138
138
  "typescript": "^6.0.3",
139
- "typescript-eslint": "^8.70.0",
139
+ "typescript-eslint": "^8.71.0",
140
140
  "werift-sctp": "^0.0.11"
141
141
  }
142
142
  }
@@ -70,7 +70,6 @@ enum RtpHeaderExtensionUri: uint8 {
70
70
  SsrcAudioLevel,
71
71
  DependencyDescriptor,
72
72
  VideoOrientation,
73
- TimeOffset,
74
73
  AbsCaptureTime,
75
74
  PlayoutDelay,
76
75
  MediasoupPacketId,
@@ -92,10 +92,12 @@ void FuzzerUtils::Fuzz(const uint8_t* data, size_t len)
92
92
 
93
93
  /* Time class. */
94
94
 
95
- auto ntp = Utils::Time::TimeUs2Ntp(static_cast<int64_t>(len));
95
+ auto ntp = Utils::Time::TimeUsToNtp(static_cast<int64_t>(len));
96
96
 
97
- Utils::Time::Ntp2TimeUs(ntp);
97
+ Utils::Time::NtpToTimeUs(ntp);
98
+ Utils::Time::CompactNtpIntervalToTimeUs(static_cast<uint32_t>(len));
99
+ Utils::Time::CompactNtpRttToTimeUs(static_cast<uint32_t>(len));
98
100
  Utils::Time::TimeUsToAbsSendTime(static_cast<int64_t>(len));
99
101
  Utils::Time::Q32x32ToTimeUs(static_cast<int64_t>(len));
100
- Utils::Time::TimeUs2Q32x32(static_cast<int64_t>(len));
102
+ Utils::Time::TimeUsToQ32x32(static_cast<int64_t>(len));
101
103
  }
@@ -2,6 +2,7 @@
2
2
  #include "RTC/RTP/HeaderExtensionIds.hpp"
3
3
  #include "RTC/RTP/Packet.hpp"
4
4
  #include "RTC/RtpDictionaries.hpp"
5
+ #include "Utils.hpp"
5
6
  #include <string>
6
7
  #include <vector>
7
8
 
@@ -35,6 +36,8 @@ void FuzzerRtcRtcPacket::Fuzz(const uint8_t* data, size_t len)
35
36
  bool flip;
36
37
  uint16_t rotation;
37
38
  uint32_t absSendTime;
39
+ uint64_t absCaptureTimestamp;
40
+ int64_t estimatedCaptureClockOffset;
38
41
  uint16_t playoutDelayMinDelay;
39
42
  uint16_t playoutDelayMaxDelay;
40
43
  uint16_t wideSeqNumber;
@@ -76,6 +79,7 @@ void FuzzerRtcRtcPacket::Fuzz(const uint8_t* data, size_t len)
76
79
  headerExtensionIds.ssrcAudioLevel = 1;
77
80
  headerExtensionIds.videoOrientation = 2;
78
81
  headerExtensionIds.playoutDelay = 8;
82
+ headerExtensionIds.absCaptureTime = 9;
79
83
 
80
84
  packet->AssignExtensionIds(headerExtensionIds);
81
85
 
@@ -91,7 +95,7 @@ void FuzzerRtcRtcPacket::Fuzz(const uint8_t* data, size_t len)
91
95
  packet->HasExtension(3);
92
96
  packet->GetExtensionValue(3, extenLen);
93
97
  packet->ReadAbsSendTime(absSendTime);
94
- packet->UpdateAbsSendTime(12345678);
98
+ packet->UpdateAbsSendTime(Utils::Time::TimeUsToAbsSendTime(12345678));
95
99
 
96
100
  packet->HasExtension(4);
97
101
  packet->GetExtensionValue(4, extenLen);
@@ -110,6 +114,11 @@ void FuzzerRtcRtcPacket::Fuzz(const uint8_t* data, size_t len)
110
114
  packet->GetExtensionValue(8, extenLen);
111
115
  packet->ReadPlayoutDelay(playoutDelayMinDelay, playoutDelayMaxDelay);
112
116
 
117
+ packet->HasExtension(9);
118
+ packet->GetExtensionValue(9, extenLen);
119
+ packet->ReadAbsCaptureTime(absCaptureTimestamp, estimatedCaptureClockOffset);
120
+ packet->UpdateAbsCaptureTime(12345678);
121
+
113
122
  packet->HasExtension(6);
114
123
  packet->HasExtension(7);
115
124
  packet->HasExtension(8);
@@ -189,7 +198,7 @@ void FuzzerRtcRtcPacket::Fuzz(const uint8_t* data, size_t len)
189
198
  packet->HasExtension(13);
190
199
  packet->GetExtensionValue(13, extenLen);
191
200
  packet->ReadAbsSendTime(absSendTime);
192
- packet->UpdateAbsSendTime(12345678);
201
+ packet->UpdateAbsSendTime(Utils::Time::TimeUsToAbsSendTime(12345678));
193
202
 
194
203
  packet->HasExtension(14);
195
204
  packet->GetExtensionValue(14, extenLen);
@@ -208,6 +217,11 @@ void FuzzerRtcRtcPacket::Fuzz(const uint8_t* data, size_t len)
208
217
  packet->GetExtensionValue(15, extenLen);
209
218
  packet->ReadPlayoutDelay(playoutDelayMinDelay, playoutDelayMaxDelay);
210
219
 
220
+ packet->HasExtension(16);
221
+ packet->GetExtensionValue(16, extenLen);
222
+ packet->ReadAbsCaptureTime(absCaptureTimestamp, estimatedCaptureClockOffset);
223
+ packet->UpdateAbsCaptureTime(12345678);
224
+
211
225
  packet->HasPayload();
212
226
  packet->GetPayload();
213
227
  packet->GetPayloadLength();