1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/filters/audio_clock.h"
9 #include "base/time/time.h"
10 #include "media/base/audio_timestamp_helper.h"
11 #include "testing/gtest/include/gtest/gtest.h"
15 class AudioClockTest : public testing::Test {
17 AudioClockTest() { SetupClock(base::TimeDelta(), 10); }
19 AudioClockTest(const AudioClockTest&) = delete;
20 AudioClockTest& operator=(const AudioClockTest&) = delete;
22 ~AudioClockTest() override = default;
24 void WroteAudio(int frames_written,
27 double playback_rate) {
28 clock_->WroteAudio(frames_written, frames_requested, delay_frames,
32 void SetupClock(base::TimeDelta start_time, int sample_rate) {
33 sample_rate_ = sample_rate;
34 clock_ = std::make_unique<AudioClock>(start_time, sample_rate_);
37 int FrontTimestampInDays() { return clock_->front_timestamp().InDays(); }
39 int FrontTimestampInMilliseconds() {
40 return clock_->front_timestamp().InMilliseconds();
43 int BackTimestampInMilliseconds() {
44 return clock_->back_timestamp().InMilliseconds();
47 int TimeUntilPlaybackInMilliseconds(int timestamp_ms) {
48 return clock_->TimeUntilPlayback(base::Milliseconds(timestamp_ms))
52 int ContiguousAudioDataBufferedInDays() {
53 base::TimeDelta total, same_rate_total;
54 clock_->ContiguousAudioDataBufferedForTesting(&total, &same_rate_total);
55 return total.InDays();
58 int ContiguousAudioDataBufferedInMilliseconds() {
59 base::TimeDelta total, same_rate_total;
60 clock_->ContiguousAudioDataBufferedForTesting(&total, &same_rate_total);
61 return total.InMilliseconds();
64 int ContiguousAudioDataBufferedAtSameRateInMilliseconds() {
65 base::TimeDelta total, same_rate_total;
66 clock_->ContiguousAudioDataBufferedForTesting(&total, &same_rate_total);
67 return same_rate_total.InMilliseconds();
71 std::unique_ptr<AudioClock> clock_;
74 TEST_F(AudioClockTest, FrontTimestampStartsAtStartTimestamp) {
75 base::TimeDelta expected = base::Seconds(123);
76 AudioClock clock(expected, sample_rate_);
78 EXPECT_EQ(expected, clock.front_timestamp());
81 TEST_F(AudioClockTest, BackTimestampStartsAtStartTimestamp) {
82 base::TimeDelta expected = base::Seconds(123);
83 AudioClock clock(expected, sample_rate_);
85 EXPECT_EQ(expected, clock.back_timestamp());
88 TEST_F(AudioClockTest, Playback) {
89 // The first time we write data we should still expect our start timestamp
91 WroteAudio(10, 10, 20, 1.0);
92 EXPECT_EQ(0, FrontTimestampInMilliseconds());
93 EXPECT_EQ(1000, BackTimestampInMilliseconds());
94 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
95 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
97 // The media time should remain at start timestamp as we write data.
98 WroteAudio(10, 10, 20, 1.0);
99 EXPECT_EQ(0, FrontTimestampInMilliseconds());
100 EXPECT_EQ(2000, BackTimestampInMilliseconds());
101 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
102 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
104 WroteAudio(10, 10, 20, 1.0);
105 EXPECT_EQ(0, FrontTimestampInMilliseconds());
106 EXPECT_EQ(3000, BackTimestampInMilliseconds());
107 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
108 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
110 // The media time should now start advanced now that delay has been covered.
111 WroteAudio(10, 10, 20, 1.0);
112 EXPECT_EQ(1000, FrontTimestampInMilliseconds());
113 EXPECT_EQ(4000, BackTimestampInMilliseconds());
114 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
115 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
117 WroteAudio(10, 10, 20, 1.0);
118 EXPECT_EQ(2000, FrontTimestampInMilliseconds());
119 EXPECT_EQ(5000, BackTimestampInMilliseconds());
120 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
121 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
123 // Introduce a rate change to slow down time:
124 // - Current time will advance by one second until it hits rate change
125 // - Contiguous audio data will start shrinking immediately
126 WroteAudio(10, 10, 20, 0.5);
127 EXPECT_EQ(3000, FrontTimestampInMilliseconds());
128 EXPECT_EQ(5500, BackTimestampInMilliseconds());
129 EXPECT_EQ(2500, ContiguousAudioDataBufferedInMilliseconds());
130 EXPECT_EQ(2000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
132 WroteAudio(10, 10, 20, 0.5);
133 EXPECT_EQ(4000, FrontTimestampInMilliseconds());
134 EXPECT_EQ(6000, BackTimestampInMilliseconds());
135 EXPECT_EQ(2000, ContiguousAudioDataBufferedInMilliseconds());
136 EXPECT_EQ(1000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
138 WroteAudio(10, 10, 20, 0.5);
139 EXPECT_EQ(5000, FrontTimestampInMilliseconds());
140 EXPECT_EQ(6500, BackTimestampInMilliseconds());
141 EXPECT_EQ(1500, ContiguousAudioDataBufferedInMilliseconds());
142 EXPECT_EQ(1500, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
144 WroteAudio(10, 10, 20, 0.5);
145 EXPECT_EQ(5500, FrontTimestampInMilliseconds());
146 EXPECT_EQ(7000, BackTimestampInMilliseconds());
147 EXPECT_EQ(1500, ContiguousAudioDataBufferedInMilliseconds());
148 EXPECT_EQ(1500, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
150 // Introduce a rate change to speed up time:
151 // - Current time will advance by half a second until it hits rate change
152 // - Contiguous audio data will start growing immediately
153 WroteAudio(10, 10, 20, 2);
154 EXPECT_EQ(6000, FrontTimestampInMilliseconds());
155 EXPECT_EQ(9000, BackTimestampInMilliseconds());
156 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
157 EXPECT_EQ(1000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
159 WroteAudio(10, 10, 20, 2);
160 EXPECT_EQ(6500, FrontTimestampInMilliseconds());
161 EXPECT_EQ(11000, BackTimestampInMilliseconds());
162 EXPECT_EQ(4500, ContiguousAudioDataBufferedInMilliseconds());
163 EXPECT_EQ(500, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
165 WroteAudio(10, 10, 20, 2);
166 EXPECT_EQ(7000, FrontTimestampInMilliseconds());
167 EXPECT_EQ(13000, BackTimestampInMilliseconds());
168 EXPECT_EQ(6000, ContiguousAudioDataBufferedInMilliseconds());
169 EXPECT_EQ(6000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
171 WroteAudio(10, 10, 20, 2);
172 EXPECT_EQ(9000, FrontTimestampInMilliseconds());
173 EXPECT_EQ(15000, BackTimestampInMilliseconds());
174 EXPECT_EQ(6000, ContiguousAudioDataBufferedInMilliseconds());
175 EXPECT_EQ(6000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
177 // Write silence to simulate reaching end of stream:
178 // - Current time will advance by half a second until it hits silence
179 // - Contiguous audio data will start shrinking towards zero
180 WroteAudio(0, 10, 20, 2);
181 EXPECT_EQ(11000, FrontTimestampInMilliseconds());
182 EXPECT_EQ(15000, BackTimestampInMilliseconds());
183 EXPECT_EQ(4000, ContiguousAudioDataBufferedInMilliseconds());
184 EXPECT_EQ(4000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
186 WroteAudio(0, 10, 20, 2);
187 EXPECT_EQ(13000, FrontTimestampInMilliseconds());
188 EXPECT_EQ(15000, BackTimestampInMilliseconds());
189 EXPECT_EQ(2000, ContiguousAudioDataBufferedInMilliseconds());
190 EXPECT_EQ(2000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
192 WroteAudio(0, 10, 20, 2);
193 EXPECT_EQ(15000, FrontTimestampInMilliseconds());
194 EXPECT_EQ(15000, BackTimestampInMilliseconds());
195 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
196 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
198 // At this point media time should stop increasing.
199 WroteAudio(0, 10, 20, 2);
200 EXPECT_EQ(15000, FrontTimestampInMilliseconds());
201 EXPECT_EQ(15000, BackTimestampInMilliseconds());
202 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
203 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
206 TEST_F(AudioClockTest, AlternatingAudioAndSilence) {
207 // Buffer #1: [0, 1000)
208 WroteAudio(10, 10, 20, 1.0);
209 EXPECT_EQ(0, FrontTimestampInMilliseconds());
210 EXPECT_EQ(1000, BackTimestampInMilliseconds());
211 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
213 // Buffer #2: 1000ms of silence
214 WroteAudio(0, 10, 20, 1.0);
215 EXPECT_EQ(0, FrontTimestampInMilliseconds());
216 EXPECT_EQ(1000, BackTimestampInMilliseconds());
217 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
219 // Buffer #3: [1000, 2000):
220 // - Buffer #1 is at front with 1000ms of contiguous audio data
221 WroteAudio(10, 10, 20, 1.0);
222 EXPECT_EQ(0, FrontTimestampInMilliseconds());
223 EXPECT_EQ(2000, BackTimestampInMilliseconds());
224 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
226 // Buffer #4: 1000ms of silence
227 // - Buffer #1 has been played out
228 // - Buffer #2 of silence leaves us with 0ms of contiguous audio data
229 WroteAudio(0, 10, 20, 1.0);
230 EXPECT_EQ(1000, FrontTimestampInMilliseconds());
231 EXPECT_EQ(2000, BackTimestampInMilliseconds());
232 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
234 // Buffer #5: [2000, 3000):
235 // - Buffer #3 is at front with 1000ms of contiguous audio data
236 WroteAudio(10, 10, 20, 1.0);
237 EXPECT_EQ(1000, FrontTimestampInMilliseconds());
238 EXPECT_EQ(3000, BackTimestampInMilliseconds());
239 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
242 TEST_F(AudioClockTest, ZeroDelay) {
243 // The first time we write data we should expect the first timestamp
245 WroteAudio(10, 10, 0, 1.0);
246 EXPECT_EQ(0, FrontTimestampInMilliseconds());
247 EXPECT_EQ(1000, BackTimestampInMilliseconds());
248 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
250 // Ditto for all subsequent buffers.
251 WroteAudio(10, 10, 0, 1.0);
252 EXPECT_EQ(1000, FrontTimestampInMilliseconds());
253 EXPECT_EQ(2000, BackTimestampInMilliseconds());
254 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
256 WroteAudio(10, 10, 0, 1.0);
257 EXPECT_EQ(2000, FrontTimestampInMilliseconds());
258 EXPECT_EQ(3000, BackTimestampInMilliseconds());
259 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
261 // Ditto for silence.
262 WroteAudio(0, 10, 0, 1.0);
263 EXPECT_EQ(3000, FrontTimestampInMilliseconds());
264 EXPECT_EQ(3000, BackTimestampInMilliseconds());
265 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
267 WroteAudio(0, 10, 0, 1.0);
268 EXPECT_EQ(3000, FrontTimestampInMilliseconds());
269 EXPECT_EQ(3000, BackTimestampInMilliseconds());
270 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
273 TEST_F(AudioClockTest, TimeUntilPlayback) {
274 // Construct an audio clock with the following representation:
277 // |- delay -|------------------ calls to WroteAudio() ------------------|
278 // +------------+---------+------------+-----------+------------+-----------+
279 // | 20 silence | 10 @ 1x | 10 silence | 10 @ 0.5x | 10 silence | 10 @ 2.0x |
280 // +------------+---------+------------+-----------+------------+-----------+
281 // Media: 0 1000 1000 1500 1500 3500
282 // Wall: 2000 3000 4000 5000 6000 7000
283 WroteAudio(10, 10, 60, 1.0);
284 WroteAudio(0, 10, 60, 1.0);
285 WroteAudio(10, 10, 60, 0.5);
286 WroteAudio(0, 10, 60, 0.5);
287 WroteAudio(10, 10, 60, 2.0);
288 EXPECT_EQ(0, FrontTimestampInMilliseconds());
289 EXPECT_EQ(3500, BackTimestampInMilliseconds());
290 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
292 // Media timestamp zero has to wait for silence to pass.
293 EXPECT_EQ(2000, TimeUntilPlaybackInMilliseconds(0));
295 // From then on out it's simply adding up the number of frames and taking
296 // silence into account.
297 EXPECT_EQ(2500, TimeUntilPlaybackInMilliseconds(500));
298 EXPECT_EQ(3000, TimeUntilPlaybackInMilliseconds(1000));
299 EXPECT_EQ(4500, TimeUntilPlaybackInMilliseconds(1250));
300 EXPECT_EQ(5000, TimeUntilPlaybackInMilliseconds(1500));
301 EXPECT_EQ(6500, TimeUntilPlaybackInMilliseconds(2500));
302 EXPECT_EQ(7000, TimeUntilPlaybackInMilliseconds(3500));
305 TEST_F(AudioClockTest, SupportsYearsWorthOfAudioData) {
306 // Use number of frames that would be likely to overflow 32-bit integer math.
307 const int huge_amount_of_frames = std::numeric_limits<int>::max();
308 const base::TimeDelta huge =
309 base::Seconds(huge_amount_of_frames / sample_rate_);
310 EXPECT_EQ(2485, huge.InDays()); // Just to give some context on how big...
312 // Use zero delay to test calculation of current timestamp.
313 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
314 EXPECT_EQ(0, FrontTimestampInDays());
315 EXPECT_EQ(2485, ContiguousAudioDataBufferedInDays());
317 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
318 EXPECT_EQ(huge.InDays(), FrontTimestampInDays());
319 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays());
321 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
322 EXPECT_EQ((huge * 2).InDays(), FrontTimestampInDays());
323 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays());
325 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
326 EXPECT_EQ((huge * 3).InDays(), FrontTimestampInDays());
327 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays());
329 // Use huge delay to test calculation of buffered data.
331 huge_amount_of_frames, huge_amount_of_frames, huge_amount_of_frames, 1.0);
332 EXPECT_EQ((huge * 3).InDays(), FrontTimestampInDays());
333 EXPECT_EQ((huge * 2).InDays(), ContiguousAudioDataBufferedInDays());
336 TEST_F(AudioClockTest, CompensateForSuspendedWrites) {
337 // Buffer 6 seconds of delay and 1 second of audio data.
338 WroteAudio(10, 10, 60, 1.0);
340 // Media timestamp zero has to wait for silence to pass.
341 const int kBaseTimeMs = 6000;
342 EXPECT_EQ(kBaseTimeMs, TimeUntilPlaybackInMilliseconds(0));
344 // Elapsing frames less than we have buffered should do nothing.
345 const int kDelayFrames = 2;
346 for (int i = 1000; i <= kBaseTimeMs; i += 1000) {
347 clock_->CompensateForSuspendedWrites(base::Milliseconds(i), kDelayFrames);
348 EXPECT_EQ(kBaseTimeMs - (i - 1000), TimeUntilPlaybackInMilliseconds(0));
350 // Write silence to simulate maintaining a 7s output buffer.
351 WroteAudio(0, 10, 60, 1.0);
354 // Exhausting all frames should advance timestamps and prime the buffer with
355 // our delay frames value.
356 clock_->CompensateForSuspendedWrites(base::Milliseconds(7000), kDelayFrames);
357 EXPECT_EQ(kDelayFrames * 100, TimeUntilPlaybackInMilliseconds(1000));
360 TEST_F(AudioClockTest, FramesToTimePrecision) {
361 SetupClock(base::TimeDelta(), 48000);
362 double micros_per_frame = base::Time::kMicrosecondsPerSecond / 48000.0;
363 int frames_written = 0;
365 // Write ~2 hours of data to clock to give any error a significant chance to
367 while (clock_->back_timestamp() <= base::Hours(2)) {
368 frames_written += 1024;
369 WroteAudio(1024, 1024, 0, 1);
372 // Verify no error accumulated.
373 EXPECT_EQ(std::round(frames_written * micros_per_frame),
374 clock_->back_timestamp().InMicroseconds());