1 // Copyright (c) 2012 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 "base/bind.h" 6 #include "base/callback_helpers.h" 7 #include "base/gtest_prod_util.h" 8 #include "base/memory/scoped_vector.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/stl_util.h" 11 #include "base/strings/stringprintf.h" 12 #include "media/base/audio_buffer.h" 13 #include "media/base/audio_timestamp_helper.h" 14 #include "media/base/gmock_callback_support.h" 15 #include "media/base/mock_audio_renderer_sink.h" 16 #include "media/base/mock_filters.h" 17 #include "media/base/test_helpers.h" 18 #include "media/filters/audio_renderer_impl.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 using ::base::Time; 22 using ::base::TimeTicks; 23 using ::base::TimeDelta; 24 using ::testing::_; 25 using ::testing::AnyNumber; 26 using ::testing::Invoke; 27 using ::testing::Return; 28 using ::testing::NiceMock; 29 using ::testing::StrictMock; 30 31 namespace media { 32 33 // Constants to specify the type of audio data used. 34 static AudioCodec kCodec = kCodecVorbis; 35 static SampleFormat kSampleFormat = kSampleFormatPlanarF32; 36 static ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; 37 static int kChannels = ChannelLayoutToChannelCount(kChannelLayout); 38 static int kSamplesPerSecond = 44100; 39 40 // Constants for distinguishing between muted audio and playing audio when using 41 // ConsumeBufferedData(). Must match the type needed by kSampleFormat. 42 static float kMutedAudio = 0.0f; 43 static float kPlayingAudio = 0.5f; 44 45 class AudioRendererImplTest : public ::testing::Test { 46 public: 47 // Give the decoder some non-garbage media properties. 48 AudioRendererImplTest() 49 : demuxer_stream_(DemuxerStream::AUDIO), 50 decoder_(new MockAudioDecoder()) { 51 AudioDecoderConfig audio_config(kCodec, 52 kSampleFormat, 53 kChannelLayout, 54 kSamplesPerSecond, 55 NULL, 56 0, 57 false); 58 demuxer_stream_.set_audio_decoder_config(audio_config); 59 60 // Used to save callbacks and run them at a later time. 61 EXPECT_CALL(*decoder_, Read(_)) 62 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ReadDecoder)); 63 64 // Set up audio properties. 65 EXPECT_CALL(*decoder_, bits_per_channel()) 66 .WillRepeatedly(Return(audio_config.bits_per_channel())); 67 EXPECT_CALL(*decoder_, channel_layout()) 68 .WillRepeatedly(Return(audio_config.channel_layout())); 69 EXPECT_CALL(*decoder_, samples_per_second()) 70 .WillRepeatedly(Return(audio_config.samples_per_second())); 71 72 ScopedVector<AudioDecoder> decoders; 73 decoders.push_back(decoder_); 74 75 renderer_.reset(new AudioRendererImpl( 76 message_loop_.message_loop_proxy(), 77 new NiceMock<MockAudioRendererSink>(), 78 decoders.Pass(), 79 SetDecryptorReadyCB(), 80 false)); 81 82 // Stub out time. 83 renderer_->set_now_cb_for_testing(base::Bind( 84 &AudioRendererImplTest::GetTime, base::Unretained(this))); 85 } 86 87 virtual ~AudioRendererImplTest() { 88 SCOPED_TRACE("~AudioRendererImplTest()"); 89 WaitableMessageLoopEvent event; 90 renderer_->Stop(event.GetClosure()); 91 event.RunAndWait(); 92 } 93 94 void ExpectUnsupportedAudioDecoder() { 95 EXPECT_CALL(*decoder_, Initialize(_, _, _)) 96 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); 97 } 98 99 void ExpectUnsupportedAudioDecoderConfig() { 100 EXPECT_CALL(*decoder_, bits_per_channel()) 101 .WillRepeatedly(Return(3)); 102 EXPECT_CALL(*decoder_, channel_layout()) 103 .WillRepeatedly(Return(CHANNEL_LAYOUT_UNSUPPORTED)); 104 EXPECT_CALL(*decoder_, samples_per_second()) 105 .WillRepeatedly(Return(0)); 106 EXPECT_CALL(*decoder_, Initialize(_, _, _)) 107 .WillOnce(RunCallback<1>(PIPELINE_OK)); 108 } 109 110 MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&)); 111 MOCK_METHOD0(OnUnderflow, void()); 112 MOCK_METHOD0(OnDisabled, void()); 113 MOCK_METHOD1(OnError, void(PipelineStatus)); 114 115 void OnAudioTimeCallback(TimeDelta current_time, TimeDelta max_time) { 116 CHECK(current_time <= max_time); 117 } 118 119 void Initialize() { 120 EXPECT_CALL(*decoder_, Initialize(_, _, _)) 121 .WillOnce(RunCallback<1>(PIPELINE_OK)); 122 123 InitializeWithStatus(PIPELINE_OK); 124 125 next_timestamp_.reset( 126 new AudioTimestampHelper(decoder_->samples_per_second())); 127 } 128 129 void InitializeWithStatus(PipelineStatus expected) { 130 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected)); 131 132 WaitableMessageLoopEvent event; 133 renderer_->Initialize( 134 &demuxer_stream_, 135 event.GetPipelineStatusCB(), 136 base::Bind(&AudioRendererImplTest::OnStatistics, 137 base::Unretained(this)), 138 base::Bind(&AudioRendererImplTest::OnUnderflow, 139 base::Unretained(this)), 140 base::Bind(&AudioRendererImplTest::OnAudioTimeCallback, 141 base::Unretained(this)), 142 ended_event_.GetClosure(), 143 base::Bind(&AudioRendererImplTest::OnDisabled, 144 base::Unretained(this)), 145 base::Bind(&AudioRendererImplTest::OnError, 146 base::Unretained(this))); 147 event.RunAndWaitForStatus(expected); 148 149 // We should have no reads. 150 EXPECT_TRUE(read_cb_.is_null()); 151 } 152 153 void Preroll() { 154 Preroll(0, PIPELINE_OK); 155 } 156 157 void Preroll(int timestamp_ms, PipelineStatus expected) { 158 SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected)); 159 160 TimeDelta timestamp = TimeDelta::FromMilliseconds(timestamp_ms); 161 next_timestamp_->SetBaseTimestamp(timestamp); 162 163 // Fill entire buffer to complete prerolling. 164 WaitableMessageLoopEvent event; 165 renderer_->Preroll(timestamp, event.GetPipelineStatusCB()); 166 WaitForPendingRead(); 167 DeliverRemainingAudio(); 168 event.RunAndWaitForStatus(PIPELINE_OK); 169 170 // We should have no reads. 171 EXPECT_TRUE(read_cb_.is_null()); 172 } 173 174 void Play() { 175 SCOPED_TRACE("Play()"); 176 WaitableMessageLoopEvent event; 177 renderer_->Play(event.GetClosure()); 178 renderer_->SetPlaybackRate(1.0f); 179 event.RunAndWait(); 180 } 181 182 void WaitForEnded() { 183 SCOPED_TRACE("WaitForEnded()"); 184 ended_event_.RunAndWait(); 185 } 186 187 void WaitForPendingRead() { 188 SCOPED_TRACE("WaitForPendingRead()"); 189 if (!read_cb_.is_null()) 190 return; 191 192 DCHECK(wait_for_pending_read_cb_.is_null()); 193 194 WaitableMessageLoopEvent event; 195 wait_for_pending_read_cb_ = event.GetClosure(); 196 event.RunAndWait(); 197 198 DCHECK(!read_cb_.is_null()); 199 DCHECK(wait_for_pending_read_cb_.is_null()); 200 } 201 202 // Delivers |size| frames with value kPlayingAudio to |renderer_|. 203 void SatisfyPendingRead(size_t size) { 204 CHECK(!read_cb_.is_null()); 205 206 scoped_refptr<AudioBuffer> buffer = 207 MakePlanarAudioBuffer<float>(kSampleFormat, 208 kChannels, 209 kPlayingAudio, 210 0.0f, 211 size, 212 next_timestamp_->GetTimestamp(), 213 next_timestamp_->GetFrameDuration(size)); 214 next_timestamp_->AddFrames(size); 215 216 DeliverBuffer(AudioDecoder::kOk, buffer); 217 } 218 219 void AbortPendingRead() { 220 DeliverBuffer(AudioDecoder::kAborted, NULL); 221 } 222 223 void DeliverEndOfStream() { 224 DeliverBuffer(AudioDecoder::kOk, AudioBuffer::CreateEOSBuffer()); 225 } 226 227 // Delivers frames until |renderer_|'s internal buffer is full and no longer 228 // has pending reads. 229 void DeliverRemainingAudio() { 230 SatisfyPendingRead(frames_remaining_in_buffer()); 231 } 232 233 // Attempts to consume |requested_frames| frames from |renderer_|'s internal 234 // buffer, returning true if all |requested_frames| frames were consumed, 235 // false if less than |requested_frames| frames were consumed. 236 // 237 // |muted| is optional and if passed will get set if the value of 238 // the consumed data is muted audio. 239 bool ConsumeBufferedData(uint32 requested_frames, bool* muted) { 240 scoped_ptr<AudioBus> bus = 241 AudioBus::Create(kChannels, std::max(requested_frames, 1u)); 242 uint32 frames_read = renderer_->FillBuffer(bus.get(), requested_frames, 0); 243 244 if (muted) 245 *muted = frames_read < 1 || bus->channel(0)[0] == kMutedAudio; 246 return frames_read == requested_frames; 247 } 248 249 // Attempts to consume all data available from the renderer. Returns the 250 // number of frames read. Since time is frozen, the audio delay will increase 251 // as frames come in. 252 int ConsumeAllBufferedData() { 253 renderer_->DisableUnderflowForTesting(); 254 255 int frames_read = 0; 256 int total_frames_read = 0; 257 258 const int kRequestFrames = 1024; 259 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kRequestFrames); 260 261 do { 262 TimeDelta audio_delay = TimeDelta::FromMicroseconds( 263 total_frames_read * Time::kMicrosecondsPerSecond / 264 static_cast<float>(decoder_->samples_per_second())); 265 266 frames_read = renderer_->FillBuffer( 267 bus.get(), kRequestFrames, audio_delay.InMilliseconds()); 268 total_frames_read += frames_read; 269 } while (frames_read > 0); 270 271 return total_frames_read; 272 } 273 274 uint32 frames_buffered() { 275 return renderer_->algorithm_->frames_buffered(); 276 } 277 278 uint32 buffer_capacity() { 279 return renderer_->algorithm_->QueueCapacity(); 280 } 281 282 uint32 frames_remaining_in_buffer() { 283 // This can happen if too much data was delivered, in which case the buffer 284 // will accept the data but not increase capacity. 285 if (frames_buffered() > buffer_capacity()) { 286 return 0; 287 } 288 return buffer_capacity() - frames_buffered(); 289 } 290 291 void CallResumeAfterUnderflow() { 292 renderer_->ResumeAfterUnderflow(); 293 } 294 295 TimeDelta CalculatePlayTime(int frames_filled) { 296 return TimeDelta::FromMicroseconds( 297 frames_filled * Time::kMicrosecondsPerSecond / 298 renderer_->audio_parameters_.sample_rate()); 299 } 300 301 void EndOfStreamTest(float playback_rate) { 302 Initialize(); 303 Preroll(); 304 Play(); 305 renderer_->SetPlaybackRate(playback_rate); 306 307 // Drain internal buffer, we should have a pending read. 308 int total_frames = frames_buffered(); 309 int frames_filled = ConsumeAllBufferedData(); 310 WaitForPendingRead(); 311 312 // Due to how the cross-fade algorithm works we won't get an exact match 313 // between the ideal and expected number of frames consumed. In the faster 314 // than normal playback case, more frames are created than should exist and 315 // vice versa in the slower than normal playback case. 316 const float kEpsilon = 0.20 * (total_frames / playback_rate); 317 EXPECT_NEAR(frames_filled, total_frames / playback_rate, kEpsilon); 318 319 // Figure out how long until the ended event should fire. 320 TimeDelta audio_play_time = CalculatePlayTime(frames_filled); 321 DVLOG(1) << "audio_play_time = " << audio_play_time.InSecondsF(); 322 323 // Fulfill the read with an end-of-stream packet. We shouldn't report ended 324 // nor have a read until we drain the internal buffer. 325 DeliverEndOfStream(); 326 327 // Advance time half way without an ended expectation. 328 AdvanceTime(audio_play_time / 2); 329 ConsumeBufferedData(frames_buffered(), NULL); 330 331 // Advance time by other half and expect the ended event. 332 AdvanceTime(audio_play_time / 2); 333 ConsumeBufferedData(frames_buffered(), NULL); 334 WaitForEnded(); 335 } 336 337 void AdvanceTime(TimeDelta time) { 338 base::AutoLock auto_lock(lock_); 339 time_ += time; 340 } 341 342 // Fixture members. 343 base::MessageLoop message_loop_; 344 scoped_ptr<AudioRendererImpl> renderer_; 345 346 private: 347 TimeTicks GetTime() { 348 base::AutoLock auto_lock(lock_); 349 return time_; 350 } 351 352 void ReadDecoder(const AudioDecoder::ReadCB& read_cb) { 353 // TODO(scherkus): Make this a DCHECK after threading semantics are fixed. 354 if (base::MessageLoop::current() != &message_loop_) { 355 message_loop_.PostTask(FROM_HERE, base::Bind( 356 &AudioRendererImplTest::ReadDecoder, 357 base::Unretained(this), read_cb)); 358 return; 359 } 360 361 CHECK(read_cb_.is_null()) << "Overlapping reads are not permitted"; 362 read_cb_ = read_cb; 363 364 // Wake up WaitForPendingRead() if needed. 365 if (!wait_for_pending_read_cb_.is_null()) 366 base::ResetAndReturn(&wait_for_pending_read_cb_).Run(); 367 } 368 369 void DeliverBuffer(AudioDecoder::Status status, 370 const scoped_refptr<AudioBuffer>& buffer) { 371 CHECK(!read_cb_.is_null()); 372 base::ResetAndReturn(&read_cb_).Run(status, buffer); 373 } 374 375 MockDemuxerStream demuxer_stream_; 376 MockAudioDecoder* decoder_; 377 378 // Used for stubbing out time in the audio callback thread. 379 base::Lock lock_; 380 TimeTicks time_; 381 382 // Used for satisfying reads. 383 AudioDecoder::ReadCB read_cb_; 384 scoped_ptr<AudioTimestampHelper> next_timestamp_; 385 386 WaitableMessageLoopEvent ended_event_; 387 388 // Run during ReadDecoder() to unblock WaitForPendingRead(). 389 base::Closure wait_for_pending_read_cb_; 390 391 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); 392 }; 393 394 TEST_F(AudioRendererImplTest, Initialize_Failed) { 395 ExpectUnsupportedAudioDecoderConfig(); 396 InitializeWithStatus(PIPELINE_ERROR_INITIALIZATION_FAILED); 397 } 398 399 TEST_F(AudioRendererImplTest, Initialize_Successful) { 400 Initialize(); 401 } 402 403 TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) { 404 ExpectUnsupportedAudioDecoder(); 405 InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED); 406 } 407 408 TEST_F(AudioRendererImplTest, Preroll) { 409 Initialize(); 410 Preroll(); 411 } 412 413 TEST_F(AudioRendererImplTest, Play) { 414 Initialize(); 415 Preroll(); 416 Play(); 417 418 // Drain internal buffer, we should have a pending read. 419 EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); 420 WaitForPendingRead(); 421 } 422 423 TEST_F(AudioRendererImplTest, EndOfStream) { 424 EndOfStreamTest(1.0); 425 } 426 427 TEST_F(AudioRendererImplTest, EndOfStream_FasterPlaybackSpeed) { 428 EndOfStreamTest(2.0); 429 } 430 431 TEST_F(AudioRendererImplTest, EndOfStream_SlowerPlaybackSpeed) { 432 EndOfStreamTest(0.5); 433 } 434 435 TEST_F(AudioRendererImplTest, Underflow) { 436 Initialize(); 437 Preroll(); 438 Play(); 439 440 // Drain internal buffer, we should have a pending read. 441 EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); 442 WaitForPendingRead(); 443 444 // Verify the next FillBuffer() call triggers the underflow callback 445 // since the decoder hasn't delivered any data after it was drained. 446 const size_t kDataSize = 1024; 447 EXPECT_CALL(*this, OnUnderflow()); 448 EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); 449 450 renderer_->ResumeAfterUnderflow(); 451 452 // Verify after resuming that we're still not getting data. 453 bool muted = false; 454 EXPECT_EQ(0u, frames_buffered()); 455 EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); 456 EXPECT_TRUE(muted); 457 458 // Deliver data, we should get non-muted audio. 459 DeliverRemainingAudio(); 460 EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted)); 461 EXPECT_FALSE(muted); 462 } 463 464 TEST_F(AudioRendererImplTest, Underflow_EndOfStream) { 465 Initialize(); 466 Preroll(); 467 Play(); 468 469 // Figure out how long until the ended event should fire. Since 470 // ConsumeBufferedData() doesn't provide audio delay information, the time 471 // until the ended event fires is equivalent to the longest buffered section, 472 // which is the initial frames_buffered() read. 473 TimeDelta time_until_ended = CalculatePlayTime(frames_buffered()); 474 475 // Drain internal buffer, we should have a pending read. 476 EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); 477 WaitForPendingRead(); 478 479 // Verify the next FillBuffer() call triggers the underflow callback 480 // since the decoder hasn't delivered any data after it was drained. 481 const size_t kDataSize = 1024; 482 EXPECT_CALL(*this, OnUnderflow()); 483 EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); 484 485 // Deliver a little bit of data. 486 SatisfyPendingRead(kDataSize); 487 WaitForPendingRead(); 488 489 // Verify we're getting muted audio during underflow. 490 bool muted = false; 491 EXPECT_EQ(kDataSize, frames_buffered()); 492 EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); 493 EXPECT_TRUE(muted); 494 495 // Now deliver end of stream, we should get our little bit of data back. 496 DeliverEndOfStream(); 497 EXPECT_EQ(kDataSize, frames_buffered()); 498 EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted)); 499 EXPECT_FALSE(muted); 500 501 // Attempt to read to make sure we're truly at the end of stream. 502 AdvanceTime(time_until_ended); 503 EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); 504 EXPECT_TRUE(muted); 505 WaitForEnded(); 506 } 507 508 TEST_F(AudioRendererImplTest, Underflow_ResumeFromCallback) { 509 Initialize(); 510 Preroll(); 511 Play(); 512 513 // Drain internal buffer, we should have a pending read. 514 EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); 515 WaitForPendingRead(); 516 517 // Verify the next FillBuffer() call triggers the underflow callback 518 // since the decoder hasn't delivered any data after it was drained. 519 const size_t kDataSize = 1024; 520 EXPECT_CALL(*this, OnUnderflow()) 521 .WillOnce(Invoke(this, &AudioRendererImplTest::CallResumeAfterUnderflow)); 522 EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); 523 524 // Verify after resuming that we're still not getting data. 525 bool muted = false; 526 EXPECT_EQ(0u, frames_buffered()); 527 EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); 528 EXPECT_TRUE(muted); 529 530 // Deliver data, we should get non-muted audio. 531 DeliverRemainingAudio(); 532 EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted)); 533 EXPECT_FALSE(muted); 534 } 535 536 TEST_F(AudioRendererImplTest, AbortPendingRead_Preroll) { 537 Initialize(); 538 539 // Start prerolling and wait for a read. 540 WaitableMessageLoopEvent event; 541 renderer_->Preroll(TimeDelta(), event.GetPipelineStatusCB()); 542 WaitForPendingRead(); 543 544 // Simulate the decoder aborting the pending read. 545 AbortPendingRead(); 546 event.RunAndWaitForStatus(PIPELINE_OK); 547 548 // Preroll again to a different timestamp and verify it completed normally. 549 Preroll(1000, PIPELINE_OK); 550 } 551 552 TEST_F(AudioRendererImplTest, AbortPendingRead_Pause) { 553 Initialize(); 554 555 Preroll(); 556 Play(); 557 558 // Partially drain internal buffer so we get a pending read. 559 EXPECT_TRUE(ConsumeBufferedData(frames_buffered() / 2, NULL)); 560 WaitForPendingRead(); 561 562 // Start pausing. 563 WaitableMessageLoopEvent event; 564 renderer_->Pause(event.GetClosure()); 565 566 // Simulate the decoder aborting the pending read. 567 AbortPendingRead(); 568 event.RunAndWait(); 569 570 // Preroll again to a different timestamp and verify it completed normally. 571 Preroll(1000, PIPELINE_OK); 572 } 573 574 } // namespace media 575