| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/callback_helpers.h" | 6 #include "base/callback_helpers.h" |
| 7 #include "base/gtest_prod_util.h" | 7 #include "base/gtest_prod_util.h" |
| 8 #include "base/memory/scoped_vector.h" | 8 #include "base/memory/scoped_vector.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "media/filters/audio_renderer_impl.h" | 22 #include "media/filters/audio_renderer_impl.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 24 |
| 25 using ::base::Time; | 25 using ::base::Time; |
| 26 using ::base::TimeTicks; | 26 using ::base::TimeTicks; |
| 27 using ::base::TimeDelta; | 27 using ::base::TimeDelta; |
| 28 using ::testing::_; | 28 using ::testing::_; |
| 29 using ::testing::AnyNumber; | 29 using ::testing::AnyNumber; |
| 30 using ::testing::Invoke; | 30 using ::testing::Invoke; |
| 31 using ::testing::Return; | 31 using ::testing::Return; |
| 32 using ::testing::SaveArg; |
| 32 | 33 |
| 33 namespace media { | 34 namespace media { |
| 34 | 35 |
| 35 // Constants to specify the type of audio data used. | 36 // Constants to specify the type of audio data used. |
| 36 static AudioCodec kCodec = kCodecVorbis; | 37 static AudioCodec kCodec = kCodecVorbis; |
| 37 static SampleFormat kSampleFormat = kSampleFormatPlanarF32; | 38 static SampleFormat kSampleFormat = kSampleFormatPlanarF32; |
| 38 static ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; | 39 static ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; |
| 39 static int kChannelCount = 2; | 40 static int kChannelCount = 2; |
| 40 static int kChannels = ChannelLayoutToChannelCount(kChannelLayout); | 41 static int kChannels = ChannelLayoutToChannelCount(kChannelLayout); |
| 41 static int kSamplesPerSecond = 44100; | 42 static int kSamplesPerSecond = 44100; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 70 0, | 71 0, |
| 71 false); | 72 false); |
| 72 demuxer_stream_.set_audio_decoder_config(audio_config); | 73 demuxer_stream_.set_audio_decoder_config(audio_config); |
| 73 | 74 |
| 74 // Used to save callbacks and run them at a later time. | 75 // Used to save callbacks and run them at a later time. |
| 75 EXPECT_CALL(*decoder_, Decode(_, _)) | 76 EXPECT_CALL(*decoder_, Decode(_, _)) |
| 76 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder)); | 77 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder)); |
| 77 EXPECT_CALL(*decoder_, Reset(_)) | 78 EXPECT_CALL(*decoder_, Reset(_)) |
| 78 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder)); | 79 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder)); |
| 79 | 80 |
| 80 // Mock out demuxer reads | 81 // Mock out demuxer reads. |
| 81 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( | 82 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( |
| 82 RunCallback<0>(DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer())); | 83 RunCallback<0>(DemuxerStream::kOk, |
| 84 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); |
| 83 EXPECT_CALL(demuxer_stream_, SupportsConfigChanges()) | 85 EXPECT_CALL(demuxer_stream_, SupportsConfigChanges()) |
| 84 .WillRepeatedly(Return(true)); | 86 .WillRepeatedly(Return(true)); |
| 85 AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 87 AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 86 kChannelLayout, | 88 kChannelLayout, |
| 87 kOutputSamplesPerSecond, | 89 kOutputSamplesPerSecond, |
| 88 SampleFormatToBytesPerChannel(kSampleFormat) * 8, | 90 SampleFormatToBytesPerChannel(kSampleFormat) * 8, |
| 89 512); | 91 512); |
| 90 hardware_config_.UpdateOutputConfig(out_params); | 92 hardware_config_.UpdateOutputConfig(out_params); |
| 91 ScopedVector<AudioDecoder> decoders; | 93 ScopedVector<AudioDecoder> decoders; |
| 92 decoders.push_back(decoder_); | 94 decoders.push_back(decoder_); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 105 virtual ~AudioRendererImplTest() { | 107 virtual ~AudioRendererImplTest() { |
| 106 SCOPED_TRACE("~AudioRendererImplTest()"); | 108 SCOPED_TRACE("~AudioRendererImplTest()"); |
| 107 if (needs_stop_) { | 109 if (needs_stop_) { |
| 108 WaitableMessageLoopEvent event; | 110 WaitableMessageLoopEvent event; |
| 109 renderer_->Stop(event.GetClosure()); | 111 renderer_->Stop(event.GetClosure()); |
| 110 event.RunAndWait(); | 112 event.RunAndWait(); |
| 111 } | 113 } |
| 112 } | 114 } |
| 113 | 115 |
| 114 void ExpectUnsupportedAudioDecoder() { | 116 void ExpectUnsupportedAudioDecoder() { |
| 115 EXPECT_CALL(*decoder_, Initialize(_, _)) | 117 EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
| 116 .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); | 118 .WillOnce(DoAll(SaveArg<2>(&output_cb_), |
| 119 RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED))); |
| 117 } | 120 } |
| 118 | 121 |
| 119 MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&)); | 122 MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&)); |
| 120 MOCK_METHOD0(OnUnderflow, void()); | 123 MOCK_METHOD0(OnUnderflow, void()); |
| 121 MOCK_METHOD1(OnError, void(PipelineStatus)); | 124 MOCK_METHOD1(OnError, void(PipelineStatus)); |
| 122 | 125 |
| 123 void OnAudioTimeCallback(TimeDelta current_time, TimeDelta max_time) { | 126 void OnAudioTimeCallback(TimeDelta current_time, TimeDelta max_time) { |
| 124 CHECK(current_time <= max_time); | 127 CHECK(current_time <= max_time); |
| 125 last_time_update_ = current_time; | 128 last_time_update_ = current_time; |
| 126 } | 129 } |
| 127 | 130 |
| 128 void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) { | 131 void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) { |
| 129 renderer_->Initialize( | 132 renderer_->Initialize( |
| 130 &demuxer_stream_, | 133 &demuxer_stream_, |
| 131 pipeline_status_cb, | 134 pipeline_status_cb, |
| 132 base::Bind(&AudioRendererImplTest::OnStatistics, | 135 base::Bind(&AudioRendererImplTest::OnStatistics, |
| 133 base::Unretained(this)), | 136 base::Unretained(this)), |
| 134 base::Bind(&AudioRendererImplTest::OnUnderflow, | 137 base::Bind(&AudioRendererImplTest::OnUnderflow, |
| 135 base::Unretained(this)), | 138 base::Unretained(this)), |
| 136 base::Bind(&AudioRendererImplTest::OnAudioTimeCallback, | 139 base::Bind(&AudioRendererImplTest::OnAudioTimeCallback, |
| 137 base::Unretained(this)), | 140 base::Unretained(this)), |
| 138 ended_event_.GetClosure(), | 141 ended_event_.GetClosure(), |
| 139 base::Bind(&AudioRendererImplTest::OnError, | 142 base::Bind(&AudioRendererImplTest::OnError, |
| 140 base::Unretained(this))); | 143 base::Unretained(this))); |
| 141 } | 144 } |
| 142 | 145 |
| 143 void Initialize() { | 146 void Initialize() { |
| 144 EXPECT_CALL(*decoder_, Initialize(_, _)) | 147 EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
| 145 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 148 .WillOnce(DoAll(SaveArg<2>(&output_cb_), |
| 149 RunCallback<1>(PIPELINE_OK))); |
| 146 EXPECT_CALL(*decoder_, Stop()); | 150 EXPECT_CALL(*decoder_, Stop()); |
| 147 InitializeWithStatus(PIPELINE_OK); | 151 InitializeWithStatus(PIPELINE_OK); |
| 148 | 152 |
| 149 next_timestamp_.reset(new AudioTimestampHelper( | 153 next_timestamp_.reset(new AudioTimestampHelper( |
| 150 hardware_config_.GetOutputConfig().sample_rate())); | 154 hardware_config_.GetOutputConfig().sample_rate())); |
| 151 } | 155 } |
| 152 | 156 |
| 153 void InitializeWithStatus(PipelineStatus expected) { | 157 void InitializeWithStatus(PipelineStatus expected) { |
| 154 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected)); | 158 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected)); |
| 155 | 159 |
| 156 WaitableMessageLoopEvent event; | 160 WaitableMessageLoopEvent event; |
| 157 InitializeRenderer(event.GetPipelineStatusCB()); | 161 InitializeRenderer(event.GetPipelineStatusCB()); |
| 158 event.RunAndWaitForStatus(expected); | 162 event.RunAndWaitForStatus(expected); |
| 159 | 163 |
| 160 // We should have no reads. | 164 // We should have no reads. |
| 161 EXPECT_TRUE(decode_cb_.is_null()); | 165 EXPECT_TRUE(decode_cb_.is_null()); |
| 162 } | 166 } |
| 163 | 167 |
| 164 void InitializeAndStop() { | 168 void InitializeAndStop() { |
| 165 EXPECT_CALL(*decoder_, Initialize(_, _)) | 169 EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
| 166 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 170 .WillOnce(DoAll(SaveArg<2>(&output_cb_), |
| 171 RunCallback<1>(PIPELINE_OK))); |
| 167 EXPECT_CALL(*decoder_, Stop()); | 172 EXPECT_CALL(*decoder_, Stop()); |
| 168 | 173 |
| 169 WaitableMessageLoopEvent event; | 174 WaitableMessageLoopEvent event; |
| 170 InitializeRenderer(event.GetPipelineStatusCB()); | 175 InitializeRenderer(event.GetPipelineStatusCB()); |
| 171 | 176 |
| 172 // Stop before we let the MessageLoop run, this simulates an interleaving | 177 // Stop before we let the MessageLoop run, this simulates an interleaving |
| 173 // in which we end up calling Stop() while the OnDecoderSelected callback | 178 // in which we end up calling Stop() while the OnDecoderSelected callback |
| 174 // is in flight. | 179 // is in flight. |
| 175 renderer_->Stop(NewExpectedClosure()); | 180 renderer_->Stop(NewExpectedClosure()); |
| 176 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); | 181 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); |
| 177 EXPECT_EQ(renderer_->state_, AudioRendererImpl::kStopped); | 182 EXPECT_EQ(renderer_->state_, AudioRendererImpl::kStopped); |
| 178 } | 183 } |
| 179 | 184 |
| 180 void InitializeAndStopDuringDecoderInit() { | 185 void InitializeAndStopDuringDecoderInit() { |
| 181 EXPECT_CALL(*decoder_, Initialize(_, _)) | 186 EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
| 182 .WillOnce(EnterPendingDecoderInitStateAction(this)); | 187 .WillOnce(DoAll(SaveArg<2>(&output_cb_), |
| 188 EnterPendingDecoderInitStateAction(this))); |
| 183 EXPECT_CALL(*decoder_, Stop()); | 189 EXPECT_CALL(*decoder_, Stop()); |
| 184 | 190 |
| 185 WaitableMessageLoopEvent event; | 191 WaitableMessageLoopEvent event; |
| 186 InitializeRenderer(event.GetPipelineStatusCB()); | 192 InitializeRenderer(event.GetPipelineStatusCB()); |
| 187 | 193 |
| 188 base::RunLoop().RunUntilIdle(); | 194 base::RunLoop().RunUntilIdle(); |
| 189 DCHECK(!init_decoder_cb_.is_null()); | 195 DCHECK(!init_decoder_cb_.is_null()); |
| 190 | 196 |
| 191 renderer_->Stop(NewExpectedClosure()); | 197 renderer_->Stop(NewExpectedClosure()); |
| 192 base::ResetAndReturn(&init_decoder_cb_).Run(PIPELINE_OK); | 198 base::ResetAndReturn(&init_decoder_cb_).Run(PIPELINE_OK); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 216 | 222 |
| 217 TimeDelta timestamp = TimeDelta::FromMilliseconds(timestamp_ms); | 223 TimeDelta timestamp = TimeDelta::FromMilliseconds(timestamp_ms); |
| 218 next_timestamp_->SetBaseTimestamp(timestamp); | 224 next_timestamp_->SetBaseTimestamp(timestamp); |
| 219 | 225 |
| 220 // Fill entire buffer to complete prerolling. | 226 // Fill entire buffer to complete prerolling. |
| 221 WaitableMessageLoopEvent event; | 227 WaitableMessageLoopEvent event; |
| 222 renderer_->Preroll(timestamp, event.GetPipelineStatusCB()); | 228 renderer_->Preroll(timestamp, event.GetPipelineStatusCB()); |
| 223 WaitForPendingRead(); | 229 WaitForPendingRead(); |
| 224 DeliverRemainingAudio(); | 230 DeliverRemainingAudio(); |
| 225 event.RunAndWaitForStatus(PIPELINE_OK); | 231 event.RunAndWaitForStatus(PIPELINE_OK); |
| 226 | |
| 227 // We should have no reads. | |
| 228 EXPECT_TRUE(decode_cb_.is_null()); | |
| 229 } | 232 } |
| 230 | 233 |
| 231 void StartRendering() { | 234 void StartRendering() { |
| 232 renderer_->StartRendering(); | 235 renderer_->StartRendering(); |
| 233 renderer_->SetPlaybackRate(1.0f); | 236 renderer_->SetPlaybackRate(1.0f); |
| 234 } | 237 } |
| 235 | 238 |
| 236 void StopRendering() { | 239 void StopRendering() { |
| 237 renderer_->StopRendering(); | 240 renderer_->StopRendering(); |
| 238 } | 241 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 kSamplesPerSecond, | 282 kSamplesPerSecond, |
| 280 kPlayingAudio, | 283 kPlayingAudio, |
| 281 0.0f, | 284 0.0f, |
| 282 size, | 285 size, |
| 283 next_timestamp_->GetTimestamp()); | 286 next_timestamp_->GetTimestamp()); |
| 284 next_timestamp_->AddFrames(size); | 287 next_timestamp_->AddFrames(size); |
| 285 | 288 |
| 286 DeliverBuffer(AudioDecoder::kOk, buffer); | 289 DeliverBuffer(AudioDecoder::kOk, buffer); |
| 287 } | 290 } |
| 288 | 291 |
| 289 void AbortPendingRead() { | |
| 290 DeliverBuffer(AudioDecoder::kAborted, NULL); | |
| 291 } | |
| 292 | |
| 293 void DeliverEndOfStream() { | 292 void DeliverEndOfStream() { |
| 294 DeliverBuffer(AudioDecoder::kOk, AudioBuffer::CreateEOSBuffer()); | 293 // Repeatedly return EOS buffer |
| 294 while (!decode_cb_.is_null()) { |
| 295 DeliverBuffer(AudioDecoder::kOk, AudioBuffer::CreateEOSBuffer()); |
| 296 } |
| 295 } | 297 } |
| 296 | 298 |
| 297 // Delivers frames until |renderer_|'s internal buffer is full and no longer | 299 // Delivers frames until |renderer_|'s internal buffer is full and no longer |
| 298 // has pending reads. | 300 // has pending reads. |
| 299 void DeliverRemainingAudio() { | 301 void DeliverRemainingAudio() { |
| 300 SatisfyPendingRead(frames_remaining_in_buffer()); | 302 SatisfyPendingRead(frames_remaining_in_buffer()); |
| 301 } | 303 } |
| 302 | 304 |
| 303 // Attempts to consume |requested_frames| frames from |renderer_|'s internal | 305 // Attempts to consume |requested_frames| frames from |renderer_|'s internal |
| 304 // buffer, returning true if all |requested_frames| frames were consumed, | 306 // buffer, returning true if all |requested_frames| frames were consumed, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 | 460 |
| 459 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not permitted"; | 461 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not permitted"; |
| 460 decode_cb_ = decode_cb; | 462 decode_cb_ = decode_cb; |
| 461 | 463 |
| 462 // Wake up WaitForPendingRead() if needed. | 464 // Wake up WaitForPendingRead() if needed. |
| 463 if (!wait_for_pending_decode_cb_.is_null()) | 465 if (!wait_for_pending_decode_cb_.is_null()) |
| 464 base::ResetAndReturn(&wait_for_pending_decode_cb_).Run(); | 466 base::ResetAndReturn(&wait_for_pending_decode_cb_).Run(); |
| 465 } | 467 } |
| 466 | 468 |
| 467 void ResetDecoder(const base::Closure& reset_cb) { | 469 void ResetDecoder(const base::Closure& reset_cb) { |
| 468 CHECK(decode_cb_.is_null()) | 470 if (!decode_cb_.is_null()) { |
| 469 << "Reset overlapping with reads is not permitted"; | 471 // |reset_cb| will be called in DeliverBuffer(), after the decoder is |
| 472 // flushed. |
| 473 reset_cb_ = reset_cb; |
| 474 return; |
| 475 } |
| 470 | 476 |
| 471 message_loop_.PostTask(FROM_HERE, reset_cb); | 477 message_loop_.PostTask(FROM_HERE, reset_cb); |
| 472 } | 478 } |
| 473 | 479 |
| 474 void DeliverBuffer(AudioDecoder::Status status, | 480 void DeliverBuffer(AudioDecoder::Status status, |
| 475 const scoped_refptr<AudioBuffer>& buffer) { | 481 const scoped_refptr<AudioBuffer>& buffer) { |
| 476 CHECK(!decode_cb_.is_null()); | 482 CHECK(!decode_cb_.is_null()); |
| 477 base::ResetAndReturn(&decode_cb_).Run(status, buffer); | 483 if (buffer) |
| 484 output_cb_.Run(buffer); |
| 485 base::ResetAndReturn(&decode_cb_).Run(status); |
| 486 |
| 487 if (!reset_cb_.is_null()) |
| 488 base::ResetAndReturn(&reset_cb_).Run(); |
| 489 |
| 490 message_loop_.RunUntilIdle(); |
| 478 } | 491 } |
| 479 | 492 |
| 480 MockDemuxerStream demuxer_stream_; | 493 MockDemuxerStream demuxer_stream_; |
| 481 MockAudioDecoder* decoder_; | 494 MockAudioDecoder* decoder_; |
| 482 | 495 |
| 483 // Used for stubbing out time in the audio callback thread. | 496 // Used for stubbing out time in the audio callback thread. |
| 484 base::Lock lock_; | 497 base::Lock lock_; |
| 485 TimeTicks time_; | 498 TimeTicks time_; |
| 486 | 499 |
| 487 // Used for satisfying reads. | 500 // Used for satisfying reads. |
| 501 AudioDecoder::OutputCB output_cb_; |
| 488 AudioDecoder::DecodeCB decode_cb_; | 502 AudioDecoder::DecodeCB decode_cb_; |
| 503 base::Closure reset_cb_; |
| 489 scoped_ptr<AudioTimestampHelper> next_timestamp_; | 504 scoped_ptr<AudioTimestampHelper> next_timestamp_; |
| 490 | 505 |
| 491 WaitableMessageLoopEvent ended_event_; | 506 WaitableMessageLoopEvent ended_event_; |
| 492 | 507 |
| 493 // Run during DecodeDecoder() to unblock WaitForPendingRead(). | 508 // Run during DecodeDecoder() to unblock WaitForPendingRead(). |
| 494 base::Closure wait_for_pending_decode_cb_; | 509 base::Closure wait_for_pending_decode_cb_; |
| 495 base::Closure stop_decoder_cb_; | 510 base::Closure stop_decoder_cb_; |
| 496 | 511 |
| 497 PipelineStatusCB init_decoder_cb_; | 512 PipelineStatusCB init_decoder_cb_; |
| 498 base::TimeDelta last_time_update_; | 513 base::TimeDelta last_time_update_; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 EXPECT_CALL(*this, OnUnderflow()); | 602 EXPECT_CALL(*this, OnUnderflow()); |
| 588 EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); | 603 EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
| 589 | 604 |
| 590 // Verify that the buffer capacity increased as a result of resuming after | 605 // Verify that the buffer capacity increased as a result of resuming after |
| 591 // underflow. | 606 // underflow. |
| 592 EXPECT_EQ(buffer_capacity(), initial_capacity); | 607 EXPECT_EQ(buffer_capacity(), initial_capacity); |
| 593 renderer_->ResumeAfterUnderflow(); | 608 renderer_->ResumeAfterUnderflow(); |
| 594 EXPECT_GT(buffer_capacity(), initial_capacity); | 609 EXPECT_GT(buffer_capacity(), initial_capacity); |
| 595 | 610 |
| 596 // Verify that the buffer capacity is restored to the |initial_capacity|. | 611 // Verify that the buffer capacity is restored to the |initial_capacity|. |
| 597 AbortPendingRead(); | 612 DeliverEndOfStream(); |
| 598 Flush(); | 613 Flush(); |
| 599 EXPECT_EQ(buffer_capacity(), initial_capacity); | 614 EXPECT_EQ(buffer_capacity(), initial_capacity); |
| 600 } | 615 } |
| 601 | 616 |
| 602 TEST_F(AudioRendererImplTest, Underflow_FlushWhileUnderflowed) { | 617 TEST_F(AudioRendererImplTest, Underflow_FlushWhileUnderflowed) { |
| 603 Initialize(); | 618 Initialize(); |
| 604 Preroll(); | 619 Preroll(); |
| 605 StartRendering(); | 620 StartRendering(); |
| 606 | 621 |
| 607 // Drain internal buffer, we should have a pending read. | 622 // Drain internal buffer, we should have a pending read. |
| 608 EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); | 623 EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); |
| 609 WaitForPendingRead(); | 624 WaitForPendingRead(); |
| 610 | 625 |
| 611 // Verify the next FillBuffer() call triggers the underflow callback | 626 // Verify the next FillBuffer() call triggers the underflow callback |
| 612 // since the decoder hasn't delivered any data after it was drained. | 627 // since the decoder hasn't delivered any data after it was drained. |
| 613 EXPECT_CALL(*this, OnUnderflow()); | 628 EXPECT_CALL(*this, OnUnderflow()); |
| 614 EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); | 629 EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
| 615 | 630 |
| 616 // Verify that we can still Flush() before entering the rebuffering state. | 631 // Verify that we can still Flush() before entering the rebuffering state. |
| 617 AbortPendingRead(); | 632 DeliverEndOfStream(); |
| 618 Flush(); | 633 Flush(); |
| 619 } | 634 } |
| 620 | 635 |
| 621 TEST_F(AudioRendererImplTest, Underflow_EndOfStream) { | 636 TEST_F(AudioRendererImplTest, Underflow_EndOfStream) { |
| 622 Initialize(); | 637 Initialize(); |
| 623 Preroll(); | 638 Preroll(); |
| 624 StartRendering(); | 639 StartRendering(); |
| 625 | 640 |
| 626 // Figure out how long until the ended event should fire. Since | 641 // Figure out how long until the ended event should fire. Since |
| 627 // ConsumeBufferedData() doesn't provide audio delay information, the time | 642 // ConsumeBufferedData() doesn't provide audio delay information, the time |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 renderer_->SetPlaybackRate(0.0); | 766 renderer_->SetPlaybackRate(0.0); |
| 752 renderer_->SetPlaybackRate(1.0); | 767 renderer_->SetPlaybackRate(1.0); |
| 753 | 768 |
| 754 // Deliver data to resolve the underflow. | 769 // Deliver data to resolve the underflow. |
| 755 DeliverRemainingAudio(); | 770 DeliverRemainingAudio(); |
| 756 | 771 |
| 757 // We should have resumed playing now. | 772 // We should have resumed playing now. |
| 758 EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); | 773 EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
| 759 } | 774 } |
| 760 | 775 |
| 761 TEST_F(AudioRendererImplTest, AbortPendingRead_Preroll) { | |
| 762 Initialize(); | |
| 763 | |
| 764 // Start prerolling and wait for a read. | |
| 765 WaitableMessageLoopEvent event; | |
| 766 renderer_->Preroll(TimeDelta(), event.GetPipelineStatusCB()); | |
| 767 WaitForPendingRead(); | |
| 768 | |
| 769 // Simulate the decoder aborting the pending read. | |
| 770 AbortPendingRead(); | |
| 771 event.RunAndWaitForStatus(PIPELINE_OK); | |
| 772 | |
| 773 Flush(); | |
| 774 | |
| 775 // Preroll again to a different timestamp and verify it completed normally. | |
| 776 Preroll(1000, PIPELINE_OK); | |
| 777 } | |
| 778 | |
| 779 TEST_F(AudioRendererImplTest, AbortPendingRead_Flush) { | |
| 780 Initialize(); | |
| 781 | |
| 782 Preroll(); | |
| 783 StartRendering(); | |
| 784 | |
| 785 // Partially drain internal buffer so we get a pending read. | |
| 786 EXPECT_TRUE(ConsumeBufferedData(frames_buffered() / 2, NULL)); | |
| 787 WaitForPendingRead(); | |
| 788 | |
| 789 StopRendering(); | |
| 790 | |
| 791 EXPECT_TRUE(IsReadPending()); | |
| 792 | |
| 793 // Start flushing. | |
| 794 WaitableMessageLoopEvent flush_event; | |
| 795 renderer_->Flush(flush_event.GetClosure()); | |
| 796 | |
| 797 // Simulate the decoder aborting the pending read. | |
| 798 AbortPendingRead(); | |
| 799 flush_event.RunAndWait(); | |
| 800 | |
| 801 EXPECT_FALSE(IsReadPending()); | |
| 802 | |
| 803 // Preroll again to a different timestamp and verify it completed normally. | |
| 804 Preroll(1000, PIPELINE_OK); | |
| 805 } | |
| 806 | |
| 807 TEST_F(AudioRendererImplTest, PendingRead_Flush) { | 776 TEST_F(AudioRendererImplTest, PendingRead_Flush) { |
| 808 Initialize(); | 777 Initialize(); |
| 809 | 778 |
| 810 Preroll(); | 779 Preroll(); |
| 811 StartRendering(); | 780 StartRendering(); |
| 812 | 781 |
| 813 // Partially drain internal buffer so we get a pending read. | 782 // Partially drain internal buffer so we get a pending read. |
| 814 EXPECT_TRUE(ConsumeBufferedData(frames_buffered() / 2, NULL)); | 783 EXPECT_TRUE(ConsumeBufferedData(frames_buffered() / 2, NULL)); |
| 815 WaitForPendingRead(); | 784 WaitForPendingRead(); |
| 816 | 785 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 Preroll(); | 887 Preroll(); |
| 919 StartRendering(); | 888 StartRendering(); |
| 920 | 889 |
| 921 AudioTimestampHelper timestamp_helper(kOutputSamplesPerSecond); | 890 AudioTimestampHelper timestamp_helper(kOutputSamplesPerSecond); |
| 922 EXPECT_EQ(kNoTimestamp(), last_time_update()); | 891 EXPECT_EQ(kNoTimestamp(), last_time_update()); |
| 923 | 892 |
| 924 // Preroll() should be buffered some data, consume half of it now. | 893 // Preroll() should be buffered some data, consume half of it now. |
| 925 int frames_to_consume = frames_buffered() / 2; | 894 int frames_to_consume = frames_buffered() / 2; |
| 926 EXPECT_TRUE(ConsumeBufferedData(frames_to_consume, NULL)); | 895 EXPECT_TRUE(ConsumeBufferedData(frames_to_consume, NULL)); |
| 927 WaitForPendingRead(); | 896 WaitForPendingRead(); |
| 897 base::RunLoop().RunUntilIdle(); |
| 928 | 898 |
| 929 // ConsumeBufferedData() uses an audio delay of zero, so ensure we received | 899 // ConsumeBufferedData() uses an audio delay of zero, so ensure we received |
| 930 // a time update that's equal to |kFramesToConsume| from above. | 900 // a time update that's equal to |kFramesToConsume| from above. |
| 931 timestamp_helper.SetBaseTimestamp(base::TimeDelta()); | 901 timestamp_helper.SetBaseTimestamp(base::TimeDelta()); |
| 932 timestamp_helper.AddFrames(frames_to_consume); | 902 timestamp_helper.AddFrames(frames_to_consume); |
| 933 EXPECT_EQ(timestamp_helper.GetTimestamp(), last_time_update()); | 903 EXPECT_EQ(timestamp_helper.GetTimestamp(), last_time_update()); |
| 934 | 904 |
| 935 // The next time update should match the remaining frames_buffered(), but only | 905 // The next time update should match the remaining frames_buffered(), but only |
| 936 // after running the message loop. | 906 // after running the message loop. |
| 937 frames_to_consume = frames_buffered(); | 907 frames_to_consume = frames_buffered(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 // Start rendering with zero playback rate. Sink should be paused until | 968 // Start rendering with zero playback rate. Sink should be paused until |
| 999 // non-zero rate is set. | 969 // non-zero rate is set. |
| 1000 renderer_->SetPlaybackRate(0.0f); | 970 renderer_->SetPlaybackRate(0.0f); |
| 1001 renderer_->StartRendering(); | 971 renderer_->StartRendering(); |
| 1002 EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state()); | 972 EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state()); |
| 1003 renderer_->SetPlaybackRate(1.0f); | 973 renderer_->SetPlaybackRate(1.0f); |
| 1004 EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); | 974 EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
| 1005 } | 975 } |
| 1006 | 976 |
| 1007 } // namespace media | 977 } // namespace media |
| OLD | NEW |