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