Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / video_engine / call_stats.cc
1 /*
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 <assert.h>
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
19 namespace webrtc {
20
21 // A rtt report is considered valid for this long.
22 const int kRttTimeoutMs = 1500;
23 // Time interval for updating the observers.
24 const int kUpdateIntervalMs = 1000;
25
26 class RtcpObserver : public RtcpRttStats {
27  public:
28   explicit RtcpObserver(CallStats* owner) : owner_(owner) {}
29   virtual ~RtcpObserver() {}
30
31   virtual void OnRttUpdate(uint32_t rtt) {
32     owner_->OnRttUpdate(rtt);
33   }
34
35   virtual uint32_t LastProcessedRtt() const {
36     return owner_->last_processed_rtt_ms();
37   }
38
39  private:
40   CallStats* owner_;
41
42   DISALLOW_COPY_AND_ASSIGN(RtcpObserver);
43 };
44
45 CallStats::CallStats()
46     : crit_(CriticalSectionWrapper::CreateCriticalSection()),
47       rtcp_rtt_stats_(new RtcpObserver(this)),
48       last_process_time_(TickTime::MillisecondTimestamp()),
49       last_processed_rtt_ms_(0) {
50 }
51
52 CallStats::~CallStats() {
53   assert(observers_.empty());
54 }
55
56 int32_t CallStats::TimeUntilNextProcess() {
57   return last_process_time_ + kUpdateIntervalMs -
58       TickTime::MillisecondTimestamp();
59 }
60
61 int32_t CallStats::Process() {
62   CriticalSectionScoped cs(crit_.get());
63   if (TickTime::MillisecondTimestamp() < last_process_time_ + kUpdateIntervalMs)
64     return 0;
65
66   // Remove invalid, as in too old, rtt values.
67   int64_t time_now = TickTime::MillisecondTimestamp();
68   while (!reports_.empty() && reports_.front().time + kRttTimeoutMs <
69          time_now) {
70     reports_.pop_front();
71   }
72
73   // Find the max stored RTT.
74   uint32_t max_rtt = 0;
75   for (std::list<RttTime>::const_iterator it = reports_.begin();
76        it != reports_.end(); ++it) {
77     if (it->rtt > max_rtt)
78       max_rtt = it->rtt;
79   }
80
81   // If there is a valid rtt, update all observers.
82   if (max_rtt > 0) {
83     for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
84          it != observers_.end(); ++it) {
85       (*it)->OnRttUpdate(max_rtt);
86     }
87   }
88   last_processed_rtt_ms_ = max_rtt;
89   last_process_time_ = time_now;
90   return 0;
91 }
92
93 uint32_t CallStats::last_processed_rtt_ms() const {
94   CriticalSectionScoped cs(crit_.get());
95   return last_processed_rtt_ms_;
96 }
97
98 RtcpRttStats* CallStats::rtcp_rtt_stats() const {
99   return rtcp_rtt_stats_.get();
100 }
101
102 void CallStats::RegisterStatsObserver(CallStatsObserver* observer) {
103   CriticalSectionScoped cs(crit_.get());
104   for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
105        it != observers_.end(); ++it) {
106     if (*it == observer)
107       return;
108   }
109   observers_.push_back(observer);
110 }
111
112 void CallStats::DeregisterStatsObserver(CallStatsObserver* observer) {
113   CriticalSectionScoped cs(crit_.get());
114   for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
115        it != observers_.end(); ++it) {
116     if (*it == observer) {
117       observers_.erase(it);
118       return;
119     }
120   }
121 }
122
123 void CallStats::OnRttUpdate(uint32_t rtt) {
124   CriticalSectionScoped cs(crit_.get());
125   int64_t time_now = TickTime::MillisecondTimestamp();
126   reports_.push_back(RttTime(rtt, time_now));
127 }
128
129 }  // namespace webrtc