Line data Source code
1 : /*
2 : * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 : *
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
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/video/send_delay_stats.h"
12 :
13 : #include <utility>
14 :
15 : #include "webrtc/base/logging.h"
16 : #include "webrtc/system_wrappers/include/metrics.h"
17 :
18 : namespace webrtc {
19 : namespace {
20 : // Packet with a larger delay are removed and excluded from the delay stats.
21 : // Set to larger than max histogram delay which is 10000.
22 : const int64_t kMaxSentPacketDelayMs = 11000;
23 : const size_t kMaxPacketMapSize = 2000;
24 :
25 : // Limit for the maximum number of streams to calculate stats for.
26 : const size_t kMaxSsrcMapSize = 50;
27 : const int kMinRequiredPeriodicSamples = 5;
28 : } // namespace
29 :
30 0 : SendDelayStats::SendDelayStats(Clock* clock)
31 0 : : clock_(clock), num_old_packets_(0), num_skipped_packets_(0) {}
32 :
33 0 : SendDelayStats::~SendDelayStats() {
34 0 : if (num_old_packets_ > 0 || num_skipped_packets_ > 0) {
35 0 : LOG(LS_WARNING) << "Delay stats: number of old packets " << num_old_packets_
36 0 : << ", skipped packets " << num_skipped_packets_
37 0 : << ". Number of streams " << send_delay_counters_.size();
38 : }
39 0 : UpdateHistograms();
40 0 : }
41 :
42 0 : void SendDelayStats::UpdateHistograms() {
43 0 : rtc::CritScope lock(&crit_);
44 0 : for (const auto& it : send_delay_counters_) {
45 0 : AggregatedStats stats = it.second->GetStats();
46 0 : if (stats.num_samples >= kMinRequiredPeriodicSamples) {
47 0 : RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SendDelayInMs", stats.average);
48 0 : LOG(LS_INFO) << "WebRTC.Video.SendDelayInMs, " << stats.ToString();
49 : }
50 : }
51 0 : }
52 :
53 0 : void SendDelayStats::AddSsrcs(const VideoSendStream::Config& config) {
54 0 : rtc::CritScope lock(&crit_);
55 0 : if (ssrcs_.size() > kMaxSsrcMapSize)
56 0 : return;
57 0 : for (const auto& ssrc : config.rtp.ssrcs)
58 0 : ssrcs_.insert(ssrc);
59 : }
60 :
61 0 : AvgCounter* SendDelayStats::GetSendDelayCounter(uint32_t ssrc) {
62 0 : const auto& it = send_delay_counters_.find(ssrc);
63 0 : if (it != send_delay_counters_.end())
64 0 : return it->second.get();
65 :
66 0 : AvgCounter* counter = new AvgCounter(clock_, nullptr, false);
67 0 : send_delay_counters_[ssrc].reset(counter);
68 0 : return counter;
69 : }
70 :
71 0 : void SendDelayStats::OnSendPacket(uint16_t packet_id,
72 : int64_t capture_time_ms,
73 : uint32_t ssrc) {
74 : // Packet sent to transport.
75 0 : rtc::CritScope lock(&crit_);
76 0 : if (ssrcs_.find(ssrc) == ssrcs_.end())
77 0 : return;
78 :
79 0 : int64_t now = clock_->TimeInMilliseconds();
80 0 : RemoveOld(now, &packets_);
81 :
82 0 : if (packets_.size() > kMaxPacketMapSize) {
83 0 : ++num_skipped_packets_;
84 0 : return;
85 : }
86 : packets_.insert(
87 0 : std::make_pair(packet_id, Packet(ssrc, capture_time_ms, now)));
88 : }
89 :
90 0 : bool SendDelayStats::OnSentPacket(int packet_id, int64_t time_ms) {
91 : // Packet leaving socket.
92 0 : if (packet_id == -1)
93 0 : return false;
94 :
95 0 : rtc::CritScope lock(&crit_);
96 0 : auto it = packets_.find(packet_id);
97 0 : if (it == packets_.end())
98 0 : return false;
99 :
100 : // TODO(asapersson): Remove SendSideDelayUpdated(), use capture -> sent.
101 : // Elapsed time from send (to transport) -> sent (leaving socket).
102 0 : int diff_ms = time_ms - it->second.send_time_ms;
103 0 : GetSendDelayCounter(it->second.ssrc)->Add(diff_ms);
104 0 : packets_.erase(it);
105 0 : return true;
106 : }
107 :
108 0 : void SendDelayStats::RemoveOld(int64_t now, PacketMap* packets) {
109 0 : while (!packets->empty()) {
110 0 : auto it = packets->begin();
111 0 : if (now - it->second.capture_time_ms < kMaxSentPacketDelayMs)
112 0 : break;
113 :
114 0 : packets->erase(it);
115 0 : ++num_old_packets_;
116 : }
117 0 : }
118 :
119 : } // namespace webrtc
|