Added A/V sync tests with drifting clocks.
adding 30% drift to media generator (e.g. audio frame generated every 7ms instead of promised 10ms) works fine
adding 2% drift to video ntp-timestamp-stamper makes A/V sync fail.

BUG=webrtc:5504
R=pbos@webrtc.org,stefan@webrtc.org

Review URL: https://codereview.webrtc.org/1674413004

Cr-Original-Commit-Position: refs/heads/master@{#11556}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 9c6a0c7f6dc4446431f5138170cc95751ee5af8b
diff --git a/test/call_test.cc b/test/call_test.cc
index e9651e3..a0b5234 100644
--- a/test/call_test.cc
+++ b/test/call_test.cc
@@ -236,6 +236,14 @@
   }
 }
 
+void CallTest::CreateFrameGeneratorCapturerWithDrift(Clock* clock,
+                                                     float speed) {
+  VideoStream stream = video_encoder_config_.streams.back();
+  frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
+      video_send_stream_->Input(), stream.width, stream.height,
+      stream.max_framerate * speed, clock));
+}
+
 void CallTest::CreateFrameGeneratorCapturer() {
   VideoStream stream = video_encoder_config_.streams.back();
   frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
@@ -245,9 +253,11 @@
 
 void CallTest::CreateFakeAudioDevices() {
   fake_send_audio_device_.reset(new FakeAudioDevice(
-      clock_, test::ResourcePath("voice_engine/audio_long16", "pcm")));
+      clock_, test::ResourcePath("voice_engine/audio_long16", "pcm"),
+      DriftingClock::kNoDrift));
   fake_recv_audio_device_.reset(new FakeAudioDevice(
-      clock_, test::ResourcePath("voice_engine/audio_long16", "pcm")));
+      clock_, test::ResourcePath("voice_engine/audio_long16", "pcm"),
+      DriftingClock::kNoDrift));
 }
 
 void CallTest::CreateVideoStreams() {
diff --git a/test/call_test.h b/test/call_test.h
index 251d7f6..327253d 100644
--- a/test/call_test.h
+++ b/test/call_test.h
@@ -71,6 +71,7 @@
                         Transport* send_transport);
   void CreateMatchingReceiveConfigs(Transport* rtcp_send_transport);
 
+  void CreateFrameGeneratorCapturerWithDrift(Clock* drift_clock, float speed);
   void CreateFrameGeneratorCapturer();
   void CreateFakeAudioDevices();
 
diff --git a/test/drifting_clock.cc b/test/drifting_clock.cc
new file mode 100644
index 0000000..76f1723
--- /dev/null
+++ b/test/drifting_clock.cc
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/test/drifting_clock.h"
+#include "webrtc/base/checks.h"
+
+namespace webrtc {
+namespace test {
+const float DriftingClock::kDoubleSpeed = 2.0f;
+const float DriftingClock::kNoDrift = 1.0f;
+const float DriftingClock::kHalfSpeed = 0.5f;
+
+DriftingClock::DriftingClock(Clock* clock, float speed)
+    : clock_(clock),
+      drift_(speed - 1.0f),
+      start_time_(clock_->TimeInMicroseconds()) {
+  RTC_CHECK(clock);
+  RTC_CHECK_GT(speed, 0.0f);
+}
+
+float DriftingClock::Drift() const {
+  int64_t now = clock_->TimeInMicroseconds();
+  RTC_DCHECK_GE(now, start_time_);
+  return (now - start_time_) * drift_;
+}
+
+int64_t DriftingClock::TimeInMilliseconds() const {
+  return clock_->TimeInMilliseconds() + Drift() / 1000.;
+}
+
+int64_t DriftingClock::TimeInMicroseconds() const {
+  return clock_->TimeInMicroseconds() + Drift();
+}
+
+void DriftingClock::CurrentNtp(uint32_t& seconds, uint32_t& fractions) const {
+  // NTP precision is 1/2^32 seconds, i.e. 2^32 ntp fractions = 1 second.
+  const double kNtpFracPerMicroSecond = 4294.967296;  // = 2^32 / 10^6
+
+  clock_->CurrentNtp(seconds, fractions);
+  uint64_t total_fractions = (static_cast<uint64_t>(seconds) << 32) | fractions;
+  total_fractions += Drift() * kNtpFracPerMicroSecond;
+  seconds = total_fractions >> 32;
+  fractions = static_cast<uint32_t>(total_fractions);
+}
+
+int64_t DriftingClock::CurrentNtpInMilliseconds() const {
+  return clock_->CurrentNtpInMilliseconds() + Drift() / 1000.;
+}
+}  // namespace test
+}  // namespace webrtc
diff --git a/test/drifting_clock.h b/test/drifting_clock.h
new file mode 100644
index 0000000..d434186
--- /dev/null
+++ b/test/drifting_clock.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef WEBRTC_TEST_DRIFTING_CLOCK_H_
+#define WEBRTC_TEST_DRIFTING_CLOCK_H_
+
+#include "webrtc/system_wrappers/include/clock.h"
+
+namespace webrtc {
+namespace test {
+class DriftingClock : public Clock {
+ public:
+  // TODO(danilchap): Make this constants constexpr when it would be supported.
+  static const float kDoubleSpeed;  // 2.0f;
+  static const float kNoDrift;      // 1.0f;
+  static const float kHalfSpeed;    // 0.5f;
+
+  DriftingClock(Clock* clock, float speed);
+
+  // TODO(danilchap): Make this functions constexpr when it would be supported.
+  static float PercentsFaster(float percent) { return 1.0f + percent / 100.0f; }
+  static float PercentsSlower(float percent) { return 1.0f - percent / 100.0f; }
+
+  int64_t TimeInMilliseconds() const override;
+  int64_t TimeInMicroseconds() const override;
+  void CurrentNtp(uint32_t& seconds, uint32_t& fractions) const override;
+  int64_t CurrentNtpInMilliseconds() const override;
+
+ private:
+  float Drift() const;
+
+  Clock* const clock_;
+  const float drift_;
+  const int64_t start_time_;
+};
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // WEBRTC_TEST_DRIFTING_CLOCK_H_
diff --git a/test/fake_audio_device.cc b/test/fake_audio_device.cc
index 31cebda..435c53f 100644
--- a/test/fake_audio_device.cc
+++ b/test/fake_audio_device.cc
@@ -22,13 +22,16 @@
 namespace webrtc {
 namespace test {
 
-FakeAudioDevice::FakeAudioDevice(Clock* clock, const std::string& filename)
+FakeAudioDevice::FakeAudioDevice(Clock* clock,
+                                 const std::string& filename,
+                                 float speed)
     : audio_callback_(NULL),
       capturing_(false),
       captured_audio_(),
       playout_buffer_(),
+      speed_(speed),
       last_playout_ms_(-1),
-      clock_(clock),
+      clock_(clock, speed),
       tick_(EventTimerWrapper::Create()),
       thread_(FakeAudioDevice::Run, this, "FakeAudioDevice"),
       file_utility_(new ModuleFileUtility(0)),
@@ -51,7 +54,7 @@
   if (file_utility_->InitPCMReading(*input_stream_.get()) != 0)
     return -1;
 
-  if (!tick_->StartTimer(true, 10))
+  if (!tick_->StartTimer(true, 10 / speed_))
     return -1;
   thread_.Start();
   thread_.SetPriority(rtc::kHighPriority);
@@ -107,7 +110,7 @@
                                                          false,
                                                          new_mic_level));
       size_t samples_needed = kFrequencyHz / 100;
-      int64_t now_ms = clock_->TimeInMilliseconds();
+      int64_t now_ms = clock_.TimeInMilliseconds();
       uint32_t time_since_last_playout_ms = now_ms - last_playout_ms_;
       if (last_playout_ms_ > 0 && time_since_last_playout_ms > 0) {
         samples_needed = std::min(
diff --git a/test/fake_audio_device.h b/test/fake_audio_device.h
index ce480c1..180abf6 100644
--- a/test/fake_audio_device.h
+++ b/test/fake_audio_device.h
@@ -16,6 +16,7 @@
 #include "webrtc/base/platform_thread.h"
 #include "webrtc/base/scoped_ptr.h"
 #include "webrtc/modules/audio_device/include/fake_audio_device.h"
+#include "webrtc/test/drifting_clock.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
@@ -29,7 +30,7 @@
 
 class FakeAudioDevice : public FakeAudioDeviceModule {
  public:
-  FakeAudioDevice(Clock* clock, const std::string& filename);
+  FakeAudioDevice(Clock* clock, const std::string& filename, float speed);
 
   virtual ~FakeAudioDevice();
 
@@ -54,9 +55,10 @@
   bool capturing_;
   int8_t captured_audio_[kBufferSizeBytes];
   int8_t playout_buffer_[kBufferSizeBytes];
+  const float speed_;
   int64_t last_playout_ms_;
 
-  Clock* clock_;
+  DriftingClock clock_;
   rtc::scoped_ptr<EventTimerWrapper> tick_;
   rtc::CriticalSection lock_;
   rtc::PlatformThread thread_;
diff --git a/test/webrtc_test_common.gyp b/test/webrtc_test_common.gyp
index 07ea2c9..318f5bb 100644
--- a/test/webrtc_test_common.gyp
+++ b/test/webrtc_test_common.gyp
@@ -22,6 +22,8 @@
         'constants.h',
         'direct_transport.cc',
         'direct_transport.h',
+        'drifting_clock.cc',
+        'drifting_clock.h',
         'encoder_settings.cc',
         'encoder_settings.h',
         'fake_audio_device.cc',