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

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

Issue 15979027: start/stop the source of the capturer when 1st audiotrack/last audiotrack is added/removed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 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 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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698