rtcp_sender.cc revision d83df50e95a73859bee1568ec7375ff832e1d628
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 "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" 12 13#include <assert.h> // assert 14#include <stdlib.h> // rand 15#include <string.h> // memcpy 16 17#include <algorithm> // min 18#include <limits> // max 19 20#include "webrtc/base/checks.h" 21#include "webrtc/common_types.h" 22#include "webrtc/modules/rtp_rtcp/source/byte_io.h" 23#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" 24#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 25#include "webrtc/system_wrappers/interface/logging.h" 26#include "webrtc/system_wrappers/interface/trace_event.h" 27 28namespace webrtc { 29 30using RTCPUtility::RTCPCnameInformation; 31 32NACKStringBuilder::NACKStringBuilder() 33 : stream_(""), count_(0), prevNack_(0), consecutive_(false) { 34} 35 36NACKStringBuilder::~NACKStringBuilder() {} 37 38void NACKStringBuilder::PushNACK(uint16_t nack) 39{ 40 if (count_ == 0) { 41 stream_ << nack; 42 } else if (nack == prevNack_ + 1) { 43 consecutive_ = true; 44 } else { 45 if (consecutive_) { 46 stream_ << "-" << prevNack_; 47 consecutive_ = false; 48 } 49 stream_ << "," << nack; 50 } 51 count_++; 52 prevNack_ = nack; 53} 54 55std::string NACKStringBuilder::GetResult() { 56 if (consecutive_) { 57 stream_ << "-" << prevNack_; 58 consecutive_ = false; 59 } 60 return stream_.str(); 61} 62 63RTCPSender::FeedbackState::FeedbackState() 64 : send_payload_type(0), 65 frequency_hz(0), 66 packets_sent(0), 67 media_bytes_sent(0), 68 send_bitrate(0), 69 last_rr_ntp_secs(0), 70 last_rr_ntp_frac(0), 71 remote_sr(0), 72 has_last_xr_rr(false), 73 module(nullptr) { 74} 75 76struct RTCPSender::RtcpContext { 77 RtcpContext(const FeedbackState& feedback_state, 78 int32_t nack_size, 79 const uint16_t* nack_list, 80 bool repeat, 81 uint64_t picture_id, 82 uint8_t* buffer, 83 uint32_t buffer_size) 84 : feedback_state(feedback_state), 85 nack_size(nack_size), 86 nack_list(nack_list), 87 repeat(repeat), 88 picture_id(picture_id), 89 buffer(buffer), 90 buffer_size(buffer_size), 91 ntp_sec(0), 92 ntp_frac(0), 93 position(0) {} 94 95 uint8_t* AllocateData(uint32_t bytes) { 96 DCHECK_LE(position + bytes, buffer_size); 97 uint8_t* ptr = &buffer[position]; 98 position += bytes; 99 return ptr; 100 } 101 102 const FeedbackState& feedback_state; 103 int32_t nack_size; 104 const uint16_t* nack_list; 105 bool repeat; 106 uint64_t picture_id; 107 uint8_t* buffer; 108 uint32_t buffer_size; 109 uint32_t ntp_sec; 110 uint32_t ntp_frac; 111 uint32_t position; 112}; 113 114// TODO(sprang): Once all builders use RtcpPacket, call SendToNetwork() here. 115class RTCPSender::PacketBuiltCallback 116 : public rtcp::RtcpPacket::PacketReadyCallback { 117 public: 118 PacketBuiltCallback(RtcpContext* context) : context_(context) {} 119 virtual ~PacketBuiltCallback() {} 120 void OnPacketReady(uint8_t* data, size_t length) override { 121 context_->position += length; 122 } 123 bool BuildPacket(const rtcp::RtcpPacket& packet) { 124 return packet.BuildExternalBuffer( 125 &context_->buffer[context_->position], 126 context_->buffer_size - context_->position, this); 127 } 128 129 private: 130 RtcpContext* const context_; 131}; 132 133RTCPSender::RTCPSender( 134 int32_t id, 135 bool audio, 136 Clock* clock, 137 ReceiveStatistics* receive_statistics, 138 RtcpPacketTypeCounterObserver* packet_type_counter_observer) 139 : id_(id), 140 audio_(audio), 141 clock_(clock), 142 method_(kRtcpOff), 143 critical_section_transport_( 144 CriticalSectionWrapper::CreateCriticalSection()), 145 cbTransport_(nullptr), 146 147 critical_section_rtcp_sender_( 148 CriticalSectionWrapper::CreateCriticalSection()), 149 using_nack_(false), 150 sending_(false), 151 remb_enabled_(false), 152 next_time_to_send_rtcp_(0), 153 start_timestamp_(0), 154 last_rtp_timestamp_(0), 155 last_frame_capture_time_ms_(-1), 156 ssrc_(0), 157 remote_ssrc_(0), 158 receive_statistics_(receive_statistics), 159 160 sequence_number_fir_(0), 161 162 remb_bitrate_(0), 163 164 tmmbr_help_(), 165 tmmbr_send_(0), 166 packet_oh_send_(0), 167 168 app_sub_type_(0), 169 app_name_(0), 170 app_data_(nullptr), 171 app_length_(0), 172 173 xr_send_receiver_reference_time_enabled_(false), 174 packet_type_counter_observer_(packet_type_counter_observer) { 175 memset(last_send_report_, 0, sizeof(last_send_report_)); 176 memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_)); 177 178 builders_[kRtcpSr] = &RTCPSender::BuildSR; 179 builders_[kRtcpRr] = &RTCPSender::BuildRR; 180 builders_[kRtcpSdes] = &RTCPSender::BuildSDES; 181 builders_[kRtcpPli] = &RTCPSender::BuildPLI; 182 builders_[kRtcpFir] = &RTCPSender::BuildFIR; 183 builders_[kRtcpSli] = &RTCPSender::BuildSLI; 184 builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI; 185 builders_[kRtcpRemb] = &RTCPSender::BuildREMB; 186 builders_[kRtcpBye] = &RTCPSender::BuildBYE; 187 builders_[kRtcpApp] = &RTCPSender::BuildAPP; 188 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; 189 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; 190 builders_[kRtcpNack] = &RTCPSender::BuildNACK; 191 builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; 192 builders_[kRtcpXrReceiverReferenceTime] = 193 &RTCPSender::BuildReceiverReferenceTime; 194 builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; 195} 196 197RTCPSender::~RTCPSender() { 198} 199 200int32_t RTCPSender::RegisterSendTransport(Transport* outgoingTransport) { 201 CriticalSectionScoped lock(critical_section_transport_.get()); 202 cbTransport_ = outgoingTransport; 203 return 0; 204} 205 206RTCPMethod RTCPSender::Status() const { 207 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 208 return method_; 209} 210 211void RTCPSender::SetRTCPStatus(RTCPMethod method) { 212 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 213 method_ = method; 214 215 if (method == kRtcpOff) 216 return; 217 next_time_to_send_rtcp_ = 218 clock_->TimeInMilliseconds() + 219 (audio_ ? RTCP_INTERVAL_AUDIO_MS / 2 : RTCP_INTERVAL_VIDEO_MS / 2); 220} 221 222bool RTCPSender::Sending() const { 223 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 224 return sending_; 225} 226 227int32_t RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, 228 bool sending) { 229 bool sendRTCPBye = false; 230 { 231 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 232 233 if (method_ != kRtcpOff) { 234 if (sending == false && sending_ == true) { 235 // Trigger RTCP bye 236 sendRTCPBye = true; 237 } 238 } 239 sending_ = sending; 240 } 241 if (sendRTCPBye) 242 return SendRTCP(feedback_state, kRtcpBye); 243 return 0; 244} 245 246bool RTCPSender::REMB() const { 247 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 248 return remb_enabled_; 249} 250 251void RTCPSender::SetREMBStatus(bool enable) { 252 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 253 remb_enabled_ = enable; 254} 255 256void RTCPSender::SetREMBData(uint32_t bitrate, 257 const std::vector<uint32_t>& ssrcs) { 258 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 259 remb_bitrate_ = bitrate; 260 remb_ssrcs_ = ssrcs; 261 262 if (remb_enabled_) 263 SetFlag(kRtcpRemb, false); 264 // Send a REMB immediately if we have a new REMB. The frequency of REMBs is 265 // throttled by the caller. 266 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds(); 267} 268 269bool RTCPSender::TMMBR() const { 270 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 271 return IsFlagPresent(RTCPPacketType::kRtcpTmmbr); 272} 273 274void RTCPSender::SetTMMBRStatus(bool enable) { 275 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 276 if (enable) { 277 SetFlag(RTCPPacketType::kRtcpTmmbr, false); 278 } else { 279 ConsumeFlag(RTCPPacketType::kRtcpTmmbr, true); 280 } 281} 282 283void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { 284 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 285 start_timestamp_ = start_timestamp; 286} 287 288void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, 289 int64_t capture_time_ms) { 290 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 291 last_rtp_timestamp_ = rtp_timestamp; 292 if (capture_time_ms < 0) { 293 // We don't currently get a capture time from VoiceEngine. 294 last_frame_capture_time_ms_ = clock_->TimeInMilliseconds(); 295 } else { 296 last_frame_capture_time_ms_ = capture_time_ms; 297 } 298} 299 300void RTCPSender::SetSSRC(uint32_t ssrc) { 301 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 302 303 if (ssrc_ != 0) { 304 // not first SetSSRC, probably due to a collision 305 // schedule a new RTCP report 306 // make sure that we send a RTP packet 307 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + 100; 308 } 309 ssrc_ = ssrc; 310} 311 312void RTCPSender::SetRemoteSSRC(uint32_t ssrc) { 313 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 314 remote_ssrc_ = ssrc; 315} 316 317int32_t RTCPSender::SetCNAME(const char* c_name) { 318 if (!c_name) 319 return -1; 320 321 DCHECK_LT(strlen(c_name), static_cast<size_t>(RTCP_CNAME_SIZE)); 322 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 323 cname_ = c_name; 324 return 0; 325} 326 327int32_t RTCPSender::AddMixedCNAME(uint32_t SSRC, const char* c_name) { 328 assert(c_name); 329 DCHECK_LT(strlen(c_name), static_cast<size_t>(RTCP_CNAME_SIZE)); 330 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 331 if (csrc_cnames_.size() >= kRtpCsrcSize) 332 return -1; 333 334 csrc_cnames_[SSRC] = c_name; 335 return 0; 336} 337 338int32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) { 339 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 340 auto it = csrc_cnames_.find(SSRC); 341 342 if (it == csrc_cnames_.end()) 343 return -1; 344 345 csrc_cnames_.erase(it); 346 return 0; 347} 348 349bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const { 350/* 351 For audio we use a fix 5 sec interval 352 353 For video we use 1 sec interval fo a BW smaller than 360 kbit/s, 354 technicaly we break the max 5% RTCP BW for video below 10 kbit/s but 355 that should be extremely rare 356 357 358From RFC 3550 359 360 MAX RTCP BW is 5% if the session BW 361 A send report is approximately 65 bytes inc CNAME 362 A receiver report is approximately 28 bytes 363 364 The RECOMMENDED value for the reduced minimum in seconds is 360 365 divided by the session bandwidth in kilobits/second. This minimum 366 is smaller than 5 seconds for bandwidths greater than 72 kb/s. 367 368 If the participant has not yet sent an RTCP packet (the variable 369 initial is true), the constant Tmin is set to 2.5 seconds, else it 370 is set to 5 seconds. 371 372 The interval between RTCP packets is varied randomly over the 373 range [0.5,1.5] times the calculated interval to avoid unintended 374 synchronization of all participants 375 376 if we send 377 If the participant is a sender (we_sent true), the constant C is 378 set to the average RTCP packet size (avg_rtcp_size) divided by 25% 379 of the RTCP bandwidth (rtcp_bw), and the constant n is set to the 380 number of senders. 381 382 if we receive only 383 If we_sent is not true, the constant C is set 384 to the average RTCP packet size divided by 75% of the RTCP 385 bandwidth. The constant n is set to the number of receivers 386 (members - senders). If the number of senders is greater than 387 25%, senders and receivers are treated together. 388 389 reconsideration NOT required for peer-to-peer 390 "timer reconsideration" is 391 employed. This algorithm implements a simple back-off mechanism 392 which causes users to hold back RTCP packet transmission if the 393 group sizes are increasing. 394 395 n = number of members 396 C = avg_size/(rtcpBW/4) 397 398 3. The deterministic calculated interval Td is set to max(Tmin, n*C). 399 400 4. The calculated interval T is set to a number uniformly distributed 401 between 0.5 and 1.5 times the deterministic calculated interval. 402 403 5. The resulting value of T is divided by e-3/2=1.21828 to compensate 404 for the fact that the timer reconsideration algorithm converges to 405 a value of the RTCP bandwidth below the intended average 406*/ 407 408 int64_t now = clock_->TimeInMilliseconds(); 409 410 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 411 412 if (method_ == kRtcpOff) 413 return false; 414 415 if (!audio_ && sendKeyframeBeforeRTP) { 416 // for video key-frames we want to send the RTCP before the large key-frame 417 // if we have a 100 ms margin 418 now += RTCP_SEND_BEFORE_KEY_FRAME_MS; 419 } 420 421 if (now >= next_time_to_send_rtcp_) { 422 return true; 423 } else if (now < 0x0000ffff && 424 next_time_to_send_rtcp_ > 0xffff0000) { // 65 sec margin 425 // wrap 426 return true; 427 } 428 return false; 429} 430 431int64_t RTCPSender::SendTimeOfSendReport(uint32_t sendReport) { 432 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 433 434 // This is only saved when we are the sender 435 if ((last_send_report_[0] == 0) || (sendReport == 0)) { 436 return 0; // will be ignored 437 } else { 438 for (int i = 0; i < RTCP_NUMBER_OF_SR; ++i) { 439 if (last_send_report_[i] == sendReport) 440 return last_rtcp_time_[i]; 441 } 442 } 443 return 0; 444} 445 446bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, 447 int64_t* time_ms) const { 448 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 449 450 if (last_xr_rr_.empty()) { 451 return false; 452 } 453 std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp); 454 if (it == last_xr_rr_.end()) { 455 return false; 456 } 457 *time_ms = it->second; 458 return true; 459} 460 461int32_t RTCPSender::AddReportBlock(const RTCPReportBlock& report_block) { 462 if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { 463 LOG(LS_WARNING) << "Too many report blocks."; 464 return -1; 465 } 466 rtcp::ReportBlock* block = &report_blocks_[report_block.remoteSSRC]; 467 block->To(report_block.remoteSSRC); 468 block->WithFractionLost(report_block.fractionLost); 469 block->WithCumulativeLost(report_block.cumulativeLost); 470 block->WithExtHighestSeqNum(report_block.extendedHighSeqNum); 471 block->WithJitter(report_block.jitter); 472 block->WithLastSr(report_block.lastSR); 473 block->WithDelayLastSr(report_block.delaySinceLastSR); 474 475 return 0; 476} 477 478RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { 479 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { 480 // shift old 481 last_send_report_[i + 1] = last_send_report_[i]; 482 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; 483 } 484 485 last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac); 486 last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 16); 487 488 // The timestamp of this RTCP packet should be estimated as the timestamp of 489 // the frame being captured at this moment. We are calculating that 490 // timestamp as the last frame's timestamp + the time since the last frame 491 // was captured. 492 uint32_t rtp_timestamp = 493 start_timestamp_ + last_rtp_timestamp_ + 494 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * 495 (ctx->feedback_state.frequency_hz / 1000); 496 497 rtcp::SenderReport report; 498 report.From(ssrc_); 499 report.WithNtpSec(ctx->ntp_sec); 500 report.WithNtpFrac(ctx->ntp_frac); 501 report.WithRtpTimestamp(rtp_timestamp); 502 report.WithPacketCount(ctx->feedback_state.packets_sent); 503 report.WithOctetCount(ctx->feedback_state.media_bytes_sent); 504 505 for (auto it : report_blocks_) 506 report.WithReportBlock(it.second); 507 508 PacketBuiltCallback callback(ctx); 509 if (!callback.BuildPacket(report)) 510 return BuildResult::kTruncated; 511 512 report_blocks_.clear(); 513 return BuildResult::kSuccess; 514} 515 516RTCPSender::BuildResult RTCPSender::BuildSDES(RtcpContext* ctx) { 517 size_t length_cname = cname_.length(); 518 CHECK_LT(length_cname, static_cast<size_t>(RTCP_CNAME_SIZE)); 519 520 rtcp::Sdes sdes; 521 sdes.WithCName(ssrc_, cname_); 522 523 for (const auto it : csrc_cnames_) 524 sdes.WithCName(it.first, it.second); 525 526 PacketBuiltCallback callback(ctx); 527 if (!callback.BuildPacket(sdes)) 528 return BuildResult::kTruncated; 529 530 return BuildResult::kSuccess; 531} 532 533RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { 534 rtcp::ReceiverReport report; 535 report.From(ssrc_); 536 for (auto it : report_blocks_) 537 report.WithReportBlock(it.second); 538 539 PacketBuiltCallback callback(ctx); 540 if (!callback.BuildPacket(report)) 541 return BuildResult::kTruncated; 542 543 report_blocks_.clear(); 544 545 return BuildResult::kSuccess; 546} 547 548RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) { 549 rtcp::Pli pli; 550 pli.From(ssrc_); 551 pli.To(remote_ssrc_); 552 553 PacketBuiltCallback callback(ctx); 554 if (!callback.BuildPacket(pli)) 555 return BuildResult::kTruncated; 556 557 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 558 "RTCPSender::PLI"); 559 ++packet_type_counter_.pli_packets; 560 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount", 561 ssrc_, packet_type_counter_.pli_packets); 562 563 return BuildResult::kSuccess; 564} 565 566RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) { 567 if (!ctx->repeat) 568 ++sequence_number_fir_; // Do not increase if repetition. 569 570 rtcp::Fir fir; 571 fir.From(ssrc_); 572 fir.To(remote_ssrc_); 573 fir.WithCommandSeqNum(sequence_number_fir_); 574 575 PacketBuiltCallback callback(ctx); 576 if (!callback.BuildPacket(fir)) 577 return BuildResult::kTruncated; 578 579 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 580 "RTCPSender::FIR"); 581 ++packet_type_counter_.fir_packets; 582 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount", 583 ssrc_, packet_type_counter_.fir_packets); 584 585 return BuildResult::kSuccess; 586} 587 588/* 589 0 1 2 3 590 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 591 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 592 | First | Number | PictureID | 593 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 594*/ 595RTCPSender::BuildResult RTCPSender::BuildSLI(RtcpContext* ctx) { 596 rtcp::Sli sli; 597 sli.From(ssrc_); 598 sli.To(remote_ssrc_); 599 // Crop picture id to 6 least significant bits. 600 sli.WithPictureId(ctx->picture_id & 0x3F); 601 sli.WithFirstMb(0); 602 sli.WithNumberOfMb(0x1FFF); // 13 bits, only ones for now. 603 604 PacketBuiltCallback callback(ctx); 605 if (!callback.BuildPacket(sli)) 606 return BuildResult::kTruncated; 607 608 return BuildResult::kSuccess; 609} 610 611/* 612 0 1 2 3 613 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 614 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 615 | PB |0| Payload Type| Native RPSI bit string | 616 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 617 | defined per codec ... | Padding (0) | 618 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 619*/ 620/* 621* Note: not generic made for VP8 622*/ 623RTCPSender::BuildResult RTCPSender::BuildRPSI(RtcpContext* ctx) { 624 if (ctx->feedback_state.send_payload_type == 0xFF) 625 return BuildResult::kError; 626 627 rtcp::Rpsi rpsi; 628 rpsi.From(ssrc_); 629 rpsi.To(remote_ssrc_); 630 rpsi.WithPayloadType(ctx->feedback_state.send_payload_type); 631 rpsi.WithPictureId(ctx->picture_id); 632 633 PacketBuiltCallback callback(ctx); 634 if (!callback.BuildPacket(rpsi)) 635 return BuildResult::kTruncated; 636 637 return BuildResult::kSuccess; 638} 639 640RTCPSender::BuildResult RTCPSender::BuildREMB(RtcpContext* ctx) { 641 rtcp::Remb remb; 642 remb.From(ssrc_); 643 for (uint32_t ssrc : remb_ssrcs_) 644 remb.AppliesTo(ssrc); 645 remb.WithBitrateBps(remb_bitrate_); 646 647 PacketBuiltCallback callback(ctx); 648 if (!callback.BuildPacket(remb)) 649 return BuildResult::kTruncated; 650 651 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 652 "RTCPSender::REMB"); 653 654 return BuildResult::kSuccess; 655} 656 657void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { 658 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 659 tmmbr_send_ = target_bitrate / 1000; 660} 661 662RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) { 663 if (ctx->feedback_state.module == NULL) 664 return BuildResult::kError; 665 // Before sending the TMMBR check the received TMMBN, only an owner is 666 // allowed to raise the bitrate: 667 // * If the sender is an owner of the TMMBN -> send TMMBR 668 // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR 669 670 // get current bounding set from RTCP receiver 671 bool tmmbrOwner = false; 672 // store in candidateSet, allocates one extra slot 673 TMMBRSet* candidateSet = tmmbr_help_.CandidateSet(); 674 675 // holding critical_section_rtcp_sender_ while calling RTCPreceiver which 676 // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but 677 // since RTCPreceiver is not doing the reverse we should be fine 678 int32_t lengthOfBoundingSet = 679 ctx->feedback_state.module->BoundingSet(tmmbrOwner, candidateSet); 680 681 if (lengthOfBoundingSet > 0) { 682 for (int32_t i = 0; i < lengthOfBoundingSet; i++) { 683 if (candidateSet->Tmmbr(i) == tmmbr_send_ && 684 candidateSet->PacketOH(i) == packet_oh_send_) { 685 // do not send the same tuple 686 return BuildResult::kAborted; 687 } 688 } 689 if (!tmmbrOwner) { 690 // use received bounding set as candidate set 691 // add current tuple 692 candidateSet->SetEntry(lengthOfBoundingSet, tmmbr_send_, packet_oh_send_, 693 ssrc_); 694 int numCandidates = lengthOfBoundingSet + 1; 695 696 // find bounding set 697 TMMBRSet* boundingSet = NULL; 698 int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet); 699 if (numBoundingSet > 0 || numBoundingSet <= numCandidates) 700 tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet); 701 if (!tmmbrOwner) { 702 // did not enter bounding set, no meaning to send this request 703 return BuildResult::kAborted; 704 } 705 } 706 } 707 708 if (tmmbr_send_) { 709 rtcp::Tmmbr tmmbr; 710 tmmbr.From(ssrc_); 711 tmmbr.To(remote_ssrc_); 712 tmmbr.WithBitrateKbps(tmmbr_send_); 713 tmmbr.WithOverhead(packet_oh_send_); 714 715 PacketBuiltCallback callback(ctx); 716 if (!callback.BuildPacket(tmmbr)) 717 return BuildResult::kTruncated; 718 } 719 return BuildResult::kSuccess; 720} 721 722RTCPSender::BuildResult RTCPSender::BuildTMMBN(RtcpContext* ctx) { 723 TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend(); 724 if (boundingSet == NULL) 725 return BuildResult::kError; 726 727 rtcp::Tmmbn tmmbn; 728 tmmbn.From(ssrc_); 729 for (uint32_t i = 0; i < boundingSet->lengthOfSet(); i++) { 730 if (boundingSet->Tmmbr(i) > 0) { 731 tmmbn.WithTmmbr(boundingSet->Ssrc(i), boundingSet->Tmmbr(i), 732 boundingSet->PacketOH(i)); 733 } 734 } 735 736 PacketBuiltCallback callback(ctx); 737 if (!callback.BuildPacket(tmmbn)) 738 return BuildResult::kTruncated; 739 740 return BuildResult::kSuccess; 741} 742 743RTCPSender::BuildResult RTCPSender::BuildAPP(RtcpContext* ctx) { 744 // sanity 745 if (app_data_ == NULL) { 746 LOG(LS_WARNING) << "Failed to build app specific."; 747 return BuildResult::kError; 748 } 749 if (ctx->position + 12 + app_length_ >= IP_PACKET_SIZE) { 750 LOG(LS_WARNING) << "Failed to build app specific."; 751 return BuildResult::kTruncated; 752 } 753 *ctx->AllocateData(1) = 0x80 + app_sub_type_; 754 755 // Add APP ID 756 *ctx->AllocateData(1) = 204; 757 758 uint16_t length = (app_length_ >> 2) + 2; // include SSRC and name 759 *ctx->AllocateData(1) = static_cast<uint8_t>(length >> 8); 760 *ctx->AllocateData(1) = static_cast<uint8_t>(length); 761 762 // Add our own SSRC 763 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); 764 765 // Add our application name 766 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), app_name_); 767 768 // Add the data 769 memcpy(ctx->AllocateData(app_length_), app_data_.get(), app_length_); 770 771 return BuildResult::kSuccess; 772} 773 774RTCPSender::BuildResult RTCPSender::BuildNACK(RtcpContext* ctx) { 775 // sanity 776 if (ctx->position + 16 >= IP_PACKET_SIZE) { 777 LOG(LS_WARNING) << "Failed to build NACK."; 778 return BuildResult::kTruncated; 779 } 780 781 // int size, uint16_t* nack_list 782 // add nack list 783 uint8_t FMT = 1; 784 *ctx->AllocateData(1) = 0x80 + FMT; 785 *ctx->AllocateData(1) = 205; 786 787 *ctx->AllocateData(1) = 0; 788 int nack_size_pos_ = ctx->position; 789 *ctx->AllocateData(1) = 3; // setting it to one kNACK signal as default 790 791 // Add our own SSRC 792 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); 793 794 // Add the remote SSRC 795 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); 796 797 // Build NACK bitmasks and write them to the RTCP message. 798 // The nack list should be sorted and not contain duplicates if one 799 // wants to build the smallest rtcp nack packet. 800 int numOfNackFields = 0; 801 int maxNackFields = 802 std::min<int>(kRtcpMaxNackFields, (IP_PACKET_SIZE - ctx->position) / 4); 803 int i = 0; 804 while (i < ctx->nack_size && numOfNackFields < maxNackFields) { 805 uint16_t nack = ctx->nack_list[i++]; 806 uint16_t bitmask = 0; 807 while (i < ctx->nack_size) { 808 int shift = static_cast<uint16_t>(ctx->nack_list[i] - nack) - 1; 809 if (shift >= 0 && shift <= 15) { 810 bitmask |= (1 << shift); 811 ++i; 812 } else { 813 break; 814 } 815 } 816 // Write the sequence number and the bitmask to the packet. 817 assert(ctx->position + 4 < IP_PACKET_SIZE); 818 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), nack); 819 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), bitmask); 820 numOfNackFields++; 821 } 822 ctx->buffer[nack_size_pos_] = static_cast<uint8_t>(2 + numOfNackFields); 823 824 if (i != ctx->nack_size) 825 LOG(LS_WARNING) << "Nack list too large for one packet."; 826 827 // Report stats. 828 NACKStringBuilder stringBuilder; 829 for (int idx = 0; idx < i; ++idx) { 830 stringBuilder.PushNACK(ctx->nack_list[idx]); 831 nack_stats_.ReportRequest(ctx->nack_list[idx]); 832 } 833 packet_type_counter_.nack_requests = nack_stats_.requests(); 834 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); 835 836 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 837 "RTCPSender::NACK", "nacks", 838 TRACE_STR_COPY(stringBuilder.GetResult().c_str())); 839 ++packet_type_counter_.nack_packets; 840 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount", 841 ssrc_, packet_type_counter_.nack_packets); 842 843 return BuildResult::kSuccess; 844} 845 846RTCPSender::BuildResult RTCPSender::BuildBYE(RtcpContext* ctx) { 847 rtcp::Bye bye; 848 bye.From(ssrc_); 849 for (uint32_t csrc : csrcs_) 850 bye.WithCsrc(csrc); 851 852 PacketBuiltCallback callback(ctx); 853 if (!callback.BuildPacket(bye)) 854 return BuildResult::kTruncated; 855 856 return BuildResult::kSuccess; 857} 858 859RTCPSender::BuildResult RTCPSender::BuildReceiverReferenceTime( 860 RtcpContext* ctx) { 861 const int kRrTimeBlockLength = 20; 862 if (ctx->position + kRrTimeBlockLength >= IP_PACKET_SIZE) 863 return BuildResult::kTruncated; 864 865 if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) 866 last_xr_rr_.erase(last_xr_rr_.begin()); 867 last_xr_rr_.insert(std::pair<uint32_t, int64_t>( 868 RTCPUtility::MidNtp(ctx->ntp_sec, ctx->ntp_frac), 869 Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac))); 870 871 // Add XR header. 872 *ctx->AllocateData(1) = 0x80; 873 *ctx->AllocateData(1) = 207; 874 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 875 4); // XR packet length. 876 877 // Add our own SSRC. 878 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); 879 880 // 0 1 2 3 881 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 882 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 883 // | BT=4 | reserved | block length = 2 | 884 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 885 // | NTP timestamp, most significant word | 886 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 887 // | NTP timestamp, least significant word | 888 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 889 890 // Add Receiver Reference Time Report block. 891 *ctx->AllocateData(1) = 4; // BT. 892 *ctx->AllocateData(1) = 0; // Reserved. 893 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 894 2); // Block length. 895 896 // NTP timestamp. 897 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_sec); 898 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_frac); 899 900 return BuildResult::kSuccess; 901} 902 903RTCPSender::BuildResult RTCPSender::BuildDlrr(RtcpContext* ctx) { 904 const int kDlrrBlockLength = 24; 905 if (ctx->position + kDlrrBlockLength >= IP_PACKET_SIZE) 906 return BuildResult::kTruncated; 907 908 // Add XR header. 909 *ctx->AllocateData(1) = 0x80; 910 *ctx->AllocateData(1) = 207; 911 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 912 5); // XR packet length. 913 914 // Add our own SSRC. 915 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); 916 917 // 0 1 2 3 918 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 919 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 920 // | BT=5 | reserved | block length | 921 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 922 // | SSRC_1 (SSRC of first receiver) | sub- 923 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 924 // | last RR (LRR) | 1 925 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 926 // | delay since last RR (DLRR) | 927 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 928 // | SSRC_2 (SSRC of second receiver) | sub- 929 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 930 // : ... : 2 931 932 // Add DLRR sub block. 933 *ctx->AllocateData(1) = 5; // BT. 934 *ctx->AllocateData(1) = 0; // Reserved. 935 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 936 3); // Block length. 937 938 // NTP timestamp. 939 940 const RtcpReceiveTimeInfo& info = ctx->feedback_state.last_xr_rr; 941 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), info.sourceSSRC); 942 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), info.lastRR); 943 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), 944 info.delaySinceLastRR); 945 946 return BuildResult::kSuccess; 947} 948 949// TODO(sprang): Add a unit test for this, or remove if the code isn't used. 950RTCPSender::BuildResult RTCPSender::BuildVoIPMetric(RtcpContext* ctx) { 951 // sanity 952 if (ctx->position + 44 >= IP_PACKET_SIZE) 953 return BuildResult::kTruncated; 954 955 // Add XR header 956 *ctx->AllocateData(1) = 0x80; 957 *ctx->AllocateData(1) = 207; 958 959 uint32_t XRLengthPos = ctx->position; 960 961 // handle length later on 962 ctx->AllocateData(2); 963 964 // Add our own SSRC 965 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); 966 967 // Add a VoIP metrics block 968 *ctx->AllocateData(1) = 7; 969 *ctx->AllocateData(1) = 0; 970 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 8); 971 972 // Add the remote SSRC 973 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); 974 975 *ctx->AllocateData(1) = xr_voip_metric_.lossRate; 976 *ctx->AllocateData(1) = xr_voip_metric_.discardRate; 977 *ctx->AllocateData(1) = xr_voip_metric_.burstDensity; 978 *ctx->AllocateData(1) = xr_voip_metric_.gapDensity; 979 980 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 981 xr_voip_metric_.burstDuration); 982 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 983 xr_voip_metric_.gapDuration); 984 985 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 986 xr_voip_metric_.roundTripDelay); 987 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 988 xr_voip_metric_.endSystemDelay); 989 990 *ctx->AllocateData(1) = xr_voip_metric_.signalLevel; 991 *ctx->AllocateData(1) = xr_voip_metric_.noiseLevel; 992 *ctx->AllocateData(1) = xr_voip_metric_.RERL; 993 *ctx->AllocateData(1) = xr_voip_metric_.Gmin; 994 995 *ctx->AllocateData(1) = xr_voip_metric_.Rfactor; 996 *ctx->AllocateData(1) = xr_voip_metric_.extRfactor; 997 *ctx->AllocateData(1) = xr_voip_metric_.MOSLQ; 998 *ctx->AllocateData(1) = xr_voip_metric_.MOSCQ; 999 1000 *ctx->AllocateData(1) = xr_voip_metric_.RXconfig; 1001 *ctx->AllocateData(1) = 0; // reserved 1002 1003 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 1004 xr_voip_metric_.JBnominal); 1005 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 1006 xr_voip_metric_.JBmax); 1007 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), 1008 xr_voip_metric_.JBabsMax); 1009 1010 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[XRLengthPos], 10); 1011 1012 return BuildResult::kSuccess; 1013} 1014 1015int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, 1016 RTCPPacketType packetType, 1017 int32_t nack_size, 1018 const uint16_t* nack_list, 1019 bool repeat, 1020 uint64_t pictureID) { 1021 return SendCompoundRTCP( 1022 feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1), 1023 nack_size, nack_list, repeat, pictureID); 1024} 1025 1026int32_t RTCPSender::SendCompoundRTCP( 1027 const FeedbackState& feedback_state, 1028 const std::set<RTCPPacketType>& packetTypes, 1029 int32_t nack_size, 1030 const uint16_t* nack_list, 1031 bool repeat, 1032 uint64_t pictureID) { 1033 { 1034 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1035 if (method_ == kRtcpOff) { 1036 LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; 1037 return -1; 1038 } 1039 } 1040 uint8_t rtcp_buffer[IP_PACKET_SIZE]; 1041 int rtcp_length = 1042 PrepareRTCP(feedback_state, packetTypes, nack_size, nack_list, repeat, 1043 pictureID, rtcp_buffer, IP_PACKET_SIZE); 1044 1045 // Sanity don't send empty packets. 1046 if (rtcp_length <= 0) 1047 return -1; 1048 1049 return SendToNetwork(rtcp_buffer, static_cast<size_t>(rtcp_length)); 1050} 1051 1052int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, 1053 const std::set<RTCPPacketType>& packetTypes, 1054 int32_t nack_size, 1055 const uint16_t* nack_list, 1056 bool repeat, 1057 uint64_t pictureID, 1058 uint8_t* rtcp_buffer, 1059 int buffer_size) { 1060 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1061 1062 RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, 1063 rtcp_buffer, buffer_size); 1064 1065 // Add all flags as volatile. Non volatile entries will not be overwritten 1066 // and all new volatile flags added will be consumed by the end of this call. 1067 SetFlags(packetTypes, true); 1068 1069 if (packet_type_counter_.first_packet_time_ms == -1) 1070 packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds(); 1071 1072 bool generate_report; 1073 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) { 1074 // Report type already explicitly set, don't automatically populate. 1075 generate_report = true; 1076 DCHECK(ConsumeFlag(kRtcpReport) == false); 1077 } else { 1078 generate_report = 1079 (ConsumeFlag(kRtcpReport) && method_ == kRtcpNonCompound) || 1080 method_ == kRtcpCompound; 1081 if (generate_report) 1082 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true); 1083 } 1084 1085 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty())) 1086 SetFlag(kRtcpSdes, true); 1087 1088 // We need to send our NTP even if we haven't received any reports. 1089 clock_->CurrentNtp(context.ntp_sec, context.ntp_frac); 1090 1091 if (generate_report) { 1092 if (!sending_ && xr_send_receiver_reference_time_enabled_) 1093 SetFlag(kRtcpXrReceiverReferenceTime, true); 1094 if (feedback_state.has_last_xr_rr) 1095 SetFlag(kRtcpXrDlrrReportBlock, true); 1096 1097 // generate next time to send an RTCP report 1098 // seeded from RTP constructor 1099 int32_t random = rand() % 1000; 1100 int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS; 1101 1102 if (audio_) { 1103 timeToNext = (RTCP_INTERVAL_AUDIO_MS / 2) + 1104 (RTCP_INTERVAL_AUDIO_MS * random / 1000); 1105 } else { 1106 uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; 1107 if (sending_) { 1108 // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. 1109 uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; 1110 if (send_bitrate_kbit != 0) 1111 minIntervalMs = 360000 / send_bitrate_kbit; 1112 } 1113 if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS) 1114 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; 1115 timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000); 1116 } 1117 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; 1118 1119 StatisticianMap statisticians = 1120 receive_statistics_->GetActiveStatisticians(); 1121 if (!statisticians.empty()) { 1122 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { 1123 RTCPReportBlock report_block; 1124 if (PrepareReport(feedback_state, it->first, it->second, 1125 &report_block)) { 1126 AddReportBlock(report_block); 1127 } 1128 } 1129 } 1130 } 1131 1132 auto it = report_flags_.begin(); 1133 while (it != report_flags_.end()) { 1134 auto builder = builders_.find(it->type); 1135 DCHECK(builder != builders_.end()); 1136 if (it->is_volatile) { 1137 report_flags_.erase(it++); 1138 } else { 1139 ++it; 1140 } 1141 1142 uint32_t start_position = context.position; 1143 BuildResult result = (this->*(builder->second))(&context); 1144 switch (result) { 1145 case BuildResult::kError: 1146 return -1; 1147 case BuildResult::kTruncated: 1148 return context.position; 1149 case BuildResult::kAborted: 1150 context.position = start_position; 1151 FALLTHROUGH(); 1152 case BuildResult::kSuccess: 1153 continue; 1154 default: 1155 abort(); 1156 } 1157 } 1158 1159 if (packet_type_counter_observer_ != NULL) { 1160 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( 1161 remote_ssrc_, packet_type_counter_); 1162 } 1163 1164 DCHECK(AllVolatileFlagsConsumed()); 1165 1166 return context.position; 1167} 1168 1169bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, 1170 uint32_t ssrc, 1171 StreamStatistician* statistician, 1172 RTCPReportBlock* report_block) { 1173 // Do we have receive statistics to send? 1174 RtcpStatistics stats; 1175 if (!statistician->GetStatistics(&stats, true)) 1176 return false; 1177 report_block->fractionLost = stats.fraction_lost; 1178 report_block->cumulativeLost = stats.cumulative_lost; 1179 report_block->extendedHighSeqNum = 1180 stats.extended_max_sequence_number; 1181 report_block->jitter = stats.jitter; 1182 report_block->remoteSSRC = ssrc; 1183 1184 // TODO(sprang): Do we really need separate time stamps for each report? 1185 // Get our NTP as late as possible to avoid a race. 1186 uint32_t ntp_secs; 1187 uint32_t ntp_frac; 1188 clock_->CurrentNtp(ntp_secs, ntp_frac); 1189 1190 // Delay since last received report. 1191 uint32_t delaySinceLastReceivedSR = 0; 1192 if ((feedback_state.last_rr_ntp_secs != 0) || 1193 (feedback_state.last_rr_ntp_frac != 0)) { 1194 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions. 1195 uint32_t now = ntp_secs & 0x0000FFFF; 1196 now <<= 16; 1197 now += (ntp_frac & 0xffff0000) >> 16; 1198 1199 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; 1200 receiveTime <<= 16; 1201 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; 1202 1203 delaySinceLastReceivedSR = now-receiveTime; 1204 } 1205 report_block->delaySinceLastSR = delaySinceLastReceivedSR; 1206 report_block->lastSR = feedback_state.remote_sr; 1207 return true; 1208} 1209 1210int32_t RTCPSender::SendToNetwork(const uint8_t* dataBuffer, size_t length) { 1211 CriticalSectionScoped lock(critical_section_transport_.get()); 1212 if (cbTransport_) { 1213 if (cbTransport_->SendRTCPPacket(id_, dataBuffer, length) > 0) 1214 return 0; 1215 } 1216 return -1; 1217} 1218 1219void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { 1220 assert(csrcs.size() <= kRtpCsrcSize); 1221 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1222 csrcs_ = csrcs; 1223} 1224 1225int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, 1226 uint32_t name, 1227 const uint8_t* data, 1228 uint16_t length) { 1229 if (length % 4 != 0) { 1230 LOG(LS_ERROR) << "Failed to SetApplicationSpecificData."; 1231 return -1; 1232 } 1233 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1234 1235 SetFlag(kRtcpApp, true); 1236 app_sub_type_ = subType; 1237 app_name_ = name; 1238 app_data_.reset(new uint8_t[length]); 1239 app_length_ = length; 1240 memcpy(app_data_.get(), data, length); 1241 return 0; 1242} 1243 1244int32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) { 1245 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1246 memcpy(&xr_voip_metric_, VoIPMetric, sizeof(RTCPVoIPMetric)); 1247 1248 SetFlag(kRtcpXrVoipMetric, true); 1249 return 0; 1250} 1251 1252void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { 1253 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1254 xr_send_receiver_reference_time_enabled_ = enable; 1255} 1256 1257bool RTCPSender::RtcpXrReceiverReferenceTime() const { 1258 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1259 return xr_send_receiver_reference_time_enabled_; 1260} 1261 1262// no callbacks allowed inside this function 1263int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, 1264 uint32_t maxBitrateKbit) { 1265 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1266 1267 if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { 1268 SetFlag(kRtcpTmmbn, true); 1269 return 0; 1270 } 1271 return -1; 1272} 1273 1274void RTCPSender::SetFlag(RTCPPacketType type, bool is_volatile) { 1275 report_flags_.insert(ReportFlag(type, is_volatile)); 1276} 1277 1278void RTCPSender::SetFlags(const std::set<RTCPPacketType>& types, 1279 bool is_volatile) { 1280 for (RTCPPacketType type : types) 1281 SetFlag(type, is_volatile); 1282} 1283 1284bool RTCPSender::IsFlagPresent(RTCPPacketType type) const { 1285 return report_flags_.find(ReportFlag(type, false)) != report_flags_.end(); 1286} 1287 1288bool RTCPSender::ConsumeFlag(RTCPPacketType type, bool forced) { 1289 auto it = report_flags_.find(ReportFlag(type, false)); 1290 if (it == report_flags_.end()) 1291 return false; 1292 if (it->is_volatile || forced) 1293 report_flags_.erase((it)); 1294 return true; 1295} 1296 1297bool RTCPSender::AllVolatileFlagsConsumed() const { 1298 for (const ReportFlag& flag : report_flags_) { 1299 if (flag.is_volatile) 1300 return false; 1301 } 1302 return true; 1303} 1304 1305} // namespace webrtc 1306