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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |