Chromium Code Reviews| 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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians(); |
| 853 LOG(LS_WARNING) << "Too many report blocks."; | 840 result.reserve(statisticians.size()); |
| 854 return false; | 841 for (auto& statistician : statisticians) { |
| 842 // Do we have receive statistics to send? | |
| 843 RtcpStatistics stats; | |
| 844 if (!statistician.second->GetStatistics(&stats, true)) | |
| 845 continue; | |
| 846 // TODO(danilchap): Support sending more than |RTCP_MAX_REPORT_BLOCKS| per | |
| 847 // compound rtcp packet when single rtcp module is used for multiple media | |
| 848 // streams. | |
| 849 if (result.size() >= RTCP_MAX_REPORT_BLOCKS) { | |
| 850 LOG(LS_WARNING) << "Too many report blocks."; | |
| 851 continue; | |
| 852 } | |
| 853 result.emplace_back(); | |
| 854 rtcp::ReportBlock& block = result.back(); | |
|
eladalon
2017/07/25 12:19:20
It would probably be overkill to make sure the emp
danilchap
2017/07/25 15:20:08
yep, specially that emplace_back has no way to rep
| |
| 855 block.SetMediaSsrc(statistician.first); | |
| 856 block.SetFractionLost(stats.fraction_lost); | |
| 857 if (!block.SetCumulativeLost(stats.cumulative_lost)) { | |
| 858 LOG(LS_WARNING) << "Cumulative lost is oversized."; | |
| 859 result.pop_back(); | |
| 860 continue; | |
| 861 } | |
| 862 block.SetExtHighestSeqNum(stats.extended_max_sequence_number); | |
| 863 block.SetJitter(stats.jitter); | |
| 855 } | 864 } |
| 856 RTC_DCHECK(report_blocks_.find(ssrc) == report_blocks_.end()); | 865 |
| 857 rtcp::ReportBlock* block = &report_blocks_[ssrc]; | 866 if (!result.empty() && ((feedback_state.last_rr_ntp_secs != 0) || |
| 858 block->SetMediaSsrc(ssrc); | 867 (feedback_state.last_rr_ntp_frac != 0))) { |
| 859 block->SetFractionLost(stats.fraction_lost); | 868 // Get our NTP as late as possible to avoid a race. |
| 860 if (!block->SetCumulativeLost(stats.cumulative_lost)) { | 869 uint32_t now = CompactNtp(clock_->CurrentNtpTime()); |
| 861 report_blocks_.erase(ssrc); | 870 |
| 862 LOG(LS_WARNING) << "Cumulative lost is oversized."; | 871 uint32_t receive_time = feedback_state.last_rr_ntp_secs & 0x0000FFFF; |
| 863 return false; | 872 receive_time <<= 16; |
| 873 receive_time += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; | |
| 874 | |
| 875 uint32_t delay_since_last_sr = now - receive_time; | |
| 876 // TODO(danilchap): Instead of setting same value on all report blocks, | |
| 877 // set only when media_ssrc match sender ssrc of the sender report | |
| 878 // remote times were taken from. | |
| 879 for (auto& report_block : result) { | |
| 880 report_block.SetLastSr(feedback_state.remote_sr); | |
| 881 report_block.SetDelayLastSr(delay_since_last_sr); | |
| 882 } | |
| 864 } | 883 } |
| 865 block->SetExtHighestSeqNum(stats.extended_max_sequence_number); | 884 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 } | 885 } |
| 887 | 886 |
| 888 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { | 887 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { |
| 889 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize); | 888 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize); |
| 890 rtc::CritScope lock(&critical_section_rtcp_sender_); | 889 rtc::CritScope lock(&critical_section_rtcp_sender_); |
| 891 csrcs_ = csrcs; | 890 csrcs_ = csrcs; |
| 892 } | 891 } |
| 893 | 892 |
| 894 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, | 893 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, |
| 895 uint32_t name, | 894 uint32_t name, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1008 max_packet_size = max_packet_size_; | 1007 max_packet_size = max_packet_size_; |
| 1009 } | 1008 } |
| 1010 | 1009 |
| 1011 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE); | 1010 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE); |
| 1012 uint8_t buffer[IP_PACKET_SIZE]; | 1011 uint8_t buffer[IP_PACKET_SIZE]; |
| 1013 return packet.BuildExternalBuffer(buffer, max_packet_size, &sender) && | 1012 return packet.BuildExternalBuffer(buffer, max_packet_size, &sender) && |
| 1014 !sender.send_failure_; | 1013 !sender.send_failure_; |
| 1015 } | 1014 } |
| 1016 | 1015 |
| 1017 } // namespace webrtc | 1016 } // namespace webrtc |
| OLD | NEW |