1 // Copyright 2014 The Chromium Authors. All rights reserved.
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/base/audio_timestamp_helper.h"
6 #include "media/base/buffers.h"
7 #include "media/filters/audio_clock.h"
8 #include "testing/gtest/include/gtest/gtest.h"
12 class AudioClockTest : public testing::Test {
15 : sample_rate_(10), clock_(base::TimeDelta(), sample_rate_) {}
17 virtual ~AudioClockTest() {}
19 void WroteAudio(int frames_written,
22 float playback_rate) {
24 frames_written, frames_requested, delay_frames, playback_rate);
27 int CurrentMediaTimestampInDays() {
28 return clock_.current_media_timestamp().InDays();
31 int CurrentMediaTimestampInMilliseconds() {
32 return clock_.current_media_timestamp().InMilliseconds();
35 int CurrentMediaTimestampSinceLastWritingInMilliseconds(int milliseconds) {
36 return clock_.CurrentMediaTimestampSinceWriting(
37 base::TimeDelta::FromMilliseconds(milliseconds))
41 int ContiguousAudioDataBufferedInDays() {
42 return clock_.contiguous_audio_data_buffered().InDays();
45 int ContiguousAudioDataBufferedInMilliseconds() {
46 return clock_.contiguous_audio_data_buffered().InMilliseconds();
49 int ContiguousAudioDataBufferedAtSameRateInMilliseconds() {
50 return clock_.contiguous_audio_data_buffered_at_same_rate()
54 const int sample_rate_;
58 DISALLOW_COPY_AND_ASSIGN(AudioClockTest);
61 TEST_F(AudioClockTest, CurrentMediaTimestampStartsAtStartTimestamp) {
62 base::TimeDelta expected = base::TimeDelta::FromSeconds(123);
63 AudioClock clock(expected, sample_rate_);
65 EXPECT_EQ(expected, clock.current_media_timestamp());
68 TEST_F(AudioClockTest,
69 CurrentMediaTimestampSinceWritingStartsAtStartTimestamp) {
70 base::TimeDelta expected = base::TimeDelta::FromSeconds(123);
71 AudioClock clock(expected, sample_rate_);
73 base::TimeDelta time_since_writing = base::TimeDelta::FromSeconds(456);
75 clock.CurrentMediaTimestampSinceWriting(time_since_writing));
78 TEST_F(AudioClockTest, ContiguousAudioDataBufferedStartsAtZero) {
79 EXPECT_EQ(base::TimeDelta(), clock_.contiguous_audio_data_buffered());
82 TEST_F(AudioClockTest, ContiguousAudioDataBufferedAtSameRateStartsAtZero) {
83 EXPECT_EQ(base::TimeDelta(),
84 clock_.contiguous_audio_data_buffered_at_same_rate());
87 TEST_F(AudioClockTest, AudioDataBufferedStartsAtFalse) {
88 EXPECT_FALSE(clock_.audio_data_buffered());
91 TEST_F(AudioClockTest, Playback) {
92 // The first time we write data we should still expect our start timestamp
94 WroteAudio(10, 10, 20, 1.0);
95 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
96 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
97 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
98 EXPECT_TRUE(clock_.audio_data_buffered());
100 // The media time should remain at start timestamp as we write data.
101 WroteAudio(10, 10, 20, 1.0);
102 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
103 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
104 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
106 WroteAudio(10, 10, 20, 1.0);
107 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
108 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
109 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
111 // The media time should now start advanced now that delay has been covered.
112 WroteAudio(10, 10, 20, 1.0);
113 EXPECT_EQ(1000, CurrentMediaTimestampInMilliseconds());
114 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
115 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
117 WroteAudio(10, 10, 20, 1.0);
118 EXPECT_EQ(2000, CurrentMediaTimestampInMilliseconds());
119 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
120 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
122 // Introduce a rate change to slow down time:
123 // - Current time will advance by one second until it hits rate change
124 // - Contiguous audio data will start shrinking immediately
125 WroteAudio(10, 10, 20, 0.5);
126 EXPECT_EQ(3000, CurrentMediaTimestampInMilliseconds());
127 EXPECT_EQ(2500, ContiguousAudioDataBufferedInMilliseconds());
128 EXPECT_EQ(2000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
130 WroteAudio(10, 10, 20, 0.5);
131 EXPECT_EQ(4000, CurrentMediaTimestampInMilliseconds());
132 EXPECT_EQ(2000, ContiguousAudioDataBufferedInMilliseconds());
133 EXPECT_EQ(1000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
135 WroteAudio(10, 10, 20, 0.5);
136 EXPECT_EQ(5000, CurrentMediaTimestampInMilliseconds());
137 EXPECT_EQ(1500, ContiguousAudioDataBufferedInMilliseconds());
138 EXPECT_EQ(1500, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
140 WroteAudio(10, 10, 20, 0.5);
141 EXPECT_EQ(5500, CurrentMediaTimestampInMilliseconds());
142 EXPECT_EQ(1500, ContiguousAudioDataBufferedInMilliseconds());
143 EXPECT_EQ(1500, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
145 // Introduce a rate change to speed up time:
146 // - Current time will advance by half a second until it hits rate change
147 // - Contiguous audio data will start growing immediately
148 WroteAudio(10, 10, 20, 2);
149 EXPECT_EQ(6000, CurrentMediaTimestampInMilliseconds());
150 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds());
151 EXPECT_EQ(1000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
153 WroteAudio(10, 10, 20, 2);
154 EXPECT_EQ(6500, CurrentMediaTimestampInMilliseconds());
155 EXPECT_EQ(4500, ContiguousAudioDataBufferedInMilliseconds());
156 EXPECT_EQ(500, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
158 WroteAudio(10, 10, 20, 2);
159 EXPECT_EQ(7000, CurrentMediaTimestampInMilliseconds());
160 EXPECT_EQ(6000, ContiguousAudioDataBufferedInMilliseconds());
161 EXPECT_EQ(6000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
163 WroteAudio(10, 10, 20, 2);
164 EXPECT_EQ(9000, CurrentMediaTimestampInMilliseconds());
165 EXPECT_EQ(6000, ContiguousAudioDataBufferedInMilliseconds());
166 EXPECT_EQ(6000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
168 // Write silence to simulate reaching end of stream:
169 // - Current time will advance by half a second until it hits silence
170 // - Contiguous audio data will start shrinking towards zero
171 WroteAudio(0, 10, 20, 2);
172 EXPECT_EQ(11000, CurrentMediaTimestampInMilliseconds());
173 EXPECT_EQ(4000, ContiguousAudioDataBufferedInMilliseconds());
174 EXPECT_EQ(4000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
176 WroteAudio(0, 10, 20, 2);
177 EXPECT_EQ(13000, CurrentMediaTimestampInMilliseconds());
178 EXPECT_EQ(2000, ContiguousAudioDataBufferedInMilliseconds());
179 EXPECT_EQ(2000, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
180 EXPECT_TRUE(clock_.audio_data_buffered()); // Still audio data buffered.
182 WroteAudio(0, 10, 20, 2);
183 EXPECT_EQ(15000, CurrentMediaTimestampInMilliseconds());
184 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
185 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
186 EXPECT_FALSE(clock_.audio_data_buffered()); // No more audio data buffered.
188 // At this point media time should stop increasing.
189 WroteAudio(0, 10, 20, 2);
190 EXPECT_EQ(15000, CurrentMediaTimestampInMilliseconds());
191 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
192 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds());
193 EXPECT_FALSE(clock_.audio_data_buffered());
196 TEST_F(AudioClockTest, AlternatingAudioAndSilence) {
197 // Buffer #1: [0, 1000)
198 WroteAudio(10, 10, 20, 1.0);
199 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
200 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
202 // Buffer #2: 1000ms of silence
203 WroteAudio(0, 10, 20, 1.0);
204 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
205 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
207 // Buffer #3: [1000, 2000):
208 // - Buffer #1 is at front with 1000ms of contiguous audio data
209 WroteAudio(10, 10, 20, 1.0);
210 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
211 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
213 // Buffer #4: 1000ms of silence
214 // - Buffer #1 has been played out
215 // - Buffer #2 of silence leaves us with 0ms of contiguous audio data
216 WroteAudio(0, 10, 20, 1.0);
217 EXPECT_EQ(1000, CurrentMediaTimestampInMilliseconds());
218 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
220 // Buffer #5: [2000, 3000):
221 // - Buffer #3 is at front with 1000ms of contiguous audio data
222 WroteAudio(10, 10, 20, 1.0);
223 EXPECT_EQ(1000, CurrentMediaTimestampInMilliseconds());
224 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
227 TEST_F(AudioClockTest, ZeroDelay) {
228 // The first time we write data we should expect the first timestamp
230 WroteAudio(10, 10, 0, 1.0);
231 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
232 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
234 // Ditto for all subsequent buffers.
235 WroteAudio(10, 10, 0, 1.0);
236 EXPECT_EQ(1000, CurrentMediaTimestampInMilliseconds());
237 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
239 WroteAudio(10, 10, 0, 1.0);
240 EXPECT_EQ(2000, CurrentMediaTimestampInMilliseconds());
241 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds());
243 // Ditto for silence.
244 WroteAudio(0, 10, 0, 1.0);
245 EXPECT_EQ(3000, CurrentMediaTimestampInMilliseconds());
246 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
248 WroteAudio(0, 10, 0, 1.0);
249 EXPECT_EQ(3000, CurrentMediaTimestampInMilliseconds());
250 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
253 TEST_F(AudioClockTest, CurrentMediaTimestampSinceLastWriting) {
254 // Construct an audio clock with the following representation:
256 // +-------------------+----------------+------------------+----------------+
257 // | 10 frames silence | 10 frames @ 1x | 10 frames @ 0.5x | 10 frames @ 2x |
258 // +-------------------+----------------+------------------+----------------+
259 // Media timestamp: 0 1000 1500 3500
260 // Wall clock time: 2000 3000 4000 5000
261 WroteAudio(10, 10, 40, 1.0);
262 WroteAudio(10, 10, 40, 0.5);
263 WroteAudio(10, 10, 40, 2.0);
264 EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
265 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds());
267 // Simulate passing 2000ms of initial delay in the audio hardware.
268 EXPECT_EQ(0, CurrentMediaTimestampSinceLastWritingInMilliseconds(0));
269 EXPECT_EQ(0, CurrentMediaTimestampSinceLastWritingInMilliseconds(500));
270 EXPECT_EQ(0, CurrentMediaTimestampSinceLastWritingInMilliseconds(1000));
271 EXPECT_EQ(0, CurrentMediaTimestampSinceLastWritingInMilliseconds(1500));
272 EXPECT_EQ(0, CurrentMediaTimestampSinceLastWritingInMilliseconds(2000));
274 // Now we should see the 1.0x buffer.
275 EXPECT_EQ(500, CurrentMediaTimestampSinceLastWritingInMilliseconds(2500));
276 EXPECT_EQ(1000, CurrentMediaTimestampSinceLastWritingInMilliseconds(3000));
278 // Now we should see the 0.5x buffer.
279 EXPECT_EQ(1250, CurrentMediaTimestampSinceLastWritingInMilliseconds(3500));
280 EXPECT_EQ(1500, CurrentMediaTimestampSinceLastWritingInMilliseconds(4000));
282 // Now we should see the 2.0x buffer.
283 EXPECT_EQ(2500, CurrentMediaTimestampSinceLastWritingInMilliseconds(4500));
284 EXPECT_EQ(3500, CurrentMediaTimestampSinceLastWritingInMilliseconds(5000));
286 // Times beyond the known length of the audio clock should return the last
287 // media timestamp we know of.
288 EXPECT_EQ(3500, CurrentMediaTimestampSinceLastWritingInMilliseconds(5001));
289 EXPECT_EQ(3500, CurrentMediaTimestampSinceLastWritingInMilliseconds(6000));
292 TEST_F(AudioClockTest, SupportsYearsWorthOfAudioData) {
293 // Use number of frames that would be likely to overflow 32-bit integer math.
294 const int huge_amount_of_frames = std::numeric_limits<int>::max();
295 const base::TimeDelta huge =
296 base::TimeDelta::FromSeconds(huge_amount_of_frames / sample_rate_);
297 EXPECT_EQ(2485, huge.InDays()); // Just to give some context on how big...
299 // Use zero delay to test calculation of current timestamp.
300 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
301 EXPECT_EQ(0, CurrentMediaTimestampInDays());
302 EXPECT_EQ(2485, ContiguousAudioDataBufferedInDays());
304 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
305 EXPECT_EQ(huge.InDays(), CurrentMediaTimestampInDays());
306 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays());
308 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
309 EXPECT_EQ((huge * 2).InDays(), CurrentMediaTimestampInDays());
310 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays());
312 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0);
313 EXPECT_EQ((huge * 3).InDays(), CurrentMediaTimestampInDays());
314 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays());
316 // Use huge delay to test calculation of buffered data.
318 huge_amount_of_frames, huge_amount_of_frames, huge_amount_of_frames, 1.0);
319 EXPECT_EQ((huge * 3).InDays(), CurrentMediaTimestampInDays());
320 EXPECT_EQ((huge * 2).InDays(), ContiguousAudioDataBufferedInDays());