mediasoup 3.24.2 → 3.26.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 (55) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/node/lib/Consumer.js +1 -1
  3. package/node/lib/Transport.d.ts.map +1 -1
  4. package/node/lib/Transport.js +7 -0
  5. package/node/lib/ortc.d.ts.map +1 -1
  6. package/node/lib/ortc.js +10 -0
  7. package/node/lib/test/test-PipeTransport.js +35 -30
  8. package/package.json +6 -6
  9. package/worker/include/DepLibUV.hpp +33 -4
  10. package/worker/include/RTC/Consumer.hpp +4 -1
  11. package/worker/include/RTC/Producer.hpp +34 -5
  12. package/worker/include/RTC/RTCP/Packet.hpp +7 -1
  13. package/worker/include/RTC/RTP/Packet.hpp +18 -0
  14. package/worker/include/RTC/RTP/RtpStream.hpp +76 -14
  15. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +191 -7
  16. package/worker/include/RTC/RTP/RtpStreamSend.hpp +56 -10
  17. package/worker/include/RTC/RTP/RtxStream.hpp +34 -2
  18. package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +92 -0
  19. package/worker/include/RTC/RemoteClockOffsetEstimator.hpp +87 -0
  20. package/worker/include/RTC/Router.hpp +2 -5
  21. package/worker/include/RTC/SimulcastProducerStreamManager.hpp +3 -0
  22. package/worker/include/RTC/Transport.hpp +15 -7
  23. package/worker/include/Shared.hpp +5 -0
  24. package/worker/include/SharedInterface.hpp +6 -0
  25. package/worker/include/Utils.hpp +44 -3
  26. package/worker/meson.build +4 -0
  27. package/worker/mocks/include/MockShared.hpp +7 -0
  28. package/worker/src/DepLibUV.cpp +17 -0
  29. package/worker/src/RTC/Consumer.cpp +8 -5
  30. package/worker/src/RTC/Producer.cpp +85 -16
  31. package/worker/src/RTC/RTP/Packet.cpp +9 -1
  32. package/worker/src/RTC/RTP/RtpStream.cpp +14 -10
  33. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +150 -23
  34. package/worker/src/RTC/RTP/RtpStreamSend.cpp +34 -19
  35. package/worker/src/RTC/RTP/RtxStream.cpp +12 -6
  36. package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +77 -0
  37. package/worker/src/RTC/RemoteClockOffsetEstimator.cpp +106 -0
  38. package/worker/src/RTC/Router.cpp +10 -8
  39. package/worker/src/RTC/RtpDictionaries/RtcpParameters.cpp +13 -3
  40. package/worker/src/RTC/SCTP/packet/chunks/SackChunk.cpp +6 -2
  41. package/worker/src/RTC/SimulcastProducerStreamManager.cpp +115 -56
  42. package/worker/src/RTC/SvcProducerStreamManager.cpp +22 -17
  43. package/worker/src/RTC/Transport.cpp +96 -4
  44. package/worker/test/src/RTC/RTP/TestPacket.cpp +6 -0
  45. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +2 -2
  46. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +119 -0
  47. package/worker/test/src/RTC/TestConsumer.cpp +4 -3
  48. package/worker/test/src/RTC/TestPortManager.cpp +1 -1
  49. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +164 -0
  50. package/worker/test/src/RTC/TestRemoteClockOffsetEstimator.cpp +241 -0
  51. package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +2 -2
  52. package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +340 -15
  53. package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +2 -2
  54. package/worker/test/src/RTC/TestTransportTuple.cpp +1 -1
  55. package/worker/test/src/Utils/TestTime.cpp +49 -0
@@ -16,14 +16,34 @@ namespace RTC
16
16
  public RTC::NackGenerator::Listener,
17
17
  public TimerHandleInterface::Listener
18
18
  {
19
+ public:
20
+ /**
21
+ * How far the RTP timestamp of a packet may be from the last received
22
+ * `abs-capture-time` RTP header extension for its capture instant to still be
23
+ * interpolated from it (ms).
24
+ *
25
+ * @remarks
26
+ * - Same value libwebrtc uses in `AbsoluteCaptureTimeInterpolator`, which
27
+ * pairs with senders emitting the extension at least once per second.
28
+ */
29
+ static constexpr uint64_t MaxAbsCaptureTimeInterpolationMs{ 5000 };
30
+ /**
31
+ * How far the RTP timestamp of a packet may be from the last received RTCP
32
+ * Sender Report for its capture instant to still be interpolated from it (ms).
33
+ */
34
+ static constexpr uint64_t MaxSenderReportInterpolationMs{ 10000 };
35
+
19
36
  public:
20
37
  class Listener : public RTP::RtpStream::Listener
21
38
  {
22
39
  public:
23
40
  virtual void OnRtpStreamSendRtcpPacket(
24
41
  RTP::RtpStreamRecv* rtpStream, RTC::RTCP::Packet* packet) = 0;
25
- virtual void OnRtpStreamNeedWorstRemoteFractionLost(
26
- RTP::RtpStreamRecv* rtpStream, uint8_t& worstRemoteFractionLost) = 0;
42
+ /**
43
+ * Obtains the worst remote fraction lost of all the RtpStreamSend
44
+ * streams consuming this RtpStreamRecv.
45
+ */
46
+ virtual uint8_t OnRtpStreamNeedWorstRemoteFractionLost(RTP::RtpStreamRecv* rtpStream) = 0;
27
47
  };
28
48
 
29
49
  public:
@@ -32,18 +52,77 @@ namespace RTC
32
52
  public:
33
53
  TransmissionCounter(
34
54
  SharedInterface* shared, uint8_t spatialLayers, uint8_t temporalLayers, size_t windowSize);
55
+
56
+ public:
35
57
  void Update(const RTP::Packet* packet);
58
+
36
59
  uint32_t GetBitrate(uint64_t nowMs);
60
+
37
61
  uint32_t GetBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer);
62
+
38
63
  uint32_t GetSpatialLayerBitrate(uint64_t nowMs, uint8_t spatialLayer);
64
+
39
65
  uint32_t GetLayerBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer);
66
+
40
67
  size_t GetPacketCount() const;
68
+
41
69
  size_t GetBytes() const;
42
70
 
43
71
  private:
44
72
  std::vector<std::vector<RTC::RtpDataCounter>> spatialLayerCounters;
45
73
  };
46
74
 
75
+ public:
76
+ /**
77
+ * Correspondence between the RTP timeline of this stream and our own monotonic
78
+ * clock.
79
+ */
80
+ struct CaptureMapping
81
+ {
82
+ /**
83
+ * Capture instant of the media carried by the RTP timestamp below, in our own
84
+ * monotonic clock (ms).
85
+ */
86
+ uint64_t captureMs;
87
+ /**
88
+ * RTP timestamp the capture instant above refers to.
89
+ */
90
+ uint32_t ts;
91
+ };
92
+
93
+ private:
94
+ /**
95
+ * Data of a received RTCP Sender Report needed to report LSR and DLSR back in a
96
+ * Receiver Report.
97
+ */
98
+ struct SenderReportTiming
99
+ {
100
+ /**
101
+ * Middle 32 bits out of 64 in the NTP timestamp of the Sender Report.
102
+ */
103
+ uint32_t compactNtp;
104
+ /**
105
+ * Local time at which the Sender Report arrived.
106
+ */
107
+ uint64_t receivedMs;
108
+ };
109
+
110
+ /**
111
+ * Capture instant carried by an `abs-capture-time` RTP header extension, together
112
+ * with the RTP timestamp it refers to.
113
+ */
114
+ struct AbsCaptureTime
115
+ {
116
+ /**
117
+ * RTP timestamp the capture instant below refers to.
118
+ */
119
+ uint32_t ts;
120
+ /**
121
+ * Capture instant in the remote sender's wall clock (ms).
122
+ */
123
+ uint64_t ntpMs;
124
+ };
125
+
47
126
  public:
48
127
  RtpStreamRecv(
49
128
  RTP::RtpStreamRecv::Listener* listener,
@@ -51,36 +130,126 @@ namespace RTC
51
130
  RTP::RtpStream::Params& params,
52
131
  uint32_t sendNackDelayMs,
53
132
  bool useRtpInactivityCheck);
133
+
54
134
  ~RtpStreamRecv() override;
55
135
 
136
+ public:
56
137
  flatbuffers::Offset<FBS::RtpStream::Stats> FillBufferStats(
57
138
  flatbuffers::FlatBufferBuilder& builder) override;
139
+
58
140
  bool ReceivePacket(RTP::Packet* packet);
141
+
59
142
  bool ReceiveRtxPacket(RTP::Packet* packet);
143
+
60
144
  RTC::RTCP::ReceiverReport* GetRtcpReceiverReport();
145
+
61
146
  RTC::RTCP::ReceiverReport* GetRtxRtcpReceiverReport();
147
+
62
148
  void ReceiveRtcpSenderReport(RTC::RTCP::SenderReport* report);
149
+
63
150
  void ReceiveRtxRtcpSenderReport(RTC::RTCP::SenderReport* report);
151
+
64
152
  void ReceiveRtcpXrDelaySinceLastRr(RTC::RTCP::DelaySinceLastRr::SsrcInfo* ssrcInfo);
153
+
154
+ /**
155
+ * Local time at which the last RTCP Sender Report arrived.
156
+ *
157
+ * @returns No value if no Sender Report has arrived yet.
158
+ */
159
+ std::optional<uint64_t> GetSenderReportReceivedMs() const
160
+ {
161
+ if (!this->lastSenderReportTiming.has_value())
162
+ {
163
+ return std::nullopt;
164
+ }
165
+
166
+ return this->lastSenderReportTiming.value().receivedMs;
167
+ }
168
+
169
+ /**
170
+ * Store the correspondence between the RTP timeline of this stream and our own
171
+ * monotonic clock.
172
+ *
173
+ * @remarks
174
+ * - Only the Producer can tell it, since translating the capture instant of the
175
+ * remote sender into our own clock needs the whole set of streams of that
176
+ * sender.
177
+ *
178
+ * @param captureMs - Capture instant of `ts` in our own monotonic clock.
179
+ * @param ts - RTP timestamp the capture instant refers to.
180
+ */
181
+ void SetCaptureMapping(uint64_t captureMs, uint32_t ts)
182
+ {
183
+ this->lastCaptureMapping = RTP::RtpStreamRecv::CaptureMapping{
184
+ .captureMs = captureMs,
185
+ .ts = ts,
186
+ };
187
+ }
188
+
189
+ /**
190
+ * Correspondence between the RTP timeline of this stream and our own monotonic
191
+ * clock, as of the last RTP timestamp whose capture instant could be told.
192
+ *
193
+ * @remarks
194
+ * - Once set it is never unset, so any two streams of a same sender that have it
195
+ * can always be aligned to each other.
196
+ *
197
+ * @returns No value if no capture instant could be told yet.
198
+ */
199
+ std::optional<RTP::RtpStreamRecv::CaptureMapping> GetCaptureMapping() const
200
+ {
201
+ return this->lastCaptureMapping;
202
+ }
203
+
204
+ /**
205
+ * Capture instant of the given RTP timestamp, expressed in the remote sender's
206
+ * wall clock, interpolated from the last received `abs-capture-time` RTP header
207
+ * extension.
208
+ *
209
+ * @param ts - RTP timestamp whose capture instant is wanted.
210
+ *
211
+ * @returns No value if no such extension has been received, or if the given RTP
212
+ * timestamp is too far away from the one it referred to.
213
+ */
214
+ std::optional<uint64_t> GetRemoteCaptureMsFromAbsCaptureTime(uint32_t ts) const;
215
+
216
+ /**
217
+ * Capture instant of the given RTP timestamp, expressed in the remote sender's
218
+ * wall clock, interpolated from the last received RTCP Sender Report.
219
+ *
220
+ * @param ts - RTP timestamp whose capture instant is wanted.
221
+ *
222
+ * @returns No value if no Sender Report has been received, or if the given RTP
223
+ * timestamp is too far away from the one it reported.
224
+ */
225
+ std::optional<uint64_t> GetRemoteCaptureMsFromSenderReport(uint32_t ts) const;
226
+
65
227
  void RequestKeyFrame();
228
+
66
229
  void Pause() override;
230
+
67
231
  void Resume() override;
232
+
68
233
  uint32_t GetBitrate(uint64_t nowMs) override
69
234
  {
70
235
  return this->transmissionCounter.GetBitrate(nowMs);
71
236
  }
237
+
72
238
  uint32_t GetBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer) override
73
239
  {
74
240
  return this->transmissionCounter.GetBitrate(nowMs, spatialLayer, temporalLayer);
75
241
  }
242
+
76
243
  uint32_t GetSpatialLayerBitrate(uint64_t nowMs, uint8_t spatialLayer) override
77
244
  {
78
245
  return this->transmissionCounter.GetSpatialLayerBitrate(nowMs, spatialLayer);
79
246
  }
247
+
80
248
  uint32_t GetLayerBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer) override
81
249
  {
82
250
  return this->transmissionCounter.GetLayerBitrate(nowMs, spatialLayer, temporalLayer);
83
251
  }
252
+
84
253
  bool HasRtpInactivityCheckEnabled() const
85
254
  {
86
255
  return this->useRtpInactivityCheck;
@@ -88,8 +257,21 @@ namespace RTC
88
257
 
89
258
  private:
90
259
  void CalculateJitter(uint32_t rtpTimestamp);
260
+
91
261
  void UpdateScore();
92
262
 
263
+ /**
264
+ * Interpolate the capture instant of `ts` from a reference pair, all of them
265
+ * expressed in the remote sender's wall clock.
266
+ *
267
+ * @param referenceNtpMs - Capture instant of `referenceTs`.
268
+ * @param referenceTs - RTP timestamp the reference instant refers to.
269
+ * @param ts - RTP timestamp whose capture instant is wanted.
270
+ * @param maxDistanceMs - How far `ts` may be from `referenceTs`.
271
+ */
272
+ std::optional<uint64_t> InterpolateRemoteCaptureMs(
273
+ uint64_t referenceNtpMs, uint32_t referenceTs, uint32_t ts, uint64_t maxDistanceMs) const;
274
+
93
275
  /* Pure virtual methods inherited from RTP::RtpStream. */
94
276
  public:
95
277
  void UserOnSequenceNumberReset() override;
@@ -101,6 +283,7 @@ namespace RTC
101
283
  /* Pure virtual methods inherited from RTC::NackGenerator. */
102
284
  protected:
103
285
  void OnNackGeneratorNackRequired(const std::vector<uint16_t>& seqNumbers) override;
286
+
104
287
  void OnNackGeneratorKeyFrameRequired() override;
105
288
 
106
289
  private:
@@ -116,11 +299,12 @@ namespace RTC
116
299
  uint32_t receivedPrior{ 0u };
117
300
  // Packets received at last interval for score calculation.
118
301
  uint32_t receivedPriorScore{ 0u };
119
- // The middle 32 bits out of 64 in the NTP timestamp received in the most
120
- // recent sender report.
121
- uint32_t lastSrTimestamp{ 0u };
122
- // Wallclock time representing the most recent sender report arrival.
123
- uint64_t lastSrReceived{ 0u };
302
+ // Timing data of the most recent Sender Report received.
303
+ std::optional<SenderReportTiming> lastSenderReportTiming;
304
+ // Most recent `abs-capture-time` RTP header extension received.
305
+ std::optional<AbsCaptureTime> lastAbsCaptureTime;
306
+ // Most recent RTP timestamp whose capture instant could be told, along with it.
307
+ std::optional<CaptureMapping> lastCaptureMapping;
124
308
  // Relative transit time for prev packet.
125
309
  int32_t transit{ 0u };
126
310
  uint8_t firSeqNumber{ 0u };
@@ -13,10 +13,24 @@ namespace RTC
13
13
  class RtpStreamSend : public RTP::RtpStream
14
14
  {
15
15
  public:
16
- // Maximum retransmission buffer size for video (ms).
17
- static const uint32_t MaxRetransmissionDelayForVideoMs;
18
- // Maximum retransmission buffer size for audio (ms).
19
- static const uint32_t MaxRetransmissionDelayForAudioMs;
16
+ /**
17
+ * Maximum retransmission buffer size for video (ms).
18
+ */
19
+ static constexpr uint32_t MaxRetransmissionDelayForVideoMs{ 2000 };
20
+ /**
21
+ * Maximum retransmission buffer size for audio (ms).
22
+ */
23
+ static constexpr uint32_t MaxRetransmissionDelayForAudioMs{ 1000 };
24
+ /**
25
+ * How old the last packet sent may be for a Sender Report to still be generated
26
+ * (ms).
27
+ *
28
+ * @remarks
29
+ * - Above the interval between packets of any legitimate stream, including Opus
30
+ * with a 120 ms ptime and screen sharing at 1 fps, so that it only triggers on
31
+ * a stream that has really stopped sending.
32
+ */
33
+ static constexpr uint32_t MaxSenderReportReferenceAgeMs{ 2000 };
20
34
 
21
35
  public:
22
36
  enum class ReceivePacketResult : uint8_t
@@ -34,37 +48,73 @@ namespace RTC
34
48
  RTP::RtpStreamSend* rtpStream, RTP::Packet* packet) = 0;
35
49
  };
36
50
 
51
+ private:
52
+ /**
53
+ * Data of a received Receiver Reference Time Extended Report needed to
54
+ * report LRR and DLRR back in a Delay Since Last Receiver Report Extended
55
+ * Report.
56
+ */
57
+ struct ReceiverReferenceTime
58
+ {
59
+ /**
60
+ * Middle 32 bits out of 64 in the NTP timestamp of the Receiver Reference Time.
61
+ */
62
+ uint32_t compactNtp;
63
+ /**
64
+ * Local time at which the Receiver Reference Time arrived.
65
+ */
66
+ uint64_t receivedMs;
67
+ };
68
+
37
69
  public:
38
70
  RtpStreamSend(
39
71
  RTP::RtpStreamSend::Listener* listener,
40
72
  SharedInterface* shared,
41
73
  RTP::RtpStream::Params& params,
42
74
  std::string& mid);
75
+
43
76
  ~RtpStreamSend() override;
44
77
 
78
+ public:
45
79
  flatbuffers::Offset<FBS::RtpStream::Stats> FillBufferStats(
46
80
  flatbuffers::FlatBufferBuilder& builder) override;
81
+
47
82
  void SetRtx(uint8_t payloadType, uint32_t ssrc) override;
83
+
48
84
  ReceivePacketResult ReceivePacket(RTP::Packet* packet, const RTP::SharedPacket& sharedPacket);
85
+
49
86
  void ReceiveNack(RTC::RTCP::FeedbackRtpNackPacket* nackPacket);
87
+
50
88
  void ReceiveKeyFrameRequest(RTC::RTCP::FeedbackPs::MessageType messageType);
89
+
51
90
  void ReceiveRtcpReceiverReport(RTC::RTCP::ReceiverReport* report);
91
+
52
92
  void ReceiveRtcpXrReceiverReferenceTime(RTC::RTCP::ReceiverReferenceTime* report);
93
+
53
94
  RTC::RTCP::SenderReport* GetRtcpSenderReport(uint64_t nowMs);
95
+
54
96
  RTC::RTCP::DelaySinceLastRr::SsrcInfo* GetRtcpXrDelaySinceLastRrSsrcInfo(uint64_t nowMs);
97
+
55
98
  RTC::RTCP::SdesChunk* GetRtcpSdesChunk();
99
+
56
100
  void Pause() override;
101
+
57
102
  void Resume() override;
103
+
58
104
  uint32_t GetBitrate(uint64_t nowMs) override
59
105
  {
60
106
  return this->transmissionCounter.GetBitrate(nowMs);
61
107
  }
108
+
62
109
  uint32_t GetBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer) override;
110
+
63
111
  uint32_t GetSpatialLayerBitrate(uint64_t nowMs, uint8_t spatialLayer) override;
112
+
64
113
  uint32_t GetLayerBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer) override;
65
114
 
66
115
  private:
67
116
  void FillRetransmissionContainer(uint16_t seq, uint16_t bitmask);
117
+
68
118
  void UpdateScore(RTC::RTCP::ReceiverReport* report);
69
119
 
70
120
  /* Pure virtual methods inherited from RTP::RtpStream. */
@@ -80,12 +130,8 @@ namespace RTC
80
130
  uint16_t rtxSeq{ 0u };
81
131
  RTC::RtpDataCounter transmissionCounter;
82
132
  RTP::RetransmissionBuffer* retransmissionBuffer{ nullptr };
83
- // The middle 32 bits out of 64 in the NTP timestamp received in the most
84
- // recent receiver reference timestamp.
85
- uint32_t lastRrTimestamp{ 0u };
86
- // Wallclock time representing the most recent receiver reference timestamp
87
- // arrival.
88
- uint64_t lastRrReceivedMs{ 0u };
133
+ // Timing data of the most recent Receiver Reference Time received.
134
+ std::optional<ReceiverReferenceTime> lastReceiverReferenceTime;
89
135
  };
90
136
  } // namespace RTP
91
137
  } // namespace RTC
@@ -30,54 +30,86 @@ namespace RTC
30
30
  std::string cname;
31
31
  };
32
32
 
33
+ private:
34
+ /**
35
+ * Data of a received RTCP Sender Report needed to report LSR and DLSR back in a
36
+ * Receiver Report.
37
+ */
38
+ struct SenderReportTiming
39
+ {
40
+ /**
41
+ * Middle 32 bits out of 64 in the NTP timestamp of the Sender Report.
42
+ */
43
+ uint32_t compactNtp;
44
+ /**
45
+ * Local time at which the Sender Report arrived.
46
+ */
47
+ uint64_t receivedMs;
48
+ };
49
+
33
50
  public:
34
51
  explicit RtxStream(SharedInterface* shared, RTP::RtxStream::Params& params);
52
+
35
53
  virtual ~RtxStream();
36
54
 
55
+ public:
37
56
  flatbuffers::Offset<FBS::RtxStream::RtxDump> FillBuffer(
38
57
  flatbuffers::FlatBufferBuilder& builder) const;
58
+
39
59
  uint32_t GetSsrc() const
40
60
  {
41
61
  return this->params.ssrc;
42
62
  }
63
+
43
64
  uint8_t GetPayloadType() const
44
65
  {
45
66
  return this->params.payloadType;
46
67
  }
68
+
47
69
  const RTC::RtpCodecMimeType& GetMimeType() const
48
70
  {
49
71
  return this->params.mimeType;
50
72
  }
73
+
51
74
  uint32_t GetClockRate() const
52
75
  {
53
76
  return this->params.clockRate;
54
77
  }
78
+
55
79
  const std::string& GetRrid() const
56
80
  {
57
81
  return this->params.rrid;
58
82
  }
83
+
59
84
  const std::string& GetCname() const
60
85
  {
61
86
  return this->params.cname;
62
87
  }
88
+
63
89
  uint8_t GetFractionLost() const
64
90
  {
65
91
  return this->fractionLost;
66
92
  }
93
+
67
94
  float GetLossPercentage() const
68
95
  {
69
96
  return static_cast<float>(this->fractionLost) * 100 / 256;
70
97
  }
98
+
71
99
  size_t GetPacketsDiscarded() const
72
100
  {
73
101
  return this->packetsDiscarded;
74
102
  }
103
+
75
104
  bool ReceivePacket(const RTP::Packet* packet);
105
+
76
106
  RTC::RTCP::ReceiverReport* GetRtcpReceiverReport();
107
+
77
108
  void ReceiveRtcpSenderReport(RTC::RTCP::SenderReport* report);
78
109
 
79
110
  protected:
80
111
  bool UpdateSeq(const RTP::Packet* packet);
112
+
81
113
  uint32_t GetExpectedPackets() const
82
114
  {
83
115
  return (this->cycles + this->maxSeq) - this->baseSeq + 1;
@@ -109,8 +141,8 @@ namespace RTC
109
141
  // Fields for generating Receiver Reports.
110
142
  uint32_t expectedPrior{ 0u };
111
143
  uint32_t receivedPrior{ 0u };
112
- uint32_t lastSrTimestamp{ 0u };
113
- uint64_t lastSrReceived{ 0u };
144
+ // Timing data of the most recent Sender Report received.
145
+ std::optional<SenderReportTiming> lastSenderReportTiming;
114
146
  int32_t reportedPacketsLost{ 0 };
115
147
  };
116
148
  } // namespace RTP
@@ -0,0 +1,92 @@
1
+ #ifndef MS_RTC_REMOTE_CAPTURE_TIME_ESTIMATOR_HPP
2
+ #define MS_RTC_REMOTE_CAPTURE_TIME_ESTIMATOR_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/RTP/RtpStreamRecv.hpp"
6
+ #include "RTC/RemoteClockOffsetEstimator.hpp"
7
+
8
+ namespace RTC
9
+ {
10
+ /**
11
+ * Tells at which instant of our own monotonic clock the media carried by a given
12
+ * RTP timestamp was captured, for every RTP stream of a same remote sender.
13
+ *
14
+ * The capture instant is read from one of two sources, and the same one is used
15
+ * for every stream of the sender. Mixing them would reintroduce the very inter
16
+ * stream skew this is meant to remove, since they do not carry the same residual
17
+ * error: `abs-capture-time` is exact while a Sender Report is biased by its own
18
+ * one way delay.
19
+ *
20
+ * The source is chosen from what the Producers of the sender negotiated. The
21
+ * first Producer chooses it, and a single Producer that did not negotiate
22
+ * `abs-capture-time` moves it to Sender Report for the rest of the life of this
23
+ * object, never back.
24
+ *
25
+ * A single instance is meant to be shared by all the RTP streams of a given
26
+ * CNAME, which is what identifies media coming from a same machine and hence
27
+ * from a same wall clock.
28
+ */
29
+ class RemoteCaptureTimeEstimator
30
+ {
31
+ public:
32
+ enum class Source : uint8_t
33
+ {
34
+ ABS_CAPTURE_TIME = 1,
35
+ SENDER_REPORT
36
+ };
37
+
38
+ public:
39
+ /**
40
+ * Take a Producer of this sender into account to choose the source.
41
+ *
42
+ * @param absCaptureTimeNegotiated - Whether the Producer negotiated the
43
+ * `abs-capture-time` RTP header extension.
44
+ */
45
+ void UpdateSource(bool absCaptureTimeNegotiated);
46
+
47
+ /**
48
+ * Source the capture instant is being read from.
49
+ *
50
+ * @returns No value until the first Producer has been taken into account.
51
+ */
52
+ std::optional<Source> GetSource() const
53
+ {
54
+ return this->source;
55
+ }
56
+
57
+ /**
58
+ * Notify that a Sender Report has been received on one of the RTP streams of
59
+ * this sender.
60
+ */
61
+ void SenderReportReceived(const RTC::RTP::RtpStreamRecv* rtpStream);
62
+
63
+ /**
64
+ * Offset between the wall clock of this sender and our own monotonic one (ms).
65
+ *
66
+ * @returns No value while the offset cannot be told yet.
67
+ */
68
+ std::optional<int64_t> GetClockOffsetMs() const
69
+ {
70
+ return this->clockOffsetEstimator.GetOffsetMs();
71
+ }
72
+
73
+ /**
74
+ * Capture instant of the given RTP timestamp of the given RTP stream,
75
+ * expressed in our own monotonic clock.
76
+ *
77
+ * @param rtpStream - RTP stream the RTP timestamp belongs to.
78
+ * @param ts - RTP timestamp whose capture instant is wanted.
79
+ *
80
+ * @returns No value while the capture instant cannot be told yet.
81
+ */
82
+ std::optional<uint64_t> GetLocalCaptureMs(const RTC::RTP::RtpStreamRecv* rtpStream, uint32_t ts) const;
83
+
84
+ private:
85
+ // Offset between the wall clock of the sender and our monotonic one.
86
+ RTC::RemoteClockOffsetEstimator clockOffsetEstimator;
87
+ // Source the capture instant is read from, for every stream of this sender.
88
+ std::optional<Source> source;
89
+ };
90
+ } // namespace RTC
91
+
92
+ #endif
@@ -0,0 +1,87 @@
1
+ #ifndef MS_RTC_REMOTE_CLOCK_OFFSET_ESTIMATOR_HPP
2
+ #define MS_RTC_REMOTE_CLOCK_OFFSET_ESTIMATOR_HPP
3
+
4
+ #include "common.hpp"
5
+ #include <vector>
6
+
7
+ namespace RTC
8
+ {
9
+ /**
10
+ * Estimates the offset between the wall clock of a remote sender, as reported in
11
+ * the NTP field of the RTCP Sender Reports it sends, and mediasoup's own monotonic
12
+ * clock. Both are expressed in milliseconds, so the estimated offset satisfies:
13
+ *
14
+ * localMs = remoteMs + offsetMs
15
+ *
16
+ * Each sample is the difference between the arrival time of a Sender Report and
17
+ * the NTP value it carries, so it holds the clock offset plus the one way delay
18
+ * of that Sender Report. That delay is removed with half of the RTT when known,
19
+ * and the median of a sliding window is taken so that transient delay spikes are
20
+ * rejected.
21
+ *
22
+ * A single instance is meant to be shared by all the RTP streams of a given
23
+ * CNAME. Those streams come from the same machine and hence from the same wall
24
+ * clock, and using a different offset for each of them would reintroduce the
25
+ * very inter stream skew this is meant to remove.
26
+ *
27
+ * @remarks
28
+ * - Based on the RemoteNtpTimeEstimator class of libwebrtc.
29
+ */
30
+ class RemoteClockOffsetEstimator
31
+ {
32
+ public:
33
+ /**
34
+ * Number of most recent samples the median is computed over.
35
+ */
36
+ static constexpr size_t WindowSize{ 7 };
37
+ /**
38
+ * Number of samples required before an offset is reported.
39
+ */
40
+ static constexpr size_t MinSampleCount{ 3 };
41
+
42
+ public:
43
+ RemoteClockOffsetEstimator();
44
+
45
+ public:
46
+ /**
47
+ * Feed a received RTCP Sender Report.
48
+ *
49
+ * @param remoteNtpMs - NTP field of the Sender Report, in milliseconds.
50
+ * @param localArrivalMs - Our local time at which the Sender Report arrived.
51
+ * @param rttMs - RTT towards the sender, or 0 if not known yet.
52
+ */
53
+ void AddSenderReport(uint64_t remoteNtpMs, uint64_t localArrivalMs, uint32_t rttMs);
54
+
55
+ /**
56
+ * The estimated offset, or no value while less than `MinSampleCount` samples
57
+ * have been gathered.
58
+ */
59
+ std::optional<int64_t> GetOffsetMs() const
60
+ {
61
+ return this->offsetMs;
62
+ }
63
+
64
+ /**
65
+ * Translate a time expressed in the remote sender's wall clock into our own
66
+ * monotonic clock. Returns no value if there is no offset yet or if the given
67
+ * time does not map into our clock.
68
+ */
69
+ std::optional<uint64_t> RemoteMsToLocalMs(uint64_t remoteMs) const;
70
+
71
+ void Reset();
72
+
73
+ private:
74
+ void UpdateOffsetMs();
75
+
76
+ private:
77
+ // Most recent samples, oldest first.
78
+ std::vector<int64_t> samples;
79
+ // Arrival time of the last accepted Sender Report, so that all the Sender
80
+ // Reports of a same compound packet produce a single sample.
81
+ uint64_t lastLocalArrivalMs{ 0 };
82
+ // Median of the samples in the window.
83
+ std::optional<int64_t> offsetMs;
84
+ };
85
+ } // namespace RTC
86
+
87
+ #endif
@@ -79,11 +79,8 @@ namespace RTC
79
79
  bool first) override;
80
80
  void OnTransportProducerRtpPacketReceived(
81
81
  RTC::Transport* transport, RTC::Producer* producer, RTC::RTP::Packet* packet) override;
82
- void OnTransportNeedWorstRemoteFractionLost(
83
- RTC::Transport* transport,
84
- RTC::Producer* producer,
85
- uint32_t mappedSsrc,
86
- uint8_t& worstRemoteFractionLost) override;
82
+ uint8_t OnTransportNeedWorstRemoteFractionLost(
83
+ RTC::Transport* transport, RTC::Producer* producer, uint32_t mappedSsrc) override;
87
84
  void OnTransportNewConsumer(
88
85
  RTC::Transport* transport, RTC::Consumer* consumer, const std::string& producerId) override;
89
86
  void OnTransportConsumerClosed(RTC::Transport* transport, RTC::Consumer* consumer) override;