mediasoup 3.10.3 → 3.10.4

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.
@@ -15,7 +15,7 @@ export declare class EnhancedEventEmitter<E extends Events = Events> extends Eve
15
15
  once<K extends keyof E & string>(eventName: K, listener: (...args: E[K]) => void): this;
16
16
  prependOnceListener<K extends keyof E & string>(eventName: K, listener: (...args: E[K]) => void): this;
17
17
  removeListener<K extends keyof E & string>(eventName: K, listener: (...args: E[K]) => void): this;
18
- removeAllListeners<K extends keyof E & string>(eventName: K): this;
18
+ removeAllListeners<K extends keyof E & string>(eventName?: K): this;
19
19
  listenerCount<K extends keyof E & string>(eventName: K): number;
20
20
  listeners<K extends keyof E & string>(eventName: K): Function[];
21
21
  rawListeners<K extends keyof E & string>(eventName: K): Function[];
@@ -1 +1 @@
1
- {"version":3,"file":"EnhancedEventEmitter.d.ts","sourceRoot":"","sources":["../src/EnhancedEventEmitter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,aAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;AAEnC,qBAAa,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,YAAY;;IAQhF,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO;IAKtE;;OAEG;IACH,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO;IAkB1E,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC5B,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC7B,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EACrC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EACzC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC9B,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC7C,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EACxC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI;IAOlE,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM;IAK/D,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE;IAK/D,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE;CAIlE"}
1
+ {"version":3,"file":"EnhancedEventEmitter.d.ts","sourceRoot":"","sources":["../src/EnhancedEventEmitter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,aAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;AAEnC,qBAAa,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,YAAY;;IAQhF,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO;IAKtE;;OAEG;IACH,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO;IAkB1E,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC5B,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC7B,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EACrC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EACzC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC9B,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAC7C,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EACxC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/B,IAAI;IAOP,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI;IAOnE,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM;IAK/D,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE;IAK/D,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE;CAIlE"}
@@ -81,7 +81,7 @@ class Worker extends EnhancedEventEmitter_1.EnhancedEventEmitter {
81
81
  // options
82
82
  {
83
83
  env: {
84
- MEDIASOUP_VERSION: '3.10.3',
84
+ MEDIASOUP_VERSION: '3.10.4',
85
85
  // Let the worker process inherit all environment variables, useful
86
86
  // if a custom and not in the path GCC is used so the user can set
87
87
  // LD_LIBRARY_PATH environment variable for runtime.
@@ -9,7 +9,7 @@ export { types };
9
9
  /**
10
10
  * Expose mediasoup version.
11
11
  */
12
- export declare const version = "3.10.3";
12
+ export declare const version = "3.10.4";
13
13
  /**
14
14
  * Expose parseScalabilityMode() function.
15
15
  */
package/node/lib/index.js CHANGED
@@ -11,7 +11,7 @@ exports.types = types;
11
11
  /**
12
12
  * Expose mediasoup version.
13
13
  */
14
- exports.version = '3.10.3';
14
+ exports.version = '3.10.4';
15
15
  /**
16
16
  * Expose parseScalabilityMode() function.
17
17
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup",
3
- "version": "3.10.3",
3
+ "version": "3.10.4",
4
4
  "description": "Cutting Edge WebRTC Video Conferencing",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -78,10 +78,10 @@
78
78
  "devDependencies": {
79
79
  "@types/debug": "^4.1.7",
80
80
  "@types/uuid": "^8.3.4",
81
- "@typescript-eslint/eslint-plugin": "^5.30.5",
82
- "@typescript-eslint/parser": "^5.30.5",
83
- "eslint": "^8.19.0",
84
- "eslint-plugin-jest": "^26.5.3",
81
+ "@typescript-eslint/eslint-plugin": "^5.30.6",
82
+ "@typescript-eslint/parser": "^5.30.6",
83
+ "eslint": "^8.20.0",
84
+ "eslint-plugin-jest": "^26.6.0",
85
85
  "jest": "^27.5.1",
86
86
  "jest-tobetype": "^1.2.3",
87
87
  "open-cli": "^7.0.1",
@@ -142,8 +142,8 @@ namespace RTC
142
142
  virtual uint32_t IncreaseLayer(uint32_t bitrate, bool considerLoss) = 0;
143
143
  virtual void ApplyLayers() = 0;
144
144
  virtual uint32_t GetDesiredBitrate() const = 0;
145
- virtual void SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet) = 0;
146
- virtual std::vector<RTC::RtpStreamSend*> GetRtpStreams() = 0;
145
+ virtual void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) = 0;
146
+ virtual std::vector<RTC::RtpStreamSend*> GetRtpStreams() = 0;
147
147
  virtual void GetRtcp(
148
148
  RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) = 0;
149
149
  virtual void NeedWorstRemoteFractionLost(uint32_t mappedSsrc, uint8_t& worstRemoteFractionLost) = 0;
@@ -30,7 +30,7 @@ namespace RTC
30
30
  uint32_t IncreaseLayer(uint32_t bitrate, bool considerLoss) override;
31
31
  void ApplyLayers() override;
32
32
  uint32_t GetDesiredBitrate() const override;
33
- void SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet) override;
33
+ void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) override;
34
34
  void GetRtcp(RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) override;
35
35
  std::vector<RTC::RtpStreamSend*> GetRtpStreams() override
36
36
  {
@@ -71,7 +71,7 @@ namespace RTC
71
71
 
72
72
  void FillJsonStats(json& jsonObject) override;
73
73
  void SetRtx(uint8_t payloadType, uint32_t ssrc) override;
74
- bool ReceivePacket(std::shared_ptr<RTC::RtpPacket> packet);
74
+ bool ReceivePacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket);
75
75
  void ReceiveNack(RTC::RTCP::FeedbackRtpNackPacket* nackPacket);
76
76
  void ReceiveKeyFrameRequest(RTC::RTCP::FeedbackPs::MessageType messageType);
77
77
  void ReceiveRtcpReceiverReport(RTC::RTCP::ReceiverReport* report);
@@ -90,7 +90,7 @@ namespace RTC
90
90
  uint32_t GetLayerBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer) override;
91
91
 
92
92
  private:
93
- void StorePacket(std::shared_ptr<RTC::RtpPacket> packet);
93
+ void StorePacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket);
94
94
  void ClearOldPackets(const RtpPacket* packet);
95
95
  void ClearBuffer();
96
96
  void FillRetransmissionContainer(uint16_t seq, uint16_t bitmask);
@@ -40,7 +40,7 @@ namespace RTC
40
40
  uint32_t IncreaseLayer(uint32_t bitrate, bool considerLoss) override;
41
41
  void ApplyLayers() override;
42
42
  uint32_t GetDesiredBitrate() const override;
43
- void SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet) override;
43
+ void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) override;
44
44
  std::vector<RTC::RtpStreamSend*> GetRtpStreams() override
45
45
  {
46
46
  return this->rtpStreams;
@@ -56,7 +56,7 @@ namespace RTC
56
56
  uint32_t IncreaseLayer(uint32_t bitrate, bool considerLoss) override;
57
57
  void ApplyLayers() override;
58
58
  uint32_t GetDesiredBitrate() const override;
59
- void SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet) override;
59
+ void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) override;
60
60
  void GetRtcp(RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) override;
61
61
  std::vector<RTC::RtpStreamSend*> GetRtpStreams() override
62
62
  {
@@ -51,7 +51,7 @@ namespace RTC
51
51
  uint32_t IncreaseLayer(uint32_t bitrate, bool considerLoss) override;
52
52
  void ApplyLayers() override;
53
53
  uint32_t GetDesiredBitrate() const override;
54
- void SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet) override;
54
+ void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) override;
55
55
  void GetRtcp(RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) override;
56
56
  std::vector<RTC::RtpStreamSend*> GetRtpStreams() override
57
57
  {
@@ -980,28 +980,25 @@ namespace RTC
980
980
  {
981
981
  MS_TRACE();
982
982
 
983
+ MS_ASSERT(this->ssl, "this->ssl is not set");
983
984
  MS_ASSERT(
984
985
  this->state == DtlsState::CONNECTING || this->state == DtlsState::CONNECTED,
985
986
  "invalid DTLS state");
986
987
 
987
- int64_t ret;
988
988
  uv_timeval_t dtlsTimeout{ 0, 0 };
989
989
  uint64_t timeoutMs;
990
990
 
991
- // NOTE: No DTLSv_1_2_get_timeout() or DTLS_get_timeout() in OpenSSL 1.1.0-dev.
992
- ret = DTLSv1_get_timeout(this->ssl, static_cast<void*>(&dtlsTimeout)); // NOLINT
993
-
994
- if (ret == 0)
995
- {
996
- OnTimer(this->timer);
997
-
998
- return true;
999
- }
991
+ // DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is
992
+ // a timeout in progress, it sets *out to the time remaining and returns
993
+ // one. Otherwise, it returns zero.
994
+ DTLSv1_get_timeout(this->ssl, static_cast<void*>(&dtlsTimeout)); // NOLINT
1000
995
 
1001
996
  timeoutMs = (dtlsTimeout.tv_sec * static_cast<uint64_t>(1000)) + (dtlsTimeout.tv_usec / 1000);
1002
997
 
1003
998
  if (timeoutMs == 0)
1004
999
  {
1000
+ MS_DEBUG_DEV("timeout is 0, calling OnTimer() callback directly");
1001
+
1005
1002
  OnTimer(this->timer);
1006
1003
 
1007
1004
  return true;
@@ -1424,11 +1421,21 @@ namespace RTC
1424
1421
  return;
1425
1422
  }
1426
1423
 
1424
+ // DTLSv1_handle_timeout is called when a DTLS handshake timeout expires.
1425
+ // If no timeout had expired, it returns 0. Otherwise, it retransmits the
1426
+ // previous flight of handshake messages and returns 1. If too many timeouts
1427
+ // had expired without progress or an error occurs, it returns -1.
1427
1428
  auto ret = DTLSv1_handle_timeout(this->ssl);
1428
1429
 
1429
- // -1 means that too many timeouts had expired without progress or an
1430
- // error occurs.
1431
- if (ret == -1)
1430
+ if (ret == 1)
1431
+ {
1432
+ // If required, send DTLS data.
1433
+ SendPendingOutgoingDtlsData();
1434
+
1435
+ // Set the DTLS timer again.
1436
+ SetTimeout();
1437
+ }
1438
+ else if (ret == -1)
1432
1439
  {
1433
1440
  MS_WARN_TAG(dtls, "DTLSv1_handle_timeout() failed");
1434
1441
 
@@ -1438,13 +1445,5 @@ namespace RTC
1438
1445
  this->state = DtlsState::FAILED;
1439
1446
  this->listener->OnDtlsTransportFailed(this);
1440
1447
  }
1441
- else
1442
- {
1443
- // If required, send DTLS data.
1444
- SendPendingOutgoingDtlsData();
1445
-
1446
- // Set the DTLS timer again.
1447
- SetTimeout();
1448
- }
1449
1448
  }
1450
1449
  } // namespace RTC
@@ -184,7 +184,7 @@ namespace RTC
184
184
  return 0u;
185
185
  }
186
186
 
187
- void PipeConsumer::SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet)
187
+ void PipeConsumer::SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket)
188
188
  {
189
189
  MS_TRACE();
190
190
 
@@ -253,13 +253,13 @@ namespace RTC
253
253
  }
254
254
 
255
255
  // Process the packet.
256
- if (rtpStream->ReceivePacket(packet))
256
+ if (rtpStream->ReceivePacket(packet, sharedPacket))
257
257
  {
258
258
  // Send the packet.
259
- this->listener->OnConsumerSendRtpPacket(this, packet.get());
259
+ this->listener->OnConsumerSendRtpPacket(this, packet);
260
260
 
261
261
  // May emit 'trace' event.
262
- EmitTraceEventRtpAndKeyFrameTypes(packet.get());
262
+ EmitTraceEventRtpAndKeyFrameTypes(packet);
263
263
  }
264
264
  else
265
265
  {
@@ -798,9 +798,10 @@ namespace RTC
798
798
 
799
799
  if (!consumers.empty())
800
800
  {
801
- // Clone the packet so it holds its own buffer, usable for future
802
- // retransmissions.
803
- std::shared_ptr<RTC::RtpPacket> sharedPacket(packet->Clone());
801
+ // Cloned ref-counted packet that RtpStreamSend will store for as long as
802
+ // needed avoiding multiple allocations unless absolutely necessary.
803
+ // Clone only happens if needed.
804
+ std::shared_ptr<RTC::RtpPacket> sharedPacket;
804
805
 
805
806
  for (auto* consumer : consumers)
806
807
  {
@@ -810,7 +811,7 @@ namespace RTC
810
811
  if (!mid.empty())
811
812
  packet->UpdateMid(mid);
812
813
 
813
- consumer->SendRtpPacket(sharedPacket);
814
+ consumer->SendRtpPacket(packet, sharedPacket);
814
815
  }
815
816
  }
816
817
 
@@ -194,20 +194,20 @@ namespace RTC
194
194
  this->rtxSeq = Utils::Crypto::GetRandomUInt(0u, 0xFFFF);
195
195
  }
196
196
 
197
- bool RtpStreamSend::ReceivePacket(std::shared_ptr<RTC::RtpPacket> packet)
197
+ bool RtpStreamSend::ReceivePacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket)
198
198
  {
199
199
  MS_TRACE();
200
200
 
201
201
  // Call the parent method.
202
- if (!RtpStream::ReceiveStreamPacket(packet.get()))
202
+ if (!RtpStream::ReceiveStreamPacket(packet))
203
203
  return false;
204
204
 
205
205
  // If NACK is enabled, store the packet into the buffer.
206
206
  if (this->params.useNack)
207
- StorePacket(packet);
207
+ StorePacket(packet, sharedPacket);
208
208
 
209
209
  // Increase transmission counter.
210
- this->transmissionCounter.Update(packet.get());
210
+ this->transmissionCounter.Update(packet);
211
211
 
212
212
  return true;
213
213
  }
@@ -433,7 +433,7 @@ namespace RTC
433
433
  MS_ABORT("invalid method call");
434
434
  }
435
435
 
436
- void RtpStreamSend::StorePacket(std::shared_ptr<RTC::RtpPacket> packet)
436
+ void RtpStreamSend::StorePacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket)
437
437
  {
438
438
  MS_TRACE();
439
439
 
@@ -452,7 +452,7 @@ namespace RTC
452
452
  return;
453
453
  }
454
454
 
455
- this->ClearOldPackets(packet.get());
455
+ this->ClearOldPackets(packet);
456
456
 
457
457
  auto seq = packet->GetSequenceNumber();
458
458
  auto* storageItem = this->storageItemBuffer.Get(seq);
@@ -476,8 +476,14 @@ namespace RTC
476
476
  this->storageItemBuffer.Insert(seq, storageItem);
477
477
  }
478
478
 
479
+ // Only clone once and only if necessary.
480
+ if (!sharedPacket.get())
481
+ {
482
+ sharedPacket.reset(packet->Clone());
483
+ }
484
+
479
485
  // Store original packet and some extra info into the storage item.
480
- storageItem->packet = packet;
486
+ storageItem->packet = sharedPacket;
481
487
  storageItem->ssrc = packet->GetSsrc();
482
488
  storageItem->sequenceNumber = packet->GetSequenceNumber();
483
489
  storageItem->timestamp = packet->GetTimestamp();
@@ -249,7 +249,7 @@ namespace RTC
249
249
  return desiredBitrate;
250
250
  }
251
251
 
252
- void SimpleConsumer::SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet)
252
+ void SimpleConsumer::SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket)
253
253
  {
254
254
  MS_TRACE();
255
255
 
@@ -328,13 +328,13 @@ namespace RTC
328
328
  }
329
329
 
330
330
  // Process the packet.
331
- if (this->rtpStream->ReceivePacket(packet))
331
+ if (this->rtpStream->ReceivePacket(packet, sharedPacket))
332
332
  {
333
333
  // Send the packet.
334
- this->listener->OnConsumerSendRtpPacket(this, packet.get());
334
+ this->listener->OnConsumerSendRtpPacket(this, packet);
335
335
 
336
336
  // May emit 'trace' event.
337
- EmitTraceEventRtpAndKeyFrameTypes(packet.get());
337
+ EmitTraceEventRtpAndKeyFrameTypes(packet);
338
338
  }
339
339
  else
340
340
  {
@@ -640,7 +640,8 @@ namespace RTC
640
640
  return desiredBitrate;
641
641
  }
642
642
 
643
- void SimulcastConsumer::SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet)
643
+ void SimulcastConsumer::SendRtpPacket(
644
+ RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket)
644
645
  {
645
646
  MS_TRACE();
646
647
 
@@ -912,16 +913,16 @@ namespace RTC
912
913
  }
913
914
 
914
915
  // Process the packet.
915
- if (this->rtpStream->ReceivePacket(packet))
916
+ if (this->rtpStream->ReceivePacket(packet, sharedPacket))
916
917
  {
917
918
  if (this->rtpSeqManager.GetMaxOutput() == packet->GetSequenceNumber())
918
919
  this->lastSentPacketHasMarker = packet->HasMarker();
919
920
 
920
921
  // Send the packet.
921
- this->listener->OnConsumerSendRtpPacket(this, packet.get());
922
+ this->listener->OnConsumerSendRtpPacket(this, packet);
922
923
 
923
924
  // May emit 'trace' event.
924
- EmitTraceEventRtpAndKeyFrameTypes(packet.get());
925
+ EmitTraceEventRtpAndKeyFrameTypes(packet);
925
926
  }
926
927
  else
927
928
  {
@@ -532,7 +532,7 @@ namespace RTC
532
532
  return desiredBitrate;
533
533
  }
534
534
 
535
- void SvcConsumer::SendRtpPacket(std::shared_ptr<RTC::RtpPacket> packet)
535
+ void SvcConsumer::SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket)
536
536
  {
537
537
  MS_TRACE();
538
538
 
@@ -633,13 +633,13 @@ namespace RTC
633
633
  }
634
634
 
635
635
  // Process the packet.
636
- if (this->rtpStream->ReceivePacket(packet))
636
+ if (this->rtpStream->ReceivePacket(packet, sharedPacket))
637
637
  {
638
638
  // Send the packet.
639
- this->listener->OnConsumerSendRtpPacket(this, packet.get());
639
+ this->listener->OnConsumerSendRtpPacket(this, packet);
640
640
 
641
641
  // May emit 'trace' event.
642
- EmitTraceEventRtpAndKeyFrameTypes(packet.get());
642
+ EmitTraceEventRtpAndKeyFrameTypes(packet);
643
643
  }
644
644
  else
645
645
  {
@@ -6,24 +6,29 @@
6
6
  #include <catch2/catch.hpp>
7
7
  #include <vector>
8
8
 
9
+ // #define PERFORMANCE_TEST 1
10
+
9
11
  using namespace RTC;
10
12
 
11
- static std::shared_ptr<RtpPacket> CreateRtpPacket(uint8_t* buffer, uint16_t seq, uint32_t timestamp)
13
+ static RtpPacket* CreateRtpPacket(uint8_t* buffer, uint16_t seq, uint32_t timestamp)
12
14
  {
13
15
  auto* packet = RtpPacket::Parse(buffer, 1500);
14
16
 
15
17
  packet->SetSequenceNumber(seq);
16
18
  packet->SetTimestamp(timestamp);
17
19
 
18
- std::shared_ptr<RtpPacket> shared(packet);
19
-
20
- return shared;
20
+ return packet;
21
21
  }
22
22
 
23
- static void SendRtpPacket(RtpStreamSend* stream, std::shared_ptr<RtpPacket> packet, uint32_t ssrc)
23
+ static void SendRtpPacket(std::vector<std::pair<RtpStreamSend*, uint32_t>> streams, RtpPacket* packet)
24
24
  {
25
- packet->SetSsrc(ssrc);
26
- stream->ReceivePacket(packet);
25
+ std::shared_ptr<RtpPacket> sharedPacket;
26
+
27
+ for (auto& stream : streams)
28
+ {
29
+ packet->SetSsrc(stream.second);
30
+ stream.first->ReceivePacket(packet, sharedPacket);
31
+ }
27
32
  }
28
33
 
29
34
  static void CheckRtxPacket(RtpPacket* packet, uint16_t seq, uint32_t timestamp)
@@ -88,21 +93,22 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
88
93
 
89
94
  RtpStream::Params params;
90
95
 
91
- params.ssrc = 1111;
92
- params.clockRate = 90000;
93
- params.useNack = true;
96
+ params.ssrc = 1111;
97
+ params.clockRate = 90000;
98
+ params.useNack = true;
99
+ params.mimeType.type = RTC::RtpCodecMimeType::Type::VIDEO;
94
100
 
95
101
  std::string mid;
96
102
  RtpStreamSend* stream = new RtpStreamSend(&testRtpStreamListener, params, mid);
97
103
 
98
104
  // Receive all the packets (some of them not in order and/or duplicated).
99
- SendRtpPacket(stream, packet1, params.ssrc);
100
- SendRtpPacket(stream, packet3, params.ssrc);
101
- SendRtpPacket(stream, packet2, params.ssrc);
102
- SendRtpPacket(stream, packet3, params.ssrc);
103
- SendRtpPacket(stream, packet4, params.ssrc);
104
- SendRtpPacket(stream, packet5, params.ssrc);
105
- SendRtpPacket(stream, packet5, params.ssrc);
105
+ SendRtpPacket({ { stream, params.ssrc } }, packet1);
106
+ SendRtpPacket({ { stream, params.ssrc } }, packet3);
107
+ SendRtpPacket({ { stream, params.ssrc } }, packet2);
108
+ SendRtpPacket({ { stream, params.ssrc } }, packet3);
109
+ SendRtpPacket({ { stream, params.ssrc } }, packet4);
110
+ SendRtpPacket({ { stream, params.ssrc } }, packet5);
111
+ SendRtpPacket({ { stream, params.ssrc } }, packet5);
106
112
 
107
113
  // Create a NACK item that request for all the packets.
108
114
  RTCP::FeedbackRtpNackPacket nackPacket(0, params.ssrc);
@@ -134,6 +140,112 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
134
140
  delete stream;
135
141
  }
136
142
 
143
+ SECTION("receive NACK and get zero retransmitted packets if useNack is not set")
144
+ {
145
+ // packet1 [pt:123, seq:21006, timestamp:1533790901]
146
+ auto packet1 = CreateRtpPacket(rtpBuffer1, 21006, 1533790901);
147
+ // packet2 [pt:123, seq:21007, timestamp:1533790901]
148
+ auto packet2 = CreateRtpPacket(rtpBuffer2, 21007, 1533790901);
149
+ // packet3 [pt:123, seq:21008, timestamp:1533793871]
150
+ auto packet3 = CreateRtpPacket(rtpBuffer3, 21008, 1533793871);
151
+ // packet4 [pt:123, seq:21009, timestamp:1533793871]
152
+ auto packet4 = CreateRtpPacket(rtpBuffer4, 21009, 1533793871);
153
+ // packet5 [pt:123, seq:21010, timestamp:1533796931]
154
+ auto packet5 = CreateRtpPacket(rtpBuffer5, 21010, 1533796931);
155
+
156
+ // Create a RtpStreamSend instance.
157
+ TestRtpStreamListener testRtpStreamListener;
158
+
159
+ RtpStream::Params params;
160
+
161
+ params.ssrc = 1111;
162
+ params.clockRate = 90000;
163
+ params.useNack = false;
164
+ params.mimeType.type = RTC::RtpCodecMimeType::Type::VIDEO;
165
+
166
+ std::string mid;
167
+ RtpStreamSend* stream = new RtpStreamSend(&testRtpStreamListener, params, mid);
168
+
169
+ // Receive all the packets (some of them not in order and/or duplicated).
170
+ SendRtpPacket({ { stream, params.ssrc } }, packet1);
171
+ SendRtpPacket({ { stream, params.ssrc } }, packet3);
172
+ SendRtpPacket({ { stream, params.ssrc } }, packet2);
173
+ SendRtpPacket({ { stream, params.ssrc } }, packet3);
174
+ SendRtpPacket({ { stream, params.ssrc } }, packet4);
175
+ SendRtpPacket({ { stream, params.ssrc } }, packet5);
176
+ SendRtpPacket({ { stream, params.ssrc } }, packet5);
177
+
178
+ // Create a NACK item that request for all the packets.
179
+ RTCP::FeedbackRtpNackPacket nackPacket(0, params.ssrc);
180
+ auto* nackItem = new RTCP::FeedbackRtpNackItem(21006, 0b0000000000001111);
181
+
182
+ nackPacket.AddItem(nackItem);
183
+
184
+ REQUIRE(nackItem->GetPacketId() == 21006);
185
+ REQUIRE(nackItem->GetLostPacketBitmask() == 0b0000000000001111);
186
+
187
+ stream->ReceiveNack(&nackPacket);
188
+
189
+ REQUIRE(testRtpStreamListener.retransmittedPackets.size() == 0);
190
+
191
+ testRtpStreamListener.retransmittedPackets.clear();
192
+
193
+ delete stream;
194
+ }
195
+
196
+ SECTION("receive NACK and get zero retransmitted packets for audio")
197
+ {
198
+ // packet1 [pt:123, seq:21006, timestamp:1533790901]
199
+ auto packet1 = CreateRtpPacket(rtpBuffer1, 21006, 1533790901);
200
+ // packet2 [pt:123, seq:21007, timestamp:1533790901]
201
+ auto packet2 = CreateRtpPacket(rtpBuffer2, 21007, 1533790901);
202
+ // packet3 [pt:123, seq:21008, timestamp:1533793871]
203
+ auto packet3 = CreateRtpPacket(rtpBuffer3, 21008, 1533793871);
204
+ // packet4 [pt:123, seq:21009, timestamp:1533793871]
205
+ auto packet4 = CreateRtpPacket(rtpBuffer4, 21009, 1533793871);
206
+ // packet5 [pt:123, seq:21010, timestamp:1533796931]
207
+ auto packet5 = CreateRtpPacket(rtpBuffer5, 21010, 1533796931);
208
+
209
+ // Create a RtpStreamSend instance.
210
+ TestRtpStreamListener testRtpStreamListener;
211
+
212
+ RtpStream::Params params;
213
+
214
+ params.ssrc = 1111;
215
+ params.clockRate = 90000;
216
+ params.useNack = false;
217
+ params.mimeType.type = RTC::RtpCodecMimeType::Type::AUDIO;
218
+
219
+ std::string mid;
220
+ RtpStreamSend* stream = new RtpStreamSend(&testRtpStreamListener, params, mid);
221
+
222
+ // Receive all the packets (some of them not in order and/or duplicated).
223
+ SendRtpPacket({ { stream, params.ssrc } }, packet1);
224
+ SendRtpPacket({ { stream, params.ssrc } }, packet3);
225
+ SendRtpPacket({ { stream, params.ssrc } }, packet2);
226
+ SendRtpPacket({ { stream, params.ssrc } }, packet3);
227
+ SendRtpPacket({ { stream, params.ssrc } }, packet4);
228
+ SendRtpPacket({ { stream, params.ssrc } }, packet5);
229
+ SendRtpPacket({ { stream, params.ssrc } }, packet5);
230
+
231
+ // Create a NACK item that request for all the packets.
232
+ RTCP::FeedbackRtpNackPacket nackPacket(0, params.ssrc);
233
+ auto* nackItem = new RTCP::FeedbackRtpNackItem(21006, 0b0000000000001111);
234
+
235
+ nackPacket.AddItem(nackItem);
236
+
237
+ REQUIRE(nackItem->GetPacketId() == 21006);
238
+ REQUIRE(nackItem->GetLostPacketBitmask() == 0b0000000000001111);
239
+
240
+ stream->ReceiveNack(&nackPacket);
241
+
242
+ REQUIRE(testRtpStreamListener.retransmittedPackets.size() == 0);
243
+
244
+ testRtpStreamListener.retransmittedPackets.clear();
245
+
246
+ delete stream;
247
+ }
248
+
137
249
  SECTION("receive NACK in different RtpStreamSend instances and get retransmitted packets")
138
250
  {
139
251
  // packet1 [pt:123, seq:21006, timestamp:1533790901]
@@ -147,27 +259,26 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
147
259
 
148
260
  RtpStream::Params params1;
149
261
 
150
- params1.ssrc = 1111;
151
- params1.clockRate = 90000;
152
- params1.useNack = true;
262
+ params1.ssrc = 1111;
263
+ params1.clockRate = 90000;
264
+ params1.useNack = true;
265
+ params1.mimeType.type = RTC::RtpCodecMimeType::Type::VIDEO;
153
266
 
154
267
  std::string mid;
155
268
  RtpStreamSend* stream1 = new RtpStreamSend(&testRtpStreamListener1, params1, mid);
156
269
 
157
270
  RtpStream::Params params2;
158
271
 
159
- params2.ssrc = 2222;
160
- params2.clockRate = 90000;
161
- params2.useNack = true;
272
+ params2.ssrc = 2222;
273
+ params2.clockRate = 90000;
274
+ params2.useNack = true;
275
+ params2.mimeType.type = RTC::RtpCodecMimeType::Type::VIDEO;
162
276
 
163
277
  RtpStreamSend* stream2 = new RtpStreamSend(&testRtpStreamListener2, params2, mid);
164
278
 
165
279
  // Receive all the packets in both streams.
166
- SendRtpPacket(stream1, packet1, params1.ssrc);
167
- SendRtpPacket(stream2, packet1, params2.ssrc);
168
-
169
- SendRtpPacket(stream1, packet2, params1.ssrc);
170
- SendRtpPacket(stream2, packet2, params2.ssrc);
280
+ SendRtpPacket({ { stream1, params1.ssrc }, { stream2, params2.ssrc } }, packet1);
281
+ SendRtpPacket({ { stream1, params1.ssrc }, { stream2, params2.ssrc } }, packet2);
171
282
 
172
283
  // Create a NACK item that request for all the packets.
173
284
  RTCP::FeedbackRtpNackPacket nackPacket(0, params1.ssrc);
@@ -223,16 +334,17 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
223
334
 
224
335
  RtpStream::Params params1;
225
336
 
226
- params1.ssrc = 1111;
227
- params1.clockRate = clockRate;
228
- params1.useNack = true;
337
+ params1.ssrc = 1111;
338
+ params1.clockRate = clockRate;
339
+ params1.useNack = true;
340
+ params1.mimeType.type = RTC::RtpCodecMimeType::Type::VIDEO;
229
341
 
230
342
  std::string mid;
231
- RtpStreamSend* stream1 = new RtpStreamSend(&testRtpStreamListener1, params1, mid);
343
+ RtpStreamSend* stream = new RtpStreamSend(&testRtpStreamListener1, params1, mid);
232
344
 
233
345
  // Receive all the packets.
234
- SendRtpPacket(stream1, packet1, params1.ssrc);
235
- SendRtpPacket(stream1, packet2, params1.ssrc);
346
+ SendRtpPacket({ { stream, params1.ssrc } }, packet1);
347
+ SendRtpPacket({ { stream, params1.ssrc } }, packet2);
236
348
 
237
349
  // Create a NACK item that request for all the packets.
238
350
  RTCP::FeedbackRtpNackPacket nackPacket(0, params1.ssrc);
@@ -244,7 +356,7 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
244
356
  REQUIRE(nackItem->GetLostPacketBitmask() == 0b0000000000000001);
245
357
 
246
358
  // Process the NACK packet on stream1.
247
- stream1->ReceiveNack(&nackPacket);
359
+ stream->ReceiveNack(&nackPacket);
248
360
 
249
361
  REQUIRE(testRtpStreamListener1.retransmittedPackets.size() == 2);
250
362
 
@@ -256,7 +368,7 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
256
368
  CheckRtxPacket(rtxPacket1, packet1->GetSequenceNumber(), packet1->GetTimestamp());
257
369
  CheckRtxPacket(rtxPacket2, packet2->GetSequenceNumber(), packet2->GetTimestamp());
258
370
 
259
- delete stream1;
371
+ delete stream;
260
372
  }
261
373
 
262
374
  SECTION("packets don't get retransmitted if MaxRetransmissionDelay is exceeded")
@@ -274,16 +386,17 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
274
386
 
275
387
  RtpStream::Params params1;
276
388
 
277
- params1.ssrc = 1111;
278
- params1.clockRate = clockRate;
279
- params1.useNack = true;
389
+ params1.ssrc = 1111;
390
+ params1.clockRate = clockRate;
391
+ params1.useNack = true;
392
+ params1.mimeType.type = RTC::RtpCodecMimeType::Type::VIDEO;
280
393
 
281
394
  std::string mid;
282
- RtpStreamSend* stream1 = new RtpStreamSend(&testRtpStreamListener1, params1, mid);
395
+ RtpStreamSend* stream = new RtpStreamSend(&testRtpStreamListener1, params1, mid);
283
396
 
284
397
  // Receive all the packets.
285
- SendRtpPacket(stream1, packet1, params1.ssrc);
286
- SendRtpPacket(stream1, packet2, params1.ssrc);
398
+ SendRtpPacket({ { stream, params1.ssrc } }, packet1);
399
+ SendRtpPacket({ { stream, params1.ssrc } }, packet2);
287
400
 
288
401
  // Create a NACK item that request for all the packets.
289
402
  RTCP::FeedbackRtpNackPacket nackPacket(0, params1.ssrc);
@@ -295,7 +408,7 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
295
408
  REQUIRE(nackItem->GetLostPacketBitmask() == 0b0000000000000001);
296
409
 
297
410
  // Process the NACK packet on stream1.
298
- stream1->ReceiveNack(&nackPacket);
411
+ stream->ReceiveNack(&nackPacket);
299
412
 
300
413
  REQUIRE(testRtpStreamListener1.retransmittedPackets.size() == 1);
301
414
 
@@ -305,6 +418,65 @@ SCENARIO("NACK and RTP packets retransmission", "[rtp][rtcp][nack]")
305
418
 
306
419
  CheckRtxPacket(rtxPacket2, packet2->GetSequenceNumber(), packet2->GetTimestamp());
307
420
 
308
- delete stream1;
421
+ delete stream;
422
+ }
423
+
424
+ #ifdef PERFORMANCE_TEST
425
+ SECTION("Performance")
426
+ {
427
+ // Create a RtpStreamSend instance.
428
+ TestRtpStreamListener testRtpStreamListener;
429
+
430
+ RtpStream::Params params;
431
+
432
+ params.ssrc = 1111;
433
+ params.clockRate = 90000;
434
+ params.useNack = true;
435
+ params.mimeType.type = RTC::RtpCodecMimeType::Type::VIDEO;
436
+
437
+ std::string mid;
438
+ RtpStreamSend* stream = new RtpStreamSend(&testRtpStreamListener, params, mid);
439
+
440
+ size_t iterations = 10000000;
441
+
442
+ auto start = std::chrono::system_clock::now();
443
+
444
+ for (size_t i = 0; i < iterations; i++)
445
+ {
446
+ // Create packet.
447
+ auto* packet = RtpPacket::Parse(rtpBuffer1, 1500);
448
+ packet->SetSsrc(1111);
449
+
450
+ std::shared_ptr<RtpPacket> sharedPacket(packet);
451
+
452
+ stream->ReceivePacket(packet, sharedPacket);
453
+ }
454
+
455
+ std::chrono::duration<double> dur = std::chrono::system_clock::now() - start;
456
+ std::cout << "nullptr && initialized shared_ptr: \t" << dur.count() << " seconds" << std::endl;
457
+
458
+ delete stream;
459
+
460
+ params.mimeType.type = RTC::RtpCodecMimeType::Type::AUDIO;
461
+ stream = new RtpStreamSend(&testRtpStreamListener, params, mid);
462
+
463
+ start = std::chrono::system_clock::now();
464
+
465
+ for (size_t i = 0; i < iterations; i++)
466
+ {
467
+ std::shared_ptr<RtpPacket> sharedPacket;
468
+
469
+ // Create packet.
470
+ auto* packet = RtpPacket::Parse(rtpBuffer1, 1500);
471
+ packet->SetSsrc(1111);
472
+
473
+ stream->ReceivePacket(packet, sharedPacket);
474
+ }
475
+
476
+ dur = std::chrono::system_clock::now() - start;
477
+ std::cout << "raw && empty shared_ptr duration: \t" << dur.count() << " seconds" << std::endl;
478
+
479
+ delete stream;
309
480
  }
481
+ #endif
310
482
  }