| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chromecast/media/audio/cast_audio_output_stream.h" | 5 #include "chromecast/media/audio/cast_audio_output_stream.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 bool error_; | 182 bool error_; |
| 183 }; | 183 }; |
| 184 | 184 |
| 185 class FakeAudioManager : public CastAudioManager { | 185 class FakeAudioManager : public CastAudioManager { |
| 186 public: | 186 public: |
| 187 FakeAudioManager() | 187 FakeAudioManager() |
| 188 : CastAudioManager(nullptr, nullptr), media_pipeline_backend_(nullptr) {} | 188 : CastAudioManager(nullptr, nullptr), media_pipeline_backend_(nullptr) {} |
| 189 ~FakeAudioManager() override {} | 189 ~FakeAudioManager() override {} |
| 190 | 190 |
| 191 // CastAudioManager overrides. | 191 // CastAudioManager overrides. |
| 192 scoped_ptr<MediaPipelineBackend> CreateMediaPipelineBackend( | 192 std::unique_ptr<MediaPipelineBackend> CreateMediaPipelineBackend( |
| 193 const MediaPipelineDeviceParams& params) override { | 193 const MediaPipelineDeviceParams& params) override { |
| 194 DCHECK(media::MediaMessageLoop::GetTaskRunner()->BelongsToCurrentThread()); | 194 DCHECK(media::MediaMessageLoop::GetTaskRunner()->BelongsToCurrentThread()); |
| 195 DCHECK(!media_pipeline_backend_); | 195 DCHECK(!media_pipeline_backend_); |
| 196 | 196 |
| 197 scoped_ptr<FakeMediaPipelineBackend> backend( | 197 std::unique_ptr<FakeMediaPipelineBackend> backend( |
| 198 new FakeMediaPipelineBackend()); | 198 new FakeMediaPipelineBackend()); |
| 199 // Cache the backend locally to be used by tests. | 199 // Cache the backend locally to be used by tests. |
| 200 media_pipeline_backend_ = backend.get(); | 200 media_pipeline_backend_ = backend.get(); |
| 201 return std::move(backend); | 201 return std::move(backend); |
| 202 } | 202 } |
| 203 void ReleaseOutputStream(::media::AudioOutputStream* stream) override { | 203 void ReleaseOutputStream(::media::AudioOutputStream* stream) override { |
| 204 DCHECK(media_pipeline_backend_); | 204 DCHECK(media_pipeline_backend_); |
| 205 media_pipeline_backend_ = nullptr; | 205 media_pipeline_backend_ = nullptr; |
| 206 CastAudioManager::ReleaseOutputStream(stream); | 206 CastAudioManager::ReleaseOutputStream(stream); |
| 207 } | 207 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 completion_event->Signal(); | 350 completion_event->Signal(); |
| 351 } | 351 } |
| 352 void OpenStreamOnAudioThread(::media::AudioOutputStream* stream, | 352 void OpenStreamOnAudioThread(::media::AudioOutputStream* stream, |
| 353 bool* success, | 353 bool* success, |
| 354 base::WaitableEvent* completion_event) { | 354 base::WaitableEvent* completion_event) { |
| 355 DCHECK(audio_task_runner_->BelongsToCurrentThread()); | 355 DCHECK(audio_task_runner_->BelongsToCurrentThread()); |
| 356 *success = stream->Open(); | 356 *success = stream->Open(); |
| 357 completion_event->Signal(); | 357 completion_event->Signal(); |
| 358 } | 358 } |
| 359 | 359 |
| 360 scoped_ptr<FakeAudioManager> audio_manager_; | 360 std::unique_ptr<FakeAudioManager> audio_manager_; |
| 361 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; | 361 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; |
| 362 scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_; | 362 scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_; |
| 363 | 363 |
| 364 // AudioParameters used to create AudioOutputStream. | 364 // AudioParameters used to create AudioOutputStream. |
| 365 // Tests can modify these parameters before calling CreateStream. | 365 // Tests can modify these parameters before calling CreateStream. |
| 366 ::media::AudioParameters::Format format_; | 366 ::media::AudioParameters::Format format_; |
| 367 ::media::ChannelLayout channel_layout_; | 367 ::media::ChannelLayout channel_layout_; |
| 368 int sample_rate_; | 368 int sample_rate_; |
| 369 int bits_per_sample_; | 369 int bits_per_sample_; |
| 370 int frames_per_buffer_; | 370 int frames_per_buffer_; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 ASSERT_TRUE(stream); | 443 ASSERT_TRUE(stream); |
| 444 EXPECT_FALSE(GetAudio()); | 444 EXPECT_FALSE(GetAudio()); |
| 445 | 445 |
| 446 EXPECT_TRUE(OpenStream(stream)); | 446 EXPECT_TRUE(OpenStream(stream)); |
| 447 FakeAudioDecoder* audio_decoder = GetAudio(); | 447 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 448 ASSERT_TRUE(audio_decoder); | 448 ASSERT_TRUE(audio_decoder); |
| 449 FakeMediaPipelineBackend* backend = GetBackend(); | 449 FakeMediaPipelineBackend* backend = GetBackend(); |
| 450 ASSERT_TRUE(backend); | 450 ASSERT_TRUE(backend); |
| 451 EXPECT_EQ(FakeMediaPipelineBackend::kStateStopped, backend->state()); | 451 EXPECT_EQ(FakeMediaPipelineBackend::kStateStopped, backend->state()); |
| 452 | 452 |
| 453 scoped_ptr<FakeAudioSourceCallback> source_callback( | 453 std::unique_ptr<FakeAudioSourceCallback> source_callback( |
| 454 new FakeAudioSourceCallback); | 454 new FakeAudioSourceCallback); |
| 455 StartStream(stream, source_callback.get()); | 455 StartStream(stream, source_callback.get()); |
| 456 EXPECT_EQ(FakeMediaPipelineBackend::kStateRunning, backend->state()); | 456 EXPECT_EQ(FakeMediaPipelineBackend::kStateRunning, backend->state()); |
| 457 | 457 |
| 458 StopStream(stream); | 458 StopStream(stream); |
| 459 EXPECT_EQ(FakeMediaPipelineBackend::kStatePaused, backend->state()); | 459 EXPECT_EQ(FakeMediaPipelineBackend::kStatePaused, backend->state()); |
| 460 | 460 |
| 461 CloseStream(stream); | 461 CloseStream(stream); |
| 462 EXPECT_FALSE(GetAudio()); | 462 EXPECT_FALSE(GetAudio()); |
| 463 } | 463 } |
| 464 | 464 |
| 465 TEST_F(CastAudioOutputStreamTest, PushFrame) { | 465 TEST_F(CastAudioOutputStreamTest, PushFrame) { |
| 466 ::media::AudioOutputStream* stream = CreateStream(); | 466 ::media::AudioOutputStream* stream = CreateStream(); |
| 467 ASSERT_TRUE(stream); | 467 ASSERT_TRUE(stream); |
| 468 EXPECT_TRUE(OpenStream(stream)); | 468 EXPECT_TRUE(OpenStream(stream)); |
| 469 | 469 |
| 470 FakeAudioDecoder* audio_decoder = GetAudio(); | 470 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 471 ASSERT_TRUE(audio_decoder); | 471 ASSERT_TRUE(audio_decoder); |
| 472 // Verify initial state. | 472 // Verify initial state. |
| 473 EXPECT_EQ(0u, audio_decoder->pushed_buffer_count()); | 473 EXPECT_EQ(0u, audio_decoder->pushed_buffer_count()); |
| 474 EXPECT_FALSE(audio_decoder->last_buffer()); | 474 EXPECT_FALSE(audio_decoder->last_buffer()); |
| 475 | 475 |
| 476 scoped_ptr<FakeAudioSourceCallback> source_callback( | 476 std::unique_ptr<FakeAudioSourceCallback> source_callback( |
| 477 new FakeAudioSourceCallback); | 477 new FakeAudioSourceCallback); |
| 478 StartStream(stream, source_callback.get()); | 478 StartStream(stream, source_callback.get()); |
| 479 StopStream(stream); | 479 StopStream(stream); |
| 480 | 480 |
| 481 // Verify that the stream pushed frames to the backend. | 481 // Verify that the stream pushed frames to the backend. |
| 482 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); | 482 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); |
| 483 EXPECT_TRUE(audio_decoder->last_buffer()); | 483 EXPECT_TRUE(audio_decoder->last_buffer()); |
| 484 | 484 |
| 485 // Verify decoder buffer. | 485 // Verify decoder buffer. |
| 486 ::media::AudioParameters audio_params = GetAudioParams(); | 486 ::media::AudioParameters audio_params = GetAudioParams(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 500 | 500 |
| 501 TEST_F(CastAudioOutputStreamTest, DeviceBusy) { | 501 TEST_F(CastAudioOutputStreamTest, DeviceBusy) { |
| 502 ::media::AudioOutputStream* stream = CreateStream(); | 502 ::media::AudioOutputStream* stream = CreateStream(); |
| 503 ASSERT_TRUE(stream); | 503 ASSERT_TRUE(stream); |
| 504 EXPECT_TRUE(OpenStream(stream)); | 504 EXPECT_TRUE(OpenStream(stream)); |
| 505 | 505 |
| 506 FakeAudioDecoder* audio_decoder = GetAudio(); | 506 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 507 ASSERT_TRUE(audio_decoder); | 507 ASSERT_TRUE(audio_decoder); |
| 508 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_BUSY); | 508 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_BUSY); |
| 509 | 509 |
| 510 scoped_ptr<FakeAudioSourceCallback> source_callback( | 510 std::unique_ptr<FakeAudioSourceCallback> source_callback( |
| 511 new FakeAudioSourceCallback); | 511 new FakeAudioSourceCallback); |
| 512 StartStream(stream, source_callback.get()); | 512 StartStream(stream, source_callback.get()); |
| 513 | 513 |
| 514 // Make sure that one frame was pushed. | 514 // Make sure that one frame was pushed. |
| 515 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); | 515 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); |
| 516 // No error must be reported to source callback. | 516 // No error must be reported to source callback. |
| 517 EXPECT_FALSE(source_callback->error()); | 517 EXPECT_FALSE(source_callback->error()); |
| 518 | 518 |
| 519 // Sleep for a few frames and verify that more frames were not pushed | 519 // Sleep for a few frames and verify that more frames were not pushed |
| 520 // because the backend device was busy. | 520 // because the backend device was busy. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 545 | 545 |
| 546 TEST_F(CastAudioOutputStreamTest, DeviceError) { | 546 TEST_F(CastAudioOutputStreamTest, DeviceError) { |
| 547 ::media::AudioOutputStream* stream = CreateStream(); | 547 ::media::AudioOutputStream* stream = CreateStream(); |
| 548 ASSERT_TRUE(stream); | 548 ASSERT_TRUE(stream); |
| 549 EXPECT_TRUE(OpenStream(stream)); | 549 EXPECT_TRUE(OpenStream(stream)); |
| 550 | 550 |
| 551 FakeAudioDecoder* audio_decoder = GetAudio(); | 551 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 552 ASSERT_TRUE(audio_decoder); | 552 ASSERT_TRUE(audio_decoder); |
| 553 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_ERROR); | 553 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_ERROR); |
| 554 | 554 |
| 555 scoped_ptr<FakeAudioSourceCallback> source_callback( | 555 std::unique_ptr<FakeAudioSourceCallback> source_callback( |
| 556 new FakeAudioSourceCallback); | 556 new FakeAudioSourceCallback); |
| 557 StartStream(stream, source_callback.get()); | 557 StartStream(stream, source_callback.get()); |
| 558 | 558 |
| 559 // Make sure that AudioOutputStream attempted to push the initial frame. | 559 // Make sure that AudioOutputStream attempted to push the initial frame. |
| 560 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); | 560 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); |
| 561 // AudioOutputStream must report error to source callback. | 561 // AudioOutputStream must report error to source callback. |
| 562 EXPECT_TRUE(source_callback->error()); | 562 EXPECT_TRUE(source_callback->error()); |
| 563 | 563 |
| 564 StopStream(stream); | 564 StopStream(stream); |
| 565 CloseStream(stream); | 565 CloseStream(stream); |
| 566 } | 566 } |
| 567 | 567 |
| 568 TEST_F(CastAudioOutputStreamTest, DeviceAsyncError) { | 568 TEST_F(CastAudioOutputStreamTest, DeviceAsyncError) { |
| 569 ::media::AudioOutputStream* stream = CreateStream(); | 569 ::media::AudioOutputStream* stream = CreateStream(); |
| 570 ASSERT_TRUE(stream); | 570 ASSERT_TRUE(stream); |
| 571 EXPECT_TRUE(OpenStream(stream)); | 571 EXPECT_TRUE(OpenStream(stream)); |
| 572 | 572 |
| 573 FakeAudioDecoder* audio_decoder = GetAudio(); | 573 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 574 ASSERT_TRUE(audio_decoder); | 574 ASSERT_TRUE(audio_decoder); |
| 575 audio_decoder->set_pipeline_status( | 575 audio_decoder->set_pipeline_status( |
| 576 FakeAudioDecoder::PIPELINE_STATUS_ASYNC_ERROR); | 576 FakeAudioDecoder::PIPELINE_STATUS_ASYNC_ERROR); |
| 577 | 577 |
| 578 scoped_ptr<FakeAudioSourceCallback> source_callback( | 578 std::unique_ptr<FakeAudioSourceCallback> source_callback( |
| 579 new FakeAudioSourceCallback); | 579 new FakeAudioSourceCallback); |
| 580 StartStream(stream, source_callback.get()); | 580 StartStream(stream, source_callback.get()); |
| 581 | 581 |
| 582 // Make sure that one frame was pushed. | 582 // Make sure that one frame was pushed. |
| 583 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); | 583 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); |
| 584 | 584 |
| 585 // Unblock the pipeline and verify that PushFrame resumes. | 585 // Unblock the pipeline and verify that PushFrame resumes. |
| 586 // (have to post because this directly calls buffer complete) | 586 // (have to post because this directly calls buffer complete) |
| 587 backend_task_runner_->PostTask( | 587 backend_task_runner_->PostTask( |
| 588 FROM_HERE, | 588 FROM_HERE, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 616 EXPECT_EQ(0.5f, audio_decoder->volume()); | 616 EXPECT_EQ(0.5f, audio_decoder->volume()); |
| 617 | 617 |
| 618 CloseStream(stream); | 618 CloseStream(stream); |
| 619 } | 619 } |
| 620 | 620 |
| 621 TEST_F(CastAudioOutputStreamTest, StartStopStart) { | 621 TEST_F(CastAudioOutputStreamTest, StartStopStart) { |
| 622 ::media::AudioOutputStream* stream = CreateStream(); | 622 ::media::AudioOutputStream* stream = CreateStream(); |
| 623 ASSERT_TRUE(stream); | 623 ASSERT_TRUE(stream); |
| 624 ASSERT_TRUE(OpenStream(stream)); | 624 ASSERT_TRUE(OpenStream(stream)); |
| 625 | 625 |
| 626 scoped_ptr<FakeAudioSourceCallback> source_callback( | 626 std::unique_ptr<FakeAudioSourceCallback> source_callback( |
| 627 new FakeAudioSourceCallback); | 627 new FakeAudioSourceCallback); |
| 628 audio_task_runner_->PostTask( | 628 audio_task_runner_->PostTask( |
| 629 FROM_HERE, base::Bind(&::media::AudioOutputStream::Start, | 629 FROM_HERE, base::Bind(&::media::AudioOutputStream::Start, |
| 630 base::Unretained(stream), source_callback.get())); | 630 base::Unretained(stream), source_callback.get())); |
| 631 audio_task_runner_->PostTask( | 631 audio_task_runner_->PostTask( |
| 632 FROM_HERE, | 632 FROM_HERE, |
| 633 base::Bind(&::media::AudioOutputStream::Stop, base::Unretained(stream))); | 633 base::Bind(&::media::AudioOutputStream::Stop, base::Unretained(stream))); |
| 634 audio_task_runner_->PostTask( | 634 audio_task_runner_->PostTask( |
| 635 FROM_HERE, base::Bind(&::media::AudioOutputStream::Start, | 635 FROM_HERE, base::Bind(&::media::AudioOutputStream::Start, |
| 636 base::Unretained(stream), source_callback.get())); | 636 base::Unretained(stream), source_callback.get())); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 647 TEST_F(CastAudioOutputStreamTest, CloseWithoutStart) { | 647 TEST_F(CastAudioOutputStreamTest, CloseWithoutStart) { |
| 648 ::media::AudioOutputStream* stream = CreateStream(); | 648 ::media::AudioOutputStream* stream = CreateStream(); |
| 649 ASSERT_TRUE(stream); | 649 ASSERT_TRUE(stream); |
| 650 ASSERT_TRUE(OpenStream(stream)); | 650 ASSERT_TRUE(OpenStream(stream)); |
| 651 CloseStream(stream); | 651 CloseStream(stream); |
| 652 } | 652 } |
| 653 | 653 |
| 654 } // namespace | 654 } // namespace |
| 655 } // namespace media | 655 } // namespace media |
| 656 } // namespace chromecast | 656 } // namespace chromecast |
| OLD | NEW |