rtcp_sender.cc (29847B)
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/rtcp_sender.h" 12 13 #include <algorithm> 14 #include <cstdint> 15 #include <cstring> 16 #include <memory> 17 #include <optional> 18 #include <string> 19 #include <utility> 20 #include <vector> 21 22 #include "absl/strings/string_view.h" 23 #include "api/array_view.h" 24 #include "api/call/transport.h" 25 #include "api/environment/environment.h" 26 #include "api/rtc_event_log/rtc_event_log.h" 27 #include "api/rtp_headers.h" 28 #include "api/units/data_rate.h" 29 #include "api/units/time_delta.h" 30 #include "api/units/timestamp.h" 31 #include "api/video/video_bitrate_allocation.h" 32 #include "api/video/video_codec_constants.h" 33 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h" 34 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 35 #include "modules/rtp_rtcp/source/ntp_time_util.h" 36 #include "modules/rtp_rtcp/source/rtcp_packet.h" 37 #include "modules/rtp_rtcp/source/rtcp_packet/app.h" 38 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h" 39 #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" 40 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h" 41 #include "modules/rtp_rtcp/source/rtcp_packet/fir.h" 42 #include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h" 43 #include "modules/rtp_rtcp/source/rtcp_packet/nack.h" 44 #include "modules/rtp_rtcp/source/rtcp_packet/pli.h" 45 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" 46 #include "modules/rtp_rtcp/source/rtcp_packet/remb.h" 47 #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" 48 #include "modules/rtp_rtcp/source/rtcp_packet/rrtr.h" 49 #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h" 50 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" 51 #include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h" 52 #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" 53 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbn.h" 54 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h" 55 #include "modules/rtp_rtcp/source/rtp_rtcp_config.h" 56 #include "modules/rtp_rtcp/source/tmmbr_help.h" 57 #include "rtc_base/checks.h" 58 #include "rtc_base/logging.h" 59 #include "rtc_base/numerics/safe_conversions.h" 60 #include "rtc_base/synchronization/mutex.h" 61 #include "rtc_base/trace_event.h" 62 63 namespace webrtc { 64 65 namespace { 66 const uint32_t kRtcpAnyExtendedReports = kRtcpXrReceiverReferenceTime | 67 kRtcpXrDlrrReportBlock | 68 kRtcpXrTargetBitrate; 69 } // namespace 70 71 // Helper to put several RTCP packets into lower layer datagram RTCP packet. 72 class RTCPSender::PacketSender { 73 public: 74 PacketSender(rtcp::RtcpPacket::PacketReadyCallback callback, 75 size_t max_packet_size) 76 : callback_(callback), max_packet_size_(max_packet_size) { 77 RTC_CHECK_LE(max_packet_size, IP_PACKET_SIZE); 78 } 79 ~PacketSender() { RTC_DCHECK_EQ(index_, 0) << "Unsent rtcp packet."; } 80 81 // Appends a packet to pending compound packet. 82 // Sends rtcp packet if buffer is full and resets the buffer. 83 void AppendPacket(const rtcp::RtcpPacket& packet) { 84 packet.Create(buffer_, &index_, max_packet_size_, callback_); 85 } 86 87 // Sends pending rtcp packet. 88 void Send() { 89 if (index_ > 0) { 90 callback_(ArrayView<const uint8_t>(buffer_, index_)); 91 index_ = 0; 92 } 93 } 94 95 private: 96 const rtcp::RtcpPacket::PacketReadyCallback callback_; 97 const size_t max_packet_size_; 98 size_t index_ = 0; 99 uint8_t buffer_[IP_PACKET_SIZE]; 100 }; 101 102 RTCPSender::FeedbackState::FeedbackState() 103 : packets_sent(0), 104 media_bytes_sent(0), 105 send_bitrate(DataRate::Zero()), 106 remote_sr(0), 107 receiver(nullptr) {} 108 109 RTCPSender::FeedbackState::FeedbackState(const FeedbackState&) = default; 110 111 RTCPSender::FeedbackState::FeedbackState(FeedbackState&&) = default; 112 113 RTCPSender::FeedbackState::~FeedbackState() = default; 114 115 class RTCPSender::RtcpContext { 116 public: 117 RtcpContext(const FeedbackState& feedback_state, 118 ArrayView<const uint16_t> nacks, 119 Timestamp now) 120 : feedback_state_(feedback_state), nacks_(nacks), now_(now) {} 121 122 const FeedbackState& feedback_state_; 123 const ArrayView<const uint16_t> nacks_; 124 const Timestamp now_; 125 }; 126 127 RTCPSender::RTCPSender(const Environment& env, Configuration config) 128 : env_(env), 129 audio_(config.audio), 130 ssrc_(config.local_media_ssrc), 131 random_(env_.clock().TimeInMicroseconds()), 132 method_(RtcpMode::kOff), 133 transport_(config.outgoing_transport), 134 report_interval_(config.rtcp_report_interval), 135 schedule_next_rtcp_send_evaluation_( 136 std::move(config.schedule_next_rtcp_send_evaluation)), 137 sending_(false), 138 timestamp_offset_(0), 139 last_rtp_timestamp_(0), 140 remote_ssrc_(0), 141 receive_statistics_(config.receive_statistics), 142 sequence_number_fir_(0), 143 remb_bitrate_(0), 144 tmmbr_send_bps_(0), 145 packet_oh_send_(0), 146 max_packet_size_(IP_PACKET_SIZE - 28), // IPv4 + UDP by default. 147 xr_send_receiver_reference_time_enabled_( 148 config.non_sender_rtt_measurement), 149 packet_type_counter_observer_(config.rtcp_packet_type_counter_observer), 150 send_video_bitrate_allocation_(false), 151 last_payload_type_(-1) { 152 RTC_CHECK(schedule_next_rtcp_send_evaluation_); 153 RTC_CHECK_GT(report_interval_, TimeDelta::Zero()); 154 RTC_DCHECK(transport_ != nullptr); 155 156 builders_[kRtcpSr] = &RTCPSender::BuildSR; 157 builders_[kRtcpRr] = &RTCPSender::BuildRR; 158 builders_[kRtcpSdes] = &RTCPSender::BuildSDES; 159 builders_[kRtcpPli] = &RTCPSender::BuildPLI; 160 builders_[kRtcpFir] = &RTCPSender::BuildFIR; 161 builders_[kRtcpRemb] = &RTCPSender::BuildREMB; 162 builders_[kRtcpBye] = &RTCPSender::BuildBYE; 163 builders_[kRtcpLossNotification] = &RTCPSender::BuildLossNotification; 164 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; 165 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; 166 builders_[kRtcpNack] = &RTCPSender::BuildNACK; 167 builders_[kRtcpAnyExtendedReports] = &RTCPSender::BuildExtendedReports; 168 } 169 170 RTCPSender::~RTCPSender() {} 171 172 RtcpMode RTCPSender::Status() const { 173 MutexLock lock(&mutex_rtcp_sender_); 174 return method_; 175 } 176 177 void RTCPSender::SetRTCPStatus(RtcpMode new_method) { 178 MutexLock lock(&mutex_rtcp_sender_); 179 180 if (new_method == RtcpMode::kOff) { 181 next_time_to_send_rtcp_ = std::nullopt; 182 } else if (method_ == RtcpMode::kOff) { 183 // When switching on, reschedule the next packet 184 SetNextRtcpSendEvaluationDuration(RTCP_INTERVAL_RAPID_SYNC_MS / 2); 185 } 186 method_ = new_method; 187 } 188 189 bool RTCPSender::Sending() const { 190 MutexLock lock(&mutex_rtcp_sender_); 191 return sending_; 192 } 193 194 void RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, 195 bool sending) { 196 bool sendRTCPBye = false; 197 { 198 MutexLock lock(&mutex_rtcp_sender_); 199 200 if (method_ != RtcpMode::kOff) { 201 if (sending == false && sending_ == true) { 202 // Trigger RTCP bye 203 sendRTCPBye = true; 204 } 205 } 206 sending_ = sending; 207 } 208 if (sendRTCPBye) { 209 if (SendRTCP(feedback_state, kRtcpBye) != 0) { 210 RTC_LOG(LS_WARNING) << "Failed to send RTCP BYE"; 211 } 212 } 213 } 214 215 void RTCPSender::SetNonSenderRttMeasurement(bool enabled) { 216 MutexLock lock(&mutex_rtcp_sender_); 217 xr_send_receiver_reference_time_enabled_ = enabled; 218 } 219 220 int32_t RTCPSender::SendLossNotification(const FeedbackState& feedback_state, 221 uint16_t last_decoded_seq_num, 222 uint16_t last_received_seq_num, 223 bool decodability_flag, 224 bool buffering_allowed) { 225 int32_t error_code = -1; 226 auto callback = [&](ArrayView<const uint8_t> packet) { 227 transport_->SendRtcp(packet, /*packet_options=*/{}); 228 error_code = 0; 229 env_.event_log().Log(std::make_unique<RtcEventRtcpPacketOutgoing>(packet)); 230 }; 231 std::optional<PacketSender> sender; 232 { 233 MutexLock lock(&mutex_rtcp_sender_); 234 235 if (!loss_notification_.Set(last_decoded_seq_num, last_received_seq_num, 236 decodability_flag)) { 237 return -1; 238 } 239 240 SetFlag(kRtcpLossNotification, /*is_volatile=*/true); 241 242 if (buffering_allowed) { 243 // The loss notification will be batched with additional feedback 244 // messages. 245 return 0; 246 } 247 248 sender.emplace(callback, max_packet_size_); 249 auto result = ComputeCompoundRTCPPacket( 250 feedback_state, RTCPPacketType::kRtcpLossNotification, {}, *sender); 251 if (result) { 252 return *result; 253 } 254 } 255 sender->Send(); 256 257 return error_code; 258 } 259 260 void RTCPSender::SetRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) { 261 RTC_CHECK_GE(bitrate_bps, 0); 262 MutexLock lock(&mutex_rtcp_sender_); 263 if (method_ == RtcpMode::kOff) { 264 RTC_LOG(LS_WARNING) << "Can't send RTCP if it is disabled."; 265 return; 266 } 267 remb_bitrate_ = bitrate_bps; 268 remb_ssrcs_ = std::move(ssrcs); 269 270 SetFlag(kRtcpRemb, /*is_volatile=*/false); 271 // Send a REMB immediately if we have a new REMB. The frequency of REMBs is 272 // throttled by the caller. 273 SetNextRtcpSendEvaluationDuration(TimeDelta::Zero()); 274 } 275 276 void RTCPSender::UnsetRemb() { 277 MutexLock lock(&mutex_rtcp_sender_); 278 // Stop sending REMB each report until it is reenabled and REMB data set. 279 ConsumeFlag(kRtcpRemb, /*forced=*/true); 280 } 281 282 bool RTCPSender::TMMBR() const { 283 MutexLock lock(&mutex_rtcp_sender_); 284 return IsFlagPresent(RTCPPacketType::kRtcpTmmbr); 285 } 286 287 void RTCPSender::SetMaxRtpPacketSize(size_t max_packet_size) { 288 MutexLock lock(&mutex_rtcp_sender_); 289 max_packet_size_ = max_packet_size; 290 } 291 292 void RTCPSender::SetTimestampOffset(uint32_t timestamp_offset) { 293 MutexLock lock(&mutex_rtcp_sender_); 294 timestamp_offset_ = timestamp_offset; 295 } 296 297 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, 298 std::optional<Timestamp> capture_time, 299 std::optional<int8_t> payload_type) { 300 MutexLock lock(&mutex_rtcp_sender_); 301 // For compatibility with clients who don't set payload type correctly on all 302 // calls. 303 if (payload_type.has_value()) { 304 last_payload_type_ = *payload_type; 305 } 306 last_rtp_timestamp_ = rtp_timestamp; 307 if (!capture_time.has_value()) { 308 // We don't currently get a capture time from VoiceEngine. 309 last_frame_capture_time_ = env_.clock().CurrentTime(); 310 } else { 311 last_frame_capture_time_ = *capture_time; 312 } 313 } 314 315 void RTCPSender::SetRtpClockRate(int8_t payload_type, int rtp_clock_rate_hz) { 316 MutexLock lock(&mutex_rtcp_sender_); 317 rtp_clock_rates_khz_[payload_type] = rtp_clock_rate_hz / 1000; 318 } 319 320 uint32_t RTCPSender::SSRC() const { 321 MutexLock lock(&mutex_rtcp_sender_); 322 return ssrc_; 323 } 324 325 void RTCPSender::SetSsrc(uint32_t ssrc) { 326 MutexLock lock(&mutex_rtcp_sender_); 327 ssrc_ = ssrc; 328 } 329 330 void RTCPSender::SetRemoteSSRC(uint32_t ssrc) { 331 MutexLock lock(&mutex_rtcp_sender_); 332 remote_ssrc_ = ssrc; 333 } 334 335 int32_t RTCPSender::SetCNAME(absl::string_view c_name) { 336 RTC_DCHECK_LT(c_name.size(), RTCP_CNAME_SIZE); 337 MutexLock lock(&mutex_rtcp_sender_); 338 cname_ = std::string(c_name); 339 return 0; 340 } 341 342 bool RTCPSender::TimeToSendRTCPReport(bool send_keyframe_before_rtp) const { 343 Timestamp now = env_.clock().CurrentTime(); 344 345 MutexLock lock(&mutex_rtcp_sender_); 346 RTC_DCHECK( 347 (method_ == RtcpMode::kOff && !next_time_to_send_rtcp_.has_value()) || 348 (method_ != RtcpMode::kOff && next_time_to_send_rtcp_.has_value())); 349 if (method_ == RtcpMode::kOff) 350 return false; 351 352 if (!audio_ && send_keyframe_before_rtp) { 353 // For video key-frames we want to send the RTCP before the large key-frame 354 // if we have a 100 ms margin 355 now += TimeDelta::Millis(100); 356 } 357 358 return now >= *next_time_to_send_rtcp_; 359 } 360 361 void RTCPSender::BuildSR(const RtcpContext& ctx, PacketSender& sender) { 362 // Timestamp shouldn't be estimated before first media frame. 363 RTC_DCHECK(last_frame_capture_time_.has_value()); 364 // The timestamp of this RTCP packet should be estimated as the timestamp of 365 // the frame being captured at this moment. We are calculating that 366 // timestamp as the last frame's timestamp + the time since the last frame 367 // was captured. 368 int rtp_rate = rtp_clock_rates_khz_[last_payload_type_]; 369 if (rtp_rate <= 0) { 370 rtp_rate = 371 (audio_ ? kBogusRtpRateForAudioRtcp : kVideoPayloadTypeFrequency) / 372 1000; 373 } 374 // Round now_us_ to the closest millisecond, because Ntp time is rounded 375 // when converted to milliseconds, 376 uint32_t rtp_timestamp = 377 timestamp_offset_ + last_rtp_timestamp_ + 378 ((ctx.now_.us() + 500) / 1000 - last_frame_capture_time_->ms()) * 379 rtp_rate; 380 381 rtcp::SenderReport report; 382 report.SetSenderSsrc(ssrc_); 383 report.SetNtp(env_.clock().ConvertTimestampToNtpTime(ctx.now_)); 384 report.SetRtpTimestamp(rtp_timestamp); 385 report.SetPacketCount(ctx.feedback_state_.packets_sent); 386 report.SetOctetCount(ctx.feedback_state_.media_bytes_sent); 387 report.SetReportBlocks(CreateReportBlocks(ctx.feedback_state_)); 388 sender.AppendPacket(report); 389 } 390 391 void RTCPSender::BuildSDES(const RtcpContext& /* ctx */, PacketSender& sender) { 392 size_t length_cname = cname_.length(); 393 RTC_CHECK_LT(length_cname, RTCP_CNAME_SIZE); 394 395 rtcp::Sdes sdes; 396 sdes.AddCName(ssrc_, cname_); 397 sender.AppendPacket(sdes); 398 } 399 400 void RTCPSender::BuildRR(const RtcpContext& ctx, PacketSender& sender) { 401 rtcp::ReceiverReport report; 402 report.SetSenderSsrc(ssrc_); 403 report.SetReportBlocks(CreateReportBlocks(ctx.feedback_state_)); 404 if (method_ == RtcpMode::kCompound || !report.report_blocks().empty()) { 405 sender.AppendPacket(report); 406 } 407 } 408 409 void RTCPSender::BuildPLI(const RtcpContext& /* ctx */, PacketSender& sender) { 410 rtcp::Pli pli; 411 pli.SetSenderSsrc(ssrc_); 412 pli.SetMediaSsrc(remote_ssrc_); 413 414 ++packet_type_counter_.pli_packets; 415 sender.AppendPacket(pli); 416 } 417 418 void RTCPSender::BuildFIR(const RtcpContext& /* ctx */, PacketSender& sender) { 419 ++sequence_number_fir_; 420 421 rtcp::Fir fir; 422 fir.SetSenderSsrc(ssrc_); 423 fir.AddRequestTo(remote_ssrc_, sequence_number_fir_); 424 425 ++packet_type_counter_.fir_packets; 426 sender.AppendPacket(fir); 427 } 428 429 void RTCPSender::BuildREMB(const RtcpContext& /* ctx */, PacketSender& sender) { 430 rtcp::Remb remb; 431 remb.SetSenderSsrc(ssrc_); 432 remb.SetBitrateBps(remb_bitrate_); 433 remb.SetSsrcs(remb_ssrcs_); 434 sender.AppendPacket(remb); 435 } 436 437 void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { 438 MutexLock lock(&mutex_rtcp_sender_); 439 tmmbr_send_bps_ = target_bitrate; 440 } 441 442 void RTCPSender::BuildTMMBR(const RtcpContext& ctx, PacketSender& sender) { 443 if (ctx.feedback_state_.receiver == nullptr) 444 return; 445 // Before sending the TMMBR check the received TMMBN, only an owner is 446 // allowed to raise the bitrate: 447 // * If the sender is an owner of the TMMBN -> send TMMBR 448 // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR 449 450 // get current bounding set from RTCP receiver 451 bool tmmbr_owner = false; 452 453 // holding mutex_rtcp_sender_ while calling RTCPreceiver which 454 // will acquire criticalSectionRTCPReceiver_ is a potential deadlock but 455 // since RTCPreceiver is not doing the reverse we should be fine 456 std::vector<rtcp::TmmbItem> candidates = 457 ctx.feedback_state_.receiver->BoundingSet(&tmmbr_owner); 458 459 if (!candidates.empty()) { 460 for (const auto& candidate : candidates) { 461 if (candidate.bitrate_bps() == tmmbr_send_bps_ && 462 candidate.packet_overhead() == packet_oh_send_) { 463 // Do not send the same tuple. 464 return; 465 } 466 } 467 if (!tmmbr_owner) { 468 // Use received bounding set as candidate set. 469 // Add current tuple. 470 candidates.emplace_back(ssrc_, tmmbr_send_bps_, packet_oh_send_); 471 472 // Find bounding set. 473 std::vector<rtcp::TmmbItem> bounding = 474 TMMBRHelp::FindBoundingSet(std::move(candidates)); 475 tmmbr_owner = TMMBRHelp::IsOwner(bounding, ssrc_); 476 if (!tmmbr_owner) { 477 // Did not enter bounding set, no meaning to send this request. 478 return; 479 } 480 } 481 } 482 483 if (!tmmbr_send_bps_) 484 return; 485 486 rtcp::Tmmbr tmmbr; 487 tmmbr.SetSenderSsrc(ssrc_); 488 rtcp::TmmbItem request; 489 request.set_ssrc(remote_ssrc_); 490 request.set_bitrate_bps(tmmbr_send_bps_); 491 request.set_packet_overhead(packet_oh_send_); 492 tmmbr.AddTmmbr(request); 493 sender.AppendPacket(tmmbr); 494 } 495 496 void RTCPSender::BuildTMMBN(const RtcpContext& /* ctx */, 497 PacketSender& sender) { 498 rtcp::Tmmbn tmmbn; 499 tmmbn.SetSenderSsrc(ssrc_); 500 for (const rtcp::TmmbItem& tmmbr : tmmbn_to_send_) { 501 if (tmmbr.bitrate_bps() > 0) { 502 tmmbn.AddTmmbr(tmmbr); 503 } 504 } 505 sender.AppendPacket(tmmbn); 506 } 507 508 void RTCPSender::BuildAPP(const RtcpContext& /* ctx */, PacketSender& sender) { 509 rtcp::App app; 510 app.SetSenderSsrc(ssrc_); 511 sender.AppendPacket(app); 512 } 513 514 void RTCPSender::BuildLossNotification(const RtcpContext& /* ctx */, 515 PacketSender& sender) { 516 loss_notification_.SetSenderSsrc(ssrc_); 517 loss_notification_.SetMediaSsrc(remote_ssrc_); 518 sender.AppendPacket(loss_notification_); 519 } 520 521 void RTCPSender::BuildNACK(const RtcpContext& ctx, PacketSender& sender) { 522 rtcp::Nack nack; 523 nack.SetSenderSsrc(ssrc_); 524 nack.SetMediaSsrc(remote_ssrc_); 525 nack.SetPacketIds(ctx.nacks_.data(), ctx.nacks_.size()); 526 527 // Report stats. 528 for (uint16_t sequence_number : ctx.nacks_) { 529 nack_stats_.ReportRequest(sequence_number); 530 } 531 packet_type_counter_.nack_requests = nack_stats_.requests(); 532 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); 533 534 ++packet_type_counter_.nack_packets; 535 sender.AppendPacket(nack); 536 } 537 538 void RTCPSender::BuildBYE(const RtcpContext& /* ctx */, PacketSender& sender) { 539 rtcp::Bye bye; 540 bye.SetSenderSsrc(ssrc_); 541 bye.SetCsrcs(csrcs_); 542 sender.AppendPacket(bye); 543 } 544 545 void RTCPSender::BuildExtendedReports(const RtcpContext& ctx, 546 PacketSender& sender) { 547 rtcp::ExtendedReports xr; 548 xr.SetSenderSsrc(ssrc_); 549 550 if (!sending_ && xr_send_receiver_reference_time_enabled_) { 551 rtcp::Rrtr rrtr; 552 rrtr.SetNtp(env_.clock().ConvertTimestampToNtpTime(ctx.now_)); 553 xr.SetRrtr(rrtr); 554 } 555 556 for (const rtcp::ReceiveTimeInfo& rti : ctx.feedback_state_.last_xr_rtis) { 557 xr.AddDlrrItem(rti); 558 } 559 560 if (send_video_bitrate_allocation_) { 561 rtcp::TargetBitrate target_bitrate; 562 563 for (int sl = 0; sl < kMaxSpatialLayers; ++sl) { 564 for (int tl = 0; tl < kMaxTemporalStreams; ++tl) { 565 if (video_bitrate_allocation_.HasBitrate(sl, tl)) { 566 target_bitrate.AddTargetBitrate( 567 sl, tl, video_bitrate_allocation_.GetBitrate(sl, tl) / 1000); 568 } 569 } 570 } 571 572 xr.SetTargetBitrate(target_bitrate); 573 send_video_bitrate_allocation_ = false; 574 } 575 sender.AppendPacket(xr); 576 } 577 578 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, 579 RTCPPacketType packet_type, 580 ArrayView<const uint16_t> nacks) { 581 int32_t error_code = -1; 582 auto callback = [&](ArrayView<const uint8_t> packet) { 583 if (transport_->SendRtcp(packet, /*packet_options=*/{})) { 584 error_code = 0; 585 env_.event_log().Log( 586 std::make_unique<RtcEventRtcpPacketOutgoing>(packet)); 587 } 588 }; 589 std::optional<PacketSender> sender; 590 { 591 MutexLock lock(&mutex_rtcp_sender_); 592 sender.emplace(callback, max_packet_size_); 593 auto result = 594 ComputeCompoundRTCPPacket(feedback_state, packet_type, nacks, *sender); 595 if (result) { 596 return *result; 597 } 598 } 599 sender->Send(); 600 601 return error_code; 602 } 603 604 std::optional<int32_t> RTCPSender::ComputeCompoundRTCPPacket( 605 const FeedbackState& feedback_state, 606 RTCPPacketType packet_type, 607 ArrayView<const uint16_t> nacks, 608 PacketSender& sender) { 609 if (method_ == RtcpMode::kOff) { 610 RTC_LOG(LS_WARNING) << "Can't send RTCP if it is disabled."; 611 return -1; 612 } 613 // Add the flag as volatile. Non volatile entries will not be overwritten. 614 // The new volatile flag will be consumed by the end of this call. 615 SetFlag(packet_type, true); 616 617 // Prevent sending streams to send SR before any media has been sent. 618 const bool can_calculate_rtp_timestamp = last_frame_capture_time_.has_value(); 619 if (!can_calculate_rtp_timestamp) { 620 bool consumed_sr_flag = ConsumeFlag(kRtcpSr); 621 bool consumed_report_flag = sending_ && ConsumeFlag(kRtcpReport); 622 bool sender_report = consumed_report_flag || consumed_sr_flag; 623 if (sender_report && AllVolatileFlagsConsumed()) { 624 // This call was for Sender Report and nothing else. 625 return 0; 626 } 627 if (sending_ && method_ == RtcpMode::kCompound) { 628 // Not allowed to send any RTCP packet without sender report. 629 return -1; 630 } 631 } 632 633 // We need to send our NTP even if we haven't received any reports. 634 RtcpContext context(feedback_state, nacks, env_.clock().CurrentTime()); 635 636 PrepareReport(feedback_state); 637 638 bool create_bye = false; 639 640 auto it = report_flags_.begin(); 641 while (it != report_flags_.end()) { 642 uint32_t rtcp_packet_type = it->type; 643 644 if (it->is_volatile) { 645 report_flags_.erase(it++); 646 } else { 647 ++it; 648 } 649 650 // If there is a BYE, don't append now - save it and append it 651 // at the end later. 652 if (rtcp_packet_type == kRtcpBye) { 653 create_bye = true; 654 continue; 655 } 656 auto builder_it = builders_.find(rtcp_packet_type); 657 if (builder_it == builders_.end()) { 658 RTC_DCHECK_NOTREACHED() 659 << "Could not find builder for packet type " << rtcp_packet_type; 660 } else { 661 BuilderFunc func = builder_it->second; 662 (this->*func)(context, sender); 663 } 664 } 665 666 // Append the BYE now at the end 667 if (create_bye) { 668 BuildBYE(context, sender); 669 } 670 671 if (packet_type_counter_observer_ != nullptr) { 672 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( 673 remote_ssrc_, packet_type_counter_); 674 } 675 676 RTC_DCHECK(AllVolatileFlagsConsumed()); 677 return std::nullopt; 678 } 679 680 TimeDelta RTCPSender::ComputeTimeUntilNextReport(DataRate send_bitrate) { 681 /* 682 For audio we use a configurable interval (default: 5 seconds) 683 684 For video we use a configurable interval (default: 1 second) 685 for a BW smaller than ~200 kbit/s, technicaly we break the max 5% RTCP 686 BW for video but that should be extremely rare 687 688 From RFC 3550, https://www.rfc-editor.org/rfc/rfc3550#section-6.2 689 690 The RECOMMENDED value for the reduced minimum in seconds is 360 691 divided by the session bandwidth in kilobits/second. This minimum 692 is smaller than 5 seconds for bandwidths greater than 72 kb/s. 693 694 The interval between RTCP packets is varied randomly over the 695 range [0.5,1.5] times the calculated interval to avoid unintended 696 synchronization of all participants 697 */ 698 699 TimeDelta min_interval = report_interval_; 700 701 if (!audio_ && sending_ && send_bitrate > DataRate::BitsPerSec(72'000)) { 702 // Calculate bandwidth for video; 360 / send bandwidth in kbit/s per 703 // https://www.rfc-editor.org/rfc/rfc3550#section-6.2 recommendation. 704 min_interval = std::min(TimeDelta::Seconds(360) / send_bitrate.kbps(), 705 report_interval_); 706 } 707 708 // The interval between RTCP packets is varied randomly over the 709 // range [1/2,3/2] times the calculated interval. 710 int min_interval_int = dchecked_cast<int>(min_interval.ms()); 711 TimeDelta time_to_next = TimeDelta::Millis( 712 random_.Rand(min_interval_int * 1 / 2, min_interval_int * 3 / 2)); 713 714 // To be safer clamp the result. 715 return std::max(time_to_next, TimeDelta::Millis(1)); 716 } 717 718 void RTCPSender::PrepareReport(const FeedbackState& feedback_state) { 719 bool generate_report; 720 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) { 721 // Report type already explicitly set, don't automatically populate. 722 generate_report = true; 723 RTC_DCHECK(ConsumeFlag(kRtcpReport) == false); 724 } else { 725 generate_report = 726 (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) || 727 method_ == RtcpMode::kCompound; 728 if (generate_report) 729 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true); 730 } 731 732 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty())) 733 SetFlag(kRtcpSdes, true); 734 735 if (generate_report) { 736 if ((!sending_ && xr_send_receiver_reference_time_enabled_) || 737 !feedback_state.last_xr_rtis.empty() || 738 send_video_bitrate_allocation_) { 739 SetFlag(kRtcpAnyExtendedReports, true); 740 } 741 742 SetNextRtcpSendEvaluationDuration( 743 ComputeTimeUntilNextReport(feedback_state.send_bitrate)); 744 745 // RtcpSender expected to be used for sending either just sender reports 746 // or just receiver reports. 747 RTC_DCHECK(!(IsFlagPresent(kRtcpSr) && IsFlagPresent(kRtcpRr))); 748 } 749 } 750 751 std::vector<rtcp::ReportBlock> RTCPSender::CreateReportBlocks( 752 const FeedbackState& feedback_state) { 753 std::vector<rtcp::ReportBlock> result; 754 if (!receive_statistics_) 755 return result; 756 757 result = receive_statistics_->RtcpReportBlocks(RTCP_MAX_REPORT_BLOCKS); 758 759 if (!result.empty() && feedback_state.last_rr.Valid()) { 760 // Get our NTP as late as possible to avoid a race. 761 uint32_t now = CompactNtp(env_.clock().CurrentNtpTime()); 762 uint32_t receive_time = CompactNtp(feedback_state.last_rr); 763 uint32_t delay_since_last_sr = now - receive_time; 764 765 for (auto& report_block : result) { 766 report_block.SetLastSr(feedback_state.remote_sr); 767 report_block.SetDelayLastSr(delay_since_last_sr); 768 } 769 } 770 return result; 771 } 772 773 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { 774 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize); 775 MutexLock lock(&mutex_rtcp_sender_); 776 csrcs_ = csrcs; 777 } 778 779 void RTCPSender::SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) { 780 MutexLock lock(&mutex_rtcp_sender_); 781 tmmbn_to_send_ = std::move(bounding_set); 782 SetFlag(kRtcpTmmbn, true); 783 } 784 785 void RTCPSender::SetFlag(uint32_t type, bool is_volatile) { 786 if (type & kRtcpAnyExtendedReports) { 787 report_flags_.insert(ReportFlag(kRtcpAnyExtendedReports, is_volatile)); 788 } else { 789 report_flags_.insert(ReportFlag(type, is_volatile)); 790 } 791 } 792 793 bool RTCPSender::IsFlagPresent(uint32_t type) const { 794 return report_flags_.find(ReportFlag(type, false)) != report_flags_.end(); 795 } 796 797 bool RTCPSender::ConsumeFlag(uint32_t type, bool forced) { 798 auto it = report_flags_.find(ReportFlag(type, false)); 799 if (it == report_flags_.end()) 800 return false; 801 if (it->is_volatile || forced) 802 report_flags_.erase((it)); 803 return true; 804 } 805 806 bool RTCPSender::AllVolatileFlagsConsumed() const { 807 for (const ReportFlag& flag : report_flags_) { 808 if (flag.is_volatile) 809 return false; 810 } 811 return true; 812 } 813 814 void RTCPSender::SetVideoBitrateAllocation( 815 const VideoBitrateAllocation& bitrate) { 816 MutexLock lock(&mutex_rtcp_sender_); 817 if (method_ == RtcpMode::kOff) { 818 RTC_LOG(LS_WARNING) << "Can't send RTCP if it is disabled."; 819 return; 820 } 821 // Check if this allocation is first ever, or has a different set of 822 // spatial/temporal layers signaled and enabled, if so trigger an rtcp report 823 // as soon as possible. 824 std::optional<VideoBitrateAllocation> new_bitrate = 825 CheckAndUpdateLayerStructure(bitrate); 826 if (new_bitrate) { 827 video_bitrate_allocation_ = *new_bitrate; 828 RTC_LOG(LS_INFO) << "Emitting TargetBitrate XR for SSRC " << ssrc_ 829 << " with new layers enabled/disabled: " 830 << video_bitrate_allocation_.ToString(); 831 SetNextRtcpSendEvaluationDuration(TimeDelta::Zero()); 832 } else { 833 video_bitrate_allocation_ = bitrate; 834 } 835 836 send_video_bitrate_allocation_ = true; 837 SetFlag(kRtcpAnyExtendedReports, true); 838 } 839 840 std::optional<VideoBitrateAllocation> RTCPSender::CheckAndUpdateLayerStructure( 841 const VideoBitrateAllocation& bitrate) const { 842 std::optional<VideoBitrateAllocation> updated_bitrate; 843 for (size_t si = 0; si < kMaxSpatialLayers; ++si) { 844 for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) { 845 if (!updated_bitrate && 846 (bitrate.HasBitrate(si, ti) != 847 video_bitrate_allocation_.HasBitrate(si, ti) || 848 (bitrate.GetBitrate(si, ti) == 0) != 849 (video_bitrate_allocation_.GetBitrate(si, ti) == 0))) { 850 updated_bitrate = bitrate; 851 } 852 if (video_bitrate_allocation_.GetBitrate(si, ti) > 0 && 853 bitrate.GetBitrate(si, ti) == 0) { 854 // Make sure this stream disabling is explicitly signaled. 855 updated_bitrate->SetBitrate(si, ti, 0); 856 } 857 } 858 } 859 860 return updated_bitrate; 861 } 862 863 void RTCPSender::SendCombinedRtcpPacket( 864 std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) { 865 size_t max_packet_size; 866 uint32_t ssrc; 867 { 868 MutexLock lock(&mutex_rtcp_sender_); 869 if (method_ == RtcpMode::kOff) { 870 RTC_LOG(LS_WARNING) << "Can't send RTCP if it is disabled."; 871 return; 872 } 873 874 max_packet_size = max_packet_size_; 875 ssrc = ssrc_; 876 } 877 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE); 878 auto callback = [&](ArrayView<const uint8_t> packet) { 879 if (transport_->SendRtcp(packet, /*packet_options=*/{})) { 880 env_.event_log().Log( 881 std::make_unique<RtcEventRtcpPacketOutgoing>(packet)); 882 } 883 }; 884 PacketSender sender(callback, max_packet_size); 885 for (auto& rtcp_packet : rtcp_packets) { 886 rtcp_packet->SetSenderSsrc(ssrc); 887 sender.AppendPacket(*rtcp_packet); 888 } 889 sender.Send(); 890 } 891 892 void RTCPSender::SetNextRtcpSendEvaluationDuration(TimeDelta duration) { 893 next_time_to_send_rtcp_ = env_.clock().CurrentTime() + duration; 894 schedule_next_rtcp_send_evaluation_(duration); 895 } 896 897 } // namespace webrtc