xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/underrun_optimizer.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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