OLD | NEW |
---|---|
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 "content/renderer/media/audio_device.h" | 5 #include "content/renderer/media/audio_device.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 params.bits_per_sample = bits_per_sample_; | 101 params.bits_per_sample = bits_per_sample_; |
102 params.samples_per_packet = buffer_size_; | 102 params.samples_per_packet = buffer_size_; |
103 | 103 |
104 ChildProcess::current()->io_message_loop()->PostTask( | 104 ChildProcess::current()->io_message_loop()->PostTask( |
105 FROM_HERE, | 105 FROM_HERE, |
106 base::Bind(&AudioDevice::InitializeOnIOThread, this, params)); | 106 base::Bind(&AudioDevice::InitializeOnIOThread, this, params)); |
107 } | 107 } |
108 | 108 |
109 void AudioDevice::Stop() { | 109 void AudioDevice::Stop() { |
110 DCHECK(MessageLoop::current() != ChildProcess::current()->io_message_loop()); | 110 DCHECK(MessageLoop::current() != ChildProcess::current()->io_message_loop()); |
111 // Max waiting time for Stop() to complete. If this time limit is passed, | |
112 // we will stop waiting and return false. It ensures that Stop() can't block | |
113 // the calling thread forever. | |
114 const base::TimeDelta kMaxTimeOut = base::TimeDelta::FromMilliseconds(1000); | |
115 | |
116 base::WaitableEvent completion(false, false); | 111 base::WaitableEvent completion(false, false); |
117 | 112 |
118 ChildProcess::current()->io_message_loop()->PostTask( | 113 ChildProcess::current()->io_message_loop()->PostTask( |
119 FROM_HERE, | 114 FROM_HERE, |
120 base::Bind(&AudioDevice::ShutDownOnIOThread, this, &completion)); | 115 base::Bind(&AudioDevice::ShutDownOnIOThread, this, &completion)); |
121 | 116 |
122 // We wait here for the IO task to be completed to remove race conflicts | 117 // We wait here for the IO task to be completed to remove race conflicts |
123 // with OnLowLatencyCreated() and to ensure that Stop() acts as a synchronous | 118 // with OnLowLatencyCreated() and to ensure that Stop() acts as a synchronous |
124 // function call. | 119 // function call. |
125 if (!completion.TimedWait(kMaxTimeOut)) { | 120 completion.Wait(); |
Chris Rogers
2012/01/06 18:26:28
Is there a case where the time-out is actually nee
tommi (sloooow) - chröme
2012/01/12 13:13:07
What about moving the call to ShutDownAudioThread
| |
126 LOG(ERROR) << "Failed to shut down audio output on IO thread"; | |
127 } | |
128 ShutDownAudioThread(); | 121 ShutDownAudioThread(); |
129 } | 122 } |
130 | 123 |
131 void AudioDevice::Play() { | 124 void AudioDevice::Play() { |
132 ChildProcess::current()->io_message_loop()->PostTask( | 125 ChildProcess::current()->io_message_loop()->PostTask( |
133 FROM_HERE, | 126 FROM_HERE, |
134 base::Bind(&AudioDevice::PlayOnIOThread, this)); | 127 base::Bind(&AudioDevice::PlayOnIOThread, this)); |
135 } | 128 } |
136 | 129 |
137 void AudioDevice::Pause(bool flush) { | 130 void AudioDevice::Pause(bool flush) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 // the stream is first starting. | 181 // the stream is first starting. |
189 play_on_start_ = false; | 182 play_on_start_ = false; |
190 } | 183 } |
191 } | 184 } |
192 | 185 |
193 void AudioDevice::ShutDownOnIOThread(base::WaitableEvent* completion) { | 186 void AudioDevice::ShutDownOnIOThread(base::WaitableEvent* completion) { |
194 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop()); | 187 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop()); |
195 is_started_ = false; | 188 is_started_ = false; |
196 | 189 |
197 // Make sure we don't call shutdown more than once. | 190 // Make sure we don't call shutdown more than once. |
198 if (!stream_id_) { | 191 if (!stream_id_) { |
tommi (sloooow) - chröme
2012/01/12 13:13:07
nit: this method can be simplified by removing thi
| |
199 if (completion) | 192 if (completion) |
200 completion->Signal(); | 193 completion->Signal(); |
201 return; | 194 return; |
202 } | 195 } |
203 | 196 |
204 filter_->RemoveDelegate(stream_id_); | 197 filter_->RemoveDelegate(stream_id_); |
205 Send(new AudioHostMsg_CloseStream(stream_id_)); | 198 Send(new AudioHostMsg_CloseStream(stream_id_)); |
206 stream_id_ = 0; | 199 stream_id_ = 0; |
207 | 200 |
208 if (completion) | 201 if (completion) |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 data, | 331 data, |
339 buffer_size_); | 332 buffer_size_); |
340 } | 333 } |
341 return num_frames; | 334 return num_frames; |
342 } | 335 } |
343 | 336 |
344 void AudioDevice::ShutDownAudioThread() { | 337 void AudioDevice::ShutDownAudioThread() { |
345 // Synchronize with OnLowLatencyCreated(). | 338 // Synchronize with OnLowLatencyCreated(). |
346 base::AutoLock auto_lock(lock_); | 339 base::AutoLock auto_lock(lock_); |
347 if (audio_thread_.get()) { | 340 if (audio_thread_.get()) { |
348 // Close the socket to terminate the main thread function in the | 341 // Close the socket to terminate the main thread function in the |
tommi (sloooow) - chröme
2012/01/12 13:13:07
add a check that makes sure we're not currently on
| |
349 // audio thread. | 342 // audio thread. |
350 audio_socket_->Close(); | 343 audio_socket_->Close(); |
351 audio_thread_->Join(); | 344 audio_thread_->Join(); |
352 audio_thread_.reset(NULL); | 345 audio_thread_.reset(NULL); |
353 } | 346 } |
354 } | 347 } |
OLD | NEW |