Any file that uses the RTC_DISALLOW_* macros should #include "webrtc/base/constructormagic.h", but a shocking number of them don't. This causes trouble when we try to wean files off of #including scoped_ptr.h, since a bunch of files get their constructormagic macros only from there. Rather than fixing these errors one by one as they turn up, this CL simply ensures that every file in the WebRTC tree that uses the RTC_DISALLOW_* macros #includes "webrtc/base/constructormagic.h". BUG=webrtc:5520 Review URL: https://codereview.webrtc.org/1917043005 Cr-Commit-Position: refs/heads/master@{#12509}
191 lines
5.2 KiB
C++
191 lines
5.2 KiB
C++
/*
|
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/video/call_stats.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include "webrtc/base/checks.h"
|
|
#include "webrtc/base/constructormagic.h"
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
|
#include "webrtc/system_wrappers/include/metrics.h"
|
|
#include "webrtc/system_wrappers/include/tick_util.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
// Time interval for updating the observers.
|
|
const int64_t kUpdateIntervalMs = 1000;
|
|
// Weight factor to apply to the average rtt.
|
|
const float kWeightFactor = 0.3f;
|
|
|
|
void RemoveOldReports(int64_t now, std::list<CallStats::RttTime>* reports) {
|
|
// A rtt report is considered valid for this long.
|
|
const int64_t kRttTimeoutMs = 1500;
|
|
while (!reports->empty() &&
|
|
(now - reports->front().time) > kRttTimeoutMs) {
|
|
reports->pop_front();
|
|
}
|
|
}
|
|
|
|
int64_t GetMaxRttMs(std::list<CallStats::RttTime>* reports) {
|
|
if (reports->empty())
|
|
return -1;
|
|
int64_t max_rtt_ms = 0;
|
|
for (const CallStats::RttTime& rtt_time : *reports)
|
|
max_rtt_ms = std::max(rtt_time.rtt, max_rtt_ms);
|
|
return max_rtt_ms;
|
|
}
|
|
|
|
int64_t GetAvgRttMs(std::list<CallStats::RttTime>* reports) {
|
|
if (reports->empty()) {
|
|
return -1;
|
|
}
|
|
int64_t sum = 0;
|
|
for (std::list<CallStats::RttTime>::const_iterator it = reports->begin();
|
|
it != reports->end(); ++it) {
|
|
sum += it->rtt;
|
|
}
|
|
return sum / reports->size();
|
|
}
|
|
|
|
void UpdateAvgRttMs(std::list<CallStats::RttTime>* reports, int64_t* avg_rtt) {
|
|
int64_t cur_rtt_ms = GetAvgRttMs(reports);
|
|
if (cur_rtt_ms == -1) {
|
|
// Reset.
|
|
*avg_rtt = -1;
|
|
return;
|
|
}
|
|
if (*avg_rtt == -1) {
|
|
// Initialize.
|
|
*avg_rtt = cur_rtt_ms;
|
|
return;
|
|
}
|
|
*avg_rtt = *avg_rtt * (1.0f - kWeightFactor) + cur_rtt_ms * kWeightFactor;
|
|
}
|
|
} // namespace
|
|
|
|
class RtcpObserver : public RtcpRttStats {
|
|
public:
|
|
explicit RtcpObserver(CallStats* owner) : owner_(owner) {}
|
|
virtual ~RtcpObserver() {}
|
|
|
|
virtual void OnRttUpdate(int64_t rtt) {
|
|
owner_->OnRttUpdate(rtt);
|
|
}
|
|
|
|
// Returns the average RTT.
|
|
virtual int64_t LastProcessedRtt() const {
|
|
return owner_->avg_rtt_ms();
|
|
}
|
|
|
|
private:
|
|
CallStats* owner_;
|
|
|
|
RTC_DISALLOW_COPY_AND_ASSIGN(RtcpObserver);
|
|
};
|
|
|
|
CallStats::CallStats(Clock* clock)
|
|
: clock_(clock),
|
|
rtcp_rtt_stats_(new RtcpObserver(this)),
|
|
last_process_time_(clock_->TimeInMilliseconds()),
|
|
max_rtt_ms_(-1),
|
|
avg_rtt_ms_(-1),
|
|
sum_avg_rtt_ms_(0),
|
|
num_avg_rtt_(0),
|
|
time_of_first_rtt_ms_(-1) {}
|
|
|
|
CallStats::~CallStats() {
|
|
RTC_DCHECK(observers_.empty());
|
|
UpdateHistograms();
|
|
}
|
|
|
|
int64_t CallStats::TimeUntilNextProcess() {
|
|
return last_process_time_ + kUpdateIntervalMs - clock_->TimeInMilliseconds();
|
|
}
|
|
|
|
void CallStats::Process() {
|
|
rtc::CritScope cs(&crit_);
|
|
int64_t now = clock_->TimeInMilliseconds();
|
|
if (now < last_process_time_ + kUpdateIntervalMs)
|
|
return;
|
|
|
|
last_process_time_ = now;
|
|
|
|
RemoveOldReports(now, &reports_);
|
|
max_rtt_ms_ = GetMaxRttMs(&reports_);
|
|
UpdateAvgRttMs(&reports_, &avg_rtt_ms_);
|
|
|
|
// If there is a valid rtt, update all observers with the max rtt.
|
|
if (max_rtt_ms_ >= 0) {
|
|
RTC_DCHECK_GE(avg_rtt_ms_, 0);
|
|
for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
|
|
it != observers_.end(); ++it) {
|
|
(*it)->OnRttUpdate(avg_rtt_ms_, max_rtt_ms_);
|
|
}
|
|
// Sum for Histogram of average RTT reported over the entire call.
|
|
sum_avg_rtt_ms_ += avg_rtt_ms_;
|
|
++num_avg_rtt_;
|
|
}
|
|
}
|
|
|
|
int64_t CallStats::avg_rtt_ms() const {
|
|
rtc::CritScope cs(&crit_);
|
|
return avg_rtt_ms_;
|
|
}
|
|
|
|
RtcpRttStats* CallStats::rtcp_rtt_stats() const {
|
|
return rtcp_rtt_stats_.get();
|
|
}
|
|
|
|
void CallStats::RegisterStatsObserver(CallStatsObserver* observer) {
|
|
rtc::CritScope cs(&crit_);
|
|
for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
|
|
it != observers_.end(); ++it) {
|
|
if (*it == observer)
|
|
return;
|
|
}
|
|
observers_.push_back(observer);
|
|
}
|
|
|
|
void CallStats::DeregisterStatsObserver(CallStatsObserver* observer) {
|
|
rtc::CritScope cs(&crit_);
|
|
for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
|
|
it != observers_.end(); ++it) {
|
|
if (*it == observer) {
|
|
observers_.erase(it);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CallStats::OnRttUpdate(int64_t rtt) {
|
|
rtc::CritScope cs(&crit_);
|
|
int64_t now_ms = clock_->TimeInMilliseconds();
|
|
reports_.push_back(RttTime(rtt, now_ms));
|
|
if (time_of_first_rtt_ms_ == -1)
|
|
time_of_first_rtt_ms_ = now_ms;
|
|
}
|
|
|
|
void CallStats::UpdateHistograms() {
|
|
rtc::CritScope cs(&crit_);
|
|
if (time_of_first_rtt_ms_ == -1 || num_avg_rtt_ < 1)
|
|
return;
|
|
|
|
int64_t elapsed_sec =
|
|
(clock_->TimeInMilliseconds() - time_of_first_rtt_ms_) / 1000;
|
|
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
|
int64_t avg_rtt_ms = (sum_avg_rtt_ms_ + num_avg_rtt_ / 2) / num_avg_rtt_;
|
|
RTC_LOGGED_HISTOGRAM_COUNTS_10000(
|
|
"WebRTC.Video.AverageRoundTripTimeInMilliseconds", avg_rtt_ms);
|
|
}
|
|
}
|
|
|
|
} // namespace webrtc
|