mediasoup 3.28.0 → 3.29.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 (155) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/node/lib/PipeTransportTypes.d.ts +6 -1
  3. package/node/lib/PipeTransportTypes.d.ts.map +1 -1
  4. package/node/lib/PlainTransportTypes.d.ts +6 -1
  5. package/node/lib/PlainTransportTypes.d.ts.map +1 -1
  6. package/node/lib/Router.d.ts +4 -4
  7. package/node/lib/Router.d.ts.map +1 -1
  8. package/node/lib/Router.js +10 -7
  9. package/node/lib/RouterTypes.d.ts +7 -1
  10. package/node/lib/RouterTypes.d.ts.map +1 -1
  11. package/node/lib/Transport.d.ts +2 -1
  12. package/node/lib/Transport.d.ts.map +1 -1
  13. package/node/lib/Transport.js +17 -6
  14. package/node/lib/TransportTypes.d.ts +12 -2
  15. package/node/lib/TransportTypes.d.ts.map +1 -1
  16. package/node/lib/WebRtcTransportTypes.d.ts +6 -1
  17. package/node/lib/WebRtcTransportTypes.d.ts.map +1 -1
  18. package/node/lib/fbs/transport/options.d.ts +6 -2
  19. package/node/lib/fbs/transport/options.d.ts.map +1 -1
  20. package/node/lib/fbs/transport/options.js +19 -7
  21. package/node/lib/fbs/transport/sctp-zero-checksum.d.ts +6 -0
  22. package/node/lib/fbs/transport/sctp-zero-checksum.d.ts.map +1 -0
  23. package/node/lib/fbs/transport/sctp-zero-checksum.js +11 -0
  24. package/node/lib/fbs/transport/stats.d.ts +2 -8
  25. package/node/lib/fbs/transport/stats.d.ts.map +1 -1
  26. package/node/lib/fbs/transport/stats.js +5 -29
  27. package/node/lib/fbs/transport.d.ts +1 -0
  28. package/node/lib/fbs/transport.d.ts.map +1 -1
  29. package/node/lib/fbs/transport.js +4 -2
  30. package/npm-scripts.mjs +35 -44
  31. package/package.json +10 -6
  32. package/worker/fbs/transport.fbs +9 -2
  33. package/worker/fuzzer/src/RTC/RTP/FuzzerRetransmissionBuffer.cpp +14 -1
  34. package/worker/fuzzer/src/RTC/RTP/FuzzerRtpStreamSend.cpp +17 -4
  35. package/worker/include/RTC/BWE/AimdRateControl.hpp +9 -9
  36. package/worker/include/RTC/BWE/BweTypes.hpp +54 -17
  37. package/worker/include/RTC/BWE/DelayBasedBwe.hpp +3 -3
  38. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +2 -2
  39. package/worker/include/RTC/BWE/LossBasedController.hpp +4 -4
  40. package/worker/include/RTC/BWE/OveruseDetector.hpp +5 -4
  41. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +1 -1
  42. package/worker/include/RTC/BWE/ProbeController.hpp +6 -6
  43. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +2 -6
  44. package/worker/include/RTC/BWE/ProbingScheduler.hpp +3 -7
  45. package/worker/include/RTC/BWE/ReceiverTransportCongestionController.hpp +148 -0
  46. package/worker/include/RTC/BWE/RembGenerator.hpp +4 -3
  47. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +1 -1
  48. package/worker/include/RTC/BWE/SenderTransportCongestionController.hpp +343 -0
  49. package/worker/include/RTC/BWE/TargetRateController.hpp +4 -1
  50. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +5 -4
  51. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +3 -3
  52. package/worker/include/RTC/Consumer.hpp +8 -1
  53. package/worker/include/RTC/RTP/RetransmissionBuffer.hpp +36 -10
  54. package/worker/include/RTC/RTP/RtpStream.hpp +21 -0
  55. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +1 -0
  56. package/worker/include/RTC/RTP/RtpStreamSend.hpp +122 -9
  57. package/worker/include/RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp +12 -3
  58. package/worker/include/RTC/TransportCongestionControlClient.hpp +0 -5
  59. package/worker/include/RTC/TransportCongestionControlServer.hpp +0 -5
  60. package/worker/include/Utils.hpp +9 -2
  61. package/worker/meson.build +4 -0
  62. package/worker/src/RTC/BWE/AimdRateControl.cpp +22 -22
  63. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +16 -20
  64. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +1 -1
  65. package/worker/src/RTC/BWE/OveruseDetector.cpp +8 -8
  66. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +2 -2
  67. package/worker/src/RTC/BWE/ProbeController.cpp +1 -1
  68. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +1 -6
  69. package/worker/src/RTC/BWE/ProbingScheduler.cpp +2 -7
  70. package/worker/src/RTC/BWE/ReceiverTransportCongestionController.cpp +207 -0
  71. package/worker/src/RTC/BWE/RembGenerator.cpp +1 -1
  72. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +1 -1
  73. package/worker/src/RTC/BWE/SenderTransportCongestionController.cpp +599 -0
  74. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +2 -3
  75. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +5 -5
  76. package/worker/src/RTC/Consumer.cpp +3 -2
  77. package/worker/src/RTC/DataConsumer.cpp +2 -2
  78. package/worker/src/RTC/RTP/RetransmissionBuffer.cpp +21 -8
  79. package/worker/src/RTC/RTP/RtpStream.cpp +0 -3
  80. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +57 -71
  81. package/worker/src/RTC/RTP/RtpStreamSend.cpp +428 -244
  82. package/worker/src/RTC/RTP/RtxStream.cpp +14 -19
  83. package/worker/src/RTC/SCTP/association/Association.cpp +3 -2
  84. package/worker/src/RTC/SCTP/association/StateCookie.cpp +26 -6
  85. package/worker/src/RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.cpp +4 -3
  86. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  87. package/worker/src/RTC/SCTP/tx/RetransmissionQueue.cpp +4 -2
  88. package/worker/src/RTC/Transport.cpp +49 -20
  89. package/worker/src/RTC/TransportCongestionControlClient.cpp +0 -66
  90. package/worker/src/RTC/TransportCongestionControlServer.cpp +0 -55
  91. package/worker/src/Utils/Crypto.cpp +114 -98
  92. package/worker/subprojects/catch2.wrap +6 -6
  93. package/worker/subprojects/openssl.wrap +11 -12
  94. package/worker/subprojects/packagefiles/ankerl-unordered-dense/meson.build +1 -1
  95. package/worker/subprojects/unordered-dense.wrap +4 -4
  96. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +5 -5
  97. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +26 -23
  98. package/worker/test/src/RTC/BWE/TestInterArrivalDelta.cpp +8 -8
  99. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +4 -4
  100. package/worker/test/src/RTC/BWE/TestProbeController.cpp +35 -32
  101. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +2 -17
  102. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +1 -25
  103. package/worker/test/src/RTC/BWE/TestReceiverTransportCongestionController.cpp +346 -0
  104. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +1 -1
  105. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +9 -9
  106. package/worker/test/src/RTC/BWE/TestSenderTransportCongestionController.cpp +510 -0
  107. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +16 -14
  108. package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +6 -6
  109. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +1 -2
  110. package/worker/test/src/RTC/RTCP/TestBye.cpp +1 -1
  111. package/worker/test/src/RTC/RTCP/TestFeedbackPsAfb.cpp +1 -1
  112. package/worker/test/src/RTC/RTCP/TestFeedbackPsFir.cpp +1 -1
  113. package/worker/test/src/RTC/RTCP/TestFeedbackPsLei.cpp +1 -1
  114. package/worker/test/src/RTC/RTCP/TestFeedbackPsPli.cpp +1 -1
  115. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +1 -1
  116. package/worker/test/src/RTC/RTCP/TestFeedbackPsRpsi.cpp +1 -1
  117. package/worker/test/src/RTC/RTCP/TestFeedbackPsSli.cpp +1 -1
  118. package/worker/test/src/RTC/RTCP/TestFeedbackPsTst.cpp +1 -1
  119. package/worker/test/src/RTC/RTCP/TestFeedbackPsVbcm.cpp +1 -1
  120. package/worker/test/src/RTC/RTCP/TestFeedbackRtpEcn.cpp +1 -1
  121. package/worker/test/src/RTC/RTCP/TestFeedbackRtpNack.cpp +1 -1
  122. package/worker/test/src/RTC/RTCP/TestFeedbackRtpSrReq.cpp +1 -1
  123. package/worker/test/src/RTC/RTCP/TestFeedbackRtpTllei.cpp +1 -1
  124. package/worker/test/src/RTC/RTCP/TestFeedbackRtpTmmb.cpp +1 -1
  125. package/worker/test/src/RTC/RTCP/TestFeedbackRtpTransport.cpp +1 -1
  126. package/worker/test/src/RTC/RTCP/TestReceiverReport.cpp +1 -1
  127. package/worker/test/src/RTC/RTCP/TestSenderReport.cpp +1 -1
  128. package/worker/test/src/RTC/RTP/TestRetransmissionBuffer.cpp +60 -28
  129. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +1 -1
  130. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +746 -24
  131. package/worker/test/src/RTC/RTP/TestSharedPacket.cpp +1 -1
  132. package/worker/test/src/RTC/SCTP/association/TestAssociation.cpp +42 -0
  133. package/worker/test/src/RTC/SCTP/association/TestNegotiatedCapabilities.cpp +54 -5
  134. package/worker/test/src/RTC/SCTP/association/TestStateCookie.cpp +80 -15
  135. package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +410 -3
  136. package/worker/test/src/RTC/SCTP/association/TestTransmissionControlBlock.cpp +1 -1
  137. package/worker/test/src/RTC/SCTP/packet/parameters/TestZeroChecksumAcceptableParameter.cpp +37 -5
  138. package/worker/test/src/RTC/SCTP/rx/TestDataTracker.cpp +5 -4
  139. package/worker/test/src/RTC/SCTP/rx/TestInterleavedReassemblyStreams.cpp +1 -1
  140. package/worker/test/src/RTC/SCTP/rx/TestReassemblyQueue.cpp +1 -1
  141. package/worker/test/src/RTC/SCTP/rx/TestTraditionalReassemblyStreams.cpp +1 -1
  142. package/worker/test/src/RTC/SCTP/tx/TestOutstandingData.cpp +1 -1
  143. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionQueue.cpp +11 -10
  144. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionTimeout.cpp +1 -1
  145. package/worker/test/src/RTC/TestNackGenerator.cpp +1 -1
  146. package/worker/test/src/RTC/TestPortManager.cpp +2 -2
  147. package/worker/test/src/RTC/TestRateCalculator.cpp +1 -1
  148. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +21 -15
  149. package/worker/test/src/RTC/TestRemoteClockOffsetEstimator.cpp +13 -13
  150. package/worker/test/src/RTC/TestRtpEncodingParameters.cpp +1 -1
  151. package/worker/test/src/RTC/TestSubchannelsCodec.cpp +2 -2
  152. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +1 -1
  153. package/worker/test/src/RTC/TestTransportTuple.cpp +3 -2
  154. package/worker/test/src/Utils/TestCrypto.cpp +71 -2
  155. package/worker/test/src/Utils/TestTime.cpp +2 -2
@@ -44,7 +44,8 @@ SCENARIO("BWE RemoteBitrateEstimatorAbsSendTime", "[bwe][remotebitrateestimatora
44
44
  //
45
45
  // NOTE: Every scenario reuses `rtpCommon::FactoryBuffer`, so the returned
46
46
  // packet is only valid until the next call.
47
- auto buildPacket = [](size_t payloadSize, int64_t sendTimeUs) -> std::unique_ptr<RTC::RTP::Packet>
47
+ const auto buildPacket =
48
+ [](size_t payloadSize, int64_t sendTimeUs) -> std::unique_ptr<RTC::RTP::Packet>
48
49
  {
49
50
  std::unique_ptr<RTC::RTP::Packet> packet(
50
51
  RTC::RTP::Packet::Factory(rtpCommon::FactoryBuffer, sizeof(rtpCommon::FactoryBuffer)));
@@ -66,7 +67,6 @@ SCENARIO("BWE RemoteBitrateEstimatorAbsSendTime", "[bwe][remotebitrateestimatora
66
67
  headerExtensionIds.absSendTime = absSendTimeId;
67
68
 
68
69
  packet->AssignExtensionIds(headerExtensionIds);
69
-
70
70
  packet->SetPayloadLength(payloadSize);
71
71
 
72
72
  REQUIRE(packet->UpdateAbsSendTime(Utils::Time::TimeUsToAbsSendTime(sendTimeUs)));
@@ -76,16 +76,16 @@ SCENARIO("BWE RemoteBitrateEstimatorAbsSendTime", "[bwe][remotebitrateestimatora
76
76
 
77
77
  // Feeds a packet that says it left at `sendTimeUs` and arrived at
78
78
  // `arrivalTimeUs`, which is also taken as the current instant.
79
- auto feedPacket = [&buildPacket](
80
- RTC::BWE::RemoteBitrateEstimatorAbsSendTime& remoteBitrateEstimator,
81
- size_t payloadSize,
82
- int64_t sendTimeUs,
83
- int64_t arrivalTimeUs,
84
- int64_t nowUs) -> void
79
+ const auto feedPacket = [&buildPacket](
80
+ RTC::BWE::RemoteBitrateEstimatorAbsSendTime& remoteBitrateEstimator,
81
+ size_t payloadSize,
82
+ int64_t sendTimeUs,
83
+ int64_t arrivalTimeUs,
84
+ int64_t nowUs) -> void
85
85
  {
86
86
  const auto packet = buildPacket(payloadSize, sendTimeUs);
87
87
 
88
- remoteBitrateEstimator.IncomingPacket(packet.get(), arrivalTimeUs, nowUs);
88
+ remoteBitrateEstimator.ReceiveRtpPacket(packet.get(), arrivalTimeUs, nowUs);
89
89
  };
90
90
 
91
91
  SECTION("a burst faster than the one before it raises the estimation")
@@ -0,0 +1,510 @@
1
+ #include "common.hpp"
2
+ #include "RTC/BWE/SenderTransportCongestionController.hpp"
3
+ #include "RTC/Consts.hpp"
4
+ #include "RTC/RTCP/FeedbackRtpTransport.hpp"
5
+ #include "RTC/RTP/HeaderExtensionIds.hpp"
6
+ #include "RTC/RTP/Packet.hpp"
7
+ #include "RTC/RtpDictionaries.hpp"
8
+ #include "Utils.hpp"
9
+ #include "test/include/RTC/RTP/rtpCommon.hpp"
10
+ #include "mocks/include/MockShared.hpp"
11
+ #include <catch2/catch_test_macros.hpp>
12
+ #include <string_view>
13
+ #include <vector>
14
+
15
+ SCENARIO("BWE SenderTransportCongestionController", "[bwe][sendertransportcongestioncontroller]")
16
+ {
17
+ // The clock starts well away from zero so that a mistake taking a time for a
18
+ // duration doesn't go unnoticed.
19
+ constexpr int64_t InitialTimeUs{ 100000000 };
20
+ // The remote clock has nothing to do with ours, and is a whole number of base
21
+ // time ticks so that the arrival times survive the feedback untouched.
22
+ constexpr int64_t RemoteTimeUs{ 1000000000000 };
23
+ constexpr int64_t StartBitrate{ 300000 };
24
+ constexpr int64_t MinBitrate{ 30000 };
25
+ constexpr int64_t MaxBitrate{ 5000000 };
26
+ constexpr uint32_t Ssrc{ 1111 };
27
+ constexpr uint8_t TransportWideCc01Id{ 5 };
28
+ constexpr uint8_t AbsSendTimeId{ 4 };
29
+ constexpr size_t PayloadSize{ 1000 };
30
+ constexpr std::string_view ProcessTimerLabel{ "sender-transport-congestion-controller-process" };
31
+
32
+ class TestSenderTransportCongestionControllerListener
33
+ : public RTC::BWE::SenderTransportCongestionController::Listener
34
+ {
35
+ public:
36
+ void OnSenderTransportCongestionControllerTargetBitrate(
37
+ RTC::BWE::SenderTransportCongestionController* /*senderTransportCongestionController*/,
38
+ int64_t targetBitrate) override
39
+ {
40
+ this->targetBitrates.push_back(targetBitrate);
41
+ }
42
+
43
+ void OnSenderTransportCongestionControllerSendRtpProbePacket(
44
+ RTC::BWE::SenderTransportCongestionController* /*senderTransportCongestionController*/,
45
+ RTC::RTP::Packet* packet,
46
+ int64_t sequenceNumber) override
47
+ {
48
+ this->sentLengths.push_back(packet->GetLength());
49
+ this->sentSequenceNumbers.push_back(sequenceNumber);
50
+
51
+ // What goes on the wire has to be what we were handed, since that is what
52
+ // the remote endpoint will report back about.
53
+ uint16_t wideSeqNumber{ 0 };
54
+ uint32_t absSendTime{ 0 };
55
+
56
+ this->sentWithExtensions.push_back(
57
+ packet->ReadTransportWideCc01(wideSeqNumber) && packet->ReadAbsSendTime(absSendTime) &&
58
+ wideSeqNumber == static_cast<uint16_t>(sequenceNumber));
59
+ }
60
+
61
+ public:
62
+ std::vector<int64_t> targetBitrates;
63
+ std::vector<size_t> sentLengths;
64
+ std::vector<int64_t> sentSequenceNumbers;
65
+ std::vector<bool> sentWithExtensions;
66
+ };
67
+
68
+ int64_t nowUs{ InitialTimeUs };
69
+
70
+ mocks::MockShared shared(/*getTimeUs*/
71
+ [&nowUs]() -> int64_t
72
+ {
73
+ return nowUs;
74
+ });
75
+
76
+ TestSenderTransportCongestionControllerListener listener;
77
+
78
+ RTC::BWE::SenderTransportCongestionController senderTransportCongestionController(
79
+ std::addressof(listener),
80
+ std::addressof(shared),
81
+ { .startBitrate = StartBitrate, .minBitrate = MinBitrate, .maxBitrate = MaxBitrate });
82
+
83
+ // Builds a packet carrying both extensions with no value in either, which is
84
+ // what the sending side hands over.
85
+ //
86
+ // NOTE: Every scenario reuses `rtpCommon::FactoryBuffer`, so the returned
87
+ // packet is only valid until the next call.
88
+ const auto buildPacket = []() -> std::unique_ptr<RTC::RTP::Packet>
89
+ {
90
+ std::unique_ptr<RTC::RTP::Packet> packet(
91
+ RTC::RTP::Packet::Factory(rtpCommon::FactoryBuffer, sizeof(rtpCommon::FactoryBuffer)));
92
+
93
+ REQUIRE(packet);
94
+
95
+ packet->SetSsrc(Ssrc);
96
+
97
+ const std::vector<RTC::RTP::Packet::Extension> extensions{
98
+ { RTC::RtpHeaderExtensionUri::Type::TRANSPORT_WIDE_CC_01,
99
+ TransportWideCc01Id, /*len*/ 2,
100
+ rtpCommon::DataBuffer },
101
+ { RTC::RtpHeaderExtensionUri::Type::ABS_SEND_TIME, AbsSendTimeId, /*len*/ 3, rtpCommon::DataBuffer }
102
+ };
103
+
104
+ packet->SetExtensions(RTC::RTP::Packet::ExtensionsType::OneByte, extensions);
105
+
106
+ RTC::RTP::HeaderExtensionIds headerExtensionIds;
107
+
108
+ headerExtensionIds.transportWideCc01 = TransportWideCc01Id;
109
+ headerExtensionIds.absSendTime = AbsSendTimeId;
110
+
111
+ packet->AssignExtensionIds(headerExtensionIds);
112
+ packet->SetPayloadLength(PayloadSize);
113
+
114
+ return packet;
115
+ };
116
+
117
+ // Let the periodic work run once.
118
+ const auto runProcessTimer = [&nowUs, &shared, &ProcessTimerLabel]()
119
+ {
120
+ auto* timer = shared.GetTimer(ProcessTimerLabel);
121
+
122
+ REQUIRE(timer);
123
+
124
+ nowUs += timer->GetRepeatMs() * 1000;
125
+
126
+ REQUIRE(timer->EvaluateHasExpired());
127
+ };
128
+
129
+ // Builds the feedback a receiver would send, reporting the given arrival
130
+ // times. The sequence numbers left out of them are reported as lost.
131
+ const auto createFeedback = [](
132
+ uint16_t baseSequenceNumber,
133
+ int64_t baseTimeUs,
134
+ const std::vector<std::pair<uint16_t, int64_t>>& receivedPackets)
135
+ -> std::unique_ptr<RTC::RTCP::FeedbackRtpTransportPacket>
136
+ {
137
+ constexpr uint32_t SenderSsrc{ 2222 };
138
+ constexpr uint32_t MediaSsrc{ 3333 };
139
+ constexpr size_t RtcpMtu{ 1200 };
140
+
141
+ auto feedback = std::make_unique<RTC::RTCP::FeedbackRtpTransportPacket>(SenderSsrc, MediaSsrc);
142
+
143
+ feedback->SetBase(baseSequenceNumber, baseTimeUs);
144
+
145
+ for (const auto& [sequenceNumber, receivedAtUs] : receivedPackets)
146
+ {
147
+ feedback->AddPacket(sequenceNumber, receivedAtUs, RtcpMtu);
148
+ }
149
+
150
+ feedback->Finish();
151
+
152
+ return feedback;
153
+ };
154
+
155
+ // Sends a packet every 50 ms for the given span and feeds back the arrival of
156
+ // each one, with an arrival that falls further and further behind by
157
+ // `delayPerPacketUs` on every packet, which is what a queue filling up looks
158
+ // like. Answers the target the loop is left at.
159
+ uint16_t nextRtpSequenceNumber{ 0 };
160
+
161
+ const auto transmitAndFeedBack = [&nowUs,
162
+ &shared,
163
+ &ProcessTimerLabel,
164
+ &senderTransportCongestionController,
165
+ &buildPacket,
166
+ &createFeedback,
167
+ &nextRtpSequenceNumber](
168
+ int64_t runtimeMs, int64_t delayPerPacketUs) -> int64_t
169
+ {
170
+ const int64_t startUs = nowUs;
171
+ int64_t delayBuildupUs{ 0 };
172
+
173
+ while (nowUs - startUs < runtimeMs * 1000)
174
+ {
175
+ const auto packet = buildPacket();
176
+
177
+ packet->SetSequenceNumber(nextRtpSequenceNumber++);
178
+
179
+ const auto sequenceNumber = senderTransportCongestionController.OnRtpPacketToBeSent(
180
+ packet.get(), RTC::BWE::SenderTransportCongestionController::RtpPacketToBeSentOptions{});
181
+
182
+ REQUIRE(sequenceNumber.has_value());
183
+
184
+ senderTransportCongestionController.OnRtpPacketSent(sequenceNumber, PayloadSize, nowUs);
185
+
186
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
187
+ const auto wideSeqNumber = static_cast<uint16_t>(sequenceNumber.value());
188
+ const int64_t arrivalUs = RemoteTimeUs + (nowUs - InitialTimeUs) + delayBuildupUs;
189
+
190
+ const auto feedback = createFeedback(
191
+ wideSeqNumber,
192
+ arrivalUs,
193
+ {
194
+ { wideSeqNumber, arrivalUs }
195
+ });
196
+
197
+ delayBuildupUs += delayPerPacketUs;
198
+
199
+ senderTransportCongestionController.ReceiveTransportWideCcFeedback(feedback.get(), nowUs);
200
+
201
+ nowUs += 50000;
202
+
203
+ shared.GetTimer(ProcessTimerLabel)->EvaluateHasExpired();
204
+ }
205
+
206
+ return senderTransportCongestionController.GetAvailableBitrate();
207
+ };
208
+
209
+ SECTION("the target starts at the bitrate it was given")
210
+ {
211
+ runProcessTimer();
212
+
213
+ REQUIRE(listener.targetBitrates.size() == 1);
214
+ REQUIRE(listener.targetBitrates.at(0) == StartBitrate);
215
+
216
+ REQUIRE(senderTransportCongestionController.GetAvailableBitrate() == StartBitrate);
217
+ }
218
+
219
+ SECTION("nothing is told twice while nothing changes")
220
+ {
221
+ runProcessTimer();
222
+
223
+ REQUIRE(listener.targetBitrates.size() == 1);
224
+
225
+ runProcessTimer();
226
+ runProcessTimer();
227
+
228
+ REQUIRE(listener.targetBitrates.size() == 1);
229
+ }
230
+
231
+ SECTION("what the remote endpoint says it can take caps the target")
232
+ {
233
+ runProcessTimer();
234
+
235
+ senderTransportCongestionController.ReceiveEstimatedBitrate(StartBitrate / 2);
236
+
237
+ runProcessTimer();
238
+
239
+ REQUIRE(listener.targetBitrates.back() == StartBitrate / 2);
240
+
241
+ // And it follows it back up, since the cap is not a ratchet.
242
+ senderTransportCongestionController.ReceiveEstimatedBitrate(StartBitrate);
243
+
244
+ runProcessTimer();
245
+
246
+ REQUIRE(listener.targetBitrates.back() == StartBitrate);
247
+ }
248
+
249
+ SECTION("a REMB of zero is no cap at all")
250
+ {
251
+ runProcessTimer();
252
+
253
+ senderTransportCongestionController.ReceiveEstimatedBitrate(StartBitrate / 2);
254
+
255
+ runProcessTimer();
256
+
257
+ REQUIRE(listener.targetBitrates.back() == StartBitrate / 2);
258
+
259
+ senderTransportCongestionController.ReceiveEstimatedBitrate(0);
260
+
261
+ runProcessTimer();
262
+
263
+ REQUIRE(listener.targetBitrates.back() == StartBitrate);
264
+ }
265
+
266
+ SECTION("the loss the Receiver Reports measure brings the target down")
267
+ {
268
+ runProcessTimer();
269
+
270
+ const int64_t targetBeforeLoss = listener.targetBitrates.back();
271
+
272
+ // Well above the tenth of the packets where the loss rules start cutting.
273
+ for (size_t idx{ 0 }; idx < 10; ++idx)
274
+ {
275
+ senderTransportCongestionController.ReceiveRtcpReceiverReport(30, 100);
276
+
277
+ runProcessTimer();
278
+ }
279
+
280
+ REQUIRE(listener.targetBitrates.back() < targetBeforeLoss);
281
+ }
282
+
283
+ SECTION("a stretch where nothing got through at all is not a measurement")
284
+ {
285
+ runProcessTimer();
286
+
287
+ REQUIRE(listener.targetBitrates.size() == 1);
288
+
289
+ // Not a single packet arriving is a stretch the remote endpoint could not
290
+ // report on rather than a loss of everything, so it is left out instead of
291
+ // being fed as the worst measurement there is.
292
+ for (size_t idx{ 0 }; idx < 10; ++idx)
293
+ {
294
+ senderTransportCongestionController.ReceiveRtcpReceiverReport(100, 100);
295
+
296
+ runProcessTimer();
297
+ }
298
+
299
+ REQUIRE(listener.targetBitrates.size() == 1);
300
+ }
301
+
302
+ SECTION("changing the bounds does not send the target back to where it started")
303
+ {
304
+ runProcessTimer();
305
+
306
+ // Something the remote endpoint says brings the target down, which is what a
307
+ // reconfiguration must not undo.
308
+ senderTransportCongestionController.ReceiveEstimatedBitrate(StartBitrate / 2);
309
+
310
+ runProcessTimer();
311
+
312
+ REQUIRE(senderTransportCongestionController.GetAvailableBitrate() == StartBitrate / 2);
313
+
314
+ senderTransportCongestionController.SetBitrateLimits(MinBitrate, MaxBitrate / 2);
315
+
316
+ REQUIRE(senderTransportCongestionController.GetAvailableBitrate() == StartBitrate / 2);
317
+ }
318
+
319
+ SECTION("the bounds are brought into a range the loop can work with")
320
+ {
321
+ // A maximum below the minimum is not a range, and a minimum below what the
322
+ // module works with cannot be honoured either.
323
+ senderTransportCongestionController.SetBitrateLimits(/*minBitrate*/ 1, /*maxBitrate*/ 1);
324
+
325
+ REQUIRE(senderTransportCongestionController.GetAvailableBitrate() >= RTC::Consts::BweMinBitrate);
326
+ }
327
+
328
+ SECTION("a packet about to be sent gets both extensions written")
329
+ {
330
+ const auto packet = buildPacket();
331
+
332
+ const auto sequenceNumber = senderTransportCongestionController.OnRtpPacketToBeSent(
333
+ packet.get(), RTC::BWE::SenderTransportCongestionController::RtpPacketToBeSentOptions{});
334
+
335
+ REQUIRE(sequenceNumber.has_value());
336
+
337
+ uint16_t wideSeqNumber{ 0 };
338
+
339
+ REQUIRE(packet->ReadTransportWideCc01(wideSeqNumber));
340
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
341
+ REQUIRE(wideSeqNumber == static_cast<uint16_t>(sequenceNumber.value()));
342
+
343
+ uint32_t absSendTime{ 0 };
344
+
345
+ REQUIRE(packet->ReadAbsSendTime(absSendTime));
346
+ REQUIRE(absSendTime == Utils::Time::TimeUsToAbsSendTime(nowUs));
347
+ }
348
+
349
+ SECTION("the sequence numbers handed out follow one another")
350
+ {
351
+ const auto firstPacket = buildPacket();
352
+
353
+ const auto firstSequenceNumber = senderTransportCongestionController.OnRtpPacketToBeSent(
354
+ firstPacket.get(), RTC::BWE::SenderTransportCongestionController::RtpPacketToBeSentOptions{});
355
+
356
+ const auto secondPacket = buildPacket();
357
+
358
+ const auto secondSequenceNumber = senderTransportCongestionController.OnRtpPacketToBeSent(
359
+ secondPacket.get(), RTC::BWE::SenderTransportCongestionController::RtpPacketToBeSentOptions{});
360
+
361
+ REQUIRE(firstSequenceNumber.has_value());
362
+ REQUIRE(secondSequenceNumber.has_value());
363
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
364
+ REQUIRE(secondSequenceNumber.value() == firstSequenceNumber.value() + 1);
365
+ }
366
+
367
+ SECTION("a packet with no room for the sequence number is not taken note of")
368
+ {
369
+ const auto firstVideoPacket = buildPacket();
370
+
371
+ const auto firstVideoSequenceNumber = senderTransportCongestionController.OnRtpPacketToBeSent(
372
+ firstVideoPacket.get(),
373
+ RTC::BWE::SenderTransportCongestionController::RtpPacketToBeSentOptions{});
374
+
375
+ // Which is what every audio packet looks like, since the extension is only
376
+ // written into video ones.
377
+ std::unique_ptr<RTC::RTP::Packet> audioPacket(
378
+ RTC::RTP::Packet::Factory(rtpCommon::FactoryBuffer, sizeof(rtpCommon::FactoryBuffer)));
379
+
380
+ REQUIRE(audioPacket);
381
+
382
+ audioPacket->SetSsrc(Ssrc);
383
+
384
+ RTC::RTP::HeaderExtensionIds headerExtensionIds;
385
+
386
+ headerExtensionIds.transportWideCc01 = TransportWideCc01Id;
387
+ headerExtensionIds.absSendTime = AbsSendTimeId;
388
+
389
+ audioPacket->AssignExtensionIds(headerExtensionIds);
390
+ audioPacket->SetPayloadLength(PayloadSize);
391
+
392
+ const auto audioSequenceNumber = senderTransportCongestionController.OnRtpPacketToBeSent(
393
+ audioPacket.get(), RTC::BWE::SenderTransportCongestionController::RtpPacketToBeSentOptions{});
394
+
395
+ REQUIRE(audioSequenceNumber.has_value() == false);
396
+
397
+ // And no sequence number was spent on it either, which would leave a hole in
398
+ // the sequence space that the remote endpoint would report as a lost packet
399
+ // that never existed.
400
+ const auto secondVideoPacket = buildPacket();
401
+
402
+ const auto secondVideoSequenceNumber = senderTransportCongestionController.OnRtpPacketToBeSent(
403
+ secondVideoPacket.get(),
404
+ RTC::BWE::SenderTransportCongestionController::RtpPacketToBeSentOptions{});
405
+
406
+ REQUIRE(firstVideoSequenceNumber.has_value());
407
+ REQUIRE(secondVideoSequenceNumber.has_value());
408
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
409
+ REQUIRE(secondVideoSequenceNumber.value() == firstVideoSequenceNumber.value() + 1);
410
+ }
411
+
412
+ SECTION("a growing delay brings the target below what a clean link leaves it at")
413
+ {
414
+ constexpr int64_t RunTimeMs{ 6000 };
415
+
416
+ senderTransportCongestionController.SetNetworkAvailable(true);
417
+
418
+ // Long enough for the delay based path to have something to say, over a link
419
+ // that delays nothing and therefore builds no queue.
420
+ const int64_t targetBeforeDelay = transmitAndFeedBack(RunTimeMs, /*delayPerPacketUs*/ 0);
421
+
422
+ // A link that never delays anything gives the estimator no reason to back
423
+ // off, so whatever it was given to start from still stands.
424
+ REQUIRE(targetBeforeDelay >= StartBitrate);
425
+
426
+ // And again, with every packet arriving later than the one before it.
427
+ const int64_t targetAfterDelay = transmitAndFeedBack(RunTimeMs, /*delayPerPacketUs*/ 50000);
428
+
429
+ REQUIRE(targetAfterDelay < targetBeforeDelay);
430
+ }
431
+
432
+ SECTION("a feedback about packets that were never sent does nothing")
433
+ {
434
+ senderTransportCongestionController.SetNetworkAvailable(true);
435
+
436
+ runProcessTimer();
437
+
438
+ const int64_t targetBefore = senderTransportCongestionController.GetAvailableBitrate();
439
+
440
+ const auto feedback = createFeedback(
441
+ 1000,
442
+ RemoteTimeUs,
443
+ {
444
+ { 1000, RemoteTimeUs },
445
+ { 1001, RemoteTimeUs + 10000 }
446
+ });
447
+
448
+ senderTransportCongestionController.ReceiveTransportWideCcFeedback(feedback.get(), nowUs);
449
+
450
+ REQUIRE(senderTransportCongestionController.GetAvailableBitrate() == targetBefore);
451
+ }
452
+
453
+ SECTION("a confirmation for a packet that was never taken note of does nothing")
454
+ {
455
+ senderTransportCongestionController.OnRtpPacketSent(
456
+ /*sequenceNumber*/ 12345, PayloadSize, nowUs);
457
+
458
+ runProcessTimer();
459
+
460
+ REQUIRE(listener.targetBitrates.size() == 1);
461
+ REQUIRE(listener.targetBitrates.at(0) == StartBitrate);
462
+ }
463
+
464
+ SECTION("nothing is probed until there is a network to probe")
465
+ {
466
+ auto* timer = shared.GetTimer("probing-scheduler-next-probe");
467
+
468
+ REQUIRE(timer);
469
+ REQUIRE(timer->IsActive() == false);
470
+
471
+ senderTransportCongestionController.SetNetworkAvailable(true);
472
+
473
+ REQUIRE(timer->IsActive());
474
+ }
475
+
476
+ SECTION("every packet of a burst goes out numbered and with both extensions written")
477
+ {
478
+ senderTransportCongestionController.SetNetworkAvailable(true);
479
+
480
+ auto* timer = shared.GetTimer("probing-scheduler-next-probe");
481
+
482
+ REQUIRE(timer);
483
+
484
+ // Let the whole burst out, shot by shot.
485
+ while (timer->IsActive())
486
+ {
487
+ nowUs = std::max(nowUs, timer->GetExpiresAtMs() * 1000);
488
+
489
+ REQUIRE(timer->EvaluateHasExpired());
490
+ }
491
+
492
+ REQUIRE(!listener.sentLengths.empty());
493
+ REQUIRE(listener.sentSequenceNumbers.size() == listener.sentLengths.size());
494
+ REQUIRE(listener.sentWithExtensions.size() == listener.sentLengths.size());
495
+
496
+ for (size_t idx{ 0 }; idx < listener.sentSequenceNumbers.size(); ++idx)
497
+ {
498
+ // Each packet carries the very number it was handed over with, and the
499
+ // room for the arrival time the remote endpoint fills in.
500
+ REQUIRE(listener.sentWithExtensions.at(idx));
501
+
502
+ // And they are handed out one after another, so that the feedback can
503
+ // name every one of them.
504
+ if (idx > 0)
505
+ {
506
+ REQUIRE(listener.sentSequenceNumbers.at(idx) == listener.sentSequenceNumbers.at(idx - 1) + 1);
507
+ }
508
+ }
509
+ }
510
+ }
@@ -33,7 +33,7 @@ SCENARIO("BWE TransportWideCcFeedbackGenerator", "[bwe][transportwideccfeedbackg
33
33
  : public RTC::BWE::TransportWideCcFeedbackGenerator::Listener
34
34
  {
35
35
  public:
36
- void OnTransportWideCcFeedbackGeneratorSendRtcpPacket(
36
+ void OnTransportWideCcFeedbackGeneratorSendPacket(
37
37
  RTC::BWE::TransportWideCcFeedbackGenerator* /*transportWideCcFeedbackGenerator*/,
38
38
  RTC::RTCP::FeedbackRtpTransportPacket* packet) override
39
39
  {
@@ -84,7 +84,8 @@ SCENARIO("BWE TransportWideCcFeedbackGenerator", "[bwe][transportwideccfeedbackg
84
84
  //
85
85
  // NOTE: Every scenario reuses `rtpCommon::FactoryBuffer`, so the returned
86
86
  // packet is only valid until the next call.
87
- auto buildPacket = [](size_t payloadSize, uint16_t wideSeqNumber) -> std::unique_ptr<RTC::RTP::Packet>
87
+ const auto buildPacket =
88
+ [](size_t payloadSize, uint16_t wideSeqNumber) -> std::unique_ptr<RTC::RTP::Packet>
88
89
  {
89
90
  std::unique_ptr<RTC::RTP::Packet> packet(
90
91
  RTC::RTP::Packet::Factory(rtpCommon::FactoryBuffer, sizeof(rtpCommon::FactoryBuffer)));
@@ -106,7 +107,6 @@ SCENARIO("BWE TransportWideCcFeedbackGenerator", "[bwe][transportwideccfeedbackg
106
107
  headerExtensionIds.transportWideCc01 = TransportWideCc01Id;
107
108
 
108
109
  packet->AssignExtensionIds(headerExtensionIds);
109
-
110
110
  packet->SetPayloadLength(payloadSize);
111
111
 
112
112
  REQUIRE(packet->UpdateTransportWideCc01(wideSeqNumber));
@@ -116,24 +116,25 @@ SCENARIO("BWE TransportWideCcFeedbackGenerator", "[bwe][transportwideccfeedbackg
116
116
 
117
117
  // Feeds a packet that arrived at the given instant, which is also taken as
118
118
  // the current one since the meter of incoming data reads the clock itself.
119
- auto feedPacket = [&buildPacket, &nowUs](
120
- RTC::BWE::TransportWideCcFeedbackGenerator& transportWideCcFeedbackGenerator,
121
- uint16_t wideSeqNumber,
122
- int64_t arrivalTimeUs,
123
- size_t payloadSize) -> void
119
+ const auto feedPacket =
120
+ [&buildPacket, &nowUs](
121
+ RTC::BWE::TransportWideCcFeedbackGenerator& transportWideCcFeedbackGenerator,
122
+ uint16_t wideSeqNumber,
123
+ int64_t arrivalTimeUs,
124
+ size_t payloadSize) -> void
124
125
  {
125
126
  nowUs = arrivalTimeUs;
126
127
 
127
128
  const auto packet = buildPacket(payloadSize, wideSeqNumber);
128
129
 
129
- transportWideCcFeedbackGenerator.IncomingPacket(arrivalTimeUs, packet.get());
130
+ transportWideCcFeedbackGenerator.ReceiveRtpPacket(arrivalTimeUs, packet.get());
130
131
  };
131
132
 
132
133
  // Checks that the feedback packets the listener got are the expected ones,
133
134
  // status by status.
134
- auto checkFeedbacks = [](
135
- const TestTransportWideCcFeedbackGeneratorListener& listener,
136
- const TestResults& expectedResults) -> void
135
+ const auto checkFeedbacks = [](
136
+ const TestTransportWideCcFeedbackGeneratorListener& listener,
137
+ const TestResults& expectedResults) -> void
137
138
  {
138
139
  REQUIRE(listener.feedbacks.size() == expectedResults.size());
139
140
 
@@ -162,8 +163,9 @@ SCENARIO("BWE TransportWideCcFeedbackGenerator", "[bwe][transportwideccfeedbackg
162
163
 
163
164
  // Feeds the given packets, emitting a feedback every time 100 ms have gone by
164
165
  // since the previous one, and checks what came out.
165
- auto validate = [&shared, &feedPacket, &checkFeedbacks](
166
- const std::vector<TestInput>& inputs, const TestResults& expectedResults) -> void
166
+ const auto validate = [&shared, &feedPacket, &checkFeedbacks](
167
+ const std::vector<TestInput>& inputs,
168
+ const TestResults& expectedResults) -> void
167
169
  {
168
170
  TestTransportWideCcFeedbackGeneratorListener listener;
169
171
  RTC::BWE::TransportWideCcFeedbackGenerator transportWideCcFeedbackGenerator(
@@ -16,12 +16,12 @@ SCENARIO("BWE TrendlineEstimator", "[bwe][trendlineestimator]")
16
16
  // Both `count` and `arrivalTimeUs` are shared by every run within a test, so
17
17
  // that consecutive runs consume a single budget of packets and carry on from
18
18
  // the network conditions left by the previous one.
19
- auto runUntilStateChange = [](
20
- RTC::BWE::TrendlineEstimator& trendlineEstimator,
21
- double deliveryPace,
22
- size_t& count,
23
- size_t packetCount,
24
- int64_t& arrivalTimeUs) -> void
19
+ const auto runUntilStateChange = [](
20
+ RTC::BWE::TrendlineEstimator& trendlineEstimator,
21
+ double deliveryPace,
22
+ size_t& count,
23
+ size_t packetCount,
24
+ int64_t& arrivalTimeUs) -> void
25
25
  {
26
26
  const auto initialState = trendlineEstimator.GetState();
27
27
  const auto arrivalDeltaUs = static_cast<int64_t>(SendDeltaUs * deliveryPace);
@@ -91,14 +91,13 @@ namespace bweHelpers
91
91
  headerExtensionIds.absSendTime = AbsSendTimeId;
92
92
 
93
93
  packet->AssignExtensionIds(headerExtensionIds);
94
-
95
94
  packet->SetPayloadLength(payloadSize);
96
95
 
97
96
  REQUIRE(packet->UpdateAbsSendTime(absSendTime));
98
97
 
99
98
  const int64_t arrivalTimeUs = (arrivalTimeMs + this->arrivalTimeOffsetMs) * 1000;
100
99
 
101
- this->remoteBitrateEstimator.IncomingPacket(packet.get(), arrivalTimeUs, this->nowUs);
100
+ this->remoteBitrateEstimator.ReceiveRtpPacket(packet.get(), arrivalTimeUs, this->nowUs);
102
101
  }
103
102
 
104
103
  bool RemoteBitrateEstimatorAbsSendTimeTestHelper::GenerateAndProcessFrame(
@@ -28,7 +28,7 @@ SCENARIO("RTCP BYE", "[rtcp][bye]")
28
28
  // NOTE: No need to pass const integers to the lambda.
29
29
  // NOTE: If we pass const integers then clang-tidy complains with
30
30
  // 'clang-diagnostic-unused-lambda-capture'.
31
- auto verify = [&reason](RTC::RTCP::ByePacket* packet)
31
+ const auto verify = [&reason](RTC::RTCP::ByePacket* packet)
32
32
  {
33
33
  REQUIRE(packet->GetReason() == reason);
34
34
 
@@ -21,7 +21,7 @@ SCENARIO("RTCP Feedback PS AFB", "[rtcp][feedback-ps][afb]")
21
21
  const uint32_t senderSsrc{ 0xfa17fa17 };
22
22
  const uint32_t mediaSsrc{ 0 };
23
23
 
24
- auto verify = [](RTC::RTCP::FeedbackPsAfbPacket* packet)
24
+ const auto verify = [](RTC::RTCP::FeedbackPsAfbPacket* packet)
25
25
  {
26
26
  REQUIRE(packet->GetSenderSsrc() == senderSsrc);
27
27
  REQUIRE(packet->GetMediaSsrc() == mediaSsrc);