blob: 5029453bf791d839a024cbee19fd6f96db463c05 [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"
Niels Möller834a5542019-09-23 10:31:16 +020018#include "modules/include/module_common_types.h"
Tommi38c5d932018-03-27 23:11:09 +020019#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/constructor_magic.h"
21#include "rtc_base/critical_section.h"
Tommi38c5d932018-03-27 23:11:09 +020022#include "rtc_base/thread_checker.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "system_wrappers/include/clock.h"
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000024
25namespace webrtc {
26
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000027// CallStats keeps track of statistics for a call.
Tommi38c5d932018-03-27 23:11:09 +020028class CallStats : public Module, public RtcpRttStats {
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000029 public:
Tommi38c5d932018-03-27 23:11:09 +020030 // Time interval for updating the observers.
31 static constexpr int64_t kUpdateIntervalMs = 1000;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000032
Tommi38c5d932018-03-27 23:11:09 +020033 CallStats(Clock* clock, ProcessThread* process_thread);
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020034 ~CallStats() override;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000035
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000036 // Registers/deregisters a new observer to receive statistics updates.
Tommi38c5d932018-03-27 23:11:09 +020037 // Must be called from the construction thread.
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +000038 void RegisterStatsObserver(CallStatsObserver* observer);
39 void DeregisterStatsObserver(CallStatsObserver* observer);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000040
Tommi38c5d932018-03-27 23:11:09 +020041 // Expose |LastProcessedRtt()| from RtcpRttStats to the public interface, as
42 // it is the part of the API that is needed by direct users of CallStats.
43 // TODO(tommi): Threading or lifetime guarantees are not explicit in how
44 // CallStats is used as RtcpRttStats or how pointers are cached in a
45 // few different places (distributed via Call). It would be good to clarify
46 // from what thread/TQ calls to OnRttUpdate and LastProcessedRtt need to be
47 // allowed.
48 int64_t LastProcessedRtt() const override;
49
50 // Exposed for tests to test histogram support.
51 void UpdateHistogramsForTest() { UpdateHistograms(); }
52
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000053 // Helper struct keeping track of the time a rtt value is reported.
54 struct RttTime {
Yves Gerey665174f2018-06-19 15:03:05 +020055 RttTime(int64_t new_rtt, int64_t rtt_time) : rtt(new_rtt), time(rtt_time) {}
pkasting@chromium.org16825b12015-01-12 21:51:21 +000056 const int64_t rtt;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000057 const int64_t time;
58 };
59
asapersson@webrtc.org8084f952014-12-10 11:04:13 +000060 private:
Tommi38c5d932018-03-27 23:11:09 +020061 // RtcpRttStats implementation.
62 void OnRttUpdate(int64_t rtt) override;
63
64 // Implements Module, to use the process thread.
65 int64_t TimeUntilNextProcess() override;
66 void Process() override;
67
68 // TODO(tommi): Use this to know when we're attached to the process thread?
69 // Alternatively, inject that pointer via the ctor since the call_stats
70 // test code, isn't using a processthread atm.
71 void ProcessThreadAttached(ProcessThread* process_thread) override;
72
73 // This method must only be called when the process thread is not
74 // running, and from the construction thread.
sprange2d83d62016-02-19 09:03:26 -080075 void UpdateHistograms();
76
Peter Boströmd3c94472015-12-09 11:20:58 +010077 Clock* const clock_;
Tommi38c5d932018-03-27 23:11:09 +020078
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000079 // The last time 'Process' resulted in statistic update.
Tommi38c5d932018-03-27 23:11:09 +020080 int64_t last_process_time_ RTC_GUARDED_BY(process_thread_checker_);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000081 // The last RTT in the statistics update (zero if there is no valid estimate).
Tommi38c5d932018-03-27 23:11:09 +020082 int64_t max_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
83
84 // Accessed from random threads (seemingly). Consider atomic.
85 // |avg_rtt_ms_| is allowed to be read on the process thread without a lock.
86 // |avg_rtt_ms_lock_| must be held elsewhere for reading.
87 // |avg_rtt_ms_lock_| must be held on the process thread for writing.
pkasting@chromium.org16825b12015-01-12 21:51:21 +000088 int64_t avg_rtt_ms_;
Tommi38c5d932018-03-27 23:11:09 +020089
90 // Protects |avg_rtt_ms_|.
91 rtc::CriticalSection avg_rtt_ms_lock_;
92
93 // |sum_avg_rtt_ms_|, |num_avg_rtt_| and |time_of_first_rtt_ms_| are only used
94 // on the ProcessThread when running. When the Process Thread is not running,
95 // (and only then) they can be used in UpdateHistograms(), usually called from
96 // the dtor.
97 int64_t sum_avg_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
98 int64_t num_avg_rtt_ RTC_GUARDED_BY(process_thread_checker_);
99 int64_t time_of_first_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000100
101 // All Rtt reports within valid time interval, oldest first.
Tommi38c5d932018-03-27 23:11:09 +0200102 std::list<RttTime> reports_ RTC_GUARDED_BY(process_thread_checker_);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000103
104 // Observers getting stats reports.
Tommi38c5d932018-03-27 23:11:09 +0200105 // When attached to ProcessThread, this is read-only. In order to allow
106 // modification, we detach from the process thread while the observer
107 // list is updated, to avoid races. This allows us to not require a lock
108 // for the observers_ list, which makes the most common case lock free.
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +0000109 std::list<CallStatsObserver*> observers_;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000110
Tommi38c5d932018-03-27 23:11:09 +0200111 rtc::ThreadChecker construction_thread_checker_;
112 rtc::ThreadChecker process_thread_checker_;
113 ProcessThread* const process_thread_;
114 bool process_thread_running_ RTC_GUARDED_BY(construction_thread_checker_);
115
henrikg3c089d72015-09-16 05:37:44 -0700116 RTC_DISALLOW_COPY_AND_ASSIGN(CallStats);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000117};
118
119} // namespace webrtc
120
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200121#endif // VIDEO_CALL_STATS_H_