| 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..64e1aeacc1cde5277be14adf30b2bf1e8d855ad0 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());
|
| - rtp_send_modules_.remove(rtp_module);
|
| - 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);
|
| - }
|
| + MaybeRemoveRembModuleCandidate(rtp_module, /* sender = */ true);
|
| + auto it =
|
| + std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), rtp_module);
|
| + RTC_DCHECK(it != rtp_send_modules_.end());
|
| + rtp_send_modules_.erase(it);
|
| }
|
|
|
| -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,69 @@ bool PacketRouter::SendTransportFeedback(rtcp::TransportFeedback* packet) {
|
| return false;
|
| }
|
|
|
| +void PacketRouter::AddRembModuleCandidate(RtpRtcp* candidate_module,
|
| + bool sender) {
|
| + RTC_DCHECK(candidate_module);
|
| + std::vector<RtpRtcp*>& candidates =
|
| + sender ? sender_remb_candidates_ : receiver_remb_candidates_;
|
| + RTC_DCHECK(std::find(candidates.cbegin(), candidates.cend(),
|
| + candidate_module) == candidates.cend());
|
| + candidates.push_back(candidate_module);
|
| + DetermineActiveRembModule();
|
| +}
|
| +
|
| +void PacketRouter::MaybeRemoveRembModuleCandidate(RtpRtcp* candidate_module,
|
| + bool sender) {
|
| + RTC_DCHECK(candidate_module);
|
| + std::vector<RtpRtcp*>& candidates =
|
| + sender ? sender_remb_candidates_ : receiver_remb_candidates_;
|
| + auto it = std::find(candidates.begin(), candidates.end(), candidate_module);
|
| +
|
| + if (it == candidates.end()) {
|
| + return; // Function called due to removal of non-REMB-candidate module.
|
| + }
|
| +
|
| + if (*it == active_remb_module_) {
|
| + UnsetActiveRembModule();
|
| + }
|
| + candidates.erase(it);
|
| + DetermineActiveRembModule();
|
| +}
|
| +
|
| +void PacketRouter::UnsetActiveRembModule() {
|
| + RTC_CHECK(active_remb_module_);
|
| + RTC_DCHECK(active_remb_module_->REMB());
|
| + active_remb_module_->SetREMBStatus(false);
|
| + active_remb_module_ = nullptr;
|
| +}
|
| +
|
| +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* new_active_remb_module_;
|
| +
|
| + if (!sender_remb_candidates_.empty()) {
|
| + new_active_remb_module_ = sender_remb_candidates_.front();
|
| + } else if (!receiver_remb_candidates_.empty()) {
|
| + new_active_remb_module_ = receiver_remb_candidates_.front();
|
| + } else {
|
| + new_active_remb_module_ = nullptr;
|
| + }
|
| +
|
| + if (new_active_remb_module_ != active_remb_module_) {
|
| + if (active_remb_module_) {
|
| + UnsetActiveRembModule();
|
| + }
|
| + if (new_active_remb_module_) {
|
| + RTC_DCHECK(!new_active_remb_module_->REMB());
|
| + new_active_remb_module_->SetREMBStatus(true);
|
| + }
|
| + }
|
| +
|
| + active_remb_module_ = new_active_remb_module_;
|
| +}
|
| +
|
| } // namespace webrtc
|
|
|