Chromium Code Reviews

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

Issue 2536613002: Use RateAccCounter for sent bitrate stats. Reports average of periodically computed stats over a ca… (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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 90 matching lines...)
101 const char* prefix, 101 const char* prefix,
102 const VideoSendStream::Stats& stats, 102 const VideoSendStream::Stats& stats,
103 Clock* const clock) 103 Clock* const clock)
104 : uma_prefix_(prefix), 104 : uma_prefix_(prefix),
105 clock_(clock), 105 clock_(clock),
106 max_sent_width_per_timestamp_(0), 106 max_sent_width_per_timestamp_(0),
107 max_sent_height_per_timestamp_(0), 107 max_sent_height_per_timestamp_(0),
108 input_frame_rate_tracker_(100, 10u), 108 input_frame_rate_tracker_(100, 10u),
109 input_fps_counter_(clock, nullptr, true), 109 input_fps_counter_(clock, nullptr, true),
110 sent_fps_counter_(clock, nullptr, true), 110 sent_fps_counter_(clock, nullptr, true),
111 total_byte_counter_(clock, nullptr, true),
112 media_byte_counter_(clock, nullptr, true),
113 rtx_byte_counter_(clock, nullptr, true),
114 padding_byte_counter_(clock, nullptr, true),
115 retransmit_byte_counter_(clock, nullptr, true),
116 fec_byte_counter_(clock, nullptr, true),
111 first_rtcp_stats_time_ms_(-1), 117 first_rtcp_stats_time_ms_(-1),
112 first_rtp_stats_time_ms_(-1), 118 first_rtp_stats_time_ms_(-1),
113 start_stats_(stats) {} 119 start_stats_(stats) {
120 InitializeBitrateCounters(stats);
121 }
114 122
115 SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {} 123 SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {}
116 124
117 void AccumulateRtxStats(const VideoSendStream::Stats& stats, 125 void SendStatisticsProxy::UmaSamplesContainer::InitializeBitrateCounters(
118 const std::vector<uint32_t>& rtx_ssrcs, 126 const VideoSendStream::Stats& stats) {
119 StreamDataCounters* total_rtp_stats, 127 for (const auto& it : stats.substreams) {
120 StreamDataCounters* rtx_stats) { 128 uint32_t ssrc = it.first;
121 for (auto it : stats.substreams) { 129 total_byte_counter_.SetLast(it.second.rtp_stats.transmitted.TotalBytes(),
122 if (std::find(rtx_ssrcs.begin(), rtx_ssrcs.end(), it.first) != 130 ssrc);
123 rtx_ssrcs.end()) { 131 padding_byte_counter_.SetLast(it.second.rtp_stats.transmitted.padding_bytes,
124 rtx_stats->Add(it.second.rtp_stats); 132 ssrc);
133 retransmit_byte_counter_.SetLast(
134 it.second.rtp_stats.retransmitted.TotalBytes(), ssrc);
135 fec_byte_counter_.SetLast(it.second.rtp_stats.fec.TotalBytes(), ssrc);
136 if (it.second.is_rtx) {
137 rtx_byte_counter_.SetLast(it.second.rtp_stats.transmitted.TotalBytes(),
138 ssrc);
125 } else { 139 } else {
126 total_rtp_stats->Add(it.second.rtp_stats); 140 media_byte_counter_.SetLast(it.second.rtp_stats.MediaPayloadBytes(),
141 ssrc);
127 } 142 }
128 } 143 }
129 } 144 }
130 145
131 void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( 146 void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
132 const VideoSendStream::Config::Rtp& rtp_config, 147 const VideoSendStream::Config::Rtp& rtp_config,
133 const VideoSendStream::Stats& current_stats) { 148 const VideoSendStream::Stats& current_stats) {
134 RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix); 149 RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix);
135 const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0; 150 const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0;
136 const int kMinRequiredPeriodicSamples = 6; 151 const int kMinRequiredPeriodicSamples = 6;
(...skipping 174 matching lines...)
311 uma_prefix_ + "PliPacketsReceivedPerMinute", 326 uma_prefix_ + "PliPacketsReceivedPerMinute",
312 counters.pli_packets * 60 / elapsed_sec); 327 counters.pli_packets * 60 / elapsed_sec);
313 if (counters.nack_requests > 0) { 328 if (counters.nack_requests > 0) {
314 RTC_HISTOGRAMS_PERCENTAGE( 329 RTC_HISTOGRAMS_PERCENTAGE(
315 kIndex, uma_prefix_ + "UniqueNackRequestsReceivedInPercent", 330 kIndex, uma_prefix_ + "UniqueNackRequestsReceivedInPercent",
316 counters.UniqueNackRequestsInPercent()); 331 counters.UniqueNackRequestsInPercent());
317 } 332 }
318 } 333 }
319 } 334 }
320 335
321 if (first_rtp_stats_time_ms_ != -1) { 336 AggregatedStats total_bytes_per_sec = total_byte_counter_.GetStats();
322 int64_t elapsed_sec = 337 if (total_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
323 (clock_->TimeInMilliseconds() - first_rtp_stats_time_ms_) / 1000; 338 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "BitrateSentInKbps",
324 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { 339 total_bytes_per_sec.average * 8 / 1000);
325 StreamDataCounters rtp; 340 LOG(LS_INFO) << uma_prefix_ << "BitrateSentInBps, "
326 StreamDataCounters rtx; 341 << total_bytes_per_sec.ToStringWithMultiplier(8);
327 AccumulateRtxStats(current_stats, rtp_config.rtx.ssrcs, &rtp, &rtx); 342 }
328 StreamDataCounters start_rtp; 343 AggregatedStats media_bytes_per_sec = media_byte_counter_.GetStats();
329 StreamDataCounters start_rtx; 344 if (media_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
330 AccumulateRtxStats(start_stats_, rtp_config.rtx.ssrcs, &start_rtp, 345 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "MediaBitrateSentInKbps",
331 &start_rtx); 346 media_bytes_per_sec.average * 8 / 1000);
332 rtp.Subtract(start_rtp); 347 LOG(LS_INFO) << uma_prefix_ << "MediaBitrateSentInBps, "
333 rtx.Subtract(start_rtx); 348 << media_bytes_per_sec.ToStringWithMultiplier(8);
334 StreamDataCounters rtp_rtx = rtp; 349 }
335 rtp_rtx.Add(rtx); 350 AggregatedStats padding_bytes_per_sec = padding_byte_counter_.GetStats();
336 351 if (padding_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
337 RTC_HISTOGRAMS_COUNTS_10000( 352 RTC_HISTOGRAMS_COUNTS_10000(kIndex,
338 kIndex, uma_prefix_ + "BitrateSentInKbps", 353 uma_prefix_ + "PaddingBitrateSentInKbps",
339 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 354 padding_bytes_per_sec.average * 8 / 1000);
340 1000)); 355 LOG(LS_INFO) << uma_prefix_ << "PaddingBitrateSentInBps, "
341 RTC_HISTOGRAMS_COUNTS_10000( 356 << padding_bytes_per_sec.ToStringWithMultiplier(8);
342 kIndex, uma_prefix_ + "MediaBitrateSentInKbps", 357 }
343 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); 358 AggregatedStats retransmit_bytes_per_sec =
344 RTC_HISTOGRAMS_COUNTS_10000( 359 retransmit_byte_counter_.GetStats();
345 kIndex, uma_prefix_ + "PaddingBitrateSentInKbps", 360 if (retransmit_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
346 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / 361 RTC_HISTOGRAMS_COUNTS_10000(kIndex,
347 1000)); 362 uma_prefix_ + "RetransmittedBitrateSentInKbps",
348 RTC_HISTOGRAMS_COUNTS_10000( 363 retransmit_bytes_per_sec.average * 8 / 1000);
349 kIndex, uma_prefix_ + "RetransmittedBitrateSentInKbps", 364 LOG(LS_INFO) << uma_prefix_ << "RetransmittedBitrateSentInBps, "
350 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / 365 << retransmit_bytes_per_sec.ToStringWithMultiplier(8);
351 elapsed_sec / 1000)); 366 }
stefan-webrtc 2017/01/10 09:16:23 A lot of code duplication here. can we create a me
åsapersson 2017/01/13 13:02:57 For the histograms, the name needs to be unique pe
352 if (!rtp_config.rtx.ssrcs.empty()) { 367 if (!rtp_config.rtx.ssrcs.empty()) {
353 RTC_HISTOGRAMS_COUNTS_10000( 368 AggregatedStats rtx_bytes_per_sec = rtx_byte_counter_.GetStats();
354 kIndex, uma_prefix_ + "RtxBitrateSentInKbps", 369 int rtx_bytes_per_sec_avg = -1;
355 static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 370 if (rtx_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
356 1000)); 371 rtx_bytes_per_sec_avg = rtx_bytes_per_sec.average;
357 } 372 LOG(LS_INFO) << uma_prefix_ << "RtxBitrateSentInBps, "
358 if (rtp_config.flexfec.flexfec_payload_type != -1 || 373 << rtx_bytes_per_sec.ToStringWithMultiplier(8);
359 rtp_config.ulpfec.red_payload_type != -1) { 374 } else if (total_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
360 RTC_HISTOGRAMS_COUNTS_10000(kIndex, 375 rtx_bytes_per_sec_avg = 0;
stefan-webrtc 2017/01/10 09:16:23 Please comment on why we do this. It's not clear w
åsapersson 2017/01/13 13:02:57 Added a comment.
361 uma_prefix_ + "FecBitrateSentInKbps", 376 }
362 static_cast<int>(rtp_rtx.fec.TotalBytes() * 377 if (rtx_bytes_per_sec_avg != -1) {
363 8 / elapsed_sec / 1000)); 378 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "RtxBitrateSentInKbps",
364 } 379 rtx_bytes_per_sec_avg * 8 / 1000);
380 }
381 }
382 if (rtp_config.flexfec.flexfec_payload_type != -1 ||
383 rtp_config.ulpfec.red_payload_type != -1) {
384 AggregatedStats fec_bytes_per_sec = fec_byte_counter_.GetStats();
385 if (fec_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
386 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "FecBitrateSentInKbps",
387 fec_bytes_per_sec.average * 8 / 1000);
388 LOG(LS_INFO) << uma_prefix_ << "FecBitrateSentInBps, "
389 << fec_bytes_per_sec.ToStringWithMultiplier(8);
365 } 390 }
366 } 391 }
367 } 392 }
368 393
369 void SendStatisticsProxy::OnEncoderReconfigured( 394 void SendStatisticsProxy::OnEncoderReconfigured(
370 const VideoEncoderConfig& config, 395 const VideoEncoderConfig& config,
371 uint32_t preferred_bitrate_bps) { 396 uint32_t preferred_bitrate_bps) {
372 rtc::CritScope lock(&crit_); 397 rtc::CritScope lock(&crit_);
373 stats_.preferred_media_bitrate_bps = preferred_bitrate_bps; 398 stats_.preferred_media_bitrate_bps = preferred_bitrate_bps;
374 399
(...skipping 18 matching lines...)
393 rtc::CritScope lock(&crit_); 418 rtc::CritScope lock(&crit_);
394 uma_container_->encode_time_counter_.Add(encode_time_ms); 419 uma_container_->encode_time_counter_.Add(encode_time_ms);
395 encode_time_.Apply(1.0f, encode_time_ms); 420 encode_time_.Apply(1.0f, encode_time_ms);
396 stats_.avg_encode_time_ms = round(encode_time_.filtered()); 421 stats_.avg_encode_time_ms = round(encode_time_.filtered());
397 stats_.encode_usage_percent = metrics.encode_usage_percent; 422 stats_.encode_usage_percent = metrics.encode_usage_percent;
398 } 423 }
399 424
400 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) { 425 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
401 rtc::CritScope lock(&crit_); 426 rtc::CritScope lock(&crit_);
402 stats_.suspended = is_suspended; 427 stats_.suspended = is_suspended;
403 // Pause framerate stats.
404 if (is_suspended) { 428 if (is_suspended) {
405 uma_container_->input_fps_counter_.ProcessAndPause(); 429 // Pause framerate (add min pause time since there may be frames/packets
406 uma_container_->sent_fps_counter_.ProcessAndPause(); 430 // that are not yet sent).
431 const int64_t kMinMs = 500;
432 uma_container_->input_fps_counter_.ProcessAndPauseWithMin(kMinMs);
433 uma_container_->sent_fps_counter_.ProcessAndPauseWithMin(kMinMs);
434 // Pause bitrate stats.
435 uma_container_->total_byte_counter_.ProcessAndPauseWithMin(kMinMs);
436 uma_container_->media_byte_counter_.ProcessAndPauseWithMin(kMinMs);
437 uma_container_->rtx_byte_counter_.ProcessAndPauseWithMin(kMinMs);
438 uma_container_->padding_byte_counter_.ProcessAndPauseWithMin(kMinMs);
439 uma_container_->retransmit_byte_counter_.ProcessAndPauseWithMin(kMinMs);
440 uma_container_->fec_byte_counter_.ProcessAndPauseWithMin(kMinMs);
441 } else {
442 // Stop pause explicitly for stats that may be zero/not updated for some
443 // time.
444 uma_container_->rtx_byte_counter_.ProcessAndStopPause();
445 uma_container_->padding_byte_counter_.ProcessAndStopPause();
446 uma_container_->retransmit_byte_counter_.ProcessAndStopPause();
447 uma_container_->fec_byte_counter_.ProcessAndStopPause();
407 } 448 }
408 } 449 }
409 450
410 VideoSendStream::Stats SendStatisticsProxy::GetStats() { 451 VideoSendStream::Stats SendStatisticsProxy::GetStats() {
411 rtc::CritScope lock(&crit_); 452 rtc::CritScope lock(&crit_);
412 PurgeOldStats(); 453 PurgeOldStats();
413 stats_.input_frame_rate = 454 stats_.input_frame_rate =
414 round(uma_container_->input_frame_rate_tracker_.ComputeRate()); 455 round(uma_container_->input_frame_rate_tracker_.ComputeRate());
415 return stats_; 456 return stats_;
416 } 457 }
(...skipping 215 matching lines...)
632 uma_container_->report_block_stats_.Store(statistics, 0, ssrc); 673 uma_container_->report_block_stats_.Store(statistics, 0, ssrc);
633 } 674 }
634 675
635 void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {} 676 void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {}
636 677
637 void SendStatisticsProxy::DataCountersUpdated( 678 void SendStatisticsProxy::DataCountersUpdated(
638 const StreamDataCounters& counters, 679 const StreamDataCounters& counters,
639 uint32_t ssrc) { 680 uint32_t ssrc) {
640 rtc::CritScope lock(&crit_); 681 rtc::CritScope lock(&crit_);
641 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); 682 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
642 RTC_DCHECK(stats) << "DataCountersUpdated reported for unknown ssrc: " 683 RTC_DCHECK(stats) << "DataCountersUpdated reported for unknown ssrc " << ssrc;
643 << ssrc;
644 684
645 if (stats->is_flexfec) { 685 if (stats->is_flexfec) {
646 // The same counters are reported for both the media ssrc and flexfec ssrc. 686 // The same counters are reported for both the media ssrc and flexfec ssrc.
647 // Bitrate stats are summed for all SSRCs. Use fec stats from media update. 687 // Bitrate stats are summed for all SSRCs. Use fec stats from media update.
648 return; 688 return;
649 } 689 }
650 690
651 stats->rtp_stats = counters; 691 stats->rtp_stats = counters;
652 if (uma_container_->first_rtp_stats_time_ms_ == -1) 692 if (uma_container_->first_rtp_stats_time_ms_ == -1)
653 uma_container_->first_rtp_stats_time_ms_ = clock_->TimeInMilliseconds(); 693 uma_container_->first_rtp_stats_time_ms_ = clock_->TimeInMilliseconds();
694
695 uma_container_->total_byte_counter_.Set(counters.transmitted.TotalBytes(),
696 ssrc);
697 uma_container_->padding_byte_counter_.Set(counters.transmitted.padding_bytes,
698 ssrc);
699 uma_container_->retransmit_byte_counter_.Set(
700 counters.retransmitted.TotalBytes(), ssrc);
701 uma_container_->fec_byte_counter_.Set(counters.fec.TotalBytes(), ssrc);
702 if (stats->is_rtx) {
703 uma_container_->rtx_byte_counter_.Set(counters.transmitted.TotalBytes(),
704 ssrc);
705 } else {
706 uma_container_->media_byte_counter_.Set(counters.MediaPayloadBytes(), ssrc);
707 }
654 } 708 }
655 709
656 void SendStatisticsProxy::Notify(uint32_t total_bitrate_bps, 710 void SendStatisticsProxy::Notify(uint32_t total_bitrate_bps,
657 uint32_t retransmit_bitrate_bps, 711 uint32_t retransmit_bitrate_bps,
658 uint32_t ssrc) { 712 uint32_t ssrc) {
659 rtc::CritScope lock(&crit_); 713 rtc::CritScope lock(&crit_);
660 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); 714 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
661 if (!stats) 715 if (!stats)
662 return; 716 return;
663 717
(...skipping 52 matching lines...)
716 return Fraction(min_required_samples, 1000.0f); 770 return Fraction(min_required_samples, 1000.0f);
717 } 771 }
718 772
719 int SendStatisticsProxy::BoolSampleCounter::Fraction( 773 int SendStatisticsProxy::BoolSampleCounter::Fraction(
720 int min_required_samples, float multiplier) const { 774 int min_required_samples, float multiplier) const {
721 if (num_samples < min_required_samples || num_samples == 0) 775 if (num_samples < min_required_samples || num_samples == 0)
722 return -1; 776 return -1;
723 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); 777 return static_cast<int>((sum * multiplier / num_samples) + 0.5f);
724 } 778 }
725 } // namespace webrtc 779 } // namespace webrtc
OLDNEW

Powered by Google App Engine