Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1385)

Side by Side Diff: content/renderer/media/webrtc_audio_device_unittest.cc

Issue 11880009: Introduce AudioHardwareConfig for renderer side audio device info. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Plumb. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/environment.h" 5 #include "base/environment.h"
6 #include "base/test/test_timeouts.h" 6 #include "base/test/test_timeouts.h"
7 #include "content/renderer/media/audio_hardware.h" 7 #include "content/renderer/media/renderer_audio_hardware_config.h"
8 #include "content/renderer/media/webrtc_audio_capturer.h" 8 #include "content/renderer/media/webrtc_audio_capturer.h"
9 #include "content/renderer/media/webrtc_audio_device_impl.h" 9 #include "content/renderer/media/webrtc_audio_device_impl.h"
10 #include "content/renderer/media/webrtc_audio_renderer.h" 10 #include "content/renderer/media/webrtc_audio_renderer.h"
11 #include "content/renderer/render_thread_impl.h"
11 #include "content/test/webrtc_audio_device_test.h" 12 #include "content/test/webrtc_audio_device_test.h"
12 #include "media/audio/audio_manager.h" 13 #include "media/audio/audio_manager_base.h"
13 #include "media/audio/audio_util.h" 14 #include "media/audio/audio_util.h"
14 #include "testing/gmock/include/gmock/gmock.h" 15 #include "testing/gmock/include/gmock/gmock.h"
15 #include "third_party/webrtc/voice_engine/include/voe_audio_processing.h" 16 #include "third_party/webrtc/voice_engine/include/voe_audio_processing.h"
16 #include "third_party/webrtc/voice_engine/include/voe_base.h" 17 #include "third_party/webrtc/voice_engine/include/voe_base.h"
17 #include "third_party/webrtc/voice_engine/include/voe_external_media.h" 18 #include "third_party/webrtc/voice_engine/include/voe_external_media.h"
18 #include "third_party/webrtc/voice_engine/include/voe_file.h" 19 #include "third_party/webrtc/voice_engine/include/voe_file.h"
19 #include "third_party/webrtc/voice_engine/include/voe_network.h" 20 #include "third_party/webrtc/voice_engine/include/voe_network.h"
20 21
21 using testing::_; 22 using testing::_;
22 using testing::AnyNumber; 23 using testing::AnyNumber;
23 using testing::InvokeWithoutArgs; 24 using testing::InvokeWithoutArgs;
24 using testing::Return; 25 using testing::Return;
25 using testing::StrEq; 26 using testing::StrEq;
26 27
27 namespace content { 28 namespace content {
28 29
29 namespace { 30 namespace {
30 31
31 const int kRenderViewId = 1; 32 const int kRenderViewId = 1;
32 33
33 class AudioUtil : public AudioUtilInterface { 34 class RealAudioHardwareConfig : public media::AudioHardwareConfig {
34 public: 35 public:
35 AudioUtil() {} 36 RealAudioHardwareConfig() {}
37 virtual ~RealAudioHardwareConfig() {}
36 38
37 virtual int GetAudioHardwareSampleRate() OVERRIDE { 39 virtual int GetOutputBufferSize() OVERRIDE {
40 return media::GetAudioHardwareBufferSize();
41 }
42
43 virtual int GetOutputSampleRate() OVERRIDE {
38 return media::GetAudioHardwareSampleRate(); 44 return media::GetAudioHardwareSampleRate();
39 } 45 }
40 virtual int GetAudioInputHardwareSampleRate(
41 const std::string& device_id) OVERRIDE {
42 return media::GetAudioInputHardwareSampleRate(device_id);
43 }
44 virtual media::ChannelLayout GetAudioInputHardwareChannelLayout(
45 const std::string& device_id) OVERRIDE {
46 return media::GetAudioInputHardwareChannelLayout(device_id);
47 }
48 private:
49 DISALLOW_COPY_AND_ASSIGN(AudioUtil);
50 };
51 46
52 class AudioUtilNoHardware : public AudioUtilInterface { 47 virtual int GetInputSampleRate() OVERRIDE {
53 public: 48 return media::GetAudioInputHardwareSampleRate(
54 AudioUtilNoHardware(int output_rate, int input_rate, 49 media::AudioManagerBase::kDefaultDeviceId);
55 media::ChannelLayout input_channel_layout)
56 : output_rate_(output_rate),
57 input_rate_(input_rate),
58 input_channel_layout_(input_channel_layout) {
59 } 50 }
60 51
61 virtual int GetAudioHardwareSampleRate() OVERRIDE { 52 virtual media::ChannelLayout GetInputChannelLayout() OVERRIDE {
62 return output_rate_; 53 return media::GetAudioInputHardwareChannelLayout(
63 } 54 media::AudioManagerBase::kDefaultDeviceId);
64 virtual int GetAudioInputHardwareSampleRate(
65 const std::string& device_id) OVERRIDE {
66 return input_rate_;
67 }
68 virtual media::ChannelLayout GetAudioInputHardwareChannelLayout(
69 const std::string& device_id) OVERRIDE {
70 return input_channel_layout_;
71 } 55 }
72 56
73 private: 57 private:
74 int output_rate_; 58 DISALLOW_COPY_AND_ASSIGN(RealAudioHardwareConfig);
75 int input_rate_;
76 media::ChannelLayout input_channel_layout_;
77 DISALLOW_COPY_AND_ASSIGN(AudioUtilNoHardware);
78 }; 59 };
79 60
80 // Return true if at least one element in the array matches |value|. 61 // Return true if at least one element in the array matches |value|.
81 bool FindElementInArray(int* array, int size, int value) { 62 bool FindElementInArray(int* array, int size, int value) {
82 return (std::find(&array[0], &array[0] + size, value) != &array[size]); 63 return (std::find(&array[0], &array[0] + size, value) != &array[size]);
83 } 64 }
84 65
85 // This method returns false if a non-supported rate is detected on the 66 // This method returns false if a non-supported rate is detected on the
86 // input or output side. 67 // input or output side.
87 // TODO(henrika): add support for automatic fallback to Windows Wave audio 68 // TODO(henrika): add support for automatic fallback to Windows Wave audio
88 // if a non-supported rate is detected. It is probably better to detect 69 // if a non-supported rate is detected. It is probably better to detect
89 // invalid audio settings by actually trying to open the audio streams instead 70 // invalid audio settings by actually trying to open the audio streams instead
90 // of relying on hard coded conditions. 71 // of relying on hard coded conditions.
91 bool HardwareSampleRatesAreValid() { 72 bool HardwareSampleRatesAreValid() {
92 // These are the currently supported hardware sample rates in both directions. 73 // These are the currently supported hardware sample rates in both directions.
93 // The actual WebRTC client can limit these ranges further depending on 74 // The actual WebRTC client can limit these ranges further depending on
94 // platform but this is the maximum range we support today. 75 // platform but this is the maximum range we support today.
95 int valid_input_rates[] = {16000, 32000, 44100, 48000, 96000}; 76 int valid_input_rates[] = {16000, 32000, 44100, 48000, 96000};
96 int valid_output_rates[] = {44100, 48000, 96000}; 77 int valid_output_rates[] = {44100, 48000, 96000};
97 78
79 RendererAudioHardwareConfig* hardware_config =
miu 2013/01/29 04:55:43 Possible root cause of crash on Mac: If GetAudioHa
DaleCurtis 2013/01/30 01:31:06 Crash is in Chrome not tests, may be related to ht
80 RenderThreadImpl::current()->GetAudioHardwareConfig();
81
98 // Verify the input sample rate. 82 // Verify the input sample rate.
99 int input_sample_rate = GetAudioInputSampleRate(); 83 int input_sample_rate = hardware_config->GetInputSampleRate();
100 84
101 if (!FindElementInArray(valid_input_rates, arraysize(valid_input_rates), 85 if (!FindElementInArray(valid_input_rates, arraysize(valid_input_rates),
102 input_sample_rate)) { 86 input_sample_rate)) {
103 LOG(WARNING) << "Non-supported input sample rate detected."; 87 LOG(WARNING) << "Non-supported input sample rate detected.";
104 return false; 88 return false;
105 } 89 }
106 90
107 // Given that the input rate was OK, verify the output rate as well. 91 // Given that the input rate was OK, verify the output rate as well.
108 int output_sample_rate = GetAudioOutputSampleRate(); 92 int output_sample_rate = hardware_config->GetOutputSampleRate();
109 if (!FindElementInArray(valid_output_rates, arraysize(valid_output_rates), 93 if (!FindElementInArray(valid_output_rates, arraysize(valid_output_rates),
110 output_sample_rate)) { 94 output_sample_rate)) {
111 LOG(WARNING) << "Non-supported output sample rate detected."; 95 LOG(WARNING) << "Non-supported output sample rate detected.";
112 return false; 96 return false;
113 } 97 }
114 98
115 return true; 99 return true;
116 } 100 }
117 101
118 // Utility method which initializes the audio capturer contained in the 102 // Utility method which initializes the audio capturer contained in the
119 // WebRTC audio device. This method should be used in tests where 103 // WebRTC audio device. This method should be used in tests where
120 // HardwareSampleRatesAreValid() has been called and returned true. 104 // HardwareSampleRatesAreValid() has been called and returned true.
121 bool InitializeCapturer(WebRtcAudioDeviceImpl* webrtc_audio_device) { 105 bool InitializeCapturer(WebRtcAudioDeviceImpl* webrtc_audio_device) {
122 // Access the capturer owned and created by the audio device. 106 // Access the capturer owned and created by the audio device.
123 WebRtcAudioCapturer* capturer = webrtc_audio_device->capturer(); 107 WebRtcAudioCapturer* capturer = webrtc_audio_device->capturer();
124 if (!capturer) 108 if (!capturer)
125 return false; 109 return false;
126 110
111 RendererAudioHardwareConfig* hardware_config =
112 RenderThreadImpl::current()->GetAudioHardwareConfig();
113
127 // Use native capture sample rate and channel configuration to get some 114 // Use native capture sample rate and channel configuration to get some
128 // action in this test. 115 // action in this test.
129 int sample_rate = GetAudioInputSampleRate(); 116 int sample_rate = hardware_config->GetInputSampleRate();
130 media::ChannelLayout channel_layout = GetAudioInputChannelLayout(); 117 media::ChannelLayout channel_layout =
118 hardware_config->GetInputChannelLayout();
131 if (!capturer->Initialize(channel_layout, sample_rate)) 119 if (!capturer->Initialize(channel_layout, sample_rate))
132 return false; 120 return false;
133 121
134 // Ensures that the default capture device is utilized. 122 // Ensures that the default capture device is utilized.
135 webrtc_audio_device->capturer()->SetDevice(1); 123 webrtc_audio_device->capturer()->SetDevice(1);
136 return true; 124 return true;
137 } 125 }
138 126
139 127
140 class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess { 128 class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 int invalid_rates[] = {-1, 0, 8000, 11025, 22050, 32000, 192000}; 227 int invalid_rates[] = {-1, 0, 8000, 11025, 22050, 32000, 192000};
240 for (size_t i = 0; i < arraysize(invalid_rates); ++i) { 228 for (size_t i = 0; i < arraysize(invalid_rates); ++i) {
241 EXPECT_FALSE(FindElementInArray(valid_rates, arraysize(valid_rates), 229 EXPECT_FALSE(FindElementInArray(valid_rates, arraysize(valid_rates),
242 invalid_rates[i])); 230 invalid_rates[i]));
243 } 231 }
244 } 232 }
245 233
246 // Basic test that instantiates and initializes an instance of 234 // Basic test that instantiates and initializes an instance of
247 // WebRtcAudioDeviceImpl. 235 // WebRtcAudioDeviceImpl.
248 TEST_F(WebRTCAudioDeviceTest, Construct) { 236 TEST_F(WebRTCAudioDeviceTest, Construct) {
249 AudioUtilNoHardware audio_util(48000, 48000, media::CHANNEL_LAYOUT_MONO); 237 RendererAudioHardwareConfig audio_config(
250 SetAudioUtilCallback(&audio_util); 238 480, 48000, 48000, media::CHANNEL_LAYOUT_MONO);
239 SetAudioHardwareConfig(&audio_config);
251 240
252 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 241 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
253 new WebRtcAudioDeviceImpl()); 242 new WebRtcAudioDeviceImpl());
254 243
255 // The capturer is not created until after the WebRtcAudioDeviceImpl has 244 // The capturer is not created until after the WebRtcAudioDeviceImpl has
256 // been initialized. 245 // been initialized.
257 EXPECT_FALSE(InitializeCapturer(webrtc_audio_device.get())); 246 EXPECT_FALSE(InitializeCapturer(webrtc_audio_device.get()));
258 247
259 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 248 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
260 ASSERT_TRUE(engine.valid()); 249 ASSERT_TRUE(engine.valid());
(...skipping 11 matching lines...) Expand all
272 // webrtc::VoEExternalMedia implementation to hijack the output audio and 261 // webrtc::VoEExternalMedia implementation to hijack the output audio and
273 // verify that streaming starts correctly. 262 // verify that streaming starts correctly.
274 // Disabled when running headless since the bots don't have the required config. 263 // Disabled when running headless since the bots don't have the required config.
275 // Flaky, http://crbug.com/167299 . 264 // Flaky, http://crbug.com/167299 .
276 TEST_F(WebRTCAudioDeviceTest, DISABLED_StartPlayout) { 265 TEST_F(WebRTCAudioDeviceTest, DISABLED_StartPlayout) {
277 if (!has_output_devices_) { 266 if (!has_output_devices_) {
278 LOG(WARNING) << "No output device detected."; 267 LOG(WARNING) << "No output device detected.";
279 return; 268 return;
280 } 269 }
281 270
282 AudioUtil audio_util; 271 RealAudioHardwareConfig audio_config;
283 SetAudioUtilCallback(&audio_util); 272 SetAudioHardwareConfig(&audio_config);
284 273
285 if (!HardwareSampleRatesAreValid()) 274 if (!HardwareSampleRatesAreValid())
286 return; 275 return;
287 276
288 EXPECT_CALL(media_observer(), 277 EXPECT_CALL(media_observer(),
289 OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1); 278 OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
290 EXPECT_CALL(media_observer(), 279 EXPECT_CALL(media_observer(),
291 OnSetAudioStreamPlaying(_, 1, true)).Times(1); 280 OnSetAudioStreamPlaying(_, 1, true)).Times(1);
292 EXPECT_CALL(media_observer(), 281 EXPECT_CALL(media_observer(),
293 OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1); 282 OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 // is also required to ensure that "sending" can start without actually trying 339 // is also required to ensure that "sending" can start without actually trying
351 // to send encoded packets to the network. Our main interest here is to ensure 340 // to send encoded packets to the network. Our main interest here is to ensure
352 // that the audio capturing starts as it should. 341 // that the audio capturing starts as it should.
353 // Disabled when running headless since the bots don't have the required config. 342 // Disabled when running headless since the bots don't have the required config.
354 TEST_F(WebRTCAudioDeviceTest, StartRecording) { 343 TEST_F(WebRTCAudioDeviceTest, StartRecording) {
355 if (!has_input_devices_ || !has_output_devices_) { 344 if (!has_input_devices_ || !has_output_devices_) {
356 LOG(WARNING) << "Missing audio devices."; 345 LOG(WARNING) << "Missing audio devices.";
357 return; 346 return;
358 } 347 }
359 348
360 AudioUtil audio_util; 349 RealAudioHardwareConfig audio_config;
361 SetAudioUtilCallback(&audio_util); 350 SetAudioHardwareConfig(&audio_config);
362 351
363 if (!HardwareSampleRatesAreValid()) 352 if (!HardwareSampleRatesAreValid())
364 return; 353 return;
365 354
366 // TODO(tommi): extend MediaObserver and MockMediaObserver with support 355 // TODO(tommi): extend MediaObserver and MockMediaObserver with support
367 // for new interfaces, like OnSetAudioStreamRecording(). When done, add 356 // for new interfaces, like OnSetAudioStreamRecording(). When done, add
368 // EXPECT_CALL() macros here. 357 // EXPECT_CALL() macros here.
369 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 358 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
370 new WebRtcAudioDeviceImpl()); 359 new WebRtcAudioDeviceImpl());
371 360
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 // Flaky, http://crbug.com/167298 . 412 // Flaky, http://crbug.com/167298 .
424 TEST_F(WebRTCAudioDeviceTest, DISABLED_PlayLocalFile) { 413 TEST_F(WebRTCAudioDeviceTest, DISABLED_PlayLocalFile) {
425 if (!has_output_devices_) { 414 if (!has_output_devices_) {
426 LOG(WARNING) << "No output device detected."; 415 LOG(WARNING) << "No output device detected.";
427 return; 416 return;
428 } 417 }
429 418
430 std::string file_path( 419 std::string file_path(
431 GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm"))); 420 GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm")));
432 421
433 AudioUtil audio_util; 422 RealAudioHardwareConfig audio_config;
434 SetAudioUtilCallback(&audio_util); 423 SetAudioHardwareConfig(&audio_config);
435 424
436 if (!HardwareSampleRatesAreValid()) 425 if (!HardwareSampleRatesAreValid())
437 return; 426 return;
438 427
439 EXPECT_CALL(media_observer(), 428 EXPECT_CALL(media_observer(),
440 OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1); 429 OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
441 EXPECT_CALL(media_observer(), 430 EXPECT_CALL(media_observer(),
442 OnSetAudioStreamPlaying(_, 1, true)).Times(1); 431 OnSetAudioStreamPlaying(_, 1, true)).Times(1);
443 EXPECT_CALL(media_observer(), 432 EXPECT_CALL(media_observer(),
444 OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1); 433 OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 // where they are decoded and played out on the default audio output device. 483 // where they are decoded and played out on the default audio output device.
495 // Disabled when running headless since the bots don't have the required config. 484 // Disabled when running headless since the bots don't have the required config.
496 // TODO(henrika): improve quality by using a wideband codec, enabling noise- 485 // TODO(henrika): improve quality by using a wideband codec, enabling noise-
497 // suppressions etc. 486 // suppressions etc.
498 TEST_F(WebRTCAudioDeviceTest, FullDuplexAudioWithAGC) { 487 TEST_F(WebRTCAudioDeviceTest, FullDuplexAudioWithAGC) {
499 if (!has_output_devices_ || !has_input_devices_) { 488 if (!has_output_devices_ || !has_input_devices_) {
500 LOG(WARNING) << "Missing audio devices."; 489 LOG(WARNING) << "Missing audio devices.";
501 return; 490 return;
502 } 491 }
503 492
504 AudioUtil audio_util; 493 RealAudioHardwareConfig audio_config;
505 SetAudioUtilCallback(&audio_util); 494 SetAudioHardwareConfig(&audio_config);
506 495
507 if (!HardwareSampleRatesAreValid()) 496 if (!HardwareSampleRatesAreValid())
508 return; 497 return;
509 498
510 EXPECT_CALL(media_observer(), 499 EXPECT_CALL(media_observer(),
511 OnSetAudioStreamStatus(_, 1, StrEq("created"))); 500 OnSetAudioStreamStatus(_, 1, StrEq("created")));
512 EXPECT_CALL(media_observer(), 501 EXPECT_CALL(media_observer(),
513 OnSetAudioStreamPlaying(_, 1, true)); 502 OnSetAudioStreamPlaying(_, 1, true));
514 EXPECT_CALL(media_observer(), 503 EXPECT_CALL(media_observer(),
515 OnSetAudioStreamStatus(_, 1, StrEq("closed"))); 504 OnSetAudioStreamStatus(_, 1, StrEq("closed")));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 549
561 renderer->Stop(); 550 renderer->Stop();
562 EXPECT_EQ(0, base->StopSend(ch)); 551 EXPECT_EQ(0, base->StopSend(ch));
563 EXPECT_EQ(0, base->StopPlayout(ch)); 552 EXPECT_EQ(0, base->StopPlayout(ch));
564 553
565 EXPECT_EQ(0, base->DeleteChannel(ch)); 554 EXPECT_EQ(0, base->DeleteChannel(ch));
566 EXPECT_EQ(0, base->Terminate()); 555 EXPECT_EQ(0, base->Terminate());
567 } 556 }
568 557
569 } // namespace content 558 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698