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_input_device.h" | 5 #include "content/renderer/media/audio_input_device.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/threading/thread_restrictions.h" | 9 #include "base/threading/thread_restrictions.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 // NOTE: |completion| may be NULL. | 139 // NOTE: |completion| may be NULL. |
140 // Make sure we don't call shutdown more than once. | 140 // Make sure we don't call shutdown more than once. |
141 if (stream_id_) { | 141 if (stream_id_) { |
142 filter_->RemoveDelegate(stream_id_); | 142 filter_->RemoveDelegate(stream_id_); |
143 Send(new AudioInputHostMsg_CloseStream(stream_id_)); | 143 Send(new AudioInputHostMsg_CloseStream(stream_id_)); |
144 | 144 |
145 stream_id_ = 0; | 145 stream_id_ = 0; |
146 session_id_ = 0; | 146 session_id_ = 0; |
147 pending_device_ready_ = false; | 147 pending_device_ready_ = false; |
148 } | 148 } |
| 149 |
| 150 // We can run into an issue where ShutDownOnIOThread is called right after |
| 151 // OnStreamCreated is called in cases where Start/Stop are called before we |
| 152 // get the OnStreamCreated callback. To handle that corner case, we call |
| 153 // Stop(). In most cases, the thread will already be stopped. |
| 154 // Another situation is when the IO thread goes away before Stop() is called |
| 155 // in which case, we cannot use the message loop to close the thread handle |
| 156 // and can't not rely on the main thread existing either. |
| 157 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 158 audio_thread_.Stop(NULL); |
149 audio_callback_.reset(); | 159 audio_callback_.reset(); |
150 } | 160 } |
151 | 161 |
152 void AudioInputDevice::SetVolumeOnIOThread(double volume) { | 162 void AudioInputDevice::SetVolumeOnIOThread(double volume) { |
153 DCHECK(message_loop()->BelongsToCurrentThread()); | 163 DCHECK(message_loop()->BelongsToCurrentThread()); |
154 if (stream_id_) | 164 if (stream_id_) |
155 Send(new AudioInputHostMsg_SetVolume(stream_id_, volume)); | 165 Send(new AudioInputHostMsg_SetVolume(stream_id_, volume)); |
156 } | 166 } |
157 | 167 |
158 void AudioInputDevice::OnStreamCreated( | 168 void AudioInputDevice::OnStreamCreated( |
(...skipping 12 matching lines...) Expand all Loading... |
171 DVLOG(1) << "OnStreamCreated (stream_id=" << stream_id_ << ")"; | 181 DVLOG(1) << "OnStreamCreated (stream_id=" << stream_id_ << ")"; |
172 | 182 |
173 // Takes care of the case when Stop() is called before OnStreamCreated(). | 183 // Takes care of the case when Stop() is called before OnStreamCreated(). |
174 if (!stream_id_) { | 184 if (!stream_id_) { |
175 base::SharedMemory::CloseHandle(handle); | 185 base::SharedMemory::CloseHandle(handle); |
176 // Close the socket handler. | 186 // Close the socket handler. |
177 base::SyncSocket socket(socket_handle); | 187 base::SyncSocket socket(socket_handle); |
178 return; | 188 return; |
179 } | 189 } |
180 | 190 |
| 191 DCHECK(audio_thread_.IsStopped()); |
181 audio_callback_.reset( | 192 audio_callback_.reset( |
182 new AudioInputDevice::AudioThreadCallback(audio_parameters_, handle, | 193 new AudioInputDevice::AudioThreadCallback(audio_parameters_, handle, |
183 length, callback_)); | 194 length, callback_)); |
184 audio_thread_.Start(audio_callback_.get(), socket_handle, | 195 audio_thread_.Start(audio_callback_.get(), socket_handle, "AudioInputDevice"); |
185 "AudioInputDevice"); | |
186 | 196 |
187 MessageLoop::current()->PostTask(FROM_HERE, | 197 MessageLoop::current()->PostTask(FROM_HERE, |
188 base::Bind(&AudioInputDevice::StartOnIOThread, this)); | 198 base::Bind(&AudioInputDevice::StartOnIOThread, this)); |
189 } | 199 } |
190 | 200 |
191 void AudioInputDevice::OnVolume(double volume) { | 201 void AudioInputDevice::OnVolume(double volume) { |
192 NOTIMPLEMENTED(); | 202 NOTIMPLEMENTED(); |
193 } | 203 } |
194 | 204 |
195 void AudioInputDevice::OnStateChanged(AudioStreamState state) { | 205 void AudioInputDevice::OnStateChanged(AudioStreamState state) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 // Notify the client that the device has been started. | 261 // Notify the client that the device has been started. |
252 if (event_handler_) | 262 if (event_handler_) |
253 event_handler_->OnDeviceStarted(device_id); | 263 event_handler_->OnDeviceStarted(device_id); |
254 } | 264 } |
255 | 265 |
256 void AudioInputDevice::Send(IPC::Message* message) { | 266 void AudioInputDevice::Send(IPC::Message* message) { |
257 filter_->Send(message); | 267 filter_->Send(message); |
258 } | 268 } |
259 | 269 |
260 void AudioInputDevice::WillDestroyCurrentMessageLoop() { | 270 void AudioInputDevice::WillDestroyCurrentMessageLoop() { |
| 271 LOG(ERROR) << "IO loop going away before the input device has been stopped"; |
261 ShutDownOnIOThread(); | 272 ShutDownOnIOThread(); |
262 } | 273 } |
263 | 274 |
264 // AudioInputDevice::AudioThreadCallback | 275 // AudioInputDevice::AudioThreadCallback |
265 AudioInputDevice::AudioThreadCallback::AudioThreadCallback( | 276 AudioInputDevice::AudioThreadCallback::AudioThreadCallback( |
266 const AudioParameters& audio_parameters, | 277 const AudioParameters& audio_parameters, |
267 base::SharedMemoryHandle memory, | 278 base::SharedMemoryHandle memory, |
268 int memory_length, | 279 int memory_length, |
269 CaptureCallback* capture_callback) | 280 CaptureCallback* capture_callback) |
270 : AudioDeviceThread::Callback(audio_parameters, memory, memory_length), | 281 : AudioDeviceThread::Callback(audio_parameters, memory, memory_length), |
(...skipping 23 matching lines...) Expand all Loading... |
294 channel_index, | 305 channel_index, |
295 bytes_per_sample, | 306 bytes_per_sample, |
296 number_of_frames); | 307 number_of_frames); |
297 } | 308 } |
298 | 309 |
299 // Deliver captured data to the client in floating point format | 310 // Deliver captured data to the client in floating point format |
300 // and update the audio-delay measurement. | 311 // and update the audio-delay measurement. |
301 capture_callback_->Capture(audio_data_, number_of_frames, | 312 capture_callback_->Capture(audio_data_, number_of_frames, |
302 audio_delay_milliseconds); | 313 audio_delay_milliseconds); |
303 } | 314 } |
OLD | NEW |