OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_mixer.h" | 5 #include "chromecast/media/audio/cast_audio_mixer.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
18 #include "chromecast/media/audio/cast_audio_manager.h" | 18 #include "chromecast/media/audio/cast_audio_manager.h" |
19 #include "chromecast/media/audio/cast_audio_output_stream.h" | 19 #include "chromecast/media/audio/cast_audio_output_stream.h" |
| 20 #include "chromecast/media/cma/test/mock_media_pipeline_backend_factory.h" |
20 #include "media/audio/test_audio_thread.h" | 21 #include "media/audio/test_audio_thread.h" |
21 #include "testing/gmock/include/gmock/gmock.h" | 22 #include "testing/gmock/include/gmock/gmock.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
23 | 24 |
24 namespace chromecast { | 25 namespace chromecast { |
25 namespace media { | 26 namespace media { |
26 namespace { | 27 namespace { |
27 | 28 |
28 using ::testing::_; | 29 using testing::_; |
29 using ::testing::Invoke; | 30 using testing::Assign; |
30 using ::testing::Return; | 31 using testing::Invoke; |
31 using ::testing::StrictMock; | 32 using testing::Return; |
| 33 using testing::SaveArg; |
| 34 using testing::StrictMock; |
32 | 35 |
33 // Utility functions | 36 // Utility functions |
34 ::media::AudioParameters GetAudioParams() { | 37 ::media::AudioParameters GetAudioParams() { |
35 return ::media::AudioParameters( | 38 return ::media::AudioParameters( |
36 ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | 39 ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
37 ::media::CHANNEL_LAYOUT_STEREO, 48000, 16, 1024); | 40 ::media::CHANNEL_LAYOUT_STEREO, 48000, 16, 1024); |
38 } | 41 } |
39 | 42 |
40 // Mock implementations | 43 // Mock implementations |
41 class MockAudioSourceCallback | 44 class MockAudioSourceCallback |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 audio_bus.get()); | 83 audio_bus.get()); |
81 } | 84 } |
82 | 85 |
83 void SignalError(AudioSourceCallback* source_callback) { | 86 void SignalError(AudioSourceCallback* source_callback) { |
84 source_callback->OnError(); | 87 source_callback->OnError(); |
85 } | 88 } |
86 }; | 89 }; |
87 | 90 |
88 class MockCastAudioManager : public CastAudioManager { | 91 class MockCastAudioManager : public CastAudioManager { |
89 public: | 92 public: |
90 MockCastAudioManager(CastAudioMixer* audio_mixer) | 93 MockCastAudioManager() |
91 : CastAudioManager(base::MakeUnique<::media::TestAudioThread>(), | 94 : CastAudioManager(base::MakeUnique<::media::TestAudioThread>(), |
92 nullptr, | 95 nullptr, |
93 nullptr, | 96 nullptr, |
94 audio_mixer) { | 97 nullptr, |
| 98 true /* use_mixer */) { |
95 ON_CALL(*this, ReleaseOutputStream(_)) | 99 ON_CALL(*this, ReleaseOutputStream(_)) |
96 .WillByDefault( | 100 .WillByDefault( |
97 Invoke(this, &MockCastAudioManager::ReleaseOutputStreamConcrete)); | 101 Invoke(this, &MockCastAudioManager::ReleaseOutputStreamConcrete)); |
98 } | 102 } |
99 | 103 |
100 MOCK_METHOD1( | 104 MOCK_METHOD1( |
101 MakeMixerOutputStream, | 105 MakeMixerOutputStream, |
102 ::media::AudioOutputStream*(const ::media::AudioParameters& params)); | 106 ::media::AudioOutputStream*(const ::media::AudioParameters& params)); |
103 MOCK_METHOD1(ReleaseOutputStream, void(::media::AudioOutputStream* stream)); | 107 MOCK_METHOD1(ReleaseOutputStream, void(::media::AudioOutputStream* stream)); |
104 | 108 |
105 private: | 109 private: |
106 void ReleaseOutputStreamConcrete(::media::AudioOutputStream* stream) { | 110 void ReleaseOutputStreamConcrete(::media::AudioOutputStream* stream) { |
107 CastAudioManager::ReleaseOutputStream(stream); | 111 CastAudioManager::ReleaseOutputStream(stream); |
108 } | 112 } |
109 }; | 113 }; |
110 | 114 |
111 class MockCastAudioMixer : public CastAudioMixer { | |
112 public: | |
113 explicit MockCastAudioMixer(const RealStreamFactory& real_stream_factory) | |
114 : CastAudioMixer(real_stream_factory) { | |
115 ON_CALL(*this, MakeStream(_, _)) | |
116 .WillByDefault(Invoke(this, &MockCastAudioMixer::MakeStreamConcrete)); | |
117 } | |
118 | |
119 MOCK_METHOD2( | |
120 MakeStream, | |
121 ::media::AudioOutputStream*(const ::media::AudioParameters& params, | |
122 CastAudioManager* audio_manager)); | |
123 | |
124 private: | |
125 ::media::AudioOutputStream* MakeStreamConcrete( | |
126 const ::media::AudioParameters& params, | |
127 CastAudioManager* audio_manager) { | |
128 return CastAudioMixer::MakeStream(params, audio_manager); | |
129 } | |
130 }; | |
131 | |
132 // Generates StrictMocks of Mixer, Manager, and Mixer OutputStream. | 115 // Generates StrictMocks of Mixer, Manager, and Mixer OutputStream. |
133 class CastAudioMixerTest : public ::testing::Test { | 116 class CastAudioMixerTest : public ::testing::Test { |
134 public: | 117 public: |
135 CastAudioMixerTest() {} | 118 CastAudioMixerTest() : source_callback_(nullptr) {} |
136 ~CastAudioMixerTest() override {} | 119 ~CastAudioMixerTest() override {} |
137 | 120 |
138 protected: | 121 protected: |
139 void SetUp() override { | 122 void SetUp() override { |
140 // |this| will outlive |mock_mixer_| | 123 mock_manager_.reset(new StrictMock<MockCastAudioManager>()); |
141 mock_mixer_ = new StrictMock<MockCastAudioMixer>( | |
142 base::Bind(&CastAudioMixerTest::MakeMixerOutputStreamProxy, | |
143 base::Unretained(this))); | |
144 mock_manager_.reset(new StrictMock<MockCastAudioManager>(mock_mixer_)); | |
145 mock_mixer_stream_.reset(new StrictMock<MockCastAudioOutputStream>( | 124 mock_mixer_stream_.reset(new StrictMock<MockCastAudioOutputStream>( |
146 GetAudioParams(), mock_manager_.get())); | 125 GetAudioParams(), mock_manager_.get())); |
| 126 |
| 127 ON_CALL(*mock_manager_, MakeMixerOutputStream(_)) |
| 128 .WillByDefault(Return(mock_mixer_stream_.get())); |
| 129 ON_CALL(*mock_mixer_stream_, Start(_)) |
| 130 .WillByDefault(SaveArg<0>(&source_callback_)); |
| 131 ON_CALL(*mock_mixer_stream_, Stop()) |
| 132 .WillByDefault(Assign(&source_callback_, nullptr)); |
147 } | 133 } |
148 | 134 |
149 void TearDown() override { mock_manager_->Shutdown(); } | 135 void TearDown() override { mock_manager_->Shutdown(); } |
150 | 136 |
151 MockCastAudioManager& mock_manager() { return *mock_manager_; } | 137 MockCastAudioManager& mock_manager() { return *mock_manager_; } |
152 | |
153 MockCastAudioMixer& mock_mixer() { return *mock_mixer_; } | |
154 | |
155 MockCastAudioOutputStream& mock_mixer_stream() { return *mock_mixer_stream_; } | 138 MockCastAudioOutputStream& mock_mixer_stream() { return *mock_mixer_stream_; } |
156 | 139 |
157 ::media::AudioOutputStream* CreateMixerStream() { | 140 ::media::AudioOutputStream* CreateMixerStream() { |
158 EXPECT_CALL(*mock_mixer_, MakeStream(_, &mock_manager())); | |
159 return mock_manager_->MakeAudioOutputStream( | 141 return mock_manager_->MakeAudioOutputStream( |
160 GetAudioParams(), "", ::media::AudioManager::LogCallback()); | 142 GetAudioParams(), "", ::media::AudioManager::LogCallback()); |
161 } | 143 } |
162 | 144 |
163 private: | |
164 ::media::AudioOutputStream* MakeMixerOutputStreamProxy( | |
165 const ::media::AudioParameters& audio_params) { | |
166 return mock_manager_ ? mock_manager_->MakeMixerOutputStream(audio_params) | |
167 : nullptr; | |
168 } | |
169 | |
170 base::MessageLoop message_loop_; | 145 base::MessageLoop message_loop_; |
171 MockCastAudioMixer* mock_mixer_; | |
172 std::unique_ptr<MockCastAudioManager> mock_manager_; | 146 std::unique_ptr<MockCastAudioManager> mock_manager_; |
173 std::unique_ptr<MockCastAudioOutputStream> mock_mixer_stream_; | 147 std::unique_ptr<MockCastAudioOutputStream> mock_mixer_stream_; |
| 148 |
| 149 // Saved params passed to |mock_mixer_stream_|. |
| 150 ::media::AudioOutputStream::AudioSourceCallback* source_callback_; |
174 }; | 151 }; |
175 | 152 |
176 TEST_F(CastAudioMixerTest, Volume) { | 153 TEST_F(CastAudioMixerTest, Volume) { |
177 ::media::AudioOutputStream* stream = CreateMixerStream(); | 154 ::media::AudioOutputStream* stream = CreateMixerStream(); |
178 ASSERT_TRUE(stream); | 155 ASSERT_TRUE(stream); |
179 | 156 |
180 double volume; | 157 double volume; |
181 stream->GetVolume(&volume); | 158 stream->GetVolume(&volume); |
182 ASSERT_EQ(volume, 1.0); | 159 ASSERT_EQ(volume, 1.0); |
183 | 160 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 204 |
228 // Should not trigger mixer actions. | 205 // Should not trigger mixer actions. |
229 stream->Start(&source); | 206 stream->Start(&source); |
230 stream->Stop(); | 207 stream->Stop(); |
231 | 208 |
232 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 209 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) |
233 .WillOnce(Return(&mock_mixer_stream())); | 210 .WillOnce(Return(&mock_mixer_stream())); |
234 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | 211 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); |
235 ASSERT_TRUE(stream->Open()); | 212 ASSERT_TRUE(stream->Open()); |
236 | 213 |
237 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | 214 EXPECT_CALL(mock_mixer_stream(), Start(_)); |
238 stream->Start(&source); | 215 stream->Start(&source); |
239 stream->Start(&source); | 216 stream->Start(&source); |
240 | 217 |
241 EXPECT_CALL(mock_mixer_stream(), Stop()); | 218 EXPECT_CALL(mock_mixer_stream(), Stop()); |
242 EXPECT_CALL(mock_mixer_stream(), Close()); | 219 EXPECT_CALL(mock_mixer_stream(), Close()); |
243 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); | 220 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); |
244 stream->Close(); // Close abruptly without Stop(), should not fail. | 221 stream->Close(); // Close abruptly without Stop(), should not fail. |
245 } | 222 } |
246 | 223 |
247 TEST_F(CastAudioMixerTest, SingleStreamCycle) { | 224 TEST_F(CastAudioMixerTest, SingleStreamCycle) { |
248 MockAudioSourceCallback source; | 225 MockAudioSourceCallback source; |
249 ::media::AudioOutputStream* stream = CreateMixerStream(); | 226 ::media::AudioOutputStream* stream = CreateMixerStream(); |
250 ASSERT_TRUE(stream); | 227 ASSERT_TRUE(stream); |
251 | 228 |
252 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 229 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) |
253 .WillOnce(Return(&mock_mixer_stream())); | 230 .WillOnce(Return(&mock_mixer_stream())); |
254 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | 231 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); |
255 ASSERT_TRUE(stream->Open()); | 232 ASSERT_TRUE(stream->Open()); |
256 | 233 |
257 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())).Times(2); | 234 EXPECT_CALL(mock_mixer_stream(), Start(_)).Times(2); |
258 EXPECT_CALL(mock_mixer_stream(), Stop()).Times(2); | 235 EXPECT_CALL(mock_mixer_stream(), Stop()).Times(2); |
259 stream->Start(&source); | 236 stream->Start(&source); |
260 stream->Stop(); | 237 stream->Stop(); |
261 stream->Start(&source); | 238 stream->Start(&source); |
262 stream->Stop(); | 239 stream->Stop(); |
263 | 240 |
264 EXPECT_CALL(mock_mixer_stream(), Close()); | 241 EXPECT_CALL(mock_mixer_stream(), Close()); |
265 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); | 242 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); |
266 stream->Close(); | 243 stream->Close(); |
267 } | 244 } |
268 | 245 |
269 TEST_F(CastAudioMixerTest, MultiStreamCycle) { | 246 TEST_F(CastAudioMixerTest, MultiStreamCycle) { |
270 // This test will break if run with < 1 stream. | 247 // This test will break if run with < 1 stream. |
271 std::vector<::media::AudioOutputStream*> streams(5); | 248 std::vector<::media::AudioOutputStream*> streams(5); |
272 std::vector<std::unique_ptr<MockAudioSourceCallback>> sources(streams.size()); | 249 std::vector<std::unique_ptr<MockAudioSourceCallback>> sources(streams.size()); |
273 std::generate(streams.begin(), streams.end(), | 250 std::generate(streams.begin(), streams.end(), |
274 [this] { return CreateMixerStream(); }); | 251 [this] { return CreateMixerStream(); }); |
275 std::generate(sources.begin(), sources.end(), [this] { | 252 std::generate(sources.begin(), sources.end(), [this] { |
276 return std::unique_ptr<MockAudioSourceCallback>( | 253 return std::unique_ptr<MockAudioSourceCallback>( |
277 new StrictMock<MockAudioSourceCallback>()); | 254 new StrictMock<MockAudioSourceCallback>()); |
278 }); | 255 }); |
279 | 256 |
280 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 257 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) |
281 .WillOnce(Return(&mock_mixer_stream())); | 258 .WillOnce(Return(&mock_mixer_stream())); |
282 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | 259 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); |
283 for (auto* stream : streams) | 260 for (auto* stream : streams) |
284 ASSERT_TRUE(stream->Open()); | 261 ASSERT_TRUE(stream->Open()); |
285 | 262 |
286 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | 263 EXPECT_CALL(mock_mixer_stream(), Start(_)); |
287 for (unsigned int i = 0; i < streams.size(); i++) | 264 for (unsigned int i = 0; i < streams.size(); i++) |
288 streams[i]->Start(sources[i].get()); | 265 streams[i]->Start(sources[i].get()); |
289 | 266 |
290 // Individually pull out streams | 267 // Individually pull out streams |
291 while (streams.size() > 1) { | 268 while (streams.size() > 1) { |
292 ::media::AudioOutputStream* stream = streams.front(); | 269 ::media::AudioOutputStream* stream = streams.front(); |
293 stream->Stop(); | 270 stream->Stop(); |
294 streams.erase(streams.begin()); | 271 streams.erase(streams.begin()); |
295 sources.erase(sources.begin()); | 272 sources.erase(sources.begin()); |
296 | 273 |
297 for (auto& source : sources) | 274 for (auto& source : sources) |
298 EXPECT_CALL(*source, OnMoreData(_, _, _, _)); | 275 EXPECT_CALL(*source, OnMoreData(_, _, _, _)); |
299 mock_mixer_stream().SignalPull(&mock_mixer(), base::TimeDelta()); | 276 mock_mixer_stream().SignalPull(source_callback_, base::TimeDelta()); |
300 | 277 |
301 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); | 278 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); |
302 stream->Close(); | 279 stream->Close(); |
303 } | 280 } |
304 | 281 |
305 EXPECT_CALL(mock_mixer_stream(), Stop()); | 282 EXPECT_CALL(mock_mixer_stream(), Stop()); |
306 EXPECT_CALL(mock_mixer_stream(), Close()); | 283 EXPECT_CALL(mock_mixer_stream(), Close()); |
307 EXPECT_CALL(mock_manager(), ReleaseOutputStream(streams.front())); | 284 EXPECT_CALL(mock_manager(), ReleaseOutputStream(streams.front())); |
308 streams.front()->Close(); | 285 streams.front()->Close(); |
309 } | 286 } |
310 | 287 |
311 TEST_F(CastAudioMixerTest, TwoStreamRestart) { | 288 TEST_F(CastAudioMixerTest, TwoStreamRestart) { |
312 MockAudioSourceCallback source; | 289 MockAudioSourceCallback source; |
313 ::media::AudioOutputStream *stream1, *stream2; | 290 ::media::AudioOutputStream *stream1, *stream2; |
314 | 291 |
315 for (int i = 0; i < 2; i++) { | 292 for (int i = 0; i < 2; i++) { |
316 stream1 = CreateMixerStream(); | 293 stream1 = CreateMixerStream(); |
317 stream2 = CreateMixerStream(); | 294 stream2 = CreateMixerStream(); |
318 ASSERT_TRUE(stream1); | 295 ASSERT_TRUE(stream1); |
319 ASSERT_TRUE(stream2); | 296 ASSERT_TRUE(stream2); |
320 | 297 |
321 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 298 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) |
322 .WillOnce(Return(&mock_mixer_stream())); | 299 .WillOnce(Return(&mock_mixer_stream())); |
323 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | 300 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); |
324 ASSERT_TRUE(stream1->Open()); | 301 ASSERT_TRUE(stream1->Open()); |
325 ASSERT_TRUE(stream2->Open()); | 302 ASSERT_TRUE(stream2->Open()); |
326 | 303 |
327 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | 304 EXPECT_CALL(mock_mixer_stream(), Start(_)); |
328 stream1->Start(&source); | 305 stream1->Start(&source); |
329 stream2->Start(&source); | 306 stream2->Start(&source); |
330 | 307 |
331 stream1->Stop(); | 308 stream1->Stop(); |
332 EXPECT_CALL(mock_mixer_stream(), Stop()); | 309 EXPECT_CALL(mock_mixer_stream(), Stop()); |
333 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream2)); | 310 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream2)); |
334 stream2->Close(); | 311 stream2->Close(); |
335 EXPECT_CALL(mock_mixer_stream(), Close()); | 312 EXPECT_CALL(mock_mixer_stream(), Close()); |
336 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream1)); | 313 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream1)); |
337 stream1->Close(); | 314 stream1->Close(); |
338 } | 315 } |
339 } | 316 } |
340 | 317 |
341 TEST_F(CastAudioMixerTest, OnErrorRecovery) { | 318 TEST_F(CastAudioMixerTest, OnError) { |
342 MockAudioSourceCallback source; | 319 MockAudioSourceCallback source; |
343 std::vector<::media::AudioOutputStream*> streams; | 320 std::vector<::media::AudioOutputStream*> streams; |
344 | 321 |
345 streams.push_back(CreateMixerStream()); | |
346 streams.push_back(CreateMixerStream()); | |
347 for (auto* stream : streams) | |
348 ASSERT_TRUE(stream); | |
349 | |
350 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | |
351 .WillOnce(Return(&mock_mixer_stream())); | |
352 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | |
353 for (auto* stream : streams) | |
354 ASSERT_TRUE(stream->Open()); | |
355 | |
356 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | |
357 streams.front()->Start(&source); | |
358 | |
359 EXPECT_CALL(mock_mixer_stream(), Stop()); | |
360 EXPECT_CALL(mock_mixer_stream(), Close()); | |
361 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | |
362 .WillOnce(Return(&mock_mixer_stream())); | |
363 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | |
364 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | |
365 | |
366 // The MockAudioSourceCallback should not receive any call OnError. | |
367 mock_mixer_stream().SignalError(&mock_mixer()); | |
368 | |
369 // Try to add another stream. | |
370 streams.push_back(CreateMixerStream()); | |
371 ASSERT_TRUE(streams.back()); | |
372 ASSERT_TRUE(streams.back()->Open()); | |
373 | |
374 EXPECT_CALL(mock_mixer_stream(), Stop()); | |
375 EXPECT_CALL(mock_mixer_stream(), Close()); | |
376 for (auto* stream : streams) { | |
377 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); | |
378 stream->Close(); | |
379 } | |
380 } | |
381 | |
382 TEST_F(CastAudioMixerTest, OnErrorNoRecovery) { | |
383 MockAudioSourceCallback source; | |
384 std::vector<::media::AudioOutputStream*> streams; | |
385 | |
386 streams.push_back(CreateMixerStream()); | 322 streams.push_back(CreateMixerStream()); |
387 streams.push_back(CreateMixerStream()); | 323 streams.push_back(CreateMixerStream()); |
388 for (auto* stream : streams) | 324 for (auto* stream : streams) |
389 ASSERT_TRUE(stream); | 325 ASSERT_TRUE(stream); |
390 | 326 |
391 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 327 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) |
392 .WillOnce(Return(&mock_mixer_stream())); | 328 .WillOnce(Return(&mock_mixer_stream())); |
393 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | 329 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); |
394 for (auto* stream : streams) | 330 for (auto* stream : streams) |
395 ASSERT_TRUE(stream->Open()); | 331 ASSERT_TRUE(stream->Open()); |
396 | 332 |
397 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | 333 EXPECT_CALL(mock_mixer_stream(), Start(_)); |
398 streams.front()->Start(&source); | 334 streams.front()->Start(&source); |
399 | 335 |
400 EXPECT_CALL(mock_mixer_stream(), Stop()); | 336 // Note that error will only be triggered on the first stream because that |
401 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 337 // is the only stream that has been started. |
402 .WillOnce(Return(&mock_mixer_stream())); | |
403 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(false)); | |
404 EXPECT_CALL(mock_mixer_stream(), Close()).Times(2); | |
405 EXPECT_CALL(source, OnError()); | 338 EXPECT_CALL(source, OnError()); |
406 | 339 mock_mixer_stream().SignalError(source_callback_); |
407 // The MockAudioSourceCallback should receive an OnError call. | 340 base::RunLoop().RunUntilIdle(); |
408 mock_mixer_stream().SignalError(&mock_mixer()); | |
409 | 341 |
410 // Try to add another stream. | 342 // Try to add another stream. |
411 streams.push_back(CreateMixerStream()); | 343 streams.push_back(CreateMixerStream()); |
412 ASSERT_TRUE(streams.back()); | 344 ASSERT_TRUE(streams.back()); |
413 ASSERT_FALSE(streams.back()->Open()); | 345 ASSERT_FALSE(streams.back()->Open()); |
414 | 346 |
| 347 EXPECT_CALL(mock_mixer_stream(), Stop()); |
| 348 EXPECT_CALL(mock_mixer_stream(), Close()); |
415 for (auto* stream : streams) { | 349 for (auto* stream : streams) { |
416 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); | 350 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); |
417 stream->Close(); | 351 stream->Close(); |
418 } | 352 } |
| 353 streams.clear(); |
419 | 354 |
420 // Now that the state has been refreshed, attempt to open a stream. | 355 // Now that the state has been refreshed, attempt to open a stream. |
421 streams.clear(); | |
422 streams.push_back(CreateMixerStream()); | 356 streams.push_back(CreateMixerStream()); |
423 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 357 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) |
424 .WillOnce(Return(&mock_mixer_stream())); | 358 .WillOnce(Return(&mock_mixer_stream())); |
425 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | 359 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); |
426 ASSERT_TRUE(streams.front()->Open()); | 360 ASSERT_TRUE(streams.front()->Open()); |
427 | 361 |
428 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | 362 EXPECT_CALL(mock_mixer_stream(), Start(_)); |
429 streams.front()->Start(&source); | 363 streams.front()->Start(&source); |
430 | 364 |
431 EXPECT_CALL(mock_mixer_stream(), Stop()); | 365 EXPECT_CALL(mock_mixer_stream(), Stop()); |
432 EXPECT_CALL(mock_mixer_stream(), Close()); | 366 EXPECT_CALL(mock_mixer_stream(), Close()); |
433 EXPECT_CALL(mock_manager(), ReleaseOutputStream(streams.front())); | 367 EXPECT_CALL(mock_manager(), ReleaseOutputStream(streams.front())); |
434 streams.front()->Close(); | 368 streams.front()->Close(); |
435 } | 369 } |
436 | 370 |
437 TEST_F(CastAudioMixerTest, Delay) { | 371 TEST_F(CastAudioMixerTest, Delay) { |
438 MockAudioSourceCallback source; | 372 MockAudioSourceCallback source; |
439 ::media::AudioOutputStream* stream = CreateMixerStream(); | 373 ::media::AudioOutputStream* stream = CreateMixerStream(); |
440 | 374 |
441 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) | 375 EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) |
442 .WillOnce(Return(&mock_mixer_stream())); | 376 .WillOnce(Return(&mock_mixer_stream())); |
443 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); | 377 EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); |
444 ASSERT_TRUE(stream->Open()); | 378 ASSERT_TRUE(stream->Open()); |
445 | 379 |
446 EXPECT_CALL(mock_mixer_stream(), Start(&mock_mixer())); | 380 EXPECT_CALL(mock_mixer_stream(), Start(_)); |
447 stream->Start(&source); | 381 stream->Start(&source); |
448 | 382 |
449 // |delay| is the same because the Mixer and stream are | 383 // |delay| is the same because the Mixer and stream are |
450 // using the same AudioParameters. | 384 // using the same AudioParameters. |
451 base::TimeDelta delay = base::TimeDelta::FromMicroseconds(1000); | 385 base::TimeDelta delay = base::TimeDelta::FromMicroseconds(1000); |
452 EXPECT_CALL(source, OnMoreData(delay, _, 0, _)); | 386 EXPECT_CALL(source, OnMoreData(delay, _, 0, _)); |
453 mock_mixer_stream().SignalPull(&mock_mixer(), delay); | 387 mock_mixer_stream().SignalPull(source_callback_, delay); |
454 | 388 |
455 EXPECT_CALL(mock_mixer_stream(), Stop()); | 389 EXPECT_CALL(mock_mixer_stream(), Stop()); |
456 EXPECT_CALL(mock_mixer_stream(), Close()); | 390 EXPECT_CALL(mock_mixer_stream(), Close()); |
457 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); | 391 EXPECT_CALL(mock_manager(), ReleaseOutputStream(stream)); |
458 stream->Close(); | 392 stream->Close(); |
459 } | 393 } |
460 | 394 |
461 } // namespace | 395 } // namespace |
462 } // namespace media | 396 } // namespace media |
463 } // namespace chromecast | 397 } // namespace chromecast |
OLD | NEW |