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

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: Fix tests 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 14 matching lines...) Expand all
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 // Some metrics are reported as a maximum over this period. 48 // Some metrics are reported as a maximum over this period.
47 const int kMovingMaxWindowMs = 10000; 49 const int kMovingMaxWindowMs = 10000;
48 50
49 // How large window we use to calculate the framerate/bitrate. 51 // How large window we use to calculate the framerate/bitrate.
50 const int kRateStatisticsWindowSizeMs = 1000; 52 const int kRateStatisticsWindowSizeMs = 1000;
53
54 std::string UmaPrefixForContentType(VideoContentType content_type) {
55 std::stringstream ss;
56 ss << "WebRTC.Video";
57 if (content_type.IsScreenshare()) {
58 ss << ".Screenshare";
59 }
60 return ss.str();
61 }
62
63 std::string UmaSpatialSuffixForContentType(VideoContentType content_type) {
64 std::stringstream ss;
65 int simulcast_id = content_type.GetSimulcastId();
66 if (simulcast_id > 0) {
67 ss << ".S" << simulcast_id - 1;
68 }
69 return ss.str();
70 }
71
72 std::string UmaExperimentSuffixForConentType(VideoContentType content_type) {
73 std::stringstream ss;
74 int experiment_id = content_type.GetExperimentId();
75 if (experiment_id > 0) {
76 ss << ".ExperimentGroup" << experiment_id - 1;
77 }
78 return ss.str();
79 }
51 } // namespace 80 } // namespace
52 81
53 ReceiveStatisticsProxy::ReceiveStatisticsProxy( 82 ReceiveStatisticsProxy::ReceiveStatisticsProxy(
54 const VideoReceiveStream::Config* config, 83 const VideoReceiveStream::Config* config,
55 Clock* clock) 84 Clock* clock)
56 : clock_(clock), 85 : clock_(clock),
57 config_(*config), 86 config_(*config),
58 start_ms_(clock->TimeInMilliseconds()), 87 start_ms_(clock->TimeInMilliseconds()),
59 last_sample_time_(clock->TimeInMilliseconds()), 88 last_sample_time_(clock->TimeInMilliseconds()),
60 fps_threshold_(kLowFpsThreshold, 89 fps_threshold_(kLowFpsThreshold,
61 kHighFpsThreshold, 90 kHighFpsThreshold,
62 kBadFraction, 91 kBadFraction,
63 kNumMeasurements), 92 kNumMeasurements),
64 qp_threshold_(kLowQpThresholdVp8, 93 qp_threshold_(kLowQpThresholdVp8,
65 kHighQpThresholdVp8, 94 kHighQpThresholdVp8,
66 kBadFraction, 95 kBadFraction,
67 kNumMeasurements), 96 kNumMeasurements),
68 variance_threshold_(kLowVarianceThreshold, 97 variance_threshold_(kLowVarianceThreshold,
69 kHighVarianceThreshold, 98 kHighVarianceThreshold,
70 kBadFraction, 99 kBadFraction,
71 kNumMeasurementsVariance), 100 kNumMeasurementsVariance),
72 num_bad_states_(0), 101 num_bad_states_(0),
73 num_certain_states_(0), 102 num_certain_states_(0),
74 // 1000ms window, scale 1000 for ms to s. 103 // 1000ms window, scale 1000 for ms to s.
75 decode_fps_estimator_(1000, 1000), 104 decode_fps_estimator_(1000, 1000),
76 renders_fps_estimator_(1000, 1000), 105 renders_fps_estimator_(1000, 1000),
77 render_fps_tracker_(100, 10u), 106 render_fps_tracker_(100, 10u),
78 render_pixel_tracker_(100, 10u), 107 render_pixel_tracker_(100, 10u),
79 total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count 108 total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count
80 e2e_delay_max_ms_video_(-1),
81 e2e_delay_max_ms_screenshare_(-1),
82 interframe_delay_max_ms_video_(-1),
83 interframe_delay_max_ms_screenshare_(-1),
84 interframe_delay_max_moving_(kMovingMaxWindowMs), 109 interframe_delay_max_moving_(kMovingMaxWindowMs),
85 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs), 110 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs),
86 first_report_block_time_ms_(-1), 111 first_report_block_time_ms_(-1),
87 avg_rtt_ms_(0), 112 avg_rtt_ms_(0),
88 last_content_type_(VideoContentType::UNSPECIFIED) { 113 last_content_type_(VideoContentType::UNSPECIFIED) {
89 stats_.ssrc = config_.rtp.remote_ssrc; 114 stats_.ssrc = config_.rtp.remote_ssrc;
90 // TODO(brandtr): Replace |rtx_stats_| with a single instance of 115 // TODO(brandtr): Replace |rtx_stats_| with a single instance of
91 // StreamDataCounters. 116 // StreamDataCounters.
92 if (config_.rtp.rtx_ssrc) { 117 if (config_.rtp.rtx_ssrc) {
93 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters(); 118 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters();
94 } 119 }
95 } 120 }
96 121
97 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { 122 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() {
98 UpdateHistograms(); 123 UpdateHistograms();
99 } 124 }
100 125
101 void ReceiveStatisticsProxy::UpdateHistograms() { 126 void ReceiveStatisticsProxy::UpdateHistograms() {
102 RTC_HISTOGRAM_COUNTS_100000( 127 const int kMinRequiredSamples = 200;
103 "WebRTC.Video.ReceiveStreamLifetimeInSeconds",
104 (clock_->TimeInMilliseconds() - start_ms_) / 1000);
105 128
106 if (first_report_block_time_ms_ != -1 &&
107 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >=
108 metrics::kMinRunTimeInSeconds) {
109 int fraction_lost = report_block_stats_.FractionLostInPercent();
110 if (fraction_lost != -1) {
111 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent",
112 fraction_lost);
113 LOG(LS_INFO) << "WebRTC.Video.ReceivedPacketsLostInPercent "
114 << fraction_lost;
115 }
116 }
117
118 const int kMinRequiredSamples = 200;
119 int samples = static_cast<int>(render_fps_tracker_.TotalSampleCount()); 129 int samples = static_cast<int>(render_fps_tracker_.TotalSampleCount());
120 if (samples >= kMinRequiredSamples) { 130 if (samples >= kMinRequiredSamples) {
121 RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", 131 RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond",
122 round(render_fps_tracker_.ComputeTotalRate())); 132 round(render_fps_tracker_.ComputeTotalRate()));
123 RTC_HISTOGRAM_COUNTS_100000( 133 RTC_HISTOGRAM_COUNTS_100000(
124 "WebRTC.Video.RenderSqrtPixelsPerSecond", 134 "WebRTC.Video.RenderSqrtPixelsPerSecond",
125 round(render_pixel_tracker_.ComputeTotalRate())); 135 round(render_pixel_tracker_.ComputeTotalRate()));
126 } 136 }
137
138 // Slice on content type and simulcast id.
139 for (auto it : content_specific_stats_) {
sprang_webrtc 2017/08/28 07:58:30 I think it would be good with a comment outlining
ilnik 2017/08/28 14:54:34 Should be more clear now.
140 auto content_type = it.first;
141 if (content_type.GetExperimentId() == 0 &&
142 content_type.GetSimulcastId() == 0) {
143 // Name of a metric sliced on simulcast is the same as sliced on
144 // experiment because no slice information is available in both cases.
145 // Don't report the metric here to not duplicate the metric.
146 continue;
147 }
148 auto stats = it.second;
149 std::string uma_prefix = UmaPrefixForContentType(content_type);
150 std::string uma_suffix = UmaSpatialSuffixForContentType(content_type);
sprang_webrtc 2017/08/28 07:58:30 Will this work? If we slice on experiment and spat
ilnik 2017/08/28 14:54:34 Done.
151 // The same line of code can't report different histograms because of how
152 // macro is done. Additional index needed to be different for all different
153 // names. Since experiment can't change during call, we could report 4*2
sprang_webrtc 2017/08/28 07:58:30 Experiments can change during a call....
ilnik 2017/08/28 14:54:34 Done.
154 // different content types (4 simulcast_ids x 2 content types).
155 // Conveniently all of these are stored in 3 lower bits in VideoContentType.
156 int idx = content_type.content_type & 0x07;
sprang_webrtc 2017/08/28 07:58:30 This is starting to get cluttered. Could we move t
ilnik 2017/08/28 14:54:34 Reporting below is removed (except for 3 already e
157 int e2e_delay_ms = stats.e2e_delay_counter.Avg(kMinRequiredSamples);
158 if (e2e_delay_ms != -1) {
159 RTC_HISTOGRAMS_COUNTS_10000(
160 idx, uma_prefix + ".EndToEndDelayInMs" + uma_suffix, e2e_delay_ms);
161 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayInMs" << uma_suffix << " "
162 << e2e_delay_ms;
163 }
164 int e2e_delay_max_ms = stats.e2e_delay_counter.Max();
165 if (e2e_delay_max_ms != -1 && e2e_delay_ms != -1) {
166 RTC_HISTOGRAMS_COUNTS_100000(
167 idx, uma_prefix + ".EndToEndDelayMaxInMs" + uma_suffix,
168 e2e_delay_max_ms);
169 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayMaxInMs" << uma_suffix << " "
170 << e2e_delay_max_ms;
171 }
172 int interframe_delay_ms =
173 stats.interframe_delay_counter.Avg(kMinRequiredSamples);
174 if (interframe_delay_ms != -1) {
175 RTC_HISTOGRAMS_COUNTS_10000(
176 idx, uma_prefix + ".InterframeDelayInMs" + uma_suffix,
177 interframe_delay_ms);
178 LOG(LS_INFO) << uma_prefix << ".InterframeDelayInMs" << uma_suffix << " "
179 << interframe_delay_ms;
180 }
181 int interframe_delay_max_ms = stats.interframe_delay_counter.Max();
182 if (interframe_delay_max_ms != -1 && interframe_delay_ms != -1) {
183 RTC_HISTOGRAMS_COUNTS_10000(
184 idx, uma_prefix + ".InterframeDelayMaxInMs" + uma_suffix,
185 interframe_delay_max_ms);
186 LOG(LS_INFO) << uma_prefix << ".InterframeDelayMaxInMs" << uma_suffix
187 << " " << interframe_delay_max_ms;
188 }
189
190 float flow_duration_sec = stats.flow_duration_ms / 1000.0;
191 if (flow_duration_sec >= metrics::kMinRunTimeInSeconds) {
192 int media_bitrate_kbps = static_cast<int>(stats.total_media_bytes * 8 /
193 flow_duration_sec / 1000);
194 RTC_HISTOGRAM_COUNTS_10000(
195 uma_prefix + ".MediaBitrateReceivedInKbps" + uma_suffix,
196 media_bitrate_kbps);
197 LOG(LS_INFO) << uma_prefix << ".MediaBitrateReceivedInKbps" << uma_suffix
198 << " " << media_bitrate_kbps;
199 }
200
201 int qp = stats.qp_counter.Avg(kMinRequiredSamples);
202 if (qp != -1) {
203 RTC_HISTOGRAMS_COUNTS_200(
204 idx, uma_prefix + ".Decoded.Vp8.Qp" + uma_suffix, qp);
205 LOG(LS_INFO) << uma_prefix << ".Decoded.Vp8.Qp" << uma_suffix << " "
206 << qp;
207 }
208
209 int width = stats.received_width.Avg(kMinRequiredSamples);
210 if (width != -1) {
211 RTC_HISTOGRAMS_COUNTS_10000(
212 idx, uma_prefix + ".ReceivedWidthInPixels" + uma_suffix, width);
213 LOG(LS_INFO) << uma_prefix << ".ReceivedWidthInPixels" << uma_suffix
214 << " " << width;
215 }
216
217 int height = stats.received_height.Avg(kMinRequiredSamples);
218 if (height != -1) {
219 RTC_HISTOGRAMS_COUNTS_10000(
220 idx, uma_prefix + ".ReceivedHeightInPixels" + uma_suffix, height);
221 LOG(LS_INFO) << uma_prefix << ".ReceivedHeightInPixels" << uma_suffix
222 << " " << height;
223 }
224 }
225
226 // Metrics sliced on experiment are not sliced on screenshare/realtime video.
227 std::string uma_prefix = UmaPrefixForContentType(
228 VideoContentType::UNSPECIFIED);
229 std::string uma_experiment_suffix =
230 UmaExperimentSuffixForConentType(last_content_type_);
231 int idx = last_content_type_.GetExperimentId();
232
233 if (first_report_block_time_ms_ != -1 &&
234 ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >=
235 metrics::kMinRunTimeInSeconds) {
236 int fraction_lost = report_block_stats_.FractionLostInPercent();
237 if (fraction_lost != -1) {
238 RTC_HISTOGRAMS_PERCENTAGE(
239 idx,
240 uma_prefix + ".ReceivedPacketsLostInPercent" + uma_experiment_suffix,
241 fraction_lost);
242 LOG(LS_INFO) << uma_prefix << ".ReceivedPacketsLostInPercent"
243 << uma_experiment_suffix << " " << fraction_lost;
244 }
245 }
246
247 int stream_duration_sec = (clock_->TimeInMilliseconds() - start_ms_) / 1000;
248 RTC_HISTOGRAMS_COUNTS_100000(
249 idx,
250 uma_prefix + ".ReceiveStreamLifetimeInSeconds" + uma_experiment_suffix,
251 stream_duration_sec);
252 LOG(LS_INFO) << uma_prefix << ".ReceiveStreamLifetimeInSeconds"
253 << uma_experiment_suffix << " " << stream_duration_sec;
254
255 int e2e_delay_ms = e2e_delay_counter.Avg(kMinRequiredSamples);
256 if (e2e_delay_ms != -1) {
257 RTC_HISTOGRAMS_COUNTS_10000(
258 idx, uma_prefix + ".EndToEndDelayInMs" + uma_experiment_suffix,
259 e2e_delay_ms);
260 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayInMs" << uma_experiment_suffix
261 << " " << e2e_delay_ms;
262 }
263 int e2e_delay_max_ms = e2e_delay_counter.Max();
264 if (e2e_delay_max_ms != -1 && e2e_delay_ms != -1) {
265 RTC_HISTOGRAMS_COUNTS_100000(
266 idx, uma_prefix + ".EndToEndDelayMaxInMs" + uma_experiment_suffix,
267 e2e_delay_max_ms);
268 LOG(LS_INFO) << uma_prefix << ".EndToEndDelayMaxInMs"
269 << uma_experiment_suffix << " " << e2e_delay_max_ms;
270 }
271 int interframe_delay_ms = interframe_delay_counter.Avg(kMinRequiredSamples);
272 if (interframe_delay_ms != -1) {
273 RTC_HISTOGRAMS_COUNTS_10000(
274 idx, uma_prefix + ".InterframeDelayInMs" + uma_experiment_suffix,
275 interframe_delay_ms);
276 LOG(LS_INFO) << uma_prefix << ".InterframeDelayInMs"
277 << uma_experiment_suffix << " " << interframe_delay_ms;
278 }
279 int interframe_delay_max_ms = interframe_delay_counter.Max();
280 if (interframe_delay_max_ms != -1 && interframe_delay_ms != -1) {
281 RTC_HISTOGRAMS_COUNTS_10000(
282 idx, uma_prefix + ".InterframeDelayMaxInMs" + uma_experiment_suffix,
283 interframe_delay_max_ms);
284 LOG(LS_INFO) << uma_prefix << ".InterframeDelayMaxInMs"
285 << uma_experiment_suffix << " " << interframe_delay_max_ms;
286 }
287
127 int width = render_width_counter_.Avg(kMinRequiredSamples); 288 int width = render_width_counter_.Avg(kMinRequiredSamples);
128 int height = render_height_counter_.Avg(kMinRequiredSamples); 289 int height = render_height_counter_.Avg(kMinRequiredSamples);
129 if (width != -1) { 290 if (width != -1) {
130 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedWidthInPixels", width); 291 RTC_HISTOGRAMS_COUNTS_10000(
131 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedHeightInPixels", height); 292 idx, uma_prefix + ".ReceivedWidthInPixels" + uma_experiment_suffix,
132 LOG(LS_INFO) << "WebRTC.Video.ReceivedWidthInPixels " << width; 293 width);
133 LOG(LS_INFO) << "WebRTC.Video.ReceivedHeightInPixels " << height; 294 RTC_HISTOGRAMS_COUNTS_10000(
295 idx, uma_prefix + ".ReceivedHeightInPixels" + uma_experiment_suffix,
296 height);
297 LOG(LS_INFO) << uma_prefix << ".ReceivedWidthInPixels"
298 << uma_experiment_suffix << " " << width;
299 LOG(LS_INFO) << uma_prefix << ".ReceivedHeightInPixels"
300 << uma_experiment_suffix << " " << height;
134 } 301 }
135 int sync_offset_ms = sync_offset_counter_.Avg(kMinRequiredSamples); 302 int sync_offset_ms = sync_offset_counter_.Avg(kMinRequiredSamples);
136 if (sync_offset_ms != -1) { 303 if (sync_offset_ms != -1) {
137 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs", sync_offset_ms); 304 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs", sync_offset_ms);
138 LOG(LS_INFO) << "WebRTC.Video.AVSyncOffsetInMs " << sync_offset_ms; 305 LOG(LS_INFO) << "WebRTC.Video.AVSyncOffsetInMs " << sync_offset_ms;
139 } 306 }
140 AggregatedStats freq_offset_stats = freq_offset_counter_.GetStats(); 307 AggregatedStats freq_offset_stats = freq_offset_counter_.GetStats();
141 if (freq_offset_stats.num_samples > 0) { 308 if (freq_offset_stats.num_samples > 0) {
142 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 309 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtpToNtpFreqOffsetInKhz",
143 freq_offset_stats.average); 310 freq_offset_stats.average);
144 LOG(LS_INFO) << "WebRTC.Video.RtpToNtpFreqOffsetInKhz, " 311 LOG(LS_INFO) << "WebRTC.Video.RtpToNtpFreqOffsetInKhz, "
145 << freq_offset_stats.ToString(); 312 << freq_offset_stats.ToString();
146 } 313 }
147 314
148 int num_total_frames = 315 int num_total_frames =
149 stats_.frame_counts.key_frames + stats_.frame_counts.delta_frames; 316 stats_.frame_counts.key_frames + stats_.frame_counts.delta_frames;
150 if (num_total_frames >= kMinRequiredSamples) { 317 if (num_total_frames >= kMinRequiredSamples) {
151 int num_key_frames = stats_.frame_counts.key_frames; 318 int num_key_frames = stats_.frame_counts.key_frames;
152 int key_frames_permille = 319 int key_frames_permille =
153 (num_key_frames * 1000 + num_total_frames / 2) / num_total_frames; 320 (num_key_frames * 1000 + num_total_frames / 2) / num_total_frames;
154 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille", 321 RTC_HISTOGRAMS_COUNTS_1000(
155 key_frames_permille); 322 idx,
156 LOG(LS_INFO) << "WebRTC.Video.KeyFramesReceivedInPermille " 323 uma_prefix + ".KeyFramesReceivedInPermille" + uma_experiment_suffix,
157 << key_frames_permille; 324 key_frames_permille);
325 LOG(LS_INFO) << uma_prefix << ".KeyFramesReceivedInPermille"
326 << uma_experiment_suffix << " " << key_frames_permille;
158 } 327 }
159 328
160 int qp = qp_counters_.vp8.Avg(kMinRequiredSamples); 329 int qp = qp_counters_.vp8.Avg(kMinRequiredSamples);
161 if (qp != -1) { 330 if (qp != -1) {
162 RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp); 331 RTC_HISTOGRAMS_COUNTS_200(
163 LOG(LS_INFO) << "WebRTC.Video.Decoded.Vp8.Qp " << qp; 332 idx, uma_prefix + ".Decoded.Vp8.Qp" + uma_experiment_suffix, qp);
333 LOG(LS_INFO) << uma_prefix << ".Decoded.Vp8.Qp" << uma_experiment_suffix
334 << " " << qp;
164 } 335 }
165 int decode_ms = decode_time_counter_.Avg(kMinRequiredSamples); 336 int decode_ms = decode_time_counter_.Avg(kMinRequiredSamples);
166 if (decode_ms != -1) { 337 if (decode_ms != -1) {
167 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms); 338 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms);
168 LOG(LS_INFO) << "WebRTC.Video.DecodeTimeInMs " << decode_ms; 339 LOG(LS_INFO) << "WebRTC.Video.DecodeTimeInMs " << decode_ms;
169 } 340 }
170 int jb_delay_ms = jitter_buffer_delay_counter_.Avg(kMinRequiredSamples); 341 int jb_delay_ms = jitter_buffer_delay_counter_.Avg(kMinRequiredSamples);
171 if (jb_delay_ms != -1) { 342 if (jb_delay_ms != -1) {
172 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs", 343 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs",
173 jb_delay_ms); 344 jb_delay_ms);
174 LOG(LS_INFO) << "WebRTC.Video.JitterBufferDelayInMs " << jb_delay_ms; 345 LOG(LS_INFO) << "WebRTC.Video.JitterBufferDelayInMs " << jb_delay_ms;
175 } 346 }
176 347
177 int target_delay_ms = target_delay_counter_.Avg(kMinRequiredSamples); 348 int target_delay_ms = target_delay_counter_.Avg(kMinRequiredSamples);
178 if (target_delay_ms != -1) { 349 if (target_delay_ms != -1) {
179 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms); 350 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms);
180 LOG(LS_INFO) << "WebRTC.Video.TargetDelayInMs " << target_delay_ms; 351 LOG(LS_INFO) << "WebRTC.Video.TargetDelayInMs " << target_delay_ms;
181 } 352 }
182 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples); 353 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples);
183 if (current_delay_ms != -1) { 354 if (current_delay_ms != -1) {
184 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", 355 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs",
185 current_delay_ms); 356 current_delay_ms);
186 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms; 357 LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms;
187 } 358 }
188 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); 359 int delay_ms = delay_counter_.Avg(kMinRequiredSamples);
189 if (delay_ms != -1) 360 if (delay_ms != -1)
190 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms); 361 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms);
191 362
192 int e2e_delay_ms_video = e2e_delay_counter_video_.Avg(kMinRequiredSamples);
193 if (e2e_delay_ms_video != -1) {
194 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.EndToEndDelayInMs",
195 e2e_delay_ms_video);
196 LOG(LS_INFO) << "WebRTC.Video.EndToEndDelayInMs " << e2e_delay_ms_video;
197 }
198
199 int e2e_delay_ms_screenshare =
200 e2e_delay_counter_screenshare_.Avg(kMinRequiredSamples);
201 if (e2e_delay_ms_screenshare != -1) {
202 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.EndToEndDelayInMs",
203 e2e_delay_ms_screenshare);
204 }
205
206 int e2e_delay_max_ms_video = e2e_delay_max_ms_video_;
207 if (e2e_delay_max_ms_video != -1) {
208 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.EndToEndDelayMaxInMs",
209 e2e_delay_max_ms_video);
210 }
211
212 int e2e_delay_max_ms_screenshare = e2e_delay_max_ms_screenshare_;
213 if (e2e_delay_max_ms_screenshare != -1) {
214 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.Screenshare.EndToEndDelayMaxInMs",
215 e2e_delay_max_ms_screenshare);
216 }
217
218 int interframe_delay_ms_screenshare =
219 interframe_delay_counter_screenshare_.Avg(kMinRequiredSamples);
220 if (interframe_delay_ms_screenshare != -1) {
221 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.InterframeDelayInMs",
222 interframe_delay_ms_screenshare);
223 RTC_DCHECK_GE(interframe_delay_max_ms_screenshare_,
224 interframe_delay_ms_screenshare);
225 RTC_HISTOGRAM_COUNTS_10000(
226 "WebRTC.Video.Screenshare.InterframeDelayMaxInMs",
227 interframe_delay_max_ms_screenshare_);
228 }
229
230 int interframe_delay_ms_video =
231 interframe_delay_counter_video_.Avg(kMinRequiredSamples);
232 if (interframe_delay_ms_video != -1) {
233 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InterframeDelayInMs",
234 interframe_delay_ms_video);
235 RTC_DCHECK_GE(interframe_delay_max_ms_video_, interframe_delay_ms_video);
236 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InterframeDelayMaxInMs",
237 interframe_delay_max_ms_video_);
238 }
239
240 StreamDataCounters rtp = stats_.rtp_stats; 363 StreamDataCounters rtp = stats_.rtp_stats;
241 StreamDataCounters rtx; 364 StreamDataCounters rtx;
242 for (auto it : rtx_stats_) 365 for (auto it : rtx_stats_)
243 rtx.Add(it.second); 366 rtx.Add(it.second);
244 StreamDataCounters rtp_rtx = rtp; 367 StreamDataCounters rtp_rtx = rtp;
245 rtp_rtx.Add(rtx); 368 rtp_rtx.Add(rtx);
246 int64_t elapsed_sec = 369 int64_t elapsed_sec =
247 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000; 370 rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000;
248 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { 371 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
249 RTC_HISTOGRAM_COUNTS_10000( 372 RTC_HISTOGRAM_COUNTS_10000(
250 "WebRTC.Video.BitrateReceivedInKbps", 373 "WebRTC.Video.BitrateReceivedInKbps",
251 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 374 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
252 1000)); 375 1000));
253 RTC_HISTOGRAM_COUNTS_10000( 376 int media_bitrate_kbs =
254 "WebRTC.Video.MediaBitrateReceivedInKbps", 377 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000);
255 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); 378 RTC_HISTOGRAMS_COUNTS_10000(
379 idx, uma_prefix + ".MediaBitrateReceivedInKbps" + uma_experiment_suffix,
380 media_bitrate_kbs);
381 LOG(LS_INFO) << uma_prefix << ".MediaBitrateReceivedInKbps"
382 << uma_experiment_suffix << " " << media_bitrate_kbs;
256 RTC_HISTOGRAM_COUNTS_10000( 383 RTC_HISTOGRAM_COUNTS_10000(
257 "WebRTC.Video.PaddingBitrateReceivedInKbps", 384 "WebRTC.Video.PaddingBitrateReceivedInKbps",
258 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / 385 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec /
259 1000)); 386 1000));
260 RTC_HISTOGRAM_COUNTS_10000( 387 RTC_HISTOGRAM_COUNTS_10000(
261 "WebRTC.Video.RetransmittedBitrateReceivedInKbps", 388 "WebRTC.Video.RetransmittedBitrateReceivedInKbps",
262 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec / 389 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec /
263 1000)); 390 1000));
264 if (!rtx_stats_.empty()) { 391 if (!rtx_stats_.empty()) {
265 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtxBitrateReceivedInKbps", 392 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtxBitrateReceivedInKbps",
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 } 649 }
523 if (total_bytes > last_total_bytes) 650 if (total_bytes > last_total_bytes)
524 total_byte_tracker_.AddSamples(total_bytes - last_total_bytes); 651 total_byte_tracker_.AddSamples(total_bytes - last_total_bytes);
525 } 652 }
526 653
527 void ReceiveStatisticsProxy::OnDecodedFrame(rtc::Optional<uint8_t> qp, 654 void ReceiveStatisticsProxy::OnDecodedFrame(rtc::Optional<uint8_t> qp,
528 VideoContentType content_type) { 655 VideoContentType content_type) {
529 uint64_t now = clock_->TimeInMilliseconds(); 656 uint64_t now = clock_->TimeInMilliseconds();
530 657
531 rtc::CritScope lock(&crit_); 658 rtc::CritScope lock(&crit_);
659
660 ContentSpecificStats* content_specific_stats =
661 &content_specific_stats_[content_type];
532 ++stats_.frames_decoded; 662 ++stats_.frames_decoded;
533 if (qp) { 663 if (qp) {
534 if (!stats_.qp_sum) { 664 if (!stats_.qp_sum) {
535 if (stats_.frames_decoded != 1) { 665 if (stats_.frames_decoded != 1) {
536 LOG(LS_WARNING) 666 LOG(LS_WARNING)
537 << "Frames decoded was not 1 when first qp value was received."; 667 << "Frames decoded was not 1 when first qp value was received.";
538 stats_.frames_decoded = 1; 668 stats_.frames_decoded = 1;
539 } 669 }
540 stats_.qp_sum = rtc::Optional<uint64_t>(0); 670 stats_.qp_sum = rtc::Optional<uint64_t>(0);
541 } 671 }
542 *stats_.qp_sum += *qp; 672 *stats_.qp_sum += *qp;
673 content_specific_stats->qp_counter.Add(*qp);
543 } else if (stats_.qp_sum) { 674 } else if (stats_.qp_sum) {
544 LOG(LS_WARNING) 675 LOG(LS_WARNING)
545 << "QP sum was already set and no QP was given for a frame."; 676 << "QP sum was already set and no QP was given for a frame.";
546 stats_.qp_sum = rtc::Optional<uint64_t>(); 677 stats_.qp_sum = rtc::Optional<uint64_t>();
547 } 678 }
548 last_content_type_ = content_type; 679 last_content_type_ = content_type;
549 decode_fps_estimator_.Update(1, now); 680 decode_fps_estimator_.Update(1, now);
550 if (last_decoded_frame_time_ms_) { 681 if (last_decoded_frame_time_ms_) {
551 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_; 682 int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_;
552 RTC_DCHECK_GE(interframe_delay_ms, 0); 683 RTC_DCHECK_GE(interframe_delay_ms, 0);
553 interframe_delay_max_moving_.Add(interframe_delay_ms, now); 684 interframe_delay_max_moving_.Add(interframe_delay_ms, now);
554 if (last_content_type_ == VideoContentType::SCREENSHARE) { 685 content_specific_stats->interframe_delay_counter.Add(interframe_delay_ms);
555 interframe_delay_counter_screenshare_.Add(interframe_delay_ms); 686 content_specific_stats->flow_duration_ms += interframe_delay_ms;
556 if (interframe_delay_max_ms_screenshare_ < interframe_delay_ms) { 687 interframe_delay_counter.Add(interframe_delay_ms);
557 interframe_delay_max_ms_screenshare_ = interframe_delay_ms;
558 }
559 } else {
560 interframe_delay_counter_video_.Add(interframe_delay_ms);
561 if (interframe_delay_max_ms_video_ < interframe_delay_ms) {
562 interframe_delay_max_ms_video_ = interframe_delay_ms;
563 }
564 }
565 } 688 }
566 last_decoded_frame_time_ms_.emplace(now); 689 last_decoded_frame_time_ms_.emplace(now);
567 } 690 }
568 691
569 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) { 692 void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) {
570 int width = frame.width(); 693 int width = frame.width();
571 int height = frame.height(); 694 int height = frame.height();
572 RTC_DCHECK_GT(width, 0); 695 RTC_DCHECK_GT(width, 0);
573 RTC_DCHECK_GT(height, 0); 696 RTC_DCHECK_GT(height, 0);
574 uint64_t now = clock_->TimeInMilliseconds(); 697 uint64_t now = clock_->TimeInMilliseconds();
575
576 rtc::CritScope lock(&crit_); 698 rtc::CritScope lock(&crit_);
699 ContentSpecificStats* content_specific_stats =
700 &content_specific_stats_[last_content_type_];
577 renders_fps_estimator_.Update(1, now); 701 renders_fps_estimator_.Update(1, now);
578 ++stats_.frames_rendered; 702 ++stats_.frames_rendered;
579 stats_.width = width; 703 stats_.width = width;
580 stats_.height = height; 704 stats_.height = height;
581 render_width_counter_.Add(width); 705 render_width_counter_.Add(width);
582 render_height_counter_.Add(height); 706 render_height_counter_.Add(height);
583 render_fps_tracker_.AddSamples(1); 707 render_fps_tracker_.AddSamples(1);
584 render_pixel_tracker_.AddSamples(sqrt(width * height)); 708 render_pixel_tracker_.AddSamples(sqrt(width * height));
709 content_specific_stats->received_width.Add(width);
710 content_specific_stats->received_height.Add(height);
585 711
586 if (frame.ntp_time_ms() > 0) { 712 if (frame.ntp_time_ms() > 0) {
587 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms(); 713 int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms();
588 if (delay_ms >= 0) { 714 if (delay_ms >= 0) {
589 if (last_content_type_ == VideoContentType::SCREENSHARE) { 715 content_specific_stats->e2e_delay_counter.Add(delay_ms);
590 e2e_delay_max_ms_screenshare_ = 716 e2e_delay_counter.Add(delay_ms);
591 std::max(delay_ms, e2e_delay_max_ms_screenshare_);
592 e2e_delay_counter_screenshare_.Add(delay_ms);
593 } else {
594 e2e_delay_max_ms_video_ = std::max(delay_ms, e2e_delay_max_ms_video_);
595 e2e_delay_counter_video_.Add(delay_ms);
596 }
597 } 717 }
598 } 718 }
599 } 719 }
600 720
601 void ReceiveStatisticsProxy::OnSyncOffsetUpdated(int64_t sync_offset_ms, 721 void ReceiveStatisticsProxy::OnSyncOffsetUpdated(int64_t sync_offset_ms,
602 double estimated_freq_khz) { 722 double estimated_freq_khz) {
603 rtc::CritScope lock(&crit_); 723 rtc::CritScope lock(&crit_);
604 sync_offset_counter_.Add(std::abs(sync_offset_ms)); 724 sync_offset_counter_.Add(std::abs(sync_offset_ms));
605 stats_.sync_offset_ms = sync_offset_ms; 725 stats_.sync_offset_ms = sync_offset_ms;
606 726
(...skipping 11 matching lines...) Expand all
618 } 738 }
619 739
620 void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe, 740 void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe,
621 size_t size_bytes) { 741 size_t size_bytes) {
622 rtc::CritScope lock(&crit_); 742 rtc::CritScope lock(&crit_);
623 if (is_keyframe) 743 if (is_keyframe)
624 ++stats_.frame_counts.key_frames; 744 ++stats_.frame_counts.key_frames;
625 else 745 else
626 ++stats_.frame_counts.delta_frames; 746 ++stats_.frame_counts.delta_frames;
627 747
748 // Todo(ilnik): May be incorrect for the first frame of a new content type
749 // stream. Leads to a bit incorrect |total_media_bytes| count.
750 ContentSpecificStats* content_specific_stats =
751 &content_specific_stats_[last_content_type_];
752
753 content_specific_stats->total_media_bytes += size_bytes;
754
628 int64_t now_ms = clock_->TimeInMilliseconds(); 755 int64_t now_ms = clock_->TimeInMilliseconds();
629 frame_window_.insert(std::make_pair(now_ms, size_bytes)); 756 frame_window_.insert(std::make_pair(now_ms, size_bytes));
630 UpdateFramerate(now_ms); 757 UpdateFramerate(now_ms);
631 } 758 }
632 759
633 void ReceiveStatisticsProxy::OnFrameCountsUpdated( 760 void ReceiveStatisticsProxy::OnFrameCountsUpdated(
634 const FrameCounts& frame_counts) { 761 const FrameCounts& frame_counts) {
635 rtc::CritScope lock(&crit_); 762 rtc::CritScope lock(&crit_);
636 stats_.frame_counts = frame_counts; 763 stats_.frame_counts = frame_counts;
637 } 764 }
(...skipping 20 matching lines...) Expand all
658 // TODO(sprang): Figure out any other state that should be reset. 785 // TODO(sprang): Figure out any other state that should be reset.
659 786
660 rtc::CritScope lock(&crit_); 787 rtc::CritScope lock(&crit_);
661 // Don't report inter-frame delay if stream was paused. 788 // Don't report inter-frame delay if stream was paused.
662 last_decoded_frame_time_ms_.reset(); 789 last_decoded_frame_time_ms_.reset();
663 } 790 }
664 791
665 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { 792 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) {
666 sum += sample; 793 sum += sample;
667 ++num_samples; 794 ++num_samples;
795 if (!max || *max < sample) {
796 max.emplace(sample);
797 }
668 } 798 }
669 799
670 int ReceiveStatisticsProxy::SampleCounter::Avg( 800 int ReceiveStatisticsProxy::SampleCounter::Avg(
671 int64_t min_required_samples) const { 801 int64_t min_required_samples) const {
672 if (num_samples < min_required_samples || num_samples == 0) 802 if (num_samples < min_required_samples || num_samples == 0)
673 return -1; 803 return -1;
674 return static_cast<int>(sum / num_samples); 804 return static_cast<int>(sum / num_samples);
675 } 805 }
676 806
807 int ReceiveStatisticsProxy::SampleCounter::Max() const {
808 if (!max) {
809 return -1;
810 } else {
811 return *max;
812 }
813 }
814
677 void ReceiveStatisticsProxy::SampleCounter::Reset() { 815 void ReceiveStatisticsProxy::SampleCounter::Reset() {
678 num_samples = 0; 816 num_samples = 0;
679 sum = 0; 817 sum = 0;
818 max.reset();
680 } 819 }
681 820
682 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms, 821 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms,
683 int64_t max_rtt_ms) { 822 int64_t max_rtt_ms) {
684 rtc::CritScope lock(&crit_); 823 rtc::CritScope lock(&crit_);
685 avg_rtt_ms_ = avg_rtt_ms; 824 avg_rtt_ms_ = avg_rtt_ms;
686 } 825 }
687 826
688 } // namespace webrtc 827 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/receive_statistics_proxy.h ('k') | webrtc/video/receive_statistics_proxy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698