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