Don't increment timestamp on drop/reencode in LibvpxVp8Encoder.

I don't think this has any impact, just wanted to have a first unit
test to play around with.

Bug: None
Change-Id: I892e2642f0243c5c9ee807cf71abcd96112b25f4
Reviewed-on: https://webrtc-review.googlesource.com/c/105000
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25089}
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 82ac132..e97f4c8 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -723,6 +723,7 @@
     }
 
     deps = [
+      ":mock_headers",
       ":video_codecs_test_framework",
       ":video_coding_utility",
       ":videocodec_test_impl",
@@ -778,6 +779,10 @@
       # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
       suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
     }
+
+    if (rtc_build_libvpx) {
+      deps += [ rtc_libvpx_dir ]
+    }
   }
 
   rtc_source_set("video_coding_unittests") {
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
index 41dad40..06b2b22 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
@@ -831,10 +831,11 @@
     }
     if (error)
       return WEBRTC_VIDEO_CODEC_ERROR;
-    timestamp_ += duration;
     // Examines frame timestamps only.
     error = GetEncodedPartitions(frame);
   }
+  // TODO(sprang): Shouldn't we use the frame timestamp instead?
+  timestamp_ += duration;
   return error;
 }
 
diff --git a/modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h b/modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h
index 5804e81..dcff1e6 100644
--- a/modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h
+++ b/modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h
@@ -32,7 +32,7 @@
                                   unsigned int,
                                   unsigned int,
                                   unsigned char*));
-  MOCK_CONST_METHOD1(img_free, vpx_codec_err_t(const vpx_codec_enc_cfg_t*));
+  MOCK_CONST_METHOD1(img_free, void(vpx_image_t* img));
   MOCK_CONST_METHOD2(codec_enc_config_set,
                      vpx_codec_err_t(vpx_codec_ctx_t*,
                                      const vpx_codec_enc_cfg_t*));
@@ -84,7 +84,7 @@
                                      uint64_t,
                                      vpx_enc_frame_flags_t,
                                      uint64_t));
-  MOCK_CONST_METHOD3(codec_get_cx_data,
+  MOCK_CONST_METHOD2(codec_get_cx_data,
                      const vpx_codec_cx_pkt_t*(vpx_codec_ctx_t*,
                                                vpx_codec_iter_t*));
 };
diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
index 45a090d..23f1416 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -16,12 +16,20 @@
 #include "modules/video_coding/codecs/test/video_codec_unittest.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
 #include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
+#include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
+#include "modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h"
+#include "modules/video_coding/include/mock/mock_video_codec_interface.h"
 #include "modules/video_coding/utility/vp8_header_parser.h"
 #include "rtc_base/timeutils.h"
 #include "test/video_codec_settings.h"
 
 namespace webrtc {
 
+using testing::Invoke;
+using testing::NiceMock;
+using testing::Return;
+using testing::_;
+
 namespace {
 constexpr uint32_t kInitialTimestampRtp = 123;
 constexpr int64_t kTestNtpTimeMs = 456;
@@ -380,4 +388,41 @@
   EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
 }
 
+TEST_F(TestVp8Impl, KeepsTimestampOnReencode) {
+  auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
+  LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
+
+  // Settings needed to trigger ScreenshareLayers usage, which is required for
+  // overshoot-drop-reencode logic.
+  codec_settings_.targetBitrate = 200;
+  codec_settings_.maxBitrate = 1000;
+  codec_settings_.mode = VideoCodecMode::kScreensharing;
+  codec_settings_.VP8()->numberOfTemporalLayers = 2;
+
+  EXPECT_CALL(*vpx, img_wrap(_, _, _, _, _, _))
+      .WillOnce(Invoke([](vpx_image_t* img, vpx_img_fmt_t fmt, unsigned int d_w,
+                          unsigned int d_h, unsigned int stride_align,
+                          unsigned char* img_data) {
+        img->fmt = fmt;
+        img->d_w = d_w;
+        img->d_h = d_h;
+        img->img_data = img_data;
+        return img;
+      }));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            encoder.InitEncode(&codec_settings_, 1, 1000));
+  MockEncodedImageCallback callback;
+  encoder.RegisterEncodeCompleteCallback(&callback);
+
+  // Simulate overshoot drop, re-encode: encode function will be called twice
+  // with the same parameters. codec_get_cx_data() will by default return no
+  // image data and be interpreted as drop.
+  EXPECT_CALL(*vpx, codec_encode(_, _, /* pts = */ 0, _, _, _))
+      .Times(2)
+      .WillRepeatedly(Return(vpx_codec_err_t::VPX_CODEC_OK));
+
+  auto delta_frame = std::vector<FrameType>{kVideoFrameDelta};
+  encoder.Encode(*NextInputFrame(), nullptr, &delta_frame);
+}
+
 }  // namespace webrtc