• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 namespace {
18 
19 // Returns its smallest positive argument. If neither argument is positive,
20 // returns an arbitrary nonpositive value.
MinPositive(int a,int b)21 int 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 
33 namespace webrtc {
RtpBitrateConfigurator(const BitrateConstraints & bitrate_config)34 RtpBitrateConfigurator::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 
46 RtpBitrateConfigurator::~RtpBitrateConfigurator() = default;
47 
GetConfig() const48 BitrateConstraints RtpBitrateConfigurator::GetConfig() const {
49   return bitrate_config_;
50 }
51 
52 absl::optional<BitrateConstraints>
UpdateWithSdpParameters(const BitrateConstraints & bitrate_config)53 RtpBitrateConfigurator::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 
61   absl::optional<int> new_start;
62   // 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   }
71   base_bitrate_config_ = bitrate_config;
72   return UpdateConstraints(new_start);
73 }
74 
75 absl::optional<BitrateConstraints>
UpdateWithClientPreferences(const BitrateSettings & bitrate_mask)76 RtpBitrateConfigurator::UpdateWithClientPreferences(
77     const BitrateSettings& bitrate_mask) {
78   bitrate_config_mask_ = bitrate_mask;
79   return UpdateConstraints(bitrate_mask.start_bitrate_bps);
80 }
81 
82 // Relay cap can change only max bitrate.
UpdateWithRelayCap(DataRate cap)83 absl::optional<BitrateConstraints> RtpBitrateConfigurator::UpdateWithRelayCap(
84     DataRate cap) {
85   if (cap.IsFinite()) {
86     RTC_DCHECK(!cap.IsZero());
87   }
88   max_bitrate_over_relay_ = cap;
89   return UpdateConstraints(absl::nullopt);
90 }
91 
UpdateConstraints(const absl::optional<int> & new_start)92 absl::optional<BitrateConstraints> RtpBitrateConfigurator::UpdateConstraints(
93     const absl::optional<int>& new_start) {
94   BitrateConstraints updated;
95   updated.min_bitrate_bps =
96       std::max(bitrate_config_mask_.min_bitrate_bps.value_or(0),
97                base_bitrate_config_.min_bitrate_bps);
98 
99   updated.max_bitrate_bps =
100       MinPositive(bitrate_config_mask_.max_bitrate_bps.value_or(-1),
101                   base_bitrate_config_.max_bitrate_bps);
102   updated.max_bitrate_bps =
103       MinPositive(updated.max_bitrate_bps, max_bitrate_over_relay_.bps_or(-1));
104 
105   // If the combined min ends up greater than the combined max, the max takes
106   // priority.
107   if (updated.max_bitrate_bps != -1 &&
108       updated.min_bitrate_bps > updated.max_bitrate_bps) {
109     updated.min_bitrate_bps = updated.max_bitrate_bps;
110   }
111 
112   // If there is nothing to update (min/max unchanged, no new bandwidth
113   // estimation start value), return early.
114   if (updated.min_bitrate_bps == bitrate_config_.min_bitrate_bps &&
115       updated.max_bitrate_bps == bitrate_config_.max_bitrate_bps &&
116       !new_start) {
117     return absl::nullopt;
118   }
119 
120   if (new_start) {
121     // Clamp start by min and max.
122     updated.start_bitrate_bps = MinPositive(
123         std::max(*new_start, updated.min_bitrate_bps), updated.max_bitrate_bps);
124   } else {
125     updated.start_bitrate_bps = -1;
126   }
127   BitrateConstraints config_to_return = updated;
128   if (!new_start) {
129     updated.start_bitrate_bps = bitrate_config_.start_bitrate_bps;
130   }
131   bitrate_config_ = updated;
132   return config_to_return;
133 }
134 
135 }  // namespace webrtc
136