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.
- package/CHANGELOG.md +16 -0
- package/node/lib/Consumer.js +1 -1
- package/node/lib/Transport.d.ts.map +1 -1
- package/node/lib/Transport.js +7 -0
- package/node/lib/ortc.d.ts.map +1 -1
- package/node/lib/ortc.js +10 -0
- package/node/lib/test/test-PipeTransport.js +35 -30
- package/package.json +6 -6
- package/worker/include/DepLibUV.hpp +33 -4
- package/worker/include/RTC/Consumer.hpp +4 -1
- package/worker/include/RTC/Producer.hpp +34 -5
- package/worker/include/RTC/RTCP/Packet.hpp +7 -1
- package/worker/include/RTC/RTP/Packet.hpp +18 -0
- package/worker/include/RTC/RTP/RtpStream.hpp +76 -14
- package/worker/include/RTC/RTP/RtpStreamRecv.hpp +191 -7
- package/worker/include/RTC/RTP/RtpStreamSend.hpp +56 -10
- package/worker/include/RTC/RTP/RtxStream.hpp +34 -2
- package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +92 -0
- package/worker/include/RTC/RemoteClockOffsetEstimator.hpp +87 -0
- package/worker/include/RTC/Router.hpp +2 -5
- package/worker/include/RTC/SimulcastProducerStreamManager.hpp +3 -0
- package/worker/include/RTC/Transport.hpp +15 -7
- package/worker/include/Shared.hpp +5 -0
- package/worker/include/SharedInterface.hpp +6 -0
- package/worker/include/Utils.hpp +44 -3
- package/worker/meson.build +4 -0
- package/worker/mocks/include/MockShared.hpp +7 -0
- package/worker/src/DepLibUV.cpp +17 -0
- package/worker/src/RTC/Consumer.cpp +8 -5
- package/worker/src/RTC/Producer.cpp +85 -16
- package/worker/src/RTC/RTP/Packet.cpp +9 -1
- package/worker/src/RTC/RTP/RtpStream.cpp +14 -10
- package/worker/src/RTC/RTP/RtpStreamRecv.cpp +150 -23
- package/worker/src/RTC/RTP/RtpStreamSend.cpp +34 -19
- package/worker/src/RTC/RTP/RtxStream.cpp +12 -6
- package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +77 -0
- package/worker/src/RTC/RemoteClockOffsetEstimator.cpp +106 -0
- package/worker/src/RTC/Router.cpp +10 -8
- package/worker/src/RTC/RtpDictionaries/RtcpParameters.cpp +13 -3
- package/worker/src/RTC/SCTP/packet/chunks/SackChunk.cpp +6 -2
- package/worker/src/RTC/SimulcastProducerStreamManager.cpp +115 -56
- package/worker/src/RTC/SvcProducerStreamManager.cpp +22 -17
- package/worker/src/RTC/Transport.cpp +96 -4
- package/worker/test/src/RTC/RTP/TestPacket.cpp +6 -0
- package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +2 -2
- package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +119 -0
- package/worker/test/src/RTC/TestConsumer.cpp +4 -3
- package/worker/test/src/RTC/TestPortManager.cpp +1 -1
- package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +164 -0
- package/worker/test/src/RTC/TestRemoteClockOffsetEstimator.cpp +241 -0
- package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +2 -2
- package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +340 -15
- package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +2 -2
- package/worker/test/src/RTC/TestTransportTuple.cpp +1 -1
- 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
|
-
|
|
26
|
-
|
|
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
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
static
|
|
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
|
-
//
|
|
84
|
-
|
|
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
|
-
|
|
113
|
-
|
|
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
|
-
|
|
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;
|