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

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2011 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/modules/video_coding/rtt_filter.h"
      12             : 
      13             : #include <math.h>
      14             : #include <stdlib.h>
      15             : #include <string.h>
      16             : 
      17             : #include "webrtc/modules/video_coding/internal_defines.h"
      18             : 
      19             : namespace webrtc {
      20             : 
      21           0 : VCMRttFilter::VCMRttFilter()
      22             :     : _filtFactMax(35),
      23             :       _jumpStdDevs(2.5),
      24             :       _driftStdDevs(3.5),
      25           0 :       _detectThreshold(kMaxDriftJumpCount) {
      26           0 :   Reset();
      27           0 : }
      28             : 
      29           0 : VCMRttFilter& VCMRttFilter::operator=(const VCMRttFilter& rhs) {
      30           0 :   if (this != &rhs) {
      31           0 :     _gotNonZeroUpdate = rhs._gotNonZeroUpdate;
      32           0 :     _avgRtt = rhs._avgRtt;
      33           0 :     _varRtt = rhs._varRtt;
      34           0 :     _maxRtt = rhs._maxRtt;
      35           0 :     _filtFactCount = rhs._filtFactCount;
      36           0 :     _jumpCount = rhs._jumpCount;
      37           0 :     _driftCount = rhs._driftCount;
      38           0 :     memcpy(_jumpBuf, rhs._jumpBuf, sizeof(_jumpBuf));
      39           0 :     memcpy(_driftBuf, rhs._driftBuf, sizeof(_driftBuf));
      40             :   }
      41           0 :   return *this;
      42             : }
      43             : 
      44           0 : void VCMRttFilter::Reset() {
      45           0 :   _gotNonZeroUpdate = false;
      46           0 :   _avgRtt = 0;
      47           0 :   _varRtt = 0;
      48           0 :   _maxRtt = 0;
      49           0 :   _filtFactCount = 1;
      50           0 :   _jumpCount = 0;
      51           0 :   _driftCount = 0;
      52           0 :   memset(_jumpBuf, 0, sizeof(_jumpBuf));
      53           0 :   memset(_driftBuf, 0, sizeof(_driftBuf));
      54           0 : }
      55             : 
      56           0 : void VCMRttFilter::Update(int64_t rttMs) {
      57           0 :   if (!_gotNonZeroUpdate) {
      58           0 :     if (rttMs == 0) {
      59           0 :       return;
      60             :     }
      61           0 :     _gotNonZeroUpdate = true;
      62             :   }
      63             : 
      64             :   // Sanity check
      65           0 :   if (rttMs > 3000) {
      66           0 :     rttMs = 3000;
      67             :   }
      68             : 
      69           0 :   double filtFactor = 0;
      70           0 :   if (_filtFactCount > 1) {
      71           0 :     filtFactor = static_cast<double>(_filtFactCount - 1) / _filtFactCount;
      72             :   }
      73           0 :   _filtFactCount++;
      74           0 :   if (_filtFactCount > _filtFactMax) {
      75             :     // This prevents filtFactor from going above
      76             :     // (_filtFactMax - 1) / _filtFactMax,
      77             :     // e.g., _filtFactMax = 50 => filtFactor = 49/50 = 0.98
      78           0 :     _filtFactCount = _filtFactMax;
      79             :   }
      80           0 :   double oldAvg = _avgRtt;
      81           0 :   double oldVar = _varRtt;
      82           0 :   _avgRtt = filtFactor * _avgRtt + (1 - filtFactor) * rttMs;
      83           0 :   _varRtt = filtFactor * _varRtt +
      84           0 :             (1 - filtFactor) * (rttMs - _avgRtt) * (rttMs - _avgRtt);
      85           0 :   _maxRtt = VCM_MAX(rttMs, _maxRtt);
      86           0 :   if (!JumpDetection(rttMs) || !DriftDetection(rttMs)) {
      87             :     // In some cases we don't want to update the statistics
      88           0 :     _avgRtt = oldAvg;
      89           0 :     _varRtt = oldVar;
      90             :   }
      91             : }
      92             : 
      93           0 : bool VCMRttFilter::JumpDetection(int64_t rttMs) {
      94           0 :   double diffFromAvg = _avgRtt - rttMs;
      95           0 :   if (fabs(diffFromAvg) > _jumpStdDevs * sqrt(_varRtt)) {
      96           0 :     int diffSign = (diffFromAvg >= 0) ? 1 : -1;
      97           0 :     int jumpCountSign = (_jumpCount >= 0) ? 1 : -1;
      98           0 :     if (diffSign != jumpCountSign) {
      99             :       // Since the signs differ the samples currently
     100             :       // in the buffer is useless as they represent a
     101             :       // jump in a different direction.
     102           0 :       _jumpCount = 0;
     103             :     }
     104           0 :     if (abs(_jumpCount) < kMaxDriftJumpCount) {
     105             :       // Update the buffer used for the short time
     106             :       // statistics.
     107             :       // The sign of the diff is used for updating the counter since
     108             :       // we want to use the same buffer for keeping track of when
     109             :       // the RTT jumps down and up.
     110           0 :       _jumpBuf[abs(_jumpCount)] = rttMs;
     111           0 :       _jumpCount += diffSign;
     112             :     }
     113           0 :     if (abs(_jumpCount) >= _detectThreshold) {
     114             :       // Detected an RTT jump
     115           0 :       ShortRttFilter(_jumpBuf, abs(_jumpCount));
     116           0 :       _filtFactCount = _detectThreshold + 1;
     117           0 :       _jumpCount = 0;
     118             :     } else {
     119           0 :       return false;
     120             :     }
     121             :   } else {
     122           0 :     _jumpCount = 0;
     123             :   }
     124           0 :   return true;
     125             : }
     126             : 
     127           0 : bool VCMRttFilter::DriftDetection(int64_t rttMs) {
     128           0 :   if (_maxRtt - _avgRtt > _driftStdDevs * sqrt(_varRtt)) {
     129           0 :     if (_driftCount < kMaxDriftJumpCount) {
     130             :       // Update the buffer used for the short time
     131             :       // statistics.
     132           0 :       _driftBuf[_driftCount] = rttMs;
     133           0 :       _driftCount++;
     134             :     }
     135           0 :     if (_driftCount >= _detectThreshold) {
     136             :       // Detected an RTT drift
     137           0 :       ShortRttFilter(_driftBuf, _driftCount);
     138           0 :       _filtFactCount = _detectThreshold + 1;
     139           0 :       _driftCount = 0;
     140             :     }
     141             :   } else {
     142           0 :     _driftCount = 0;
     143             :   }
     144           0 :   return true;
     145             : }
     146             : 
     147           0 : void VCMRttFilter::ShortRttFilter(int64_t* buf, uint32_t length) {
     148           0 :   if (length == 0) {
     149           0 :     return;
     150             :   }
     151           0 :   _maxRtt = 0;
     152           0 :   _avgRtt = 0;
     153           0 :   for (uint32_t i = 0; i < length; i++) {
     154           0 :     if (buf[i] > _maxRtt) {
     155           0 :       _maxRtt = buf[i];
     156             :     }
     157           0 :     _avgRtt += buf[i];
     158             :   }
     159           0 :   _avgRtt = _avgRtt / static_cast<double>(length);
     160             : }
     161             : 
     162           0 : int64_t VCMRttFilter::RttMs() const {
     163           0 :   return static_cast<int64_t>(_maxRtt + 0.5);
     164             : }
     165             : }  // namespace webrtc

Generated by: LCOV version 1.13