| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "chromecast/base/metrics/cast_metrics_test_helper.h" | 16 #include "chromecast/base/metrics/cast_metrics_test_helper.h" |
| 17 #include "chromecast/media/audio/cast_audio_manager.h" | 17 #include "chromecast/media/audio/cast_audio_manager.h" |
| 18 #include "chromecast/media/audio/cast_audio_mixer.h" |
| 19 #include "chromecast/media/cma/test/mock_media_pipeline_backend_factory.h" |
| 18 #include "chromecast/public/media/cast_decoder_buffer.h" | 20 #include "chromecast/public/media/cast_decoder_buffer.h" |
| 19 #include "chromecast/public/media/media_pipeline_backend.h" | 21 #include "chromecast/public/media/media_pipeline_backend.h" |
| 22 #include "chromecast/public/task_runner.h" |
| 23 #include "media/audio/mock_audio_source_callback.h" |
| 20 #include "media/audio/test_audio_thread.h" | 24 #include "media/audio/test_audio_thread.h" |
| 21 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
| 22 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 23 | 27 |
| 24 using ::testing::Invoke; | 28 using testing::_; |
| 25 using ::testing::_; | 29 using testing::Invoke; |
| 30 using testing::NiceMock; |
| 26 | 31 |
| 27 namespace chromecast { | 32 namespace chromecast { |
| 28 namespace media { | 33 namespace media { |
| 29 namespace { | 34 namespace { |
| 30 const char kDefaultDeviceId[] = ""; | 35 const char kDefaultDeviceId[] = ""; |
| 31 const int64_t kDelayUs = 123; | 36 const int64_t kDelayUs = 123; |
| 32 const int64_t kDelayTimestampUs = 123456789; | 37 const int64_t kDelayTimestampUs = 123456789; |
| 33 | 38 |
| 34 int OnMoreData(base::TimeDelta /* delay */, | 39 int OnMoreData(base::TimeDelta /* delay */, |
| 35 base::TimeTicks /* delay_timestamp */, | 40 base::TimeTicks /* delay_timestamp */, |
| 36 int /* prior_frames_skipped */, | 41 int /* prior_frames_skipped */, |
| 37 ::media::AudioBus* dest) { | 42 ::media::AudioBus* dest) { |
| 38 dest->Zero(); | 43 dest->Zero(); |
| 39 return dest->frames(); | 44 return dest->frames(); |
| 40 } | 45 } |
| 41 | 46 |
| 47 class NotifyPushBufferCompleteTask : public chromecast::TaskRunner::Task { |
| 48 public: |
| 49 NotifyPushBufferCompleteTask( |
| 50 MediaPipelineBackend::Decoder::Delegate* delegate) |
| 51 : delegate_(delegate) {} |
| 52 ~NotifyPushBufferCompleteTask() override = default; |
| 53 void Run() override { |
| 54 delegate_->OnPushBufferComplete(MediaPipelineBackend::kBufferSuccess); |
| 55 } |
| 56 |
| 57 private: |
| 58 MediaPipelineBackend::Decoder::Delegate* const delegate_; |
| 59 }; |
| 60 |
| 42 class FakeAudioDecoder : public MediaPipelineBackend::AudioDecoder { | 61 class FakeAudioDecoder : public MediaPipelineBackend::AudioDecoder { |
| 43 public: | 62 public: |
| 44 enum PipelineStatus { | 63 enum PipelineStatus { |
| 45 PIPELINE_STATUS_OK, | 64 PIPELINE_STATUS_OK, |
| 46 PIPELINE_STATUS_BUSY, | 65 PIPELINE_STATUS_BUSY, |
| 47 PIPELINE_STATUS_ERROR, | 66 PIPELINE_STATUS_ERROR, |
| 48 PIPELINE_STATUS_ASYNC_ERROR, | 67 PIPELINE_STATUS_ASYNC_ERROR, |
| 49 }; | 68 }; |
| 50 | 69 |
| 51 FakeAudioDecoder() | 70 FakeAudioDecoder(const MediaPipelineDeviceParams& params) |
| 52 : volume_(1.0f), | 71 : params_(params), |
| 72 volume_(1.0f), |
| 53 pipeline_status_(PIPELINE_STATUS_OK), | 73 pipeline_status_(PIPELINE_STATUS_OK), |
| 54 pending_push_(false), | 74 pending_push_(false), |
| 55 pushed_buffer_count_(0), | 75 pushed_buffer_count_(0), |
| 56 last_buffer_(nullptr), | 76 last_buffer_(nullptr), |
| 57 delegate_(nullptr) {} | 77 delegate_(nullptr) {} |
| 58 ~FakeAudioDecoder() override {} | 78 ~FakeAudioDecoder() override {} |
| 59 | 79 |
| 60 // MediaPipelineBackend::AudioDecoder implementation: | 80 // MediaPipelineBackend::AudioDecoder implementation: |
| 61 void SetDelegate(Delegate* delegate) override { | 81 void SetDelegate(Delegate* delegate) override { |
| 62 DCHECK(delegate); | 82 DCHECK(delegate); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 92 volume_ = volume; | 112 volume_ = volume; |
| 93 return true; | 113 return true; |
| 94 } | 114 } |
| 95 RenderingDelay GetRenderingDelay() override { return rendering_delay_; } | 115 RenderingDelay GetRenderingDelay() override { return rendering_delay_; } |
| 96 | 116 |
| 97 const AudioConfig& config() const { return config_; } | 117 const AudioConfig& config() const { return config_; } |
| 98 float volume() const { return volume_; } | 118 float volume() const { return volume_; } |
| 99 void set_pipeline_status(PipelineStatus status) { | 119 void set_pipeline_status(PipelineStatus status) { |
| 100 if (status == PIPELINE_STATUS_OK && pending_push_) { | 120 if (status == PIPELINE_STATUS_OK && pending_push_) { |
| 101 pending_push_ = false; | 121 pending_push_ = false; |
| 102 delegate_->OnPushBufferComplete(MediaPipelineBackend::kBufferSuccess); | 122 params_.task_runner->PostTask(new NotifyPushBufferCompleteTask(delegate_), |
| 123 0); |
| 103 } | 124 } |
| 104 pipeline_status_ = status; | 125 pipeline_status_ = status; |
| 105 } | 126 } |
| 106 void set_rendering_delay(RenderingDelay rendering_delay) { | 127 void set_rendering_delay(RenderingDelay rendering_delay) { |
| 107 rendering_delay_ = rendering_delay; | 128 rendering_delay_ = rendering_delay; |
| 108 } | 129 } |
| 109 unsigned pushed_buffer_count() const { return pushed_buffer_count_; } | 130 unsigned pushed_buffer_count() const { return pushed_buffer_count_; } |
| 110 CastDecoderBuffer* last_buffer() { return last_buffer_; } | 131 CastDecoderBuffer* last_buffer() { return last_buffer_; } |
| 111 | 132 |
| 112 private: | 133 private: |
| 134 const MediaPipelineDeviceParams params_; |
| 113 AudioConfig config_; | 135 AudioConfig config_; |
| 114 float volume_; | 136 float volume_; |
| 115 | 137 |
| 116 PipelineStatus pipeline_status_; | 138 PipelineStatus pipeline_status_; |
| 117 bool pending_push_; | 139 bool pending_push_; |
| 118 int pushed_buffer_count_; | 140 int pushed_buffer_count_; |
| 119 CastDecoderBuffer* last_buffer_; | 141 CastDecoderBuffer* last_buffer_; |
| 120 Delegate* delegate_; | 142 Delegate* delegate_; |
| 121 RenderingDelay rendering_delay_; | 143 RenderingDelay rendering_delay_; |
| 122 }; | 144 }; |
| 123 | 145 |
| 124 class FakeMediaPipelineBackend : public MediaPipelineBackend { | 146 class FakeMediaPipelineBackend : public MediaPipelineBackend { |
| 125 public: | 147 public: |
| 126 enum State { kStateStopped, kStateRunning, kStatePaused }; | 148 enum State { kStateStopped, kStateRunning, kStatePaused }; |
| 127 | 149 |
| 128 FakeMediaPipelineBackend() : state_(kStateStopped), audio_decoder_(nullptr) {} | 150 FakeMediaPipelineBackend(const MediaPipelineDeviceParams& params) |
| 151 : params_(params), state_(kStateStopped), audio_decoder_(nullptr) {} |
| 129 ~FakeMediaPipelineBackend() override {} | 152 ~FakeMediaPipelineBackend() override {} |
| 130 | 153 |
| 131 // MediaPipelineBackend implementation: | 154 // MediaPipelineBackend implementation: |
| 132 AudioDecoder* CreateAudioDecoder() override { | 155 AudioDecoder* CreateAudioDecoder() override { |
| 133 DCHECK(!audio_decoder_); | 156 DCHECK(!audio_decoder_); |
| 134 audio_decoder_ = base::MakeUnique<FakeAudioDecoder>(); | 157 audio_decoder_ = base::MakeUnique<FakeAudioDecoder>(params_); |
| 135 return audio_decoder_.get(); | 158 return audio_decoder_.get(); |
| 136 } | 159 } |
| 137 VideoDecoder* CreateVideoDecoder() override { | 160 VideoDecoder* CreateVideoDecoder() override { |
| 138 NOTREACHED(); | 161 NOTREACHED(); |
| 139 return nullptr; | 162 return nullptr; |
| 140 } | 163 } |
| 141 | 164 |
| 142 bool Initialize() override { return true; } | 165 bool Initialize() override { return true; } |
| 143 bool Start(int64_t start_pts) override { | 166 bool Start(int64_t start_pts) override { |
| 144 EXPECT_EQ(kStateStopped, state_); | 167 EXPECT_EQ(kStateStopped, state_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 159 state_ = kStateRunning; | 182 state_ = kStateRunning; |
| 160 return true; | 183 return true; |
| 161 } | 184 } |
| 162 int64_t GetCurrentPts() override { return 0; } | 185 int64_t GetCurrentPts() override { return 0; } |
| 163 bool SetPlaybackRate(float rate) override { return true; } | 186 bool SetPlaybackRate(float rate) override { return true; } |
| 164 | 187 |
| 165 State state() const { return state_; } | 188 State state() const { return state_; } |
| 166 FakeAudioDecoder* decoder() const { return audio_decoder_.get(); } | 189 FakeAudioDecoder* decoder() const { return audio_decoder_.get(); } |
| 167 | 190 |
| 168 private: | 191 private: |
| 192 const MediaPipelineDeviceParams params_; |
| 169 State state_; | 193 State state_; |
| 170 std::unique_ptr<FakeAudioDecoder> audio_decoder_; | 194 std::unique_ptr<FakeAudioDecoder> audio_decoder_; |
| 171 }; | 195 }; |
| 172 | 196 |
| 173 class MockAudioSourceCallback | |
| 174 : public ::media::AudioOutputStream::AudioSourceCallback { | |
| 175 public: | |
| 176 // ::media::AudioOutputStream::AudioSourceCallback overrides. | |
| 177 MOCK_METHOD4(OnMoreData, | |
| 178 int(base::TimeDelta, base::TimeTicks, int, ::media::AudioBus*)); | |
| 179 MOCK_METHOD0(OnError, void()); | |
| 180 }; | |
| 181 | |
| 182 class FakeAudioManager : public CastAudioManager { | |
| 183 public: | |
| 184 FakeAudioManager() | |
| 185 : CastAudioManager(base::MakeUnique<::media::TestAudioThread>(), | |
| 186 nullptr, | |
| 187 nullptr, | |
| 188 nullptr), | |
| 189 media_pipeline_backend_(nullptr) {} | |
| 190 ~FakeAudioManager() override {} | |
| 191 | |
| 192 // CastAudioManager overrides. | |
| 193 std::unique_ptr<MediaPipelineBackend> CreateMediaPipelineBackend( | |
| 194 const MediaPipelineDeviceParams& params) override { | |
| 195 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | |
| 196 DCHECK(!media_pipeline_backend_); | |
| 197 | |
| 198 std::unique_ptr<FakeMediaPipelineBackend> backend( | |
| 199 new FakeMediaPipelineBackend()); | |
| 200 // Cache the backend locally to be used by tests. | |
| 201 media_pipeline_backend_ = backend.get(); | |
| 202 return std::move(backend); | |
| 203 } | |
| 204 void ReleaseOutputStream(::media::AudioOutputStream* stream) override { | |
| 205 DCHECK(media_pipeline_backend_); | |
| 206 media_pipeline_backend_ = nullptr; | |
| 207 CastAudioManager::ReleaseOutputStream(stream); | |
| 208 } | |
| 209 | |
| 210 // Returns the MediaPipelineBackend being used by the AudioOutputStream. | |
| 211 // Note: here is a valid MediaPipelineBackend only while the stream is open. | |
| 212 // Returns NULL at all other times. | |
| 213 FakeMediaPipelineBackend* media_pipeline_backend() { | |
| 214 return media_pipeline_backend_; | |
| 215 } | |
| 216 | |
| 217 private: | |
| 218 FakeMediaPipelineBackend* media_pipeline_backend_; | |
| 219 }; | |
| 220 | |
| 221 class CastAudioOutputStreamTest : public ::testing::Test { | 197 class CastAudioOutputStreamTest : public ::testing::Test { |
| 222 public: | 198 public: |
| 223 CastAudioOutputStreamTest() | 199 CastAudioOutputStreamTest() |
| 224 : format_(::media::AudioParameters::AUDIO_PCM_LINEAR), | 200 : media_thread_("CastMediaThread"), |
| 201 media_pipeline_backend_(nullptr), |
| 202 format_(::media::AudioParameters::AUDIO_PCM_LINEAR), |
| 225 channel_layout_(::media::CHANNEL_LAYOUT_MONO), | 203 channel_layout_(::media::CHANNEL_LAYOUT_MONO), |
| 226 sample_rate_(::media::AudioParameters::kAudioCDSampleRate), | 204 sample_rate_(::media::AudioParameters::kAudioCDSampleRate), |
| 227 bits_per_sample_(16), | 205 bits_per_sample_(16), |
| 228 frames_per_buffer_(256) {} | 206 frames_per_buffer_(256) {} |
| 229 ~CastAudioOutputStreamTest() override {} | 207 ~CastAudioOutputStreamTest() override {} |
| 230 | 208 |
| 231 protected: | 209 protected: |
| 232 void SetUp() override { | 210 void SetUp() override { |
| 233 metrics::InitializeMetricsHelperForTesting(); | 211 metrics::InitializeMetricsHelperForTesting(); |
| 234 audio_manager_ = base::MakeUnique<FakeAudioManager>(); | 212 |
| 213 CHECK(media_thread_.Start()); |
| 214 auto backend_factory = |
| 215 base::MakeUnique<NiceMock<MockMediaPipelineBackendFactory>>(); |
| 216 ON_CALL(*backend_factory, CreateBackend(_)) |
| 217 .WillByDefault(Invoke([this](const MediaPipelineDeviceParams& params) { |
| 218 media_pipeline_backend_ = new FakeMediaPipelineBackend(params); |
| 219 return base::WrapUnique(media_pipeline_backend_); |
| 220 })); |
| 221 audio_manager_ = base::MakeUnique<CastAudioManager>( |
| 222 base::MakeUnique<::media::TestAudioThread>(), nullptr, |
| 223 std::move(backend_factory), media_thread_.task_runner(), false); |
| 235 } | 224 } |
| 236 | 225 |
| 237 void TearDown() override { audio_manager_->Shutdown(); } | 226 void TearDown() override { audio_manager_->Shutdown(); } |
| 238 | 227 |
| 239 ::media::AudioParameters GetAudioParams() { | 228 ::media::AudioParameters GetAudioParams() { |
| 240 return ::media::AudioParameters(format_, channel_layout_, sample_rate_, | 229 return ::media::AudioParameters(format_, channel_layout_, sample_rate_, |
| 241 bits_per_sample_, frames_per_buffer_); | 230 bits_per_sample_, frames_per_buffer_); |
| 242 } | 231 } |
| 243 | 232 |
| 244 FakeMediaPipelineBackend* GetBackend() { | 233 FakeMediaPipelineBackend* GetBackend() { return media_pipeline_backend_; } |
| 245 return audio_manager_->media_pipeline_backend(); | |
| 246 } | |
| 247 | 234 |
| 248 FakeAudioDecoder* GetAudio() { | 235 FakeAudioDecoder* GetAudio() { |
| 249 FakeMediaPipelineBackend* backend = GetBackend(); | 236 FakeMediaPipelineBackend* backend = GetBackend(); |
| 250 return (backend ? backend->decoder() : nullptr); | 237 return (backend ? backend->decoder() : nullptr); |
| 251 } | 238 } |
| 252 | 239 |
| 253 ::media::AudioOutputStream* CreateStream() { | 240 ::media::AudioOutputStream* CreateStream() { |
| 254 return audio_manager_->MakeAudioOutputStream( | 241 return audio_manager_->MakeAudioOutputStream( |
| 255 GetAudioParams(), kDefaultDeviceId, | 242 GetAudioParams(), kDefaultDeviceId, |
| 256 ::media::AudioManager::LogCallback()); | 243 ::media::AudioManager::LogCallback()); |
| 257 } | 244 } |
| 258 | 245 |
| 259 // Runs the messsage loop for duration equivalent to the given number of | 246 // Runs the messsage loop for duration equivalent to the given number of |
| 260 // audio |frames|. | 247 // audio |frames|. |
| 261 void RunMessageLoopFor(int frames) { | 248 void RunMessageLoopFor(int frames) { |
| 262 ::media::AudioParameters audio_params = GetAudioParams(); | 249 ::media::AudioParameters audio_params = GetAudioParams(); |
| 263 base::TimeDelta duration = audio_params.GetBufferDuration() * frames; | 250 base::TimeDelta duration = audio_params.GetBufferDuration() * frames; |
| 264 | 251 |
| 265 base::RunLoop run_loop; | 252 base::RunLoop run_loop; |
| 266 message_loop_.task_runner()->PostDelayedTask( | 253 message_loop_.task_runner()->PostDelayedTask( |
| 267 FROM_HERE, run_loop.QuitClosure(), duration); | 254 FROM_HERE, run_loop.QuitClosure(), duration); |
| 268 run_loop.Run(); | 255 run_loop.Run(); |
| 269 } | 256 } |
| 270 | 257 |
| 271 base::MessageLoop message_loop_; | 258 base::MessageLoop message_loop_; |
| 272 std::unique_ptr<FakeAudioManager> audio_manager_; | 259 base::Thread media_thread_; |
| 260 std::unique_ptr<CastAudioManager> audio_manager_; |
| 261 // MockMediaPipelineBackendFactory* backend_factory_; |
| 262 FakeMediaPipelineBackend* media_pipeline_backend_; |
| 273 // AudioParameters used to create AudioOutputStream. | 263 // AudioParameters used to create AudioOutputStream. |
| 274 // Tests can modify these parameters before calling CreateStream. | 264 // Tests can modify these parameters before calling CreateStream. |
| 275 ::media::AudioParameters::Format format_; | 265 ::media::AudioParameters::Format format_; |
| 276 ::media::ChannelLayout channel_layout_; | 266 ::media::ChannelLayout channel_layout_; |
| 277 int sample_rate_; | 267 int sample_rate_; |
| 278 int bits_per_sample_; | 268 int bits_per_sample_; |
| 279 int frames_per_buffer_; | 269 int frames_per_buffer_; |
| 280 }; | 270 }; |
| 281 | 271 |
| 282 TEST_F(CastAudioOutputStreamTest, Format) { | 272 TEST_F(CastAudioOutputStreamTest, Format) { |
| 283 ::media::AudioParameters::Format format[] = { | 273 ::media::AudioParameters::Format format[] = { |
| 284 //::media::AudioParameters::AUDIO_PCM_LINEAR, | 274 ::media::AudioParameters::AUDIO_PCM_LINEAR, |
| 285 ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY}; | 275 ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY}; |
| 286 for (size_t i = 0; i < arraysize(format); ++i) { | 276 for (size_t i = 0; i < arraysize(format); ++i) { |
| 287 format_ = format[i]; | 277 format_ = format[i]; |
| 288 ::media::AudioOutputStream* stream = CreateStream(); | 278 ::media::AudioOutputStream* stream = CreateStream(); |
| 289 ASSERT_TRUE(stream); | 279 ASSERT_TRUE(stream); |
| 290 EXPECT_TRUE(stream->Open()); | 280 EXPECT_TRUE(stream->Open()); |
| 291 | 281 |
| 292 FakeAudioDecoder* audio_decoder = GetAudio(); | 282 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 293 ASSERT_TRUE(audio_decoder); | 283 ASSERT_TRUE(audio_decoder); |
| 294 const AudioConfig& audio_config = audio_decoder->config(); | 284 const AudioConfig& audio_config = audio_decoder->config(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 ASSERT_TRUE(audio_decoder); | 333 ASSERT_TRUE(audio_decoder); |
| 344 const AudioConfig& audio_config = audio_decoder->config(); | 334 const AudioConfig& audio_config = audio_decoder->config(); |
| 345 EXPECT_EQ(bits_per_sample_ / 8, audio_config.bytes_per_channel); | 335 EXPECT_EQ(bits_per_sample_ / 8, audio_config.bytes_per_channel); |
| 346 | 336 |
| 347 stream->Close(); | 337 stream->Close(); |
| 348 } | 338 } |
| 349 | 339 |
| 350 TEST_F(CastAudioOutputStreamTest, DeviceState) { | 340 TEST_F(CastAudioOutputStreamTest, DeviceState) { |
| 351 ::media::AudioOutputStream* stream = CreateStream(); | 341 ::media::AudioOutputStream* stream = CreateStream(); |
| 352 ASSERT_TRUE(stream); | 342 ASSERT_TRUE(stream); |
| 353 EXPECT_FALSE(GetAudio()); | |
| 354 | 343 |
| 355 EXPECT_TRUE(stream->Open()); | 344 EXPECT_TRUE(stream->Open()); |
| 356 FakeAudioDecoder* audio_decoder = GetAudio(); | 345 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 357 ASSERT_TRUE(audio_decoder); | 346 ASSERT_TRUE(audio_decoder); |
| 358 FakeMediaPipelineBackend* backend = GetBackend(); | 347 FakeMediaPipelineBackend* backend = GetBackend(); |
| 359 ASSERT_TRUE(backend); | 348 ASSERT_TRUE(backend); |
| 360 EXPECT_EQ(FakeMediaPipelineBackend::kStateStopped, backend->state()); | 349 EXPECT_EQ(FakeMediaPipelineBackend::kStateStopped, backend->state()); |
| 361 | 350 |
| 362 auto source_callback(base::MakeUnique<MockAudioSourceCallback>()); | 351 ::media::MockAudioSourceCallback source_callback; |
| 363 ON_CALL(*source_callback, OnMoreData(_, _, _, _)) | 352 EXPECT_CALL(source_callback, OnMoreData(_, _, _, _)) |
| 364 .WillByDefault(Invoke(OnMoreData)); | 353 .WillRepeatedly(Invoke(OnMoreData)); |
| 365 stream->Start(source_callback.get()); | 354 stream->Start(&source_callback); |
| 355 media_thread_.FlushForTesting(); |
| 366 EXPECT_EQ(FakeMediaPipelineBackend::kStateRunning, backend->state()); | 356 EXPECT_EQ(FakeMediaPipelineBackend::kStateRunning, backend->state()); |
| 367 | 357 |
| 368 stream->Stop(); | 358 stream->Stop(); |
| 359 media_thread_.FlushForTesting(); |
| 369 EXPECT_EQ(FakeMediaPipelineBackend::kStatePaused, backend->state()); | 360 EXPECT_EQ(FakeMediaPipelineBackend::kStatePaused, backend->state()); |
| 370 | 361 |
| 371 stream->Close(); | 362 stream->Close(); |
| 372 EXPECT_FALSE(GetAudio()); | |
| 373 } | 363 } |
| 374 | 364 |
| 375 TEST_F(CastAudioOutputStreamTest, PushFrame) { | 365 TEST_F(CastAudioOutputStreamTest, PushFrame) { |
| 376 ::media::AudioOutputStream* stream = CreateStream(); | 366 ::media::AudioOutputStream* stream = CreateStream(); |
| 377 ASSERT_TRUE(stream); | 367 ASSERT_TRUE(stream); |
| 378 EXPECT_TRUE(stream->Open()); | 368 EXPECT_TRUE(stream->Open()); |
| 379 | 369 |
| 380 FakeAudioDecoder* audio_decoder = GetAudio(); | 370 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 381 ASSERT_TRUE(audio_decoder); | 371 ASSERT_TRUE(audio_decoder); |
| 382 // Verify initial state. | 372 // Verify initial state. |
| 383 EXPECT_EQ(0u, audio_decoder->pushed_buffer_count()); | 373 EXPECT_EQ(0u, audio_decoder->pushed_buffer_count()); |
| 384 EXPECT_FALSE(audio_decoder->last_buffer()); | 374 EXPECT_FALSE(audio_decoder->last_buffer()); |
| 385 | 375 |
| 386 auto source_callback(base::MakeUnique<MockAudioSourceCallback>()); | 376 ::media::MockAudioSourceCallback source_callback; |
| 387 ON_CALL(*source_callback, OnMoreData(_, _, _, _)) | 377 EXPECT_CALL(source_callback, OnMoreData(_, _, _, _)) |
| 388 .WillByDefault(Invoke(OnMoreData)); | 378 .WillRepeatedly(Invoke(OnMoreData)); |
| 389 // No error must be reported to source callback. | 379 // No error must be reported to source callback. |
| 390 EXPECT_CALL(*source_callback, OnError()).Times(0); | 380 EXPECT_CALL(source_callback, OnError()).Times(0); |
| 391 stream->Start(source_callback.get()); | 381 stream->Start(&source_callback); |
| 392 RunMessageLoopFor(2); | 382 RunMessageLoopFor(2); |
| 393 stream->Stop(); | 383 stream->Stop(); |
| 394 | 384 |
| 395 // Verify that the stream pushed frames to the backend. | 385 // Verify that the stream pushed frames to the backend. |
| 396 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); | 386 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); |
| 397 EXPECT_TRUE(audio_decoder->last_buffer()); | 387 EXPECT_TRUE(audio_decoder->last_buffer()); |
| 398 | 388 |
| 399 // Verify decoder buffer. | 389 // Verify decoder buffer. |
| 400 ::media::AudioParameters audio_params = GetAudioParams(); | 390 ::media::AudioParameters audio_params = GetAudioParams(); |
| 401 const size_t expected_frame_size = | 391 const size_t expected_frame_size = |
| 402 static_cast<size_t>(audio_params.GetBytesPerBuffer()); | 392 static_cast<size_t>(audio_params.GetBytesPerBuffer()); |
| 403 const CastDecoderBuffer* buffer = audio_decoder->last_buffer(); | 393 const CastDecoderBuffer* buffer = audio_decoder->last_buffer(); |
| 404 EXPECT_TRUE(buffer->data()); | 394 EXPECT_TRUE(buffer->data()); |
| 405 EXPECT_EQ(expected_frame_size, buffer->data_size()); | 395 EXPECT_EQ(expected_frame_size, buffer->data_size()); |
| 406 EXPECT_FALSE(buffer->decrypt_config()); // Null because of raw audio. | 396 EXPECT_FALSE(buffer->decrypt_config()); // Null because of raw audio. |
| 407 EXPECT_FALSE(buffer->end_of_stream()); | 397 EXPECT_FALSE(buffer->end_of_stream()); |
| 408 | 398 |
| 409 stream->Close(); | 399 stream->Close(); |
| 410 } | 400 } |
| 411 | 401 |
| 412 TEST_F(CastAudioOutputStreamTest, DeviceBusy) { | 402 TEST_F(CastAudioOutputStreamTest, DeviceBusy) { |
| 413 ::media::AudioOutputStream* stream = CreateStream(); | 403 ::media::AudioOutputStream* stream = CreateStream(); |
| 414 ASSERT_TRUE(stream); | 404 ASSERT_TRUE(stream); |
| 415 EXPECT_TRUE(stream->Open()); | 405 EXPECT_TRUE(stream->Open()); |
| 416 | 406 |
| 417 FakeAudioDecoder* audio_decoder = GetAudio(); | 407 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 418 ASSERT_TRUE(audio_decoder); | 408 ASSERT_TRUE(audio_decoder); |
| 419 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_BUSY); | 409 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_BUSY); |
| 420 | 410 |
| 421 auto source_callback(base::MakeUnique<MockAudioSourceCallback>()); | 411 ::media::MockAudioSourceCallback source_callback; |
| 422 ON_CALL(*source_callback, OnMoreData(_, _, _, _)) | 412 EXPECT_CALL(source_callback, OnMoreData(_, _, _, _)) |
| 423 .WillByDefault(Invoke(OnMoreData)); | 413 .WillRepeatedly(Invoke(OnMoreData)); |
| 424 // No error must be reported to source callback. | 414 // No error must be reported to source callback. |
| 425 EXPECT_CALL(*source_callback, OnError()).Times(0); | 415 EXPECT_CALL(source_callback, OnError()).Times(0); |
| 426 stream->Start(source_callback.get()); | 416 stream->Start(&source_callback); |
| 427 RunMessageLoopFor(5); | 417 RunMessageLoopFor(5); |
| 428 // Make sure that one frame was pushed. | 418 // Make sure that one frame was pushed. |
| 429 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); | 419 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); |
| 430 | 420 |
| 431 // Sleep for a few frames and verify that more frames were not pushed | 421 // Sleep for a few frames and verify that more frames were not pushed |
| 432 // because the backend device was busy. | 422 // because the backend device was busy. |
| 433 RunMessageLoopFor(5); | 423 RunMessageLoopFor(5); |
| 434 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); | 424 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); |
| 435 | 425 |
| 436 // Unblock the pipeline and verify that PushFrame resumes. | 426 // Unblock the pipeline and verify that PushFrame resumes. |
| 437 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_OK); | 427 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_OK); |
| 438 RunMessageLoopFor(5); | 428 RunMessageLoopFor(5); |
| 439 EXPECT_LT(1u, audio_decoder->pushed_buffer_count()); | 429 EXPECT_LT(1u, audio_decoder->pushed_buffer_count()); |
| 440 | 430 |
| 441 stream->Stop(); | 431 stream->Stop(); |
| 442 stream->Close(); | 432 stream->Close(); |
| 443 } | 433 } |
| 444 | 434 |
| 445 TEST_F(CastAudioOutputStreamTest, DeviceError) { | 435 TEST_F(CastAudioOutputStreamTest, DeviceError) { |
| 446 ::media::AudioOutputStream* stream = CreateStream(); | 436 ::media::AudioOutputStream* stream = CreateStream(); |
| 447 ASSERT_TRUE(stream); | 437 ASSERT_TRUE(stream); |
| 448 EXPECT_TRUE(stream->Open()); | 438 EXPECT_TRUE(stream->Open()); |
| 449 | 439 |
| 450 FakeAudioDecoder* audio_decoder = GetAudio(); | 440 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 451 ASSERT_TRUE(audio_decoder); | 441 ASSERT_TRUE(audio_decoder); |
| 452 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_ERROR); | 442 audio_decoder->set_pipeline_status(FakeAudioDecoder::PIPELINE_STATUS_ERROR); |
| 453 | 443 |
| 454 auto source_callback(base::MakeUnique<MockAudioSourceCallback>()); | 444 ::media::MockAudioSourceCallback source_callback; |
| 455 ON_CALL(*source_callback, OnMoreData(_, _, _, _)) | 445 EXPECT_CALL(source_callback, OnMoreData(_, _, _, _)) |
| 456 .WillByDefault(Invoke(OnMoreData)); | 446 .WillRepeatedly(Invoke(OnMoreData)); |
| 457 // AudioOutputStream must report error to source callback. | 447 // AudioOutputStream must report error to source callback. |
| 458 EXPECT_CALL(*source_callback, OnError()); | 448 EXPECT_CALL(source_callback, OnError()); |
| 459 stream->Start(source_callback.get()); | 449 stream->Start(&source_callback); |
| 460 RunMessageLoopFor(2); | 450 RunMessageLoopFor(2); |
| 461 // Make sure that AudioOutputStream attempted to push the initial frame. | 451 // Make sure that AudioOutputStream attempted to push the initial frame. |
| 462 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); | 452 EXPECT_LT(0u, audio_decoder->pushed_buffer_count()); |
| 463 | 453 |
| 464 stream->Stop(); | 454 stream->Stop(); |
| 465 stream->Close(); | 455 stream->Close(); |
| 466 } | 456 } |
| 467 | 457 |
| 468 TEST_F(CastAudioOutputStreamTest, DeviceAsyncError) { | 458 TEST_F(CastAudioOutputStreamTest, DeviceAsyncError) { |
| 469 ::media::AudioOutputStream* stream = CreateStream(); | 459 ::media::AudioOutputStream* stream = CreateStream(); |
| 470 ASSERT_TRUE(stream); | 460 ASSERT_TRUE(stream); |
| 471 EXPECT_TRUE(stream->Open()); | 461 EXPECT_TRUE(stream->Open()); |
| 472 | 462 |
| 473 FakeAudioDecoder* audio_decoder = GetAudio(); | 463 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 474 ASSERT_TRUE(audio_decoder); | 464 ASSERT_TRUE(audio_decoder); |
| 475 audio_decoder->set_pipeline_status( | 465 audio_decoder->set_pipeline_status( |
| 476 FakeAudioDecoder::PIPELINE_STATUS_ASYNC_ERROR); | 466 FakeAudioDecoder::PIPELINE_STATUS_ASYNC_ERROR); |
| 477 | 467 |
| 478 auto source_callback(base::MakeUnique<MockAudioSourceCallback>()); | 468 ::media::MockAudioSourceCallback source_callback; |
| 479 ON_CALL(*source_callback, OnMoreData(_, _, _, _)) | 469 EXPECT_CALL(source_callback, OnMoreData(_, _, _, _)) |
| 480 .WillByDefault(Invoke(OnMoreData)); | 470 .WillRepeatedly(Invoke(OnMoreData)); |
| 481 // AudioOutputStream must report error to source callback. | 471 // AudioOutputStream must report error to source callback. |
| 482 EXPECT_CALL(*source_callback, OnError()); | 472 EXPECT_CALL(source_callback, OnError()); |
| 483 stream->Start(source_callback.get()); | 473 stream->Start(&source_callback); |
| 484 RunMessageLoopFor(5); | 474 RunMessageLoopFor(5); |
| 485 | 475 |
| 486 // Make sure that one frame was pushed. | 476 // Make sure that one frame was pushed. |
| 487 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); | 477 EXPECT_EQ(1u, audio_decoder->pushed_buffer_count()); |
| 488 | 478 |
| 489 stream->Stop(); | 479 stream->Stop(); |
| 490 stream->Close(); | 480 stream->Close(); |
| 491 } | 481 } |
| 492 | 482 |
| 493 TEST_F(CastAudioOutputStreamTest, Volume) { | 483 TEST_F(CastAudioOutputStreamTest, Volume) { |
| 494 ::media::AudioOutputStream* stream = CreateStream(); | 484 ::media::AudioOutputStream* stream = CreateStream(); |
| 495 ASSERT_TRUE(stream); | 485 ASSERT_TRUE(stream); |
| 496 ASSERT_TRUE(stream->Open()); | 486 ASSERT_TRUE(stream->Open()); |
| 497 FakeAudioDecoder* audio_decoder = GetAudio(); | 487 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 498 ASSERT_TRUE(audio_decoder); | 488 ASSERT_TRUE(audio_decoder); |
| 499 | 489 |
| 500 double volume = 0.0; | 490 double volume = 0.0; |
| 501 stream->GetVolume(&volume); | 491 stream->GetVolume(&volume); |
| 502 EXPECT_EQ(1.0, volume); | 492 EXPECT_EQ(1.0, volume); |
| 503 EXPECT_EQ(1.0f, audio_decoder->volume()); | 493 EXPECT_EQ(1.0f, audio_decoder->volume()); |
| 504 | 494 |
| 505 stream->SetVolume(0.5); | 495 stream->SetVolume(0.5); |
| 496 media_thread_.FlushForTesting(); |
| 506 stream->GetVolume(&volume); | 497 stream->GetVolume(&volume); |
| 507 EXPECT_EQ(0.5, volume); | 498 EXPECT_EQ(0.5, volume); |
| 508 EXPECT_EQ(0.5f, audio_decoder->volume()); | 499 EXPECT_EQ(0.5f, audio_decoder->volume()); |
| 509 | 500 |
| 510 stream->Close(); | 501 stream->Close(); |
| 511 } | 502 } |
| 512 | 503 |
| 513 TEST_F(CastAudioOutputStreamTest, StartStopStart) { | 504 TEST_F(CastAudioOutputStreamTest, StartStopStart) { |
| 514 ::media::AudioOutputStream* stream = CreateStream(); | 505 ::media::AudioOutputStream* stream = CreateStream(); |
| 515 ASSERT_TRUE(stream); | 506 ASSERT_TRUE(stream); |
| 516 ASSERT_TRUE(stream->Open()); | 507 ASSERT_TRUE(stream->Open()); |
| 517 | 508 |
| 518 auto source_callback(base::MakeUnique<MockAudioSourceCallback>()); | 509 ::media::MockAudioSourceCallback source_callback; |
| 519 ON_CALL(*source_callback, OnMoreData(_, _, _, _)) | 510 EXPECT_CALL(source_callback, OnMoreData(_, _, _, _)) |
| 520 .WillByDefault(Invoke(OnMoreData)); | 511 .WillRepeatedly(Invoke(OnMoreData)); |
| 521 stream->Start(source_callback.get()); | 512 stream->Start(&source_callback); |
| 522 RunMessageLoopFor(2); | 513 RunMessageLoopFor(2); |
| 523 stream->Stop(); | 514 stream->Stop(); |
| 524 stream->Start(source_callback.get()); | 515 stream->Start(&source_callback); |
| 525 RunMessageLoopFor(2); | 516 RunMessageLoopFor(2); |
| 526 | 517 |
| 527 FakeAudioDecoder* audio_device = GetAudio(); | 518 FakeAudioDecoder* audio_device = GetAudio(); |
| 528 EXPECT_TRUE(audio_device); | 519 EXPECT_TRUE(audio_device); |
| 529 EXPECT_EQ(FakeMediaPipelineBackend::kStateRunning, GetBackend()->state()); | 520 EXPECT_EQ(FakeMediaPipelineBackend::kStateRunning, GetBackend()->state()); |
| 530 | 521 |
| 531 stream->Close(); | 522 stream->Close(); |
| 532 } | 523 } |
| 533 | 524 |
| 534 TEST_F(CastAudioOutputStreamTest, CloseWithoutStart) { | 525 TEST_F(CastAudioOutputStreamTest, CloseWithoutStart) { |
| 535 ::media::AudioOutputStream* stream = CreateStream(); | 526 ::media::AudioOutputStream* stream = CreateStream(); |
| 536 ASSERT_TRUE(stream); | 527 ASSERT_TRUE(stream); |
| 537 ASSERT_TRUE(stream->Open()); | 528 ASSERT_TRUE(stream->Open()); |
| 538 stream->Close(); | 529 stream->Close(); |
| 539 } | 530 } |
| 540 | 531 |
| 541 TEST_F(CastAudioOutputStreamTest, AudioDelay) { | 532 TEST_F(CastAudioOutputStreamTest, AudioDelay) { |
| 542 ::media::AudioOutputStream* stream = CreateStream(); | 533 ::media::AudioOutputStream* stream = CreateStream(); |
| 543 ASSERT_TRUE(stream); | 534 ASSERT_TRUE(stream); |
| 544 ASSERT_TRUE(stream->Open()); | 535 ASSERT_TRUE(stream->Open()); |
| 545 | 536 |
| 546 FakeAudioDecoder* audio_decoder = GetAudio(); | 537 FakeAudioDecoder* audio_decoder = GetAudio(); |
| 547 ASSERT_TRUE(audio_decoder); | 538 ASSERT_TRUE(audio_decoder); |
| 548 audio_decoder->set_rendering_delay( | 539 audio_decoder->set_rendering_delay( |
| 549 MediaPipelineBackend::AudioDecoder::RenderingDelay(kDelayUs, | 540 MediaPipelineBackend::AudioDecoder::RenderingDelay(kDelayUs, |
| 550 kDelayTimestampUs)); | 541 kDelayTimestampUs)); |
| 551 | 542 |
| 552 auto source_callback(base::MakeUnique<MockAudioSourceCallback>()); | 543 ::media::MockAudioSourceCallback source_callback; |
| 553 const base::TimeDelta delay(base::TimeDelta::FromMicroseconds(kDelayUs)); | 544 const base::TimeDelta delay(base::TimeDelta::FromMicroseconds(kDelayUs)); |
| 554 const base::TimeTicks delay_timestamp( | 545 const base::TimeTicks delay_timestamp( |
| 555 base::TimeTicks() + base::TimeDelta::FromMicroseconds(kDelayTimestampUs)); | 546 base::TimeTicks() + base::TimeDelta::FromMicroseconds(kDelayTimestampUs)); |
| 556 EXPECT_CALL(*source_callback, OnMoreData(delay, delay_timestamp, _, _)) | 547 EXPECT_CALL(source_callback, OnMoreData(delay, delay_timestamp, _, _)) |
| 557 .WillRepeatedly(Invoke(OnMoreData)); | 548 .WillRepeatedly(Invoke(OnMoreData)); |
| 558 | 549 |
| 559 stream->Start(source_callback.get()); | 550 stream->Start(&source_callback); |
| 560 RunMessageLoopFor(2); | 551 RunMessageLoopFor(2); |
| 561 stream->Stop(); | 552 stream->Stop(); |
| 562 stream->Close(); | 553 stream->Close(); |
| 563 } | 554 } |
| 564 | 555 |
| 565 } // namespace | 556 } // namespace |
| 566 } // namespace media | 557 } // namespace media |
| 567 } // namespace chromecast | 558 } // namespace chromecast |
| OLD | NEW |