| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 |
| 11 #include "webrtc/video/send_statistics_proxy.h" | 11 #include "webrtc/video/send_statistics_proxy.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <cmath> | 14 #include <cmath> |
| 15 #include <map> | 15 #include <map> |
| 16 #include <vector> |
| 16 | 17 |
| 17 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 19 #include "webrtc/system_wrappers/include/metrics.h" | 20 #include "webrtc/system_wrappers/include/metrics.h" |
| 20 | 21 |
| 21 namespace webrtc { | 22 namespace webrtc { |
| 22 namespace { | 23 namespace { |
| 23 const float kEncodeTimeWeigthFactor = 0.5f; | 24 const float kEncodeTimeWeigthFactor = 0.5f; |
| 24 | 25 |
| 25 // Used by histograms. Values of entries should not be changed. | 26 // Used by histograms. Values of entries should not be changed. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( | 122 void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( |
| 122 const VideoSendStream::Config& config, | 123 const VideoSendStream::Config& config, |
| 123 const VideoSendStream::Stats& current_stats) { | 124 const VideoSendStream::Stats& current_stats) { |
| 124 RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix); | 125 RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix); |
| 125 const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0; | 126 const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0; |
| 126 const int kMinRequiredSamples = 200; | 127 const int kMinRequiredSamples = 200; |
| 127 int in_width = input_width_counter_.Avg(kMinRequiredSamples); | 128 int in_width = input_width_counter_.Avg(kMinRequiredSamples); |
| 128 int in_height = input_height_counter_.Avg(kMinRequiredSamples); | 129 int in_height = input_height_counter_.Avg(kMinRequiredSamples); |
| 129 int in_fps = round(input_frame_rate_tracker_.ComputeTotalRate()); | 130 int in_fps = round(input_frame_rate_tracker_.ComputeTotalRate()); |
| 130 if (in_width != -1) { | 131 if (in_width != -1) { |
| 131 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputWidthInPixels", | 132 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 132 in_width); | 133 kIndex, uma_prefix_ + "InputWidthInPixels", in_width); |
| 133 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputHeightInPixels", | 134 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 134 in_height); | 135 kIndex, uma_prefix_ + "InputHeightInPixels", in_height); |
| 135 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "InputFramesPerSecond", | 136 RTC_LOGGED_HISTOGRAMS_COUNTS_100( |
| 136 in_fps); | 137 kIndex, uma_prefix_ + "InputFramesPerSecond", in_fps); |
| 137 } | 138 } |
| 138 int sent_width = sent_width_counter_.Avg(kMinRequiredSamples); | 139 int sent_width = sent_width_counter_.Avg(kMinRequiredSamples); |
| 139 int sent_height = sent_height_counter_.Avg(kMinRequiredSamples); | 140 int sent_height = sent_height_counter_.Avg(kMinRequiredSamples); |
| 140 int sent_fps = round(sent_frame_rate_tracker_.ComputeTotalRate()); | 141 int sent_fps = round(sent_frame_rate_tracker_.ComputeTotalRate()); |
| 141 if (sent_width != -1) { | 142 if (sent_width != -1) { |
| 142 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentWidthInPixels", | 143 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 143 sent_width); | 144 kIndex, uma_prefix_ + "SentWidthInPixels", sent_width); |
| 144 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentHeightInPixels", | 145 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 145 sent_height); | 146 kIndex, uma_prefix_ + "SentHeightInPixels", sent_height); |
| 146 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "SentFramesPerSecond", | 147 RTC_LOGGED_HISTOGRAMS_COUNTS_100( |
| 147 sent_fps); | 148 kIndex, uma_prefix_ + "SentFramesPerSecond", sent_fps); |
| 148 } | 149 } |
| 149 int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples); | 150 int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples); |
| 150 if (encode_ms != -1) { | 151 if (encode_ms != -1) { |
| 151 RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "EncodeTimeInMs", | 152 RTC_LOGGED_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "EncodeTimeInMs", |
| 152 encode_ms); | 153 encode_ms); |
| 153 } | 154 } |
| 154 int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples); | 155 int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples); |
| 155 if (key_frames_permille != -1) { | 156 if (key_frames_permille != -1) { |
| 156 RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "KeyFramesSentInPermille", | 157 RTC_LOGGED_HISTOGRAMS_COUNTS_1000( |
| 157 key_frames_permille); | 158 kIndex, uma_prefix_ + "KeyFramesSentInPermille", key_frames_permille); |
| 158 } | 159 } |
| 159 int quality_limited = | 160 int quality_limited = |
| 160 quality_limited_frame_counter_.Percent(kMinRequiredSamples); | 161 quality_limited_frame_counter_.Percent(kMinRequiredSamples); |
| 161 if (quality_limited != -1) { | 162 if (quality_limited != -1) { |
| 162 RTC_HISTOGRAMS_PERCENTAGE(kIndex, | 163 RTC_LOGGED_HISTOGRAMS_PERCENTAGE( |
| 163 uma_prefix_ + "QualityLimitedResolutionInPercent", | 164 kIndex, uma_prefix_ + "QualityLimitedResolutionInPercent", |
| 164 quality_limited); | 165 quality_limited); |
| 165 } | 166 } |
| 166 int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples); | 167 int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples); |
| 167 if (downscales != -1) { | 168 if (downscales != -1) { |
| 168 RTC_HISTOGRAMS_ENUMERATION( | 169 RTC_LOGGED_HISTOGRAMS_ENUMERATION( |
| 169 kIndex, uma_prefix_ + "QualityLimitedResolutionDownscales", downscales, | 170 kIndex, uma_prefix_ + "QualityLimitedResolutionDownscales", downscales, |
| 170 20); | 171 20); |
| 171 } | 172 } |
| 172 int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples); | 173 int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples); |
| 173 if (bw_limited != -1) { | 174 if (bw_limited != -1) { |
| 174 RTC_HISTOGRAMS_PERCENTAGE( | 175 RTC_LOGGED_HISTOGRAMS_PERCENTAGE( |
| 175 kIndex, uma_prefix_ + "BandwidthLimitedResolutionInPercent", | 176 kIndex, uma_prefix_ + "BandwidthLimitedResolutionInPercent", |
| 176 bw_limited); | 177 bw_limited); |
| 177 } | 178 } |
| 178 int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples); | 179 int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples); |
| 179 if (num_disabled != -1) { | 180 if (num_disabled != -1) { |
| 180 RTC_HISTOGRAMS_ENUMERATION( | 181 RTC_LOGGED_HISTOGRAMS_ENUMERATION( |
| 181 kIndex, uma_prefix_ + "BandwidthLimitedResolutionsDisabled", | 182 kIndex, uma_prefix_ + "BandwidthLimitedResolutionsDisabled", |
| 182 num_disabled, 10); | 183 num_disabled, 10); |
| 183 } | 184 } |
| 184 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); | 185 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); |
| 185 if (delay_ms != -1) | 186 if (delay_ms != -1) |
| 186 RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayInMs", | 187 RTC_LOGGED_HISTOGRAMS_COUNTS_100000( |
| 187 delay_ms); | 188 kIndex, uma_prefix_ + "SendSideDelayInMs", delay_ms); |
| 188 | 189 |
| 189 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples); | 190 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples); |
| 190 if (max_delay_ms != -1) { | 191 if (max_delay_ms != -1) { |
| 191 RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayMaxInMs", | 192 RTC_LOGGED_HISTOGRAMS_COUNTS_100000( |
| 192 max_delay_ms); | 193 kIndex, uma_prefix_ + "SendSideDelayMaxInMs", max_delay_ms); |
| 193 } | 194 } |
| 194 | 195 |
| 195 if (first_rtcp_stats_time_ms_ != -1) { | 196 if (first_rtcp_stats_time_ms_ != -1) { |
| 196 int64_t elapsed_sec = | 197 int64_t elapsed_sec = |
| 197 (clock_->TimeInMilliseconds() - first_rtcp_stats_time_ms_) / 1000; | 198 (clock_->TimeInMilliseconds() - first_rtcp_stats_time_ms_) / 1000; |
| 198 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { | 199 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { |
| 199 int fraction_lost = report_block_stats_.FractionLostInPercent(); | 200 int fraction_lost = report_block_stats_.FractionLostInPercent(); |
| 200 if (fraction_lost != -1) { | 201 if (fraction_lost != -1) { |
| 201 RTC_HISTOGRAMS_PERCENTAGE( | 202 RTC_LOGGED_HISTOGRAMS_PERCENTAGE( |
| 202 kIndex, uma_prefix_ + "SentPacketsLostInPercent", fraction_lost); | 203 kIndex, uma_prefix_ + "SentPacketsLostInPercent", fraction_lost); |
| 203 } | 204 } |
| 204 | 205 |
| 205 // The RTCP packet type counters, delivered via the | 206 // The RTCP packet type counters, delivered via the |
| 206 // RtcpPacketTypeCounterObserver interface, are aggregates over the entire | 207 // RtcpPacketTypeCounterObserver interface, are aggregates over the entire |
| 207 // life of the send stream and are not reset when switching content type. | 208 // life of the send stream and are not reset when switching content type. |
| 208 // For the purpose of these statistics though, we want new counts when | 209 // For the purpose of these statistics though, we want new counts when |
| 209 // switching since we switch histogram name. On every reset of the | 210 // switching since we switch histogram name. On every reset of the |
| 210 // UmaSamplesContainer, we save the initial state of the counters, so that | 211 // UmaSamplesContainer, we save the initial state of the counters, so that |
| 211 // we can calculate the delta here and aggregate over all ssrcs. | 212 // we can calculate the delta here and aggregate over all ssrcs. |
| 212 RtcpPacketTypeCounter counters; | 213 RtcpPacketTypeCounter counters; |
| 213 for (uint32_t ssrc : config.rtp.ssrcs) { | 214 for (uint32_t ssrc : config.rtp.ssrcs) { |
| 214 auto kv = current_stats.substreams.find(ssrc); | 215 auto kv = current_stats.substreams.find(ssrc); |
| 215 if (kv == current_stats.substreams.end()) | 216 if (kv == current_stats.substreams.end()) |
| 216 continue; | 217 continue; |
| 217 | 218 |
| 218 RtcpPacketTypeCounter stream_counters = | 219 RtcpPacketTypeCounter stream_counters = |
| 219 kv->second.rtcp_packet_type_counts; | 220 kv->second.rtcp_packet_type_counts; |
| 220 kv = start_stats_.substreams.find(ssrc); | 221 kv = start_stats_.substreams.find(ssrc); |
| 221 if (kv != start_stats_.substreams.end()) | 222 if (kv != start_stats_.substreams.end()) |
| 222 stream_counters.Subtract(kv->second.rtcp_packet_type_counts); | 223 stream_counters.Subtract(kv->second.rtcp_packet_type_counts); |
| 223 | 224 |
| 224 counters.Add(stream_counters); | 225 counters.Add(stream_counters); |
| 225 } | 226 } |
| 226 RTC_HISTOGRAMS_COUNTS_10000(kIndex, | 227 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 227 uma_prefix_ + "NackPacketsReceivedPerMinute", | 228 kIndex, uma_prefix_ + "NackPacketsReceivedPerMinute", |
| 228 counters.nack_packets * 60 / elapsed_sec); | 229 counters.nack_packets * 60 / elapsed_sec); |
| 229 RTC_HISTOGRAMS_COUNTS_10000(kIndex, | 230 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 230 uma_prefix_ + "FirPacketsReceivedPerMinute", | 231 kIndex, uma_prefix_ + "FirPacketsReceivedPerMinute", |
| 231 counters.fir_packets * 60 / elapsed_sec); | 232 counters.fir_packets * 60 / elapsed_sec); |
| 232 RTC_HISTOGRAMS_COUNTS_10000(kIndex, | 233 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 233 uma_prefix_ + "PliPacketsReceivedPerMinute", | 234 kIndex, uma_prefix_ + "PliPacketsReceivedPerMinute", |
| 234 counters.pli_packets * 60 / elapsed_sec); | 235 counters.pli_packets * 60 / elapsed_sec); |
| 235 if (counters.nack_requests > 0) { | 236 if (counters.nack_requests > 0) { |
| 236 RTC_HISTOGRAMS_PERCENTAGE( | 237 RTC_LOGGED_HISTOGRAMS_PERCENTAGE( |
| 237 kIndex, uma_prefix_ + "UniqueNackRequestsReceivedInPercent", | 238 kIndex, uma_prefix_ + "UniqueNackRequestsReceivedInPercent", |
| 238 counters.UniqueNackRequestsInPercent()); | 239 counters.UniqueNackRequestsInPercent()); |
| 239 } | 240 } |
| 240 } | 241 } |
| 241 } | 242 } |
| 242 | 243 |
| 243 if (first_rtp_stats_time_ms_ != -1) { | 244 if (first_rtp_stats_time_ms_ != -1) { |
| 244 int64_t elapsed_sec = | 245 int64_t elapsed_sec = |
| 245 (clock_->TimeInMilliseconds() - first_rtp_stats_time_ms_) / 1000; | 246 (clock_->TimeInMilliseconds() - first_rtp_stats_time_ms_) / 1000; |
| 246 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { | 247 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { |
| 247 StreamDataCounters rtp; | 248 StreamDataCounters rtp; |
| 248 StreamDataCounters rtx; | 249 StreamDataCounters rtx; |
| 249 AccumulateRtpStats(current_stats, config, &rtp, &rtx); | 250 AccumulateRtpStats(current_stats, config, &rtp, &rtx); |
| 250 StreamDataCounters start_rtp; | 251 StreamDataCounters start_rtp; |
| 251 StreamDataCounters start_rtx; | 252 StreamDataCounters start_rtx; |
| 252 AccumulateRtpStats(start_stats_, config, &start_rtp, &start_rtx); | 253 AccumulateRtpStats(start_stats_, config, &start_rtp, &start_rtx); |
| 253 rtp.Subtract(start_rtp); | 254 rtp.Subtract(start_rtp); |
| 254 rtx.Subtract(start_rtx); | 255 rtx.Subtract(start_rtx); |
| 255 StreamDataCounters rtp_rtx = rtp; | 256 StreamDataCounters rtp_rtx = rtp; |
| 256 rtp_rtx.Add(rtx); | 257 rtp_rtx.Add(rtx); |
| 257 | 258 |
| 258 RTC_HISTOGRAMS_COUNTS_10000( | 259 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 259 kIndex, uma_prefix_ + "BitrateSentInKbps", | 260 kIndex, uma_prefix_ + "BitrateSentInKbps", |
| 260 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | 261 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / |
| 261 1000)); | 262 1000)); |
| 262 RTC_HISTOGRAMS_COUNTS_10000( | 263 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 263 kIndex, uma_prefix_ + "MediaBitrateSentInKbps", | 264 kIndex, uma_prefix_ + "MediaBitrateSentInKbps", |
| 264 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); | 265 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); |
| 265 RTC_HISTOGRAMS_COUNTS_10000( | 266 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 266 kIndex, uma_prefix_ + "PaddingBitrateSentInKbps", | 267 kIndex, uma_prefix_ + "PaddingBitrateSentInKbps", |
| 267 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / | 268 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / |
| 268 1000)); | 269 1000)); |
| 269 RTC_HISTOGRAMS_COUNTS_10000( | 270 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 270 kIndex, uma_prefix_ + "RetransmittedBitrateSentInKbps", | 271 kIndex, uma_prefix_ + "RetransmittedBitrateSentInKbps", |
| 271 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / | 272 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / |
| 272 elapsed_sec / 1000)); | 273 elapsed_sec / 1000)); |
| 273 if (!config.rtp.rtx.ssrcs.empty()) { | 274 if (!config.rtp.rtx.ssrcs.empty()) { |
| 274 RTC_HISTOGRAMS_COUNTS_10000( | 275 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 275 kIndex, uma_prefix_ + "RtxBitrateSentInKbps", | 276 kIndex, uma_prefix_ + "RtxBitrateSentInKbps", |
| 276 static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | 277 static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec / |
| 277 1000)); | 278 1000)); |
| 278 } | 279 } |
| 279 if (config.rtp.fec.red_payload_type != -1) { | 280 if (config.rtp.fec.red_payload_type != -1) { |
| 280 RTC_HISTOGRAMS_COUNTS_10000(kIndex, | 281 RTC_LOGGED_HISTOGRAMS_COUNTS_10000( |
| 281 uma_prefix_ + "FecBitrateSentInKbps", | 282 kIndex, uma_prefix_ + "FecBitrateSentInKbps", |
| 282 static_cast<int>(rtp_rtx.fec.TotalBytes() * | 283 static_cast<int>(rtp_rtx.fec.TotalBytes() * 8 / elapsed_sec / |
| 283 8 / elapsed_sec / 1000)); | 284 1000)); |
| 284 } | 285 } |
| 285 } | 286 } |
| 286 } | 287 } |
| 287 } | 288 } |
| 288 | 289 |
| 289 void SendStatisticsProxy::SetContentType( | 290 void SendStatisticsProxy::SetContentType( |
| 290 VideoEncoderConfig::ContentType content_type) { | 291 VideoEncoderConfig::ContentType content_type) { |
| 291 rtc::CritScope lock(&crit_); | 292 rtc::CritScope lock(&crit_); |
| 292 if (content_type_ != content_type) { | 293 if (content_type_ != content_type) { |
| 293 uma_container_->UpdateHistograms(config_, stats_); | 294 uma_container_->UpdateHistograms(config_, stats_); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 return Fraction(min_required_samples, 1000.0f); | 558 return Fraction(min_required_samples, 1000.0f); |
| 558 } | 559 } |
| 559 | 560 |
| 560 int SendStatisticsProxy::BoolSampleCounter::Fraction( | 561 int SendStatisticsProxy::BoolSampleCounter::Fraction( |
| 561 int min_required_samples, float multiplier) const { | 562 int min_required_samples, float multiplier) const { |
| 562 if (num_samples < min_required_samples || num_samples == 0) | 563 if (num_samples < min_required_samples || num_samples == 0) |
| 563 return -1; | 564 return -1; |
| 564 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); | 565 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); |
| 565 } | 566 } |
| 566 } // namespace webrtc | 567 } // namespace webrtc |
| OLD | NEW |