Line data Source code
1 : /*
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 :
11 : #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h"
12 :
13 : #include <cmath>
14 : #include <utility>
15 :
16 : #include "webrtc/base/ignore_wundef.h"
17 : #include "webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.h"
18 : #include "webrtc/modules/audio_coding/audio_network_adaptor/channel_controller.h"
19 : #include "webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.h"
20 : #include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h"
21 : #include "webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h"
22 : #include "webrtc/system_wrappers/include/clock.h"
23 :
24 : #ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
25 : RTC_PUSH_IGNORING_WUNDEF()
26 : #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
27 : #include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h"
28 : #else
29 : #include "webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h"
30 : #endif
31 : RTC_POP_IGNORING_WUNDEF()
32 : #endif
33 :
34 : namespace webrtc {
35 :
36 : namespace {
37 :
38 : #ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
39 :
40 : std::unique_ptr<FecController> CreateFecController(
41 : const audio_network_adaptor::config::FecController& config,
42 : bool initial_fec_enabled,
43 : const Clock* clock) {
44 : RTC_CHECK(config.has_fec_enabling_threshold());
45 : RTC_CHECK(config.has_fec_disabling_threshold());
46 : RTC_CHECK(config.has_time_constant_ms());
47 :
48 : auto& fec_enabling_threshold = config.fec_enabling_threshold();
49 : RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_bps());
50 : RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_packet_loss());
51 : RTC_CHECK(fec_enabling_threshold.has_high_bandwidth_bps());
52 : RTC_CHECK(fec_enabling_threshold.has_high_bandwidth_packet_loss());
53 :
54 : auto& fec_disabling_threshold = config.fec_disabling_threshold();
55 : RTC_CHECK(fec_disabling_threshold.has_low_bandwidth_bps());
56 : RTC_CHECK(fec_disabling_threshold.has_low_bandwidth_packet_loss());
57 : RTC_CHECK(fec_disabling_threshold.has_high_bandwidth_bps());
58 : RTC_CHECK(fec_disabling_threshold.has_high_bandwidth_packet_loss());
59 :
60 : return std::unique_ptr<FecController>(new FecController(FecController::Config(
61 : initial_fec_enabled,
62 : FecController::Config::Threshold(
63 : fec_enabling_threshold.low_bandwidth_bps(),
64 : fec_enabling_threshold.low_bandwidth_packet_loss(),
65 : fec_enabling_threshold.high_bandwidth_bps(),
66 : fec_enabling_threshold.high_bandwidth_packet_loss()),
67 : FecController::Config::Threshold(
68 : fec_disabling_threshold.low_bandwidth_bps(),
69 : fec_disabling_threshold.low_bandwidth_packet_loss(),
70 : fec_disabling_threshold.high_bandwidth_bps(),
71 : fec_disabling_threshold.high_bandwidth_packet_loss()),
72 : config.time_constant_ms(), clock)));
73 : }
74 :
75 : std::unique_ptr<FrameLengthController> CreateFrameLengthController(
76 : const audio_network_adaptor::config::FrameLengthController& config,
77 : rtc::ArrayView<const int> encoder_frame_lengths_ms,
78 : int initial_frame_length_ms) {
79 : RTC_CHECK(config.has_fl_increasing_packet_loss_fraction());
80 : RTC_CHECK(config.has_fl_decreasing_packet_loss_fraction());
81 : RTC_CHECK(config.has_fl_20ms_to_60ms_bandwidth_bps());
82 : RTC_CHECK(config.has_fl_60ms_to_20ms_bandwidth_bps());
83 :
84 : FrameLengthController::Config ctor_config(
85 : std::vector<int>(), initial_frame_length_ms,
86 : config.fl_increasing_packet_loss_fraction(),
87 : config.fl_decreasing_packet_loss_fraction(),
88 : config.fl_20ms_to_60ms_bandwidth_bps(),
89 : config.fl_60ms_to_20ms_bandwidth_bps());
90 :
91 : for (auto frame_length : encoder_frame_lengths_ms)
92 : ctor_config.encoder_frame_lengths_ms.push_back(frame_length);
93 :
94 : return std::unique_ptr<FrameLengthController>(
95 : new FrameLengthController(ctor_config));
96 : }
97 :
98 : std::unique_ptr<ChannelController> CreateChannelController(
99 : const audio_network_adaptor::config::ChannelController& config,
100 : size_t num_encoder_channels,
101 : size_t intial_channels_to_encode) {
102 : RTC_CHECK(config.has_channel_1_to_2_bandwidth_bps());
103 : RTC_CHECK(config.has_channel_2_to_1_bandwidth_bps());
104 :
105 : return std::unique_ptr<ChannelController>(new ChannelController(
106 : ChannelController::Config(num_encoder_channels, intial_channels_to_encode,
107 : config.channel_1_to_2_bandwidth_bps(),
108 : config.channel_2_to_1_bandwidth_bps())));
109 : }
110 :
111 : std::unique_ptr<DtxController> CreateDtxController(
112 : const audio_network_adaptor::config::DtxController& dtx_config,
113 : bool initial_dtx_enabled) {
114 : RTC_CHECK(dtx_config.has_dtx_enabling_bandwidth_bps());
115 : RTC_CHECK(dtx_config.has_dtx_disabling_bandwidth_bps());
116 :
117 : return std::unique_ptr<DtxController>(new DtxController(DtxController::Config(
118 : initial_dtx_enabled, dtx_config.dtx_enabling_bandwidth_bps(),
119 : dtx_config.dtx_disabling_bandwidth_bps())));
120 : }
121 :
122 : using audio_network_adaptor::BitrateController;
123 : std::unique_ptr<BitrateController> CreateBitrateController(
124 : int initial_bitrate_bps,
125 : int initial_frame_length_ms) {
126 : return std::unique_ptr<BitrateController>(new BitrateController(
127 : BitrateController::Config(initial_bitrate_bps, initial_frame_length_ms)));
128 : }
129 : #endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
130 :
131 : } // namespace
132 :
133 0 : ControllerManagerImpl::Config::Config(int min_reordering_time_ms,
134 : float min_reordering_squared_distance,
135 0 : const Clock* clock)
136 : : min_reordering_time_ms(min_reordering_time_ms),
137 : min_reordering_squared_distance(min_reordering_squared_distance),
138 0 : clock(clock) {}
139 :
140 : ControllerManagerImpl::Config::~Config() = default;
141 :
142 0 : std::unique_ptr<ControllerManager> ControllerManagerImpl::Create(
143 : const std::string& config_string,
144 : size_t num_encoder_channels,
145 : rtc::ArrayView<const int> encoder_frame_lengths_ms,
146 : size_t intial_channels_to_encode,
147 : int initial_frame_length_ms,
148 : int initial_bitrate_bps,
149 : bool initial_fec_enabled,
150 : bool initial_dtx_enabled,
151 : const Clock* clock) {
152 : #ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
153 : audio_network_adaptor::config::ControllerManager controller_manager_config;
154 : controller_manager_config.ParseFromString(config_string);
155 :
156 : std::vector<std::unique_ptr<Controller>> controllers;
157 : std::map<const Controller*, std::pair<int, float>> chracteristic_points;
158 :
159 : for (int i = 0; i < controller_manager_config.controllers_size(); ++i) {
160 : auto& controller_config = controller_manager_config.controllers(i);
161 : std::unique_ptr<Controller> controller;
162 : switch (controller_config.controller_case()) {
163 : case audio_network_adaptor::config::Controller::kFecController:
164 : controller = CreateFecController(controller_config.fec_controller(),
165 : initial_fec_enabled, clock);
166 : break;
167 : case audio_network_adaptor::config::Controller::kFrameLengthController:
168 : controller = CreateFrameLengthController(
169 : controller_config.frame_length_controller(),
170 : encoder_frame_lengths_ms, initial_frame_length_ms);
171 : break;
172 : case audio_network_adaptor::config::Controller::kChannelController:
173 : controller = CreateChannelController(
174 : controller_config.channel_controller(), num_encoder_channels,
175 : intial_channels_to_encode);
176 : break;
177 : case audio_network_adaptor::config::Controller::kDtxController:
178 : controller = CreateDtxController(controller_config.dtx_controller(),
179 : initial_dtx_enabled);
180 : break;
181 : case audio_network_adaptor::config::Controller::kBitrateController:
182 : controller = CreateBitrateController(initial_bitrate_bps,
183 : initial_frame_length_ms);
184 : break;
185 : default:
186 : RTC_NOTREACHED();
187 : }
188 : if (controller_config.has_scoring_point()) {
189 : auto& characteristic_point = controller_config.scoring_point();
190 : RTC_CHECK(characteristic_point.has_uplink_bandwidth_bps());
191 : RTC_CHECK(characteristic_point.has_uplink_packet_loss_fraction());
192 : chracteristic_points[controller.get()] = std::make_pair<int, float>(
193 : characteristic_point.uplink_bandwidth_bps(),
194 : characteristic_point.uplink_packet_loss_fraction());
195 : }
196 : controllers.push_back(std::move(controller));
197 : }
198 :
199 : RTC_CHECK(controller_manager_config.has_min_reordering_time_ms());
200 : RTC_CHECK(controller_manager_config.has_min_reordering_squared_distance());
201 : return std::unique_ptr<ControllerManagerImpl>(new ControllerManagerImpl(
202 : ControllerManagerImpl::Config(
203 : controller_manager_config.min_reordering_time_ms(),
204 : controller_manager_config.min_reordering_squared_distance(), clock),
205 : std::move(controllers), chracteristic_points));
206 : #else
207 0 : RTC_NOTREACHED();
208 0 : return nullptr;
209 : #endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
210 : }
211 :
212 0 : ControllerManagerImpl::ControllerManagerImpl(const Config& config)
213 : : ControllerManagerImpl(
214 : config,
215 0 : std::vector<std::unique_ptr<Controller>>(),
216 0 : std::map<const Controller*, std::pair<int, float>>()) {}
217 :
218 0 : ControllerManagerImpl::ControllerManagerImpl(
219 : const Config& config,
220 : std::vector<std::unique_ptr<Controller>>&& controllers,
221 : const std::map<const Controller*, std::pair<int, float>>&
222 0 : chracteristic_points)
223 : : config_(config),
224 0 : controllers_(std::move(controllers)),
225 : last_reordering_time_ms_(rtc::Optional<int64_t>()),
226 0 : last_scoring_point_(0, 0.0) {
227 0 : for (auto& controller : controllers_)
228 0 : default_sorted_controllers_.push_back(controller.get());
229 0 : sorted_controllers_ = default_sorted_controllers_;
230 0 : for (auto& controller_point : chracteristic_points) {
231 0 : controller_scoring_points_.insert(std::make_pair(
232 0 : controller_point.first, ScoringPoint(controller_point.second.first,
233 0 : controller_point.second.second)));
234 : }
235 0 : }
236 :
237 : ControllerManagerImpl::~ControllerManagerImpl() = default;
238 :
239 0 : std::vector<Controller*> ControllerManagerImpl::GetSortedControllers(
240 : const Controller::NetworkMetrics& metrics) {
241 0 : int64_t now_ms = config_.clock->TimeInMilliseconds();
242 :
243 0 : if (!metrics.uplink_bandwidth_bps || !metrics.uplink_packet_loss_fraction)
244 0 : return sorted_controllers_;
245 :
246 0 : if (last_reordering_time_ms_ &&
247 0 : now_ms - *last_reordering_time_ms_ < config_.min_reordering_time_ms)
248 0 : return sorted_controllers_;
249 :
250 0 : ScoringPoint scoring_point(*metrics.uplink_bandwidth_bps,
251 0 : *metrics.uplink_packet_loss_fraction);
252 :
253 0 : if (last_reordering_time_ms_ &&
254 0 : last_scoring_point_.SquaredDistanceTo(scoring_point) <
255 0 : config_.min_reordering_squared_distance)
256 0 : return sorted_controllers_;
257 :
258 : // Sort controllers according to the distances of |scoring_point| to the
259 : // characteristic scoring points of controllers.
260 : //
261 : // A controller that does not associate with any scoring point
262 : // are treated as if
263 : // 1) they are less important than any controller that has a scoring point,
264 : // 2) they are equally important to any controller that has no scoring point,
265 : // and their relative order will follow |default_sorted_controllers_|.
266 0 : std::vector<Controller*> sorted_controllers(default_sorted_controllers_);
267 0 : std::stable_sort(
268 : sorted_controllers.begin(), sorted_controllers.end(),
269 0 : [this, &scoring_point](const Controller* lhs, const Controller* rhs) {
270 0 : auto lhs_scoring_point = controller_scoring_points_.find(lhs);
271 0 : auto rhs_scoring_point = controller_scoring_points_.find(rhs);
272 :
273 0 : if (lhs_scoring_point == controller_scoring_points_.end())
274 0 : return false;
275 :
276 0 : if (rhs_scoring_point == controller_scoring_points_.end())
277 0 : return true;
278 :
279 0 : return lhs_scoring_point->second.SquaredDistanceTo(scoring_point) <
280 0 : rhs_scoring_point->second.SquaredDistanceTo(scoring_point);
281 0 : });
282 :
283 0 : if (sorted_controllers_ != sorted_controllers) {
284 0 : sorted_controllers_ = sorted_controllers;
285 0 : last_reordering_time_ms_ = rtc::Optional<int64_t>(now_ms);
286 0 : last_scoring_point_ = scoring_point;
287 : }
288 0 : return sorted_controllers_;
289 : }
290 :
291 0 : std::vector<Controller*> ControllerManagerImpl::GetControllers() const {
292 0 : return default_sorted_controllers_;
293 : }
294 :
295 0 : ControllerManagerImpl::ScoringPoint::ScoringPoint(
296 : int uplink_bandwidth_bps,
297 0 : float uplink_packet_loss_fraction)
298 : : uplink_bandwidth_bps(uplink_bandwidth_bps),
299 0 : uplink_packet_loss_fraction(uplink_packet_loss_fraction) {}
300 :
301 : namespace {
302 :
303 : constexpr int kMinUplinkBandwidthBps = 0;
304 : constexpr int kMaxUplinkBandwidthBps = 120000;
305 :
306 0 : float NormalizeUplinkBandwidth(int uplink_bandwidth_bps) {
307 0 : uplink_bandwidth_bps =
308 0 : std::min(kMaxUplinkBandwidthBps,
309 0 : std::max(kMinUplinkBandwidthBps, uplink_bandwidth_bps));
310 0 : return static_cast<float>(uplink_bandwidth_bps - kMinUplinkBandwidthBps) /
311 0 : (kMaxUplinkBandwidthBps - kMinUplinkBandwidthBps);
312 : }
313 :
314 0 : float NormalizePacketLossFraction(float uplink_packet_loss_fraction) {
315 : // |uplink_packet_loss_fraction| is seldom larger than 0.3, so we scale it up
316 : // by 3.3333f.
317 0 : return std::min(uplink_packet_loss_fraction * 3.3333f, 1.0f);
318 : }
319 :
320 : } // namespace
321 :
322 0 : float ControllerManagerImpl::ScoringPoint::SquaredDistanceTo(
323 : const ScoringPoint& scoring_point) const {
324 : float diff_normalized_bitrate_bps =
325 0 : NormalizeUplinkBandwidth(scoring_point.uplink_bandwidth_bps) -
326 0 : NormalizeUplinkBandwidth(uplink_bandwidth_bps);
327 : float diff_normalized_packet_loss =
328 0 : NormalizePacketLossFraction(scoring_point.uplink_packet_loss_fraction) -
329 0 : NormalizePacketLossFraction(uplink_packet_loss_fraction);
330 0 : return std::pow(diff_normalized_bitrate_bps, 2) +
331 0 : std::pow(diff_normalized_packet_loss, 2);
332 : }
333 :
334 : } // namespace webrtc
|