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 14 matching lines...) Expand all Loading... |
25 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | 25 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
26 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | 26 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
27 #include "webrtc/modules/utility/include/process_thread.h" | 27 #include "webrtc/modules/utility/include/process_thread.h" |
28 #include "webrtc/modules/video_coding/include/video_coding.h" | 28 #include "webrtc/modules/video_coding/include/video_coding.h" |
29 #include "webrtc/modules/video_processing/include/video_processing.h" | 29 #include "webrtc/modules/video_processing/include/video_processing.h" |
30 #include "webrtc/modules/video_render/video_render_defines.h" | 30 #include "webrtc/modules/video_render/video_render_defines.h" |
31 #include "webrtc/system_wrappers/include/metrics.h" | 31 #include "webrtc/system_wrappers/include/metrics.h" |
32 #include "webrtc/video/call_stats.h" | 32 #include "webrtc/video/call_stats.h" |
33 #include "webrtc/video/payload_router.h" | 33 #include "webrtc/video/payload_router.h" |
34 #include "webrtc/video/receive_statistics_proxy.h" | 34 #include "webrtc/video/receive_statistics_proxy.h" |
35 #include "webrtc/video/report_block_stats.h" | |
36 | 35 |
37 namespace webrtc { | 36 namespace webrtc { |
38 | 37 |
39 static const int kMaxTargetDelayMs = 10000; | 38 static const int kMaxTargetDelayMs = 10000; |
40 const int kMinSendSidePacketHistorySize = 600; | 39 const int kMinSendSidePacketHistorySize = 600; |
41 const int kMaxPacketAgeToNack = 450; | 40 const int kMaxPacketAgeToNack = 450; |
42 const int kMaxNackListSize = 250; | 41 const int kMaxNackListSize = 250; |
43 | 42 |
44 // Helper class receiving statistics callbacks. | 43 // Helper class receiving statistics callbacks. |
45 class ChannelStatsObserver : public CallStatsObserver { | 44 class ChannelStatsObserver : public CallStatsObserver { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 incoming_video_stream_(nullptr), | 99 incoming_video_stream_(nullptr), |
101 intra_frame_observer_(intra_frame_observer), | 100 intra_frame_observer_(intra_frame_observer), |
102 rtt_stats_(rtt_stats), | 101 rtt_stats_(rtt_stats), |
103 paced_sender_(paced_sender), | 102 paced_sender_(paced_sender), |
104 packet_router_(packet_router), | 103 packet_router_(packet_router), |
105 bandwidth_observer_(bandwidth_observer), | 104 bandwidth_observer_(bandwidth_observer), |
106 transport_feedback_observer_(transport_feedback_observer), | 105 transport_feedback_observer_(transport_feedback_observer), |
107 nack_history_size_sender_(kMinSendSidePacketHistorySize), | 106 nack_history_size_sender_(kMinSendSidePacketHistorySize), |
108 max_nack_reordering_threshold_(kMaxPacketAgeToNack), | 107 max_nack_reordering_threshold_(kMaxPacketAgeToNack), |
109 pre_render_callback_(NULL), | 108 pre_render_callback_(NULL), |
110 report_block_stats_sender_(new ReportBlockStats()), | |
111 time_of_first_rtt_ms_(-1), | |
112 rtt_sum_ms_(0), | |
113 last_rtt_ms_(0), | 109 last_rtt_ms_(0), |
114 num_rtts_(0), | |
115 rtp_rtcp_modules_( | 110 rtp_rtcp_modules_( |
116 CreateRtpRtcpModules(!sender, | 111 CreateRtpRtcpModules(!sender, |
117 vie_receiver_.GetReceiveStatistics(), | 112 vie_receiver_.GetReceiveStatistics(), |
118 transport, | 113 transport, |
119 intra_frame_observer_, | 114 intra_frame_observer_, |
120 bandwidth_observer_.get(), | 115 bandwidth_observer_.get(), |
121 transport_feedback_observer_, | 116 transport_feedback_observer_, |
122 rtt_stats_, | 117 rtt_stats_, |
123 &rtcp_packet_type_counter_observer_, | 118 &rtcp_packet_type_counter_observer_, |
124 remote_bitrate_estimator, | 119 remote_bitrate_estimator, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i], sender_); | 176 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i], sender_); |
182 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | 177 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
183 module_process_thread_->DeRegisterModule(rtp_rtcp); | 178 module_process_thread_->DeRegisterModule(rtp_rtcp); |
184 delete rtp_rtcp; | 179 delete rtp_rtcp; |
185 } | 180 } |
186 } | 181 } |
187 | 182 |
188 void ViEChannel::UpdateHistograms() { | 183 void ViEChannel::UpdateHistograms() { |
189 int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds(); | 184 int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds(); |
190 | 185 |
191 { | |
192 rtc::CritScope lock(&crit_); | |
193 int64_t elapsed_sec = (now - time_of_first_rtt_ms_) / 1000; | |
194 if (time_of_first_rtt_ms_ != -1 && num_rtts_ > 0 && | |
195 elapsed_sec > metrics::kMinRunTimeInSeconds) { | |
196 int64_t avg_rtt_ms = (rtt_sum_ms_ + num_rtts_ / 2) / num_rtts_; | |
197 RTC_HISTOGRAM_COUNTS_10000( | |
198 "WebRTC.Video.AverageRoundTripTimeInMilliseconds", avg_rtt_ms); | |
199 } | |
200 } | |
201 | |
202 if (sender_) { | 186 if (sender_) { |
203 RtcpPacketTypeCounter rtcp_counter; | 187 RtcpPacketTypeCounter rtcp_counter; |
204 GetSendRtcpPacketTypeCounter(&rtcp_counter); | 188 GetSendRtcpPacketTypeCounter(&rtcp_counter); |
205 int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000; | 189 int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000; |
206 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { | 190 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { |
207 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute", | 191 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute", |
208 rtcp_counter.nack_packets * 60 / elapsed_sec); | 192 rtcp_counter.nack_packets * 60 / elapsed_sec); |
209 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute", | 193 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute", |
210 rtcp_counter.fir_packets * 60 / elapsed_sec); | 194 rtcp_counter.fir_packets * 60 / elapsed_sec); |
211 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute", | 195 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute", |
212 rtcp_counter.pli_packets * 60 / elapsed_sec); | 196 rtcp_counter.pli_packets * 60 / elapsed_sec); |
213 if (rtcp_counter.nack_requests > 0) { | 197 if (rtcp_counter.nack_requests > 0) { |
214 RTC_HISTOGRAM_PERCENTAGE( | 198 RTC_HISTOGRAM_PERCENTAGE( |
215 "WebRTC.Video.UniqueNackRequestsReceivedInPercent", | 199 "WebRTC.Video.UniqueNackRequestsReceivedInPercent", |
216 rtcp_counter.UniqueNackRequestsInPercent()); | 200 rtcp_counter.UniqueNackRequestsInPercent()); |
217 } | 201 } |
218 int fraction_lost = report_block_stats_sender_->FractionLostInPercent(); | |
219 if (fraction_lost != -1) { | |
220 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.SentPacketsLostInPercent", | |
221 fraction_lost); | |
222 } | |
223 } | 202 } |
224 | 203 |
225 StreamDataCounters rtp; | 204 StreamDataCounters rtp; |
226 StreamDataCounters rtx; | 205 StreamDataCounters rtx; |
227 GetSendStreamDataCounters(&rtp, &rtx); | 206 GetSendStreamDataCounters(&rtp, &rtx); |
228 StreamDataCounters rtp_rtx = rtp; | 207 StreamDataCounters rtp_rtx = rtp; |
229 rtp_rtx.Add(rtx); | 208 rtp_rtx.Add(rtx); |
230 elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs( | 209 elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs( |
231 Clock::GetRealTimeClock()->TimeInMilliseconds()) / | 210 Clock::GetRealTimeClock()->TimeInMilliseconds()) / |
232 1000; | 211 1000; |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 int32_t ViEChannel::SetRTCPCName(const char* rtcp_cname) { | 617 int32_t ViEChannel::SetRTCPCName(const char* rtcp_cname) { |
639 RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending()); | 618 RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending()); |
640 return rtp_rtcp_modules_[0]->SetCNAME(rtcp_cname); | 619 return rtp_rtcp_modules_[0]->SetCNAME(rtcp_cname); |
641 } | 620 } |
642 | 621 |
643 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) { | 622 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) { |
644 uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc(); | 623 uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc(); |
645 return rtp_rtcp_modules_[0]->RemoteCNAME(remoteSSRC, rtcp_cname); | 624 return rtp_rtcp_modules_[0]->RemoteCNAME(remoteSSRC, rtcp_cname); |
646 } | 625 } |
647 | 626 |
648 int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, | |
649 uint32_t* cumulative_lost, | |
650 uint32_t* extended_max, | |
651 uint32_t* jitter_samples, | |
652 int64_t* rtt_ms) const { | |
653 // Aggregate the report blocks associated with streams sent on this channel. | |
654 std::vector<RTCPReportBlock> report_blocks; | |
655 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
656 rtp_rtcp->RemoteRTCPStat(&report_blocks); | |
657 | |
658 if (report_blocks.empty()) | |
659 return -1; | |
660 | |
661 uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc(); | |
662 std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin(); | |
663 for (; it != report_blocks.end(); ++it) { | |
664 if (it->remoteSSRC == remote_ssrc) | |
665 break; | |
666 } | |
667 if (it == report_blocks.end()) { | |
668 // We have not received packets with an SSRC matching the report blocks. To | |
669 // have a chance of calculating an RTT we will try with the SSRC of the | |
670 // first report block received. | |
671 // This is very important for send-only channels where we don't know the | |
672 // SSRC of the other end. | |
673 remote_ssrc = report_blocks[0].remoteSSRC; | |
674 } | |
675 | |
676 // TODO(asapersson): Change report_block_stats to not rely on | |
677 // GetSendRtcpStatistics to be called. | |
678 RTCPReportBlock report = | |
679 report_block_stats_sender_->AggregateAndStore(report_blocks); | |
680 *fraction_lost = report.fractionLost; | |
681 *cumulative_lost = report.cumulativeLost; | |
682 *extended_max = report.extendedHighSeqNum; | |
683 *jitter_samples = report.jitter; | |
684 | |
685 int64_t dummy; | |
686 int64_t rtt = 0; | |
687 if (rtp_rtcp_modules_[0]->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != | |
688 0) { | |
689 return -1; | |
690 } | |
691 *rtt_ms = rtt; | |
692 return 0; | |
693 } | |
694 | |
695 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback( | 627 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback( |
696 RtcpStatisticsCallback* callback) { | 628 RtcpStatisticsCallback* callback) { |
697 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | 629 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
698 rtp_rtcp->RegisterRtcpStatisticsCallback(callback); | 630 rtp_rtcp->RegisterRtcpStatisticsCallback(callback); |
699 } | 631 } |
700 | 632 |
701 void ViEChannel::RegisterRtcpPacketTypeCounterObserver( | 633 void ViEChannel::RegisterRtcpPacketTypeCounterObserver( |
702 RtcpPacketTypeCounterObserver* observer) { | 634 RtcpPacketTypeCounterObserver* observer) { |
703 rtcp_packet_type_counter_observer_.Set(observer); | 635 rtcp_packet_type_counter_observer_.Set(observer); |
704 } | 636 } |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers, | 840 int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers, |
909 uint16_t length) { | 841 uint16_t length) { |
910 return rtp_rtcp_modules_[0]->SendNACK(sequence_numbers, length); | 842 return rtp_rtcp_modules_[0]->SendNACK(sequence_numbers, length); |
911 } | 843 } |
912 | 844 |
913 void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 845 void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
914 if (!sender_) | 846 if (!sender_) |
915 vcm_->SetReceiveChannelParameters(max_rtt_ms); | 847 vcm_->SetReceiveChannelParameters(max_rtt_ms); |
916 | 848 |
917 rtc::CritScope lock(&crit_); | 849 rtc::CritScope lock(&crit_); |
918 if (time_of_first_rtt_ms_ == -1) | |
919 time_of_first_rtt_ms_ = Clock::GetRealTimeClock()->TimeInMilliseconds(); | |
920 rtt_sum_ms_ += avg_rtt_ms; | |
921 last_rtt_ms_ = avg_rtt_ms; | 850 last_rtt_ms_ = avg_rtt_ms; |
922 ++num_rtts_; | |
923 } | 851 } |
924 | 852 |
925 int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params, | 853 int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params, |
926 const FecProtectionParams* key_fec_params, | 854 const FecProtectionParams* key_fec_params, |
927 uint32_t* video_rate_bps, | 855 uint32_t* video_rate_bps, |
928 uint32_t* nack_rate_bps, | 856 uint32_t* nack_rate_bps, |
929 uint32_t* fec_rate_bps) { | 857 uint32_t* fec_rate_bps) { |
930 *video_rate_bps = 0; | 858 *video_rate_bps = 0; |
931 *nack_rate_bps = 0; | 859 *nack_rate_bps = 0; |
932 *fec_rate_bps = 0; | 860 *fec_rate_bps = 0; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 rtc::CritScope lock(&crit_); | 959 rtc::CritScope lock(&crit_); |
1032 receive_stats_callback_ = receive_statistics_proxy; | 960 receive_stats_callback_ = receive_statistics_proxy; |
1033 } | 961 } |
1034 | 962 |
1035 void ViEChannel::SetIncomingVideoStream( | 963 void ViEChannel::SetIncomingVideoStream( |
1036 IncomingVideoStream* incoming_video_stream) { | 964 IncomingVideoStream* incoming_video_stream) { |
1037 rtc::CritScope lock(&crit_); | 965 rtc::CritScope lock(&crit_); |
1038 incoming_video_stream_ = incoming_video_stream; | 966 incoming_video_stream_ = incoming_video_stream; |
1039 } | 967 } |
1040 } // namespace webrtc | 968 } // namespace webrtc |
OLD | NEW |