Index: media/filters/audio_clock_unittest.cc |
diff --git a/media/filters/audio_clock_unittest.cc b/media/filters/audio_clock_unittest.cc |
index 303e8e34573bfe8eec4043de6fa804bcef542c7f..832b2a805de57e24e13dfbc107a1369264ec9068 100644 |
--- a/media/filters/audio_clock_unittest.cc |
+++ b/media/filters/audio_clock_unittest.cc |
@@ -3,6 +3,7 @@ |
// found in the LICENSE file. |
#include "base/macros.h" |
+#include "base/memory/scoped_ptr.h" |
#include "media/base/audio_timestamp_helper.h" |
#include "media/filters/audio_clock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -11,8 +12,7 @@ namespace media { |
class AudioClockTest : public testing::Test { |
public: |
- AudioClockTest() |
- : sample_rate_(10), clock_(base::TimeDelta(), sample_rate_) {} |
+ AudioClockTest() {} |
~AudioClockTest() override {} |
@@ -20,51 +20,61 @@ class AudioClockTest : public testing::Test { |
int frames_requested, |
int delay_frames, |
double playback_rate) { |
- clock_.WroteAudio( |
- frames_written, frames_requested, delay_frames, playback_rate); |
+ clock_->WroteAudio(frames_written, frames_requested, delay_frames, |
+ playback_rate); |
} |
- int FrontTimestampInDays() { return clock_.front_timestamp().InDays(); } |
+ void SetupClock() { SetupClock(base::TimeDelta(), 10); } |
+ |
+ void SetupClock(base::TimeDelta start_time, int sample_rate) { |
+ sample_rate_ = sample_rate; |
+ clock_.reset(new AudioClock(start_time, sample_rate_)); |
+ } |
+ |
+ int FrontTimestampInDays() { return clock_->front_timestamp().InDays(); } |
int FrontTimestampInMilliseconds() { |
- return clock_.front_timestamp().InMilliseconds(); |
+ return clock_->front_timestamp().InMilliseconds(); |
} |
int BackTimestampInMilliseconds() { |
- return clock_.back_timestamp().InMilliseconds(); |
+ return clock_->back_timestamp().InMilliseconds(); |
} |
int TimeUntilPlaybackInMilliseconds(int timestamp_ms) { |
- return clock_.TimeUntilPlayback(base::TimeDelta::FromMilliseconds( |
- timestamp_ms)).InMilliseconds(); |
+ return clock_ |
+ ->TimeUntilPlayback(base::TimeDelta::FromMilliseconds(timestamp_ms)) |
+ .InMilliseconds(); |
} |
int ContiguousAudioDataBufferedInDays() { |
base::TimeDelta total, same_rate_total; |
- clock_.ContiguousAudioDataBufferedForTesting(&total, &same_rate_total); |
+ clock_->ContiguousAudioDataBufferedForTesting(&total, &same_rate_total); |
return total.InDays(); |
} |
int ContiguousAudioDataBufferedInMilliseconds() { |
base::TimeDelta total, same_rate_total; |
- clock_.ContiguousAudioDataBufferedForTesting(&total, &same_rate_total); |
+ clock_->ContiguousAudioDataBufferedForTesting(&total, &same_rate_total); |
return total.InMilliseconds(); |
} |
int ContiguousAudioDataBufferedAtSameRateInMilliseconds() { |
base::TimeDelta total, same_rate_total; |
- clock_.ContiguousAudioDataBufferedForTesting(&total, &same_rate_total); |
+ clock_->ContiguousAudioDataBufferedForTesting(&total, &same_rate_total); |
return same_rate_total.InMilliseconds(); |
} |
- const int sample_rate_; |
- AudioClock clock_; |
+ int sample_rate_; |
+ scoped_ptr<AudioClock> clock_; |
private: |
DISALLOW_COPY_AND_ASSIGN(AudioClockTest); |
}; |
TEST_F(AudioClockTest, FrontTimestampStartsAtStartTimestamp) { |
+ SetupClock(); |
DaleCurtis
2016/02/18 01:48:33
Instead of having every method call this, just cal
chcunningham
2016/02/18 20:43:37
Done.
|
+ |
base::TimeDelta expected = base::TimeDelta::FromSeconds(123); |
AudioClock clock(expected, sample_rate_); |
@@ -72,6 +82,8 @@ TEST_F(AudioClockTest, FrontTimestampStartsAtStartTimestamp) { |
} |
TEST_F(AudioClockTest, BackTimestampStartsAtStartTimestamp) { |
+ SetupClock(); |
+ |
base::TimeDelta expected = base::TimeDelta::FromSeconds(123); |
AudioClock clock(expected, sample_rate_); |
@@ -79,6 +91,8 @@ TEST_F(AudioClockTest, BackTimestampStartsAtStartTimestamp) { |
} |
TEST_F(AudioClockTest, Playback) { |
+ SetupClock(); |
+ |
// The first time we write data we should still expect our start timestamp |
// due to delay. |
WroteAudio(10, 10, 20, 1.0); |
@@ -197,6 +211,8 @@ TEST_F(AudioClockTest, Playback) { |
} |
TEST_F(AudioClockTest, AlternatingAudioAndSilence) { |
+ SetupClock(); |
+ |
// Buffer #1: [0, 1000) |
WroteAudio(10, 10, 20, 1.0); |
EXPECT_EQ(0, FrontTimestampInMilliseconds()); |
@@ -233,6 +249,8 @@ TEST_F(AudioClockTest, AlternatingAudioAndSilence) { |
} |
TEST_F(AudioClockTest, ZeroDelay) { |
+ SetupClock(); |
+ |
// The first time we write data we should expect the first timestamp |
// immediately. |
WroteAudio(10, 10, 0, 1.0); |
@@ -264,6 +282,8 @@ TEST_F(AudioClockTest, ZeroDelay) { |
} |
TEST_F(AudioClockTest, TimeUntilPlayback) { |
+ SetupClock(); |
+ |
// Construct an audio clock with the following representation: |
// |
// existing |
@@ -296,6 +316,8 @@ TEST_F(AudioClockTest, TimeUntilPlayback) { |
} |
TEST_F(AudioClockTest, SupportsYearsWorthOfAudioData) { |
+ SetupClock(); |
+ |
// Use number of frames that would be likely to overflow 32-bit integer math. |
const int huge_amount_of_frames = std::numeric_limits<int>::max(); |
const base::TimeDelta huge = |
@@ -327,6 +349,8 @@ TEST_F(AudioClockTest, SupportsYearsWorthOfAudioData) { |
} |
TEST_F(AudioClockTest, CompensateForSuspendedWrites) { |
+ SetupClock(); |
+ |
// Buffer 6 seconds of delay and 1 second of audio data. |
WroteAudio(10, 10, 60, 1.0); |
@@ -337,8 +361,8 @@ TEST_F(AudioClockTest, CompensateForSuspendedWrites) { |
// Elapsing frames less than we have buffered should do nothing. |
const int kDelayFrames = 2; |
for (int i = 1000; i <= kBaseTimeMs; i += 1000) { |
- clock_.CompensateForSuspendedWrites(base::TimeDelta::FromMilliseconds(i), |
- kDelayFrames); |
+ clock_->CompensateForSuspendedWrites(base::TimeDelta::FromMilliseconds(i), |
+ kDelayFrames); |
EXPECT_EQ(kBaseTimeMs - (i - 1000), TimeUntilPlaybackInMilliseconds(0)); |
// Write silence to simulate maintaining a 7s output buffer. |
@@ -347,9 +371,28 @@ TEST_F(AudioClockTest, CompensateForSuspendedWrites) { |
// Exhausting all frames should advance timestamps and prime the buffer with |
// our delay frames value. |
- clock_.CompensateForSuspendedWrites(base::TimeDelta::FromMilliseconds(7000), |
- kDelayFrames); |
+ clock_->CompensateForSuspendedWrites(base::TimeDelta::FromMilliseconds(7000), |
+ kDelayFrames); |
EXPECT_EQ(kDelayFrames * 100, TimeUntilPlaybackInMilliseconds(1000)); |
} |
+TEST_F(AudioClockTest, FramesToTimePrecision) { |
+ SetupClock(base::TimeDelta(), 48000); |
+ int frames_written = 0; |
+ |
+ double micros_per_frame = |
+ static_cast<double>(base::Time::kMicrosecondsPerSecond) / 48000; |
DaleCurtis
2016/02/18 01:48:33
I'd just use 48000.0 to avoid the cast.
chcunningham
2016/02/18 20:43:37
Done.
|
+ |
+ // Write ~2 hours of data to clock to give any error a significant chance to |
+ // accumulate. |
+ while (clock_->back_timestamp() <= base::TimeDelta::FromHours(2)) { |
+ frames_written += 1024; |
+ WroteAudio(1024, 1024, 0, 1); |
+ } |
+ |
+ // Verify no error accumulated. |
+ EXPECT_EQ(std::round(frames_written * micros_per_frame), |
+ clock_->back_timestamp().InMicroseconds()); |
+} |
+ |
} // namespace media |