delay_manager.cc (3686B)
1 /* 2 * Copyright (c) 2012 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/delay_manager.h" 12 13 #include <algorithm> 14 #include <cstdlib> 15 #include <memory> 16 17 #include "api/field_trials_view.h" 18 #include "api/neteq/neteq_controller.h" 19 #include "api/neteq/tick_timer.h" 20 #include "modules/audio_coding/neteq/reorder_optimizer.h" 21 #include "rtc_base/experiments/struct_parameters_parser.h" 22 #include "rtc_base/logging.h" 23 24 namespace webrtc { 25 namespace { 26 27 constexpr int kStartDelayMs = 80; 28 29 std::unique_ptr<ReorderOptimizer> MaybeCreateReorderOptimizer( 30 const DelayManager::Config& config) { 31 if (!config.use_reorder_optimizer) { 32 return nullptr; 33 } 34 return std::make_unique<ReorderOptimizer>( 35 (1 << 15) * config.reorder_forget_factor, config.ms_per_loss_percent, 36 config.start_forget_weight); 37 } 38 39 } // namespace 40 41 DelayManager::Config::Config(const FieldTrialsView& field_trials) { 42 StructParametersParser::Create( // 43 "quantile", &quantile, // 44 "forget_factor", &forget_factor, // 45 "start_forget_weight", &start_forget_weight, // 46 "resample_interval_ms", &resample_interval_ms, // 47 "use_reorder_optimizer", &use_reorder_optimizer, // 48 "reorder_forget_factor", &reorder_forget_factor, // 49 "ms_per_loss_percent", &ms_per_loss_percent) 50 ->Parse(field_trials.Lookup("WebRTC-Audio-NetEqDelayManagerConfig")); 51 } 52 53 void DelayManager::Config::Log() { 54 RTC_LOG(LS_INFO) << "Delay manager config:" 55 " quantile=" 56 << quantile << " forget_factor=" << forget_factor 57 << " start_forget_weight=" << start_forget_weight.value_or(0) 58 << " resample_interval_ms=" 59 << resample_interval_ms.value_or(0) 60 << " use_reorder_optimizer=" << use_reorder_optimizer 61 << " reorder_forget_factor=" << reorder_forget_factor 62 << " ms_per_loss_percent=" << ms_per_loss_percent; 63 } 64 65 DelayManager::DelayManager(const Config& config, const TickTimer* tick_timer) 66 : underrun_optimizer_(tick_timer, 67 (1 << 30) * config.quantile, 68 (1 << 15) * config.forget_factor, 69 config.start_forget_weight, 70 config.resample_interval_ms), 71 reorder_optimizer_(MaybeCreateReorderOptimizer(config)), 72 target_level_ms_(kStartDelayMs) { 73 Reset(); 74 } 75 76 void DelayManager::Update(int arrival_delay_ms, 77 bool reordered, 78 NetEqController::PacketArrivedInfo info) { 79 if (!reorder_optimizer_ || !reordered) { 80 underrun_optimizer_.Update(arrival_delay_ms); 81 } 82 target_level_ms_ = 83 underrun_optimizer_.GetOptimalDelayMs().value_or(kStartDelayMs); 84 if (reorder_optimizer_) { 85 reorder_optimizer_->Update(arrival_delay_ms, reordered, target_level_ms_); 86 target_level_ms_ = std::max( 87 target_level_ms_, reorder_optimizer_->GetOptimalDelayMs().value_or(0)); 88 } 89 } 90 91 void DelayManager::Reset() { 92 underrun_optimizer_.Reset(); 93 target_level_ms_ = kStartDelayMs; 94 if (reorder_optimizer_) { 95 reorder_optimizer_->Reset(); 96 } 97 } 98 99 int DelayManager::TargetDelayMs() const { 100 return target_level_ms_; 101 } 102 103 } // namespace webrtc