Implement CpuOveruseMetrics as callbacks.

Adds avg_encode_ms and encode_usage_percent in WebRtcVideoEngine2 and
corresponding stats to VideoSendStream::Stats.

BUG=1667, 1788
R=asapersson@webrtc.org, mflodman@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/42429004

Cr-Commit-Position: refs/heads/master@{#8513}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8513 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h
index b38a757..0247a4e 100644
--- a/talk/media/webrtc/fakewebrtcvideoengine.h
+++ b/talk/media/webrtc/fakewebrtcvideoengine.h
@@ -699,6 +699,8 @@
     return 0;
   }
   WEBRTC_STUB(GetCpuOveruseMetrics, (int, webrtc::CpuOveruseMetrics*));
+  WEBRTC_VOID_STUB(RegisterCpuOveruseMetricsObserver,
+                   (int, webrtc::CpuOveruseMetricsObserver*));
   WEBRTC_FUNC(SetCpuOveruseOptions,
       (int channel, const webrtc::CpuOveruseOptions& options)) {
     WEBRTC_CHECK_CHANNEL(channel);
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index baa0911..5a380cb 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -1774,6 +1774,8 @@
   }
   info.framerate_input = stats.input_frame_rate;
   info.framerate_sent = stats.encode_frame_rate;
+  info.avg_encode_ms = stats.avg_encode_time_ms;
+  info.encode_usage_percent = stats.encode_usage_percent;
 
   info.nominal_bitrate = stats.media_bitrate_bps;
 
diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
index 3fa2204..751765d 100644
--- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -2038,6 +2038,19 @@
   EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
 }
 
+TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) {
+  FakeVideoSendStream* stream = AddSendStream();
+  webrtc::VideoSendStream::Stats stats;
+  stats.avg_encode_time_ms = 13;
+  stats.encode_usage_percent = 42;
+  stream->SetStats(stats);
+
+  cricket::VideoMediaInfo info;
+  ASSERT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
+  EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
+  EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
+}
+
 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
   FakeVideoSendStream* stream = AddSendStream();
   webrtc::VideoSendStream::Stats stats;
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 3d46cc3..07e3fdc 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -1660,6 +1660,9 @@
       send_stats_filled_["NumStreams"] |=
           stats.substreams.size() == expected_send_ssrcs_.size();
 
+      send_stats_filled_["CpuOveruseMetrics"] |=
+          stats.avg_encode_time_ms != 0 || stats.encode_usage_percent != 0;
+
       for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
                stats.substreams.begin();
            it != stats.substreams.end(); ++it) {
diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc
index 64126d2..7c148b7 100644
--- a/webrtc/video/send_statistics_proxy.cc
+++ b/webrtc/video/send_statistics_proxy.cc
@@ -38,6 +38,13 @@
   stats_.media_bitrate_bps = bitrate;
 }
 
+void SendStatisticsProxy::CpuOveruseMetricsUpdated(
+    const CpuOveruseMetrics& metrics) {
+  CriticalSectionScoped lock(crit_.get());
+  stats_.avg_encode_time_ms = metrics.avg_encode_time_ms;
+  stats_.encode_usage_percent = metrics.encode_usage_percent;
+}
+
 void SendStatisticsProxy::SuspendChange(int video_channel, bool is_suspended) {
   CriticalSectionScoped lock(crit_.get());
   stats_.suspended = is_suspended;
diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h
index 5d4edcd..540ee32 100644
--- a/webrtc/video/send_statistics_proxy.h
+++ b/webrtc/video/send_statistics_proxy.h
@@ -18,6 +18,7 @@
 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
 #include "webrtc/system_wrappers/interface/clock.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/video_engine/include/vie_base.h"
 #include "webrtc/video_engine/include/vie_capture.h"
 #include "webrtc/video_engine/include/vie_codec.h"
 #include "webrtc/video_send_stream.h"
@@ -26,7 +27,8 @@
 
 class CriticalSectionWrapper;
 
-class SendStatisticsProxy : public RtcpStatisticsCallback,
+class SendStatisticsProxy : public CpuOveruseMetricsObserver,
+                            public RtcpStatisticsCallback,
                             public RtcpPacketTypeCounterObserver,
                             public StreamDataCountersCallback,
                             public BitrateStatisticsObserver,
@@ -46,6 +48,8 @@
                                   const RTPVideoHeader* rtp_video_header);
 
  protected:
+  // From CpuOveruseMetricsObserver.
+  void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) OVERRIDE;
   // From RtcpStatisticsCallback.
   virtual void StatisticsUpdated(const RtcpStatistics& statistics,
                                  uint32_t ssrc) OVERRIDE;
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 82af66e..881802a 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -210,6 +210,9 @@
 
   if (overuse_observer)
     video_engine_base_->RegisterCpuOveruseObserver(channel_, overuse_observer);
+  // Registered regardless of monitoring, used for stats.
+  video_engine_base_->RegisterCpuOveruseMetricsObserver(channel_,
+                                                        &stats_proxy_);
 
   video_engine_base_->RegisterSendSideDelayObserver(channel_, &stats_proxy_);
   video_engine_base_->RegisterSendStatisticsProxy(channel_, &stats_proxy_);
diff --git a/webrtc/video_engine/include/vie_base.h b/webrtc/video_engine/include/vie_base.h
index 3f4840a..7262ca2 100644
--- a/webrtc/video_engine/include/vie_base.h
+++ b/webrtc/video_engine/include/vie_base.h
@@ -112,7 +112,6 @@
       : capture_jitter_ms(-1),
         avg_encode_time_ms(-1),
         encode_usage_percent(-1),
-        encode_rsd(-1),
         capture_queue_delay_ms_per_s(-1) {}
 
   int capture_jitter_ms;  // The current estimated jitter in ms based on
@@ -120,14 +119,18 @@
   int avg_encode_time_ms;   // The average encode time in ms.
   int encode_usage_percent; // The average encode time divided by the average
                             // time difference between incoming captured frames.
-  // TODO(asapersson): Remove metric, not used.
-  int encode_rsd;           // The relative std dev of encode time of frames.
   int capture_queue_delay_ms_per_s;  // The current time delay between an
                                      // incoming captured frame until the frame
                                      // is being processed. The delay is
                                      // expressed in ms delay per second.
 };
 
+class CpuOveruseMetricsObserver {
+ public:
+  virtual ~CpuOveruseMetricsObserver() {}
+  virtual void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) = 0;
+};
+
 class WEBRTC_DLLEXPORT VideoEngine {
  public:
   // Creates a VideoEngine object, which can then be used to acquire subā€APIs.
@@ -208,6 +211,9 @@
 
   // Gets cpu overuse measures.
   virtual int GetCpuOveruseMetrics(int channel, CpuOveruseMetrics* metrics) = 0;
+  virtual void RegisterCpuOveruseMetricsObserver(
+      int channel,
+      CpuOveruseMetricsObserver* observer) = 0;
 
   // Registers a callback which is called when send-side delay statistics has
   // been updated.
diff --git a/webrtc/video_engine/overuse_frame_detector.cc b/webrtc/video_engine/overuse_frame_detector.cc
index b4e1e36..b4204db 100644
--- a/webrtc/video_engine/overuse_frame_detector.cc
+++ b/webrtc/video_engine/overuse_frame_detector.cc
@@ -317,8 +317,11 @@
   scoped_ptr<rtc::ExpFilter> filtered_delay_ms_per_s_;
 };
 
-OveruseFrameDetector::OveruseFrameDetector(Clock* clock)
+OveruseFrameDetector::OveruseFrameDetector(
+    Clock* clock,
+    CpuOveruseMetricsObserver* metrics_observer)
     : observer_(NULL),
+      metrics_observer_(metrics_observer),
       clock_(clock),
       next_process_time_(clock_->TimeInMilliseconds()),
       num_process_times_(0),
@@ -336,6 +339,7 @@
       frame_queue_(new FrameQueue()),
       last_sample_time_ms_(0),
       capture_queue_delay_(new CaptureQueueDelay()) {
+  DCHECK(metrics_observer != nullptr);
   processing_thread_.DetachFromThread();
 }
 
@@ -374,14 +378,13 @@
   return frame_queue_->NumFrames();
 }
 
-void OveruseFrameDetector::GetCpuOveruseMetrics(
-    CpuOveruseMetrics* metrics) const {
-  rtc::CritScope cs(&crit_);
-  metrics->capture_jitter_ms = static_cast<int>(capture_deltas_.StdDev() + 0.5);
-  metrics->avg_encode_time_ms = encode_time_->Value();
-  metrics->encode_rsd = 0;
-  metrics->encode_usage_percent = usage_->Value();
-  metrics->capture_queue_delay_ms_per_s = capture_queue_delay_->Value();
+void OveruseFrameDetector::UpdateCpuOveruseMetrics() {
+  metrics_.capture_jitter_ms = static_cast<int>(capture_deltas_.StdDev() + 0.5);
+  metrics_.avg_encode_time_ms = encode_time_->Value();
+  metrics_.encode_usage_percent = usage_->Value();
+  metrics_.capture_queue_delay_ms_per_s = capture_queue_delay_->Value();
+
+  metrics_observer_->CpuOveruseMetricsUpdated(metrics_);
 }
 
 int64_t OveruseFrameDetector::TimeUntilNextProcess() {
@@ -411,6 +414,7 @@
   capture_queue_delay_->ClearFrames();
   last_capture_time_ = 0;
   num_process_times_ = 0;
+  UpdateCpuOveruseMetrics();
 }
 
 void OveruseFrameDetector::FrameCaptured(int width,
@@ -434,6 +438,7 @@
   if (options_.enable_extended_processing_usage) {
     frame_queue_->Start(capture_time_ms, now);
   }
+  UpdateCpuOveruseMetrics();
 }
 
 void OveruseFrameDetector::FrameProcessingStarted() {
@@ -453,6 +458,7 @@
   if (!options_.enable_extended_processing_usage) {
     AddProcessingTime(encode_time_ms);
   }
+  UpdateCpuOveruseMetrics();
 }
 
 void OveruseFrameDetector::FrameSent(int64_t capture_time_ms) {
@@ -465,6 +471,7 @@
   if (delay_ms > 0) {
     AddProcessingTime(delay_ms);
   }
+  UpdateCpuOveruseMetrics();
 }
 
 void OveruseFrameDetector::AddProcessingTime(int elapsed_ms) {
@@ -492,6 +499,7 @@
   ++num_process_times_;
 
   capture_queue_delay_->CalculateDelayChange(diff_ms);
+  UpdateCpuOveruseMetrics();
 
   if (num_process_times_ <= options_.min_process_count) {
     return 0;
@@ -537,6 +545,7 @@
                   << " encode usage " << usage_->Value()
                   << " overuse detections " << num_overuse_detections_
                   << " rampup delay " << rampup_delay;
+
   return 0;
 }
 
diff --git a/webrtc/video_engine/overuse_frame_detector.h b/webrtc/video_engine/overuse_frame_detector.h
index 969639c..28bac39 100644
--- a/webrtc/video_engine/overuse_frame_detector.h
+++ b/webrtc/video_engine/overuse_frame_detector.h
@@ -52,7 +52,8 @@
 // Use to detect system overuse based on jitter in incoming frames.
 class OveruseFrameDetector : public Module {
  public:
-  explicit OveruseFrameDetector(Clock* clock);
+  OveruseFrameDetector(Clock* clock,
+                       CpuOveruseMetricsObserver* metrics_observer);
   ~OveruseFrameDetector();
 
   // Registers an observer receiving overuse and underuse callbacks. Set
@@ -74,26 +75,6 @@
   // Called for each sent frame.
   void FrameSent(int64_t capture_time_ms);
 
-  // Accessors.
-
-  // Returns CpuOveruseMetrics where
-  // capture_jitter_ms: The estimated jitter based on incoming captured frames.
-  // avg_encode_time_ms: Running average of reported encode time
-  //                     (FrameEncoded()). Only used for stats.
-  // TODO(asapersson): Rename metric.
-  // encode_usage_percent: The average processing time of a frame on the
-  //                       send-side divided by the average time difference
-  //                       between incoming captured frames.
-  // capture_queue_delay_ms_per_s: The current time delay between an incoming
-  //                               captured frame (FrameCaptured()) until the
-  //                               frame is being processed
-  //                               (FrameProcessingStarted()). (Note: if a new
-  //                               frame is received before an old frame has
-  //                               been processed, the old frame is skipped).
-  //                               The delay is expressed in ms delay per sec.
-  //                               Only used for stats.
-  void GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const;
-
   // Only public for testing.
   int CaptureQueueDelayMsPerS() const;
   int LastProcessingTimeMs() const;
@@ -109,6 +90,8 @@
   class CaptureQueueDelay;
   class FrameQueue;
 
+  void UpdateCpuOveruseMetrics() EXCLUSIVE_LOCKS_REQUIRED(crit_);
+
   // TODO(asapersson): This method is only used on one thread, so it shouldn't
   // need a guard.
   void AddProcessingTime(int elapsed_ms) EXCLUSIVE_LOCKS_REQUIRED(crit_);
@@ -136,6 +119,10 @@
 
   CpuOveruseOptions options_ GUARDED_BY(crit_);
 
+  // Stats metrics.
+  CpuOveruseMetricsObserver* const metrics_observer_;
+  CpuOveruseMetrics metrics_ GUARDED_BY(crit_);
+
   Clock* const clock_;
   int64_t next_process_time_;  // Only accessed on the processing thread.
   int64_t num_process_times_ GUARDED_BY(crit_);
diff --git a/webrtc/video_engine/overuse_frame_detector_unittest.cc b/webrtc/video_engine/overuse_frame_detector_unittest.cc
index 84f0e04..d10d81f 100644
--- a/webrtc/video_engine/overuse_frame_detector_unittest.cc
+++ b/webrtc/video_engine/overuse_frame_detector_unittest.cc
@@ -47,12 +47,13 @@
   int normaluse_;
 };
 
-class OveruseFrameDetectorTest : public ::testing::Test {
+class OveruseFrameDetectorTest : public ::testing::Test,
+                                 public CpuOveruseMetricsObserver {
  protected:
   virtual void SetUp() {
     clock_.reset(new SimulatedClock(1234));
     observer_.reset(new MockCpuOveruseObserver());
-    overuse_detector_.reset(new OveruseFrameDetector(clock_.get()));
+    overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), this));
 
     options_.low_capture_jitter_threshold_ms = 10.0f;
     options_.high_capture_jitter_threshold_ms = 15.0f;
@@ -61,6 +62,11 @@
     overuse_detector_->SetObserver(observer_.get());
   }
 
+  virtual void CpuOveruseMetricsUpdated(
+      const CpuOveruseMetrics& metrics) override {
+    metrics_ = metrics;
+  }
+
   int InitialJitter() {
     return ((options_.low_capture_jitter_threshold_ms +
              options_.high_capture_jitter_threshold_ms) / 2.0f) + 0.5;
@@ -124,28 +130,17 @@
     overuse_detector_->Process();
   }
 
-  int CaptureJitterMs() {
-    CpuOveruseMetrics metrics;
-    overuse_detector_->GetCpuOveruseMetrics(&metrics);
-    return metrics.capture_jitter_ms;
-  }
+  int CaptureJitterMs() { return metrics_.capture_jitter_ms; }
 
-  int AvgEncodeTimeMs() {
-    CpuOveruseMetrics metrics;
-    overuse_detector_->GetCpuOveruseMetrics(&metrics);
-    return metrics.avg_encode_time_ms;
-  }
+  int AvgEncodeTimeMs() { return metrics_.avg_encode_time_ms; }
 
-  int UsagePercent() {
-    CpuOveruseMetrics metrics;
-    overuse_detector_->GetCpuOveruseMetrics(&metrics);
-    return metrics.encode_usage_percent;
-  }
+  int UsagePercent() { return metrics_.encode_usage_percent; }
 
   CpuOveruseOptions options_;
   scoped_ptr<SimulatedClock> clock_;
   scoped_ptr<MockCpuOveruseObserver> observer_;
   scoped_ptr<OveruseFrameDetector> overuse_detector_;
+  CpuOveruseMetrics metrics_;
 };
 
 // enable_capture_jitter_method = true;
@@ -257,16 +252,6 @@
   TriggerOveruse(1);
 }
 
-TEST_F(OveruseFrameDetectorTest, GetCpuOveruseMetrics) {
-  CpuOveruseMetrics metrics;
-  overuse_detector_->GetCpuOveruseMetrics(&metrics);
-  EXPECT_GT(metrics.capture_jitter_ms, 0);
-  EXPECT_GT(metrics.avg_encode_time_ms, 0);
-  EXPECT_GT(metrics.encode_usage_percent, 0);
-  EXPECT_GE(metrics.capture_queue_delay_ms_per_s, 0);
-  EXPECT_GE(metrics.encode_rsd, 0);
-}
-
 TEST_F(OveruseFrameDetectorTest, CaptureJitter) {
   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
   InsertFramesWithInterval(1000, kFrameInterval33ms, kWidth, kHeight);
diff --git a/webrtc/video_engine/vie_base_impl.cc b/webrtc/video_engine/vie_base_impl.cc
index 9e9350d..4b977de 100644
--- a/webrtc/video_engine/vie_base_impl.cc
+++ b/webrtc/video_engine/vie_base_impl.cc
@@ -120,6 +120,23 @@
   return -1;
 }
 
+void ViEBaseImpl::RegisterCpuOveruseMetricsObserver(
+    int video_channel,
+    CpuOveruseMetricsObserver* observer) {
+  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
+  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
+  assert(vie_encoder);
+
+  ViEInputManagerScoped is(*(shared_data_.input_manager()));
+  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
+  assert(provider != NULL);
+
+  ViECapturer* capturer = is.Capture(provider->Id());
+  assert(capturer);
+
+  capturer->RegisterCpuOveruseMetricsObserver(observer);
+}
+
 int ViEBaseImpl::GetCpuOveruseMetrics(int video_channel,
                                       CpuOveruseMetrics* metrics) {
   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
diff --git a/webrtc/video_engine/vie_base_impl.h b/webrtc/video_engine/vie_base_impl.h
index dd21a04..7e025c7 100644
--- a/webrtc/video_engine/vie_base_impl.h
+++ b/webrtc/video_engine/vie_base_impl.h
@@ -35,6 +35,9 @@
                                          CpuOveruseObserver* observer);
   virtual int SetCpuOveruseOptions(int channel,
                                    const CpuOveruseOptions& options);
+  virtual void RegisterCpuOveruseMetricsObserver(
+      int channel,
+      CpuOveruseMetricsObserver* observer) override;
   virtual int GetCpuOveruseMetrics(int channel,
                                    CpuOveruseMetrics* metrics);
   virtual void RegisterSendSideDelayObserver(int channel,
diff --git a/webrtc/video_engine/vie_capturer.cc b/webrtc/video_engine/vie_capturer.cc
index f9e42e6..29685fd 100644
--- a/webrtc/video_engine/vie_capturer.cc
+++ b/webrtc/video_engine/vie_capturer.cc
@@ -32,6 +32,32 @@
 
 const int kThreadWaitTimeMs = 100;
 
+class RegistrableCpuOveruseMetricsObserver : public CpuOveruseMetricsObserver {
+ public:
+  virtual void CpuOveruseMetricsUpdated(
+      const CpuOveruseMetrics& metrics) override {
+    rtc::CritScope lock(&crit_);
+    if (observer_)
+      observer_->CpuOveruseMetricsUpdated(metrics);
+    metrics_ = metrics;
+  }
+
+  CpuOveruseMetrics GetCpuOveruseMetrics() const {
+    rtc::CritScope lock(&crit_);
+    return metrics_;
+  }
+
+  void Set(CpuOveruseMetricsObserver* observer) {
+    rtc::CritScope lock(&crit_);
+    observer_ = observer;
+  }
+
+ private:
+  mutable rtc::CriticalSection crit_;
+  CpuOveruseMetricsObserver* observer_ GUARDED_BY(crit_) = nullptr;
+  CpuOveruseMetrics metrics_ GUARDED_BY(crit_);
+};
+
 ViECapturer::ViECapturer(int capture_id,
                          int engine_id,
                          const Config& config,
@@ -45,7 +71,8 @@
       capture_id_(capture_id),
       incoming_frame_cs_(CriticalSectionWrapper::CreateCriticalSection()),
       capture_thread_(*ThreadWrapper::CreateThread(ViECaptureThreadFunction,
-                                                   this, kHighPriority,
+                                                   this,
+                                                   kHighPriority,
                                                    "ViECaptureThread")),
       capture_event_(*EventWrapper::Create()),
       deliver_event_(*EventWrapper::Create()),
@@ -59,7 +86,10 @@
       reported_brightness_level_(Normal),
       observer_cs_(CriticalSectionWrapper::CreateCriticalSection()),
       observer_(NULL),
-      overuse_detector_(new OveruseFrameDetector(Clock::GetRealTimeClock())) {
+      cpu_overuse_metrics_observer_(new RegistrableCpuOveruseMetricsObserver()),
+      overuse_detector_(
+          new OveruseFrameDetector(Clock::GetRealTimeClock(),
+                                   cpu_overuse_metrics_observer_.get())) {
   unsigned int t_id = 0;
   if (!capture_thread_.Start(t_id)) {
     assert(false);
@@ -246,8 +276,13 @@
   overuse_detector_->SetOptions(options);
 }
 
+void ViECapturer::RegisterCpuOveruseMetricsObserver(
+    CpuOveruseMetricsObserver* observer) {
+  cpu_overuse_metrics_observer_->Set(observer);
+}
+
 void ViECapturer::GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const {
-  overuse_detector_->GetCpuOveruseMetrics(metrics);
+  *metrics = cpu_overuse_metrics_observer_->GetCpuOveruseMetrics();
 }
 
 int32_t ViECapturer::SetCaptureDelay(int32_t delay_ms) {
diff --git a/webrtc/video_engine/vie_capturer.h b/webrtc/video_engine/vie_capturer.h
index 00e2f36..3183d8c 100644
--- a/webrtc/video_engine/vie_capturer.h
+++ b/webrtc/video_engine/vie_capturer.h
@@ -13,6 +13,7 @@
 
 #include <vector>
 
+#include "webrtc/base/criticalsection.h"
 #include "webrtc/base/thread_annotations.h"
 #include "webrtc/common_types.h"
 #include "webrtc/engine_configurations.h"
@@ -20,6 +21,7 @@
 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
 #include "webrtc/modules/video_processing/main/interface/video_processing.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/typedefs.h"
 #include "webrtc/video_engine/include/vie_base.h"
@@ -39,6 +41,7 @@
 class ViEEffectFilter;
 class ViEEncoder;
 struct ViEPicture;
+class RegistrableCpuOveruseMetricsObserver;
 
 class ViECapturer
     : public ViEFrameProviderBase,
@@ -107,6 +110,7 @@
 
   void RegisterCpuOveruseObserver(CpuOveruseObserver* observer);
   void SetCpuOveruseOptions(const CpuOveruseOptions& options);
+  void RegisterCpuOveruseMetricsObserver(CpuOveruseMetricsObserver* observer);
   void GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const;
 
  protected:
@@ -187,6 +191,9 @@
 
   CaptureCapability requested_capability_;
 
+  // Must be declared before overuse_detector_ where it's registered.
+  const scoped_ptr<RegistrableCpuOveruseMetricsObserver>
+      cpu_overuse_metrics_observer_;
   scoped_ptr<OveruseFrameDetector> overuse_detector_;
 };
 
diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h
index dbb07b1..73dbb2b 100644
--- a/webrtc/video_engine/vie_channel.h
+++ b/webrtc/video_engine/vie_channel.h
@@ -442,8 +442,7 @@
       if (callback_)
         callback_->Notify(total_stats, retransmit_stats, ssrc);
     }
-  }
-  send_bitrate_observer_;
+  } send_bitrate_observer_;
 
   class RegisterableFrameCountObserver
       : public RegisterableCallback<FrameCountObserver> {
diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h
index 0e41cc5..eb6dfe6 100644
--- a/webrtc/video_send_stream.h
+++ b/webrtc/video_send_stream.h
@@ -55,10 +55,14 @@
     Stats()
         : input_frame_rate(0),
           encode_frame_rate(0),
+          avg_encode_time_ms(0),
+          encode_usage_percent(0),
           media_bitrate_bps(0),
           suspended(false) {}
     int input_frame_rate;
     int encode_frame_rate;
+    int avg_encode_time_ms;
+    int encode_usage_percent;
     int media_bitrate_bps;
     bool suspended;
     std::map<uint32_t, StreamStats> substreams;