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

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

Issue 1433393002: Add separate send-side UMA stats for screenshare and video. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Reset stats and update histograms on content type change Created 5 years, 1 month 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
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.Encoder.CodecType", 48 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.Encoder.CodecType",
49 PayloadNameToHistogramCodecType(payload_name), kVideoMax); 49 PayloadNameToHistogramCodecType(payload_name), kVideoMax);
50 } 50 }
51 } // namespace 51 } // namespace
52 52
53 53
54 const int SendStatisticsProxy::kStatsTimeoutMs = 5000; 54 const int SendStatisticsProxy::kStatsTimeoutMs = 5000;
55 55
56 SendStatisticsProxy::SendStatisticsProxy(Clock* clock, 56 SendStatisticsProxy::SendStatisticsProxy(Clock* clock,
57 const VideoSendStream::Config& config) 57 const VideoSendStream::Config& config)
58 : clock_(clock), 58 : clock_(clock), config_(config), codec_mode_(kRealtimeVideo) {
59 config_(config),
60 input_frame_rate_tracker_(100u, 10u),
61 sent_frame_rate_tracker_(100u, 10u),
62 last_sent_frame_timestamp_(0),
63 max_sent_width_per_timestamp_(0),
64 max_sent_height_per_timestamp_(0) {
65 UpdateCodecTypeHistogram(config_.encoder_settings.payload_name); 59 UpdateCodecTypeHistogram(config_.encoder_settings.payload_name);
66 } 60 }
67 61
68 SendStatisticsProxy::~SendStatisticsProxy() { 62 SendStatisticsProxy::~SendStatisticsProxy() {
69 UpdateHistograms(); 63 stats_set_->UpdateHistograms();
70 } 64 }
71 65
72 void SendStatisticsProxy::UpdateHistograms() { 66 void SendStatisticsProxy::StatsSet::UpdateHistograms() {
73 int input_fps = 67 int input_fps =
pbos-webrtc 2015/11/12 10:38:19 This one should probably also have kMinRequiredSam
sprang_webrtc 2015/11/12 11:01:25 Done.
74 round(input_frame_rate_tracker_.ComputeTotalRate()); 68 round(input_frame_rate_tracker_.ComputeTotalRate());
75 if (input_fps > 0) 69 if (input_fps > 0)
76 RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.InputFramesPerSecond", input_fps); 70 RTC_HISTOGRAM_COUNTS_100(kPrefix + "InputFramesPerSecond", input_fps);
77 int sent_fps = 71 int sent_fps =
78 round(sent_frame_rate_tracker_.ComputeTotalRate()); 72 round(sent_frame_rate_tracker_.ComputeTotalRate());
79 if (sent_fps > 0) 73 if (sent_fps > 0)
80 RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.SentFramesPerSecond", sent_fps); 74 RTC_HISTOGRAM_COUNTS_100(kPrefix + "SentFramesPerSecond", sent_fps);
81 75
82 const int kMinRequiredSamples = 200; 76 const int kMinRequiredSamples = 200;
83 int in_width = input_width_counter_.Avg(kMinRequiredSamples); 77 int in_width = input_width_counter_.Avg(kMinRequiredSamples);
84 int in_height = input_height_counter_.Avg(kMinRequiredSamples); 78 int in_height = input_height_counter_.Avg(kMinRequiredSamples);
85 if (in_width != -1) { 79 if (in_width != -1) {
86 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InputWidthInPixels", in_width); 80 RTC_HISTOGRAM_COUNTS_10000(kPrefix + "InputWidthInPixels", in_width);
87 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InputHeightInPixels", in_height); 81 RTC_HISTOGRAM_COUNTS_10000(kPrefix + "InputHeightInPixels", in_height);
88 } 82 }
89 int sent_width = sent_width_counter_.Avg(kMinRequiredSamples); 83 int sent_width = sent_width_counter_.Avg(kMinRequiredSamples);
90 int sent_height = sent_height_counter_.Avg(kMinRequiredSamples); 84 int sent_height = sent_height_counter_.Avg(kMinRequiredSamples);
91 if (sent_width != -1) { 85 if (sent_width != -1) {
92 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentWidthInPixels", sent_width); 86 RTC_HISTOGRAM_COUNTS_10000(kPrefix + "SentWidthInPixels", sent_width);
93 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentHeightInPixels", sent_height); 87 RTC_HISTOGRAM_COUNTS_10000(kPrefix + "SentHeightInPixels", sent_height);
94 } 88 }
95 int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples); 89 int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples);
96 if (encode_ms != -1) 90 if (encode_ms != -1)
97 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.EncodeTimeInMs", encode_ms); 91 RTC_HISTOGRAM_COUNTS_1000(kPrefix + "EncodeTimeInMs", encode_ms);
98 92
99 int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples); 93 int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples);
100 if (key_frames_permille != -1) { 94 if (key_frames_permille != -1) {
101 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesSentInPermille", 95 RTC_HISTOGRAM_COUNTS_1000(kPrefix + "KeyFramesSentInPermille",
102 key_frames_permille); 96 key_frames_permille);
103 } 97 }
104 int quality_limited = 98 int quality_limited =
105 quality_limited_frame_counter_.Percent(kMinRequiredSamples); 99 quality_limited_frame_counter_.Percent(kMinRequiredSamples);
106 if (quality_limited != -1) { 100 if (quality_limited != -1) {
107 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.QualityLimitedResolutionInPercent", 101 RTC_HISTOGRAM_PERCENTAGE(kPrefix + "QualityLimitedResolutionInPercent",
108 quality_limited); 102 quality_limited);
109 } 103 }
110 int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples); 104 int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples);
111 if (downscales != -1) { 105 if (downscales != -1) {
112 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.QualityLimitedResolutionDownscales", 106 RTC_HISTOGRAM_ENUMERATION(kPrefix + "QualityLimitedResolutionDownscales",
113 downscales, 20); 107 downscales, 20);
114 } 108 }
115 int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples); 109 int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples);
116 if (bw_limited != -1) { 110 if (bw_limited != -1) {
117 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BandwidthLimitedResolutionInPercent", 111 RTC_HISTOGRAM_PERCENTAGE(kPrefix + "BandwidthLimitedResolutionInPercent",
118 bw_limited); 112 bw_limited);
119 } 113 }
120 int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples); 114 int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples);
121 if (num_disabled != -1) { 115 if (num_disabled != -1) {
122 RTC_HISTOGRAM_ENUMERATION( 116 RTC_HISTOGRAM_ENUMERATION(kPrefix + "BandwidthLimitedResolutionsDisabled",
123 "WebRTC.Video.BandwidthLimitedResolutionsDisabled", num_disabled, 10); 117 num_disabled, 10);
124 } 118 }
125 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); 119 int delay_ms = delay_counter_.Avg(kMinRequiredSamples);
126 if (delay_ms != -1) 120 if (delay_ms != -1)
127 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.SendSideDelayInMs", delay_ms); 121 RTC_HISTOGRAM_COUNTS_100000(kPrefix + "SendSideDelayInMs", delay_ms);
128 122
129 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples); 123 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples);
130 if (max_delay_ms != -1) { 124 if (max_delay_ms != -1) {
131 RTC_HISTOGRAM_COUNTS_100000( 125 RTC_HISTOGRAM_COUNTS_100000(kPrefix + "SendSideDelayMaxInMs", max_delay_ms);
132 "WebRTC.Video.SendSideDelayMaxInMs", max_delay_ms);
133 } 126 }
134 } 127 }
135 128
136 void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) { 129 void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) {
137 rtc::CritScope lock(&crit_); 130 rtc::CritScope lock(&crit_);
138 stats_.encode_frame_rate = framerate; 131 stats_.encode_frame_rate = framerate;
139 stats_.media_bitrate_bps = bitrate; 132 stats_.media_bitrate_bps = bitrate;
140 } 133 }
141 134
142 void SendStatisticsProxy::CpuOveruseMetricsUpdated( 135 void SendStatisticsProxy::CpuOveruseMetricsUpdated(
143 const CpuOveruseMetrics& metrics) { 136 const CpuOveruseMetrics& metrics) {
144 rtc::CritScope lock(&crit_); 137 rtc::CritScope lock(&crit_);
145 // TODO(asapersson): Change to use OnEncodedFrame() for avg_encode_time_ms. 138 // TODO(asapersson): Change to use OnEncodedFrame() for avg_encode_time_ms.
146 stats_.avg_encode_time_ms = metrics.avg_encode_time_ms; 139 stats_.avg_encode_time_ms = metrics.avg_encode_time_ms;
147 stats_.encode_usage_percent = metrics.encode_usage_percent; 140 stats_.encode_usage_percent = metrics.encode_usage_percent;
148 } 141 }
149 142
150 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) { 143 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
151 rtc::CritScope lock(&crit_); 144 rtc::CritScope lock(&crit_);
152 stats_.suspended = is_suspended; 145 stats_.suspended = is_suspended;
153 } 146 }
154 147
155 VideoSendStream::Stats SendStatisticsProxy::GetStats() { 148 VideoSendStream::Stats SendStatisticsProxy::GetStats() {
156 rtc::CritScope lock(&crit_); 149 rtc::CritScope lock(&crit_);
157 PurgeOldStats(); 150 PurgeOldStats();
158 stats_.input_frame_rate = 151 stats_.input_frame_rate =
159 round(input_frame_rate_tracker_.ComputeRate()); 152 round(stats_set_->input_frame_rate_tracker_.ComputeRate());
160 return stats_; 153 return stats_;
161 } 154 }
162 155
163 void SendStatisticsProxy::PurgeOldStats() { 156 void SendStatisticsProxy::PurgeOldStats() {
164 int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs; 157 int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs;
165 for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it = 158 for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
166 stats_.substreams.begin(); 159 stats_.substreams.begin();
167 it != stats_.substreams.end(); ++it) { 160 it != stats_.substreams.end(); ++it) {
168 uint32_t ssrc = it->first; 161 uint32_t ssrc = it->first;
169 if (update_times_[ssrc].resolution_update_ms <= old_stats_ms) { 162 if (stats_set_->update_times_[ssrc].resolution_update_ms <= old_stats_ms) {
170 it->second.width = 0; 163 it->second.width = 0;
171 it->second.height = 0; 164 it->second.height = 0;
172 } 165 }
173 } 166 }
174 } 167 }
175 168
176 VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry( 169 VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
177 uint32_t ssrc) { 170 uint32_t ssrc) {
178 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it = 171 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
179 stats_.substreams.find(ssrc); 172 stats_.substreams.find(ssrc);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 213 }
221 uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx]; 214 uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
222 215
223 rtc::CritScope lock(&crit_); 216 rtc::CritScope lock(&crit_);
224 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); 217 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
225 if (stats == nullptr) 218 if (stats == nullptr)
226 return; 219 return;
227 220
228 stats->width = encoded_image._encodedWidth; 221 stats->width = encoded_image._encodedWidth;
229 stats->height = encoded_image._encodedHeight; 222 stats->height = encoded_image._encodedHeight;
230 update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds(); 223 stats_set_->update_times_[ssrc].resolution_update_ms =
224 clock_->TimeInMilliseconds();
231 225
232 key_frame_counter_.Add(encoded_image._frameType == kVideoFrameKey); 226 stats_set_->key_frame_counter_.Add(encoded_image._frameType ==
227 kVideoFrameKey);
233 228
234 if (encoded_image.adapt_reason_.quality_resolution_downscales != -1) { 229 if (encoded_image.adapt_reason_.quality_resolution_downscales != -1) {
235 bool downscaled = 230 bool downscaled =
236 encoded_image.adapt_reason_.quality_resolution_downscales > 0; 231 encoded_image.adapt_reason_.quality_resolution_downscales > 0;
237 quality_limited_frame_counter_.Add(downscaled); 232 stats_set_->quality_limited_frame_counter_.Add(downscaled);
238 if (downscaled) { 233 if (downscaled) {
239 quality_downscales_counter_.Add( 234 stats_set_->quality_downscales_counter_.Add(
240 encoded_image.adapt_reason_.quality_resolution_downscales); 235 encoded_image.adapt_reason_.quality_resolution_downscales);
241 } 236 }
242 } 237 }
243 if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) { 238 if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) {
244 bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0; 239 bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
245 bw_limited_frame_counter_.Add(bw_limited); 240 stats_set_->bw_limited_frame_counter_.Add(bw_limited);
246 if (bw_limited) { 241 if (bw_limited) {
247 bw_resolutions_disabled_counter_.Add( 242 stats_set_->bw_resolutions_disabled_counter_.Add(
248 encoded_image.adapt_reason_.bw_resolutions_disabled); 243 encoded_image.adapt_reason_.bw_resolutions_disabled);
249 } 244 }
250 } 245 }
251 246
252 // TODO(asapersson): This is incorrect if simulcast layers are encoded on 247 // TODO(asapersson): This is incorrect if simulcast layers are encoded on
253 // different threads and there is no guarantee that one frame of all layers 248 // different threads and there is no guarantee that one frame of all layers
254 // are encoded before the next start. 249 // are encoded before the next start.
255 if (last_sent_frame_timestamp_ > 0 && 250 if (stats_set_->last_sent_frame_timestamp_ > 0 &&
256 encoded_image._timeStamp != last_sent_frame_timestamp_) { 251 encoded_image._timeStamp != stats_set_->last_sent_frame_timestamp_) {
257 sent_frame_rate_tracker_.AddSamples(1); 252 stats_set_->sent_frame_rate_tracker_.AddSamples(1);
258 sent_width_counter_.Add(max_sent_width_per_timestamp_); 253 stats_set_->sent_width_counter_.Add(
259 sent_height_counter_.Add(max_sent_height_per_timestamp_); 254 stats_set_->max_sent_width_per_timestamp_);
260 max_sent_width_per_timestamp_ = 0; 255 stats_set_->sent_height_counter_.Add(
261 max_sent_height_per_timestamp_ = 0; 256 stats_set_->max_sent_height_per_timestamp_);
257 stats_set_->max_sent_width_per_timestamp_ = 0;
258 stats_set_->max_sent_height_per_timestamp_ = 0;
262 } 259 }
263 last_sent_frame_timestamp_ = encoded_image._timeStamp; 260 stats_set_->last_sent_frame_timestamp_ = encoded_image._timeStamp;
264 max_sent_width_per_timestamp_ = 261 stats_set_->max_sent_width_per_timestamp_ =
265 std::max(max_sent_width_per_timestamp_, 262 std::max(stats_set_->max_sent_width_per_timestamp_,
266 static_cast<int>(encoded_image._encodedWidth)); 263 static_cast<int>(encoded_image._encodedWidth));
267 max_sent_height_per_timestamp_ = 264 stats_set_->max_sent_height_per_timestamp_ =
268 std::max(max_sent_height_per_timestamp_, 265 std::max(stats_set_->max_sent_height_per_timestamp_,
269 static_cast<int>(encoded_image._encodedHeight)); 266 static_cast<int>(encoded_image._encodedHeight));
270 } 267 }
271 268
272 void SendStatisticsProxy::OnIncomingFrame(int width, int height) { 269 void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
273 rtc::CritScope lock(&crit_); 270 rtc::CritScope lock(&crit_);
274 input_frame_rate_tracker_.AddSamples(1); 271 stats_set_->input_frame_rate_tracker_.AddSamples(1);
275 input_width_counter_.Add(width); 272 stats_set_->input_width_counter_.Add(width);
276 input_height_counter_.Add(height); 273 stats_set_->input_height_counter_.Add(height);
277 } 274 }
278 275
279 void SendStatisticsProxy::OnEncodedFrame(int encode_time_ms) { 276 void SendStatisticsProxy::OnEncodedFrame(int encode_time_ms) {
280 rtc::CritScope lock(&crit_); 277 rtc::CritScope lock(&crit_);
281 encode_time_counter_.Add(encode_time_ms); 278 stats_set_->encode_time_counter_.Add(encode_time_ms);
282 } 279 }
283 280
284 void SendStatisticsProxy::RtcpPacketTypesCounterUpdated( 281 void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
285 uint32_t ssrc, 282 uint32_t ssrc,
286 const RtcpPacketTypeCounter& packet_counter) { 283 const RtcpPacketTypeCounter& packet_counter) {
287 rtc::CritScope lock(&crit_); 284 rtc::CritScope lock(&crit_);
288 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); 285 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
289 if (stats == nullptr) 286 if (stats == nullptr)
290 return; 287 return;
291 288
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms, 338 void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
342 int max_delay_ms, 339 int max_delay_ms,
343 uint32_t ssrc) { 340 uint32_t ssrc) {
344 rtc::CritScope lock(&crit_); 341 rtc::CritScope lock(&crit_);
345 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); 342 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
346 if (stats == nullptr) 343 if (stats == nullptr)
347 return; 344 return;
348 stats->avg_delay_ms = avg_delay_ms; 345 stats->avg_delay_ms = avg_delay_ms;
349 stats->max_delay_ms = max_delay_ms; 346 stats->max_delay_ms = max_delay_ms;
350 347
351 delay_counter_.Add(avg_delay_ms); 348 stats_set_->delay_counter_.Add(avg_delay_ms);
352 max_delay_counter_.Add(max_delay_ms); 349 stats_set_->max_delay_counter_.Add(max_delay_ms);
353 } 350 }
354 351
355 void SendStatisticsProxy::SampleCounter::Add(int sample) { 352 void SendStatisticsProxy::SampleCounter::Add(int sample) {
356 sum += sample; 353 sum += sample;
357 ++num_samples; 354 ++num_samples;
358 } 355 }
359 356
360 int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { 357 int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
361 if (num_samples < min_required_samples || num_samples == 0) 358 if (num_samples < min_required_samples || num_samples == 0)
362 return -1; 359 return -1;
(...skipping 16 matching lines...) Expand all
379 return Fraction(min_required_samples, 1000.0f); 376 return Fraction(min_required_samples, 1000.0f);
380 } 377 }
381 378
382 int SendStatisticsProxy::BoolSampleCounter::Fraction( 379 int SendStatisticsProxy::BoolSampleCounter::Fraction(
383 int min_required_samples, float multiplier) const { 380 int min_required_samples, float multiplier) const {
384 if (num_samples < min_required_samples || num_samples == 0) 381 if (num_samples < min_required_samples || num_samples == 0)
385 return -1; 382 return -1;
386 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); 383 return static_cast<int>((sum * multiplier / num_samples) + 0.5f);
387 } 384 }
388 385
386 void SendStatisticsProxy::SetCodecMode(VideoCodecMode mode) {
387 rtc::CritScope lock(&crit_);
388 if (codec_mode_ != mode) {
389 stats_set_->UpdateHistograms();
390 stats_set_.reset(new StatsSet(mode == kRealtimeVideo
391 ? "WebRTC.Video."
392 : "WebRTC.Video.Screenshare."));
393 codec_mode_ = mode;
394 }
395 }
396
389 } // namespace webrtc 397 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698