| 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 |
| 11 #include "webrtc/video/send_statistics_proxy.h" | 11 #include "webrtc/video/send_statistics_proxy.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <cmath> | 14 #include <cmath> |
| 15 #include <map> | 15 #include <map> |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 20 #include "webrtc/base/trace_event.h" |
| 20 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 21 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 21 #include "webrtc/system_wrappers/include/metrics.h" | 22 #include "webrtc/system_wrappers/include/metrics.h" |
| 22 | 23 |
| 23 namespace webrtc { | 24 namespace webrtc { |
| 24 namespace { | 25 namespace { |
| 25 const float kEncodeTimeWeigthFactor = 0.5f; | 26 const float kEncodeTimeWeigthFactor = 0.5f; |
| 26 | 27 |
| 27 // Used by histograms. Values of entries should not be changed. | 28 // Used by histograms. Values of entries should not be changed. |
| 28 enum HistogramCodecType { | 29 enum HistogramCodecType { |
| 29 kVideoUnknown = 0, | 30 kVideoUnknown = 0, |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 GetUmaPrefix(config.content_type), stats_, clock_)); | 420 GetUmaPrefix(config.content_type), stats_, clock_)); |
| 420 content_type_ = config.content_type; | 421 content_type_ = config.content_type; |
| 421 } | 422 } |
| 422 } | 423 } |
| 423 | 424 |
| 424 void SendStatisticsProxy::OnEncoderStatsUpdate(uint32_t framerate, | 425 void SendStatisticsProxy::OnEncoderStatsUpdate(uint32_t framerate, |
| 425 uint32_t bitrate) { | 426 uint32_t bitrate) { |
| 426 rtc::CritScope lock(&crit_); | 427 rtc::CritScope lock(&crit_); |
| 427 stats_.encode_frame_rate = framerate; | 428 stats_.encode_frame_rate = framerate; |
| 428 stats_.media_bitrate_bps = bitrate; | 429 stats_.media_bitrate_bps = bitrate; |
| 430 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.FrameRateSent", |
| 431 "frame_rate", framerate, "ssrc", rtp_config_.ssrcs[0]); |
| 429 } | 432 } |
| 430 | 433 |
| 431 void SendStatisticsProxy::OnEncodedFrameTimeMeasured( | 434 void SendStatisticsProxy::OnEncodedFrameTimeMeasured( |
| 432 int encode_time_ms, | 435 int encode_time_ms, |
| 433 const CpuOveruseMetrics& metrics) { | 436 const CpuOveruseMetrics& metrics) { |
| 434 rtc::CritScope lock(&crit_); | 437 rtc::CritScope lock(&crit_); |
| 435 uma_container_->encode_time_counter_.Add(encode_time_ms); | 438 uma_container_->encode_time_counter_.Add(encode_time_ms); |
| 436 encode_time_.Apply(1.0f, encode_time_ms); | 439 encode_time_.Apply(1.0f, encode_time_ms); |
| 437 stats_.avg_encode_time_ms = round(encode_time_.filtered()); | 440 stats_.avg_encode_time_ms = round(encode_time_.filtered()); |
| 438 stats_.encode_usage_percent = metrics.encode_usage_percent; | 441 stats_.encode_usage_percent = metrics.encode_usage_percent; |
| 442 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.EncodeTimeInMs", |
| 443 "encode_time_ms", stats_.avg_encode_time_ms, |
| 444 "ssrc", rtp_config_.ssrcs[0]); |
| 445 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.EncodeUsagePercent", |
| 446 "encode_usage_percent", stats_.encode_usage_percent, |
| 447 "ssrc", rtp_config_.ssrcs[0]); |
| 439 } | 448 } |
| 440 | 449 |
| 441 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) { | 450 void SendStatisticsProxy::OnSuspendChange(bool is_suspended) { |
| 442 rtc::CritScope lock(&crit_); | 451 rtc::CritScope lock(&crit_); |
| 443 stats_.suspended = is_suspended; | 452 stats_.suspended = is_suspended; |
| 444 if (is_suspended) { | 453 if (is_suspended) { |
| 445 // Pause framerate (add min pause time since there may be frames/packets | 454 // Pause framerate (add min pause time since there may be frames/packets |
| 446 // that are not yet sent). | 455 // that are not yet sent). |
| 447 const int64_t kMinMs = 500; | 456 const int64_t kMinMs = 500; |
| 448 uma_container_->input_fps_counter_.ProcessAndPauseForDuration(kMinMs); | 457 uma_container_->input_fps_counter_.ProcessAndPauseForDuration(kMinMs); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 uma_container_->max_sent_width_per_timestamp_ = 0; | 645 uma_container_->max_sent_width_per_timestamp_ = 0; |
| 637 uma_container_->max_sent_height_per_timestamp_ = 0; | 646 uma_container_->max_sent_height_per_timestamp_ = 0; |
| 638 } | 647 } |
| 639 last_sent_frame_timestamp_ = encoded_image._timeStamp; | 648 last_sent_frame_timestamp_ = encoded_image._timeStamp; |
| 640 uma_container_->max_sent_width_per_timestamp_ = | 649 uma_container_->max_sent_width_per_timestamp_ = |
| 641 std::max(uma_container_->max_sent_width_per_timestamp_, | 650 std::max(uma_container_->max_sent_width_per_timestamp_, |
| 642 static_cast<int>(encoded_image._encodedWidth)); | 651 static_cast<int>(encoded_image._encodedWidth)); |
| 643 uma_container_->max_sent_height_per_timestamp_ = | 652 uma_container_->max_sent_height_per_timestamp_ = |
| 644 std::max(uma_container_->max_sent_height_per_timestamp_, | 653 std::max(uma_container_->max_sent_height_per_timestamp_, |
| 645 static_cast<int>(encoded_image._encodedHeight)); | 654 static_cast<int>(encoded_image._encodedHeight)); |
| 655 |
| 656 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.SentWidthInPixels", |
| 657 "frame_width", encoded_image._encodedWidth, "ssrc", ssrc); |
| 658 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.SentHeightInPixels", |
| 659 "frame_height", encoded_image._encodedHeight, "ssrc", ssrc); |
| 646 } | 660 } |
| 647 | 661 |
| 648 int SendStatisticsProxy::GetSendFrameRate() const { | 662 int SendStatisticsProxy::GetSendFrameRate() const { |
| 649 rtc::CritScope lock(&crit_); | 663 rtc::CritScope lock(&crit_); |
| 650 return stats_.encode_frame_rate; | 664 return stats_.encode_frame_rate; |
| 651 } | 665 } |
| 652 | 666 |
| 653 void SendStatisticsProxy::OnIncomingFrame(int width, int height) { | 667 void SendStatisticsProxy::OnIncomingFrame(int width, int height) { |
| 654 rtc::CritScope lock(&crit_); | 668 rtc::CritScope lock(&crit_); |
| 655 uma_container_->input_frame_rate_tracker_.AddSamples(1); | 669 uma_container_->input_frame_rate_tracker_.AddSamples(1); |
| 656 uma_container_->input_fps_counter_.Add(1); | 670 uma_container_->input_fps_counter_.Add(1); |
| 657 uma_container_->input_width_counter_.Add(width); | 671 uma_container_->input_width_counter_.Add(width); |
| 658 uma_container_->input_height_counter_.Add(height); | 672 uma_container_->input_height_counter_.Add(height); |
| 659 uma_container_->cpu_limited_frame_counter_.Add(stats_.cpu_limited_resolution); | 673 uma_container_->cpu_limited_frame_counter_.Add(stats_.cpu_limited_resolution); |
| 674 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.InputFrameRate", |
| 675 "frame_rate", round( |
| 676 uma_container_->input_frame_rate_tracker_.ComputeRate()), |
| 677 "ssrc", rtp_config_.ssrcs[0]); |
| 660 } | 678 } |
| 661 | 679 |
| 662 void SendStatisticsProxy::SetResolutionRestrictionStats( | 680 void SendStatisticsProxy::SetResolutionRestrictionStats( |
| 663 bool scaling_enabled, | 681 bool scaling_enabled, |
| 664 bool cpu_restricted, | 682 bool cpu_restricted, |
| 665 int num_quality_downscales) { | 683 int num_quality_downscales) { |
| 666 rtc::CritScope lock(&crit_); | 684 rtc::CritScope lock(&crit_); |
| 667 if (scaling_enabled) { | 685 if (scaling_enabled) { |
| 668 quality_downscales_ = num_quality_downscales; | 686 quality_downscales_ = num_quality_downscales; |
| 669 stats_.bw_limited_resolution = quality_downscales_ > 0; | 687 stats_.bw_limited_resolution = quality_downscales_ > 0; |
| 670 stats_.cpu_limited_resolution = cpu_restricted; | 688 stats_.cpu_limited_resolution = cpu_restricted; |
| 671 } else { | 689 } else { |
| 672 stats_.bw_limited_resolution = false; | 690 stats_.bw_limited_resolution = false; |
| 673 stats_.cpu_limited_resolution = false; | 691 stats_.cpu_limited_resolution = false; |
| 674 quality_downscales_ = -1; | 692 quality_downscales_ = -1; |
| 675 } | 693 } |
| 676 } | 694 } |
| 677 | 695 |
| 678 void SendStatisticsProxy::OnCpuRestrictedResolutionChanged( | 696 void SendStatisticsProxy::OnCpuRestrictedResolutionChanged( |
| 679 bool cpu_restricted_resolution) { | 697 bool cpu_restricted_resolution) { |
| 680 rtc::CritScope lock(&crit_); | 698 rtc::CritScope lock(&crit_); |
| 681 stats_.cpu_limited_resolution = cpu_restricted_resolution; | 699 stats_.cpu_limited_resolution = cpu_restricted_resolution; |
| 682 ++stats_.number_of_cpu_adapt_changes; | 700 ++stats_.number_of_cpu_adapt_changes; |
| 701 TRACE_EVENT_INSTANT0("webrtc_stats", "WebRTC.Video.AdaptationChanges"); |
| 683 } | 702 } |
| 684 | 703 |
| 685 void SendStatisticsProxy::OnQualityRestrictedResolutionChanged( | 704 void SendStatisticsProxy::OnQualityRestrictedResolutionChanged( |
| 686 int num_quality_downscales) { | 705 int num_quality_downscales) { |
| 687 rtc::CritScope lock(&crit_); | 706 rtc::CritScope lock(&crit_); |
| 688 quality_downscales_ = num_quality_downscales; | 707 quality_downscales_ = num_quality_downscales; |
| 689 stats_.bw_limited_resolution = quality_downscales_ > 0; | 708 stats_.bw_limited_resolution = quality_downscales_ > 0; |
| 690 } | 709 } |
| 691 | 710 |
| 692 void SendStatisticsProxy::RtcpPacketTypesCounterUpdated( | 711 void SendStatisticsProxy::RtcpPacketTypesCounterUpdated( |
| 693 uint32_t ssrc, | 712 uint32_t ssrc, |
| 694 const RtcpPacketTypeCounter& packet_counter) { | 713 const RtcpPacketTypeCounter& packet_counter) { |
| 695 rtc::CritScope lock(&crit_); | 714 rtc::CritScope lock(&crit_); |
| 696 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); | 715 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); |
| 697 if (!stats) | 716 if (!stats) |
| 698 return; | 717 return; |
| 699 | 718 |
| 700 stats->rtcp_packet_type_counts = packet_counter; | 719 stats->rtcp_packet_type_counts = packet_counter; |
| 701 if (uma_container_->first_rtcp_stats_time_ms_ == -1) | 720 if (uma_container_->first_rtcp_stats_time_ms_ == -1) |
| 702 uma_container_->first_rtcp_stats_time_ms_ = clock_->TimeInMilliseconds(); | 721 uma_container_->first_rtcp_stats_time_ms_ = clock_->TimeInMilliseconds(); |
| 722 |
| 723 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.FirPacketsReceived", |
| 724 "fir_packets_received", packet_counter.fir_packets, "ssrc", ssrc); |
| 725 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.NackPacketsReceived", |
| 726 "nack_packets_received", packet_counter.nack_packets, "ssrc", ssrc); |
| 727 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.PliPacketsReceived", |
| 728 "pli_packets_received", packet_counter.pli_packets, "ssrc", ssrc); |
| 703 } | 729 } |
| 704 | 730 |
| 705 void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics, | 731 void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics, |
| 706 uint32_t ssrc) { | 732 uint32_t ssrc) { |
| 707 rtc::CritScope lock(&crit_); | 733 rtc::CritScope lock(&crit_); |
| 708 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); | 734 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); |
| 709 if (!stats) | 735 if (!stats) |
| 710 return; | 736 return; |
| 711 | 737 |
| 712 stats->rtcp_stats = statistics; | 738 stats->rtcp_stats = statistics; |
| 713 uma_container_->report_block_stats_.Store(statistics, 0, ssrc); | 739 uma_container_->report_block_stats_.Store(statistics, 0, ssrc); |
| 740 |
| 741 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.SentPacketsLost", |
| 742 "packets_lost", statistics.cumulative_lost, "ssrc", ssrc); |
| 714 } | 743 } |
| 715 | 744 |
| 716 void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {} | 745 void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {} |
| 717 | 746 |
| 718 void SendStatisticsProxy::DataCountersUpdated( | 747 void SendStatisticsProxy::DataCountersUpdated( |
| 719 const StreamDataCounters& counters, | 748 const StreamDataCounters& counters, |
| 720 uint32_t ssrc) { | 749 uint32_t ssrc) { |
| 721 rtc::CritScope lock(&crit_); | 750 rtc::CritScope lock(&crit_); |
| 722 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); | 751 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); |
| 723 RTC_DCHECK(stats) << "DataCountersUpdated reported for unknown ssrc " << ssrc; | 752 RTC_DCHECK(stats) << "DataCountersUpdated reported for unknown ssrc " << ssrc; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 738 ssrc); | 767 ssrc); |
| 739 uma_container_->retransmit_byte_counter_.Set( | 768 uma_container_->retransmit_byte_counter_.Set( |
| 740 counters.retransmitted.TotalBytes(), ssrc); | 769 counters.retransmitted.TotalBytes(), ssrc); |
| 741 uma_container_->fec_byte_counter_.Set(counters.fec.TotalBytes(), ssrc); | 770 uma_container_->fec_byte_counter_.Set(counters.fec.TotalBytes(), ssrc); |
| 742 if (stats->is_rtx) { | 771 if (stats->is_rtx) { |
| 743 uma_container_->rtx_byte_counter_.Set(counters.transmitted.TotalBytes(), | 772 uma_container_->rtx_byte_counter_.Set(counters.transmitted.TotalBytes(), |
| 744 ssrc); | 773 ssrc); |
| 745 } else { | 774 } else { |
| 746 uma_container_->media_byte_counter_.Set(counters.MediaPayloadBytes(), ssrc); | 775 uma_container_->media_byte_counter_.Set(counters.MediaPayloadBytes(), ssrc); |
| 747 } | 776 } |
| 777 |
| 778 TRACE_EVENT_INSTANT2("webrtc_stats", "WebRTC.Video.SentPackets", |
| 779 "packets_sent", counters.transmitted.packets, "ssrc", ssrc); |
| 748 } | 780 } |
| 749 | 781 |
| 750 void SendStatisticsProxy::Notify(uint32_t total_bitrate_bps, | 782 void SendStatisticsProxy::Notify(uint32_t total_bitrate_bps, |
| 751 uint32_t retransmit_bitrate_bps, | 783 uint32_t retransmit_bitrate_bps, |
| 752 uint32_t ssrc) { | 784 uint32_t ssrc) { |
| 753 rtc::CritScope lock(&crit_); | 785 rtc::CritScope lock(&crit_); |
| 754 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); | 786 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); |
| 755 if (!stats) | 787 if (!stats) |
| 756 return; | 788 return; |
| 757 | 789 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 } | 849 } |
| 818 | 850 |
| 819 int SendStatisticsProxy::BoolSampleCounter::Fraction( | 851 int SendStatisticsProxy::BoolSampleCounter::Fraction( |
| 820 int64_t min_required_samples, | 852 int64_t min_required_samples, |
| 821 float multiplier) const { | 853 float multiplier) const { |
| 822 if (num_samples < min_required_samples || num_samples == 0) | 854 if (num_samples < min_required_samples || num_samples == 0) |
| 823 return -1; | 855 return -1; |
| 824 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); | 856 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); |
| 825 } | 857 } |
| 826 } // namespace webrtc | 858 } // namespace webrtc |
| OLD | NEW |