blob: 823c33602b5d6158040effc991775d5b31bf948a [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
11#include "webrtc/video_engine/call_stats.h"
12
13#include <cassert>
14
15#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
16#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
17#include "webrtc/system_wrappers/interface/tick_util.h"
18#include "webrtc/system_wrappers/interface/trace.h"
19
20namespace webrtc {
21
22// A rtt report is considered valid for this long.
23const int kRttTimeoutMs = 1500;
24// Time interval for updating the observers.
25const int kUpdateIntervalMs = 1000;
stefan@webrtc.orgccd4b2a2013-04-23 15:58:23 +000026const uint32_t kInitialRttMs = 200;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000027
28class RtcpObserver : public RtcpRttObserver {
29 public:
30 explicit RtcpObserver(CallStats* owner) : owner_(owner) {}
31 virtual ~RtcpObserver() {}
32
33 virtual void OnRttUpdate(uint32_t rtt) {
34 owner_->OnRttUpdate(rtt);
35 }
36
37 private:
38 CallStats* owner_;
39
40 DISALLOW_COPY_AND_ASSIGN(RtcpObserver);
41};
42
43CallStats::CallStats()
44 : crit_(CriticalSectionWrapper::CreateCriticalSection()),
45 rtcp_rtt_observer_(new RtcpObserver(this)),
stefan@webrtc.orgccd4b2a2013-04-23 15:58:23 +000046 last_process_time_(TickTime::MillisecondTimestamp()),
47 last_reported_rtt_(kInitialRttMs),
48 rtt_report_received_(false) {
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000049}
50
51CallStats::~CallStats() {
52 assert(observers_.empty());
53}
54
55int32_t CallStats::TimeUntilNextProcess() {
56 return last_process_time_ + kUpdateIntervalMs -
57 TickTime::MillisecondTimestamp();
58}
59
60int32_t CallStats::Process() {
61 CriticalSectionScoped cs(crit_.get());
62 if (TickTime::MillisecondTimestamp() < last_process_time_ + kUpdateIntervalMs)
63 return 0;
64
65 // Remove invalid, as in too old, rtt values.
66 int64_t time_now = TickTime::MillisecondTimestamp();
67 while (!reports_.empty() && reports_.front().time + kRttTimeoutMs <
68 time_now) {
69 reports_.pop_front();
70 }
71
72 // Find the max stored RTT.
73 uint32_t max_rtt = 0;
74 for (std::list<RttTime>::const_iterator it = reports_.begin();
75 it != reports_.end(); ++it) {
76 if (it->rtt > max_rtt)
77 max_rtt = it->rtt;
78 }
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000079 if (max_rtt > 0) {
stefan@webrtc.orgccd4b2a2013-04-23 15:58:23 +000080 last_reported_rtt_ = max_rtt;
81 }
82 // If there is a valid rtt, update all observers.
83 for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
84 it != observers_.end(); ++it) {
85 (*it)->OnRttUpdate(last_reported_rtt_);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000086 }
87 last_process_time_ = time_now;
88 return 0;
89}
90
91RtcpRttObserver* CallStats::rtcp_rtt_observer() const {
92 return rtcp_rtt_observer_.get();
93}
94
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +000095void CallStats::RegisterStatsObserver(CallStatsObserver* observer) {
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000096 CriticalSectionScoped cs(crit_.get());
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +000097 for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000098 it != observers_.end(); ++it) {
99 if (*it == observer)
100 return;
101 }
102 observers_.push_back(observer);
103}
104
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +0000105void CallStats::DeregisterStatsObserver(CallStatsObserver* observer) {
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000106 CriticalSectionScoped cs(crit_.get());
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +0000107 for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000108 it != observers_.end(); ++it) {
109 if (*it == observer) {
110 observers_.erase(it);
111 return;
112 }
113 }
114}
115
116void CallStats::OnRttUpdate(uint32_t rtt) {
117 CriticalSectionScoped cs(crit_.get());
118 int64_t time_now = TickTime::MillisecondTimestamp();
119 reports_.push_back(RttTime(rtt, time_now));
stefan@webrtc.orgccd4b2a2013-04-23 15:58:23 +0000120 rtt_report_received_ = true;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000121}
122
123} // namespace webrtc