blob: 822685320f67c042e7b904c325ab78d72740c009 [file] [log] [blame]
Tommi822a8742020-05-10 22:42:301/*
2 * Copyright (c) 2020 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#ifndef VIDEO_CALL_STATS2_H_
12#define VIDEO_CALL_STATS2_H_
13
14#include <list>
15#include <memory>
16
Tommia0a44802020-05-13 16:27:2617#include "api/units/timestamp.h"
Tommi822a8742020-05-10 22:42:3018#include "modules/include/module_common_types.h"
19#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
20#include "rtc_base/constructor_magic.h"
Tommi822a8742020-05-10 22:42:3021#include "rtc_base/synchronization/sequence_checker.h"
22#include "rtc_base/task_queue.h"
23#include "rtc_base/task_utils/pending_task_safety_flag.h"
Tommia0a44802020-05-13 16:27:2624#include "rtc_base/task_utils/repeating_task.h"
Tommi822a8742020-05-10 22:42:3025#include "system_wrappers/include/clock.h"
26
27namespace webrtc {
28namespace internal {
29
30class CallStats {
31 public:
32 // Time interval for updating the observers.
Tommia0a44802020-05-13 16:27:2633 static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(1000);
Tommi822a8742020-05-10 22:42:3034
35 CallStats(Clock* clock, TaskQueueBase* task_queue);
36 ~CallStats();
37
38 // Expose an RtcpRttStats implementation without inheriting from RtcpRttStats.
39 // That allows us to separate the threading model of how RtcpRttStats is
40 // used (mostly on a process thread) and how CallStats is used (mostly on
41 // the TQ/worker thread). Since for both cases, there is a LastProcessedRtt()
42 // method, this separation allows us to not need a lock for either.
43 RtcpRttStats* AsRtcpRttStats() { return &rtcp_rtt_stats_impl_; }
44
45 // Registers/deregisters a new observer to receive statistics updates.
46 // Must be called from the construction thread.
47 void RegisterStatsObserver(CallStatsObserver* observer);
48 void DeregisterStatsObserver(CallStatsObserver* observer);
49
50 // Expose |LastProcessedRtt()| from RtcpRttStats to the public interface, as
51 // it is the part of the API that is needed by direct users of CallStats.
52 // TODO(tommi): Threading or lifetime guarantees are not explicit in how
53 // CallStats is used as RtcpRttStats or how pointers are cached in a
54 // few different places (distributed via Call). It would be good to clarify
55 // from what thread/TQ calls to OnRttUpdate and LastProcessedRtt need to be
56 // allowed.
57 int64_t LastProcessedRtt() const;
58
59 // Exposed for tests to test histogram support.
60 void UpdateHistogramsForTest() { UpdateHistograms(); }
61
62 // Helper struct keeping track of the time a rtt value is reported.
63 struct RttTime {
64 RttTime(int64_t new_rtt, int64_t rtt_time) : rtt(new_rtt), time(rtt_time) {}
65 const int64_t rtt;
66 const int64_t time;
67 };
68
69 private:
70 // Part of the RtcpRttStats implementation. Called by RtcpRttStatsImpl.
71 void OnRttUpdate(int64_t rtt);
Tommi822a8742020-05-10 22:42:3072
Tommi822a8742020-05-10 22:42:3073 void UpdateAndReport();
74
75 // This method must only be called when the process thread is not
76 // running, and from the construction thread.
77 void UpdateHistograms();
78
79 class RtcpRttStatsImpl : public RtcpRttStats {
80 public:
Tomas Gunnarssonba0ba712020-07-01 06:53:2181 explicit RtcpRttStatsImpl(CallStats* owner) : owner_(owner) {}
Tommi822a8742020-05-10 22:42:3082 ~RtcpRttStatsImpl() override = default;
83
84 private:
85 void OnRttUpdate(int64_t rtt) override {
Tomas Gunnarssonba0ba712020-07-01 06:53:2186 // For video send streams (video/video_send_stream.cc), the RtpRtcp module
87 // is currently created on a transport worker TaskQueue and not the worker
88 // thread - which is what happens in other cases. We should probably fix
89 // that so that the call consistently comes in on the right thread.
Tommi822a8742020-05-10 22:42:3090 owner_->OnRttUpdate(rtt);
91 }
92
93 int64_t LastProcessedRtt() const override {
Tomas Gunnarssonba0ba712020-07-01 06:53:2194 // This call path shouldn't be used anymore. This impl is only for
95 // propagating the rtt from the RtpRtcp module, which does not call
96 // LastProcessedRtt(). Down the line we should consider removing
97 // LastProcessedRtt() and use the interface for event notifications only.
98 RTC_NOTREACHED() << "Legacy call path";
99 return 0;
Tommi822a8742020-05-10 22:42:30100 }
101
102 CallStats* const owner_;
Tommi822a8742020-05-10 22:42:30103 } rtcp_rtt_stats_impl_{this};
104
105 Clock* const clock_;
106
Tommia0a44802020-05-13 16:27:26107 // Used to regularly call UpdateAndReport().
108 RepeatingTaskHandle repeating_task_
109 RTC_GUARDED_BY(construction_thread_checker_);
110
Tommi822a8742020-05-10 22:42:30111 // The last RTT in the statistics update (zero if there is no valid estimate).
112 int64_t max_rtt_ms_ RTC_GUARDED_BY(construction_thread_checker_);
113
Tomas Gunnarssonba0ba712020-07-01 06:53:21114 // Last reported average RTT value.
115 int64_t avg_rtt_ms_ RTC_GUARDED_BY(construction_thread_checker_);
Tommi822a8742020-05-10 22:42:30116
117 // |sum_avg_rtt_ms_|, |num_avg_rtt_| and |time_of_first_rtt_ms_| are only used
118 // on the ProcessThread when running. When the Process Thread is not running,
119 // (and only then) they can be used in UpdateHistograms(), usually called from
120 // the dtor.
121 int64_t sum_avg_rtt_ms_ RTC_GUARDED_BY(construction_thread_checker_);
122 int64_t num_avg_rtt_ RTC_GUARDED_BY(construction_thread_checker_);
123 int64_t time_of_first_rtt_ms_ RTC_GUARDED_BY(construction_thread_checker_);
124
125 // All Rtt reports within valid time interval, oldest first.
126 std::list<RttTime> reports_ RTC_GUARDED_BY(construction_thread_checker_);
127
128 // Observers getting stats reports.
129 // When attached to ProcessThread, this is read-only. In order to allow
130 // modification, we detach from the process thread while the observer
131 // list is updated, to avoid races. This allows us to not require a lock
132 // for the observers_ list, which makes the most common case lock free.
133 std::list<CallStatsObserver*> observers_;
134
135 SequenceChecker construction_thread_checker_;
136 SequenceChecker process_thread_checker_;
137 TaskQueueBase* const task_queue_;
138
139 // Used to signal destruction to potentially pending tasks.
Tommia98cea82020-05-13 13:06:19140 ScopedTaskSafety task_safety_;
Tommi822a8742020-05-10 22:42:30141
142 RTC_DISALLOW_COPY_AND_ASSIGN(CallStats);
143};
144
145} // namespace internal
146} // namespace webrtc
147
148#endif // VIDEO_CALL_STATS2_H_