blob: f22df54165f891e2b5801ba3f907228e840f25b2 [file] [log] [blame]
minyuecaa9cb22016-09-13 13:34:15 -07001/*
2 * Copyright (c) 2016 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_coding/audio_network_adaptor/controller_manager.h"
minyuebc77ed72016-09-22 00:45:16 -070012
13#include <cmath>
Mirko Bonadeie45c6882019-02-16 09:59:29 +010014#include <string>
minyuecaa9cb22016-09-13 13:34:15 -070015#include <utility>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_coding/audio_network_adaptor/bitrate_controller.h"
18#include "modules/audio_coding/audio_network_adaptor/channel_controller.h"
19#include "modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
20#include "modules/audio_coding/audio_network_adaptor/dtx_controller.h"
21#include "modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h"
22#include "modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h"
23#include "modules/audio_coding/audio_network_adaptor/frame_length_controller.h"
24#include "modules/audio_coding/audio_network_adaptor/util/threshold_curve.h"
25#include "rtc_base/ignore_wundef.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "rtc_base/time_utils.h"
minyuecaa9cb22016-09-13 13:34:15 -070027
minyue-webrtc7ed35f42017-06-13 11:49:29 +020028#if WEBRTC_ENABLE_PROTOBUF
minyuea1d9ad02016-10-02 14:53:37 -070029RTC_PUSH_IGNORING_WUNDEF()
30#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
31#include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h"
32#else
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "modules/audio_coding/audio_network_adaptor/config.pb.h"
minyuea1d9ad02016-10-02 14:53:37 -070034#endif
35RTC_POP_IGNORING_WUNDEF()
36#endif
37
minyuecaa9cb22016-09-13 13:34:15 -070038namespace webrtc {
39
minyuea1d9ad02016-10-02 14:53:37 -070040namespace {
41
minyue-webrtc7ed35f42017-06-13 11:49:29 +020042#if WEBRTC_ENABLE_PROTOBUF
minyuea1d9ad02016-10-02 14:53:37 -070043
elad.alon6d7900d2017-03-24 04:12:56 -070044std::unique_ptr<FecControllerPlrBased> CreateFecControllerPlrBased(
minyuea1d9ad02016-10-02 14:53:37 -070045 const audio_network_adaptor::config::FecController& config,
michaelt92aef172017-04-18 00:11:48 -070046 bool initial_fec_enabled) {
minyuea1d9ad02016-10-02 14:53:37 -070047 RTC_CHECK(config.has_fec_enabling_threshold());
48 RTC_CHECK(config.has_fec_disabling_threshold());
49 RTC_CHECK(config.has_time_constant_ms());
50
51 auto& fec_enabling_threshold = config.fec_enabling_threshold();
52 RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_bps());
53 RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_packet_loss());
54 RTC_CHECK(fec_enabling_threshold.has_high_bandwidth_bps());
55 RTC_CHECK(fec_enabling_threshold.has_high_bandwidth_packet_loss());
56
57 auto& fec_disabling_threshold = config.fec_disabling_threshold();
58 RTC_CHECK(fec_disabling_threshold.has_low_bandwidth_bps());
59 RTC_CHECK(fec_disabling_threshold.has_low_bandwidth_packet_loss());
60 RTC_CHECK(fec_disabling_threshold.has_high_bandwidth_bps());
61 RTC_CHECK(fec_disabling_threshold.has_high_bandwidth_packet_loss());
62
elad.alon6d7900d2017-03-24 04:12:56 -070063 return std::unique_ptr<FecControllerPlrBased>(
64 new FecControllerPlrBased(FecControllerPlrBased::Config(
65 initial_fec_enabled,
elad.alon326263a2017-03-29 03:16:58 -070066 ThresholdCurve(fec_enabling_threshold.low_bandwidth_bps(),
67 fec_enabling_threshold.low_bandwidth_packet_loss(),
68 fec_enabling_threshold.high_bandwidth_bps(),
69 fec_enabling_threshold.high_bandwidth_packet_loss()),
70 ThresholdCurve(fec_disabling_threshold.low_bandwidth_bps(),
71 fec_disabling_threshold.low_bandwidth_packet_loss(),
72 fec_disabling_threshold.high_bandwidth_bps(),
73 fec_disabling_threshold.high_bandwidth_packet_loss()),
michaelt92aef172017-04-18 00:11:48 -070074 config.time_constant_ms())));
minyuea1d9ad02016-10-02 14:53:37 -070075}
76
elad.alon28770482017-03-28 05:03:55 -070077std::unique_ptr<FecControllerRplrBased> CreateFecControllerRplrBased(
78 const audio_network_adaptor::config::FecControllerRplrBased& config,
79 bool initial_fec_enabled) {
80 RTC_CHECK(config.has_fec_enabling_threshold());
81 RTC_CHECK(config.has_fec_disabling_threshold());
82
83 auto& fec_enabling_threshold = config.fec_enabling_threshold();
84 RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_bps());
85 RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_recoverable_packet_loss());
86 RTC_CHECK(fec_enabling_threshold.has_high_bandwidth_bps());
87 RTC_CHECK(
88 fec_enabling_threshold.has_high_bandwidth_recoverable_packet_loss());
89
90 auto& fec_disabling_threshold = config.fec_disabling_threshold();
91 RTC_CHECK(fec_disabling_threshold.has_low_bandwidth_bps());
92 RTC_CHECK(
93 fec_disabling_threshold.has_low_bandwidth_recoverable_packet_loss());
94 RTC_CHECK(fec_disabling_threshold.has_high_bandwidth_bps());
95 RTC_CHECK(
96 fec_disabling_threshold.has_high_bandwidth_recoverable_packet_loss());
97
98 return std::unique_ptr<FecControllerRplrBased>(
99 new FecControllerRplrBased(FecControllerRplrBased::Config(
100 initial_fec_enabled,
elad.alon326263a2017-03-29 03:16:58 -0700101 ThresholdCurve(
elad.alon28770482017-03-28 05:03:55 -0700102 fec_enabling_threshold.low_bandwidth_bps(),
103 fec_enabling_threshold.low_bandwidth_recoverable_packet_loss(),
104 fec_enabling_threshold.high_bandwidth_bps(),
105 fec_enabling_threshold.high_bandwidth_recoverable_packet_loss()),
elad.alon326263a2017-03-29 03:16:58 -0700106 ThresholdCurve(
elad.alon28770482017-03-28 05:03:55 -0700107 fec_disabling_threshold.low_bandwidth_bps(),
108 fec_disabling_threshold.low_bandwidth_recoverable_packet_loss(),
109 fec_disabling_threshold.high_bandwidth_bps(),
110 fec_disabling_threshold
111 .high_bandwidth_recoverable_packet_loss()))));
112}
113
minyuea1d9ad02016-10-02 14:53:37 -0700114std::unique_ptr<FrameLengthController> CreateFrameLengthController(
115 const audio_network_adaptor::config::FrameLengthController& config,
116 rtc::ArrayView<const int> encoder_frame_lengths_ms,
michaelt6f08d7d2017-02-22 07:35:05 -0800117 int initial_frame_length_ms,
118 int min_encoder_bitrate_bps) {
minyuea1d9ad02016-10-02 14:53:37 -0700119 RTC_CHECK(config.has_fl_increasing_packet_loss_fraction());
120 RTC_CHECK(config.has_fl_decreasing_packet_loss_fraction());
minyuea1d9ad02016-10-02 14:53:37 -0700121
michaelta55f0212017-02-02 07:47:19 -0800122 std::map<FrameLengthController::Config::FrameLengthChange, int>
Ying Wang0e1a5582019-08-16 16:45:30 +0200123 fl_changing_bandwidths_bps;
michaelta55f0212017-02-02 07:47:19 -0800124
Ying Wang0e1a5582019-08-16 16:45:30 +0200125 if (config.has_fl_20ms_to_60ms_bandwidth_bps()) {
126 fl_changing_bandwidths_bps.insert(
127 std::make_pair(FrameLengthController::Config::FrameLengthChange(20, 60),
128 config.fl_20ms_to_60ms_bandwidth_bps()));
129 }
130
131 if (config.has_fl_60ms_to_20ms_bandwidth_bps()) {
132 fl_changing_bandwidths_bps.insert(
133 std::make_pair(FrameLengthController::Config::FrameLengthChange(60, 20),
134 config.fl_60ms_to_20ms_bandwidth_bps()));
135 }
136
137 if (config.has_fl_20ms_to_40ms_bandwidth_bps()) {
138 fl_changing_bandwidths_bps.insert(
139 std::make_pair(FrameLengthController::Config::FrameLengthChange(20, 40),
140 config.fl_20ms_to_40ms_bandwidth_bps()));
141 }
142
143 if (config.has_fl_40ms_to_20ms_bandwidth_bps()) {
144 fl_changing_bandwidths_bps.insert(
145 std::make_pair(FrameLengthController::Config::FrameLengthChange(40, 20),
146 config.fl_40ms_to_20ms_bandwidth_bps()));
147 }
148
149 if (config.has_fl_40ms_to_60ms_bandwidth_bps()) {
150 fl_changing_bandwidths_bps.insert(
151 std::make_pair(FrameLengthController::Config::FrameLengthChange(40, 60),
152 config.fl_40ms_to_60ms_bandwidth_bps()));
153 }
154
155 if (config.has_fl_60ms_to_40ms_bandwidth_bps()) {
156 fl_changing_bandwidths_bps.insert(
157 std::make_pair(FrameLengthController::Config::FrameLengthChange(60, 40),
158 config.fl_60ms_to_40ms_bandwidth_bps()));
159 }
160
161 if (config.has_fl_60ms_to_120ms_bandwidth_bps()) {
michaelta55f0212017-02-02 07:47:19 -0800162 fl_changing_bandwidths_bps.insert(std::make_pair(
163 FrameLengthController::Config::FrameLengthChange(60, 120),
164 config.fl_60ms_to_120ms_bandwidth_bps()));
Ying Wang0e1a5582019-08-16 16:45:30 +0200165 }
166
167 if (config.has_fl_120ms_to_60ms_bandwidth_bps()) {
michaelta55f0212017-02-02 07:47:19 -0800168 fl_changing_bandwidths_bps.insert(std::make_pair(
169 FrameLengthController::Config::FrameLengthChange(120, 60),
170 config.fl_120ms_to_60ms_bandwidth_bps()));
171 }
172
ivoc7e9c6142017-09-28 01:11:16 -0700173 int fl_increase_overhead_offset = 0;
174 if (config.has_fl_increase_overhead_offset()) {
175 fl_increase_overhead_offset = config.fl_increase_overhead_offset();
176 }
177 int fl_decrease_overhead_offset = 0;
178 if (config.has_fl_decrease_overhead_offset()) {
179 fl_decrease_overhead_offset = config.fl_decrease_overhead_offset();
180 }
181
minyuea1d9ad02016-10-02 14:53:37 -0700182 FrameLengthController::Config ctor_config(
Minyue Li8319e7f2019-01-02 16:57:02 +0100183 std::set<int>(), initial_frame_length_ms, min_encoder_bitrate_bps,
minyuea1d9ad02016-10-02 14:53:37 -0700184 config.fl_increasing_packet_loss_fraction(),
ivoc7e9c6142017-09-28 01:11:16 -0700185 config.fl_decreasing_packet_loss_fraction(), fl_increase_overhead_offset,
186 fl_decrease_overhead_offset, std::move(fl_changing_bandwidths_bps));
minyuea1d9ad02016-10-02 14:53:37 -0700187
188 for (auto frame_length : encoder_frame_lengths_ms)
Minyue Li8319e7f2019-01-02 16:57:02 +0100189 ctor_config.encoder_frame_lengths_ms.insert(frame_length);
minyuea1d9ad02016-10-02 14:53:37 -0700190
191 return std::unique_ptr<FrameLengthController>(
192 new FrameLengthController(ctor_config));
193}
194
195std::unique_ptr<ChannelController> CreateChannelController(
196 const audio_network_adaptor::config::ChannelController& config,
197 size_t num_encoder_channels,
198 size_t intial_channels_to_encode) {
199 RTC_CHECK(config.has_channel_1_to_2_bandwidth_bps());
200 RTC_CHECK(config.has_channel_2_to_1_bandwidth_bps());
201
202 return std::unique_ptr<ChannelController>(new ChannelController(
203 ChannelController::Config(num_encoder_channels, intial_channels_to_encode,
204 config.channel_1_to_2_bandwidth_bps(),
205 config.channel_2_to_1_bandwidth_bps())));
206}
207
208std::unique_ptr<DtxController> CreateDtxController(
209 const audio_network_adaptor::config::DtxController& dtx_config,
210 bool initial_dtx_enabled) {
211 RTC_CHECK(dtx_config.has_dtx_enabling_bandwidth_bps());
212 RTC_CHECK(dtx_config.has_dtx_disabling_bandwidth_bps());
213
214 return std::unique_ptr<DtxController>(new DtxController(DtxController::Config(
215 initial_dtx_enabled, dtx_config.dtx_enabling_bandwidth_bps(),
216 dtx_config.dtx_disabling_bandwidth_bps())));
217}
218
219using audio_network_adaptor::BitrateController;
220std::unique_ptr<BitrateController> CreateBitrateController(
ivoc7e9c6142017-09-28 01:11:16 -0700221 const audio_network_adaptor::config::BitrateController& bitrate_config,
minyuea1d9ad02016-10-02 14:53:37 -0700222 int initial_bitrate_bps,
223 int initial_frame_length_ms) {
ivoc7e9c6142017-09-28 01:11:16 -0700224 int fl_increase_overhead_offset = 0;
225 if (bitrate_config.has_fl_increase_overhead_offset()) {
226 fl_increase_overhead_offset = bitrate_config.fl_increase_overhead_offset();
227 }
228 int fl_decrease_overhead_offset = 0;
229 if (bitrate_config.has_fl_decrease_overhead_offset()) {
230 fl_decrease_overhead_offset = bitrate_config.fl_decrease_overhead_offset();
231 }
232 return std::unique_ptr<BitrateController>(
233 new BitrateController(BitrateController::Config(
234 initial_bitrate_bps, initial_frame_length_ms,
235 fl_increase_overhead_offset, fl_decrease_overhead_offset)));
minyuea1d9ad02016-10-02 14:53:37 -0700236}
minyue-webrtc7ed35f42017-06-13 11:49:29 +0200237#endif // WEBRTC_ENABLE_PROTOBUF
minyuea1d9ad02016-10-02 14:53:37 -0700238
239} // namespace
240
minyuebc77ed72016-09-22 00:45:16 -0700241ControllerManagerImpl::Config::Config(int min_reordering_time_ms,
michaelt92aef172017-04-18 00:11:48 -0700242 float min_reordering_squared_distance)
minyuebc77ed72016-09-22 00:45:16 -0700243 : min_reordering_time_ms(min_reordering_time_ms),
michaelt92aef172017-04-18 00:11:48 -0700244 min_reordering_squared_distance(min_reordering_squared_distance) {}
minyuecaa9cb22016-09-13 13:34:15 -0700245
246ControllerManagerImpl::Config::~Config() = default;
247
minyuea1d9ad02016-10-02 14:53:37 -0700248std::unique_ptr<ControllerManager> ControllerManagerImpl::Create(
Mirko Bonadeie45c6882019-02-16 09:59:29 +0100249 const std::string& config_string,
minyuea1d9ad02016-10-02 14:53:37 -0700250 size_t num_encoder_channels,
251 rtc::ArrayView<const int> encoder_frame_lengths_ms,
michaelt6f08d7d2017-02-22 07:35:05 -0800252 int min_encoder_bitrate_bps,
minyuea1d9ad02016-10-02 14:53:37 -0700253 size_t intial_channels_to_encode,
254 int initial_frame_length_ms,
255 int initial_bitrate_bps,
256 bool initial_fec_enabled,
michaelt92aef172017-04-18 00:11:48 -0700257 bool initial_dtx_enabled) {
minyue-webrtc9c6430f2017-07-10 16:29:17 +0200258 return Create(config_string, num_encoder_channels, encoder_frame_lengths_ms,
259 min_encoder_bitrate_bps, intial_channels_to_encode,
260 initial_frame_length_ms, initial_bitrate_bps,
261 initial_fec_enabled, initial_dtx_enabled, nullptr);
262}
263
264std::unique_ptr<ControllerManager> ControllerManagerImpl::Create(
Mirko Bonadeie45c6882019-02-16 09:59:29 +0100265 const std::string& config_string,
minyue-webrtc9c6430f2017-07-10 16:29:17 +0200266 size_t num_encoder_channels,
267 rtc::ArrayView<const int> encoder_frame_lengths_ms,
268 int min_encoder_bitrate_bps,
269 size_t intial_channels_to_encode,
270 int initial_frame_length_ms,
271 int initial_bitrate_bps,
272 bool initial_fec_enabled,
273 bool initial_dtx_enabled,
274 DebugDumpWriter* debug_dump_writer) {
minyue-webrtc7ed35f42017-06-13 11:49:29 +0200275#if WEBRTC_ENABLE_PROTOBUF
minyuea1d9ad02016-10-02 14:53:37 -0700276 audio_network_adaptor::config::ControllerManager controller_manager_config;
minyue-webrtc9c6430f2017-07-10 16:29:17 +0200277 RTC_CHECK(controller_manager_config.ParseFromString(config_string));
278 if (debug_dump_writer)
279 debug_dump_writer->DumpControllerManagerConfig(controller_manager_config,
280 rtc::TimeMillis());
minyuea1d9ad02016-10-02 14:53:37 -0700281
282 std::vector<std::unique_ptr<Controller>> controllers;
minyue678d2ee2017-05-30 07:36:20 -0700283 std::map<const Controller*, std::pair<int, float>> scoring_points;
minyuea1d9ad02016-10-02 14:53:37 -0700284
285 for (int i = 0; i < controller_manager_config.controllers_size(); ++i) {
286 auto& controller_config = controller_manager_config.controllers(i);
287 std::unique_ptr<Controller> controller;
288 switch (controller_config.controller_case()) {
289 case audio_network_adaptor::config::Controller::kFecController:
elad.alon6d7900d2017-03-24 04:12:56 -0700290 controller = CreateFecControllerPlrBased(
michaelt92aef172017-04-18 00:11:48 -0700291 controller_config.fec_controller(), initial_fec_enabled);
minyuea1d9ad02016-10-02 14:53:37 -0700292 break;
elad.alon28770482017-03-28 05:03:55 -0700293 case audio_network_adaptor::config::Controller::kFecControllerRplrBased:
294 controller = CreateFecControllerRplrBased(
295 controller_config.fec_controller_rplr_based(), initial_fec_enabled);
296 break;
minyuea1d9ad02016-10-02 14:53:37 -0700297 case audio_network_adaptor::config::Controller::kFrameLengthController:
298 controller = CreateFrameLengthController(
299 controller_config.frame_length_controller(),
michaelt6f08d7d2017-02-22 07:35:05 -0800300 encoder_frame_lengths_ms, initial_frame_length_ms,
301 min_encoder_bitrate_bps);
minyuea1d9ad02016-10-02 14:53:37 -0700302 break;
303 case audio_network_adaptor::config::Controller::kChannelController:
304 controller = CreateChannelController(
305 controller_config.channel_controller(), num_encoder_channels,
306 intial_channels_to_encode);
307 break;
308 case audio_network_adaptor::config::Controller::kDtxController:
309 controller = CreateDtxController(controller_config.dtx_controller(),
310 initial_dtx_enabled);
311 break;
312 case audio_network_adaptor::config::Controller::kBitrateController:
ivoc7e9c6142017-09-28 01:11:16 -0700313 controller = CreateBitrateController(
314 controller_config.bitrate_controller(), initial_bitrate_bps,
315 initial_frame_length_ms);
minyuea1d9ad02016-10-02 14:53:37 -0700316 break;
317 default:
318 RTC_NOTREACHED();
319 }
320 if (controller_config.has_scoring_point()) {
minyue678d2ee2017-05-30 07:36:20 -0700321 auto& scoring_point = controller_config.scoring_point();
322 RTC_CHECK(scoring_point.has_uplink_bandwidth_bps());
323 RTC_CHECK(scoring_point.has_uplink_packet_loss_fraction());
324 scoring_points[controller.get()] = std::make_pair<int, float>(
325 scoring_point.uplink_bandwidth_bps(),
326 scoring_point.uplink_packet_loss_fraction());
minyuea1d9ad02016-10-02 14:53:37 -0700327 }
328 controllers.push_back(std::move(controller));
329 }
330
minyue12de0772017-05-30 08:56:08 -0700331 if (scoring_points.size() == 0) {
Yves Gerey665174f2018-06-19 15:03:05 +0200332 return std::unique_ptr<ControllerManagerImpl>(
333 new ControllerManagerImpl(ControllerManagerImpl::Config(0, 0),
334 std::move(controllers), scoring_points));
minyue12de0772017-05-30 08:56:08 -0700335 } else {
336 RTC_CHECK(controller_manager_config.has_min_reordering_time_ms());
337 RTC_CHECK(controller_manager_config.has_min_reordering_squared_distance());
338 return std::unique_ptr<ControllerManagerImpl>(new ControllerManagerImpl(
339 ControllerManagerImpl::Config(
340 controller_manager_config.min_reordering_time_ms(),
341 controller_manager_config.min_reordering_squared_distance()),
342 std::move(controllers), scoring_points));
343 }
344
minyuea1d9ad02016-10-02 14:53:37 -0700345#else
346 RTC_NOTREACHED();
347 return nullptr;
minyue-webrtc7ed35f42017-06-13 11:49:29 +0200348#endif // WEBRTC_ENABLE_PROTOBUF
minyuea1d9ad02016-10-02 14:53:37 -0700349}
350
minyuecaa9cb22016-09-13 13:34:15 -0700351ControllerManagerImpl::ControllerManagerImpl(const Config& config)
minyuebc77ed72016-09-22 00:45:16 -0700352 : ControllerManagerImpl(
353 config,
354 std::vector<std::unique_ptr<Controller>>(),
355 std::map<const Controller*, std::pair<int, float>>()) {}
minyuecaa9cb22016-09-13 13:34:15 -0700356
357ControllerManagerImpl::ControllerManagerImpl(
358 const Config& config,
minyue-webrtc5d689102017-08-14 14:33:32 +0200359 std::vector<std::unique_ptr<Controller>> controllers,
minyue678d2ee2017-05-30 07:36:20 -0700360 const std::map<const Controller*, std::pair<int, float>>& scoring_points)
minyuebc77ed72016-09-22 00:45:16 -0700361 : config_(config),
362 controllers_(std::move(controllers)),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200363 last_reordering_time_ms_(absl::nullopt),
minyuebc77ed72016-09-22 00:45:16 -0700364 last_scoring_point_(0, 0.0) {
365 for (auto& controller : controllers_)
minyuecaa9cb22016-09-13 13:34:15 -0700366 default_sorted_controllers_.push_back(controller.get());
minyuebc77ed72016-09-22 00:45:16 -0700367 sorted_controllers_ = default_sorted_controllers_;
minyue678d2ee2017-05-30 07:36:20 -0700368 for (auto& controller_point : scoring_points) {
minyuebc77ed72016-09-22 00:45:16 -0700369 controller_scoring_points_.insert(std::make_pair(
370 controller_point.first, ScoringPoint(controller_point.second.first,
371 controller_point.second.second)));
minyuecaa9cb22016-09-13 13:34:15 -0700372 }
373}
374
375ControllerManagerImpl::~ControllerManagerImpl() = default;
376
377std::vector<Controller*> ControllerManagerImpl::GetSortedControllers(
378 const Controller::NetworkMetrics& metrics) {
minyue12de0772017-05-30 08:56:08 -0700379 if (controller_scoring_points_.size() == 0)
380 return default_sorted_controllers_;
minyuebc77ed72016-09-22 00:45:16 -0700381
382 if (!metrics.uplink_bandwidth_bps || !metrics.uplink_packet_loss_fraction)
383 return sorted_controllers_;
384
minyue12de0772017-05-30 08:56:08 -0700385 const int64_t now_ms = rtc::TimeMillis();
minyuebc77ed72016-09-22 00:45:16 -0700386 if (last_reordering_time_ms_ &&
387 now_ms - *last_reordering_time_ms_ < config_.min_reordering_time_ms)
388 return sorted_controllers_;
389
390 ScoringPoint scoring_point(*metrics.uplink_bandwidth_bps,
391 *metrics.uplink_packet_loss_fraction);
392
393 if (last_reordering_time_ms_ &&
394 last_scoring_point_.SquaredDistanceTo(scoring_point) <
395 config_.min_reordering_squared_distance)
396 return sorted_controllers_;
397
398 // Sort controllers according to the distances of |scoring_point| to the
minyue678d2ee2017-05-30 07:36:20 -0700399 // scoring points of controllers.
minyuebc77ed72016-09-22 00:45:16 -0700400 //
401 // A controller that does not associate with any scoring point
402 // are treated as if
403 // 1) they are less important than any controller that has a scoring point,
404 // 2) they are equally important to any controller that has no scoring point,
405 // and their relative order will follow |default_sorted_controllers_|.
406 std::vector<Controller*> sorted_controllers(default_sorted_controllers_);
407 std::stable_sort(
408 sorted_controllers.begin(), sorted_controllers.end(),
409 [this, &scoring_point](const Controller* lhs, const Controller* rhs) {
410 auto lhs_scoring_point = controller_scoring_points_.find(lhs);
411 auto rhs_scoring_point = controller_scoring_points_.find(rhs);
412
413 if (lhs_scoring_point == controller_scoring_points_.end())
414 return false;
415
416 if (rhs_scoring_point == controller_scoring_points_.end())
417 return true;
418
419 return lhs_scoring_point->second.SquaredDistanceTo(scoring_point) <
420 rhs_scoring_point->second.SquaredDistanceTo(scoring_point);
421 });
422
423 if (sorted_controllers_ != sorted_controllers) {
424 sorted_controllers_ = sorted_controllers;
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100425 last_reordering_time_ms_ = now_ms;
minyuebc77ed72016-09-22 00:45:16 -0700426 last_scoring_point_ = scoring_point;
427 }
428 return sorted_controllers_;
minyuecaa9cb22016-09-13 13:34:15 -0700429}
430
431std::vector<Controller*> ControllerManagerImpl::GetControllers() const {
432 return default_sorted_controllers_;
433}
434
minyuebc77ed72016-09-22 00:45:16 -0700435ControllerManagerImpl::ScoringPoint::ScoringPoint(
436 int uplink_bandwidth_bps,
437 float uplink_packet_loss_fraction)
438 : uplink_bandwidth_bps(uplink_bandwidth_bps),
439 uplink_packet_loss_fraction(uplink_packet_loss_fraction) {}
440
441namespace {
442
443constexpr int kMinUplinkBandwidthBps = 0;
444constexpr int kMaxUplinkBandwidthBps = 120000;
445
446float NormalizeUplinkBandwidth(int uplink_bandwidth_bps) {
447 uplink_bandwidth_bps =
448 std::min(kMaxUplinkBandwidthBps,
449 std::max(kMinUplinkBandwidthBps, uplink_bandwidth_bps));
450 return static_cast<float>(uplink_bandwidth_bps - kMinUplinkBandwidthBps) /
451 (kMaxUplinkBandwidthBps - kMinUplinkBandwidthBps);
452}
453
454float NormalizePacketLossFraction(float uplink_packet_loss_fraction) {
455 // |uplink_packet_loss_fraction| is seldom larger than 0.3, so we scale it up
456 // by 3.3333f.
457 return std::min(uplink_packet_loss_fraction * 3.3333f, 1.0f);
458}
459
460} // namespace
461
462float ControllerManagerImpl::ScoringPoint::SquaredDistanceTo(
463 const ScoringPoint& scoring_point) const {
464 float diff_normalized_bitrate_bps =
465 NormalizeUplinkBandwidth(scoring_point.uplink_bandwidth_bps) -
466 NormalizeUplinkBandwidth(uplink_bandwidth_bps);
467 float diff_normalized_packet_loss =
468 NormalizePacketLossFraction(scoring_point.uplink_packet_loss_fraction) -
469 NormalizePacketLossFraction(uplink_packet_loss_fraction);
470 return std::pow(diff_normalized_bitrate_bps, 2) +
471 std::pow(diff_normalized_packet_loss, 2);
472}
473
minyuecaa9cb22016-09-13 13:34:15 -0700474} // namespace webrtc