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" |
11 #include "media/base/audio_capturer_source.h" | 11 #include "media/base/audio_capturer_source.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | 12 #include "testing/gmock/include/gmock/gmock.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 | 14 |
15 using ::testing::_; | 15 using ::testing::_; |
16 using ::testing::AnyNumber; | |
16 using ::testing::AtLeast; | 17 using ::testing::AtLeast; |
17 using ::testing::Return; | 18 using ::testing::Return; |
18 | 19 |
19 namespace content { | 20 namespace content { |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 ACTION_P(SignalEvent, event) { | 24 ACTION_P(SignalEvent, event) { |
24 event->Signal(); | 25 event->Signal(); |
25 } | 26 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 protected: | 109 protected: |
109 virtual void SetUp() OVERRIDE { | 110 virtual void SetUp() OVERRIDE { |
110 capturer_ = WebRtcAudioCapturer::CreateCapturer(); | 111 capturer_ = WebRtcAudioCapturer::CreateCapturer(); |
111 capturer_source_ = new MockCapturerSource(); | 112 capturer_source_ = new MockCapturerSource(); |
112 EXPECT_CALL(*capturer_source_.get(), Initialize(_, capturer_.get(), 0)) | 113 EXPECT_CALL(*capturer_source_.get(), Initialize(_, capturer_.get(), 0)) |
113 .WillOnce(Return()); | 114 .WillOnce(Return()); |
114 capturer_->SetCapturerSource(capturer_source_, | 115 capturer_->SetCapturerSource(capturer_source_, |
115 media::CHANNEL_LAYOUT_STEREO, | 116 media::CHANNEL_LAYOUT_STEREO, |
116 48000); | 117 48000); |
117 | 118 |
118 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | |
119 EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(false)) | 119 EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(false)) |
120 .WillOnce(Return()); | 120 .WillOnce(Return()); |
121 capturer_->Start(); | |
122 audio_thread_.reset(new FakeAudioThread(capturer_)); | 121 audio_thread_.reset(new FakeAudioThread(capturer_)); |
123 audio_thread_->Start(); | 122 audio_thread_->Start(); |
124 } | 123 } |
125 | 124 |
126 virtual void TearDown() { | 125 virtual void TearDown() { |
127 audio_thread_->Stop(); | 126 audio_thread_->Stop(); |
128 audio_thread_.reset(); | 127 audio_thread_.reset(); |
129 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | |
130 capturer_->Stop(); | |
131 } | 128 } |
132 | 129 |
133 scoped_refptr<MockCapturerSource> capturer_source_; | 130 scoped_refptr<MockCapturerSource> capturer_source_; |
134 scoped_refptr<WebRtcAudioCapturer> capturer_; | 131 scoped_refptr<WebRtcAudioCapturer> capturer_; |
135 scoped_ptr<FakeAudioThread> audio_thread_; | 132 scoped_ptr<FakeAudioThread> audio_thread_; |
136 }; | 133 }; |
137 | 134 |
138 // Creates a capturer and audio track, fakes its audio thread, and | 135 // Creates a capturer and audio track, fakes its audio thread, and |
139 // connect/disconnect the sink to the audio track on the fly, the sink should | 136 // connect/disconnect the sink to the audio track on the fly, the sink should |
140 // get data callback when the track is connected to the capturer but not when | 137 // get data callback when the track is connected to the capturer but not when |
141 // the track is disconnected from the capturer. | 138 // the track is disconnected from the capturer. |
142 TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { | 139 TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { |
140 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | |
143 scoped_refptr<WebRtcLocalAudioTrack> track = | 141 scoped_refptr<WebRtcLocalAudioTrack> track = |
144 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 142 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
143 track->Start(); | |
145 EXPECT_TRUE(track->enabled()); | 144 EXPECT_TRUE(track->enabled()); |
146 scoped_ptr<MockWebRtcAudioCapturerSink> sink( | 145 scoped_ptr<MockWebRtcAudioCapturerSink> sink( |
147 new MockWebRtcAudioCapturerSink()); | 146 new MockWebRtcAudioCapturerSink()); |
148 const media::AudioParameters params = capturer_->audio_parameters(); | 147 const media::AudioParameters params = capturer_->audio_parameters(); |
149 base::WaitableEvent event(false, false); | 148 base::WaitableEvent event(false, false); |
150 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); | 149 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); |
151 EXPECT_CALL(*sink, CaptureData( | 150 EXPECT_CALL(*sink, CaptureData( |
152 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 151 _, params.channels(), params.frames_per_buffer(), 0, 0)) |
153 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); | 152 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); |
154 track->AddSink(sink.get()); | 153 track->AddSink(sink.get()); |
155 | 154 |
156 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | 155 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |
157 track->RemoveSink(sink.get()); | 156 track->RemoveSink(sink.get()); |
157 | |
158 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | |
159 track->Stop(); | |
henrika (OOO until Aug 14)
2013/06/05 09:09:20
What happens if you call Stop before RemoveSink?
no longer working on chromium
2013/06/05 16:29:45
Nothing will happen.
| |
158 track = NULL; | 160 track = NULL; |
159 } | 161 } |
160 | 162 |
161 // The same setup as ConnectAndDisconnectOneSink, but enable and disable the | 163 // The same setup as ConnectAndDisconnectOneSink, but enable and disable the |
162 // audio track on the fly. When the audio track is disabled, there is no data | 164 // audio track on the fly. When the audio track is disabled, there is no data |
163 // callback to the sink; when the audio track is enabled, there comes data | 165 // callback to the sink; when the audio track is enabled, there comes data |
164 // callback. | 166 // callback. |
165 // TODO(xians): Enable this test after resolving the racing issue that TSAN | 167 // TODO(xians): Enable this test after resolving the racing issue that TSAN |
166 // reports on MediaStreamTrack::enabled(); | 168 // reports on MediaStreamTrack::enabled(); |
167 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { | 169 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { |
170 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | |
168 scoped_refptr<WebRtcLocalAudioTrack> track = | 171 scoped_refptr<WebRtcLocalAudioTrack> track = |
169 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 172 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
173 track->Start(); | |
170 EXPECT_TRUE(track->enabled()); | 174 EXPECT_TRUE(track->enabled()); |
171 EXPECT_TRUE(track->set_enabled(false)); | 175 EXPECT_TRUE(track->set_enabled(false)); |
172 scoped_ptr<MockWebRtcAudioCapturerSink> sink( | 176 scoped_ptr<MockWebRtcAudioCapturerSink> sink( |
173 new MockWebRtcAudioCapturerSink()); | 177 new MockWebRtcAudioCapturerSink()); |
174 const media::AudioParameters params = capturer_->audio_parameters(); | 178 const media::AudioParameters params = capturer_->audio_parameters(); |
175 base::WaitableEvent event(false, false); | 179 base::WaitableEvent event(false, false); |
176 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); | 180 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); |
177 EXPECT_CALL(*sink, CaptureData( | 181 EXPECT_CALL(*sink, CaptureData( |
178 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 182 _, params.channels(), params.frames_per_buffer(), 0, 0)) |
179 .Times(0); | 183 .Times(0); |
180 track->AddSink(sink.get()); | 184 track->AddSink(sink.get()); |
181 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); | 185 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); |
182 | 186 |
183 event.Reset(); | 187 event.Reset(); |
184 EXPECT_CALL(*sink, CaptureData( | 188 EXPECT_CALL(*sink, CaptureData( |
185 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 189 _, params.channels(), params.frames_per_buffer(), 0, 0)) |
186 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); | 190 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); |
187 EXPECT_TRUE(track->set_enabled(true)); | 191 EXPECT_TRUE(track->set_enabled(true)); |
188 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | 192 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |
189 track->RemoveSink(sink.get()); | 193 track->RemoveSink(sink.get()); |
194 | |
195 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | |
196 track->Stop(); | |
190 track = NULL; | 197 track = NULL; |
191 } | 198 } |
192 | 199 |
193 // Create multiple audio tracks and enable/disable them, verify that the audio | 200 // Create multiple audio tracks and enable/disable them, verify that the audio |
194 // callbacks appear/disappear. | 201 // callbacks appear/disappear. |
195 // TODO(xians): Enable the test after the racing problem is resolved. | 202 // TODO(xians): Enable the test after the racing problem is resolved. |
196 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) { | 203 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) { |
204 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | |
henrika (OOO until Aug 14)
2013/06/05 09:09:20
Who is default here and what is the difference whe
no longer working on chromium
2013/06/05 16:29:45
It does not have the default_sink here.
The defau
| |
197 scoped_refptr<WebRtcLocalAudioTrack> track_1 = | 205 scoped_refptr<WebRtcLocalAudioTrack> track_1 = |
198 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 206 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
207 track_1->Start(); | |
199 EXPECT_TRUE(track_1->enabled()); | 208 EXPECT_TRUE(track_1->enabled()); |
200 scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( | 209 scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( |
201 new MockWebRtcAudioCapturerSink()); | 210 new MockWebRtcAudioCapturerSink()); |
202 const media::AudioParameters params = capturer_->audio_parameters(); | 211 const media::AudioParameters params = capturer_->audio_parameters(); |
203 base::WaitableEvent event_1(false, false); | 212 base::WaitableEvent event_1(false, false); |
204 EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); | 213 EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); |
205 EXPECT_CALL(*sink_1, CaptureData( | 214 EXPECT_CALL(*sink_1, CaptureData( |
206 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 215 _, params.channels(), params.frames_per_buffer(), 0, 0)) |
207 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); | 216 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); |
208 track_1->AddSink(sink_1.get()); | 217 track_1->AddSink(sink_1.get()); |
209 | 218 |
210 scoped_refptr<WebRtcLocalAudioTrack> track_2 = | 219 scoped_refptr<WebRtcLocalAudioTrack> track_2 = |
211 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 220 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
221 track_2->Start(); | |
212 EXPECT_TRUE(track_2->set_enabled(false)); | 222 EXPECT_TRUE(track_2->set_enabled(false)); |
213 scoped_ptr<MockWebRtcAudioCapturerSink> sink_2( | 223 scoped_ptr<MockWebRtcAudioCapturerSink> sink_2( |
214 new MockWebRtcAudioCapturerSink()); | 224 new MockWebRtcAudioCapturerSink()); |
215 EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); | 225 EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); |
216 EXPECT_CALL(*sink_2, CaptureData( | 226 EXPECT_CALL(*sink_2, CaptureData( |
217 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 227 _, params.channels(), params.frames_per_buffer(), 0, 0)) |
218 .Times(0); | 228 .Times(0); |
219 track_2->AddSink(sink_2.get()); | 229 track_2->AddSink(sink_2.get()); |
220 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); | 230 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |
221 | 231 |
222 | 232 |
223 // Enable |track_2|, and verify the data callback comes to |sink_2|; | 233 // Enable |track_2|, and verify the data callback comes to |sink_2|; |
224 event_1.Reset(); | 234 event_1.Reset(); |
225 base::WaitableEvent event_2(false, false); | 235 base::WaitableEvent event_2(false, false); |
226 EXPECT_CALL(*sink_1, CaptureData( | 236 EXPECT_CALL(*sink_1, CaptureData( |
227 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 237 _, params.channels(), params.frames_per_buffer(), 0, 0)) |
228 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); | 238 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); |
229 EXPECT_CALL(*sink_2, CaptureData( | 239 EXPECT_CALL(*sink_2, CaptureData( |
230 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 240 _, params.channels(), params.frames_per_buffer(), 0, 0)) |
231 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); | 241 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); |
232 EXPECT_TRUE(track_2->set_enabled(true)); | 242 EXPECT_TRUE(track_2->set_enabled(true)); |
233 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); | 243 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |
234 EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); | 244 EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); |
235 | 245 |
236 track_1->RemoveSink(sink_1.get()); | 246 track_1->RemoveSink(sink_1.get()); |
247 track_1->Stop(); | |
248 track_1 = NULL; | |
249 | |
250 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | |
237 track_2->RemoveSink(sink_2.get()); | 251 track_2->RemoveSink(sink_2.get()); |
238 track_1 = NULL; | 252 track_2->Stop(); |
239 track_2 = NULL; | 253 track_2 = NULL; |
240 } | 254 } |
241 | 255 |
256 // Start/Stop tracks and verify the capturer is correctly starting/stopping | |
257 // its source. | |
258 TEST_F(WebRtcLocalAudioTrackTest, StartAndStopCapturer) { | |
259 // SetDefaultSink() should not trigger the Start() on |capturer_source_|. | |
260 base::WaitableEvent event(false, false); | |
261 scoped_ptr<MockWebRtcAudioCapturerSink> default_sink( | |
262 new MockWebRtcAudioCapturerSink()); | |
263 EXPECT_CALL(*default_sink, SetCaptureFormat(_)).WillOnce(Return()); | |
264 EXPECT_CALL(*default_sink, CaptureData( | |
265 _, _, _, 0, 0)) | |
266 .Times(AnyNumber()).WillRepeatedly(Return()); | |
267 capturer_->SetDefaultSink(default_sink.get()); | |
268 EXPECT_CALL(*capturer_source_.get(), Start()).Times(0); | |
269 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); | |
270 | |
271 // Starting the first audio track will start the |capturer_source_|. | |
272 event.Reset(); | |
273 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(SignalEvent(&event)); | |
274 scoped_refptr<WebRtcLocalAudioTrack> track_1 = | |
275 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | |
276 track_1->Start(); | |
henrika (OOO until Aug 14)
2013/06/05 09:09:20
The sequence is track calls AddSink on default sin
no longer working on chromium
2013/06/05 16:29:45
It does not matter on the order, but mostly it is
| |
277 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | |
278 | |
279 // Start the second audio track will not start the |capturer_source_| | |
280 // since it has been started. | |
281 EXPECT_CALL(*capturer_source_.get(), Start()).Times(0); | |
henrika (OOO until Aug 14)
2013/06/05 09:09:20
Should you also verify that default start is not c
no longer working on chromium
2013/06/05 16:29:45
It is done here:
Note that it is Times(0);
| |
282 scoped_refptr<WebRtcLocalAudioTrack> track_2 = | |
283 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | |
284 track_2->Start(); | |
285 | |
286 // Stop the first audio track will not stop the |capturer_source_|. | |
287 EXPECT_CALL(*capturer_source_.get(), Stop()).Times(0); | |
288 track_1->Stop(); | |
henrika (OOO until Aug 14)
2013/06/05 09:09:20
Any difference if you stop #2 first?
no longer working on chromium
2013/06/05 16:29:45
No difference.
| |
289 track_1 = NULL; | |
290 | |
291 // Stop the last audio track will stop the |capturer_source_|. | |
292 event.Reset(); | |
293 EXPECT_CALL(*capturer_source_.get(), Stop()) | |
294 .Times(1).WillOnce(SignalEvent(&event)); | |
295 track_2->Stop(); | |
296 track_2 = NULL; | |
297 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | |
298 | |
299 capturer_->SetDefaultSink(NULL); | |
henrika (OOO until Aug 14)
2013/06/05 09:09:20
Is this required?
no longer working on chromium
2013/06/05 16:29:45
Yes, ADM does it this way.
| |
300 } | |
301 | |
242 } // namespace content | 302 } // namespace content |
OLD | NEW |