• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include "api/task_queue/pending_task_safety_flag.h"
18 #include "api/task_queue/task_queue_base.h"
19 #include "api/units/timestamp.h"
20 #include "modules/include/module_common_types.h"
21 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
22 #include "rtc_base/task_utils/repeating_task.h"
23 #include "system_wrappers/include/clock.h"
24 
25 namespace webrtc {
26 namespace internal {
27 
28 class CallStats {
29  public:
30   // Time interval for updating the observers.
31   static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(1000);
32 
33   // Must be created and destroyed on the same task_queue.
34   CallStats(Clock* clock, TaskQueueBase* task_queue);
35   ~CallStats();
36 
37   CallStats(const CallStats&) = delete;
38   CallStats& operator=(const CallStats&) = delete;
39 
40   // Ensure that necessary repeating tasks are started.
41   void EnsureStarted();
42 
43   // Expose an RtcpRttStats implementation without inheriting from RtcpRttStats.
44   // That allows us to separate the threading model of how RtcpRttStats is
45   // used (mostly on a process thread) and how CallStats is used (mostly on
46   // the TQ/worker thread). Since for both cases, there is a LastProcessedRtt()
47   // method, this separation allows us to not need a lock for either.
AsRtcpRttStats()48   RtcpRttStats* AsRtcpRttStats() { return &rtcp_rtt_stats_impl_; }
49 
50   // Registers/deregisters a new observer to receive statistics updates.
51   // Must be called from the construction thread.
52   void RegisterStatsObserver(CallStatsObserver* observer);
53   void DeregisterStatsObserver(CallStatsObserver* observer);
54 
55   // Expose `LastProcessedRtt()` from RtcpRttStats to the public interface, as
56   // it is the part of the API that is needed by direct users of CallStats.
57   int64_t LastProcessedRtt() const;
58 
59   // Exposed for tests to test histogram support.
UpdateHistogramsForTest()60   void UpdateHistogramsForTest() { UpdateHistograms(); }
61 
62   // Helper struct keeping track of the time a rtt value is reported.
63   struct RttTime {
RttTimeRttTime64     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);
72 
73   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:
RtcpRttStatsImpl(CallStats * owner)81     explicit RtcpRttStatsImpl(CallStats* owner) : owner_(owner) {}
82     ~RtcpRttStatsImpl() override = default;
83 
84    private:
OnRttUpdate(int64_t rtt)85     void OnRttUpdate(int64_t rtt) override {
86       // 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.
90       owner_->OnRttUpdate(rtt);
91     }
92 
LastProcessedRtt()93     int64_t LastProcessedRtt() const override {
94       // 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_DCHECK_NOTREACHED() << "Legacy call path";
99       return 0;
100     }
101 
102     CallStats* const owner_;
103   } rtcp_rtt_stats_impl_{this};
104 
105   Clock* const clock_;
106 
107   // Used to regularly call UpdateAndReport().
108   RepeatingTaskHandle repeating_task_ RTC_GUARDED_BY(task_queue_);
109 
110   // The last RTT in the statistics update (zero if there is no valid estimate).
111   int64_t max_rtt_ms_ RTC_GUARDED_BY(task_queue_);
112 
113   // Last reported average RTT value.
114   int64_t avg_rtt_ms_ RTC_GUARDED_BY(task_queue_);
115 
116   int64_t sum_avg_rtt_ms_ RTC_GUARDED_BY(task_queue_);
117   int64_t num_avg_rtt_ RTC_GUARDED_BY(task_queue_);
118   int64_t time_of_first_rtt_ms_ RTC_GUARDED_BY(task_queue_);
119 
120   // All Rtt reports within valid time interval, oldest first.
121   std::list<RttTime> reports_ RTC_GUARDED_BY(task_queue_);
122 
123   // Observers getting stats reports.
124   std::list<CallStatsObserver*> observers_ RTC_GUARDED_BY(task_queue_);
125 
126   TaskQueueBase* const task_queue_;
127 
128   // Used to signal destruction to potentially pending tasks.
129   ScopedTaskSafety task_safety_;
130 };
131 
132 }  // namespace internal
133 }  // namespace webrtc
134 
135 #endif  // VIDEO_CALL_STATS2_H_
136