1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef VIDEO_CALL_STATS2_H_ 12*d9f75844SAndroid Build Coastguard Worker #define VIDEO_CALL_STATS2_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <list> 15*d9f75844SAndroid Build Coastguard Worker #include <memory> 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/pending_task_safety_flag.h" 18*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h" 19*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h" 20*d9f75844SAndroid Build Coastguard Worker #include "modules/include/module_common_types.h" 21*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_utils/repeating_task.h" 23*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h" 24*d9f75844SAndroid Build Coastguard Worker 25*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 26*d9f75844SAndroid Build Coastguard Worker namespace internal { 27*d9f75844SAndroid Build Coastguard Worker 28*d9f75844SAndroid Build Coastguard Worker class CallStats { 29*d9f75844SAndroid Build Coastguard Worker public: 30*d9f75844SAndroid Build Coastguard Worker // Time interval for updating the observers. 31*d9f75844SAndroid Build Coastguard Worker static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(1000); 32*d9f75844SAndroid Build Coastguard Worker 33*d9f75844SAndroid Build Coastguard Worker // Must be created and destroyed on the same task_queue. 34*d9f75844SAndroid Build Coastguard Worker CallStats(Clock* clock, TaskQueueBase* task_queue); 35*d9f75844SAndroid Build Coastguard Worker ~CallStats(); 36*d9f75844SAndroid Build Coastguard Worker 37*d9f75844SAndroid Build Coastguard Worker CallStats(const CallStats&) = delete; 38*d9f75844SAndroid Build Coastguard Worker CallStats& operator=(const CallStats&) = delete; 39*d9f75844SAndroid Build Coastguard Worker 40*d9f75844SAndroid Build Coastguard Worker // Ensure that necessary repeating tasks are started. 41*d9f75844SAndroid Build Coastguard Worker void EnsureStarted(); 42*d9f75844SAndroid Build Coastguard Worker 43*d9f75844SAndroid Build Coastguard Worker // Expose an RtcpRttStats implementation without inheriting from RtcpRttStats. 44*d9f75844SAndroid Build Coastguard Worker // That allows us to separate the threading model of how RtcpRttStats is 45*d9f75844SAndroid Build Coastguard Worker // used (mostly on a process thread) and how CallStats is used (mostly on 46*d9f75844SAndroid Build Coastguard Worker // the TQ/worker thread). Since for both cases, there is a LastProcessedRtt() 47*d9f75844SAndroid Build Coastguard Worker // method, this separation allows us to not need a lock for either. AsRtcpRttStats()48*d9f75844SAndroid Build Coastguard Worker RtcpRttStats* AsRtcpRttStats() { return &rtcp_rtt_stats_impl_; } 49*d9f75844SAndroid Build Coastguard Worker 50*d9f75844SAndroid Build Coastguard Worker // Registers/deregisters a new observer to receive statistics updates. 51*d9f75844SAndroid Build Coastguard Worker // Must be called from the construction thread. 52*d9f75844SAndroid Build Coastguard Worker void RegisterStatsObserver(CallStatsObserver* observer); 53*d9f75844SAndroid Build Coastguard Worker void DeregisterStatsObserver(CallStatsObserver* observer); 54*d9f75844SAndroid Build Coastguard Worker 55*d9f75844SAndroid Build Coastguard Worker // Expose `LastProcessedRtt()` from RtcpRttStats to the public interface, as 56*d9f75844SAndroid Build Coastguard Worker // it is the part of the API that is needed by direct users of CallStats. 57*d9f75844SAndroid Build Coastguard Worker int64_t LastProcessedRtt() const; 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker // Exposed for tests to test histogram support. UpdateHistogramsForTest()60*d9f75844SAndroid Build Coastguard Worker void UpdateHistogramsForTest() { UpdateHistograms(); } 61*d9f75844SAndroid Build Coastguard Worker 62*d9f75844SAndroid Build Coastguard Worker // Helper struct keeping track of the time a rtt value is reported. 63*d9f75844SAndroid Build Coastguard Worker struct RttTime { RttTimeRttTime64*d9f75844SAndroid Build Coastguard Worker RttTime(int64_t new_rtt, int64_t rtt_time) : rtt(new_rtt), time(rtt_time) {} 65*d9f75844SAndroid Build Coastguard Worker const int64_t rtt; 66*d9f75844SAndroid Build Coastguard Worker const int64_t time; 67*d9f75844SAndroid Build Coastguard Worker }; 68*d9f75844SAndroid Build Coastguard Worker 69*d9f75844SAndroid Build Coastguard Worker private: 70*d9f75844SAndroid Build Coastguard Worker // Part of the RtcpRttStats implementation. Called by RtcpRttStatsImpl. 71*d9f75844SAndroid Build Coastguard Worker void OnRttUpdate(int64_t rtt); 72*d9f75844SAndroid Build Coastguard Worker 73*d9f75844SAndroid Build Coastguard Worker void UpdateAndReport(); 74*d9f75844SAndroid Build Coastguard Worker 75*d9f75844SAndroid Build Coastguard Worker // This method must only be called when the process thread is not 76*d9f75844SAndroid Build Coastguard Worker // running, and from the construction thread. 77*d9f75844SAndroid Build Coastguard Worker void UpdateHistograms(); 78*d9f75844SAndroid Build Coastguard Worker 79*d9f75844SAndroid Build Coastguard Worker class RtcpRttStatsImpl : public RtcpRttStats { 80*d9f75844SAndroid Build Coastguard Worker public: RtcpRttStatsImpl(CallStats * owner)81*d9f75844SAndroid Build Coastguard Worker explicit RtcpRttStatsImpl(CallStats* owner) : owner_(owner) {} 82*d9f75844SAndroid Build Coastguard Worker ~RtcpRttStatsImpl() override = default; 83*d9f75844SAndroid Build Coastguard Worker 84*d9f75844SAndroid Build Coastguard Worker private: OnRttUpdate(int64_t rtt)85*d9f75844SAndroid Build Coastguard Worker void OnRttUpdate(int64_t rtt) override { 86*d9f75844SAndroid Build Coastguard Worker // For video send streams (video/video_send_stream.cc), the RtpRtcp module 87*d9f75844SAndroid Build Coastguard Worker // is currently created on a transport worker TaskQueue and not the worker 88*d9f75844SAndroid Build Coastguard Worker // thread - which is what happens in other cases. We should probably fix 89*d9f75844SAndroid Build Coastguard Worker // that so that the call consistently comes in on the right thread. 90*d9f75844SAndroid Build Coastguard Worker owner_->OnRttUpdate(rtt); 91*d9f75844SAndroid Build Coastguard Worker } 92*d9f75844SAndroid Build Coastguard Worker LastProcessedRtt()93*d9f75844SAndroid Build Coastguard Worker int64_t LastProcessedRtt() const override { 94*d9f75844SAndroid Build Coastguard Worker // This call path shouldn't be used anymore. This impl is only for 95*d9f75844SAndroid Build Coastguard Worker // propagating the rtt from the RtpRtcp module, which does not call 96*d9f75844SAndroid Build Coastguard Worker // LastProcessedRtt(). Down the line we should consider removing 97*d9f75844SAndroid Build Coastguard Worker // LastProcessedRtt() and use the interface for event notifications only. 98*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_NOTREACHED() << "Legacy call path"; 99*d9f75844SAndroid Build Coastguard Worker return 0; 100*d9f75844SAndroid Build Coastguard Worker } 101*d9f75844SAndroid Build Coastguard Worker 102*d9f75844SAndroid Build Coastguard Worker CallStats* const owner_; 103*d9f75844SAndroid Build Coastguard Worker } rtcp_rtt_stats_impl_{this}; 104*d9f75844SAndroid Build Coastguard Worker 105*d9f75844SAndroid Build Coastguard Worker Clock* const clock_; 106*d9f75844SAndroid Build Coastguard Worker 107*d9f75844SAndroid Build Coastguard Worker // Used to regularly call UpdateAndReport(). 108*d9f75844SAndroid Build Coastguard Worker RepeatingTaskHandle repeating_task_ RTC_GUARDED_BY(task_queue_); 109*d9f75844SAndroid Build Coastguard Worker 110*d9f75844SAndroid Build Coastguard Worker // The last RTT in the statistics update (zero if there is no valid estimate). 111*d9f75844SAndroid Build Coastguard Worker int64_t max_rtt_ms_ RTC_GUARDED_BY(task_queue_); 112*d9f75844SAndroid Build Coastguard Worker 113*d9f75844SAndroid Build Coastguard Worker // Last reported average RTT value. 114*d9f75844SAndroid Build Coastguard Worker int64_t avg_rtt_ms_ RTC_GUARDED_BY(task_queue_); 115*d9f75844SAndroid Build Coastguard Worker 116*d9f75844SAndroid Build Coastguard Worker int64_t sum_avg_rtt_ms_ RTC_GUARDED_BY(task_queue_); 117*d9f75844SAndroid Build Coastguard Worker int64_t num_avg_rtt_ RTC_GUARDED_BY(task_queue_); 118*d9f75844SAndroid Build Coastguard Worker int64_t time_of_first_rtt_ms_ RTC_GUARDED_BY(task_queue_); 119*d9f75844SAndroid Build Coastguard Worker 120*d9f75844SAndroid Build Coastguard Worker // All Rtt reports within valid time interval, oldest first. 121*d9f75844SAndroid Build Coastguard Worker std::list<RttTime> reports_ RTC_GUARDED_BY(task_queue_); 122*d9f75844SAndroid Build Coastguard Worker 123*d9f75844SAndroid Build Coastguard Worker // Observers getting stats reports. 124*d9f75844SAndroid Build Coastguard Worker std::list<CallStatsObserver*> observers_ RTC_GUARDED_BY(task_queue_); 125*d9f75844SAndroid Build Coastguard Worker 126*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* const task_queue_; 127*d9f75844SAndroid Build Coastguard Worker 128*d9f75844SAndroid Build Coastguard Worker // Used to signal destruction to potentially pending tasks. 129*d9f75844SAndroid Build Coastguard Worker ScopedTaskSafety task_safety_; 130*d9f75844SAndroid Build Coastguard Worker }; 131*d9f75844SAndroid Build Coastguard Worker 132*d9f75844SAndroid Build Coastguard Worker } // namespace internal 133*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 134*d9f75844SAndroid Build Coastguard Worker 135*d9f75844SAndroid Build Coastguard Worker #endif // VIDEO_CALL_STATS2_H_ 136