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 const int kMaxDecodeWaitTimeMs = 50; | 38 const int kMaxDecodeWaitTimeMs = 50; |
40 static const int kMaxTargetDelayMs = 10000; | 39 static const int kMaxTargetDelayMs = 10000; |
41 const int kMinSendSidePacketHistorySize = 600; | 40 const int kMinSendSidePacketHistorySize = 600; |
42 const int kMaxPacketAgeToNack = 450; | 41 const int kMaxPacketAgeToNack = 450; |
43 const int kMaxNackListSize = 250; | 42 const int kMaxNackListSize = 250; |
44 | 43 |
45 // Helper class receiving statistics callbacks. | 44 // Helper class receiving statistics callbacks. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 intra_frame_observer_(intra_frame_observer), | 104 intra_frame_observer_(intra_frame_observer), |
106 rtt_stats_(rtt_stats), | 105 rtt_stats_(rtt_stats), |
107 paced_sender_(paced_sender), | 106 paced_sender_(paced_sender), |
108 packet_router_(packet_router), | 107 packet_router_(packet_router), |
109 bandwidth_observer_(bandwidth_observer), | 108 bandwidth_observer_(bandwidth_observer), |
110 transport_feedback_observer_(transport_feedback_observer), | 109 transport_feedback_observer_(transport_feedback_observer), |
111 decode_thread_(ChannelDecodeThreadFunction, this, "DecodingThread"), | 110 decode_thread_(ChannelDecodeThreadFunction, this, "DecodingThread"), |
112 nack_history_size_sender_(kMinSendSidePacketHistorySize), | 111 nack_history_size_sender_(kMinSendSidePacketHistorySize), |
113 max_nack_reordering_threshold_(kMaxPacketAgeToNack), | 112 max_nack_reordering_threshold_(kMaxPacketAgeToNack), |
114 pre_render_callback_(NULL), | 113 pre_render_callback_(NULL), |
115 report_block_stats_sender_(new ReportBlockStats()), | |
116 time_of_first_rtt_ms_(-1), | |
117 rtt_sum_ms_(0), | |
118 last_rtt_ms_(0), | 114 last_rtt_ms_(0), |
119 num_rtts_(0), | |
120 rtp_rtcp_modules_( | 115 rtp_rtcp_modules_( |
121 CreateRtpRtcpModules(!sender, | 116 CreateRtpRtcpModules(!sender, |
122 vie_receiver_.GetReceiveStatistics(), | 117 vie_receiver_.GetReceiveStatistics(), |
123 transport, | 118 transport, |
124 intra_frame_observer_, | 119 intra_frame_observer_, |
125 bandwidth_observer_.get(), | 120 bandwidth_observer_.get(), |
126 transport_feedback_observer_, | 121 transport_feedback_observer_, |
127 rtt_stats_, | 122 rtt_stats_, |
128 &rtcp_packet_type_counter_observer_, | 123 &rtcp_packet_type_counter_observer_, |
129 remote_bitrate_estimator, | 124 remote_bitrate_estimator, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 module_process_thread_->DeRegisterModule(rtp_rtcp); | 186 module_process_thread_->DeRegisterModule(rtp_rtcp); |
192 delete rtp_rtcp; | 187 delete rtp_rtcp; |
193 } | 188 } |
194 if (!sender_) | 189 if (!sender_) |
195 StopDecodeThread(); | 190 StopDecodeThread(); |
196 } | 191 } |
197 | 192 |
198 void ViEChannel::UpdateHistograms() { | 193 void ViEChannel::UpdateHistograms() { |
199 int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds(); | 194 int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds(); |
200 | 195 |
201 { | |
202 rtc::CritScope lock(&crit_); | |
203 int64_t elapsed_sec = (now - time_of_first_rtt_ms_) / 1000; | |
204 if (time_of_first_rtt_ms_ != -1 && num_rtts_ > 0 && | |
205 elapsed_sec > metrics::kMinRunTimeInSeconds) { | |
206 int64_t avg_rtt_ms = (rtt_sum_ms_ + num_rtts_ / 2) / num_rtts_; | |
207 RTC_HISTOGRAM_COUNTS_10000( | |
208 "WebRTC.Video.AverageRoundTripTimeInMilliseconds", avg_rtt_ms); | |
209 } | |
210 } | |
211 | |
212 if (sender_) { | 196 if (sender_) { |
213 RtcpPacketTypeCounter rtcp_counter; | 197 RtcpPacketTypeCounter rtcp_counter; |
214 GetSendRtcpPacketTypeCounter(&rtcp_counter); | 198 GetSendRtcpPacketTypeCounter(&rtcp_counter); |
215 int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000; | 199 int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000; |
216 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { | 200 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { |
217 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute", | 201 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute", |
218 rtcp_counter.nack_packets * 60 / elapsed_sec); | 202 rtcp_counter.nack_packets * 60 / elapsed_sec); |
219 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute", | 203 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute", |
220 rtcp_counter.fir_packets * 60 / elapsed_sec); | 204 rtcp_counter.fir_packets * 60 / elapsed_sec); |
221 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute", | 205 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute", |
222 rtcp_counter.pli_packets * 60 / elapsed_sec); | 206 rtcp_counter.pli_packets * 60 / elapsed_sec); |
223 if (rtcp_counter.nack_requests > 0) { | 207 if (rtcp_counter.nack_requests > 0) { |
224 RTC_HISTOGRAM_PERCENTAGE( | 208 RTC_HISTOGRAM_PERCENTAGE( |
225 "WebRTC.Video.UniqueNackRequestsReceivedInPercent", | 209 "WebRTC.Video.UniqueNackRequestsReceivedInPercent", |
226 rtcp_counter.UniqueNackRequestsInPercent()); | 210 rtcp_counter.UniqueNackRequestsInPercent()); |
227 } | 211 } |
228 int fraction_lost = report_block_stats_sender_->FractionLostInPercent(); | |
229 if (fraction_lost != -1) { | |
230 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.SentPacketsLostInPercent", | |
231 fraction_lost); | |
232 } | |
233 } | 212 } |
234 | 213 |
235 StreamDataCounters rtp; | 214 StreamDataCounters rtp; |
236 StreamDataCounters rtx; | 215 StreamDataCounters rtx; |
237 GetSendStreamDataCounters(&rtp, &rtx); | 216 GetSendStreamDataCounters(&rtp, &rtx); |
238 StreamDataCounters rtp_rtx = rtp; | 217 StreamDataCounters rtp_rtx = rtp; |
239 rtp_rtx.Add(rtx); | 218 rtp_rtx.Add(rtx); |
240 elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs( | 219 elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs( |
241 Clock::GetRealTimeClock()->TimeInMilliseconds()) / | 220 Clock::GetRealTimeClock()->TimeInMilliseconds()) / |
242 1000; | 221 1000; |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 int32_t ViEChannel::SetRTCPCName(const char* rtcp_cname) { | 705 int32_t ViEChannel::SetRTCPCName(const char* rtcp_cname) { |
727 RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending()); | 706 RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending()); |
728 return rtp_rtcp_modules_[0]->SetCNAME(rtcp_cname); | 707 return rtp_rtcp_modules_[0]->SetCNAME(rtcp_cname); |
729 } | 708 } |
730 | 709 |
731 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) { | 710 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) { |
732 uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc(); | 711 uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc(); |
733 return rtp_rtcp_modules_[0]->RemoteCNAME(remoteSSRC, rtcp_cname); | 712 return rtp_rtcp_modules_[0]->RemoteCNAME(remoteSSRC, rtcp_cname); |
734 } | 713 } |
735 | 714 |
736 int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, | |
737 uint32_t* cumulative_lost, | |
738 uint32_t* extended_max, | |
739 uint32_t* jitter_samples, | |
740 int64_t* rtt_ms) { | |
741 // Aggregate the report blocks associated with streams sent on this channel. | |
742 std::vector<RTCPReportBlock> report_blocks; | |
743 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
744 rtp_rtcp->RemoteRTCPStat(&report_blocks); | |
745 | |
746 if (report_blocks.empty()) | |
747 return -1; | |
748 | |
749 uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc(); | |
750 std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin(); | |
751 for (; it != report_blocks.end(); ++it) { | |
752 if (it->remoteSSRC == remote_ssrc) | |
753 break; | |
754 } | |
755 if (it == report_blocks.end()) { | |
756 // We have not received packets with an SSRC matching the report blocks. To | |
757 // have a chance of calculating an RTT we will try with the SSRC of the | |
758 // first report block received. | |
759 // This is very important for send-only channels where we don't know the | |
760 // SSRC of the other end. | |
761 remote_ssrc = report_blocks[0].remoteSSRC; | |
762 } | |
763 | |
764 // TODO(asapersson): Change report_block_stats to not rely on | |
765 // GetSendRtcpStatistics to be called. | |
766 RTCPReportBlock report = | |
767 report_block_stats_sender_->AggregateAndStore(report_blocks); | |
768 *fraction_lost = report.fractionLost; | |
769 *cumulative_lost = report.cumulativeLost; | |
770 *extended_max = report.extendedHighSeqNum; | |
771 *jitter_samples = report.jitter; | |
772 | |
773 int64_t dummy; | |
774 int64_t rtt = 0; | |
775 if (rtp_rtcp_modules_[0]->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != | |
776 0) { | |
777 return -1; | |
778 } | |
779 *rtt_ms = rtt; | |
780 return 0; | |
781 } | |
782 | |
783 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback( | 715 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback( |
784 RtcpStatisticsCallback* callback) { | 716 RtcpStatisticsCallback* callback) { |
785 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | 717 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
786 rtp_rtcp->RegisterRtcpStatisticsCallback(callback); | 718 rtp_rtcp->RegisterRtcpStatisticsCallback(callback); |
787 } | 719 } |
788 | 720 |
789 void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback( | 721 void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback( |
790 RtcpStatisticsCallback* callback) { | 722 RtcpStatisticsCallback* callback) { |
791 vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback( | 723 vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback( |
792 callback); | 724 callback); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 RTC_DCHECK(!sender_); | 973 RTC_DCHECK(!sender_); |
1042 vcm_->Decode(kMaxDecodeWaitTimeMs); | 974 vcm_->Decode(kMaxDecodeWaitTimeMs); |
1043 return true; | 975 return true; |
1044 } | 976 } |
1045 | 977 |
1046 void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 978 void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
1047 if (!sender_) | 979 if (!sender_) |
1048 vcm_->SetReceiveChannelParameters(max_rtt_ms); | 980 vcm_->SetReceiveChannelParameters(max_rtt_ms); |
1049 | 981 |
1050 rtc::CritScope lock(&crit_); | 982 rtc::CritScope lock(&crit_); |
1051 if (time_of_first_rtt_ms_ == -1) | |
1052 time_of_first_rtt_ms_ = Clock::GetRealTimeClock()->TimeInMilliseconds(); | |
1053 rtt_sum_ms_ += avg_rtt_ms; | |
1054 last_rtt_ms_ = avg_rtt_ms; | 983 last_rtt_ms_ = avg_rtt_ms; |
1055 ++num_rtts_; | |
1056 } | 984 } |
1057 | 985 |
1058 int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params, | 986 int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params, |
1059 const FecProtectionParams* key_fec_params, | 987 const FecProtectionParams* key_fec_params, |
1060 uint32_t* video_rate_bps, | 988 uint32_t* video_rate_bps, |
1061 uint32_t* nack_rate_bps, | 989 uint32_t* nack_rate_bps, |
1062 uint32_t* fec_rate_bps) { | 990 uint32_t* fec_rate_bps) { |
1063 *video_rate_bps = 0; | 991 *video_rate_bps = 0; |
1064 *nack_rate_bps = 0; | 992 *nack_rate_bps = 0; |
1065 *fec_rate_bps = 0; | 993 *fec_rate_bps = 0; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 rtc::CritScope lock(&crit_); | 1126 rtc::CritScope lock(&crit_); |
1199 receive_stats_callback_ = receive_statistics_proxy; | 1127 receive_stats_callback_ = receive_statistics_proxy; |
1200 } | 1128 } |
1201 | 1129 |
1202 void ViEChannel::SetIncomingVideoStream( | 1130 void ViEChannel::SetIncomingVideoStream( |
1203 IncomingVideoStream* incoming_video_stream) { | 1131 IncomingVideoStream* incoming_video_stream) { |
1204 rtc::CritScope lock(&crit_); | 1132 rtc::CritScope lock(&crit_); |
1205 incoming_video_stream_ = incoming_video_stream; | 1133 incoming_video_stream_ = incoming_video_stream; |
1206 } | 1134 } |
1207 } // namespace webrtc | 1135 } // namespace webrtc |
OLD | NEW |