Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: webrtc/modules/pacing/packet_router.cc

Issue 2973363002: Explicitly inform PacketRouter which RTP-RTCP modules are REMB-candidates (Closed)
Patch Set: . Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/pacing/packet_router.h ('k') | webrtc/modules/pacing/packet_router_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 13 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
14 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 14 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
15 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" 15 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
16 #include "webrtc/rtc_base/atomicops.h" 16 #include "webrtc/rtc_base/atomicops.h"
17 #include "webrtc/rtc_base/checks.h" 17 #include "webrtc/rtc_base/checks.h"
18 #include "webrtc/rtc_base/timeutils.h" 18 #include "webrtc/rtc_base/timeutils.h"
19 19
20 namespace webrtc { 20 namespace webrtc {
21 21
22 PacketRouter::PacketRouter() 22 PacketRouter::PacketRouter()
23 : last_remb_time_ms_(rtc::TimeMillis()), 23 : last_remb_time_ms_(rtc::TimeMillis()),
24 last_send_bitrate_bps_(0), 24 last_send_bitrate_bps_(0),
25 active_remb_module_(nullptr),
25 transport_seq_(0) {} 26 transport_seq_(0) {}
26 27
27 PacketRouter::~PacketRouter() { 28 PacketRouter::~PacketRouter() {
28 RTC_DCHECK(rtp_send_modules_.empty()); 29 RTC_DCHECK(rtp_send_modules_.empty());
29 RTC_DCHECK(rtp_receive_modules_.empty()); 30 RTC_DCHECK(rtp_receive_modules_.empty());
31 RTC_DCHECK(sender_remb_candidates_.empty());
32 RTC_DCHECK(receiver_remb_candidates_.empty());
33 RTC_DCHECK(active_remb_module_ == nullptr);
30 } 34 }
31 35
32 void PacketRouter::AddSendRtpModule(RtpRtcp* rtp_module) { 36 void PacketRouter::AddSendRtpModule(RtpRtcp* rtp_module, bool remb_candidate) {
33 rtc::CritScope cs(&modules_crit_); 37 rtc::CritScope cs(&modules_crit_);
34 RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), 38 RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(),
35 rtp_module) == rtp_send_modules_.end()); 39 rtp_module) == rtp_send_modules_.end());
36 if (rtp_send_modules_.empty() && !rtp_receive_modules_.empty()) {
37 rtp_receive_modules_.front()->SetREMBStatus(false);
38 }
39
40 // Put modules which can use regular payload packets (over rtx) instead of 40 // Put modules which can use regular payload packets (over rtx) instead of
41 // padding first as it's less of a waste 41 // padding first as it's less of a waste
42 if ((rtp_module->RtxSendStatus() & kRtxRedundantPayloads) > 0) { 42 if ((rtp_module->RtxSendStatus() & kRtxRedundantPayloads) > 0) {
43 if (!rtp_send_modules_.empty()) {
44 rtp_send_modules_.front()->SetREMBStatus(false);
45 }
46 rtp_send_modules_.push_front(rtp_module); 43 rtp_send_modules_.push_front(rtp_module);
47 rtp_module->SetREMBStatus(true);
48 } else { 44 } else {
49 if (rtp_send_modules_.empty()) { 45 rtp_send_modules_.push_back(rtp_module);
50 rtp_module->SetREMBStatus(true); 46 }
51 }
52 47
53 rtp_send_modules_.push_back(rtp_module); 48 if (remb_candidate) {
49 AddRembModuleCandidate(rtp_module, true);
54 } 50 }
55 } 51 }
56 52
57 void PacketRouter::RemoveSendRtpModule(RtpRtcp* rtp_module) { 53 void PacketRouter::RemoveSendRtpModule(RtpRtcp* rtp_module) {
58 rtc::CritScope cs(&modules_crit_); 54 rtc::CritScope cs(&modules_crit_);
59 RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), 55 MaybeRemoveRembModuleCandidate(rtp_module, /* sender = */ true);
60 rtp_module) != rtp_send_modules_.end()); 56 auto it =
61 rtp_send_modules_.remove(rtp_module); 57 std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), rtp_module);
62 rtp_module->SetREMBStatus(false); 58 RTC_DCHECK(it != rtp_send_modules_.end());
63 if (!rtp_send_modules_.empty()) { 59 rtp_send_modules_.erase(it);
64 rtp_send_modules_.front()->SetREMBStatus(true);
65 } else if (!rtp_receive_modules_.empty()) {
66 rtp_receive_modules_.front()->SetREMBStatus(true);
67 }
68 } 60 }
69 61
70 void PacketRouter::AddReceiveRtpModule(RtpRtcp* rtp_module) { 62 void PacketRouter::AddReceiveRtpModule(RtpRtcp* rtp_module,
63 bool remb_candidate) {
71 rtc::CritScope cs(&modules_crit_); 64 rtc::CritScope cs(&modules_crit_);
72 RTC_DCHECK(std::find(rtp_receive_modules_.begin(), rtp_receive_modules_.end(), 65 RTC_DCHECK(std::find(rtp_receive_modules_.begin(), rtp_receive_modules_.end(),
73 rtp_module) == rtp_receive_modules_.end()); 66 rtp_module) == rtp_receive_modules_.end());
74 if (rtp_send_modules_.empty() && rtp_receive_modules_.empty()) { 67
75 rtp_module->SetREMBStatus(true); 68 rtp_receive_modules_.push_back(rtp_module);
69
70 if (remb_candidate) {
71 AddRembModuleCandidate(rtp_module, false);
76 } 72 }
77 rtp_receive_modules_.push_back(rtp_module);
78 } 73 }
79 74
80 void PacketRouter::RemoveReceiveRtpModule(RtpRtcp* rtp_module) { 75 void PacketRouter::RemoveReceiveRtpModule(RtpRtcp* rtp_module) {
81 rtc::CritScope cs(&modules_crit_); 76 rtc::CritScope cs(&modules_crit_);
77 MaybeRemoveRembModuleCandidate(rtp_module, /* sender = */ false);
82 const auto& it = std::find(rtp_receive_modules_.begin(), 78 const auto& it = std::find(rtp_receive_modules_.begin(),
83 rtp_receive_modules_.end(), rtp_module); 79 rtp_receive_modules_.end(), rtp_module);
84 RTC_DCHECK(it != rtp_receive_modules_.end()); 80 RTC_DCHECK(it != rtp_receive_modules_.end());
85 rtp_receive_modules_.erase(it); 81 rtp_receive_modules_.erase(it);
86 if (rtp_send_modules_.empty()) {
87 rtp_module->SetREMBStatus(false);
88 if (!rtp_receive_modules_.empty()) {
89 rtp_receive_modules_.front()->SetREMBStatus(true);
90 }
91 }
92 } 82 }
93 83
94 bool PacketRouter::TimeToSendPacket(uint32_t ssrc, 84 bool PacketRouter::TimeToSendPacket(uint32_t ssrc,
95 uint16_t sequence_number, 85 uint16_t sequence_number,
96 int64_t capture_timestamp, 86 int64_t capture_timestamp,
97 bool retransmission, 87 bool retransmission,
98 const PacedPacketInfo& pacing_info) { 88 const PacedPacketInfo& pacing_info) {
99 RTC_DCHECK_RUNS_SERIALIZED(&pacer_race_); 89 RTC_DCHECK_RUNS_SERIALIZED(&pacer_race_);
100 rtc::CritScope cs(&modules_crit_); 90 rtc::CritScope cs(&modules_crit_);
101 for (auto* rtp_module : rtp_send_modules_) { 91 for (auto* rtp_module : rtp_send_modules_) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 // a module to actually send it. 173 // a module to actually send it.
184 last_remb_time_ms_ = now_ms; 174 last_remb_time_ms_ = now_ms;
185 last_send_bitrate_bps_ = bitrate_bps; 175 last_send_bitrate_bps_ = bitrate_bps;
186 } 176 }
187 SendRemb(bitrate_bps, ssrcs); 177 SendRemb(bitrate_bps, ssrcs);
188 } 178 }
189 179
190 bool PacketRouter::SendRemb(uint32_t bitrate_bps, 180 bool PacketRouter::SendRemb(uint32_t bitrate_bps,
191 const std::vector<uint32_t>& ssrcs) { 181 const std::vector<uint32_t>& ssrcs) {
192 rtc::CritScope lock(&modules_crit_); 182 rtc::CritScope lock(&modules_crit_);
193 RtpRtcp* remb_module; 183
194 if (!rtp_send_modules_.empty()) 184 if (!active_remb_module_) {
195 remb_module = rtp_send_modules_.front();
196 else if (!rtp_receive_modules_.empty())
197 remb_module = rtp_receive_modules_.front();
198 else
199 return false; 185 return false;
186 }
187
200 // The Add* and Remove* methods above ensure that this (and only this) module 188 // The Add* and Remove* methods above ensure that this (and only this) module
201 // has REMB enabled. REMB should be disabled on all other modules, because 189 // has REMB enabled. REMB should be disabled on all other modules, because
202 // otherwise, they will send REMB with stale info. 190 // otherwise, they will send REMB with stale info.
203 RTC_DCHECK(remb_module->REMB()); 191 RTC_DCHECK(active_remb_module_->REMB());
204 remb_module->SetREMBData(bitrate_bps, ssrcs); 192 active_remb_module_->SetREMBData(bitrate_bps, ssrcs);
193
205 return true; 194 return true;
206 } 195 }
207 196
208 bool PacketRouter::SendTransportFeedback(rtcp::TransportFeedback* packet) { 197 bool PacketRouter::SendTransportFeedback(rtcp::TransportFeedback* packet) {
209 RTC_DCHECK_RUNS_SERIALIZED(&pacer_race_); 198 RTC_DCHECK_RUNS_SERIALIZED(&pacer_race_);
210 rtc::CritScope cs(&modules_crit_); 199 rtc::CritScope cs(&modules_crit_);
211 // Prefer send modules. 200 // Prefer send modules.
212 for (auto* rtp_module : rtp_send_modules_) { 201 for (auto* rtp_module : rtp_send_modules_) {
213 packet->SetSenderSsrc(rtp_module->SSRC()); 202 packet->SetSenderSsrc(rtp_module->SSRC());
214 if (rtp_module->SendFeedbackPacket(*packet)) 203 if (rtp_module->SendFeedbackPacket(*packet))
215 return true; 204 return true;
216 } 205 }
217 for (auto* rtp_module : rtp_receive_modules_) { 206 for (auto* rtp_module : rtp_receive_modules_) {
218 packet->SetSenderSsrc(rtp_module->SSRC()); 207 packet->SetSenderSsrc(rtp_module->SSRC());
219 if (rtp_module->SendFeedbackPacket(*packet)) 208 if (rtp_module->SendFeedbackPacket(*packet))
220 return true; 209 return true;
221 } 210 }
222 return false; 211 return false;
223 } 212 }
224 213
214 void PacketRouter::AddRembModuleCandidate(RtpRtcp* candidate_module,
215 bool sender) {
216 RTC_DCHECK(candidate_module);
217 std::vector<RtpRtcp*>& candidates =
218 sender ? sender_remb_candidates_ : receiver_remb_candidates_;
219 RTC_DCHECK(std::find(candidates.cbegin(), candidates.cend(),
220 candidate_module) == candidates.cend());
221 candidates.push_back(candidate_module);
222 DetermineActiveRembModule();
223 }
224
225 void PacketRouter::MaybeRemoveRembModuleCandidate(RtpRtcp* candidate_module,
226 bool sender) {
227 RTC_DCHECK(candidate_module);
228 std::vector<RtpRtcp*>& candidates =
229 sender ? sender_remb_candidates_ : receiver_remb_candidates_;
230 auto it = std::find(candidates.begin(), candidates.end(), candidate_module);
231
232 if (it == candidates.end()) {
233 return; // Function called due to removal of non-REMB-candidate module.
234 }
235
236 if (*it == active_remb_module_) {
237 UnsetActiveRembModule();
238 }
239 candidates.erase(it);
240 DetermineActiveRembModule();
241 }
242
243 void PacketRouter::UnsetActiveRembModule() {
244 RTC_CHECK(active_remb_module_);
245 RTC_DCHECK(active_remb_module_->REMB());
246 active_remb_module_->SetREMBStatus(false);
247 active_remb_module_ = nullptr;
248 }
249
250 void PacketRouter::DetermineActiveRembModule() {
251 // Sender modules take precedence over receiver modules, because SRs (sender
252 // reports) are sent more frequently than RR (receiver reports).
253 // When adding the first sender module, we should change the active REMB
254 // module to be that. Otherwise, we remain with the current active module.
255
256 RtpRtcp* new_active_remb_module_;
257
258 if (!sender_remb_candidates_.empty()) {
259 new_active_remb_module_ = sender_remb_candidates_.front();
260 } else if (!receiver_remb_candidates_.empty()) {
261 new_active_remb_module_ = receiver_remb_candidates_.front();
262 } else {
263 new_active_remb_module_ = nullptr;
264 }
265
266 if (new_active_remb_module_ != active_remb_module_) {
267 if (active_remb_module_) {
268 UnsetActiveRembModule();
269 }
270 if (new_active_remb_module_) {
271 RTC_DCHECK(!new_active_remb_module_->REMB());
272 new_active_remb_module_->SetREMBStatus(true);
273 }
274 }
275
276 active_remb_module_ = new_active_remb_module_;
277 }
278
225 } // namespace webrtc 279 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/pacing/packet_router.h ('k') | webrtc/modules/pacing/packet_router_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698