Chromium Code Reviews| 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/receive_statistics_proxy.h" | 11 #include "webrtc/video/receive_statistics_proxy.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <cmath> | 14 #include <cmath> |
| 15 #include <sstream> | |
| 15 #include <utility> | 16 #include <utility> |
| 16 | 17 |
| 18 #include "webrtc/modules/pacing/alr_detector.h" | |
| 17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 19 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 18 #include "webrtc/rtc_base/checks.h" | 20 #include "webrtc/rtc_base/checks.h" |
| 19 #include "webrtc/rtc_base/logging.h" | 21 #include "webrtc/rtc_base/logging.h" |
| 20 #include "webrtc/rtc_base/trace_event.h" | 22 #include "webrtc/rtc_base/trace_event.h" |
| 21 #include "webrtc/system_wrappers/include/clock.h" | 23 #include "webrtc/system_wrappers/include/clock.h" |
| 22 #include "webrtc/system_wrappers/include/field_trial.h" | 24 #include "webrtc/system_wrappers/include/field_trial.h" |
| 23 #include "webrtc/system_wrappers/include/metrics.h" | 25 #include "webrtc/system_wrappers/include/metrics.h" |
| 24 | 26 |
| 25 namespace webrtc { | 27 namespace webrtc { |
| 26 namespace { | 28 namespace { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 39 const int kHighFpsThreshold = 14; | 41 const int kHighFpsThreshold = 14; |
| 40 // For qp and fps variance: | 42 // For qp and fps variance: |
| 41 // Low means low enough to be good, high means high enough to be bad | 43 // Low means low enough to be good, high means high enough to be bad |
| 42 const int kLowQpThresholdVp8 = 60; | 44 const int kLowQpThresholdVp8 = 60; |
| 43 const int kHighQpThresholdVp8 = 70; | 45 const int kHighQpThresholdVp8 = 70; |
| 44 const int kLowVarianceThreshold = 1; | 46 const int kLowVarianceThreshold = 1; |
| 45 const int kHighVarianceThreshold = 2; | 47 const int kHighVarianceThreshold = 2; |
| 46 | 48 |
| 47 // How large window we use to calculate the framerate/bitrate. | 49 // How large window we use to calculate the framerate/bitrate. |
| 48 const int kRateStatisticsWindowSizeMs = 1000; | 50 const int kRateStatisticsWindowSizeMs = 1000; |
| 51 | |
| 52 std::string UmaPrefixForContentType(VideoContentType content_type) { | |
| 53 std::stringstream ss; | |
| 54 ss << "WebRTC.Video"; | |
| 55 int simulcast_id = content_type.GetSimulcastId(); | |
| 56 if (content_type.IsScreenshare()) { | |
| 57 ss << ".Screenshare"; | |
| 58 } | |
| 59 if (simulcast_id > 0) { | |
| 60 ss << "_S" << simulcast_id - 1; | |
| 61 } | |
| 62 return ss.str(); | |
| 63 } | |
| 64 | |
| 49 } // namespace | 65 } // namespace |
| 50 | 66 |
| 51 ReceiveStatisticsProxy::ReceiveStatisticsProxy( | 67 ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
| 52 const VideoReceiveStream::Config* config, | 68 const VideoReceiveStream::Config* config, |
| 53 Clock* clock) | 69 Clock* clock) |
| 54 : clock_(clock), | 70 : clock_(clock), |
| 55 config_(*config), | 71 config_(*config), |
| 56 start_ms_(clock->TimeInMilliseconds()), | 72 start_ms_(clock->TimeInMilliseconds()), |
| 57 last_sample_time_(clock->TimeInMilliseconds()), | 73 last_sample_time_(clock->TimeInMilliseconds()), |
| 58 fps_threshold_(kLowFpsThreshold, | 74 fps_threshold_(kLowFpsThreshold, |
| 59 kHighFpsThreshold, | 75 kHighFpsThreshold, |
| 60 kBadFraction, | 76 kBadFraction, |
| 61 kNumMeasurements), | 77 kNumMeasurements), |
| 62 qp_threshold_(kLowQpThresholdVp8, | 78 qp_threshold_(kLowQpThresholdVp8, |
| 63 kHighQpThresholdVp8, | 79 kHighQpThresholdVp8, |
| 64 kBadFraction, | 80 kBadFraction, |
| 65 kNumMeasurements), | 81 kNumMeasurements), |
| 66 variance_threshold_(kLowVarianceThreshold, | 82 variance_threshold_(kLowVarianceThreshold, |
| 67 kHighVarianceThreshold, | 83 kHighVarianceThreshold, |
| 68 kBadFraction, | 84 kBadFraction, |
| 69 kNumMeasurementsVariance), | 85 kNumMeasurementsVariance), |
| 70 num_bad_states_(0), | 86 num_bad_states_(0), |
| 71 num_certain_states_(0), | 87 num_certain_states_(0), |
| 72 // 1000ms window, scale 1000 for ms to s. | 88 // 1000ms window, scale 1000 for ms to s. |
| 73 decode_fps_estimator_(1000, 1000), | 89 decode_fps_estimator_(1000, 1000), |
| 74 renders_fps_estimator_(1000, 1000), | 90 renders_fps_estimator_(1000, 1000), |
| 75 render_fps_tracker_(100, 10u), | 91 render_fps_tracker_(100, 10u), |
| 76 render_pixel_tracker_(100, 10u), | 92 render_pixel_tracker_(100, 10u), |
| 77 total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count | 93 total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count |
| 78 e2e_delay_max_ms_video_(-1), | |
| 79 e2e_delay_max_ms_screenshare_(-1), | |
| 80 interframe_delay_max_ms_video_(-1), | |
| 81 interframe_delay_max_ms_screenshare_(-1), | |
| 82 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs), | 94 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs), |
| 83 first_report_block_time_ms_(-1), | 95 first_report_block_time_ms_(-1), |
| 84 avg_rtt_ms_(0), | 96 avg_rtt_ms_(0), |
| 85 last_content_type_(VideoContentType::UNSPECIFIED) { | 97 last_content_type_(VideoContentType::UNSPECIFIED) { |
| 86 stats_.ssrc = config_.rtp.remote_ssrc; | 98 stats_.ssrc = config_.rtp.remote_ssrc; |
| 87 // TODO(brandtr): Replace |rtx_stats_| with a single instance of | 99 // TODO(brandtr): Replace |rtx_stats_| with a single instance of |
| 88 // StreamDataCounters. | 100 // StreamDataCounters. |
| 89 if (config_.rtp.rtx_ssrc) { | 101 if (config_.rtp.rtx_ssrc) { |
| 90 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters(); | 102 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters(); |
| 91 } | 103 } |
| 92 } | 104 } |
| 93 | 105 |
| 94 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { | 106 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { |
| 95 UpdateHistograms(); | 107 UpdateHistograms(); |
| 96 } | 108 } |
| 97 | 109 |
| 98 void ReceiveStatisticsProxy::UpdateHistograms() { | 110 void ReceiveStatisticsProxy::UpdateHistograms() { |
| 111 // Set synthetic field trial based on received experiment id. | |
| 112 // Since experiment is set at the send side and is not changed during the | |
| 113 // call, any received content type may be used. | |
|
sprang_webrtc
2017/07/26 14:13:43
Unfortunately this is not necessarily correct. I t
ilnik
2017/07/26 14:49:48
This is a big problem, I realize now. What if seve
| |
| 114 int experiment_id = last_content_type_.GetExperimentId(); | |
| 115 if (experiment_id != 0) { // 0 means no experiment is active. | |
| 116 std::stringstream group_name; | |
| 117 group_name << "Group-" << experiment_id - 1; | |
| 118 field_trial::RegisterSyntheticFieldTrial( | |
| 119 AlrDetector::kScreenshareProbingBweExperimentNameOnReceiveSide, | |
| 120 group_name.str()); | |
| 121 } else { | |
| 122 // No experiment group specified. | |
| 123 field_trial::RegisterSyntheticFieldTrial( | |
| 124 AlrDetector::kScreenshareProbingBweExperimentNameOnReceiveSide, ""); | |
| 125 } | |
| 126 | |
| 99 RTC_HISTOGRAM_COUNTS_100000( | 127 RTC_HISTOGRAM_COUNTS_100000( |
| 100 "WebRTC.Video.ReceiveStreamLifetimeInSeconds", | 128 "WebRTC.Video.ReceiveStreamLifetimeInSeconds", |
| 101 (clock_->TimeInMilliseconds() - start_ms_) / 1000); | 129 (clock_->TimeInMilliseconds() - start_ms_) / 1000); |
| 102 | 130 |
| 103 if (first_report_block_time_ms_ != -1 && | 131 if (first_report_block_time_ms_ != -1 && |
| 104 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >= | 132 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >= |
| 105 metrics::kMinRunTimeInSeconds) { | 133 metrics::kMinRunTimeInSeconds) { |
| 106 int fraction_lost = report_block_stats_.FractionLostInPercent(); | 134 int fraction_lost = report_block_stats_.FractionLostInPercent(); |
| 107 if (fraction_lost != -1) { | 135 if (fraction_lost != -1) { |
| 108 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", | 136 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples); | 207 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples); |
| 180 if (current_delay_ms != -1) { | 208 if (current_delay_ms != -1) { |
| 181 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", | 209 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", |
| 182 current_delay_ms); | 210 current_delay_ms); |
| 183 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms; | 211 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms; |
| 184 } | 212 } |
| 185 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); | 213 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); |
| 186 if (delay_ms != -1) | 214 if (delay_ms != -1) |
| 187 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms); | 215 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms); |
| 188 | 216 |
| 189 int e2e_delay_ms_video = e2e_delay_counter_video_.Avg(kMinRequiredSamples); | 217 for (auto it : content_specific_stats_) { |
|
sprang_webrtc
2017/07/26 14:13:43
const auto& it ?
| |
| 190 if (e2e_delay_ms_video != -1) { | 218 auto content_type = it.first; |
| 191 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.EndToEndDelayInMs", | 219 auto stats = it.second; |
|
sprang_webrtc
2017/07/26 14:13:43
auto is good for |it| here, since its type is kind
| |
| 192 e2e_delay_ms_video); | 220 std::string uma_prefix = UmaPrefixForContentType(content_type); |
| 193 LOG(LS_INFO) << "WebRTC.Video.EndToEndDelayInMs " << e2e_delay_ms_video; | 221 // The same line of code can't report different histograms because of how |
| 222 // macro is done. Additional index needed to be different for all different | |
| 223 // names. Since experiment can't change during call, we could report 4*2 | |
| 224 // different content types (4 simulcast_ids x 2 content types). | |
| 225 // Conveniently all of these are stored in 3 lower bits in VideoContentType. | |
| 226 int idx = content_type.content_type & 0x07; | |
| 227 int e2e_delay_ms = stats.e2e_delay_counter.Avg(kMinRequiredSamples); | |
| 228 if (e2e_delay_ms != -1) { | |
| 229 RTC_HISTOGRAMS_COUNTS_10000(idx, uma_prefix + ".EndToEndDelayInMs", | |
| 230 e2e_delay_ms); | |
| 231 LOG(LS_INFO) << uma_prefix + ".EndToEndDelayInMs " << e2e_delay_ms; | |
| 232 } | |
| 233 int e2e_delay_max_ms = stats.e2e_delay_counter.Max(); | |
| 234 | |
| 235 if (e2e_delay_max_ms != -1) { | |
| 236 RTC_HISTOGRAMS_COUNTS_100000(idx, uma_prefix + ".EndToEndDelayMaxInMs", | |
| 237 e2e_delay_max_ms); | |
| 238 LOG(LS_INFO) << uma_prefix + ".EndToEndDelayMaxInMs " << e2e_delay_max_ms; | |
| 239 } | |
| 240 int interframe_delay_ms = | |
| 241 stats.interframe_delay_counter.Avg(kMinRequiredSamples); | |
| 242 if (interframe_delay_ms != -1) { | |
| 243 RTC_HISTOGRAMS_COUNTS_10000(idx, uma_prefix + ".InterframeDelayInMs", | |
| 244 interframe_delay_ms); | |
| 245 LOG(LS_INFO) << uma_prefix + ".InterframeDelayInMs " | |
| 246 << interframe_delay_ms; | |
| 247 } | |
| 248 int interframe_delay_max_ms = stats.interframe_delay_counter.Max(); | |
| 249 if (interframe_delay_max_ms != -1) { | |
| 250 RTC_HISTOGRAMS_COUNTS_10000(idx, uma_prefix + ".InterframeDelayMaxInMs", | |
| 251 interframe_delay_max_ms); | |
| 252 LOG(LS_INFO) << uma_prefix + ".InterframeDelayMaxInMs " | |
| 253 << interframe_delay_max_ms; | |
| 254 } | |
| 194 } | 255 } |
| 195 | 256 |
| 196 int e2e_delay_ms_screenshare = | |
| 197 e2e_delay_counter_screenshare_.Avg(kMinRequiredSamples); | |
| 198 if (e2e_delay_ms_screenshare != -1) { | |
| 199 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.EndToEndDelayInMs", | |
| 200 e2e_delay_ms_screenshare); | |
| 201 } | |
| 202 | |
| 203 int e2e_delay_max_ms_video = e2e_delay_max_ms_video_; | |
| 204 if (e2e_delay_max_ms_video != -1) { | |
| 205 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.EndToEndDelayMaxInMs", | |
| 206 e2e_delay_max_ms_video); | |
| 207 } | |
| 208 | |
| 209 int e2e_delay_max_ms_screenshare = e2e_delay_max_ms_screenshare_; | |
| 210 if (e2e_delay_max_ms_screenshare != -1) { | |
| 211 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.Screenshare.EndToEndDelayMaxInMs", | |
| 212 e2e_delay_max_ms_screenshare); | |
| 213 } | |
| 214 | |
| 215 int interframe_delay_ms_screenshare = | |
| 216 interframe_delay_counter_screenshare_.Avg(kMinRequiredSamples); | |
| 217 if (interframe_delay_ms_screenshare != -1) { | |
| 218 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.InterframeDelayInMs", | |
| 219 interframe_delay_ms_screenshare); | |
| 220 } | |
| 221 | |
| 222 int interframe_delay_ms_video = | |
| 223 interframe_delay_counter_video_.Avg(kMinRequiredSamples); | |
| 224 if (interframe_delay_ms_video != -1) { | |
| 225 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InterframeDelayInMs", | |
| 226 interframe_delay_ms_video); | |
| 227 } | |
| 228 | |
| 229 int interframe_delay_max_ms_screenshare = | |
| 230 interframe_delay_max_ms_screenshare_; | |
| 231 if (interframe_delay_max_ms_screenshare != -1) { | |
| 232 RTC_HISTOGRAM_COUNTS_10000( | |
| 233 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs", | |
| 234 interframe_delay_ms_screenshare); | |
| 235 } | |
| 236 | |
| 237 int interframe_delay_max_ms_video = interframe_delay_max_ms_video_; | |
| 238 if (interframe_delay_max_ms_video != -1) { | |
| 239 RTC_HISTOGRAM_COUNTS_10000( | |
| 240 "WebRTC.Video.InterframeDelayMaxInMs", | |
| 241 interframe_delay_ms_video); | |
| 242 } | |
| 243 | |
| 244 | |
| 245 StreamDataCounters rtp = stats_.rtp_stats; | 257 StreamDataCounters rtp = stats_.rtp_stats; |
| 246 StreamDataCounters rtx; | 258 StreamDataCounters rtx; |
| 247 for (auto it : rtx_stats_) | 259 for (auto it : rtx_stats_) |
| 248 rtx.Add(it.second); | 260 rtx.Add(it.second); |
| 249 StreamDataCounters rtp_rtx = rtp; | 261 StreamDataCounters rtp_rtx = rtp; |
| 250 rtp_rtx.Add(rtx); | 262 rtp_rtx.Add(rtx); |
| 251 int64_t elapsed_sec = | 263 int64_t elapsed_sec = |
| 252 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000; | 264 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000; |
| 253 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { | 265 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { |
| 254 RTC_HISTOGRAM_COUNTS_10000( | 266 RTC_HISTOGRAM_COUNTS_10000( |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 LOG(LS_WARNING) | 579 LOG(LS_WARNING) |
| 568 << "QP sum was already set and no QP was given for a frame."; | 580 << "QP sum was already set and no QP was given for a frame."; |
| 569 stats_.qp_sum = rtc::Optional<uint64_t>(); | 581 stats_.qp_sum = rtc::Optional<uint64_t>(); |
| 570 } | 582 } |
| 571 last_content_type_ = content_type; | 583 last_content_type_ = content_type; |
| 572 decode_fps_estimator_.Update(1, now); | 584 decode_fps_estimator_.Update(1, now); |
| 573 if (last_decoded_frame_time_ms_) { | 585 if (last_decoded_frame_time_ms_) { |
| 574 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_; | 586 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_; |
| 575 RTC_DCHECK_GE(interframe_delay_ms, 0); | 587 RTC_DCHECK_GE(interframe_delay_ms, 0); |
| 576 stats_.interframe_delay_sum_ms += interframe_delay_ms; | 588 stats_.interframe_delay_sum_ms += interframe_delay_ms; |
| 577 if (last_content_type_ == VideoContentType::SCREENSHARE) { | 589 auto it = content_specific_stats_.find(last_content_type_); |
| 578 interframe_delay_counter_screenshare_.Add(interframe_delay_ms); | 590 if (it == content_specific_stats_.end()) { |
| 579 if (interframe_delay_max_ms_screenshare_ < interframe_delay_ms) { | 591 content_specific_stats_[last_content_type_] = ContentSpecificStats(); |
| 580 interframe_delay_max_ms_screenshare_ = interframe_delay_ms; | 592 it = content_specific_stats_.find(last_content_type_); |
| 581 } | |
| 582 } else { | |
| 583 interframe_delay_counter_video_.Add(interframe_delay_ms); | |
| 584 if (interframe_delay_max_ms_video_ < interframe_delay_ms) { | |
| 585 interframe_delay_max_ms_video_ = interframe_delay_ms; | |
| 586 } | |
| 587 } | 593 } |
| 594 ContentSpecificStats* stats = &it->second; | |
| 595 stats->interframe_delay_counter.Add(interframe_delay_ms); | |
| 588 } | 596 } |
| 589 last_decoded_frame_time_ms_.emplace(now); | 597 last_decoded_frame_time_ms_.emplace(now); |
| 590 } | 598 } |
| 591 | 599 |
| 592 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) { | 600 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) { |
| 593 int width = frame.width(); | 601 int width = frame.width(); |
| 594 int height = frame.height(); | 602 int height = frame.height(); |
| 595 RTC_DCHECK_GT(width, 0); | 603 RTC_DCHECK_GT(width, 0); |
| 596 RTC_DCHECK_GT(height, 0); | 604 RTC_DCHECK_GT(height, 0); |
| 597 uint64_t now = clock_->TimeInMilliseconds(); | 605 uint64_t now = clock_->TimeInMilliseconds(); |
| 598 | 606 |
| 599 rtc::CritScope lock(&crit_); | 607 rtc::CritScope lock(&crit_); |
| 600 renders_fps_estimator_.Update(1, now); | 608 renders_fps_estimator_.Update(1, now); |
| 601 ++stats_.frames_rendered; | 609 ++stats_.frames_rendered; |
| 602 stats_.width = width; | 610 stats_.width = width; |
| 603 stats_.height = height; | 611 stats_.height = height; |
| 604 render_width_counter_.Add(width); | 612 render_width_counter_.Add(width); |
| 605 render_height_counter_.Add(height); | 613 render_height_counter_.Add(height); |
| 606 render_fps_tracker_.AddSamples(1); | 614 render_fps_tracker_.AddSamples(1); |
| 607 render_pixel_tracker_.AddSamples(sqrt(width * height)); | 615 render_pixel_tracker_.AddSamples(sqrt(width * height)); |
| 608 | 616 |
| 609 if (frame.ntp_time_ms() > 0) { | 617 if (frame.ntp_time_ms() > 0) { |
| 610 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms(); | 618 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms(); |
| 611 if (delay_ms >= 0) { | 619 if (delay_ms >= 0) { |
| 612 if (last_content_type_ == VideoContentType::SCREENSHARE) { | 620 auto it = content_specific_stats_.find(last_content_type_); |
| 613 e2e_delay_max_ms_screenshare_ = | 621 if (it == content_specific_stats_.end()) { |
| 614 std::max(delay_ms, e2e_delay_max_ms_screenshare_); | 622 content_specific_stats_[last_content_type_] = ContentSpecificStats(); |
| 615 e2e_delay_counter_screenshare_.Add(delay_ms); | 623 it = content_specific_stats_.find(last_content_type_); |
| 616 } else { | |
| 617 e2e_delay_max_ms_video_ = std::max(delay_ms, e2e_delay_max_ms_video_); | |
| 618 e2e_delay_counter_video_.Add(delay_ms); | |
| 619 } | 624 } |
| 625 ContentSpecificStats* stats = &it->second; | |
| 626 stats->e2e_delay_counter.Add(delay_ms); | |
| 620 } | 627 } |
| 621 } | 628 } |
| 622 | 629 |
| 623 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedWidthInPixels", | 630 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedWidthInPixels", |
| 624 "width", width, "ssrc", stats_.ssrc); | 631 "width", width, "ssrc", stats_.ssrc); |
| 625 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedHeightInPixels", | 632 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedHeightInPixels", |
| 626 "height", height, "ssrc", stats_.ssrc); | 633 "height", height, "ssrc", stats_.ssrc); |
| 627 TRACE_EVENT_INSTANT1("webrtc_stats", "WebRTC.Video.OnRenderedFrame", | 634 TRACE_EVENT_INSTANT1("webrtc_stats", "WebRTC.Video.OnRenderedFrame", |
| 628 "ssrc", stats_.ssrc); | 635 "ssrc", stats_.ssrc); |
| 629 } | 636 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 if (codec_specific_info->codecType == kVideoCodecVP8) { | 687 if (codec_specific_info->codecType == kVideoCodecVP8) { |
| 681 qp_counters_.vp8.Add(encoded_image.qp_); | 688 qp_counters_.vp8.Add(encoded_image.qp_); |
| 682 rtc::CritScope lock(&crit_); | 689 rtc::CritScope lock(&crit_); |
| 683 qp_sample_.Add(encoded_image.qp_); | 690 qp_sample_.Add(encoded_image.qp_); |
| 684 } | 691 } |
| 685 } | 692 } |
| 686 | 693 |
| 687 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { | 694 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { |
| 688 sum += sample; | 695 sum += sample; |
| 689 ++num_samples; | 696 ++num_samples; |
| 697 if (!max || *max < sample) { | |
| 698 max.emplace(sample); | |
| 699 } | |
| 690 } | 700 } |
| 691 | 701 |
| 692 int ReceiveStatisticsProxy::SampleCounter::Avg( | 702 int ReceiveStatisticsProxy::SampleCounter::Avg( |
| 693 int64_t min_required_samples) const { | 703 int64_t min_required_samples) const { |
| 694 if (num_samples < min_required_samples || num_samples == 0) | 704 if (num_samples < min_required_samples || num_samples == 0) |
| 695 return -1; | 705 return -1; |
| 696 return static_cast<int>(sum / num_samples); | 706 return static_cast<int>(sum / num_samples); |
| 697 } | 707 } |
| 698 | 708 |
| 709 int ReceiveStatisticsProxy::SampleCounter::Max() const { | |
| 710 if (!max) { | |
| 711 return -1; | |
| 712 } else { | |
| 713 return static_cast<int>(*max); | |
| 714 } | |
|
sprang_webrtc
2017/07/26 14:13:43
return max.value_or(-1);
| |
| 715 } | |
| 716 | |
| 699 void ReceiveStatisticsProxy::SampleCounter::Reset() { | 717 void ReceiveStatisticsProxy::SampleCounter::Reset() { |
| 700 num_samples = 0; | 718 num_samples = 0; |
| 701 sum = 0; | 719 sum = 0; |
| 720 max.reset(); | |
| 702 } | 721 } |
| 703 | 722 |
| 704 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms, | 723 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms, |
| 705 int64_t max_rtt_ms) { | 724 int64_t max_rtt_ms) { |
| 706 rtc::CritScope lock(&crit_); | 725 rtc::CritScope lock(&crit_); |
| 707 avg_rtt_ms_ = avg_rtt_ms; | 726 avg_rtt_ms_ = avg_rtt_ms; |
| 708 } | 727 } |
| 709 | 728 |
| 710 } // namespace webrtc | 729 } // namespace webrtc |
| OLD | NEW |