mediasoup 3.27.0 → 3.27.1

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 (27) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/package.json +1 -1
  3. package/worker/fbs/FBS/meson.build +25 -0
  4. package/worker/fbs/meson.build +15 -18
  5. package/worker/include/RTC/BWE/BweTypes.hpp +1 -1
  6. package/worker/include/RTC/BWE/LossBasedController.hpp +520 -0
  7. package/worker/include/RTC/BWE/TargetRateController.hpp +306 -0
  8. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +58 -16
  9. package/worker/include/RTC/BWE/Utils.hpp +39 -0
  10. package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +36 -0
  11. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +5 -5
  12. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +10 -0
  13. package/worker/meson.build +6 -0
  14. package/worker/src/RTC/BWE/LossBasedController.cpp +1046 -0
  15. package/worker/src/RTC/BWE/TargetRateController.cpp +435 -0
  16. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +83 -5
  17. package/worker/src/RTC/BWE/Utils.cpp +54 -0
  18. package/worker/src/RTC/SCTP/association/Association.cpp +15 -1
  19. package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +106 -1
  20. package/worker/src/RTC/SCTP/public/AssociationMetrics.cpp +1 -1
  21. package/worker/src/RTC/Transport.cpp +37 -18
  22. package/worker/tasks.py +43 -18
  23. package/worker/test/src/RTC/BWE/TestLossBasedController.cpp +1199 -0
  24. package/worker/test/src/RTC/BWE/TestTargetRateController.cpp +337 -0
  25. package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +45 -0
  26. package/worker/test/src/RTC/BWE/TestUtils.cpp +61 -0
  27. package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +111 -0
@@ -0,0 +1,306 @@
1
+ #ifndef MS_RTC_BWE_TARGET_RATE_CONTROLLER_HPP
2
+ #define MS_RTC_BWE_TARGET_RATE_CONTROLLER_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/BWE/BweTypes.hpp"
6
+ #include "RTC/BWE/LossBasedController.hpp"
7
+ #include <deque>
8
+ #include <vector>
9
+
10
+ namespace RTC
11
+ {
12
+ namespace BWE
13
+ {
14
+ /**
15
+ * Holds the target bitrate and every bound that applies to it.
16
+ *
17
+ * The delay based path, the receiver of the media and the application each
18
+ * produce a limit rather than a bitrate, so something has to hold the value
19
+ * they bound and decide how it moves within them. That is this class, and it
20
+ * also owns the two inputs that move the target down on their own: a round
21
+ * trip time long enough to mean that the queues of the network are full, and
22
+ * the loss the receiver reports.
23
+ *
24
+ * How loss moves the target depends on how much is known about it. Until the
25
+ * loss controller has seen enough feedback to tell congestion from the loss a
26
+ * link has by itself, this class applies rules of its own on the fraction of
27
+ * packets reported as lost: increase while it stays under 2%, leave the target
28
+ * alone up to 10%, and decrease it above that. They are coarse on purpose, and
29
+ * their weakness is precisely what they cannot tell apart, so on a link with
30
+ * steady loss above 2% they hold the target still and above 10% they drive it
31
+ * to the minimum. As soon as the loss controller is ready, its estimate
32
+ * replaces them.
33
+ *
34
+ * @remarks
35
+ * - This class is a port of the SendSideBandwidthEstimation class in
36
+ * libwebrtc (renamed to a better name).
37
+ */
38
+ class TargetRateController
39
+ {
40
+ public:
41
+ struct TargetRateControllerOptions
42
+ {
43
+ /**
44
+ * Reported loss under which the bitrate is increased.
45
+ */
46
+ double lowLossThreshold{ 0.02 };
47
+ /**
48
+ * Reported loss over which the bitrate is decreased.
49
+ */
50
+ double highLossThreshold{ 0.1 };
51
+ /**
52
+ * Bitrate under which loss is ignored altogether, since at a low enough
53
+ * bitrate loss is unlikely to be caused by the traffic itself.
54
+ */
55
+ int64_t bitrateThreshold{ 0 };
56
+ /**
57
+ * Whether the bound asked for by the receiver takes part in how the
58
+ * target moves, rather than only capping the value this controller
59
+ * hands out.
60
+ */
61
+ bool disableReceiverLimitCapsOnly{ false };
62
+ /**
63
+ * Round trip time over which the bitrate is dropped regardless of loss.
64
+ * A round trip time this long means the queues of the network are full.
65
+ */
66
+ int64_t maxRttUs{ 3 * 1000 * 1000 };
67
+ /**
68
+ * Fraction of the target the bitrate is dropped to on each of those
69
+ * drops.
70
+ */
71
+ double rttBackoffDropFraction{ 0.8 };
72
+ /**
73
+ * How often the bitrate may be dropped due to the round trip time.
74
+ */
75
+ int64_t rttBackoffDropIntervalUs{ 1000 * 1000 };
76
+ /**
77
+ * Bitrate the round trip time backoff never drops below.
78
+ */
79
+ int64_t rttBackoffBitrateFloor{ 5000 };
80
+ };
81
+
82
+ private:
83
+ /**
84
+ * Drops the bitrate when the round trip time stays long enough to mean
85
+ * that the queues of the network are full, which is a congestion signal
86
+ * that loss and delay may both miss.
87
+ */
88
+ struct RttBackoff
89
+ {
90
+ /**
91
+ * Round trip time corrected for the sender being idle. Without the
92
+ * correction a sender that stops transmitting would keep reporting the
93
+ * last measured value forever.
94
+ */
95
+ int64_t GetCorrectedRttUs() const
96
+ {
97
+ int64_t timeoutCorrectionUs{ 0 };
98
+
99
+ // While either instant is missing there is nothing to correct: no
100
+ // feedback has arrived, or nothing that gets feedback has been sent.
101
+ if (this->lastPacketSentAtUs.has_value() && this->lastPropagationRttAtUs.has_value())
102
+ {
103
+ timeoutCorrectionUs = std::max<int64_t>(
104
+ this->lastPacketSentAtUs.value() - this->lastPropagationRttAtUs.value(), 0);
105
+ }
106
+
107
+ return timeoutCorrectionUs + this->lastPropagationRttUs;
108
+ }
109
+
110
+ std::optional<int64_t> lastPropagationRttAtUs;
111
+ std::optional<int64_t> lastPacketSentAtUs;
112
+ int64_t lastPropagationRttUs{ 0 };
113
+ };
114
+
115
+ public:
116
+ TargetRateController();
117
+
118
+ explicit TargetRateController(TargetRateControllerOptions options);
119
+
120
+ /**
121
+ * Bitrate this controller may produce, already within every bound.
122
+ */
123
+ int64_t GetTargetBitrate() const;
124
+
125
+ /**
126
+ * Latest fraction of lost packets reported by the receiver, in 1/256 units.
127
+ */
128
+ uint8_t GetFractionLost() const
129
+ {
130
+ return this->lastFractionLost;
131
+ }
132
+
133
+ int64_t GetRttUs() const
134
+ {
135
+ return this->lastRttUs;
136
+ }
137
+
138
+ /**
139
+ * Whether the round trip time is long enough to be taken as congestion on
140
+ * its own.
141
+ */
142
+ bool IsRttAboveLimit() const
143
+ {
144
+ return this->rttBackoff.GetCorrectedRttUs() > this->options.maxRttUs;
145
+ }
146
+
147
+ /**
148
+ * Forget everything learnt about the network, which is what a transport
149
+ * that is not going through the same path anymore calls for.
150
+ *
151
+ * @remarks
152
+ * - The bounds set by the application are dropped too, so they have to be
153
+ * set again afterwards.
154
+ */
155
+ void OnRouteChange();
156
+
157
+ /**
158
+ * Bounds set by the application.
159
+ *
160
+ * @remarks
161
+ * - A max bitrate of zero means no limit.
162
+ */
163
+ void SetBitrateLimits(int64_t minBitrate, int64_t maxBitrate);
164
+
165
+ /**
166
+ * Place the target at the given bitrate, dropping the bound that could
167
+ * hold it back and the history that limits how fast it grows.
168
+ */
169
+ void SetSendBitrate(int64_t bitrate);
170
+
171
+ /**
172
+ * Upper bound produced by the delay based path.
173
+ */
174
+ void SetDelayBasedEstimate(int64_t bitrate);
175
+
176
+ /**
177
+ * Upper bound asked for by the receiver of the media, which reaches us as
178
+ * a REMB message.
179
+ *
180
+ * @remarks
181
+ * - A bitrate of zero means no limit.
182
+ */
183
+ void SetReceiverEstimate(int64_t bitrate);
184
+
185
+ /**
186
+ * Feed a loss report of the receiver.
187
+ *
188
+ * @remarks
189
+ * - Reports are accumulated until they cover enough packets, so most calls
190
+ * change nothing.
191
+ */
192
+ void UpdatePacketsLost(int64_t lostPackets, int64_t totalPackets, int64_t nowUs);
193
+
194
+ void UpdateRtt(int64_t rttUs);
195
+
196
+ /**
197
+ * Feed the round trip time the round trip time backoff watches, which is
198
+ * the one measured by the transport feedback rather than by RTCP.
199
+ */
200
+ void UpdatePropagationRtt(int64_t propagationRttUs, int64_t nowUs);
201
+
202
+ /**
203
+ * Tell that a packet that will be reported back has just been sent.
204
+ */
205
+ void OnPacketSent(int64_t sentAtUs);
206
+
207
+ /**
208
+ * Reconsider the target. Called after every loss report and periodically,
209
+ * since the increase depends on how much time has elapsed.
210
+ */
211
+ void Update(int64_t nowUs);
212
+
213
+ /**
214
+ * Bitrate the network is known to be delivering.
215
+ */
216
+ void SetAcknowledgedBitrate(int64_t acknowledgedBitrate);
217
+
218
+ /**
219
+ * Feed the results of a feedback message to the loss controller, which is
220
+ * the only thing in here that looks at packets one by one.
221
+ *
222
+ * @param inAlr - Whether the sender is not sending enough to fill the link.
223
+ */
224
+ void UpdateLossBasedController(
225
+ const std::vector<Types::PacketResult>& packetResults, bool inAlr, int64_t nowUs);
226
+
227
+ /**
228
+ * What the loss controller is doing with the target, which tells whether
229
+ * probing makes sense.
230
+ */
231
+ LossBasedController::State GetLossBasedState() const
232
+ {
233
+ return this->lossBasedState;
234
+ }
235
+
236
+ private:
237
+ /**
238
+ * Whether the target is still allowed to just follow the bounds because
239
+ * not enough is known about the network yet.
240
+ */
241
+ bool IsInStartPhase(int64_t nowUs) const;
242
+
243
+ /**
244
+ * Lowest bitrate the target has had during the last second, which is what
245
+ * the increase grows from.
246
+ */
247
+ void UpdateMinBitrateHistory(int64_t nowUs);
248
+
249
+ /**
250
+ * Upper bound of every kind that applies to the target.
251
+ */
252
+ int64_t GetUpperLimit() const;
253
+
254
+ /**
255
+ * Set the target to the given bitrate, keeping it within its bounds.
256
+ */
257
+ void SetTargetBitrate(int64_t bitrate);
258
+
259
+ /**
260
+ * Reapply the bounds to the current target, which is needed when one of
261
+ * them changes.
262
+ */
263
+ void ApplyTargetLimits();
264
+
265
+ private:
266
+ // Passed by argument.
267
+ const TargetRateControllerOptions options;
268
+ // Others.
269
+ // Tells congestion from the loss the link has by itself, and takes over
270
+ // the target as soon as it has enough observations.
271
+ LossBasedController lossBasedController;
272
+ LossBasedController::State lossBasedState{ LossBasedController::State::DELAY_BASED_ESTIMATE };
273
+ struct RttBackoff rttBackoff;
274
+ // Lowest target of the last second, as a sliding window minimum of
275
+ // (instant in us, bitrate in bps) pairs.
276
+ std::deque<std::pair<int64_t, int64_t>> minBitrateHistory;
277
+ // Loss reports too small to tell anything on their own, accumulated until
278
+ // they cover enough packets.
279
+ int64_t lostPacketsSinceLastLossUpdate{ 0 };
280
+ int64_t expectedPacketsSinceLastLossUpdate{ 0 };
281
+ int64_t currentTarget{ 0 };
282
+ int64_t minBitrateConfigured{ 0 };
283
+ int64_t maxBitrateConfigured{ 0 };
284
+ // Instant of the first loss report ever received, which is when the start
285
+ // phase begins.
286
+ std::optional<int64_t> firstLossReportAtUs;
287
+ // Instant of the latest loss report that covered enough packets to tell
288
+ // something.
289
+ std::optional<int64_t> lastLossReportAtUs;
290
+ // Instant at which the target was last decreased, by the loss rules or by
291
+ // the round trip time backoff.
292
+ std::optional<int64_t> lastDecreaseAtUs;
293
+ // Whether the target has already been decreased for the loss currently
294
+ // reported, so that a same report doesn't decrease it twice.
295
+ bool hasDecreasedSinceLastFractionLoss{ false };
296
+ uint8_t lastFractionLost{ 0 };
297
+ int64_t lastRttUs{ 0 };
298
+ // Upper bound asked for by the receiver of the media.
299
+ int64_t receiverLimit{ Types::BitrateInfinite };
300
+ // Upper bound produced by the delay based path.
301
+ int64_t delayBasedLimit{ Types::BitrateInfinite };
302
+ };
303
+ } // namespace BWE
304
+ } // namespace RTC
305
+
306
+ #endif
@@ -26,30 +26,61 @@ namespace RTC
26
26
  */
27
27
  class TrendlineEstimator
28
28
  {
29
+ public:
30
+ struct TrendlineEstimatorOptions
31
+ {
32
+ /**
33
+ * Number of samples of the least squares regression window. A shorter
34
+ * window reacts sooner at the cost of being noisier.
35
+ *
36
+ * @remarks
37
+ * - It must be at least 2, since a line cannot be fitted to a single
38
+ * point.
39
+ */
40
+ size_t windowSize{ 20 };
41
+ /**
42
+ * Whether the samples of the window are kept sorted by arrival time.
43
+ * Feedback should already give them in order, so this is a safety net
44
+ * against a source that doesn't.
45
+ */
46
+ bool enableSort{ false };
47
+ /**
48
+ * Whether the slope is capped by the one that the least delayed packets
49
+ * of both ends of the window describe, which keeps a burst of delayed
50
+ * packets in the middle from being read as a growing queue.
51
+ */
52
+ bool enableCap{ false };
53
+ /**
54
+ * How many packets of the beginning of the window that cap looks at.
55
+ */
56
+ size_t beginningPackets{ 7 };
57
+ /**
58
+ * How many packets of the end of the window that cap looks at.
59
+ */
60
+ size_t endPackets{ 7 };
61
+ /**
62
+ * Slack added to that cap, so that a slope barely above it is not
63
+ * capped.
64
+ */
65
+ double capUncertainty{ 0.0 };
66
+ };
67
+
29
68
  private:
30
69
  struct PacketTiming
31
70
  {
32
71
  double arrivalTimeUs;
33
72
  double smoothedDelayUs;
73
+ /**
74
+ * Accumulated delay before it's smoothed, which is what the slope cap
75
+ * looks at.
76
+ */
77
+ double rawDelayUs;
34
78
  };
35
79
 
36
80
  public:
37
- /**
38
- * Number of samples of the least squares regression window used unless
39
- * another one is given.
40
- */
41
- static constexpr size_t DefaultWindowSize{ 20 };
81
+ TrendlineEstimator();
42
82
 
43
- public:
44
- /**
45
- * @param windowSize - Number of samples of the least squares regression
46
- * window. A shorter window reacts sooner at the cost of being noisier.
47
- *
48
- * @remarks
49
- * - `windowSize` must be at least 2, since a line cannot be fitted to a
50
- * single point.
51
- */
52
- explicit TrendlineEstimator(size_t windowSize = DefaultWindowSize);
83
+ explicit TrendlineEstimator(TrendlineEstimatorOptions options);
53
84
 
54
85
  /**
55
86
  * Feed the deltas between two consecutive groups of packets.
@@ -77,12 +108,23 @@ namespace RTC
77
108
  */
78
109
  std::optional<double> GetLinearFitSlope() const;
79
110
 
111
+ /**
112
+ * Highest slope that the least delayed samples of both ends of the window
113
+ * describe, or no value if they are too close in time to tell.
114
+ *
115
+ * @remarks
116
+ * - A burst of delayed packets in the middle of the window tilts the
117
+ * fitted line even though the queue never grew, and this is what keeps
118
+ * that from being read as overuse.
119
+ */
120
+ std::optional<double> GetSlopeCap() const;
121
+
80
122
  void Detect(double trend, double sendDeltaUs, int64_t arrivalTimeUs);
81
123
 
82
124
  void UpdateThreshold(double modifiedTrend, int64_t arrivalTimeUs);
83
125
 
84
126
  private:
85
- const size_t windowSize;
127
+ const TrendlineEstimatorOptions options;
86
128
  int numOfDeltas{ 0 };
87
129
  std::optional<int64_t> firstArrivalTimeUs;
88
130
  double accumulatedDelayUs{ 0 };
@@ -0,0 +1,39 @@
1
+ #ifndef MS_RTC_BWE_UTILS_HPP
2
+ #define MS_RTC_BWE_UTILS_HPP
3
+
4
+ #include "common.hpp"
5
+
6
+ namespace RTC
7
+ {
8
+ namespace BWE
9
+ {
10
+ class Utils
11
+ {
12
+ public:
13
+ /**
14
+ * Bitrate that results from applying a factor to another one (bps).
15
+ *
16
+ * @remarks
17
+ * - The algorithm derives a bitrate from another one this way all over the
18
+ * place, and the result has to come back to an int64_t. A value beyond
19
+ * what that type holds becomes `Types::BitrateInfinite` rather than the
20
+ * undefined one that converting it would give.
21
+ * - The result is rounded, not truncated, since each bitrate is derived
22
+ * from the previous one and dropping the fraction every time would drift
23
+ * downwards.
24
+ */
25
+ static int64_t ApplyBitrateFactor(int64_t bitrate, double factor);
26
+
27
+ /**
28
+ * Sum of two bitrates (bps).
29
+ *
30
+ * @remarks
31
+ * - A sum beyond what an int64_t can hold becomes `Types::BitrateInfinite`
32
+ * rather than wrapping around into a negative bitrate.
33
+ */
34
+ static int64_t AddBitrates(int64_t bitrate, int64_t otherBitrate);
35
+ };
36
+ } // namespace BWE
37
+ } // namespace RTC
38
+
39
+ #endif
@@ -163,6 +163,25 @@ namespace RTC
163
163
  bool isDeferred{ false };
164
164
  };
165
165
 
166
+ /**
167
+ * Represents a received outgoing stream reset request whose processing
168
+ * had to be deferred because the sender's last assigned TSN had not been
169
+ * reached yet (aka "deferred reset processing").
170
+ */
171
+ struct DeferredIncomingRequest
172
+ {
173
+ /**
174
+ * The sender's (that's the peer) last assigned TSN. Deferred reset
175
+ * processing must end once the cumulative ack TSN reaches it.
176
+ */
177
+ uint32_t senderLastAssignedTsn;
178
+
179
+ /**
180
+ * The streams that are to be reset.
181
+ */
182
+ std::vector<uint16_t> streamIds;
183
+ };
184
+
166
185
  private:
167
186
  using UnwrappedReConfigRequestSn = Utils::UnwrappedSequenceNumber<uint32_t>;
168
187
 
@@ -211,6 +230,18 @@ namespace RTC
211
230
  */
212
231
  void HandleReceivedReConfigChunk(const ReConfigChunk* receivedReConfigChunk);
213
232
 
233
+ /**
234
+ * Called at the end of processing a received SCTP packet. If this
235
+ * association is in "deferred reset processing" and the cumulative ack TSN
236
+ * has reached the sender's last assigned TSN, the deferred stream reset is
237
+ * performed and deferred reset processing ends.
238
+ *
239
+ * Returns `true` if deferred reset processing ended, in which case the
240
+ * chunks queued while it lasted have been released and there may be
241
+ * messages to deliver.
242
+ */
243
+ bool MayLeaveDeferredReset();
244
+
214
245
  private:
215
246
  /**
216
247
  * Called to validate a received RE-CONFIG chunk.
@@ -279,6 +310,11 @@ namespace RTC
279
310
  ReconfigurationResponseParameter::Result lastProcessedReqResult;
280
311
  // The current stream request operation.
281
312
  std::optional<CurrentRequest> currentRequest;
313
+ // The received request being deferred, if in deferred reset processing.
314
+ std::optional<DeferredIncomingRequest> deferredIncomingRequest;
315
+ // The received request that was performed when deferred reset processing
316
+ // ended, until the peer retries it and gets the final response.
317
+ std::optional<DeferredIncomingRequest> performedDeferredRequest;
282
318
  };
283
319
  } // namespace SCTP
284
320
  } // namespace RTC
@@ -48,7 +48,7 @@ namespace RTC
48
48
  SHUTTING_DOWN
49
49
  };
50
50
 
51
- constexpr std::string_view AssociationStateToString(AssociationState associationState)
51
+ constexpr std::string_view associationStateToString(AssociationState associationState)
52
52
  {
53
53
  switch (associationState)
54
54
  {
@@ -128,7 +128,7 @@ namespace RTC
128
128
  UNSUPPORTED_OPERATION
129
129
  };
130
130
 
131
- constexpr std::string_view ErrorKindToString(ErrorKind errorKind)
131
+ constexpr std::string_view errorKindToString(ErrorKind errorKind)
132
132
  {
133
133
  switch (errorKind)
134
134
  {
@@ -195,7 +195,7 @@ namespace RTC
195
195
  USRSCTP
196
196
  };
197
197
 
198
- constexpr std::string_view SctpImplementationToString(SctpImplementation sctpImplementation)
198
+ constexpr std::string_view sctpImplementationToString(SctpImplementation sctpImplementation)
199
199
  {
200
200
  switch (sctpImplementation)
201
201
  {
@@ -246,7 +246,7 @@ namespace RTC
246
246
  NOT_SUPPORTED
247
247
  };
248
248
 
249
- constexpr std::string_view ResetStreamsStatusToString(ResetStreamsStatus status)
249
+ constexpr std::string_view resetStreamsStatusToString(ResetStreamsStatus status)
250
250
  {
251
251
  switch (status)
252
252
  {
@@ -303,7 +303,7 @@ namespace RTC
303
303
  ERROR_SHUTTING_DOWN
304
304
  };
305
305
 
306
- constexpr std::string_view SendMessageStatusToString(SendMessageStatus status)
306
+ constexpr std::string_view sendMessageStatusToString(SendMessageStatus status)
307
307
  {
308
308
  switch (status)
309
309
  {
@@ -141,9 +141,19 @@ namespace RTC
141
141
 
142
142
  /**
143
143
  * The remaining bytes until the queue has reached the watermark limit.
144
+ *
145
+ * @remarks
146
+ * - The queued bytes are allowed to go above the watermark limit (data is
147
+ * only rejected once the queue is full), so this returns 0 rather than
148
+ * wrapping around.
144
149
  */
145
150
  size_t GetRemainingBytes() const
146
151
  {
152
+ if (this->queuedBytes >= this->watermarkBytes)
153
+ {
154
+ return 0;
155
+ }
156
+
147
157
  return this->watermarkBytes - this->queuedBytes;
148
158
  }
149
159
 
@@ -169,9 +169,12 @@ common_sources = [
169
169
  'src/RTC/BWE/FeedbackAdapter.cpp',
170
170
  'src/RTC/BWE/InterArrivalDelta.cpp',
171
171
  'src/RTC/BWE/LinkCapacityEstimator.cpp',
172
+ 'src/RTC/BWE/LossBasedController.cpp',
172
173
  'src/RTC/BWE/RobustThroughputEstimator.cpp',
173
174
  'src/RTC/BWE/SendPacketHistory.cpp',
175
+ 'src/RTC/BWE/TargetRateController.cpp',
174
176
  'src/RTC/BWE/TrendlineEstimator.cpp',
177
+ 'src/RTC/BWE/Utils.cpp',
175
178
  'src/RTC/ICE/IceCandidate.cpp',
176
179
  'src/RTC/ICE/IceServer.cpp',
177
180
  'src/RTC/ICE/StunPacket.cpp',
@@ -475,9 +478,12 @@ test_sources = [
475
478
  'test/src/RTC/BWE/TestFeedbackAdapter.cpp',
476
479
  'test/src/RTC/BWE/TestInterArrivalDelta.cpp',
477
480
  'test/src/RTC/BWE/TestLinkCapacityEstimator.cpp',
481
+ 'test/src/RTC/BWE/TestLossBasedController.cpp',
478
482
  'test/src/RTC/BWE/TestRobustThroughputEstimator.cpp',
479
483
  'test/src/RTC/BWE/TestSendPacketHistory.cpp',
484
+ 'test/src/RTC/BWE/TestTargetRateController.cpp',
480
485
  'test/src/RTC/BWE/TestTrendlineEstimator.cpp',
486
+ 'test/src/RTC/BWE/TestUtils.cpp',
481
487
  'test/src/RTC/ICE/iceCommon.cpp',
482
488
  'test/src/RTC/ICE/TestStunPacket.cpp',
483
489
  'test/src/RTC/RTP/rtpCommon.cpp',