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',