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. 4 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" 9 10namespace media { 11 12class AudioClockTest : public testing::Test { 13 public: 14 AudioClockTest() 15 : sample_rate_(10), clock_(base::TimeDelta(), sample_rate_) {} 16 17 virtual ~AudioClockTest() {} 18 19 void WroteAudio(int frames_written, 20 int frames_requested, 21 int delay_frames, 22 float playback_rate) { 23 clock_.WroteAudio( 24 frames_written, frames_requested, delay_frames, playback_rate); 25 } 26 27 int FrontTimestampInDays() { return clock_.front_timestamp().InDays(); } 28 29 int FrontTimestampInMilliseconds() { 30 return clock_.front_timestamp().InMilliseconds(); 31 } 32 33 int BackTimestampInMilliseconds() { 34 return clock_.back_timestamp().InMilliseconds(); 35 } 36 37 int TimestampSinceLastWritingInMilliseconds(int milliseconds) { 38 return clock_.TimestampSinceWriting(base::TimeDelta::FromMilliseconds( 39 milliseconds)).InMilliseconds(); 40 } 41 42 int TimeUntilPlaybackInMilliseconds(int timestamp_ms) { 43 return clock_.TimeUntilPlayback(base::TimeDelta::FromMilliseconds( 44 timestamp_ms)).InMilliseconds(); 45 } 46 47 int ContiguousAudioDataBufferedInDays() { 48 return clock_.contiguous_audio_data_buffered().InDays(); 49 } 50 51 int ContiguousAudioDataBufferedInMilliseconds() { 52 return clock_.contiguous_audio_data_buffered().InMilliseconds(); 53 } 54 55 int ContiguousAudioDataBufferedAtSameRateInMilliseconds() { 56 return clock_.contiguous_audio_data_buffered_at_same_rate() 57 .InMilliseconds(); 58 } 59 60 const int sample_rate_; 61 AudioClock clock_; 62 63 private: 64 DISALLOW_COPY_AND_ASSIGN(AudioClockTest); 65}; 66 67TEST_F(AudioClockTest, FrontTimestampStartsAtStartTimestamp) { 68 base::TimeDelta expected = base::TimeDelta::FromSeconds(123); 69 AudioClock clock(expected, sample_rate_); 70 71 EXPECT_EQ(expected, clock.front_timestamp()); 72} 73 74TEST_F(AudioClockTest, BackTimestampStartsAtStartTimestamp) { 75 base::TimeDelta expected = base::TimeDelta::FromSeconds(123); 76 AudioClock clock(expected, sample_rate_); 77 78 EXPECT_EQ(expected, clock.back_timestamp()); 79} 80 81TEST_F(AudioClockTest, TimestampSinceWritingStartsAtStartTimestamp) { 82 base::TimeDelta expected = base::TimeDelta::FromSeconds(123); 83 AudioClock clock(expected, sample_rate_); 84 85 base::TimeDelta time_since_writing = base::TimeDelta::FromSeconds(456); 86 EXPECT_EQ(expected, clock.TimestampSinceWriting(time_since_writing)); 87} 88 89TEST_F(AudioClockTest, ContiguousAudioDataBufferedStartsAtZero) { 90 EXPECT_EQ(base::TimeDelta(), clock_.contiguous_audio_data_buffered()); 91} 92 93TEST_F(AudioClockTest, ContiguousAudioDataBufferedAtSameRateStartsAtZero) { 94 EXPECT_EQ(base::TimeDelta(), 95 clock_.contiguous_audio_data_buffered_at_same_rate()); 96} 97 98TEST_F(AudioClockTest, Playback) { 99 // The first time we write data we should still expect our start timestamp 100 // due to delay. 101 WroteAudio(10, 10, 20, 1.0); 102 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 103 EXPECT_EQ(1000, BackTimestampInMilliseconds()); 104 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 105 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 106 107 // The media time should remain at start timestamp as we write data. 108 WroteAudio(10, 10, 20, 1.0); 109 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 110 EXPECT_EQ(2000, BackTimestampInMilliseconds()); 111 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 112 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 113 114 WroteAudio(10, 10, 20, 1.0); 115 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 116 EXPECT_EQ(3000, BackTimestampInMilliseconds()); 117 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds()); 118 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 119 120 // The media time should now start advanced now that delay has been covered. 121 WroteAudio(10, 10, 20, 1.0); 122 EXPECT_EQ(1000, FrontTimestampInMilliseconds()); 123 EXPECT_EQ(4000, BackTimestampInMilliseconds()); 124 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds()); 125 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 126 127 WroteAudio(10, 10, 20, 1.0); 128 EXPECT_EQ(2000, FrontTimestampInMilliseconds()); 129 EXPECT_EQ(5000, BackTimestampInMilliseconds()); 130 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds()); 131 EXPECT_EQ(3000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 132 133 // Introduce a rate change to slow down time: 134 // - Current time will advance by one second until it hits rate change 135 // - Contiguous audio data will start shrinking immediately 136 WroteAudio(10, 10, 20, 0.5); 137 EXPECT_EQ(3000, FrontTimestampInMilliseconds()); 138 EXPECT_EQ(5500, BackTimestampInMilliseconds()); 139 EXPECT_EQ(2500, ContiguousAudioDataBufferedInMilliseconds()); 140 EXPECT_EQ(2000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 141 142 WroteAudio(10, 10, 20, 0.5); 143 EXPECT_EQ(4000, FrontTimestampInMilliseconds()); 144 EXPECT_EQ(6000, BackTimestampInMilliseconds()); 145 EXPECT_EQ(2000, ContiguousAudioDataBufferedInMilliseconds()); 146 EXPECT_EQ(1000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 147 148 WroteAudio(10, 10, 20, 0.5); 149 EXPECT_EQ(5000, FrontTimestampInMilliseconds()); 150 EXPECT_EQ(6500, BackTimestampInMilliseconds()); 151 EXPECT_EQ(1500, ContiguousAudioDataBufferedInMilliseconds()); 152 EXPECT_EQ(1500, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 153 154 WroteAudio(10, 10, 20, 0.5); 155 EXPECT_EQ(5500, FrontTimestampInMilliseconds()); 156 EXPECT_EQ(7000, BackTimestampInMilliseconds()); 157 EXPECT_EQ(1500, ContiguousAudioDataBufferedInMilliseconds()); 158 EXPECT_EQ(1500, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 159 160 // Introduce a rate change to speed up time: 161 // - Current time will advance by half a second until it hits rate change 162 // - Contiguous audio data will start growing immediately 163 WroteAudio(10, 10, 20, 2); 164 EXPECT_EQ(6000, FrontTimestampInMilliseconds()); 165 EXPECT_EQ(9000, BackTimestampInMilliseconds()); 166 EXPECT_EQ(3000, ContiguousAudioDataBufferedInMilliseconds()); 167 EXPECT_EQ(1000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 168 169 WroteAudio(10, 10, 20, 2); 170 EXPECT_EQ(6500, FrontTimestampInMilliseconds()); 171 EXPECT_EQ(11000, BackTimestampInMilliseconds()); 172 EXPECT_EQ(4500, ContiguousAudioDataBufferedInMilliseconds()); 173 EXPECT_EQ(500, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 174 175 WroteAudio(10, 10, 20, 2); 176 EXPECT_EQ(7000, FrontTimestampInMilliseconds()); 177 EXPECT_EQ(13000, BackTimestampInMilliseconds()); 178 EXPECT_EQ(6000, ContiguousAudioDataBufferedInMilliseconds()); 179 EXPECT_EQ(6000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 180 181 WroteAudio(10, 10, 20, 2); 182 EXPECT_EQ(9000, FrontTimestampInMilliseconds()); 183 EXPECT_EQ(15000, BackTimestampInMilliseconds()); 184 EXPECT_EQ(6000, ContiguousAudioDataBufferedInMilliseconds()); 185 EXPECT_EQ(6000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 186 187 // Write silence to simulate reaching end of stream: 188 // - Current time will advance by half a second until it hits silence 189 // - Contiguous audio data will start shrinking towards zero 190 WroteAudio(0, 10, 20, 2); 191 EXPECT_EQ(11000, FrontTimestampInMilliseconds()); 192 EXPECT_EQ(15000, BackTimestampInMilliseconds()); 193 EXPECT_EQ(4000, ContiguousAudioDataBufferedInMilliseconds()); 194 EXPECT_EQ(4000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 195 196 WroteAudio(0, 10, 20, 2); 197 EXPECT_EQ(13000, FrontTimestampInMilliseconds()); 198 EXPECT_EQ(15000, BackTimestampInMilliseconds()); 199 EXPECT_EQ(2000, ContiguousAudioDataBufferedInMilliseconds()); 200 EXPECT_EQ(2000, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 201 202 WroteAudio(0, 10, 20, 2); 203 EXPECT_EQ(15000, FrontTimestampInMilliseconds()); 204 EXPECT_EQ(15000, BackTimestampInMilliseconds()); 205 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 206 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 207 208 // At this point media time should stop increasing. 209 WroteAudio(0, 10, 20, 2); 210 EXPECT_EQ(15000, FrontTimestampInMilliseconds()); 211 EXPECT_EQ(15000, BackTimestampInMilliseconds()); 212 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 213 EXPECT_EQ(0, ContiguousAudioDataBufferedAtSameRateInMilliseconds()); 214} 215 216TEST_F(AudioClockTest, AlternatingAudioAndSilence) { 217 // Buffer #1: [0, 1000) 218 WroteAudio(10, 10, 20, 1.0); 219 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 220 EXPECT_EQ(1000, BackTimestampInMilliseconds()); 221 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 222 223 // Buffer #2: 1000ms of silence 224 WroteAudio(0, 10, 20, 1.0); 225 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 226 EXPECT_EQ(1000, BackTimestampInMilliseconds()); 227 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 228 229 // Buffer #3: [1000, 2000): 230 // - Buffer #1 is at front with 1000ms of contiguous audio data 231 WroteAudio(10, 10, 20, 1.0); 232 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 233 EXPECT_EQ(2000, BackTimestampInMilliseconds()); 234 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds()); 235 236 // Buffer #4: 1000ms of silence 237 // - Buffer #1 has been played out 238 // - Buffer #2 of silence leaves us with 0ms of contiguous audio data 239 WroteAudio(0, 10, 20, 1.0); 240 EXPECT_EQ(1000, FrontTimestampInMilliseconds()); 241 EXPECT_EQ(2000, BackTimestampInMilliseconds()); 242 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 243 244 // Buffer #5: [2000, 3000): 245 // - Buffer #3 is at front with 1000ms of contiguous audio data 246 WroteAudio(10, 10, 20, 1.0); 247 EXPECT_EQ(1000, FrontTimestampInMilliseconds()); 248 EXPECT_EQ(3000, BackTimestampInMilliseconds()); 249 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds()); 250} 251 252TEST_F(AudioClockTest, ZeroDelay) { 253 // The first time we write data we should expect the first timestamp 254 // immediately. 255 WroteAudio(10, 10, 0, 1.0); 256 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 257 EXPECT_EQ(1000, BackTimestampInMilliseconds()); 258 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds()); 259 260 // Ditto for all subsequent buffers. 261 WroteAudio(10, 10, 0, 1.0); 262 EXPECT_EQ(1000, FrontTimestampInMilliseconds()); 263 EXPECT_EQ(2000, BackTimestampInMilliseconds()); 264 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds()); 265 266 WroteAudio(10, 10, 0, 1.0); 267 EXPECT_EQ(2000, FrontTimestampInMilliseconds()); 268 EXPECT_EQ(3000, BackTimestampInMilliseconds()); 269 EXPECT_EQ(1000, ContiguousAudioDataBufferedInMilliseconds()); 270 271 // Ditto for silence. 272 WroteAudio(0, 10, 0, 1.0); 273 EXPECT_EQ(3000, FrontTimestampInMilliseconds()); 274 EXPECT_EQ(3000, BackTimestampInMilliseconds()); 275 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 276 277 WroteAudio(0, 10, 0, 1.0); 278 EXPECT_EQ(3000, FrontTimestampInMilliseconds()); 279 EXPECT_EQ(3000, BackTimestampInMilliseconds()); 280 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 281} 282 283TEST_F(AudioClockTest, TimestampSinceLastWriting) { 284 // Construct an audio clock with the following representation: 285 // 286 // |- existing delay -|------------ calls to WroteAudio() -----------------| 287 // +-------------------+----------------+------------------+----------------+ 288 // | 20 frames silence | 10 frames @ 1x | 10 frames @ 0.5x | 10 frames @ 2x | 289 // +-------------------+----------------+------------------+----------------+ 290 // Media timestamp: 0 1000 1500 3500 291 // Wall clock time: 2000 3000 4000 5000 292 WroteAudio(10, 10, 40, 1.0); 293 WroteAudio(10, 10, 40, 0.5); 294 WroteAudio(10, 10, 40, 2.0); 295 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 296 EXPECT_EQ(3500, BackTimestampInMilliseconds()); 297 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 298 299 // Simulate passing 2000ms of initial delay in the audio hardware. 300 EXPECT_EQ(0, TimestampSinceLastWritingInMilliseconds(0)); 301 EXPECT_EQ(0, TimestampSinceLastWritingInMilliseconds(500)); 302 EXPECT_EQ(0, TimestampSinceLastWritingInMilliseconds(1000)); 303 EXPECT_EQ(0, TimestampSinceLastWritingInMilliseconds(1500)); 304 EXPECT_EQ(0, TimestampSinceLastWritingInMilliseconds(2000)); 305 306 // Now we should see the 1.0x buffer. 307 EXPECT_EQ(500, TimestampSinceLastWritingInMilliseconds(2500)); 308 EXPECT_EQ(1000, TimestampSinceLastWritingInMilliseconds(3000)); 309 310 // Now we should see the 0.5x buffer. 311 EXPECT_EQ(1250, TimestampSinceLastWritingInMilliseconds(3500)); 312 EXPECT_EQ(1500, TimestampSinceLastWritingInMilliseconds(4000)); 313 314 // Now we should see the 2.0x buffer. 315 EXPECT_EQ(2500, TimestampSinceLastWritingInMilliseconds(4500)); 316 EXPECT_EQ(3500, TimestampSinceLastWritingInMilliseconds(5000)); 317 318 // Times beyond the known length of the audio clock should return the last 319 // media timestamp we know of. 320 EXPECT_EQ(3500, TimestampSinceLastWritingInMilliseconds(5001)); 321 EXPECT_EQ(3500, TimestampSinceLastWritingInMilliseconds(6000)); 322} 323 324TEST_F(AudioClockTest, TimeUntilPlayback) { 325 // Construct an audio clock with the following representation: 326 // 327 // existing 328 // |- delay -|------------------ calls to WroteAudio() ------------------| 329 // +------------+---------+------------+-----------+------------+-----------+ 330 // | 20 silence | 10 @ 1x | 10 silence | 10 @ 0.5x | 10 silence | 10 @ 2.0x | 331 // +------------+---------+------------+-----------+------------+-----------+ 332 // Media: 0 1000 1000 1500 1500 3500 333 // Wall: 2000 3000 4000 5000 6000 7000 334 WroteAudio(10, 10, 60, 1.0); 335 WroteAudio(0, 10, 60, 1.0); 336 WroteAudio(10, 10, 60, 0.5); 337 WroteAudio(0, 10, 60, 0.5); 338 WroteAudio(10, 10, 60, 2.0); 339 EXPECT_EQ(0, FrontTimestampInMilliseconds()); 340 EXPECT_EQ(3500, BackTimestampInMilliseconds()); 341 EXPECT_EQ(0, ContiguousAudioDataBufferedInMilliseconds()); 342 343 // Media timestamp zero has to wait for silence to pass. 344 EXPECT_EQ(2000, TimeUntilPlaybackInMilliseconds(0)); 345 346 // From then on out it's simply adding up the number of frames and taking 347 // silence into account. 348 EXPECT_EQ(2500, TimeUntilPlaybackInMilliseconds(500)); 349 EXPECT_EQ(3000, TimeUntilPlaybackInMilliseconds(1000)); 350 EXPECT_EQ(4500, TimeUntilPlaybackInMilliseconds(1250)); 351 EXPECT_EQ(5000, TimeUntilPlaybackInMilliseconds(1500)); 352 EXPECT_EQ(6500, TimeUntilPlaybackInMilliseconds(2500)); 353 EXPECT_EQ(7000, TimeUntilPlaybackInMilliseconds(3500)); 354} 355 356TEST_F(AudioClockTest, SupportsYearsWorthOfAudioData) { 357 // Use number of frames that would be likely to overflow 32-bit integer math. 358 const int huge_amount_of_frames = std::numeric_limits<int>::max(); 359 const base::TimeDelta huge = 360 base::TimeDelta::FromSeconds(huge_amount_of_frames / sample_rate_); 361 EXPECT_EQ(2485, huge.InDays()); // Just to give some context on how big... 362 363 // Use zero delay to test calculation of current timestamp. 364 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0); 365 EXPECT_EQ(0, FrontTimestampInDays()); 366 EXPECT_EQ(2485, ContiguousAudioDataBufferedInDays()); 367 368 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0); 369 EXPECT_EQ(huge.InDays(), FrontTimestampInDays()); 370 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays()); 371 372 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0); 373 EXPECT_EQ((huge * 2).InDays(), FrontTimestampInDays()); 374 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays()); 375 376 WroteAudio(huge_amount_of_frames, huge_amount_of_frames, 0, 1.0); 377 EXPECT_EQ((huge * 3).InDays(), FrontTimestampInDays()); 378 EXPECT_EQ(huge.InDays(), ContiguousAudioDataBufferedInDays()); 379 380 // Use huge delay to test calculation of buffered data. 381 WroteAudio( 382 huge_amount_of_frames, huge_amount_of_frames, huge_amount_of_frames, 1.0); 383 EXPECT_EQ((huge * 3).InDays(), FrontTimestampInDays()); 384 EXPECT_EQ((huge * 2).InDays(), ContiguousAudioDataBufferedInDays()); 385} 386 387} // namespace media 388