diff --git a/src/modules/rtp_rtcp/interface/rtp_rtcp.h b/src/modules/rtp_rtcp/interface/rtp_rtcp.h index ab67164ff2..6b55202dde 100644 --- a/src/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/src/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -813,6 +813,10 @@ public: const WebRtc_UWord8 numberOfSSRC, const WebRtc_UWord32* SSRC) = 0; + // Used to set maximum bitrate estimate received in a REMB packet. + virtual WebRtc_Word32 SetMaximumBitrateEstimate( + const WebRtc_UWord32 bitrate) = 0; + // Registers an observer to call when the estimate of the incoming channel // changes. virtual bool SetRemoteBitrateObserver( diff --git a/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h index ea94e49834..b6a8a547c6 100644 --- a/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h +++ b/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h @@ -266,8 +266,14 @@ public: class RtpRemoteBitrateObserver { public: + // Called when a receive channel has a new bitrate estimate for the incoming + // stream. virtual void OnReceiveBitrateChanged(unsigned int ssrc, unsigned int bitrate) = 0; + + // Called when a REMB packet has been received. + virtual void OnReceivedRemb(unsigned int bitrate) = 0; + virtual ~RtpRemoteBitrateObserver() {} }; diff --git a/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index 68d5d9b3d4..92147cf732 100644 --- a/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -204,6 +204,8 @@ class MockRtpRtcp : public RtpRtcp { WebRtc_Word32(const bool enable)); MOCK_METHOD3(SetREMBData, WebRtc_Word32(const WebRtc_UWord32 bitrate, const WebRtc_UWord8 numberOfSSRC, const WebRtc_UWord32* SSRC)); + MOCK_METHOD1(SetMaximumBitrateEstimate, + WebRtc_Word32(const WebRtc_UWord32 bitrate)); MOCK_METHOD1(SetRemoteBitrateObserver, bool(RtpRemoteBitrateObserver*)); MOCK_CONST_METHOD0(IJ, diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.cc b/src/modules/rtp_rtcp/source/rtcp_sender.cc index 88c8cee5ef..58e849fc8d 100644 --- a/src/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/src/modules/rtp_rtcp/source/rtcp_sender.cc @@ -277,6 +277,13 @@ void RTCPSender::UpdateRemoteBitrateEstimate(unsigned int target_bitrate) { } } +void RTCPSender::ReceivedRemb(unsigned int estimated_bitrate) { + CriticalSectionScoped lock(_criticalSectionRTCPSender); + if (_bitrate_observer) { + _bitrate_observer->OnReceivedRemb(estimated_bitrate); + } +} + bool RTCPSender::TMMBR() const { diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.h b/src/modules/rtp_rtcp/source/rtcp_sender.h index 4c4f64a9fa..966b64fff8 100644 --- a/src/modules/rtp_rtcp/source/rtcp_sender.h +++ b/src/modules/rtp_rtcp/source/rtcp_sender.h @@ -91,6 +91,8 @@ public: void UpdateRemoteBitrateEstimate(unsigned int target_bitrate); + void ReceivedRemb(unsigned int estimated_bitrate); + /* * TMMBR */ diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 3f771f09a9..08da8f849e 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -1661,6 +1661,17 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetREMBData(const WebRtc_UWord32 bitrate, return _rtcpSender.SetREMBData(bitrate, numberOfSSRC, SSRC); } +WebRtc_Word32 ModuleRtpRtcpImpl::SetMaximumBitrateEstimate( + const WebRtc_UWord32 bitrate) { + if(!_rtcpSender.REMB()) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "SetMaximumBitrateEstimate - REMB not enabled."); + return -1; + } + OnReceivedEstimatedMaxBitrate(bitrate); + return 0; +} + bool ModuleRtpRtcpImpl::SetRemoteBitrateObserver( RtpRemoteBitrateObserver* observer) { return _rtcpSender.SetRemoteBitrateObserver(observer); @@ -2499,17 +2510,16 @@ void ModuleRtpRtcpImpl::OnReceivedIntraFrameRequest(const RtpRtcp* caller) { void ModuleRtpRtcpImpl::OnReceivedEstimatedMaxBitrate( const WebRtc_UWord32 maxBitrate) { + // TODO(mflodman) Split this function in two parts. One for the child module + // and one for the default module. // We received a REMB. if (_defaultModule) { - // Let the default module handle this. - CriticalSectionScoped lock(_criticalSectionModulePtrs); - if (_defaultModule) { - // if we use a default module pass this info to the default module - _defaultModule->OnReceivedEstimatedMaxBitrate(maxBitrate); - return; - } + // Send this update to the REMB instance to take actions. + _rtcpSender.ReceivedRemb(maxBitrate); + return; } + WebRtc_UWord32 newBitrate = 0; WebRtc_UWord8 fractionLost = 0; WebRtc_UWord16 roundTripTime = 0; @@ -2518,8 +2528,6 @@ void ModuleRtpRtcpImpl::OnReceivedEstimatedMaxBitrate( &newBitrate, &fractionLost, &roundTripTime) == 0) { - // TODO(mflodman) When encoding two streams, we need to split the - // bitrate between REMB sending channels. _rtpReceiver.UpdateBandwidthManagement(newBitrate, fractionLost, roundTripTime); diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h index e7ea41a47f..e16bf71c2a 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -333,6 +333,9 @@ public: const WebRtc_UWord8 numberOfSSRC, const WebRtc_UWord32* SSRC); + virtual WebRtc_Word32 SetMaximumBitrateEstimate( + const WebRtc_UWord32 bitrate); + virtual bool SetRemoteBitrateObserver(RtpRemoteBitrateObserver* observer); /* * (IJ) Extended jitter report. diff --git a/src/video_engine/vie_channel_manager.cc b/src/video_engine/vie_channel_manager.cc index e297281836..9e418dab72 100644 --- a/src/video_engine/vie_channel_manager.cc +++ b/src/video_engine/vie_channel_manager.cc @@ -226,7 +226,7 @@ int ViEChannelManager::DeleteChannel(int channel_id) { // Deregister possible remb modules. RtpRtcp* rtp_module = vie_channel->rtp_rtcp(); - remb_->RemoveSendChannel(rtp_module); + remb_->RemoveRembSender(rtp_module); remb_->RemoveReceiveChannel(rtp_module); // Deregister the channel from the ViEEncoder to stop the media flow. @@ -238,6 +238,8 @@ int ViEChannelManager::DeleteChannel(int channel_id) { assert(e_it != vie_encoder_map_.end()); vie_encoder = e_it->second; + remb_->RemoveSendChannel(vie_encoder->SendRtpRtcpModule()); + // Check if other channels are using the same encoder. if (ChannelUsingViEEncoder(channel_id)) { // Don't delete the ViEEncoder, at least one other channel is using it. @@ -338,6 +340,8 @@ bool ViEChannelManager::SetRembStatus(int channel_id, bool sender, return false; } + ViEEncoder* encoder = ViEEncoderPtr(channel_id); + if (sender || receiver) { if (!channel->EnableRemb(true)) { return false; @@ -347,15 +351,20 @@ bool ViEChannelManager::SetRembStatus(int channel_id, bool sender, } RtpRtcp* rtp_module = channel->rtp_rtcp(); if (sender) { - remb_->AddSendChannel(rtp_module); + remb_->AddRembSender(rtp_module); + remb_->AddSendChannel(encoder->SendRtpRtcpModule()); } else { - remb_->RemoveSendChannel(rtp_module); + remb_->RemoveRembSender(rtp_module); + remb_->RemoveSendChannel(encoder->SendRtpRtcpModule()); } if (receiver) { remb_->AddReceiveChannel(rtp_module); - rtp_module->SetRemoteBitrateObserver(remb_.get()); } else { remb_->RemoveReceiveChannel(rtp_module); + } + if (sender || receiver) { + rtp_module->SetRemoteBitrateObserver(remb_.get()); + } else { rtp_module->SetRemoteBitrateObserver(NULL); } return true; diff --git a/src/video_engine/vie_remb.cc b/src/video_engine/vie_remb.cc index 2ebde551f5..7732408fe0 100644 --- a/src/video_engine/vie_remb.cc +++ b/src/video_engine/vie_remb.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -10,6 +10,7 @@ #include "video_engine/vie_remb.h" +#include #include #include "modules/rtp_rtcp/interface/rtp_rtcp.h" @@ -35,16 +36,14 @@ VieRemb::~VieRemb() { } void VieRemb::AddReceiveChannel(RtpRtcp* rtp_rtcp) { - WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, - "VieRemb::AddReceiveChannel"); assert(rtp_rtcp); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, + "VieRemb::AddReceiveChannel(%p)", rtp_rtcp); CriticalSectionScoped cs(list_crit_.get()); - for (RtpModules::iterator it = receive_modules_.begin(); - it != receive_modules_.end(); ++it) { - if ((*it) == rtp_rtcp) - return; - } + if (std::find(receive_modules_.begin(), receive_modules_.end(), rtp_rtcp) != + receive_modules_.end()) + return; WEBRTC_TRACE(kTraceInfo, kTraceVideo, engine_id_, "AddRembChannel"); // The module probably doesn't have a remote SSRC yet, so don't add it to the @@ -53,9 +52,9 @@ void VieRemb::AddReceiveChannel(RtpRtcp* rtp_rtcp) { } void VieRemb::RemoveReceiveChannel(RtpRtcp* rtp_rtcp) { - WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, - "VieRemb::RemoveReceiveChannel"); assert(rtp_rtcp); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, + "VieRemb::RemoveReceiveChannel(%p)", rtp_rtcp); CriticalSectionScoped cs(list_crit_.get()); unsigned int ssrc = rtp_rtcp->RemoteSSRC(); @@ -69,27 +68,57 @@ void VieRemb::RemoveReceiveChannel(RtpRtcp* rtp_rtcp) { bitrates_.erase(ssrc); } -void VieRemb::AddSendChannel(RtpRtcp* rtp_rtcp) { - WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, - "VieRemb::AddSendChannel"); +void VieRemb::AddRembSender(RtpRtcp* rtp_rtcp) { assert(rtp_rtcp); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, + "VieRemb::AddRembSender(%p)", rtp_rtcp); CriticalSectionScoped cs(list_crit_.get()); - // TODO(mflodman) Allow multiple senders. - assert(send_modules_.empty()); + // Verify this module hasn't been added earlier. + if (std::find(rtcp_sender_.begin(), rtcp_sender_.end(), rtp_rtcp) != + rtcp_sender_.end()) + return; + rtcp_sender_.push_back(rtp_rtcp); +} +void VieRemb::RemoveRembSender(RtpRtcp* rtp_rtcp) { + assert(rtp_rtcp); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, + "VieRemb::RemoveRembSender(%p)", rtp_rtcp); + + CriticalSectionScoped cs(list_crit_.get()); + for (RtpModules::iterator it = rtcp_sender_.begin(); + it != rtcp_sender_.end(); ++it) { + if ((*it) == rtp_rtcp) { + rtcp_sender_.erase(it); + return; + } + } +} + +void VieRemb::AddSendChannel(RtpRtcp* rtp_rtcp) { + assert(rtp_rtcp); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, + "VieRemb::AddSendChannel(%p)", rtp_rtcp); + + CriticalSectionScoped cs(list_crit_.get()); + + // Verify this module hasn't been added earlier. + if (std::find(send_modules_.begin(), send_modules_.end(), rtp_rtcp) != + send_modules_.end()) + return; send_modules_.push_back(rtp_rtcp); } void VieRemb::RemoveSendChannel(RtpRtcp* rtp_rtcp) { - WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, - "VieRemb::AddSendChannel"); assert(rtp_rtcp); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, + "VieRemb::RemoveSendChannel(%p)", rtp_rtcp); CriticalSectionScoped cs(list_crit_.get()); for (RtpModules::iterator it = send_modules_.begin(); - it != send_modules_.end(); ++it) { + it != send_modules_.end(); ++it) { if ((*it) == rtp_rtcp) { send_modules_.erase(it); return; @@ -98,7 +127,7 @@ void VieRemb::RemoveSendChannel(RtpRtcp* rtp_rtcp) { } void VieRemb::OnReceiveBitrateChanged(unsigned int ssrc, unsigned int bitrate) { - WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, engine_id_, + WEBRTC_TRACE(kTraceStream, kTraceVideo, engine_id_, "VieRemb::UpdateBitrateEstimate(ssrc: %u, bitrate: %u)", ssrc, bitrate); CriticalSectionScoped cs(list_crit_.get()); @@ -117,10 +146,19 @@ void VieRemb::OnReceiveBitrateChanged(unsigned int ssrc, unsigned int bitrate) { bitrates_[ssrc] = bitrate; } -WebRtc_Word32 VieRemb::Version(WebRtc_Word8* version, - WebRtc_UWord32& remaining_buffer_in_bytes, - WebRtc_UWord32& position) const { - return 0; +void VieRemb::OnReceivedRemb(unsigned int bitrate) { + WEBRTC_TRACE(kTraceStream, kTraceVideo, engine_id_, + "VieRemb::OnReceivedRemb(bitrate: %u)", bitrate); + // TODO(mflodman) Should be extended to allow different split of bitrate. + // TODO(mflodman) Do we want to call |SetMaximumBitrateEstimate| from + // |Process| instead? + + // Split the bitrate estimate between all sending channels. + CriticalSectionScoped cs(list_crit_.get()); + for (RtpModules::iterator it = send_modules_.begin(); + it != send_modules_.end(); ++it) { + (*it)->SetMaximumBitrateEstimate(bitrate / send_modules_.size()); + } } WebRtc_Word32 VieRemb::ChangeUniqueId(const WebRtc_Word32 id) { @@ -161,8 +199,8 @@ WebRtc_Word32 VieRemb::Process() { // Send a REMB packet. RtpRtcp* sender = NULL; - if (!send_modules_.empty()) { - sender = send_modules_.front(); + if (!rtcp_sender_.empty()) { + sender = rtcp_sender_.front(); } last_send_bitrate_ = total_bitrate; list_crit_->Leave(); diff --git a/src/video_engine/vie_remb.h b/src/video_engine/vie_remb.h index b091cf4a4d..32d58a7a4d 100644 --- a/src/video_engine/vie_remb.h +++ b/src/video_engine/vie_remb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -41,7 +41,14 @@ class VieRemb : public RtpRemoteBitrateObserver, public Module { // Removes the specified channel from REMB estimate. void RemoveReceiveChannel(RtpRtcp* rtp_rtcp); - // Called to add a send channel to include in the REMB packet. + // Called to add a module that can generate and send REMB RTCP. + void AddRembSender(RtpRtcp* rtp_rtcp); + + // Removes a REMB RTCP sender. + void RemoveRembSender(RtpRtcp* rtp_rtcp); + + // Called to add a send channel encoding and sending data, affected by + // received REMB packets. void AddSendChannel(RtpRtcp* rtp_rtcp); // Removes the specified channel from receiving REMB packet estimates. @@ -54,10 +61,11 @@ class VieRemb : public RtpRemoteBitrateObserver, public Module { // Implements RtpReceiveBitrateUpdate. virtual void OnReceiveBitrateChanged(unsigned int ssrc, unsigned int bitrate); + // Called for every new receive REMB packet and distributes the estmate + // between all sending modules. + virtual void OnReceivedRemb(unsigned int bitrate); + // Implements Module. - virtual WebRtc_Word32 Version(WebRtc_Word8* version, - WebRtc_UWord32& remaining_buffer_in_bytes, - WebRtc_UWord32& position) const; virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); virtual WebRtc_Word32 TimeUntilNextProcess(); virtual WebRtc_Word32 Process(); @@ -79,6 +87,9 @@ class VieRemb : public RtpRemoteBitrateObserver, public Module { // All modules encoding and sending data. RtpModules send_modules_; + // All modules that can send REMB RTCP. + RtpModules rtcp_sender_; + // The last bitrate update for each SSRC. SsrcBitrate bitrates_; }; diff --git a/src/video_engine/vie_remb_unittest.cc b/src/video_engine/vie_remb_unittest.cc index b6cb083647..a842103bd3 100644 --- a/src/video_engine/vie_remb_unittest.cc +++ b/src/video_engine/vie_remb_unittest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.8 + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -49,6 +49,7 @@ TEST_F(ViERembTest, OneModuleTestForSendingRemb) MockRtpRtcp rtp; vie_remb_->AddReceiveChannel(&rtp); vie_remb_->AddSendChannel(&rtp); + vie_remb_->AddRembSender(&rtp); const unsigned int bitrate_estimate = 456; unsigned int ssrc[] = { 1234 }; @@ -71,6 +72,7 @@ TEST_F(ViERembTest, OneModuleTestForSendingRemb) vie_remb_->RemoveReceiveChannel(&rtp); vie_remb_->RemoveSendChannel(&rtp); + vie_remb_->RemoveRembSender(&rtp); } TEST_F(ViERembTest, LowerEstimateToSendRemb) @@ -78,6 +80,7 @@ TEST_F(ViERembTest, LowerEstimateToSendRemb) MockRtpRtcp rtp; vie_remb_->AddReceiveChannel(&rtp); vie_remb_->AddSendChannel(&rtp); + vie_remb_->AddRembSender(&rtp); unsigned int bitrate_estimate = 456; unsigned int ssrc[] = { 1234 }; @@ -101,6 +104,7 @@ TEST_F(ViERembTest, VerifyCombinedBitrateEstimate) MockRtpRtcp rtp_1; vie_remb_->AddReceiveChannel(&rtp_0); vie_remb_->AddSendChannel(&rtp_0); + vie_remb_->AddRembSender(&rtp_0); vie_remb_->AddReceiveChannel(&rtp_1); unsigned int bitrate_estimate[] = { 456, 789 }; @@ -125,15 +129,47 @@ TEST_F(ViERembTest, VerifyCombinedBitrateEstimate) vie_remb_->RemoveReceiveChannel(&rtp_0); vie_remb_->RemoveSendChannel(&rtp_0); + vie_remb_->RemoveRembSender(&rtp_0); vie_remb_->RemoveReceiveChannel(&rtp_1); } +// Add two senders, and insert a received REMB estimate. Both sending channels +// should get half of the received value. +TEST_F(ViERembTest, IncomingRemb) +{ + MockRtpRtcp rtp_0; + MockRtpRtcp rtp_1; + vie_remb_->AddSendChannel(&rtp_0); + vie_remb_->AddSendChannel(&rtp_1); + + const unsigned int bitrate_estimate = 1200; + + // Fake received REMB and verify both modules get half of the bitrate. + EXPECT_CALL(rtp_0, SetMaximumBitrateEstimate(bitrate_estimate/2)) + .Times(1); + EXPECT_CALL(rtp_1, SetMaximumBitrateEstimate(bitrate_estimate/2)) + .Times(1); + vie_remb_->OnReceivedRemb(bitrate_estimate); + + // Remove one of the modules and verify the other module get the entire + // bitrate. + vie_remb_->RemoveSendChannel(&rtp_0); + EXPECT_CALL(rtp_0, SetMaximumBitrateEstimate(_)) + .Times(0); + EXPECT_CALL(rtp_1, SetMaximumBitrateEstimate(bitrate_estimate)) + .Times(1); + vie_remb_->OnReceivedRemb(bitrate_estimate); + + vie_remb_->RemoveSendChannel(&rtp_1); +} + TEST_F(ViERembTest, NoRembForIncreasedBitrate) { MockRtpRtcp rtp_0; MockRtpRtcp rtp_1; vie_remb_->AddReceiveChannel(&rtp_0); vie_remb_->AddSendChannel(&rtp_0); + vie_remb_->AddRembSender(&rtp_0); vie_remb_->AddReceiveChannel(&rtp_1); unsigned int bitrate_estimate[] = { 456, 789 }; @@ -172,6 +208,7 @@ TEST_F(ViERembTest, NoRembForIncreasedBitrate) vie_remb_->RemoveReceiveChannel(&rtp_1); vie_remb_->RemoveReceiveChannel(&rtp_0); vie_remb_->RemoveSendChannel(&rtp_0); + vie_remb_->RemoveRembSender(&rtp_0); } TEST_F(ViERembTest, ChangeSendRtpModule) @@ -180,6 +217,7 @@ TEST_F(ViERembTest, ChangeSendRtpModule) MockRtpRtcp rtp_1; vie_remb_->AddReceiveChannel(&rtp_0); vie_remb_->AddSendChannel(&rtp_0); + vie_remb_->AddRembSender(&rtp_0); vie_remb_->AddReceiveChannel(&rtp_1); unsigned int bitrate_estimate[] = { 456, 789 }; @@ -206,7 +244,9 @@ TEST_F(ViERembTest, ChangeSendRtpModule) // Remove the sending module, add it again -> should get remb on the second // module. vie_remb_->RemoveSendChannel(&rtp_0); + vie_remb_->RemoveRembSender(&rtp_0); vie_remb_->AddSendChannel(&rtp_1); + vie_remb_->AddRembSender(&rtp_1); vie_remb_->OnReceiveBitrateChanged(ssrc[0], bitrate_estimate[0]); bitrate_estimate[1] = bitrate_estimate[1] - 100; @@ -229,6 +269,7 @@ TEST_F(ViERembTest, OnlyOneRembForDoubleProcess) vie_remb_->AddReceiveChannel(&rtp); vie_remb_->AddSendChannel(&rtp); + vie_remb_->AddRembSender(&rtp); vie_remb_->OnReceiveBitrateChanged(ssrc[0], bitrate_estimate); EXPECT_CALL(rtp, RemoteSSRC()) .WillRepeatedly(Return(ssrc[0])); @@ -246,6 +287,7 @@ TEST_F(ViERembTest, OnlyOneRembForDoubleProcess) vie_remb_->Process(); vie_remb_->RemoveReceiveChannel(&rtp); vie_remb_->RemoveSendChannel(&rtp); + vie_remb_->RemoveRembSender(&rtp); } TEST_F(ViERembTest, NoOnReceivedBitrateChangedCall) @@ -256,6 +298,7 @@ TEST_F(ViERembTest, NoOnReceivedBitrateChangedCall) vie_remb_->AddReceiveChannel(&rtp); vie_remb_->AddSendChannel(&rtp); + vie_remb_->AddRembSender(&rtp); // TODO(mflodman) Add fake clock. TestSleep(1010); // No bitrate estimate given, no callback expected. @@ -265,6 +308,7 @@ TEST_F(ViERembTest, NoOnReceivedBitrateChangedCall) vie_remb_->RemoveReceiveChannel(&rtp); vie_remb_->RemoveSendChannel(&rtp); + vie_remb_->RemoveRembSender(&rtp); } TEST_F(ViERembTest, NoSendingRtpModule)