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

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