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
@@ -20,62 +20,177 @@ namespace RTC
20
20
  MS_TRACE();
21
21
  }
22
22
 
23
- int64_t SendPacketHistory::AddPacket(
24
- uint32_t ssrc, uint16_t seq, size_t size, bool audio, int64_t sentAtUs)
23
+ int64_t SendPacketHistory::AddPacket(const AddPacketOptions& addPacketOptions)
25
24
  {
26
25
  MS_TRACE();
27
26
 
28
- // Drop the packets held for longer than the window, since a feedback
29
- // reporting on them is not of any use anymore.
30
- while (!this->history.empty() && sentAtUs - this->history.begin()->second.sentPacket.sendTimeUs >
31
- this->options.windowDurationUs)
27
+ while (!this->history.empty())
32
28
  {
33
- const auto& entry = this->history.begin()->second;
29
+ const auto it = this->history.begin();
30
+ const auto& oldestEntry = it->second;
31
+
32
+ // The packets are held for as long as the window, beyond which a
33
+ // feedback reporting on them is not of any use anymore.
34
+ if (addPacketOptions.createdAtUs - oldestEntry.createdAtUs <= this->options.windowDurationUs)
35
+ {
36
+ break;
37
+ }
34
38
 
35
39
  // Only the packets that no feedback has reported on yet count as in
36
40
  // flight, since those already reported had their bytes removed then.
37
- if (entry.sentPacket.sequenceNumber > this->lastAckSequenceNumber)
41
+ if (oldestEntry.sentPacket.sequenceNumber > this->lastAckSequenceNumber)
38
42
  {
39
- RemoveOutstandingBytes(entry);
43
+ RemoveOutstandingBytes(oldestEntry);
40
44
  }
41
45
 
42
- RemoveSsrcAndSeq(entry);
46
+ RemoveSsrcAndSeq(oldestEntry);
43
47
 
44
- this->history.erase(this->history.begin());
48
+ this->history.erase(it);
45
49
  }
46
50
 
47
- const int64_t sequenceNumber = this->nextSequenceNumber++;
51
+ // The unwrapper is what counts, so that what goes on the wire and what this
52
+ // history is keyed by can never be two different counts.
53
+ const int64_t sequenceNumber =
54
+ this->sequenceNumberUnwrapper.Unwrap(this->nextWrappedSequenceNumber++).GetValue();
48
55
 
49
56
  SentPacketEntry entry;
50
57
 
51
58
  entry.sentPacket.sequenceNumber = sequenceNumber;
52
- entry.sentPacket.sendTimeUs = sentAtUs;
53
- entry.sentPacket.size = size;
54
- entry.sentPacket.audio = audio;
55
- entry.ssrc = ssrc;
56
- entry.seq = seq;
59
+ entry.sentPacket.size = addPacketOptions.size;
60
+ entry.sentPacket.isAudio = addPacketOptions.isAudio;
61
+ entry.sentPacket.probeCluster = addPacketOptions.probeCluster;
62
+ entry.createdAtUs = addPacketOptions.createdAtUs;
63
+ entry.ssrc = addPacketOptions.ssrc;
64
+ entry.seq = addPacketOptions.seq;
65
+ entry.isRetransmission = addPacketOptions.isRetransmission;
66
+ entry.sentWithEct1 = addPacketOptions.sentWithEct1;
57
67
 
58
68
  // The very same SSRC and RTP sequence number can be sent twice, as an audio
59
- // retransmission does, so let the latest send take the mapping over.
60
- this->ssrcAndSeqToSequenceNumber[SsrcAndSeq{ .ssrc = ssrc, .seq = seq }] = sequenceNumber;
69
+ // retransmission does. What a feedback then reports as the arrival time of
70
+ // either of them may be of the other one, so both are marked and the
71
+ // mapping is left on the first of them.
72
+ const auto [it, inserted] = this->ssrcAndSeqToSequenceNumber.emplace(
73
+ SsrcAndSeq{ .ssrc = addPacketOptions.ssrc, .seq = addPacketOptions.seq }, sequenceNumber);
74
+
75
+ if (!inserted)
76
+ {
77
+ entry.ambiguousReceiveTime = true;
61
78
 
62
- this->outstandingBytes += size;
79
+ const int64_t previousSequenceNumber = it->second;
80
+ const auto previousIt = this->history.find(previousSequenceNumber);
63
81
 
64
- entry.sentPacket.dataInFlight = this->outstandingBytes;
82
+ if (previousIt != this->history.end())
83
+ {
84
+ auto& previousEntry = previousIt->second;
85
+
86
+ previousEntry.ambiguousReceiveTime = true;
87
+ }
88
+ }
89
+ // A retransmission that goes without RTX carries the very same SSRC and RTP
90
+ // sequence number as what it retransmits, so it is just as ambiguous even
91
+ // when the packet it repeats is not held anymore.
92
+ else if (
93
+ addPacketOptions.isRetransmission &&
94
+ (!addPacketOptions.originalSsrc.has_value() ||
95
+ addPacketOptions.originalSsrc.value() == addPacketOptions.ssrc))
96
+ {
97
+ entry.ambiguousReceiveTime = true;
98
+ }
65
99
 
66
100
  this->history.emplace(sequenceNumber, entry);
67
101
 
102
+ this->highestSequenceNumber =
103
+ std::max(this->highestSequenceNumber.value_or(sequenceNumber), sequenceNumber);
104
+
68
105
  return sequenceNumber;
69
106
  }
70
107
 
71
- std::optional<Types::SentPacket> SendPacketHistory::RetrievePacket(
108
+ int64_t SendPacketHistory::UnwrapSequenceNumber(uint16_t wrappedSequenceNumber)
109
+ {
110
+ MS_TRACE();
111
+
112
+ return this->sequenceNumberUnwrapper.Unwrap(wrappedSequenceNumber).GetValue();
113
+ }
114
+
115
+ std::optional<Types::SentPacket> SendPacketHistory::ProcessSentPacket(
116
+ int64_t sequenceNumber, int64_t sentAtUs)
117
+ {
118
+ MS_TRACE();
119
+
120
+ const auto it = this->history.find(sequenceNumber);
121
+
122
+ if (it == this->history.end())
123
+ {
124
+ MS_DEBUG_DEV("packet not held anymore [sequenceNumber:%" PRIi64 "]", sequenceNumber);
125
+
126
+ return std::nullopt;
127
+ }
128
+
129
+ auto& entry = it->second;
130
+
131
+ // It already left, so taking note of it again would count its bytes twice.
132
+ const bool alreadySent = entry.sentPacket.sendTimeUs != Types::TimeUsInfinite;
133
+
134
+ entry.sentPacket.sendTimeUs = sentAtUs;
135
+
136
+ this->lastSendTimeUs = std::max(this->lastSendTimeUs.value_or(sentAtUs), sentAtUs);
137
+
138
+ // The bytes that left untracked belong to whoever leaves next, which is
139
+ // this packet.
140
+ //
141
+ // TODO: (libwebrtc) Don't do this on retransmit.
142
+ if (this->pendingUntrackedBytes > 0)
143
+ {
144
+ if (this->lastUntrackedSendTimeUs.has_value() && sentAtUs < this->lastUntrackedSendTimeUs.value())
145
+ {
146
+ MS_WARN_DEV("attributing untracked bytes to a packet that left before them");
147
+ }
148
+
149
+ entry.sentPacket.priorUnackedData += this->pendingUntrackedBytes;
150
+
151
+ this->pendingUntrackedBytes = 0;
152
+ }
153
+
154
+ if (alreadySent)
155
+ {
156
+ return std::nullopt;
157
+ }
158
+
159
+ if (entry.sentPacket.sequenceNumber > this->lastAckSequenceNumber)
160
+ {
161
+ this->outstandingBytes += entry.sentPacket.size;
162
+ }
163
+
164
+ entry.sentPacket.dataInFlight = this->outstandingBytes;
165
+
166
+ return entry.sentPacket;
167
+ }
168
+
169
+ void SendPacketHistory::ProcessSentUntrackedPacket(size_t size, int64_t sentAtUs)
170
+ {
171
+ MS_TRACE();
172
+
173
+ if (this->lastSendTimeUs.has_value() && sentAtUs < this->lastSendTimeUs.value())
174
+ {
175
+ MS_WARN_DEV("untracked bytes left before the latest tracked packet did");
176
+ }
177
+
178
+ this->pendingUntrackedBytes += size;
179
+
180
+ this->lastUntrackedSendTimeUs =
181
+ std::max(this->lastUntrackedSendTimeUs.value_or(sentAtUs), sentAtUs);
182
+ }
183
+
184
+ std::optional<SendPacketHistory::SentPacketEntry> SendPacketHistory::RetrievePacket(
72
185
  int64_t sequenceNumber, bool received)
73
186
  {
74
187
  MS_TRACE();
75
188
 
76
189
  // A sequence number this history never gave out cannot be resolved, and
77
190
  // must not move the acknowledged mark either.
78
- if (sequenceNumber < 0 || sequenceNumber >= this->nextSequenceNumber)
191
+ if (
192
+ sequenceNumber < 0 || !this->highestSequenceNumber.has_value() ||
193
+ sequenceNumber > this->highestSequenceNumber.value())
79
194
  {
80
195
  MS_DEBUG_DEV(
81
196
  "sequence number was never given out [sequenceNumber:%" PRIi64 "]", sequenceNumber);
@@ -91,7 +206,9 @@ namespace RTC
91
206
  it != this->history.upper_bound(sequenceNumber);
92
207
  ++it)
93
208
  {
94
- RemoveOutstandingBytes(it->second);
209
+ const auto& entry = it->second;
210
+
211
+ RemoveOutstandingBytes(entry);
95
212
  }
96
213
 
97
214
  this->lastAckSequenceNumber = sequenceNumber;
@@ -108,21 +225,41 @@ namespace RTC
108
225
  return std::nullopt;
109
226
  }
110
227
 
111
- const auto sentPacket = it->second.sentPacket;
228
+ auto& storedEntry = it->second;
229
+
230
+ // A feedback cannot report on a packet that was never taken note of as
231
+ // having left.
232
+ if (storedEntry.sentPacket.sendTimeUs == Types::TimeUsInfinite)
233
+ {
234
+ MS_DEBUG_DEV(
235
+ "feedback reports on a packet that never left [sequenceNumber:%" PRIi64 "]",
236
+ sequenceNumber);
237
+
238
+ return std::nullopt;
239
+ }
240
+
241
+ const auto entry = storedEntry;
112
242
 
113
243
  // A packet reported as lost is kept, since a later feedback may still
114
244
  // report it as received.
115
245
  if (received)
116
246
  {
117
- RemoveSsrcAndSeq(it->second);
247
+ RemoveSsrcAndSeq(storedEntry);
118
248
 
119
249
  this->history.erase(it);
120
250
  }
251
+ // Marked after the copy was taken, so that the caller sees the value the
252
+ // packet had when this feedback reported on it and can hence tell a first
253
+ // loss from the same loss reported again.
254
+ else
255
+ {
256
+ storedEntry.previouslyReportedLost = true;
257
+ }
121
258
 
122
- return sentPacket;
259
+ return entry;
123
260
  }
124
261
 
125
- std::optional<Types::SentPacket> SendPacketHistory::RetrievePacket(
262
+ std::optional<SendPacketHistory::SentPacketEntry> SendPacketHistory::RetrievePacket(
126
263
  uint32_t ssrc, uint16_t seq, bool received)
127
264
  {
128
265
  MS_TRACE();
@@ -136,25 +273,21 @@ namespace RTC
136
273
  return std::nullopt;
137
274
  }
138
275
 
139
- return RetrievePacket(it->second, received);
276
+ const int64_t sequenceNumber = it->second;
277
+
278
+ return RetrievePacket(sequenceNumber, received);
140
279
  }
141
280
 
142
- std::optional<int64_t> SendPacketHistory::GetLastSequenceNumber() const
281
+ void SendPacketHistory::RemoveOutstandingBytes(const SentPacketEntry& entry)
143
282
  {
144
283
  MS_TRACE();
145
284
 
146
- if (this->nextSequenceNumber == 0)
285
+ // A packet that never left never counted as in flight.
286
+ if (entry.sentPacket.sendTimeUs == Types::TimeUsInfinite)
147
287
  {
148
- return std::nullopt;
288
+ return;
149
289
  }
150
290
 
151
- return this->nextSequenceNumber - 1;
152
- }
153
-
154
- void SendPacketHistory::RemoveOutstandingBytes(const SentPacketEntry& entry)
155
- {
156
- MS_TRACE();
157
-
158
291
  // The acknowledged mark only moves forward, so the bytes of a packet are
159
292
  // removed at most once.
160
293
  MS_ASSERT(
@@ -168,17 +301,7 @@ namespace RTC
168
301
  {
169
302
  MS_TRACE();
170
303
 
171
- const auto it =
172
- this->ssrcAndSeqToSequenceNumber.find(SsrcAndSeq{ .ssrc = entry.ssrc, .seq = entry.seq });
173
-
174
- // A later send of the very same SSRC and RTP sequence number took the
175
- // mapping over, so it's not this packet's to drop.
176
- if (it == this->ssrcAndSeqToSequenceNumber.end() || it->second != entry.sentPacket.sequenceNumber)
177
- {
178
- return;
179
- }
180
-
181
- this->ssrcAndSeqToSequenceNumber.erase(it);
304
+ this->ssrcAndSeqToSequenceNumber.erase(SsrcAndSeq{ .ssrc = entry.ssrc, .seq = entry.seq });
182
305
  }
183
306
  } // namespace BWE
184
307
  } // namespace RTC