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