Clear bitrate stats for unused SSRCs.

Prevents bug where transmitted bitrate was reported as higher than what
was actually sent, since unused RTP modules weren't updated to say that
they sent zero.

BUG=
R=stefan@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#9192}
diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc
index 6330719..a6cb5b3 100644
--- a/webrtc/video/send_statistics_proxy.cc
+++ b/webrtc/video/send_statistics_proxy.cc
@@ -58,17 +58,15 @@
 }
 
 void SendStatisticsProxy::PurgeOldStats() {
-  int64_t current_time_ms = clock_->TimeInMilliseconds();
+  int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs;
   for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
            stats_.substreams.begin();
        it != stats_.substreams.end(); ++it) {
     uint32_t ssrc = it->first;
-    if (update_times_[ssrc].resolution_update_ms + kStatsTimeoutMs >
-        current_time_ms)
-      continue;
-
-    it->second.width = 0;
-    it->second.height = 0;
+    if (update_times_[ssrc].resolution_update_ms <= old_stats_ms) {
+      it->second.width = 0;
+      it->second.height = 0;
+    }
   }
 }
 
@@ -90,6 +88,18 @@
   return &stats_.substreams[ssrc];  // Insert new entry and return ptr.
 }
 
+void SendStatisticsProxy::OnInactiveSsrc(uint32_t ssrc) {
+  rtc::CritScope lock(&crit_);
+  VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
+  if (stats == nullptr)
+    return;
+
+  stats->total_bitrate_bps = 0;
+  stats->retransmit_bitrate_bps = 0;
+  stats->height = 0;
+  stats->width = 0;
+}
+
 void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
   rtc::CritScope lock(&crit_);
   stats_.target_media_bitrate_bps = bitrate_bps;
diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h
index 6dc4a8a..4aa74f3 100644
--- a/webrtc/video/send_statistics_proxy.h
+++ b/webrtc/video/send_statistics_proxy.h
@@ -52,6 +52,8 @@
   // From VideoEncoderRateObserver.
   void OnSetRates(uint32_t bitrate_bps, int framerate) override;
 
+  void OnInactiveSsrc(uint32_t ssrc);
+
  protected:
   // From CpuOveruseMetricsObserver.
   void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) override;
@@ -91,6 +93,7 @@
   struct StatsUpdateTimes {
     StatsUpdateTimes() : resolution_update_ms(0) {}
     int64_t resolution_update_ms;
+    int64_t bitrate_update_ms;
   };
   void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
   VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
diff --git a/webrtc/video/send_statistics_proxy_unittest.cc b/webrtc/video/send_statistics_proxy_unittest.cc
index 0243add..b808865 100644
--- a/webrtc/video/send_statistics_proxy_unittest.cc
+++ b/webrtc/video/send_statistics_proxy_unittest.cc
@@ -364,4 +364,44 @@
   EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
 }
 
+TEST_F(SendStatisticsProxyTest, ClearsResolutionFromInactiveSsrcs) {
+  static const int kEncodedWidth = 123;
+  static const int kEncodedHeight = 81;
+  EncodedImage encoded_image;
+  encoded_image._encodedWidth = kEncodedWidth;
+  encoded_image._encodedHeight = kEncodedHeight;
+
+  RTPVideoHeader rtp_video_header;
+
+  rtp_video_header.simulcastIdx = 0;
+  statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
+  rtp_video_header.simulcastIdx = 1;
+  statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
+
+  statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
+  VideoSendStream::Stats stats = statistics_proxy_->GetStats();
+  EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
+  EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
+  EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].width);
+  EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].height);
+}
+
+TEST_F(SendStatisticsProxyTest, ClearsBitratesFromInactiveSsrcs) {
+  BitrateStatistics bitrate;
+  bitrate.bitrate_bps = 42;
+  BitrateStatisticsObserver* observer = statistics_proxy_.get();
+  observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[0]);
+  observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[1]);
+
+  statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
+
+  VideoSendStream::Stats stats = statistics_proxy_->GetStats();
+  EXPECT_EQ(static_cast<int>(bitrate.bitrate_bps),
+            stats.substreams[config_.rtp.ssrcs[0]].total_bitrate_bps);
+  EXPECT_EQ(static_cast<int>(bitrate.bitrate_bps),
+            stats.substreams[config_.rtp.ssrcs[0]].retransmit_bitrate_bps);
+  EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].total_bitrate_bps);
+  EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].retransmit_bitrate_bps);
+}
+
 }  // namespace webrtc
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 7b1bfae..8fc03c5 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -399,6 +399,12 @@
   if (!SetSendCodec(video_codec))
     return false;
 
+  // Clear stats for disabled layers.
+  for (size_t i = video_codec.numberOfSimulcastStreams;
+       i < config_.rtp.ssrcs.size(); ++i) {
+    stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]);
+  }
+
   DCHECK_GE(config.min_transmit_bitrate_bps, 0);
   vie_encoder_->SetMinTransmitBitrate(config.min_transmit_bitrate_bps / 1000);