Reland "Add fine grained dropped video frames counters on sending side"

Add fine grained dropped video frames counters on sending side

4 new counters added to SendStatisticsProxy and reported to UMA and logs.

Bug: webrtc:8355
Change-Id: I1f9bdfea9cbf17cf38b3cb2f55d406ffdb06614f
Reviewed-on: https://webrtc-review.googlesource.com/14580
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20421}
diff --git a/modules/video_coding/generic_encoder_unittest.cc b/modules/video_coding/generic_encoder_unittest.cc
index 90d3c05..9c879e3 100644
--- a/modules/video_coding/generic_encoder_unittest.cc
+++ b/modules/video_coding/generic_encoder_unittest.cc
@@ -27,7 +27,8 @@
 
 class FakeEncodedImageCallback : public EncodedImageCallback {
  public:
-  FakeEncodedImageCallback() : last_frame_was_timing_(false) {}
+  FakeEncodedImageCallback()
+      : last_frame_was_timing_(false), num_frames_dropped_(0) {}
   Result OnEncodedImage(const EncodedImage& encoded_image,
                         const CodecSpecificInfo* codec_specific_info,
                         const RTPFragmentationHeader* fragmentation) override {
@@ -36,10 +37,15 @@
     return Result(Result::OK);
   };
 
+  void OnDroppedFrame(DropReason reason) override { ++num_frames_dropped_; }
+
   bool WasTimingFrame() { return last_frame_was_timing_; }
 
+  size_t GetNumFramesDropped() { return num_frames_dropped_; }
+
  private:
   bool last_frame_was_timing_;
+  size_t num_frames_dropped_;
 };
 
 enum class FrameType {
@@ -190,5 +196,34 @@
   EXPECT_FALSE(sink.WasTimingFrame());
 }
 
+TEST(TestVCMEncodedFrameCallback, NotifiesAboutDroppedFrames) {
+  EncodedImage image;
+  CodecSpecificInfo codec_specific;
+  const int64_t timestamp1 = 100;
+  const int64_t timestamp2 = 110;
+  const int64_t timestamp3 = 120;
+  const int64_t timestamp4 = 130;
+  codec_specific.codecType = kVideoCodecGeneric;
+  codec_specific.codecSpecific.generic.simulcast_idx = 0;
+  FakeEncodedImageCallback sink;
+  VCMEncodedFrameCallback callback(&sink, nullptr);
+  callback.OnEncodeStarted(timestamp1, 0);
+  EXPECT_EQ(0u, sink.GetNumFramesDropped());
+  image.capture_time_ms_ = timestamp1;
+  callback.OnEncodedImage(image, &codec_specific, nullptr);
+  callback.OnEncodeStarted(timestamp2, 0);
+  // No OnEncodedImageCall for timestamp2. Yet, at this moment it's not known
+  // that frame with timestamp2 was dropped.
+  EXPECT_EQ(0u, sink.GetNumFramesDropped());
+  callback.OnEncodeStarted(timestamp3, 0);
+  image.capture_time_ms_ = timestamp3;
+  callback.OnEncodedImage(image, &codec_specific, nullptr);
+  EXPECT_EQ(1u, sink.GetNumFramesDropped());
+  callback.OnEncodeStarted(timestamp4, 0);
+  image.capture_time_ms_ = timestamp4;
+  callback.OnEncodedImage(image, &codec_specific, nullptr);
+  EXPECT_EQ(1u, sink.GetNumFramesDropped());
+}
+
 }  // namespace test
 }  // namespace webrtc