diff --git a/webrtc/audio/BUILD.gn b/webrtc/audio/BUILD.gn index 80d541624c..acd8dfa7e8 100644 --- a/webrtc/audio/BUILD.gn +++ b/webrtc/audio/BUILD.gn @@ -37,6 +37,7 @@ rtc_static_library("audio") { "../common_audio", "../modules/audio_device", "../modules/audio_processing", + "../modules/bitrate_controller:bitrate_controller", "../modules/congestion_controller:congestion_controller", "../modules/pacing:pacing", "../modules/remote_bitrate_estimator:remote_bitrate_estimator", diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc index c43d0da573..8d4ad3221f 100644 --- a/webrtc/audio/audio_send_stream.cc +++ b/webrtc/audio/audio_send_stream.cc @@ -19,6 +19,7 @@ #include "webrtc/base/event.h" #include "webrtc/base/logging.h" #include "webrtc/base/task_queue.h" +#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" #include "webrtc/modules/congestion_controller/include/congestion_controller.h" #include "webrtc/modules/pacing/paced_sender.h" #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" @@ -62,9 +63,6 @@ AudioSendStream::AudioSendStream( channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id); channel_proxy_->SetRtcEventLog(event_log); channel_proxy_->SetRtcpRttStats(rtcp_rtt_stats); - channel_proxy_->RegisterSenderCongestionControlObjects( - congestion_controller->pacer(), - congestion_controller->GetTransportFeedbackObserver(), packet_router); channel_proxy_->SetRTCPStatus(true); channel_proxy_->SetLocalSSRC(config.rtp.ssrc); channel_proxy_->SetRTCP_CNAME(config.rtp.c_name); @@ -81,10 +79,16 @@ AudioSendStream::AudioSendStream( } else if (extension.uri == RtpExtension::kTransportSequenceNumberUri) { channel_proxy_->EnableSendTransportSequenceNumber(extension.id); congestion_controller->EnablePeriodicAlrProbing(true); + bandwidth_observer_.reset(congestion_controller->GetBitrateController() + ->CreateRtcpBandwidthObserver()); } else { RTC_NOTREACHED() << "Registering unsupported RTP extension."; } } + channel_proxy_->RegisterSenderCongestionControlObjects( + congestion_controller->pacer(), + congestion_controller->GetTransportFeedbackObserver(), packet_router, + bandwidth_observer_.get()); if (!SetupSendCodec()) { LOG(LS_ERROR) << "Failed to set up send codec state."; } diff --git a/webrtc/audio/audio_send_stream.h b/webrtc/audio/audio_send_stream.h index 05ed3aaeb8..5ee49da91a 100644 --- a/webrtc/audio/audio_send_stream.h +++ b/webrtc/audio/audio_send_stream.h @@ -23,6 +23,7 @@ namespace webrtc { class CongestionController; class VoiceEngine; class RtcEventLog; +class RtcpBandwidthObserver; class RtcpRttStats; class PacketRouter; @@ -77,6 +78,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, BitrateAllocator* const bitrate_allocator_; CongestionController* const congestion_controller_; + std::unique_ptr bandwidth_observer_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream); }; diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc index 4b7415a738..9ae0a87999 100644 --- a/webrtc/audio/audio_send_stream_unittest.cc +++ b/webrtc/audio/audio_send_stream_unittest.cc @@ -32,6 +32,8 @@ namespace test { namespace { using testing::_; +using testing::Eq; +using testing::Ne; using testing::Return; const int kChannelId = 1; @@ -62,7 +64,7 @@ class MockLimitObserver : public BitrateAllocator::LimitObserver { }; struct ConfigHelper { - ConfigHelper() + explicit ConfigHelper(bool audio_bwe_enabled) : simulated_clock_(123456), stream_config_(nullptr), congestion_controller_(&simulated_clock_, @@ -87,7 +89,7 @@ struct ConfigHelper { config.audio_mixer = AudioMixerImpl::Create(); audio_state_ = AudioState::Create(config); - SetupDefaultChannelProxy(); + SetupDefaultChannelProxy(audio_bwe_enabled); EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId)) .WillOnce(Invoke([this](int channel_id) { @@ -102,8 +104,12 @@ struct ConfigHelper { stream_config_.rtp.c_name = kCName; stream_config_.rtp.extensions.push_back( RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId)); - stream_config_.rtp.extensions.push_back(RtpExtension( - RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId)); + if (audio_bwe_enabled) { + stream_config_.rtp.extensions.push_back( + RtpExtension(RtpExtension::kTransportSequenceNumberUri, + kTransportSequenceNumberId)); + stream_config_.send_codec_spec.transport_cc_enabled = true; + } // Use ISAC as default codec so as to prevent unnecessary |voice_engine_| // calls from the default ctor behavior. stream_config_.send_codec_spec.codec_inst = kIsacCodec; @@ -123,7 +129,7 @@ struct ConfigHelper { RtcEventLog* event_log() { return &event_log_; } MockVoiceEngine* voice_engine() { return &voice_engine_; } - void SetupDefaultChannelProxy() { + void SetupDefaultChannelProxy(bool audio_bwe_enabled) { using testing::StrEq; channel_proxy_ = new testing::StrictMock(); EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1); @@ -133,15 +139,25 @@ struct ConfigHelper { EXPECT_CALL(*channel_proxy_, SetSendAudioLevelIndicationStatus(true, kAudioLevelId)) .Times(1); - EXPECT_CALL(*channel_proxy_, - EnableSendTransportSequenceNumber(kTransportSequenceNumberId)) - .Times(1); - EXPECT_CALL(*channel_proxy_, - RegisterSenderCongestionControlObjects( - congestion_controller_.pacer(), - congestion_controller_.GetTransportFeedbackObserver(), - packet_router())) - .Times(1); + + if (audio_bwe_enabled) { + EXPECT_CALL(*channel_proxy_, + EnableSendTransportSequenceNumber(kTransportSequenceNumberId)) + .Times(1); + EXPECT_CALL(*channel_proxy_, + RegisterSenderCongestionControlObjects( + congestion_controller_.pacer(), + congestion_controller_.GetTransportFeedbackObserver(), + packet_router(), Ne(nullptr))) + .Times(1); + } else { + EXPECT_CALL(*channel_proxy_, + RegisterSenderCongestionControlObjects( + congestion_controller_.pacer(), + congestion_controller_.GetTransportFeedbackObserver(), + packet_router(), Eq(nullptr))) + .Times(1); + } EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects()).Times(1); EXPECT_CALL(*channel_proxy_, RegisterExternalTransport(nullptr)).Times(1); EXPECT_CALL(*channel_proxy_, DeRegisterExternalTransport()).Times(1); @@ -271,7 +287,7 @@ TEST(AudioSendStreamTest, ConfigToString) { } TEST(AudioSendStreamTest, ConstructDestruct) { - ConfigHelper helper; + ConfigHelper helper(false); internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), @@ -279,7 +295,7 @@ TEST(AudioSendStreamTest, ConstructDestruct) { } TEST(AudioSendStreamTest, SendTelephoneEvent) { - ConfigHelper helper; + ConfigHelper helper(false); internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), @@ -291,7 +307,7 @@ TEST(AudioSendStreamTest, SendTelephoneEvent) { } TEST(AudioSendStreamTest, SetMuted) { - ConfigHelper helper; + ConfigHelper helper(false); internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), @@ -300,8 +316,24 @@ TEST(AudioSendStreamTest, SetMuted) { send_stream.SetMuted(true); } +TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) { + ConfigHelper helper(true); + internal::AudioSendStream send_stream( + helper.config(), helper.audio_state(), helper.worker_queue(), + helper.packet_router(), helper.congestion_controller(), + helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); +} + +TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) { + ConfigHelper helper(false); + internal::AudioSendStream send_stream( + helper.config(), helper.audio_state(), helper.worker_queue(), + helper.packet_router(), helper.congestion_controller(), + helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); +} + TEST(AudioSendStreamTest, GetStats) { - ConfigHelper helper; + ConfigHelper helper(false); internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), @@ -332,7 +364,7 @@ TEST(AudioSendStreamTest, GetStats) { } TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { - ConfigHelper helper; + ConfigHelper helper(false); internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), @@ -351,7 +383,7 @@ TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { } TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) { - ConfigHelper helper; + ConfigHelper helper(false); auto stream_config = helper.config(); const CodecInst kOpusCodec = {111, "opus", 48000, 960, 2, 64000}; stream_config.send_codec_spec.codec_inst = kOpusCodec; @@ -396,7 +428,7 @@ TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) { // VAD is applied when codec is mono and the CNG frequency matches the codec // sample rate. TEST(AudioSendStreamTest, SendCodecCanApplyVad) { - ConfigHelper helper; + ConfigHelper helper(false); auto stream_config = helper.config(); const CodecInst kG722Codec = {9, "g722", 8000, 160, 1, 16000}; stream_config.send_codec_spec.codec_inst = kG722Codec; @@ -411,7 +443,7 @@ TEST(AudioSendStreamTest, SendCodecCanApplyVad) { } TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { - ConfigHelper helper; + ConfigHelper helper(false); internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), @@ -423,7 +455,7 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { } TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) { - ConfigHelper helper; + ConfigHelper helper(false); internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h index 39b2e9fd58..ea51154f54 100644 --- a/webrtc/test/mock_voe_channel_proxy.h +++ b/webrtc/test/mock_voe_channel_proxy.h @@ -29,10 +29,11 @@ class MockVoEChannelProxy : public voe::ChannelProxy { MOCK_METHOD2(SetReceiveAudioLevelIndicationStatus, void(bool enable, int id)); MOCK_METHOD1(EnableSendTransportSequenceNumber, void(int id)); MOCK_METHOD1(EnableReceiveTransportSequenceNumber, void(int id)); - MOCK_METHOD3(RegisterSenderCongestionControlObjects, + MOCK_METHOD4(RegisterSenderCongestionControlObjects, void(RtpPacketSender* rtp_packet_sender, TransportFeedbackObserver* transport_feedback_observer, - PacketRouter* packet_router)); + PacketRouter* packet_router, + RtcpBandwidthObserver* bandwidth_observer)); MOCK_METHOD1(RegisterReceiverCongestionControlObjects, void(PacketRouter* packet_router)); MOCK_METHOD0(ResetCongestionControlObjects, void()); diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc index 9c734604ec..42d057daa3 100644 --- a/webrtc/video/video_quality_test.cc +++ b/webrtc/video/video_quality_test.cc @@ -927,6 +927,8 @@ std::string VideoQualityTest::GenerateGraphTitle() const { } void VideoQualityTest::CheckParams() { + if (!params_.video.enabled) + return; // Add a default stream in none specified. if (params_.ss.streams.empty()) params_.ss.streams.push_back(VideoQualityTest::DefaultVideoStream(params_)); diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index 2791f7f8b4..a9cf2b26dc 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -333,16 +333,32 @@ class StatisticsProxy : public RtcpStatisticsCallback { class VoERtcpObserver : public RtcpBandwidthObserver { public: - explicit VoERtcpObserver(Channel* owner) : owner_(owner) {} + explicit VoERtcpObserver(Channel* owner) + : owner_(owner), bandwidth_observer_(nullptr) {} virtual ~VoERtcpObserver() {} + void SetBandwidthObserver(RtcpBandwidthObserver* bandwidth_observer) { + rtc::CritScope lock(&crit_); + bandwidth_observer_ = bandwidth_observer; + } + void OnReceivedEstimatedBitrate(uint32_t bitrate) override { - // Not used for Voice Engine. + rtc::CritScope lock(&crit_); + if (bandwidth_observer_) { + bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate); + } } void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks, int64_t rtt, int64_t now_ms) override { + { + rtc::CritScope lock(&crit_); + if (bandwidth_observer_) { + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, rtt, + now_ms); + } + } // TODO(mflodman): Do we need to aggregate reports here or can we jut send // what we get? I.e. do we ever get multiple reports bundled into one RTCP // report for VoiceEngine? @@ -384,6 +400,8 @@ class VoERtcpObserver : public RtcpBandwidthObserver { Channel* owner_; // Maps remote side ssrc to extended highest sequence number received. std::map extended_max_sequence_number_; + rtc::CriticalSection crit_; + RtcpBandwidthObserver* bandwidth_observer_ GUARDED_BY(crit_); }; int32_t Channel::SendData(FrameType frameType, @@ -2424,10 +2442,12 @@ void Channel::EnableReceiveTransportSequenceNumber(int id) { void Channel::RegisterSenderCongestionControlObjects( RtpPacketSender* rtp_packet_sender, TransportFeedbackObserver* transport_feedback_observer, - PacketRouter* packet_router) { + PacketRouter* packet_router, + RtcpBandwidthObserver* bandwidth_observer) { RTC_DCHECK(rtp_packet_sender); RTC_DCHECK(transport_feedback_observer); RTC_DCHECK(packet_router && !packet_router_); + rtcp_observer_->SetBandwidthObserver(bandwidth_observer); feedback_observer_proxy_->SetTransportFeedbackObserver( transport_feedback_observer); seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router); @@ -2447,6 +2467,7 @@ void Channel::RegisterReceiverCongestionControlObjects( void Channel::ResetCongestionControlObjects() { RTC_DCHECK(packet_router_); _rtpRtcpModule->SetStorePacketsStatus(false, 600); + rtcp_observer_->SetBandwidthObserver(nullptr); feedback_observer_proxy_->SetTransportFeedbackObserver(nullptr); seq_num_allocator_proxy_->SetSequenceNumberAllocator(nullptr); packet_router_->RemoveRtpModule(_rtpRtcpModule.get()); diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index 62adc5bdff..c512c08384 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -304,12 +304,13 @@ class Channel void EnableSendTransportSequenceNumber(int id); void EnableReceiveTransportSequenceNumber(int id); - void RegisterSenderCongestionControlObjects( - RtpPacketSender* rtp_packet_sender, - TransportFeedbackObserver* transport_feedback_observer, - PacketRouter* packet_router); - void RegisterReceiverCongestionControlObjects(PacketRouter* packet_router); - void ResetCongestionControlObjects(); + void RegisterSenderCongestionControlObjects( + RtpPacketSender* rtp_packet_sender, + TransportFeedbackObserver* transport_feedback_observer, + PacketRouter* packet_router, + RtcpBandwidthObserver* bandwidth_observer); + void RegisterReceiverCongestionControlObjects(PacketRouter* packet_router); + void ResetCongestionControlObjects(); void SetRTCPStatus(bool enable); int GetRTCPStatus(bool& enabled); diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc index e5e3804b71..a58b2e1955 100644 --- a/webrtc/voice_engine/channel_proxy.cc +++ b/webrtc/voice_engine/channel_proxy.cc @@ -75,10 +75,12 @@ void ChannelProxy::EnableReceiveTransportSequenceNumber(int id) { void ChannelProxy::RegisterSenderCongestionControlObjects( RtpPacketSender* rtp_packet_sender, TransportFeedbackObserver* transport_feedback_observer, - PacketRouter* packet_router) { + PacketRouter* packet_router, + RtcpBandwidthObserver* bandwidth_observer) { RTC_DCHECK(thread_checker_.CalledOnValidThread()); channel()->RegisterSenderCongestionControlObjects( - rtp_packet_sender, transport_feedback_observer, packet_router); + rtp_packet_sender, transport_feedback_observer, packet_router, + bandwidth_observer); } void ChannelProxy::RegisterReceiverCongestionControlObjects( diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h index 20aba6fd95..966abc4868 100644 --- a/webrtc/voice_engine/channel_proxy.h +++ b/webrtc/voice_engine/channel_proxy.h @@ -27,6 +27,7 @@ namespace webrtc { class AudioSinkInterface; class PacketRouter; class RtcEventLog; +class RtcpBandwidthObserver; class RtcpRttStats; class RtpPacketSender; class RtpReceiver; @@ -62,7 +63,8 @@ class ChannelProxy { virtual void RegisterSenderCongestionControlObjects( RtpPacketSender* rtp_packet_sender, TransportFeedbackObserver* transport_feedback_observer, - PacketRouter* packet_router); + PacketRouter* packet_router, + RtcpBandwidthObserver* bandwidth_observer); virtual void RegisterReceiverCongestionControlObjects( PacketRouter* packet_router); virtual void ResetCongestionControlObjects();