| 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/message_loop.h" |
| 8 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 9 #include "media/base/data_buffer.h" | 10 #include "media/base/data_buffer.h" |
| 10 #include "media/base/mock_audio_renderer_sink.h" | 11 #include "media/base/mock_audio_renderer_sink.h" |
| 11 #include "media/base/mock_callback.h" | 12 #include "media/base/mock_callback.h" |
| 12 #include "media/base/mock_filters.h" | 13 #include "media/base/mock_filters.h" |
| 13 #include "media/filters/audio_renderer_impl.h" | 14 #include "media/filters/audio_renderer_impl.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 16 |
| 16 using ::testing::_; | 17 using ::testing::_; |
| 17 using ::testing::AnyNumber; | 18 using ::testing::AnyNumber; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 .Times(AnyNumber()); | 52 .Times(AnyNumber()); |
| 52 EXPECT_CALL(*decoder_, channel_layout()) | 53 EXPECT_CALL(*decoder_, channel_layout()) |
| 53 .Times(AnyNumber()); | 54 .Times(AnyNumber()); |
| 54 EXPECT_CALL(*decoder_, samples_per_second()) | 55 EXPECT_CALL(*decoder_, samples_per_second()) |
| 55 .Times(AnyNumber()); | 56 .Times(AnyNumber()); |
| 56 | 57 |
| 57 decoders_.push_back(decoder_); | 58 decoders_.push_back(decoder_); |
| 58 } | 59 } |
| 59 | 60 |
| 60 virtual ~AudioRendererImplTest() { | 61 virtual ~AudioRendererImplTest() { |
| 62 message_loop_.RunUntilIdle(); |
| 61 renderer_->Stop(NewExpectedClosure()); | 63 renderer_->Stop(NewExpectedClosure()); |
| 62 } | 64 } |
| 63 | 65 |
| 64 void SetSupportedAudioDecoderProperties() { | 66 void SetSupportedAudioDecoderProperties() { |
| 65 ON_CALL(*decoder_, bits_per_channel()) | 67 ON_CALL(*decoder_, bits_per_channel()) |
| 66 .WillByDefault(Return(16)); | 68 .WillByDefault(Return(16)); |
| 67 ON_CALL(*decoder_, channel_layout()) | 69 ON_CALL(*decoder_, channel_layout()) |
| 68 .WillByDefault(Return(CHANNEL_LAYOUT_MONO)); | 70 .WillByDefault(Return(CHANNEL_LAYOUT_MONO)); |
| 69 ON_CALL(*decoder_, samples_per_second()) | 71 ON_CALL(*decoder_, samples_per_second()) |
| 70 .WillByDefault(Return(44100)); | 72 .WillByDefault(Return(44100)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 94 void OnAudioTimeCallback( | 96 void OnAudioTimeCallback( |
| 95 base::TimeDelta current_time, base::TimeDelta max_time) { | 97 base::TimeDelta current_time, base::TimeDelta max_time) { |
| 96 CHECK(current_time <= max_time); | 98 CHECK(current_time <= max_time); |
| 97 } | 99 } |
| 98 | 100 |
| 99 void Initialize() { | 101 void Initialize() { |
| 100 EXPECT_CALL(*decoder_, Initialize(_, _, _)) | 102 EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
| 101 .WillOnce(RunPipelineStatusCB1(PIPELINE_OK)); | 103 .WillOnce(RunPipelineStatusCB1(PIPELINE_OK)); |
| 102 | 104 |
| 103 InitializeWithStatus(PIPELINE_OK); | 105 InitializeWithStatus(PIPELINE_OK); |
| 106 message_loop_.RunUntilIdle(); |
| 104 } | 107 } |
| 105 | 108 |
| 106 void InitializeWithStatus(PipelineStatus expected) { | 109 void InitializeWithStatus(PipelineStatus expected) { |
| 107 renderer_->Initialize( | 110 renderer_->Initialize( |
| 108 demuxer_stream_, | 111 demuxer_stream_, |
| 109 decoders_, | 112 decoders_, |
| 110 NewExpectedStatusCB(expected), | 113 NewExpectedStatusCB(expected), |
| 111 base::Bind(&AudioRendererImplTest::OnStatistics, | 114 base::Bind(&AudioRendererImplTest::OnStatistics, |
| 112 base::Unretained(this)), | 115 base::Unretained(this)), |
| 113 base::Bind(&AudioRendererImplTest::OnUnderflow, | 116 base::Bind(&AudioRendererImplTest::OnUnderflow, |
| 114 base::Unretained(this)), | 117 base::Unretained(this)), |
| 115 base::Bind(&AudioRendererImplTest::OnAudioTimeCallback, | 118 base::Bind(&AudioRendererImplTest::OnAudioTimeCallback, |
| 116 base::Unretained(this)), | 119 base::Unretained(this)), |
| 117 base::Bind(&AudioRendererImplTest::OnEnded, | 120 base::Bind(&AudioRendererImplTest::OnEnded, |
| 118 base::Unretained(this)), | 121 base::Unretained(this)), |
| 119 base::Bind(&AudioRendererImplTest::OnDisabled, | 122 base::Bind(&AudioRendererImplTest::OnDisabled, |
| 120 base::Unretained(this)), | 123 base::Unretained(this)), |
| 121 base::Bind(&AudioRendererImplTest::OnError, | 124 base::Bind(&AudioRendererImplTest::OnError, |
| 122 base::Unretained(this))); | 125 base::Unretained(this))); |
| 123 } | 126 } |
| 124 | 127 |
| 125 void Preroll() { | 128 void Preroll() { |
| 126 // Fill entire buffer to complete prerolling. | 129 // Fill entire buffer to complete prerolling. |
| 127 EXPECT_CALL(*decoder_, Read(_)); | 130 EXPECT_CALL(*decoder_, Read(_)); |
| 128 renderer_->Preroll(base::TimeDelta(), NewPrerollCB()); | 131 renderer_->Preroll(base::TimeDelta(), NewPrerollCB()); |
| 129 EXPECT_CALL(*this, OnPrerollComplete(PIPELINE_OK)); | 132 EXPECT_CALL(*this, OnPrerollComplete(PIPELINE_OK)); |
| 133 message_loop_.RunUntilIdle(); |
| 130 DeliverRemainingAudio(); | 134 DeliverRemainingAudio(); |
| 131 } | 135 } |
| 132 | 136 |
| 133 void Play() { | 137 void Play() { |
| 134 renderer_->Play(NewExpectedClosure()); | 138 renderer_->Play(NewExpectedClosure()); |
| 135 renderer_->SetPlaybackRate(1.0f); | 139 renderer_->SetPlaybackRate(1.0f); |
| 136 } | 140 } |
| 137 | 141 |
| 138 void Preroll(base::TimeDelta preroll_time) { | 142 void Preroll(base::TimeDelta preroll_time) { |
| 139 next_timestamp_ = preroll_time; | 143 next_timestamp_ = preroll_time; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 // |size| bytes were consumed. | 190 // |size| bytes were consumed. |
| 187 // | 191 // |
| 188 // |muted| is optional and if passed will get set if the byte value of | 192 // |muted| is optional and if passed will get set if the byte value of |
| 189 // the consumed data is muted audio. | 193 // the consumed data is muted audio. |
| 190 bool ConsumeBufferedData(uint32 size, bool* muted) { | 194 bool ConsumeBufferedData(uint32 size, bool* muted) { |
| 191 scoped_array<uint8> buffer(new uint8[size]); | 195 scoped_array<uint8> buffer(new uint8[size]); |
| 192 uint32 bytes_per_frame = (decoder_->bits_per_channel() / 8) * | 196 uint32 bytes_per_frame = (decoder_->bits_per_channel() / 8) * |
| 193 ChannelLayoutToChannelCount(decoder_->channel_layout()); | 197 ChannelLayoutToChannelCount(decoder_->channel_layout()); |
| 194 uint32 requested_frames = size / bytes_per_frame; | 198 uint32 requested_frames = size / bytes_per_frame; |
| 195 uint32 frames_read = renderer_->FillBuffer( | 199 uint32 frames_read = renderer_->FillBuffer( |
| 196 buffer.get(), requested_frames, base::TimeDelta()); | 200 buffer.get(), requested_frames, 0); |
| 197 | 201 |
| 198 if (frames_read > 0 && muted) { | 202 if (frames_read > 0 && muted) { |
| 199 *muted = (buffer[0] == kMutedAudio); | 203 *muted = (buffer[0] == kMutedAudio); |
| 200 } | 204 } |
| 201 return (frames_read == requested_frames); | 205 return (frames_read == requested_frames); |
| 202 } | 206 } |
| 203 | 207 |
| 204 uint32 bytes_buffered() { | 208 uint32 bytes_buffered() { |
| 205 return renderer_->algorithm_->bytes_buffered(); | 209 return renderer_->algorithm_->bytes_buffered(); |
| 206 } | 210 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 222 renderer_->ResumeAfterUnderflow(false); | 226 renderer_->ResumeAfterUnderflow(false); |
| 223 } | 227 } |
| 224 | 228 |
| 225 // Fixture members. | 229 // Fixture members. |
| 226 scoped_refptr<AudioRendererImpl> renderer_; | 230 scoped_refptr<AudioRendererImpl> renderer_; |
| 227 scoped_refptr<MockDemuxerStream> demuxer_stream_; | 231 scoped_refptr<MockDemuxerStream> demuxer_stream_; |
| 228 scoped_refptr<MockAudioDecoder> decoder_; | 232 scoped_refptr<MockAudioDecoder> decoder_; |
| 229 AudioRendererImpl::AudioDecoderList decoders_; | 233 AudioRendererImpl::AudioDecoderList decoders_; |
| 230 AudioDecoder::ReadCB read_cb_; | 234 AudioDecoder::ReadCB read_cb_; |
| 231 base::TimeDelta next_timestamp_; | 235 base::TimeDelta next_timestamp_; |
| 236 MessageLoop message_loop_; |
| 232 | 237 |
| 233 private: | 238 private: |
| 234 void SaveReadCallback(const AudioDecoder::ReadCB& callback) { | 239 void SaveReadCallback(const AudioDecoder::ReadCB& callback) { |
| 235 CHECK(read_cb_.is_null()) << "Overlapping reads are not permitted"; | 240 CHECK(read_cb_.is_null()) << "Overlapping reads are not permitted"; |
| 236 read_cb_ = callback; | 241 read_cb_ = callback; |
| 237 } | 242 } |
| 238 | 243 |
| 239 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); | 244 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); |
| 240 }; | 245 }; |
| 241 | 246 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 EXPECT_CALL(*decoder_, Read(_)); | 299 EXPECT_CALL(*decoder_, Read(_)); |
| 295 EXPECT_TRUE(ConsumeBufferedData(bytes_buffered(), NULL)); | 300 EXPECT_TRUE(ConsumeBufferedData(bytes_buffered(), NULL)); |
| 296 } | 301 } |
| 297 | 302 |
| 298 TEST_F(AudioRendererImplTest, EndOfStream) { | 303 TEST_F(AudioRendererImplTest, EndOfStream) { |
| 299 Initialize(); | 304 Initialize(); |
| 300 Preroll(); | 305 Preroll(); |
| 301 Play(); | 306 Play(); |
| 302 | 307 |
| 303 // Drain internal buffer, we should have a pending read. | 308 // Drain internal buffer, we should have a pending read. |
| 309 int audio_bytes_filled = bytes_buffered(); |
| 304 EXPECT_CALL(*decoder_, Read(_)); | 310 EXPECT_CALL(*decoder_, Read(_)); |
| 305 EXPECT_TRUE(ConsumeBufferedData(bytes_buffered(), NULL)); | 311 EXPECT_TRUE(ConsumeBufferedData(audio_bytes_filled, NULL)); |
| 312 |
| 313 // Check and clear |earliest_end_time_| so the ended event fires on the next |
| 314 // ConsumeBufferedData() call. |
| 315 base::TimeDelta audio_play_time = base::TimeDelta::FromMicroseconds( |
| 316 audio_bytes_filled * base::Time::kMicrosecondsPerSecond / |
| 317 static_cast<float>(renderer_->audio_parameters_.GetBytesPerSecond())); |
| 318 base::TimeDelta time_until_ended = |
| 319 renderer_->earliest_end_time_ - base::Time::Now(); |
| 320 EXPECT_TRUE(time_until_ended > base::TimeDelta()); |
| 321 EXPECT_TRUE(time_until_ended <= audio_play_time); |
| 322 renderer_->earliest_end_time_ = base::Time(); |
| 306 | 323 |
| 307 // Fulfill the read with an end-of-stream packet, we shouldn't report ended | 324 // Fulfill the read with an end-of-stream packet, we shouldn't report ended |
| 308 // nor have a read until we drain the internal buffer. | 325 // nor have a read until we drain the internal buffer. |
| 309 DeliverEndOfStream(); | 326 DeliverEndOfStream(); |
| 310 | 327 |
| 311 // Drain internal buffer, now we should report ended. | 328 // Drain internal buffer, now we should report ended. |
| 312 EXPECT_CALL(*this, OnEnded()); | 329 EXPECT_CALL(*this, OnEnded()); |
| 313 EXPECT_TRUE(ConsumeBufferedData(bytes_buffered(), NULL)); | 330 EXPECT_TRUE(ConsumeBufferedData(bytes_buffered(), NULL)); |
| 314 } | 331 } |
| 315 | 332 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 | 400 |
| 384 // Deliver another end of stream buffer and attempt to read to make sure | 401 // Deliver another end of stream buffer and attempt to read to make sure |
| 385 // we're truly at the end of stream. | 402 // we're truly at the end of stream. |
| 386 // | 403 // |
| 387 // TODO(scherkus): fix AudioRendererImpl and AudioRendererAlgorithmBase to | 404 // TODO(scherkus): fix AudioRendererImpl and AudioRendererAlgorithmBase to |
| 388 // stop reading after receiving an end of stream buffer. It should have also | 405 // stop reading after receiving an end of stream buffer. It should have also |
| 389 // fired the ended callback http://crbug.com/106641 | 406 // fired the ended callback http://crbug.com/106641 |
| 390 DeliverEndOfStream(); | 407 DeliverEndOfStream(); |
| 391 EXPECT_CALL(*this, OnEnded()); | 408 EXPECT_CALL(*this, OnEnded()); |
| 392 | 409 |
| 410 // Clear |earliest_end_time_| so ended fires on the next ConsumeBufferedData() |
| 411 // call. |
| 412 renderer_->earliest_end_time_ = base::Time(); |
| 413 |
| 393 EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); | 414 EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); |
| 394 EXPECT_FALSE(muted); | 415 EXPECT_FALSE(muted); |
| 395 } | 416 } |
| 396 | 417 |
| 397 TEST_F(AudioRendererImplTest, Underflow_ResumeFromCallback) { | 418 TEST_F(AudioRendererImplTest, Underflow_ResumeFromCallback) { |
| 398 Initialize(); | 419 Initialize(); |
| 399 Preroll(); | 420 Preroll(); |
| 400 Play(); | 421 Play(); |
| 401 | 422 |
| 402 // Drain internal buffer, we should have a pending read. | 423 // Drain internal buffer, we should have a pending read. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 EXPECT_TRUE(ConsumeBufferedData(bytes_buffered() / 2, NULL)); | 472 EXPECT_TRUE(ConsumeBufferedData(bytes_buffered() / 2, NULL)); |
| 452 | 473 |
| 453 renderer_->Pause(NewExpectedClosure()); | 474 renderer_->Pause(NewExpectedClosure()); |
| 454 | 475 |
| 455 AbortPendingRead(); | 476 AbortPendingRead(); |
| 456 | 477 |
| 457 Preroll(base::TimeDelta::FromSeconds(1)); | 478 Preroll(base::TimeDelta::FromSeconds(1)); |
| 458 } | 479 } |
| 459 | 480 |
| 460 } // namespace media | 481 } // namespace media |
| OLD | NEW |