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

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: Nits after review by Tommi 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 11 matching lines...) Expand all
34 } 35 }
35 }; 36 };
36 37
37 bool IsRunningHeadless() { 38 bool IsRunningHeadless() {
38 scoped_ptr<base::Environment> env(base::Environment::Create()); 39 scoped_ptr<base::Environment> env(base::Environment::Create());
39 if (env->HasVar("CHROME_HEADLESS")) 40 if (env->HasVar("CHROME_HEADLESS"))
40 return true; 41 return true;
41 return false; 42 return false;
42 } 43 }
43 44
45 class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess {
46 public:
47 explicit WebRTCMediaProcessImpl(base::WaitableEvent* event)
48 : event_(event),
scherkus (not reviewing) 2011/11/16 01:23:13 indent by two more spaces
henrika (OOO until Aug 14) 2011/11/16 11:25:34 Done.
49 channel_id_(-1),
50 type_(webrtc::kPlaybackPerChannel),
51 packet_size_(0),
52 sample_rate_(0),
53 channels_(0) {
54 }
55 virtual ~WebRTCMediaProcessImpl() {}
56
57 // TODO(henrika): Refactor in WebRTC and convert to Chrome coding style.
58 virtual void Process(const int channel,
59 const webrtc::ProcessingTypes type,
60 WebRtc_Word16 audio_10ms[],
61 const int length,
62 const int sampling_freq,
63 const bool is_stereo) {
64 channel_id_ = channel;
65 type_ = type;
66 packet_size_ = length;
67 sample_rate_ = sampling_freq;
68 channels_ = (is_stereo ? 2 : 1);
69 if (event_) {
70 // Signal that a new callback has been received.
71 event_->Signal();
72 }
73 }
74
75 int channel_id() const { return channel_id_; }
76 int type() const { return type_; }
77 int packet_size() const { return packet_size_; }
78 int sample_rate() const { return sample_rate_; }
79 int channels() const { return channels_; }
80
81 private:
82 base::WaitableEvent* event_;
83 int channel_id_;
84 webrtc::ProcessingTypes type_;
85 int packet_size_;
86 int sample_rate_;
87 int channels_;
88 DISALLOW_COPY_AND_ASSIGN(WebRTCMediaProcessImpl);
89 };
90
44 } // end namespace 91 } // end namespace
45 92
46 // Basic test that instantiates and initializes an instance of 93 // Basic test that instantiates and initializes an instance of
47 // WebRtcAudioDeviceImpl. 94 // WebRtcAudioDeviceImpl.
48 TEST_F(WebRTCAudioDeviceTest, Construct) { 95 TEST_F(WebRTCAudioDeviceTest, Construct) {
49 AudioUtil audio_util; 96 AudioUtil audio_util;
50 set_audio_util_callback(&audio_util); 97 set_audio_util_callback(&audio_util);
51 scoped_refptr<WebRtcAudioDeviceImpl> audio_device( 98 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
52 new WebRtcAudioDeviceImpl()); 99 new WebRtcAudioDeviceImpl());
53 audio_device->SetSessionId(1); 100 audio_device->SetSessionId(1);
54 101
55 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 102 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
56 ASSERT_TRUE(engine.valid()); 103 ASSERT_TRUE(engine.valid());
57 104
58 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 105 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
59 int err = base->Init(audio_device); 106 int err = base->Init(audio_device);
60 EXPECT_EQ(0, err); 107 EXPECT_EQ(0, err);
61 EXPECT_EQ(0, base->Terminate()); 108 EXPECT_EQ(0, base->Terminate());
62 } 109 }
63 110
111 // Verify that a call to webrtc::VoEBase::StartPlayout() starts audio output
112 // with the correct set of parameters. A WebRtcAudioDeviceImpl instance will
113 // be utilized to implement the actual audio path. The test registers a
114 // webrtc::VoEExternalMedia implementation to hijack the output audio and
115 // verify that streaming starts correctly.
116 // Disabled when running headless since the bots don't have the required config.
117 TEST_F(WebRTCAudioDeviceTest, StartPlayout) {
118 if (IsRunningHeadless())
119 return;
120
121 AudioUtil audio_util;
122 set_audio_util_callback(&audio_util);
123
124 EXPECT_CALL(media_observer(),
125 OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
126 EXPECT_CALL(media_observer(),
127 OnSetAudioStreamPlaying(_, 1, true)).Times(1);
128 EXPECT_CALL(media_observer(),
129 OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
130 EXPECT_CALL(media_observer(),
131 OnDeleteAudioStream(_, 1)).Times(1);
132
133 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
134 new WebRtcAudioDeviceImpl());
135 audio_device->SetSessionId(1);
136 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
137 ASSERT_TRUE(engine.valid());
138
139 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
140 ASSERT_TRUE(base.valid());
141 int err = base->Init(audio_device);
142 ASSERT_EQ(0, err);
143
144 int ch = base->CreateChannel();
145 EXPECT_NE(-1, ch);
146
147 ScopedWebRTCPtr<webrtc::VoEExternalMedia> external_media(engine.get());
148 ASSERT_TRUE(external_media.valid());
149
150 base::WaitableEvent event(false, false);
151 scoped_ptr<WebRTCMediaProcessImpl> media_process(
152 new WebRTCMediaProcessImpl(&event));
153 EXPECT_EQ(0, external_media->RegisterExternalMediaProcessing(
154 ch, webrtc::kPlaybackPerChannel, *media_process.get()));
155
156 EXPECT_EQ(0, base->StartPlayout(ch));
157
158 EXPECT_TRUE(event.TimedWait(
159 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
160 WaitForIOThreadCompletion();
161
162 EXPECT_TRUE(audio_device->playing());
163 EXPECT_FALSE(audio_device->recording());
164 EXPECT_EQ(ch, media_process->channel_id());
165 EXPECT_EQ(webrtc::kPlaybackPerChannel, media_process->type());
166 EXPECT_EQ(80, media_process->packet_size());
167 EXPECT_EQ(8000, media_process->sample_rate());
168
169 EXPECT_EQ(0, external_media->DeRegisterExternalMediaProcessing(
170 ch, webrtc::kPlaybackPerChannel));
171 EXPECT_EQ(0, base->StopPlayout(ch));
172
173 EXPECT_EQ(0, base->DeleteChannel(ch));
174 EXPECT_EQ(0, base->Terminate());
175 }
176
177 // Verify that a call to webrtc::VoEBase::StartRecording() starts audio input
178 // with the correct set of parameters. A WebRtcAudioDeviceImpl instance will
179 // be utilized to implement the actual audio path. The test registers a
180 // webrtc::VoEExternalMedia implementation to hijack the input audio and
181 // verify that streaming starts correctly. An external transport implementation
182 // is also required to ensure that "sending" can start without actually trying
183 // to send encoded packets to the network. Our main interest here is to ensure
184 // that the audio capturing starts as it should.
185 // Disabled when running headless since the bots don't have the required config.
186 TEST_F(WebRTCAudioDeviceTest, StartRecording) {
187 if (IsRunningHeadless())
188 return;
189
190 AudioUtil audio_util;
191 set_audio_util_callback(&audio_util);
192
193 // TODO(tommi): extend MediaObserver and MockMediaObserver with support
194 // for new interfaces, like OnSetAudioStreamRecording(). When done, add
195 // EXPECT_CALL() macros here.
196
197 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
198 new WebRtcAudioDeviceImpl());
199 audio_device->SetSessionId(1);
200 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
201 ASSERT_TRUE(engine.valid());
202
203 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
204 ASSERT_TRUE(base.valid());
205 int err = base->Init(audio_device);
206 ASSERT_EQ(0, err);
207
208 int ch = base->CreateChannel();
209 EXPECT_NE(-1, ch);
210
211 ScopedWebRTCPtr<webrtc::VoEExternalMedia> external_media(engine.get());
212 ASSERT_TRUE(external_media.valid());
213
214 base::WaitableEvent event(false, false);
215 scoped_ptr<WebRTCMediaProcessImpl> media_process(
216 new WebRTCMediaProcessImpl(&event));
217 EXPECT_EQ(0, external_media->RegisterExternalMediaProcessing(
218 ch, webrtc::kRecordingPerChannel, *media_process.get()));
219
220 // We must add an external transport implementation to be able to start
221 // recording without actually sending encoded packets to the network. All
222 // we want to do here is to verify that audio capturing starts as it should.
223 ScopedWebRTCPtr<webrtc::VoENetwork> network(engine.get());
224 scoped_ptr<WebRTCTransportImpl> transport(
225 new WebRTCTransportImpl(network.get()));
226 EXPECT_EQ(0, network->RegisterExternalTransport(ch, *transport.get()));
227 EXPECT_EQ(0, base->StartSend(ch));
228
229 EXPECT_TRUE(event.TimedWait(
230 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
231 WaitForIOThreadCompletion();
232
233 EXPECT_FALSE(audio_device->playing());
234 EXPECT_TRUE(audio_device->recording());
235 EXPECT_EQ(ch, media_process->channel_id());
236 EXPECT_EQ(webrtc::kRecordingPerChannel, media_process->type());
237 EXPECT_EQ(80, media_process->packet_size());
238 EXPECT_EQ(8000, media_process->sample_rate());
239
240 EXPECT_EQ(0, external_media->DeRegisterExternalMediaProcessing(
241 ch, webrtc::kRecordingPerChannel));
242 EXPECT_EQ(0, base->StopSend(ch));
243
244 EXPECT_EQ(0, base->DeleteChannel(ch));
245 EXPECT_EQ(0, base->Terminate());
246 }
247
64 // Uses WebRtcAudioDeviceImpl to play a local wave file. 248 // Uses WebRtcAudioDeviceImpl to play a local wave file.
65 // Disabled when running headless since the bots don't have the required config. 249 // Disabled when running headless since the bots don't have the required config.
66 TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) { 250 TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) {
67 if (IsRunningHeadless()) 251 if (IsRunningHeadless())
68 return; 252 return;
69 253
70 std::string file_path( 254 std::string file_path(
71 GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm"))); 255 GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm")));
72 256
73 AudioUtil audio_util; 257 AudioUtil audio_util;
(...skipping 24 matching lines...) Expand all
98 EXPECT_NE(-1, ch); 282 EXPECT_NE(-1, ch);
99 EXPECT_EQ(0, base->StartPlayout(ch)); 283 EXPECT_EQ(0, base->StartPlayout(ch));
100 284
101 ScopedWebRTCPtr<webrtc::VoEFile> file(engine.get()); 285 ScopedWebRTCPtr<webrtc::VoEFile> file(engine.get());
102 int duration = 0; 286 int duration = 0;
103 EXPECT_EQ(0, file->GetFileDuration(file_path.c_str(), duration, 287 EXPECT_EQ(0, file->GetFileDuration(file_path.c_str(), duration,
104 webrtc::kFileFormatPcm16kHzFile)); 288 webrtc::kFileFormatPcm16kHzFile));
105 EXPECT_NE(0, duration); 289 EXPECT_NE(0, duration);
106 290
107 EXPECT_EQ(0, file->StartPlayingFileLocally(ch, file_path.c_str(), false, 291 EXPECT_EQ(0, file->StartPlayingFileLocally(ch, file_path.c_str(), false,
108 webrtc::kFileFormatPcm16kHzFile)); 292 webrtc::kFileFormatPcm16kHzFile));
109 293
110 message_loop_.PostDelayedTask(FROM_HERE, 294 message_loop_.PostDelayedTask(FROM_HERE,
111 new MessageLoop::QuitTask(), 295 new MessageLoop::QuitTask(),
112 TestTimeouts::action_timeout_ms()); 296 TestTimeouts::action_timeout_ms());
113 message_loop_.Run(); 297 message_loop_.Run();
114 298
115 EXPECT_EQ(0, base->Terminate()); 299 EXPECT_EQ(0, base->Terminate());
116 } 300 }
301
302 // Uses WebRtcAudioDeviceImpl to play out recorded audio in loopback.
303 // An external transport implementation is utilized to feed back RTP packets
304 // which are recorded, encoded, packetized into RTP packets and finally
305 // "transmitted". The RTP packets are then fed back into the VoiceEngine
306 // where they are decoded and played out on the default audio output device.
307 // Disabled when running headless since the bots don't have the required config.
308 // TODO(henrika): improve quality by using a wideband codec, enabling noise-
309 // suppressions and perhaps also the digital AGC.
310 TEST_F(WebRTCAudioDeviceTest, FullDuplexAudio) {
311 if (IsRunningHeadless())
312 return;
313
314 AudioUtil audio_util;
315 set_audio_util_callback(&audio_util);
316
317 scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
318 new WebRtcAudioDeviceImpl());
319 audio_device->SetSessionId(1);
320 WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create());
321 ASSERT_TRUE(engine.valid());
322
323 ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get());
324 ASSERT_TRUE(base.valid());
325 int err = base->Init(audio_device);
326 ASSERT_EQ(0, err);
327
328 int ch = base->CreateChannel();
329 EXPECT_NE(-1, ch);
330
331 ScopedWebRTCPtr<webrtc::VoENetwork> network(engine.get());
332 scoped_ptr<WebRTCTransportImpl> transport(
333 new WebRTCTransportImpl(network.get()));
334 EXPECT_EQ(0, network->RegisterExternalTransport(ch, *transport.get()));
335 EXPECT_EQ(0, base->StartPlayout(ch));
336 EXPECT_EQ(0, base->StartSend(ch));
337
338 LOG(INFO) << ">> You should now be able to hear yourself in loopback...";
339 message_loop_.PostDelayedTask(FROM_HERE,
340 new MessageLoop::QuitTask(),
341 TestTimeouts::action_timeout_ms());
342 message_loop_.Run();
343
344 EXPECT_EQ(0, base->StopSend(ch));
345 EXPECT_EQ(0, base->StopPlayout(ch));
346
347 EXPECT_EQ(0, base->DeleteChannel(ch));
348 EXPECT_EQ(0, base->Terminate());
349 }
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