underrun_optimizer.cc (2352B)
1 /* 2 * Copyright (c) 2021 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 "modules/audio_coding/neteq/underrun_optimizer.h" 12 13 #include <algorithm> 14 #include <optional> 15 16 #include "api/neteq/tick_timer.h" 17 18 namespace webrtc { 19 20 namespace { 21 22 constexpr int kDelayBuckets = 100; 23 constexpr int kBucketSizeMs = 20; 24 25 } // namespace 26 27 UnderrunOptimizer::UnderrunOptimizer(const TickTimer* tick_timer, 28 int histogram_quantile, 29 int forget_factor, 30 std::optional<int> start_forget_weight, 31 std::optional<int> resample_interval_ms) 32 : tick_timer_(tick_timer), 33 histogram_(kDelayBuckets, forget_factor, start_forget_weight), 34 histogram_quantile_(histogram_quantile), 35 resample_interval_ms_(resample_interval_ms) {} 36 37 void UnderrunOptimizer::Update(int relative_delay_ms) { 38 std::optional<int> histogram_update; 39 if (resample_interval_ms_) { 40 if (!resample_stopwatch_) { 41 resample_stopwatch_ = tick_timer_->GetNewStopwatch(); 42 } 43 if (static_cast<int>(resample_stopwatch_->ElapsedMs()) > 44 *resample_interval_ms_) { 45 histogram_update = max_delay_in_interval_ms_; 46 resample_stopwatch_ = tick_timer_->GetNewStopwatch(); 47 max_delay_in_interval_ms_ = 0; 48 } 49 max_delay_in_interval_ms_ = 50 std::max(max_delay_in_interval_ms_, relative_delay_ms); 51 } else { 52 histogram_update = relative_delay_ms; 53 } 54 if (!histogram_update) { 55 return; 56 } 57 58 const int index = *histogram_update / kBucketSizeMs; 59 if (index < histogram_.NumBuckets()) { 60 // Maximum delay to register is 2000 ms. 61 histogram_.Add(index); 62 } 63 int bucket_index = histogram_.Quantile(histogram_quantile_); 64 optimal_delay_ms_ = (1 + bucket_index) * kBucketSizeMs; 65 } 66 67 void UnderrunOptimizer::Reset() { 68 histogram_.Reset(); 69 resample_stopwatch_.reset(); 70 max_delay_in_interval_ms_ = 0; 71 optimal_delay_ms_.reset(); 72 } 73 74 } // namespace webrtc