rtp_sender.cc (29435B)
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 <cstddef> 15 #include <cstdint> 16 #include <cstring> 17 #include <memory> 18 #include <optional> 19 #include <string> 20 #include <utility> 21 #include <vector> 22 23 #include "absl/strings/string_view.h" 24 #include "api/array_view.h" 25 #include "api/environment/environment.h" 26 #include "api/rtp_headers.h" 27 #include "api/rtp_packet_sender.h" 28 #include "api/units/time_delta.h" 29 #include "api/units/timestamp.h" 30 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" 31 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" 32 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 33 #include "modules/rtp_rtcp/source/byte_io.h" 34 #include "modules/rtp_rtcp/source/corruption_detection_extension.h" 35 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h" 36 #include "modules/rtp_rtcp/source/rtp_header_extension_size.h" 37 #include "modules/rtp_rtcp/source/rtp_header_extensions.h" 38 #include "modules/rtp_rtcp/source/rtp_packet_history.h" 39 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" 40 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" 41 #include "rtc_base/checks.h" 42 #include "rtc_base/logging.h" 43 #include "rtc_base/numerics/safe_minmax.h" 44 #include "rtc_base/rate_limiter.h" 45 #include "rtc_base/synchronization/mutex.h" 46 47 namespace webrtc { 48 49 namespace { 50 constexpr size_t kMinAudioPaddingLength = 50; 51 constexpr size_t kRtpHeaderLength = 12; 52 53 // Min size needed to get payload padding from packet history. 54 constexpr int kMinPayloadPaddingBytes = 50; 55 56 // Determines how much larger a payload padding packet may be, compared to the 57 // requested padding size. 58 constexpr double kMaxPaddingSizeFactor = 3.0; 59 60 template <typename Extension> 61 constexpr RtpExtensionSize CreateExtensionSize() { 62 return {Extension::kId, Extension::kValueSizeBytes}; 63 } 64 65 template <typename Extension> 66 constexpr RtpExtensionSize CreateMaxExtensionSize() { 67 return {Extension::kId, Extension::kMaxValueSizeBytes}; 68 } 69 70 // Size info for header extensions that might be used in padding or FEC packets. 71 constexpr RtpExtensionSize kFecOrPaddingExtensionSizes[] = { 72 CreateExtensionSize<AbsoluteSendTime>(), 73 CreateExtensionSize<TransmissionOffset>(), 74 CreateExtensionSize<TransportSequenceNumber>(), 75 CreateExtensionSize<PlayoutDelayLimits>(), 76 CreateMaxExtensionSize<RtpMid>(), 77 CreateExtensionSize<VideoTimingExtension>(), 78 }; 79 80 // Size info for header extensions that might be used in video packets. 81 constexpr RtpExtensionSize kVideoExtensionSizes[] = { 82 CreateExtensionSize<AbsoluteSendTime>(), 83 CreateExtensionSize<AbsoluteCaptureTimeExtension>(), 84 CreateExtensionSize<TransmissionOffset>(), 85 CreateExtensionSize<TransportSequenceNumber>(), 86 CreateExtensionSize<PlayoutDelayLimits>(), 87 CreateExtensionSize<VideoOrientation>(), 88 CreateExtensionSize<VideoContentTypeExtension>(), 89 CreateExtensionSize<VideoTimingExtension>(), 90 CreateMaxExtensionSize<RtpStreamId>(), 91 CreateMaxExtensionSize<RepairedRtpStreamId>(), 92 CreateMaxExtensionSize<RtpMid>(), 93 CreateMaxExtensionSize<CorruptionDetectionExtension>(), 94 {.type = RtpGenericFrameDescriptorExtension00::kId, 95 .value_size = RtpGenericFrameDescriptorExtension00::kMaxSizeBytes}, 96 }; 97 98 // Size info for header extensions that might be used in audio packets. 99 constexpr RtpExtensionSize kAudioExtensionSizes[] = { 100 CreateExtensionSize<AbsoluteSendTime>(), 101 CreateExtensionSize<AbsoluteCaptureTimeExtension>(), 102 CreateExtensionSize<AudioLevelExtension>(), 103 CreateExtensionSize<InbandComfortNoiseExtension>(), 104 CreateExtensionSize<TransmissionOffset>(), 105 CreateExtensionSize<TransportSequenceNumber>(), 106 CreateMaxExtensionSize<RtpMid>(), 107 }; 108 109 // Non-volatile extensions can be expected on all packets, if registered. 110 // Volatile ones, such as VideoContentTypeExtension which is only set on 111 // key-frames, are removed to simplify overhead calculations at the expense of 112 // some accuracy. 113 bool IsNonVolatile(RTPExtensionType type) { 114 switch (type) { 115 case kRtpExtensionTransmissionTimeOffset: 116 case kRtpExtensionAudioLevel: 117 #if !defined(WEBRTC_MOZILLA_BUILD) 118 case kRtpExtensionCsrcAudioLevel: 119 #endif 120 case kRtpExtensionAbsoluteSendTime: 121 case kRtpExtensionTransportSequenceNumber: 122 case kRtpExtensionTransportSequenceNumber02: 123 case kRtpExtensionRtpStreamId: 124 case kRtpExtensionRepairedRtpStreamId: 125 case kRtpExtensionMid: 126 case kRtpExtensionGenericFrameDescriptor: 127 case kRtpExtensionDependencyDescriptor: 128 return true; 129 case kRtpExtensionInbandComfortNoise: 130 case kRtpExtensionAbsoluteCaptureTime: 131 case kRtpExtensionVideoRotation: 132 case kRtpExtensionPlayoutDelay: 133 case kRtpExtensionVideoContentType: 134 case kRtpExtensionVideoLayersAllocation: 135 case kRtpExtensionVideoTiming: 136 case kRtpExtensionColorSpace: 137 case kRtpExtensionVideoFrameTrackingId: 138 case kRtpExtensionCorruptionDetection: 139 return false; 140 case kRtpExtensionNone: 141 case kRtpExtensionNumberOfExtensions: 142 RTC_DCHECK_NOTREACHED(); 143 return false; 144 #if defined(WEBRTC_MOZILLA_BUILD) 145 case kRtpExtensionCsrcAudioLevel: 146 // TODO: Mozilla implement for CsrcAudioLevel 147 RTC_CHECK(false); 148 return false; 149 #endif 150 } 151 RTC_CHECK_NOTREACHED(); 152 } 153 154 bool HasBweExtension(const RtpHeaderExtensionMap& extensions_map) { 155 return extensions_map.IsRegistered(kRtpExtensionTransportSequenceNumber) || 156 extensions_map.IsRegistered(kRtpExtensionTransportSequenceNumber02) || 157 extensions_map.IsRegistered(kRtpExtensionAbsoluteSendTime) || 158 extensions_map.IsRegistered(kRtpExtensionTransmissionTimeOffset); 159 } 160 161 } // namespace 162 163 RTPSender::RTPSender(const Environment& env, 164 const RtpRtcpInterface::Configuration& config, 165 RtpPacketHistory* packet_history, 166 RtpPacketSender* packet_sender) 167 : clock_(&env.clock()), 168 random_(clock_->TimeInMicroseconds()), 169 audio_configured_(config.audio), 170 ssrc_(config.local_media_ssrc), 171 rtx_ssrc_(config.rtx_send_ssrc), 172 flexfec_ssrc_(config.fec_generator ? config.fec_generator->FecSsrc() 173 : std::nullopt), 174 packet_history_(packet_history), 175 paced_sender_(packet_sender), 176 sending_media_(true), // Default to sending media. 177 max_packet_size_(IP_PACKET_SIZE - 28), // Default is IP-v4/UDP. 178 rtp_header_extension_map_(config.extmap_allow_mixed), 179 // RTP variables 180 rid_(config.rid), 181 always_send_mid_and_rid_(config.always_send_mid_and_rid), 182 ssrc_has_acked_(false), 183 rtx_ssrc_has_acked_(false), 184 rtx_(kRtxOff), 185 supports_bwe_extension_(false), 186 retransmission_rate_limiter_(config.retransmission_rate_limiter) { 187 // This random initialization is not intended to be cryptographic strong. 188 timestamp_offset_ = random_.Rand<uint32_t>(); 189 190 RTC_DCHECK(paced_sender_); 191 RTC_DCHECK(packet_history_); 192 RTC_DCHECK_LE(rid_.size(), RtpStreamId::kMaxValueSizeBytes); 193 194 UpdateHeaderSizes(); 195 } 196 197 RTPSender::~RTPSender() { 198 // TODO(tommi): Use a thread checker to ensure the object is created and 199 // deleted on the same thread. At the moment this isn't possible due to 200 // voe::ChannelOwner in voice engine. To reproduce, run: 201 // voe_auto_test --automated --gtest_filter=*MixManyChannelsForStressOpus 202 203 // TODO(tommi,holmer): We don't grab locks in the dtor before accessing member 204 // variables but we grab them in all other methods. (what's the design?) 205 // Start documenting what thread we're on in what method so that it's easier 206 // to understand performance attributes and possibly remove locks. 207 } 208 209 ArrayView<const RtpExtensionSize> RTPSender::FecExtensionSizes() { 210 return kFecOrPaddingExtensionSizes; 211 } 212 213 ArrayView<const RtpExtensionSize> RTPSender::VideoExtensionSizes() { 214 return kVideoExtensionSizes; 215 } 216 217 ArrayView<const RtpExtensionSize> RTPSender::AudioExtensionSizes() { 218 return kAudioExtensionSizes; 219 } 220 221 void RTPSender::SetExtmapAllowMixed(bool extmap_allow_mixed) { 222 MutexLock lock(&send_mutex_); 223 rtp_header_extension_map_.SetExtmapAllowMixed(extmap_allow_mixed); 224 } 225 226 bool RTPSender::RegisterRtpHeaderExtension(absl::string_view uri, int id) { 227 MutexLock lock(&send_mutex_); 228 bool registered = rtp_header_extension_map_.RegisterByUri(id, uri); 229 supports_bwe_extension_ = HasBweExtension(rtp_header_extension_map_); 230 UpdateHeaderSizes(); 231 return registered; 232 } 233 234 bool RTPSender::IsRtpHeaderExtensionRegistered(RTPExtensionType type) const { 235 MutexLock lock(&send_mutex_); 236 return rtp_header_extension_map_.IsRegistered(type); 237 } 238 239 void RTPSender::DeregisterRtpHeaderExtension(absl::string_view uri) { 240 MutexLock lock(&send_mutex_); 241 rtp_header_extension_map_.Deregister(uri); 242 supports_bwe_extension_ = HasBweExtension(rtp_header_extension_map_); 243 UpdateHeaderSizes(); 244 } 245 246 void RTPSender::SetMaxRtpPacketSize(size_t max_packet_size) { 247 RTC_DCHECK_GE(max_packet_size, 100); 248 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE); 249 MutexLock lock(&send_mutex_); 250 max_packet_size_ = max_packet_size; 251 } 252 253 size_t RTPSender::MaxRtpPacketSize() const { 254 return max_packet_size_; 255 } 256 257 void RTPSender::SetRtxStatus(int mode) { 258 MutexLock lock(&send_mutex_); 259 if (mode != kRtxOff && 260 (!rtx_ssrc_.has_value() || rtx_payload_type_map_.empty())) { 261 RTC_LOG(LS_ERROR) 262 << "Failed to enable RTX without RTX SSRC or payload types."; 263 return; 264 } 265 rtx_ = mode; 266 } 267 268 int RTPSender::RtxStatus() const { 269 MutexLock lock(&send_mutex_); 270 return rtx_; 271 } 272 273 void RTPSender::SetRtxPayloadType(int payload_type, 274 int associated_payload_type) { 275 MutexLock lock(&send_mutex_); 276 RTC_DCHECK_LE(payload_type, 127); 277 RTC_DCHECK_LE(associated_payload_type, 127); 278 if (payload_type < 0) { 279 RTC_LOG(LS_ERROR) << "Invalid RTX payload type: " << payload_type << "."; 280 return; 281 } 282 283 rtx_payload_type_map_[associated_payload_type] = payload_type; 284 } 285 286 int32_t RTPSender::ReSendPacket(uint16_t packet_id) { 287 int32_t packet_size = 0; 288 const bool rtx = (RtxStatus() & kRtxRetransmitted) > 0; 289 290 std::unique_ptr<RtpPacketToSend> packet = 291 packet_history_->GetPacketAndMarkAsPending( 292 packet_id, [&](const RtpPacketToSend& stored_packet) { 293 // Check if we're overusing retransmission bitrate. 294 // TODO(sprang): Add histograms for nack success or failure 295 // reasons. 296 packet_size = stored_packet.size(); 297 std::unique_ptr<RtpPacketToSend> retransmit_packet; 298 if (retransmission_rate_limiter_ && 299 !retransmission_rate_limiter_->TryUseRate(packet_size)) { 300 return retransmit_packet; 301 } 302 if (rtx) { 303 retransmit_packet = BuildRtxPacket(stored_packet); 304 } else { 305 retransmit_packet = 306 std::make_unique<RtpPacketToSend>(stored_packet); 307 } 308 if (retransmit_packet) { 309 retransmit_packet->set_retransmitted_sequence_number( 310 stored_packet.SequenceNumber()); 311 retransmit_packet->set_original_ssrc(stored_packet.Ssrc()); 312 } 313 return retransmit_packet; 314 }); 315 if (packet_size == 0) { 316 // Packet not found or already queued for retransmission, ignore. 317 RTC_DCHECK(!packet); 318 return 0; 319 } 320 if (!packet) { 321 // Packet was found, but lambda helper above chose not to create 322 // `retransmit_packet` out of it. 323 return -1; 324 } 325 packet->set_packet_type(RtpPacketMediaType::kRetransmission); 326 packet->set_fec_protect_packet(false); 327 std::vector<std::unique_ptr<RtpPacketToSend>> packets; 328 packets.emplace_back(std::move(packet)); 329 paced_sender_->EnqueuePackets(std::move(packets)); 330 331 return packet_size; 332 } 333 334 void RTPSender::OnReceivedAckOnSsrc( 335 int64_t /* extended_highest_sequence_number */) { 336 MutexLock lock(&send_mutex_); 337 bool update_required = !ssrc_has_acked_; 338 ssrc_has_acked_ = true; 339 if (update_required) { 340 UpdateHeaderSizes(); 341 } 342 } 343 344 void RTPSender::OnReceivedAckOnRtxSsrc( 345 int64_t /* extended_highest_sequence_number */) { 346 MutexLock lock(&send_mutex_); 347 bool update_required = !rtx_ssrc_has_acked_; 348 rtx_ssrc_has_acked_ = true; 349 if (update_required) { 350 UpdateHeaderSizes(); 351 } 352 } 353 354 void RTPSender::OnReceivedNack( 355 const std::vector<uint16_t>& nack_sequence_numbers, 356 int64_t avg_rtt) { 357 packet_history_->SetRtt(TimeDelta::Millis(5 + avg_rtt)); 358 for (uint16_t seq_no : nack_sequence_numbers) { 359 const int32_t bytes_sent = ReSendPacket(seq_no); 360 if (bytes_sent < 0) { 361 // Failed to send one Sequence number. Give up the rest in this nack. 362 RTC_LOG(LS_WARNING) << "Failed resending RTP packet " << seq_no 363 << ", Discard rest of packets."; 364 break; 365 } 366 } 367 } 368 369 bool RTPSender::SupportsPadding() const { 370 MutexLock lock(&send_mutex_); 371 return sending_media_ && supports_bwe_extension_; 372 } 373 374 bool RTPSender::SupportsRtxPayloadPadding() const { 375 MutexLock lock(&send_mutex_); 376 return sending_media_ && supports_bwe_extension_ && 377 (rtx_ & kRtxRedundantPayloads); 378 } 379 380 std::vector<std::unique_ptr<RtpPacketToSend>> RTPSender::GeneratePadding( 381 size_t target_size_bytes, 382 bool media_has_been_sent, 383 bool can_send_padding_on_media_ssrc) { 384 // This method does not actually send packets, it just generates 385 // them and puts them in the pacer queue. Since this should incur 386 // low overhead, keep the lock for the scope of the method in order 387 // to make the code more readable. 388 389 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets; 390 size_t bytes_left = target_size_bytes; 391 if (SupportsRtxPayloadPadding()) { 392 while (bytes_left >= kMinPayloadPaddingBytes) { 393 std::unique_ptr<RtpPacketToSend> packet = 394 packet_history_->GetPayloadPaddingPacket( 395 [&](const RtpPacketToSend& packet) 396 -> std::unique_ptr<RtpPacketToSend> { 397 // Limit overshoot, generate <= `kMaxPaddingSizeFactor` * 398 // `target_size_bytes`. 399 const size_t max_overshoot_bytes = static_cast<size_t>( 400 ((kMaxPaddingSizeFactor - 1.0) * target_size_bytes) + 0.5); 401 if (packet.payload_size() + kRtxHeaderSize > 402 max_overshoot_bytes + bytes_left) { 403 return nullptr; 404 } 405 return BuildRtxPacket(packet); 406 }); 407 if (!packet) { 408 break; 409 } 410 411 bytes_left -= std::min(bytes_left, packet->payload_size()); 412 packet->set_packet_type(RtpPacketMediaType::kPadding); 413 padding_packets.push_back(std::move(packet)); 414 } 415 } 416 417 MutexLock lock(&send_mutex_); 418 if (!sending_media_) { 419 return {}; 420 } 421 422 size_t padding_bytes_in_packet; 423 const size_t max_payload_size = 424 max_packet_size_ - max_padding_fec_packet_header_; 425 if (audio_configured_) { 426 // Allow smaller padding packets for audio. 427 padding_bytes_in_packet = 428 SafeClamp<size_t>(bytes_left, kMinAudioPaddingLength, 429 SafeMin(max_payload_size, kMaxPaddingLength)); 430 } else { 431 // Always send full padding packets. This is accounted for by the 432 // RtpPacketSender, which will make sure we don't send too much padding even 433 // if a single packet is larger than requested. 434 // We do this to avoid frequently sending small packets on higher bitrates. 435 padding_bytes_in_packet = SafeMin(max_payload_size, kMaxPaddingLength); 436 } 437 438 while (bytes_left > 0) { 439 auto padding_packet = 440 std::make_unique<RtpPacketToSend>(&rtp_header_extension_map_); 441 padding_packet->set_packet_type(RtpPacketMediaType::kPadding); 442 padding_packet->SetMarker(false); 443 if (rtx_ == kRtxOff) { 444 if (!can_send_padding_on_media_ssrc) { 445 break; 446 } 447 padding_packet->SetSsrc(ssrc_); 448 449 if (always_send_mid_and_rid_ || !ssrc_has_acked_) { 450 // These are no-ops if the corresponding header extension is not 451 // registered. 452 if (!mid_.empty()) { 453 padding_packet->SetExtension<RtpMid>(mid_); 454 } 455 if (!rid_.empty()) { 456 padding_packet->SetExtension<RtpStreamId>(rid_); 457 } 458 } 459 } else { 460 // Without abs-send-time or transport sequence number a media packet 461 // must be sent before padding so that the timestamps used for 462 // estimation are correct. 463 if (!media_has_been_sent && 464 !(rtp_header_extension_map_.IsRegistered(AbsoluteSendTime::kId) || 465 rtp_header_extension_map_.IsRegistered( 466 TransportSequenceNumber::kId))) { 467 break; 468 } 469 470 RTC_DCHECK(rtx_ssrc_); 471 RTC_DCHECK(!rtx_payload_type_map_.empty()); 472 padding_packet->SetSsrc(*rtx_ssrc_); 473 padding_packet->SetPayloadType(rtx_payload_type_map_.begin()->second); 474 475 if (always_send_mid_and_rid_ || !rtx_ssrc_has_acked_) { 476 if (!mid_.empty()) { 477 padding_packet->SetExtension<RtpMid>(mid_); 478 } 479 if (!rid_.empty()) { 480 padding_packet->SetExtension<RepairedRtpStreamId>(rid_); 481 } 482 } 483 } 484 485 padding_packet->ReserveExtension<TransportSequenceNumber>(); 486 padding_packet->ReserveExtension<TransmissionOffset>(); 487 padding_packet->ReserveExtension<AbsoluteSendTime>(); 488 489 padding_packet->SetPadding(padding_bytes_in_packet); 490 bytes_left -= std::min(bytes_left, padding_bytes_in_packet); 491 padding_packets.push_back(std::move(padding_packet)); 492 } 493 494 return padding_packets; 495 } 496 497 void RTPSender::EnqueuePackets( 498 std::vector<std::unique_ptr<RtpPacketToSend>> packets) { 499 RTC_DCHECK(!packets.empty()); 500 Timestamp now = clock_->CurrentTime(); 501 for (auto& packet : packets) { 502 RTC_DCHECK(packet); 503 RTC_CHECK(packet->packet_type().has_value()) 504 << "Packet type must be set before sending."; 505 if (packet->capture_time() <= Timestamp::Zero()) { 506 packet->set_capture_time(now); 507 } 508 } 509 510 paced_sender_->EnqueuePackets(std::move(packets)); 511 } 512 513 size_t RTPSender::FecOrPaddingPacketMaxRtpHeaderLength() const { 514 MutexLock lock(&send_mutex_); 515 return max_padding_fec_packet_header_; 516 } 517 518 size_t RTPSender::ExpectedPerPacketOverhead() const { 519 MutexLock lock(&send_mutex_); 520 return max_media_packet_header_; 521 } 522 523 std::unique_ptr<RtpPacketToSend> RTPSender::AllocatePacket( 524 ArrayView<const uint32_t> csrcs) { 525 MutexLock lock(&send_mutex_); 526 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize); 527 if (csrcs.size() > max_num_csrcs_) { 528 max_num_csrcs_ = csrcs.size(); 529 UpdateHeaderSizes(); 530 } 531 auto packet = std::make_unique<RtpPacketToSend>(&rtp_header_extension_map_, 532 max_packet_size_); 533 packet->SetSsrc(ssrc_); 534 packet->SetCsrcs(csrcs); 535 536 // Reserve extensions, if registered, RtpSender set in SendToNetwork. 537 packet->ReserveExtension<AbsoluteSendTime>(); 538 packet->ReserveExtension<TransmissionOffset>(); 539 packet->ReserveExtension<TransportSequenceNumber>(); 540 541 // BUNDLE requires that the receiver "bind" the received SSRC to the values 542 // in the MID and/or (R)RID header extensions if present. Therefore, the 543 // sender can reduce overhead by omitting these header extensions once it 544 // knows that the receiver has "bound" the SSRC. 545 // This optimization can be configured by setting 546 // `always_send_mid_and_rid_` appropriately. 547 // 548 // The algorithm here is fairly simple: Always attach a MID and/or RID (if 549 // configured) to the outgoing packets until an RTCP receiver report comes 550 // back for this SSRC. That feedback indicates the receiver must have 551 // received a packet with the SSRC and header extension(s), so the sender 552 // then stops attaching the MID and RID. 553 if (always_send_mid_and_rid_ || !ssrc_has_acked_) { 554 // These are no-ops if the corresponding header extension is not registered. 555 if (!mid_.empty()) { 556 packet->SetExtension<RtpMid>(mid_); 557 } 558 if (!rid_.empty()) { 559 packet->SetExtension<RtpStreamId>(rid_); 560 } 561 } 562 return packet; 563 } 564 565 size_t RTPSender::RtxPacketOverhead() const { 566 MutexLock lock(&send_mutex_); 567 if (rtx_ == kRtxOff) { 568 return 0; 569 } 570 size_t overhead = 0; 571 572 // Count space for the RTP header extensions that might need to be added to 573 // the RTX packet. 574 if (!always_send_mid_and_rid_ && (!rtx_ssrc_has_acked_ && ssrc_has_acked_)) { 575 // Prefer to reserve extra byte in case two byte header rtp header 576 // extensions are used. 577 static constexpr int kRtpExtensionHeaderSize = 2; 578 579 // Rtx packets hasn't been acked and would need to have mid and rrsid rtp 580 // header extensions, while media packets no longer needs to include mid and 581 // rsid extensions. 582 if (!mid_.empty()) { 583 overhead += (kRtpExtensionHeaderSize + mid_.size()); 584 } 585 if (!rid_.empty()) { 586 overhead += (kRtpExtensionHeaderSize + rid_.size()); 587 } 588 // RTP header extensions are rounded up to 4 bytes. Depending on already 589 // present extensions adding mid & rrsid may add up to 3 bytes of padding. 590 overhead += 3; 591 } 592 593 // Add two bytes for the original sequence number in the RTP payload. 594 overhead += kRtxHeaderSize; 595 return overhead; 596 } 597 598 void RTPSender::SetSendingMediaStatus(bool enabled) { 599 MutexLock lock(&send_mutex_); 600 sending_media_ = enabled; 601 } 602 603 bool RTPSender::SendingMedia() const { 604 MutexLock lock(&send_mutex_); 605 return sending_media_; 606 } 607 608 bool RTPSender::IsAudioConfigured() const { 609 return audio_configured_; 610 } 611 612 void RTPSender::SetTimestampOffset(uint32_t timestamp) { 613 MutexLock lock(&send_mutex_); 614 timestamp_offset_ = timestamp; 615 } 616 617 uint32_t RTPSender::TimestampOffset() const { 618 MutexLock lock(&send_mutex_); 619 return timestamp_offset_; 620 } 621 622 void RTPSender::SetMid(absl::string_view mid) { 623 // This is configured via the API. 624 MutexLock lock(&send_mutex_); 625 RTC_DCHECK_LE(mid.length(), RtpMid::kMaxValueSizeBytes); 626 mid_ = std::string(mid); 627 UpdateHeaderSizes(); 628 } 629 630 static void CopyHeaderAndExtensionsToRtxPacket(const RtpPacketToSend& packet, 631 RtpPacketToSend* rtx_packet) { 632 // Set the relevant fixed packet headers. The following are not set: 633 // * Payload type - it is replaced in rtx packets. 634 // * Sequence number - RTX has a separate sequence numbering. 635 // * SSRC - RTX stream has its own SSRC. 636 rtx_packet->SetMarker(packet.Marker()); 637 rtx_packet->SetTimestamp(packet.Timestamp()); 638 639 // Set the variable fields in the packet header: 640 // * CSRCs - must be set before header extensions. 641 // * Header extensions - replace Rid header with RepairedRid header. 642 rtx_packet->SetCsrcs(packet.Csrcs()); 643 for (int extension_num = kRtpExtensionNone + 1; 644 extension_num < kRtpExtensionNumberOfExtensions; ++extension_num) { 645 auto extension = static_cast<RTPExtensionType>(extension_num); 646 647 // Stream ID header extensions (MID, RSID) are sent per-SSRC. Since RTX 648 // operates on a different SSRC, the presence and values of these header 649 // extensions should be determined separately and not blindly copied. 650 if (extension == kRtpExtensionMid || 651 extension == kRtpExtensionRtpStreamId) { 652 continue; 653 } 654 655 // Empty extensions should be supported, so not checking `source.empty()`. 656 if (!packet.HasExtension(extension)) { 657 continue; 658 } 659 660 ArrayView<const uint8_t> source = packet.FindExtension(extension); 661 662 ArrayView<uint8_t> destination = 663 rtx_packet->AllocateExtension(extension, source.size()); 664 665 // Could happen if any: 666 // 1. Extension has 0 length. 667 // 2. Extension is not registered in destination. 668 // 3. Allocating extension in destination failed. 669 if (destination.empty() || source.size() != destination.size()) { 670 continue; 671 } 672 673 std::memcpy(destination.begin(), source.begin(), destination.size()); 674 } 675 } 676 677 std::unique_ptr<RtpPacketToSend> RTPSender::BuildRtxPacket( 678 const RtpPacketToSend& packet) { 679 std::unique_ptr<RtpPacketToSend> rtx_packet; 680 681 // Add original RTP header. 682 { 683 MutexLock lock(&send_mutex_); 684 if (!sending_media_) 685 return nullptr; 686 687 RTC_DCHECK(rtx_ssrc_); 688 689 // Replace payload type. 690 auto kv = rtx_payload_type_map_.find(packet.PayloadType()); 691 if (kv == rtx_payload_type_map_.end()) 692 return nullptr; 693 694 rtx_packet = std::make_unique<RtpPacketToSend>(&rtp_header_extension_map_, 695 max_packet_size_); 696 697 rtx_packet->SetPayloadType(kv->second); 698 699 // Replace SSRC. 700 rtx_packet->SetSsrc(*rtx_ssrc_); 701 702 CopyHeaderAndExtensionsToRtxPacket(packet, rtx_packet.get()); 703 704 // RTX packets are sent on an SSRC different from the main media, so the 705 // decision to attach MID and/or RRID header extensions is completely 706 // separate from that of the main media SSRC. 707 // 708 // Note that RTX packets must used the RepairedRtpStreamId (RRID) header 709 // extension instead of the RtpStreamId (RID) header extension even though 710 // the payload is identical. 711 if (always_send_mid_and_rid_ || !rtx_ssrc_has_acked_) { 712 // These are no-ops if the corresponding header extension is not 713 // registered. 714 if (!mid_.empty()) { 715 rtx_packet->SetExtension<RtpMid>(mid_); 716 } 717 if (!rid_.empty()) { 718 rtx_packet->SetExtension<RepairedRtpStreamId>(rid_); 719 } 720 } 721 } 722 RTC_DCHECK(rtx_packet); 723 724 uint8_t* rtx_payload = 725 rtx_packet->AllocatePayload(packet.payload_size() + kRtxHeaderSize); 726 RTC_CHECK(rtx_payload); 727 728 // Add OSN (original sequence number). 729 ByteWriter<uint16_t>::WriteBigEndian(rtx_payload, packet.SequenceNumber()); 730 731 // Add original payload data. 732 auto payload = packet.payload(); 733 if (!payload.empty()) { 734 memcpy(rtx_payload + kRtxHeaderSize, payload.data(), payload.size()); 735 } 736 737 // Add original additional data. 738 rtx_packet->set_additional_data(packet.additional_data()); 739 740 // Copy capture time so e.g. TransmissionOffset is correctly set. 741 rtx_packet->set_capture_time(packet.capture_time()); 742 743 return rtx_packet; 744 } 745 746 void RTPSender::SetRtpState(const RtpState& rtp_state) { 747 MutexLock lock(&send_mutex_); 748 749 timestamp_offset_ = rtp_state.start_timestamp; 750 ssrc_has_acked_ = rtp_state.ssrc_has_acked; 751 UpdateHeaderSizes(); 752 } 753 754 RtpState RTPSender::GetRtpState() const { 755 MutexLock lock(&send_mutex_); 756 757 RtpState state; 758 state.start_timestamp = timestamp_offset_; 759 state.ssrc_has_acked = ssrc_has_acked_; 760 return state; 761 } 762 763 void RTPSender::SetRtxRtpState(const RtpState& rtp_state) { 764 MutexLock lock(&send_mutex_); 765 rtx_ssrc_has_acked_ = rtp_state.ssrc_has_acked; 766 } 767 768 RtpState RTPSender::GetRtxRtpState() const { 769 MutexLock lock(&send_mutex_); 770 771 RtpState state; 772 state.start_timestamp = timestamp_offset_; 773 state.ssrc_has_acked = rtx_ssrc_has_acked_; 774 775 return state; 776 } 777 778 void RTPSender::UpdateHeaderSizes() { 779 const size_t rtp_header_length = 780 kRtpHeaderLength + sizeof(uint32_t) * max_num_csrcs_; 781 782 max_padding_fec_packet_header_ = 783 rtp_header_length + RtpHeaderExtensionSize(kFecOrPaddingExtensionSizes, 784 rtp_header_extension_map_); 785 786 // RtpStreamId, Mid and RepairedRtpStreamId are treated specially in that 787 // we check if they currently are being sent. RepairedRtpStreamId can be 788 // sent instead of RtpStreamID on RTX packets and may share the same space. 789 // When the primary SSRC has already been acked but the RTX SSRC has not 790 // yet been acked, RepairedRtpStreamId needs to be taken into account 791 // separately. 792 const bool send_mid_rid_on_rtx = 793 rtx_ssrc_.has_value() && 794 (always_send_mid_and_rid_ || !rtx_ssrc_has_acked_); 795 const bool send_mid_rid = always_send_mid_and_rid_ || !ssrc_has_acked_; 796 std::vector<RtpExtensionSize> non_volatile_extensions; 797 for (auto& extension : 798 audio_configured_ ? AudioExtensionSizes() : VideoExtensionSizes()) { 799 if (IsNonVolatile(extension.type)) { 800 switch (extension.type) { 801 case RTPExtensionType::kRtpExtensionMid: 802 if ((send_mid_rid || send_mid_rid_on_rtx) && !mid_.empty()) { 803 non_volatile_extensions.push_back(extension); 804 } 805 break; 806 case RTPExtensionType::kRtpExtensionRtpStreamId: 807 if (send_mid_rid && !rid_.empty()) { 808 non_volatile_extensions.push_back(extension); 809 } 810 break; 811 case RTPExtensionType::kRtpExtensionRepairedRtpStreamId: 812 if (send_mid_rid_on_rtx && !send_mid_rid && !rid_.empty()) { 813 non_volatile_extensions.push_back(extension); 814 } 815 break; 816 default: 817 non_volatile_extensions.push_back(extension); 818 } 819 } 820 } 821 max_media_packet_header_ = 822 rtp_header_length + RtpHeaderExtensionSize(non_volatile_extensions, 823 rtp_header_extension_map_); 824 // Reserve extra bytes if packet might be resent in an rtx packet. 825 if (rtx_ssrc_.has_value()) { 826 max_media_packet_header_ += kRtxHeaderSize; 827 } 828 } 829 } // namespace webrtc