Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: webrtc/video/receive_statistics_proxy.cc

Issue 2986893002: Piggybacking simulcast id and ALR experiment id into video content type extension. (Closed)
Patch Set: Change nameing style of metrics with simulcast suffixies Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 if (content_type.IsScreenshare()) {
56 ss << ".Screenshare";
57 }
58 return ss.str();
59 }
60
61 std::string UmaSuffixForContentType(VideoContentType content_type) {
62 std::stringstream ss;
63 int simulcast_id = content_type.GetSimulcastId();
64 if (simulcast_id > 0) {
65 ss << ".S" << simulcast_id - 1;
66 }
67 return ss.str();
68 }
49 } // namespace 69 } // namespace
50 70
51 ReceiveStatisticsProxy::ReceiveStatisticsProxy( 71 ReceiveStatisticsProxy::ReceiveStatisticsProxy(
52 const VideoReceiveStream::Config* config, 72 const VideoReceiveStream::Config* config,
53 Clock* clock) 73 Clock* clock)
54 : clock_(clock), 74 : clock_(clock),
55 config_(*config), 75 config_(*config),
56 start_ms_(clock->TimeInMilliseconds()), 76 start_ms_(clock->TimeInMilliseconds()),
57 last_sample_time_(clock->TimeInMilliseconds()), 77 last_sample_time_(clock->TimeInMilliseconds()),
58 fps_threshold_(kLowFpsThreshold, 78 fps_threshold_(kLowFpsThreshold,
59 kHighFpsThreshold, 79 kHighFpsThreshold,
60 kBadFraction, 80 kBadFraction,
61 kNumMeasurements), 81 kNumMeasurements),
62 qp_threshold_(kLowQpThresholdVp8, 82 qp_threshold_(kLowQpThresholdVp8,
63 kHighQpThresholdVp8, 83 kHighQpThresholdVp8,
64 kBadFraction, 84 kBadFraction,
65 kNumMeasurements), 85 kNumMeasurements),
66 variance_threshold_(kLowVarianceThreshold, 86 variance_threshold_(kLowVarianceThreshold,
67 kHighVarianceThreshold, 87 kHighVarianceThreshold,
68 kBadFraction, 88 kBadFraction,
69 kNumMeasurementsVariance), 89 kNumMeasurementsVariance),
70 num_bad_states_(0), 90 num_bad_states_(0),
71 num_certain_states_(0), 91 num_certain_states_(0),
72 // 1000ms window, scale 1000 for ms to s. 92 // 1000ms window, scale 1000 for ms to s.
73 decode_fps_estimator_(1000, 1000), 93 decode_fps_estimator_(1000, 1000),
74 renders_fps_estimator_(1000, 1000), 94 renders_fps_estimator_(1000, 1000),
75 render_fps_tracker_(100, 10u), 95 render_fps_tracker_(100, 10u),
76 render_pixel_tracker_(100, 10u), 96 render_pixel_tracker_(100, 10u),
77 total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count 97 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), 98 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs),
83 first_report_block_time_ms_(-1), 99 first_report_block_time_ms_(-1),
84 avg_rtt_ms_(0), 100 avg_rtt_ms_(0),
85 last_content_type_(VideoContentType::UNSPECIFIED) { 101 last_content_type_(VideoContentType::UNSPECIFIED) {
86 stats_.ssrc = config_.rtp.remote_ssrc; 102 stats_.ssrc = config_.rtp.remote_ssrc;
87 // TODO(brandtr): Replace |rtx_stats_| with a single instance of 103 // TODO(brandtr): Replace |rtx_stats_| with a single instance of
88 // StreamDataCounters. 104 // StreamDataCounters.
89 if (config_.rtp.rtx_ssrc) { 105 if (config_.rtp.rtx_ssrc) {
90 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters(); 106 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters();
91 } 107 }
92 } 108 }
93 109
94 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { 110 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() {
95 UpdateHistograms(); 111 UpdateHistograms();
96 } 112 }
97 113
98 void ReceiveStatisticsProxy::UpdateHistograms() { 114 void ReceiveStatisticsProxy::UpdateHistograms() {
115 // Set synthetic field trial based on received experiment id.
116 // Since experiment is set at the send side and is not changed during the
117 // call, any received content type may be used.
118 int experiment_id = last_content_type_.GetExperimentId();
119 if (experiment_id != 0) { // 0 means no experiment is active.
120 std::stringstream group_name;
121 group_name << "Group-" << experiment_id - 1;
122 field_trial::RegisterSyntheticFieldTrial(
123 AlrDetector::kScreenshareProbingBweExperimentNameOnReceiveSide,
124 group_name.str());
125 } else {
126 // No experiment group specified.
127 field_trial::RegisterSyntheticFieldTrial(
128 AlrDetector::kScreenshareProbingBweExperimentNameOnReceiveSide, "");
129 }
130
99 RTC_HISTOGRAM_COUNTS_100000( 131 RTC_HISTOGRAM_COUNTS_100000(
100 "WebRTC.Video.ReceiveStreamLifetimeInSeconds", 132 "WebRTC.Video.ReceiveStreamLifetimeInSeconds",
101 (clock_->TimeInMilliseconds() - start_ms_) / 1000); 133 (clock_->TimeInMilliseconds() - start_ms_) / 1000);
102 134
103 if (first_report_block_time_ms_ != -1 && 135 if (first_report_block_time_ms_ != -1 &&
104 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >= 136 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >=
105 metrics::kMinRunTimeInSeconds) { 137 metrics::kMinRunTimeInSeconds) {
106 int fraction_lost = report_block_stats_.FractionLostInPercent(); 138 int fraction_lost = report_block_stats_.FractionLostInPercent();
107 if (fraction_lost != -1) { 139 if (fraction_lost != -1) {
108 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", 140 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent",
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples); 211 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples);
180 if (current_delay_ms != -1) { 212 if (current_delay_ms != -1) {
181 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", 213 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs",
182 current_delay_ms); 214 current_delay_ms);
183 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms; 215 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms;
184 } 216 }
185 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); 217 int delay_ms = delay_counter_.Avg(kMinRequiredSamples);
186 if (delay_ms != -1) 218 if (delay_ms != -1)
187 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms); 219 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms);
188 220
189 int e2e_delay_ms_video = e2e_delay_counter_video_.Avg(kMinRequiredSamples); 221 for (auto it : content_specific_stats_) {
190 if (e2e_delay_ms_video != -1) { 222 auto content_type = it.first;
191 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.EndToEndDelayInMs", 223 auto stats = it.second;
192 e2e_delay_ms_video); 224 std::string uma_prefix = UmaPrefixForContentType(content_type);
193 LOG(LS_INFO) << "WebRTC.Video.EndToEndDelayInMs " << e2e_delay_ms_video; 225 std::string uma_suffix = UmaSuffixForContentType(content_type);
226 // The same line of code can't report different histograms because of how
227 // macro is done. Additional index needed to be different for all different
228 // names. Since experiment can't change during call, we could report 4*2
229 // different content types (4 simulcast_ids x 2 content types).
230 // Conveniently all of these are stored in 3 lower bits in VideoContentType.
231 int idx = content_type.content_type & 0x07;
232 int e2e_delay_ms = stats.e2e_delay_counter.Avg(kMinRequiredSamples);
233 if (e2e_delay_ms != -1) {
234 RTC_HISTOGRAMS_COUNTS_10000(
235 idx, uma_prefix + "EndToEndDelayInMs" + uma_suffix, e2e_delay_ms);
236 LOG(LS_INFO) << uma_prefix << "EndToEndDelayInMs " << uma_suffix
237 << e2e_delay_ms;
238 }
239 int e2e_delay_max_ms = stats.e2e_delay_counter.Max();
240
241 if (e2e_delay_max_ms != -1) {
242 RTC_HISTOGRAMS_COUNTS_100000(
243 idx, uma_prefix + "EndToEndDelayMaxInMs" + uma_suffix,
244 e2e_delay_max_ms);
245 LOG(LS_INFO) << uma_prefix << "EndToEndDelayMaxInMs" << uma_suffix << " "
246 << e2e_delay_max_ms;
247 }
248 int interframe_delay_ms =
249 stats.interframe_delay_counter.Avg(kMinRequiredSamples);
250 if (interframe_delay_ms != -1) {
251 RTC_HISTOGRAMS_COUNTS_10000(
252 idx, uma_prefix + "InterframeDelayInMs" + uma_suffix,
253 interframe_delay_ms);
254 LOG(LS_INFO) << uma_prefix << "InterframeDelayInMs" << uma_suffix << " "
255 << interframe_delay_ms;
256 }
257 int interframe_delay_max_ms = stats.interframe_delay_counter.Max();
258 if (interframe_delay_max_ms != -1) {
259 RTC_HISTOGRAMS_COUNTS_10000(
260 idx, uma_prefix + "InterframeDelayMaxInMs" + uma_suffix,
261 interframe_delay_max_ms);
262 LOG(LS_INFO) << uma_prefix << "InterframeDelayMaxInMs" << uma_suffix
263 << " " << interframe_delay_max_ms;
264 }
194 } 265 }
195 266
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; 267 StreamDataCounters rtp = stats_.rtp_stats;
246 StreamDataCounters rtx; 268 StreamDataCounters rtx;
247 for (auto it : rtx_stats_) 269 for (auto it : rtx_stats_)
248 rtx.Add(it.second); 270 rtx.Add(it.second);
249 StreamDataCounters rtp_rtx = rtp; 271 StreamDataCounters rtp_rtx = rtp;
250 rtp_rtx.Add(rtx); 272 rtp_rtx.Add(rtx);
251 int64_t elapsed_sec = 273 int64_t elapsed_sec =
252 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000; 274 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000;
253 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { 275 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
254 RTC_HISTOGRAM_COUNTS_10000( 276 RTC_HISTOGRAM_COUNTS_10000(
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 LOG(LS_WARNING) 589 LOG(LS_WARNING)
568 << "QP sum was already set and no QP was given for a frame."; 590 << "QP sum was already set and no QP was given for a frame.";
569 stats_.qp_sum = rtc::Optional<uint64_t>(); 591 stats_.qp_sum = rtc::Optional<uint64_t>();
570 } 592 }
571 last_content_type_ = content_type; 593 last_content_type_ = content_type;
572 decode_fps_estimator_.Update(1, now); 594 decode_fps_estimator_.Update(1, now);
573 if (last_decoded_frame_time_ms_) { 595 if (last_decoded_frame_time_ms_) {
574 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_; 596 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_;
575 RTC_DCHECK_GE(interframe_delay_ms, 0); 597 RTC_DCHECK_GE(interframe_delay_ms, 0);
576 stats_.interframe_delay_sum_ms += interframe_delay_ms; 598 stats_.interframe_delay_sum_ms += interframe_delay_ms;
577 if (last_content_type_ == VideoContentType::SCREENSHARE) { 599 auto it = content_specific_stats_.find(last_content_type_);
578 interframe_delay_counter_screenshare_.Add(interframe_delay_ms); 600 if (it == content_specific_stats_.end()) {
579 if (interframe_delay_max_ms_screenshare_ < interframe_delay_ms) { 601 content_specific_stats_[last_content_type_] = ContentSpecificStats();
580 interframe_delay_max_ms_screenshare_ = interframe_delay_ms; 602 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 } 603 }
604 ContentSpecificStats* stats = &it->second;
605 stats->interframe_delay_counter.Add(interframe_delay_ms);
588 } 606 }
589 last_decoded_frame_time_ms_.emplace(now); 607 last_decoded_frame_time_ms_.emplace(now);
590 } 608 }
591 609
592 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) { 610 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) {
593 int width = frame.width(); 611 int width = frame.width();
594 int height = frame.height(); 612 int height = frame.height();
595 RTC_DCHECK_GT(width, 0); 613 RTC_DCHECK_GT(width, 0);
596 RTC_DCHECK_GT(height, 0); 614 RTC_DCHECK_GT(height, 0);
597 uint64_t now = clock_->TimeInMilliseconds(); 615 uint64_t now = clock_->TimeInMilliseconds();
598 616
599 rtc::CritScope lock(&crit_); 617 rtc::CritScope lock(&crit_);
600 renders_fps_estimator_.Update(1, now); 618 renders_fps_estimator_.Update(1, now);
601 ++stats_.frames_rendered; 619 ++stats_.frames_rendered;
602 stats_.width = width; 620 stats_.width = width;
603 stats_.height = height; 621 stats_.height = height;
604 render_width_counter_.Add(width); 622 render_width_counter_.Add(width);
605 render_height_counter_.Add(height); 623 render_height_counter_.Add(height);
606 render_fps_tracker_.AddSamples(1); 624 render_fps_tracker_.AddSamples(1);
607 render_pixel_tracker_.AddSamples(sqrt(width * height)); 625 render_pixel_tracker_.AddSamples(sqrt(width * height));
608 626
609 if (frame.ntp_time_ms() > 0) { 627 if (frame.ntp_time_ms() > 0) {
610 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms(); 628 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms();
611 if (delay_ms >= 0) { 629 if (delay_ms >= 0) {
612 if (last_content_type_ == VideoContentType::SCREENSHARE) { 630 auto it = content_specific_stats_.find(last_content_type_);
613 e2e_delay_max_ms_screenshare_ = 631 if (it == content_specific_stats_.end()) {
614 std::max(delay_ms, e2e_delay_max_ms_screenshare_); 632 content_specific_stats_[last_content_type_] = ContentSpecificStats();
615 e2e_delay_counter_screenshare_.Add(delay_ms); 633 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 } 634 }
635 ContentSpecificStats* stats = &it->second;
636 stats->e2e_delay_counter.Add(delay_ms);
620 } 637 }
621 } 638 }
622 639
623 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedWidthInPixels", 640 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedWidthInPixels",
624 "width", width, "ssrc", stats_.ssrc); 641 "width", width, "ssrc", stats_.ssrc);
625 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedHeightInPixels", 642 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.ReceivedHeightInPixels",
626 "height", height, "ssrc", stats_.ssrc); 643 "height", height, "ssrc", stats_.ssrc);
627 TRACE_EVENT_INSTANT1("webrtc_stats", "WebRTC.Video.OnRenderedFrame", 644 TRACE_EVENT_INSTANT1("webrtc_stats", "WebRTC.Video.OnRenderedFrame",
628 "ssrc", stats_.ssrc); 645 "ssrc", stats_.ssrc);
629 } 646 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 if (codec_specific_info->codecType == kVideoCodecVP8) { 697 if (codec_specific_info->codecType == kVideoCodecVP8) {
681 qp_counters_.vp8.Add(encoded_image.qp_); 698 qp_counters_.vp8.Add(encoded_image.qp_);
682 rtc::CritScope lock(&crit_); 699 rtc::CritScope lock(&crit_);
683 qp_sample_.Add(encoded_image.qp_); 700 qp_sample_.Add(encoded_image.qp_);
684 } 701 }
685 } 702 }
686 703
687 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { 704 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) {
688 sum += sample; 705 sum += sample;
689 ++num_samples; 706 ++num_samples;
707 if (!max || *max < sample) {
708 max.emplace(sample);
709 }
690 } 710 }
691 711
692 int ReceiveStatisticsProxy::SampleCounter::Avg( 712 int ReceiveStatisticsProxy::SampleCounter::Avg(
693 int64_t min_required_samples) const { 713 int64_t min_required_samples) const {
694 if (num_samples < min_required_samples || num_samples == 0) 714 if (num_samples < min_required_samples || num_samples == 0)
695 return -1; 715 return -1;
696 return static_cast<int>(sum / num_samples); 716 return static_cast<int>(sum / num_samples);
697 } 717 }
698 718
719 int ReceiveStatisticsProxy::SampleCounter::Max() const {
720 if (!max) {
721 return -1;
722 } else {
723 return static_cast<int>(*max);
724 }
725 }
726
699 void ReceiveStatisticsProxy::SampleCounter::Reset() { 727 void ReceiveStatisticsProxy::SampleCounter::Reset() {
700 num_samples = 0; 728 num_samples = 0;
701 sum = 0; 729 sum = 0;
730 max.reset();
702 } 731 }
703 732
704 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms, 733 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms,
705 int64_t max_rtt_ms) { 734 int64_t max_rtt_ms) {
706 rtc::CritScope lock(&crit_); 735 rtc::CritScope lock(&crit_);
707 avg_rtt_ms_ = avg_rtt_ms; 736 avg_rtt_ms_ = avg_rtt_ms;
708 } 737 }
709 738
710 } // namespace webrtc 739 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698