blob: 34519ba0cb719310c1cf59d2b0458e5b9dfd1d94 [file] [log] [blame]
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +00001/*
2 * Copyright (c) 2012 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef VIDEO_CALL_STATS_H_
12#define VIDEO_CALL_STATS_H_
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000013
14#include <list>
kwiberg27f982b2016-03-01 11:52:33 -080015#include <memory>
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/include/module.h"
Tommi38c5d932018-03-27 23:11:09 +020018#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "rtc_base/constructor_magic.h"
20#include "rtc_base/critical_section.h"
Tommi38c5d932018-03-27 23:11:09 +020021#include "rtc_base/thread_checker.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "system_wrappers/include/clock.h"
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000023
24namespace webrtc {
25
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +000026class CallStatsObserver;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000027
28// CallStats keeps track of statistics for a call.
Tommi38c5d932018-03-27 23:11:09 +020029class CallStats : public Module, public RtcpRttStats {
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000030 public:
Tommi38c5d932018-03-27 23:11:09 +020031 // Time interval for updating the observers.
32 static constexpr int64_t kUpdateIntervalMs = 1000;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000033
Tommi38c5d932018-03-27 23:11:09 +020034 CallStats(Clock* clock, ProcessThread* process_thread);
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020035 ~CallStats() override;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000036
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000037 // Registers/deregisters a new observer to receive statistics updates.
Tommi38c5d932018-03-27 23:11:09 +020038 // Must be called from the construction thread.
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +000039 void RegisterStatsObserver(CallStatsObserver* observer);
40 void DeregisterStatsObserver(CallStatsObserver* observer);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000041
Tommi38c5d932018-03-27 23:11:09 +020042 // Expose |LastProcessedRtt()| from RtcpRttStats to the public interface, as
43 // it is the part of the API that is needed by direct users of CallStats.
44 // TODO(tommi): Threading or lifetime guarantees are not explicit in how
45 // CallStats is used as RtcpRttStats or how pointers are cached in a
46 // few different places (distributed via Call). It would be good to clarify
47 // from what thread/TQ calls to OnRttUpdate and LastProcessedRtt need to be
48 // allowed.
49 int64_t LastProcessedRtt() const override;
50
51 // Exposed for tests to test histogram support.
52 void UpdateHistogramsForTest() { UpdateHistograms(); }
53
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000054 // Helper struct keeping track of the time a rtt value is reported.
55 struct RttTime {
Yves Gerey665174f2018-06-19 15:03:05 +020056 RttTime(int64_t new_rtt, int64_t rtt_time) : rtt(new_rtt), time(rtt_time) {}
pkasting@chromium.org16825b12015-01-12 21:51:21 +000057 const int64_t rtt;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000058 const int64_t time;
59 };
60
asapersson@webrtc.org8084f952014-12-10 11:04:13 +000061 private:
Tommi38c5d932018-03-27 23:11:09 +020062 // RtcpRttStats implementation.
63 void OnRttUpdate(int64_t rtt) override;
64
65 // Implements Module, to use the process thread.
66 int64_t TimeUntilNextProcess() override;
67 void Process() override;
68
69 // TODO(tommi): Use this to know when we're attached to the process thread?
70 // Alternatively, inject that pointer via the ctor since the call_stats
71 // test code, isn't using a processthread atm.
72 void ProcessThreadAttached(ProcessThread* process_thread) override;
73
74 // This method must only be called when the process thread is not
75 // running, and from the construction thread.
sprange2d83d62016-02-19 09:03:26 -080076 void UpdateHistograms();
77
Peter Boströmd3c94472015-12-09 11:20:58 +010078 Clock* const clock_;
Tommi38c5d932018-03-27 23:11:09 +020079
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000080 // The last time 'Process' resulted in statistic update.
Tommi38c5d932018-03-27 23:11:09 +020081 int64_t last_process_time_ RTC_GUARDED_BY(process_thread_checker_);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000082 // The last RTT in the statistics update (zero if there is no valid estimate).
Tommi38c5d932018-03-27 23:11:09 +020083 int64_t max_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
84
85 // Accessed from random threads (seemingly). Consider atomic.
86 // |avg_rtt_ms_| is allowed to be read on the process thread without a lock.
87 // |avg_rtt_ms_lock_| must be held elsewhere for reading.
88 // |avg_rtt_ms_lock_| must be held on the process thread for writing.
pkasting@chromium.org16825b12015-01-12 21:51:21 +000089 int64_t avg_rtt_ms_;
Tommi38c5d932018-03-27 23:11:09 +020090
91 // Protects |avg_rtt_ms_|.
92 rtc::CriticalSection avg_rtt_ms_lock_;
93
94 // |sum_avg_rtt_ms_|, |num_avg_rtt_| and |time_of_first_rtt_ms_| are only used
95 // on the ProcessThread when running. When the Process Thread is not running,
96 // (and only then) they can be used in UpdateHistograms(), usually called from
97 // the dtor.
98 int64_t sum_avg_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
99 int64_t num_avg_rtt_ RTC_GUARDED_BY(process_thread_checker_);
100 int64_t time_of_first_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000101
102 // All Rtt reports within valid time interval, oldest first.
Tommi38c5d932018-03-27 23:11:09 +0200103 std::list<RttTime> reports_ RTC_GUARDED_BY(process_thread_checker_);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000104
105 // Observers getting stats reports.
Tommi38c5d932018-03-27 23:11:09 +0200106 // When attached to ProcessThread, this is read-only. In order to allow
107 // modification, we detach from the process thread while the observer
108 // list is updated, to avoid races. This allows us to not require a lock
109 // for the observers_ list, which makes the most common case lock free.
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +0000110 std::list<CallStatsObserver*> observers_;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000111
Tommi38c5d932018-03-27 23:11:09 +0200112 rtc::ThreadChecker construction_thread_checker_;
113 rtc::ThreadChecker process_thread_checker_;
114 ProcessThread* const process_thread_;
115 bool process_thread_running_ RTC_GUARDED_BY(construction_thread_checker_);
116
henrikg3c089d72015-09-16 05:37:44 -0700117 RTC_DISALLOW_COPY_AND_ASSIGN(CallStats);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000118};
119
120} // namespace webrtc
121
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200122#endif // VIDEO_CALL_STATS_H_