Chromium Code Reviews| 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/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/environment.h" | 6 #include "base/environment.h" |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
| 10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
| 11 #include "base/test/test_timeouts.h" | 11 #include "base/test/test_timeouts.h" |
| 12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "media/audio/audio_io.h" | 14 #include "media/audio/audio_io.h" |
| 15 #include "media/audio/audio_manager_base.h" | 15 #include "media/audio/audio_manager_base.h" |
| 16 #include "media/audio/fake_audio_log_factory.h" | 16 #include "media/audio/fake_audio_log_factory.h" |
| 17 #include "media/base/seekable_buffer.h" | 17 #include "media/base/seekable_buffer.h" |
| 18 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 20 |
| 21 #if defined(USE_ALSA) | 21 #if defined(USE_ALSA) |
| 22 #include "media/audio/alsa/audio_manager_alsa.h" | 22 #include "media/audio/alsa/audio_manager_alsa.h" |
| 23 #elif defined(USE_PULSEAUDIO) | |
| 24 #include "media/audio/pulse/audio_manager_pulse.h" | |
| 23 #elif defined(OS_MACOSX) | 25 #elif defined(OS_MACOSX) |
| 24 #include "media/audio/mac/audio_manager_mac.h" | 26 #include "media/audio/mac/audio_manager_mac.h" |
| 25 #elif defined(OS_WIN) | 27 #elif defined(OS_WIN) |
| 26 #include "media/audio/win/audio_manager_win.h" | 28 #include "media/audio/win/audio_manager_win.h" |
| 27 #include "media/audio/win/core_audio_util_win.h" | 29 #include "media/audio/win/core_audio_util_win.h" |
| 28 #elif defined(OS_ANDROID) | 30 #elif defined(OS_ANDROID) |
| 29 #include "media/audio/android/audio_manager_android.h" | 31 #include "media/audio/android/audio_manager_android.h" |
| 30 #else | 32 #else |
| 31 #include "media/audio/fake_audio_manager.h" | 33 #include "media/audio/fake_audio_manager.h" |
| 32 #endif | 34 #endif |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 // Reported capture/input delay. Typical value is ~10 [ms]. | 77 // Reported capture/input delay. Typical value is ~10 [ms]. |
| 76 int input_delay_ms; | 78 int input_delay_ms; |
| 77 | 79 |
| 78 // Reported render/output delay. Typical value is ~40 [ms]. | 80 // Reported render/output delay. Typical value is ~40 [ms]. |
| 79 int output_delay_ms; | 81 int output_delay_ms; |
| 80 }; | 82 }; |
| 81 | 83 |
| 82 // This class mocks the platform specific audio manager and overrides | 84 // This class mocks the platform specific audio manager and overrides |
| 83 // the GetMessageLoop() method to ensure that we can run our tests on | 85 // the GetMessageLoop() method to ensure that we can run our tests on |
| 84 // the main thread instead of the audio thread. | 86 // the main thread instead of the audio thread. |
| 87 /* | |
|
henrika (OOO until Aug 14)
2014/06/10 15:14:06
This complete test is actually disabled. I only us
| |
| 85 class MockAudioManager : public AudioManagerAnyPlatform { | 88 class MockAudioManager : public AudioManagerAnyPlatform { |
| 86 public: | 89 public: |
| 87 MockAudioManager() : AudioManagerAnyPlatform(&fake_audio_log_factory_) {} | 90 MockAudioManager() : AudioManagerAnyPlatform(&fake_audio_log_factory_) {} |
| 88 virtual ~MockAudioManager() {} | 91 virtual ~MockAudioManager() {} |
| 89 | 92 |
| 90 virtual scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() OVERRIDE { | 93 virtual scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() OVERRIDE { |
| 91 return base::MessageLoop::current()->message_loop_proxy(); | 94 return base::MessageLoop::current()->message_loop_proxy(); |
| 92 } | 95 } |
| 93 | 96 |
| 94 private: | 97 private: |
| 95 FakeAudioLogFactory fake_audio_log_factory_; | 98 FakeAudioLogFactory fake_audio_log_factory_; |
| 96 DISALLOW_COPY_AND_ASSIGN(MockAudioManager); | 99 DISALLOW_COPY_AND_ASSIGN(MockAudioManager); |
| 97 }; | 100 }; |
| 101 */ | |
| 98 | 102 |
| 99 // Test fixture class. | 103 // Test fixture class. |
| 100 class AudioLowLatencyInputOutputTest : public testing::Test { | 104 class AudioLowLatencyInputOutputTest : public testing::Test { |
| 101 protected: | 105 protected: |
| 102 AudioLowLatencyInputOutputTest() {} | 106 AudioLowLatencyInputOutputTest() |
| 107 : audio_manager_(AudioManager::CreateForTesting()) {} | |
| 103 | 108 |
| 104 virtual ~AudioLowLatencyInputOutputTest() {} | 109 virtual ~AudioLowLatencyInputOutputTest() {} |
| 105 | 110 |
| 106 AudioManager* audio_manager() { return &mock_audio_manager_; } | 111 AudioManager* audio_manager() { return audio_manager_.get(); } |
| 107 base::MessageLoopForUI* message_loop() { return &message_loop_; } | 112 base::MessageLoopForUI* message_loop() { return &message_loop_; } |
| 108 | 113 |
| 109 // Convenience method which ensures that we are not running on the build | 114 // Convenience method which ensures that we are not running on the build |
| 110 // bots and that at least one valid input and output device can be found. | 115 // bots and that at least one valid input and output device can be found. |
| 111 bool CanRunAudioTests() { | 116 bool CanRunAudioTests() { |
| 112 bool input = audio_manager()->HasAudioInputDevices(); | 117 bool input = audio_manager()->HasAudioInputDevices(); |
| 113 bool output = audio_manager()->HasAudioOutputDevices(); | 118 bool output = audio_manager()->HasAudioOutputDevices(); |
| 114 LOG_IF(WARNING, !input) << "No input device detected."; | 119 LOG_IF(WARNING, !input) << "No input device detected."; |
| 115 LOG_IF(WARNING, !output) << "No output device detected."; | 120 LOG_IF(WARNING, !output) << "No output device detected."; |
| 116 return input && output; | 121 return input && output; |
| 117 } | 122 } |
| 118 | 123 |
| 119 private: | 124 private: |
| 120 base::MessageLoopForUI message_loop_; | 125 base::MessageLoopForUI message_loop_; |
| 121 MockAudioManager mock_audio_manager_; | 126 // MockAudioManager mock_audio_manager_; |
| 127 scoped_ptr<AudioManager> audio_manager_; | |
| 122 | 128 |
| 123 DISALLOW_COPY_AND_ASSIGN(AudioLowLatencyInputOutputTest); | 129 DISALLOW_COPY_AND_ASSIGN(AudioLowLatencyInputOutputTest); |
| 124 }; | 130 }; |
| 125 | 131 |
| 126 // This audio source/sink implementation should be used for manual tests | 132 // This audio source/sink implementation should be used for manual tests |
| 127 // only since delay measurements are stored on an output text file. | 133 // only since delay measurements are stored on an output text file. |
| 128 // All incoming/recorded audio packets are stored in an intermediate media | 134 // All incoming/recorded audio packets are stored in an intermediate media |
| 129 // buffer which the renderer reads from when it needs audio for playout. | 135 // buffer which the renderer reads from when it needs audio for playout. |
| 130 // The total effect is that recorded audio is played out in loop back using | 136 // The total effect is that recorded audio is played out in loop back using |
| 131 // a sync buffer as temporary storage. | 137 // a sync buffer as temporary storage. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 state.input_delay_ms, | 183 state.input_delay_ms, |
| 178 state.output_delay_ms); | 184 state.output_delay_ms); |
| 179 ++elements_written; | 185 ++elements_written; |
| 180 } | 186 } |
| 181 | 187 |
| 182 base::CloseFile(text_file); | 188 base::CloseFile(text_file); |
| 183 } | 189 } |
| 184 | 190 |
| 185 // AudioInputStream::AudioInputCallback. | 191 // AudioInputStream::AudioInputCallback. |
| 186 virtual void OnData(AudioInputStream* stream, | 192 virtual void OnData(AudioInputStream* stream, |
| 187 const uint8* src, uint32 size, | 193 const AudioBus* source, |
| 188 uint32 hardware_delay_bytes, | 194 uint32 hardware_delay_bytes, |
| 189 double volume) OVERRIDE { | 195 double volume) OVERRIDE { |
| 190 base::AutoLock lock(lock_); | 196 base::AutoLock lock(lock_); |
| 191 | 197 |
| 192 // Update three components in the AudioDelayState for this recorded | 198 // Update three components in the AudioDelayState for this recorded |
| 193 // audio packet. | 199 // audio packet. |
| 194 const base::TimeTicks now_time = base::TimeTicks::Now(); | 200 const base::TimeTicks now_time = base::TimeTicks::Now(); |
| 195 const int diff = (now_time - previous_write_time_).InMilliseconds(); | 201 const int diff = (now_time - previous_write_time_).InMilliseconds(); |
| 196 previous_write_time_ = now_time; | 202 previous_write_time_ = now_time; |
| 197 if (input_elements_to_write_ < kMaxDelayMeasurements) { | 203 if (input_elements_to_write_ < kMaxDelayMeasurements) { |
| 198 delay_states_[input_elements_to_write_].delta_time_ms = diff; | 204 delay_states_[input_elements_to_write_].delta_time_ms = diff; |
| 199 delay_states_[input_elements_to_write_].buffer_delay_ms = | 205 delay_states_[input_elements_to_write_].buffer_delay_ms = |
| 200 BytesToMilliseconds(buffer_->forward_bytes()); | 206 BytesToMilliseconds(buffer_->forward_bytes()); |
| 201 delay_states_[input_elements_to_write_].input_delay_ms = | 207 delay_states_[input_elements_to_write_].input_delay_ms = |
| 202 BytesToMilliseconds(hardware_delay_bytes); | 208 BytesToMilliseconds(hardware_delay_bytes); |
| 203 ++input_elements_to_write_; | 209 ++input_elements_to_write_; |
| 204 } | 210 } |
| 205 | 211 |
| 212 /* | |
| 206 // Store the captured audio packet in a seekable media buffer. | 213 // Store the captured audio packet in a seekable media buffer. |
| 207 if (!buffer_->Append(src, size)) { | 214 if (!buffer_->Append(src, size)) { |
| 208 // An attempt to write outside the buffer limits has been made. | 215 // An attempt to write outside the buffer limits has been made. |
| 209 // Double the buffer capacity to ensure that we have a buffer large | 216 // Double the buffer capacity to ensure that we have a buffer large |
| 210 // enough to handle the current sample test scenario. | 217 // enough to handle the current sample test scenario. |
| 211 buffer_->set_forward_capacity(2 * buffer_->forward_capacity()); | 218 buffer_->set_forward_capacity(2 * buffer_->forward_capacity()); |
| 212 buffer_->Clear(); | 219 buffer_->Clear(); |
| 213 } | 220 } |
| 221 */ | |
| 214 } | 222 } |
| 215 | 223 |
| 216 virtual void OnError(AudioInputStream* stream) OVERRIDE {} | 224 virtual void OnError(AudioInputStream* stream) OVERRIDE {} |
| 217 | 225 |
| 218 // AudioOutputStream::AudioSourceCallback. | 226 // AudioOutputStream::AudioSourceCallback. |
| 219 virtual int OnMoreData(AudioBus* audio_bus, | 227 virtual int OnMoreData(AudioBus* audio_bus, |
| 220 AudioBuffersState buffers_state) OVERRIDE { | 228 AudioBuffersState buffers_state) OVERRIDE { |
| 221 base::AutoLock lock(lock_); | 229 base::AutoLock lock(lock_); |
| 222 | 230 |
| 223 // Update one component in the AudioDelayState for the packet | 231 // Update one component in the AudioDelayState for the packet |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 // This test only supports identical parameters in both directions. | 407 // This test only supports identical parameters in both directions. |
| 400 // TODO(henrika): it is possible to cut delay here by using different | 408 // TODO(henrika): it is possible to cut delay here by using different |
| 401 // buffer sizes for input and output. | 409 // buffer sizes for input and output. |
| 402 if (aisw.sample_rate() != aosw.sample_rate() || | 410 if (aisw.sample_rate() != aosw.sample_rate() || |
| 403 aisw.samples_per_packet() != aosw.samples_per_packet() || | 411 aisw.samples_per_packet() != aosw.samples_per_packet() || |
| 404 aisw.channels()!= aosw.channels() || | 412 aisw.channels()!= aosw.channels() || |
| 405 aisw.bits_per_sample() != aosw.bits_per_sample()) { | 413 aisw.bits_per_sample() != aosw.bits_per_sample()) { |
| 406 LOG(ERROR) << "This test requires symmetric input and output parameters. " | 414 LOG(ERROR) << "This test requires symmetric input and output parameters. " |
| 407 "Ensure that sample rate and number of channels are identical in " | 415 "Ensure that sample rate and number of channels are identical in " |
| 408 "both directions"; | 416 "both directions"; |
| 417 DVLOG(1) << aisw.sample_rate() << " " << aosw.sample_rate(); | |
| 418 DVLOG(1) << aisw.samples_per_packet() << " " << aosw.samples_per_packet(); | |
| 409 aos->Close(); | 419 aos->Close(); |
| 410 ais->Close(); | 420 ais->Close(); |
| 411 return; | 421 return; |
| 412 } | 422 } |
| 413 | 423 |
| 414 EXPECT_TRUE(ais->Open()); | 424 EXPECT_TRUE(ais->Open()); |
| 415 EXPECT_TRUE(aos->Open()); | 425 EXPECT_TRUE(aos->Open()); |
| 416 | 426 |
| 417 FullDuplexAudioSinkSource full_duplex( | 427 FullDuplexAudioSinkSource full_duplex( |
| 418 aisw.sample_rate(), aisw.samples_per_packet(), aisw.channels()); | 428 aisw.sample_rate(), aisw.samples_per_packet(), aisw.channels()); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 437 | 447 |
| 438 // All Close() operations that run on the mocked audio thread, | 448 // All Close() operations that run on the mocked audio thread, |
| 439 // should be synchronous and not post additional close tasks to | 449 // should be synchronous and not post additional close tasks to |
| 440 // mocked the audio thread. Hence, there is no need to call | 450 // mocked the audio thread. Hence, there is no need to call |
| 441 // message_loop()->RunUntilIdle() after the Close() methods. | 451 // message_loop()->RunUntilIdle() after the Close() methods. |
| 442 aos->Close(); | 452 aos->Close(); |
| 443 ais->Close(); | 453 ais->Close(); |
| 444 } | 454 } |
| 445 | 455 |
| 446 } // namespace media | 456 } // namespace media |
| OLD | NEW |