From 2b19f0631233488e891d9db0d170b637dc8fc464 Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Thu, 11 Dec 2014 13:26:09 +0000 Subject: [PATCH] Wire up RTT statistics to webrtc::Call. R=mflodman@webrtc.org, stefan@webrtc.org BUG=1667,1788 Review URL: https://webrtc-codereview.appspot.com/32249004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7876 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/media/webrtc/webrtcvideoengine2.cc | 11 +++-- talk/media/webrtc/webrtcvideoengine2.h | 3 +- .../webrtc/webrtcvideoengine2_unittest.cc | 22 +++++++++- .../webrtc/webrtcvideoengine2_unittest.h | 2 + webrtc/call.h | 7 ++- webrtc/video/call.cc | 3 ++ webrtc/video/end_to_end_tests.cc | 43 ++++++++++++++++++- webrtc/video/video_send_stream.cc | 10 +++++ webrtc/video/video_send_stream.h | 2 + 9 files changed, 95 insertions(+), 8 deletions(-) diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc index 419f251149..deaded6089 100644 --- a/talk/media/webrtc/webrtcvideoengine2.cc +++ b/talk/media/webrtc/webrtcvideoengine2.cc @@ -1141,7 +1141,13 @@ bool WebRtcVideoChannel2::GetStats(const StatsOptions& options, info->Clear(); FillSenderStats(info); FillReceiverStats(info); - FillBandwidthEstimationStats(info); + webrtc::Call::Stats stats = call_->GetStats(); + FillBandwidthEstimationStats(stats, info); + if (stats.rtt_ms != -1) { + for (size_t i = 0; i < info->senders.size(); ++i) { + info->senders[i].rtt_ms = stats.rtt_ms; + } + } return true; } @@ -1166,9 +1172,9 @@ void WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { } void WebRtcVideoChannel2::FillBandwidthEstimationStats( + const webrtc::Call::Stats& stats, VideoMediaInfo* video_media_info) { BandwidthEstimationInfo bwe_info; - webrtc::Call::Stats stats = call_->GetStats(); bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; bwe_info.bucket_delay = stats.pacer_delay_ms; @@ -1905,7 +1911,6 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { // TODO(pbos): Support or remove the following stats. info.packets_cached = -1; - info.rtt_ms = -1; return info; } diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h index a7532f54da..2318971db2 100644 --- a/talk/media/webrtc/webrtcvideoengine2.h +++ b/talk/media/webrtc/webrtcvideoengine2.h @@ -469,7 +469,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, void FillSenderStats(VideoMediaInfo* info); void FillReceiverStats(VideoMediaInfo* info); - void FillBandwidthEstimationStats(VideoMediaInfo* info); + void FillBandwidthEstimationStats(const webrtc::Call::Stats& stats, + VideoMediaInfo* info); uint32_t rtcp_receiver_report_ssrc_; bool sending_; diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc index 2f72f1cddc..1248b316d2 100644 --- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc @@ -307,9 +307,12 @@ webrtc::PacketReceiver* FakeCall::Receiver() { return NULL; } +void FakeCall::SetStats(const webrtc::Call::Stats& stats) { + stats_ = stats; +} + webrtc::Call::Stats FakeCall::GetStats() const { - webrtc::Call::Stats stats; - return stats; + return stats_; } void FakeCall::SetBitrateConfig( @@ -1904,6 +1907,20 @@ TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) { EXPECT_EQ(90, info.senders[0].send_frame_height); } +TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) { + AddSendStream(); + AddSendStream(); + webrtc::Call::Stats stats; + stats.rtt_ms = 123; + fake_call_->SetStats(stats); + + cricket::VideoMediaInfo info; + ASSERT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info)); + ASSERT_EQ(2u, info.senders.size()); + EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms); + EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms); +} + class WebRtcVideoEngine2SimulcastTest : public testing::Test { public: WebRtcVideoEngine2SimulcastTest() @@ -2351,4 +2368,5 @@ TEST_F(WebRtcVideoChannel2SimulcastTest, // TODO(pbos): Implement. FAIL() << "Not implemented."; } + } // namespace cricket diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.h b/talk/media/webrtc/webrtcvideoengine2_unittest.h index dcfaf86d6d..40d3973f81 100644 --- a/talk/media/webrtc/webrtcvideoengine2_unittest.h +++ b/talk/media/webrtc/webrtcvideoengine2_unittest.h @@ -113,6 +113,7 @@ class FakeCall : public webrtc::Call { std::vector GetDefaultVideoCodecs(); webrtc::Call::NetworkState GetNetworkState() const; + void SetStats(const webrtc::Call::Stats& stats); private: virtual webrtc::VideoSendStream* CreateVideoSendStream( @@ -137,6 +138,7 @@ class FakeCall : public webrtc::Call { webrtc::Call::Config config_; webrtc::Call::NetworkState network_state_; + webrtc::Call::Stats stats_; std::vector codecs_; std::vector video_send_streams_; std::vector video_receive_streams_; diff --git a/webrtc/call.h b/webrtc/call.h index 920c00660d..56efacb0d2 100644 --- a/webrtc/call.h +++ b/webrtc/call.h @@ -97,11 +97,16 @@ class Call { }; struct Stats { - Stats() : send_bandwidth_bps(0), recv_bandwidth_bps(0), pacer_delay_ms(0) {} + Stats() + : send_bandwidth_bps(0), + recv_bandwidth_bps(0), + pacer_delay_ms(0), + rtt_ms(-1) {} int send_bandwidth_bps; int recv_bandwidth_bps; int pacer_delay_ms; + int rtt_ms; }; static Call* Create(const Call::Config& config); diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc index 512e82ca64..15cc835aa4 100644 --- a/webrtc/video/call.cc +++ b/webrtc/video/call.cc @@ -342,6 +342,9 @@ Call::Stats Call::GetStats() const { ++it) { stats.pacer_delay_ms = std::max(it->second->GetPacerQueuingDelayMs(), stats.pacer_delay_ms); + int rtt_ms = it->second->GetRtt(); + if (rtt_ms > 0) + stats.rtt_ms = rtt_ms; } } return stats; diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index 0871da403f..4bf58202fc 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -1213,8 +1213,9 @@ TEST_F(EndToEndTest, VerifyBandwidthStats) { if (!has_seen_pacer_delay_) has_seen_pacer_delay_ = sender_stats.pacer_delay_ms > 0; if (sender_stats.send_bandwidth_bps > 0 && - receiver_stats.recv_bandwidth_bps > 0 && has_seen_pacer_delay_) + receiver_stats.recv_bandwidth_bps > 0 && has_seen_pacer_delay_) { observation_complete_->Set(); + } return receiver_call_->Receiver()->DeliverPacket(packet, length); } @@ -2135,6 +2136,46 @@ TEST_F(EndToEndTest, RespectsNetworkState) { RunBaseTest(&test); } +TEST_F(EndToEndTest, CallReportsRttForSender) { + static const int kSendDelayMs = 30; + static const int kReceiveDelayMs = 70; + + FakeNetworkPipe::Config config; + config.queue_delay_ms = kSendDelayMs; + test::DirectTransport sender_transport(config); + config.queue_delay_ms = kReceiveDelayMs; + test::DirectTransport receiver_transport(config); + + CreateCalls(Call::Config(&sender_transport), + Call::Config(&receiver_transport)); + + sender_transport.SetReceiver(receiver_call_->Receiver()); + receiver_transport.SetReceiver(sender_call_->Receiver()); + + CreateSendConfig(1); + CreateMatchingReceiveConfigs(); + + CreateStreams(); + CreateFrameGeneratorCapturer(); + Start(); + + int64_t start_time_ms = clock_->TimeInMilliseconds(); + while (true) { + Call::Stats stats = sender_call_->GetStats(); + ASSERT_GE(start_time_ms + kDefaultTimeoutMs, + clock_->TimeInMilliseconds()) + << "No RTT stats before timeout!"; + if (stats.rtt_ms != -1) { + EXPECT_GE(stats.rtt_ms, kSendDelayMs + kReceiveDelayMs); + break; + } + SleepMs(10); + } + + Stop(); + DestroyStreams(); +} + TEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) { class UnusedEncoder : public test::FakeEncoder { public: diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 01e2bdd8d8..cd8554e910 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -529,5 +529,15 @@ int VideoSendStream::GetPacerQueuingDelayMs() const { } return pacer_delay_ms; } + +int VideoSendStream::GetRtt() const { + webrtc::RtcpStatistics rtcp_stats; + int rtt_ms; + if (rtp_rtcp_->GetSendChannelRtcpStatistics(channel_, rtcp_stats, rtt_ms) == + 0) { + return rtt_ms; + } + return -1; +} } // namespace internal } // namespace webrtc diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h index 2e0791434d..6f7f400455 100644 --- a/webrtc/video/video_send_stream.h +++ b/webrtc/video/video_send_stream.h @@ -77,6 +77,8 @@ class VideoSendStream : public webrtc::VideoSendStream, int GetPacerQueuingDelayMs() const; + int GetRtt() const; + private: void ConfigureSsrcs(); TransportAdapter transport_adapter_;