RTCMediaStreamTrackStats.framesReceived collected by RTCStatsCollector.

VideoReceiverInfo::frames_received added based on
VideoReceiveStream::Stats::frame_counts (.key_frames + .delta_frames).

BUG=webrtc:6757, chromium:659137, chromium:627816

Review-Url: https://codereview.webrtc.org/2607913002
Cr-Commit-Position: refs/heads/master@{#16185}
diff --git a/webrtc/api/rtcstats_integrationtest.cc b/webrtc/api/rtcstats_integrationtest.cc
index 33b1436..5ded447 100644
--- a/webrtc/api/rtcstats_integrationtest.cc
+++ b/webrtc/api/rtcstats_integrationtest.cc
@@ -439,7 +439,12 @@
           media_stream_track.frame_height);
       verifier.TestMemberIsUndefined(media_stream_track.frames_per_second);
       verifier.TestMemberIsUndefined(media_stream_track.frames_sent);
-      verifier.TestMemberIsUndefined(media_stream_track.frames_received);
+      if (*media_stream_track.remote_source) {
+        verifier.TestMemberIsNonNegative<uint32_t>(
+            media_stream_track.frames_received);
+      } else {
+        verifier.TestMemberIsUndefined(media_stream_track.frames_received);
+      }
       verifier.TestMemberIsUndefined(media_stream_track.frames_decoded);
       verifier.TestMemberIsUndefined(media_stream_track.frames_dropped);
       verifier.TestMemberIsUndefined(media_stream_track.frames_corrupted);
@@ -451,6 +456,8 @@
       verifier.TestMemberIsUndefined(
           media_stream_track.echo_return_loss_enhancement);
     } else {
+      RTC_DCHECK_EQ(*media_stream_track.kind,
+                    RTCMediaStreamTrackKind::kAudio);
       // Video-only members should be undefined
       verifier.TestMemberIsUndefined(media_stream_track.frame_width);
       verifier.TestMemberIsUndefined(media_stream_track.frame_height);
diff --git a/webrtc/api/rtcstatscollector.cc b/webrtc/api/rtcstatscollector.cc
index 216a5ac..5d78273 100644
--- a/webrtc/api/rtcstatscollector.cc
+++ b/webrtc/api/rtcstatscollector.cc
@@ -436,6 +436,7 @@
     video_track_stats->frame_height = static_cast<uint32_t>(
         video_receiver_info.frame_height);
   }
+  video_track_stats->frames_received = video_receiver_info.frames_received;
   return video_track_stats;
 }
 
diff --git a/webrtc/api/rtcstatscollector_unittest.cc b/webrtc/api/rtcstatscollector_unittest.cc
index cf6dcf6..83d9fc8 100644
--- a/webrtc/api/rtcstatscollector_unittest.cc
+++ b/webrtc/api/rtcstatscollector_unittest.cc
@@ -1540,6 +1540,7 @@
   video_receiver_info_ssrc3.local_stats[0].ssrc = 3;
   video_receiver_info_ssrc3.frame_width = 6789;
   video_receiver_info_ssrc3.frame_height = 9876;
+  video_receiver_info_ssrc3.frames_received = 2468;
 
   // Remote video track with undefined (default) values
   rtc::scoped_refptr<MediaStreamTrackInterface> remote_video_track_ssrc4 =
@@ -1553,6 +1554,7 @@
   video_receiver_info_ssrc4.local_stats[0].ssrc = 4;
   video_receiver_info_ssrc4.frame_width = 0;
   video_receiver_info_ssrc4.frame_height = 0;
+  video_receiver_info_ssrc4.frames_received = 0;
 
   test_->CreateMockRtpSendersReceiversAndChannels(
       {}, {},
@@ -1625,6 +1627,7 @@
   expected_remote_video_track_ssrc3.detached = false;
   expected_remote_video_track_ssrc3.frame_width = 6789;
   expected_remote_video_track_ssrc3.frame_height = 9876;
+  expected_remote_video_track_ssrc3.frames_received = 2468;
   ASSERT_TRUE(report->Get(expected_remote_video_track_ssrc3.id()));
   EXPECT_EQ(expected_remote_video_track_ssrc3,
             report->Get(expected_remote_video_track_ssrc3.id())->cast_to<
@@ -1638,6 +1641,7 @@
   expected_remote_video_track_ssrc4.remote_source = true;
   expected_remote_video_track_ssrc4.ended = false;
   expected_remote_video_track_ssrc4.detached = false;
+  expected_remote_video_track_ssrc4.frames_received = 0;
   // Should be undefined: |expected_remote_video_track_ssrc4.frame_width| and
   // |expected_remote_video_track_ssrc4.frame_height|.
   ASSERT_TRUE(report->Get(expected_remote_video_track_ssrc4.id()));
diff --git a/webrtc/api/stats/rtcstats_objects.h b/webrtc/api/stats/rtcstats_objects.h
index e8a1842..e8b0170 100644
--- a/webrtc/api/stats/rtcstats_objects.h
+++ b/webrtc/api/stats/rtcstats_objects.h
@@ -267,7 +267,6 @@
   RTCStatsMember<double> frames_per_second;
   // TODO(hbos): Not collected by |RTCStatsCollector|. crbug.com/659137
   RTCStatsMember<uint32_t> frames_sent;
-  // TODO(hbos): Not collected by |RTCStatsCollector|. crbug.com/659137
   RTCStatsMember<uint32_t> frames_received;
   // TODO(hbos): Not collected by |RTCStatsCollector|. crbug.com/659137
   RTCStatsMember<uint32_t> frames_decoded;
diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h
index 70d6268..ecff95a 100644
--- a/webrtc/media/base/mediachannel.h
+++ b/webrtc/media/base/mediachannel.h
@@ -749,6 +749,7 @@
         framerate_output(0),
         framerate_render_input(0),
         framerate_render_output(0),
+        frames_received(0),
         frames_decoded(0),
         decode_ms(0),
         max_decode_ms(0),
@@ -776,6 +777,7 @@
   int framerate_render_input;
   // Framerate that the renderer reports.
   int framerate_render_output;
+  uint32_t frames_received;
   uint32_t frames_decoded;
 
   // All stats below are gathered per-VideoReceiver, but some will be correlated
diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc
index b0d3b89..da045ec 100644
--- a/webrtc/media/engine/webrtcvideoengine2.cc
+++ b/webrtc/media/engine/webrtcvideoengine2.cc
@@ -2383,6 +2383,8 @@
   info.jitter_buffer_ms = stats.jitter_buffer_ms;
   info.min_playout_delay_ms = stats.min_playout_delay_ms;
   info.render_delay_ms = stats.render_delay_ms;
+  info.frames_received = stats.frame_counts.key_frames +
+                         stats.frame_counts.delta_frames;
   info.frames_decoded = stats.frames_decoded;
 
   info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type);
diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc
index bf01767..4667ea8 100644
--- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc
+++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc
@@ -3301,7 +3301,9 @@
   stats.render_delay_ms = 8;
   stats.width = 9;
   stats.height = 10;
-  stats.frames_decoded = 11;
+  stats.frame_counts.key_frames = 11;
+  stats.frame_counts.delta_frames = 12;
+  stats.frames_decoded = 13;
   stream->SetStats(stats);
 
   cricket::VideoMediaInfo info;
@@ -3317,6 +3319,8 @@
   EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
   EXPECT_EQ(stats.width, info.receivers[0].frame_width);
   EXPECT_EQ(stats.height, info.receivers[0].frame_height);
+  EXPECT_EQ(stats.frame_counts.key_frames + stats.frame_counts.delta_frames,
+            info.receivers[0].frames_received);
   EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
 }