diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc index ee84b96aaa..377002f929 100644 --- a/webrtc/audio/audio_send_stream.cc +++ b/webrtc/audio/audio_send_stream.cc @@ -64,7 +64,8 @@ AudioSendStream::AudioSendStream( rtc::TaskQueue* worker_queue, 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), @@ -77,6 +78,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(), diff --git a/webrtc/audio/audio_send_stream.h b/webrtc/audio/audio_send_stream.h index 2e0b7aed58..0f980fa370 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; namespace voe { class ChannelProxy; @@ -37,7 +38,8 @@ class AudioSendStream final : public webrtc::AudioSendStream, rtc::TaskQueue* worker_queue, 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 a05c00ba49..bebeacecb0 100644 --- a/webrtc/audio/audio_send_stream_unittest.cc +++ b/webrtc/audio/audio_send_stream_unittest.cc @@ -20,6 +20,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" @@ -109,6 +110,8 @@ struct ConfigHelper { .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); return channel_proxy_; })); stream_config_.voe_channel_id = kChannelId; @@ -132,6 +135,7 @@ struct ConfigHelper { BitrateAllocator* bitrate_allocator() { return &bitrate_allocator_; } rtc::TaskQueue* worker_queue() { return &worker_queue_; } RtcEventLog* event_log() { return &event_log_; } + RtcpRttStats* rtcp_rtt_stats() { return &rtcp_rtt_stats_; } void SetupMockForSendTelephoneEvent() { EXPECT_TRUE(channel_proxy_); @@ -186,6 +190,7 @@ struct ConfigHelper { testing::NiceMock remote_bitrate_observer_; 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 @@ -215,7 +220,7 @@ TEST(AudioSendStreamTest, ConstructDestruct) { internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.congestion_controller(), helper.bitrate_allocator(), - helper.event_log()); + helper.event_log(), helper.rtcp_rtt_stats()); } TEST(AudioSendStreamTest, SendTelephoneEvent) { @@ -223,7 +228,7 @@ TEST(AudioSendStreamTest, SendTelephoneEvent) { internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.congestion_controller(), helper.bitrate_allocator(), - helper.event_log()); + helper.event_log(), helper.rtcp_rtt_stats()); helper.SetupMockForSendTelephoneEvent(); EXPECT_TRUE(send_stream.SendTelephoneEvent(kTelephoneEventPayloadType, kTelephoneEventCode, kTelephoneEventDuration)); @@ -234,7 +239,7 @@ TEST(AudioSendStreamTest, SetMuted) { internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.congestion_controller(), helper.bitrate_allocator(), - helper.event_log()); + helper.event_log(), helper.rtcp_rtt_stats()); EXPECT_CALL(*helper.channel_proxy(), SetInputMute(true)); send_stream.SetMuted(true); } @@ -244,7 +249,7 @@ TEST(AudioSendStreamTest, GetStats) { internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.congestion_controller(), helper.bitrate_allocator(), - helper.event_log()); + helper.event_log(), helper.rtcp_rtt_stats()); helper.SetupMockForGetStats(); AudioSendStream::Stats stats = send_stream.GetStats(); EXPECT_EQ(kSsrc, stats.local_ssrc); @@ -274,7 +279,7 @@ TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { internal::AudioSendStream send_stream( helper.config(), helper.audio_state(), helper.worker_queue(), helper.congestion_controller(), helper.bitrate_allocator(), - helper.event_log()); + helper.event_log(), helper.rtcp_rtt_stats()); helper.SetupMockForGetStats(); EXPECT_FALSE(send_stream.GetStats().typing_noise_detected); diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc index 9515ac10f1..a68a60e120 100644 --- a/webrtc/call/call.cc +++ b/webrtc/call/call.cc @@ -373,7 +373,7 @@ webrtc::AudioSendStream* Call::CreateAudioSendStream( event_log_->LogAudioSendStreamConfig(config); AudioSendStream* send_stream = new AudioSendStream( config, config_.audio_state, &worker_queue_, congestion_controller_.get(), - bitrate_allocator_.get(), event_log_); + 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..aeabafa730 --- /dev/null +++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h @@ -0,0 +1,26 @@ +/* + * 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 1847cf4711..1a89d9a1d2 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(SetBitrate, void(int bitrate_bps)); }; } // namespace test diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index 8f196c6d31..97132995ba 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -157,6 +157,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_ == nullptr) + 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) { @@ -815,6 +843,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(RTPPayloadStrategy::CreateStrategy(true))), @@ -900,6 +929,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(); @@ -2811,6 +2841,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); +} + int Channel::RegisterExternalMediaProcessing(ProcessingTypes type, VoEMediaProcess& processObject) { WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index 4988e079d1..f2d48d8aad 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -67,6 +67,7 @@ namespace voe { class OutputMixer; class RtcEventLogProxy; +class RtcpRttStatsProxy; class RtpPacketSenderProxy; class Statistics; class StatisticsProxy; @@ -417,6 +418,8 @@ class Channel // Set a RtcEventLog logging object. void SetRtcEventLog(RtcEventLog* event_log); + void SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats); + protected: void OnIncomingFractionLoss(int fraction_lost); @@ -452,6 +455,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 fc22180566..b7cfa9fd01 100644 --- a/webrtc/voice_engine/channel_proxy.cc +++ b/webrtc/voice_engine/channel_proxy.cc @@ -214,6 +214,11 @@ void ChannelProxy::SetRtcEventLog(RtcEventLog* event_log) { channel()->SetRtcEventLog(event_log); } +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 d84e73b60f..1d0116d969 100644 --- a/webrtc/voice_engine/channel_proxy.h +++ b/webrtc/voice_engine/channel_proxy.h @@ -25,6 +25,7 @@ namespace webrtc { class AudioSinkInterface; class PacketRouter; class RtcEventLog; +class RtcpRttStats; class RtpPacketSender; class Transport; class TransportFeedbackObserver; @@ -91,6 +92,8 @@ class ChannelProxy { virtual void SetRtcEventLog(RtcEventLog* event_log); + virtual void SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats); + private: Channel* channel() const;