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

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

Issue 1478253002: Add histogram stats for send delay for a sent video stream. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 8 months 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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698