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 "media/audio/win/audio_low_latency_input_win.h" | 5 #include "media/audio/win/audio_low_latency_input_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <mmsystem.h> | 8 #include <mmsystem.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <stdint.h> | 10 #include <stdint.h> |
11 | 11 |
12 #include <memory> | 12 #include <memory> |
13 | 13 |
14 #include "base/environment.h" | 14 #include "base/environment.h" |
15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
18 #include "base/path_service.h" | 18 #include "base/path_service.h" |
19 #include "base/run_loop.h" | 19 #include "base/run_loop.h" |
| 20 #include "base/single_thread_task_runner.h" |
20 #include "base/test/test_timeouts.h" | 21 #include "base/test/test_timeouts.h" |
21 #include "base/win/scoped_com_initializer.h" | 22 #include "base/win/scoped_com_initializer.h" |
22 #include "media/audio/audio_device_description.h" | 23 #include "media/audio/audio_device_description.h" |
23 #include "media/audio/audio_io.h" | 24 #include "media/audio/audio_io.h" |
24 #include "media/audio/audio_manager.h" | 25 #include "media/audio/audio_manager.h" |
25 #include "media/audio/audio_unittest_util.h" | 26 #include "media/audio/audio_unittest_util.h" |
26 #include "media/audio/win/core_audio_util_win.h" | 27 #include "media/audio/win/core_audio_util_win.h" |
27 #include "media/base/seekable_buffer.h" | 28 #include "media/base/seekable_buffer.h" |
28 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
29 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
30 | 31 |
31 using ::testing::_; | 32 using ::testing::_; |
32 using ::testing::AnyNumber; | 33 using ::testing::AnyNumber; |
33 using ::testing::AtLeast; | 34 using ::testing::AtLeast; |
34 using ::testing::Gt; | 35 using ::testing::Gt; |
35 using ::testing::NotNull; | 36 using ::testing::NotNull; |
36 | 37 |
37 namespace media { | 38 namespace media { |
38 | 39 |
39 ACTION_P3(CheckCountAndPostQuitTask, count, limit, run_loop) { | 40 ACTION_P4(CheckCountAndPostQuitTask, count, limit, task_runner, quit_closure) { |
40 if (++*count >= limit) | 41 if (++*count >= limit) |
41 run_loop->QuitWhenIdle(); | 42 task_runner->PostTask(FROM_HERE, quit_closure); |
42 } | 43 } |
43 | 44 |
44 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { | 45 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { |
45 public: | 46 public: |
46 MOCK_METHOD4(OnData, | 47 MOCK_METHOD4(OnData, |
47 void(AudioInputStream* stream, | 48 void(AudioInputStream* stream, |
48 const AudioBus* src, | 49 const AudioBus* src, |
49 uint32_t hardware_delay_bytes, | 50 uint32_t hardware_delay_bytes, |
50 double volume)); | 51 double volume)); |
51 MOCK_METHOD1(OnError, void(AudioInputStream* stream)); | 52 MOCK_METHOD1(OnError, void(AudioInputStream* stream)); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 EXPECT_TRUE(wais->started()); | 354 EXPECT_TRUE(wais->started()); |
354 | 355 |
355 // Stop(), Stop() is a valid calling sequence (second call does nothing). | 356 // Stop(), Stop() is a valid calling sequence (second call does nothing). |
356 ais->Stop(); | 357 ais->Stop(); |
357 EXPECT_FALSE(wais->started()); | 358 EXPECT_FALSE(wais->started()); |
358 ais->Stop(); | 359 ais->Stop(); |
359 EXPECT_FALSE(wais->started()); | 360 EXPECT_FALSE(wais->started()); |
360 ais.Close(); | 361 ais.Close(); |
361 } | 362 } |
362 | 363 |
363 // TODO(fdoray): investigate failure and re-enable. crbug.com/641142 | 364 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { |
364 TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamTestPacketSizes) { | |
365 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 365 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
366 | 366 |
367 int count = 0; | 367 int count = 0; |
368 | 368 |
369 // 10 ms packet size. | 369 // 10 ms packet size. |
370 | 370 |
371 // Create default WASAPI input stream which records in stereo using | 371 // Create default WASAPI input stream which records in stereo using |
372 // the shared mixing rate. The default buffer size is 10ms. | 372 // the shared mixing rate. The default buffer size is 10ms. |
373 AudioInputStreamWrapper aisw(audio_manager_.get()); | 373 AudioInputStreamWrapper aisw(audio_manager_.get()); |
374 ScopedAudioInputStream ais(aisw.Create()); | 374 ScopedAudioInputStream ais(aisw.Create()); |
375 EXPECT_TRUE(ais->Open()); | 375 EXPECT_TRUE(ais->Open()); |
376 | 376 |
377 MockAudioInputCallback sink; | 377 MockAudioInputCallback sink; |
378 | 378 |
379 // Derive the expected size in bytes of each recorded packet. | 379 // Derive the expected size in bytes of each recorded packet. |
380 uint32_t bytes_per_packet = | 380 uint32_t bytes_per_packet = |
381 aisw.channels() * aisw.frames_per_buffer() * (aisw.bits_per_sample() / 8); | 381 aisw.channels() * aisw.frames_per_buffer() * (aisw.bits_per_sample() / 8); |
382 | 382 |
383 { | 383 { |
384 // We use 10ms packets and will run the test until ten packets are received. | 384 // We use 10ms packets and will run the test until ten packets are received. |
385 // All should contain valid packets of the same size and a valid delay | 385 // All should contain valid packets of the same size and a valid delay |
386 // estimate. | 386 // estimate. |
387 base::RunLoop run_loop; | 387 base::RunLoop run_loop; |
388 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) | 388 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) |
389 .Times(AtLeast(10)) | 389 .Times(AtLeast(10)) |
390 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &run_loop)); | 390 .WillRepeatedly( |
| 391 CheckCountAndPostQuitTask(&count, 10, message_loop_.task_runner(), |
| 392 run_loop.QuitWhenIdleClosure())); |
391 ais->Start(&sink); | 393 ais->Start(&sink); |
392 run_loop.Run(); | 394 run_loop.Run(); |
393 ais->Stop(); | 395 ais->Stop(); |
394 } | 396 } |
395 | 397 |
396 // Store current packet size (to be used in the subsequent tests). | 398 // Store current packet size (to be used in the subsequent tests). |
397 int frames_per_buffer_10ms = aisw.frames_per_buffer(); | 399 int frames_per_buffer_10ms = aisw.frames_per_buffer(); |
398 | 400 |
399 ais.Close(); | 401 ais.Close(); |
400 | 402 |
401 // 20 ms packet size. | 403 // 20 ms packet size. |
402 | 404 |
403 count = 0; | 405 count = 0; |
404 ais.Reset(aisw.Create(2 * frames_per_buffer_10ms)); | 406 ais.Reset(aisw.Create(2 * frames_per_buffer_10ms)); |
405 EXPECT_TRUE(ais->Open()); | 407 EXPECT_TRUE(ais->Open()); |
406 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * | 408 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * |
407 (aisw.bits_per_sample() / 8); | 409 (aisw.bits_per_sample() / 8); |
408 | 410 |
409 { | 411 { |
410 base::RunLoop run_loop; | 412 base::RunLoop run_loop; |
411 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) | 413 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) |
412 .Times(AtLeast(10)) | 414 .Times(AtLeast(10)) |
413 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &run_loop)); | 415 .WillRepeatedly( |
| 416 CheckCountAndPostQuitTask(&count, 10, message_loop_.task_runner(), |
| 417 run_loop.QuitWhenIdleClosure())); |
414 ais->Start(&sink); | 418 ais->Start(&sink); |
415 run_loop.Run(); | 419 run_loop.Run(); |
416 ais->Stop(); | 420 ais->Stop(); |
417 ais.Close(); | 421 ais.Close(); |
418 } | 422 } |
419 | 423 |
420 // 5 ms packet size. | 424 // 5 ms packet size. |
421 | 425 |
422 count = 0; | 426 count = 0; |
423 ais.Reset(aisw.Create(frames_per_buffer_10ms / 2)); | 427 ais.Reset(aisw.Create(frames_per_buffer_10ms / 2)); |
424 EXPECT_TRUE(ais->Open()); | 428 EXPECT_TRUE(ais->Open()); |
425 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * | 429 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * |
426 (aisw.bits_per_sample() / 8); | 430 (aisw.bits_per_sample() / 8); |
427 | 431 |
428 { | 432 { |
429 base::RunLoop run_loop; | 433 base::RunLoop run_loop; |
430 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) | 434 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) |
431 .Times(AtLeast(10)) | 435 .Times(AtLeast(10)) |
432 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &run_loop)); | 436 .WillRepeatedly( |
| 437 CheckCountAndPostQuitTask(&count, 10, message_loop_.task_runner(), |
| 438 run_loop.QuitWhenIdleClosure())); |
433 ais->Start(&sink); | 439 ais->Start(&sink); |
434 run_loop.Run(); | 440 run_loop.Run(); |
435 ais->Stop(); | 441 ais->Stop(); |
436 ais.Close(); | 442 ais.Close(); |
437 } | 443 } |
438 } | 444 } |
439 | 445 |
440 // Test that we can capture a stream in loopback. | 446 // Test that we can capture a stream in loopback. |
441 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { | 447 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { |
442 ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices() && | 448 ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices() && |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); | 494 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); |
489 VLOG(0) << ">> Speak into the default microphone while recording."; | 495 VLOG(0) << ">> Speak into the default microphone while recording."; |
490 ais->Start(&file_sink); | 496 ais->Start(&file_sink); |
491 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); | 497 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); |
492 ais->Stop(); | 498 ais->Stop(); |
493 VLOG(0) << ">> Recording has stopped."; | 499 VLOG(0) << ">> Recording has stopped."; |
494 ais.Close(); | 500 ais.Close(); |
495 } | 501 } |
496 | 502 |
497 } // namespace media | 503 } // namespace media |
OLD | NEW |