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

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

Issue 2979413002: Refactor composing report blocks for rtcp Sender/Receiver reports (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 uint32_t rtp_timestamp = 448 uint32_t rtp_timestamp =
449 timestamp_offset_ + last_rtp_timestamp_ + 449 timestamp_offset_ + last_rtp_timestamp_ +
450 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * rtp_rate; 450 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * rtp_rate;
451 451
452 rtcp::SenderReport* report = new rtcp::SenderReport(); 452 rtcp::SenderReport* report = new rtcp::SenderReport();
453 report->SetSenderSsrc(ssrc_); 453 report->SetSenderSsrc(ssrc_);
454 report->SetNtp(ctx.now_); 454 report->SetNtp(ctx.now_);
455 report->SetRtpTimestamp(rtp_timestamp); 455 report->SetRtpTimestamp(rtp_timestamp);
456 report->SetPacketCount(ctx.feedback_state_.packets_sent); 456 report->SetPacketCount(ctx.feedback_state_.packets_sent);
457 report->SetOctetCount(ctx.feedback_state_.media_bytes_sent); 457 report->SetOctetCount(ctx.feedback_state_.media_bytes_sent);
458 458 report->SetReportBlocks(CreateReportBlocks(ctx.feedback_state_));
459 for (auto it : report_blocks_)
460 report->AddReportBlock(it.second);
461
462 report_blocks_.clear();
463 459
464 return std::unique_ptr<rtcp::RtcpPacket>(report); 460 return std::unique_ptr<rtcp::RtcpPacket>(report);
465 } 461 }
466 462
467 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildSDES( 463 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildSDES(
468 const RtcpContext& ctx) { 464 const RtcpContext& ctx) {
469 size_t length_cname = cname_.length(); 465 size_t length_cname = cname_.length();
470 RTC_CHECK_LT(length_cname, RTCP_CNAME_SIZE); 466 RTC_CHECK_LT(length_cname, RTCP_CNAME_SIZE);
471 467
472 rtcp::Sdes* sdes = new rtcp::Sdes(); 468 rtcp::Sdes* sdes = new rtcp::Sdes();
473 sdes->AddCName(ssrc_, cname_); 469 sdes->AddCName(ssrc_, cname_);
474 470
475 for (const auto& it : csrc_cnames_) 471 for (const auto& it : csrc_cnames_)
476 RTC_CHECK(sdes->AddCName(it.first, it.second)); 472 RTC_CHECK(sdes->AddCName(it.first, it.second));
477 473
478 return std::unique_ptr<rtcp::RtcpPacket>(sdes); 474 return std::unique_ptr<rtcp::RtcpPacket>(sdes);
479 } 475 }
480 476
481 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildRR(const RtcpContext& ctx) { 477 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildRR(const RtcpContext& ctx) {
482 rtcp::ReceiverReport* report = new rtcp::ReceiverReport(); 478 rtcp::ReceiverReport* report = new rtcp::ReceiverReport();
483 report->SetSenderSsrc(ssrc_); 479 report->SetSenderSsrc(ssrc_);
484 for (auto it : report_blocks_) 480 report->SetReportBlocks(CreateReportBlocks(ctx.feedback_state_));
485 report->AddReportBlock(it.second);
486 481
487 report_blocks_.clear();
488 return std::unique_ptr<rtcp::RtcpPacket>(report); 482 return std::unique_ptr<rtcp::RtcpPacket>(report);
489 } 483 }
490 484
491 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildPLI(const RtcpContext& ctx) { 485 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildPLI(const RtcpContext& ctx) {
492 rtcp::Pli* pli = new rtcp::Pli(); 486 rtcp::Pli* pli = new rtcp::Pli();
493 pli->SetSenderSsrc(ssrc_); 487 pli->SetSenderSsrc(ssrc_);
494 pli->SetMediaSsrc(remote_ssrc_); 488 pli->SetMediaSsrc(remote_ssrc_);
495 489
496 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 490 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
497 "RTCPSender::PLI"); 491 "RTCPSender::PLI");
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 } 817 }
824 if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS) 818 if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS)
825 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; 819 minIntervalMs = RTCP_INTERVAL_VIDEO_MS;
826 } 820 }
827 // The interval between RTCP packets is varied randomly over the 821 // The interval between RTCP packets is varied randomly over the
828 // range [1/2,3/2] times the calculated interval. 822 // range [1/2,3/2] times the calculated interval.
829 uint32_t timeToNext = 823 uint32_t timeToNext =
830 random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2); 824 random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2);
831 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; 825 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext;
832 826
833 if (receive_statistics_) { 827 // RtcpSender expected to be used for sending either just sender reports
834 StatisticianMap statisticians = 828 // or just receiver reports.
835 receive_statistics_->GetActiveStatisticians(); 829 RTC_DCHECK(!(IsFlagPresent(kRtcpSr) && IsFlagPresent(kRtcpRr)));
836 RTC_DCHECK(report_blocks_.empty());
837 for (auto& it : statisticians) {
838 AddReportBlock(feedback_state, it.first, it.second);
839 }
840 }
841 } 830 }
842 } 831 }
843 832
844 bool RTCPSender::AddReportBlock(const FeedbackState& feedback_state, 833 std::vector<rtcp::ReportBlock> RTCPSender::CreateReportBlocks(
845 uint32_t ssrc, 834 const FeedbackState& feedback_state) {
846 StreamStatistician* statistician) { 835 std::vector<rtcp::ReportBlock> result;
847 // Do we have receive statistics to send? 836 if (!receive_statistics_)
848 RtcpStatistics stats; 837 return result;
849 if (!statistician->GetStatistics(&stats, true))
850 return false;
851 838
852 if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { 839 for (auto& statistician : receive_statistics_->GetActiveStatisticians()) {
eladalon 2017/07/21 13:34:45 Maybe: auto name_me = receive_statistics_->GetAc
danilchap 2017/07/21 17:11:14 Done, that is an optimization and closer to the or
853 LOG(LS_WARNING) << "Too many report blocks."; 840 // Do we have receive statistics to send?
854 return false; 841 RtcpStatistics stats;
842 if (!statistician.second->GetStatistics(&stats, true))
eladalon 2017/07/21 13:34:45 nits: 1. Inside of ReceiveStatisticsImpl::GetActi
danilchap 2017/07/21 17:11:14 This CL is about refactoring rtcp_sender, would pr
eladalon 2017/07/25 12:19:20 1. Yes, I didn't intend for this to be done in thi
danilchap 2017/07/25 15:20:08 That is my assumption since I never seen code in w
843 continue;
844 // TODO(danilchap): Support sending more than |RTCP_MAX_REPORT_BLOCKS| per
845 // compound rtcp packet when single rtcp module is used for multiple media
846 // streams.
847 if (result.size() >= RTCP_MAX_REPORT_BLOCKS) {
848 LOG(LS_WARNING) << "Too many report blocks.";
849 continue;
eladalon 2017/07/21 13:34:45 When I read this, I wonder if we should |continue|
danilchap 2017/07/21 17:11:14 I initially put more reasonable break, but then sw
eladalon 2017/07/25 12:19:20 Due to my lack of context, I'm okay with either br
danilchap 2017/07/25 15:20:08 Next CL (early draft is https://codereview.webrtc.
850 }
851 rtcp::ReportBlock block;
852 block.SetMediaSsrc(statistician.first);
853 block.SetFractionLost(stats.fraction_lost);
854 if (!block.SetCumulativeLost(stats.cumulative_lost)) {
855 LOG(LS_WARNING) << "Cumulative lost is oversized.";
856 continue;
857 }
858 block.SetExtHighestSeqNum(stats.extended_max_sequence_number);
859 block.SetJitter(stats.jitter);
860
861 result.push_back(block);
eladalon 2017/07/21 13:34:45 Brainstorming - what do you think about constructi
danilchap 2017/07/21 17:11:14 Done.
855 } 862 }
856 RTC_DCHECK(report_blocks_.find(ssrc) == report_blocks_.end()); 863
857 rtcp::ReportBlock* block = &report_blocks_[ssrc]; 864 if (!result.empty() && ((feedback_state.last_rr_ntp_secs != 0) ||
858 block->SetMediaSsrc(ssrc); 865 (feedback_state.last_rr_ntp_frac != 0))) {
859 block->SetFractionLost(stats.fraction_lost); 866 // Get our NTP as late as possible to avoid a race.
860 if (!block->SetCumulativeLost(stats.cumulative_lost)) { 867 uint32_t now = CompactNtp(clock_->CurrentNtpTime());
861 report_blocks_.erase(ssrc); 868
862 LOG(LS_WARNING) << "Cumulative lost is oversized."; 869 uint32_t receive_time = feedback_state.last_rr_ntp_secs & 0x0000FFFF;
863 return false; 870 receive_time <<= 16;
871 receive_time += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
872
873 uint32_t delay_since_last_sr = now - receive_time;
874 // TODO(danilchap): Instead of setting same value on all report blocks,
875 // set only when media_ssrc match sender ssrc of the sender report
876 // remote times were taken from.
877 for (auto& report_block : result) {
878 report_block.SetLastSr(feedback_state.remote_sr);
879 report_block.SetDelayLastSr(delay_since_last_sr);
880 }
864 } 881 }
865 block->SetExtHighestSeqNum(stats.extended_max_sequence_number); 882 return result;
866 block->SetJitter(stats.jitter);
867 block->SetLastSr(feedback_state.remote_sr);
868
869 // TODO(sprang): Do we really need separate time stamps for each report?
870 // Get our NTP as late as possible to avoid a race.
871 NtpTime ntp = clock_->CurrentNtpTime();
872
873 // Delay since last received report.
874 if ((feedback_state.last_rr_ntp_secs != 0) ||
875 (feedback_state.last_rr_ntp_frac != 0)) {
876 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions.
877 uint32_t now = CompactNtp(ntp);
878
879 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF;
880 receiveTime <<= 16;
881 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
882
883 block->SetDelayLastSr(now - receiveTime);
884 }
885 return true;
886 } 883 }
887 884
888 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { 885 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
889 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize); 886 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize);
890 rtc::CritScope lock(&critical_section_rtcp_sender_); 887 rtc::CritScope lock(&critical_section_rtcp_sender_);
891 csrcs_ = csrcs; 888 csrcs_ = csrcs;
892 } 889 }
893 890
894 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, 891 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType,
895 uint32_t name, 892 uint32_t name,
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 max_packet_size = max_packet_size_; 1005 max_packet_size = max_packet_size_;
1009 } 1006 }
1010 1007
1011 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE); 1008 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE);
1012 uint8_t buffer[IP_PACKET_SIZE]; 1009 uint8_t buffer[IP_PACKET_SIZE];
1013 return packet.BuildExternalBuffer(buffer, max_packet_size, &sender) && 1010 return packet.BuildExternalBuffer(buffer, max_packet_size, &sender) &&
1014 !sender.send_failure_; 1011 !sender.send_failure_;
1015 } 1012 }
1016 1013
1017 } // namespace webrtc 1014 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698