mediasoup 3.27.0 → 3.28.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 (213) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/node/lib/Consumer.d.ts.map +1 -1
  3. package/node/lib/Consumer.js +4 -51
  4. package/node/lib/Producer.d.ts.map +1 -1
  5. package/node/lib/Producer.js +4 -8
  6. package/node/lib/ProducerTypes.d.ts +4 -2
  7. package/node/lib/ProducerTypes.d.ts.map +1 -1
  8. package/node/lib/Router.d.ts.map +1 -1
  9. package/node/lib/Router.js +4 -0
  10. package/node/lib/Transport.d.ts.map +1 -1
  11. package/node/lib/Transport.js +7 -10
  12. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts +3 -4
  13. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts.map +1 -1
  14. package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.js +3 -4
  15. package/node/lib/ortc.d.ts +0 -2
  16. package/node/lib/ortc.d.ts.map +1 -1
  17. package/node/lib/ortc.js +11 -21
  18. package/node/lib/rtpMappingFbsUtils.d.ts +6 -0
  19. package/node/lib/rtpMappingFbsUtils.d.ts.map +1 -0
  20. package/node/lib/rtpMappingFbsUtils.js +65 -0
  21. package/node/lib/rtpParametersFbsUtils.d.ts.map +1 -1
  22. package/node/lib/rtpParametersFbsUtils.js +0 -6
  23. package/node/lib/rtpParametersTypes.d.ts +1 -1
  24. package/node/lib/rtpParametersTypes.d.ts.map +1 -1
  25. package/node/lib/rtpStreamFbsUtils.d.ts +4 -0
  26. package/node/lib/rtpStreamFbsUtils.d.ts.map +1 -0
  27. package/node/lib/rtpStreamFbsUtils.js +51 -0
  28. package/node/lib/supportedRtpCapabilities.d.ts.map +1 -1
  29. package/node/lib/supportedRtpCapabilities.js +6 -13
  30. package/node/lib/test/test-Consumer.js +1 -13
  31. package/node/lib/test/test-DataConsumer.js +9 -0
  32. package/node/lib/test/test-DataProducer.js +38 -0
  33. package/node/lib/test/test-PipeTransport.js +27 -29
  34. package/node/lib/test/test-Producer.js +97 -0
  35. package/node/lib/test/test-ortc.js +34 -14
  36. package/package.json +10 -10
  37. package/worker/fbs/FBS/meson.build +25 -0
  38. package/worker/fbs/meson.build +15 -18
  39. package/worker/fbs/rtpParameters.fbs +0 -1
  40. package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
  41. package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
  42. package/worker/include/DepLibUV.hpp +13 -0
  43. package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
  44. package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
  45. package/worker/include/RTC/BWE/BitrateUtils.hpp +39 -0
  46. package/worker/include/RTC/BWE/BweTypes.hpp +171 -3
  47. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
  48. package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
  49. package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
  50. package/worker/include/RTC/BWE/LossBasedController.hpp +625 -0
  51. package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
  52. package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
  53. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
  54. package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
  55. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
  56. package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
  57. package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
  58. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
  59. package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
  60. package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
  61. package/worker/include/RTC/BWE/TargetRateController.hpp +306 -0
  62. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
  63. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +73 -16
  64. package/worker/include/RTC/Consts.hpp +70 -0
  65. package/worker/include/RTC/DataConsumer.hpp +3 -5
  66. package/worker/include/RTC/DirectTransport.hpp +4 -5
  67. package/worker/include/RTC/PipeTransport.hpp +4 -5
  68. package/worker/include/RTC/PlainTransport.hpp +4 -5
  69. package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
  70. package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
  71. package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
  72. package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
  73. package/worker/include/RTC/RTP/Packet.hpp +16 -4
  74. package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
  75. package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
  76. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
  77. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
  78. package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
  79. package/worker/include/RTC/RateCalculator.hpp +103 -24
  80. package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
  81. package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
  82. package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
  83. package/worker/include/RTC/RtpDictionaries.hpp +3 -4
  84. package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
  85. package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +36 -0
  86. package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
  87. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +9 -9
  88. package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
  89. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +11 -1
  90. package/worker/include/RTC/SctpDictionaries.hpp +2 -2
  91. package/worker/include/RTC/TcpConnection.hpp +2 -1
  92. package/worker/include/RTC/Transport.hpp +23 -8
  93. package/worker/include/RTC/TransportTuple.hpp +61 -6
  94. package/worker/include/RTC/WebRtcTransport.hpp +4 -5
  95. package/worker/include/Shared.hpp +5 -0
  96. package/worker/include/SharedInterface.hpp +10 -0
  97. package/worker/include/Utils.hpp +72 -3
  98. package/worker/include/common.hpp +12 -4
  99. package/worker/include/handles/SendCallbacks.hpp +34 -0
  100. package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
  101. package/worker/include/handles/UdpSocketHandle.hpp +4 -8
  102. package/worker/meson.build +45 -1
  103. package/worker/meson_options.txt +1 -0
  104. package/worker/mocks/include/MockShared.hpp +16 -2
  105. package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
  106. package/worker/scripts/package-lock.json +6 -6
  107. package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
  108. package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
  109. package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
  110. package/worker/src/RTC/BWE/BitrateUtils.cpp +54 -0
  111. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
  112. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
  113. package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
  114. package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
  115. package/worker/src/RTC/BWE/LossBasedController.cpp +1194 -0
  116. package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
  117. package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
  118. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
  119. package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
  120. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
  121. package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
  122. package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
  123. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
  124. package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
  125. package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
  126. package/worker/src/RTC/BWE/TargetRateController.cpp +433 -0
  127. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
  128. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +102 -5
  129. package/worker/src/RTC/Consumer.cpp +7 -5
  130. package/worker/src/RTC/DataConsumer.cpp +8 -10
  131. package/worker/src/RTC/DirectTransport.cpp +14 -8
  132. package/worker/src/RTC/DtlsTransport.cpp +8 -8
  133. package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
  134. package/worker/src/RTC/ICE/IceServer.cpp +1 -1
  135. package/worker/src/RTC/PipeTransport.cpp +13 -8
  136. package/worker/src/RTC/PlainTransport.cpp +13 -8
  137. package/worker/src/RTC/Producer.cpp +14 -31
  138. package/worker/src/RTC/RTCP/Bye.cpp +1 -1
  139. package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
  140. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
  141. package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
  142. package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
  143. package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
  144. package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
  145. package/worker/src/RTC/RTP/Packet.cpp +26 -11
  146. package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
  147. package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
  148. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
  149. package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
  150. package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
  151. package/worker/src/RTC/RateCalculator.cpp +133 -28
  152. package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
  153. package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
  154. package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
  155. package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
  156. package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
  157. package/worker/src/RTC/SCTP/association/Association.cpp +16 -2
  158. package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +106 -1
  159. package/worker/src/RTC/SCTP/public/AssociationMetrics.cpp +1 -1
  160. package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
  161. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  162. package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
  163. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
  164. package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
  165. package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
  166. package/worker/src/RTC/SrtpSession.cpp +2 -2
  167. package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
  168. package/worker/src/RTC/TcpConnection.cpp +2 -2
  169. package/worker/src/RTC/Transport.cpp +112 -75
  170. package/worker/src/RTC/TransportTuple.cpp +4 -4
  171. package/worker/src/RTC/WebRtcServer.cpp +4 -3
  172. package/worker/src/RTC/WebRtcTransport.cpp +20 -13
  173. package/worker/src/Utils/BitStream.cpp +24 -0
  174. package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
  175. package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
  176. package/worker/src/handles/UdpSocketHandle.cpp +14 -21
  177. package/worker/tasks.py +43 -18
  178. package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
  179. package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
  180. package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
  181. package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
  182. package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
  183. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
  184. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
  185. package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
  186. package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
  187. package/worker/test/src/RTC/BWE/TestLossBasedController.cpp +1199 -0
  188. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
  189. package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
  190. package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
  191. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
  192. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
  193. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
  194. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
  195. package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
  196. package/worker/test/src/RTC/BWE/TestTargetRateController.cpp +337 -0
  197. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
  198. package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +45 -0
  199. package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
  200. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
  201. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
  202. package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
  203. package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
  204. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
  205. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
  206. package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +111 -0
  207. package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
  208. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
  209. package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
  210. package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
  211. package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
  212. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
  213. package/worker/test/src/Utils/TestTime.cpp +120 -21
@@ -0,0 +1,140 @@
1
+ #define MS_CLASS "RTC::BWE::ProbePacketGenerator"
2
+ // #define MS_LOG_DEV_LEVEL 3
3
+
4
+ #include "RTC/BWE/ProbePacketGenerator.hpp"
5
+ #include "Logger.hpp"
6
+ #include "RTC/Consts.hpp"
7
+ #include "RTC/RtpDictionaries.hpp"
8
+ #include "Utils.hpp"
9
+ #include <cstring> // std::memcpy()
10
+ #include <vector>
11
+
12
+ namespace RTC
13
+ {
14
+ namespace BWE
15
+ {
16
+ /* Static. */
17
+
18
+ static constexpr size_t ExtensionsBufferLength{ 200 };
19
+ alignas(4) static thread_local uint8_t ExtensionsBuffer[ExtensionsBufferLength];
20
+ // How much the RTP timestamp moves from one packet to the next.
21
+ // NOTE: It stands for no lapse of media, since there is none to play out.
22
+ // It just has to move so that the packets don't all claim to belong to the
23
+ // same instant.
24
+ static constexpr uint32_t TimestampStep{ 20 };
25
+
26
+ /* Instance methods. */
27
+
28
+ ProbePacketGenerator::ProbePacketGenerator(Listener* listener) : listener(listener)
29
+ {
30
+ MS_TRACE();
31
+
32
+ this->packet.reset(
33
+ RTC::RTP::Packet::Factory(this->packetBuffer.data(), this->packetBuffer.size()));
34
+
35
+ this->packet->SetPayloadType(RTC::Consts::BweProbeRtpPayloadType);
36
+ this->packet->SetSsrc(RTC::Consts::BweProbeRtpSsrc);
37
+ this->packet->SetSequenceNumber(Utils::Crypto::GetRandomUInt<uint16_t>(0, 65535));
38
+ this->packet->SetTimestamp(Utils::Crypto::GetRandomUInt<uint32_t>(0, 4294967295));
39
+
40
+ // The extensions that make the packets reportable, so that the receiver
41
+ // tells when each of them arrived.
42
+ std::vector<RTC::RTP::Packet::Extension> extensions;
43
+ uint8_t extenLen;
44
+ uint8_t* bufferPtr{ ExtensionsBuffer };
45
+
46
+ // urn:ietf:params:rtp-hdrext:sdes:mid.
47
+ {
48
+ extenLen = RTC::Consts::BweProbeRtpMid.size();
49
+
50
+ extensions.emplace_back(
51
+ /*type*/ RTC::RtpHeaderExtensionUri::Type::MID,
52
+ /*id*/ static_cast<uint8_t>(RTC::RtpHeaderExtensionUri::Type::MID),
53
+ /*len*/ extenLen,
54
+ /*value*/ bufferPtr);
55
+
56
+ std::memcpy(bufferPtr, RTC::Consts::BweProbeRtpMid.data(), extenLen);
57
+
58
+ bufferPtr += extenLen;
59
+ }
60
+
61
+ // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time.
62
+ //
63
+ // NOTE: Just the id and the room for its value, which whoever sends the
64
+ // packet fills in.
65
+ {
66
+ extenLen = 3;
67
+
68
+ extensions.emplace_back(
69
+ /*type*/ RTC::RtpHeaderExtensionUri::Type::ABS_SEND_TIME,
70
+ /*id*/ static_cast<uint8_t>(RTC::RtpHeaderExtensionUri::Type::ABS_SEND_TIME),
71
+ /*len*/ extenLen,
72
+ /*value*/ bufferPtr);
73
+
74
+ bufferPtr += extenLen;
75
+ }
76
+
77
+ // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01.
78
+ //
79
+ // NOTE: The same, and it's the one the arrival times come back in.
80
+ {
81
+ extenLen = 2;
82
+
83
+ extensions.emplace_back(
84
+ /*type*/ RTC::RtpHeaderExtensionUri::Type::TRANSPORT_WIDE_CC_01,
85
+ /*id*/ static_cast<uint8_t>(RTC::RtpHeaderExtensionUri::Type::TRANSPORT_WIDE_CC_01),
86
+ /*len*/ extenLen,
87
+ /*value*/ bufferPtr);
88
+ }
89
+
90
+ this->packet->SetExtensions(RTC::RTP::Packet::ExtensionsType::OneByte, extensions);
91
+
92
+ this->minPacketLength = this->packet->GetLength();
93
+ }
94
+
95
+ void ProbePacketGenerator::GeneratePackets(size_t size)
96
+ {
97
+ MS_TRACE();
98
+
99
+ if (size > ProbePacketGenerator::MaxGeneratePacketsSize)
100
+ {
101
+ MS_WARN_TAG(
102
+ bwe,
103
+ "burst of more bytes than any real one could be, sending fewer [asked:%zu, sending:%zu]",
104
+ size,
105
+ ProbePacketGenerator::MaxGeneratePacketsSize);
106
+
107
+ size = ProbePacketGenerator::MaxGeneratePacketsSize;
108
+ }
109
+
110
+ size_t remaining{ size };
111
+
112
+ while (remaining > 0)
113
+ {
114
+ // A packet cannot be shorter than its own header, so the last one of a
115
+ // burst overshoots rather than falling short.
116
+ size_t length = std::clamp(
117
+ Utils::Byte::PadTo4Bytes(remaining),
118
+ this->minPacketLength,
119
+ ProbePacketGenerator::MaxPacketLength);
120
+
121
+ this->packet->SetSequenceNumber(this->packet->GetSequenceNumber() + 1);
122
+ this->packet->SetTimestamp(this->packet->GetTimestamp() + TimestampStep);
123
+ this->packet->SetPayloadLength(length - this->minPacketLength);
124
+
125
+ // NOTE: The length is read back rather than assumed, since padding the
126
+ // payload to 4 bytes may have made the packet longer than asked for.
127
+ length = this->packet->GetLength();
128
+
129
+ remaining -= std::min(remaining, length);
130
+
131
+ if (!this->listener->OnProbePacketGeneratorSendRtpPacket(this, this->packet.get()))
132
+ {
133
+ MS_DEBUG_DEV("burst given up on, %zu bytes were left", remaining);
134
+
135
+ break;
136
+ }
137
+ }
138
+ }
139
+ } // namespace BWE
140
+ } // namespace RTC
@@ -0,0 +1,196 @@
1
+ #define MS_CLASS "RTC::BWE::ProbingScheduler"
2
+ // #define MS_LOG_DEV_LEVEL 3
3
+
4
+ #include "RTC/BWE/ProbingScheduler.hpp"
5
+ #include "Logger.hpp"
6
+
7
+ namespace RTC
8
+ {
9
+ namespace BWE
10
+ {
11
+ /* Static. */
12
+
13
+ // How long before it is due a shot may go out. The instants of a burst are
14
+ // microseconds apart while the timer only counts milliseconds, so without
15
+ // this every shot would leave slightly late and the whole burst would
16
+ // measure a bitrate below the one it was asked for.
17
+ static constexpr int64_t MaxEarlyProbeProcessingUs{ 1000 };
18
+
19
+ /* Instance methods. */
20
+
21
+ ProbingScheduler::ScopedShot::ScopedShot(
22
+ ProbingScheduler& probingScheduler, const Types::ProbeCluster& probeCluster)
23
+ : probingScheduler(probingScheduler)
24
+ {
25
+ MS_TRACE();
26
+
27
+ this->probingScheduler.shotProbeCluster = probeCluster;
28
+ this->probingScheduler.shotSentBytes = 0;
29
+ }
30
+
31
+ ProbingScheduler::ScopedShot::~ScopedShot()
32
+ {
33
+ MS_TRACE();
34
+
35
+ this->probingScheduler.shotProbeCluster = {};
36
+ this->probingScheduler.shotSentBytes = 0;
37
+ }
38
+
39
+ ProbingScheduler::ProbingScheduler(Listener* listener, SharedInterface* shared)
40
+ : listener(listener),
41
+ shared(shared),
42
+ // A burst is made of packets this fabricates, so there is no traffic of
43
+ // somebody else's to wait for before one may begin.
44
+ bitrateProber(BitrateProber::BitrateProberOptions{ .allowStartProbingImmediately = true }),
45
+ probePacketGenerator(this),
46
+ nextProbeTimer(shared->CreateTimer(this, "probing-scheduler-next-probe"))
47
+ {
48
+ MS_TRACE();
49
+ }
50
+
51
+ void ProbingScheduler::CreateProbeClusters(const std::vector<Types::ProbeClusterConfig>& clusterConfigs)
52
+ {
53
+ MS_TRACE();
54
+
55
+ for (const auto& clusterConfig : clusterConfigs)
56
+ {
57
+ this->bitrateProber.CreateProbeCluster(clusterConfig);
58
+ }
59
+
60
+ // They are scheduled as soon as they are asked for, but not in the stack
61
+ // of whoever asked: the next turn of the loop picks them up. Emitting from
62
+ // here would put the send path inside a call that may itself come from the
63
+ // send path.
64
+ this->nextProbeTimer->Restart(0);
65
+ }
66
+
67
+ bool ProbingScheduler::OnProbePacketGeneratorSendRtpPacket(
68
+ ProbePacketGenerator* /*probePacketGenerator*/, RTC::RTP::Packet* packet)
69
+ {
70
+ MS_TRACE();
71
+
72
+ if (!this->listener->OnProbingSchedulerSendRtpPacket(this, packet, this->shotProbeCluster))
73
+ {
74
+ return false;
75
+ }
76
+
77
+ // What the burst is measured against is what the link has to carry, which
78
+ // is more than what the packet itself is worth.
79
+ this->shotSentBytes += packet->GetLength() + this->packetOverhead;
80
+
81
+ return true;
82
+ }
83
+
84
+ void ProbingScheduler::OnTimer(TimerHandleInterface* timer)
85
+ {
86
+ MS_TRACE();
87
+
88
+ if (timer == this->nextProbeTimer.get())
89
+ {
90
+ Process();
91
+ }
92
+ }
93
+
94
+ void ProbingScheduler::Process()
95
+ {
96
+ MS_TRACE();
97
+
98
+ // Every shot that is already due goes out before giving the loop back,
99
+ // since one left for the next turn is a shot emitted late and a burst
100
+ // stretched below the bitrate it was asked for. It always ends: a shot
101
+ // that goes out pushes the next one forward by the time its bytes take
102
+ // at the burst's bitrate, which outruns the clock straight away.
103
+ while (true)
104
+ {
105
+ const int64_t nowUs = this->shared->GetTimeUs();
106
+
107
+ // NOTE: This may give up on a burst that is due too far in the past, so
108
+ // it's what decides whether there is anything to emit at all.
109
+ const auto currentCluster = this->bitrateProber.GetCurrentCluster(nowUs);
110
+
111
+ if (!currentCluster.has_value())
112
+ {
113
+ ScheduleNextProbe(std::nullopt, nowUs);
114
+
115
+ return;
116
+ }
117
+
118
+ const int64_t nextProbeTimeUs = this->bitrateProber.GetNextProbeTimeUs(nowUs).value_or(nowUs);
119
+
120
+ // A shot that is almost due goes out now rather than waiting for
121
+ // another tick of a timer that cannot count in microseconds.
122
+ if (nowUs + MaxEarlyProbeProcessingUs < nextProbeTimeUs)
123
+ {
124
+ ScheduleNextProbe(nextProbeTimeUs, nowUs);
125
+
126
+ return;
127
+ }
128
+
129
+ const ScopedShot shot(*this, currentCluster.value().probeCluster);
130
+
131
+ const size_t recommendedSize = this->bitrateProber.GetRecommendedMinProbeSize();
132
+
133
+ // A burst whose bitrate doesn't amount to a single byte over the time
134
+ // between two of its shots cannot be emitted at all.
135
+ if (recommendedSize == 0)
136
+ {
137
+ MS_DEBUG_DEV("the burst carries no bytes between shots, giving up on it");
138
+
139
+ ScheduleNextProbe(std::nullopt, nowUs);
140
+
141
+ return;
142
+ }
143
+
144
+ // The burst opens with the smallest packet there is. What measures it
145
+ // leaves out the size of the first packet to arrive, so a big one there
146
+ // throws away much of what the burst carried.
147
+ if (currentCluster.value().sentBytes == 0)
148
+ {
149
+ this->probePacketGenerator.GeneratePackets(this->probePacketGenerator.GetMinPacketLength());
150
+ }
151
+
152
+ if (this->shotSentBytes < recommendedSize)
153
+ {
154
+ this->probePacketGenerator.GeneratePackets(recommendedSize - this->shotSentBytes);
155
+ }
156
+
157
+ // Nothing went out, so there is nothing to report and no reason to
158
+ // believe that trying again would do any better. A burst asked for
159
+ // later starts everything over.
160
+ if (this->shotSentBytes == 0)
161
+ {
162
+ MS_DEBUG_DEV("no packet of the burst could be sent, giving up on it");
163
+
164
+ ScheduleNextProbe(std::nullopt, nowUs);
165
+
166
+ return;
167
+ }
168
+
169
+ // NOTE: Reported once for the whole shot rather than per packet, since
170
+ // this is also what counts the shots a burst is made of. The clock is
171
+ // read again because handing the packets over took time of its own, and
172
+ // this instant is what the rest of the burst is measured from.
173
+ this->bitrateProber.ProbeSent(this->shared->GetTimeUs(), this->shotSentBytes);
174
+ }
175
+ }
176
+
177
+ void ProbingScheduler::ScheduleNextProbe(std::optional<int64_t> nextProbeTimeUs, int64_t nowUs)
178
+ {
179
+ MS_TRACE();
180
+
181
+ if (!nextProbeTimeUs.has_value())
182
+ {
183
+ this->nextProbeTimer->Stop();
184
+
185
+ return;
186
+ }
187
+
188
+ // Truncated rather than rounded up, so that the tick lands just before
189
+ // the shot is due instead of just after. What is left of the wait by then
190
+ // is under a millisecond, which is what the margin above is for.
191
+ const auto timeoutMs = std::max<int64_t>(nextProbeTimeUs.value() - nowUs, 0) / 1000;
192
+
193
+ this->nextProbeTimer->Restart(timeoutMs);
194
+ }
195
+ } // namespace BWE
196
+ } // namespace RTC
@@ -0,0 +1,169 @@
1
+ #define MS_CLASS "RTC::BWE::RembGenerator"
2
+ // #define MS_LOG_DEV_LEVEL 3
3
+
4
+ #include "RTC/BWE/RembGenerator.hpp"
5
+ #include "Logger.hpp"
6
+
7
+ namespace RTC
8
+ {
9
+ namespace BWE
10
+ {
11
+ /* Static. */
12
+
13
+ // How often a REMB may be sent when the estimation only goes up or barely
14
+ // moves.
15
+ static constexpr int64_t RembSendIntervalMs{ 200 };
16
+ // How much lower than the latest one an estimation has to be for its REMB to
17
+ // go out without waiting, as a percentage.
18
+ static constexpr int64_t SendThresholdPercent{ 103 };
19
+ // How long the cap may go without being stated, either by a REMB of its own
20
+ // or by one carrying an estimation that already honours it.
21
+ static constexpr int64_t LimitationRembIntervalMs{ 1500 };
22
+ // How many REMBs are sent to announce that the cap is gone, since losing the
23
+ // only one would leave the remote sender limited forever.
24
+ static constexpr uint8_t UnlimitedRembNumPackets{ 4 };
25
+
26
+ /* Instance methods. */
27
+
28
+ RembGenerator::RembGenerator(Listener* listener) : listener(listener)
29
+ {
30
+ MS_TRACE();
31
+ }
32
+
33
+ void RembGenerator::OnReceiveBitrateChanged(
34
+ int64_t nowMs, const std::vector<uint32_t>& ssrcs, int64_t bitrate)
35
+ {
36
+ MS_TRACE();
37
+
38
+ if (
39
+ this->lastSentRembBitrate.has_value() && this->lastRembSentAtMs.has_value() &&
40
+ (bitrate * SendThresholdPercent) / 100 > this->lastSentRembBitrate.value() &&
41
+ nowMs - this->lastRembSentAtMs.value() < RembSendIntervalMs)
42
+ {
43
+ return;
44
+ }
45
+
46
+ this->lastRembSentAtMs = nowMs;
47
+ this->lastSentRembBitrate = bitrate;
48
+
49
+ if (this->maxIncomingBitrate.has_value())
50
+ {
51
+ bitrate = std::min(bitrate, this->maxIncomingBitrate.value());
52
+ }
53
+
54
+ SendRemb(bitrate, ssrcs);
55
+ }
56
+
57
+ void RembGenerator::SetMaxIncomingBitrate(int64_t nowMs, std::optional<int64_t> bitrate)
58
+ {
59
+ MS_TRACE();
60
+
61
+ // A cap of zero cannot be told apart from no cap at all, since that is what
62
+ // a REMB of zero means on the wire, and a negative one means nothing. Both
63
+ // leave the cap as it was rather than turning into its opposite.
64
+ if (bitrate.has_value() && bitrate.value() <= 0)
65
+ {
66
+ MS_WARN_TAG(
67
+ bwe, "ignoring invalid max incoming bitrate [bitrate:%" PRIi64 "]", bitrate.value());
68
+
69
+ return;
70
+ }
71
+
72
+ const bool wasLimited = this->maxIncomingBitrate.has_value();
73
+
74
+ this->maxIncomingBitrate = bitrate;
75
+
76
+ if (!this->maxIncomingBitrate.has_value())
77
+ {
78
+ if (wasLimited)
79
+ {
80
+ this->unlimitedRembCounter = UnlimitedRembNumPackets;
81
+
82
+ MaySendLimitationRembFeedback(nowMs);
83
+ }
84
+
85
+ return;
86
+ }
87
+
88
+ // The cap is back, so the REMBs that were still owed to announce that it
89
+ // was gone no longer say anything true.
90
+ this->unlimitedRembCounter = 0;
91
+
92
+ // Nothing to tell if a REMB went out recently carrying a bitrate that the
93
+ // new cap already allows.
94
+ // NOTE: The instant is taken down either way, since what is already on the
95
+ // wire honours the cap just as well, and otherwise the next incoming
96
+ // packet would announce it again right behind that REMB.
97
+ this->limitationRembSentAtMs = nowMs;
98
+
99
+ if (
100
+ this->lastRembSentAtMs.has_value() &&
101
+ nowMs - this->lastRembSentAtMs.value() < RembSendIntervalMs &&
102
+ this->lastSentRembBitrate.has_value() && this->lastSentRembBitrate.value() != 0 &&
103
+ this->lastSentRembBitrate.value() <= this->maxIncomingBitrate.value())
104
+ {
105
+ return;
106
+ }
107
+
108
+ SendRemb(this->maxIncomingBitrate.value(), {});
109
+ }
110
+
111
+ void RembGenerator::MaySendLimitationRembFeedback(int64_t nowMs)
112
+ {
113
+ MS_TRACE();
114
+
115
+ const bool announcingRemoval = this->unlimitedRembCounter > 0;
116
+
117
+ if (!announcingRemoval && !this->maxIncomingBitrate.has_value())
118
+ {
119
+ return;
120
+ }
121
+
122
+ // A REMB carrying the estimation is already no higher than the cap, so
123
+ // while those keep flowing the cap needs no announcement of its own.
124
+ if (!announcingRemoval && this->lastRembSentAtMs.has_value() && nowMs - this->lastRembSentAtMs.value() <= LimitationRembIntervalMs)
125
+ {
126
+ return;
127
+ }
128
+
129
+ const bool dueAgain = !this->limitationRembSentAtMs.has_value() ||
130
+ nowMs - this->limitationRembSentAtMs.value() > LimitationRembIntervalMs;
131
+
132
+ // The first of the REMBs announcing that the cap is gone goes out without
133
+ // waiting.
134
+ if (!dueAgain && this->unlimitedRembCounter != UnlimitedRembNumPackets)
135
+ {
136
+ return;
137
+ }
138
+
139
+ const int64_t bitrate = this->maxIncomingBitrate.value_or(0);
140
+
141
+ MS_DEBUG_DEV("sending limitation REMB [bitrate:%" PRIi64 "]", bitrate);
142
+
143
+ this->limitationRembSentAtMs = nowMs;
144
+
145
+ if (this->unlimitedRembCounter > 0)
146
+ {
147
+ this->unlimitedRembCounter--;
148
+ }
149
+
150
+ SendRemb(bitrate, {});
151
+ }
152
+
153
+ void RembGenerator::SendRemb(int64_t bitrate, const std::vector<uint32_t>& ssrcs)
154
+ {
155
+ MS_TRACE();
156
+
157
+ RTC::RTCP::FeedbackPsRembPacket packet(uint32_t{ 0 }, uint32_t{ 0 });
158
+
159
+ packet.SetBitrate(bitrate);
160
+
161
+ if (!ssrcs.empty())
162
+ {
163
+ packet.SetSsrcs(ssrcs);
164
+ }
165
+
166
+ this->listener->OnRembGeneratorSendRemb(this, std::addressof(packet));
167
+ }
168
+ } // namespace BWE
169
+ } // namespace RTC