mediasoup 3.27.1 → 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 (203) hide show
  1. package/CHANGELOG.md +14 -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/rtpParameters.fbs +0 -1
  38. package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
  39. package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
  40. package/worker/include/DepLibUV.hpp +13 -0
  41. package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
  42. package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
  43. package/worker/include/RTC/BWE/{Utils.hpp → BitrateUtils.hpp} +3 -3
  44. package/worker/include/RTC/BWE/BweTypes.hpp +170 -2
  45. package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
  46. package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
  47. package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
  48. package/worker/include/RTC/BWE/LossBasedController.hpp +105 -0
  49. package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
  50. package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
  51. package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
  52. package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
  53. package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
  54. package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
  55. package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
  56. package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
  57. package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
  58. package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
  59. package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
  60. package/worker/include/RTC/BWE/TrendlineEstimator.hpp +15 -0
  61. package/worker/include/RTC/Consts.hpp +70 -0
  62. package/worker/include/RTC/DataConsumer.hpp +3 -5
  63. package/worker/include/RTC/DirectTransport.hpp +4 -5
  64. package/worker/include/RTC/PipeTransport.hpp +4 -5
  65. package/worker/include/RTC/PlainTransport.hpp +4 -5
  66. package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
  67. package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
  68. package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
  69. package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
  70. package/worker/include/RTC/RTP/Packet.hpp +16 -4
  71. package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
  72. package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
  73. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
  74. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
  75. package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
  76. package/worker/include/RTC/RateCalculator.hpp +103 -24
  77. package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
  78. package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
  79. package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
  80. package/worker/include/RTC/RtpDictionaries.hpp +3 -4
  81. package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
  82. package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
  83. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +4 -4
  84. package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
  85. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +1 -1
  86. package/worker/include/RTC/SctpDictionaries.hpp +2 -2
  87. package/worker/include/RTC/TcpConnection.hpp +2 -1
  88. package/worker/include/RTC/Transport.hpp +23 -8
  89. package/worker/include/RTC/TransportTuple.hpp +61 -6
  90. package/worker/include/RTC/WebRtcTransport.hpp +4 -5
  91. package/worker/include/Shared.hpp +5 -0
  92. package/worker/include/SharedInterface.hpp +10 -0
  93. package/worker/include/Utils.hpp +72 -3
  94. package/worker/include/common.hpp +12 -4
  95. package/worker/include/handles/SendCallbacks.hpp +34 -0
  96. package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
  97. package/worker/include/handles/UdpSocketHandle.hpp +4 -8
  98. package/worker/meson.build +41 -3
  99. package/worker/meson_options.txt +1 -0
  100. package/worker/mocks/include/MockShared.hpp +16 -2
  101. package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
  102. package/worker/scripts/package-lock.json +6 -6
  103. package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
  104. package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
  105. package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
  106. package/worker/src/RTC/BWE/{Utils.cpp → BitrateUtils.cpp} +4 -4
  107. package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
  108. package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
  109. package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
  110. package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
  111. package/worker/src/RTC/BWE/LossBasedController.cpp +189 -41
  112. package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
  113. package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
  114. package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
  115. package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
  116. package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
  117. package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
  118. package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
  119. package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
  120. package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
  121. package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
  122. package/worker/src/RTC/BWE/TargetRateController.cpp +12 -14
  123. package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
  124. package/worker/src/RTC/BWE/TrendlineEstimator.cpp +19 -0
  125. package/worker/src/RTC/Consumer.cpp +7 -5
  126. package/worker/src/RTC/DataConsumer.cpp +8 -10
  127. package/worker/src/RTC/DirectTransport.cpp +14 -8
  128. package/worker/src/RTC/DtlsTransport.cpp +8 -8
  129. package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
  130. package/worker/src/RTC/ICE/IceServer.cpp +1 -1
  131. package/worker/src/RTC/PipeTransport.cpp +13 -8
  132. package/worker/src/RTC/PlainTransport.cpp +13 -8
  133. package/worker/src/RTC/Producer.cpp +14 -31
  134. package/worker/src/RTC/RTCP/Bye.cpp +1 -1
  135. package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
  136. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
  137. package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
  138. package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
  139. package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
  140. package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
  141. package/worker/src/RTC/RTP/Packet.cpp +26 -11
  142. package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
  143. package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
  144. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
  145. package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
  146. package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
  147. package/worker/src/RTC/RateCalculator.cpp +133 -28
  148. package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
  149. package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
  150. package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
  151. package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
  152. package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
  153. package/worker/src/RTC/SCTP/association/Association.cpp +1 -1
  154. package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
  155. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
  156. package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
  157. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
  158. package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
  159. package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
  160. package/worker/src/RTC/SrtpSession.cpp +2 -2
  161. package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
  162. package/worker/src/RTC/TcpConnection.cpp +2 -2
  163. package/worker/src/RTC/Transport.cpp +111 -93
  164. package/worker/src/RTC/TransportTuple.cpp +4 -4
  165. package/worker/src/RTC/WebRtcServer.cpp +4 -3
  166. package/worker/src/RTC/WebRtcTransport.cpp +20 -13
  167. package/worker/src/Utils/BitStream.cpp +24 -0
  168. package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
  169. package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
  170. package/worker/src/handles/UdpSocketHandle.cpp +14 -21
  171. package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
  172. package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
  173. package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
  174. package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
  175. package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
  176. package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
  177. package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
  178. package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
  179. package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
  180. package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
  181. package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
  182. package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
  183. package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
  184. package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
  185. package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
  186. package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
  187. package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
  188. package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
  189. package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
  190. package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
  191. package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
  192. package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
  193. package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
  194. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
  195. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
  196. package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
  197. package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
  198. package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
  199. package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
  200. package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
  201. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
  202. package/worker/test/src/Utils/TestTime.cpp +120 -21
  203. package/worker/test/src/RTC/BWE/TestUtils.cpp +0 -61
@@ -16,12 +16,25 @@ namespace RTC
16
16
  * and GetRate() are O(1) amortized.
17
17
  *
18
18
  * It is considered that the time source increases monotonically. Timestamps
19
- * going backwards are however tolerated (time comparisons are wrap safe):
20
- * data still within the window is added to the newest item, older data is
21
- * ignored, and nothing is ever expired ahead of time.
19
+ * going backwards are however tolerated (time comparisons are wrap safe): no
20
+ * data is ever lost nor expired ahead of time, and whatever is given with an
21
+ * instant that is not newer than the newest item is added to that item.
22
22
  */
23
23
  class RateCalculator
24
24
  {
25
+ private:
26
+ struct Item
27
+ {
28
+ /**
29
+ * Sum of the sizes given to Update() within this item.
30
+ */
31
+ uint64_t count{ 0 };
32
+ /**
33
+ * Number of Update() calls accounted for within this item.
34
+ */
35
+ uint64_t samples{ 0 };
36
+ };
37
+
25
38
  public:
26
39
  static constexpr int64_t DefaultWindowSizeMs{ 1000 };
27
40
  static constexpr float DefaultBpsScale{ 8000.0f };
@@ -33,11 +46,43 @@ namespace RTC
33
46
  float scale = DefaultBpsScale,
34
47
  uint16_t windowItems = DefaultWindowItems);
35
48
 
49
+ /**
50
+ * Accounts for `size` units of data taken at `nowMs`.
51
+ *
52
+ * @remarks
53
+ * - A sample that arrives when the window holds none starts a new measured
54
+ * period, unless the previous sample is recent enough for both to be taken
55
+ * as the same stretch of traffic. That is what keeps a stream which sends
56
+ * less often than the window from restarting its period at every sample and
57
+ * hence never being measured at all.
58
+ */
36
59
  void Update(size_t size, int64_t nowMs);
37
60
 
38
- int64_t GetRate(int64_t nowMs);
39
-
40
- size_t GetBytes() const
61
+ /**
62
+ * Rate of the data within the window ending at `nowMs`, computed over the
63
+ * period the data actually spans rather than over the whole window, so that
64
+ * a window which has not filled yet is not reported as a fraction of the
65
+ * rate it is measuring.
66
+ *
67
+ * While that period starts at a sample rather than at the edge of the window,
68
+ * the data of that sample is left out, since the period does not cover the
69
+ * time it took to arrive.
70
+ *
71
+ * Returns no value when there is nothing to measure, which is any of:
72
+ *
73
+ * - Not a single sample within the window.
74
+ * - A period of a single millisecond, which gives no duration to divide by.
75
+ * - A single sample while the window has not filled, since one sample says
76
+ * how much data arrived at an instant but nothing about how fast it is
77
+ * arriving.
78
+ *
79
+ * Returns zero when there are enough samples to measure but the data they
80
+ * add up to rounds down to zero at the configured scale, which takes
81
+ * Update() calls of size zero.
82
+ */
83
+ std::optional<int64_t> GetRate(int64_t nowMs);
84
+
85
+ uint64_t GetBytes() const
41
86
  {
42
87
  return this->bytes;
43
88
  }
@@ -52,31 +97,56 @@ namespace RTC
52
97
  int64_t windowSizeMs{ DefaultWindowSizeMs };
53
98
  // Item size (in milliseconds). Always >= 1.
54
99
  int64_t itemSizeMs{ 1 };
55
- // Precomputed `scale / windowSizeMs`.
56
- double rateScale{ 0.0 };
57
- // Ring of items, each one holding the count of the data within it. Never
58
- // empty, and always long enough to cover the whole window.
59
- std::vector<size_t> buffer;
100
+ // Factor the in-window count is multiplied by before being divided by the
101
+ // period it spans.
102
+ double scale{ 0.0 };
103
+ // How long after a sample the next one still counts as the same stretch of
104
+ // traffic (in milliseconds). Derived from the window size.
105
+ int64_t recentSampleMarginMs{ 0 };
106
+ // Ring of items. Never empty, and always long enough to cover the whole
107
+ // window.
108
+ std::vector<Item> buffer;
60
109
  // Index of the newest item. Always < buffer.size().
61
110
  size_t newestItemIndex{ 0 };
62
111
  // Time (in milliseconds) at which the newest item starts.
63
112
  int64_t newestItemStartTimeMs{ 0 };
113
+ // Time (in milliseconds) at which the measured period starts. Unset until the
114
+ // very first sample, and from then on only ever moved forward by a sample
115
+ // that finds the window empty after long enough without traffic.
116
+ // NOTE: Expiration does not move it, so once the data reaches back beyond the
117
+ // window it names a sample that is already gone. That is on purpose: from
118
+ // that point on the period is the window itself, which is what the reader
119
+ // clamps it to.
120
+ std::optional<int64_t> firstSampleTimeMs;
121
+ // Count of the sample that starts the measured period, which is left out of
122
+ // the rate for as long as the period is anchored to it.
123
+ uint64_t firstSampleCount{ 0 };
124
+ // Time (in milliseconds) of the latest sample, which together with the window
125
+ // still holding it is what tells a stream that simply sends less often than
126
+ // the window apart from one that stopped.
127
+ std::optional<int64_t> lastSampleTimeMs;
64
128
  // Sum of the count of every item.
65
- size_t totalCount{ 0 };
129
+ uint64_t totalCount{ 0 };
130
+ // Sum of the samples of every item.
131
+ uint64_t totalSamples{ 0 };
66
132
  // Total bytes accounted for. Not affected by Reset().
67
- size_t bytes{ 0 };
68
- // Rate memoized by GetRate(), only valid while both `lastTimeMs` and
69
- // `lastTotalCount` below still match. `lastTotalCount` is the one that makes
70
- // any Update() changing the rate invalidate this implicitly, so that the hot
71
- // path needs no memoization store.
133
+ // NOTE: Nothing bounds this one, unlike the in-window total above, so it is
134
+ // as wide as the stats field it ends up in.
135
+ uint64_t bytes{ 0 };
136
+ // Rate memoized by GetRate(), only valid while `lastTimeMs`,
137
+ // `lastTotalCount` and `lastTotalSamples` below all still match.
138
+ // `lastTotalSamples` is the one that makes any Update() invalidate this
139
+ // implicitly, so that the hot path needs no memoization store.
72
140
  // NOTE: No "not calculated yet" mark is needed, since the initial and post
73
- // Reset() state is a valid entry on its own: a zero rate for a zero count.
74
- int64_t lastRate{ 0 };
141
+ // Reset() state is a valid entry on its own: no rate for no samples.
142
+ std::optional<int64_t> lastRate;
75
143
  // Time of the latest GetRate() call. Prevents reusing `lastRate` once time
76
144
  // has moved on and there is data pending expiration.
77
145
  int64_t lastTimeMs{ 0 };
78
146
  // Total count at the latest GetRate() call.
79
- size_t lastTotalCount{ 0 };
147
+ uint64_t lastTotalCount{ 0 };
148
+ // Total samples at the latest GetRate() call.
149
+ uint64_t lastTotalSamples{ 0 };
80
150
  };
81
151
 
82
152
  class RtpDataCounter
@@ -91,17 +161,25 @@ namespace RTC
91
161
  public:
92
162
  void Update(const RTC::RTP::Packet* packet);
93
163
 
94
- int64_t GetBitrate(int64_t nowMs)
164
+ /**
165
+ * Bitrate (bps) of the RTP traffic within the window ending at `nowMs`,
166
+ * measured over the period that traffic actually spans.
167
+ *
168
+ * @returns No value while there is nothing to measure, which is any of: no
169
+ * packet within the window, a period of a single millisecond, and a single
170
+ * packet while the window has not filled.
171
+ */
172
+ std::optional<int64_t> GetBitrate(int64_t nowMs)
95
173
  {
96
174
  return this->rate.GetRate(nowMs);
97
175
  }
98
176
 
99
- size_t GetPacketCount() const
177
+ uint64_t GetPacketCount() const
100
178
  {
101
179
  return this->packets;
102
180
  }
103
181
 
104
- size_t GetBytes() const
182
+ uint64_t GetBytes() const
105
183
  {
106
184
  return this->rate.GetBytes();
107
185
  }
@@ -112,7 +190,8 @@ namespace RTC
112
190
  // account.
113
191
  bool ignorePaddingOnlyPackets{ false };
114
192
  RateCalculator rate;
115
- size_t packets{ 0 };
193
+ // Total packets accounted for, which nothing bounds either.
194
+ uint64_t packets{ 0 };
116
195
  };
117
196
  } // namespace RTC
118
197
 
@@ -14,14 +14,19 @@ namespace RTC
14
14
  * The capture instant is read from one of two sources, and the same one is used
15
15
  * for every stream of the sender. Mixing them would reintroduce the very inter
16
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
17
+ * error: 'abs-capture-time' is exact while a Sender Report is biased by its own
18
18
  * one way delay.
19
19
  *
20
20
  * The source is chosen from what the Producers of the sender negotiated. The
21
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
22
+ * 'abs-capture-time' moves it to Sender Report for the rest of the life of this
23
23
  * object, never back.
24
24
  *
25
+ * A sender may negotiate that extension and then never send it, which would
26
+ * leave every stream of it without a capture instant forever. So the source also
27
+ * falls back to Sender Report when no stream of this sender has carried the
28
+ * extension for long enough since its first packet.
29
+ *
25
30
  * A single instance is meant to be shared by all the RTP streams of a given
26
31
  * CNAME, which is what identifies media coming from a same machine and hence
27
32
  * from a same wall clock.
@@ -76,17 +81,42 @@ namespace RTC
76
81
  *
77
82
  * @param rtpStream - RTP stream the RTP timestamp belongs to.
78
83
  * @param ts - RTP timestamp whose capture instant is wanted.
84
+ * @param nowUs - Current instant, which is also what the fall back to Sender
85
+ * Report is timed against.
79
86
  *
80
87
  * @returns No value while the capture instant cannot be told yet.
81
88
  */
82
89
  std::optional<int64_t> GetLocalCaptureAtUs(
83
- const RTC::RTP::RtpStreamRecv* rtpStream, uint32_t ts) const;
90
+ const RTC::RTP::RtpStreamRecv* rtpStream, uint32_t ts, int64_t nowUs);
91
+
92
+ private:
93
+ /**
94
+ * Move the source to Sender Report when 'abs-capture-time' was negotiated but
95
+ * no stream of this sender has ever carried it, which is told apart from it
96
+ * being merely early by how long this sender has been sending.
97
+ *
98
+ * @param rtpStream - RTP stream whose packet is being looked at.
99
+ * @param nowUs - Current instant.
100
+ */
101
+ void MayFallBackToSenderReport(const RTC::RTP::RtpStreamRecv* rtpStream, int64_t nowUs);
84
102
 
85
103
  private:
86
104
  // Offset between the wall clock of the sender and our monotonic one.
87
105
  RTC::RemoteClockOffsetEstimator clockOffsetEstimator;
88
106
  // Source the capture instant is read from, for every stream of this sender.
89
107
  std::optional<Source> source;
108
+ // Instant the first packet of this sender was asked about, or no value until
109
+ // then. The fall back to Sender Report is measured against it, so it must be
110
+ // something that exists even when the extension never arrives.
111
+ //
112
+ // NOTE: Not every packet is asked about, only the one holding the highest RTP
113
+ // timestamp of its stream, so this is the first one that got here rather than
114
+ // the first one that arrived.
115
+ std::optional<int64_t> firstPacketAtUs;
116
+ // Whether any stream of this sender has ever carried 'abs-capture-time', which
117
+ // is what tells a sender that does not send it from a stream whose first
118
+ // packets carrying it are still on their way.
119
+ bool absCaptureTimeReceived{ false };
90
120
  };
91
121
  } // namespace RTC
92
122
 
@@ -1,8 +1,9 @@
1
- #ifndef MS_RTC_RTC_LOGGER_HPP
2
- #define MS_RTC_RTC_LOGGER_HPP
1
+ #ifndef MS_RTC_RTC_LOGGER_RTP_PACKET_HPP
2
+ #define MS_RTC_RTC_LOGGER_RTP_PACKET_HPP
3
3
 
4
4
  #include "common.hpp"
5
5
  #include <ankerl/unordered_dense.h>
6
+ #include <string>
6
7
 
7
8
  namespace RTC
8
9
  {
@@ -55,6 +56,7 @@ namespace RTC
55
56
  bool discarded{};
56
57
  DiscardReason discardReason{ DiscardReason::NONE };
57
58
  };
58
- }; // namespace RtcLogger
59
+ } // namespace RtcLogger
59
60
  } // namespace RTC
61
+
60
62
  #endif
@@ -0,0 +1,88 @@
1
+ #ifndef MS_RTC_RTC_LOGGER_SEND_BURST_HPP
2
+ #define MS_RTC_RTC_LOGGER_SEND_BURST_HPP
3
+
4
+ #include "common.hpp"
5
+ #include <map>
6
+ #include <string>
7
+
8
+ namespace RTC
9
+ {
10
+ namespace RtcLogger
11
+ {
12
+ /**
13
+ * How many RTP packets a transport sends within a single iteration of the event
14
+ * loop.
15
+ *
16
+ * Nothing spaces those packets out, so a whole iteration's worth of them reaches
17
+ * the wire back to back and lands in the first queue of the path as a single
18
+ * lump. This gathers how big those lumps are and how much of each one is
19
+ * retransmissions, which is what says whether there is anything worth pacing.
20
+ */
21
+ class SendBurst
22
+ {
23
+ private:
24
+ /**
25
+ * What all the bursts of a given size added up to.
26
+ */
27
+ struct Counters
28
+ {
29
+ /**
30
+ * How many of them there were.
31
+ */
32
+ uint64_t count{ 0 };
33
+ /**
34
+ * Retransmissions they carried between all of them, so that the tail of
35
+ * the distribution can be attributed.
36
+ */
37
+ uint64_t retransmissions{ 0 };
38
+ /**
39
+ * Probation packets they carried between all of them.
40
+ */
41
+ uint64_t probations{ 0 };
42
+ };
43
+
44
+ public:
45
+ SendBurst() = default;
46
+ ~SendBurst() = default;
47
+
48
+ /**
49
+ * Account for a packet that is about to be sent.
50
+ *
51
+ * @param loopTimeMs - Time at which the current iteration of the event loop
52
+ * began, which is what tells one burst from the next.
53
+ */
54
+ void Sent(uint64_t loopTimeMs, size_t length, bool isRetransmission, bool isProbation);
55
+
56
+ /**
57
+ * Print what has been gathered so far and start over.
58
+ */
59
+ void Log();
60
+
61
+ private:
62
+ /**
63
+ * Add the burst in progress, if there is one, to the distribution.
64
+ */
65
+ void CloseBurst();
66
+
67
+ void Clear();
68
+
69
+ public:
70
+ std::string transportId;
71
+
72
+ private:
73
+ // Time of the iteration of the event loop that the burst in progress belongs
74
+ // to.
75
+ uint64_t loopTimeMs{ 0 };
76
+ size_t packets{ 0 };
77
+ size_t retransmissions{ 0 };
78
+ size_t probations{ 0 };
79
+ size_t bytes{ 0 };
80
+ // Bursts seen, keyed by how many packets each of them carried.
81
+ std::map<size_t /*packets*/, Counters> bursts;
82
+ size_t maxPackets{ 0 };
83
+ size_t maxBytes{ 0 };
84
+ };
85
+ } // namespace RtcLogger
86
+ } // namespace RTC
87
+
88
+ #endif
@@ -123,10 +123,9 @@ namespace RTC
123
123
  SSRC_AUDIO_LEVEL = 6,
124
124
  DEPENDENCY_DESCRIPTOR = 7,
125
125
  VIDEO_ORIENTATION = 8,
126
- TIME_OFFSET = 9,
127
- ABS_CAPTURE_TIME = 10,
128
- PLAYOUT_DELAY = 11,
129
- MEDIASOUP_PACKET_ID = 12
126
+ ABS_CAPTURE_TIME = 9,
127
+ PLAYOUT_DELAY = 10,
128
+ MEDIASOUP_PACKET_ID = 11
130
129
  };
131
130
 
132
131
  public:
@@ -128,7 +128,7 @@ namespace RTC
128
128
  return "SHUTDOWN_ACK_SENT";
129
129
  }
130
130
 
131
- NO_DEFAULT_GCC();
131
+ NO_DEFAULT();
132
132
  }
133
133
  }
134
134
 
@@ -2,7 +2,6 @@
2
2
  #define MS_RTC_SCTP_ASSOCIATION_METRICS_HPP
3
3
 
4
4
  #include "common.hpp"
5
- #include "RTC/SCTP/association/StateCookie.hpp"
6
5
  #include "RTC/SCTP/public/SctpTypes.hpp"
7
6
 
8
7
  namespace RTC
@@ -77,7 +77,7 @@ namespace RTC
77
77
  return "SHUTTING_DOWN";
78
78
  }
79
79
 
80
- NO_DEFAULT_GCC();
80
+ NO_DEFAULT();
81
81
  }
82
82
  }
83
83
 
@@ -179,7 +179,7 @@ namespace RTC
179
179
  return "UNSUPPORTED_OPERATION";
180
180
  }
181
181
 
182
- NO_DEFAULT_GCC();
182
+ NO_DEFAULT();
183
183
  }
184
184
  }
185
185
 
@@ -219,7 +219,7 @@ namespace RTC
219
219
  return "usrsctp";
220
220
  }
221
221
 
222
- NO_DEFAULT_GCC();
222
+ NO_DEFAULT();
223
223
  }
224
224
  }
225
225
 
@@ -332,7 +332,7 @@ namespace RTC
332
332
  return "ERROR_SHUTTING_DOWN";
333
333
  }
334
334
 
335
- NO_DEFAULT_GCC();
335
+ NO_DEFAULT();
336
336
  }
337
337
  }
338
338
 
@@ -105,7 +105,7 @@ namespace RTC
105
105
  return "IMMEDIATE";
106
106
  }
107
107
 
108
- NO_DEFAULT_GCC();
108
+ NO_DEFAULT();
109
109
  }
110
110
  }
111
111
 
@@ -57,7 +57,7 @@ namespace RTC
57
57
  * SCTP association should restrict incoming data to avoid filling up the
58
58
  * queue.
59
59
  */
60
- static constexpr float HighWatermarkLimit{ 0.9 };
60
+ static constexpr double HighWatermarkLimit{ 0.9 };
61
61
 
62
62
  private:
63
63
  struct DeferredResetStreams
@@ -18,8 +18,8 @@ namespace RTC
18
18
  public:
19
19
  uint16_t streamId{ 0 };
20
20
  bool ordered{ true };
21
- uint16_t maxPacketLifeTime{ 0 };
22
- uint16_t maxRetransmits{ 0 };
21
+ std::optional<uint16_t> maxPacketLifeTime;
22
+ std::optional<uint16_t> maxRetransmits;
23
23
  };
24
24
  } // namespace RTC
25
25
 
@@ -2,6 +2,7 @@
2
2
  #define MS_RTC_TCP_CONNECTION_HPP
3
3
 
4
4
  #include "common.hpp"
5
+ #include "handles/SendCallbacks.hpp"
5
6
  #include "handles/TcpConnectionHandle.hpp"
6
7
  #include "SharedInterface.hpp"
7
8
 
@@ -29,7 +30,7 @@ namespace RTC
29
30
  ~TcpConnection() override;
30
31
 
31
32
  public:
32
- void Send(const uint8_t* data, size_t len, ::TcpConnectionHandle::onSendCallback* cb);
33
+ void Send(const uint8_t* data, size_t len, onSendCallback cb);
33
34
 
34
35
  /* Pure virtual methods inherited from ::TcpConnectionHandle. */
35
36
  public:
@@ -6,6 +6,7 @@
6
6
  #include "Channel/ChannelRequest.hpp"
7
7
  #include "Channel/ChannelSocket.hpp"
8
8
  #include "FBS/transport.h"
9
+ #include "handles/SendCallbacks.hpp"
9
10
  #include "handles/TimerHandleInterface.hpp"
10
11
  #include "RTC/Consumer.hpp"
11
12
  #include "RTC/DataConsumer.hpp"
@@ -28,6 +29,9 @@
28
29
  #include "RTC/TransportCongestionControlServer.hpp"
29
30
  #endif
30
31
  #include "SharedInterface.hpp"
32
+ #ifdef MS_RTC_LOGGER_SEND_BURST
33
+ #include "RTC/RtcLogger/SendBurst.hpp"
34
+ #endif
31
35
  #include <ankerl/unordered_dense.h>
32
36
  #include <string>
33
37
  #include <vector>
@@ -47,10 +51,6 @@ namespace RTC
47
51
  public Channel::ChannelSocket::NotificationHandler,
48
52
  public TimerHandleInterface::Listener
49
53
  {
50
- protected:
51
- using onSendCallback = const std::function<void(bool sent)>;
52
- using onQueuedCallback = const std::function<void(bool queued, bool sctpSendBufferFull)>;
53
-
54
54
  public:
55
55
  class Listener
56
56
  {
@@ -202,7 +202,9 @@ namespace RTC
202
202
  virtual void ReceiveRtcpPacket(RTC::RTCP::Packet* packet, int64_t receivedAtUs) final;
203
203
  virtual void ReceiveSctpData(const uint8_t* data, size_t len, int64_t receivedAtUs) final;
204
204
  virtual void SendSctpMessage(
205
- RTC::DataConsumer* dataConsumer, RTC::SCTP::Message message, onQueuedCallback* cb = nullptr) final;
205
+ RTC::DataConsumer* dataConsumer,
206
+ RTC::SCTP::Message message,
207
+ onMessageQueuedCallback cb = {}) final;
206
208
 
207
209
  private:
208
210
  virtual RTC::Producer* AssertAndGetProducerById(
@@ -228,14 +230,20 @@ namespace RTC
228
230
  {
229
231
  return false;
230
232
  }
233
+ /**
234
+ * Bytes that every packet sent through this transport carries on top of its
235
+ * own length once it's on the network, or zero while no path has been
236
+ * chosen yet.
237
+ */
238
+ virtual size_t GetPacketOverhead() const = 0;
231
239
  virtual void SendRtpPacket(
232
- RTC::Consumer* consumer, RTC::RTP::Packet* packet, const onSendCallback* cb = nullptr) = 0;
240
+ RTC::Consumer* consumer, RTC::RTP::Packet* packet, onSendCallback cb = {}) = 0;
233
241
  virtual void HandleRtcpPacket(RTC::RTCP::Packet* packet, int64_t receivedAtUs) final;
234
242
  virtual void SendRtcp(int64_t nowUs) final;
235
243
  virtual void SendRtcpPacket(RTC::RTCP::Packet* packet) = 0;
236
244
  virtual void SendRtcpCompoundPacket(RTC::RTCP::CompoundPacket* packet) = 0;
237
245
  virtual void SendMessage(
238
- RTC::DataConsumer* dataConsumer, RTC::SCTP::Message message, onQueuedCallback* cb = nullptr) = 0;
246
+ RTC::DataConsumer* dataConsumer, RTC::SCTP::Message message, onMessageQueuedCallback cb = {}) = 0;
239
247
  virtual bool SendData(const uint8_t* data, size_t len) = 0;
240
248
  virtual void RecvStreamClosed(uint32_t ssrc) = 0;
241
249
  virtual void SendStreamClosed(uint32_t ssrc) = 0;
@@ -308,7 +316,7 @@ namespace RTC
308
316
  /* Pure virtual methods inherited from RTC::DataConsumer::Listener. */
309
317
  public:
310
318
  void OnDataConsumerSendMessage(
311
- RTC::DataConsumer* dataConsumer, RTC::SCTP::Message message, onQueuedCallback* cb) override;
319
+ RTC::DataConsumer* dataConsumer, RTC::SCTP::Message message, onMessageQueuedCallback cb) override;
312
320
  void OnDataConsumerNeedBufferedAmount(
313
321
  const RTC::DataConsumer* dataConsumer, uint32_t& bufferedAmount) const override;
314
322
  void OnDataConsumerNeedBufferedAmountLowThreshold(
@@ -412,6 +420,13 @@ namespace RTC
412
420
  size_t maxSendMessageSize{ 0 };
413
421
  size_t maxReceiveMessageSize{ 0 };
414
422
  struct TraceEventTypes traceEventTypes;
423
+
424
+ #ifdef MS_RTC_LOGGER_SEND_BURST
425
+ private:
426
+ RTC::RtcLogger::SendBurst sendBurstLogger;
427
+ // Allocated by this.
428
+ TimerHandleInterface* sendBurstLoggerTimer{ nullptr };
429
+ #endif
415
430
  };
416
431
  } // namespace RTC
417
432
 
@@ -3,6 +3,8 @@
3
3
 
4
4
  #include "common.hpp"
5
5
  #include "FBS/transport.h"
6
+ #include "handles/SendCallbacks.hpp"
7
+ #include "RTC/Consts.hpp"
6
8
  #include "RTC/TcpConnection.hpp"
7
9
  #include "RTC/UdpSocket.hpp"
8
10
  #include "Utils.hpp"
@@ -13,9 +15,6 @@ namespace RTC
13
15
  {
14
16
  class TransportTuple
15
17
  {
16
- protected:
17
- using onSendCallback = const std::function<void(bool sent)>;
18
-
19
18
  public:
20
19
  enum class Protocol : uint8_t
21
20
  {
@@ -139,15 +138,15 @@ namespace RTC
139
138
  this->localAnnouncedAddress = localAnnouncedAddress;
140
139
  }
141
140
 
142
- void Send(const uint8_t* data, size_t len, RTC::TransportTuple::onSendCallback* cb = nullptr)
141
+ void Send(const uint8_t* data, size_t len, onSendCallback cb = {})
143
142
  {
144
143
  if (this->protocol == Protocol::UDP)
145
144
  {
146
- this->udpSocket->Send(data, len, this->udpRemoteAddr, cb);
145
+ this->udpSocket->Send(data, len, this->udpRemoteAddr, std::move(cb));
147
146
  }
148
147
  else
149
148
  {
150
- this->tcpConnection->Send(data, len, cb);
149
+ this->tcpConnection->Send(data, len, std::move(cb));
151
150
  }
152
151
  }
153
152
 
@@ -156,6 +155,62 @@ namespace RTC
156
155
  return this->protocol;
157
156
  }
158
157
 
158
+ /**
159
+ * Bytes that every packet sent through this tuple carries on top of its own
160
+ * length, which is what the network sees but nothing in here counts.
161
+ *
162
+ * @remarks
163
+ * - It only contemplates IPv4 and IPv6 for the network layer and UDP and
164
+ * TCP for the transport one, both without options, plus the length field
165
+ * that frames a packet sent over TCP. Anything below that, such as the
166
+ * Ethernet frame or a tunnel, is not counted.
167
+ */
168
+ size_t GetPacketOverhead() const
169
+ {
170
+ size_t overhead{ 0 };
171
+
172
+ switch (GetLocalAddress()->sa_family)
173
+ {
174
+ case AF_INET:
175
+ {
176
+ overhead += RTC::Consts::Ipv4HeaderSize;
177
+
178
+ break;
179
+ }
180
+
181
+ case AF_INET6:
182
+ {
183
+ overhead += RTC::Consts::Ipv6HeaderSize;
184
+
185
+ break;
186
+ }
187
+
188
+ default:
189
+ {
190
+ break;
191
+ }
192
+ }
193
+
194
+ switch (this->protocol)
195
+ {
196
+ case Protocol::UDP:
197
+ {
198
+ overhead += RTC::Consts::UdpHeaderSize;
199
+
200
+ break;
201
+ }
202
+
203
+ case Protocol::TCP:
204
+ {
205
+ overhead += RTC::Consts::TcpHeaderSize + RTC::Consts::TcpFramingSize;
206
+
207
+ break;
208
+ }
209
+ }
210
+
211
+ return overhead;
212
+ }
213
+
159
214
  const struct sockaddr* GetLocalAddress() const
160
215
  {
161
216
  if (this->protocol == Protocol::UDP)