blob: 99ccfc98f726057eb9e3715897d3bc599e3f4b81 [file] [log] [blame]
Sebastian Janssondf023aa2018-02-20 19:38:37 +01001/*
2 * Copyright (c) 2018 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 "call/rtp_bitrate_configurator.h"
12
13#include <algorithm>
14
15#include "rtc_base/checks.h"
16
Mirko Bonadei53227cc2019-09-18 14:15:52 +020017namespace {
18
19// Returns its smallest positive argument. If neither argument is positive,
20// returns an arbitrary nonpositive value.
21int MinPositive(int a, int b) {
22 if (a <= 0) {
23 return b;
24 }
25 if (b <= 0) {
26 return a;
27 }
28 return std::min(a, b);
29}
30
31} // namespace
32
Sebastian Janssondf023aa2018-02-20 19:38:37 +010033namespace webrtc {
34RtpBitrateConfigurator::RtpBitrateConfigurator(
35 const BitrateConstraints& bitrate_config)
36 : bitrate_config_(bitrate_config), base_bitrate_config_(bitrate_config) {
37 RTC_DCHECK_GE(bitrate_config.min_bitrate_bps, 0);
38 RTC_DCHECK_GE(bitrate_config.start_bitrate_bps,
39 bitrate_config.min_bitrate_bps);
40 if (bitrate_config.max_bitrate_bps != -1) {
41 RTC_DCHECK_GE(bitrate_config.max_bitrate_bps,
42 bitrate_config.start_bitrate_bps);
43 }
44}
45
46RtpBitrateConfigurator::~RtpBitrateConfigurator() = default;
47
48BitrateConstraints RtpBitrateConfigurator::GetConfig() const {
49 return bitrate_config_;
50}
51
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020052absl::optional<BitrateConstraints>
Sebastian Janssondf023aa2018-02-20 19:38:37 +010053RtpBitrateConfigurator::UpdateWithSdpParameters(
54 const BitrateConstraints& bitrate_config) {
55 RTC_DCHECK_GE(bitrate_config.min_bitrate_bps, 0);
56 RTC_DCHECK_NE(bitrate_config.start_bitrate_bps, 0);
57 if (bitrate_config.max_bitrate_bps != -1) {
58 RTC_DCHECK_GT(bitrate_config.max_bitrate_bps, 0);
59 }
60
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020061 absl::optional<int> new_start;
Sebastian Janssondf023aa2018-02-20 19:38:37 +010062 // Only update the "start" bitrate if it's set, and different from the old
63 // value. In practice, this value comes from the x-google-start-bitrate codec
64 // parameter in SDP, and setting the same remote description twice shouldn't
65 // restart bandwidth estimation.
66 if (bitrate_config.start_bitrate_bps != -1 &&
67 bitrate_config.start_bitrate_bps !=
68 base_bitrate_config_.start_bitrate_bps) {
69 new_start.emplace(bitrate_config.start_bitrate_bps);
70 }
Mirko Bonadeib408bb72020-01-10 15:34:49 +000071 base_bitrate_config_ = bitrate_config;
Sebastian Janssondf023aa2018-02-20 19:38:37 +010072 return UpdateConstraints(new_start);
73}
74
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020075absl::optional<BitrateConstraints>
Sebastian Janssondf023aa2018-02-20 19:38:37 +010076RtpBitrateConfigurator::UpdateWithClientPreferences(
Niels Möller0c4f7be2018-05-07 14:01:37 +020077 const BitrateSettings& bitrate_mask) {
Sebastian Janssondf023aa2018-02-20 19:38:37 +010078 bitrate_config_mask_ = bitrate_mask;
79 return UpdateConstraints(bitrate_mask.start_bitrate_bps);
80}
81
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020082absl::optional<BitrateConstraints> RtpBitrateConfigurator::UpdateConstraints(
83 const absl::optional<int>& new_start) {
Sebastian Janssondf023aa2018-02-20 19:38:37 +010084 BitrateConstraints updated;
85 updated.min_bitrate_bps =
86 std::max(bitrate_config_mask_.min_bitrate_bps.value_or(0),
87 base_bitrate_config_.min_bitrate_bps);
88
89 updated.max_bitrate_bps =
90 MinPositive(bitrate_config_mask_.max_bitrate_bps.value_or(-1),
91 base_bitrate_config_.max_bitrate_bps);
92
93 // If the combined min ends up greater than the combined max, the max takes
94 // priority.
95 if (updated.max_bitrate_bps != -1 &&
96 updated.min_bitrate_bps > updated.max_bitrate_bps) {
97 updated.min_bitrate_bps = updated.max_bitrate_bps;
98 }
99
100 // If there is nothing to update (min/max unchanged, no new bandwidth
101 // estimation start value), return early.
102 if (updated.min_bitrate_bps == bitrate_config_.min_bitrate_bps &&
103 updated.max_bitrate_bps == bitrate_config_.max_bitrate_bps &&
104 !new_start) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200105 return absl::nullopt;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100106 }
107
108 if (new_start) {
109 // Clamp start by min and max.
110 updated.start_bitrate_bps = MinPositive(
111 std::max(*new_start, updated.min_bitrate_bps), updated.max_bitrate_bps);
112 } else {
113 updated.start_bitrate_bps = -1;
114 }
115 BitrateConstraints config_to_return = updated;
116 if (!new_start) {
117 updated.start_bitrate_bps = bitrate_config_.start_bitrate_bps;
118 }
119 bitrate_config_ = updated;
120 return config_to_return;
121}
122
123} // namespace webrtc