mediasoup 3.20.5 → 3.20.6
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/package.json +4 -4
- package/worker/include/RTC/Consumer.hpp +80 -45
- package/worker/include/RTC/PipeProducerStreamManager.hpp +78 -0
- package/worker/include/RTC/ProducerStreamManager.hpp +181 -0
- package/worker/include/RTC/SCTP/association/Association.hpp +24 -0
- package/worker/include/RTC/SCTP/association/StateCookie.hpp +104 -11
- package/worker/include/RTC/SCTP/packet/parameters/StateCookieParameter.hpp +4 -1
- package/worker/include/RTC/SCTP/public/SctpOptions.hpp +13 -0
- package/worker/include/RTC/SimpleProducerStreamManager.hpp +72 -0
- package/worker/include/RTC/SimulcastProducerStreamManager.hpp +93 -0
- package/worker/include/RTC/SvcProducerStreamManager.hpp +72 -0
- package/worker/include/RTC/Transport.hpp +7 -1
- package/worker/meson.build +9 -5
- package/worker/src/RTC/Consumer.cpp +1404 -30
- package/worker/src/RTC/DirectTransport.cpp +4 -1
- package/worker/src/RTC/PipeProducerStreamManager.cpp +266 -0
- package/worker/src/RTC/PipeTransport.cpp +4 -1
- package/worker/src/RTC/PlainTransport.cpp +4 -1
- package/worker/src/RTC/SCTP/association/Association.cpp +138 -1
- package/worker/src/RTC/SCTP/association/StateCookie.cpp +96 -31
- package/worker/src/RTC/SCTP/packet/Packet.cpp +1 -1
- package/worker/src/RTC/SCTP/packet/parameters/StateCookieParameter.cpp +12 -3
- package/worker/src/RTC/SCTP/public/SctpOptions.cpp +4 -0
- package/worker/src/RTC/SimpleProducerStreamManager.cpp +343 -0
- package/worker/src/RTC/SimulcastProducerStreamManager.cpp +1068 -0
- package/worker/src/RTC/SvcProducerStreamManager.cpp +664 -0
- package/worker/src/RTC/Transport.cpp +7 -44
- package/worker/src/RTC/WebRtcTransport.cpp +8 -2
- package/worker/test/include/RTC/SCTP/sctpCommon.hpp +1 -1
- package/worker/test/src/RTC/SCTP/association/TestAssociation.cpp +115 -0
- package/worker/test/src/RTC/SCTP/association/TestStateCookie.cpp +123 -0
- package/worker/test/src/RTC/SCTP/packet/TestPacket.cpp +4 -4
- package/worker/test/src/RTC/{TestSimpleConsumer.cpp → TestConsumer.cpp} +6 -7
- package/worker/test/src/RTC/TestPipeProducerStreamManager.cpp +471 -0
- package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +531 -0
- package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +1040 -0
- package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +1278 -0
- package/worker/include/RTC/PipeConsumer.hpp +0 -95
- package/worker/include/RTC/SimpleConsumer.hpp +0 -102
- package/worker/include/RTC/SimulcastConsumer.hpp +0 -141
- package/worker/include/RTC/SvcConsumer.hpp +0 -118
- package/worker/src/RTC/PipeConsumer.cpp +0 -874
- package/worker/src/RTC/SimpleConsumer.cpp +0 -882
- package/worker/src/RTC/SimulcastConsumer.cpp +0 -1887
- package/worker/src/RTC/SvcConsumer.cpp +0 -1384
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mediasoup",
|
|
3
|
-
"version": "3.20.
|
|
3
|
+
"version": "3.20.6",
|
|
4
4
|
"description": "Cutting Edge WebRTC Video Conferencing",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"@types/ini": "^4.1.1",
|
|
116
116
|
"@types/jest": "^30.0.0",
|
|
117
117
|
"@types/node": "^25.6.2",
|
|
118
|
-
"eslint": "^10.
|
|
118
|
+
"eslint": "^10.5.0",
|
|
119
119
|
"eslint-config-prettier": "^10.1.8",
|
|
120
120
|
"eslint-plugin-jest": "^29.15.2",
|
|
121
121
|
"eslint-plugin-prettier": "^5.5.6",
|
|
@@ -126,10 +126,10 @@
|
|
|
126
126
|
"marked": "^18.0.5",
|
|
127
127
|
"open-cli": "^9.0.0",
|
|
128
128
|
"pick-port": "^2.2.0",
|
|
129
|
-
"prettier": "^3.8.
|
|
129
|
+
"prettier": "^3.8.4",
|
|
130
130
|
"ts-jest": "^29.4.11",
|
|
131
131
|
"typescript": "^6.0.3",
|
|
132
|
-
"typescript-eslint": "^8.
|
|
132
|
+
"typescript-eslint": "^8.61.0",
|
|
133
133
|
"werift-sctp": "^0.0.11"
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
#include "FBS/consumer.h"
|
|
8
8
|
#include "FBS/transport.h"
|
|
9
9
|
#include "RTC/ConsumerTypes.hpp"
|
|
10
|
+
#include "RTC/ProducerStreamManager.hpp"
|
|
10
11
|
#include "RTC/RTCP/CompoundPacket.hpp"
|
|
11
12
|
#include "RTC/RTCP/FeedbackRtpNack.hpp"
|
|
12
13
|
#include "RTC/RTCP/ReceiverReport.hpp"
|
|
@@ -16,15 +17,24 @@
|
|
|
16
17
|
#include "RTC/RTP/RtpStreamSend.hpp"
|
|
17
18
|
#include "RTC/RTP/SharedPacket.hpp"
|
|
18
19
|
#include "RTC/RtpDictionaries.hpp"
|
|
20
|
+
#include "RTC/SeqManager.hpp"
|
|
21
|
+
#include "Shared.hpp"
|
|
19
22
|
#include "SharedInterface.hpp"
|
|
23
|
+
#include <ankerl/unordered_dense.h>
|
|
20
24
|
#include <bitset>
|
|
25
|
+
#include <map>
|
|
21
26
|
#include <string>
|
|
22
27
|
#include <vector>
|
|
23
28
|
|
|
24
29
|
namespace RTC
|
|
25
30
|
{
|
|
26
|
-
class Consumer : public Channel::ChannelSocket::RequestHandler
|
|
31
|
+
class Consumer : public Channel::ChannelSocket::RequestHandler,
|
|
32
|
+
public RTC::RTP::RtpStreamSend::Listener,
|
|
33
|
+
public RTC::ProducerStreamManager::Listener
|
|
27
34
|
{
|
|
35
|
+
using RetransmissionBuffer =
|
|
36
|
+
std::map<uint16_t, RTC::RTP::SharedPacket, RTC::SeqManager<uint16_t>::SeqLowerThan>;
|
|
37
|
+
|
|
28
38
|
public:
|
|
29
39
|
class Listener
|
|
30
40
|
{
|
|
@@ -56,20 +66,18 @@ namespace RTC
|
|
|
56
66
|
const std::string& id,
|
|
57
67
|
const std::string& producerId,
|
|
58
68
|
RTC::Consumer::Listener* listener,
|
|
59
|
-
const FBS::Transport::ConsumeRequest* data
|
|
60
|
-
RTC::RtpParameters::Type type);
|
|
69
|
+
const FBS::Transport::ConsumeRequest* data);
|
|
61
70
|
~Consumer() override;
|
|
62
71
|
|
|
63
72
|
public:
|
|
64
|
-
flatbuffers::Offset<FBS::Consumer::
|
|
73
|
+
flatbuffers::Offset<FBS::Consumer::DumpResponse> FillBuffer(
|
|
74
|
+
flatbuffers::FlatBufferBuilder& builder) const;
|
|
75
|
+
flatbuffers::Offset<FBS::Consumer::BaseConsumerDump> FillBufferBase(
|
|
76
|
+
flatbuffers::FlatBufferBuilder& builder) const;
|
|
77
|
+
flatbuffers::Offset<FBS::Consumer::GetStatsResponse> FillBufferStats(
|
|
78
|
+
flatbuffers::FlatBufferBuilder& builder);
|
|
79
|
+
flatbuffers::Offset<FBS::Consumer::ConsumerScore> FillBufferScore(
|
|
65
80
|
flatbuffers::FlatBufferBuilder& builder) const;
|
|
66
|
-
virtual flatbuffers::Offset<FBS::Consumer::GetStatsResponse> FillBufferStats(
|
|
67
|
-
flatbuffers::FlatBufferBuilder& builder) = 0;
|
|
68
|
-
virtual flatbuffers::Offset<FBS::Consumer::ConsumerScore> FillBufferScore(
|
|
69
|
-
flatbuffers::FlatBufferBuilder& /*builder*/) const
|
|
70
|
-
{
|
|
71
|
-
return 0;
|
|
72
|
-
};
|
|
73
81
|
RTC::Media::Kind GetKind() const
|
|
74
82
|
{
|
|
75
83
|
return this->kind;
|
|
@@ -86,12 +94,9 @@ namespace RTC
|
|
|
86
94
|
{
|
|
87
95
|
return this->type;
|
|
88
96
|
}
|
|
89
|
-
|
|
97
|
+
RTC::ConsumerTypes::VideoLayers GetPreferredLayers() const
|
|
90
98
|
{
|
|
91
|
-
|
|
92
|
-
RTC::ConsumerTypes::VideoLayers layers;
|
|
93
|
-
|
|
94
|
-
return layers;
|
|
99
|
+
return this->producerStreamManager->GetPreferredLayers();
|
|
95
100
|
}
|
|
96
101
|
const std::vector<uint32_t>& GetMediaSsrcs() const
|
|
97
102
|
{
|
|
@@ -101,10 +106,8 @@ namespace RTC
|
|
|
101
106
|
{
|
|
102
107
|
return this->rtxSsrcs;
|
|
103
108
|
}
|
|
104
|
-
|
|
109
|
+
bool IsActive() const override
|
|
105
110
|
{
|
|
106
|
-
// The parent Consumer just checks whether Consumer and Producer are
|
|
107
|
-
// not paused and the transport connected.
|
|
108
111
|
// clang-format off
|
|
109
112
|
return (
|
|
110
113
|
this->transportConnected &&
|
|
@@ -126,32 +129,30 @@ namespace RTC
|
|
|
126
129
|
}
|
|
127
130
|
void ProducerPaused();
|
|
128
131
|
void ProducerResumed();
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
void ProducerRtpStream(RTC::RTP::RtpStreamRecv* rtpStream, uint32_t mappedSsrc);
|
|
133
|
+
void ProducerNewRtpStream(RTC::RTP::RtpStreamRecv* rtpStream, uint32_t mappedSsrc);
|
|
131
134
|
void ProducerRtpStreamScores(const std::vector<uint8_t>* scores);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
virtual void ProducerRtcpSenderReport(RTC::RTP::RtpStreamRecv* rtpStream, bool first) = 0;
|
|
135
|
+
void ProducerRtpStreamScore(RTC::RTP::RtpStreamRecv* rtpStream, uint8_t score, uint8_t previousScore);
|
|
136
|
+
void ProducerRtcpSenderReport(RTC::RTP::RtpStreamRecv* rtpStream, bool first);
|
|
135
137
|
void ProducerClosed();
|
|
136
138
|
void SetExternallyManagedBitrate()
|
|
137
139
|
{
|
|
138
140
|
this->externallyManagedBitrate = true;
|
|
141
|
+
this->producerStreamManager->SetExternallyManagedBitrate();
|
|
139
142
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
virtual uint32_t GetTransmissionRate(uint64_t nowMs) = 0;
|
|
154
|
-
virtual float GetRtt() const = 0;
|
|
143
|
+
uint8_t GetBitratePriority() const;
|
|
144
|
+
uint32_t IncreaseLayer(uint32_t bitrate, bool considerLoss);
|
|
145
|
+
void ApplyLayers();
|
|
146
|
+
uint32_t GetDesiredBitrate() const;
|
|
147
|
+
void SendRtpPacket(RTC::RTP::Packet* packet, RTC::RTP::SharedPacket& sharedPacket);
|
|
148
|
+
bool GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs);
|
|
149
|
+
void NeedWorstRemoteFractionLost(uint32_t mappedSsrc, uint8_t& worstRemoteFractionLost);
|
|
150
|
+
void ReceiveNack(RTC::RTCP::FeedbackRtpNackPacket* nackPacket);
|
|
151
|
+
void ReceiveKeyFrameRequest(RTC::RTCP::FeedbackPs::MessageType messageType, uint32_t ssrc);
|
|
152
|
+
void ReceiveRtcpReceiverReport(RTC::RTCP::ReceiverReport* report);
|
|
153
|
+
void ReceiveRtcpXrReceiverReferenceTime(RTC::RTCP::ReceiverReferenceTime* report);
|
|
154
|
+
uint32_t GetTransmissionRate(uint64_t nowMs);
|
|
155
|
+
float GetRtt() const;
|
|
155
156
|
|
|
156
157
|
/* Methods inherited from Channel::ChannelSocket::RequestHandler. */
|
|
157
158
|
public:
|
|
@@ -165,10 +166,35 @@ namespace RTC
|
|
|
165
166
|
void EmitTraceEvent(flatbuffers::Offset<FBS::Consumer::TraceNotification>& notification) const;
|
|
166
167
|
|
|
167
168
|
private:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
void EmitScore() const;
|
|
170
|
+
void EmitLayersChange() const;
|
|
171
|
+
|
|
172
|
+
private:
|
|
173
|
+
void UserOnTransportConnected();
|
|
174
|
+
void UserOnTransportDisconnected();
|
|
175
|
+
void UserOnPaused();
|
|
176
|
+
void UserOnResumed();
|
|
177
|
+
|
|
178
|
+
private:
|
|
179
|
+
void CreateRtpStreams();
|
|
180
|
+
static void StorePacketInTargetLayerRetransmissionBuffer(
|
|
181
|
+
RetransmissionBuffer& targetLayerRetransmissionBuffer,
|
|
182
|
+
RTC::RTP::Packet* packet,
|
|
183
|
+
RTC::RTP::SharedPacket& sharedPacket);
|
|
184
|
+
|
|
185
|
+
/* Pure virtual methods inherited from RtpStreamSend::Listener. */
|
|
186
|
+
public:
|
|
187
|
+
void OnRtpStreamScore(RTC::RTP::RtpStream* rtpStream, uint8_t score, uint8_t previousScore) override;
|
|
188
|
+
void OnRtpStreamRetransmitRtpPacket(
|
|
189
|
+
RTC::RTP::RtpStreamSend* rtpStream, RTC::RTP::Packet* packet) override;
|
|
190
|
+
|
|
191
|
+
/* Pure virtual methods inherited from ProducerStreamManager::Listener. */
|
|
192
|
+
public:
|
|
193
|
+
void OnProducerStreamManagerKeyFrameRequested(uint32_t mappedSsrc) override;
|
|
194
|
+
void OnProducerStreamManagerNeedBitrateChange() override;
|
|
195
|
+
void OnProducerStreamManagerLayersChanged() override;
|
|
196
|
+
void OnProducerStreamManagerClearRetransmissionBuffer() override;
|
|
197
|
+
void OnProducerStreamManagerScore() override;
|
|
172
198
|
|
|
173
199
|
public:
|
|
174
200
|
// Passed by argument.
|
|
@@ -186,8 +212,6 @@ namespace RTC
|
|
|
186
212
|
struct RTC::RTP::HeaderExtensionIds rtpHeaderExtensionIds;
|
|
187
213
|
const std::vector<uint8_t>* producerRtpStreamScores{ nullptr };
|
|
188
214
|
// Others.
|
|
189
|
-
// Whether a payload type is supported or not is represented in the
|
|
190
|
-
// corresponding position of the bitset.
|
|
191
215
|
std::bitset<128u> supportedCodecPayloadTypes;
|
|
192
216
|
uint64_t lastRtcpSentTime{ 0u };
|
|
193
217
|
uint16_t maxRtcpInterval{ 0u };
|
|
@@ -196,13 +220,24 @@ namespace RTC
|
|
|
196
220
|
struct TraceEventTypes traceEventTypes;
|
|
197
221
|
|
|
198
222
|
private:
|
|
223
|
+
bool pipe{ false };
|
|
199
224
|
// Others.
|
|
225
|
+
std::vector<RTC::RTP::RtpStreamSend*> rtpStreams;
|
|
226
|
+
ankerl::unordered_dense::map<uint32_t, uint32_t> mapMappedSsrcSsrc;
|
|
227
|
+
ankerl::unordered_dense::map<uint32_t, RTC::RTP::RtpStreamSend*> mapSsrcRtpStream;
|
|
228
|
+
ankerl::unordered_dense::map<RTC::RTP::RtpStreamSend*, RTC::SeqManager<uint16_t>> mapRtpStreamRtpSeqManager;
|
|
229
|
+
// Buffers to store packets that arrive earlier than the first packet of the
|
|
230
|
+
// video key frame.
|
|
231
|
+
ankerl::unordered_dense::map<RTC::RTP::RtpStreamSend*, RetransmissionBuffer>
|
|
232
|
+
mapRtpStreamTargetLayerRetransmissionBuffer;
|
|
200
233
|
std::vector<uint32_t> mediaSsrcs;
|
|
201
234
|
std::vector<uint32_t> rtxSsrcs;
|
|
202
235
|
bool transportConnected{ false };
|
|
203
236
|
bool paused{ false };
|
|
204
237
|
bool producerPaused{ false };
|
|
205
238
|
bool producerClosed{ false };
|
|
239
|
+
bool lastSentPacketHasMarker{ false };
|
|
240
|
+
std::unique_ptr<RTC::ProducerStreamManager> producerStreamManager;
|
|
206
241
|
};
|
|
207
242
|
} // namespace RTC
|
|
208
243
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#ifndef MS_RTC_PIPE_PRODUCER_STREAM_MANAGER_HPP
|
|
2
|
+
#define MS_RTC_PIPE_PRODUCER_STREAM_MANAGER_HPP
|
|
3
|
+
|
|
4
|
+
#include "RTC/ProducerStreamManager.hpp"
|
|
5
|
+
#include <ankerl/unordered_dense.h>
|
|
6
|
+
|
|
7
|
+
namespace RTC
|
|
8
|
+
{
|
|
9
|
+
class PipeProducerStreamManager : public ProducerStreamManager
|
|
10
|
+
{
|
|
11
|
+
public:
|
|
12
|
+
PipeProducerStreamManager(
|
|
13
|
+
const std::vector<RTC::RtpEncodingParameters>& consumableRtpEncodings,
|
|
14
|
+
const RTC::ConsumerTypes::VideoLayers& preferredLayers,
|
|
15
|
+
std::unique_ptr<RTC::RTP::Codecs::EncodingContext> encodingContext,
|
|
16
|
+
RTC::Media::Kind kind,
|
|
17
|
+
bool keyFrameSupported,
|
|
18
|
+
Listener* listener,
|
|
19
|
+
SharedInterface* shared);
|
|
20
|
+
|
|
21
|
+
public:
|
|
22
|
+
RTC::ConsumerTypes::VideoLayers GetTargetLayers() const override
|
|
23
|
+
{
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
int16_t GetCurrentSpatialLayer() const override
|
|
27
|
+
{
|
|
28
|
+
return -1;
|
|
29
|
+
}
|
|
30
|
+
int16_t GetCurrentTemporalLayer() const override
|
|
31
|
+
{
|
|
32
|
+
return -1;
|
|
33
|
+
}
|
|
34
|
+
RTC::RTP::RtpStreamRecv* GetProducerCurrentRtpStream() const override
|
|
35
|
+
{
|
|
36
|
+
return nullptr;
|
|
37
|
+
}
|
|
38
|
+
RTC::RTP::RtpStreamRecv* GetProducerTargetRtpStream() const override
|
|
39
|
+
{
|
|
40
|
+
return nullptr;
|
|
41
|
+
}
|
|
42
|
+
bool IsPacketForCurrentStream(const RTC::RTP::Packet* /*packet*/) const override
|
|
43
|
+
{
|
|
44
|
+
// Pipe has no concept of "current" stream — all packets belong.
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
bool IsActive() const override;
|
|
48
|
+
void ProducerRtpStream(RTC::RTP::RtpStreamRecv* rtpStream, uint32_t mappedSsrc) override;
|
|
49
|
+
void ProducerNewRtpStream(RTC::RTP::RtpStreamRecv* rtpStream, uint32_t mappedSsrc) override;
|
|
50
|
+
void ProducerRtpStreamScore(
|
|
51
|
+
RTC::RTP::RtpStreamRecv* rtpStream, uint8_t score, uint8_t previousScore) override;
|
|
52
|
+
void ProducerRtcpSenderReport(RTC::RTP::RtpStreamRecv* rtpStream, bool first) override;
|
|
53
|
+
uint32_t IncreaseLayer(
|
|
54
|
+
uint32_t bitrate, bool considerLoss, float lossPercentage, uint64_t nowMs) override;
|
|
55
|
+
void ApplyLayers(uint64_t rtpStreamActiveMs) override;
|
|
56
|
+
uint32_t GetDesiredBitrate(uint64_t nowMs) const override;
|
|
57
|
+
RtpPacketProcessResult ProcessRtpPacket(
|
|
58
|
+
RTC::RTP::Packet* packet,
|
|
59
|
+
bool lastSentPacketHasMarker,
|
|
60
|
+
uint32_t clockRate,
|
|
61
|
+
uint32_t maxPacketTs) override;
|
|
62
|
+
void RequestKeyFrame() override;
|
|
63
|
+
void RequestKeyFrameForTargetSpatialLayer() override;
|
|
64
|
+
void RequestKeyFrameForCurrentSpatialLayer() override;
|
|
65
|
+
void UpdateTargetLayers(int16_t spatial, int16_t temporal) override;
|
|
66
|
+
bool RecalculateTargetLayers(RTC::ConsumerTypes::VideoLayers& newTargetLayers) const override;
|
|
67
|
+
void OnTransportConnected() override;
|
|
68
|
+
void OnTransportDisconnected() override;
|
|
69
|
+
void OnPaused() override;
|
|
70
|
+
void OnResumed() override;
|
|
71
|
+
|
|
72
|
+
private:
|
|
73
|
+
// Per-stream sync state, keyed by mapped SSRC.
|
|
74
|
+
ankerl::unordered_dense::map<uint32_t, bool> mapMappedSsrcSyncRequired;
|
|
75
|
+
};
|
|
76
|
+
} // namespace RTC
|
|
77
|
+
|
|
78
|
+
#endif
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#ifndef MS_RTC_PRODUCER_STREAM_MANAGER_HPP
|
|
2
|
+
#define MS_RTC_PRODUCER_STREAM_MANAGER_HPP
|
|
3
|
+
|
|
4
|
+
#include "common.hpp"
|
|
5
|
+
#include "RTC/ConsumerTypes.hpp"
|
|
6
|
+
#include "RTC/RTP/Codecs/PayloadDescriptorHandler.hpp"
|
|
7
|
+
#include "RTC/RTP/Packet.hpp"
|
|
8
|
+
#include "RTC/RTP/RtpStreamRecv.hpp"
|
|
9
|
+
#include "RTC/RtpDictionaries.hpp"
|
|
10
|
+
#include "SharedInterface.hpp"
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace RTC
|
|
14
|
+
{
|
|
15
|
+
class ProducerStreamManager
|
|
16
|
+
{
|
|
17
|
+
public:
|
|
18
|
+
class Listener
|
|
19
|
+
{
|
|
20
|
+
public:
|
|
21
|
+
virtual ~Listener() = default;
|
|
22
|
+
|
|
23
|
+
public:
|
|
24
|
+
virtual bool IsActive() const = 0;
|
|
25
|
+
virtual void OnProducerStreamManagerKeyFrameRequested(uint32_t mappedSsrc) = 0;
|
|
26
|
+
virtual void OnProducerStreamManagerNeedBitrateChange() = 0;
|
|
27
|
+
virtual void OnProducerStreamManagerLayersChanged() = 0;
|
|
28
|
+
virtual void OnProducerStreamManagerClearRetransmissionBuffer() = 0;
|
|
29
|
+
virtual void OnProducerStreamManagerScore() = 0;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
struct RtpPacketProcessResult
|
|
33
|
+
{
|
|
34
|
+
enum class Type : uint8_t
|
|
35
|
+
{
|
|
36
|
+
FORWARD,
|
|
37
|
+
DROP,
|
|
38
|
+
SILENT_DROP,
|
|
39
|
+
BUFFER
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
Type type{ Type::FORWARD };
|
|
43
|
+
|
|
44
|
+
// Valid when type == FORWARD:
|
|
45
|
+
uint32_t tsOffset{ 0u };
|
|
46
|
+
bool isSyncPacket{ false };
|
|
47
|
+
uint16_t syncSeqValue{ 0u };
|
|
48
|
+
bool shouldSyncEncodingContext{ false };
|
|
49
|
+
bool spatialLayerSwitched{ false };
|
|
50
|
+
bool temporalLayerChanged{ false };
|
|
51
|
+
bool marker{ false };
|
|
52
|
+
bool sendBufferedPackets{ false };
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
public:
|
|
56
|
+
ProducerStreamManager(
|
|
57
|
+
const std::vector<RTC::RtpEncodingParameters>& consumableRtpEncodings,
|
|
58
|
+
const RTC::ConsumerTypes::VideoLayers& preferredLayers,
|
|
59
|
+
std::unique_ptr<RTC::RTP::Codecs::EncodingContext> encodingContext,
|
|
60
|
+
RTC::Media::Kind kind,
|
|
61
|
+
bool keyFrameSupported,
|
|
62
|
+
Listener* listener,
|
|
63
|
+
SharedInterface* shared)
|
|
64
|
+
: listener(listener),
|
|
65
|
+
shared(shared),
|
|
66
|
+
keyFrameSupported(keyFrameSupported),
|
|
67
|
+
kind(kind),
|
|
68
|
+
consumableRtpEncodings(consumableRtpEncodings),
|
|
69
|
+
encodingContext(std::move(encodingContext)),
|
|
70
|
+
preferredLayers(preferredLayers)
|
|
71
|
+
{
|
|
72
|
+
}
|
|
73
|
+
virtual ~ProducerStreamManager() = default;
|
|
74
|
+
|
|
75
|
+
public:
|
|
76
|
+
virtual RTC::ConsumerTypes::VideoLayers GetTargetLayers() const = 0;
|
|
77
|
+
virtual int16_t GetCurrentSpatialLayer() const = 0;
|
|
78
|
+
virtual int16_t GetCurrentTemporalLayer() const = 0;
|
|
79
|
+
virtual RTC::RTP::RtpStreamRecv* GetProducerCurrentRtpStream() const = 0;
|
|
80
|
+
virtual RTC::RTP::RtpStreamRecv* GetProducerTargetRtpStream() const = 0;
|
|
81
|
+
// Returns true if the given packet belongs to the stream currently being
|
|
82
|
+
// forwarded to the consumer. Used by Consumer to decide whether to account
|
|
83
|
+
// a discarded packet in the RTP sequence manager.
|
|
84
|
+
virtual bool IsPacketForCurrentStream(const RTC::RTP::Packet* packet) const = 0;
|
|
85
|
+
RTC::RTP::Codecs::EncodingContext* GetEncodingContext() const
|
|
86
|
+
{
|
|
87
|
+
return this->encodingContext.get();
|
|
88
|
+
}
|
|
89
|
+
const RTC::ConsumerTypes::VideoLayers& GetPreferredLayers() const
|
|
90
|
+
{
|
|
91
|
+
return this->preferredLayers;
|
|
92
|
+
}
|
|
93
|
+
void SetPreferredLayers(const RTC::ConsumerTypes::VideoLayers& layers)
|
|
94
|
+
{
|
|
95
|
+
this->preferredLayers = layers;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
virtual void ProducerRtpStream(RTC::RTP::RtpStreamRecv* rtpStream, uint32_t mappedSsrc) = 0;
|
|
99
|
+
virtual void ProducerNewRtpStream(RTC::RTP::RtpStreamRecv* rtpStream, uint32_t mappedSsrc) = 0;
|
|
100
|
+
virtual void ProducerRtpStreamScore(
|
|
101
|
+
RTC::RTP::RtpStreamRecv* rtpStream, uint8_t score, uint8_t previousScore) = 0;
|
|
102
|
+
virtual void ProducerRtcpSenderReport(RTC::RTP::RtpStreamRecv* rtpStream, bool first) = 0;
|
|
103
|
+
|
|
104
|
+
void SetExternallyManagedBitrate()
|
|
105
|
+
{
|
|
106
|
+
this->externallyManagedBitrate = true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
virtual uint32_t IncreaseLayer(
|
|
110
|
+
uint32_t bitrate, bool considerLoss, float lossPercentage, uint64_t nowMs) = 0;
|
|
111
|
+
virtual void ApplyLayers(uint64_t rtpStreamActiveMs) = 0;
|
|
112
|
+
virtual uint32_t GetDesiredBitrate(uint64_t nowMs) const = 0;
|
|
113
|
+
|
|
114
|
+
virtual RtpPacketProcessResult ProcessRtpPacket(
|
|
115
|
+
RTC::RTP::Packet* packet,
|
|
116
|
+
bool lastSentPacketHasMarker,
|
|
117
|
+
uint32_t clockRate,
|
|
118
|
+
uint32_t maxPacketTs) = 0;
|
|
119
|
+
|
|
120
|
+
virtual void RequestKeyFrame() = 0;
|
|
121
|
+
virtual void RequestKeyFrameForTargetSpatialLayer() = 0;
|
|
122
|
+
virtual void RequestKeyFrameForCurrentSpatialLayer() = 0;
|
|
123
|
+
|
|
124
|
+
virtual void UpdateTargetLayers(int16_t newTargetSpatialLayer, int16_t newTargetTemporalLayer) = 0;
|
|
125
|
+
virtual bool RecalculateTargetLayers(RTC::ConsumerTypes::VideoLayers& newTargetLayers) const = 0;
|
|
126
|
+
|
|
127
|
+
void MayChangeLayers(bool force)
|
|
128
|
+
{
|
|
129
|
+
RTC::ConsumerTypes::VideoLayers newTargetLayers;
|
|
130
|
+
|
|
131
|
+
if (RecalculateTargetLayers(newTargetLayers))
|
|
132
|
+
{
|
|
133
|
+
// If bitrate externally managed, don't bother the transport unless
|
|
134
|
+
// the newTargetSpatialLayer has changed (or force is true).
|
|
135
|
+
// This is because, if bitrate is externally managed, the target temporal
|
|
136
|
+
// layer is managed by the available given bitrate so the transport
|
|
137
|
+
// will let us change it when it considers.
|
|
138
|
+
if (this->externallyManagedBitrate)
|
|
139
|
+
{
|
|
140
|
+
if (newTargetLayers.spatial != GetTargetLayers().spatial || force)
|
|
141
|
+
{
|
|
142
|
+
this->listener->OnProducerStreamManagerNeedBitrateChange();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else
|
|
146
|
+
{
|
|
147
|
+
UpdateTargetLayers(newTargetLayers.spatial, newTargetLayers.temporal);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
virtual void OnTransportConnected() = 0;
|
|
152
|
+
virtual void OnTransportDisconnected() = 0;
|
|
153
|
+
virtual void OnPaused() = 0;
|
|
154
|
+
virtual void OnResumed() = 0;
|
|
155
|
+
|
|
156
|
+
protected:
|
|
157
|
+
virtual bool IsActive() const = 0;
|
|
158
|
+
|
|
159
|
+
// Passed by argument.
|
|
160
|
+
Listener* listener{ nullptr };
|
|
161
|
+
SharedInterface* shared{ nullptr };
|
|
162
|
+
bool keyFrameSupported{ false };
|
|
163
|
+
RTC::Media::Kind kind{};
|
|
164
|
+
std::vector<RTC::RtpEncodingParameters> consumableRtpEncodings;
|
|
165
|
+
|
|
166
|
+
// Encoding context.
|
|
167
|
+
std::unique_ptr<RTC::RTP::Codecs::EncodingContext> encodingContext;
|
|
168
|
+
|
|
169
|
+
// Externally managed bitrate.
|
|
170
|
+
bool externallyManagedBitrate{ false };
|
|
171
|
+
|
|
172
|
+
// Layer preferences.
|
|
173
|
+
RTC::ConsumerTypes::VideoLayers preferredLayers;
|
|
174
|
+
RTC::ConsumerTypes::VideoLayers provisionalTargetLayers;
|
|
175
|
+
|
|
176
|
+
// Sync state.
|
|
177
|
+
bool syncRequired{ false };
|
|
178
|
+
};
|
|
179
|
+
} // namespace RTC
|
|
180
|
+
|
|
181
|
+
#endif
|
|
@@ -168,6 +168,14 @@ namespace RTC
|
|
|
168
168
|
bool usesZeroChecksum{ false };
|
|
169
169
|
};
|
|
170
170
|
|
|
171
|
+
private:
|
|
172
|
+
/**
|
|
173
|
+
* Length of the per-association random secret key used to authenticate the
|
|
174
|
+
* State Cookies we generate when `SctpOptions::requireAuthenticatedCookie`
|
|
175
|
+
* is enabled.
|
|
176
|
+
*/
|
|
177
|
+
static constexpr size_t StateCookieSecretLength{ 32 };
|
|
178
|
+
|
|
171
179
|
public:
|
|
172
180
|
explicit Association(
|
|
173
181
|
const SctpOptions& sctpOptions,
|
|
@@ -470,6 +478,19 @@ namespace RTC
|
|
|
470
478
|
bool HandleReceivedUnknownChunk(
|
|
471
479
|
const Packet* receivedPacket, const UnknownChunk* receivedUnknownChunk);
|
|
472
480
|
|
|
481
|
+
/**
|
|
482
|
+
* Verify the MAC and freshness of an authenticated State Cookie received
|
|
483
|
+
* in a COOKIE-ECHO chunk. Only called when
|
|
484
|
+
* `SctpOptions::requireAuthenticatedCookie` is enabled.
|
|
485
|
+
*
|
|
486
|
+
* Returns `true` if the cookie is authentic and not stale, `false`
|
|
487
|
+
* otherwise (in which case the COOKIE-ECHO must be discarded). A Stale
|
|
488
|
+
* Cookie ERROR chunk is sent to the peer if the cookie is stale.
|
|
489
|
+
*
|
|
490
|
+
* @see RFC 9260 section 5.1.4.
|
|
491
|
+
*/
|
|
492
|
+
bool VerifyReceivedStateCookie(const StateCookie* cookie);
|
|
493
|
+
|
|
473
494
|
void OnT1InitTimer(uint64_t& baseTimeoutMs, bool& stop);
|
|
474
495
|
|
|
475
496
|
void OnT1CookieTimer(uint64_t& baseTimeoutMs, bool& stop);
|
|
@@ -540,6 +561,9 @@ namespace RTC
|
|
|
540
561
|
// Whether `MayConnect()` should be called when SCTP data is received.
|
|
541
562
|
// See the constructor for details.
|
|
542
563
|
bool mayConnectOnReceivedSctpData;
|
|
564
|
+
// Per-association random secret key used to authenticate the State Cookies
|
|
565
|
+
// we generate when `SctpOptions::requireAuthenticatedCookie` is enabled.
|
|
566
|
+
uint8_t stateCookieSecret[Association::StateCookieSecretLength]{};
|
|
543
567
|
};
|
|
544
568
|
} // namespace SCTP
|
|
545
569
|
} // namespace RTC
|