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/debug/trace_event.h" | 7 #include "base/debug/trace_event.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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 | 171 |
172 // Make sure we don't call shutdown more than once. | 172 // Make sure we don't call shutdown more than once. |
173 if (stream_id_) { | 173 if (stream_id_) { |
174 is_started_ = false; | 174 is_started_ = false; |
175 | 175 |
176 filter_->RemoveDelegate(stream_id_); | 176 filter_->RemoveDelegate(stream_id_); |
177 Send(new AudioHostMsg_CloseStream(stream_id_)); | 177 Send(new AudioHostMsg_CloseStream(stream_id_)); |
178 stream_id_ = 0; | 178 stream_id_ = 0; |
179 } | 179 } |
180 | 180 |
| 181 // We can run into an issue where ShutDownOnIOThread is called right after |
| 182 // OnStreamCreated is called in cases where Start/Stop are called before we |
| 183 // get the OnStreamCreated callback. To handle that corner case, we call |
| 184 // Stop(). In most cases, the thread will already be stopped. |
| 185 // Another situation is when the IO thread goes away before Stop() is called |
| 186 // in which case, we cannot use the message loop to close the thread handle |
| 187 // and can't not rely on the main thread existing either. |
| 188 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 189 audio_thread_.Stop(NULL); |
181 audio_callback_.reset(); | 190 audio_callback_.reset(); |
182 } | 191 } |
183 | 192 |
184 void AudioDevice::SetVolumeOnIOThread(double volume) { | 193 void AudioDevice::SetVolumeOnIOThread(double volume) { |
185 DCHECK(message_loop()->BelongsToCurrentThread()); | 194 DCHECK(message_loop()->BelongsToCurrentThread()); |
186 if (stream_id_) | 195 if (stream_id_) |
187 Send(new AudioHostMsg_SetVolume(stream_id_, volume)); | 196 Send(new AudioHostMsg_SetVolume(stream_id_, volume)); |
188 } | 197 } |
189 | 198 |
190 void AudioDevice::OnStateChanged(AudioStreamState state) { | 199 void AudioDevice::OnStateChanged(AudioStreamState state) { |
(...skipping 20 matching lines...) Expand all Loading... |
211 #endif | 220 #endif |
212 | 221 |
213 // Takes care of the case when Stop() is called before OnStreamCreated(). | 222 // Takes care of the case when Stop() is called before OnStreamCreated(). |
214 if (!stream_id_) { | 223 if (!stream_id_) { |
215 base::SharedMemory::CloseHandle(handle); | 224 base::SharedMemory::CloseHandle(handle); |
216 // Close the socket handler. | 225 // Close the socket handler. |
217 base::SyncSocket socket(socket_handle); | 226 base::SyncSocket socket(socket_handle); |
218 return; | 227 return; |
219 } | 228 } |
220 | 229 |
| 230 DCHECK(audio_thread_.IsStopped()); |
221 audio_callback_.reset(new AudioDevice::AudioThreadCallback(audio_parameters_, | 231 audio_callback_.reset(new AudioDevice::AudioThreadCallback(audio_parameters_, |
222 handle, length, callback_)); | 232 handle, length, callback_)); |
223 audio_thread_.Start(audio_callback_.get(), socket_handle, "AudioDevice"); | 233 audio_thread_.Start(audio_callback_.get(), socket_handle, "AudioDevice"); |
224 | 234 |
225 // We handle the case where Play() and/or Pause() may have been called | 235 // We handle the case where Play() and/or Pause() may have been called |
226 // multiple times before OnStreamCreated() gets called. | 236 // multiple times before OnStreamCreated() gets called. |
227 is_started_ = true; | 237 is_started_ = true; |
228 if (play_on_start_) | 238 if (play_on_start_) |
229 PlayOnIOThread(); | 239 PlayOnIOThread(); |
230 } | 240 } |
231 | 241 |
232 void AudioDevice::Send(IPC::Message* message) { | 242 void AudioDevice::Send(IPC::Message* message) { |
233 filter_->Send(message); | 243 filter_->Send(message); |
234 } | 244 } |
235 | 245 |
236 void AudioDevice::WillDestroyCurrentMessageLoop() { | 246 void AudioDevice::WillDestroyCurrentMessageLoop() { |
| 247 LOG(ERROR) << "IO loop going away before the audio device has been stopped"; |
237 ShutDownOnIOThread(); | 248 ShutDownOnIOThread(); |
238 } | 249 } |
239 | 250 |
240 // AudioDevice::AudioThreadCallback | 251 // AudioDevice::AudioThreadCallback |
241 | 252 |
242 AudioDevice::AudioThreadCallback::AudioThreadCallback( | 253 AudioDevice::AudioThreadCallback::AudioThreadCallback( |
243 const AudioParameters& audio_parameters, | 254 const AudioParameters& audio_parameters, |
244 base::SharedMemoryHandle memory, | 255 base::SharedMemoryHandle memory, |
245 int memory_length, | 256 int memory_length, |
246 media::AudioRendererSink::RenderCallback* render_callback) | 257 media::AudioRendererSink::RenderCallback* render_callback) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 // to the browser process as float, so we don't lose precision for | 289 // to the browser process as float, so we don't lose precision for |
279 // audio hardware which has better than 16bit precision. | 290 // audio hardware which has better than 16bit precision. |
280 int16* data = reinterpret_cast<int16*>(shared_memory_.memory()); | 291 int16* data = reinterpret_cast<int16*>(shared_memory_.memory()); |
281 media::InterleaveFloatToInt16(audio_data_, data, | 292 media::InterleaveFloatToInt16(audio_data_, data, |
282 audio_parameters_.samples_per_packet); | 293 audio_parameters_.samples_per_packet); |
283 | 294 |
284 // Let the host know we are done. | 295 // Let the host know we are done. |
285 media::SetActualDataSizeInBytes(&shared_memory_, memory_length_, | 296 media::SetActualDataSizeInBytes(&shared_memory_, memory_length_, |
286 num_frames * audio_parameters_.channels * sizeof(data[0])); | 297 num_frames * audio_parameters_.channels * sizeof(data[0])); |
287 } | 298 } |
OLD | NEW |