xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/reorder_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/reorder_optimizer.h"
12 
13 #include <algorithm>
14 #include <limits>
15 #include <vector>
16 
17 namespace webrtc {
18 
19 namespace {
20 
21 constexpr int kDelayBuckets = 100;
22 constexpr int kBucketSizeMs = 20;
23 
24 }  // namespace
25 
ReorderOptimizer(int forget_factor,int ms_per_loss_percent,absl::optional<int> start_forget_weight)26 ReorderOptimizer::ReorderOptimizer(int forget_factor,
27                                    int ms_per_loss_percent,
28                                    absl::optional<int> start_forget_weight)
29     : histogram_(kDelayBuckets, forget_factor, start_forget_weight),
30       ms_per_loss_percent_(ms_per_loss_percent) {}
31 
Update(int relative_delay_ms,bool reordered,int base_delay_ms)32 void ReorderOptimizer::Update(int relative_delay_ms,
33                               bool reordered,
34                               int base_delay_ms) {
35   const int index = reordered ? relative_delay_ms / kBucketSizeMs : 0;
36   if (index < histogram_.NumBuckets()) {
37     // Maximum delay to register is 2000 ms.
38     histogram_.Add(index);
39   }
40   int bucket_index = MinimizeCostFunction(base_delay_ms);
41   optimal_delay_ms_ = (1 + bucket_index) * kBucketSizeMs;
42 }
43 
Reset()44 void ReorderOptimizer::Reset() {
45   histogram_.Reset();
46   optimal_delay_ms_.reset();
47 }
48 
MinimizeCostFunction(int base_delay_ms) const49 int ReorderOptimizer::MinimizeCostFunction(int base_delay_ms) const {
50   const std::vector<int>& buckets = histogram_.buckets();
51 
52   // Values are calculated in Q30.
53   int64_t loss_probability = 1 << 30;
54   int64_t min_cost = std::numeric_limits<int64_t>::max();
55   int min_bucket = 0;
56   for (int i = 0; i < static_cast<int>(buckets.size()); ++i) {
57     loss_probability -= buckets[i];
58     int64_t delay_ms =
59         static_cast<int64_t>(std::max(0, i * kBucketSizeMs - base_delay_ms))
60         << 30;
61     int64_t cost = delay_ms + 100 * ms_per_loss_percent_ * loss_probability;
62 
63     if (cost < min_cost) {
64       min_cost = cost;
65       min_bucket = i;
66     }
67     if (loss_probability == 0) {
68       break;
69     }
70   }
71 
72   return min_bucket;
73 }
74 
75 }  // namespace webrtc
76