Wire up preferred/nominal_bitrate to stats.

Also adds a test that shows that actual_enc_bitrate was not summed
correctly plus fixing it.

Additionally reducing locking when grabbing stats.

BUG=1778
R=stefan@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#8464}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8464 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index 7658986..781acf6 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -1732,19 +1732,41 @@
 VideoSenderInfo
 WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() {
   VideoSenderInfo info;
-  rtc::CritScope cs(&lock_);
-  for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) {
-    info.add_ssrc(parameters_.config.rtp.ssrcs[i]);
-  }
+  webrtc::VideoSendStream::Stats stats;
+  {
+    rtc::CritScope cs(&lock_);
+    for (uint32_t ssrc : parameters_.config.rtp.ssrcs)
+      info.add_ssrc(ssrc);
 
-  if (stream_ == NULL) {
-    return info;
-  }
+    for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) {
+      if (i == parameters_.encoder_config.streams.size() - 1) {
+        info.preferred_bitrate +=
+            parameters_.encoder_config.streams[i].max_bitrate_bps;
+      } else {
+        info.preferred_bitrate +=
+            parameters_.encoder_config.streams[i].target_bitrate_bps;
+      }
+    }
 
-  webrtc::VideoSendStream::Stats stats = stream_->GetStats();
+    if (stream_ == NULL)
+      return info;
+
+    stats = stream_->GetStats();
+
+    if (capturer_ != NULL && !capturer_->IsMuted()) {
+      VideoFormat last_captured_frame_format;
+      capturer_->GetStats(&info.adapt_frame_drops, &info.effects_frame_drops,
+                          &info.capturer_frame_time,
+                          &last_captured_frame_format);
+      info.input_frame_width = last_captured_frame_format.width;
+      info.input_frame_height = last_captured_frame_format.height;
+    }
+  }
   info.framerate_input = stats.input_frame_rate;
   info.framerate_sent = stats.encode_frame_rate;
 
+  info.nominal_bitrate = stats.media_bitrate_bps;
+
   info.send_frame_width = 0;
   info.send_frame_height = 0;
   for (std::map<uint32_t, webrtc::SsrcStats>::iterator it =
@@ -1775,19 +1797,6 @@
         (1 << 8);
   }
 
-  if (capturer_ != NULL && !capturer_->IsMuted()) {
-    VideoFormat last_captured_frame_format;
-    capturer_->GetStats(&info.adapt_frame_drops,
-                        &info.effects_frame_drops,
-                        &info.capturer_frame_time,
-                        &last_captured_frame_format);
-    info.input_frame_width = last_captured_frame_format.width;
-    info.input_frame_height = last_captured_frame_format.height;
-  }
-
-  // TODO(pbos): Support or remove the following stats.
-  info.packets_cached = -1;
-
   return info;
 }
 
@@ -1805,7 +1814,7 @@
     bwe_info->transmit_bitrate += it->second.total_bitrate_bps;
     bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps;
   }
-  bwe_info->actual_enc_bitrate = stats.media_bitrate_bps;
+  bwe_info->actual_enc_bitrate += stats.media_bitrate_bps;
 }
 
 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnCpuResolutionRequest(
@@ -2041,9 +2050,6 @@
   info.plis_sent = stats.rtcp_packet_type_counts.pli_packets;
   info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets;
 
-  // TODO(pbos): Support or remove the following stats.
-  info.packets_concealed = -1;
-
   return info;
 }
 
diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
index 7dc7693..be19833 100644
--- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -2112,6 +2112,40 @@
   EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
 }
 
+TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
+  FakeVideoSendStream* stream = AddSendStream();
+  webrtc::VideoSendStream::Stats stats;
+  stats.media_bitrate_bps = 123;
+  stats.substreams[17].total_bitrate_bps = 1;
+  stats.substreams[17].retransmit_bitrate_bps = 2;
+  stats.substreams[42].total_bitrate_bps = 3;
+  stats.substreams[42].retransmit_bitrate_bps = 4;
+  stream->SetStats(stats);
+
+  FakeVideoSendStream* stream2 = AddSendStream();
+  webrtc::VideoSendStream::Stats stats2;
+  stats2.media_bitrate_bps = 321;
+  stats2.substreams[13].total_bitrate_bps = 5;
+  stats2.substreams[13].retransmit_bitrate_bps = 6;
+  stats2.substreams[21].total_bitrate_bps = 7;
+  stats2.substreams[21].retransmit_bitrate_bps = 8;
+  stream2->SetStats(stats2);
+
+  cricket::VideoMediaInfo info;
+  ASSERT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
+  ASSERT_EQ(2u, info.senders.size());
+  // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
+  // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
+  EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
+  EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
+  EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
+            info.bw_estimations[0].actual_enc_bitrate);
+  EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)
+      << "Bandwidth stats should take all streams into account.";
+  EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate)
+      << "Bandwidth stats should take all streams into account.";
+}
+
 class WebRtcVideoEngine2SimulcastTest : public testing::Test {
  public:
   WebRtcVideoEngine2SimulcastTest()
@@ -2211,6 +2245,7 @@
     ASSERT_EQ(expected_streams.size(), video_streams.size());
 
     size_t num_streams = video_streams.size();
+    int total_max_bitrate_bps = 0;
     for (size_t i = 0; i < num_streams; ++i) {
       EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
       EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
@@ -2237,7 +2272,18 @@
       EXPECT_FALSE(expected_streams[i].temporal_layer_thresholds_bps.empty());
       EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
                 video_streams[i].temporal_layer_thresholds_bps);
+
+      if (i == num_streams - 1) {
+        total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
+      } else {
+        total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
+      }
     }
+    cricket::VideoMediaInfo info;
+    ASSERT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
+    ASSERT_EQ(1u, info.senders.size());
+    EXPECT_EQ(total_max_bitrate_bps, info.senders[0].preferred_bitrate);
+
     EXPECT_TRUE(channel_->SetCapturer(ssrcs.front(), NULL));
   }