OLD | NEW |
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...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { | 339 if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { |
325 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "NumberOfPauseEvents", | 340 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "NumberOfPauseEvents", |
326 target_rate_updates_.pause_resume_events); | 341 target_rate_updates_.pause_resume_events); |
327 | 342 |
328 int paused_time_percent = | 343 int paused_time_percent = |
329 paused_time_counter_.Percent(metrics::kMinRunTimeInSeconds * 1000); | 344 paused_time_counter_.Percent(metrics::kMinRunTimeInSeconds * 1000); |
330 if (paused_time_percent != -1) { | 345 if (paused_time_percent != -1) { |
331 RTC_HISTOGRAMS_PERCENTAGE(kIndex, uma_prefix_ + "PausedTimeInPercent", | 346 RTC_HISTOGRAMS_PERCENTAGE(kIndex, uma_prefix_ + "PausedTimeInPercent", |
332 paused_time_percent); | 347 paused_time_percent); |
333 } | 348 } |
| 349 } |
| 350 } |
334 | 351 |
335 StreamDataCounters rtp; | 352 AggregatedStats total_bytes_per_sec = total_byte_counter_.GetStats(); |
336 StreamDataCounters rtx; | 353 if (total_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) { |
337 AccumulateRtxStats(current_stats, rtp_config.rtx.ssrcs, &rtp, &rtx); | 354 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "BitrateSentInKbps", |
338 StreamDataCounters start_rtp; | 355 total_bytes_per_sec.average * 8 / 1000); |
339 StreamDataCounters start_rtx; | 356 LOG(LS_INFO) << uma_prefix_ << "BitrateSentInBps, " |
340 AccumulateRtxStats(start_stats_, rtp_config.rtx.ssrcs, &start_rtp, | 357 << total_bytes_per_sec.ToStringWithMultiplier(8); |
341 &start_rtx); | 358 } |
342 rtp.Subtract(start_rtp); | 359 AggregatedStats media_bytes_per_sec = media_byte_counter_.GetStats(); |
343 rtx.Subtract(start_rtx); | 360 if (media_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) { |
344 StreamDataCounters rtp_rtx = rtp; | 361 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "MediaBitrateSentInKbps", |
345 rtp_rtx.Add(rtx); | 362 media_bytes_per_sec.average * 8 / 1000); |
346 | 363 LOG(LS_INFO) << uma_prefix_ << "MediaBitrateSentInBps, " |
347 RTC_HISTOGRAMS_COUNTS_10000( | 364 << media_bytes_per_sec.ToStringWithMultiplier(8); |
348 kIndex, uma_prefix_ + "BitrateSentInKbps", | 365 } |
349 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | 366 AggregatedStats padding_bytes_per_sec = padding_byte_counter_.GetStats(); |
350 1000)); | 367 if (padding_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) { |
351 RTC_HISTOGRAMS_COUNTS_10000( | 368 RTC_HISTOGRAMS_COUNTS_10000(kIndex, |
352 kIndex, uma_prefix_ + "MediaBitrateSentInKbps", | 369 uma_prefix_ + "PaddingBitrateSentInKbps", |
353 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); | 370 padding_bytes_per_sec.average * 8 / 1000); |
354 RTC_HISTOGRAMS_COUNTS_10000( | 371 LOG(LS_INFO) << uma_prefix_ << "PaddingBitrateSentInBps, " |
355 kIndex, uma_prefix_ + "PaddingBitrateSentInKbps", | 372 << padding_bytes_per_sec.ToStringWithMultiplier(8); |
356 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / | 373 } |
357 1000)); | 374 AggregatedStats retransmit_bytes_per_sec = |
358 RTC_HISTOGRAMS_COUNTS_10000( | 375 retransmit_byte_counter_.GetStats(); |
359 kIndex, uma_prefix_ + "RetransmittedBitrateSentInKbps", | 376 if (retransmit_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) { |
360 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / | 377 RTC_HISTOGRAMS_COUNTS_10000(kIndex, |
361 elapsed_sec / 1000)); | 378 uma_prefix_ + "RetransmittedBitrateSentInKbps", |
362 if (!rtp_config.rtx.ssrcs.empty()) { | 379 retransmit_bytes_per_sec.average * 8 / 1000); |
363 RTC_HISTOGRAMS_COUNTS_10000( | 380 LOG(LS_INFO) << uma_prefix_ << "RetransmittedBitrateSentInBps, " |
364 kIndex, uma_prefix_ + "RtxBitrateSentInKbps", | 381 << retransmit_bytes_per_sec.ToStringWithMultiplier(8); |
365 static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | 382 } |
366 1000)); | 383 if (!rtp_config.rtx.ssrcs.empty()) { |
367 } | 384 AggregatedStats rtx_bytes_per_sec = rtx_byte_counter_.GetStats(); |
368 if (rtp_config.flexfec.payload_type != -1 || | 385 int rtx_bytes_per_sec_avg = -1; |
369 rtp_config.ulpfec.red_payload_type != -1) { | 386 if (rtx_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) { |
370 RTC_HISTOGRAMS_COUNTS_10000(kIndex, | 387 rtx_bytes_per_sec_avg = rtx_bytes_per_sec.average; |
371 uma_prefix_ + "FecBitrateSentInKbps", | 388 LOG(LS_INFO) << uma_prefix_ << "RtxBitrateSentInBps, " |
372 static_cast<int>(rtp_rtx.fec.TotalBytes() * | 389 << rtx_bytes_per_sec.ToStringWithMultiplier(8); |
373 8 / elapsed_sec / 1000)); | 390 } else if (total_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) { |
374 } | 391 rtx_bytes_per_sec_avg = 0; // RTX enabled but no RTX data sent, record 0. |
| 392 } |
| 393 if (rtx_bytes_per_sec_avg != -1) { |
| 394 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "RtxBitrateSentInKbps", |
| 395 rtx_bytes_per_sec_avg * 8 / 1000); |
| 396 } |
| 397 } |
| 398 if (rtp_config.flexfec.payload_type != -1 || |
| 399 rtp_config.ulpfec.red_payload_type != -1) { |
| 400 AggregatedStats fec_bytes_per_sec = fec_byte_counter_.GetStats(); |
| 401 if (fec_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) { |
| 402 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "FecBitrateSentInKbps", |
| 403 fec_bytes_per_sec.average * 8 / 1000); |
| 404 LOG(LS_INFO) << uma_prefix_ << "FecBitrateSentInBps, " |
| 405 << fec_bytes_per_sec.ToStringWithMultiplier(8); |
375 } | 406 } |
376 } | 407 } |
377 } | 408 } |
378 | 409 |
379 void SendStatisticsProxy::OnEncoderReconfigured( | 410 void SendStatisticsProxy::OnEncoderReconfigured( |
380 const VideoEncoderConfig& config, | 411 const VideoEncoderConfig& config, |
381 uint32_t preferred_bitrate_bps) { | 412 uint32_t preferred_bitrate_bps) { |
382 rtc::CritScope lock(&crit_); | 413 rtc::CritScope lock(&crit_); |
383 stats_.preferred_media_bitrate_bps = preferred_bitrate_bps; | 414 stats_.preferred_media_bitrate_bps = preferred_bitrate_bps; |
384 | 415 |
(...skipping 18 matching lines...) Expand all Loading... |
403 rtc::CritScope lock(&crit_); | 434 rtc::CritScope lock(&crit_); |
404 uma_container_->encode_time_counter_.Add(encode_time_ms); | 435 uma_container_->encode_time_counter_.Add(encode_time_ms); |
405 encode_time_.Apply(1.0f, encode_time_ms); | 436 encode_time_.Apply(1.0f, encode_time_ms); |
406 stats_.avg_encode_time_ms = round(encode_time_.filtered()); | 437 stats_.avg_encode_time_ms = round(encode_time_.filtered()); |
407 stats_.encode_usage_percent = metrics.encode_usage_percent; | 438 stats_.encode_usage_percent = metrics.encode_usage_percent; |
408 } | 439 } |
409 | 440 |
410 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) { | 441 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) { |
411 rtc::CritScope lock(&crit_); | 442 rtc::CritScope lock(&crit_); |
412 stats_.suspended = is_suspended; | 443 stats_.suspended = is_suspended; |
413 // Pause framerate stats. | |
414 if (is_suspended) { | 444 if (is_suspended) { |
415 uma_container_->input_fps_counter_.ProcessAndPause(); | 445 // Pause framerate (add min pause time since there may be frames/packets |
416 uma_container_->sent_fps_counter_.ProcessAndPause(); | 446 // that are not yet sent). |
| 447 const int64_t kMinMs = 500; |
| 448 uma_container_->input_fps_counter_.ProcessAndPauseForDuration(kMinMs); |
| 449 uma_container_->sent_fps_counter_.ProcessAndPauseForDuration(kMinMs); |
| 450 // Pause bitrate stats. |
| 451 uma_container_->total_byte_counter_.ProcessAndPauseForDuration(kMinMs); |
| 452 uma_container_->media_byte_counter_.ProcessAndPauseForDuration(kMinMs); |
| 453 uma_container_->rtx_byte_counter_.ProcessAndPauseForDuration(kMinMs); |
| 454 uma_container_->padding_byte_counter_.ProcessAndPauseForDuration(kMinMs); |
| 455 uma_container_->retransmit_byte_counter_.ProcessAndPauseForDuration(kMinMs); |
| 456 uma_container_->fec_byte_counter_.ProcessAndPauseForDuration(kMinMs); |
| 457 } else { |
| 458 // Stop pause explicitly for stats that may be zero/not updated for some |
| 459 // time. |
| 460 uma_container_->rtx_byte_counter_.ProcessAndStopPause(); |
| 461 uma_container_->padding_byte_counter_.ProcessAndStopPause(); |
| 462 uma_container_->retransmit_byte_counter_.ProcessAndStopPause(); |
| 463 uma_container_->fec_byte_counter_.ProcessAndStopPause(); |
417 } | 464 } |
418 } | 465 } |
419 | 466 |
420 VideoSendStream::Stats SendStatisticsProxy::GetStats() { | 467 VideoSendStream::Stats SendStatisticsProxy::GetStats() { |
421 rtc::CritScope lock(&crit_); | 468 rtc::CritScope lock(&crit_); |
422 PurgeOldStats(); | 469 PurgeOldStats(); |
423 stats_.input_frame_rate = | 470 stats_.input_frame_rate = |
424 round(uma_container_->input_frame_rate_tracker_.ComputeRate()); | 471 round(uma_container_->input_frame_rate_tracker_.ComputeRate()); |
425 return stats_; | 472 return stats_; |
426 } | 473 } |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 uma_container_->report_block_stats_.Store(statistics, 0, ssrc); | 713 uma_container_->report_block_stats_.Store(statistics, 0, ssrc); |
667 } | 714 } |
668 | 715 |
669 void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {} | 716 void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {} |
670 | 717 |
671 void SendStatisticsProxy::DataCountersUpdated( | 718 void SendStatisticsProxy::DataCountersUpdated( |
672 const StreamDataCounters& counters, | 719 const StreamDataCounters& counters, |
673 uint32_t ssrc) { | 720 uint32_t ssrc) { |
674 rtc::CritScope lock(&crit_); | 721 rtc::CritScope lock(&crit_); |
675 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); | 722 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); |
676 RTC_DCHECK(stats) << "DataCountersUpdated reported for unknown ssrc: " | 723 RTC_DCHECK(stats) << "DataCountersUpdated reported for unknown ssrc " << ssrc; |
677 << ssrc; | |
678 | 724 |
679 if (stats->is_flexfec) { | 725 if (stats->is_flexfec) { |
680 // The same counters are reported for both the media ssrc and flexfec ssrc. | 726 // The same counters are reported for both the media ssrc and flexfec ssrc. |
681 // Bitrate stats are summed for all SSRCs. Use fec stats from media update. | 727 // Bitrate stats are summed for all SSRCs. Use fec stats from media update. |
682 return; | 728 return; |
683 } | 729 } |
684 | 730 |
685 stats->rtp_stats = counters; | 731 stats->rtp_stats = counters; |
686 if (uma_container_->first_rtp_stats_time_ms_ == -1) | 732 if (uma_container_->first_rtp_stats_time_ms_ == -1) |
687 uma_container_->first_rtp_stats_time_ms_ = clock_->TimeInMilliseconds(); | 733 uma_container_->first_rtp_stats_time_ms_ = clock_->TimeInMilliseconds(); |
| 734 |
| 735 uma_container_->total_byte_counter_.Set(counters.transmitted.TotalBytes(), |
| 736 ssrc); |
| 737 uma_container_->padding_byte_counter_.Set(counters.transmitted.padding_bytes, |
| 738 ssrc); |
| 739 uma_container_->retransmit_byte_counter_.Set( |
| 740 counters.retransmitted.TotalBytes(), ssrc); |
| 741 uma_container_->fec_byte_counter_.Set(counters.fec.TotalBytes(), ssrc); |
| 742 if (stats->is_rtx) { |
| 743 uma_container_->rtx_byte_counter_.Set(counters.transmitted.TotalBytes(), |
| 744 ssrc); |
| 745 } else { |
| 746 uma_container_->media_byte_counter_.Set(counters.MediaPayloadBytes(), ssrc); |
| 747 } |
688 } | 748 } |
689 | 749 |
690 void SendStatisticsProxy::Notify(uint32_t total_bitrate_bps, | 750 void SendStatisticsProxy::Notify(uint32_t total_bitrate_bps, |
691 uint32_t retransmit_bitrate_bps, | 751 uint32_t retransmit_bitrate_bps, |
692 uint32_t ssrc) { | 752 uint32_t ssrc) { |
693 rtc::CritScope lock(&crit_); | 753 rtc::CritScope lock(&crit_); |
694 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); | 754 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); |
695 if (!stats) | 755 if (!stats) |
696 return; | 756 return; |
697 | 757 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 } | 817 } |
758 | 818 |
759 int SendStatisticsProxy::BoolSampleCounter::Fraction( | 819 int SendStatisticsProxy::BoolSampleCounter::Fraction( |
760 int64_t min_required_samples, | 820 int64_t min_required_samples, |
761 float multiplier) const { | 821 float multiplier) const { |
762 if (num_samples < min_required_samples || num_samples == 0) | 822 if (num_samples < min_required_samples || num_samples == 0) |
763 return -1; | 823 return -1; |
764 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); | 824 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); |
765 } | 825 } |
766 } // namespace webrtc | 826 } // namespace webrtc |
OLD | NEW |