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