diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc index 29789aab7c..aff605fe6a 100644 --- a/webrtc/audio/audio_send_stream.cc +++ b/webrtc/audio/audio_send_stream.cc @@ -48,7 +48,8 @@ AudioSendStream::AudioSendStream( PacketRouter* packet_router, CongestionController* congestion_controller, BitrateAllocator* bitrate_allocator, - RtcEventLog* event_log) + RtcEventLog* event_log, + RtcpRttStats* rtcp_rtt_stats) : worker_queue_(worker_queue), config_(config), audio_state_(audio_state), @@ -61,6 +62,7 @@ AudioSendStream::AudioSendStream( VoiceEngineImpl* voe_impl = static_cast(voice_engine()); 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); @@ -94,6 +96,7 @@ AudioSendStream::~AudioSendStream() { channel_proxy_->DeRegisterExternalTransport(); channel_proxy_->ResetCongestionControlObjects(); channel_proxy_->SetRtcEventLog(nullptr); + channel_proxy_->SetRtcpRttStats(nullptr); } void AudioSendStream::Start() { diff --git a/webrtc/audio/audio_send_stream.h b/webrtc/audio/audio_send_stream.h index ad8266a4dc..23a7485014 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 RtcpRttStats; class PacketRouter; namespace voe { @@ -39,7 +40,8 @@ class AudioSendStream final : public webrtc::AudioSendStream, PacketRouter* packet_router, CongestionController* congestion_controller, BitrateAllocator* bitrate_allocator, - RtcEventLog* event_log); + RtcEventLog* event_log, + RtcpRttStats* rtcp_rtt_stats); ~AudioSendStream() override; // webrtc::AudioSendStream implementation. diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc index 55e234f940..4efd91b3e5 100644 --- a/webrtc/audio/audio_send_stream_unittest.cc +++ b/webrtc/audio/audio_send_stream_unittest.cc @@ -22,6 +22,7 @@ #include "webrtc/modules/congestion_controller/include/mock/mock_congestion_controller.h" #include "webrtc/modules/pacing/paced_sender.h" #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h" +#include "webrtc/modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h" #include "webrtc/test/gtest.h" #include "webrtc/test/mock_voe_channel_proxy.h" #include "webrtc/test/mock_voice_engine.h" @@ -147,6 +148,9 @@ struct ConfigHelper { EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::NotNull())).Times(1); EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::IsNull())) .Times(1); // Destructor resets the event log + EXPECT_CALL(*channel_proxy_, SetRtcpRttStats(&rtcp_rtt_stats_)).Times(1); + EXPECT_CALL(*channel_proxy_, SetRtcpRttStats(testing::IsNull())) + .Times(1); // Destructor resets the rtt stats. } void SetupMockForSetupSendCodec() { @@ -161,6 +165,7 @@ struct ConfigHelper { .WillOnce(Return(-1)); EXPECT_CALL(voice_engine_, SetSendCodec(kChannelId, _)).WillOnce(Return(0)); } + RtcpRttStats* rtcp_rtt_stats() { return &rtcp_rtt_stats_; } void SetupMockForSendTelephoneEvent() { EXPECT_TRUE(channel_proxy_); @@ -225,6 +230,7 @@ struct ConfigHelper { PacketRouter packet_router_; CongestionController congestion_controller_; MockRtcEventLog event_log_; + MockRtcpRttStats rtcp_rtt_stats_; testing::NiceMock limit_observer_; BitrateAllocator bitrate_allocator_; // |worker_queue| is defined last to ensure all pending tasks are cancelled @@ -270,7 +276,7 @@ TEST(AudioSendStreamTest, ConstructDestruct) { 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.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); } TEST(AudioSendStreamTest, SendTelephoneEvent) { @@ -278,7 +284,7 @@ TEST(AudioSendStreamTest, SendTelephoneEvent) { 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.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); helper.SetupMockForSendTelephoneEvent(); EXPECT_TRUE(send_stream.SendTelephoneEvent(kTelephoneEventPayloadType, kTelephoneEventPayloadFrequency, kTelephoneEventCode, @@ -290,7 +296,7 @@ TEST(AudioSendStreamTest, SetMuted) { 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.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); EXPECT_CALL(*helper.channel_proxy(), SetInputMute(true)); send_stream.SetMuted(true); } @@ -300,7 +306,7 @@ TEST(AudioSendStreamTest, GetStats) { 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.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); helper.SetupMockForGetStats(); AudioSendStream::Stats stats = send_stream.GetStats(); EXPECT_EQ(kSsrc, stats.local_ssrc); @@ -331,7 +337,7 @@ TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { 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.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); helper.SetupMockForGetStats(); EXPECT_FALSE(send_stream.GetStats().typing_noise_detected); @@ -385,7 +391,7 @@ TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) { internal::AudioSendStream send_stream( stream_config, helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), - helper.bitrate_allocator(), helper.event_log()); + helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); } // VAD is applied when codec is mono and the CNG frequency matches the codec @@ -402,7 +408,7 @@ TEST(AudioSendStreamTest, SendCodecCanApplyVad) { internal::AudioSendStream send_stream( stream_config, helper.audio_state(), helper.worker_queue(), helper.packet_router(), helper.congestion_controller(), - helper.bitrate_allocator(), helper.event_log()); + helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); } TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { @@ -410,7 +416,7 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { 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.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); EXPECT_CALL(*helper.channel_proxy(), SetBitrate(helper.config().max_bitrate_bps, _)); send_stream.OnBitrateUpdated(helper.config().max_bitrate_bps + 5000, 0.0, 50, @@ -422,7 +428,7 @@ TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) { 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.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); EXPECT_CALL(*helper.channel_proxy(), SetBitrate(_, 5000)); send_stream.OnBitrateUpdated(50000, 0.0, 50, 5000); } diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc index e76df360bc..3d940b619a 100644 --- a/webrtc/call/call.cc +++ b/webrtc/call/call.cc @@ -426,7 +426,8 @@ webrtc::AudioSendStream* Call::CreateAudioSendStream( event_log_->LogAudioSendStreamConfig(config); AudioSendStream* send_stream = new AudioSendStream( config, config_.audio_state, &worker_queue_, &packet_router_, - congestion_controller_.get(), bitrate_allocator_.get(), event_log_); + congestion_controller_.get(), bitrate_allocator_.get(), event_log_, + call_stats_->rtcp_rtt_stats()); { WriteLockScoped write_lock(*send_crit_); RTC_DCHECK(audio_send_ssrcs_.find(config.rtp.ssrc) == diff --git a/webrtc/modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h new file mode 100644 index 0000000000..5f2fae9e73 --- /dev/null +++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 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 + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_RTP_RTCP_MOCKS_MOCK_RTCP_RTT_STATS_H_ +#define WEBRTC_MODULES_RTP_RTCP_MOCKS_MOCK_RTCP_RTT_STATS_H_ + +#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "webrtc/test/gmock.h" + +namespace webrtc { + +class MockRtcpRttStats : public RtcpRttStats { + public: + MOCK_METHOD1(OnRttUpdate, void(int64_t rtt)); + MOCK_CONST_METHOD0(LastProcessedRtt, int64_t()); +}; +} // namespace webrtc +#endif // WEBRTC_MODULES_RTP_RTCP_MOCKS_MOCK_RTCP_RTT_STATS_H_ diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h index 4f5a0d2156..44f3c7cbf5 100644 --- a/webrtc/test/mock_voe_channel_proxy.h +++ b/webrtc/test/mock_voe_channel_proxy.h @@ -59,6 +59,7 @@ class MockVoEChannelProxy : public voe::ChannelProxy { const rtc::scoped_refptr&()); MOCK_METHOD1(SetChannelOutputVolumeScaling, void(float scaling)); MOCK_METHOD1(SetRtcEventLog, void(RtcEventLog* event_log)); + MOCK_METHOD1(SetRtcpRttStats, void(RtcpRttStats* rtcp_rtt_stats)); MOCK_METHOD1(EnableAudioNetworkAdaptor, void(const std::string& config_string)); MOCK_METHOD0(DisableAudioNetworkAdaptor, void()); diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index 4579cdbe8d..6e2e91c0a1 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -151,6 +151,34 @@ class RtcEventLogProxy final : public webrtc::RtcEventLog { RTC_DISALLOW_COPY_AND_ASSIGN(RtcEventLogProxy); }; +class RtcpRttStatsProxy final : public RtcpRttStats { + public: + RtcpRttStatsProxy() : rtcp_rtt_stats_(nullptr) {} + + void OnRttUpdate(int64_t rtt) override { + rtc::CritScope lock(&crit_); + if (rtcp_rtt_stats_) + rtcp_rtt_stats_->OnRttUpdate(rtt); + } + + int64_t LastProcessedRtt() const override { + rtc::CritScope lock(&crit_); + if (!rtcp_rtt_stats_) + return 0; + return rtcp_rtt_stats_->LastProcessedRtt(); + } + + void SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats) { + rtc::CritScope lock(&crit_); + rtcp_rtt_stats_ = rtcp_rtt_stats; + } + + private: + rtc::CriticalSection crit_; + RtcpRttStats* rtcp_rtt_stats_ GUARDED_BY(crit_); + RTC_DISALLOW_COPY_AND_ASSIGN(RtcpRttStatsProxy); +}; + class TransportFeedbackProxy : public TransportFeedbackObserver { public: TransportFeedbackProxy() : feedback_observer_(nullptr) { @@ -834,6 +862,7 @@ Channel::Channel(int32_t channelId, : _instanceId(instanceId), _channelId(channelId), event_log_proxy_(new RtcEventLogProxy()), + rtcp_rtt_stats_proxy_(new RtcpRttStatsProxy()), rtp_header_parser_(RtpHeaderParser::Create()), rtp_payload_registry_(new RTPPayloadRegistry()), rtp_receive_statistics_( @@ -920,6 +949,7 @@ Channel::Channel(int32_t channelId, configuration.transport_feedback_callback = feedback_observer_proxy_.get(); } configuration.event_log = &(*event_log_proxy_); + configuration.rtt_stats = &(*rtcp_rtt_stats_proxy_); configuration.retransmission_rate_limiter = retransmission_rate_limiter_.get(); @@ -2849,6 +2879,10 @@ void Channel::SetRtcEventLog(RtcEventLog* event_log) { event_log_proxy_->SetEventLog(event_log); } +void Channel::SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats) { + rtcp_rtt_stats_proxy_->SetRtcpRttStats(rtcp_rtt_stats); +} + void Channel::SetTransportOverhead(int transport_overhead_per_packet) { _rtpRtcpModule->SetTransportOverhead(transport_overhead_per_packet); } diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index 8cac437f7b..4056c7fb56 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -68,6 +68,7 @@ namespace voe { class OutputMixer; class RtcEventLogProxy; +class RtcpRttStatsProxy; class RtpPacketSenderProxy; class Statistics; class StatisticsProxy; @@ -413,6 +414,7 @@ class Channel // Set a RtcEventLog logging object. void SetRtcEventLog(RtcEventLog* event_log); + void SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats); void SetTransportOverhead(int transport_overhead_per_packet); protected: @@ -450,6 +452,7 @@ class Channel ChannelState channel_state_; std::unique_ptr event_log_proxy_; + std::unique_ptr rtcp_rtt_stats_proxy_; std::unique_ptr rtp_header_parser_; std::unique_ptr rtp_payload_registry_; diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc index 04fa93f6ab..2dd74facb4 100644 --- a/webrtc/voice_engine/channel_proxy.cc +++ b/webrtc/voice_engine/channel_proxy.cc @@ -249,6 +249,11 @@ void ChannelProxy::DisassociateSendChannel() { channel()->set_associate_send_channel(ChannelOwner(nullptr)); } +void ChannelProxy::SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats) { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + channel()->SetRtcpRttStats(rtcp_rtt_stats); +} + Channel* ChannelProxy::channel() const { RTC_DCHECK(channel_owner_.channel()); return channel_owner_.channel(); diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h index 6d5f7b0d28..8a78069609 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 RtcpRttStats; class RtpPacketSender; class Transport; class TransportFeedbackObserver; @@ -97,6 +98,8 @@ class ChannelProxy { virtual void AssociateSendChannel(const ChannelProxy& send_channel_proxy); virtual void DisassociateSendChannel(); + virtual void SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats); + private: Channel* channel() const;