OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/synchronization/waitable_event.h" | 5 #include "base/synchronization/waitable_event.h" |
6 #include "base/test/test_timeouts.h" | 6 #include "base/test/test_timeouts.h" |
7 #include "content/renderer/media/webrtc_audio_capturer.h" | 7 #include "content/renderer/media/webrtc_audio_capturer.h" |
8 #include "content/renderer/media/webrtc_local_audio_track.h" | 8 #include "content/renderer/media/webrtc_local_audio_track.h" |
9 #include "media/audio/audio_parameters.h" | 9 #include "media/audio/audio_parameters.h" |
10 #include "media/base/audio_bus.h" | 10 #include "media/base/audio_bus.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 // base::PlatformThread::Delegate: | 42 // base::PlatformThread::Delegate: |
43 virtual void ThreadMain() OVERRIDE { | 43 virtual void ThreadMain() OVERRIDE { |
44 while (true) { | 44 while (true) { |
45 if (closure_.IsSignaled()) | 45 if (closure_.IsSignaled()) |
46 return; | 46 return; |
47 | 47 |
48 media::AudioCapturerSource::CaptureCallback* callback = | 48 media::AudioCapturerSource::CaptureCallback* callback = |
49 static_cast<media::AudioCapturerSource::CaptureCallback*>( | 49 static_cast<media::AudioCapturerSource::CaptureCallback*>( |
50 capturer_.get()); | 50 capturer_.get()); |
51 audio_bus_->Zero(); | 51 audio_bus_->Zero(); |
52 callback->Capture(audio_bus_.get(), 0, 0); | 52 callback->Capture(audio_bus_.get(), 0, 0, false); |
53 | 53 |
54 // Sleep 1ms to yield the resource for the main thread. | 54 // Sleep 1ms to yield the resource for the main thread. |
55 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); | 55 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |
56 } | 56 } |
57 } | 57 } |
58 | 58 |
59 void Start() { | 59 void Start() { |
60 base::PlatformThread::CreateWithPriority( | 60 base::PlatformThread::CreateWithPriority( |
61 0, this, &thread_, base::kThreadPriority_RealtimeAudio); | 61 0, this, &thread_, base::kThreadPriority_RealtimeAudio); |
62 CHECK(!thread_.is_null()); | 62 CHECK(!thread_.is_null()); |
(...skipping 25 matching lines...) Expand all Loading... |
88 MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); | 88 MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); |
89 | 89 |
90 protected: | 90 protected: |
91 virtual ~MockCapturerSource() {} | 91 virtual ~MockCapturerSource() {} |
92 }; | 92 }; |
93 | 93 |
94 class MockWebRtcAudioCapturerSink : public WebRtcAudioCapturerSink { | 94 class MockWebRtcAudioCapturerSink : public WebRtcAudioCapturerSink { |
95 public: | 95 public: |
96 MockWebRtcAudioCapturerSink() {} | 96 MockWebRtcAudioCapturerSink() {} |
97 ~MockWebRtcAudioCapturerSink() {} | 97 ~MockWebRtcAudioCapturerSink() {} |
98 MOCK_METHOD5(CaptureData, void(const int16* audio_data, | 98 MOCK_METHOD6(CaptureData, |
99 int number_of_channels, | 99 void(const int16* audio_data, |
100 int number_of_frames, | 100 int number_of_channels, |
101 int audio_delay_milliseconds, | 101 int number_of_frames, |
102 double volume)); | 102 int audio_delay_milliseconds, |
| 103 double volume, |
| 104 bool key_pressed)); |
103 MOCK_METHOD1(SetCaptureFormat, void(const media::AudioParameters& params)); | 105 MOCK_METHOD1(SetCaptureFormat, void(const media::AudioParameters& params)); |
104 }; | 106 }; |
105 | 107 |
106 } // namespace | 108 } // namespace |
107 | 109 |
108 class WebRtcLocalAudioTrackTest : public ::testing::Test { | 110 class WebRtcLocalAudioTrackTest : public ::testing::Test { |
109 protected: | 111 protected: |
110 virtual void SetUp() OVERRIDE { | 112 virtual void SetUp() OVERRIDE { |
111 capturer_ = WebRtcAudioCapturer::CreateCapturer(); | 113 capturer_ = WebRtcAudioCapturer::CreateCapturer(); |
112 capturer_source_ = new MockCapturerSource(); | 114 capturer_source_ = new MockCapturerSource(); |
(...skipping 27 matching lines...) Expand all Loading... |
140 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | 142 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); |
141 scoped_refptr<WebRtcLocalAudioTrack> track = | 143 scoped_refptr<WebRtcLocalAudioTrack> track = |
142 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 144 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
143 track->Start(); | 145 track->Start(); |
144 EXPECT_TRUE(track->enabled()); | 146 EXPECT_TRUE(track->enabled()); |
145 scoped_ptr<MockWebRtcAudioCapturerSink> sink( | 147 scoped_ptr<MockWebRtcAudioCapturerSink> sink( |
146 new MockWebRtcAudioCapturerSink()); | 148 new MockWebRtcAudioCapturerSink()); |
147 const media::AudioParameters params = capturer_->audio_parameters(); | 149 const media::AudioParameters params = capturer_->audio_parameters(); |
148 base::WaitableEvent event(false, false); | 150 base::WaitableEvent event(false, false); |
149 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); | 151 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); |
150 EXPECT_CALL(*sink, CaptureData( | 152 EXPECT_CALL( |
151 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 153 *sink, |
| 154 CaptureData( |
| 155 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
152 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); | 156 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); |
153 track->AddSink(sink.get()); | 157 track->AddSink(sink.get()); |
154 | 158 |
155 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | 159 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |
156 track->RemoveSink(sink.get()); | 160 track->RemoveSink(sink.get()); |
157 | 161 |
158 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | 162 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); |
159 track->Stop(); | 163 track->Stop(); |
160 track = NULL; | 164 track = NULL; |
161 } | 165 } |
162 | 166 |
163 // The same setup as ConnectAndDisconnectOneSink, but enable and disable the | 167 // The same setup as ConnectAndDisconnectOneSink, but enable and disable the |
164 // audio track on the fly. When the audio track is disabled, there is no data | 168 // audio track on the fly. When the audio track is disabled, there is no data |
165 // callback to the sink; when the audio track is enabled, there comes data | 169 // callback to the sink; when the audio track is enabled, there comes data |
166 // callback. | 170 // callback. |
167 // TODO(xians): Enable this test after resolving the racing issue that TSAN | 171 // TODO(xians): Enable this test after resolving the racing issue that TSAN |
168 // reports on MediaStreamTrack::enabled(); | 172 // reports on MediaStreamTrack::enabled(); |
169 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { | 173 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { |
170 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | 174 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); |
171 scoped_refptr<WebRtcLocalAudioTrack> track = | 175 scoped_refptr<WebRtcLocalAudioTrack> track = |
172 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 176 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
173 track->Start(); | 177 track->Start(); |
174 EXPECT_TRUE(track->enabled()); | 178 EXPECT_TRUE(track->enabled()); |
175 EXPECT_TRUE(track->set_enabled(false)); | 179 EXPECT_TRUE(track->set_enabled(false)); |
176 scoped_ptr<MockWebRtcAudioCapturerSink> sink( | 180 scoped_ptr<MockWebRtcAudioCapturerSink> sink( |
177 new MockWebRtcAudioCapturerSink()); | 181 new MockWebRtcAudioCapturerSink()); |
178 const media::AudioParameters params = capturer_->audio_parameters(); | 182 const media::AudioParameters params = capturer_->audio_parameters(); |
179 base::WaitableEvent event(false, false); | 183 base::WaitableEvent event(false, false); |
180 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); | 184 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); |
181 EXPECT_CALL(*sink, CaptureData( | 185 EXPECT_CALL( |
182 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 186 *sink, |
| 187 CaptureData( |
| 188 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
183 .Times(0); | 189 .Times(0); |
184 track->AddSink(sink.get()); | 190 track->AddSink(sink.get()); |
185 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); | 191 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); |
186 | 192 |
187 event.Reset(); | 193 event.Reset(); |
188 EXPECT_CALL(*sink, CaptureData( | 194 EXPECT_CALL( |
189 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 195 *sink, |
| 196 CaptureData( |
| 197 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
190 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); | 198 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); |
191 EXPECT_TRUE(track->set_enabled(true)); | 199 EXPECT_TRUE(track->set_enabled(true)); |
192 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | 200 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |
193 track->RemoveSink(sink.get()); | 201 track->RemoveSink(sink.get()); |
194 | 202 |
195 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | 203 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); |
196 track->Stop(); | 204 track->Stop(); |
197 track = NULL; | 205 track = NULL; |
198 } | 206 } |
199 | 207 |
200 // Create multiple audio tracks and enable/disable them, verify that the audio | 208 // Create multiple audio tracks and enable/disable them, verify that the audio |
201 // callbacks appear/disappear. | 209 // callbacks appear/disappear. |
202 TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { | 210 TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { |
203 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | 211 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); |
204 scoped_refptr<WebRtcLocalAudioTrack> track_1 = | 212 scoped_refptr<WebRtcLocalAudioTrack> track_1 = |
205 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 213 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
206 track_1->Start(); | 214 track_1->Start(); |
207 EXPECT_TRUE(track_1->enabled()); | 215 EXPECT_TRUE(track_1->enabled()); |
208 scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( | 216 scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( |
209 new MockWebRtcAudioCapturerSink()); | 217 new MockWebRtcAudioCapturerSink()); |
210 const media::AudioParameters params = capturer_->audio_parameters(); | 218 const media::AudioParameters params = capturer_->audio_parameters(); |
211 base::WaitableEvent event_1(false, false); | 219 base::WaitableEvent event_1(false, false); |
212 EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); | 220 EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); |
213 EXPECT_CALL(*sink_1, CaptureData( | 221 EXPECT_CALL( |
214 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 222 *sink_1, |
| 223 CaptureData( |
| 224 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
215 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); | 225 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); |
216 track_1->AddSink(sink_1.get()); | 226 track_1->AddSink(sink_1.get()); |
217 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); | 227 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |
218 | 228 |
219 scoped_refptr<WebRtcLocalAudioTrack> track_2 = | 229 scoped_refptr<WebRtcLocalAudioTrack> track_2 = |
220 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 230 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
221 track_2->Start(); | 231 track_2->Start(); |
222 EXPECT_TRUE(track_2->enabled()); | 232 EXPECT_TRUE(track_2->enabled()); |
223 | 233 |
224 // Verify both |sink_1| and |sink_2| get data. | 234 // Verify both |sink_1| and |sink_2| get data. |
225 event_1.Reset(); | 235 event_1.Reset(); |
226 base::WaitableEvent event_2(false, false); | 236 base::WaitableEvent event_2(false, false); |
227 | 237 |
228 scoped_ptr<MockWebRtcAudioCapturerSink> sink_2( | 238 scoped_ptr<MockWebRtcAudioCapturerSink> sink_2( |
229 new MockWebRtcAudioCapturerSink()); | 239 new MockWebRtcAudioCapturerSink()); |
230 EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); | 240 EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); |
231 EXPECT_CALL(*sink_1, CaptureData( | 241 EXPECT_CALL( |
232 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 242 *sink_1, |
| 243 CaptureData( |
| 244 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
233 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); | 245 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); |
234 EXPECT_CALL(*sink_2, CaptureData( | 246 EXPECT_CALL( |
235 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 247 *sink_2, |
| 248 CaptureData( |
| 249 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
236 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); | 250 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); |
237 track_2->AddSink(sink_2.get()); | 251 track_2->AddSink(sink_2.get()); |
238 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); | 252 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |
239 EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); | 253 EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); |
240 | 254 |
241 track_1->RemoveSink(sink_1.get()); | 255 track_1->RemoveSink(sink_1.get()); |
242 track_1->Stop(); | 256 track_1->Stop(); |
243 track_1 = NULL; | 257 track_1 = NULL; |
244 | 258 |
245 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | 259 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); |
(...skipping 18 matching lines...) Expand all Loading... |
264 } | 278 } |
265 | 279 |
266 // Start/Stop tracks and verify the capturer is correctly starting/stopping | 280 // Start/Stop tracks and verify the capturer is correctly starting/stopping |
267 // its source. | 281 // its source. |
268 TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { | 282 TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { |
269 // SetDefaultSink() should not trigger the Start() on |capturer_source_|. | 283 // SetDefaultSink() should not trigger the Start() on |capturer_source_|. |
270 base::WaitableEvent event(false, false); | 284 base::WaitableEvent event(false, false); |
271 scoped_ptr<MockWebRtcAudioCapturerSink> default_sink( | 285 scoped_ptr<MockWebRtcAudioCapturerSink> default_sink( |
272 new MockWebRtcAudioCapturerSink()); | 286 new MockWebRtcAudioCapturerSink()); |
273 EXPECT_CALL(*default_sink, SetCaptureFormat(_)).WillOnce(Return()); | 287 EXPECT_CALL(*default_sink, SetCaptureFormat(_)).WillOnce(Return()); |
274 EXPECT_CALL(*default_sink, CaptureData(_, _, _, 0, 0)) | 288 EXPECT_CALL(*default_sink, CaptureData(_, _, _, 0, 0, false)) |
275 .Times(AnyNumber()).WillRepeatedly(Return()); | 289 .Times(AnyNumber()).WillRepeatedly(Return()); |
276 capturer_->SetDefaultSink(default_sink.get()); | 290 capturer_->SetDefaultSink(default_sink.get()); |
277 EXPECT_CALL(*capturer_source_.get(), Start()).Times(0); | 291 EXPECT_CALL(*capturer_source_.get(), Start()).Times(0); |
278 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); | 292 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); |
279 | 293 |
280 // Starting the first audio track will start the |capturer_source_|. | 294 // Starting the first audio track will start the |capturer_source_|. |
281 event.Reset(); | 295 event.Reset(); |
282 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(SignalEvent(&event)); | 296 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(SignalEvent(&event)); |
283 scoped_refptr<WebRtcLocalAudioTrack> track_1 = | 297 scoped_refptr<WebRtcLocalAudioTrack> track_1 = |
284 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 298 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 media::CHANNEL_LAYOUT_STEREO, | 341 media::CHANNEL_LAYOUT_STEREO, |
328 48000); | 342 48000); |
329 | 343 |
330 // Stop the track. | 344 // Stop the track. |
331 EXPECT_CALL(*new_source.get(), Stop()); | 345 EXPECT_CALL(*new_source.get(), Stop()); |
332 track->Stop(); | 346 track->Stop(); |
333 track = NULL; | 347 track = NULL; |
334 } | 348 } |
335 | 349 |
336 } // namespace content | 350 } // namespace content |
OLD | NEW |