Add histogram for percentage of sent frames that are limited in resolution due to bandwidth:
- "WebRTC.Video.BandwidthLimitedResolutionInPercent"

If the frame is bandwidth limited, the average number of disabled resolutions is logged:
- "WebRTC.Video.BandwidthLimitedResolutionsDisabled"

BUG=

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

Cr-Commit-Position: refs/heads/master@{#10333}
diff --git a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc
index d6f36f2..6ac840e 100644
--- a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc
+++ b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc
@@ -131,6 +131,15 @@
   }
   return true;
 }
+
+int NumStreamsDisabled(std::vector<bool>& streams) {
+  int num_disabled = 0;
+  for (bool stream : streams) {
+    if (!stream)
+      ++num_disabled;
+  }
+  return num_disabled;
+}
 }  // namespace
 
 const float kTl1MaxTimeToDropFrames = 20.0f;
@@ -951,6 +960,9 @@
 
 int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image,
                                          bool only_predicting_from_key_frame) {
+  int bw_resolutions_disabled =
+      (encoders_.size() > 1) ? NumStreamsDisabled(send_stream_) : -1;
+
   int stream_idx = static_cast<int>(encoders_.size()) - 1;
   int result = WEBRTC_VIDEO_CODEC_OK;
   for (size_t encoder_idx = 0; encoder_idx < encoders_.size();
@@ -1018,6 +1030,9 @@
         encoded_images_[encoder_idx]
             .adapt_reason_.quality_resolution_downscales =
             quality_scaler_enabled_ ? quality_scaler_.downscale_shift() : -1;
+        // Report once per frame (lowest stream always sent).
+        encoded_images_[encoder_idx].adapt_reason_.bw_resolutions_disabled =
+            (stream_idx == 0) ? bw_resolutions_disabled : -1;
         encoded_complete_callback_->Encoded(encoded_images_[encoder_idx],
                                             &codec_specific, &frag_info);
       } else if (codec_.mode == kScreensharing) {
diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc
index 00edd06..32b7902 100644
--- a/webrtc/video/send_statistics_proxy.cc
+++ b/webrtc/video/send_statistics_proxy.cc
@@ -81,6 +81,16 @@
     RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.QualityLimitedResolutionDownscales",
                               downscales, 20);
   }
+  int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples);
+  if (bw_limited != -1) {
+    RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BandwidthLimitedResolutionInPercent",
+        bw_limited);
+  }
+  int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples);
+  if (num_disabled != -1) {
+    RTC_HISTOGRAM_ENUMERATION(
+        "WebRTC.Video.BandwidthLimitedResolutionsDisabled", num_disabled, 10);
+  }
 }
 
 void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) {
@@ -190,6 +200,14 @@
           encoded_image.adapt_reason_.quality_resolution_downscales);
     }
   }
+  if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) {
+    bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
+    bw_limited_frame_counter_.Add(bw_limited);
+    if (bw_limited) {
+      bw_resolutions_disabled_counter_.Add(
+         encoded_image.adapt_reason_.bw_resolutions_disabled);
+    }
+  }
 
   // TODO(asapersson): This is incorrect if simulcast layers are encoded on
   // different threads and there is no guarantee that one frame of all layers
@@ -299,7 +317,7 @@
 int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
   if (num_samples < min_required_samples || num_samples == 0)
     return -1;
-  return sum / num_samples;
+  return (sum + (num_samples / 2)) / num_samples;
 }
 
 void SendStatisticsProxy::BoolSampleCounter::Add(bool sample) {
diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h
index cd2327e..7451bb5 100644
--- a/webrtc/video/send_statistics_proxy.h
+++ b/webrtc/video/send_statistics_proxy.h
@@ -87,8 +87,10 @@
                             uint32_t ssrc) override;
 
  private:
-  struct SampleCounter {
+  class SampleCounter {
+   public:
     SampleCounter() : sum(0), num_samples(0) {}
+    ~SampleCounter() {}
     void Add(int sample);
     int Avg(int min_required_samples) const;
 
@@ -96,8 +98,10 @@
     int sum;
     int num_samples;
   };
-  struct BoolSampleCounter {
+  class BoolSampleCounter {
+   public:
     BoolSampleCounter() : sum(0), num_samples(0) {}
+    ~BoolSampleCounter() {}
     void Add(bool sample);
     int Percent(int min_required_samples) const;
     int Permille(int min_required_samples) const;
@@ -136,6 +140,8 @@
   BoolSampleCounter key_frame_counter_ GUARDED_BY(crit_);
   BoolSampleCounter quality_limited_frame_counter_ GUARDED_BY(crit_);
   SampleCounter quality_downscales_counter_ GUARDED_BY(crit_);
+  BoolSampleCounter bw_limited_frame_counter_ GUARDED_BY(crit_);
+  SampleCounter bw_resolutions_disabled_counter_ GUARDED_BY(crit_);
 };
 
 }  // namespace webrtc
diff --git a/webrtc/video_frame.h b/webrtc/video_frame.h
index 1968a69..821bfc2 100644
--- a/webrtc/video_frame.h
+++ b/webrtc/video_frame.h
@@ -167,6 +167,7 @@
   VideoRotation rotation_;
 };
 
+
 // TODO(pbos): Rename EncodedFrame and reformat this class' members.
 class EncodedImage {
  public:
@@ -176,11 +177,15 @@
 
   struct AdaptReason {
     AdaptReason()
-        : quality_resolution_downscales(-1) {}
+        : quality_resolution_downscales(-1),
+          bw_resolutions_disabled(-1) {}
 
     int quality_resolution_downscales;  // Number of times this frame is down
                                         // scaled in resolution due to quality.
                                         // Or -1 if information is not provided.
+    int bw_resolutions_disabled;  // Number of resolutions that are not sent
+                                  // due to bandwidth for this frame.
+                                  // Or -1 if information is not provided.
   };
   uint32_t _encodedWidth = 0;
   uint32_t _encodedHeight = 0;