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

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: Add metrics sliced on AlrExperiment group Created 3 years, 3 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/system_wrappers/include/clock.h" 22 #include "webrtc/system_wrappers/include/clock.h"
21 #include "webrtc/system_wrappers/include/field_trial.h" 23 #include "webrtc/system_wrappers/include/field_trial.h"
22 #include "webrtc/system_wrappers/include/metrics.h" 24 #include "webrtc/system_wrappers/include/metrics.h"
23 25
24 namespace webrtc { 26 namespace webrtc {
25 namespace { 27 namespace {
26 // Periodic time interval for processing samples for |freq_offset_counter_|. 28 // Periodic time interval for processing samples for |freq_offset_counter_|.
(...skipping 11 matching lines...) Expand all
38 const int kHighFpsThreshold = 14; 40 const int kHighFpsThreshold = 14;
39 // For qp and fps variance: 41 // For qp and fps variance:
40 // Low means low enough to be good, high means high enough to be bad 42 // Low means low enough to be good, high means high enough to be bad
41 const int kLowQpThresholdVp8 = 60; 43 const int kLowQpThresholdVp8 = 60;
42 const int kHighQpThresholdVp8 = 70; 44 const int kHighQpThresholdVp8 = 70;
43 const int kLowVarianceThreshold = 1; 45 const int kLowVarianceThreshold = 1;
44 const int kHighVarianceThreshold = 2; 46 const int kHighVarianceThreshold = 2;
45 47
46 // How large window we use to calculate the framerate/bitrate. 48 // How large window we use to calculate the framerate/bitrate.
47 const int kRateStatisticsWindowSizeMs = 1000; 49 const int kRateStatisticsWindowSizeMs = 1000;
50
51 std::string UmaPrefixForContentType(VideoContentType content_type) {
52 std::stringstream ss;
53 ss << "WebRTC.Video";
54 if (content_type.IsScreenshare()) {
55 ss << ".Screenshare";
56 }
57 return ss.str();
58 }
59
60 std::string UmaSuffixForContentType(VideoContentType content_type) {
61 std::stringstream ss;
62 int simulcast_id = content_type.GetSimulcastId();
63 if (simulcast_id > 0) {
64 ss << ".S" << simulcast_id - 1;
65 }
66 return ss.str();
67 }
68
69 std::string UmaPrefixForExperiment(VideoContentType content_type) {
70 std::stringstream ss;
71 ss << "WebRTC.Video.AlrExperiment";
72 if (content_type.IsScreenshare()) {
73 ss << ".Screenshare";
74 }
75 return ss.str();
76 }
77
78 std::string UmaSuffixForExperiment(VideoContentType content_type) {
79 std::stringstream ss;
80 int experiment_id = content_type.GetExperimentId();
81 if (experiment_id > 0) {
82 ss << ".Group" << experiment_id - 1;
83 }
84 return ss.str();
85 }
48 } // namespace 86 } // namespace
49 87
50 ReceiveStatisticsProxy::ReceiveStatisticsProxy( 88 ReceiveStatisticsProxy::ReceiveStatisticsProxy(
51 const VideoReceiveStream::Config* config, 89 const VideoReceiveStream::Config* config,
52 Clock* clock) 90 Clock* clock)
53 : clock_(clock), 91 : clock_(clock),
54 config_(*config), 92 config_(*config),
55 start_ms_(clock->TimeInMilliseconds()), 93 start_ms_(clock->TimeInMilliseconds()),
56 last_sample_time_(clock->TimeInMilliseconds()), 94 last_sample_time_(clock->TimeInMilliseconds()),
57 fps_threshold_(kLowFpsThreshold, 95 fps_threshold_(kLowFpsThreshold,
58 kHighFpsThreshold, 96 kHighFpsThreshold,
59 kBadFraction, 97 kBadFraction,
60 kNumMeasurements), 98 kNumMeasurements),
61 qp_threshold_(kLowQpThresholdVp8, 99 qp_threshold_(kLowQpThresholdVp8,
62 kHighQpThresholdVp8, 100 kHighQpThresholdVp8,
63 kBadFraction, 101 kBadFraction,
64 kNumMeasurements), 102 kNumMeasurements),
65 variance_threshold_(kLowVarianceThreshold, 103 variance_threshold_(kLowVarianceThreshold,
66 kHighVarianceThreshold, 104 kHighVarianceThreshold,
67 kBadFraction, 105 kBadFraction,
68 kNumMeasurementsVariance), 106 kNumMeasurementsVariance),
69 num_bad_states_(0), 107 num_bad_states_(0),
70 num_certain_states_(0), 108 num_certain_states_(0),
71 // 1000ms window, scale 1000 for ms to s. 109 // 1000ms window, scale 1000 for ms to s.
72 decode_fps_estimator_(1000, 1000), 110 decode_fps_estimator_(1000, 1000),
73 renders_fps_estimator_(1000, 1000), 111 renders_fps_estimator_(1000, 1000),
74 render_fps_tracker_(100, 10u), 112 render_fps_tracker_(100, 10u),
75 render_pixel_tracker_(100, 10u), 113 render_pixel_tracker_(100, 10u),
76 total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count 114 total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count
77 e2e_delay_max_ms_video_(-1),
78 e2e_delay_max_ms_screenshare_(-1),
79 interframe_delay_max_ms_video_(-1),
80 interframe_delay_max_ms_screenshare_(-1),
81 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs), 115 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs),
82 first_report_block_time_ms_(-1), 116 first_report_block_time_ms_(-1),
83 avg_rtt_ms_(0), 117 avg_rtt_ms_(0),
84 last_content_type_(VideoContentType::UNSPECIFIED) { 118 last_content_type_(VideoContentType::UNSPECIFIED) {
85 stats_.ssrc = config_.rtp.remote_ssrc; 119 stats_.ssrc = config_.rtp.remote_ssrc;
86 // TODO(brandtr): Replace |rtx_stats_| with a single instance of 120 // TODO(brandtr): Replace |rtx_stats_| with a single instance of
87 // StreamDataCounters. 121 // StreamDataCounters.
88 if (config_.rtp.rtx_ssrc) { 122 if (config_.rtp.rtx_ssrc) {
89 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters(); 123 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters();
90 } 124 }
91 } 125 }
92 126
93 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { 127 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() {
94 UpdateHistograms(); 128 UpdateHistograms();
95 } 129 }
96 130
97 void ReceiveStatisticsProxy::UpdateHistograms() { 131 void ReceiveStatisticsProxy::UpdateHistograms() {
132 // Use to report experiment-specific metrics.
133 int experiment_id = last_content_type_.GetExperimentId();
134
98 RTC_HISTOGRAM_COUNTS_100000( 135 RTC_HISTOGRAM_COUNTS_100000(
99 "WebRTC.Video.ReceiveStreamLifetimeInSeconds", 136 "WebRTC.Video.ReceiveStreamLifetimeInSeconds",
100 (clock_->TimeInMilliseconds() - start_ms_) / 1000); 137 (clock_->TimeInMilliseconds() - start_ms_) / 1000);
101 138
102 if (first_report_block_time_ms_ != -1 && 139 if (first_report_block_time_ms_ != -1 &&
103 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >= 140 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >=
104 metrics::kMinRunTimeInSeconds) { 141 metrics::kMinRunTimeInSeconds) {
105 int fraction_lost = report_block_stats_.FractionLostInPercent(); 142 int fraction_lost = report_block_stats_.FractionLostInPercent();
106 if (fraction_lost != -1) { 143 if (fraction_lost != -1) {
107 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", 144 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent",
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples); 215 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples);
179 if (current_delay_ms != -1) { 216 if (current_delay_ms != -1) {
180 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", 217 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs",
181 current_delay_ms); 218 current_delay_ms);
182 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms; 219 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms;
183 } 220 }
184 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); 221 int delay_ms = delay_counter_.Avg(kMinRequiredSamples);
185 if (delay_ms != -1) 222 if (delay_ms != -1)
186 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms); 223 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms);
187 224
188 int e2e_delay_ms_video = e2e_delay_counter_video_.Avg(kMinRequiredSamples); 225 int avg_interframe_delay = 0;
189 if (e2e_delay_ms_video != -1) { 226 int max_interframe_delay = -1;
190 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.EndToEndDelayInMs", 227 int interframe_delay_slices = 0;
191 e2e_delay_ms_video); 228 int avg_e2e_delay = 0;
192 LOG(LS_INFO) << "WebRTC.Video.EndToEndDelayInMs " << e2e_delay_ms_video; 229 int max_e2e_delay = -1;
230 int e2e_delay_slices = 0;
231
232 // Slice on content type and simulcast id.
233 for (auto it : content_specific_stats_) {
234 auto content_type = it.first;
235 auto stats = it.second;
236 std::string uma_prefix = UmaPrefixForContentType(content_type);
237 std::string uma_suffix = UmaSuffixForContentType(content_type);
238 // The same line of code can't report different histograms because of how
239 // macro is done. Additional index needed to be different for all different
240 // names. Since experiment can't change during call, we could report 4*2
241 // different content types (4 simulcast_ids x 2 content types).
242 // Conveniently all of these are stored in 3 lower bits in VideoContentType.
243 int idx = content_type.content_type & 0x07;
244 int e2e_delay_ms = stats.e2e_delay_counter.Avg(kMinRequiredSamples);
245 if (e2e_delay_ms != -1) {
246 RTC_HISTOGRAMS_COUNTS_10000(
247 idx, uma_prefix + ".EndToEndDelayInMs" + uma_suffix, e2e_delay_ms);
248 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayInMs" << uma_suffix << " "
249 << e2e_delay_ms;
250 avg_e2e_delay += e2e_delay_ms;
251 ++e2e_delay_slices;
252 }
253 int e2e_delay_max_ms = stats.e2e_delay_counter.Max();
254
255 if (e2e_delay_max_ms != -1 && e2e_delay_ms != -1) {
256 RTC_HISTOGRAMS_COUNTS_100000(
257 idx, uma_prefix + ".EndToEndDelayMaxInMs" + uma_suffix,
258 e2e_delay_max_ms);
259 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayMaxInMs" << uma_suffix << " "
260 << e2e_delay_max_ms;
261 if (e2e_delay_max_ms > max_e2e_delay)
262 max_e2e_delay = e2e_delay_max_ms;
263 }
264 int interframe_delay_ms =
265 stats.interframe_delay_counter.Avg(kMinRequiredSamples);
266 if (interframe_delay_ms != -1) {
267 RTC_HISTOGRAMS_COUNTS_10000(
268 idx, uma_prefix + ".InterframeDelayInMs" + uma_suffix,
269 interframe_delay_ms);
270 LOG(LS_INFO) << uma_prefix << ".InterframeDelayInMs" << uma_suffix << " "
271 << interframe_delay_ms;
272 avg_interframe_delay += interframe_delay_ms;
273 ++interframe_delay_slices;
274 }
275 int interframe_delay_max_ms = stats.interframe_delay_counter.Max();
276 if (interframe_delay_max_ms != -1 && interframe_delay_ms != -1) {
277 RTC_HISTOGRAMS_COUNTS_10000(
278 idx, uma_prefix + ".InterframeDelayMaxInMs" + uma_suffix,
279 interframe_delay_max_ms);
280 LOG(LS_INFO) << uma_prefix << ".InterframeDelayMaxInMs" << uma_suffix
281 << " " << interframe_delay_max_ms;
282 if (interframe_delay_max_ms > max_interframe_delay)
283 max_interframe_delay = interframe_delay_max_ms;
284 }
285 }
286 if (e2e_delay_slices > 0) {
287 avg_e2e_delay /= e2e_delay_slices;
288 } else {
289 avg_e2e_delay = -1;
290 }
291 if (interframe_delay_slices > 0) {
292 avg_interframe_delay /= interframe_delay_slices;
293 } else {
294 avg_interframe_delay = -1;
193 } 295 }
194 296
195 int e2e_delay_ms_screenshare = 297 int media_bitrate = 0;
196 e2e_delay_counter_screenshare_.Avg(kMinRequiredSamples);
197 if (e2e_delay_ms_screenshare != -1) {
198 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.EndToEndDelayInMs",
199 e2e_delay_ms_screenshare);
200 }
201
202 int e2e_delay_max_ms_video = e2e_delay_max_ms_video_;
203 if (e2e_delay_max_ms_video != -1) {
204 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.EndToEndDelayMaxInMs",
205 e2e_delay_max_ms_video);
206 }
207
208 int e2e_delay_max_ms_screenshare = e2e_delay_max_ms_screenshare_;
209 if (e2e_delay_max_ms_screenshare != -1) {
210 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.Screenshare.EndToEndDelayMaxInMs",
211 e2e_delay_max_ms_screenshare);
212 }
213
214 int interframe_delay_ms_screenshare =
215 interframe_delay_counter_screenshare_.Avg(kMinRequiredSamples);
216 if (interframe_delay_ms_screenshare != -1) {
217 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.InterframeDelayInMs",
218 interframe_delay_ms_screenshare);
219 RTC_DCHECK_GE(interframe_delay_max_ms_screenshare_,
220 interframe_delay_ms_screenshare);
221 RTC_HISTOGRAM_COUNTS_10000(
222 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs",
223 interframe_delay_max_ms_screenshare_);
224 }
225
226 int interframe_delay_ms_video =
227 interframe_delay_counter_video_.Avg(kMinRequiredSamples);
228 if (interframe_delay_ms_video != -1) {
229 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InterframeDelayInMs",
230 interframe_delay_ms_video);
231 RTC_DCHECK_GE(interframe_delay_max_ms_video_, interframe_delay_ms_video);
232 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InterframeDelayMaxInMs",
233 interframe_delay_max_ms_video_);
234 }
235 298
236 StreamDataCounters rtp = stats_.rtp_stats; 299 StreamDataCounters rtp = stats_.rtp_stats;
237 StreamDataCounters rtx; 300 StreamDataCounters rtx;
238 for (auto it : rtx_stats_) 301 for (auto it : rtx_stats_)
239 rtx.Add(it.second); 302 rtx.Add(it.second);
240 StreamDataCounters rtp_rtx = rtp; 303 StreamDataCounters rtp_rtx = rtp;
241 rtp_rtx.Add(rtx); 304 rtp_rtx.Add(rtx);
242 int64_t elapsed_sec = 305 int64_t elapsed_sec =
243 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000; 306 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000;
244 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { 307 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
245 RTC_HISTOGRAM_COUNTS_10000( 308 RTC_HISTOGRAM_COUNTS_10000(
246 "WebRTC.Video.BitrateReceivedInKbps", 309 "WebRTC.Video.BitrateReceivedInKbps",
247 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 310 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
248 1000)); 311 1000));
249 RTC_HISTOGRAM_COUNTS_10000( 312 media_bitrate =
250 "WebRTC.Video.MediaBitrateReceivedInKbps", 313 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000);
251 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); 314 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.MediaBitrateReceivedInKbps",
315 media_bitrate);
252 RTC_HISTOGRAM_COUNTS_10000( 316 RTC_HISTOGRAM_COUNTS_10000(
253 "WebRTC.Video.PaddingBitrateReceivedInKbps", 317 "WebRTC.Video.PaddingBitrateReceivedInKbps",
254 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / 318 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec /
255 1000)); 319 1000));
256 RTC_HISTOGRAM_COUNTS_10000( 320 RTC_HISTOGRAM_COUNTS_10000(
257 "WebRTC.Video.RetransmittedBitrateReceivedInKbps", 321 "WebRTC.Video.RetransmittedBitrateReceivedInKbps",
258 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec / 322 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec /
259 1000)); 323 1000));
260 if (!rtx_stats_.empty()) { 324 if (!rtx_stats_.empty()) {
261 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtxBitrateReceivedInKbps", 325 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtxBitrateReceivedInKbps",
(...skipping 11 matching lines...) Expand all
273 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsSentPerMinute", 337 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsSentPerMinute",
274 counters.fir_packets * 60 / elapsed_sec); 338 counters.fir_packets * 60 / elapsed_sec);
275 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute", 339 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute",
276 counters.pli_packets * 60 / elapsed_sec); 340 counters.pli_packets * 60 / elapsed_sec);
277 if (counters.nack_requests > 0) { 341 if (counters.nack_requests > 0) {
278 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent", 342 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent",
279 counters.UniqueNackRequestsInPercent()); 343 counters.UniqueNackRequestsInPercent());
280 } 344 }
281 } 345 }
282 346
347 // Report metrics sliced on ALR experiment group.
348 if (experiment_id > 0 && content_specific_stats_.size() > 0) {
349 VideoContentType content_type = content_specific_stats_.begin()->first;
350 std::string uma_prefix = UmaPrefixForExperiment(content_type);
351 std::string uma_suffix = UmaSuffixForExperiment(content_type);
352 if (avg_e2e_delay != -1) {
353 RTC_HISTOGRAM_COUNTS_10000(uma_prefix + ".EndToEndDelayInMs" + uma_suffix,
354 avg_e2e_delay);
355 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayInMs" << uma_suffix << " "
356 << avg_e2e_delay;
357 }
358 if (max_e2e_delay != -1) {
359 RTC_HISTOGRAM_COUNTS_100000(
360 uma_prefix + ".EndToEndDelayMaxInMs" + uma_suffix, max_e2e_delay);
361 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayMaxInMs" << uma_suffix << " "
362 << max_e2e_delay;
363 }
364 if (avg_interframe_delay != -1) {
365 RTC_HISTOGRAM_COUNTS_10000(
366 uma_prefix + ".InterframeDelayInMs" + uma_suffix,
367 avg_interframe_delay);
368 LOG(LS_INFO) << uma_prefix << ".InterframeDelayInMs" << uma_suffix << " "
369 << avg_interframe_delay;
370 }
371 if (max_interframe_delay != -1) {
372 RTC_HISTOGRAM_COUNTS_10000(
373 uma_prefix + ".InterframeDelayMaxInMs" + uma_suffix,
374 max_interframe_delay);
375 LOG(LS_INFO) << uma_prefix << ".InterframeDelayMaxInMs" << uma_suffix
376 << " " << max_interframe_delay;
377 }
378 if (media_bitrate != 0) {
379 RTC_HISTOGRAM_COUNTS_10000(
380 uma_prefix + ".MediaBitrateReceivedInKbps" + uma_suffix,
381 media_bitrate);
382 LOG(LS_INFO) << uma_prefix << ".MediaBitrateReceivedInKbps" << uma_suffix
383 << " " << media_bitrate;
384 }
385 }
386
sprang_webrtc 2017/08/24 09:13:16 Why isn't this reported in the same way as for the
ilnik 2017/08/25 12:35:07 Because currently we can't get slice on both simul
283 if (num_certain_states_ >= kBadCallMinRequiredSamples) { 387 if (num_certain_states_ >= kBadCallMinRequiredSamples) {
284 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BadCall.Any", 388 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BadCall.Any",
285 100 * num_bad_states_ / num_certain_states_); 389 100 * num_bad_states_ / num_certain_states_);
286 } 390 }
287 rtc::Optional<double> fps_fraction = 391 rtc::Optional<double> fps_fraction =
288 fps_threshold_.FractionHigh(kBadCallMinRequiredSamples); 392 fps_threshold_.FractionHigh(kBadCallMinRequiredSamples);
289 if (fps_fraction) { 393 if (fps_fraction) {
290 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BadCall.FrameRate", 394 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BadCall.FrameRate",
291 static_cast<int>(100 * (1 - *fps_fraction))); 395 static_cast<int>(100 * (1 - *fps_fraction)));
292 } 396 }
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 LOG(LS_WARNING) 642 LOG(LS_WARNING)
539 << "QP sum was already set and no QP was given for a frame."; 643 << "QP sum was already set and no QP was given for a frame.";
540 stats_.qp_sum = rtc::Optional<uint64_t>(); 644 stats_.qp_sum = rtc::Optional<uint64_t>();
541 } 645 }
542 last_content_type_ = content_type; 646 last_content_type_ = content_type;
543 decode_fps_estimator_.Update(1, now); 647 decode_fps_estimator_.Update(1, now);
544 if (last_decoded_frame_time_ms_) { 648 if (last_decoded_frame_time_ms_) {
545 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_; 649 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_;
546 RTC_DCHECK_GE(interframe_delay_ms, 0); 650 RTC_DCHECK_GE(interframe_delay_ms, 0);
547 stats_.interframe_delay_sum_ms += interframe_delay_ms; 651 stats_.interframe_delay_sum_ms += interframe_delay_ms;
548 if (last_content_type_ == VideoContentType::SCREENSHARE) { 652 auto it = content_specific_stats_.find(last_content_type_);
549 interframe_delay_counter_screenshare_.Add(interframe_delay_ms); 653 if (it == content_specific_stats_.end()) {
550 if (interframe_delay_max_ms_screenshare_ < interframe_delay_ms) { 654 content_specific_stats_[last_content_type_] = ContentSpecificStats();
551 interframe_delay_max_ms_screenshare_ = interframe_delay_ms; 655 it = content_specific_stats_.find(last_content_type_);
552 }
553 } else {
554 interframe_delay_counter_video_.Add(interframe_delay_ms);
555 if (interframe_delay_max_ms_video_ < interframe_delay_ms) {
556 interframe_delay_max_ms_video_ = interframe_delay_ms;
557 }
558 } 656 }
sprang_webrtc 2017/08/24 09:13:16 I think you can just do auto it = content_specif
ilnik 2017/08/25 12:35:07 Redone using plain [] operator. According to docum
657 ContentSpecificStats* stats = &it->second;
658 stats->interframe_delay_counter.Add(interframe_delay_ms);
559 } 659 }
560 last_decoded_frame_time_ms_.emplace(now); 660 last_decoded_frame_time_ms_.emplace(now);
561 } 661 }
562 662
563 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) { 663 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) {
564 int width = frame.width(); 664 int width = frame.width();
565 int height = frame.height(); 665 int height = frame.height();
566 RTC_DCHECK_GT(width, 0); 666 RTC_DCHECK_GT(width, 0);
567 RTC_DCHECK_GT(height, 0); 667 RTC_DCHECK_GT(height, 0);
568 uint64_t now = clock_->TimeInMilliseconds(); 668 uint64_t now = clock_->TimeInMilliseconds();
569 669
570 rtc::CritScope lock(&crit_); 670 rtc::CritScope lock(&crit_);
571 renders_fps_estimator_.Update(1, now); 671 renders_fps_estimator_.Update(1, now);
572 ++stats_.frames_rendered; 672 ++stats_.frames_rendered;
573 stats_.width = width; 673 stats_.width = width;
574 stats_.height = height; 674 stats_.height = height;
575 render_width_counter_.Add(width); 675 render_width_counter_.Add(width);
576 render_height_counter_.Add(height); 676 render_height_counter_.Add(height);
577 render_fps_tracker_.AddSamples(1); 677 render_fps_tracker_.AddSamples(1);
578 render_pixel_tracker_.AddSamples(sqrt(width * height)); 678 render_pixel_tracker_.AddSamples(sqrt(width * height));
579 679
580 if (frame.ntp_time_ms() > 0) { 680 if (frame.ntp_time_ms() > 0) {
581 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms(); 681 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms();
582 if (delay_ms >= 0) { 682 if (delay_ms >= 0) {
583 if (last_content_type_ == VideoContentType::SCREENSHARE) { 683 auto it = content_specific_stats_.find(last_content_type_);
584 e2e_delay_max_ms_screenshare_ = 684 if (it == content_specific_stats_.end()) {
585 std::max(delay_ms, e2e_delay_max_ms_screenshare_); 685 content_specific_stats_[last_content_type_] = ContentSpecificStats();
586 e2e_delay_counter_screenshare_.Add(delay_ms); 686 it = content_specific_stats_.find(last_content_type_);
587 } else {
588 e2e_delay_max_ms_video_ = std::max(delay_ms, e2e_delay_max_ms_video_);
589 e2e_delay_counter_video_.Add(delay_ms);
590 } 687 }
688 ContentSpecificStats* stats = &it->second;
689 stats->e2e_delay_counter.Add(delay_ms);
591 } 690 }
592 } 691 }
593 } 692 }
594 693
595 void ReceiveStatisticsProxy::OnSyncOffsetUpdated(int64_t sync_offset_ms, 694 void ReceiveStatisticsProxy::OnSyncOffsetUpdated(int64_t sync_offset_ms,
596 double estimated_freq_khz) { 695 double estimated_freq_khz) {
597 rtc::CritScope lock(&crit_); 696 rtc::CritScope lock(&crit_);
598 sync_offset_counter_.Add(std::abs(sync_offset_ms)); 697 sync_offset_counter_.Add(std::abs(sync_offset_ms));
599 stats_.sync_offset_ms = sync_offset_ms; 698 stats_.sync_offset_ms = sync_offset_ms;
600 699
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 // TODO(sprang): Figure out any other state that should be reset. 751 // TODO(sprang): Figure out any other state that should be reset.
653 752
654 rtc::CritScope lock(&crit_); 753 rtc::CritScope lock(&crit_);
655 // Don't report inter-frame delay if stream was paused. 754 // Don't report inter-frame delay if stream was paused.
656 last_decoded_frame_time_ms_.reset(); 755 last_decoded_frame_time_ms_.reset();
657 } 756 }
658 757
659 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { 758 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) {
660 sum += sample; 759 sum += sample;
661 ++num_samples; 760 ++num_samples;
761 if (!max || *max < sample) {
762 max.emplace(sample);
763 }
662 } 764 }
663 765
664 int ReceiveStatisticsProxy::SampleCounter::Avg( 766 int ReceiveStatisticsProxy::SampleCounter::Avg(
665 int64_t min_required_samples) const { 767 int64_t min_required_samples) const {
666 if (num_samples < min_required_samples || num_samples == 0) 768 if (num_samples < min_required_samples || num_samples == 0)
667 return -1; 769 return -1;
668 return static_cast<int>(sum / num_samples); 770 return static_cast<int>(sum / num_samples);
669 } 771 }
670 772
773 int ReceiveStatisticsProxy::SampleCounter::Max() const {
774 if (!max) {
775 return -1;
776 } else {
777 return *max;
778 }
779 }
780
671 void ReceiveStatisticsProxy::SampleCounter::Reset() { 781 void ReceiveStatisticsProxy::SampleCounter::Reset() {
672 num_samples = 0; 782 num_samples = 0;
673 sum = 0; 783 sum = 0;
784 max.reset();
674 } 785 }
675 786
676 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms, 787 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms,
677 int64_t max_rtt_ms) { 788 int64_t max_rtt_ms) {
678 rtc::CritScope lock(&crit_); 789 rtc::CritScope lock(&crit_);
679 avg_rtt_ms_ = avg_rtt_ms; 790 avg_rtt_ms_ = avg_rtt_ms;
680 } 791 }
681 792
682 } // namespace webrtc 793 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698