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 |