LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/video - call_stats.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 97 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 20 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/call_stats.h"
      12             : 
      13             : #include <algorithm>
      14             : 
      15             : #include "webrtc/base/checks.h"
      16             : #include "webrtc/base/constructormagic.h"
      17             : #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
      18             : #include "webrtc/system_wrappers/include/metrics.h"
      19             : 
      20             : namespace webrtc {
      21             : namespace {
      22             : // Time interval for updating the observers.
      23             : const int64_t kUpdateIntervalMs = 1000;
      24             : // Weight factor to apply to the average rtt.
      25             : const float kWeightFactor = 0.3f;
      26             : 
      27           0 : void RemoveOldReports(int64_t now, std::list<CallStats::RttTime>* reports) {
      28             :   // A rtt report is considered valid for this long.
      29           0 :   const int64_t kRttTimeoutMs = 1500;
      30           0 :   while (!reports->empty() &&
      31           0 :          (now - reports->front().time) > kRttTimeoutMs) {
      32           0 :     reports->pop_front();
      33             :   }
      34           0 : }
      35             : 
      36           0 : int64_t GetMaxRttMs(std::list<CallStats::RttTime>* reports) {
      37           0 :   if (reports->empty())
      38           0 :     return -1;
      39           0 :   int64_t max_rtt_ms = 0;
      40           0 :   for (const CallStats::RttTime& rtt_time : *reports)
      41           0 :     max_rtt_ms = std::max(rtt_time.rtt, max_rtt_ms);
      42           0 :   return max_rtt_ms;
      43             : }
      44             : 
      45           0 : int64_t GetAvgRttMs(std::list<CallStats::RttTime>* reports) {
      46           0 :   if (reports->empty()) {
      47           0 :     return -1;
      48             :   }
      49           0 :   int64_t sum = 0;
      50           0 :   for (std::list<CallStats::RttTime>::const_iterator it = reports->begin();
      51           0 :        it != reports->end(); ++it) {
      52           0 :     sum += it->rtt;
      53             :   }
      54           0 :   return sum / reports->size();
      55             : }
      56             : 
      57           0 : void UpdateAvgRttMs(std::list<CallStats::RttTime>* reports, int64_t* avg_rtt) {
      58           0 :   int64_t cur_rtt_ms = GetAvgRttMs(reports);
      59           0 :   if (cur_rtt_ms == -1) {
      60             :     // Reset.
      61           0 :     *avg_rtt = -1;
      62           0 :     return;
      63             :   }
      64           0 :   if (*avg_rtt == -1) {
      65             :     // Initialize.
      66           0 :     *avg_rtt = cur_rtt_ms;
      67           0 :     return;
      68             :   }
      69           0 :   *avg_rtt = *avg_rtt * (1.0f - kWeightFactor) + cur_rtt_ms * kWeightFactor;
      70             : }
      71             : }  // namespace
      72             : 
      73             : class RtcpObserver : public RtcpRttStats {
      74             :  public:
      75           0 :   explicit RtcpObserver(CallStats* owner) : owner_(owner) {}
      76           0 :   virtual ~RtcpObserver() {}
      77             : 
      78           0 :   virtual void OnRttUpdate(int64_t rtt) {
      79           0 :     owner_->OnRttUpdate(rtt);
      80           0 :   }
      81             : 
      82             :   // Returns the average RTT.
      83           0 :   virtual int64_t LastProcessedRtt() const {
      84           0 :     return owner_->avg_rtt_ms();
      85             :   }
      86             : 
      87             :  private:
      88             :   CallStats* owner_;
      89             : 
      90             :   RTC_DISALLOW_COPY_AND_ASSIGN(RtcpObserver);
      91             : };
      92             : 
      93           0 : CallStats::CallStats(Clock* clock)
      94             :     : clock_(clock),
      95           0 :       rtcp_rtt_stats_(new RtcpObserver(this)),
      96           0 :       last_process_time_(clock_->TimeInMilliseconds()),
      97             :       max_rtt_ms_(-1),
      98             :       avg_rtt_ms_(-1),
      99             :       sum_avg_rtt_ms_(0),
     100             :       num_avg_rtt_(0),
     101           0 :       time_of_first_rtt_ms_(-1) {}
     102             : 
     103           0 : CallStats::~CallStats() {
     104           0 :   RTC_DCHECK(observers_.empty());
     105           0 :   UpdateHistograms();
     106           0 : }
     107             : 
     108           0 : int64_t CallStats::TimeUntilNextProcess() {
     109           0 :   return last_process_time_ + kUpdateIntervalMs - clock_->TimeInMilliseconds();
     110             : }
     111             : 
     112           0 : void CallStats::Process() {
     113           0 :   rtc::CritScope cs(&crit_);
     114           0 :   int64_t now = clock_->TimeInMilliseconds();
     115           0 :   if (now < last_process_time_ + kUpdateIntervalMs)
     116           0 :     return;
     117             : 
     118           0 :   last_process_time_ = now;
     119             : 
     120           0 :   RemoveOldReports(now, &reports_);
     121           0 :   max_rtt_ms_ = GetMaxRttMs(&reports_);
     122           0 :   UpdateAvgRttMs(&reports_, &avg_rtt_ms_);
     123             : 
     124             :   // If there is a valid rtt, update all observers with the max rtt.
     125           0 :   if (max_rtt_ms_ >= 0) {
     126           0 :     RTC_DCHECK_GE(avg_rtt_ms_, 0);
     127           0 :     for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
     128           0 :          it != observers_.end(); ++it) {
     129           0 :       (*it)->OnRttUpdate(avg_rtt_ms_, max_rtt_ms_);
     130             :     }
     131             :     // Sum for Histogram of average RTT reported over the entire call.
     132           0 :     sum_avg_rtt_ms_ += avg_rtt_ms_;
     133           0 :     ++num_avg_rtt_;
     134             :   }
     135             : }
     136             : 
     137           0 : int64_t CallStats::avg_rtt_ms() const {
     138           0 :   rtc::CritScope cs(&crit_);
     139           0 :   return avg_rtt_ms_;
     140             : }
     141             : 
     142           0 : RtcpRttStats* CallStats::rtcp_rtt_stats() const {
     143           0 :   return rtcp_rtt_stats_.get();
     144             : }
     145             : 
     146           0 : void CallStats::RegisterStatsObserver(CallStatsObserver* observer) {
     147           0 :   rtc::CritScope cs(&crit_);
     148           0 :   for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
     149           0 :        it != observers_.end(); ++it) {
     150           0 :     if (*it == observer)
     151           0 :       return;
     152             :   }
     153           0 :   observers_.push_back(observer);
     154             : }
     155             : 
     156           0 : void CallStats::DeregisterStatsObserver(CallStatsObserver* observer) {
     157           0 :   rtc::CritScope cs(&crit_);
     158           0 :   for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
     159           0 :        it != observers_.end(); ++it) {
     160           0 :     if (*it == observer) {
     161           0 :       observers_.erase(it);
     162           0 :       return;
     163             :     }
     164             :   }
     165             : }
     166             : 
     167           0 : void CallStats::OnRttUpdate(int64_t rtt) {
     168           0 :   rtc::CritScope cs(&crit_);
     169           0 :   int64_t now_ms = clock_->TimeInMilliseconds();
     170           0 :   reports_.push_back(RttTime(rtt, now_ms));
     171           0 :   if (time_of_first_rtt_ms_ == -1)
     172           0 :     time_of_first_rtt_ms_ = now_ms;
     173           0 : }
     174             : 
     175           0 : void CallStats::UpdateHistograms() {
     176           0 :   rtc::CritScope cs(&crit_);
     177           0 :   if (time_of_first_rtt_ms_ == -1 || num_avg_rtt_ < 1)
     178           0 :     return;
     179             : 
     180             :   int64_t elapsed_sec =
     181           0 :       (clock_->TimeInMilliseconds() - time_of_first_rtt_ms_) / 1000;
     182           0 :   if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
     183           0 :     int64_t avg_rtt_ms = (sum_avg_rtt_ms_ + num_avg_rtt_ / 2) / num_avg_rtt_;
     184           0 :     RTC_HISTOGRAM_COUNTS_10000(
     185             :         "WebRTC.Video.AverageRoundTripTimeInMilliseconds", avg_rtt_ms);
     186             :   }
     187             : }
     188             : 
     189             : }  // namespace webrtc

Generated by: LCOV version 1.13