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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/pacing/packet_router.cc
diff --git a/webrtc/modules/pacing/packet_router.cc b/webrtc/modules/pacing/packet_router.cc
index 1cee90a44153137f3ee61b68325ca41aadfaf0c1..298a173ba52c7494adcc0cd049a8de80acf898d0 100644
--- a/webrtc/modules/pacing/packet_router.cc
+++ b/webrtc/modules/pacing/packet_router.cc
@@ -22,73 +22,63 @@ namespace webrtc {
PacketRouter::PacketRouter()
: last_remb_time_ms_(rtc::TimeMillis()),
last_send_bitrate_bps_(0),
+ active_remb_module_(nullptr),
transport_seq_(0) {}
PacketRouter::~PacketRouter() {
RTC_DCHECK(rtp_send_modules_.empty());
RTC_DCHECK(rtp_receive_modules_.empty());
+ RTC_DCHECK(sender_remb_candidates_.empty());
+ RTC_DCHECK(receiver_remb_candidates_.empty());
+ RTC_DCHECK(active_remb_module_ == nullptr);
}
-void PacketRouter::AddSendRtpModule(RtpRtcp* rtp_module) {
+void PacketRouter::AddSendRtpModule(RtpRtcp* rtp_module, bool remb_candidate) {
rtc::CritScope cs(&modules_crit_);
RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(),
rtp_module) == rtp_send_modules_.end());
- if (rtp_send_modules_.empty() && !rtp_receive_modules_.empty()) {
- rtp_receive_modules_.front()->SetREMBStatus(false);
- }
-
// Put modules which can use regular payload packets (over rtx) instead of
// padding first as it's less of a waste
if ((rtp_module->RtxSendStatus() & kRtxRedundantPayloads) > 0) {
- if (!rtp_send_modules_.empty()) {
- rtp_send_modules_.front()->SetREMBStatus(false);
- }
rtp_send_modules_.push_front(rtp_module);
- rtp_module->SetREMBStatus(true);
} else {
- if (rtp_send_modules_.empty()) {
- rtp_module->SetREMBStatus(true);
- }
-
rtp_send_modules_.push_back(rtp_module);
}
+
+ if (remb_candidate) {
+ AddRembModuleCandidate(rtp_module, true);
+ }
}
void PacketRouter::RemoveSendRtpModule(RtpRtcp* rtp_module) {
rtc::CritScope cs(&modules_crit_);
- RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(),
- rtp_module) != rtp_send_modules_.end());
+ MaybeRemoveRembModuleCandidate(rtp_module, /* sender = */ true);
+ const auto& it =
danilchap 2017/07/31 13:18:03 auto it = (iterators normally passed by value)
eladalon 2017/07/31 14:08:26 Done.
+ std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), rtp_module);
+ RTC_DCHECK(it != rtp_send_modules_.end());
rtp_send_modules_.remove(rtp_module);
danilchap 2017/07/31 13:18:04 may be erase(it) to avoid double lookup
eladalon 2017/07/31 14:08:26 Done.
- rtp_module->SetREMBStatus(false);
- if (!rtp_send_modules_.empty()) {
- rtp_send_modules_.front()->SetREMBStatus(true);
- } else if (!rtp_receive_modules_.empty()) {
- rtp_receive_modules_.front()->SetREMBStatus(true);
- }
}
-void PacketRouter::AddReceiveRtpModule(RtpRtcp* rtp_module) {
+void PacketRouter::AddReceiveRtpModule(RtpRtcp* rtp_module,
+ bool remb_candidate) {
rtc::CritScope cs(&modules_crit_);
RTC_DCHECK(std::find(rtp_receive_modules_.begin(), rtp_receive_modules_.end(),
rtp_module) == rtp_receive_modules_.end());
- if (rtp_send_modules_.empty() && rtp_receive_modules_.empty()) {
- rtp_module->SetREMBStatus(true);
- }
+
rtp_receive_modules_.push_back(rtp_module);
+
+ if (remb_candidate) {
+ AddRembModuleCandidate(rtp_module, false);
+ }
}
void PacketRouter::RemoveReceiveRtpModule(RtpRtcp* rtp_module) {
rtc::CritScope cs(&modules_crit_);
+ MaybeRemoveRembModuleCandidate(rtp_module, /* sender = */ false);
const auto& it = std::find(rtp_receive_modules_.begin(),
rtp_receive_modules_.end(), rtp_module);
RTC_DCHECK(it != rtp_receive_modules_.end());
rtp_receive_modules_.erase(it);
- if (rtp_send_modules_.empty()) {
- rtp_module->SetREMBStatus(false);
- if (!rtp_receive_modules_.empty()) {
- rtp_receive_modules_.front()->SetREMBStatus(true);
- }
- }
}
bool PacketRouter::TimeToSendPacket(uint32_t ssrc,
@@ -190,18 +180,17 @@ void PacketRouter::OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
bool PacketRouter::SendRemb(uint32_t bitrate_bps,
const std::vector<uint32_t>& ssrcs) {
rtc::CritScope lock(&modules_crit_);
- RtpRtcp* remb_module;
- if (!rtp_send_modules_.empty())
- remb_module = rtp_send_modules_.front();
- else if (!rtp_receive_modules_.empty())
- remb_module = rtp_receive_modules_.front();
- else
+
+ if (!active_remb_module_) {
return false;
+ }
+
// The Add* and Remove* methods above ensure that this (and only this) module
// has REMB enabled. REMB should be disabled on all other modules, because
// otherwise, they will send REMB with stale info.
- RTC_DCHECK(remb_module->REMB());
- remb_module->SetREMBData(bitrate_bps, ssrcs);
+ RTC_DCHECK(active_remb_module_->REMB());
+ active_remb_module_->SetREMBData(bitrate_bps, ssrcs);
+
return true;
}
@@ -222,4 +211,66 @@ bool PacketRouter::SendTransportFeedback(rtcp::TransportFeedback* packet) {
return false;
}
+void PacketRouter::AddRembModuleCandidate(RtpRtcp* candidate_module,
+ bool sender) {
+ RTC_DCHECK(candidate_module);
+ std::vector<RtpRtcp*>& candidates_vector =
danilchap 2017/07/31 13:18:04 may be just candidates (function is short enough t
eladalon 2017/07/31 14:08:26 Done.
+ sender ? sender_remb_candidates_ : receiver_remb_candidates_;
+ RTC_DCHECK(std::find(candidates_vector.cbegin(), candidates_vector.cend(),
+ candidate_module) == candidates_vector.cend());
+ candidates_vector.push_back(candidate_module);
+ DetermineActiveRembModule();
+}
+
+void PacketRouter::MaybeRemoveRembModuleCandidate(RtpRtcp* candidate_module,
+ bool sender) {
+ RTC_DCHECK(candidate_module);
+ std::vector<RtpRtcp*>& candidates_vector =
+ sender ? sender_remb_candidates_ : receiver_remb_candidates_;
+ auto it = std::find(candidates_vector.begin(), candidates_vector.end(),
+ candidate_module);
+
+ if (it == candidates_vector.end()) {
+ return; // Function called due to removal of non-REMB-candidate module.
+ }
+
+ if (*it == active_remb_module_) {
danilchap 2017/07/31 13:18:04 is this block needed? (DetermineActiveRembModule s
eladalon 2017/07/31 14:08:26 You're right that it would work, but I find it to
danilchap 2017/07/31 14:37:17 yep, removal (and addition) are naturally split be
eladalon 2017/07/31 14:51:20 That's one side of the coin. The other side is tha
danilchap 2017/07/31 15:10:05 Looking at implmentation of the DetermineActiveRem
eladalon 2017/07/31 15:22:32 My reservation against Update vs. Determine is tha
+ RTC_DCHECK(active_remb_module_->REMB());
+ active_remb_module_->SetREMBStatus(false);
+ active_remb_module_ = nullptr;
+ }
+
+ candidates_vector.erase(it);
+
+ DetermineActiveRembModule();
+}
+
+void PacketRouter::DetermineActiveRembModule() {
+ // Sender modules take precedence over receiver modules, because SRs (sender
+ // reports) are sent more frequently than RR (receiver reports).
+ // When adding the first sender module, we should change the active REMB
+ // module to be that. Otherwise, we remain with the current active module.
+
+ RtpRtcp* previous_active_remb_module = active_remb_module_;
+
+ if (!sender_remb_candidates_.empty()) {
+ active_remb_module_ = sender_remb_candidates_.front();
+ } else if (!receiver_remb_candidates_.empty()) {
+ active_remb_module_ = receiver_remb_candidates_.front();
+ } else {
+ active_remb_module_ = nullptr;
+ }
+
+ if (active_remb_module_ != previous_active_remb_module) {
+ if (previous_active_remb_module) {
+ RTC_DCHECK(previous_active_remb_module->REMB());
+ previous_active_remb_module->SetREMBStatus(false);
+ }
+ if (active_remb_module_) {
+ RTC_DCHECK(!active_remb_module_->REMB());
+ active_remb_module_->SetREMBStatus(true);
+ }
+ }
+}
+
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698