Add average rtt to CallStatsObserver and an average rtt histogram.

TBR=mflodman@webrtc.org

BUG=webrtc:4711,webrtc:4548

Review URL: https://codereview.webrtc.org/1279543005

Cr-Commit-Position: refs/heads/master@{#9687}
diff --git a/webrtc/modules/interface/module_common_types.h b/webrtc/modules/interface/module_common_types.h
index 232e695..02ce03f 100644
--- a/webrtc/modules/interface/module_common_types.h
+++ b/webrtc/modules/interface/module_common_types.h
@@ -440,7 +440,7 @@
 // CallStats object using RegisterStatsObserver.
 class CallStatsObserver {
  public:
-  virtual void OnRttUpdate(int64_t rtt_ms) = 0;
+  virtual void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) = 0;
 
   virtual ~CallStatsObserver() {}
 };
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
index c5faf16..2050ea1 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
@@ -372,9 +372,10 @@
   }
 }
 
-void RemoteBitrateEstimatorAbsSendTime::OnRttUpdate(int64_t rtt) {
+void RemoteBitrateEstimatorAbsSendTime::OnRttUpdate(int64_t avg_rtt_ms,
+                                                    int64_t max_rtt_ms) {
   CriticalSectionScoped cs(crit_sect_.get());
-  remote_rate_.SetRtt(rtt);
+  remote_rate_.SetRtt(avg_rtt_ms);
 }
 
 void RemoteBitrateEstimatorAbsSendTime::RemoveStream(unsigned int ssrc) {
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h
index 0d3802a..1bee6bd 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h
@@ -83,7 +83,7 @@
   // deleted.
   int32_t Process() override;
   int64_t TimeUntilNextProcess() override;
-  void OnRttUpdate(int64_t rtt) override;
+  void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
   void RemoveStream(unsigned int ssrc) override;
   bool LatestEstimate(std::vector<unsigned int>* ssrcs,
                       unsigned int* bitrate_bps) const override;
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
index 762a317..6fd54e9 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
@@ -182,9 +182,10 @@
   }
 }
 
-void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t rtt) {
+void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t avg_rtt_ms,
+                                                     int64_t max_rtt_ms) {
   CriticalSectionScoped cs(crit_sect_.get());
-  remote_rate_->SetRtt(rtt);
+  remote_rate_->SetRtt(avg_rtt_ms);
 }
 
 void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h
index 0432355..5ca2100 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h
@@ -34,7 +34,7 @@
                       bool was_paced) override;
   int32_t Process() override;
   int64_t TimeUntilNextProcess() override;
-  void OnRttUpdate(int64_t rtt) override;
+  void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
   void RemoveStream(unsigned int ssrc) override;
   bool LatestEstimate(std::vector<unsigned int>* ssrcs,
                       unsigned int* bitrate_bps) const override;
diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc
index f0d57ad..8ec2b72 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc
@@ -77,7 +77,7 @@
   ss << "Estimate_" << flow_id_ << "#1";
   estimate_log_prefix_ = ss.str();
   // Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic.
-  estimator_->OnRttUpdate(50);
+  estimator_->OnRttUpdate(50, 50);
 }
 
 RembReceiver::~RembReceiver() {
diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc
index b003d45..1f95f65 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc
@@ -61,7 +61,7 @@
 
   int64_t rtt_ms =
       clock_->TimeInMilliseconds() - feedback.latest_send_time_ms();
-  rbe_->OnRttUpdate(rtt_ms);
+  rbe_->OnRttUpdate(rtt_ms, rtt_ms);
   BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms);
 
   rbe_->IncomingPacketFeedbackVector(packet_feedback_vector);
diff --git a/webrtc/video_engine/call_stats.cc b/webrtc/video_engine/call_stats.cc
index 6e51eeb..92855e3 100644
--- a/webrtc/video_engine/call_stats.cc
+++ b/webrtc/video_engine/call_stats.cc
@@ -123,7 +123,7 @@
   if (max_rtt_ms_ > 0) {
     for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
          it != observers_.end(); ++it) {
-      (*it)->OnRttUpdate(max_rtt_ms_);
+      (*it)->OnRttUpdate(avg_rtt_ms_, max_rtt_ms_);
     }
   }
   return 0;
diff --git a/webrtc/video_engine/call_stats_unittest.cc b/webrtc/video_engine/call_stats_unittest.cc
index 0febbd0..bfe52da 100644
--- a/webrtc/video_engine/call_stats_unittest.cc
+++ b/webrtc/video_engine/call_stats_unittest.cc
@@ -27,7 +27,7 @@
   MockStatsObserver() {}
   virtual ~MockStatsObserver() {}
 
-  MOCK_METHOD1(OnRttUpdate, void(int64_t));
+  MOCK_METHOD2(OnRttUpdate, void(int64_t, int64_t));
 };
 
 class CallStatsTest : public ::testing::Test {
@@ -48,15 +48,13 @@
 
   const int64_t kRtt = 25;
   rtcp_rtt_stats->OnRttUpdate(kRtt);
-  EXPECT_CALL(stats_observer, OnRttUpdate(kRtt))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt)).Times(1);
   call_stats_->Process();
   EXPECT_EQ(kRtt, rtcp_rtt_stats->LastProcessedRtt());
 
   const int64_t kRttTimeOutMs = 1500 + 10;
   TickTime::AdvanceFakeClock(kRttTimeOutMs);
-  EXPECT_CALL(stats_observer, OnRttUpdate(_))
-      .Times(0);
+  EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
   call_stats_->Process();
   EXPECT_EQ(0, rtcp_rtt_stats->LastProcessedRtt());
 
@@ -70,27 +68,23 @@
   rtcp_rtt_stats->OnRttUpdate(100);
 
   // Time isn't updated yet.
-  EXPECT_CALL(stats_observer, OnRttUpdate(_))
-      .Times(0);
+  EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
   call_stats_->Process();
 
   // Advance clock and verify we get an update.
   TickTime::AdvanceFakeClock(1000);
-  EXPECT_CALL(stats_observer, OnRttUpdate(_))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
   call_stats_->Process();
 
   // Advance clock just too little to get an update.
   TickTime::AdvanceFakeClock(999);
   rtcp_rtt_stats->OnRttUpdate(100);
-  EXPECT_CALL(stats_observer, OnRttUpdate(_))
-      .Times(0);
+  EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
   call_stats_->Process();
 
   // Advance enough to trigger a new update.
   TickTime::AdvanceFakeClock(1);
-  EXPECT_CALL(stats_observer, OnRttUpdate(_))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
   call_stats_->Process();
 
   call_stats_->DeregisterStatsObserver(&stats_observer);
@@ -113,10 +107,8 @@
 
   // Verify both observers are updated.
   TickTime::AdvanceFakeClock(1000);
-  EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt))
-      .Times(1);
-  EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt))
-      .Times(1);
+  EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
+  EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(1);
   call_stats_->Process();
 
   // Deregister the second observer and verify update is only sent to the first
@@ -124,20 +116,16 @@
   call_stats_->DeregisterStatsObserver(&stats_observer_2);
   rtcp_rtt_stats->OnRttUpdate(kRtt);
   TickTime::AdvanceFakeClock(1000);
-  EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt))
-      .Times(1);
-  EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt))
-      .Times(0);
+  EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
+  EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
   call_stats_->Process();
 
   // Deregister the first observer.
   call_stats_->DeregisterStatsObserver(&stats_observer_1);
   rtcp_rtt_stats->OnRttUpdate(kRtt);
   TickTime::AdvanceFakeClock(1000);
-  EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt))
-      .Times(0);
-  EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt))
-      .Times(0);
+  EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(0);
+  EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
   call_stats_->Process();
 }
 
@@ -153,16 +141,15 @@
   // Set a first value and verify the callback is triggered.
   const int64_t kFirstRtt = 100;
   rtcp_rtt_stats->OnRttUpdate(kFirstRtt);
-  EXPECT_CALL(stats_observer, OnRttUpdate(kFirstRtt))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(kFirstRtt, kFirstRtt)).Times(1);
   call_stats_->Process();
 
   // Increase rtt and verify the new value is reported.
   TickTime::AdvanceFakeClock(1000);
   const int64_t kHighRtt = kFirstRtt + 20;
+  const int64_t kAvgRtt1 = 103;
   rtcp_rtt_stats->OnRttUpdate(kHighRtt);
-  EXPECT_CALL(stats_observer, OnRttUpdate(kHighRtt))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt1, kHighRtt)).Times(1);
   call_stats_->Process();
 
   // Increase time enough for a new update, but not too much to make the
@@ -170,16 +157,16 @@
   // in the callback.
   TickTime::AdvanceFakeClock(1000);
   const int64_t kLowRtt = kFirstRtt - 20;
+  const int64_t kAvgRtt2 = 102;
   rtcp_rtt_stats->OnRttUpdate(kLowRtt);
-  EXPECT_CALL(stats_observer, OnRttUpdate(kHighRtt))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt2, kHighRtt)).Times(1);
   call_stats_->Process();
 
   // Advance time to make the high report invalid, the lower rtt should now be
   // in the callback.
   TickTime::AdvanceFakeClock(1000);
-  EXPECT_CALL(stats_observer, OnRttUpdate(kLowRtt))
-      .Times(1);
+  const int64_t kAvgRtt3 = 95;
+  EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt3, kLowRtt)).Times(1);
   call_stats_->Process();
 
   call_stats_->DeregisterStatsObserver(&stats_observer);
@@ -198,8 +185,7 @@
   const int64_t kAvgRtt = 20;
   rtcp_rtt_stats->OnRttUpdate(kRttLow);
   rtcp_rtt_stats->OnRttUpdate(kRttHigh);
-  EXPECT_CALL(stats_observer, OnRttUpdate(kRttHigh))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
   call_stats_->Process();
   EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
 
@@ -207,8 +193,7 @@
   TickTime::AdvanceFakeClock(1000);
   rtcp_rtt_stats->OnRttUpdate(kRttLow);
   rtcp_rtt_stats->OnRttUpdate(kRttHigh);
-  EXPECT_CALL(stats_observer, OnRttUpdate(kRttHigh))
-      .Times(1);
+  EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
   call_stats_->Process();
   EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
 
diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc
index df371ed..b8664ce 100644
--- a/webrtc/video_engine/vie_channel.cc
+++ b/webrtc/video_engine/vie_channel.cc
@@ -49,8 +49,8 @@
   virtual ~ChannelStatsObserver() {}
 
   // Implements StatsObserver.
-  virtual void OnRttUpdate(int64_t rtt) {
-    owner_->OnRttUpdate(rtt);
+  virtual void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
+    owner_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
   }
 
  private:
@@ -119,6 +119,9 @@
       max_nack_reordering_threshold_(kMaxPacketAgeToNack),
       pre_render_callback_(NULL),
       report_block_stats_sender_(new ReportBlockStats()),
+      time_of_first_rtt_ms_(-1),
+      rtt_sum_ms_(0),
+      num_rtts_(0),
       rtp_rtcp_modules_(
           CreateRtpRtcpModules(ViEModuleId(engine_id_, channel_id_),
                                !sender,
@@ -198,6 +201,17 @@
 void ViEChannel::UpdateHistograms() {
   int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds();
 
+  {
+    CriticalSectionScoped cs(crit_.get());
+    int64_t elapsed_sec = (now - time_of_first_rtt_ms_) / 1000;
+    if (time_of_first_rtt_ms_ != -1 && num_rtts_ > 0 &&
+        elapsed_sec > metrics::kMinRunTimeInSeconds) {
+      int64_t avg_rtt_ms = (rtt_sum_ms_ + num_rtts_ / 2) / num_rtts_;
+      RTC_HISTOGRAM_COUNTS_10000(
+          "WebRTC.Video.AverageRoundTripTimeInMilliseconds", avg_rtt_ms);
+    }
+  }
+
   if (sender_) {
     RtcpPacketTypeCounter rtcp_counter;
     GetSendRtcpPacketTypeCounter(&rtcp_counter);
@@ -1119,8 +1133,14 @@
   return true;
 }
 
-void ViEChannel::OnRttUpdate(int64_t rtt) {
-  vcm_->SetReceiveChannelParameters(rtt);
+void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
+  vcm_->SetReceiveChannelParameters(max_rtt_ms);
+
+  CriticalSectionScoped cs(crit_.get());
+  if (time_of_first_rtt_ms_ == -1)
+    time_of_first_rtt_ms_ = Clock::GetRealTimeClock()->TimeInMilliseconds();
+  rtt_sum_ms_ += avg_rtt_ms;
+  ++num_rtts_;
 }
 
 int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params,
diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h
index 6c5782e..85b18cf 100644
--- a/webrtc/video_engine/vie_channel.h
+++ b/webrtc/video_engine/vie_channel.h
@@ -318,7 +318,7 @@
   static bool ChannelDecodeThreadFunction(void* obj);
   bool ChannelDecodeProcess();
 
-  void OnRttUpdate(int64_t rtt);
+  void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms);
 
   int ProtectionRequest(const FecProtectionParams* delta_fec_params,
                         const FecProtectionParams* key_fec_params,
@@ -488,6 +488,10 @@
 
   const rtc::scoped_ptr<ReportBlockStats> report_block_stats_sender_;
 
+  int64_t time_of_first_rtt_ms_ GUARDED_BY(crit_);
+  int64_t rtt_sum_ms_ GUARDED_BY(crit_);
+  size_t num_rtts_ GUARDED_BY(crit_);
+
   // RtpRtcp modules, declared last as they use other members on construction.
   const std::vector<RtpRtcp*> rtp_rtcp_modules_;
   size_t num_active_rtp_rtcp_modules_ GUARDED_BY(crit_);
diff --git a/webrtc/video_engine/vie_channel_group.cc b/webrtc/video_engine/vie_channel_group.cc
index cf6b19c..b1a21f0 100644
--- a/webrtc/video_engine/vie_channel_group.cc
+++ b/webrtc/video_engine/vie_channel_group.cc
@@ -70,9 +70,9 @@
     return rbe_->TimeUntilNextProcess();
   }
 
-  void OnRttUpdate(int64_t rtt) override {
+  void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override {
     CriticalSectionScoped cs(crit_sect_.get());
-    rbe_->OnRttUpdate(rtt);
+    rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
   }
 
   void RemoveStream(unsigned int ssrc) override {