LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/neteq - delay_peak_detector.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 51 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 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/modules/audio_coding/neteq/delay_peak_detector.h"
      12             : 
      13             : #include <algorithm>  // max
      14             : 
      15             : #include "webrtc/base/checks.h"
      16             : #include "webrtc/base/safe_conversions.h"
      17             : 
      18             : namespace webrtc {
      19             : 
      20             : // The DelayPeakDetector keeps track of severe inter-arrival times, called
      21             : // delay peaks. When a peak is observed, the "height" (the time elapsed since
      22             : // the previous packet arrival) and the peak "period" (the time since the last
      23             : // observed peak) is recorded in a vector. When enough peaks have been observed,
      24             : // peak-mode is engaged and the DelayManager asks the DelayPeakDetector for
      25             : // the worst peak height.
      26             : 
      27             : DelayPeakDetector::~DelayPeakDetector() = default;
      28             : 
      29           0 : DelayPeakDetector::DelayPeakDetector(const TickTimer* tick_timer)
      30             :     : peak_found_(false),
      31             :       peak_detection_threshold_(0),
      32           0 :       tick_timer_(tick_timer) {
      33           0 :   RTC_DCHECK(!peak_period_stopwatch_);
      34           0 : }
      35             : 
      36           0 : void DelayPeakDetector::Reset() {
      37           0 :   peak_period_stopwatch_.reset();
      38           0 :   peak_found_ = false;
      39           0 :   peak_history_.clear();
      40           0 : }
      41             : 
      42             : // Calculates the threshold in number of packets.
      43           0 : void DelayPeakDetector::SetPacketAudioLength(int length_ms) {
      44           0 :   if (length_ms > 0) {
      45           0 :     peak_detection_threshold_ = kPeakHeightMs / length_ms;
      46             :   }
      47           0 : }
      48             : 
      49           0 : bool DelayPeakDetector::peak_found() {
      50           0 :   return peak_found_;
      51             : }
      52             : 
      53           0 : int DelayPeakDetector::MaxPeakHeight() const {
      54           0 :   int max_height = -1;  // Returns -1 for an empty history.
      55           0 :   std::list<Peak>::const_iterator it;
      56           0 :   for (it = peak_history_.begin(); it != peak_history_.end(); ++it) {
      57           0 :     max_height = std::max(max_height, it->peak_height_packets);
      58             :   }
      59           0 :   return max_height;
      60             : }
      61             : 
      62           0 : uint64_t DelayPeakDetector::MaxPeakPeriod() const {
      63             :   auto max_period_element = std::max_element(
      64             :       peak_history_.begin(), peak_history_.end(),
      65           0 :       [](Peak a, Peak b) { return a.period_ms < b.period_ms; });
      66           0 :   if (max_period_element == peak_history_.end()) {
      67           0 :     return 0;  // |peak_history_| is empty.
      68             :   }
      69           0 :   RTC_DCHECK_GT(max_period_element->period_ms, 0);
      70           0 :   return max_period_element->period_ms;
      71             : }
      72             : 
      73           0 : bool DelayPeakDetector::Update(int inter_arrival_time, int target_level) {
      74           0 :   if (inter_arrival_time > target_level + peak_detection_threshold_ ||
      75           0 :       inter_arrival_time > 2 * target_level) {
      76             :     // A delay peak is observed.
      77           0 :     if (!peak_period_stopwatch_) {
      78             :       // This is the first peak. Reset the period counter.
      79           0 :       peak_period_stopwatch_ = tick_timer_->GetNewStopwatch();
      80           0 :     } else if (peak_period_stopwatch_->ElapsedMs() > 0) {
      81           0 :       if (peak_period_stopwatch_->ElapsedMs() <= kMaxPeakPeriodMs) {
      82             :         // This is not the first peak, and the period is valid.
      83             :         // Store peak data in the vector.
      84             :         Peak peak_data;
      85           0 :         peak_data.period_ms = peak_period_stopwatch_->ElapsedMs();
      86           0 :         peak_data.peak_height_packets = inter_arrival_time;
      87           0 :         peak_history_.push_back(peak_data);
      88           0 :         while (peak_history_.size() > kMaxNumPeaks) {
      89             :           // Delete the oldest data point.
      90           0 :           peak_history_.pop_front();
      91             :         }
      92           0 :         peak_period_stopwatch_ = tick_timer_->GetNewStopwatch();
      93           0 :       } else if (peak_period_stopwatch_->ElapsedMs() <= 2 * kMaxPeakPeriodMs) {
      94             :         // Invalid peak due to too long period. Reset period counter and start
      95             :         // looking for next peak.
      96           0 :         peak_period_stopwatch_ = tick_timer_->GetNewStopwatch();
      97             :       } else {
      98             :         // More than 2 times the maximum period has elapsed since the last peak
      99             :         // was registered. It seams that the network conditions have changed.
     100             :         // Reset the peak statistics.
     101           0 :         Reset();
     102             :       }
     103             :     }
     104             :   }
     105           0 :   return CheckPeakConditions();
     106             : }
     107             : 
     108           0 : bool DelayPeakDetector::CheckPeakConditions() {
     109           0 :   size_t s = peak_history_.size();
     110           0 :   if (s >= kMinPeaksToTrigger &&
     111           0 :       peak_period_stopwatch_->ElapsedMs() <= 2 * MaxPeakPeriod()) {
     112           0 :     peak_found_ = true;
     113             :   } else {
     114           0 :     peak_found_ = false;
     115             :   }
     116           0 :   return peak_found_;
     117             : }
     118             : }  // namespace webrtc

Generated by: LCOV version 1.13