Chromium Code Reviews| 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 |