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

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

Issue 8528026: Adds more unit tests for WebRTC. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Removed DISABLED_ for some tests. Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/webrtc_audio_device_impl.h" 7 #include "content/renderer/media/webrtc_audio_device_impl.h"
8 #include "content/test/webrtc_audio_device_test.h" 8 #include "content/test/webrtc_audio_device_test.h"
9 #include "media/audio/audio_util.h" 9 #include "media/audio/audio_util.h"
10 #include "testing/gmock/include/gmock/gmock.h" 10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "third_party/webrtc/voice_engine/main/interface/voe_audio_processing.h" 11 #include "third_party/webrtc/voice_engine/main/interface/voe_audio_processing.h"
12 #include "third_party/webrtc/voice_engine/main/interface/voe_base.h" 12 #include "third_party/webrtc/voice_engine/main/interface/voe_base.h"
13 #include "third_party/webrtc/voice_engine/main/interface/voe_external_media.h"
13 #include "third_party/webrtc/voice_engine/main/interface/voe_file.h" 14 #include "third_party/webrtc/voice_engine/main/interface/voe_file.h"
14 #include "third_party/webrtc/voice_engine/main/interface/voe_network.h" 15 #include "third_party/webrtc/voice_engine/main/interface/voe_network.h"
15 16
16 using testing::_; 17 using testing::_;
17 using testing::InvokeWithoutArgs; 18 using testing::InvokeWithoutArgs;
18 using testing::Return; 19 using testing::Return;
19 using testing::StrEq; 20 using testing::StrEq;
20 21
21 namespace { 22 namespace {
22 23
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 DISALLOW_COPY_AND_ASSIGN(AudioUtilNoHardware); 58 DISALLOW_COPY_AND_ASSIGN(AudioUtilNoHardware);
58 }; 59 };
59 60
60 bool IsRunningHeadless() { 61 bool IsRunningHeadless() {
61 scoped_ptr<base::Environment> env(base::Environment::Create()); 62 scoped_ptr<base::Environment> env(base::Environment::Create());
62 if (env->HasVar("CHROME_HEADLESS")) 63 if (env->HasVar("CHROME_HEADLESS"))
63 return true; 64 return true;
64 return false; 65 return false;
65 } 66 }
66 67
68 class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess {
69 public:
70 explicit WebRTCMediaProcessImpl(base::WaitableEvent* event)
71 : event_(event),
72 channel_id_(-1),
73 type_(webrtc::kPlaybackPerChannel),
74 packet_size_(0),
75 sample_rate_(0),
76 channels_(0) {
77 }
78 virtual ~WebRTCMediaProcessImpl() {}
79
80 // TODO(henrika): Refactor in WebRTC and convert to Chrome coding style.
81 virtual void Process(const int channel,
82 const webrtc::ProcessingTypes type,
83 WebRtc_Word16 audio_10ms[],
84 const int length,
85 const int sampling_freq,
86 const bool is_stereo) {
87 channel_id_ = channel;
88 type_ = type;
89 packet_size_ = length;
90 sample_rate_ = sampling_freq;
91 channels_ = (is_stereo ? 2 : 1);
92 if (event_) {
93 // Signal that a new callback has been received.
94 event_->Signal();
95 }
96 }
97
98 int channel_id() const { return channel_id_; }
99 int type() const { return type_; }
100 int packet_size() const { return packet_size_; }
101 int sample_rate() const { return sample_rate_; }
102 int channels() const { return channels_; }
103
104 private:
105 base::WaitableEvent* event_;
106 int channel_id_;
107 webrtc::ProcessingTypes type_;
108 int packet_size_;
109 int sample_rate_;
110 int channels_;
111 DISALLOW_COPY_AND_ASSIGN(WebRTCMediaProcessImpl);
112 };
113
67 } // end namespace 114 } // end namespace
68 115
69 // Basic test that instantiates and initializes an instance of 116 // Basic test that instantiates and initializes an instance of
70 // WebRtcAudioDeviceImpl. 117 // WebRtcAudioDeviceImpl.
71 TEST_F(WebRTCAudioDeviceTest, Construct) { 118 TEST_F(WebRTCAudioDeviceTest, Construct) {
72 AudioUtilNoHardware audio_util(48000.0, 48000.0); 119 AudioUtilNoHardware audio_util(48000.0, 48000.0);
73 set_audio_util_callback(&audio_util); 120 set_audio_util_callback(&audio_util);
74 scoped_refptr<WebRtcAudioDeviceImpl> audio_device( 121 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
75 new WebRtcAudioDeviceImpl()); 122 new WebRtcAudioDeviceImpl());
76 audio_device->SetSessionId(1); 123 audio_device->SetSessionId(1);
77 124
78 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 125 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
79 ASSERT_TRUE(engine.valid()); 126 ASSERT_TRUE(engine.valid());
80 127
81 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 128 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
82 int err = base->Init(audio_device); 129 int err = base->Init(audio_device);
83 EXPECT_EQ(0, err); 130 EXPECT_EQ(0, err);
84 EXPECT_EQ(0, base->Terminate()); 131 EXPECT_EQ(0, base->Terminate());
85 } 132 }
86 133
134 // Verify that a call to webrtc::VoEBase::StartPlayout() starts audio output
135 // with the correct set of parameters. A WebRtcAudioDeviceImpl instance will
136 // be utilized to implement the actual audio path. The test registers a
137 // webrtc::VoEExternalMedia implementation to hijack the output audio and
138 // verify that streaming starts correctly.
139 // Disabled when running headless since the bots don't have the required config.
140 TEST_F(WebRTCAudioDeviceTest, StartPlayout) {
141 if (IsRunningHeadless())
142 return;
143
144 AudioUtil audio_util;
145 set_audio_util_callback(&audio_util);
146
147 EXPECT_CALL(media_observer(),
148 OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
149 EXPECT_CALL(media_observer(),
150 OnSetAudioStreamPlaying(_, 1, true)).Times(1);
151 EXPECT_CALL(media_observer(),
152 OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
153 EXPECT_CALL(media_observer(),
154 OnDeleteAudioStream(_, 1)).Times(1);
155
156 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
157 new WebRtcAudioDeviceImpl());
158 audio_device->SetSessionId(1);
159 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
160 ASSERT_TRUE(engine.valid());
161
162 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
163 ASSERT_TRUE(base.valid());
164 int err = base->Init(audio_device);
165 ASSERT_EQ(0, err);
166
167 int ch = base->CreateChannel();
168 EXPECT_NE(-1, ch);
169
170 ScopedWebRTCPtr<webrtc::VoEExternalMedia> external_media(engine.get());
171 ASSERT_TRUE(external_media.valid());
172
173 base::WaitableEvent event(false, false);
174 scoped_ptr<WebRTCMediaProcessImpl> media_process(
175 new WebRTCMediaProcessImpl(&event));
176 EXPECT_EQ(0, external_media->RegisterExternalMediaProcessing(
177 ch, webrtc::kPlaybackPerChannel, *media_process.get()));
178
179 EXPECT_EQ(0, base->StartPlayout(ch));
180
181 EXPECT_TRUE(event.TimedWait(
182 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
183 WaitForIOThreadCompletion();
184
185 EXPECT_TRUE(audio_device->playing());
186 EXPECT_FALSE(audio_device->recording());
187 EXPECT_EQ(ch, media_process->channel_id());
188 EXPECT_EQ(webrtc::kPlaybackPerChannel, media_process->type());
189 EXPECT_EQ(80, media_process->packet_size());
190 EXPECT_EQ(8000, media_process->sample_rate());
191
192 EXPECT_EQ(0, external_media->DeRegisterExternalMediaProcessing(
193 ch, webrtc::kPlaybackPerChannel));
194 EXPECT_EQ(0, base->StopPlayout(ch));
195
196 EXPECT_EQ(0, base->DeleteChannel(ch));
197 EXPECT_EQ(0, base->Terminate());
198 }
199
200 // Verify that a call to webrtc::VoEBase::StartRecording() starts audio input
201 // with the correct set of parameters. A WebRtcAudioDeviceImpl instance will
202 // be utilized to implement the actual audio path. The test registers a
203 // webrtc::VoEExternalMedia implementation to hijack the input audio and
204 // verify that streaming starts correctly. An external transport implementation
205 // is also required to ensure that "sending" can start without actually trying
206 // to send encoded packets to the network. Our main interest here is to ensure
207 // that the audio capturing starts as it should.
208 // Disabled when running headless since the bots don't have the required config.
209 TEST_F(WebRTCAudioDeviceTest, StartRecording) {
210 if (IsRunningHeadless())
211 return;
212
213 AudioUtil audio_util;
214 set_audio_util_callback(&audio_util);
215
216 // TODO(tommi): extend MediaObserver and MockMediaObserver with support
217 // for new interfaces, like OnSetAudioStreamRecording(). When done, add
218 // EXPECT_CALL() macros here.
219
220 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
221 new WebRtcAudioDeviceImpl());
222 audio_device->SetSessionId(1);
223 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
224 ASSERT_TRUE(engine.valid());
225
226 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
227 ASSERT_TRUE(base.valid());
228 int err = base->Init(audio_device);
229 ASSERT_EQ(0, err);
230
231 int ch = base->CreateChannel();
232 EXPECT_NE(-1, ch);
233
234 ScopedWebRTCPtr<webrtc::VoEExternalMedia> external_media(engine.get());
235 ASSERT_TRUE(external_media.valid());
236
237 base::WaitableEvent event(false, false);
238 scoped_ptr<WebRTCMediaProcessImpl> media_process(
239 new WebRTCMediaProcessImpl(&event));
240 EXPECT_EQ(0, external_media->RegisterExternalMediaProcessing(
241 ch, webrtc::kRecordingPerChannel, *media_process.get()));
242
243 // We must add an external transport implementation to be able to start
244 // recording without actually sending encoded packets to the network. All
245 // we want to do here is to verify that audio capturing starts as it should.
246 ScopedWebRTCPtr<webrtc::VoENetwork> network(engine.get());
247 scoped_ptr<WebRTCTransportImpl> transport(
248 new WebRTCTransportImpl(network.get()));
249 EXPECT_EQ(0, network->RegisterExternalTransport(ch, *transport.get()));
250 EXPECT_EQ(0, base->StartSend(ch));
251
252 EXPECT_TRUE(event.TimedWait(
253 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
254 WaitForIOThreadCompletion();
255
256 EXPECT_FALSE(audio_device->playing());
257 EXPECT_TRUE(audio_device->recording());
258 EXPECT_EQ(ch, media_process->channel_id());
259 EXPECT_EQ(webrtc::kRecordingPerChannel, media_process->type());
260 EXPECT_EQ(80, media_process->packet_size());
261 EXPECT_EQ(8000, media_process->sample_rate());
262
263 EXPECT_EQ(0, external_media->DeRegisterExternalMediaProcessing(
264 ch, webrtc::kRecordingPerChannel));
265 EXPECT_EQ(0, base->StopSend(ch));
266
267 EXPECT_EQ(0, base->DeleteChannel(ch));
268 EXPECT_EQ(0, base->Terminate());
269 }
270
87 // Uses WebRtcAudioDeviceImpl to play a local wave file. 271 // Uses WebRtcAudioDeviceImpl to play a local wave file.
88 // Disabled when running headless since the bots don't have the required config. 272 // Disabled when running headless since the bots don't have the required config.
89 TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) { 273 TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) {
90 if (IsRunningHeadless()) 274 if (IsRunningHeadless())
91 return; 275 return;
92 276
93 std::string file_path( 277 std::string file_path(
94 GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm"))); 278 GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm")));
95 279
96 AudioUtil audio_util; 280 AudioUtil audio_util;
(...skipping 24 matching lines...) Expand all
121 EXPECT_NE(-1, ch); 305 EXPECT_NE(-1, ch);
122 EXPECT_EQ(0, base->StartPlayout(ch)); 306 EXPECT_EQ(0, base->StartPlayout(ch));
123 307
124 ScopedWebRTCPtr<webrtc::VoEFile> file(engine.get()); 308 ScopedWebRTCPtr<webrtc::VoEFile> file(engine.get());
125 int duration = 0; 309 int duration = 0;
126 EXPECT_EQ(0, file->GetFileDuration(file_path.c_str(), duration, 310 EXPECT_EQ(0, file->GetFileDuration(file_path.c_str(), duration,
127 webrtc::kFileFormatPcm16kHzFile)); 311 webrtc::kFileFormatPcm16kHzFile));
128 EXPECT_NE(0, duration); 312 EXPECT_NE(0, duration);
129 313
130 EXPECT_EQ(0, file->StartPlayingFileLocally(ch, file_path.c_str(), false, 314 EXPECT_EQ(0, file->StartPlayingFileLocally(ch, file_path.c_str(), false,
131 webrtc::kFileFormatPcm16kHzFile)); 315 webrtc::kFileFormatPcm16kHzFile));
132 316
133 message_loop_.PostDelayedTask(FROM_HERE, 317 message_loop_.PostDelayedTask(FROM_HERE,
134 new MessageLoop::QuitTask(), 318 new MessageLoop::QuitTask(),
135 TestTimeouts::action_timeout_ms()); 319 TestTimeouts::action_timeout_ms());
136 message_loop_.Run(); 320 message_loop_.Run();
137 321
138 EXPECT_EQ(0, base->Terminate()); 322 EXPECT_EQ(0, base->Terminate());
139 } 323 }
324
325 // Uses WebRtcAudioDeviceImpl to play out recorded audio in loopback.
326 // An external transport implementation is utilized to feed back RTP packets
327 // which are recorded, encoded, packetized into RTP packets and finally
328 // "transmitted". The RTP packets are then fed back into the VoiceEngine
329 // where they are decoded and played out on the default audio output device.
330 // Disabled when running headless since the bots don't have the required config.
331 // TODO(henrika): improve quality by using a wideband codec, enabling noise-
332 // suppressions and perhaps also the digital AGC.
333 TEST_F(WebRTCAudioDeviceTest, FullDuplexAudio) {
334 if (IsRunningHeadless())
335 return;
336
337 AudioUtil audio_util;
338 set_audio_util_callback(&audio_util);
339
340 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
341 new WebRtcAudioDeviceImpl());
342 audio_device->SetSessionId(1);
343 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
344 ASSERT_TRUE(engine.valid());
345
346 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
347 ASSERT_TRUE(base.valid());
348 int err = base->Init(audio_device);
349 ASSERT_EQ(0, err);
350
351 int ch = base->CreateChannel();
352 EXPECT_NE(-1, ch);
353
354 ScopedWebRTCPtr<webrtc::VoENetwork> network(engine.get());
355 scoped_ptr<WebRTCTransportImpl> transport(
356 new WebRTCTransportImpl(network.get()));
357 EXPECT_EQ(0, network->RegisterExternalTransport(ch, *transport.get()));
358 EXPECT_EQ(0, base->StartPlayout(ch));
359 EXPECT_EQ(0, base->StartSend(ch));
360
361 LOG(INFO) << ">> You should now be able to hear yourself in loopback...";
362 message_loop_.PostDelayedTask(FROM_HERE,
363 new MessageLoop::QuitTask(),
364 TestTimeouts::action_timeout_ms());
365 message_loop_.Run();
366
367 EXPECT_EQ(0, base->StopSend(ch));
368 EXPECT_EQ(0, base->StopPlayout(ch));
369
370 EXPECT_EQ(0, base->DeleteChannel(ch));
371 EXPECT_EQ(0, base->Terminate());
372 }
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_device_impl.h ('k') | content/test/webrtc_audio_device_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698