blob: 5ca44faba5298e0f969015c3a459a1814041f5c8 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "rtc_base/constructormagic.h"
20#include "rtc_base/criticalsection.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);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000035 ~CallStats();
36
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 {
pkasting@chromium.org16825b12015-01-12 21:51:21 +000056 RttTime(int64_t new_rtt, int64_t rtt_time)
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000057 : rtt(new_rtt), time(rtt_time) {}
pkasting@chromium.org16825b12015-01-12 21:51:21 +000058 const int64_t rtt;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000059 const int64_t time;
60 };
61
asapersson@webrtc.org8084f952014-12-10 11:04:13 +000062 private:
Tommi38c5d932018-03-27 23:11:09 +020063 // RtcpRttStats implementation.
64 void OnRttUpdate(int64_t rtt) override;
65
66 // Implements Module, to use the process thread.
67 int64_t TimeUntilNextProcess() override;
68 void Process() override;
69
70 // TODO(tommi): Use this to know when we're attached to the process thread?
71 // Alternatively, inject that pointer via the ctor since the call_stats
72 // test code, isn't using a processthread atm.
73 void ProcessThreadAttached(ProcessThread* process_thread) override;
74
75 // This method must only be called when the process thread is not
76 // running, and from the construction thread.
sprange2d83d62016-02-19 09:03:26 -080077 void UpdateHistograms();
78
Peter Boströmd3c94472015-12-09 11:20:58 +010079 Clock* const clock_;
Tommi38c5d932018-03-27 23:11:09 +020080
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000081 // The last time 'Process' resulted in statistic update.
Tommi38c5d932018-03-27 23:11:09 +020082 int64_t last_process_time_ RTC_GUARDED_BY(process_thread_checker_);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000083 // The last RTT in the statistics update (zero if there is no valid estimate).
Tommi38c5d932018-03-27 23:11:09 +020084 int64_t max_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
85
86 // Accessed from random threads (seemingly). Consider atomic.
87 // |avg_rtt_ms_| is allowed to be read on the process thread without a lock.
88 // |avg_rtt_ms_lock_| must be held elsewhere for reading.
89 // |avg_rtt_ms_lock_| must be held on the process thread for writing.
pkasting@chromium.org16825b12015-01-12 21:51:21 +000090 int64_t avg_rtt_ms_;
Tommi38c5d932018-03-27 23:11:09 +020091
92 // Protects |avg_rtt_ms_|.
93 rtc::CriticalSection avg_rtt_ms_lock_;
94
95 // |sum_avg_rtt_ms_|, |num_avg_rtt_| and |time_of_first_rtt_ms_| are only used
96 // on the ProcessThread when running. When the Process Thread is not running,
97 // (and only then) they can be used in UpdateHistograms(), usually called from
98 // the dtor.
99 int64_t sum_avg_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
100 int64_t num_avg_rtt_ RTC_GUARDED_BY(process_thread_checker_);
101 int64_t time_of_first_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000102
103 // All Rtt reports within valid time interval, oldest first.
Tommi38c5d932018-03-27 23:11:09 +0200104 std::list<RttTime> reports_ RTC_GUARDED_BY(process_thread_checker_);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000105
106 // Observers getting stats reports.
Tommi38c5d932018-03-27 23:11:09 +0200107 // When attached to ProcessThread, this is read-only. In order to allow
108 // modification, we detach from the process thread while the observer
109 // list is updated, to avoid races. This allows us to not require a lock
110 // for the observers_ list, which makes the most common case lock free.
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +0000111 std::list<CallStatsObserver*> observers_;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000112
Tommi38c5d932018-03-27 23:11:09 +0200113 rtc::ThreadChecker construction_thread_checker_;
114 rtc::ThreadChecker process_thread_checker_;
115 ProcessThread* const process_thread_;
116 bool process_thread_running_ RTC_GUARDED_BY(construction_thread_checker_);
117
henrikg3c089d72015-09-16 05:37:44 -0700118 RTC_DISALLOW_COPY_AND_ASSIGN(CallStats);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000119};
120
121} // namespace webrtc
122
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200123#endif // VIDEO_CALL_STATS_H_