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/system_wrappers/include/metrics.h" | 20 #include "webrtc/system_wrappers/include/metrics.h" |
21 | 21 |
22 namespace webrtc { | 22 namespace webrtc { |
23 namespace { | 23 namespace { |
24 const float kEncodeTimeWeigthFactor = 0.5f; | 24 const float kEncodeTimeWeigthFactor = 0.5f; |
25 | 25 |
26 // Packet with a larger delay are removed and excluded from the delay stats. | |
27 // Set to larger than max histogram delay which is 10000. | |
28 const int64_t kMaxSentPacketDelayMs = 11000; | |
29 const size_t kMaxSendPacketMapSize = 2000; | |
30 | |
26 // Used by histograms. Values of entries should not be changed. | 31 // Used by histograms. Values of entries should not be changed. |
27 enum HistogramCodecType { | 32 enum HistogramCodecType { |
28 kVideoUnknown = 0, | 33 kVideoUnknown = 0, |
29 kVideoVp8 = 1, | 34 kVideoVp8 = 1, |
30 kVideoVp9 = 2, | 35 kVideoVp9 = 2, |
31 kVideoH264 = 3, | 36 kVideoH264 = 3, |
32 kVideoMax = 64, | 37 kVideoMax = 64, |
33 }; | 38 }; |
34 | 39 |
35 const char* kRealtimePrefix = "WebRTC.Video."; | 40 const char* kRealtimePrefix = "WebRTC.Video."; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 | 76 |
72 SendStatisticsProxy::SendStatisticsProxy( | 77 SendStatisticsProxy::SendStatisticsProxy( |
73 Clock* clock, | 78 Clock* clock, |
74 const VideoSendStream::Config& config, | 79 const VideoSendStream::Config& config, |
75 VideoEncoderConfig::ContentType content_type) | 80 VideoEncoderConfig::ContentType content_type) |
76 : clock_(clock), | 81 : clock_(clock), |
77 config_(config), | 82 config_(config), |
78 content_type_(content_type), | 83 content_type_(content_type), |
79 last_sent_frame_timestamp_(0), | 84 last_sent_frame_timestamp_(0), |
80 encode_time_(kEncodeTimeWeigthFactor), | 85 encode_time_(kEncodeTimeWeigthFactor), |
86 num_old_packets_(0), | |
87 num_skipped_packets_(0), | |
81 uma_container_( | 88 uma_container_( |
82 new UmaSamplesContainer(GetUmaPrefix(content_type_), stats_, clock)) { | 89 new UmaSamplesContainer(GetUmaPrefix(content_type_), stats_, clock)) { |
83 UpdateCodecTypeHistogram(config_.encoder_settings.payload_name); | 90 UpdateCodecTypeHistogram(config_.encoder_settings.payload_name); |
84 } | 91 } |
85 | 92 |
86 SendStatisticsProxy::~SendStatisticsProxy() { | 93 SendStatisticsProxy::~SendStatisticsProxy() { |
94 if (num_old_packets_ > 0 || num_skipped_packets_ > 0) { | |
95 LOG(LS_WARNING) << "Delay stats: number of old packets " << num_old_packets_ | |
96 << ", skipped packets " << num_skipped_packets_; | |
97 } | |
87 rtc::CritScope lock(&crit_); | 98 rtc::CritScope lock(&crit_); |
88 uma_container_->UpdateHistograms(config_, stats_); | 99 uma_container_->UpdateHistograms(config_, stats_); |
89 } | 100 } |
90 | 101 |
91 SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer( | 102 SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer( |
92 const char* prefix, | 103 const char* prefix, |
93 const VideoSendStream::Stats& stats, | 104 const VideoSendStream::Stats& stats, |
94 Clock* const clock) | 105 Clock* const clock) |
95 : uma_prefix_(prefix), | 106 : uma_prefix_(prefix), |
96 clock_(clock), | 107 clock_(clock), |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); | 196 int delay_ms = delay_counter_.Avg(kMinRequiredSamples); |
186 if (delay_ms != -1) | 197 if (delay_ms != -1) |
187 RTC_LOGGED_HISTOGRAMS_COUNTS_100000( | 198 RTC_LOGGED_HISTOGRAMS_COUNTS_100000( |
188 kIndex, uma_prefix_ + "SendSideDelayInMs", delay_ms); | 199 kIndex, uma_prefix_ + "SendSideDelayInMs", delay_ms); |
189 | 200 |
190 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples); | 201 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples); |
191 if (max_delay_ms != -1) { | 202 if (max_delay_ms != -1) { |
192 RTC_LOGGED_HISTOGRAMS_COUNTS_100000( | 203 RTC_LOGGED_HISTOGRAMS_COUNTS_100000( |
193 kIndex, uma_prefix_ + "SendSideDelayMaxInMs", max_delay_ms); | 204 kIndex, uma_prefix_ + "SendSideDelayMaxInMs", max_delay_ms); |
194 } | 205 } |
206 for (const auto& it : send_delay_counters_) { | |
207 int send_delay_ms = it.second.Avg(kMinRequiredSamples); | |
208 if (send_delay_ms != -1) { | |
209 RTC_LOGGED_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SendDelayInMs", | |
210 send_delay_ms); | |
211 } | |
212 } | |
195 | 213 |
196 for (const auto& it : qp_counters_) { | 214 for (const auto& it : qp_counters_) { |
197 int qp_vp8 = it.second.vp8.Avg(kMinRequiredSamples); | 215 int qp_vp8 = it.second.vp8.Avg(kMinRequiredSamples); |
198 if (qp_vp8 != -1) { | 216 if (qp_vp8 != -1) { |
199 int spatial_idx = it.first; | 217 int spatial_idx = it.first; |
200 if (spatial_idx == -1) { | 218 if (spatial_idx == -1) { |
201 RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8", | 219 RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8", |
202 qp_vp8); | 220 qp_vp8); |
203 } else if (spatial_idx == 0) { | 221 } else if (spatial_idx == 0) { |
204 RTC_LOGGED_HISTOGRAMS_COUNTS_200( | 222 RTC_LOGGED_HISTOGRAMS_COUNTS_200( |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); | 599 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc); |
582 if (!stats) | 600 if (!stats) |
583 return; | 601 return; |
584 stats->avg_delay_ms = avg_delay_ms; | 602 stats->avg_delay_ms = avg_delay_ms; |
585 stats->max_delay_ms = max_delay_ms; | 603 stats->max_delay_ms = max_delay_ms; |
586 | 604 |
587 uma_container_->delay_counter_.Add(avg_delay_ms); | 605 uma_container_->delay_counter_.Add(avg_delay_ms); |
588 uma_container_->max_delay_counter_.Add(max_delay_ms); | 606 uma_container_->max_delay_counter_.Add(max_delay_ms); |
589 } | 607 } |
590 | 608 |
609 void SendStatisticsProxy::OnSendPacket(uint16_t packet_id, | |
610 int64_t capture_time_ms, | |
611 uint32_t ssrc) { | |
612 // Packet sent to transport. | |
613 rtc::CritScope lock(&crit_); | |
614 if (GetStatsEntry(ssrc) == nullptr) | |
615 return; | |
616 | |
617 int64_t now = clock_->TimeInMilliseconds(); | |
618 RemoveOld(now, &packets_); | |
619 | |
620 if (packets_.size() > kMaxSendPacketMapSize) { | |
621 ++num_skipped_packets_; | |
622 return; | |
623 } | |
624 packets_.insert( | |
625 std::make_pair(packet_id, Packet(ssrc, capture_time_ms, now))); | |
626 } | |
627 | |
628 bool SendStatisticsProxy::OnSentPacket(int packet_id) { | |
629 // Packet leaving socket. | |
630 if (packet_id == -1) | |
631 return false; | |
632 | |
633 rtc::CritScope lock(&crit_); | |
634 auto it = packets_.find(packet_id); | |
635 if (it == packets_.end()) | |
636 return false; | |
637 | |
638 // TODO(asapersson): Remove SendSideDelayUpdated(), use capture -> sent. | |
639 // Elapsed time from send (to transport) -> sent (leaving socket). | |
640 int diff_ms = clock_->TimeInMilliseconds() - it->second.send_time_ms; | |
mflodman
2016/04/26 06:49:11
Is there some way we could get this time when actu
åsapersson
2016/04/28 12:26:19
Right, it is not working due to clock differences.
| |
641 uma_container_->send_delay_counters_[it->second.ssrc].Add(diff_ms); | |
642 packets_.erase(it); | |
643 return true; | |
644 } | |
645 | |
646 void SendStatisticsProxy::RemoveOld(int64_t now, PacketMap* packets) { | |
647 while (!packets->empty()) { | |
648 auto it = packets->begin(); | |
649 if (now - it->second.capture_time_ms < kMaxSentPacketDelayMs) | |
650 break; | |
651 | |
652 packets->erase(it); | |
653 ++num_old_packets_; | |
654 } | |
655 } | |
656 | |
591 void SendStatisticsProxy::SampleCounter::Add(int sample) { | 657 void SendStatisticsProxy::SampleCounter::Add(int sample) { |
592 sum += sample; | 658 sum += sample; |
593 ++num_samples; | 659 ++num_samples; |
594 } | 660 } |
595 | 661 |
596 int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { | 662 int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { |
597 if (num_samples < min_required_samples || num_samples == 0) | 663 if (num_samples < min_required_samples || num_samples == 0) |
598 return -1; | 664 return -1; |
599 return (sum + (num_samples / 2)) / num_samples; | 665 return (sum + (num_samples / 2)) / num_samples; |
600 } | 666 } |
(...skipping 14 matching lines...) Expand all Loading... | |
615 return Fraction(min_required_samples, 1000.0f); | 681 return Fraction(min_required_samples, 1000.0f); |
616 } | 682 } |
617 | 683 |
618 int SendStatisticsProxy::BoolSampleCounter::Fraction( | 684 int SendStatisticsProxy::BoolSampleCounter::Fraction( |
619 int min_required_samples, float multiplier) const { | 685 int min_required_samples, float multiplier) const { |
620 if (num_samples < min_required_samples || num_samples == 0) | 686 if (num_samples < min_required_samples || num_samples == 0) |
621 return -1; | 687 return -1; |
622 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); | 688 return static_cast<int>((sum * multiplier / num_samples) + 0.5f); |
623 } | 689 } |
624 } // namespace webrtc | 690 } // namespace webrtc |
OLD | NEW |