Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtcp_sender.cc

Issue 1309833002: Send RTCP packets via RtcpPacket callback (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Send RTCP messags directly via callback, refactoring, rebase Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 packets_sent(0), 67 packets_sent(0),
68 media_bytes_sent(0), 68 media_bytes_sent(0),
69 send_bitrate(0), 69 send_bitrate(0),
70 last_rr_ntp_secs(0), 70 last_rr_ntp_secs(0),
71 last_rr_ntp_frac(0), 71 last_rr_ntp_frac(0),
72 remote_sr(0), 72 remote_sr(0),
73 has_last_xr_rr(false), 73 has_last_xr_rr(false),
74 module(nullptr) { 74 module(nullptr) {
75 } 75 }
76 76
77 struct RTCPSender::RtcpContext { 77 class RTCPSender::RtcpContext : public rtcp::RtcpPacket::PacketReadyCallback {
78 RtcpContext(const FeedbackState& feedback_state, 78 public:
79 RtcpContext(Transport* transport,
80 const FeedbackState& feedback_state,
79 int32_t nack_size, 81 int32_t nack_size,
80 const uint16_t* nack_list, 82 const uint16_t* nack_list,
81 bool repeat, 83 bool repeat,
82 uint64_t picture_id, 84 uint64_t picture_id,
83 uint8_t* buffer, 85 uint32_t ntp_sec,
84 uint32_t buffer_size) 86 uint32_t ntp_frac)
85 : feedback_state(feedback_state), 87 : transport_(transport),
86 nack_size(nack_size), 88 buffer_{},
åsapersson 2015/11/16 14:54:39 needed?
åsapersson 2015/12/01 13:49:20 see comment
sprang_webrtc 2015/12/02 10:33:26 Done.
87 nack_list(nack_list), 89 position_(0),
88 repeat(repeat), 90 bytes_sent_(0),
89 picture_id(picture_id), 91 feedback_state_(feedback_state),
90 buffer(buffer), 92 nack_size_(nack_size),
91 buffer_size(buffer_size), 93 nack_list_(nack_list),
92 ntp_sec(0), 94 repeat_(repeat),
93 ntp_frac(0), 95 picture_id_(picture_id),
94 position(0) {} 96 ntp_sec_(ntp_sec),
97 ntp_frac_(ntp_frac) {}
95 98
96 uint8_t* AllocateData(uint32_t bytes) { 99 virtual ~RtcpContext() {}
97 RTC_DCHECK_LE(position + bytes, buffer_size); 100
98 uint8_t* ptr = &buffer[position]; 101 void OnPacketReady(uint8_t* data, size_t length) override {
99 position += bytes; 102 if (transport_->SendRtcp(data, length))
100 return ptr; 103 bytes_sent_ += length;
104 position_ = 0;
101 } 105 }
102 106
103 const FeedbackState& feedback_state;
104 int32_t nack_size;
105 const uint16_t* nack_list;
106 bool repeat;
107 uint64_t picture_id;
108 uint8_t* buffer;
109 uint32_t buffer_size;
110 uint32_t ntp_sec;
111 uint32_t ntp_frac;
112 uint32_t position;
113 };
114
115 // TODO(sprang): Once all builders use RtcpPacket, call SendToNetwork() here.
116 class RTCPSender::PacketBuiltCallback
117 : public rtcp::RtcpPacket::PacketReadyCallback {
118 public:
119 PacketBuiltCallback(RtcpContext* context) : context_(context) {}
120 virtual ~PacketBuiltCallback() {}
121 void OnPacketReady(uint8_t* data, size_t length) override {
122 context_->position += length;
123 }
124 bool BuildPacket(const rtcp::RtcpPacket& packet) { 107 bool BuildPacket(const rtcp::RtcpPacket& packet) {
åsapersson 2015/10/13 08:50:12 empty.Append(packet); ?
sprang_webrtc 2015/12/02 10:33:26 Done.
125 return packet.BuildExternalBuffer( 108 return packet.CreateAndAddAppended(buffer_, &position_, kBufferSize, this);
126 &context_->buffer[context_->position],
127 context_->buffer_size - context_->position, this);
128 } 109 }
129 110
130 private: 111 void SendRemaining() {
131 RtcpContext* const context_; 112 if (position_ > 0)
113 OnPacketReady(buffer_, position_);
114 }
115
116 static const size_t kBufferSize = IP_PACKET_SIZE - 24;
117
118 Transport* const transport_;
119 uint8_t buffer_[kBufferSize];
120 size_t position_;
121 uint32_t bytes_sent_;
122
123 const FeedbackState& feedback_state_;
124 const int32_t nack_size_;
125 const uint16_t* nack_list_;
126 const bool repeat_;
127 const uint64_t picture_id_;
128 const uint32_t ntp_sec_;
129 const uint32_t ntp_frac_;
132 }; 130 };
133 131
134 RTCPSender::RTCPSender( 132 RTCPSender::RTCPSender(
135 bool audio, 133 bool audio,
136 Clock* clock, 134 Clock* clock,
137 ReceiveStatistics* receive_statistics, 135 ReceiveStatistics* receive_statistics,
138 RtcpPacketTypeCounterObserver* packet_type_counter_observer, 136 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
139 Transport* outgoing_transport) 137 Transport* outgoing_transport)
140 : audio_(audio), 138 : audio_(audio),
141 clock_(clock), 139 clock_(clock),
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 block->WithFractionLost(report_block.fractionLost); 459 block->WithFractionLost(report_block.fractionLost);
462 block->WithCumulativeLost(report_block.cumulativeLost); 460 block->WithCumulativeLost(report_block.cumulativeLost);
463 block->WithExtHighestSeqNum(report_block.extendedHighSeqNum); 461 block->WithExtHighestSeqNum(report_block.extendedHighSeqNum);
464 block->WithJitter(report_block.jitter); 462 block->WithJitter(report_block.jitter);
465 block->WithLastSr(report_block.lastSR); 463 block->WithLastSr(report_block.lastSR);
466 block->WithDelayLastSr(report_block.delaySinceLastSR); 464 block->WithDelayLastSr(report_block.delaySinceLastSR);
467 465
468 return 0; 466 return 0;
469 } 467 }
470 468
471 RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { 469 bool RTCPSender::BuildSR(RtcpContext* ctx) {
472 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { 470 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) {
473 // shift old 471 // shift old
474 last_send_report_[i + 1] = last_send_report_[i]; 472 last_send_report_[i + 1] = last_send_report_[i];
475 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; 473 last_rtcp_time_[i + 1] = last_rtcp_time_[i];
476 } 474 }
477 475
478 last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac); 476 last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec_, ctx->ntp_frac_);
479 last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 16); 477 last_send_report_[0] = (ctx->ntp_sec_ << 16) + (ctx->ntp_frac_ >> 16);
480 478
481 // The timestamp of this RTCP packet should be estimated as the timestamp of 479 // The timestamp of this RTCP packet should be estimated as the timestamp of
482 // the frame being captured at this moment. We are calculating that 480 // the frame being captured at this moment. We are calculating that
483 // timestamp as the last frame's timestamp + the time since the last frame 481 // timestamp as the last frame's timestamp + the time since the last frame
484 // was captured. 482 // was captured.
485 uint32_t rtp_timestamp = 483 uint32_t rtp_timestamp =
486 start_timestamp_ + last_rtp_timestamp_ + 484 start_timestamp_ + last_rtp_timestamp_ +
487 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * 485 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) *
488 (ctx->feedback_state.frequency_hz / 1000); 486 (ctx->feedback_state_.frequency_hz / 1000);
489 487
490 rtcp::SenderReport report; 488 rtcp::SenderReport report;
491 report.From(ssrc_); 489 report.From(ssrc_);
492 report.WithNtpSec(ctx->ntp_sec); 490 report.WithNtpSec(ctx->ntp_sec_);
493 report.WithNtpFrac(ctx->ntp_frac); 491 report.WithNtpFrac(ctx->ntp_frac_);
494 report.WithRtpTimestamp(rtp_timestamp); 492 report.WithRtpTimestamp(rtp_timestamp);
495 report.WithPacketCount(ctx->feedback_state.packets_sent); 493 report.WithPacketCount(ctx->feedback_state_.packets_sent);
496 report.WithOctetCount(ctx->feedback_state.media_bytes_sent); 494 report.WithOctetCount(ctx->feedback_state_.media_bytes_sent);
497 495
498 for (auto it : report_blocks_) 496 for (auto it : report_blocks_)
499 report.WithReportBlock(it.second); 497 report.WithReportBlock(it.second);
500 498
501 PacketBuiltCallback callback(ctx); 499 if (!ctx->BuildPacket(report))
åsapersson 2015/10/13 08:50:12 Shouldn't the packet be appended here (e.g. append
sprang_webrtc 2015/12/02 10:33:26 Done.
502 if (!callback.BuildPacket(report)) 500 return false;
503 return BuildResult::kTruncated;
504 501
505 report_blocks_.clear(); 502 report_blocks_.clear();
506 return BuildResult::kSuccess; 503 return true;
507 } 504 }
508 505
509 RTCPSender::BuildResult RTCPSender::BuildSDES(RtcpContext* ctx) { 506 bool RTCPSender::BuildSDES(RtcpContext* ctx) {
510 size_t length_cname = cname_.length(); 507 size_t length_cname = cname_.length();
511 RTC_CHECK_LT(length_cname, static_cast<size_t>(RTCP_CNAME_SIZE)); 508 RTC_CHECK_LT(length_cname, static_cast<size_t>(RTCP_CNAME_SIZE));
512 509
513 rtcp::Sdes sdes; 510 rtcp::Sdes sdes;
514 sdes.WithCName(ssrc_, cname_); 511 sdes.WithCName(ssrc_, cname_);
515 512
516 for (const auto it : csrc_cnames_) 513 for (const auto it : csrc_cnames_)
517 sdes.WithCName(it.first, it.second); 514 sdes.WithCName(it.first, it.second);
518 515
519 PacketBuiltCallback callback(ctx); 516 return ctx->BuildPacket(sdes);
520 if (!callback.BuildPacket(sdes))
521 return BuildResult::kTruncated;
522
523 return BuildResult::kSuccess;
524 } 517 }
525 518
526 RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { 519 bool RTCPSender::BuildRR(RtcpContext* ctx) {
527 rtcp::ReceiverReport report; 520 rtcp::ReceiverReport report;
528 report.From(ssrc_); 521 report.From(ssrc_);
529 for (auto it : report_blocks_) 522 for (auto it : report_blocks_)
530 report.WithReportBlock(it.second); 523 report.WithReportBlock(it.second);
531 524
532 PacketBuiltCallback callback(ctx); 525 if (!ctx->BuildPacket(report))
533 if (!callback.BuildPacket(report)) 526 return false;
534 return BuildResult::kTruncated;
535 527
536 report_blocks_.clear(); 528 report_blocks_.clear();
537 529 return true;
538 return BuildResult::kSuccess;
539 } 530 }
540 531
541 RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) { 532 bool RTCPSender::BuildPLI(RtcpContext* ctx) {
542 rtcp::Pli pli; 533 rtcp::Pli pli;
543 pli.From(ssrc_); 534 pli.From(ssrc_);
544 pli.To(remote_ssrc_); 535 pli.To(remote_ssrc_);
545 536
546 PacketBuiltCallback callback(ctx); 537 if (!ctx->BuildPacket(pli))
547 if (!callback.BuildPacket(pli)) 538 return false;
548 return BuildResult::kTruncated;
549 539
550 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 540 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
551 "RTCPSender::PLI"); 541 "RTCPSender::PLI");
552 ++packet_type_counter_.pli_packets; 542 ++packet_type_counter_.pli_packets;
553 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount", 543 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount",
554 ssrc_, packet_type_counter_.pli_packets); 544 ssrc_, packet_type_counter_.pli_packets);
555 545
556 return BuildResult::kSuccess; 546 return true;
557 } 547 }
558 548
559 RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) { 549 bool RTCPSender::BuildFIR(RtcpContext* ctx) {
560 if (!ctx->repeat) 550 if (!ctx->repeat_)
561 ++sequence_number_fir_; // Do not increase if repetition. 551 ++sequence_number_fir_; // Do not increase if repetition.
562 552
563 rtcp::Fir fir; 553 rtcp::Fir fir;
564 fir.From(ssrc_); 554 fir.From(ssrc_);
565 fir.To(remote_ssrc_); 555 fir.To(remote_ssrc_);
566 fir.WithCommandSeqNum(sequence_number_fir_); 556 fir.WithCommandSeqNum(sequence_number_fir_);
567 557
568 PacketBuiltCallback callback(ctx); 558 if (!ctx->BuildPacket(fir))
569 if (!callback.BuildPacket(fir)) 559 return false;
570 return BuildResult::kTruncated;
571 560
572 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 561 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
573 "RTCPSender::FIR"); 562 "RTCPSender::FIR");
574 ++packet_type_counter_.fir_packets; 563 ++packet_type_counter_.fir_packets;
575 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount", 564 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount",
576 ssrc_, packet_type_counter_.fir_packets); 565 ssrc_, packet_type_counter_.fir_packets);
577 566
578 return BuildResult::kSuccess; 567 return true;
579 } 568 }
580 569
581 /* 570 /*
582 0 1 2 3 571 0 1 2 3
583 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 572 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
584 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 573 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
585 | First | Number | PictureID | 574 | First | Number | PictureID |
586 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 575 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
587 */ 576 */
588 RTCPSender::BuildResult RTCPSender::BuildSLI(RtcpContext* ctx) { 577 bool RTCPSender::BuildSLI(RtcpContext* ctx) {
589 rtcp::Sli sli; 578 rtcp::Sli sli;
590 sli.From(ssrc_); 579 sli.From(ssrc_);
591 sli.To(remote_ssrc_); 580 sli.To(remote_ssrc_);
592 // Crop picture id to 6 least significant bits. 581 // Crop picture id to 6 least significant bits.
593 sli.WithPictureId(ctx->picture_id & 0x3F); 582 sli.WithPictureId(ctx->picture_id_ & 0x3F);
594 sli.WithFirstMb(0); 583 sli.WithFirstMb(0);
595 sli.WithNumberOfMb(0x1FFF); // 13 bits, only ones for now. 584 sli.WithNumberOfMb(0x1FFF); // 13 bits, only ones for now.
596 585
597 PacketBuiltCallback callback(ctx); 586 return ctx->BuildPacket(sli);
598 if (!callback.BuildPacket(sli))
599 return BuildResult::kTruncated;
600
601 return BuildResult::kSuccess;
602 } 587 }
603 588
604 /* 589 /*
605 0 1 2 3 590 0 1 2 3
606 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 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
607 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 592 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
608 | PB |0| Payload Type| Native RPSI bit string | 593 | PB |0| Payload Type| Native RPSI bit string |
609 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 594 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
610 | defined per codec ... | Padding (0) | 595 | defined per codec ... | Padding (0) |
611 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 596 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
612 */ 597 */
613 /* 598 /*
614 * Note: not generic made for VP8 599 * Note: not generic made for VP8
615 */ 600 */
616 RTCPSender::BuildResult RTCPSender::BuildRPSI(RtcpContext* ctx) { 601 bool RTCPSender::BuildRPSI(RtcpContext* ctx) {
617 if (ctx->feedback_state.send_payload_type == 0xFF) 602 if (ctx->feedback_state_.send_payload_type == 0xFF)
618 return BuildResult::kError; 603 return false;
619 604
620 rtcp::Rpsi rpsi; 605 rtcp::Rpsi rpsi;
621 rpsi.From(ssrc_); 606 rpsi.From(ssrc_);
622 rpsi.To(remote_ssrc_); 607 rpsi.To(remote_ssrc_);
623 rpsi.WithPayloadType(ctx->feedback_state.send_payload_type); 608 rpsi.WithPayloadType(ctx->feedback_state_.send_payload_type);
624 rpsi.WithPictureId(ctx->picture_id); 609 rpsi.WithPictureId(ctx->picture_id_);
625 610
626 PacketBuiltCallback callback(ctx); 611 return ctx->BuildPacket(rpsi);
627 if (!callback.BuildPacket(rpsi))
628 return BuildResult::kTruncated;
629
630 return BuildResult::kSuccess;
631 } 612 }
632 613
633 RTCPSender::BuildResult RTCPSender::BuildREMB(RtcpContext* ctx) { 614 bool RTCPSender::BuildREMB(RtcpContext* ctx) {
634 rtcp::Remb remb; 615 rtcp::Remb remb;
635 remb.From(ssrc_); 616 remb.From(ssrc_);
636 for (uint32_t ssrc : remb_ssrcs_) 617 for (uint32_t ssrc : remb_ssrcs_)
637 remb.AppliesTo(ssrc); 618 remb.AppliesTo(ssrc);
638 remb.WithBitrateBps(remb_bitrate_); 619 remb.WithBitrateBps(remb_bitrate_);
639 620
640 PacketBuiltCallback callback(ctx); 621 if (!ctx->BuildPacket(remb))
641 if (!callback.BuildPacket(remb)) 622 return false;
642 return BuildResult::kTruncated;
643 623
644 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 624 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
645 "RTCPSender::REMB"); 625 "RTCPSender::REMB");
646 626
647 return BuildResult::kSuccess; 627 return true;
648 } 628 }
649 629
650 void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { 630 void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) {
651 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 631 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
652 tmmbr_send_ = target_bitrate / 1000; 632 tmmbr_send_ = target_bitrate / 1000;
653 } 633 }
654 634
655 RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) { 635 bool RTCPSender::BuildTMMBR(RtcpContext* ctx) {
656 if (ctx->feedback_state.module == NULL) 636 if (ctx->feedback_state_.module == nullptr)
657 return BuildResult::kError; 637 return false;
658 // Before sending the TMMBR check the received TMMBN, only an owner is 638 // Before sending the TMMBR check the received TMMBN, only an owner is
659 // allowed to raise the bitrate: 639 // allowed to raise the bitrate:
660 // * If the sender is an owner of the TMMBN -> send TMMBR 640 // * If the sender is an owner of the TMMBN -> send TMMBR
661 // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR 641 // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR
662 642
663 // get current bounding set from RTCP receiver 643 // get current bounding set from RTCP receiver
664 bool tmmbrOwner = false; 644 bool tmmbrOwner = false;
665 // store in candidateSet, allocates one extra slot 645 // store in candidateSet, allocates one extra slot
666 TMMBRSet* candidateSet = tmmbr_help_.CandidateSet(); 646 TMMBRSet* candidateSet = tmmbr_help_.CandidateSet();
667 647
668 // holding critical_section_rtcp_sender_ while calling RTCPreceiver which 648 // holding critical_section_rtcp_sender_ while calling RTCPreceiver which
669 // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but 649 // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but
670 // since RTCPreceiver is not doing the reverse we should be fine 650 // since RTCPreceiver is not doing the reverse we should be fine
671 int32_t lengthOfBoundingSet = 651 int32_t lengthOfBoundingSet =
672 ctx->feedback_state.module->BoundingSet(tmmbrOwner, candidateSet); 652 ctx->feedback_state_.module->BoundingSet(tmmbrOwner, candidateSet);
673 653
674 if (lengthOfBoundingSet > 0) { 654 if (lengthOfBoundingSet > 0) {
675 for (int32_t i = 0; i < lengthOfBoundingSet; i++) { 655 for (int32_t i = 0; i < lengthOfBoundingSet; i++) {
676 if (candidateSet->Tmmbr(i) == tmmbr_send_ && 656 if (candidateSet->Tmmbr(i) == tmmbr_send_ &&
677 candidateSet->PacketOH(i) == packet_oh_send_) { 657 candidateSet->PacketOH(i) == packet_oh_send_) {
678 // do not send the same tuple 658 // Do not send the same tuple.
679 return BuildResult::kAborted; 659 return true;
680 } 660 }
681 } 661 }
682 if (!tmmbrOwner) { 662 if (!tmmbrOwner) {
683 // use received bounding set as candidate set 663 // use received bounding set as candidate set
684 // add current tuple 664 // add current tuple
685 candidateSet->SetEntry(lengthOfBoundingSet, tmmbr_send_, packet_oh_send_, 665 candidateSet->SetEntry(lengthOfBoundingSet, tmmbr_send_, packet_oh_send_,
686 ssrc_); 666 ssrc_);
687 int numCandidates = lengthOfBoundingSet + 1; 667 int numCandidates = lengthOfBoundingSet + 1;
688 668
689 // find bounding set 669 // find bounding set
690 TMMBRSet* boundingSet = NULL; 670 TMMBRSet* boundingSet = nullptr;
691 int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet); 671 int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet);
692 if (numBoundingSet > 0 || numBoundingSet <= numCandidates) 672 if (numBoundingSet > 0 || numBoundingSet <= numCandidates)
693 tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet); 673 tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet);
694 if (!tmmbrOwner) { 674 if (!tmmbrOwner) {
695 // did not enter bounding set, no meaning to send this request 675 // Did not enter bounding set, no meaning to send this request.
696 return BuildResult::kAborted; 676 return true;
697 } 677 }
698 } 678 }
699 } 679 }
700 680
701 if (tmmbr_send_) { 681 if (tmmbr_send_) {
702 rtcp::Tmmbr tmmbr; 682 rtcp::Tmmbr tmmbr;
703 tmmbr.From(ssrc_); 683 tmmbr.From(ssrc_);
704 tmmbr.To(remote_ssrc_); 684 tmmbr.To(remote_ssrc_);
705 tmmbr.WithBitrateKbps(tmmbr_send_); 685 tmmbr.WithBitrateKbps(tmmbr_send_);
706 tmmbr.WithOverhead(packet_oh_send_); 686 tmmbr.WithOverhead(packet_oh_send_);
707 687
708 PacketBuiltCallback callback(ctx); 688 return ctx->BuildPacket(tmmbr);
709 if (!callback.BuildPacket(tmmbr))
710 return BuildResult::kTruncated;
711 } 689 }
712 return BuildResult::kSuccess; 690 return true;
713 } 691 }
714 692
715 RTCPSender::BuildResult RTCPSender::BuildTMMBN(RtcpContext* ctx) { 693 bool RTCPSender::BuildTMMBN(RtcpContext* ctx) {
716 TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend(); 694 TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend();
717 if (boundingSet == NULL) 695 if (boundingSet == nullptr)
718 return BuildResult::kError; 696 return false;
719 697
720 rtcp::Tmmbn tmmbn; 698 rtcp::Tmmbn tmmbn;
721 tmmbn.From(ssrc_); 699 tmmbn.From(ssrc_);
722 for (uint32_t i = 0; i < boundingSet->lengthOfSet(); i++) { 700 for (uint32_t i = 0; i < boundingSet->lengthOfSet(); i++) {
723 if (boundingSet->Tmmbr(i) > 0) { 701 if (boundingSet->Tmmbr(i) > 0) {
724 tmmbn.WithTmmbr(boundingSet->Ssrc(i), boundingSet->Tmmbr(i), 702 tmmbn.WithTmmbr(boundingSet->Ssrc(i), boundingSet->Tmmbr(i),
725 boundingSet->PacketOH(i)); 703 boundingSet->PacketOH(i));
726 } 704 }
727 } 705 }
728 706
729 PacketBuiltCallback callback(ctx); 707 return ctx->BuildPacket(tmmbn);
730 if (!callback.BuildPacket(tmmbn))
731 return BuildResult::kTruncated;
732
733 return BuildResult::kSuccess;
734 } 708 }
735 709
736 RTCPSender::BuildResult RTCPSender::BuildAPP(RtcpContext* ctx) { 710 bool RTCPSender::BuildAPP(RtcpContext* ctx) {
737 rtcp::App app; 711 rtcp::App app;
738 app.From(ssrc_); 712 app.From(ssrc_);
739 app.WithSubType(app_sub_type_); 713 app.WithSubType(app_sub_type_);
740 app.WithName(app_name_); 714 app.WithName(app_name_);
741 app.WithData(app_data_.get(), app_length_); 715 app.WithData(app_data_.get(), app_length_);
742 716
743 PacketBuiltCallback callback(ctx); 717 return ctx->BuildPacket(app);
744 if (!callback.BuildPacket(app))
745 return BuildResult::kTruncated;
746
747 return BuildResult::kSuccess;
748 } 718 }
749 719
750 RTCPSender::BuildResult RTCPSender::BuildNACK(RtcpContext* ctx) { 720 bool RTCPSender::BuildNACK(RtcpContext* ctx) {
751 // sanity 721 rtcp::Nack nack;
752 if (ctx->position + 16 >= IP_PACKET_SIZE) { 722 nack.From(ssrc_);
753 LOG(LS_WARNING) << "Failed to build NACK."; 723 nack.To(remote_ssrc_);
754 return BuildResult::kTruncated; 724 nack.WithList(ctx->nack_list_, ctx->nack_size_);
755 }
756 725
757 // int size, uint16_t* nack_list 726 if (!ctx->BuildPacket(nack))
758 // add nack list 727 return false;
759 uint8_t FMT = 1;
760 *ctx->AllocateData(1) = 0x80 + FMT;
761 *ctx->AllocateData(1) = 205;
762
763 *ctx->AllocateData(1) = 0;
764 int nack_size_pos_ = ctx->position;
765 *ctx->AllocateData(1) = 3; // setting it to one kNACK signal as default
766
767 // Add our own SSRC
768 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_);
769
770 // Add the remote SSRC
771 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_);
772
773 // Build NACK bitmasks and write them to the RTCP message.
774 // The nack list should be sorted and not contain duplicates if one
775 // wants to build the smallest rtcp nack packet.
776 int numOfNackFields = 0;
777 int maxNackFields =
778 std::min<int>(kRtcpMaxNackFields, (IP_PACKET_SIZE - ctx->position) / 4);
779 int i = 0;
780 while (i < ctx->nack_size && numOfNackFields < maxNackFields) {
781 uint16_t nack = ctx->nack_list[i++];
782 uint16_t bitmask = 0;
783 while (i < ctx->nack_size) {
784 int shift = static_cast<uint16_t>(ctx->nack_list[i] - nack) - 1;
785 if (shift >= 0 && shift <= 15) {
786 bitmask |= (1 << shift);
787 ++i;
788 } else {
789 break;
790 }
791 }
792 // Write the sequence number and the bitmask to the packet.
793 assert(ctx->position + 4 < IP_PACKET_SIZE);
794 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), nack);
795 ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), bitmask);
796 numOfNackFields++;
797 }
798 ctx->buffer[nack_size_pos_] = static_cast<uint8_t>(2 + numOfNackFields);
799
800 if (i != ctx->nack_size)
801 LOG(LS_WARNING) << "Nack list too large for one packet.";
802 728
803 // Report stats. 729 // Report stats.
804 NACKStringBuilder stringBuilder; 730 NACKStringBuilder stringBuilder;
805 for (int idx = 0; idx < i; ++idx) { 731 for (int idx = 0; idx < ctx->nack_size_; ++idx) {
806 stringBuilder.PushNACK(ctx->nack_list[idx]); 732 stringBuilder.PushNACK(ctx->nack_list_[idx]);
807 nack_stats_.ReportRequest(ctx->nack_list[idx]); 733 nack_stats_.ReportRequest(ctx->nack_list_[idx]);
808 } 734 }
809 packet_type_counter_.nack_requests = nack_stats_.requests(); 735 packet_type_counter_.nack_requests = nack_stats_.requests();
810 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); 736 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
811 737
812 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 738 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
813 "RTCPSender::NACK", "nacks", 739 "RTCPSender::NACK", "nacks",
814 TRACE_STR_COPY(stringBuilder.GetResult().c_str())); 740 TRACE_STR_COPY(stringBuilder.GetResult().c_str()));
815 ++packet_type_counter_.nack_packets; 741 ++packet_type_counter_.nack_packets;
816 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount", 742 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount",
817 ssrc_, packet_type_counter_.nack_packets); 743 ssrc_, packet_type_counter_.nack_packets);
818 744
819 return BuildResult::kSuccess; 745 return true;
820 } 746 }
821 747
822 RTCPSender::BuildResult RTCPSender::BuildBYE(RtcpContext* ctx) { 748 bool RTCPSender::BuildBYE(RtcpContext* ctx) {
823 rtcp::Bye bye; 749 rtcp::Bye bye;
824 bye.From(ssrc_); 750 bye.From(ssrc_);
825 for (uint32_t csrc : csrcs_) 751 for (uint32_t csrc : csrcs_)
826 bye.WithCsrc(csrc); 752 bye.WithCsrc(csrc);
827 753
828 PacketBuiltCallback callback(ctx); 754 return ctx->BuildPacket(bye);
829 if (!callback.BuildPacket(bye))
830 return BuildResult::kTruncated;
831
832 return BuildResult::kSuccess;
833 } 755 }
834 756
835 RTCPSender::BuildResult RTCPSender::BuildReceiverReferenceTime( 757 bool RTCPSender::BuildReceiverReferenceTime(RtcpContext* ctx) {
836 RtcpContext* ctx) {
837
838 if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) 758 if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR)
839 last_xr_rr_.erase(last_xr_rr_.begin()); 759 last_xr_rr_.erase(last_xr_rr_.begin());
840 last_xr_rr_.insert(std::pair<uint32_t, int64_t>( 760 last_xr_rr_.insert(std::pair<uint32_t, int64_t>(
841 RTCPUtility::MidNtp(ctx->ntp_sec, ctx->ntp_frac), 761 RTCPUtility::MidNtp(ctx->ntp_sec_, ctx->ntp_frac_),
842 Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac))); 762 Clock::NtpToMs(ctx->ntp_sec_, ctx->ntp_frac_)));
843 763
844 rtcp::Xr xr; 764 rtcp::Xr xr;
845 xr.From(ssrc_); 765 xr.From(ssrc_);
846 766
847 rtcp::Rrtr rrtr; 767 rtcp::Rrtr rrtr;
848 rrtr.WithNtpSec(ctx->ntp_sec); 768 rrtr.WithNtpSec(ctx->ntp_sec_);
849 rrtr.WithNtpFrac(ctx->ntp_frac); 769 rrtr.WithNtpFrac(ctx->ntp_frac_);
850 770
851 xr.WithRrtr(&rrtr); 771 xr.WithRrtr(&rrtr);
852 772
853 // TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP? 773 // TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP?
854 774
855 PacketBuiltCallback callback(ctx); 775 return ctx->BuildPacket(xr);
856 if (!callback.BuildPacket(xr))
857 return BuildResult::kTruncated;
858
859 return BuildResult::kSuccess;
860 } 776 }
861 777
862 RTCPSender::BuildResult RTCPSender::BuildDlrr(RtcpContext* ctx) { 778 bool RTCPSender::BuildDlrr(RtcpContext* ctx) {
863 rtcp::Xr xr; 779 rtcp::Xr xr;
864 xr.From(ssrc_); 780 xr.From(ssrc_);
865 781
866 rtcp::Dlrr dlrr; 782 rtcp::Dlrr dlrr;
867 const RtcpReceiveTimeInfo& info = ctx->feedback_state.last_xr_rr; 783 const RtcpReceiveTimeInfo& info = ctx->feedback_state_.last_xr_rr;
868 dlrr.WithDlrrItem(info.sourceSSRC, info.lastRR, info.delaySinceLastRR); 784 dlrr.WithDlrrItem(info.sourceSSRC, info.lastRR, info.delaySinceLastRR);
869 785
870 xr.WithDlrr(&dlrr); 786 xr.WithDlrr(&dlrr);
871 787
872 PacketBuiltCallback callback(ctx); 788 return ctx->BuildPacket(xr);
873 if (!callback.BuildPacket(xr))
874 return BuildResult::kTruncated;
875
876 return BuildResult::kSuccess;
877 } 789 }
878 790
879 // TODO(sprang): Add a unit test for this, or remove if the code isn't used. 791 // TODO(sprang): Add a unit test for this, or remove if the code isn't used.
880 RTCPSender::BuildResult RTCPSender::BuildVoIPMetric(RtcpContext* ctx) { 792 bool RTCPSender::BuildVoIPMetric(RtcpContext* ctx) {
881 rtcp::Xr xr; 793 rtcp::Xr xr;
882 xr.From(ssrc_); 794 xr.From(ssrc_);
883 795
884 rtcp::VoipMetric voip; 796 rtcp::VoipMetric voip;
885 voip.To(remote_ssrc_); 797 voip.To(remote_ssrc_);
886 voip.LossRate(xr_voip_metric_.lossRate); 798 voip.LossRate(xr_voip_metric_.lossRate);
887 voip.DiscardRate(xr_voip_metric_.discardRate); 799 voip.DiscardRate(xr_voip_metric_.discardRate);
888 voip.BurstDensity(xr_voip_metric_.burstDensity); 800 voip.BurstDensity(xr_voip_metric_.burstDensity);
889 voip.GapDensity(xr_voip_metric_.gapDensity); 801 voip.GapDensity(xr_voip_metric_.gapDensity);
890 voip.BurstDuration(xr_voip_metric_.burstDuration); 802 voip.BurstDuration(xr_voip_metric_.burstDuration);
891 voip.GapDuration(xr_voip_metric_.gapDuration); 803 voip.GapDuration(xr_voip_metric_.gapDuration);
892 voip.RoundTripDelay(xr_voip_metric_.roundTripDelay); 804 voip.RoundTripDelay(xr_voip_metric_.roundTripDelay);
893 voip.EndSystemDelay(xr_voip_metric_.endSystemDelay); 805 voip.EndSystemDelay(xr_voip_metric_.endSystemDelay);
894 voip.SignalLevel(xr_voip_metric_.signalLevel); 806 voip.SignalLevel(xr_voip_metric_.signalLevel);
895 voip.NoiseLevel(xr_voip_metric_.noiseLevel); 807 voip.NoiseLevel(xr_voip_metric_.noiseLevel);
896 voip.Rerl(xr_voip_metric_.RERL); 808 voip.Rerl(xr_voip_metric_.RERL);
897 voip.Gmin(xr_voip_metric_.Gmin); 809 voip.Gmin(xr_voip_metric_.Gmin);
898 voip.Rfactor(xr_voip_metric_.Rfactor); 810 voip.Rfactor(xr_voip_metric_.Rfactor);
899 voip.ExtRfactor(xr_voip_metric_.extRfactor); 811 voip.ExtRfactor(xr_voip_metric_.extRfactor);
900 voip.MosLq(xr_voip_metric_.MOSLQ); 812 voip.MosLq(xr_voip_metric_.MOSLQ);
901 voip.MosCq(xr_voip_metric_.MOSCQ); 813 voip.MosCq(xr_voip_metric_.MOSCQ);
902 voip.RxConfig(xr_voip_metric_.RXconfig); 814 voip.RxConfig(xr_voip_metric_.RXconfig);
903 voip.JbNominal(xr_voip_metric_.JBnominal); 815 voip.JbNominal(xr_voip_metric_.JBnominal);
904 voip.JbMax(xr_voip_metric_.JBmax); 816 voip.JbMax(xr_voip_metric_.JBmax);
905 voip.JbAbsMax(xr_voip_metric_.JBabsMax); 817 voip.JbAbsMax(xr_voip_metric_.JBabsMax);
906 818
907 xr.WithVoipMetric(&voip); 819 xr.WithVoipMetric(&voip);
908 820
909 PacketBuiltCallback callback(ctx); 821 return ctx->BuildPacket(xr);
910 if (!callback.BuildPacket(xr))
911 return BuildResult::kTruncated;
912
913 return BuildResult::kSuccess;
914 } 822 }
915 823
916 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, 824 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
917 RTCPPacketType packetType, 825 RTCPPacketType packetType,
918 int32_t nack_size, 826 int32_t nack_size,
919 const uint16_t* nack_list, 827 const uint16_t* nack_list,
920 bool repeat, 828 bool repeat,
921 uint64_t pictureID) { 829 uint64_t pictureID) {
922 return SendCompoundRTCP( 830 return SendCompoundRTCP(
923 feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1), 831 feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1),
924 nack_size, nack_list, repeat, pictureID); 832 nack_size, nack_list, repeat, pictureID);
925 } 833 }
926 834
927 int32_t RTCPSender::SendCompoundRTCP( 835 int32_t RTCPSender::SendCompoundRTCP(
928 const FeedbackState& feedback_state, 836 const FeedbackState& feedback_state,
929 const std::set<RTCPPacketType>& packetTypes, 837 const std::set<RTCPPacketType>& packet_types,
930 int32_t nack_size, 838 int32_t nack_size,
931 const uint16_t* nack_list, 839 const uint16_t* nack_list,
932 bool repeat, 840 bool repeat,
933 uint64_t pictureID) { 841 uint64_t pictureID) {
934 { 842 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
935 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 843
936 if (method_ == kRtcpOff) { 844 if (method_ == kRtcpOff) {
937 LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; 845 LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
938 return -1; 846 return -1;
847 }
848
849 // We need to send our NTP even if we haven't received any reports.
850 uint32_t ntp_sec;
851 uint32_t ntp_frac;
852 clock_->CurrentNtp(ntp_sec, ntp_frac);
853 RtcpContext context(transport_, feedback_state, nack_size, nack_list, repeat,
854 pictureID, ntp_sec, ntp_frac);
855
856 PrepareReport(packet_types, feedback_state);
857
858 auto it = report_flags_.begin();
859 while (it != report_flags_.end()) {
860 auto builder = builders_.find(it->type);
861 RTC_DCHECK(builder != builders_.end());
862 if (it->is_volatile) {
863 report_flags_.erase(it++);
864 } else {
865 ++it;
939 } 866 }
867
868 if (!(this->*(builder->second))(&context))
869 return false;
åsapersson 2015/11/16 14:54:39 return -1;
åsapersson 2015/12/01 13:49:20 see comment
sprang_webrtc 2015/12/02 10:33:26 Done.
940 } 870 }
941 uint8_t rtcp_buffer[IP_PACKET_SIZE];
942 int rtcp_length =
943 PrepareRTCP(feedback_state, packetTypes, nack_size, nack_list, repeat,
944 pictureID, rtcp_buffer, IP_PACKET_SIZE);
945 871
åsapersson 2015/11/16 14:54:39 lock needed when sending?
sprang_webrtc 2015/12/01 10:23:06 No, the lock was needed before to protect the poin
åsapersson 2015/12/01 13:49:20 Isn't the lock now held when sending (while it was
sprang_webrtc 2015/12/02 10:33:26 Changed so we collect RtcpPacket instances first,
946 // Sanity don't send empty packets. 872 context.SendRemaining();
947 if (rtcp_length <= 0)
948 return -1;
949 873
950 return SendToNetwork(rtcp_buffer, static_cast<size_t>(rtcp_length)); 874 if (packet_type_counter_observer_ != nullptr) {
875 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
876 remote_ssrc_, packet_type_counter_);
877 }
878
879 RTC_DCHECK(AllVolatileFlagsConsumed());
880
881 return context.bytes_sent_ > 0 ? 0 : -1;
åsapersson 2015/10/13 08:50:12 And build the packet here? something like contex
sprang_webrtc 2015/11/03 15:40:32 That was my initial thought, but it has some drawb
951 } 882 }
952 883
953 int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, 884 void RTCPSender::PrepareReport(const std::set<RTCPPacketType>& packetTypes,
954 const std::set<RTCPPacketType>& packetTypes, 885 const FeedbackState& feedback_state) {
955 int32_t nack_size,
956 const uint16_t* nack_list,
957 bool repeat,
958 uint64_t pictureID,
959 uint8_t* rtcp_buffer,
960 int buffer_size) {
961 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
962
963 RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID,
964 rtcp_buffer, buffer_size);
965
966 // Add all flags as volatile. Non volatile entries will not be overwritten 886 // Add all flags as volatile. Non volatile entries will not be overwritten
967 // and all new volatile flags added will be consumed by the end of this call. 887 // and all new volatile flags added will be consumed by the end of this call.
968 SetFlags(packetTypes, true); 888 SetFlags(packetTypes, true);
969 889
970 if (packet_type_counter_.first_packet_time_ms == -1) 890 if (packet_type_counter_.first_packet_time_ms == -1)
971 packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds(); 891 packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds();
972 892
973 bool generate_report; 893 bool generate_report;
974 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) { 894 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) {
975 // Report type already explicitly set, don't automatically populate. 895 // Report type already explicitly set, don't automatically populate.
976 generate_report = true; 896 generate_report = true;
977 RTC_DCHECK(ConsumeFlag(kRtcpReport) == false); 897 RTC_DCHECK(ConsumeFlag(kRtcpReport) == false);
978 } else { 898 } else {
979 generate_report = 899 generate_report =
980 (ConsumeFlag(kRtcpReport) && method_ == kRtcpNonCompound) || 900 (ConsumeFlag(kRtcpReport) && method_ == kRtcpNonCompound) ||
981 method_ == kRtcpCompound; 901 method_ == kRtcpCompound;
982 if (generate_report) 902 if (generate_report)
983 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true); 903 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true);
984 } 904 }
985 905
986 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty())) 906 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty()))
987 SetFlag(kRtcpSdes, true); 907 SetFlag(kRtcpSdes, true);
988 908
989 // We need to send our NTP even if we haven't received any reports.
990 clock_->CurrentNtp(context.ntp_sec, context.ntp_frac);
991
992 if (generate_report) { 909 if (generate_report) {
993 if (!sending_ && xr_send_receiver_reference_time_enabled_) 910 if (!sending_ && xr_send_receiver_reference_time_enabled_)
994 SetFlag(kRtcpXrReceiverReferenceTime, true); 911 SetFlag(kRtcpXrReceiverReferenceTime, true);
995 if (feedback_state.has_last_xr_rr) 912 if (feedback_state.has_last_xr_rr)
996 SetFlag(kRtcpXrDlrrReportBlock, true); 913 SetFlag(kRtcpXrDlrrReportBlock, true);
997 914
998 // generate next time to send an RTCP report 915 // generate next time to send an RTCP report
999 // seeded from RTP constructor 916 // seeded from RTP constructor
1000 int32_t random = rand() % 1000; 917 int32_t random = rand() % 1000;
1001 int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS; 918 int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS;
(...skipping 13 matching lines...) Expand all
1015 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; 932 minIntervalMs = RTCP_INTERVAL_VIDEO_MS;
1016 timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000); 933 timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000);
1017 } 934 }
1018 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; 935 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext;
1019 936
1020 StatisticianMap statisticians = 937 StatisticianMap statisticians =
1021 receive_statistics_->GetActiveStatisticians(); 938 receive_statistics_->GetActiveStatisticians();
1022 if (!statisticians.empty()) { 939 if (!statisticians.empty()) {
1023 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { 940 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) {
1024 RTCPReportBlock report_block; 941 RTCPReportBlock report_block;
1025 if (PrepareReport(feedback_state, it->first, it->second, 942 if (PrepareReportBlock(feedback_state, it->first, it->second,
1026 &report_block)) { 943 &report_block)) {
1027 AddReportBlock(report_block); 944 AddReportBlock(report_block);
1028 } 945 }
1029 } 946 }
1030 } 947 }
1031 } 948 }
1032
1033 auto it = report_flags_.begin();
1034 while (it != report_flags_.end()) {
1035 auto builder = builders_.find(it->type);
1036 RTC_DCHECK(builder != builders_.end());
1037 if (it->is_volatile) {
1038 report_flags_.erase(it++);
1039 } else {
1040 ++it;
1041 }
1042
1043 uint32_t start_position = context.position;
1044 BuildResult result = (this->*(builder->second))(&context);
1045 switch (result) {
1046 case BuildResult::kError:
1047 return -1;
1048 case BuildResult::kTruncated:
1049 return context.position;
1050 case BuildResult::kAborted:
1051 context.position = start_position;
1052 FALLTHROUGH();
1053 case BuildResult::kSuccess:
1054 continue;
1055 default:
1056 abort();
1057 }
1058 }
1059
1060 if (packet_type_counter_observer_ != NULL) {
1061 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
1062 remote_ssrc_, packet_type_counter_);
1063 }
1064
1065 RTC_DCHECK(AllVolatileFlagsConsumed());
1066
1067 return context.position;
1068 } 949 }
1069 950
1070 bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, 951 bool RTCPSender::PrepareReportBlock(const FeedbackState& feedback_state,
1071 uint32_t ssrc, 952 uint32_t ssrc,
1072 StreamStatistician* statistician, 953 StreamStatistician* statistician,
1073 RTCPReportBlock* report_block) { 954 RTCPReportBlock* report_block) {
1074 // Do we have receive statistics to send? 955 // Do we have receive statistics to send?
1075 RtcpStatistics stats; 956 RtcpStatistics stats;
1076 if (!statistician->GetStatistics(&stats, true)) 957 if (!statistician->GetStatistics(&stats, true))
1077 return false; 958 return false;
1078 report_block->fractionLost = stats.fraction_lost; 959 report_block->fractionLost = stats.fraction_lost;
1079 report_block->cumulativeLost = stats.cumulative_lost; 960 report_block->cumulativeLost = stats.cumulative_lost;
1080 report_block->extendedHighSeqNum = 961 report_block->extendedHighSeqNum =
1081 stats.extended_max_sequence_number; 962 stats.extended_max_sequence_number;
1082 report_block->jitter = stats.jitter; 963 report_block->jitter = stats.jitter;
1083 report_block->remoteSSRC = ssrc; 964 report_block->remoteSSRC = ssrc;
(...skipping 17 matching lines...) Expand all
1101 receiveTime <<= 16; 982 receiveTime <<= 16;
1102 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; 983 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
1103 984
1104 delaySinceLastReceivedSR = now-receiveTime; 985 delaySinceLastReceivedSR = now-receiveTime;
1105 } 986 }
1106 report_block->delaySinceLastSR = delaySinceLastReceivedSR; 987 report_block->delaySinceLastSR = delaySinceLastReceivedSR;
1107 report_block->lastSR = feedback_state.remote_sr; 988 report_block->lastSR = feedback_state.remote_sr;
1108 return true; 989 return true;
1109 } 990 }
1110 991
1111 int32_t RTCPSender::SendToNetwork(const uint8_t* dataBuffer, size_t length) {
1112 if (transport_->SendRtcp(dataBuffer, length))
1113 return 0;
1114 return -1;
1115 }
1116
1117 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { 992 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
1118 assert(csrcs.size() <= kRtpCsrcSize); 993 assert(csrcs.size() <= kRtpCsrcSize);
1119 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 994 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
1120 csrcs_ = csrcs; 995 csrcs_ = csrcs;
1121 } 996 }
1122 997
1123 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, 998 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType,
1124 uint32_t name, 999 uint32_t name,
1125 const uint8_t* data, 1000 const uint8_t* data,
1126 uint16_t length) { 1001 uint16_t length) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 Transport* const transport_; 1089 Transport* const transport_;
1215 bool send_failure_; 1090 bool send_failure_;
1216 } sender(transport_); 1091 } sender(transport_);
1217 1092
1218 uint8_t buffer[IP_PACKET_SIZE]; 1093 uint8_t buffer[IP_PACKET_SIZE];
1219 return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) && 1094 return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) &&
1220 !sender.send_failure_; 1095 !sender.send_failure_;
1221 } 1096 }
1222 1097
1223 } // namespace webrtc 1098 } // namespace webrtc
OLDNEW
« webrtc/modules/rtp_rtcp/source/rtcp_sender.h ('K') | « webrtc/modules/rtp_rtcp/source/rtcp_sender.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698