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.
- package/CHANGELOG.md +19 -0
- package/node/lib/Consumer.d.ts.map +1 -1
- package/node/lib/Consumer.js +4 -51
- package/node/lib/Producer.d.ts.map +1 -1
- package/node/lib/Producer.js +4 -8
- package/node/lib/ProducerTypes.d.ts +4 -2
- package/node/lib/ProducerTypes.d.ts.map +1 -1
- package/node/lib/Router.d.ts.map +1 -1
- package/node/lib/Router.js +4 -0
- package/node/lib/Transport.d.ts.map +1 -1
- package/node/lib/Transport.js +7 -10
- package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts +3 -4
- package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.d.ts.map +1 -1
- package/node/lib/fbs/rtp-parameters/rtp-header-extension-uri.js +3 -4
- package/node/lib/ortc.d.ts +0 -2
- package/node/lib/ortc.d.ts.map +1 -1
- package/node/lib/ortc.js +11 -21
- package/node/lib/rtpMappingFbsUtils.d.ts +6 -0
- package/node/lib/rtpMappingFbsUtils.d.ts.map +1 -0
- package/node/lib/rtpMappingFbsUtils.js +65 -0
- package/node/lib/rtpParametersFbsUtils.d.ts.map +1 -1
- package/node/lib/rtpParametersFbsUtils.js +0 -6
- package/node/lib/rtpParametersTypes.d.ts +1 -1
- package/node/lib/rtpParametersTypes.d.ts.map +1 -1
- package/node/lib/rtpStreamFbsUtils.d.ts +4 -0
- package/node/lib/rtpStreamFbsUtils.d.ts.map +1 -0
- package/node/lib/rtpStreamFbsUtils.js +51 -0
- package/node/lib/supportedRtpCapabilities.d.ts.map +1 -1
- package/node/lib/supportedRtpCapabilities.js +6 -13
- package/node/lib/test/test-Consumer.js +1 -13
- package/node/lib/test/test-DataConsumer.js +9 -0
- package/node/lib/test/test-DataProducer.js +38 -0
- package/node/lib/test/test-PipeTransport.js +27 -29
- package/node/lib/test/test-Producer.js +97 -0
- package/node/lib/test/test-ortc.js +34 -14
- package/package.json +10 -10
- package/worker/fbs/FBS/meson.build +25 -0
- package/worker/fbs/meson.build +15 -18
- package/worker/fbs/rtpParameters.fbs +0 -1
- package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
- package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +16 -2
- package/worker/include/DepLibUV.hpp +13 -0
- package/worker/include/RTC/BWE/AlrDetector.hpp +97 -0
- package/worker/include/RTC/BWE/BitrateProber.hpp +217 -0
- package/worker/include/RTC/BWE/BitrateUtils.hpp +39 -0
- package/worker/include/RTC/BWE/BweTypes.hpp +171 -3
- package/worker/include/RTC/BWE/FeedbackAdapter.hpp +0 -14
- package/worker/include/RTC/BWE/InterArrival.hpp +117 -0
- package/worker/include/RTC/BWE/IntervalBudget.hpp +81 -0
- package/worker/include/RTC/BWE/LossBasedController.hpp +625 -0
- package/worker/include/RTC/BWE/OveruseDetector.hpp +71 -0
- package/worker/include/RTC/BWE/OveruseEstimator.hpp +115 -0
- package/worker/include/RTC/BWE/ProbeBitrateEstimator.hpp +84 -0
- package/worker/include/RTC/BWE/ProbeController.hpp +379 -0
- package/worker/include/RTC/BWE/ProbePacketGenerator.hpp +130 -0
- package/worker/include/RTC/BWE/ProbingScheduler.hpp +187 -0
- package/worker/include/RTC/BWE/RembGenerator.hpp +96 -0
- package/worker/include/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.hpp +237 -0
- package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +26 -0
- package/worker/include/RTC/BWE/SendPacketHistory.hpp +161 -25
- package/worker/include/RTC/BWE/TargetRateController.hpp +306 -0
- package/worker/include/RTC/BWE/TransportWideCcFeedbackGenerator.hpp +146 -0
- package/worker/include/RTC/BWE/TrendlineEstimator.hpp +73 -16
- package/worker/include/RTC/Consts.hpp +70 -0
- package/worker/include/RTC/DataConsumer.hpp +3 -5
- package/worker/include/RTC/DirectTransport.hpp +4 -5
- package/worker/include/RTC/PipeTransport.hpp +4 -5
- package/worker/include/RTC/PlainTransport.hpp +4 -5
- package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +6 -7
- package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +3 -1
- package/worker/include/RTC/RTP/Codecs/Tools.hpp +1 -1
- package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +0 -1
- package/worker/include/RTC/RTP/Packet.hpp +16 -4
- package/worker/include/RTC/RTP/ProbationGenerator.hpp +0 -8
- package/worker/include/RTC/RTP/RtpStream.hpp +12 -9
- package/worker/include/RTC/RTP/RtpStreamRecv.hpp +22 -4
- package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -2
- package/worker/include/RTC/RTP/RtxStream.hpp +10 -4
- package/worker/include/RTC/RateCalculator.hpp +103 -24
- package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +33 -3
- package/worker/include/RTC/{RtcLogger.hpp → RtcLogger/RtpPacket.hpp} +5 -3
- package/worker/include/RTC/RtcLogger/SendBurst.hpp +88 -0
- package/worker/include/RTC/RtpDictionaries.hpp +3 -4
- package/worker/include/RTC/SCTP/association/Association.hpp +1 -1
- package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +36 -0
- package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +0 -1
- package/worker/include/RTC/SCTP/public/SctpTypes.hpp +9 -9
- package/worker/include/RTC/SCTP/rx/DataTracker.hpp +1 -1
- package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +11 -1
- package/worker/include/RTC/SctpDictionaries.hpp +2 -2
- package/worker/include/RTC/TcpConnection.hpp +2 -1
- package/worker/include/RTC/Transport.hpp +23 -8
- package/worker/include/RTC/TransportTuple.hpp +61 -6
- package/worker/include/RTC/WebRtcTransport.hpp +4 -5
- package/worker/include/Shared.hpp +5 -0
- package/worker/include/SharedInterface.hpp +10 -0
- package/worker/include/Utils.hpp +72 -3
- package/worker/include/common.hpp +12 -4
- package/worker/include/handles/SendCallbacks.hpp +34 -0
- package/worker/include/handles/TcpConnectionHandle.hpp +4 -12
- package/worker/include/handles/UdpSocketHandle.hpp +4 -8
- package/worker/meson.build +45 -1
- package/worker/meson_options.txt +1 -0
- package/worker/mocks/include/MockShared.hpp +16 -2
- package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +1 -1
- package/worker/scripts/package-lock.json +6 -6
- package/worker/src/RTC/BWE/AimdRateControl.cpp +4 -5
- package/worker/src/RTC/BWE/AlrDetector.cpp +80 -0
- package/worker/src/RTC/BWE/BitrateProber.cpp +256 -0
- package/worker/src/RTC/BWE/BitrateUtils.cpp +54 -0
- package/worker/src/RTC/BWE/DelayBasedBwe.cpp +2 -2
- package/worker/src/RTC/BWE/FeedbackAdapter.cpp +20 -37
- package/worker/src/RTC/BWE/InterArrival.cpp +216 -0
- package/worker/src/RTC/BWE/IntervalBudget.cpp +93 -0
- package/worker/src/RTC/BWE/LossBasedController.cpp +1194 -0
- package/worker/src/RTC/BWE/OveruseDetector.cpp +128 -0
- package/worker/src/RTC/BWE/OveruseEstimator.cpp +166 -0
- package/worker/src/RTC/BWE/ProbeBitrateEstimator.cpp +222 -0
- package/worker/src/RTC/BWE/ProbeController.cpp +645 -0
- package/worker/src/RTC/BWE/ProbePacketGenerator.cpp +140 -0
- package/worker/src/RTC/BWE/ProbingScheduler.cpp +196 -0
- package/worker/src/RTC/BWE/RembGenerator.cpp +169 -0
- package/worker/src/RTC/BWE/RemoteBitrateEstimatorAbsSendTime.cpp +497 -0
- package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +47 -0
- package/worker/src/RTC/BWE/SendPacketHistory.cpp +173 -50
- package/worker/src/RTC/BWE/TargetRateController.cpp +433 -0
- package/worker/src/RTC/BWE/TransportWideCcFeedbackGenerator.cpp +377 -0
- package/worker/src/RTC/BWE/TrendlineEstimator.cpp +102 -5
- package/worker/src/RTC/Consumer.cpp +7 -5
- package/worker/src/RTC/DataConsumer.cpp +8 -10
- package/worker/src/RTC/DirectTransport.cpp +14 -8
- package/worker/src/RTC/DtlsTransport.cpp +8 -8
- package/worker/src/RTC/ICE/IceCandidate.cpp +4 -4
- package/worker/src/RTC/ICE/IceServer.cpp +1 -1
- package/worker/src/RTC/PipeTransport.cpp +13 -8
- package/worker/src/RTC/PlainTransport.cpp +13 -8
- package/worker/src/RTC/Producer.cpp +14 -31
- package/worker/src/RTC/RTCP/Bye.cpp +1 -1
- package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +18 -0
- package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +2 -2
- package/worker/src/RTC/RTCP/FeedbackPsVbcm.cpp +2 -1
- package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +2 -2
- package/worker/src/RTC/RTCP/Sdes.cpp +1 -1
- package/worker/src/RTC/RTP/Codecs/DependencyDescriptor.cpp +2 -1
- package/worker/src/RTC/RTP/Packet.cpp +26 -11
- package/worker/src/RTC/RTP/ProbationGenerator.cpp +5 -6
- package/worker/src/RTC/RTP/RtpStream.cpp +1 -1
- package/worker/src/RTC/RTP/RtpStreamRecv.cpp +69 -48
- package/worker/src/RTC/RTP/RtpStreamSend.cpp +31 -31
- package/worker/src/RTC/RTP/RtxStream.cpp +22 -7
- package/worker/src/RTC/RateCalculator.cpp +133 -28
- package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +56 -1
- package/worker/src/RTC/{RtcLogger.cpp → RtcLogger/RtpPacket.cpp} +2 -2
- package/worker/src/RTC/RtcLogger/SendBurst.cpp +124 -0
- package/worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp +2 -12
- package/worker/src/RTC/RtpDictionaries/RtpParameters.cpp +1 -1
- package/worker/src/RTC/SCTP/association/Association.cpp +16 -2
- package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +106 -1
- package/worker/src/RTC/SCTP/public/AssociationMetrics.cpp +1 -1
- package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +3 -3
- package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +2 -1
- package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +4 -4
- package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +4 -4
- package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +6 -10
- package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
- package/worker/src/RTC/SrtpSession.cpp +2 -2
- package/worker/src/RTC/SvcProducerStreamManager.cpp +2 -2
- package/worker/src/RTC/TcpConnection.cpp +2 -2
- package/worker/src/RTC/Transport.cpp +112 -75
- package/worker/src/RTC/TransportTuple.cpp +4 -4
- package/worker/src/RTC/WebRtcServer.cpp +4 -3
- package/worker/src/RTC/WebRtcTransport.cpp +20 -13
- package/worker/src/Utils/BitStream.cpp +24 -0
- package/worker/src/handles/BackoffTimerHandle.cpp +1 -1
- package/worker/src/handles/TcpConnectionHandle.cpp +13 -23
- package/worker/src/handles/UdpSocketHandle.cpp +14 -21
- package/worker/tasks.py +43 -18
- package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +68 -14
- package/worker/test/include/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.hpp +125 -0
- package/worker/test/src/RTC/BWE/TestAlrDetector.cpp +110 -0
- package/worker/test/src/RTC/BWE/TestBitrateProber.cpp +418 -0
- package/worker/test/src/RTC/BWE/TestBitrateUtils.cpp +61 -0
- package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +4 -4
- package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +53 -37
- package/worker/test/src/RTC/BWE/TestInterArrival.cpp +643 -0
- package/worker/test/src/RTC/BWE/TestIntervalBudget.cpp +130 -0
- package/worker/test/src/RTC/BWE/TestLossBasedController.cpp +1199 -0
- package/worker/test/src/RTC/BWE/TestOveruseDetector.cpp +519 -0
- package/worker/test/src/RTC/BWE/TestProbeBitrateEstimator.cpp +266 -0
- package/worker/test/src/RTC/BWE/TestProbeController.cpp +1682 -0
- package/worker/test/src/RTC/BWE/TestProbePacketGenerator.cpp +265 -0
- package/worker/test/src/RTC/BWE/TestProbingScheduler.cpp +260 -0
- package/worker/test/src/RTC/BWE/TestRembGenerator.cpp +285 -0
- package/worker/test/src/RTC/BWE/TestRemoteBitrateEstimatorAbsSendTime.cpp +414 -0
- package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +296 -77
- package/worker/test/src/RTC/BWE/TestTargetRateController.cpp +337 -0
- package/worker/test/src/RTC/BWE/TestTransportWideCcFeedbackGenerator.cpp +578 -0
- package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +45 -0
- package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +133 -29
- package/worker/test/src/RTC/BWE/helpers/RemoteBitrateEstimatorAbsSendTimeTestHelper.cpp +625 -0
- package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +19 -0
- package/worker/test/src/RTC/RTP/TestPacket.cpp +58 -4
- package/worker/test/src/RTC/RTP/TestProbationGenerator.cpp +3 -2
- package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +50 -0
- package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +59 -0
- package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +111 -0
- package/worker/test/src/RTC/TestRateCalculator.cpp +322 -60
- package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +95 -7
- package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +34 -16
- package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +31 -13
- package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +37 -19
- package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +10 -10
- 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
|