1e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org/* 2e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org * 4e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org * Use of this source code is governed by a BSD-style license 5e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org * that can be found in the LICENSE file in the root of the source 6e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org * tree. An additional intellectual property rights grant can be found 7e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org * in the file PATENTS. All contributing project authors may 8e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org */ 10e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 11e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/video_engine/call_stats.h" 12e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> 14e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 15e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" 16e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 17e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h" 18e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 19e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgnamespace webrtc { 20e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 21e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org// A rtt report is considered valid for this long. 22e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgconst int kRttTimeoutMs = 1500; 23e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org// Time interval for updating the observers. 24e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgconst int kUpdateIntervalMs = 1000; 25e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 26c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.orgclass RtcpObserver : public RtcpRttStats { 27e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org public: 28e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org explicit RtcpObserver(CallStats* owner) : owner_(owner) {} 29e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org virtual ~RtcpObserver() {} 30e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 31e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org virtual void OnRttUpdate(uint32_t rtt) { 32e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org owner_->OnRttUpdate(rtt); 33e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org } 34e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 35c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org virtual uint32_t LastProcessedRtt() const { 36c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org return owner_->last_processed_rtt_ms(); 37c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org } 38c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org 39e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org private: 40e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org CallStats* owner_; 41e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 42e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org DISALLOW_COPY_AND_ASSIGN(RtcpObserver); 43e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org}; 44e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 45e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgCallStats::CallStats() 46e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org : crit_(CriticalSectionWrapper::CreateCriticalSection()), 47c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org rtcp_rtt_stats_(new RtcpObserver(this)), 48c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org last_process_time_(TickTime::MillisecondTimestamp()), 49c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org last_processed_rtt_ms_(0) { 50e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 51e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 52e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgCallStats::~CallStats() { 53e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org assert(observers_.empty()); 54e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 55e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 56e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgint32_t CallStats::TimeUntilNextProcess() { 57e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org return last_process_time_ + kUpdateIntervalMs - 58e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org TickTime::MillisecondTimestamp(); 59e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 60e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 61e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgint32_t CallStats::Process() { 62e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org CriticalSectionScoped cs(crit_.get()); 63e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org if (TickTime::MillisecondTimestamp() < last_process_time_ + kUpdateIntervalMs) 64e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org return 0; 65e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 66e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org // Remove invalid, as in too old, rtt values. 67e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org int64_t time_now = TickTime::MillisecondTimestamp(); 68e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org while (!reports_.empty() && reports_.front().time + kRttTimeoutMs < 69e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org time_now) { 70e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org reports_.pop_front(); 71e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org } 72e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 73e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org // Find the max stored RTT. 74e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org uint32_t max_rtt = 0; 75e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org for (std::list<RttTime>::const_iterator it = reports_.begin(); 76e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org it != reports_.end(); ++it) { 77e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org if (it->rtt > max_rtt) 78e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org max_rtt = it->rtt; 79e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org } 80d430f32c82239970bc7130bdb3fd8ba3ed2dde2fstefan@webrtc.org 8127881074fb7affae4d4c3e0def3a01c792b75d1dstefan@webrtc.org // If there is a valid rtt, update all observers. 82d430f32c82239970bc7130bdb3fd8ba3ed2dde2fstefan@webrtc.org if (max_rtt > 0) { 83d430f32c82239970bc7130bdb3fd8ba3ed2dde2fstefan@webrtc.org for (std::list<CallStatsObserver*>::iterator it = observers_.begin(); 84d430f32c82239970bc7130bdb3fd8ba3ed2dde2fstefan@webrtc.org it != observers_.end(); ++it) { 85d430f32c82239970bc7130bdb3fd8ba3ed2dde2fstefan@webrtc.org (*it)->OnRttUpdate(max_rtt); 86d430f32c82239970bc7130bdb3fd8ba3ed2dde2fstefan@webrtc.org } 87e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org } 88c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org last_processed_rtt_ms_ = max_rtt; 89e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org last_process_time_ = time_now; 90e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org return 0; 91e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 92e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 93c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.orguint32_t CallStats::last_processed_rtt_ms() const { 94c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org CriticalSectionScoped cs(crit_.get()); 95c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org return last_processed_rtt_ms_; 96c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org} 97c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org 98c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.orgRtcpRttStats* CallStats::rtcp_rtt_stats() const { 99c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org return rtcp_rtt_stats_.get(); 100e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 101e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 1020329e591cd17957836fd295ae9b31f7d3a73e5e8fischman@webrtc.orgvoid CallStats::RegisterStatsObserver(CallStatsObserver* observer) { 103e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org CriticalSectionScoped cs(crit_.get()); 1040329e591cd17957836fd295ae9b31f7d3a73e5e8fischman@webrtc.org for (std::list<CallStatsObserver*>::iterator it = observers_.begin(); 105e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org it != observers_.end(); ++it) { 106e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org if (*it == observer) 107e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org return; 108e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org } 109e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org observers_.push_back(observer); 110e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 111e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 1120329e591cd17957836fd295ae9b31f7d3a73e5e8fischman@webrtc.orgvoid CallStats::DeregisterStatsObserver(CallStatsObserver* observer) { 113e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org CriticalSectionScoped cs(crit_.get()); 1140329e591cd17957836fd295ae9b31f7d3a73e5e8fischman@webrtc.org for (std::list<CallStatsObserver*>::iterator it = observers_.begin(); 115e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org it != observers_.end(); ++it) { 116e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org if (*it == observer) { 117e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org observers_.erase(it); 118e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org return; 119e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org } 120e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org } 121e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 122e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 123e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgvoid CallStats::OnRttUpdate(uint32_t rtt) { 124e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org CriticalSectionScoped cs(crit_.get()); 125e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org int64_t time_now = TickTime::MillisecondTimestamp(); 126e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org reports_.push_back(RttTime(rtt, time_now)); 127e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} 128e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org 129e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org} // namespace webrtc 130