OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/pacing/packet_router.h" | 11 #include "webrtc/modules/pacing/packet_router.h" |
12 | 12 |
| 13 #include <algorithm> |
| 14 #include <limits> |
| 15 |
13 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | 16 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
14 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
15 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 18 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
16 #include "webrtc/rtc_base/atomicops.h" | 19 #include "webrtc/rtc_base/atomicops.h" |
17 #include "webrtc/rtc_base/checks.h" | 20 #include "webrtc/rtc_base/checks.h" |
18 #include "webrtc/rtc_base/timeutils.h" | 21 #include "webrtc/rtc_base/timeutils.h" |
19 | 22 |
20 namespace webrtc { | 23 namespace webrtc { |
| 24 namespace { |
| 25 |
| 26 constexpr int kRembSendIntervalMs = 200; |
| 27 |
| 28 } // namespace |
21 | 29 |
22 PacketRouter::PacketRouter() | 30 PacketRouter::PacketRouter() |
23 : last_remb_time_ms_(rtc::TimeMillis()), | 31 : last_remb_time_ms_(rtc::TimeMillis()), |
24 last_send_bitrate_bps_(0), | 32 last_send_bitrate_bps_(0), |
| 33 bitrate_bps_(0), |
| 34 max_bitrate_bps_(std::numeric_limits<decltype(max_bitrate_bps_)>::max()), |
25 active_remb_module_(nullptr), | 35 active_remb_module_(nullptr), |
26 transport_seq_(0) {} | 36 transport_seq_(0) {} |
27 | 37 |
28 PacketRouter::~PacketRouter() { | 38 PacketRouter::~PacketRouter() { |
29 RTC_DCHECK(rtp_send_modules_.empty()); | 39 RTC_DCHECK(rtp_send_modules_.empty()); |
30 RTC_DCHECK(rtp_receive_modules_.empty()); | 40 RTC_DCHECK(rtp_receive_modules_.empty()); |
31 RTC_DCHECK(sender_remb_candidates_.empty()); | 41 RTC_DCHECK(sender_remb_candidates_.empty()); |
32 RTC_DCHECK(receiver_remb_candidates_.empty()); | 42 RTC_DCHECK(receiver_remb_candidates_.empty()); |
33 RTC_DCHECK(active_remb_module_ == nullptr); | 43 RTC_DCHECK(active_remb_module_ == nullptr); |
34 } | 44 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 // return value saves us a load on retry. | 145 // return value saves us a load on retry. |
136 prev_seq = rtc::AtomicOps::CompareAndSwap(&transport_seq_, desired_prev_seq, | 146 prev_seq = rtc::AtomicOps::CompareAndSwap(&transport_seq_, desired_prev_seq, |
137 new_seq); | 147 new_seq); |
138 } while (prev_seq != desired_prev_seq); | 148 } while (prev_seq != desired_prev_seq); |
139 | 149 |
140 return new_seq; | 150 return new_seq; |
141 } | 151 } |
142 | 152 |
143 void PacketRouter::OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs, | 153 void PacketRouter::OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs, |
144 uint32_t bitrate_bps) { | 154 uint32_t bitrate_bps) { |
145 const int kRembSendIntervalMs = 200; | |
146 | |
147 // % threshold for if we should send a new REMB asap. | 155 // % threshold for if we should send a new REMB asap. |
148 const uint32_t kSendThresholdPercent = 97; | 156 const uint32_t kSendThresholdPercent = 97; |
149 | 157 |
150 int64_t now_ms = rtc::TimeMillis(); | 158 int64_t now_ms = rtc::TimeMillis(); |
151 { | 159 { |
152 rtc::CritScope lock(&remb_crit_); | 160 rtc::CritScope lock(&remb_crit_); |
153 | 161 |
154 // If we already have an estimate, check if the new total estimate is below | 162 // If we already have an estimate, check if the new total estimate is below |
155 // kSendThresholdPercent of the previous estimate. | 163 // kSendThresholdPercent of the previous estimate. |
156 if (last_send_bitrate_bps_ > 0) { | 164 if (last_send_bitrate_bps_ > 0) { |
157 uint32_t new_remb_bitrate_bps = | 165 uint32_t new_remb_bitrate_bps = |
158 last_send_bitrate_bps_ - bitrate_bps_ + bitrate_bps; | 166 last_send_bitrate_bps_ - bitrate_bps_ + bitrate_bps; |
159 | 167 |
160 if (new_remb_bitrate_bps < | 168 if (new_remb_bitrate_bps < |
161 kSendThresholdPercent * last_send_bitrate_bps_ / 100) { | 169 kSendThresholdPercent * last_send_bitrate_bps_ / 100) { |
162 // The new bitrate estimate is less than kSendThresholdPercent % of the | 170 // The new bitrate estimate is less than kSendThresholdPercent % of the |
163 // last report. Send a REMB asap. | 171 // last report. Send a REMB asap. |
164 last_remb_time_ms_ = now_ms - kRembSendIntervalMs; | 172 last_remb_time_ms_ = now_ms - kRembSendIntervalMs; |
165 } | 173 } |
166 } | 174 } |
167 bitrate_bps_ = bitrate_bps; | 175 bitrate_bps_ = bitrate_bps; |
168 | 176 |
169 if (now_ms - last_remb_time_ms_ < kRembSendIntervalMs) { | 177 if (now_ms - last_remb_time_ms_ < kRembSendIntervalMs) { |
170 return; | 178 return; |
171 } | 179 } |
172 // NOTE: Updated if we intend to send the data; we might not have | 180 // NOTE: Updated if we intend to send the data; we might not have |
173 // a module to actually send it. | 181 // a module to actually send it. |
174 last_remb_time_ms_ = now_ms; | 182 last_remb_time_ms_ = now_ms; |
175 last_send_bitrate_bps_ = bitrate_bps; | 183 last_send_bitrate_bps_ = bitrate_bps; |
| 184 // Cap the value to send in remb with configured value. |
| 185 bitrate_bps = std::min(bitrate_bps, max_bitrate_bps_); |
176 } | 186 } |
177 SendRemb(bitrate_bps, ssrcs); | 187 SendRemb(bitrate_bps, ssrcs); |
178 } | 188 } |
179 | 189 |
| 190 void PacketRouter::SetMaxDesiredReceiveBitrate(uint32_t bitrate_bps) { |
| 191 { |
| 192 rtc::CritScope lock(&remb_crit_); |
| 193 max_bitrate_bps_ = bitrate_bps; |
| 194 if (rtc::TimeMillis() - last_remb_time_ms_ < kRembSendIntervalMs && |
| 195 last_send_bitrate_bps_ > 0 && |
| 196 last_send_bitrate_bps_ <= max_bitrate_bps_) { |
| 197 // Recent measured bitrate is already below the cap. |
| 198 return; |
| 199 } |
| 200 } |
| 201 SendRemb(bitrate_bps, /*ssrcs=*/{}); |
| 202 } |
| 203 |
180 bool PacketRouter::SendRemb(uint32_t bitrate_bps, | 204 bool PacketRouter::SendRemb(uint32_t bitrate_bps, |
181 const std::vector<uint32_t>& ssrcs) { | 205 const std::vector<uint32_t>& ssrcs) { |
182 rtc::CritScope lock(&modules_crit_); | 206 rtc::CritScope lock(&modules_crit_); |
183 | 207 |
184 if (!active_remb_module_) { | 208 if (!active_remb_module_) { |
185 return false; | 209 return false; |
186 } | 210 } |
187 | 211 |
188 // The Add* and Remove* methods above ensure that this (and only this) module | 212 // The Add* and Remove* methods above ensure that this (and only this) module |
189 // has REMB enabled. REMB should be disabled on all other modules, because | 213 // has REMB enabled. REMB should be disabled on all other modules, because |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 if (new_active_remb_module_) { | 294 if (new_active_remb_module_) { |
271 RTC_DCHECK(!new_active_remb_module_->REMB()); | 295 RTC_DCHECK(!new_active_remb_module_->REMB()); |
272 new_active_remb_module_->SetREMBStatus(true); | 296 new_active_remb_module_->SetREMBStatus(true); |
273 } | 297 } |
274 } | 298 } |
275 | 299 |
276 active_remb_module_ = new_active_remb_module_; | 300 active_remb_module_ = new_active_remb_module_; |
277 } | 301 } |
278 | 302 |
279 } // namespace webrtc | 303 } // namespace webrtc |
OLD | NEW |