1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/rtp_rtcp/source/rtp_sender.h"
12
13 #include <algorithm>
14 #include <limits>
15 #include <memory>
16 #include <string>
17 #include <utility>
18
19 #include "absl/strings/match.h"
20 #include "api/array_view.h"
21 #include "api/rtc_event_log/rtc_event_log.h"
22 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
23 #include "modules/rtp_rtcp/include/rtp_cvo.h"
24 #include "modules/rtp_rtcp/source/byte_io.h"
25 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
26 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
27 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
28 #include "modules/rtp_rtcp/source/time_util.h"
29 #include "rtc_base/arraysize.h"
30 #include "rtc_base/checks.h"
31 #include "rtc_base/experiments/field_trial_parser.h"
32 #include "rtc_base/logging.h"
33 #include "rtc_base/numerics/safe_minmax.h"
34 #include "rtc_base/rate_limiter.h"
35 #include "rtc_base/time_utils.h"
36
37 namespace webrtc {
38
39 namespace {
40 // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
41 constexpr size_t kMaxPaddingLength = 224;
42 constexpr size_t kMinAudioPaddingLength = 50;
43 constexpr size_t kRtpHeaderLength = 12;
44 constexpr uint16_t kMaxInitRtpSeqNumber = 32767; // 2^15 -1.
45 constexpr uint32_t kTimestampTicksPerMs = 90;
46
47 // Min size needed to get payload padding from packet history.
48 constexpr int kMinPayloadPaddingBytes = 50;
49
50 template <typename Extension>
CreateExtensionSize()51 constexpr RtpExtensionSize CreateExtensionSize() {
52 return {Extension::kId, Extension::kValueSizeBytes};
53 }
54
55 template <typename Extension>
CreateMaxExtensionSize()56 constexpr RtpExtensionSize CreateMaxExtensionSize() {
57 return {Extension::kId, Extension::kMaxValueSizeBytes};
58 }
59
60 // Size info for header extensions that might be used in padding or FEC packets.
61 constexpr RtpExtensionSize kFecOrPaddingExtensionSizes[] = {
62 CreateExtensionSize<AbsoluteSendTime>(),
63 CreateExtensionSize<TransmissionOffset>(),
64 CreateExtensionSize<TransportSequenceNumber>(),
65 CreateExtensionSize<PlayoutDelayLimits>(),
66 CreateMaxExtensionSize<RtpMid>(),
67 CreateExtensionSize<VideoTimingExtension>(),
68 };
69
70 // Size info for header extensions that might be used in video packets.
71 constexpr RtpExtensionSize kVideoExtensionSizes[] = {
72 CreateExtensionSize<AbsoluteSendTime>(),
73 CreateExtensionSize<AbsoluteCaptureTimeExtension>(),
74 CreateExtensionSize<TransmissionOffset>(),
75 CreateExtensionSize<TransportSequenceNumber>(),
76 CreateExtensionSize<PlayoutDelayLimits>(),
77 CreateExtensionSize<VideoOrientation>(),
78 CreateExtensionSize<VideoContentTypeExtension>(),
79 CreateExtensionSize<VideoTimingExtension>(),
80 CreateMaxExtensionSize<RtpStreamId>(),
81 CreateMaxExtensionSize<RepairedRtpStreamId>(),
82 CreateMaxExtensionSize<RtpMid>(),
83 {RtpGenericFrameDescriptorExtension00::kId,
84 RtpGenericFrameDescriptorExtension00::kMaxSizeBytes},
85 };
86
87 // Size info for header extensions that might be used in audio packets.
88 constexpr RtpExtensionSize kAudioExtensionSizes[] = {
89 CreateExtensionSize<AbsoluteSendTime>(),
90 CreateExtensionSize<AbsoluteCaptureTimeExtension>(),
91 CreateExtensionSize<AudioLevel>(),
92 CreateExtensionSize<InbandComfortNoiseExtension>(),
93 CreateExtensionSize<TransmissionOffset>(),
94 CreateExtensionSize<TransportSequenceNumber>(),
95 CreateMaxExtensionSize<RtpStreamId>(),
96 CreateMaxExtensionSize<RepairedRtpStreamId>(),
97 CreateMaxExtensionSize<RtpMid>(),
98 };
99
100 // Non-volatile extensions can be expected on all packets, if registered.
101 // Volatile ones, such as VideoContentTypeExtension which is only set on
102 // key-frames, are removed to simplify overhead calculations at the expense of
103 // some accuracy.
IsNonVolatile(RTPExtensionType type)104 bool IsNonVolatile(RTPExtensionType type) {
105 switch (type) {
106 case kRtpExtensionTransmissionTimeOffset:
107 case kRtpExtensionAudioLevel:
108 case kRtpExtensionAbsoluteSendTime:
109 case kRtpExtensionTransportSequenceNumber:
110 case kRtpExtensionTransportSequenceNumber02:
111 case kRtpExtensionRtpStreamId:
112 case kRtpExtensionMid:
113 case kRtpExtensionGenericFrameDescriptor00:
114 case kRtpExtensionGenericFrameDescriptor02:
115 return true;
116 case kRtpExtensionInbandComfortNoise:
117 case kRtpExtensionAbsoluteCaptureTime:
118 case kRtpExtensionVideoRotation:
119 case kRtpExtensionPlayoutDelay:
120 case kRtpExtensionVideoContentType:
121 case kRtpExtensionVideoTiming:
122 case kRtpExtensionRepairedRtpStreamId:
123 case kRtpExtensionColorSpace:
124 return false;
125 case kRtpExtensionNone:
126 case kRtpExtensionNumberOfExtensions:
127 RTC_NOTREACHED();
128 return false;
129 }
130 }
131
HasBweExtension(const RtpHeaderExtensionMap & extensions_map)132 bool HasBweExtension(const RtpHeaderExtensionMap& extensions_map) {
133 return extensions_map.IsRegistered(kRtpExtensionTransportSequenceNumber) ||
134 extensions_map.IsRegistered(kRtpExtensionTransportSequenceNumber02) ||
135 extensions_map.IsRegistered(kRtpExtensionAbsoluteSendTime) ||
136 extensions_map.IsRegistered(kRtpExtensionTransmissionTimeOffset);
137 }
138
GetMaxPaddingSizeFactor(const WebRtcKeyValueConfig * field_trials)139 double GetMaxPaddingSizeFactor(const WebRtcKeyValueConfig* field_trials) {
140 // Too low factor means RTX payload padding is rarely used and ineffective.
141 // Too high means we risk interrupting regular media packets.
142 // In practice, 3x seems to yield reasonable results.
143 constexpr double kDefaultFactor = 3.0;
144 if (!field_trials) {
145 return kDefaultFactor;
146 }
147
148 FieldTrialOptional<double> factor("factor", kDefaultFactor);
149 ParseFieldTrial({&factor}, field_trials->Lookup("WebRTC-LimitPaddingSize"));
150 RTC_CHECK_GE(factor.Value(), 0.0);
151 return factor.Value();
152 }
153
154 } // namespace
155
RTPSender(const RtpRtcpInterface::Configuration & config,RtpPacketHistory * packet_history,RtpPacketSender * packet_sender)156 RTPSender::RTPSender(const RtpRtcpInterface::Configuration& config,
157 RtpPacketHistory* packet_history,
158 RtpPacketSender* packet_sender)
159 : clock_(config.clock),
160 random_(clock_->TimeInMicroseconds()),
161 audio_configured_(config.audio),
162 ssrc_(config.local_media_ssrc),
163 rtx_ssrc_(config.rtx_send_ssrc),
164 flexfec_ssrc_(config.fec_generator ? config.fec_generator->FecSsrc()
165 : absl::nullopt),
166 max_padding_size_factor_(GetMaxPaddingSizeFactor(config.field_trials)),
167 packet_history_(packet_history),
168 paced_sender_(packet_sender),
169 sending_media_(true), // Default to sending media.
170 max_packet_size_(IP_PACKET_SIZE - 28), // Default is IP-v4/UDP.
171 last_payload_type_(-1),
172 rtp_header_extension_map_(config.extmap_allow_mixed),
173 max_media_packet_header_(kRtpHeaderSize),
174 max_padding_fec_packet_header_(kRtpHeaderSize),
175 // RTP variables
176 sequence_number_forced_(false),
177 always_send_mid_and_rid_(config.always_send_mid_and_rid),
178 ssrc_has_acked_(false),
179 rtx_ssrc_has_acked_(false),
180 last_rtp_timestamp_(0),
181 capture_time_ms_(0),
182 last_timestamp_time_ms_(0),
183 last_packet_marker_bit_(false),
184 csrcs_(),
185 rtx_(kRtxOff),
186 supports_bwe_extension_(false),
187 retransmission_rate_limiter_(config.retransmission_rate_limiter) {
188 // This random initialization is not intended to be cryptographic strong.
189 timestamp_offset_ = random_.Rand<uint32_t>();
190 // Random start, 16 bits. Can't be 0.
191 sequence_number_rtx_ = random_.Rand(1, kMaxInitRtpSeqNumber);
192 sequence_number_ = random_.Rand(1, kMaxInitRtpSeqNumber);
193
194 RTC_DCHECK(paced_sender_);
195 RTC_DCHECK(packet_history_);
196 }
197
~RTPSender()198 RTPSender::~RTPSender() {
199 // TODO(tommi): Use a thread checker to ensure the object is created and
200 // deleted on the same thread. At the moment this isn't possible due to
201 // voe::ChannelOwner in voice engine. To reproduce, run:
202 // voe_auto_test --automated --gtest_filter=*MixManyChannelsForStressOpus
203
204 // TODO(tommi,holmer): We don't grab locks in the dtor before accessing member
205 // variables but we grab them in all other methods. (what's the design?)
206 // Start documenting what thread we're on in what method so that it's easier
207 // to understand performance attributes and possibly remove locks.
208 }
209
FecExtensionSizes()210 rtc::ArrayView<const RtpExtensionSize> RTPSender::FecExtensionSizes() {
211 return rtc::MakeArrayView(kFecOrPaddingExtensionSizes,
212 arraysize(kFecOrPaddingExtensionSizes));
213 }
214
VideoExtensionSizes()215 rtc::ArrayView<const RtpExtensionSize> RTPSender::VideoExtensionSizes() {
216 return rtc::MakeArrayView(kVideoExtensionSizes,
217 arraysize(kVideoExtensionSizes));
218 }
219
AudioExtensionSizes()220 rtc::ArrayView<const RtpExtensionSize> RTPSender::AudioExtensionSizes() {
221 return rtc::MakeArrayView(kAudioExtensionSizes,
222 arraysize(kAudioExtensionSizes));
223 }
224
SetExtmapAllowMixed(bool extmap_allow_mixed)225 void RTPSender::SetExtmapAllowMixed(bool extmap_allow_mixed) {
226 MutexLock lock(&send_mutex_);
227 rtp_header_extension_map_.SetExtmapAllowMixed(extmap_allow_mixed);
228 }
229
RegisterRtpHeaderExtension(RTPExtensionType type,uint8_t id)230 int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type,
231 uint8_t id) {
232 MutexLock lock(&send_mutex_);
233 bool registered = rtp_header_extension_map_.RegisterByType(id, type);
234 supports_bwe_extension_ = HasBweExtension(rtp_header_extension_map_);
235 UpdateHeaderSizes();
236 return registered ? 0 : -1;
237 }
238
RegisterRtpHeaderExtension(absl::string_view uri,int id)239 bool RTPSender::RegisterRtpHeaderExtension(absl::string_view uri, int id) {
240 MutexLock lock(&send_mutex_);
241 bool registered = rtp_header_extension_map_.RegisterByUri(id, uri);
242 supports_bwe_extension_ = HasBweExtension(rtp_header_extension_map_);
243 UpdateHeaderSizes();
244 return registered;
245 }
246
IsRtpHeaderExtensionRegistered(RTPExtensionType type) const247 bool RTPSender::IsRtpHeaderExtensionRegistered(RTPExtensionType type) const {
248 MutexLock lock(&send_mutex_);
249 return rtp_header_extension_map_.IsRegistered(type);
250 }
251
DeregisterRtpHeaderExtension(RTPExtensionType type)252 int32_t RTPSender::DeregisterRtpHeaderExtension(RTPExtensionType type) {
253 MutexLock lock(&send_mutex_);
254 rtp_header_extension_map_.Deregister(type);
255 supports_bwe_extension_ = HasBweExtension(rtp_header_extension_map_);
256 UpdateHeaderSizes();
257 return 0;
258 }
259
DeregisterRtpHeaderExtension(absl::string_view uri)260 void RTPSender::DeregisterRtpHeaderExtension(absl::string_view uri) {
261 MutexLock lock(&send_mutex_);
262 rtp_header_extension_map_.Deregister(uri);
263 supports_bwe_extension_ = HasBweExtension(rtp_header_extension_map_);
264 UpdateHeaderSizes();
265 }
266
SetMaxRtpPacketSize(size_t max_packet_size)267 void RTPSender::SetMaxRtpPacketSize(size_t max_packet_size) {
268 RTC_DCHECK_GE(max_packet_size, 100);
269 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE);
270 MutexLock lock(&send_mutex_);
271 max_packet_size_ = max_packet_size;
272 }
273
MaxRtpPacketSize() const274 size_t RTPSender::MaxRtpPacketSize() const {
275 return max_packet_size_;
276 }
277
SetRtxStatus(int mode)278 void RTPSender::SetRtxStatus(int mode) {
279 MutexLock lock(&send_mutex_);
280 rtx_ = mode;
281 }
282
RtxStatus() const283 int RTPSender::RtxStatus() const {
284 MutexLock lock(&send_mutex_);
285 return rtx_;
286 }
287
SetRtxPayloadType(int payload_type,int associated_payload_type)288 void RTPSender::SetRtxPayloadType(int payload_type,
289 int associated_payload_type) {
290 MutexLock lock(&send_mutex_);
291 RTC_DCHECK_LE(payload_type, 127);
292 RTC_DCHECK_LE(associated_payload_type, 127);
293 if (payload_type < 0) {
294 RTC_LOG(LS_ERROR) << "Invalid RTX payload type: " << payload_type << ".";
295 return;
296 }
297
298 rtx_payload_type_map_[associated_payload_type] = payload_type;
299 }
300
ReSendPacket(uint16_t packet_id)301 int32_t RTPSender::ReSendPacket(uint16_t packet_id) {
302 // Try to find packet in RTP packet history. Also verify RTT here, so that we
303 // don't retransmit too often.
304 absl::optional<RtpPacketHistory::PacketState> stored_packet =
305 packet_history_->GetPacketState(packet_id);
306 if (!stored_packet || stored_packet->pending_transmission) {
307 // Packet not found or already queued for retransmission, ignore.
308 return 0;
309 }
310
311 const int32_t packet_size = static_cast<int32_t>(stored_packet->packet_size);
312 const bool rtx = (RtxStatus() & kRtxRetransmitted) > 0;
313
314 std::unique_ptr<RtpPacketToSend> packet =
315 packet_history_->GetPacketAndMarkAsPending(
316 packet_id, [&](const RtpPacketToSend& stored_packet) {
317 // Check if we're overusing retransmission bitrate.
318 // TODO(sprang): Add histograms for nack success or failure
319 // reasons.
320 std::unique_ptr<RtpPacketToSend> retransmit_packet;
321 if (retransmission_rate_limiter_ &&
322 !retransmission_rate_limiter_->TryUseRate(packet_size)) {
323 return retransmit_packet;
324 }
325 if (rtx) {
326 retransmit_packet = BuildRtxPacket(stored_packet);
327 } else {
328 retransmit_packet =
329 std::make_unique<RtpPacketToSend>(stored_packet);
330 }
331 if (retransmit_packet) {
332 retransmit_packet->set_retransmitted_sequence_number(
333 stored_packet.SequenceNumber());
334 }
335 return retransmit_packet;
336 });
337 if (!packet) {
338 return -1;
339 }
340 packet->set_packet_type(RtpPacketMediaType::kRetransmission);
341 std::vector<std::unique_ptr<RtpPacketToSend>> packets;
342 packets.emplace_back(std::move(packet));
343 paced_sender_->EnqueuePackets(std::move(packets));
344
345 return packet_size;
346 }
347
OnReceivedAckOnSsrc(int64_t extended_highest_sequence_number)348 void RTPSender::OnReceivedAckOnSsrc(int64_t extended_highest_sequence_number) {
349 MutexLock lock(&send_mutex_);
350 bool update_required = !ssrc_has_acked_;
351 ssrc_has_acked_ = true;
352 if (update_required) {
353 UpdateHeaderSizes();
354 }
355 }
356
OnReceivedAckOnRtxSsrc(int64_t extended_highest_sequence_number)357 void RTPSender::OnReceivedAckOnRtxSsrc(
358 int64_t extended_highest_sequence_number) {
359 MutexLock lock(&send_mutex_);
360 rtx_ssrc_has_acked_ = true;
361 }
362
OnReceivedNack(const std::vector<uint16_t> & nack_sequence_numbers,int64_t avg_rtt)363 void RTPSender::OnReceivedNack(
364 const std::vector<uint16_t>& nack_sequence_numbers,
365 int64_t avg_rtt) {
366 packet_history_->SetRtt(5 + avg_rtt);
367 for (uint16_t seq_no : nack_sequence_numbers) {
368 const int32_t bytes_sent = ReSendPacket(seq_no);
369 if (bytes_sent < 0) {
370 // Failed to send one Sequence number. Give up the rest in this nack.
371 RTC_LOG(LS_WARNING) << "Failed resending RTP packet " << seq_no
372 << ", Discard rest of packets.";
373 break;
374 }
375 }
376 }
377
SupportsPadding() const378 bool RTPSender::SupportsPadding() const {
379 MutexLock lock(&send_mutex_);
380 return sending_media_ && supports_bwe_extension_;
381 }
382
SupportsRtxPayloadPadding() const383 bool RTPSender::SupportsRtxPayloadPadding() const {
384 MutexLock lock(&send_mutex_);
385 return sending_media_ && supports_bwe_extension_ &&
386 (rtx_ & kRtxRedundantPayloads);
387 }
388
GeneratePadding(size_t target_size_bytes,bool media_has_been_sent)389 std::vector<std::unique_ptr<RtpPacketToSend>> RTPSender::GeneratePadding(
390 size_t target_size_bytes,
391 bool media_has_been_sent) {
392 // This method does not actually send packets, it just generates
393 // them and puts them in the pacer queue. Since this should incur
394 // low overhead, keep the lock for the scope of the method in order
395 // to make the code more readable.
396
397 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets;
398 size_t bytes_left = target_size_bytes;
399 if (SupportsRtxPayloadPadding()) {
400 while (bytes_left >= kMinPayloadPaddingBytes) {
401 std::unique_ptr<RtpPacketToSend> packet =
402 packet_history_->GetPayloadPaddingPacket(
403 [&](const RtpPacketToSend& packet)
404 -> std::unique_ptr<RtpPacketToSend> {
405 // Limit overshoot, generate <= |max_padding_size_factor_| *
406 // target_size_bytes.
407 const size_t max_overshoot_bytes = static_cast<size_t>(
408 ((max_padding_size_factor_ - 1.0) * target_size_bytes) +
409 0.5);
410 if (packet.payload_size() + kRtxHeaderSize >
411 max_overshoot_bytes + bytes_left) {
412 return nullptr;
413 }
414 return BuildRtxPacket(packet);
415 });
416 if (!packet) {
417 break;
418 }
419
420 bytes_left -= std::min(bytes_left, packet->payload_size());
421 packet->set_packet_type(RtpPacketMediaType::kPadding);
422 padding_packets.push_back(std::move(packet));
423 }
424 }
425
426 MutexLock lock(&send_mutex_);
427 if (!sending_media_) {
428 return {};
429 }
430
431 size_t padding_bytes_in_packet;
432 const size_t max_payload_size =
433 max_packet_size_ - max_padding_fec_packet_header_;
434 if (audio_configured_) {
435 // Allow smaller padding packets for audio.
436 padding_bytes_in_packet = rtc::SafeClamp<size_t>(
437 bytes_left, kMinAudioPaddingLength,
438 rtc::SafeMin(max_payload_size, kMaxPaddingLength));
439 } else {
440 // Always send full padding packets. This is accounted for by the
441 // RtpPacketSender, which will make sure we don't send too much padding even
442 // if a single packet is larger than requested.
443 // We do this to avoid frequently sending small packets on higher bitrates.
444 padding_bytes_in_packet = rtc::SafeMin(max_payload_size, kMaxPaddingLength);
445 }
446
447 while (bytes_left > 0) {
448 auto padding_packet =
449 std::make_unique<RtpPacketToSend>(&rtp_header_extension_map_);
450 padding_packet->set_packet_type(RtpPacketMediaType::kPadding);
451 padding_packet->SetMarker(false);
452 padding_packet->SetTimestamp(last_rtp_timestamp_);
453 padding_packet->set_capture_time_ms(capture_time_ms_);
454 if (rtx_ == kRtxOff) {
455 if (last_payload_type_ == -1) {
456 break;
457 }
458 // Without RTX we can't send padding in the middle of frames.
459 // For audio marker bits doesn't mark the end of a frame and frames
460 // are usually a single packet, so for now we don't apply this rule
461 // for audio.
462 if (!audio_configured_ && !last_packet_marker_bit_) {
463 break;
464 }
465
466 padding_packet->SetSsrc(ssrc_);
467 padding_packet->SetPayloadType(last_payload_type_);
468 padding_packet->SetSequenceNumber(sequence_number_++);
469 } else {
470 // Without abs-send-time or transport sequence number a media packet
471 // must be sent before padding so that the timestamps used for
472 // estimation are correct.
473 if (!media_has_been_sent &&
474 !(rtp_header_extension_map_.IsRegistered(AbsoluteSendTime::kId) ||
475 rtp_header_extension_map_.IsRegistered(
476 TransportSequenceNumber::kId))) {
477 break;
478 }
479 // Only change the timestamp of padding packets sent over RTX.
480 // Padding only packets over RTP has to be sent as part of a media
481 // frame (and therefore the same timestamp).
482 int64_t now_ms = clock_->TimeInMilliseconds();
483 if (last_timestamp_time_ms_ > 0) {
484 padding_packet->SetTimestamp(padding_packet->Timestamp() +
485 (now_ms - last_timestamp_time_ms_) *
486 kTimestampTicksPerMs);
487 if (padding_packet->capture_time_ms() > 0) {
488 padding_packet->set_capture_time_ms(
489 padding_packet->capture_time_ms() +
490 (now_ms - last_timestamp_time_ms_));
491 }
492 }
493 RTC_DCHECK(rtx_ssrc_);
494 padding_packet->SetSsrc(*rtx_ssrc_);
495 padding_packet->SetSequenceNumber(sequence_number_rtx_++);
496 padding_packet->SetPayloadType(rtx_payload_type_map_.begin()->second);
497 }
498
499 if (rtp_header_extension_map_.IsRegistered(TransportSequenceNumber::kId)) {
500 padding_packet->ReserveExtension<TransportSequenceNumber>();
501 }
502 if (rtp_header_extension_map_.IsRegistered(TransmissionOffset::kId)) {
503 padding_packet->ReserveExtension<TransmissionOffset>();
504 }
505 if (rtp_header_extension_map_.IsRegistered(AbsoluteSendTime::kId)) {
506 padding_packet->ReserveExtension<AbsoluteSendTime>();
507 }
508
509 padding_packet->SetPadding(padding_bytes_in_packet);
510 bytes_left -= std::min(bytes_left, padding_bytes_in_packet);
511 padding_packets.push_back(std::move(padding_packet));
512 }
513
514 return padding_packets;
515 }
516
SendToNetwork(std::unique_ptr<RtpPacketToSend> packet)517 bool RTPSender::SendToNetwork(std::unique_ptr<RtpPacketToSend> packet) {
518 RTC_DCHECK(packet);
519 int64_t now_ms = clock_->TimeInMilliseconds();
520
521 auto packet_type = packet->packet_type();
522 RTC_CHECK(packet_type) << "Packet type must be set before sending.";
523
524 if (packet->capture_time_ms() <= 0) {
525 packet->set_capture_time_ms(now_ms);
526 }
527
528 std::vector<std::unique_ptr<RtpPacketToSend>> packets;
529 packets.emplace_back(std::move(packet));
530 paced_sender_->EnqueuePackets(std::move(packets));
531
532 return true;
533 }
534
EnqueuePackets(std::vector<std::unique_ptr<RtpPacketToSend>> packets)535 void RTPSender::EnqueuePackets(
536 std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
537 RTC_DCHECK(!packets.empty());
538 int64_t now_ms = clock_->TimeInMilliseconds();
539 for (auto& packet : packets) {
540 RTC_DCHECK(packet);
541 RTC_CHECK(packet->packet_type().has_value())
542 << "Packet type must be set before sending.";
543 if (packet->capture_time_ms() <= 0) {
544 packet->set_capture_time_ms(now_ms);
545 }
546 }
547
548 paced_sender_->EnqueuePackets(std::move(packets));
549 }
550
FecOrPaddingPacketMaxRtpHeaderLength() const551 size_t RTPSender::FecOrPaddingPacketMaxRtpHeaderLength() const {
552 MutexLock lock(&send_mutex_);
553 return max_padding_fec_packet_header_;
554 }
555
ExpectedPerPacketOverhead() const556 size_t RTPSender::ExpectedPerPacketOverhead() const {
557 MutexLock lock(&send_mutex_);
558 return max_media_packet_header_;
559 }
560
AllocateSequenceNumber(uint16_t packets_to_send)561 uint16_t RTPSender::AllocateSequenceNumber(uint16_t packets_to_send) {
562 MutexLock lock(&send_mutex_);
563 uint16_t first_allocated_sequence_number = sequence_number_;
564 sequence_number_ += packets_to_send;
565 return first_allocated_sequence_number;
566 }
567
AllocatePacket() const568 std::unique_ptr<RtpPacketToSend> RTPSender::AllocatePacket() const {
569 MutexLock lock(&send_mutex_);
570 // TODO(danilchap): Find better motivator and value for extra capacity.
571 // RtpPacketizer might slightly miscalulate needed size,
572 // SRTP may benefit from extra space in the buffer and do encryption in place
573 // saving reallocation.
574 // While sending slightly oversized packet increase chance of dropped packet,
575 // it is better than crash on drop packet without trying to send it.
576 static constexpr int kExtraCapacity = 16;
577 auto packet = std::make_unique<RtpPacketToSend>(
578 &rtp_header_extension_map_, max_packet_size_ + kExtraCapacity);
579 packet->SetSsrc(ssrc_);
580 packet->SetCsrcs(csrcs_);
581 // Reserve extensions, if registered, RtpSender set in SendToNetwork.
582 packet->ReserveExtension<AbsoluteSendTime>();
583 packet->ReserveExtension<TransmissionOffset>();
584 packet->ReserveExtension<TransportSequenceNumber>();
585
586 // BUNDLE requires that the receiver "bind" the received SSRC to the values
587 // in the MID and/or (R)RID header extensions if present. Therefore, the
588 // sender can reduce overhead by omitting these header extensions once it
589 // knows that the receiver has "bound" the SSRC.
590 // This optimization can be configured by setting
591 // |always_send_mid_and_rid_| appropriately.
592 //
593 // The algorithm here is fairly simple: Always attach a MID and/or RID (if
594 // configured) to the outgoing packets until an RTCP receiver report comes
595 // back for this SSRC. That feedback indicates the receiver must have
596 // received a packet with the SSRC and header extension(s), so the sender
597 // then stops attaching the MID and RID.
598 if (always_send_mid_and_rid_ || !ssrc_has_acked_) {
599 // These are no-ops if the corresponding header extension is not registered.
600 if (!mid_.empty()) {
601 packet->SetExtension<RtpMid>(mid_);
602 }
603 if (!rid_.empty()) {
604 packet->SetExtension<RtpStreamId>(rid_);
605 }
606 }
607 return packet;
608 }
609
AssignSequenceNumber(RtpPacketToSend * packet)610 bool RTPSender::AssignSequenceNumber(RtpPacketToSend* packet) {
611 MutexLock lock(&send_mutex_);
612 if (!sending_media_)
613 return false;
614 RTC_DCHECK(packet->Ssrc() == ssrc_);
615 packet->SetSequenceNumber(sequence_number_++);
616
617 // Remember marker bit to determine if padding can be inserted with
618 // sequence number following |packet|.
619 last_packet_marker_bit_ = packet->Marker();
620 // Remember payload type to use in the padding packet if rtx is disabled.
621 last_payload_type_ = packet->PayloadType();
622 // Save timestamps to generate timestamp field and extensions for the padding.
623 last_rtp_timestamp_ = packet->Timestamp();
624 last_timestamp_time_ms_ = clock_->TimeInMilliseconds();
625 capture_time_ms_ = packet->capture_time_ms();
626 return true;
627 }
628
SetSendingMediaStatus(bool enabled)629 void RTPSender::SetSendingMediaStatus(bool enabled) {
630 MutexLock lock(&send_mutex_);
631 sending_media_ = enabled;
632 }
633
SendingMedia() const634 bool RTPSender::SendingMedia() const {
635 MutexLock lock(&send_mutex_);
636 return sending_media_;
637 }
638
IsAudioConfigured() const639 bool RTPSender::IsAudioConfigured() const {
640 return audio_configured_;
641 }
642
SetTimestampOffset(uint32_t timestamp)643 void RTPSender::SetTimestampOffset(uint32_t timestamp) {
644 MutexLock lock(&send_mutex_);
645 timestamp_offset_ = timestamp;
646 }
647
TimestampOffset() const648 uint32_t RTPSender::TimestampOffset() const {
649 MutexLock lock(&send_mutex_);
650 return timestamp_offset_;
651 }
652
SetRid(const std::string & rid)653 void RTPSender::SetRid(const std::string& rid) {
654 // RID is used in simulcast scenario when multiple layers share the same mid.
655 MutexLock lock(&send_mutex_);
656 RTC_DCHECK_LE(rid.length(), RtpStreamId::kMaxValueSizeBytes);
657 rid_ = rid;
658 UpdateHeaderSizes();
659 }
660
SetMid(const std::string & mid)661 void RTPSender::SetMid(const std::string& mid) {
662 // This is configured via the API.
663 MutexLock lock(&send_mutex_);
664 RTC_DCHECK_LE(mid.length(), RtpMid::kMaxValueSizeBytes);
665 mid_ = mid;
666 UpdateHeaderSizes();
667 }
668
SetCsrcs(const std::vector<uint32_t> & csrcs)669 void RTPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
670 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize);
671 MutexLock lock(&send_mutex_);
672 csrcs_ = csrcs;
673 UpdateHeaderSizes();
674 }
675
SetSequenceNumber(uint16_t seq)676 void RTPSender::SetSequenceNumber(uint16_t seq) {
677 bool updated_sequence_number = false;
678 {
679 MutexLock lock(&send_mutex_);
680 sequence_number_forced_ = true;
681 if (sequence_number_ != seq) {
682 updated_sequence_number = true;
683 }
684 sequence_number_ = seq;
685 }
686
687 if (updated_sequence_number) {
688 // Sequence number series has been reset to a new value, clear RTP packet
689 // history, since any packets there may conflict with new ones.
690 packet_history_->Clear();
691 }
692 }
693
SequenceNumber() const694 uint16_t RTPSender::SequenceNumber() const {
695 MutexLock lock(&send_mutex_);
696 return sequence_number_;
697 }
698
CopyHeaderAndExtensionsToRtxPacket(const RtpPacketToSend & packet,RtpPacketToSend * rtx_packet)699 static void CopyHeaderAndExtensionsToRtxPacket(const RtpPacketToSend& packet,
700 RtpPacketToSend* rtx_packet) {
701 // Set the relevant fixed packet headers. The following are not set:
702 // * Payload type - it is replaced in rtx packets.
703 // * Sequence number - RTX has a separate sequence numbering.
704 // * SSRC - RTX stream has its own SSRC.
705 rtx_packet->SetMarker(packet.Marker());
706 rtx_packet->SetTimestamp(packet.Timestamp());
707
708 // Set the variable fields in the packet header:
709 // * CSRCs - must be set before header extensions.
710 // * Header extensions - replace Rid header with RepairedRid header.
711 const std::vector<uint32_t> csrcs = packet.Csrcs();
712 rtx_packet->SetCsrcs(csrcs);
713 for (int extension_num = kRtpExtensionNone + 1;
714 extension_num < kRtpExtensionNumberOfExtensions; ++extension_num) {
715 auto extension = static_cast<RTPExtensionType>(extension_num);
716
717 // Stream ID header extensions (MID, RSID) are sent per-SSRC. Since RTX
718 // operates on a different SSRC, the presence and values of these header
719 // extensions should be determined separately and not blindly copied.
720 if (extension == kRtpExtensionMid ||
721 extension == kRtpExtensionRtpStreamId) {
722 continue;
723 }
724
725 // Empty extensions should be supported, so not checking |source.empty()|.
726 if (!packet.HasExtension(extension)) {
727 continue;
728 }
729
730 rtc::ArrayView<const uint8_t> source = packet.FindExtension(extension);
731
732 rtc::ArrayView<uint8_t> destination =
733 rtx_packet->AllocateExtension(extension, source.size());
734
735 // Could happen if any:
736 // 1. Extension has 0 length.
737 // 2. Extension is not registered in destination.
738 // 3. Allocating extension in destination failed.
739 if (destination.empty() || source.size() != destination.size()) {
740 continue;
741 }
742
743 std::memcpy(destination.begin(), source.begin(), destination.size());
744 }
745 }
746
BuildRtxPacket(const RtpPacketToSend & packet)747 std::unique_ptr<RtpPacketToSend> RTPSender::BuildRtxPacket(
748 const RtpPacketToSend& packet) {
749 std::unique_ptr<RtpPacketToSend> rtx_packet;
750
751 // Add original RTP header.
752 {
753 MutexLock lock(&send_mutex_);
754 if (!sending_media_)
755 return nullptr;
756
757 RTC_DCHECK(rtx_ssrc_);
758
759 // Replace payload type.
760 auto kv = rtx_payload_type_map_.find(packet.PayloadType());
761 if (kv == rtx_payload_type_map_.end())
762 return nullptr;
763
764 rtx_packet = std::make_unique<RtpPacketToSend>(&rtp_header_extension_map_,
765 max_packet_size_);
766
767 rtx_packet->SetPayloadType(kv->second);
768
769 // Replace sequence number.
770 rtx_packet->SetSequenceNumber(sequence_number_rtx_++);
771
772 // Replace SSRC.
773 rtx_packet->SetSsrc(*rtx_ssrc_);
774
775 CopyHeaderAndExtensionsToRtxPacket(packet, rtx_packet.get());
776
777 // RTX packets are sent on an SSRC different from the main media, so the
778 // decision to attach MID and/or RRID header extensions is completely
779 // separate from that of the main media SSRC.
780 //
781 // Note that RTX packets must used the RepairedRtpStreamId (RRID) header
782 // extension instead of the RtpStreamId (RID) header extension even though
783 // the payload is identical.
784 if (always_send_mid_and_rid_ || !rtx_ssrc_has_acked_) {
785 // These are no-ops if the corresponding header extension is not
786 // registered.
787 if (!mid_.empty()) {
788 rtx_packet->SetExtension<RtpMid>(mid_);
789 }
790 if (!rid_.empty()) {
791 rtx_packet->SetExtension<RepairedRtpStreamId>(rid_);
792 }
793 }
794 }
795 RTC_DCHECK(rtx_packet);
796
797 uint8_t* rtx_payload =
798 rtx_packet->AllocatePayload(packet.payload_size() + kRtxHeaderSize);
799 if (rtx_payload == nullptr)
800 return nullptr;
801
802 // Add OSN (original sequence number).
803 ByteWriter<uint16_t>::WriteBigEndian(rtx_payload, packet.SequenceNumber());
804
805 // Add original payload data.
806 auto payload = packet.payload();
807 memcpy(rtx_payload + kRtxHeaderSize, payload.data(), payload.size());
808
809 // Add original application data.
810 rtx_packet->set_application_data(packet.application_data());
811
812 // Copy capture time so e.g. TransmissionOffset is correctly set.
813 rtx_packet->set_capture_time_ms(packet.capture_time_ms());
814
815 return rtx_packet;
816 }
817
SetRtpState(const RtpState & rtp_state)818 void RTPSender::SetRtpState(const RtpState& rtp_state) {
819 MutexLock lock(&send_mutex_);
820 sequence_number_ = rtp_state.sequence_number;
821 sequence_number_forced_ = true;
822 timestamp_offset_ = rtp_state.start_timestamp;
823 last_rtp_timestamp_ = rtp_state.timestamp;
824 capture_time_ms_ = rtp_state.capture_time_ms;
825 last_timestamp_time_ms_ = rtp_state.last_timestamp_time_ms;
826 ssrc_has_acked_ = rtp_state.ssrc_has_acked;
827 UpdateHeaderSizes();
828 }
829
GetRtpState() const830 RtpState RTPSender::GetRtpState() const {
831 MutexLock lock(&send_mutex_);
832
833 RtpState state;
834 state.sequence_number = sequence_number_;
835 state.start_timestamp = timestamp_offset_;
836 state.timestamp = last_rtp_timestamp_;
837 state.capture_time_ms = capture_time_ms_;
838 state.last_timestamp_time_ms = last_timestamp_time_ms_;
839 state.ssrc_has_acked = ssrc_has_acked_;
840 return state;
841 }
842
SetRtxRtpState(const RtpState & rtp_state)843 void RTPSender::SetRtxRtpState(const RtpState& rtp_state) {
844 MutexLock lock(&send_mutex_);
845 sequence_number_rtx_ = rtp_state.sequence_number;
846 rtx_ssrc_has_acked_ = rtp_state.ssrc_has_acked;
847 }
848
GetRtxRtpState() const849 RtpState RTPSender::GetRtxRtpState() const {
850 MutexLock lock(&send_mutex_);
851
852 RtpState state;
853 state.sequence_number = sequence_number_rtx_;
854 state.start_timestamp = timestamp_offset_;
855 state.ssrc_has_acked = rtx_ssrc_has_acked_;
856
857 return state;
858 }
859
LastTimestampTimeMs() const860 int64_t RTPSender::LastTimestampTimeMs() const {
861 MutexLock lock(&send_mutex_);
862 return last_timestamp_time_ms_;
863 }
864
UpdateHeaderSizes()865 void RTPSender::UpdateHeaderSizes() {
866 const size_t rtp_header_length =
867 kRtpHeaderLength + sizeof(uint32_t) * csrcs_.size();
868
869 max_padding_fec_packet_header_ =
870 rtp_header_length + RtpHeaderExtensionSize(kFecOrPaddingExtensionSizes,
871 rtp_header_extension_map_);
872
873 // RtpStreamId and Mid are treated specially in that we check if they
874 // currently are being sent. RepairedRtpStreamId is still ignored since we
875 // assume RTX will not make up large enough bitrate to treat overhead
876 // differently.
877 const bool send_mid_rid = always_send_mid_and_rid_ || !ssrc_has_acked_;
878 std::vector<RtpExtensionSize> non_volatile_extensions;
879 for (auto& extension :
880 audio_configured_ ? AudioExtensionSizes() : VideoExtensionSizes()) {
881 if (IsNonVolatile(extension.type)) {
882 switch (extension.type) {
883 case RTPExtensionType::kRtpExtensionMid:
884 if (send_mid_rid && !mid_.empty()) {
885 non_volatile_extensions.push_back(extension);
886 }
887 break;
888 case RTPExtensionType::kRtpExtensionRtpStreamId:
889 if (send_mid_rid && !rid_.empty()) {
890 non_volatile_extensions.push_back(extension);
891 }
892 break;
893 default:
894 non_volatile_extensions.push_back(extension);
895 }
896 }
897 }
898 max_media_packet_header_ =
899 rtp_header_length + RtpHeaderExtensionSize(non_volatile_extensions,
900 rtp_header_extension_map_);
901 }
902 } // namespace webrtc
903