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

Side by Side Diff: media/audio/virtual_audio_input_stream_unittest.cc

Issue 17122006: Rejigger audio capture pipeline to work with separate main+worker threads (Mac). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Replace use of scoped_refptr<Worker> with simple DeleteSoon() scheme. 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
« no previous file with comments | « media/audio/virtual_audio_input_stream.cc ('k') | media/audio/virtual_audio_output_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <list> 5 #include <list>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 } 90 }
91 91
92 private: 92 private:
93 base::WaitableEvent data_pulled_; 93 base::WaitableEvent data_pulled_;
94 94
95 DISALLOW_COPY_AND_ASSIGN(TestAudioSource); 95 DISALLOW_COPY_AND_ASSIGN(TestAudioSource);
96 }; 96 };
97 97
98 } // namespace 98 } // namespace
99 99
100 class VirtualAudioInputStreamTest : public testing::Test { 100 class VirtualAudioInputStreamTest : public testing::TestWithParam<bool> {
101 public: 101 public:
102 VirtualAudioInputStreamTest() 102 VirtualAudioInputStreamTest()
103 : audio_thread_(new base::Thread("AudioThread")), 103 : audio_thread_(new base::Thread("AudioThread")),
104 worker_thread_(new base::Thread("AudioWorkerThread")),
104 stream_(NULL), 105 stream_(NULL),
105 closed_stream_(false, false) { 106 closed_stream_(false, false) {
106 audio_thread_->Start(); 107 audio_thread_->Start();
107 audio_message_loop_ = audio_thread_->message_loop_proxy(); 108 audio_message_loop_ = audio_thread_->message_loop_proxy();
108 } 109 }
109 110
110 virtual ~VirtualAudioInputStreamTest() { 111 virtual ~VirtualAudioInputStreamTest() {
111 SyncWithAudioThread(); 112 SyncWithAudioThread();
112 113
113 DCHECK(output_streams_.empty()); 114 DCHECK(output_streams_.empty());
114 DCHECK(stopped_output_streams_.empty()); 115 DCHECK(stopped_output_streams_.empty());
115 } 116 }
116 117
117 void Create() { 118 void Create() {
119 const bool worker_is_separate_thread = GetParam();
118 stream_ = new VirtualAudioInputStream( 120 stream_ = new VirtualAudioInputStream(
119 kParams, audio_message_loop_, 121 kParams, GetWorkerLoop(worker_is_separate_thread),
120 base::Bind(&base::DeletePointer<VirtualAudioInputStream>)); 122 base::Bind(&base::DeletePointer<VirtualAudioInputStream>));
121 stream_->Open(); 123 stream_->Open();
122 } 124 }
123 125
124 void Start() { 126 void Start() {
125 EXPECT_CALL(input_callback_, OnClose(_)); 127 EXPECT_CALL(input_callback_, OnClose(_));
126 EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _)) 128 EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _))
127 .Times(AtLeast(1)); 129 .Times(AtLeast(1));
128 130
129 ASSERT_TRUE(!!stream_); 131 ASSERT_TRUE(!!stream_);
130 stream_->Start(&input_callback_); 132 stream_->Start(&input_callback_);
131 } 133 }
132 134
133 void CreateAndStartOneOutputStream() { 135 void CreateAndStartOneOutputStream() {
134 ASSERT_TRUE(!!stream_); 136 ASSERT_TRUE(!!stream_);
135 AudioOutputStream* const output_stream = new VirtualAudioOutputStream( 137 AudioOutputStream* const output_stream = new VirtualAudioOutputStream(
136 kParams, 138 kParams,
137 audio_message_loop_.get(),
138 stream_, 139 stream_,
139 base::Bind(&base::DeletePointer<VirtualAudioOutputStream>)); 140 base::Bind(&base::DeletePointer<VirtualAudioOutputStream>));
140 output_streams_.push_back(output_stream); 141 output_streams_.push_back(output_stream);
141 142
142 output_stream->Open(); 143 output_stream->Open();
143 output_stream->Start(&source_); 144 output_stream->Start(&source_);
144 } 145 }
145 146
146 void Stop() { 147 void Stop() {
147 ASSERT_TRUE(!!stream_); 148 ASSERT_TRUE(!!stream_);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 (*it)->Start(&source_); 206 (*it)->Start(&source_);
206 output_streams_.push_back(*it); 207 output_streams_.push_back(*it);
207 } 208 }
208 stopped_output_streams_.clear(); 209 stopped_output_streams_.clear();
209 } 210 }
210 211
211 const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const { 212 const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const {
212 return audio_message_loop_; 213 return audio_message_loop_;
213 } 214 }
214 215
216 const scoped_refptr<base::MessageLoopProxy>& GetWorkerLoop(
217 bool worker_is_separate_thread) {
218 if (worker_is_separate_thread) {
219 if (!worker_thread_->IsRunning()) {
220 worker_thread_->Start();
221 worker_message_loop_ = worker_thread_->message_loop_proxy();
222 }
223 return worker_message_loop_;
224 } else {
225 return audio_message_loop_;
226 }
227 }
228
215 private: 229 private:
216 void SyncWithAudioThread() { 230 void SyncWithAudioThread() {
217 base::WaitableEvent done(false, false); 231 base::WaitableEvent done(false, false);
218 audio_message_loop_->PostTask( 232 audio_message_loop_->PostTask(
219 FROM_HERE, 233 FROM_HERE,
220 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); 234 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
221 done.Wait(); 235 done.Wait();
222 } 236 }
223 237
224 scoped_ptr<base::Thread> audio_thread_; 238 scoped_ptr<base::Thread> audio_thread_;
225 scoped_refptr<base::MessageLoopProxy> audio_message_loop_; 239 scoped_refptr<base::MessageLoopProxy> audio_message_loop_;
240 scoped_ptr<base::Thread> worker_thread_;
241 scoped_refptr<base::MessageLoopProxy> worker_message_loop_;
226 242
227 VirtualAudioInputStream* stream_; 243 VirtualAudioInputStream* stream_;
228 MockInputCallback input_callback_; 244 MockInputCallback input_callback_;
229 base::WaitableEvent closed_stream_; 245 base::WaitableEvent closed_stream_;
230 246
231 std::list<AudioOutputStream*> output_streams_; 247 std::list<AudioOutputStream*> output_streams_;
232 std::list<AudioOutputStream*> stopped_output_streams_; 248 std::list<AudioOutputStream*> stopped_output_streams_;
233 TestAudioSource source_; 249 TestAudioSource source_;
234 250
235 DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest); 251 DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest);
236 }; 252 };
237 253
238 #define RUN_ON_AUDIO_THREAD(method) \ 254 #define RUN_ON_AUDIO_THREAD(method) \
239 audio_message_loop()->PostTask( \ 255 audio_message_loop()->PostTask( \
240 FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::method, \ 256 FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::method, \
241 base::Unretained(this))) 257 base::Unretained(this)))
242 258
243 TEST_F(VirtualAudioInputStreamTest, CreateAndClose) { 259 TEST_P(VirtualAudioInputStreamTest, CreateAndClose) {
244 RUN_ON_AUDIO_THREAD(Create); 260 RUN_ON_AUDIO_THREAD(Create);
245 RUN_ON_AUDIO_THREAD(Close); 261 RUN_ON_AUDIO_THREAD(Close);
246 WaitUntilClosed(); 262 WaitUntilClosed();
247 } 263 }
248 264
249 TEST_F(VirtualAudioInputStreamTest, NoOutputs) { 265 TEST_P(VirtualAudioInputStreamTest, NoOutputs) {
250 RUN_ON_AUDIO_THREAD(Create); 266 RUN_ON_AUDIO_THREAD(Create);
251 RUN_ON_AUDIO_THREAD(Start); 267 RUN_ON_AUDIO_THREAD(Start);
252 WaitForDataToFlow(); 268 WaitForDataToFlow();
253 RUN_ON_AUDIO_THREAD(Stop); 269 RUN_ON_AUDIO_THREAD(Stop);
254 RUN_ON_AUDIO_THREAD(Close); 270 RUN_ON_AUDIO_THREAD(Close);
255 WaitUntilClosed(); 271 WaitUntilClosed();
256 } 272 }
257 273
258 TEST_F(VirtualAudioInputStreamTest, SingleOutput) { 274 TEST_P(VirtualAudioInputStreamTest, SingleOutput) {
259 RUN_ON_AUDIO_THREAD(Create); 275 RUN_ON_AUDIO_THREAD(Create);
260 RUN_ON_AUDIO_THREAD(Start); 276 RUN_ON_AUDIO_THREAD(Start);
261 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); 277 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
262 WaitForDataToFlow(); 278 WaitForDataToFlow();
263 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); 279 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
264 RUN_ON_AUDIO_THREAD(Stop); 280 RUN_ON_AUDIO_THREAD(Stop);
265 RUN_ON_AUDIO_THREAD(Close); 281 RUN_ON_AUDIO_THREAD(Close);
266 WaitUntilClosed(); 282 WaitUntilClosed();
267 } 283 }
268 284
269 TEST_F(VirtualAudioInputStreamTest, SingleOutputPausedAndRestarted) { 285 TEST_P(VirtualAudioInputStreamTest, SingleOutputPausedAndRestarted) {
270 RUN_ON_AUDIO_THREAD(Create); 286 RUN_ON_AUDIO_THREAD(Create);
271 RUN_ON_AUDIO_THREAD(Start); 287 RUN_ON_AUDIO_THREAD(Start);
272 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); 288 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
273 WaitForDataToFlow(); 289 WaitForDataToFlow();
274 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); 290 RUN_ON_AUDIO_THREAD(StopFirstOutputStream);
275 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); 291 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams);
276 WaitForDataToFlow(); 292 WaitForDataToFlow();
277 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); 293 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
278 RUN_ON_AUDIO_THREAD(Stop); 294 RUN_ON_AUDIO_THREAD(Stop);
279 RUN_ON_AUDIO_THREAD(Close); 295 RUN_ON_AUDIO_THREAD(Close);
280 WaitUntilClosed(); 296 WaitUntilClosed();
281 } 297 }
282 298
283 TEST_F(VirtualAudioInputStreamTest, MultipleOutputs) { 299 TEST_P(VirtualAudioInputStreamTest, MultipleOutputs) {
284 RUN_ON_AUDIO_THREAD(Create); 300 RUN_ON_AUDIO_THREAD(Create);
285 RUN_ON_AUDIO_THREAD(Start); 301 RUN_ON_AUDIO_THREAD(Start);
286 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); 302 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
287 WaitForDataToFlow(); 303 WaitForDataToFlow();
288 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); 304 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
289 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); 305 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
290 WaitForDataToFlow(); 306 WaitForDataToFlow();
291 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); 307 RUN_ON_AUDIO_THREAD(StopFirstOutputStream);
292 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); 308 RUN_ON_AUDIO_THREAD(StopFirstOutputStream);
293 WaitForDataToFlow(); 309 WaitForDataToFlow();
294 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); 310 RUN_ON_AUDIO_THREAD(StopFirstOutputStream);
295 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); 311 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams);
296 WaitForDataToFlow(); 312 WaitForDataToFlow();
297 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); 313 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
298 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); 314 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
299 RUN_ON_AUDIO_THREAD(Stop); 315 RUN_ON_AUDIO_THREAD(Stop);
300 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); 316 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
301 RUN_ON_AUDIO_THREAD(Close); 317 RUN_ON_AUDIO_THREAD(Close);
302 WaitUntilClosed(); 318 WaitUntilClosed();
303 } 319 }
304 320
305 // A combination of all of the above tests with many output streams. 321 // A combination of all of the above tests with many output streams.
306 TEST_F(VirtualAudioInputStreamTest, ComprehensiveTest) { 322 TEST_P(VirtualAudioInputStreamTest, ComprehensiveTest) {
307 static const int kNumOutputs = 8; 323 static const int kNumOutputs = 8;
308 static const int kHalfNumOutputs = kNumOutputs / 2; 324 static const int kHalfNumOutputs = kNumOutputs / 2;
309 static const int kPauseIterations = 5; 325 static const int kPauseIterations = 5;
310 326
311 RUN_ON_AUDIO_THREAD(Create); 327 RUN_ON_AUDIO_THREAD(Create);
312 for (int i = 0; i < kHalfNumOutputs; ++i) { 328 for (int i = 0; i < kHalfNumOutputs; ++i) {
313 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); 329 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
314 } 330 }
315 RUN_ON_AUDIO_THREAD(Start); 331 RUN_ON_AUDIO_THREAD(Start);
316 WaitForDataToFlow(); 332 WaitForDataToFlow();
(...skipping 11 matching lines...) Expand all
328 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); 344 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
329 } 345 }
330 RUN_ON_AUDIO_THREAD(Stop); 346 RUN_ON_AUDIO_THREAD(Stop);
331 for (int i = 0; i < kHalfNumOutputs; ++i) { 347 for (int i = 0; i < kHalfNumOutputs; ++i) {
332 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); 348 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
333 } 349 }
334 RUN_ON_AUDIO_THREAD(Close); 350 RUN_ON_AUDIO_THREAD(Close);
335 WaitUntilClosed(); 351 WaitUntilClosed();
336 } 352 }
337 353
354 INSTANTIATE_TEST_CASE_P(SingleVersusMultithreaded,
355 VirtualAudioInputStreamTest,
356 ::testing::Values(false, true));
357
338 } // namespace media 358 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/virtual_audio_input_stream.cc ('k') | media/audio/virtual_audio_output_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698